]> O.S.I.I.S - jp/vkvg.git/commitdiff
prevent overflow of index addressing
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Mon, 20 Jul 2020 23:22:13 +0000 (01:22 +0200)
committerj-p <jp_bruyere@hotmail.com>
Wed, 22 Jul 2020 15:14:28 +0000 (17:14 +0200)
src/vkvg_context.c
src/vkvg_context_internal.c
src/vkvg_context_internal.h

index d7214c3b400545372b56e2ae8f728f7cbdb54b42..fa2ff2b90f3d88cab51b71fe3379f11aee556b1c 100644 (file)
@@ -581,12 +581,12 @@ void vkvg_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->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);
@@ -613,6 +613,7 @@ void vkvg_fill_preserve (VkvgContext ctx){
 
         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);
@@ -621,11 +622,13 @@ void vkvg_fill_preserve (VkvgContext ctx){
                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};
 
@@ -733,16 +736,10 @@ void _draw_segment (VkvgContext ctx, float hw, bool isCurve) {
                _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;
@@ -771,7 +768,7 @@ void vkvg_stroke_preserve (VkvgContext ctx)
                                totDashLength+=ctx->dashes[i];
                        if (totDashLength == 0){
                                ctx->status = VKVG_STATUS_INVALID_DASH;
-                               return;
+                               return true;
                        }
                        /*if (ctx->dashOffset == 0)
                                curDashOffset = 0;
@@ -842,6 +839,9 @@ void vkvg_stroke_preserve (VkvgContext ctx)
                }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)
@@ -849,7 +849,30 @@ void vkvg_stroke_preserve (VkvgContext ctx)
                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
index 1458e3515bbee2840757f5721848d76555d7eccb..05fcbde6026e906993bd33fa2db843d50073d39c 100644 (file)
@@ -243,7 +243,9 @@ void _create_vertices_buff (VkvgContext ctx){
 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,
@@ -253,8 +255,10 @@ void _resize_vbo (VkvgContext ctx, uint32_t new_size) {
 }
 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,
@@ -418,24 +422,30 @@ void _end_render_pass (VkvgContext ctx) {
 #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);
@@ -453,6 +463,7 @@ void _flush_undrawn_vertices (VkvgContext ctx){
        ctx->curIndStart = ctx->indCount;
        ctx->curVertOffset = ctx->vertCount;
 }
+
 void _flush_cmd_buff (VkvgContext ctx){
        _flush_undrawn_vertices (ctx);
        if (!ctx->cmdStarted)
index 6831d62c86dfe327f5584723c5cf066a8d745c25..abdf9334848b62fac39161dec070271b5e026a96 100644 (file)
 #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
@@ -209,7 +216,7 @@ void _bind_draw_pipeline    (VkvgContext ctx);
 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);