From f83ef58951e2feb5c7953c1e5c9cc8af27d2ee85 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Sat, 28 Apr 2018 18:34:23 +0200 Subject: [PATCH] operator funcs, no implementation yet, VKSDK env var handling in cmake, debug --- CMakeLists.txt | 26 ++++++++++++---- README.md | 8 +++++ include/vkvg.h | 6 ++++ screenshot1.png | Bin 0 -> 36472 bytes shaders/vkvg_main.frag | 4 +++ src/shaders.h | 10 +++---- src/vkvg_context.c | 27 ++++++++++++++--- src/vkvg_context_internal.c | 32 +++++++++++++++----- src/vkvg_context_internal.h | 22 +++++++------- src/vkvg_device.c | 7 +++-- src/vkvg_device_internal.c | 10 +++++-- src/vkvg_device_internal.h | 6 ++-- src/vkvg_surface.c | 2 +- tests/test1.c | 57 +++++++++++++++++++++++++----------- tests/vkengine.c | 18 ++++++++++-- vkh | 2 +- 16 files changed, 177 insertions(+), 60 deletions(-) create mode 100644 screenshot1.png diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d11bbf..4957945 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,8 +11,22 @@ IF(NOT CMAKE_BUILD_TYPE) ENDIF() MESSAGE(STATUS "${CMAKE_BUILD_TYPE} build.") +if (CMAKE_BUILD_TYPE STREQUAL "Debug") + ADD_DEFINITIONS (-DDEBUG) +ENDIF() + +set(VULKAN_SDK "$ENV{VULKAN_SDK}" CACHE STRING "LunarG Vulkan SDK path") +if (VULKAN_SDK) + set(ENV{VULKAN_SDK} ${VULKAN_SDK}) +endif () +SET(ENV{VK_LAYER_PATH} "${VULKAN_SDK}/etc/explicit_layer.d") + +MESSAGE(STATUS "VULKAN_SDK = $ENV{VULKAN_SDK}") +MESSAGE(STATUS "VK_LAYER_PATH = $ENV{VK_LAYER_PATH}") + add_subdirectory (vkh) +#be aware that system libraries have priority on SDK in the finding. FIND_PACKAGE(Vulkan REQUIRED) FIND_PACKAGE(GLFW3) FIND_PACKAGE(Freetype REQUIRED) @@ -100,17 +114,18 @@ SET_TARGET_PROPERTIES(vkvg PROPERTIES ) TARGET_INCLUDE_DIRECTORIES(vkvg PRIVATE + ${Vulkan_INCLUDE_DIRS} + ${FREETYPE_INCLUDE_DIRS} + ${HARFBUZZ_INCLUDE_DIRS} + ${FONTCONFIG_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/vkh/include ${CMAKE_CURRENT_SOURCE_DIR}/vkh/src - ${FREETYPE_INCLUDE_DIRS} - ${HARFBUZZ_INCLUDE_DIRS} - ${FONTCONFIG_INCLUDE_DIR} ) TARGET_LINK_LIBRARIES(${PROJECT_NAME} - ${Vulkan_LIBRARY} + ${Vulkan_LIBRARIES} ${FREETYPE_LIBRARY} ${HARFBUZZ_LIBRARIES} ${FONTCONFIG_LIBRARIES} @@ -127,13 +142,14 @@ if (GLFW3_FOUND) #build test app ADD_EXECUTABLE(${PROJECT_NAME}_test tests/test1.c tests/vkengine.c) TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME}_test PRIVATE + ${Vulkan_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/vkh/include ${CMAKE_CURRENT_SOURCE_DIR}/vkh/src ) TARGET_LINK_LIBRARIES(${PROJECT_NAME}_test - ${Vulkan_LIBRARY} + ${Vulkan_LIBRARIES} ${GLFW3_LIBRARY} vkh_static vkvg diff --git a/README.md b/README.md index 1923b8a..24c5d8b 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,12 @@ - Image loading and writing with [stb lib](https://github.com/nothings/stb) - Test includes svg rendering with [nanoSVG](https://github.com/memononen/nanosvg) +

+ + + +

