#define LOG
#endif
+typedef enum _vkvg_status {
+ VKVG_STATUS_SUCCESS,
+ VKVG_STATUS_NO_MEMORY
+}vkvg_status_t;
+
typedef enum _vkvg_direction {
VKVG_HORIZONTAL = 0,
VKVG_VERTICAL = 1
unsigned char vkvg_main_frag_spv[] = {
- 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x0d, 0x00,
+ 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x0d, 0x00,
0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30,
};
unsigned int vkvg_main_frag_spv_len = 5780;
unsigned char wired_frag_spv[] = {
- 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x0d, 0x00,
+ 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x0d, 0x00,
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30,
};
unsigned int wired_frag_spv_len = 1120;
unsigned char vkvg_main_vert_spv[] = {
- 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x0d, 0x00,
+ 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x0d, 0x00,
0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30,
};
unsigned int vkvg_main_vert_spv_len = 2680;
unsigned char shader_comp_spv[] = {
- 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x0d, 0x00,
+ 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x0d, 0x00,
0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30,
};
unsigned int shader_comp_spv_len = 3580;
unsigned char shader2_comp_spv[] = {
- 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x0d, 0x00,
+ 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x0d, 0x00,
0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30,
VkvgDevice dev = surf->dev;
VkvgContext ctx = (vkvg_context*)calloc(1, sizeof(vkvg_context));
+ if (ctx==NULL)
+ return NULL;
+
ctx->sizePoints = VKVG_PTS_SIZE;
ctx->sizeVertices = VKVG_VBO_SIZE;
ctx->sizeIndices = VKVG_IBO_SIZE;
{
VkvgSurface surf = (VkvgSurface)pat->data;
- //flush ctx in two steps to add the src transition in the cmd buff
- if (ctx->cmdStarted)//transition of img without appropriate dep in subpass must be done outside renderpass.
+ //flush ctx in two steps to add the src transitioning in the cmd buff
+ if (ctx->cmdStarted)//transition of img without appropriate dependencies 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);
typedef struct _vkvg_context_t {
VkvgContext pPrev; //double linked list of contexts
VkvgContext pNext;
- uint32_t references;
+ uint32_t references; //reference count
- VkvgSurface pSurf;
- VkFence flushFence;
+ VkvgSurface pSurf; //surface bound to context, set on creation of ctx
+ VkFence flushFence; //context fence
VkhImage source; //source of painting operation
- VkCommandPool cmdPool;//local pools ensure thread safety
- VkCommandBuffer cmd; //single cmd buff for context operations
- bool cmdStarted;//prevent flushing empty renderpass
+ 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
- VkDescriptorSet dsGrad; //gradient uniform buffer
+ VkDescriptorPool descriptorPool;//one pool per thread
+ VkDescriptorSet dsFont; //fonts glyphs texture atlas descriptor (local for thread safety)
+ VkDescriptorSet dsSrc; //source ds
+ VkDescriptorSet dsGrad; //gradient uniform buffer
- vkvg_buff uboGrad;//uniform buff obj holdings gradient infos
+ vkvg_buff uboGrad; //uniform buff obj holdings gradient infos
//vk buffers, holds data until flush
vkvg_buff indices; //index buffer with persistent map memory
size_t sizeIndices; //reserved size
uint32_t indCount; //current indice count
- uint32_t curIndStart;
+ uint32_t curIndStart; //last index recorded in cmd buff
vkvg_buff vertices; //vertex buffer with persistent mapped memory
size_t sizeVertices; //reserved size
uint32_t vertCount; //effective vertices count
//pathes, exists until stroke of fill
- vec2* points; //points array
- size_t sizePoints; //reserved size
- uint32_t pointCount; //effective points count
+ vec2* points; //points array
+ size_t sizePoints; //reserved size
+ uint32_t pointCount; //effective points count
uint32_t pathPtr;
//pathes array is a list of couple (start,end) point idx refering to point array
push_constants pushConsts;
VkvgPattern pattern;
+ vkvg_status_t status;
vkvg_context_save_t* pSavedCtxs;//last ctx saved ptr
VkPipelineColorBlendAttachmentState blendAttachmentState =
{ .colorWriteMask = 0x0, .blendEnable = VK_TRUE,
.srcColorBlendFactor = VK_BLEND_FACTOR_ONE,
- .dstColorBlendFactor= VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
- .colorBlendOp = VK_BLEND_OP_ADD,
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
+ .dstColorBlendFactor= VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
+ .colorBlendOp = VK_BLEND_OP_ADD,
.alphaBlendOp = VK_BLEND_OP_ADD,
};
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;
+ //premultiplied alpha
+ c->r = r * a;
+ c->g = g * a;
+ c->b = b * a;
+ c->a = a;// > 0.f ? 1.f : 0.f;
pat->data = c;
pat->references = 1;
};
vkCmdBlitImage (cmd,
vkh_image_get_vkimage (surf->img), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
- vkh_image_get_vkimage (stagImg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_LINEAR);
+ vkh_image_get_vkimage (stagImg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_NEAREST);
vkh_cmd_end (cmd);
vkh_cmd_submit (dev->gQueue, &cmd, dev->fence);
* THE SOFTWARE.
*/
#include "vkengine.h"
-
+#include "stdio.h"
+#include "stdlib.h"
+#include "time.h"
#include "vkvg.h"
#include "string.h" //for nanosvg
static void mouse_move_callback(GLFWwindow* window, double x, double y){}
static void mouse_button_callback(GLFWwindow* window, int but, int state, int modif){}
+double time_diff(struct timeval x , struct timeval y)
+{
+ double x_ms , y_ms , diff;
+
+ x_ms = (double)x.tv_sec*1000000 + (double)x.tv_usec;
+ y_ms = (double)y.tv_sec*1000000 + (double)y.tv_usec;
+
+ diff = (double)y_ms - (double)x_ms;
+
+ return diff;
+}
+
+void randomize_color (VkvgContext ctx) {
+ vkvg_set_source_rgba(ctx,
+ (float)rand()/RAND_MAX,
+ (float)rand()/RAND_MAX,
+ (float)rand()/RAND_MAX,
+ (float)rand()/RAND_MAX
+ );
+}
void vkvg_test_gradient (VkvgContext ctx) {
VkvgPattern pat = vkvg_pattern_create_linear(100,0,300,0);
vkvg_set_line_width(ctx, 20);
vkvg_paint(ctx);
vkvg_set_matrix(ctx,&mat);
- /*
- vkvg_set_source_rgba(ctx,0,1,0,1);
- vkvg_rectangle(ctx,0,0,600,600);
- vkvg_fill(ctx);
-
- vkvg_clip(ctx);
-
- vkvg_set_source_rgba(ctx,1,0,0,1);
- vkvg_paint(ctx);
- //vkvg_rectangle(ctx,00,00,1024,800);
- //vkvg_fill(ctx);
-
- vkvg_reset_clip(ctx);
- vkvg_set_source_rgba(ctx,0,0,1,1);
- vkvg_set_line_width(ctx,20);
- vkvg_move_to(ctx,0,0);
- vkvg_rel_line_to(ctx,800,800);
- vkvg_stroke(ctx);*/
-
-// cairo_test_clip(ctx);
-// vkvg_reset_clip(ctx);
- //test_img_surface (ctx);
cairo_print_arc(ctx);
vkvg_translate(ctx,250,0);
cairo_test_rounded_rect(ctx);
-
-/*
- vkvg_set_operator(ctx, VKVG_OPERATOR_CLEAR);
- vkvg_rectangle(ctx,100,100,500,500);
- vkvg_fill(ctx);
- vkvg_set_operator(ctx, VKVG_OPERATOR_OVER);
-*/
-
-
vkvg_translate(ctx,-450,250);
cairo_test_fill_and_stroke2(ctx);
vkvg_paint(ctx);
vkvg_destroy(ctx);
}
+void random_rectangles () {
+ vkvg_surface_clear(surf);
+ struct timeval currentTime;
+ gettimeofday(¤tTime, NULL);
+
+ srand((unsigned) currentTime.tv_usec);
+ const float w = 1024.f;
+
+ VkvgContext ctx = vkvg_create(surf);
+ vkvg_set_line_width(ctx,1);
+ for (int i=0; i<5000; i++) {
+ randomize_color(ctx);
+ float x = trunc( (0.5*(float)w*rand())/RAND_MAX );
+ float y = trunc( (0.5*(float)w*rand())/RAND_MAX );
+ float z = trunc( (0.5*(float)w*rand())/RAND_MAX ) + 1;
+ float v = trunc( (0.5*(float)w*rand())/RAND_MAX ) + 1;
+
+ vkvg_rectangle(ctx, x+1, y+1, z, v);
+ vkvg_fill_preserve(ctx);
+ randomize_color(ctx);
+ vkvg_stroke(ctx);
+ }
+ vkvg_destroy(ctx);
+}
+
void simple_rectangle_fill () {
vkvg_surface_clear(surf);
VkvgContext ctx = vkvg_create(surf);
+
vkvg_set_line_width(ctx,10);
- vkvg_set_source_rgba(ctx,0,0,1,0.2);
+ vkvg_set_source_rgba(ctx,0,0,1,0.5);
vkvg_rectangle(ctx,100,100,200,200);
- vkvg_fill_preserve(ctx);
- vkvg_set_source_rgba(ctx,1,0,0,0.2);
- vkvg_stroke(ctx);
+ vkvg_fill(ctx);
+ vkvg_rectangle(ctx,200,200,200,200);
+ vkvg_set_source_rgba(ctx,1,0,0,0.5);
+ vkvg_fill(ctx);
vkvg_destroy(ctx);
}
void simple_rectangle_stroke () {
vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height);
+ struct timeval before , after;
+ double frameTime = 0, frameTimeAccum = 0, frameCount = 0;
+
while (!vkengine_should_close (e)) {
glfwPollEvents();
+
+ gettimeofday(&before , NULL);
+
cairo_tests();
+ //random_rectangles();
+ //simple_rectangle_stroke();
//test_1();
//vkvg_surface_clear(surf);
//simple_paint();
//lines_stroke();
if (!vkh_presenter_draw (r))
vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height);
+
+ gettimeofday(&after , NULL);
+
+ frameTimeAccum += time_diff(before , after);
+ frameCount++;
}
+ frameTime = frameTimeAccum / frameCount;
+ printf ("frame (µs): %.0lf\nfps: %lf\n", frameTime, floor(1000000 / frameTime));
+
vkDeviceWaitIdle(e->dev->dev);
vkvg_surface_destroy (surf);
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
glfwWindowHint(GLFW_FLOATING, GLFW_FALSE);
- glfwWindowHint(GLFW_DECORATED, GLFW_FALSE);
+ glfwWindowHint(GLFW_DECORATED, GLFW_TRUE);
e->window = glfwCreateWindow (width, height, "Window Title", NULL, NULL);
VkSurfaceKHR surf;
e->dev = vkh_device_create(pi->phy, dev);
e->renderer = vkh_presenter_create
- (e->dev, pi->pQueue, surf, width, height, VK_FORMAT_B8G8R8A8_UNORM, VK_PRESENT_MODE_FIFO_KHR);
+ (e->dev, pi->pQueue, surf, width, height, VK_FORMAT_B8G8R8A8_UNORM, VK_PRESENT_MODE_MAILBOX_KHR);
vkh_app_free_phyinfos (phyCount, phys);