summaryrefslogtreecommitdiffstatsci
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2019-09-06 00:57:50 +0200
committerj-p <jp_bruyere@hotmail.com>2019-09-06 00:59:25 +0200
commitd9d2d2bba31ebcc34ae28843c8d4eef223d023c9 (patch)
tree9c79dad68c051fc2c78c7ab037152fe2cde8e504
parent77e4fbddfb6603a1a56b4c4fb482313fa26495ab (diff)
dyn sizing of vbo and ibo buffers
-rw-r--r--include/vkvg.h1
-rw-r--r--src/vkvg_context.c18
-rw-r--r--src/vkvg_context_internal.c148
-rw-r--r--src/vkvg_context_internal.h20
-rw-r--r--tests/common/test.c119
-rw-r--r--tests/common/test.h12
-rw-r--r--tests/hlines.c2
-rw-r--r--tests/lines.c6
-rw-r--r--tests/multilines.c6
-rw-r--r--tests/random_cirles.c20
-rw-r--r--tests/random_rects.c10
-rw-r--r--tests/svg.c1
-rw-r--r--tests/vlines.c2
13 files changed, 264 insertions, 101 deletions
diff --git a/include/vkvg.h b/include/vkvg.h
index 5cfdff0..c637625 100644
--- a/include/vkvg.h
+++ b/include/vkvg.h
@@ -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
diff --git a/src/vkvg_context.c b/src/vkvg_context.c
index edb9c19..7917f6a 100644
--- a/src/vkvg_context.c
+++ b/src/vkvg_context.c
@@ -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;
diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c
index 4be4550..f09f300 100644
--- a/src/vkvg_context_internal.c
+++ b/src/vkvg_context_internal.c
@@ -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;;
diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h
index 622cbe8..d69f944 100644
--- a/src/vkvg_context_internal.h
+++ b/src/vkvg_context_internal.h
@@ -28,11 +28,11 @@
#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);
diff --git a/tests/common/test.c b/tests/common/test.c
index 5b662e6..362ff31 100644
--- a/tests/common/test.c
+++ b/tests/common/test.c
@@ -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];
- while (!vkengine_should_close (e)) {
+ int i = 0;
+
+ 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);
+ stop_time = get_tick();
+ run_time = stop_time - start_time;
+ run_time_values[i] = run_time;
- frameTimeAccum += time_diff(before , after);
- frameCount++;
+ 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);
+ stop_time = get_tick();
+ run_time = stop_time - start_time;
+ run_time_values[i] = run_time;
- frameTimeAccum += time_diff(before , after);
- frameCount++;
- //fflush(stdout);
+ 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);
diff --git a/tests/common/test.h b/tests/common/test.h
index 8d15d05..f916c45 100644
--- a/tests/common/test.h
+++ b/tests/common/test.h
@@ -10,6 +10,14 @@
#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;
diff --git a/tests/hlines.c b/tests/hlines.c
index d5a40a2..90d0451 100644
--- a/tests/hlines.c
+++ b/tests/hlines.c
@@ -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;
diff --git a/tests/lines.c b/tests/lines.c
index 477fe79..4433c6e 100644
--- a/tests/lines.c
+++ b/tests/lines.c
@@ -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);
}
diff --git a/tests/multilines.c b/tests/multilines.c
index 3aa2849..b4616c3 100644
--- a/tests/multilines.c
+++ b/tests/multilines.c
@@ -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);
diff --git a/tests/random_cirles.c b/tests/random_cirles.c
index b9cf9ae..6953cb5 100644
--- a/tests/random_cirles.c
+++ b/tests/random_cirles.c
@@ -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);
}
diff --git a/tests/random_rects.c b/tests/random_rects.c
index b202c1f..c6630d6 100644
--- a/tests/random_rects.c
+++ b/tests/random_rects.c
@@ -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);
}
diff --git a/tests/svg.c b/tests/svg.c
index 3827f1c..36df00c 100644
--- a/tests/svg.c
+++ b/tests/svg.c
@@ -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);
diff --git a/tests/vlines.c b/tests/vlines.c
index 0ea254f..5ae3be4 100644
--- a/tests/vlines.c
+++ b/tests/vlines.c
@@ -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;