From 1bd03adb9bee721cc06453c83c7405f8235ee10a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Thu, 7 Jun 2018 01:04:02 +0200 Subject: [PATCH] prevent flushing empty render pass, use vkvg_buffer instead of vkh_buffer --- src/vkvg_context.c | 6 ++++- src/vkvg_context_internal.c | 48 ++++++++++++++++++++++++++----------- src/vkvg_context_internal.h | 3 +++ src/vkvg_fonts.c | 17 ++++++------- src/vkvg_fonts.h | 3 ++- src/vkvg_surface.c | 15 ++++++------ tests/test1.c | 20 +++++++++------- vkh | 2 +- 8 files changed, 73 insertions(+), 41 deletions(-) diff --git a/src/vkvg_context.c b/src/vkvg_context.c index f062044..7e41fc1 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -377,6 +377,7 @@ void vkvg_clip_preserve (VkvgContext ctx){ if (ctx->pointCount * 4 > ctx->sizeIndices - ctx->indCount)//flush if vk buff is full vkvg_flush(ctx); + _check_cmd_buff_state(ctx); _poly_fill (ctx); vkCmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping); @@ -396,6 +397,7 @@ void vkvg_fill_preserve (VkvgContext ctx){ if (ctx->pointCount * 4 > ctx->sizeIndices - ctx->indCount)//flush if vk buff is full vkvg_flush(ctx); + _check_cmd_buff_state(ctx); _poly_fill (ctx); _bind_draw_pipeline (ctx); @@ -535,6 +537,7 @@ void vkvg_stroke_preserve (VkvgContext ctx) _record_draw_cmd(ctx); } void vkvg_paint (VkvgContext ctx){ + _check_cmd_buff_state(ctx); vkCmdDrawIndexed (ctx->cmd,6,1,0,0,0); } inline void vkvg_set_source_rgb (VkvgContext ctx, float r, float g, float b) { @@ -548,7 +551,7 @@ void vkvg_set_source_surface(VkvgContext ctx, VkvgSurface surf, float x, float y _update_cur_pattern (ctx, vkvg_pattern_create_for_surface(surf)); ctx->pushConsts.source.x = x; ctx->pushConsts.source.y = y; - _update_push_constants (ctx); + ctx->pushCstDirty = true; } void vkvg_set_source (VkvgContext ctx, VkvgPattern pat){ _update_cur_pattern (ctx, pat); @@ -596,6 +599,7 @@ void vkvg_set_text_direction (vkvg_context* ctx, vkvg_direction_t direction){ } void vkvg_show_text (VkvgContext ctx, const char* text){ + _check_cmd_buff_state(ctx); _show_text (ctx, text); _record_draw_cmd (ctx); } diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index 68d380f..2b6a293 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -36,6 +36,12 @@ #include "vkh_queue.h" #include "vkh_image.h" +void _check_cmd_buff_state (VkvgContext ctx) { + if (!ctx->cmdStarted) + _start_cmd_for_render_pass(ctx); + else if (ctx->pushCstDirty) + _update_push_constants(ctx); +} void _check_pathes_array (VkvgContext ctx){ if (ctx->sizePathes - ctx->pathPtr > VKVG_ARRAY_THRESHOLD) return; @@ -173,6 +179,7 @@ void _record_draw_cmd (VkvgContext ctx){ LOG(LOG_INFO, "RECORD DRAW CMD: ctx = %lu; vert cpt = %d; ind cpt = %d; ind drawn = %d\n", ctx, ctx->vertCount - 4, ctx->indCount - 6, ctx->indCount - ctx->curIndStart); if (ctx->indCount == ctx->curIndStart) return; + _check_cmd_buff_state(ctx); vkCmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, 0, 1); //DEBUG @@ -188,16 +195,19 @@ inline void _submit_ctx_cmd(VkvgContext ctx){ vkh_cmd_submit (ctx->pSurf->dev->gQueue, &ctx->cmd, ctx->flushFence); } void _wait_and_reset_ctx_cmd (VkvgContext ctx){ + if (!ctx->cmdStarted) + return; vkWaitForFences(ctx->pSurf->dev->vkDev,1,&ctx->flushFence,VK_TRUE,UINT64_MAX); vkResetFences(ctx->pSurf->dev->vkDev,1,&ctx->flushFence); vkResetCommandBuffer(ctx->cmd,0); + ctx->cmdStarted = false; } inline void _submit_wait_and_reset_cmd (VkvgContext ctx){ _submit_ctx_cmd(ctx); _wait_and_reset_ctx_cmd(ctx); } -void _explicit_ms_resolve (VkvgContext ctx){ +void _explicit_ms_resolve (VkvgContext ctx){//should init cmd before calling this (unused, using automatic resolve by renderpass) vkh_image_set_layout (ctx->cmd, ctx->pSurf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); @@ -226,8 +236,9 @@ void _end_render_pass (VkvgContext ctx) { vkCmdEndRenderPass (ctx->cmd); } void _flush_cmd_buff (VkvgContext ctx){ + if (!ctx->cmdStarted) + return; _end_render_pass (ctx); - //_explicit_ms_resolve (ctx); vkh_cmd_end (ctx->cmd); _submit_wait_and_reset_cmd(ctx); @@ -256,12 +267,15 @@ 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] = { + /*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, @@ -299,23 +313,26 @@ void _init_cmd_buff (VkvgContext ctx){ vkCmdSetStencilCompareMask(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 //then trigger push constants command void _set_mat_inv_and_vkCmdPush (VkvgContext ctx) { ctx->pushConsts.matInv = ctx->pushConsts.mat; vkvg_matrix_invert (&ctx->pushConsts.matInv); - _update_push_constants (ctx); + ctx->pushCstDirty = true; } inline void _update_push_constants (VkvgContext ctx) { vkCmdPushConstants(ctx->cmd, ctx->pSurf->dev->pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(push_constants),&ctx->pushConsts); + ctx->pushCstDirty = false; } void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { VkvgPattern lastPat = ctx->pattern; ctx->pattern = pat; ctx->pushConsts.patternType = pat->type; + ctx->pushCstDirty = true; switch (pat->type) { case VKVG_PATTERN_TYPE_SOLID: @@ -324,9 +341,9 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { if (lastPat && lastPat->type == VKVG_PATTERN_TYPE_SURFACE){ _flush_cmd_buff (ctx); _reset_src_descriptor_set (ctx); - _init_cmd_buff (ctx);//push csts updated by init - }else - _update_push_constants (ctx); + //_init_cmd_buff (ctx);//push csts updated by init + }//else + //_update_push_constants (ctx); break; case VKVG_PATTERN_TYPE_SURFACE: @@ -334,7 +351,13 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { VkvgSurface surf = (VkvgSurface)pat->data; //flush ctx in two steps to add the src transition in the cmd buff - _end_render_pass (ctx); + if (ctx->cmdStarted)//transition of img without appropriate dep in subpass must be done outside renderpass. + _end_render_pass (ctx); + else { + vkh_cmd_begin (ctx->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + ctx->cmdStarted = true; + } + //transition source surface for sampling vkh_image_set_layout (ctx->cmd, surf->img, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, @@ -343,9 +366,6 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { vkh_cmd_end (ctx->cmd); _submit_wait_and_reset_cmd(ctx); - //_flush_cmd_buff(ctx); - - ctx->source = surf->img; //if (vkh_image_get_sampler (ctx->source) == VK_NULL_HANDLE){ @@ -390,7 +410,7 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { vec4 srcRect = {0,0,surf->width,surf->height}; ctx->pushConsts.source = srcRect; - _init_cmd_buff (ctx); + //_init_cmd_buff (ctx); break; } case VKVG_PATTERN_TYPE_LINEAR: @@ -412,7 +432,7 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { memcpy(ctx->uboGrad.allocInfo.pMappedData , &grad, sizeof(vkvg_gradient_t)); - _init_cmd_buff (ctx); + //_init_cmd_buff (ctx); break; } diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index 00d512e..38a9cde 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -88,6 +88,8 @@ typedef struct _vkvg_context_t { VkCommandPool cmdPool;//local pools ensure thread safety VkCommandBuffer cmd; //single cmd buff for context operations + bool cmdStarted;//prevent flushing empty renderpass + bool pushCstDirty;//prevent pushing to gpu if not requested VkDescriptorPool descriptorPool; VkDescriptorSet dsFont; //fonts glyphs texture atlas descriptor (local for thread safety) VkDescriptorSet dsSrc; //source ds @@ -161,6 +163,7 @@ void _vao_add_rectangle (VkvgContext ctx, float x, float y, float width, flo void _bind_draw_pipeline (VkvgContext ctx); void _create_cmd_buff (VkvgContext ctx); void _init_cmd_buff (VkvgContext ctx); +void _check_cmd_buff_state (VkvgContext ctx); void _flush_cmd_buff (VkvgContext ctx); void _record_draw_cmd (VkvgContext ctx); void _submit_wait_and_reset_cmd(VkvgContext ctx); diff --git a/src/vkvg_fonts.c b/src/vkvg_fonts.c index 15bc3a7..42c3182 100644 --- a/src/vkvg_fonts.c +++ b/src/vkvg_fonts.c @@ -46,10 +46,11 @@ void _init_fonts_cache (VkvgDevice dev){ cache->uploadFence = vkh_fence_create_signaled(dev); uint32_t buffLength = FONT_PAGE_SIZE*FONT_PAGE_SIZE*sizeof(uint8_t); - cache->buff = vkh_buffer_create(dev,VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - buffLength); - vkh_buffer_map(cache->buff); + + vkvg_buffer_create (dev, + VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + VMA_MEMORY_USAGE_CPU_TO_GPU, + buffLength, &cache->buff); cache->cmd = vkh_cmd_buff_create(dev,dev->cmdPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY); @@ -158,8 +159,8 @@ void _destroy_font_cache (VkvgDevice dev){ free(cache->fonts); free(cache->pensY); - vkh_buffer_unmap (cache->buff); - vkh_buffer_destroy (cache->buff); + + vkvg_buffer_destroy (&cache->buff); vkh_image_destroy (cache->cacheTex); //vkFreeCommandBuffers(dev->vkDev,dev->cmdPool, 1, &cache->cmd); vkDestroyFence (dev->vkDev,cache->uploadFence,NULL); @@ -194,7 +195,7 @@ void _flush_chars_to_tex (VkvgDevice dev, _vkvg_font_t* f) { vkResetCommandBuffer(cache->cmd,NULL); vkResetFences (dev->vkDev,1,&cache->uploadFence); - memcpy(vkh_buffer_get_mapped_pointer (cache->buff), cache->hostBuff, f->curLine.height * FONT_PAGE_SIZE); + memcpy(cache->buff.allocInfo.pMappedData, cache->hostBuff, f->curLine.height * FONT_PAGE_SIZE); vkh_cmd_begin (cache->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); @@ -209,7 +210,7 @@ void _flush_chars_to_tex (VkvgDevice dev, _vkvg_font_t* f) { .imageOffset = {f->curLine.penX,f->curLine.penY,0}, .imageExtent = {FONT_PAGE_SIZE-f->curLine.penX,f->curLine.height,1}}; - vkCmdCopyBufferToImage(cache->cmd, vkh_buffer_get_vkbuffer (cache->buff), + vkCmdCopyBufferToImage(cache->cmd, cache->buff.buffer, vkh_image_get_vkimage (cache->cacheTex), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferCopyRegion); vkh_image_set_layout_subres(cache->cmd, cache->cacheTex, subres, diff --git a/src/vkvg_fonts.h b/src/vkvg_fonts.h index 68dbe1b..93e959c 100644 --- a/src/vkvg_fonts.h +++ b/src/vkvg_fonts.h @@ -36,6 +36,7 @@ #include "vkvg_internal.h" #include "vkvg.h" +#include "vkvg_buff.h" #include "vkh.h" //#include "vkh_image.h" @@ -72,7 +73,7 @@ typedef struct { uint8_t* hostBuff; //host mem where bitmaps are first loaded VkCommandBuffer cmd; //upload cmd buff - VkhBuffer buff; //stagin buffer + vkvg_buff buff; //stagin buffer VkhImage cacheTex; //tex 2d array uint8_t cacheTexLength; //tex array length int* pensY; //y pen pos in each texture of array diff --git a/src/vkvg_surface.c b/src/vkvg_surface.c index 6a16a2b..f8d8987 100644 --- a/src/vkvg_surface.c +++ b/src/vkvg_surface.c @@ -146,9 +146,10 @@ VkvgSurface vkvg_surface_create_from_bitmap (VkvgDevice dev, unsigned char* img, vkh_image_create_descriptor (tmpImg, 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_BORDER); //staging buffer - VkhBuffer buff = vkh_buffer_create (dev, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, imgSize); - VK_CHECK_RESULT (vkh_buffer_map (buff)); - memcpy (vkh_buffer_get_mapped_pointer (buff), img, imgSize); + vkvg_buff buff = {}; + vkvg_buffer_create(dev, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU, imgSize, &buff); + + memcpy (buff.allocInfo.pMappedData, img, imgSize); /*unsigned char* mapImg = vkh_image_map (stagImg); memcpy (mapImg, img, imgSize); @@ -167,7 +168,7 @@ VkvgSurface vkvg_surface_create_from_bitmap (VkvgDevice dev, unsigned char* img, VkBufferImageCopy bufferCopyRegion = { .imageSubresource = imgSubResLayers, .imageExtent = {surf->width,surf->height,1}}; - vkCmdCopyBufferToImage(cmd, vkh_buffer_get_vkbuffer (buff), + vkCmdCopyBufferToImage(cmd, buff.buffer, vkh_image_get_vkimage (stagImg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferCopyRegion); vkh_image_set_layout (cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT, @@ -196,8 +197,7 @@ VkvgSurface vkvg_surface_create_from_bitmap (VkvgDevice dev, unsigned char* img, vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX); - vkh_buffer_unmap (buff); - vkh_buffer_destroy (buff); + vkvg_buffer_destroy (&buff); vkh_image_destroy (stagImg); //create tmp context with rendering pipeline to create the multisample img @@ -211,8 +211,9 @@ VkvgSurface vkvg_surface_create_from_bitmap (VkvgDevice dev, unsigned char* img, ctx->pushConsts.source = srcRect; ctx->pushConsts.patternType = VKVG_PATTERN_TYPE_SURFACE; - _update_push_constants (ctx); + //_update_push_constants (ctx); _update_descriptor_set (ctx, tmpImg, ctx->dsSrc); + _check_cmd_buff_state (ctx); vkvg_paint (ctx); vkvg_destroy (ctx); diff --git a/tests/test1.c b/tests/test1.c index d96c538..4e119ca 100644 --- a/tests/test1.c +++ b/tests/test1.c @@ -315,7 +315,8 @@ void vkvg_test_fill2(VkvgContext ctx){ vkvg_close_path(ctx); vkvg_fill(ctx); } -void test_img_surface (VkvgContext ctx) { +void test_img_surface () { + VkvgContext ctx = vkvg_create(surf); VkvgSurface imgSurf;// = vkvg_surface_create_from_image(device, "/mnt/data/images/blason.png"); //VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "/mnt/data/images/2000px-Tux.svg.png"); //VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "/mnt/data/images/path2674.png"); @@ -333,7 +334,9 @@ void test_img_surface (VkvgContext ctx) { vkvg_paint(ctx); //vkvg_flush(ctx); vkvg_set_source_rgba(ctx,1,0,0,1); + vkvg_surface_destroy(imgSurf); + vkvg_destroy(ctx); } void test_line_caps (VkvgContext ctx) { @@ -1086,14 +1089,10 @@ int main(int argc, char *argv[]) { //test_svg(); // - VkvgContext ctx = vkvg_create(surf); - test_img_surface(ctx); - vkvg_destroy(ctx); + + //test_grad_transforms(); - //simple_paint(); - //simple_rectangle_stroke(); - //simple_rectangle_fill(); //test_colinear(); vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf)); @@ -1101,8 +1100,11 @@ int main(int argc, char *argv[]) { while (!vkengine_should_close (e)) { glfwPollEvents(); //test_1(); - //cairo_tests(); - + cairo_tests(); + //simple_paint(); + //simple_rectangle_stroke(); + //simple_rectangle_fill(); + //test_img_surface(); //multi_test1(); //test_painting(); if (!vkh_presenter_draw (r)) diff --git a/vkh b/vkh index 7ae5642..5de4a92 160000 --- a/vkh +++ b/vkh @@ -1 +1 @@ -Subproject commit 7ae56421ae5cc41f230610e3042839e4586d4cfc +Subproject commit 5de4a9210f64615bd0b23a0d7c88f5564d0c1e5f -- 2.47.3