From 761b90a23d7ae46591e0d487917625a1f61b2275 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Sat, 28 Apr 2018 22:45:42 +0200 Subject: [PATCH] current pattern field in context, save and restore use it, pattern filter and extend (not complete) --- include/vkvg.h | 18 +++++++- src/vkvg_context.c | 83 +++++----------------------------- src/vkvg_context_internal.c | 89 +++++++++++++++++++++++++++++++++++++ src/vkvg_context_internal.h | 4 +- src/vkvg_device_internal.c | 8 ++-- src/vkvg_pattern.c | 30 ++++++++++++- src/vkvg_pattern.h | 3 +- tests/test1.c | 13 ++++-- 8 files changed, 164 insertions(+), 84 deletions(-) diff --git a/include/vkvg.h b/include/vkvg.h index 9a1e555..160c1f5 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -50,6 +50,15 @@ typedef enum _vkvg_extend { VKVG_EXTEND_PAD } vkvg_extend_t; +typedef enum _vkvg_filter { + VKVG_FILTER_FAST, + VKVG_FILTER_GOOD, + VKVG_FILTER_BEST, + VKVG_FILTER_NEAREST, + VKVG_FILTER_BILINEAR, + VKVG_FILTER_GAUSSIAN, +} vkvg_filter_t; + typedef enum _vkvg_pattern_type { VKVG_PATTERN_TYPE_SOLID, VKVG_PATTERN_TYPE_SURFACE, @@ -214,14 +223,20 @@ void vkvg_font_extents (VkvgContext ctx, vkvg_font_extents_t* extents); //pattern VkvgPattern vkvg_pattern_create (); +VkvgPattern vkvg_pattern_create_rgba (float r, float g, float b, float a); +VkvgPattern vkvg_pattern_create_rgb (float r, float g, float b); VkvgPattern vkvg_pattern_create_for_surface (VkvgSurface surf); VkvgPattern vkvg_pattern_create_linear (float x0, float y0, float x1, float y1); VkvgPattern vkvg_pattern_create_radial (float cx0, float cy0, float radius0, float cx1, float cy1, float radius1); +void vkvg_pattern_destroy (VkvgPattern pat); void vkvg_patter_add_color_stop (VkvgPattern pat, float offset, float r, float g, float b, float a); void vkvg_pattern_set_extend (VkvgPattern pat, vkvg_extend_t extend); -void vkvg_pattern_destroy (VkvgPattern pat); +void vkvg_pattern_set_filter (VkvgPattern pat, vkvg_filter_t filter); + +vkvg_extend_t vkvg_pattern_get_extend (VkvgPattern pat); +vkvg_filter_t vkvg_pattern_get_filter (VkvgPattern pat); //matrix void vkvg_matrix_init_identity (vkvg_matrix_t *matrix); @@ -239,6 +254,7 @@ void vkvg_matrix_multiply (vkvg_matrix_t *result, const vkvg_matrix_t void vkvg_matrix_transform_distance (const vkvg_matrix_t *matrix, float *dx, float *dy); void vkvg_matrix_transform_point (const vkvg_matrix_t *matrix, float *x, float *y); void vkvg_matrix_invert (vkvg_matrix_t *matrix); + #ifdef __cplusplus } #endif diff --git a/src/vkvg_context.c b/src/vkvg_context.c index b21f910..659f740 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -520,84 +520,18 @@ void _vkvg_fill_rectangle (VkvgContext ctx, float x, float y, float width, float void vkvg_paint (VkvgContext ctx){ vkCmdDrawIndexed (ctx->cmd,6,1,0,0,0); } - inline void vkvg_set_source_rgb (VkvgContext ctx, float r, float g, float b) { vkvg_set_source_rgba (ctx, r, g, b, 1); } void vkvg_set_source_rgba (VkvgContext ctx, float r, float g, float b, float a) { - uint32_t lastPat = ctx->pushConsts.patternType; - - vec4 c = {r,g,b,a}; - ctx->pushConsts.source = c; - ctx->pushConsts.patternType = VKVG_PATTERN_TYPE_SOLID; - - if (lastPat == 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); + _update_cur_pattern (ctx, vkvg_pattern_create_rgba (r,g,b,a)); } void vkvg_set_source_surface(VkvgContext ctx, VkvgSurface surf, float x, float y){ - _flush_cmd_buff(ctx); - - ctx->source = surf->img; - - if (vkh_image_get_sampler(ctx->source) == VK_NULL_HANDLE) - vkh_image_create_sampler(ctx->source,VK_FILTER_NEAREST, VK_FILTER_NEAREST, - VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER); - - if (vkh_image_get_layout (ctx->source) != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL){ - vkh_cmd_begin (ctx->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); - - vkh_image_set_layout (ctx->cmd, ctx->source, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); - vkh_cmd_end (ctx->cmd); - - _submit_wait_and_reset_cmd (ctx); - } - - _update_descriptor_set (ctx, ctx->source, ctx->dsSrc); - - vec4 srcRect = {x,y,surf->width,surf->height}; - ctx->pushConsts.source = srcRect; - ctx->pushConsts.patternType = VKVG_PATTERN_TYPE_SURFACE; - - _init_cmd_buff (ctx); + _update_cur_pattern (ctx, vkvg_pattern_create_for_surface(surf)); } void vkvg_set_source (VkvgContext ctx, VkvgPattern pat){ - if (pat->type == VKVG_PATTERN_TYPE_SOLID){ - vkvg_color_t* c = (vkvg_color_t*)pat->data; - vkvg_set_source_rgba (ctx, c->r, c->g, c->b, c->a); - return; - } - if (pat->type == VKVG_PATTERN_TYPE_SURFACE){ - vkvg_set_source_surface (ctx, (VkvgSurface)pat->data, 0, 0); - return; - } - - _flush_cmd_buff (ctx); - - if (ctx->pushConsts.patternType == VKVG_PATTERN_TYPE_SURFACE) - _reset_src_descriptor_set (ctx); - - ctx->pushConsts.patternType = pat->type; - vec4 bounds = {ctx->pSurf->width, ctx->pSurf->height, 0, 0};//store img bounds in unused source field - ctx->pushConsts.source = bounds; - _update_push_constants (ctx); - - //transform control point with current ctx matrix - vkvg_gradient_t grad = {}; - memcpy(&grad, pat->data, sizeof(vkvg_gradient_t)); - - vkvg_matrix_transform_point(&ctx->pushConsts.mat, &grad.cp[0].x, &grad.cp[0].y); - vkvg_matrix_transform_point(&ctx->pushConsts.mat, &grad.cp[1].x, &grad.cp[1].y); - //to do, scale radial radiuses in cp[2] - - memcpy(ctx->uboGrad.mapped, &grad, sizeof(vkvg_gradient_t)); - - _init_cmd_buff (ctx); + _update_cur_pattern (ctx, pat); } void vkvg_set_line_width (VkvgContext ctx, float width){ ctx->lineWidth = width; @@ -703,7 +637,7 @@ void vkvg_save (VkvgContext ctx){ sav->currentFont = ctx->currentFont; sav->textDirection= ctx->textDirection; sav->pushConsts = ctx->pushConsts; - sav->source = ctx->source; + sav->pattern = ctx->pattern; sav->pNext = ctx->pSavedCtxs; ctx->pSavedCtxs = sav; @@ -714,11 +648,16 @@ void vkvg_save (VkvgContext ctx){ void vkvg_restore (VkvgContext ctx){ if (ctx->pSavedCtxs == NULL) return; - _flush_cmd_buff(ctx); vkvg_context_save_t* sav = ctx->pSavedCtxs; ctx->pSavedCtxs = sav->pNext; + ctx->pushConsts = sav->pushConsts; + + _update_cur_pattern(ctx, sav->pattern); + + _flush_cmd_buff(ctx); + vkh_cmd_begin (ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencilMS, VK_IMAGE_ASPECT_STENCIL_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, @@ -763,8 +702,6 @@ void vkvg_restore (VkvgContext ctx){ ctx->currentFont = sav->currentFont; ctx->textDirection= sav->textDirection; - ctx->pushConsts = sav->pushConsts; - ctx->source = sav->source; _wait_and_reset_ctx_cmd (ctx); _init_cmd_buff (ctx); diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index 1723af6..fe993c2 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -275,7 +275,96 @@ 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); } +void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { + VkvgPattern lastPat = ctx->pattern; + ctx->pattern = pat; + ctx->pushConsts.patternType = pat->type; + + switch (pat->type) { + case VKVG_PATTERN_TYPE_SOLID: + memcpy (&ctx->pushConsts.source, ctx->pattern->data, sizeof(vkvg_color_t)); + + 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); + + break; + case VKVG_PATTERN_TYPE_SURFACE: + _flush_cmd_buff(ctx); + + VkvgSurface surf = (VkvgSurface)pat->data; + ctx->source = surf->img; + + //if (vkh_image_get_sampler (ctx->source) == VK_NULL_HANDLE){ + VkSamplerAddressMode addrMode; + VkFilter filter = VK_FILTER_NEAREST; + switch (pat->extend) { + case VKVG_EXTEND_NONE: + addrMode = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; + break; + case VKVG_EXTEND_PAD: + addrMode = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + break; + case VKVG_EXTEND_REPEAT: + addrMode = VK_SAMPLER_ADDRESS_MODE_REPEAT; + break; + case VKVG_EXTEND_REFLECT: + addrMode = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + break; + } + switch (pat->filter) { + case VKVG_FILTER_BILINEAR: + case VKVG_FILTER_BEST: + filter = VK_FILTER_LINEAR; + break; + } + vkh_image_create_sampler(ctx->source, filter, filter, + VK_SAMPLER_MIPMAP_MODE_NEAREST, addrMode); + //} + if (vkh_image_get_layout (ctx->source) != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL){ + vkh_cmd_begin (ctx->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + + vkh_image_set_layout (ctx->cmd, ctx->source, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); + vkh_cmd_end (ctx->cmd); + + _submit_wait_and_reset_cmd (ctx); + } + + _update_descriptor_set (ctx, ctx->source, ctx->dsSrc); + + vec4 srcRect = {0,0,surf->width,surf->height}; + ctx->pushConsts.source = srcRect; + + _init_cmd_buff (ctx); + break; + case VKVG_PATTERN_TYPE_LINEAR: + _flush_cmd_buff (ctx); + + if (lastPat && lastPat->type == VKVG_PATTERN_TYPE_SURFACE) + _reset_src_descriptor_set (ctx); + + vec4 bounds = {ctx->pSurf->width, ctx->pSurf->height, 0, 0};//store img bounds in unused source field + ctx->pushConsts.source = bounds; + + //transform control point with current ctx matrix + vkvg_gradient_t grad = {}; + memcpy(&grad, pat->data, sizeof(vkvg_gradient_t)); + + vkvg_matrix_transform_point(&ctx->pushConsts.mat, &grad.cp[0].x, &grad.cp[0].y); + vkvg_matrix_transform_point(&ctx->pushConsts.mat, &grad.cp[1].x, &grad.cp[1].y); + //to do, scale radial radiuses in cp[2] + + memcpy(ctx->uboGrad.mapped, &grad, sizeof(vkvg_gradient_t)); + + _init_cmd_buff (ctx); + break; + } +} void _update_descriptor_set (VkvgContext ctx, VkhImage img, VkDescriptorSet ds){ VkDescriptorImageInfo descSrcTex = vkh_image_get_descriptor (img, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); VkWriteDescriptorSet writeDescriptorSet = { diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index bc799b6..6901cc5 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -53,7 +53,6 @@ typedef struct { typedef struct _vkvg_context_save_t{ struct _vkvg_context_save_t* pNext; - VkhImage source; VkhImage stencilMS; uint32_t stencilRef; vec2* points; //points array @@ -74,6 +73,7 @@ typedef struct _vkvg_context_save_t{ _vkvg_font_t* currentFont; //font ready for lookup vkvg_direction_t textDirection; push_constants pushConsts; + VkvgPattern pattern; }vkvg_context_save_t; @@ -129,6 +129,7 @@ typedef struct _vkvg_context_t { vkvg_direction_t textDirection; push_constants pushConsts; + VkvgPattern pattern; vkvg_context_save_t* pSavedCtxs;//last ctx saved ptr }vkvg_context; @@ -165,6 +166,7 @@ void _submit_wait_and_reset_cmd(VkvgContext ctx); void _submit_ctx_cmd (VkvgContext ctx); void _wait_and_reset_ctx_cmd(VkvgContext ctx); void _update_push_constants (VkvgContext ctx); +void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat); void _set_mat_inv_and_vkCmdPush (VkvgContext ctx); void _createDescriptorPool (VkvgContext ctx); diff --git a/src/vkvg_device_internal.c b/src/vkvg_device_internal.c index 2e6dd23..e570fd4 100644 --- a/src/vkvg_device_internal.c +++ b/src/vkvg_device_internal.c @@ -49,14 +49,14 @@ void _setupRenderPass(VkvgDevice dev) .format = FB_COLOR_FORMAT, .samples = VKVG_SAMPLES, .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, - .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; VkAttachmentDescription attColorResolve = { .format = FB_COLOR_FORMAT, .samples = VK_SAMPLE_COUNT_1_BIT, - .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, .storeOp = VK_ATTACHMENT_STORE_OP_STORE, .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, @@ -65,8 +65,8 @@ void _setupRenderPass(VkvgDevice dev) VkAttachmentDescription attDS = { .format = VK_FORMAT_S8_UINT, .samples = VKVG_SAMPLES, - .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; diff --git a/src/vkvg_pattern.c b/src/vkvg_pattern.c index 38ab3d1..c242085 100644 --- a/src/vkvg_pattern.c +++ b/src/vkvg_pattern.c @@ -28,18 +28,36 @@ VkvgPattern vkvg_pattern_create(){ VkvgPattern pat = (vkvg_pattern_t*)calloc(1, sizeof(vkvg_pattern_t)); pat->type = VKVG_PATTERN_TYPE_SOLID; + pat->extend = VKVG_EXTEND_NONE; pat->data = (vkvg_color_t*)calloc(1,sizeof(vkvg_color_t)); return pat; } - +VkvgPattern vkvg_pattern_create_rgba (float r, float g, float b, float a){ + VkvgPattern pat = (vkvg_pattern_t*)calloc(1, sizeof(vkvg_pattern_t)); + pat->type = VKVG_PATTERN_TYPE_SOLID; + pat->extend = VKVG_EXTEND_NONE; + vkvg_color_t* c = (vkvg_color_t*)calloc(1,sizeof(vkvg_color_t)); + c->r = r; + c->g = g; + c->b = b; + c->a = a; + pat->data = c; + return pat; +} +VkvgPattern vkvg_pattern_create_rgb (float r, float g, float b){ + return vkvg_pattern_create_rgba (r,g,b,1.f); +} VkvgPattern vkvg_pattern_create_for_surface (VkvgSurface surf){ VkvgPattern pat = (vkvg_pattern_t*)calloc(1, sizeof(vkvg_pattern_t)); + pat->type = VKVG_PATTERN_TYPE_SURFACE; + pat->extend = VKVG_EXTEND_NONE; pat->data = surf; return pat; } VkvgPattern vkvg_pattern_create_linear (float x0, float y0, float x1, float y1){ VkvgPattern pat = (vkvg_pattern_t*)calloc(1, sizeof(vkvg_pattern_t)); pat->type = VKVG_PATTERN_TYPE_LINEAR; + pat->extend = VKVG_EXTEND_PAD; vkvg_gradient_t* grad = (vkvg_gradient_t*)calloc(1,sizeof(vkvg_gradient_t)); vec4 cp0 = {x0, y0}, cp1 = {x1, y1}; @@ -78,6 +96,16 @@ void vkvg_patter_add_color_stop (VkvgPattern pat, float offset, float r, float g void vkvg_pattern_set_extend (VkvgPattern pat, vkvg_extend_t extend){ pat->extend = extend; } +void vkvg_pattern_set_filter (VkvgPattern pat, vkvg_filter_t filter){ + pat->filter = filter; +} + +vkvg_extend_t vkvg_pattern_get_extend (VkvgPattern pat){ + return pat->extend; +} +vkvg_filter_t vkvg_pattern_get_filter (VkvgPattern pat){ + return pat->filter; +} void vkvg_pattern_destroy(VkvgPattern pat) { diff --git a/src/vkvg_pattern.h b/src/vkvg_pattern.h index b4977db..4211915 100644 --- a/src/vkvg_pattern.h +++ b/src/vkvg_pattern.h @@ -27,8 +27,9 @@ #include "vkh.h" typedef struct _vkvg_pattern_t { - vkvg_extend_t extend; vkvg_pattern_type_t type; + vkvg_extend_t extend; + vkvg_filter_t filter; void* data; }vkvg_pattern_t; diff --git a/tests/test1.c b/tests/test1.c index a6b1f5a..ef30b3d 100644 --- a/tests/test1.c +++ b/tests/test1.c @@ -493,7 +493,7 @@ void multi_test1 () { vkvg_test_stroke(ctx); -// vkvg_translate(ctx, 10,10); + vkvg_translate(ctx, 100,50); // vkvg_rotate(ctx, 0.2); //vkvg_scale(ctx, 2,2); @@ -514,16 +514,23 @@ void multi_test1 () { vkvg_destroy(ctx); ctx = vkvg_create(surf); - vkvg_set_source_rgba(ctx,0.0,1.0,0.0,1); + vkvg_set_source_rgba(ctx,1.0,0.0,0.0,1); vkvg_paint(ctx); // vkvg_set_source_rgba(ctx,0.0,0.0,1.0,1); // vkvg_rectangle(ctx,100,100,500,500); // vkvg_fill(ctx); - vkvg_set_source_surface(ctx, surf2, 0, 0); + VkvgPattern pat = vkvg_pattern_create_for_surface(surf2); + vkvg_pattern_set_extend(pat, VKVG_EXTEND_NONE); + vkvg_pattern_set_filter(pat, VKVG_FILTER_BILINEAR); + vkvg_set_source (ctx, pat); //vkvg_rectangle(ctx,100,100,400,400); //vkvg_fill(ctx); vkvg_paint(ctx); + vkvg_translate(ctx,200,200); + vkvg_paint(ctx); + vkvg_rotate(ctx,0.7); + vkvg_paint(ctx); vkvg_destroy(ctx); vkvg_surface_destroy(surf2); -- 2.47.3