From c407652878b43fef1a78c25c09a126c0a2b2e228 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Wed, 1 May 2019 04:07:25 +0200 Subject: [PATCH] clear stencil on context creation with renderpass begin, handle sample count 1 with a single image --- CMakeLists.txt | 2 +- src/vkvg_context.c | 42 +++++++++++++++++----------- src/vkvg_context_internal.c | 21 ++++---------- src/vkvg_context_internal.h | 3 +- src/vkvg_device.c | 11 +++++--- src/vkvg_device_internal.c | 30 ++++++++++---------- src/vkvg_device_internal.h | 5 ++-- src/vkvg_fonts.c | 6 ++-- src/vkvg_surface.c | 56 ++++++++++++++++++++++--------------- src/vkvg_surface_internal.h | 2 +- tests/common/test.c | 2 +- tests/img_surf.c | 2 +- tests/random_rects.c | 4 +-- tests/svg.c | 1 + vkh | 2 +- 15 files changed, 104 insertions(+), 85 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8609892..b643e68 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.9) -PROJECT(vkvg VERSION 0.1.0 DESCRIPTION "Vulkan Vector Graphic") +PROJECT(vkvg VERSION 0.1.1 DESCRIPTION "Vulkan Vector Graphic") INCLUDE(CheckSymbolExists) INCLUDE(CheckIncludeFile) diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 8558e79..2a5db0c 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2018 Jean-Philippe Bruyère * * Permission is hereby granted, free of charge, to any person obtaining a copy of @@ -31,6 +31,12 @@ static vec2 debugLinePoints[1000]; static uint32_t dlpCount = 0; #endif +static VkClearValue clearValues[3] = { + { {{0.0f, 0.0f, 0.0f, 1.0f}} }, + { {{1.0f, 0}} }, + { {{0.0f, 0.0f, 0.0f, 1.0f}} } +}; + /** * @brief create new context for surface * @param drawing operation output surface @@ -69,6 +75,13 @@ VkvgContext vkvg_create(VkvgSurface surf) const VkClearRect cr = {{{0},{ctx->pSurf->width, ctx->pSurf->height}},0,1}; ctx->clearRect = cr; + ctx->renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + ctx->renderPassBeginInfo.framebuffer = ctx->pSurf->fb; + ctx->renderPassBeginInfo.renderArea.extent.width = ctx->pSurf->width; + ctx->renderPassBeginInfo.renderArea.extent.height = ctx->pSurf->height; + ctx->renderPassBeginInfo.pClearValues = clearValues; + ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass_ClearStencil; + ctx->renderPassBeginInfo.clearValueCount = 3; ctx->pPrev = surf->dev->lastCtx; if (ctx->pPrev != NULL) @@ -82,6 +95,7 @@ VkvgContext vkvg_create(VkvgSurface surf) ctx->points = (vec2*) malloc (VKVG_VBO_SIZE*sizeof(vec2)); ctx->pathes = (uint32_t*) malloc (VKVG_PATHES_SIZE*sizeof(uint32_t)); + //for context to be thread safe, command pool and descriptor pool have to be created in the thread of the context. ctx->cmdPool = vkh_cmd_pool_create ((VkhDevice)dev, dev->gQueue->familyIndex, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); _create_vertices_buff (ctx); @@ -99,10 +113,6 @@ VkvgContext vkvg_create(VkvgSurface surf) _init_cmd_buff (ctx); _clear_path (ctx); - vkvg_reset_clip (ctx); - vkh_cmd_end (ctx->cmd); - _submit_wait_and_reset_cmd(ctx); - ctx->references = 1; ctx->status = VKVG_STATUS_SUCCESS; return ctx; @@ -732,17 +742,17 @@ void vkvg_save (VkvgContext ctx){ VkvgDevice dev = ctx->pSurf->dev; vkvg_context_save_t* sav = (vkvg_context_save_t*)calloc(1,sizeof(vkvg_context_save_t)); - sav->stencilMS = vkh_image_ms_create ((VkhDevice)dev,VK_FORMAT_S8_UINT, dev->samples, ctx->pSurf->width, ctx->pSurf->height, + sav->stencil = vkh_image_ms_create ((VkhDevice)dev,VK_FORMAT_S8_UINT, dev->samples, ctx->pSurf->width, ctx->pSurf->height, VMA_MEMORY_USAGE_GPU_ONLY, VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT); vkh_cmd_begin (ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); ctx->cmdStarted = true; - vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencilMS, VK_IMAGE_ASPECT_STENCIL_BIT, + vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - vkh_image_set_layout (ctx->cmd, sav->stencilMS, VK_IMAGE_ASPECT_STENCIL_BIT, + vkh_image_set_layout (ctx->cmd, sav->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); @@ -750,11 +760,11 @@ void vkvg_save (VkvgContext ctx){ .dstSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1}, .extent = {ctx->pSurf->width,ctx->pSurf->height,1}}; vkCmdCopyImage(ctx->cmd, - vkh_image_get_vkimage (ctx->pSurf->stencilMS),VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - vkh_image_get_vkimage (sav->stencilMS), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + vkh_image_get_vkimage (ctx->pSurf->stencil),VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + vkh_image_get_vkimage (sav->stencil), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cregion); - vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencilMS, VK_IMAGE_ASPECT_STENCIL_BIT, + vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT); @@ -806,10 +816,10 @@ void vkvg_restore (VkvgContext ctx){ vkh_cmd_begin (ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); ctx->cmdStarted = true; - vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencilMS, VK_IMAGE_ASPECT_STENCIL_BIT, + vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - vkh_image_set_layout (ctx->cmd, sav->stencilMS, VK_IMAGE_ASPECT_STENCIL_BIT, + vkh_image_set_layout (ctx->cmd, sav->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); @@ -817,10 +827,10 @@ void vkvg_restore (VkvgContext ctx){ .dstSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1}, .extent = {ctx->pSurf->width,ctx->pSurf->height,1}}; vkCmdCopyImage(ctx->cmd, - vkh_image_get_vkimage (sav->stencilMS), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - vkh_image_get_vkimage (ctx->pSurf->stencilMS),VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + vkh_image_get_vkimage (sav->stencil), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + vkh_image_get_vkimage (ctx->pSurf->stencil),VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cregion); - vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencilMS, VK_IMAGE_ASPECT_STENCIL_BIT, + vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT); diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index 2010e19..92f44c0 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -238,6 +238,7 @@ void _end_render_pass (VkvgContext ctx) { LOG(LOG_INFO, "FLUSH Context: ctx = %lu; vert cpt = %d; ind cpt = %d\n", ctx, ctx->vertCount -4, ctx->indCount - 6); _record_draw_cmd (ctx); CmdEndRenderPass (ctx->cmd); + ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass; } void _flush_cmd_buff (VkvgContext ctx){ if (!ctx->cmdStarted) @@ -271,22 +272,11 @@ void _init_cmd_buff (VkvgContext ctx){ //VkClearValue clearValues[2]; //clearValues[0].color = { { 0.0f, 0.0f, 0.0f, 1.0f } }; //clearValues[1].depthStencil = { 1.0f, 0 }; - /*VkClearValue clearValues[4] = { - { 0.0f, 1.0f, 0.0f, 1.0f }, - { 0.0f, 0.0f, 0.0f, 1.0f }, - { 1.0f, 0 }, - { 1.0f, 0 } - };*/ } -void _start_cmd_for_render_pass (VkvgContext ctx) { - VkRenderPassBeginInfo renderPassBeginInfo = { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .renderPass = ctx->pSurf->dev->renderPass, - .framebuffer = ctx->pSurf->fb, - .renderArea.extent = {ctx->pSurf->width,ctx->pSurf->height}}; - //.clearValueCount = 4, - //.pClearValues = clearValues}; + +void _start_cmd_for_render_pass (VkvgContext ctx) { vkh_cmd_begin (ctx->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); if (ctx->pSurf->img->layout == VK_IMAGE_LAYOUT_UNDEFINED){ @@ -299,7 +289,7 @@ void _start_cmd_for_render_pass (VkvgContext ctx) { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); } - CmdBeginRenderPass (ctx->cmd, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); + CmdBeginRenderPass (ctx->cmd, &ctx->renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); VkViewport viewport = {0,0,ctx->pSurf->width,ctx->pSurf->height,0,1}; CmdSetViewport(ctx->cmd, 0, 1, &viewport); VkRect2D scissor = {{0,0},{ctx->pSurf->width,ctx->pSurf->height}}; @@ -317,6 +307,7 @@ void _start_cmd_for_render_pass (VkvgContext ctx) { CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); _update_push_constants (ctx); + ctx->cmdStarted = true; } //compute inverse mat used in shader when context matrix has changed @@ -629,7 +620,7 @@ bool ptInTriangle(vec2 p, vec2 p0, vec2 p1, vec2 p2) { void _free_ctx_save (vkvg_context_save_t* sav){ free(sav->selectedFont.fontFile); - vkh_image_destroy (sav->stencilMS); + vkh_image_destroy (sav->stencil); free (sav); } diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index 3ae31bb..bc222d3 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -51,7 +51,7 @@ typedef struct { typedef struct _vkvg_context_save_t{ struct _vkvg_context_save_t* pNext; - VkhImage stencilMS; + VkhImage stencil; uint32_t stencilRef; float lineWidth; @@ -131,6 +131,7 @@ typedef struct _vkvg_context_t { vkvg_context_save_t* pSavedCtxs;//last ctx saved ptr VkClearRect clearRect; + VkRenderPassBeginInfo renderPassBeginInfo; }vkvg_context; typedef struct _ear_clip_point{ diff --git a/src/vkvg_device.c b/src/vkvg_device.c index a390dac..f57bae3 100644 --- a/src/vkvg_device.c +++ b/src/vkvg_device.c @@ -88,10 +88,13 @@ VkvgDevice vkvg_device_create_multisample(VkInstance inst, VkPhysicalDevice phy, _create_pipeline_cache (dev); _init_fonts_cache (dev); - if (dev->deferredResolve) - _setupRenderPassDeferredResolve(dev); - else - _setupRenderPass (dev); + if (dev->deferredResolve || dev->samples == VK_SAMPLE_COUNT_1_BIT){ + dev->renderPass = _setupRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD); + dev->renderPass_ClearStencil = _setupRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR); + }else{ + dev->renderPass = _createRenderPassMS (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD); + dev->renderPass_ClearStencil = _createRenderPassMS (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR); + } _createDescriptorSetLayout (dev); _setupPipelines (dev); diff --git a/src/vkvg_device_internal.c b/src/vkvg_device_internal.c index 5ca87e3..d8ab85d 100644 --- a/src/vkvg_device_internal.c +++ b/src/vkvg_device_internal.c @@ -47,12 +47,12 @@ void _create_pipeline_cache(VkvgDevice dev){ VK_CHECK_RESULT(vkCreatePipelineCache(dev->vkDev, &pipelineCacheCreateInfo, NULL, &dev->pipelineCache)); } -void _setupRenderPassDeferredResolve(VkvgDevice dev) +VkRenderPass _setupRenderPassNoResolve(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp) { VkAttachmentDescription attColor = { .format = FB_COLOR_FORMAT, .samples = dev->samples, - .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, + .loadOp = loadOp, .storeOp = VK_ATTACHMENT_STORE_OP_STORE, .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, @@ -63,7 +63,7 @@ void _setupRenderPassDeferredResolve(VkvgDevice dev) .samples = dev->samples, .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD, + .stencilLoadOp = stencilLoadOp, .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE, .initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; @@ -97,15 +97,16 @@ void _setupRenderPassDeferredResolve(VkvgDevice dev) .dependencyCount = 2, .pDependencies = dependencies }; - - VK_CHECK_RESULT(vkCreateRenderPass(dev->vkDev, &renderPassInfo, NULL, &dev->renderPass)); + VkRenderPass rp; + VK_CHECK_RESULT(vkCreateRenderPass(dev->vkDev, &renderPassInfo, NULL, &rp)); + return rp; } -void _setupRenderPass(VkvgDevice dev) +VkRenderPass _createRenderPassMS(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp) { VkAttachmentDescription attColor = { .format = FB_COLOR_FORMAT, .samples = dev->samples, - .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, + .loadOp = loadOp, .storeOp = VK_ATTACHMENT_STORE_OP_STORE, .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, @@ -125,15 +126,15 @@ void _setupRenderPass(VkvgDevice dev) .samples = dev->samples, .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD, + .stencilLoadOp = stencilLoadOp, .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE, .initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; - VkAttachmentDescription attachments[] = {attColor,attColorResolve,attDS}; - VkAttachmentReference colorRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - VkAttachmentReference resolveRef= {1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - VkAttachmentReference dsRef = {2, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; + VkAttachmentDescription attachments[] = {attColorResolve,attDS,attColor}; + VkAttachmentReference resolveRef= {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + VkAttachmentReference dsRef = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; + VkAttachmentReference colorRef = {2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; VkSubpassDescription subpassDescription = { .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, .colorAttachmentCount = 1, @@ -161,8 +162,9 @@ void _setupRenderPass(VkvgDevice dev) .dependencyCount = 2, .pDependencies = dependencies }; - - VK_CHECK_RESULT(vkCreateRenderPass(dev->vkDev, &renderPassInfo, NULL, &dev->renderPass)); + VkRenderPass rp; + VK_CHECK_RESULT(vkCreateRenderPass(dev->vkDev, &renderPassInfo, NULL, &rp)); + return rp; } void _setupPipelines(VkvgDevice dev) diff --git a/src/vkvg_device_internal.h b/src/vkvg_device_internal.h index f8af1ec..8bcca38 100644 --- a/src/vkvg_device_internal.h +++ b/src/vkvg_device_internal.h @@ -60,6 +60,7 @@ typedef struct _vkvg_device_t{ VkhQueue gQueue; /**< Vulkan Queue with Graphic flag */ MUTEX gQMutex; /**< queue submission has to be externally syncronized */ VkRenderPass renderPass; /**< Vulkan render pass, common for all surfaces */ + VkRenderPass renderPass_ClearStencil;/**< Vulkan render pass for first draw with context, stencil has to be cleared */ uint32_t references; /**< Reference count, prevent destroying device if still in use */ VkCommandPool cmdPool; /**< Global command pool for processing on surfaces without context */ @@ -100,8 +101,8 @@ void _init_function_pointers (VkvgDevice dev); void _create_empty_texture (VkvgDevice dev); void _check_image_format_properties (VkvgDevice dev); void _create_pipeline_cache (VkvgDevice dev); -void _setupRenderPass (VkvgDevice dev); -void _setupRenderPassDeferredResolve (VkvgDevice dev); +VkRenderPass _createRenderPassMS(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp); +VkRenderPass _setupRenderPassNoResolve(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp); void _setupPipelines (VkvgDevice dev); void _createDescriptorSetLayout (VkvgDevice dev); void _flush_all_contexes (VkvgDevice dev); diff --git a/src/vkvg_fonts.c b/src/vkvg_fonts.c index 6c7d177..dbb34f6 100644 --- a/src/vkvg_fonts.c +++ b/src/vkvg_fonts.c @@ -385,7 +385,7 @@ void _update_current_font (VkvgContext ctx) { } } //Get harfBuzz buffer for provided text. -hb_buffer_t * _get_hb_buffer (VkvgContext ctx, const char* text) { +hb_buffer_t * _get_hb_buffer (_vkvg_font_t* font, const char* text) { hb_buffer_t *buf = hb_buffer_create(); const char *lng = "fr"; @@ -398,7 +398,7 @@ hb_buffer_t * _get_hb_buffer (VkvgContext ctx, const char* text) { hb_buffer_set_language (buf, hb_language_from_string(lng,strlen(lng))); hb_buffer_add_utf8 (buf, text, strlen(text), 0, strlen(text)); - hb_shape (ctx->currentFont->hb_font, buf, NULL, 0); + hb_shape (font->hb_font, buf, NULL, 0); return buf; } //retrieve global font extends of context's current font as defined by FreeType @@ -429,7 +429,7 @@ void _create_text_run (VkvgContext ctx, const char* text, VkvgText textRun) { _update_current_font (ctx); - textRun->hbBuf = _get_hb_buffer (ctx, text); + textRun->hbBuf = _get_hb_buffer (ctx->currentFont, text); textRun->font = ctx->currentFont; textRun->dev = ctx->pSurf->dev; diff --git a/src/vkvg_surface.c b/src/vkvg_surface.c index a15f700..f3958e0 100644 --- a/src/vkvg_surface.c +++ b/src/vkvg_surface.c @@ -74,14 +74,18 @@ void _clear_surface (VkvgSurface surf, VkImageAspectFlags aspect) VkClearColorValue cclr = {{0,0,0,0}}; VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT,0,1,0,1}; - vkh_image_set_layout (cmd, surf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT, + VkhImage img = surf->imgMS; + if (surf->dev->samples == VK_SAMPLE_COUNT_1_BIT) + img = surf->img; + + vkh_image_set_layout (cmd, img, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - vkCmdClearColorImage(cmd, vkh_image_get_vkimage (surf->imgMS), + vkCmdClearColorImage(cmd, vkh_image_get_vkimage (img), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &cclr, 1, &range); - vkh_image_set_layout (cmd, surf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT, + vkh_image_set_layout (cmd, img, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); } @@ -89,14 +93,14 @@ void _clear_surface (VkvgSurface surf, VkImageAspectFlags aspect) VkClearDepthStencilValue clr = {0,0}; VkImageSubresourceRange range = {VK_IMAGE_ASPECT_STENCIL_BIT,0,1,0,1}; - vkh_image_set_layout (cmd, surf->stencilMS, VK_IMAGE_ASPECT_STENCIL_BIT, + vkh_image_set_layout (cmd, surf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - vkCmdClearDepthStencilImage (cmd, vkh_image_get_vkimage (surf->stencilMS), + vkCmdClearDepthStencilImage (cmd, vkh_image_get_vkimage (surf->stencil), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,&clr,1,&range); - vkh_image_set_layout (cmd, surf->stencilMS, VK_IMAGE_ASPECT_STENCIL_BIT, + vkh_image_set_layout (cmd, surf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT); } @@ -110,19 +114,23 @@ void _create_surface_main_image (VkvgSurface surf){ VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT); vkh_image_create_descriptor(surf->img, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE); } -void _create_surface_ms_images (VkvgSurface surf) { - surf->imgMS = vkh_image_ms_create((VkhDevice)surf->dev,surf->format,surf->dev->samples,surf->width,surf->height,VMA_MEMORY_USAGE_GPU_ONLY, - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT); - surf->stencilMS = vkh_image_ms_create((VkhDevice)surf->dev,VK_FORMAT_S8_UINT,surf->dev->samples,surf->width,surf->height,VMA_MEMORY_USAGE_GPU_ONLY, - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT); - vkh_image_create_descriptor(surf->imgMS, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE); - vkh_image_create_descriptor(surf->stencilMS, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_STENCIL_BIT, VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE); +//create multisample color img if sample count > 1 and the stencil buffer multisampled or not +void _create_surface_secondary_images (VkvgSurface surf) { + if (surf->dev->samples > VK_SAMPLE_COUNT_1_BIT){ + surf->imgMS = vkh_image_ms_create((VkhDevice)surf->dev,surf->format,surf->dev->samples,surf->width,surf->height,VMA_MEMORY_USAGE_GPU_ONLY, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT); + vkh_image_create_descriptor(surf->imgMS, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, VK_FILTER_NEAREST, + VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE); + } + surf->stencil = vkh_image_ms_create((VkhDevice)surf->dev,VK_FORMAT_S8_UINT,surf->dev->samples,surf->width,surf->height,VMA_MEMORY_USAGE_GPU_ONLY, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT); + vkh_image_create_descriptor(surf->stencil, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_STENCIL_BIT, VK_FILTER_NEAREST, + VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE); } void _create_framebuffer (VkvgSurface surf) { VkImageView attachments[] = { - vkh_image_get_view (surf->imgMS), vkh_image_get_view (surf->img), - vkh_image_get_view (surf->stencilMS), + vkh_image_get_view (surf->stencil), + vkh_image_get_view (surf->imgMS), }; VkFramebufferCreateInfo frameBufferCreateInfo = { .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, .renderPass = surf->dev->renderPass, @@ -131,8 +139,10 @@ void _create_framebuffer (VkvgSurface surf) { .width = surf->width, .height = surf->height, .layers = 1 }; - if (surf->dev->deferredResolve) { - attachments[1] = attachments[2]; + if (surf->dev->samples == VK_SAMPLE_COUNT_1_BIT) + frameBufferCreateInfo.attachmentCount = 2; + else if (surf->dev->deferredResolve) { + attachments[0] = attachments[2]; frameBufferCreateInfo.attachmentCount = 2; } VK_CHECK_RESULT(vkCreateFramebuffer(surf->dev->vkDev, &frameBufferCreateInfo, NULL, &surf->fb)); @@ -141,14 +151,14 @@ void _init_surface (VkvgSurface surf) { surf->format = FB_COLOR_FORMAT;//force bgra internally _create_surface_main_image (surf); - _create_surface_ms_images (surf); + _create_surface_secondary_images (surf); _create_framebuffer (surf); _clear_surface (surf, VK_IMAGE_ASPECT_STENCIL_BIT); #if DEBUG vkh_image_set_name(surf->img, "surfImg"); vkh_image_set_name(surf->imgMS, "surfImgMS"); - vkh_image_set_name(surf->stencilMS, "surfStencil"); + vkh_image_set_name(surf->stencil, "surfStencil"); #endif } void vkvg_surface_clear (VkvgSurface surf) { @@ -182,7 +192,7 @@ VkvgSurface vkvg_surface_create_for_VkhImage (VkvgDevice dev, void* vkhImg) { vkh_image_create_sampler(img, VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE); - _create_surface_ms_images (surf); + _create_surface_secondary_images (surf); _create_framebuffer (surf); _clear_surface (surf, VK_IMAGE_ASPECT_STENCIL_BIT); @@ -315,10 +325,10 @@ void vkvg_surface_destroy(VkvgSurface surf) if (surf->references > 0) return; vkDestroyFramebuffer(surf->dev->vkDev, surf->fb, NULL); - if (!surf->img->imported) - vkh_image_destroy(surf->img); + + vkh_image_destroy(surf->img); vkh_image_destroy(surf->imgMS); - vkh_image_destroy(surf->stencilMS); + vkh_image_destroy(surf->stencil); vkvg_device_destroy (surf->dev); free(surf); diff --git a/src/vkvg_surface_internal.h b/src/vkvg_surface_internal.h index 5b0aa7e..11e4408 100644 --- a/src/vkvg_surface_internal.h +++ b/src/vkvg_surface_internal.h @@ -34,7 +34,7 @@ typedef struct _vkvg_surface_t { VkFramebuffer fb; VkhImage img; VkhImage imgMS; - VkhImage stencilMS; + VkhImage stencil; uint32_t references; }vkvg_surface; diff --git a/tests/common/test.c b/tests/common/test.c index b23c39a..285b253 100644 --- a/tests/common/test.c +++ b/tests/common/test.c @@ -76,7 +76,7 @@ void perform_test (void(*testfunc)(void),uint width, uint height) { bool deferredResolve = false; - device = vkvg_device_create_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0, VK_SAMPLE_COUNT_8_BIT, deferredResolve); + device = vkvg_device_create_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0, VK_SAMPLE_COUNT_1_BIT, deferredResolve); vkvg_device_set_dpy(device, 96, 96); diff --git a/tests/img_surf.c b/tests/img_surf.c index 81241ab..42c4797 100644 --- a/tests/img_surf.c +++ b/tests/img_surf.c @@ -2,7 +2,7 @@ void test(){ VkvgContext ctx = vkvg_create(surf); - + vkvg_set_fill_rule(ctx,VKVG_FILL_RULE_EVEN_ODD); VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); vkvg_translate(ctx,200,200); diff --git a/tests/random_rects.c b/tests/random_rects.c index 612905f..e2063bb 100644 --- a/tests/random_rects.c +++ b/tests/random_rects.c @@ -10,8 +10,8 @@ void test(){ VkvgContext ctx = vkvg_create(surf); vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO); - vkvg_set_line_width(ctx,1); - for (int i=0; i<5000; i++) { + vkvg_set_line_width(ctx,2); + for (int i=0; i<1500; i++) { randomize_color(ctx); float x = trunc( (0.5*(float)w*rand())/RAND_MAX ); float y = trunc( (0.5*(float)w*rand())/RAND_MAX ); diff --git a/tests/svg.c b/tests/svg.c index 3dbec1b..635db33 100644 --- a/tests/svg.c +++ b/tests/svg.c @@ -23,6 +23,7 @@ void test_svg () { vkvg_matrix_translate(&mat,-512,-400); VkvgContext ctx = vkvg_create(surf); + vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD); vkvg_set_source_rgba(ctx,1.0,1.0,1.0,1); vkvg_paint(ctx); diff --git a/vkh b/vkh index b93c31b..e9cd185 160000 --- a/vkh +++ b/vkh @@ -1 +1 @@ -Subproject commit b93c31b7ba01ccfbc12dd7e907aa6cd6a986ae81 +Subproject commit e9cd1855b11fa23be0c9a452d9be4b239d76a485 -- 2.47.3