if (ctx->pointCount * 4 > ctx->sizeIndices - ctx->indCount)//flush if vk buff is full
vkvg_flush(ctx);
+ _check_cmd_buff_state(ctx);
_poly_fill (ctx);
vkCmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping);
if (ctx->pointCount * 4 > ctx->sizeIndices - ctx->indCount)//flush if vk buff is full
vkvg_flush(ctx);
+ _check_cmd_buff_state(ctx);
_poly_fill (ctx);
_bind_draw_pipeline (ctx);
_record_draw_cmd(ctx);
}
void vkvg_paint (VkvgContext ctx){
+ _check_cmd_buff_state(ctx);
vkCmdDrawIndexed (ctx->cmd,6,1,0,0,0);
}
inline void vkvg_set_source_rgb (VkvgContext ctx, float r, float g, float b) {
_update_cur_pattern (ctx, vkvg_pattern_create_for_surface(surf));
ctx->pushConsts.source.x = x;
ctx->pushConsts.source.y = y;
- _update_push_constants (ctx);
+ ctx->pushCstDirty = true;
}
void vkvg_set_source (VkvgContext ctx, VkvgPattern pat){
_update_cur_pattern (ctx, pat);
}
void vkvg_show_text (VkvgContext ctx, const char* text){
+ _check_cmd_buff_state(ctx);
_show_text (ctx, text);
_record_draw_cmd (ctx);
}
#include "vkh_queue.h"
#include "vkh_image.h"
+void _check_cmd_buff_state (VkvgContext ctx) {
+ if (!ctx->cmdStarted)
+ _start_cmd_for_render_pass(ctx);
+ else if (ctx->pushCstDirty)
+ _update_push_constants(ctx);
+}
void _check_pathes_array (VkvgContext ctx){
if (ctx->sizePathes - ctx->pathPtr > VKVG_ARRAY_THRESHOLD)
return;
LOG(LOG_INFO, "RECORD DRAW CMD: ctx = %lu; vert cpt = %d; ind cpt = %d; ind drawn = %d\n", ctx, ctx->vertCount - 4, ctx->indCount - 6, ctx->indCount - ctx->curIndStart);
if (ctx->indCount == ctx->curIndStart)
return;
+ _check_cmd_buff_state(ctx);
vkCmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, 0, 1);
//DEBUG
vkh_cmd_submit (ctx->pSurf->dev->gQueue, &ctx->cmd, ctx->flushFence);
}
void _wait_and_reset_ctx_cmd (VkvgContext ctx){
+ if (!ctx->cmdStarted)
+ return;
vkWaitForFences(ctx->pSurf->dev->vkDev,1,&ctx->flushFence,VK_TRUE,UINT64_MAX);
vkResetFences(ctx->pSurf->dev->vkDev,1,&ctx->flushFence);
vkResetCommandBuffer(ctx->cmd,0);
+ ctx->cmdStarted = false;
}
inline void _submit_wait_and_reset_cmd (VkvgContext ctx){
_submit_ctx_cmd(ctx);
_wait_and_reset_ctx_cmd(ctx);
}
-void _explicit_ms_resolve (VkvgContext ctx){
+void _explicit_ms_resolve (VkvgContext ctx){//should init cmd before calling this (unused, using automatic resolve by renderpass)
vkh_image_set_layout (ctx->cmd, ctx->pSurf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
vkCmdEndRenderPass (ctx->cmd);
}
void _flush_cmd_buff (VkvgContext ctx){
+ if (!ctx->cmdStarted)
+ return;
_end_render_pass (ctx);
- //_explicit_ms_resolve (ctx);
vkh_cmd_end (ctx->cmd);
_submit_wait_and_reset_cmd(ctx);
//VkClearValue clearValues[2];
//clearValues[0].color = { { 0.0f, 0.0f, 0.0f, 1.0f } };
//clearValues[1].depthStencil = { 1.0f, 0 };
- VkClearValue clearValues[4] = {
+ /*VkClearValue clearValues[4] = {
{ 0.0f, 1.0f, 0.0f, 1.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f },
{ 1.0f, 0 },
{ 1.0f, 0 }
- };
+ };*/
+
+}
+void _start_cmd_for_render_pass (VkvgContext ctx) {
VkRenderPassBeginInfo renderPassBeginInfo = { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.renderPass = ctx->pSurf->dev->renderPass,
.framebuffer = ctx->pSurf->fb,
vkCmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
_update_push_constants (ctx);
+ ctx->cmdStarted = 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) {
ctx->pushConsts.matInv = ctx->pushConsts.mat;
vkvg_matrix_invert (&ctx->pushConsts.matInv);
- _update_push_constants (ctx);
+ ctx->pushCstDirty = true;
}
inline void _update_push_constants (VkvgContext ctx) {
vkCmdPushConstants(ctx->cmd, ctx->pSurf->dev->pipelineLayout,
VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(push_constants),&ctx->pushConsts);
+ ctx->pushCstDirty = false;
}
void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) {
VkvgPattern lastPat = ctx->pattern;
ctx->pattern = pat;
ctx->pushConsts.patternType = pat->type;
+ ctx->pushCstDirty = true;
switch (pat->type) {
case VKVG_PATTERN_TYPE_SOLID:
if (lastPat && lastPat->type == VKVG_PATTERN_TYPE_SURFACE){
_flush_cmd_buff (ctx);
_reset_src_descriptor_set (ctx);
- _init_cmd_buff (ctx);//push csts updated by init
- }else
- _update_push_constants (ctx);
+ //_init_cmd_buff (ctx);//push csts updated by init
+ }//else
+ //_update_push_constants (ctx);
break;
case VKVG_PATTERN_TYPE_SURFACE:
VkvgSurface surf = (VkvgSurface)pat->data;
//flush ctx in two steps to add the src transition in the cmd buff
- _end_render_pass (ctx);
+ if (ctx->cmdStarted)//transition of img without appropriate dep in subpass must be done outside renderpass.
+ _end_render_pass (ctx);
+ else {
+ vkh_cmd_begin (ctx->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+ ctx->cmdStarted = true;
+ }
+
//transition source surface for sampling
vkh_image_set_layout (ctx->cmd, surf->img, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
vkh_cmd_end (ctx->cmd);
_submit_wait_and_reset_cmd(ctx);
- //_flush_cmd_buff(ctx);
-
-
ctx->source = surf->img;
//if (vkh_image_get_sampler (ctx->source) == VK_NULL_HANDLE){
vec4 srcRect = {0,0,surf->width,surf->height};
ctx->pushConsts.source = srcRect;
- _init_cmd_buff (ctx);
+ //_init_cmd_buff (ctx);
break;
}
case VKVG_PATTERN_TYPE_LINEAR:
memcpy(ctx->uboGrad.allocInfo.pMappedData , &grad, sizeof(vkvg_gradient_t));
- _init_cmd_buff (ctx);
+ //_init_cmd_buff (ctx);
break;
}
VkCommandPool cmdPool;//local pools ensure thread safety
VkCommandBuffer cmd; //single cmd buff for context operations
+ bool cmdStarted;//prevent flushing empty renderpass
+ bool pushCstDirty;//prevent pushing to gpu if not requested
VkDescriptorPool descriptorPool;
VkDescriptorSet dsFont; //fonts glyphs texture atlas descriptor (local for thread safety)
VkDescriptorSet dsSrc; //source ds
void _bind_draw_pipeline (VkvgContext ctx);
void _create_cmd_buff (VkvgContext ctx);
void _init_cmd_buff (VkvgContext ctx);
+void _check_cmd_buff_state (VkvgContext ctx);
void _flush_cmd_buff (VkvgContext ctx);
void _record_draw_cmd (VkvgContext ctx);
void _submit_wait_and_reset_cmd(VkvgContext ctx);
cache->uploadFence = vkh_fence_create_signaled(dev);
uint32_t buffLength = FONT_PAGE_SIZE*FONT_PAGE_SIZE*sizeof(uint8_t);
- cache->buff = vkh_buffer_create(dev,VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
- VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
- buffLength);
- vkh_buffer_map(cache->buff);
+
+ vkvg_buffer_create (dev,
+ VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
+ VMA_MEMORY_USAGE_CPU_TO_GPU,
+ buffLength, &cache->buff);
cache->cmd = vkh_cmd_buff_create(dev,dev->cmdPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY);
free(cache->fonts);
free(cache->pensY);
- vkh_buffer_unmap (cache->buff);
- vkh_buffer_destroy (cache->buff);
+
+ vkvg_buffer_destroy (&cache->buff);
vkh_image_destroy (cache->cacheTex);
//vkFreeCommandBuffers(dev->vkDev,dev->cmdPool, 1, &cache->cmd);
vkDestroyFence (dev->vkDev,cache->uploadFence,NULL);
vkResetCommandBuffer(cache->cmd,NULL);
vkResetFences (dev->vkDev,1,&cache->uploadFence);
- memcpy(vkh_buffer_get_mapped_pointer (cache->buff), cache->hostBuff, f->curLine.height * FONT_PAGE_SIZE);
+ memcpy(cache->buff.allocInfo.pMappedData, cache->hostBuff, f->curLine.height * FONT_PAGE_SIZE);
vkh_cmd_begin (cache->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
.imageOffset = {f->curLine.penX,f->curLine.penY,0},
.imageExtent = {FONT_PAGE_SIZE-f->curLine.penX,f->curLine.height,1}};
- vkCmdCopyBufferToImage(cache->cmd, vkh_buffer_get_vkbuffer (cache->buff),
+ vkCmdCopyBufferToImage(cache->cmd, cache->buff.buffer,
vkh_image_get_vkimage (cache->cacheTex), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferCopyRegion);
vkh_image_set_layout_subres(cache->cmd, cache->cacheTex, subres,
#include "vkvg_internal.h"
#include "vkvg.h"
+#include "vkvg_buff.h"
#include "vkh.h"
//#include "vkh_image.h"
uint8_t* hostBuff; //host mem where bitmaps are first loaded
VkCommandBuffer cmd; //upload cmd buff
- VkhBuffer buff; //stagin buffer
+ vkvg_buff buff; //stagin buffer
VkhImage cacheTex; //tex 2d array
uint8_t cacheTexLength; //tex array length
int* pensY; //y pen pos in each texture of array
vkh_image_create_descriptor (tmpImg, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT,
VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
//staging buffer
- VkhBuffer buff = vkh_buffer_create (dev, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, imgSize);
- VK_CHECK_RESULT (vkh_buffer_map (buff));
- memcpy (vkh_buffer_get_mapped_pointer (buff), img, imgSize);
+ vkvg_buff buff = {};
+ vkvg_buffer_create(dev, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU, imgSize, &buff);
+
+ memcpy (buff.allocInfo.pMappedData, img, imgSize);
/*unsigned char* mapImg = vkh_image_map (stagImg);
memcpy (mapImg, img, imgSize);
VkBufferImageCopy bufferCopyRegion = { .imageSubresource = imgSubResLayers,
.imageExtent = {surf->width,surf->height,1}};
- vkCmdCopyBufferToImage(cmd, vkh_buffer_get_vkbuffer (buff),
+ vkCmdCopyBufferToImage(cmd, buff.buffer,
vkh_image_get_vkimage (stagImg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferCopyRegion);
vkh_image_set_layout (cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT,
vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
- vkh_buffer_unmap (buff);
- vkh_buffer_destroy (buff);
+ vkvg_buffer_destroy (&buff);
vkh_image_destroy (stagImg);
//create tmp context with rendering pipeline to create the multisample img
ctx->pushConsts.source = srcRect;
ctx->pushConsts.patternType = VKVG_PATTERN_TYPE_SURFACE;
- _update_push_constants (ctx);
+ //_update_push_constants (ctx);
_update_descriptor_set (ctx, tmpImg, ctx->dsSrc);
+ _check_cmd_buff_state (ctx);
vkvg_paint (ctx);
vkvg_destroy (ctx);
vkvg_close_path(ctx);
vkvg_fill(ctx);
}
-void test_img_surface (VkvgContext ctx) {
+void test_img_surface () {
+ VkvgContext ctx = vkvg_create(surf);
VkvgSurface imgSurf;// = vkvg_surface_create_from_image(device, "/mnt/data/images/blason.png");
//VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "/mnt/data/images/2000px-Tux.svg.png");
//VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "/mnt/data/images/path2674.png");
vkvg_paint(ctx);
//vkvg_flush(ctx);
vkvg_set_source_rgba(ctx,1,0,0,1);
+
vkvg_surface_destroy(imgSurf);
+ vkvg_destroy(ctx);
}
void test_line_caps (VkvgContext ctx) {
//test_svg();
//
- VkvgContext ctx = vkvg_create(surf);
- test_img_surface(ctx);
- vkvg_destroy(ctx);
+
+
//test_grad_transforms();
- //simple_paint();
- //simple_rectangle_stroke();
- //simple_rectangle_fill();
//test_colinear();
vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf));
while (!vkengine_should_close (e)) {
glfwPollEvents();
//test_1();
- //cairo_tests();
-
+ cairo_tests();
+ //simple_paint();
+ //simple_rectangle_stroke();
+ //simple_rectangle_fill();
+ //test_img_surface();
//multi_test1();
//test_painting();
if (!vkh_presenter_draw (r))
-Subproject commit 7ae56421ae5cc41f230610e3042839e4586d4cfc
+Subproject commit 5de4a9210f64615bd0b23a0d7c88f5564d0c1e5f