LOG(VKVG_LOG_INFO, "CLIP: ctx = %p; path cpt = %d;\n", ctx, ctx->pathPtr / 2);
+ _ensure_renderpass_is_started(ctx);
+
if (ctx->curFillRule == VKVG_FILL_RULE_EVEN_ODD){
- _ensure_renderpass_is_started(ctx);
_poly_fill (ctx);
CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping);
}else{
- _ensure_renderpass_is_started(ctx);
CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping);
CmdSetStencilReference (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT);
CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
if (ctx->curFillRule == VKVG_FILL_RULE_EVEN_ODD){
_flush_undrawn_vertices(ctx);
+
_poly_fill (ctx);
_bind_draw_pipeline (ctx);
CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT);
return;
}
+ if (ctx->vertCount - ctx->curVertOffset + ctx->pointCount > VKVG_IBO_MAX)
+ _flush_undrawn_vertices(ctx);//limit draw call to addressable vx with choosen index type
+
if (ctx->pattern)//if not solid color, source img of gradient has to be bound
_ensure_renderpass_is_started(ctx);
_fill_ec(ctx);
}
-
void _draw_stoke_cap (VkvgContext ctx, float hw, vec2 p0, vec2 n, bool isStart) {
Vertex v = {{0},ctx->curColor};
_build_vb_step (ctx, hw, ctx->points[iL], ctx->points[curPathPointIdx], ctx->points[iR], isCurve);
iL = curPathPointIdx++;
}
-void vkvg_stroke_preserve (VkvgContext ctx)
-{
- if (ctx->pathPtr == 0 && _current_path_is_empty(ctx))//nothing to stroke
- return;
- _finish_path(ctx);
- LOG(VKVG_LOG_INFO, "STROKE: ctx = %p; path cpt = %d;\n", ctx, ctx->pathPtr / 2);
-
- float hw = ctx->lineWidth / 2.0f;
+bool _process_stroke (VkvgContext ctx) {
curPathPointIdx = lastPathPointIdx = ptrPath = iL = iR = 0;
+ float hw = ctx->lineWidth / 2.0f;
while (ptrPath < ctx->pathPtr){
uint32_t ptrSegment = 0, lastSegmentPointIdx = 0;
totDashLength+=ctx->dashes[i];
if (totDashLength == 0){
ctx->status = VKVG_STATUS_INVALID_DASH;
- return;
+ return true;
}
/*if (ctx->dashOffset == 0)
curDashOffset = 0;
}else
_draw_stoke_cap (ctx, hw, ctx->points[curPathPointIdx], vec2_line_norm(ctx->points[curPathPointIdx-1], ctx->points[curPathPointIdx]), false);
+ if (ctx->vertCount - ctx->curVertOffset > VKVG_IBO_MAX)
+ return false;
+
curPathPointIdx = firstPathPointIdx + pathPointCount;
if (ptrSegment > 0)
else
ptrPath++;
}
- //_record_draw_cmd(ctx);
+
+
+
+
+ return true;
+}
+
+void vkvg_stroke_preserve (VkvgContext ctx)
+{
+ if (ctx->pathPtr == 0 && _current_path_is_empty(ctx))//nothing to stroke
+ return;
+ _finish_path(ctx);
+
+ LOG(VKVG_LOG_INFO, "STROKE: ctx = %p; path ptr = %d;\n", ctx, ctx->pathPtr);
+
+ uint32_t tmpVxCount = ctx->vertCount;
+ uint32_t tmpIxCount = ctx->indCount;
+
+ if (!_process_stroke(ctx)) {
+ ctx->vertCount = tmpVxCount;
+ ctx->indCount = tmpIxCount;
+ _flush_undrawn_vertices(ctx);//limit draw call to addressable vx with choosen index type
+ _process_stroke(ctx);
+ }
}
void vkvg_paint (VkvgContext ctx){
if (ctx->pathPtr || ctx->segmentPtr){//path to fill
void _resize_vbo (VkvgContext ctx, uint32_t new_size) {
_wait_flush_fence (ctx);//wait previous cmd if not completed
ctx->sizeVBO = new_size;
- ctx->sizeVBO += ctx->sizeVBO % VKVG_VBO_SIZE;
+ uint32_t mod = ctx->sizeVBO % VKVG_VBO_SIZE;
+ if (mod > 0)
+ ctx->sizeVBO += VKVG_VBO_SIZE - mod;
LOG(VKVG_LOG_DBG_ARRAYS, "resize VBO: new size: %d\n", ctx->sizeVBO);
vkvg_buffer_destroy (&ctx->vertices);
vkvg_buffer_create (ctx->pSurf->dev,
}
void _resize_ibo (VkvgContext ctx, size_t new_size) {
_wait_flush_fence (ctx);//wait previous cmd if not completed
- ctx->sizeIBO = ctx->sizeIndices;
- ctx->sizeIBO += ctx->sizeIBO % VKVG_IBO_SIZE;
+ ctx->sizeIBO = new_size;
+ uint32_t mod = ctx->sizeIBO % VKVG_IBO_SIZE;
+ if (mod > 0)
+ ctx->sizeIBO += VKVG_IBO_SIZE - mod;
LOG(VKVG_LOG_DBG_ARRAYS, "resize IBO: new size: %d\n", ctx->sizeIBO);
vkvg_buffer_destroy (&ctx->indices);
vkvg_buffer_create (ctx->pSurf->dev,
#endif
ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass;
}
-//stroke and non-zero draw call for solid color flush
-void _flush_undrawn_vertices (VkvgContext ctx){
- if (ctx->indCount == ctx->curIndStart)
- return;
+void _check_vao_size (VkvgContext ctx) {
if (ctx->vertCount > ctx->sizeVBO || ctx->indCount > ctx->sizeIBO){
//vbo or ibo buffers too small
if (ctx->cmdStarted) {
//if cmd is started buffers, are already bound, so no resize is possible
//instead we flush, and clear vbo and ibo caches
_end_render_pass (ctx);
- _flush_vertices_caches_until_vertex_base (ctx);
+ if (ctx->curVertOffset > 0)
+ _flush_vertices_caches_until_vertex_base (ctx);
vkh_cmd_end (ctx->cmd);
_wait_and_submit_cmd (ctx);
}
_resize_vbo(ctx, ctx->sizeVertices);
_resize_ibo(ctx, ctx->sizeIndices);
}
+}
+
+//stroke and non-zero draw call for solid color flush
+void _flush_undrawn_vertices (VkvgContext ctx){
+ if (ctx->indCount == ctx->curIndStart)
+ return;
+
+ _check_vao_size(ctx);
_ensure_renderpass_is_started(ctx);
CmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, (int32_t)ctx->curVertOffset, 0);
ctx->curIndStart = ctx->indCount;
ctx->curVertOffset = ctx->vertCount;
}
+
void _flush_cmd_buff (VkvgContext ctx){
_flush_undrawn_vertices (ctx);
if (!ctx->cmdStarted)
#define VKVG_PATHES_SIZE 16
#define VKVG_ARRAY_THRESHOLD 8
#define VKVG_IBO_INDEX_TYPE uint16_t
+#if VKVG_IBO_INDEX_TYPE == uint16_t
+ #define VKVG_IBO_MAX UINT16_MAX
+#else
+ #define VKVG_IBO_MAX UINT32_MAX
+#endif
+
+
#define CreateRgba(r, g, b, a) ((a << 24) | (r << 16) | (g << 8) | b)
#ifdef VKVG_PREMULT_ALPHA
void _create_cmd_buff (VkvgContext ctx);
void _ensure_renderpass_is_started (VkvgContext ctx);
void _flush_cmd_buff (VkvgContext ctx);
-void _flush_undrawn_vertices (VkvgContext ctx);
+void _flush_undrawn_vertices(VkvgContext ctx);
void _wait_flush_fence (VkvgContext ctx);
void _reset_flush_fence (VkvgContext ctx);
void _wait_and_submit_cmd (VkvgContext ctx);