void vkvg_fill (VkvgContext ctx);
void vkvg_fill_preserve (VkvgContext ctx);
void vkvg_paint (VkvgContext ctx);
+void vkvg_clear (VkvgContext ctx);//use vkClearAttachment to speed up clearing surf
void vkvg_reset_clip (VkvgContext ctx);
void vkvg_clip (VkvgContext ctx);
void vkvg_clip_preserve (VkvgContext ctx);
};
ctx->pushConsts = pc;
+ const VkClearRect cr = {{{0},{ctx->pSurf->width, ctx->pSurf->height}},0,1};
+ ctx->clearRect = cr;
+
ctx->pPrev = surf->dev->lastCtx;
if (ctx->pPrev != NULL)
ctx->pPrev->pNext = ctx;
vkvg_close_path (ctx);
}
+const VkClearAttachment clearStencil = {VK_IMAGE_ASPECT_STENCIL_BIT, 1, {0}};
+const VkClearAttachment clearColorAttach = {VK_IMAGE_ASPECT_COLOR_BIT, 0, {0}};
void vkvg_reset_clip (VkvgContext ctx){
- _flush_cmd_buff(ctx);
- _clear_surface(ctx->pSurf, VK_IMAGE_ASPECT_STENCIL_BIT);
- _init_cmd_buff(ctx);
+ _check_cmd_buff_state (ctx);
+ vkCmdClearAttachments(ctx->cmd, 1, &clearStencil, 1, &ctx->clearRect);
}
+void vkvg_clear (VkvgContext ctx){
+ _check_cmd_buff_state (ctx);
+ VkClearAttachment ca[2] = {clearColorAttach, clearStencil};
+ vkCmdClearAttachments(ctx->cmd, 2, ca, 1, &ctx->clearRect);
+}
+
void vkvg_clip (VkvgContext ctx){
vkvg_clip_preserve(ctx);
_clear_path(ctx);
ctx->vertCount+=4;
_add_tri_indices_for_rect(ctx, firstIdx);
}
+
+
void _create_cmd_buff (VkvgContext ctx){
ctx->cmd = vkh_cmd_buff_create(ctx->pSurf->dev, ctx->cmdPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY);
}
ctx->curIndStart = ctx->indCount;
}
+void _clear_attachment (VkvgContext ctx) {
+}
inline void _submit_ctx_cmd(VkvgContext ctx){
vkh_cmd_submit (ctx->pSurf->dev->gQueue, &ctx->cmd, ctx->flushFence);
}
vkh_image_set_layout(ctx->cmd, ctx->pSurf->img, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
- VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
}
vkCmdBeginRenderPass (ctx->cmd, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
}vkvg_context_save_t;
typedef struct _vkvg_context_t {
- VkvgContext pPrev; //double linked list of contexts
- VkvgContext pNext;
- uint32_t references;
+ VkvgContext pPrev; //double linked list of contexts
+ VkvgContext pNext;
+ uint32_t references;
- VkvgSurface pSurf;
- VkFence flushFence;
- VkhImage source; //source of painting operation
+ VkvgSurface pSurf;
+ VkFence flushFence;
+ VkhImage source; //source of painting operation
VkCommandPool cmdPool;//local pools ensure thread safety
VkCommandBuffer cmd; //single cmd buff for context operations
vkvg_line_cap_t lineCap;
vkvg_line_join_t lineJoin;
- _vkvg_font_t selectedFont; //hold current face and size before cache addition
- _vkvg_font_t* currentFont; //font ready for lookup
- vkvg_direction_t textDirection;
+ _vkvg_font_t selectedFont; //hold current face and size before cache addition
+ _vkvg_font_t* currentFont; //font pointing to cached fonts ready for lookup
+ vkvg_direction_t textDirection;
- push_constants pushConsts;
- VkvgPattern pattern;
+ push_constants pushConsts;
+ VkvgPattern pattern;
vkvg_context_save_t* pSavedCtxs;//last ctx saved ptr
+
+ VkClearRect clearRect;
}vkvg_context;
bool _current_path_is_empty (VkvgContext ctx);
dev->cmd = vkh_cmd_buff_create (dev, dev->cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
dev->fence = vkh_fence_create_signaled (dev);
- //_create_pipeline_cache (dev);
+ _create_pipeline_cache (dev);
_init_fonts_cache (dev);
_setupRenderPass (dev);
_createDescriptorSetLayout (dev);
vkDestroyPipeline (dev->vkDev, dev->pipe_SUB, NULL);
vkDestroyPipeline (dev->vkDev, dev->pipe_CLEAR, NULL);
+#if DEBUG
vkDestroyPipeline (dev->vkDev, dev->pipelineWired, NULL);
vkDestroyPipeline (dev->vkDev, dev->pipelineLineList, NULL);
+#endif
vkDestroyPipelineLayout (dev->vkDev, dev->pipelineLayout, NULL);
- //vkDestroyPipelineCache (dev->vkDev, dev->pipelineCache, NULL);
+ vkDestroyPipelineCache (dev->vkDev, dev->pipelineCache, NULL);
vkDestroyRenderPass (dev->vkDev, dev->renderPass, NULL);
vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
pipelineCreateInfo.layout = dev->pipelineLayout;
- VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, VK_NULL_HANDLE, 1, &pipelineCreateInfo, NULL, &dev->pipelinePolyFill));
+ VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelinePolyFill));
inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
dsStateCreateInfo.back = dsStateCreateInfo.front = clipingOpState;
- VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, VK_NULL_HANDLE, 1, &pipelineCreateInfo, NULL, &dev->pipelineClipping));
+ VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelineClipping));
dsStateCreateInfo.back = dsStateCreateInfo.front = stencilOpState;
blendAttachmentState.colorWriteMask=0xf;
dynamicState.dynamicStateCount = 3;
- VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, VK_NULL_HANDLE, 1, &pipelineCreateInfo, NULL, &dev->pipe_OVER));
+ VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipe_OVER));
blendAttachmentState.alphaBlendOp = blendAttachmentState.colorBlendOp = VK_BLEND_OP_SUBTRACT;
- VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, VK_NULL_HANDLE, 1, &pipelineCreateInfo, NULL, &dev->pipe_SUB));
+ VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipe_SUB));
blendAttachmentState.blendEnable = VK_FALSE;
//rasterizationState.polygonMode = VK_POLYGON_MODE_POINT;
//shaderStages[1].pName = "op_CLEAR";
- VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, VK_NULL_HANDLE, 1, &pipelineCreateInfo, NULL, &dev->pipe_CLEAR));
+ VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipe_CLEAR));
+
+#if DEBUG
rasterizationState.polygonMode = VK_POLYGON_MODE_FILL;
inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
shaderStages[1].pName = "main";
- VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, VK_NULL_HANDLE, 1, &pipelineCreateInfo, NULL, &dev->pipelineLineList));
+ VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelineLineList));
shaderStages[1].module = modFragWired;
- //pipelineCreateInfo.pStages = shaderStages;
-
inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
- VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, VK_NULL_HANDLE, 1, &pipelineCreateInfo, NULL, &dev->pipelineWired));
+ VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelineWired));
+ vkDestroyShaderModule(dev->vkDev, modFragWired, NULL);
+#endif
vkDestroyShaderModule(dev->vkDev, modVert, NULL);
vkDestroyShaderModule(dev->vkDev, modFrag, NULL);
- vkDestroyShaderModule(dev->vkDev, modFragWired, NULL);
}
void _createDescriptorSetLayout (VkvgDevice dev) {
VK_CHECK_RESULT(vkCreatePipelineLayout(dev->vkDev, &pipelineLayoutCreateInfo, NULL, &dev->pipelineLayout));
}
-void _wait_device_fence (VkvgDevice dev) {
+void _wait_and_reset_device_fence (VkvgDevice dev) {
vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
vkResetFences (dev->vkDev, 1, &dev->fence);
}
uint32_t references;
VkCommandPool cmdPool;
VkCommandBuffer cmd;
+ //this fence is kept signaled when idle, wait and reset are called before each recording.
VkFence fence;
- VkPipeline pipe_OVER;
+ VkPipeline pipe_OVER; //default operator
VkPipeline pipe_SUB;
- VkPipeline pipe_CLEAR;
+ VkPipeline pipe_CLEAR; //clear operator
- VkPipeline pipelinePolyFill;
- VkPipeline pipelineClipping;
+ VkPipeline pipelinePolyFill; //
+ VkPipeline pipelineClipping; //to update clip
+
+#if DEBUG
VkPipeline pipelineWired;
VkPipeline pipelineLineList;
+#endif
VkPipelineCache pipelineCache;
VkPipelineLayout pipelineLayout;
void _createDescriptorSetLayout (VkvgDevice dev);
void _flush_all_contexes (VkvgDevice dev);
void _init_all_contexes (VkvgDevice dev);
-void _wait_device_fence (VkvgDevice dev);
+void _wait_and_reset_device_fence (VkvgDevice dev);
#endif
VkvgDevice dev = surf->dev;
VkCommandBuffer cmd = dev->cmd;
- _wait_device_fence (dev);
+ _wait_and_reset_device_fence (dev);
vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
return surf;
}
+//TODO: it would be better to blit in original size and create ms final image with dest surf dims
VkvgSurface vkvg_surface_create_from_bitmap (VkvgDevice dev, unsigned char* img, uint32_t width, uint32_t height) {
VkvgSurface surf = (vkvg_surface*)calloc(1,sizeof(vkvg_surface));
memcpy (buff.allocInfo.pMappedData, img, imgSize);
- /*unsigned char* mapImg = vkh_image_map (stagImg);
- memcpy (mapImg, img, imgSize);
- vkh_image_unmap (stagImg);*/
-
VkCommandBuffer cmd = dev->cmd;
- _wait_device_fence (dev);
+ _wait_and_reset_device_fence (dev);
vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
vkh_image_set_layout (cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT,
vkh_cmd_end (cmd);
vkh_cmd_submit (dev->gQueue, &cmd, dev->fence);
+ //don't reset fence after completion as this is the last cmd. (signaled idle fence)
vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
vkvg_buffer_destroy (&buff);
VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT);
VkCommandBuffer cmd = dev->cmd;
- _wait_device_fence (dev);
+ _wait_and_reset_device_fence (dev);
vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
vkh_image_set_layout (cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT,
vkh_cmd_end (cmd);
vkh_cmd_submit (dev->gQueue, &cmd, dev->fence);
- _wait_device_fence (dev);
+ _wait_and_reset_device_fence (dev);
void* img = vkh_image_map (stagImg);