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,
//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);
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
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;
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;
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,
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);
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 = {
typedef struct _vkvg_context_save_t{
struct _vkvg_context_save_t* pNext;
- VkhImage source;
VkhImage stencilMS;
uint32_t stencilRef;
vec2* points; //points array
_vkvg_font_t* currentFont; //font ready for lookup
vkvg_direction_t textDirection;
push_constants pushConsts;
+ VkvgPattern pattern;
}vkvg_context_save_t;
vkvg_direction_t textDirection;
push_constants pushConsts;
+ VkvgPattern pattern;
vkvg_context_save_t* pSavedCtxs;//last ctx saved ptr
}vkvg_context;
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);
.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,
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 };
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};
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)
{
#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;
vkvg_test_stroke(ctx);
-// vkvg_translate(ctx, 10,10);
+ vkvg_translate(ctx, 100,50);
// vkvg_rotate(ctx, 0.2);
//vkvg_scale(ctx, 2,2);
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);