]> O.S.I.I.S - jp/vkvg.git/commitdiff
dyn sizing of vbo and ibo buffers
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Thu, 5 Sep 2019 22:57:50 +0000 (00:57 +0200)
committerj-p <jp_bruyere@hotmail.com>
Thu, 5 Sep 2019 22:59:25 +0000 (00:59 +0200)
13 files changed:
include/vkvg.h
src/vkvg_context.c
src/vkvg_context_internal.c
src/vkvg_context_internal.h
tests/common/test.c
tests/common/test.h
tests/hlines.c
tests/lines.c
tests/multilines.c
tests/random_cirles.c
tests/random_rects.c
tests/svg.c
tests/vlines.c

index 5cfdff052852b58f547546e8b4a9d657daf8f985..c637625143dc36143866c8eddd8b65c4cddafe1c 100644 (file)
@@ -40,6 +40,7 @@ extern "C" {
 #define LOG_DEBUG              0x10
 #define LOG_INFO               0x20
 #define LOG_INFO_PATH   0x40
+#define LOG_DBG_ARRAYS  0x80
 #define LOG_FULL               0xff
 
 #ifdef DEBUG
index edb9c19ac23e48367b55d041df3cc2791afdcd8d..7917f6a650f3873af1bf7c57acd82712614ed33d 100644 (file)
@@ -57,8 +57,8 @@ VkvgContext vkvg_create(VkvgSurface surf)
     }
 
     ctx->sizePoints     = VKVG_PTS_SIZE;
-    ctx->sizeVertices   = VKVG_VBO_SIZE;
-    ctx->sizeIndices    = VKVG_IBO_SIZE;
+    ctx->sizeVertices   = ctx->sizeVBO = VKVG_VBO_SIZE;
+    ctx->sizeIndices    = ctx->sizeIBO = VKVG_IBO_SIZE;
     ctx->sizePathes     = VKVG_PATHES_SIZE;
     ctx->lineWidth      = 1;
     ctx->pSurf          = surf;
