From: Jean-Philippe Bruyère Date: Fri, 17 May 2019 06:12:44 +0000 (+0200) Subject: save stencil if save/restore layers exceed 6, recursive X-Git-Tag: v0.1-alpha~71 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=97df0b630c296651bcb2441fe2f46c1159078d57;p=jp%2Fvkvg.git save stencil if save/restore layers exceed 6, recursive --- diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 021b4dd..aeef953 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -64,11 +64,12 @@ VkvgContext vkvg_create(VkvgSurface surf) ctx->pSurf = surf; ctx->curOperator = VKVG_OPERATOR_OVER; ctx->curFillRule = VKVG_FILL_RULE_NON_ZERO; - ctx->curSavBit = 0x4; + ctx->curSavBit = 0; ctx->vertCount = 0; ctx->indCount = 0; ctx->curIndStart = 0; + ctx->savedStencils = malloc(0); push_constants pc = { {.height=1}, @@ -103,6 +104,7 @@ VkvgContext vkvg_create(VkvgSurface surf) surf->dev->lastCtx = ctx; ctx->selectedFont.fontFile = (char*)calloc(FONT_FILE_NAME_MAX_SIZE,sizeof(char)); + ctx->currentFont = NULL; ctx->flushFence = vkh_fence_create((VkhDevice)dev); @@ -204,6 +206,12 @@ void vkvg_destroy (VkvgContext ctx) if (cur->pattern) vkvg_pattern_destroy (cur->pattern); } + //free additional stencil use in save/restore process + uint8_t curSaveStencil = ctx->curSavBit / 6; + for (int i=curSaveStencil;i>0;i--) + vkh_image_destroy(ctx->savedStencils[i-1]); + + free(ctx->savedStencils); //remove context from double linked list of context in device if (ctx->pSurf->dev->lastCtx == ctx){ @@ -757,13 +765,49 @@ 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)); + uint8_t curSaveStencil = ctx->curSavBit / 6; + + if (ctx->curSavBit > 0 && ctx->curSavBit % 6 == 0){//new save/restore stencil image have to be created + ctx->savedStencils = (VkhImage*)realloc(ctx->savedStencils, curSaveStencil * sizeof (VkhImage)); + VkhImage savStencil = vkh_image_ms_create ((VkhDevice)dev,FB_STENCIL_FORMAT, 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); + ctx->savedStencils[curSaveStencil-1] = savStencil; + + vkh_cmd_begin (ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + ctx->cmdStarted = true; + + 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, savStencil, 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); + + 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 (savStencil), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, &cregion); + + 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); + + VK_CHECK_RESULT(vkEndCommandBuffer(ctx->cmd)); + _submit_wait_and_reset_cmd(ctx); + } + + uint8_t curSaveBit = 1 << (ctx->curSavBit % 6 + 2); + _start_cmd_for_render_pass(ctx); CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping); - CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT|ctx->curSavBit); + CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT|curSaveBit); CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); - CmdSetStencilWriteMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, ctx->curSavBit); + CmdSetStencilWriteMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, curSaveBit); _draw_full_screen_quad(ctx); @@ -788,7 +832,7 @@ void vkvg_save (VkvgContext ctx){ sav->pNext = ctx->pSavedCtxs; ctx->pSavedCtxs = sav; - ctx->curSavBit = (ctx->curSavBit << 1); + ctx->curSavBit++; if (ctx->pattern) vkvg_pattern_reference (ctx->pattern); @@ -811,14 +855,16 @@ void vkvg_restore (VkvgContext ctx){ _flush_cmd_buff(ctx); - ctx->curSavBit = (ctx->curSavBit >> 1); + ctx->curSavBit--; + + uint8_t curSaveBit = 1 << (ctx->curSavBit % 6 + 2); _start_cmd_for_render_pass(ctx); CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping); - CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT|ctx->curSavBit); - CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, ctx->curSavBit); + 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); @@ -826,6 +872,39 @@ void vkvg_restore (VkvgContext ctx){ _bind_draw_pipeline (ctx); CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); + _flush_cmd_buff(ctx); + + uint8_t curSaveStencil = ctx->curSavBit / 6; + if (ctx->curSavBit > 0 && ctx->curSavBit % 6 == 0){//addtional save/restore stencil image have to be copied back to surf stencil first + VkhImage savStencil = ctx->savedStencils[curSaveStencil-1]; + + vkh_cmd_begin (ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + ctx->cmdStarted = true; + + 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, savStencil, 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); + + 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 (savStencil), 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, 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); + + VK_CHECK_RESULT(vkEndCommandBuffer(ctx->cmd)); + _submit_wait_and_reset_cmd(ctx); + + vkh_image_destroy(savStencil); + } + ctx->lineWidth = sav->lineWidth; ctx->curOperator= sav->curOperator; ctx->lineCap = sav->lineCap; diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index 5fd74d7..31e0ed1 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -618,7 +618,6 @@ 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->stencil); free (sav); } diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index cf400ae..b090610 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -28,9 +28,9 @@ #include "vkh.h" #include "vkvg_fonts.h" -#define VKVG_PTS_SIZE 10000 -#define VKVG_VBO_SIZE VKVG_PTS_SIZE * 2 -#define VKVG_IBO_SIZE VKVG_VBO_SIZE * 2 +#define VKVG_PTS_SIZE 4096 +#define VKVG_VBO_SIZE 4096 * 8 +#define VKVG_IBO_SIZE VKVG_VBO_SIZE * 6 #define VKVG_PATHES_SIZE 16 #define VKVG_ARRAY_THRESHOLD 4 @@ -51,9 +51,6 @@ typedef struct { typedef struct _vkvg_context_save_t{ struct _vkvg_context_save_t* pNext; - VkhImage stencil; - uint32_t stencilRef; - float lineWidth; vkvg_operator_t curOperator; @@ -128,8 +125,9 @@ typedef struct _vkvg_context_t { VkvgPattern pattern; vkvg_status_t status; - vkvg_context_save_t* pSavedCtxs;//last ctx saved ptr - unsigned char curSavBit;//current stencil bit used to save context + vkvg_context_save_t* pSavedCtxs; //last ctx saved ptr + uint8_t curSavBit; //current stencil bit used to save context, 6 bits used by stencil for save/restore + VkhImage* savedStencils; //additional image for saving contexes once more than 6 save/restore are reached VkClearRect clearRect; VkRenderPassBeginInfo renderPassBeginInfo; @@ -186,7 +184,6 @@ void _createDescriptorPool (VkvgContext ctx); void _init_descriptor_sets (VkvgContext ctx); void _update_descriptor_set (VkvgContext ctx, VkhImage img, VkDescriptorSet ds); void _update_gradient_desc_set(VkvgContext ctx); -//void _reset_src_descriptor_set(VkvgContext ctx); void _free_ctx_save (vkvg_context_save_t* sav); static inline float vec2_zcross (vec2 v1, vec2 v2){ diff --git a/src/vkvg_fonts.c b/src/vkvg_fonts.c index 3b138e7..772b575 100644 --- a/src/vkvg_fonts.c +++ b/src/vkvg_fonts.c @@ -348,6 +348,10 @@ _vkvg_font_t* _tryFindVkvgFont (VkvgContext ctx){ void _update_current_font (VkvgContext ctx) { VkvgDevice dev = ctx->pSurf->dev; if (ctx->currentFont == NULL){ + if (ctx->selectedFont.fontFile[0] == 0) { + ctx->selectedFont.charSize = 10 << 6; + _select_font_face (ctx, "sans"); + } ctx->currentFont = _tryFindVkvgFont (ctx); if (ctx->currentFont == NULL){ //create new font in cache diff --git a/tests/common/test.c b/tests/common/test.c index 98b2ca7..88da594 100644 --- a/tests/common/test.c +++ b/tests/common/test.c @@ -141,7 +141,7 @@ void perform_test (void(*testfunc)(void),uint width, uint height) { surf = vkvg_surface_create(device, width, height); - vkvg_surface_clear(surf); + //vkvg_surface_clear(surf); vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height); diff --git a/tests/data/vkvg.svg b/tests/data/vkvg.svg new file mode 100644 index 0000000..df4f790 --- /dev/null +++ b/tests/data/vkvg.svg @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tests/gradient.c b/tests/gradient.c index 839f167..9f5fc56 100644 --- a/tests/gradient.c +++ b/tests/gradient.c @@ -36,7 +36,7 @@ void test2(){ } int main(int argc, char *argv[]) { - perform_test (test2, 1024, 768); + perform_test (test, 1024, 768); return 0; } diff --git a/tests/save_restore.c b/tests/save_restore.c index aac9ae1..2024fef 100644 --- a/tests/save_restore.c +++ b/tests/save_restore.c @@ -1,25 +1,28 @@ #include "test.h" -void test(){ - VkvgContext ctx = vkvg_create(surf); +void recurse_draw(VkvgContext ctx, int depth) { + depth++; + vkvg_save(ctx); - vkvg_set_source_rgba(ctx,1,0,0,1); - vkvg_set_line_width(ctx,10); - vkvg_rectangle(ctx,100,100,200,200); + vkvg_translate (ctx, 5,5); + vkvg_rectangle(ctx, depth,depth,200,200); + vkvg_clip_preserve(ctx); + vkvg_set_source_rgb(ctx, 1.f/depth, 1.f / depth, 1.f / depth); + vkvg_fill_preserve(ctx); + vkvg_set_source_rgb(ctx, 0,0,0); vkvg_stroke(ctx); - vkvg_set_source_rgba(ctx,0,1,0,1); - vkvg_save(ctx); - - vkvg_set_source_rgba(ctx,0,1,1,1); - vkvg_set_line_width(ctx,1); - vkvg_rectangle(ctx,200,200,200,200); - vkvg_fill(ctx); + if (depth < 20) + recurse_draw (ctx, depth); vkvg_restore(ctx); +} - vkvg_rectangle(ctx,100,100,200,200); - vkvg_stroke(ctx); + +void test(){ + VkvgContext ctx = vkvg_create(surf); + + recurse_draw(ctx, 0); vkvg_destroy(ctx); } diff --git a/tests/test1.c b/tests/test1.c index c38d7be..8036c33 100644 --- a/tests/test1.c +++ b/tests/test1.c @@ -311,7 +311,7 @@ void cairo_tests () { VkvgContext ctx = vkvg_create(surf); vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD); - vkvg_set_source_rgba(ctx,0.7f,0.7f,0.7f,1); + vkvg_set_source_rgba(ctx,1.0f,1.0f,1.0f,1); vkvg_paint(ctx); vkvg_set_matrix(ctx,&mat);