#define LOG_DEBUG 0x10
#define LOG_INFO 0x20
#define LOG_INFO_PATH 0x40
+#define LOG_DBG_ARRAYS 0x80
#define LOG_FULL 0xff
#ifdef DEBUG
}
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;
//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);
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;
}
/**
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);
}
/**
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);
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){
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;
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){
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;
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] =
{{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);
}
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) {
}
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);
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);
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;
}
_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){
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];
ptrPath+=2;
}
+ ctx->curVertOffset = ctx->vertCount;
}
void _fill_ec (VkvgContext ctx){
uint32_t ptrPath = 0;;
#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{
//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;
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);
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;
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);
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);
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 () {
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);
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
vkQueuePresentKHR(r->queue, &present);
}
#else
- testfunc();
+ if (!paused)
+ testfunc();
if (deferredResolve)
vkvg_multisample_surface_resolve(surf);
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);
#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
#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;
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;
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;
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);
}
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;
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);
gettimeofday(¤tTime, 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);
}
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);
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);
}
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);
//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;