@@ -121,6 +121,9 @@ VkvgContext vkvg_create(VkvgSurface surf)
     //for context to be thread safe, command pool and descriptor pool have to be created in the thread of the context.
     ctx->cmdPool = vkh_cmd_pool_create ((VkhDevice)dev, dev->gQueue->familyIndex, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
 
+    ctx->vertexCache = (Vertex*)malloc(ctx->sizeVertices * sizeof(Vertex));
+    ctx->indexCache = (VKVG_IBO_INDEX_TYPE*)malloc(ctx->sizeIndices * sizeof(VKVG_IBO_INDEX_TYPE));
+
     _create_vertices_buff   (ctx);
     _create_gradient_buff   (ctx);
     _create_cmd_buff        (ctx);
@@ -136,6 +139,9 @@ VkvgContext vkvg_create(VkvgSurface surf)
 
     ctx->references = 1;
     ctx->status = VKVG_STATUS_SUCCESS;
+
+    LOG(LOG_DBG_ARRAYS, "START\tctx = %lu; pathes:%d pts:%d vch:%d vbo:%d ich:%d ibo:%d\n", ctx, ctx->sizePathes, ctx->sizePoints, ctx->sizeVertices, ctx->sizeVBO, ctx->sizeIndices, ctx->sizeIBO);
+
     return ctx;
 }
 /**
@@ -240,6 +246,8 @@ void vkvg_destroy (VkvgContext ctx)
         ctx->pNext->pPrev = ctx->pPrev;
     }
 
+    LOG(LOG_DBG_ARRAYS, "END\tctx = %lu; pathes:%d pts:%d vch:%d vbo:%d ich:%d ibo:%d\n", ctx, ctx->sizePathes, ctx->sizePoints, ctx->sizeVertices, ctx->sizeVBO, ctx->sizeIndices, ctx->sizeIBO);
+
     free(ctx);
 }
 /**
@@ -502,9 +510,6 @@ void vkvg_clip_preserve (VkvgContext ctx){
 
     LOG(LOG_INFO, "CLIP: ctx = %lu; path cpt = %d;\n", ctx, ctx->pathPtr / 2);
 
-    _check_flush_needed (ctx);
-
-
     if (ctx->curFillRule == VKVG_FILL_RULE_EVEN_ODD){
         _check_cmd_buff_state(ctx);
         _poly_fill (ctx);
@@ -535,7 +540,6 @@ void vkvg_fill_preserve (VkvgContext ctx){
 
     LOG(LOG_INFO, "FILL: ctx = %lu; path cpt = %d;\n", ctx, ctx->pathPtr / 2);
 
-    _check_flush_needed (ctx);
     _check_cmd_buff_state (ctx);
 
     if (ctx->curFillRule == VKVG_FILL_RULE_EVEN_ODD){
@@ -557,8 +561,6 @@ void vkvg_stroke_preserve (VkvgContext ctx)
 
     LOG(LOG_INFO, "STROKE: ctx = %lu; path cpt = %d;\n", ctx, ctx->pathPtr / 2);
 
-    _check_flush_needed (ctx);
-
     Vertex v = {0};
     v.uv.z = -1;
 
index 4be4550293b90a9af2c575e766f72f97db8d22ff..f09f3008830a689fc1a225fbc558652e59a57830 100644 (file)
@@ -179,18 +179,14 @@ void _create_gradient_buff (VkvgContext ctx){
         sizeof(vkvg_gradient_t), &ctx->uboGrad);
 }
 void _create_vertices_buff (VkvgContext ctx){
-
-    ctx->vertexCache = (Vertex*)malloc(ctx->sizeVertices * sizeof(Vertex));
-    ctx->indexCache = (VKVG_IBO_INDEX_TYPE*)malloc(ctx->sizeIndices * sizeof(VKVG_IBO_INDEX_TYPE));
-
     vkvg_buffer_create (ctx->pSurf->dev,
         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
         VMA_MEMORY_USAGE_CPU_TO_GPU,
-        ctx->sizeVertices * sizeof(Vertex), &ctx->vertices);
+        ctx->sizeVBO * sizeof(Vertex), &ctx->vertices);
     vkvg_buffer_create (ctx->pSurf->dev,
         VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
         VMA_MEMORY_USAGE_CPU_TO_GPU,
-        ctx->sizeIndices * sizeof(VKVG_IBO_INDEX_TYPE), &ctx->indices);
+        ctx->sizeIBO * sizeof(VKVG_IBO_INDEX_TYPE), &ctx->indices);
 }
 const vec3 blankuv = {};
 void _add_vertexf (VkvgContext ctx, float x, float y){
@@ -199,15 +195,19 @@ void _add_vertexf (VkvgContext ctx, float x, float y){
     pVert->pos.y = y;
     pVert->uv = blankuv;
     ctx->vertCount++;
+
+    _check_vbo_size(ctx);
 }
 void _add_vertex(VkvgContext ctx, Vertex v){
     ctx->vertexCache[ctx->vertCount] = v;
     ctx->vertCount++;
+
+    _check_vbo_size(ctx);
 }
 void _set_vertex(VkvgContext ctx, uint32_t idx, Vertex v){
     ctx->vertexCache[idx] = v;
 }
-void _add_tri_indices_for_rect (VkvgContext ctx, uint32_t i){
+void _add_tri_indices_for_rect (VkvgContext ctx, VKVG_IBO_INDEX_TYPE i){
     VKVG_IBO_INDEX_TYPE* inds = &ctx->indexCache[ctx->indCount];
     inds[0] = i;
     inds[1] = i+2;
@@ -216,13 +216,17 @@ void _add_tri_indices_for_rect (VkvgContext ctx, uint32_t i){
     inds[4] = i+2;
     inds[5] = i+3;
     ctx->indCount+=6;
+
+    _check_ibo_size(ctx);
 }
-void _add_triangle_indices(VkvgContext ctx, uint32_t i0, uint32_t i1, uint32_t i2){
+void _add_triangle_indices(VkvgContext ctx, VKVG_IBO_INDEX_TYPE i0, VKVG_IBO_INDEX_TYPE i1, VKVG_IBO_INDEX_TYPE i2){
     VKVG_IBO_INDEX_TYPE* inds = &ctx->indexCache[ctx->indCount];
     inds[0] = i0;
     inds[1] = i1;
     inds[2] = i2;
     ctx->indCount+=3;
+
+    _check_ibo_size(ctx);
 }
 void _vao_add_rectangle (VkvgContext ctx, float x, float y, float width, float height){
     Vertex v[4] =
@@ -232,10 +236,13 @@ void _vao_add_rectangle (VkvgContext ctx, float x, float y, float width, float h
         {{x+width,y},       {0,0,-1}},
         {{x+width,y+height},{0,0,-1}}
     };
-    uint32_t firstIdx = ctx->vertCount;
+    VKVG_IBO_INDEX_TYPE firstIdx = ctx->vertCount;
     Vertex* pVert = &ctx->vertexCache[ctx->vertCount];
     memcpy (pVert,v,4*sizeof(Vertex));
     ctx->vertCount+=4;
+
+    _check_vbo_size(ctx);
+
     _add_tri_indices_for_rect(ctx, firstIdx);
 }
 
@@ -251,22 +258,6 @@ void _create_cmd_buff (VkvgContext ctx){
     vkh_device_set_object_name((VkhDevice)ctx->pSurf->dev, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)ctx->cmd, "vkvgCtxCmd");
 #endif
 }
-void _record_draw_cmd (VkvgContext ctx){
-    if (ctx->indCount == ctx->curIndStart)
-        return;
-    LOG(LOG_INFO, "RECORD DRAW CMD: ctx = %lu; vertices = %d; indices = %d\n", (ulong)ctx, ctx->vertCount - ctx->indexCache[ctx->curIndStart], ctx->indCount - ctx->curIndStart);
-    _check_cmd_buff_state(ctx);
-    CmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, (int32_t)ctx->curVertOffset, 0);
-
-#ifdef VKVG_WIRED_DEBUG
-    CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineWired);
-    CmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, 0, 1);
-    CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_OVER);
-#endif
-
-    ctx->curIndStart = ctx->indCount;
-    ctx->curVertOffset = ctx->vertCount;
-}
 void _clear_attachment (VkvgContext ctx) {
 
 }
@@ -315,13 +306,25 @@ void _wait_and_submit_cmd (VkvgContext ctx){
                           VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ,
                           VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
 }*/
