diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2026-10-24 09:36:10 +0200 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2026-10-24 09:47:23 +0200 |
| commit | 86ddd9ba28461dad4cec23f01d2a0e5c1f44b0e8 (patch) | |
| tree | 2b1b608ccec8a7e8d0cc881361037a448f3c662f | |
| parent | 64bdd9f5b5a9d515de420830de085ff5203b9278 (diff) | |
save stencil only on reset with saved clips on stackµ
| -rw-r--r-- | gunit_tests/save_restore.cpp | 157 | ||||
| -rw-r--r-- | samples/tests/clip.cpp | 2 | ||||
| -rw-r--r-- | samples/tests/save_restore.cpp | 83 | ||||
| -rw-r--r-- | src/vkvg_context.c | 146 | ||||
| -rw-r--r-- | src/vkvg_context_internal.h | 2 |
5 files changed, 304 insertions, 86 deletions
diff --git a/gunit_tests/save_restore.cpp b/gunit_tests/save_restore.cpp index f82a208..39510bd 100644 --- a/gunit_tests/save_restore.cpp +++ b/gunit_tests/save_restore.cpp @@ -37,88 +37,189 @@ class SaveRestoreTest : public DrawTestBase { float x = cos(a) * 256; float y = sin(a) * 256; + vkvg_restore(ctx); + EXPECT_EQ(VKVG_STATUS_SUCCESS, vkvg_status(ctx)); + vkvg_set_line_width(ctx, 2.f); vkvg_move_to(ctx, 256.f - x, 256.f - y); vkvg_line_to(ctx, 256.f + x, 256.f + y); vkvg_set_source_rgba(ctx, 0.f, 1.f, 0.f, 0.6f); vkvg_stroke(ctx); - vkvg_restore(ctx); - EXPECT_EQ(VKVG_STATUS_SUCCESS, vkvg_status(ctx)); - depth--; } }; -TEST_F(SaveRestoreTest, RestoreClip1) { +TEST_F(SaveRestoreTest, RecursePaint3) { VkvgContext ctx = vkvg_create(surf); - vkvg_arc(ctx, 140, 140, 100, 0, 2.f * M_PI); - vkvg_clip(ctx); - vkvg_save(ctx); - vkvg_reset_clip(ctx); - vkvg_restore(ctx); - vkvg_set_source_surface(ctx, imgSurf, 0, 0); - vkvg_paint(ctx); - EXPECT_EQ(VKVG_STATUS_SUCCESS, vkvg_status(ctx)); + EXPECT_NO_FATAL_FAILURE(recurse_draw(ctx, 0, 3)); + vkvg_destroy(ctx); compareWithRefImage(); } -TEST_F(SaveRestoreTest, RecursePaint3) { +TEST_F(SaveRestoreTest, RecursePaint10) { VkvgContext ctx = vkvg_create(surf); - EXPECT_NO_FATAL_FAILURE(recurse_draw(ctx, 0, 3)); + EXPECT_NO_FATAL_FAILURE(recurse_draw(ctx, 0, 10)); vkvg_destroy(ctx); compareWithRefImage(); } - -TEST_F(SaveRestoreTest, RecursePaint6) { +TEST_F(SaveRestoreTest, RecursePaint20) { VkvgContext ctx = vkvg_create(surf); - EXPECT_NO_FATAL_FAILURE(recurse_draw(ctx, 0, 6)); + EXPECT_NO_FATAL_FAILURE(recurse_draw(ctx, 0, 20)); vkvg_destroy(ctx); compareWithRefImage(); } - -TEST_F(SaveRestoreTest, RecursePaint9) { +TEST_F(SaveRestoreTest, NZ) { VkvgContext ctx = vkvg_create(surf); + vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO); - EXPECT_NO_FATAL_FAILURE(recurse_draw(ctx, 0, 9)); + vkvg_rectangle(ctx, 50, 50, 200, 200); + vkvg_clip(ctx); + + vkvg_set_source_rgb(ctx, 0, 0, 1); + vkvg_paint(ctx); + + vkvg_rectangle(ctx, 0, 0, 220, 220); + vkvg_set_source_rgb(ctx, 1, 0, 0); + vkvg_fill(ctx); vkvg_destroy(ctx); compareWithRefImage(); } - -TEST_F(SaveRestoreTest, RecursePaint10) { +TEST_F(SaveRestoreTest, NZ2) { VkvgContext ctx = vkvg_create(surf); + vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO); - EXPECT_NO_FATAL_FAILURE(recurse_draw(ctx, 0, 10)); + vkvg_rectangle(ctx, 50, 50, 200, 200); + vkvg_clip(ctx); + + vkvg_set_source_rgb(ctx, 0, 0, 1); + vkvg_paint(ctx); + + vkvg_save(ctx); + + vkvg_rectangle(ctx, 75, 75, 150, 150); + vkvg_clip(ctx); + + vkvg_set_source_rgb(ctx, 0, 1, 0); + vkvg_paint(ctx); + + vkvg_save(ctx); + + vkvg_rectangle(ctx, 100, 100, 100, 100); + vkvg_clip(ctx); + + vkvg_set_source_rgb(ctx, 1, 0, 0); + vkvg_paint(ctx); + + vkvg_set_line_width(ctx, 40); + vkvg_set_source_rgb(ctx, 0, 0, 1); + vkvg_move_to(ctx, 0,0); + vkvg_line_to(ctx, 512,512); + vkvg_stroke_preserve(ctx); + + vkvg_restore(ctx); + + vkvg_set_line_width(ctx, 30); + vkvg_set_source_rgb(ctx, 0, 0, 0); + vkvg_stroke_preserve(ctx); + + vkvg_restore(ctx); + + vkvg_set_line_width(ctx, 20); + vkvg_set_source_rgb(ctx, 1, 0, 0); + vkvg_stroke(ctx); vkvg_destroy(ctx); compareWithRefImage(); } -TEST_F(SaveRestoreTest, RecursePaint11) { +TEST_F(SaveRestoreTest, ResetNZ) { VkvgContext ctx = vkvg_create(surf); + vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO); + vkvg_set_line_width(ctx, 20); + + vkvg_rectangle(ctx, 50, 50, 200, 200); + vkvg_clip(ctx); + + vkvg_set_source_rgb(ctx, 0, 0, 1); + vkvg_paint(ctx); + + vkvg_save(ctx); + + vkvg_rectangle(ctx, 75, 75, 150, 150); + vkvg_clip(ctx); + + vkvg_set_source_rgb(ctx, 0, 1, 0); + vkvg_paint(ctx); + + vkvg_reset_clip(ctx); + + vkvg_set_source_rgb(ctx, 1, 1, 0); + vkvg_move_to(ctx, 512,0); + vkvg_line_to(ctx, 0,512); + vkvg_stroke(ctx); + + vkvg_restore(ctx); - EXPECT_NO_FATAL_FAILURE(recurse_draw(ctx, 0, 11)); + vkvg_set_source_rgb(ctx, 1, 0, 0); + vkvg_move_to(ctx, 0,0); + vkvg_line_to(ctx, 512,512); + vkvg_stroke(ctx); vkvg_destroy(ctx); compareWithRefImage(); } -TEST_F(SaveRestoreTest, RecursePaint20) { +TEST_F(SaveRestoreTest, ResetNZ2) { VkvgContext ctx = vkvg_create(surf); + vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO); + vkvg_set_line_width(ctx, 20); - EXPECT_NO_FATAL_FAILURE(recurse_draw(ctx, 0, 20)); + vkvg_rectangle(ctx, 50, 50, 200, 200); + vkvg_clip(ctx); + + vkvg_set_source_rgb(ctx, 0, 0, 1); + vkvg_paint(ctx); + + vkvg_save(ctx); + + vkvg_rectangle(ctx, 75, 75, 150, 150); + vkvg_clip(ctx); + + vkvg_set_source_rgb(ctx, 0, 1, 0); + vkvg_paint(ctx); + + vkvg_reset_clip(ctx); + + vkvg_set_source_rgb(ctx, 1, 1, 0); + vkvg_move_to(ctx, 512,0); + vkvg_line_to(ctx, 0,512); + vkvg_stroke(ctx); + + vkvg_rectangle(ctx, 85, 20, 30, 260); + vkvg_clip(ctx); + + vkvg_set_source_rgb(ctx, 1, 0, 0); + vkvg_paint(ctx); + + vkvg_restore(ctx); + + vkvg_set_source_rgb(ctx, 1, 0, 1); + vkvg_move_to(ctx, 0,0); + vkvg_line_to(ctx, 512,512); + vkvg_stroke(ctx); vkvg_destroy(ctx); compareWithRefImage(); -} +}
\ No newline at end of file diff --git a/samples/tests/clip.cpp b/samples/tests/clip.cpp index 0008dc0..c57c8e2 100644 --- a/samples/tests/clip.cpp +++ b/samples/tests/clip.cpp @@ -22,7 +22,7 @@ TEST(clipped_paint_eo) { vkvg_destroy(ctx); } -TEST(clipped_paint2_nz) { +TEST(clip_reset_nz) { VkvgContext ctx = vkvg_create(test->surf); vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO); vkvg_set_source_rgb(ctx, 1, 0, 0); diff --git a/samples/tests/save_restore.cpp b/samples/tests/save_restore.cpp index 66168cb..2b0db35 100644 --- a/samples/tests/save_restore.cpp +++ b/samples/tests/save_restore.cpp @@ -38,14 +38,14 @@ void recurse_draw_clipped(VkvgContext ctx, int depth, int maxDepth) { float x = cos(a) * 256; float y = sin(a) * 256; + vkvg_restore(ctx); + vkvg_set_line_width(ctx, 2.f); vkvg_move_to(ctx, 256.f - x, 256.f - y); vkvg_line_to(ctx, 256.f + x, 256.f + y); vkvg_set_source_rgba(ctx, 0.f, 1.f, 0.f, 0.6f); vkvg_stroke(ctx); - vkvg_restore(ctx); - depth--; } @@ -133,14 +133,83 @@ TEST(save_restrore_nz2) { vkvg_set_line_width(ctx, 20); vkvg_set_source_rgb(ctx, 1, 0, 0); - vkvg_stroke_preserve(ctx); + vkvg_stroke(ctx); - /*vkvg_restore(ctx); + vkvg_destroy(ctx); +} +TEST(save_restrore_clip_reset_nz) { + VkvgContext ctx = vkvg_create(test->surf); + vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO); + vkvg_set_line_width(ctx, 20); - vkvg_set_line_width(ctx, 10); - vkvg_set_source_rgb(ctx, 1, 1, 0); - vkvg_stroke(ctx);*/ + vkvg_rectangle(ctx, 50, 50, 200, 200); + vkvg_clip(ctx); + + vkvg_set_source_rgb(ctx, 0, 0, 1); + vkvg_paint(ctx); + + vkvg_save(ctx); + + vkvg_rectangle(ctx, 75, 75, 150, 150); + vkvg_clip(ctx); + + vkvg_set_source_rgb(ctx, 0, 1, 0); + vkvg_paint(ctx); + + vkvg_reset_clip(ctx); + + vkvg_set_source_rgb(ctx, 1, 1, 0); + vkvg_move_to(ctx, 512,0); + vkvg_line_to(ctx, 0,512); + vkvg_stroke(ctx); + + vkvg_restore(ctx); + + vkvg_set_source_rgb(ctx, 1, 0, 0); + vkvg_move_to(ctx, 0,0); + vkvg_line_to(ctx, 512,512); + vkvg_stroke(ctx); vkvg_destroy(ctx); } +TEST(save_restrore_clip_reset2_nz) { + VkvgContext ctx = vkvg_create(test->surf); + vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO); + vkvg_set_line_width(ctx, 20); + + vkvg_rectangle(ctx, 50, 50, 200, 200); + vkvg_clip(ctx); + + vkvg_set_source_rgb(ctx, 0, 0, 1); + vkvg_paint(ctx); + + vkvg_save(ctx); + + vkvg_rectangle(ctx, 75, 75, 150, 150); + vkvg_clip(ctx); + vkvg_set_source_rgb(ctx, 0, 1, 0); + vkvg_paint(ctx); + + vkvg_reset_clip(ctx); + + vkvg_set_source_rgb(ctx, 1, 1, 0); + vkvg_move_to(ctx, 512,0); + vkvg_line_to(ctx, 0,512); + vkvg_stroke(ctx); + + vkvg_rectangle(ctx, 85, 20, 30, 260); + vkvg_clip(ctx); + + vkvg_set_source_rgb(ctx, 1, 0, 0); + vkvg_paint(ctx); + + vkvg_restore(ctx); + + vkvg_set_source_rgb(ctx, 1, 0, 1); + vkvg_move_to(ctx, 0,0); + vkvg_line_to(ctx, 512,512); + vkvg_stroke(ctx); + + vkvg_destroy(ctx); +}
\ No newline at end of file diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 51f3a04..8f35871 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -208,23 +208,24 @@ void _clear_context(VkvgContext ctx) { // free saved context stack elmt while (ctx->ctxSaveCount > 0) { ctx->ctxSaveCount--; - pat = ctx->pSavedCtxs[ctx->ctxSaveCount].pattern; - if (pat) - vkvg_pattern_destroy(pat); - font = ctx->pSavedCtxs[ctx->ctxSaveCount].currentFont; - if (font) - vkvg_font_destroy(font); + vkvg_context_save_t* sav = &ctx->pSavedCtxs[ctx->ctxSaveCount]; + if (sav->pattern) + vkvg_pattern_destroy(sav->pattern); + if (sav->currentFont) + vkvg_font_destroy(sav->currentFont); + if (sav->stencil) + vkh_image_destroy(sav->stencil); } // free additional stencil use in save/restore process - if (ctx->savedStencils) { + /*if (ctx->savedStencils) { uint8_t curSaveStencil = ctx->curSavBit / 6; for (int i = curSaveStencil; i > 0; i--) vkh_image_destroy(ctx->savedStencils[i - 1]); free(ctx->savedStencils); ctx->savedStencils = NULL; ctx->curSavBit = 0; - } + }*/ } void vkvg_destroy(VkvgContext ctx) { @@ -728,17 +729,66 @@ static const VkClearAttachment clearStencil = {VK_IMAGE_ASPECT_STENCIL_BIT, static const VkClearAttachment clearColorAttach = {VK_IMAGE_ASPECT_COLOR_BIT, 0, {{{0}}}}; void _reset_clip(VkvgContext ctx) { + if (ctx->curClipRef == 0) + return; //nothing to do + _emit_draw_cmd_undrawn_vertices(ctx); + + if (ctx->ctxSaveCount > 0) { + vkvg_context_save_t* sav = &ctx->pSavedCtxs[ctx->ctxSaveCount - 1]; + if (sav->curClipRef > 0) { + //cur stencil must be saved + _flush_cmd_buff(ctx); + _wait_ctx_flush_end(ctx); + + VkvgDevice dev = ctx->dev; + sav->stencil = vkh_image_ms_create( + dev->vkhDev, dev->stencilFormat, ctx->pSurf->surfClass->samples, ctx->pSurf->width, ctx->pSurf->height, + VKH_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; + +#if defined(DEBUG) && defined(VKVG_DBG_UTILS) + vkh_cmd_label_start(ctx->cmd, "new save/restore stencil", DBG_LAB_COLOR_SAV); +#endif + + vkh_image_set_layout(ctx->cmd, ctx->pSurf->stencil, dev->stencilAspectFlag, + 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->stencil, dev->stencilAspectFlag, VK_IMAGE_LAYOUT_GENERAL, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT); + + VkImageCopy cregion = {.srcSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1}, + .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->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->stencil, dev->stencilAspectFlag, + 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); + +#if defined(DEBUG) && defined(VKVG_DBG_UTILS) + vkh_cmd_label_end(ctx->cmd); +#endif + VK_CHECK_RESULT(vkEndCommandBuffer(ctx->cmd)); + _wait_and_submit_cmd(ctx); + } + } + ctx->curClipRef = 0; - if (!ctx->cmdStarted) { + + if (ctx->cmdStarted) { + vkCmdClearAttachments(ctx->cmd, 1, &clearStencil, 1, &ctx->clearRect); + CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, ctx->curClipRef); + } else { // if command buffer is not already started and in a renderpass, we use the renderpass // with the loadop clear for stencil ctx->renderPassBeginInfo.renderPass = ctx->pSurf->surfClass->renderPass_ClearStencil; // force run of one renderpass (even empty) to perform clear load op _start_cmd_for_render_pass(ctx); - return; } - vkCmdClearAttachments(ctx->cmd, 1, &clearStencil, 1, &ctx->clearRect); } void vkvg_reset_clip(VkvgContext ctx) { @@ -747,12 +797,12 @@ void vkvg_reset_clip(VkvgContext ctx) { RECORD(ctx, VKVG_CMD_RESET_CLIP); - if (ctx->curClipState == vkvg_clip_state_clear) + /*if (ctx->curClipState == vkvg_clip_state_clear) return; if (_get_previous_clip_state(ctx) == vkvg_clip_state_clear) ctx->curClipState = vkvg_clip_state_none; else - ctx->curClipState = vkvg_clip_state_clear; + ctx->curClipState = vkvg_clip_state_clear;*/ _reset_clip(ctx); } @@ -1328,20 +1378,22 @@ void vkvg_save(VkvgContext ctx) { return; }*/ - sav->curClipRef = ctx->curClipRef; + /* if (ctx->curClipState == vkvg_clip_state_clip) { sav->clippingState = vkvg_clip_state_clip_saved; } else if (ctx->curClipState == vkvg_clip_state_none) sav->clippingState = (_get_previous_clip_state(ctx) & 0x03); else - sav->clippingState = vkvg_clip_state_clear; + sav->clippingState = vkvg_clip_state_clear;*/ memcpy((void*)sav, (void*)&(ctx->curColor), (void*)&(ctx->indCount) - (void*)&(ctx->curColor)); + sav->curClipRef = ctx->curClipRef; if (ctx->pattern) vkvg_pattern_reference(ctx->pattern); if (ctx->currentFont) vkvg_font_reference(ctx->currentFont); + sav->stencil = NULL; ctx->ctxSaveCount++; } @@ -1360,56 +1412,52 @@ void vkvg_restore(VkvgContext ctx) { vkvg_context_save_t* sav = &ctx->pSavedCtxs[ctx->ctxSaveCount-1]; - //_flush_cmd_buff(ctx); _emit_draw_cmd_undrawn_vertices(ctx); ctx->curClipRef = sav->curClipRef; - if (ctx->cmdStarted) - CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, ctx->curClipRef); - - if (ctx->curClipState) { //!=none - - /*if (!_wait_ctx_flush_end(ctx)) - return; - - if (ctx->curClipState == vkvg_clip_state_clip && sav->clippingState == vkvg_clip_state_clear) { - _reset_clip(ctx); - } else { - uint8_t curSaveBit = 1 << ((ctx->curSavBit - 1) % 6 + 2); + if (sav->stencil) { + //restore stencil + _flush_cmd_buff(ctx); + _wait_ctx_flush_end(ctx); - //ctx->renderPassBeginInfo.renderPass = ctx->pSurf->surfClass->renderPass_ClearStencil; - _start_cmd_for_render_pass(ctx); + vkh_cmd_begin(ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + ctx->cmdStarted = true; #if defined(DEBUG) && defined(VKVG_DBG_UTILS) - vkh_cmd_label_start(ctx->cmd, "restore rp", DBG_LAB_COLOR_SAV); + vkh_cmd_label_start(ctx->cmd, "additional stencil copy while restoring", DBG_LAB_COLOR_SAV); #endif - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->surfClass->pipelineClipping); - - CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT | curSaveBit); - CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, curSaveBit); - CmdSetStencilWriteMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); - - _draw_full_screen_quad(ctx, NULL); + vkh_image_set_layout(ctx->cmd, ctx->pSurf->stencil, ctx->dev->stencilAspectFlag, + 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->stencil, ctx->dev->stencilAspectFlag, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - _bind_draw_pipeline(ctx); - CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); + VkImageCopy cregion = {.srcSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1}, + .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->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->stencil, ctx->dev->stencilAspectFlag, + 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); #if defined(DEBUG) && defined(VKVG_DBG_UTILS) - vkh_cmd_label_end(ctx->cmd); + vkh_cmd_label_end(ctx->cmd); #endif - _flush_cmd_buff(ctx); - if (!_wait_ctx_flush_end(ctx)) - return; - }*/ - } - if (sav->clippingState == vkvg_clip_state_clip_saved) { - + VK_CHECK_RESULT(vkEndCommandBuffer(ctx->cmd)); + _wait_and_submit_cmd(ctx); + if (!_wait_ctx_flush_end(ctx)) + return; + vkh_image_destroy(sav->stencil); } - ctx->curClipState = vkvg_clip_state_none; + if (ctx->cmdStarted) + CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, ctx->curClipRef); memcpy((void*)&(ctx->curColor), (void*)sav, (void*)&(ctx->pattern) - (void*)&(ctx->curColor)); diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index 79f3bd3..b4f5f43 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -101,6 +101,7 @@ typedef struct _vkvg_context_save_t { VkvgFont currentFont; vkvg_clip_state_t clippingState; uint32_t curClipRef; + VkhImage stencil; } vkvg_context_save_t; typedef struct _vkvg_context_t { @@ -199,7 +200,6 @@ typedef struct _vkvg_context_t { vkvg_clip_state_t curClipState; // current clipping status relative to the previous saved one or clear state if uint32_t curClipRef; - uint32_t savedClipOffset; VkhImage* savedStencils; // additional image for saving contexes once more than 6 save/restore are reached VkRenderPassBeginInfo renderPassBeginInfo; |