summaryrefslogtreecommitdiffstatsci
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2026-10-25 20:26:16 +0100
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>2026-10-25 20:26:16 +0100
commit325b693e0c437a6b0f30bf701f097f4d927f2c17 (patch)
tree5dce7469a467b9fab0b676fb02cf3e8978e0ab53
parentd66b32c0b9c2bd635924a3a219aba1d82a1faa0a (diff)
remove spurious bind, add required ones, emit_draw_cmd if new pattern is img or gradient
-rw-r--r--gunit_tests/patternDraw.cpp12
-rw-r--r--src/vkvg_context.c14
-rw-r--r--src/vkvg_context_internal.c60
-rw-r--r--src/vkvg_context_internal.h1
-rw-r--r--src/vkvg_fonts.c12
-rw-r--r--src/vkvg_pattern.h1
-rw-r--r--src/vkvg_surface_internal.c2
7 files changed, 72 insertions, 30 deletions
diff --git a/gunit_tests/patternDraw.cpp b/gunit_tests/patternDraw.cpp
index ef04e39..1c2a80f 100644
--- a/gunit_tests/patternDraw.cpp
+++ b/gunit_tests/patternDraw.cpp
@@ -177,6 +177,18 @@ TEST_F(PatternDrawTest, PaintImgPattern) {
compareWithRefImage();
}
+TEST_F(PatternDrawTest, PaintImgAfterFlush) {
+
+ VkvgContext ctx = vkvg_create(surf);
+ VkvgPattern pat = vkvg_pattern_create_for_surface(imgSurf);
+ vkvg_set_source(ctx, pat);
+ vkvg_flush(ctx);
+ vkvg_paint(ctx);
+ vkvg_pattern_destroy(pat);
+ vkvg_destroy(ctx);
+
+ compareWithRefImage();
+}
TEST_F(PatternDrawTest, FillImgPattern) {
VkvgContext ctx = vkvg_create(surf);
diff --git a/src/vkvg_context.c b/src/vkvg_context.c
index 368d255..de9c75a 100644
--- a/src/vkvg_context.c
+++ b/src/vkvg_context.c
@@ -841,7 +841,10 @@ void _clip_preserve(VkvgContext ctx) {
LOG(VKVG_LOG_INFO, "CLIP: ctx = %p; path cpt = %d;\n", ctx, ctx->pathPtr / 2);
- _ensure_renderpass_is_started(ctx);
+ if (!ctx->cmdStarted)
+ _start_cmd_for_render_pass2(ctx, false);
+ else if (ctx->pushCstDirty)
+ _update_push_constants(ctx);
#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
vkh_cmd_label_start(ctx->cmd, "clip", DBG_LAB_COLOR_CLIP);
@@ -856,11 +859,10 @@ void _clip_preserve(VkvgContext ctx) {
_bind_draw_pipeline(ctx);
CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, ctx->curClipRef);
+
#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
vkh_cmd_label_end(ctx->cmd);
#endif
-
- ctx->curClipState = vkvg_clip_state_clip;
}
void _fill_preserve(VkvgContext ctx) {
_finish_path(ctx);
@@ -884,8 +886,10 @@ void _fill_preserve(VkvgContext ctx) {
if (ctx->vertCount - ctx->curVertOffset + ctx->pointCount > VKVG_IBO_MAX)
_emit_draw_cmd_undrawn_vertices(ctx); // limit draw call to addressable vx with choosen index type
- if (ctx->pattern)
- _ensure_renderpass_is_started(ctx);
+ //if (ctx->pattern && !ctx->cmdStarted) { //pattern must be correctly rebound
+ // _start_cmd_for_render_pass2(ctx, false);
+ //}
+
_fill_non_zero(ctx);
}
void _stroke_preserve(VkvgContext ctx) {
diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c
index aca970a..255eee6 100644
--- a/src/vkvg_context_internal.c
+++ b/src/vkvg_context_internal.c
@@ -604,7 +604,7 @@ const float DBG_LAB_COLOR_RP[4] = {0, 0, 1, 1};
const float DBG_LAB_COLOR_FSQ[4] = {1, 0, 0, 1};
#endif
-void _start_cmd_for_render_pass(VkvgContext ctx) {
+void _start_cmd_for_render_pass2(VkvgContext ctx, bool bindPL) {
LOG(VKVG_LOG_INFO, "START RENDER PASS: ctx = %p\n", ctx);
vkh_cmd_begin(ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
@@ -633,22 +633,36 @@ void _start_cmd_for_render_pass(VkvgContext ctx) {
CmdSetViewport(ctx->cmd, 0, 1, &viewport);
CmdSetScissor(ctx->cmd, 0, 1, &ctx->bounds);
- VkDescriptorSet dss[] = {ctx->dev->fontCache->dsFont, ctx->dev->dummySrcSet, ctx->dev->dummyGradSet};
- uint32_t offset = 0;
-
- CmdBindDescriptorSets(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineLayout, 0, 3, dss, 1, &offset);
-
VkDeviceSize offsets = 0;
CmdBindVertexBuffers(ctx->cmd, 0, 1, &ctx->vertices.buffer, &offsets);
CmdBindIndexBuffer(ctx->cmd, ctx->indices.buffer, 0, VKVG_VK_INDEX_TYPE);
_update_push_constants(ctx);
- _bind_draw_pipeline(ctx);
- CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, ctx->curClipRef);
+ VkDescriptorSet dss[] = {ctx->dev->fontCache->dsFont, ctx->dev->dummySrcSet, ctx->dev->dummyGradSet};
+ uint32_t offset = 0;
+ if (ctx->pattern) {
+ if (ctx->pattern->type == VKVG_PATTERN_TYPE_SURFACE) {
+ surface_pattern_t* sp = (surface_pattern_t*)ctx->pattern;
+ dss[1] = sp->dsSource;
+ } else {
+ vkvg_gradient_pattern_t* gradPat = (vkvg_gradient_pattern_t*)ctx->pattern;
+ offset = gradPat->offset;
+ dss[2] = ctx->pSurf->dsGradient;
+ }
+ }
+ CmdBindDescriptorSets(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineLayout, 0, 3, dss, 1, &offset);
+
+ if (bindPL) {
+ _bind_draw_pipeline(ctx);
+ CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, ctx->curClipRef);
+ }
ctx->cmdStarted = true;
}
+void _start_cmd_for_render_pass(VkvgContext ctx) {
+ _start_cmd_for_render_pass2(ctx, 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) {
@@ -711,10 +725,6 @@ void _update_cur_pattern(VkvgContext ctx, VkvgPattern pat) {
ctx->pushConsts.source.width = (float)sp->surf->width;
ctx->pushConsts.source.height = (float)sp->surf->height;
- _ensure_renderpass_is_started(ctx);
-
- CmdBindDescriptorSets(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineLayout,
- 1, 1, &sp->dsSource, 0, NULL);
vkvg_matrix_t mat;
if (pat->hasMatrix) {
vkvg_pattern_get_matrix(pat, &mat);
@@ -724,6 +734,10 @@ void _update_cur_pattern(VkvgContext ctx, VkvgPattern pat) {
// vkvg_matrix_transform_distance(&mat, &ctx->pushConsts.source.width, &ctx->pushConsts.source.height);
vkvg_matrix_multiply(&ctx->pushConsts.matInv, &ctx->pushConsts.matInv, &mat);
}
+
+ if (ctx->cmdStarted)
+ CmdBindDescriptorSets(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineLayout,
+ 1, 1, &sp->dsSource, 0, NULL);
break;
}
case VKVG_PATTERN_TYPE_LINEAR:
@@ -739,7 +753,8 @@ void _update_cur_pattern(VkvgContext ctx, VkvgPattern pat) {
ctx->pushConsts.source = bounds;
// transform control point with current ctx matrix
- vkvg_gradient_t* grad = &((vkvg_gradient_pattern_t*)pat)->gradient;
+ vkvg_gradient_pattern_t* gradPat = (vkvg_gradient_pattern_t*)pat;
+ vkvg_gradient_t* grad = &(gradPat->gradient);
if (grad->count < 2) {
ctx->status = VKVG_STATUS_PATTERN_INVALID_GRADIENT;
@@ -770,14 +785,14 @@ void _update_cur_pattern(VkvgContext ctx, VkvgPattern pat) {
vkvg_matrix_transform_distance(&ctx->pushConsts.mat, &grad->cp[0].z, &grad->cp[0].w);
vkvg_matrix_transform_distance(&ctx->pushConsts.mat, &grad->cp[1].z, &grad->cp[0].w);
}
- uint32_t offset = ctx->pSurf->gradCount * sizeof(vkvg_gradient_t);
- memcpy(vkh_buffer_get_mapped_pointer(&ctx->pSurf->uboGrad) + offset,
+ gradPat->offset = ctx->pSurf->gradCount * sizeof(vkvg_gradient_t);
+ memcpy(vkh_buffer_get_mapped_pointer(&ctx->pSurf->uboGrad) + gradPat->offset,
grad, sizeof(vkvg_gradient_t));
- vkh_buffer_flush(&ctx->pSurf->uboGrad);
+ //vkh_buffer_flush(&ctx->pSurf->uboGrad);
- _ensure_renderpass_is_started(ctx);
- CmdBindDescriptorSets(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineLayout,
- 2, 1, &ctx->pSurf->dsGradient, 1, &offset);
+ if (ctx->cmdStarted)
+ CmdBindDescriptorSets(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineLayout,
+ 2, 1, &ctx->pSurf->dsGradient, 1, &(gradPat->offset));
ctx->pSurf->gradCount++;
break;
}
@@ -1488,10 +1503,13 @@ void _poly_fill(VkvgContext ctx, vec4* bounds) {
_resize_vertex_cache(ctx, ctx->sizeVBO);
}
- _start_cmd_for_render_pass(ctx);
+ _start_cmd_for_render_pass2(ctx, false);
} else {
_ensure_vertex_cache_size(ctx, ctx->pointCount);
- _ensure_renderpass_is_started(ctx);
+ if (!ctx->cmdStarted)
+ _start_cmd_for_render_pass2(ctx, false);
+ else if (ctx->pushCstDirty)
+ _update_push_constants(ctx);
}
CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->surfClass->pipelinePolyFill);
diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h
index b4f5f43..0b22b8d 100644
--- a/src/vkvg_context_internal.h
+++ b/src/vkvg_context_internal.h
@@ -289,6 +289,7 @@ void _update_push_constants(VkvgContext ctx);
void _update_cur_pattern(VkvgContext ctx, VkvgPattern pat);
void _set_mat_inv_and_vkCmdPush(VkvgContext ctx);
void _start_cmd_for_render_pass(VkvgContext ctx);
+void _start_cmd_for_render_pass2(VkvgContext ctx, bool bindPL);
void _createDescriptorPool(VkvgContext ctx);
void _init_descriptor_sets(VkvgContext ctx);
diff --git a/src/vkvg_fonts.c b/src/vkvg_fonts.c
index 186930d..2e3dfa3 100644
--- a/src/vkvg_fonts.c
+++ b/src/vkvg_fonts.c
@@ -687,7 +687,11 @@ bool try_get_or_create_font_face_from_query (VkvgDevice dev, const char* querySt
*face = NULL;
#ifdef VKVG_USE_FONTCONFIG
- if (try_get_font_face_from_query_hash(cache, queryHash, face) && (*face)->numAxis > 0)
+ if (try_get_font_face_from_query_hash(cache, queryHash, face)
+#ifdef VKVG_USE_FREETYPE
+ && (*face)->numAxis > 0
+#endif
+ )
return true;
FcPattern* request = FcNameParse((const FcChar8*)queryString);
@@ -769,6 +773,7 @@ bool try_get_font_size (FontFace face, uint32_t pt26_6, signed long* coords, Vkv
for (int i = 0; i < face->sizes.count; ++i) {
VkvgFont f = face->sizes.elements[i];
if (f->charSize == pt26_6) {
+#ifdef VKVG_USE_FREETYPE
if (coords) {
for (int axe = 0; axe < face->numAxis; ++axe) {
if (f->coords[axe] != coords[axe])
@@ -776,6 +781,7 @@ bool try_get_font_size (FontFace face, uint32_t pt26_6, signed long* coords, Vkv
}
free(coords);//coords matche, free new coords
}
+#endif
*font = f;
return true;
}
@@ -891,7 +897,7 @@ void text_run_init(VkvgText textRun, VkvgFont font, vkvg_direction_t textDirecti
_font_lock_size(textRun->font);
-#ifdef VKVG_USE_HARFBUZZ
+#if defined(VKVG_USE_HARFBUZZ)
textRun->hbBuf = _get_hb_buffer(textRun, text, length);
textRun->glyphs = hb_buffer_get_glyph_positions(textRun->hbBuf, &textRun->glyph_count);
#else
@@ -1111,7 +1117,7 @@ VkvgFont _create_font_from_face (VkvgSurface surf, FontFace face, float pointSiz
font->charSize = pointSize;
stbtt_GetFontVMetrics(&face->stbInfo, &font->ascent, &font->descent, &font->lineGap);
font->charLookup = (glyph_ref*)calloc(face->stbInfo.numGlyphs, sizeof(glyph_ref));
- font->scale = stbtt_ScaleForMappingEmToPixels(&face->stbInfo, font->charSize * dev->vdpi / 72.f);
+ font->scale = stbtt_ScaleForMappingEmToPixels(&face->stbInfo, font->charSize * surf->vdpi / 72.f);
font->height = roundf(font->scale * (font->ascent - font->descent + font->lineGap));
font->ascent = roundf(font->scale * font->ascent);
font->descent = roundf(font->scale * font->descent);
diff --git a/src/vkvg_pattern.h b/src/vkvg_pattern.h
index 49bff1b..35e0f0b 100644
--- a/src/vkvg_pattern.h
+++ b/src/vkvg_pattern.h
@@ -39,6 +39,7 @@ typedef struct _vkvg_gradient_t {
typedef struct _vkvg_gradient_pattern_t {
vkvg_pattern_t base;
+ uint32_t offset; //descriptor offset for dyn uniform
vkvg_gradient_t gradient;
} vkvg_gradient_pattern_t;
diff --git a/src/vkvg_surface_internal.c b/src/vkvg_surface_internal.c
index 41d9f86..9862672 100644
--- a/src/vkvg_surface_internal.c
+++ b/src/vkvg_surface_internal.c
@@ -661,7 +661,7 @@ VkvgSurface _create_surface(VkvgDevice dev, VkFormat format, VkSampleCountFlags
vkh_buffer_init(dev->vkhDev, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VKH_MEMORY_USAGE_CPU_TO_GPU,
MAX_GRAD * sizeof(vkvg_gradient_t), &surf->uboGrad, true);
- VkDescriptorBufferInfo dbi = {surf->uboGrad.buffer, 0, VK_WHOLE_SIZE};
+ VkDescriptorBufferInfo dbi = {surf->uboGrad.buffer, 0, sizeof(vkvg_gradient_t)};
VkWriteDescriptorSet writeDescriptorSet = {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = surf->dsGradient,
.dstBinding = 0,