+ ### Requirements: - [Vulkan](https://www.khronos.org/vulkan/) @@ -63,6 +69,8 @@ make # Run Make - Radial gradients. - Dashed lines. +- Operators. +- Improve stroke algorithms. - Offscreen pattern building. - Optimize vulkan memory allocations by sub-allocating from a single shared memory chunk per type. - Optimize command submissions. diff --git a/include/vkvg.h b/include/vkvg.h index 581e640..9a1e555 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -187,6 +187,12 @@ void vkvg_set_line_cap (VkvgContext ctx, vkvg_line_cap_t cap); void vkvg_set_line_join (VkvgContext ctx, vkvg_line_join_t join); void vkvg_set_source_surface(VkvgContext ctx, VkvgSurface surf, float x, float y); void vkvg_set_source (VkvgContext ctx, VkvgPattern pat); +void vkvg_set_operator (VkvgContext ctx, vkvg_operator_t op); + +float vkvg_get_line_width (VkvgContext ctx); +vkvg_line_cap_t vkvg_get_line_cap (VkvgContext ctx); +vkvg_line_join_t vkvg_get_line_join (VkvgContext ctx); +vkvg_operator_t vkvg_get_operator (VkvgContext ctx); void vkvg_save (VkvgContext ctx); void vkvg_restore (VkvgContext ctx); diff --git a/screenshot1.png b/screenshot1.png new file mode 100644 index 0000000000000000000000000000000000000000..6b668b798ef43e6474d1e09b9f3b8817060ec081 GIT binary patch literal 36472 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 = VKVG_PATHES_SIZE; ctx->lineWidth = 1; ctx->pSurf = surf; + ctx->curOperator = VKVG_OPERATOR_OVER; push_constants pc = { {0,0,0,1}, @@ -360,7 +361,7 @@ void vkvg_clip_preserve (VkvgContext ctx){ vkCmdDrawIndexed (ctx->cmd,6,1,0,0,0); //should test current operator to bind correct pipeline - vkCmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipeline); + _bind_draw_pipeline (ctx); vkCmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); } void vkvg_fill_preserve (VkvgContext ctx){ @@ -373,7 +374,7 @@ void vkvg_fill_preserve (VkvgContext ctx){ _poly_fill (ctx); - vkCmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipeline); + _bind_draw_pipeline (ctx); vkCmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT); vkCmdDrawIndexed (ctx->cmd,6,1,0,0,0); vkCmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); @@ -605,7 +606,23 @@ void vkvg_set_line_cap (VkvgContext ctx, vkvg_line_cap_t cap){ ctx->lineCap = cap; } void vkvg_set_line_join (VkvgContext ctx, vkvg_line_join_t join){ - ctx->lineJoint = join; + ctx->lineJoin = join; +} +void vkvg_set_operator (VkvgContext ctx, vkvg_operator_t op){ + ctx->curOperator = op; + _bind_draw_pipeline (ctx); +} +float vkvg_get_line_width (VkvgContext ctx){ + return ctx->lineWidth; +} +vkvg_line_cap_t vkvg_get_line_cap (VkvgContext ctx){ + return ctx->lineCap; +} +vkvg_line_join_t vkvg_get_line_join (VkvgContext ctx){ + return ctx->lineJoin; +} +vkvg_operator_t vkvg_get_operator (VkvgContext ctx){ + return ctx->curOperator; } void vkvg_select_font_face (VkvgContext ctx, const char* name){ @@ -675,6 +692,7 @@ void vkvg_save (VkvgContext ctx){ memcpy (sav->pathes, ctx->pathes, sav->pathPtr * sizeof(uint32_t)); sav->lineWidth = ctx->lineWidth; + sav->curOperator= ctx->curOperator; sav->lineCap = ctx->lineCap; sav->lineWidth = ctx->lineWidth; @@ -736,8 +754,9 @@ void vkvg_restore (VkvgContext ctx){ memcpy (ctx->pathes, sav->pathes, ctx->pathPtr * sizeof(uint32_t)); ctx->lineWidth = sav->lineWidth; + ctx->curOperator= sav->curOperator; ctx->lineCap = sav->lineCap; - ctx->lineJoint = sav->lineJoint; + ctx->lineJoin = sav->lineJoint; ctx->selectedFont.charSize = sav->selectedFont.charSize; strcpy (ctx->selectedFont.fontFile, sav->selectedFont.fontFile); diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index c618863..1723af6 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -209,6 +209,21 @@ void _flush_cmd_buff (VkvgContext ctx){ _submit_wait_and_reset_cmd(ctx); } +//bind correct draw pipeline depending on current OPERATOR +void _bind_draw_pipeline (VkvgContext ctx) { + switch (ctx->curOperator) { + case VKVG_OPERATOR_OVER: + vkCmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_OVER); + break; + case VKVG_OPERATOR_CLEAR: + vkvg_set_source_rgba(ctx,0,0,0,0); + vkCmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_CLEAR); + break; + default: + vkCmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_OVER); + break; + } +} void _init_cmd_buff (VkvgContext ctx){ //full surf quad triangles is at the beginning ctx->vertCount = 4; @@ -226,9 +241,9 @@ void _init_cmd_buff (VkvgContext ctx){ VkRenderPassBeginInfo renderPassBeginInfo = { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, .renderPass = ctx->pSurf->dev->renderPass, .framebuffer = ctx->pSurf->fb, - .renderArea.extent = {ctx->pSurf->width,ctx->pSurf->height}, - .clearValueCount = 4, - .pClearValues = clearValues}; + .renderArea.extent = {ctx->pSurf->width,ctx->pSurf->height}}; + //.clearValueCount = 4, + //.pClearValues = clearValues}; vkh_cmd_begin (ctx->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); vkCmdBeginRenderPass (ctx->cmd, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); @@ -243,8 +258,9 @@ void _init_cmd_buff (VkvgContext ctx){ VkDeviceSize offsets[1] = { 0 }; vkCmdBindVertexBuffers(ctx->cmd, 0, 1, &ctx->vertices.buffer, offsets); vkCmdBindIndexBuffer(ctx->cmd, ctx->indices.buffer, 0, VK_INDEX_TYPE_UINT32); - vkCmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipeline); - vkCmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, 0); + + _bind_draw_pipeline (ctx); + vkCmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); _update_push_constants (ctx); } @@ -353,7 +369,7 @@ void _build_vb_step (vkvg_context* ctx, Vertex v, float hw, uint32_t iL, uint32_ uint32_t idx = ctx->vertCount; - if (ctx->lineJoint == VKVG_LINE_JOIN_MITER){ + if (ctx->lineJoin == VKVG_LINE_JOIN_MITER){ v.pos = vec2_add(ctx->points[i], bisec); _add_vertex(ctx, v); v.pos = vec2_sub(ctx->points[i], bisec); @@ -372,11 +388,11 @@ void _build_vb_step (vkvg_context* ctx, Vertex v, float hw, uint32_t iL, uint32_ } _add_vertex(ctx, v); - if (ctx->lineJoint == VKVG_LINE_JOIN_BEVEL){ + if (ctx->lineJoin == VKVG_LINE_JOIN_BEVEL){ _add_triangle_indices(ctx, idx, idx+2, idx+1); _add_triangle_indices(ctx, idx+2, idx+3, idx+1); _add_triangle_indices(ctx, idx+1, idx+3, idx+4); - }else if (ctx->lineJoint == VKVG_LINE_JOIN_ROUND){ + }else if (ctx->lineJoin == VKVG_LINE_JOIN_ROUND){ float step = M_PI / hw; float a = acos(vp.x); if (vp.y < 0) diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index b1c7a29..bc799b6 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -64,10 +64,9 @@ typedef struct _vkvg_context_save_t{ uint32_t* pathes; size_t sizePathes; - vec2 curPos; - bool curPosExists; float lineWidth; + vkvg_operator_t curOperator; vkvg_line_cap_t lineCap; vkvg_line_join_t lineJoint; @@ -84,14 +83,14 @@ typedef struct _vkvg_context_t { VkvgSurface pSurf; VkFence flushFence; - VkhImage source; + VkhImage source; //source of painting operation - VkCommandPool cmdPool; - VkCommandBuffer cmd; + VkCommandPool cmdPool;//local pools ensure thread safety + VkCommandBuffer cmd; //single cmd buff for context operations VkDescriptorPool descriptorPool; - VkDescriptorSet dsFont; - VkDescriptorSet dsSrc; - VkDescriptorSet dsGrad; + 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 @@ -115,15 +114,15 @@ typedef struct _vkvg_context_t { //pathes array is a list of couple (start,end) point idx refering to point array //it split points list in subpathes and tell if path is closed. //if path is closed, end index is the same as start. - //(I should use a boolean instead to keep last point in array) + //(TODO: I should use a boolean or smthg else instead to keep last point in array) uint32_t* pathes; size_t sizePathes; - vec4 curRGBA; //is store in pushConsts => may be removed. float lineWidth; + vkvg_operator_t curOperator; vkvg_line_cap_t lineCap; - vkvg_line_join_t lineJoint; + vkvg_line_join_t lineJoin; _vkvg_font_t selectedFont; //hold current face and size before cache addition _vkvg_font_t* currentFont; //font ready for lookup @@ -157,6 +156,7 @@ void _add_triangle_indices (VkvgContext ctx, uint32_t i0, uint32_t i1,uint32_t i void _add_tri_indices_for_rect (VkvgContext ctx, uint32_t i); void _build_vb_step (vkvg_context* ctx, Vertex v, float hw, uint32_t iL, uint32_t i, uint32_t iR); +void _bind_draw_pipeline (VkvgContext ctx); void _create_cmd_buff (VkvgContext ctx); void _init_cmd_buff (VkvgContext ctx); void _flush_cmd_buff (VkvgContext ctx); diff --git a/src/vkvg_device.c b/src/vkvg_device.c index 5734fd1..ee5deb5 100644 --- a/src/vkvg_device.c +++ b/src/vkvg_device.c @@ -59,9 +59,12 @@ void vkvg_device_destroy (VkvgDevice dev) vkDestroyDescriptorSetLayout (dev->vkDev, dev->dslSrc, NULL); vkDestroyPipeline (dev->vkDev, dev->pipelinePolyFill, NULL); - vkDestroyPipeline (dev->vkDev, dev->pipeline, NULL); vkDestroyPipeline (dev->vkDev, dev->pipelineClipping, NULL); - vkDestroyPipeline (dev->vkDev, dev->pipeline_OP_SUB, NULL); + + vkDestroyPipeline (dev->vkDev, dev->pipe_OVER, NULL); + vkDestroyPipeline (dev->vkDev, dev->pipe_SUB, NULL); + vkDestroyPipeline (dev->vkDev, dev->pipe_CLEAR, NULL); + vkDestroyPipeline (dev->vkDev, dev->pipelineWired, NULL); vkDestroyPipeline (dev->vkDev, dev->pipelineLineList, NULL); diff --git a/src/vkvg_device_internal.c b/src/vkvg_device_internal.c index 5c0df70..2e6dd23 100644 --- a/src/vkvg_device_internal.c +++ b/src/vkvg_device_internal.c @@ -264,13 +264,19 @@ void _setupPipelines(VkvgDevice dev) dsStateCreateInfo.back = dsStateCreateInfo.front = stencilOpState; blendAttachmentState.colorWriteMask=0xf; dynamicState.dynamicStateCount = 3; - VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipeline)); + VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipe_OVER)); blendAttachmentState.alphaBlendOp = blendAttachmentState.colorBlendOp = VK_BLEND_OP_SUBTRACT; - VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipeline_OP_SUB)); + VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipe_SUB)); + + blendAttachmentState.blendEnable = VK_FALSE; + //rasterizationState.polygonMode = VK_POLYGON_MODE_POINT; + //shaderStages[1].pName = "op_CLEAR"; + VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipe_CLEAR)); rasterizationState.polygonMode = VK_POLYGON_MODE_FILL; inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST; + shaderStages[1].pName = "main"; VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelineLineList)); shaderStages[1].module = modFragWired; diff --git a/src/vkvg_device_internal.h b/src/vkvg_device_internal.h index d3f4505..b11ac24 100644 --- a/src/vkvg_device_internal.h +++ b/src/vkvg_device_internal.h @@ -42,10 +42,12 @@ typedef struct _vkvg_device_t{ VkCommandBuffer cmd; VkFence fence; - VkPipeline pipeline; + VkPipeline pipe_OVER; + VkPipeline pipe_SUB; + VkPipeline pipe_CLEAR; + VkPipeline pipelinePolyFill; VkPipeline pipelineClipping; - VkPipeline pipeline_OP_SUB; VkPipeline pipelineWired; VkPipeline pipelineLineList; diff --git a/src/vkvg_surface.c b/src/vkvg_surface.c index 35a22dc..3c2a8cc 100644 --- a/src/vkvg_surface.c +++ b/src/vkvg_surface.c @@ -35,7 +35,7 @@ void _clear_stencil (VkvgSurface surf) vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); - VkClearDepthStencilValue clr = {1.0f,0}; + VkClearDepthStencilValue clr = {0,0}; VkImageSubresourceRange range = {VK_IMAGE_ASPECT_STENCIL_BIT,0,1,0,1}; vkh_image_set_layout (cmd, surf->stencilMS, VK_IMAGE_ASPECT_STENCIL_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, diff --git a/tests/test1.c b/tests/test1.c index d9ca902..a6b1f5a 100644 --- a/tests/test1.c +++ b/tests/test1.c @@ -455,14 +455,14 @@ void test_colinear () { } void multi_test1 () { - VkvgSurface surf2 = vkvg_surface_create (device,1024,800);; + VkvgSurface surf2 = vkvg_surface_create (device,800,800);; VkvgContext ctx = vkvg_create(surf2); vkvg_set_source_rgba(ctx,0.1,0.1,0.3,1.0); vkvg_paint(ctx); - //vkvg_test_fill(ctx); - //vkvg_test_fill2(ctx); + vkvg_test_fill(ctx); + vkvg_test_fill2(ctx); // vkvg_set_line_join(ctx,VKVG_LINE_JOIN_ROUND); @@ -491,7 +491,7 @@ void multi_test1 () { test_text(ctx); - //vkvg_test_stroke(ctx); + vkvg_test_stroke(ctx); // vkvg_translate(ctx, 10,10); // vkvg_rotate(ctx, 0.2); @@ -499,8 +499,14 @@ void multi_test1 () { //vkvg_test_gradient (ctx); - //vkvg_test_curves(ctx); - //vkvg_test_curves2(ctx); + + vkvg_test_curves(ctx); + vkvg_test_curves2(ctx); + + /*vkvg_set_operator(ctx, VKVG_OPERATOR_CLEAR); + vkvg_rectangle(ctx,100,100,300,300); + vkvg_fill(ctx); + vkvg_set_operator(ctx, VKVG_OPERATOR_OVER);*/ //test_img_surface(ctx); //test_line_caps(ctx); @@ -508,10 +514,15 @@ void multi_test1 () { vkvg_destroy(ctx); ctx = vkvg_create(surf); - vkvg_set_source_rgba(ctx,0.0,0.0,0.0,1); + vkvg_set_source_rgba(ctx,0.0,1.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); + //vkvg_rectangle(ctx,100,100,400,400); + //vkvg_fill(ctx); vkvg_paint(ctx); vkvg_destroy(ctx); @@ -797,9 +808,11 @@ void cairo_tests () { vkvg_set_source_rgba(ctx,0.7,0.7,0.7,1); vkvg_paint(ctx); - /*vkvg_set_source_rgba(ctx,0,1,0,1); - vkvg_rectangle(ctx,100,100,200,200); - //vkvg_fill(ctx); + /* + 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); @@ -814,7 +827,8 @@ void cairo_tests () { vkvg_rel_line_to(ctx,800,800); vkvg_stroke(ctx);*/ - //cairo_test_clip(ctx); +// cairo_test_clip(ctx); +// vkvg_reset_clip(ctx); cairo_print_arc(ctx); @@ -824,10 +838,14 @@ void cairo_tests () { vkvg_translate(ctx,250,0); cairo_test_rounded_rect(ctx); - vkvg_translate(ctx,250,0); - cairo_test_curves(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,-700,250); + vkvg_translate(ctx,-450,250); cairo_test_fill_and_stroke2(ctx); vkvg_translate(ctx,250,0); @@ -837,11 +855,14 @@ void cairo_tests () { cairo_test_text(ctx); vkvg_translate(ctx,-500,250); - cairo_test_line_caps(ctx); + cairo_test_curves(ctx); vkvg_translate(ctx,250,0); cairo_test_line_joins(ctx); + vkvg_translate(ctx,250,0); + cairo_test_line_caps(ctx); + vkvg_destroy(ctx); } @@ -885,13 +906,13 @@ void test_svg () { NSVGpath* path; //svg = nsvgParseFromFile("/mnt/data/images/svg/tux.svg", "px", 96); //svg = nsvgParseFromFile("/mnt/data/images/svg/world.svg", "px", 96); - //svg = nsvgParseFromFile("/mnt/data/images/svg/tiger.svg", "px", 96); + svg = nsvgParseFromFile("/mnt/data/images/svg/tiger.svg", "px", 96); //svg = nsvgParseFromFile("/mnt/data/images/svg/koch_curve.svg", "px", 96); //svg = nsvgParseFromFile("/mnt/data/images/svg/diamond1.svg", "px", 96); //svg = nsvgParseFromFile("/mnt/data/images/svg/diamond2.svg", "px", 96); //svg = nsvgParseFromFile("/home/jp/yahweh-protosinaitic.svg", "px", 96); //svg = nsvgParseFromFile("/mnt/data/images/svg/WMD-biological.svg", "px", 96); - svg = nsvgParseFromFile("/mnt/data/images/svg/Skull_and_crossbones.svg", "px", 96); + //svg = nsvgParseFromFile("/mnt/data/images/svg/Skull_and_crossbones.svg", "px", 96); //svg = nsvgParseFromFile("/mnt/data/images/svg/IconAlerte.svg", "px", 96); //svg = nsvgParseFromFile("/mnt/data/images/svg/Svg_example4.svg", "px", 96); @@ -950,6 +971,8 @@ void test_svg () { int main(int argc, char *argv[]) { + //dumpLayerExts(); + VkEngine* e = vke_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, 1024, 800); vke_set_key_callback (e, key_callback); diff --git a/tests/vkengine.c b/tests/vkengine.c index a97117d..e93cbd0 100644 --- a/tests/vkengine.c +++ b/tests/vkengine.c @@ -197,7 +197,7 @@ VkEngine* vke_create (VkPhysicalDeviceType preferedGPU, uint32_t width, uint32_t assert (glfwVulkanSupported()==GLFW_TRUE); uint32_t enabledExtsCount = 0, phyCount = 0; - const char** enabledExts = glfwGetRequiredInstanceExtensions (&enabledExtsCount); + const char ** enabledExts = glfwGetRequiredInstanceExtensions (&enabledExtsCount); e->app = vkh_app_create("vkvgTest", enabledExtsCount, enabledExts); @@ -254,9 +254,23 @@ VkEngine* vke_create (VkPhysicalDeviceType preferedGPU, uint32_t width, uint32_t } } + char const * dex [] = {"VK_KHR_swapchain"}; +#if DEBUG + uint32_t dlayCpt = 1; + static char const * dlay [] = {"VK_LAYER_LUNARG_standard_validation"}; +#else + uint32_t dlayCpt = 0; + static char const * dlay [] = {}; +#endif + VkDeviceCreateInfo device_info = { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, .queueCreateInfoCount = qCount, - .pQueueCreateInfos = &pQueueInfos}; + .pQueueCreateInfos = &pQueueInfos, + .enabledLayerCount = dlayCpt, + .ppEnabledLayerNames = dlay, + .enabledExtensionCount = 1, + .ppEnabledExtensionNames = dex + }; VK_CHECK_RESULT(vkCreateDevice(e->phy, &device_info, NULL, &e->dev)); diff --git a/vkh b/vkh index 384c3ad..9eca1ff 160000 --- a/vkh +++ b/vkh @@ -1 +1 @@ -Subproject commit 384c3add2173c9fb3de40f3679f4f5326178e331 +Subproject commit 9eca1ffd9de3da3814d634a28b10f61b1e43816e -- 2.47.3