-//this func expect cmdStarted to be true, so that vert and ind count are > 0
-void _end_render_pass (VkvgContext ctx) {
-    _record_draw_cmd        (ctx);
-    LOG(LOG_INFO, "END RENDER PASS: ctx = %lu;\n", ctx);
-    CmdEndRenderPass      (ctx->cmd);
-    ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass;
 
+//pre flush vertices because of vbo or ibo too small, all vertices except last draw call are flushed
+//this function expects a vertex offset > 0
+void _flush_vertices_caches_until_vertex_base (VkvgContext ctx) {
+    _wait_flush_fence (ctx);
+
+    memcpy(ctx->vertices.allocInfo.pMappedData, ctx->vertexCache, ctx->curVertOffset * sizeof (Vertex));
+    memcpy(ctx->indices.allocInfo.pMappedData, ctx->indexCache, ctx->curIndStart * sizeof (VKVG_IBO_INDEX_TYPE));
+
+    //copy remaining vertices and indices to caches starts
+    ctx->vertCount -= ctx->curVertOffset;
+    ctx->indCount -= ctx->curIndStart;
+    memcpy(ctx->vertexCache, &ctx->vertexCache[ctx->curVertOffset], ctx->vertCount * sizeof (Vertex));
+    memcpy(ctx->indexCache, &ctx->indexCache[ctx->curIndStart], ctx->indCount * sizeof (VKVG_IBO_INDEX_TYPE));
+
+    ctx->curVertOffset = 0;
+    ctx->curIndStart = 0;
+}
+void _flush_vertices_caches (VkvgContext ctx) {
     //copy vertex and index caches to the vbo and ibo vkbuffers
     _wait_flush_fence (ctx);
 
@@ -330,12 +333,59 @@ void _end_render_pass (VkvgContext ctx) {
 
     ctx->vertCount = ctx->indCount = ctx->curIndStart = ctx->curVertOffset = 0;
 }
+//this func expect cmdStarted to be true
+void _end_render_pass (VkvgContext ctx) {
+    LOG(LOG_INFO, "END RENDER PASS: ctx = %lu;\n", ctx);
+    CmdEndRenderPass      (ctx->cmd);
+    ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass;
+}
+void _record_draw_cmd (VkvgContext ctx){
+    if (ctx->indCount == ctx->curIndStart)
+        return;
+
+    if (ctx->vertCount > ctx->sizeVBO || ctx->indCount > ctx->sizeIBO){
+        //vbo or ibo buffers too small
+        if (ctx->cmdStarted) {
+            //if cmd is started buffers, are already bound, so no resize is possible
+            //instead we flush, and clear vbo and ibo caches
+            _end_render_pass (ctx);
+            _flush_vertices_caches_until_vertex_base (ctx);
+            vkh_cmd_end (ctx->cmd);
+            _wait_and_submit_cmd (ctx);
+            //we could resize here
+        }else{
+            //should resize vbo here
+            _wait_flush_fence (ctx);
+            ctx->sizeVBO = ctx->sizeVertices;
+            ctx->sizeIBO = ctx->sizeIndices;
+            vkvg_buffer_destroy (&ctx->indices);
+            vkvg_buffer_destroy (&ctx->vertices);
+            _create_vertices_buff (ctx);
+        }
+    }
+
+    _check_cmd_buff_state(ctx);
+    CmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, (int32_t)ctx->curVertOffset, 0);
+
+    LOG(LOG_INFO, "RECORD DRAW CMD: ctx = %lu; vertices = %d; indices = %d\n", (ulong)ctx, ctx->vertCount - ctx->indexCache[ctx->curIndStart], ctx->indCount - ctx->curIndStart);
+
+#ifdef VKVG_WIRED_DEBUG
+    CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineWired);
+    CmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, (int32_t)ctx->curVertOffset, 0);
+    CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_OVER);
+#endif
+
+    ctx->curIndStart = ctx->indCount;
+    ctx->curVertOffset = ctx->vertCount;
+}
 void _flush_cmd_buff (VkvgContext ctx){
     if (!ctx->cmdStarted)
         return;
 
-    _end_render_pass  (ctx);
-    vkh_cmd_end       (ctx->cmd);
+    _record_draw_cmd        (ctx);
+    _end_render_pass        (ctx);
+    _flush_vertices_caches  (ctx);
+    vkh_cmd_end             (ctx->cmd);
 
     LOG(LOG_INFO, "FLUSH CTX: ctx = %lu; vertices = %d; indices = %d\n", ctx, ctx->vertCount, ctx->indCount);
     _wait_and_submit_cmd(ctx);
@@ -434,9 +484,11 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) {
         VkvgSurface surf = (VkvgSurface)pat->data;
 
         //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.
+        if (ctx->cmdStarted){//transition of img without appropriate dependencies in subpass must be done outside renderpass.
+            _record_draw_cmd (ctx);//ensure all vertices are flushed
             _end_render_pass (ctx);
-        else {
+            _flush_vertices_caches (ctx);
+        }else {
             vkh_cmd_begin (ctx->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
             ctx->cmdStarted = true;
         }
@@ -903,10 +955,30 @@ void _recursive_bezier (VkvgContext ctx,
     _recursive_bezier (ctx, x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1);
 }
 void _poly_fill (VkvgContext ctx){
+    //we anticipate the check for vbo buffer size
+    if (ctx->vertCount + ctx->pointCount > ctx->sizeVBO) {
+        if (ctx->cmdStarted) {
+            _end_render_pass        (ctx);
+            _flush_vertices_caches  (ctx);
+            vkh_cmd_end             (ctx->cmd);
+            _wait_and_submit_cmd    (ctx);
+            //we could resize here after a wait fence
+        }else{
+            _wait_flush_fence (ctx);//wait previous cmd if not completed
+            ctx->sizeVBO = ctx->vertCount + ctx->pointCount;
+            vkvg_buffer_destroy (&ctx->vertices);
+            vkvg_buffer_create (ctx->pSurf->dev,
+                VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
+                VMA_MEMORY_USAGE_CPU_TO_GPU,
+                ctx->sizeVBO * sizeof(Vertex), &ctx->vertices);
+        }
+        _start_cmd_for_render_pass(ctx);
+    }
+
     CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelinePolyFill);
 
     uint32_t ptrPath = 0;
-    Vertex v = {};
+    Vertex v = {0};
     v.uv.z = -1;
 
     while (ptrPath < ctx->pathPtr){
@@ -920,7 +992,8 @@ void _poly_fill (VkvgContext ctx){
         uint32_t firstPtIdx = ctx->pathes [ptrPath] & PATH_ELT_MASK;
         uint32_t lastPtIdx  = ctx->pathes [ptrPath+1] & PATH_ELT_MASK;//_get_last_point_of_closed_path (ctx, ptrPath);
         uint32_t pathPointCount = lastPtIdx - firstPtIdx + 1;
-        uint32_t firstVertIdx = ctx->vertCount;
+
+        VKVG_IBO_INDEX_TYPE firstVertIdx = ctx->vertCount;
 
         for (uint i = 0; i < pathPointCount; i++) {
             v.pos = ctx->points [i+firstPtIdx];
@@ -932,6 +1005,7 @@ void _poly_fill (VkvgContext ctx){
 
         ptrPath+=2;
     }
+    ctx->curVertOffset = ctx->vertCount;
 }
 void _fill_ec (VkvgContext ctx){
     uint32_t ptrPath = 0;;
index 622cbe81cf93c42caeddbe86e7651dd49a198728..d69f94474d5ef69b80b870615424ac8559bf849c 100644 (file)
 #include "vkh.h"
 #include "vkvg_fonts.h"
 
-#define VKVG_PTS_SIZE                          4096
-#define VKVG_VBO_SIZE                          VKVG_PTS_SIZE * 8
+#define VKVG_PTS_SIZE                          256
+#define VKVG_VBO_SIZE                          VKVG_PTS_SIZE * 4
 #define VKVG_IBO_SIZE                          VKVG_VBO_SIZE * 6
 #define VKVG_PATHES_SIZE                       16
-#define VKVG_ARRAY_THRESHOLD           4
+#define VKVG_ARRAY_THRESHOLD           8
 #define VKVG_IBO_INDEX_TYPE         uint16_t
 
 typedef struct{
@@ -97,15 +97,17 @@ typedef struct _vkvg_context_t {
 
     //vk buffers, holds data until flush
     vkvg_buff  indices;        //index buffer with persistent map memory
+    size_t             sizeIBO;        //size of vk ibo size
     size_t             sizeIndices;    //reserved size
-    uint32_t   indCount;       //current indice count
+    VKVG_IBO_INDEX_TYPE        indCount;       //current indice count
 
-    uint32_t   curIndStart;    //last index recorded in cmd buff
-    uint32_t    curVertOffset;  //vertex offset in draw indexed command
+    VKVG_IBO_INDEX_TYPE        curIndStart;    //last index recorded in cmd buff
+    VKVG_IBO_INDEX_TYPE curVertOffset;  //vertex offset in draw indexed command
 
     vkvg_buff  vertices;       //vertex buffer with persistent mapped memory
+    size_t      sizeVBO;        //size of vk vbo size
     size_t             sizeVertices;   //reserved size
-    uint32_t   vertCount;      //effective vertices count
+    VKVG_IBO_INDEX_TYPE        vertCount;      //effective vertices count
 
     Vertex* vertexCache;
     VKVG_IBO_INDEX_TYPE* indexCache;
@@ -188,8 +190,8 @@ void _create_vertices_buff  (VkvgContext ctx);
 void _add_vertex                       (VkvgContext ctx, Vertex v);
 void _add_vertexf           (VkvgContext ctx, float x, float y);
 void _set_vertex                       (VkvgContext ctx, uint32_t idx, Vertex v);
-void _add_triangle_indices     (VkvgContext ctx, uint32_t i0, uint32_t i1,uint32_t i2);
-void _add_tri_indices_for_rect (VkvgContext ctx, uint32_t i);
+void _add_triangle_indices     (VkvgContext ctx, VKVG_IBO_INDEX_TYPE i0, VKVG_IBO_INDEX_TYPE i1, VKVG_IBO_INDEX_TYPE i2);
+void _add_tri_indices_for_rect (VkvgContext ctx, VKVG_IBO_INDEX_TYPE i);
 void _build_vb_step         (vkvg_context* ctx, Vertex v, float hw, uint32_t iL, uint32_t i, uint32_t iR, bool isCurve);
 void _vao_add_rectangle     (VkvgContext ctx, float x, float y, float width, float height);
 
index 5b662e6874053f80cceb9d7f7e3d5171493d5c2f..362ff31ef0c1ec863669f80d6c073f82c24d33b1 100644 (file)
@@ -10,15 +10,19 @@ bool mouseDown = false;
 VkvgDevice device = NULL;
 VkvgSurface surf = NULL;
 
-uint iterations = 1000;  // items drawn in one run, or complexity
-uint runs       = 10;   // repeat test n times
+uint test_size = 250;  // items drawn in one run, or complexity
+int iterations       = 100;   // repeat test n times
 
+static bool paused = false;
 static vk_engine_t* e;
 
 static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
     if (action != GLFW_PRESS)
         return;
     switch (key) {
+    case GLFW_KEY_SPACE:
+         paused = !paused;
+        break;
     case GLFW_KEY_ESCAPE :
         glfwSetWindowShouldClose(window, GLFW_TRUE);
         break;
@@ -68,6 +72,42 @@ void randomize_color (VkvgContext ctx) {
         0.5f//0.8f*rand()/RAND_MAX + 0.2f
     );
 }
+/* from caskbench */
+double
+get_tick (void)
+{
+    struct timeval now;
+    gettimeofday (&now, NULL);
+    return (double)now.tv_sec + (double)now.tv_usec / 1000000.0;
+}
+double median_run_time (double data[], int n)
+{
+    double temp;
+    int i, j;
+    for (i = 0; i < n; i++)
+        for (j = i+1; j < n; j++)
+        {
+            if (data[i] > data[j])
+            {
+                temp = data[j];
+                data[j] = data[i];
+                data[i] = temp;
+            }
+        }
+    if (n % 2 == 0)
+        return (data[n/2] + data[n/2-1])/2;
+    else
+        return data[n/2];
+}
+double standard_deviation (const double data[], int n, double mean)
+{
+    double sum_deviation = 0.0;
+    int i;
+    for (i = 0; i < n; ++i)
+    sum_deviation += (data[i]-mean) * (data[i]-mean);
+    return sqrt (sum_deviation / n);
+}
+/***************/
 
 void init_test (uint width, uint height){
     e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_MAILBOX_KHR, width, height);
@@ -91,15 +131,18 @@ void run_test_func (void(*testfunc)(void),uint width, uint height) {
     bool deferredResolve = false;
     VkhPresenter r = e->renderer;
 
-    struct timeval before , after;
-    double frameTime = 0, frameTimeAccum = 0, frameCount = 0;
+    double start_time, stop_time, run_time, run_total, min_run_time = -1, max_run_time;
+    double run_time_values[iterations];
+
+    int i = 0;
 
-    while (!vkengine_should_close (e)) {
+    while (!vkengine_should_close (e) && i < iterations) {
         glfwPollEvents();
 
-        gettimeofday(&before , NULL);
+        start_time = get_tick();
 
-        testfunc();
+        if (!paused)
+            testfunc();
 
         if (deferredResolve)
             vkvg_multisample_surface_resolve(surf);
@@ -108,14 +151,26 @@ void run_test_func (void(*testfunc)(void),uint width, uint height) {
 
         vkDeviceWaitIdle(e->dev->dev);
 
-        gettimeofday(&after , NULL);
-
-        frameTimeAccum += time_diff(before , after);
-        frameCount++;
+        stop_time = get_tick();
+        run_time = stop_time - start_time;
+        run_time_values[i] = run_time;
+
+        if (min_run_time < 0)
+            min_run_time = run_time;
+        else
+            min_run_time = MIN(run_time, min_run_time);
+        max_run_time = MAX(run_time, max_run_time);
+        run_total += run_time;
+        i++;
     }
 
-    frameTime = frameTimeAccum / frameCount;
-    printf ("frame (µs): %.0lf\nfps: %lf\n", frameTime, floor(1000000 / frameTime));
+    double avg_run_time = run_total / (double)iterations;
+    double med_run_time = median_run_time (run_time_values, iterations);
+    double standard_dev = standard_deviation (run_time_values, iterations, avg_run_time);
+    double avg_frames_per_second = (1.0 / avg_run_time);
+    avg_frames_per_second = (avg_frames_per_second<9999) ? avg_frames_per_second:9999;
+
+    printf ("size:%d iter:%d  avgFps: %f avg: %4.2f%% med: %4.2f%% sd: %4.2f%% \n", test_size, iterations, avg_frames_per_second, avg_run_time, med_run_time, standard_dev);
 
 }
 void clear_test () {
@@ -143,7 +198,7 @@ void perform_test (void(*testfunc)(void),uint width, uint height) {
 
     bool deferredResolve = false;
 
-    device  = vkvg_device_create_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0, VK_SAMPLE_COUNT_4_BIT, deferredResolve);
+    device  = vkvg_device_create_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0, VK_SAMPLE_COUNT_1_BIT, deferredResolve);
 
     vkvg_device_set_dpy(device, 96, 96);
 
@@ -155,13 +210,17 @@ void perform_test (void(*testfunc)(void),uint width, uint height) {
     surf    = vkvg_surface_create(device, width, height);
     vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height);
 #endif
-    struct timeval before , after;
-    double frameTime = 0, frameTimeAccum = 0, frameCount = 0;
 
-    while (!vkengine_should_close (e)) {
+
+    double start_time, stop_time, run_time, run_total, min_run_time = -1, max_run_time;
+    double run_time_values[iterations];
+
+    int i = 0;
+
+    while (!vkengine_should_close (e) && i < iterations) {
         glfwPollEvents();
 
-        gettimeofday(&before , NULL);
+        start_time = get_tick();
 
 #ifdef VKVG_TEST_DIRECT_DRAW
 
@@ -189,7 +248,8 @@ void perform_test (void(*testfunc)(void),uint width, uint height) {
             vkQueuePresentKHR(r->queue, &present);
         }
 #else
-        testfunc();
+        if (!paused)
+            testfunc();
 
         if (deferredResolve)
             vkvg_multisample_surface_resolve(surf);
@@ -199,15 +259,26 @@ void perform_test (void(*testfunc)(void),uint width, uint height) {
 
         vkDeviceWaitIdle(e->dev->dev);
 
-        gettimeofday(&after , NULL);
-
-        frameTimeAccum += time_diff(before , after);
-        frameCount++;
-        //fflush(stdout);
+        stop_time = get_tick();
+        run_time = stop_time - start_time;
+        run_time_values[i] = run_time;
+
+        if (min_run_time < 0)
+            min_run_time = run_time;
+        else
+            min_run_time = MIN(run_time, min_run_time);
+        max_run_time = MAX(run_time, max_run_time);
+        run_total += run_time;
+        i++;
     }
 
-    frameTime = frameTimeAccum / frameCount;
-    printf ("frame (µs): %.0lf\nfps: %lf\n", frameTime, floor(1000000 / frameTime));
+    double avg_run_time = run_total / (double)iterations;
+    double med_run_time = median_run_time (run_time_values, iterations);
+    double standard_dev = standard_deviation (run_time_values, iterations, avg_run_time);
+    double avg_frames_per_second = (1.0 / avg_run_time);
+    avg_frames_per_second = (avg_frames_per_second<9999) ? avg_frames_per_second:9999;
+
+    printf ("size:%d iter:%d  avgFps: %f avg: %4.2f%% med: %4.2f%% sd: %4.2f%% \n", test_size, iterations, avg_frames_per_second, avg_run_time, med_run_time, standard_dev);
 
     vkDeviceWaitIdle(e->dev->dev);
 
index 8d15d05a0f1aeeadb756baf8a59e6b74583929e2..f916c45f53b51cd5079140c9bbb1b10a93a0164b 100644 (file)
 #define M_PIF               3.14159265359f /* float pi */
 #define M_PIF_MULT_2        6.28318530718f
 
+#ifndef MIN
+# define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef MAX
+# define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+
 #ifdef _WIN32 // MSC_VER
     #define WIN32_LEAN_AND_MEAN
     #define NOMINMAX
@@ -66,8 +74,8 @@
     #include <sys/time.h>
 #endif // _WIN32
 
-extern uint iterations;
-extern uint runs;
+extern uint test_size;
+extern int iterations;
 
 extern float panX;
 extern float panY;
index d5a40a2e27e40df286c1195656bf57621eb94ee2..90d04516191580bf803e76dac0253e029ca4cde5 100644 (file)
@@ -14,7 +14,7 @@ void test(){
     vkvg_set_line_width(ctx,1);
     //vkvg_set_line_join(ctx,VKVG_LINE_JOIN_BEVEL);
 
-    for (uint i=0; i<iterations; i++) {
+    for (uint i=0; i<test_size; i++) {
         randomize_color(ctx);
         float x1 = w*rand()/RAND_MAX;
         float y1 = h*rand()/RAND_MAX;
index 477fe798ef9d57c1d91f1f9ae4f2ccc570b26e0f..4433c6e305d726a05106c6b9489b8173d430c2ea 100644 (file)
@@ -15,7 +15,7 @@ void test(){
     vkvg_set_line_width (ctx,1);
     //vkvg_set_line_join(ctx,VKVG_LINE_JOIN_BEVEL);
 
-    for (uint i=0; i<iterations; i++) {
+    for (uint i=0; i<test_size; i++) {
         randomize_color(ctx);
 
         float x1 = w*rand()/RAND_MAX;
@@ -27,8 +27,8 @@ void test(){
         vkvg_line_to (ctx, x2, y2);
         vkvg_stroke (ctx);
 
-        if (i%100==0)
-            vkvg_flush(ctx);
+        /*if (i%100==0)
+            vkvg_flush(ctx);*/
     }
     vkvg_destroy(ctx);
 }
index 3aa28490d3449fa03ce84bcf081157aeebb98808..b4616c3047c67f76236dec691f83103e652ed219 100644 (file)
@@ -16,7 +16,7 @@ void test(){
 
     randomize_color(ctx);
 
-    for (int i=0; i<iterations; i++) {
+    for (int i=0; i<test_size; i++) {
 
         float x1 = w*rand()/RAND_MAX;
         float y1 = h*rand()/RAND_MAX;
@@ -26,8 +26,8 @@ void test(){
         vkvg_move_to (ctx, x1, y1);
         vkvg_line_to (ctx, x2, y2);
 
-        if (i%100==0)
-            vkvg_flush(ctx);
+        /*if (i%100==0)
+            vkvg_flush(ctx);*/
     }
     vkvg_stroke (ctx);
     vkvg_destroy(ctx);
index b9cf9ae342f2ee1e9502de602c6099d62aa7084c..6953cb589aa957fb155bb8953b78ca4757bfe41b 100644 (file)
@@ -6,25 +6,27 @@ void test(){
     gettimeofday(&currentTime, NULL);
 
     srand((unsigned) currentTime.tv_usec);
-    const float w = 1024.f;
+    const float w = 800.f;
 
     VkvgContext ctx = vkvg_create(surf);
-    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO);
 
+    vkvg_set_line_width(ctx, 1.0f);
     //vkvg_set_line_join(ctx,VKVG_LINE_JOIN_BEVEL);
 
-    for (int i=0; i<iterations; i++) {
+    for (uint i=0; i<test_size; i++) {
         randomize_color(ctx);
 
-        float x = w*rand()/RAND_MAX;
-        float y = w*rand()/RAND_MAX;
-        float r = 0.1f*w*rand()/RAND_MAX;
+        float r = 0.2f*w*rand()/RAND_MAX;
+        float x = truncf(0.9f * w*rand()/RAND_MAX + r);
+        float y = truncf(0.9f * w*rand()/RAND_MAX + r);
 
-        vkvg_arc(ctx, x, y, r, 0, M_PI * 2.f);
+        vkvg_arc(ctx, x, y, r, 0, M_PI * 2.0f);
+        //vkvg_stroke(ctx);
         vkvg_fill(ctx);
 
-        if (i%50==0)
-            vkvg_flush(ctx);
+        /*if (i%50==0)
+            vkvg_flush(ctx);*/
     }
     vkvg_destroy(ctx);
 }
index b202c1f51991d9aa41c0c2ec8abd23f92dcebf1e..c6630d6ef7abc8562181b76ac38b06a910080178 100644 (file)
@@ -8,12 +8,13 @@ void test(){
     const float w = 1024.f;
 
     VkvgContext ctx = vkvg_create(surf);
-    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO);
+    vkvg_set_line_width(ctx, 2.0f);
 
     vkvg_clear(ctx);
     //vkvg_set_line_join(ctx,VKVG_LINE_JOIN_BEVEL);
 
-    for (uint i=0; i<iterations; i++) {
+    for (uint i=0; i<test_size; i++) {
         randomize_color(ctx);
 
         float x = truncf(0.8f*w*rand()/RAND_MAX);
@@ -22,10 +23,11 @@ void test(){
         float v = truncf((0.2f*w*rand()/RAND_MAX)+1.f);
 
         vkvg_rectangle(ctx, x, y, z, v);
+        //vkvg_stroke(ctx);
         vkvg_fill(ctx);
 
-        if (i%250==0)
-            vkvg_flush(ctx);
+        /*if (i%250==0)
+            vkvg_flush(ctx);*/
     }
     vkvg_destroy(ctx);
 }
index 3827f1c5333e552f322689bf28c82e9771669006..36df00ce5728dd23627cf6acccae36f461108076 100644 (file)
@@ -36,6 +36,7 @@ void test_nsvg() {
     NSVGimage* svg = nsvg_load_file(device, path);
 
     VkvgContext ctx = vkvg_create(surf);
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
     vkvg_set_source_rgba(ctx,0.9f,1.0,1.0,1);
     vkvg_paint(ctx);
 
index 0ea254ff35d8f15766b4d26339337d8d8277af72..5ae3be4ffd253b2897afc4169d96a244e9b559b6 100644 (file)
@@ -15,7 +15,7 @@ void test(){
     //vkvg_set_line_join(ctx,VKVG_LINE_JOIN_BEVEL);
     //vkvg_set_source_rgba(ctx,1.0,0.0,0.0,0.1);
 
-    for (int i=0; i<iterations; i++) {
+    for (int i=0; i<test_size; i++) {
         randomize_color(ctx);
         float x1 = w*rand()/RAND_MAX;
         float y1 = h*rand()/RAND_MAX;