From 19e971d3ab1d30aa815eea39e897c521b5fda033 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Fri, 11 Sep 2020 14:57:51 +0200 Subject: [PATCH] test fans topology --- src/vkvg_context_internal.c | 125 ++++++++++++++++++++++-------------- src/vkvg_context_internal.h | 3 + src/vkvg_device.c | 2 + src/vkvg_device_internal.c | 9 ++- src/vkvg_device_internal.h | 3 + src/vkvg_internal.h | 17 ++++- tests/random_rects.c | 20 +++--- 7 files changed, 119 insertions(+), 60 deletions(-) diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index cfe944c..741f71b 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -142,9 +142,14 @@ void _finish_path (VkvgContext ctx){ ctx->pointCount -= ctx->pathes[ctx->pathPtr];//what about the bounds? ctx->pathes[ctx->pathPtr] = 0; ctx->segmentPtr = 0; + ctx->curPathDotSignPos = ctx->curPathIsConcave = false; return; } + if (ctx->curPathIsConcave) + ctx->pathes[ctx->pathPtr] |= PATH_IS_CONCAVE_BIT; + ctx->curPathDotSignPos = ctx->curPathIsConcave = false; + if (ctx->segmentPtr > 0) { ctx->pathes[ctx->pathPtr] |= PATH_HAS_CURVES_BIT; //if last segment is not a curve and point count > 0 @@ -167,6 +172,7 @@ void _clear_path (VkvgContext ctx){ ctx->pathes [ctx->pathPtr] = 0; ctx->pointCount = 0; ctx->segmentPtr = 0; + ctx->curPathDotSignPos = ctx->curPathIsConcave = false; _resetMinMax(ctx); } void _remove_last_point (VkvgContext ctx){ @@ -489,7 +495,7 @@ void _flush_cmd_buff (VkvgContext ctx){ void _bind_draw_pipeline (VkvgContext ctx) { switch (ctx->curOperator) { case VKVG_OPERATOR_OVER: - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_OVER); + CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_TF_OVER); break; case VKVG_OPERATOR_CLEAR: vkvg_set_source_rgba(ctx,0,0,0,0); @@ -1122,62 +1128,86 @@ void _fill_ec (VkvgContext ctx){ uint32_t pathPointCount = ctx->pathes[ptrPath] & PATH_ELT_MASK; - VKVG_IBO_INDEX_TYPE firstVertIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); - ear_clip_point* ecps = (ear_clip_point*)malloc(pathPointCount*sizeof(ear_clip_point)); - uint32_t ecps_count = pathPointCount; - VKVG_IBO_INDEX_TYPE i = 0; + if (!(ctx->pathes[ptrPath] & PATH_IS_CONCAVE_BIT)){//} && pathPointCount > 50) { + _emit_draw_cmd_undrawn_vertices (ctx); + VKVG_IBO_INDEX_TYPE firstVertIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount); + if (ctx->sizeVertices < ctx->vertCount + pathPointCount) { + uint32_t newSize = (uint32_t)ceilf((float)(ctx->vertCount + pathPointCount)/VKVG_VBO_SIZE) * VKVG_VBO_SIZE; + _resize_vertex_cache (ctx, newSize); + } + if (ctx->sizeVertices > ctx->sizeVBO) { + if (ctx->cmdStarted) { + _flush_cmd_until_vx_base (ctx); + firstVertIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount); + } + _resize_vbo(ctx, ctx->sizeVertices); + } + firstVertIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount); + for (uint32_t i = 0; i < pathPointCount; i++) { + v.pos = ctx->points [i+firstPtIdx]; + ctx->vertexCache[ctx->vertCount++] = v; + } + LOG(VKVG_LOG_DBG_ARRAYS, "\tpoint count = %d; 1st vert = %d; vert count = %d; vx tot = %d\n", pathPointCount, firstVertIdx, ctx->vertCount - firstVertIdx, ctx->vertCount); + _ensure_renderpass_is_started (ctx); + CmdDraw (ctx->cmd, pathPointCount, 1, firstVertIdx , 0); + ctx->curVertOffset = ctx->vertCount; + }else{ + VKVG_IBO_INDEX_TYPE firstVertIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); + ear_clip_point* ecps = (ear_clip_point*)malloc(pathPointCount*sizeof(ear_clip_point)); + uint32_t ecps_count = pathPointCount; + VKVG_IBO_INDEX_TYPE i = 0; + + //init points link list + while (i < pathPointCount-1){ + v.pos = ctx->points[i+firstPtIdx]; + ear_clip_point ecp = {v.pos, firstVertIdx+i, &ecps[i+1]}; + ecps[i] = ecp; + _add_vertex(ctx, v); + i++; + } - //init points link list - while (i < pathPointCount-1){ v.pos = ctx->points[i+firstPtIdx]; - ear_clip_point ecp = {v.pos, firstVertIdx+i, &ecps[i+1]}; + ear_clip_point ecp = {v.pos, firstVertIdx+i, ecps}; ecps[i] = ecp; _add_vertex(ctx, v); - i++; - } - - v.pos = ctx->points[i+firstPtIdx]; - ear_clip_point ecp = {v.pos, firstVertIdx+i, ecps}; - ecps[i] = ecp; - _add_vertex(ctx, v); - ear_clip_point* ecp_current = ecps; - uint32_t tries = 0; + ear_clip_point* ecp_current = ecps; + uint32_t tries = 0; - while (ecps_count > 3) { - if (tries > ecps_count) { - break; - } - ear_clip_point* v0 = ecp_current->next, - *v1 = ecp_current, *v2 = ecp_current->next->next; - if (ecp_zcross (v0, v2, v1)<0){ - ecp_current = ecp_current->next; - tries++; - continue; - } - ear_clip_point* vP = v2->next; - bool isEar = true; - while (vP!=v1){ - if (ptInTriangle (vP->pos, v0->pos, v2->pos, v1->pos)){ - isEar = false; + while (ecps_count > 3) { + if (tries > ecps_count) { break; } - vP = vP->next; - } - if (isEar){ - _add_triangle_indices (ctx, v0->idx, v1->idx, v2->idx); - v1->next = v2; - ecps_count --; - tries = 0; - }else{ - ecp_current = ecp_current->next; - tries++; + ear_clip_point* v0 = ecp_current->next, + *v1 = ecp_current, *v2 = ecp_current->next->next; + if (ecp_zcross (v0, v2, v1)<0){ + ecp_current = ecp_current->next; + tries++; + continue; + } + ear_clip_point* vP = v2->next; + bool isEar = true; + while (vP!=v1){ + if (ptInTriangle (vP->pos, v0->pos, v2->pos, v1->pos)){ + isEar = false; + break; + } + vP = vP->next; + } + if (isEar){ + _add_triangle_indices (ctx, v0->idx, v1->idx, v2->idx); + v1->next = v2; + ecps_count --; + tries = 0; + }else{ + ecp_current = ecp_current->next; + tries++; + } } + if (ecps_count == 3) + _add_triangle_indices(ctx, ecp_current->next->idx, ecp_current->idx, ecp_current->next->next->idx); + free (ecps); } - if (ecps_count == 3) - _add_triangle_indices(ctx, ecp_current->next->idx, ecp_current->idx, ecp_current->next->next->idx); - free (ecps); - firstPtIdx += pathPointCount; if (_path_has_curves (ctx, ptrPath)) { //skip segments lengths used in stroke @@ -1187,6 +1217,7 @@ void _fill_ec (VkvgContext ctx){ totPts += (ctx->pathes[ptrPath++] & PATH_ELT_MASK); }else ptrPath++; + } } diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index e9b45c9..4e21d4e 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -143,6 +143,9 @@ typedef struct _vkvg_context_t { uint32_t* pathes; uint32_t sizePathes; + + bool curPathIsConcave; + bool curPathDotSignPos; uint32_t segmentPtr; //current segment count in current path having curves float lineWidth; diff --git a/src/vkvg_device.c b/src/vkvg_device.c index e17b81b..480095b 100644 --- a/src/vkvg_device.c +++ b/src/vkvg_device.c @@ -142,6 +142,8 @@ void vkvg_device_destroy (VkvgDevice dev) vkDestroyPipeline (dev->vkDev, dev->pipe_SUB, NULL); vkDestroyPipeline (dev->vkDev, dev->pipe_CLEAR, NULL); + vkDestroyPipeline (dev->vkDev, dev->pipe_TF_OVER, NULL); + #ifdef VKVG_WIRED_DEBUG vkDestroyPipeline (dev->vkDev, dev->pipelineWired, NULL); vkDestroyPipeline (dev->vkDev, dev->pipelineLineList, NULL); diff --git a/src/vkvg_device_internal.c b/src/vkvg_device_internal.c index 55b5050..8b99a70 100644 --- a/src/vkvg_device_internal.c +++ b/src/vkvg_device_internal.c @@ -46,6 +46,7 @@ PFN_vkCmdSetScissor CmdSetScissor; PFN_vkCmdPushConstants CmdPushConstants; PFN_vkCmdPushDescriptorSetKHR CmdPushDescriptorSet; +//PFN_vkCmdSetPrimitiveTopologyEXT CmdSetPrimitiveTopology; void _flush_all_contexes (VkvgDevice dev){ VkvgContext ctx = dev->lastCtx; @@ -239,9 +240,9 @@ void _setupPipelines(VkvgDevice dev) VkDynamicState dynamicStateEnables[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, - VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, + VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, VK_DYNAMIC_STATE_STENCIL_REFERENCE, - VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, + VK_DYNAMIC_STATE_STENCIL_WRITE_MASK }; VkPipelineDynamicStateCreateInfo dynamicState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, .dynamicStateCount = 2, @@ -342,6 +343,9 @@ void _setupPipelines(VkvgDevice dev) pipelineCreateInfo.stageCount = 2; VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipe_OVER)); + inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN; + VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipe_TF_OVER)); + blendAttachmentState.alphaBlendOp = blendAttachmentState.colorBlendOp = VK_BLEND_OP_SUBTRACT; VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipe_SUB)); @@ -434,6 +438,7 @@ bool _init_function_pointers (VkvgDevice dev) { CmdSetScissor = GetInstProcAddress(dev->instance, vkCmdSetScissor); CmdPushConstants = GetInstProcAddress(dev->instance, vkCmdPushConstants); CmdPushDescriptorSet = (PFN_vkCmdPushDescriptorSetKHR)vkGetInstanceProcAddr(dev->instance, "vkCmdDescriptorSet"); +// CmdSetPrimitiveTopology = (PFN_vkCmdSetPrimitiveTopologyEXT)vkGetInstanceProcAddr(dev->instance, "vkCmdSetPrimitiveTopologyEXT"); return true; } diff --git a/src/vkvg_device_internal.h b/src/vkvg_device_internal.h index 8d8da08..f764799 100644 --- a/src/vkvg_device_internal.h +++ b/src/vkvg_device_internal.h @@ -48,6 +48,7 @@ extern PFN_vkCmdSetScissor CmdSetScissor; extern PFN_vkCmdPushConstants CmdPushConstants; extern PFN_vkCmdPushDescriptorSetKHR CmdPushDescriptorSet; +//extern PFN_vkCmdSetPrimitiveTopologyEXT CmdSetPrimitiveTopology; typedef struct _vkvg_device_t{ VkDevice vkDev; /**< Vulkan Logical Device */ @@ -71,6 +72,8 @@ typedef struct _vkvg_device_t{ VkPipeline pipe_SUB; VkPipeline pipe_CLEAR; /**< clear operator */ + VkPipeline pipe_TF_OVER; /**< default operator triangle fan*/ + VkPipeline pipelinePolyFill; /**< even-odd polygon filling first step */ VkPipeline pipelineClipping; /**< draw on stencil to update clipping regions */ diff --git a/src/vkvg_internal.h b/src/vkvg_internal.h index 3fc4647..571d0cc 100644 --- a/src/vkvg_internal.h +++ b/src/vkvg_internal.h @@ -52,7 +52,22 @@ #define PATH_HAS_CURVES_BIT 0x40000000 /* 2rd most significant bit of path elmts is curved status * for main path, this indicate that curve datas are present * for segments, this indicate that the segment is curved or not */ -#define PATH_ELT_MASK 0x3FFFFFFF /* Bit mask for fetching path element value */ +#define PATH_IS_CONCAVE_BIT 0x20000000 /* 3rd most significant bit of path elmts is concave/convex bit + * 0=>simple concave path + * 1=>convex */ +#define PATH_DOT_PLUS_BIT 0x10000000 /* 4rd most significant bit of path elmts is current sign of dot product + * dotproduct is computed for last vector, if the sign is the same along + * a path, then it's a single concave path. This bit holds the current sign. + * If the last dot product sign is different from the one held by this bit, + * the 3rd bit is used to mark this path as convex. + * Some draw primitive have known dot product. positive arc is -, negative is +, + * rectangle is -. + * 0=>current dot product sign is negative. + * 1=>current dot product sign is positive. + * + * + * 1=>convex */ +#define PATH_ELT_MASK 0x0FFFFFFF /* Bit mask for fetching path element value */ #define ROUNDF(f, c) (((float)((int)((f) * (c))) / (c))) #define ROUND_DOWN(v,p) (floorf(v * p) / p) diff --git a/tests/random_rects.c b/tests/random_rects.c index f192206..87833d4 100644 --- a/tests/random_rects.c +++ b/tests/random_rects.c @@ -91,24 +91,24 @@ int main(int argc, char *argv[]) { //vkvg_log_level = VKVG_LOG_ERR|VKVG_LOG_DEBUG|VKVG_LOG_INFO|VKVG_LOG_INFO_PATH|VKVG_LOG_DBG_ARRAYS|VKVG_LOG_FULL; PERFORM_TEST (rectangles_fill, argc, argv); - PERFORM_TEST (rectangles_stroke, argc, argv); - PERFORM_TEST (rectangles_fill_stroke, argc, argv); + //PERFORM_TEST (rectangles_stroke, argc, argv); + //PERFORM_TEST (rectangles_fill_stroke, argc, argv); PERFORM_TEST (rounded_rects_fill, argc, argv); - PERFORM_TEST (rounded_rects_stroke, argc, argv); - PERFORM_TEST (rounded_rects_fill_stroke, argc, argv); + //PERFORM_TEST (rounded_rects_stroke, argc, argv); + //PERFORM_TEST (rounded_rects_fill_stroke, argc, argv); PERFORM_TEST (circles_fill, argc, argv); - PERFORM_TEST (circles_stroke, argc, argv); - PERFORM_TEST (circles_fill_stroke, argc, argv); + //PERFORM_TEST (circles_stroke, argc, argv); + //PERFORM_TEST (circles_fill_stroke, argc, argv); PERFORM_TEST (stars_fill, argc, argv); - PERFORM_TEST (stars_stroke, argc, argv); - PERFORM_TEST (stars_fill_stroke, argc, argv); + //PERFORM_TEST (stars_stroke, argc, argv); + //PERFORM_TEST (stars_fill_stroke, argc, argv); PERFORM_TEST (random_fill, argc, argv); - PERFORM_TEST (random_stroke, argc, argv); - PERFORM_TEST (random_fill_stroke, argc, argv); + //PERFORM_TEST (random_stroke, argc, argv); + //PERFORM_TEST (random_fill_stroke, argc, argv); return 0; } -- 2.47.3