]> O.S.I.I.S - jp/vkvg.git/commitdiff
add wired triangulations for debug and optimisation
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Thu, 12 Apr 2018 15:27:52 +0000 (17:27 +0200)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Thu, 12 Apr 2018 15:27:52 +0000 (17:27 +0200)
include/vkvg.h
shaders/wired.frag [new file with mode: 0644]
src/vkvg_context_internal.c
src/vkvg_device_internal.c
tests/test1-sav.c [new file with mode: 0644]
tests/test1.c

index c5d8f32ed8d5410518500452ea34c332e9c2ff36..0092defe5b2795d680fe8db4f26ef76469a2eea7 100644 (file)
@@ -4,7 +4,7 @@
 #include <vulkan/vulkan.h>
 #include <math.h>
 
-#define VKVG_SAMPLES 4
+#define VKVG_SAMPLES 8
 
 typedef enum _vkvg_direction {
     VKVG_HORIZONTAL    = 0,
diff --git a/shaders/wired.frag b/shaders/wired.frag
new file mode 100644 (file)
index 0000000..05f348d
--- /dev/null
@@ -0,0 +1,28 @@
+#version 450
+
+#extension GL_ARB_separate_shader_objects      : enable
+#extension GL_ARB_shading_language_420pack     : enable
+
+layout (set=0, binding = 0) uniform sampler2DArray fontMap;
+layout (set=1, binding = 0) uniform sampler2D          source;
+
+layout (location = 0) in vec4 inColor;         //source rgba
+layout (location = 1) in vec3 inFontUV;                //if it is a text drawing, inFontUV.z hold fontMap layer
+layout (location = 2) in vec4 inSrcRect;       //source bounds
+
+layout (location = 0) out vec4 outFragColor;
+
+layout (constant_id = 0) const int NUM_SAMPLES = 8;
+
+void main()
+{
+       vec4 c = inColor;
+       if (inSrcRect.z > 0.0){
+               vec2 srcUV = (gl_FragCoord.xy - inSrcRect.xy) / inSrcRect.zw;
+               c = texture(source, srcUV);
+       }
+       if (inFontUV.z >= 0.0)
+               c *= texture(fontMap, inFontUV).r;
+
+       outFragColor = vec4(0.8,0,0,1);
+}
index 97a14b1a0a8f803eddab5461aececba2c4c3908a..94ac6d006b567428ffad4de3a341fc0a738d98eb 100644 (file)
@@ -89,6 +89,13 @@ void _record_draw_cmd (VkvgContext ctx){
     if (ctx->indCount == ctx->curIndStart)
         return;
     vkCmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, 0, 1);
+
+    //DEBUG
+    /*vkCmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineWired);
+    vkCmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, 0, 1);
+    vkCmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipeline);*/
+    //////////
+
     ctx->curIndStart = ctx->indCount;
 }
 
@@ -152,7 +159,7 @@ void _init_cmd_buff (VkvgContext ctx){
     //clearValues[0].color = { { 0.0f, 0.0f, 0.0f, 1.0f } };
     //clearValues[1].depthStencil = { 1.0f, 0 };
     VkClearValue clearValues[4] = {
-        { 0.0f, 0.0f, 0.0f, 1.0f },
+        { 0.0f, 1.0f, 0.0f, 1.0f },
         { 0.0f, 0.0f, 0.0f, 1.0f },
         { 1.0f, 0 },
         { 1.0f, 0 }
@@ -161,9 +168,9 @@ void _init_cmd_buff (VkvgContext ctx){
                                                   .renderPass = ctx->pSurf->dev->renderPass,
                                                   .framebuffer = ctx->pSurf->fb,
                                                   .renderArea.extent = {ctx->pSurf->width,ctx->pSurf->height},
-                                                };
-                                                  //.clearValueCount = 4,
-                                                  //.pClearValues = clearValues};
+
+                                                  .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);
     VkViewport viewport = {0,0,ctx->pSurf->width,ctx->pSurf->height,0,1};
index 61e6a947581986cc9f7de17b2b4f81592c4ff865..360d1de4b9c728d8222656f1ad488dd2ce462583 100644 (file)
@@ -27,9 +27,9 @@ void _setupRenderPass(VkvgDevice dev)
                     .format = FB_COLOR_FORMAT,
                     .samples = VKVG_SAMPLES,
                     .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
-                    .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
-                    .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
-                    .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE,
+                    .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
+                    .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+                    .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
                     .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
     VkAttachmentDescription attColorResolve = {
                     .format = FB_COLOR_FORMAT,
@@ -43,10 +43,10 @@ void _setupRenderPass(VkvgDevice dev)
     VkAttachmentDescription attDS = {
                     .format = VK_FORMAT_S8_UINT,
                     .samples = VKVG_SAMPLES,
-                    .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
+                    .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
                     .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
-                    .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
-                    .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE,
+                    .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+                    .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
                     .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL };
 /*    VkAttachmentDescription attDSResolve = {
                     .format = VK_FORMAT_S8_UINT,
@@ -164,8 +164,8 @@ void _setupPipelines(VkvgDevice dev)
     if (VKVG_SAMPLES != VK_SAMPLE_COUNT_1_BIT){
         multisampleState.sampleShadingEnable = VK_TRUE;
         multisampleState.minSampleShading = 0.25f;
-        multisampleState.alphaToCoverageEnable = VK_FALSE;
-        multisampleState.alphaToOneEnable = VK_FALSE;
+        //multisampleState.alphaToCoverageEnable = VK_FALSE;
+        //multisampleState.alphaToOneEnable = VK_FALSE;
     }
     VkVertexInputBindingDescription vertexInputBinding = { .binding = 0,
                 .stride = sizeof(Vertex),
@@ -182,7 +182,7 @@ void _setupPipelines(VkvgDevice dev)
         .vertexAttributeDescriptionCount = 2,
         .pVertexAttributeDescriptions = vertexInputAttributs };
 
-    VkShaderModule modVert, modFrag;
+    VkShaderModule modVert, modFrag, modFragWired;
     VkShaderModuleCreateInfo createInfo = { .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
                                             .pCode = triangle_vert_spv,
                                             .codeSize = triangle_vert_spv_len };
@@ -190,6 +190,9 @@ void _setupPipelines(VkvgDevice dev)
     createInfo.pCode = triangle_frag_spv;
     createInfo.codeSize = triangle_frag_spv_len;
     VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modFrag));
+    createInfo.pCode = wired_frag_spv;
+    createInfo.codeSize = wired_frag_spv_len;
+    VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modFragWired));
 
     VkPipelineShaderStageCreateInfo vertStage = { .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
         .stage = VK_SHADER_STAGE_VERTEX_BIT,
@@ -238,16 +241,20 @@ void _setupPipelines(VkvgDevice dev)
     blendAttachmentState.alphaBlendOp = blendAttachmentState.colorBlendOp = VK_BLEND_OP_SUBTRACT;
     VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipeline_OP_SUB));
 
-    inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
-    rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
-    VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelineWired));
-
     rasterizationState.polygonMode = VK_POLYGON_MODE_FILL;
     inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
     VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelineLineList));
 
-    vkDestroyShaderModule(dev->vkDev, shaderStages[0].module, NULL);
-    vkDestroyShaderModule(dev->vkDev, shaderStages[1].module, NULL);
+    shaderStages[1].module = modFragWired;
+    //pipelineCreateInfo.pStages = shaderStages;
+
+    inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+    rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
+    VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelineWired));
+
+    vkDestroyShaderModule(dev->vkDev, modVert, NULL);
+    vkDestroyShaderModule(dev->vkDev, modFrag, NULL);
+    vkDestroyShaderModule(dev->vkDev, modFragWired, NULL);
 }
 
 void _createDescriptorSetLayout (VkvgDevice dev) {
diff --git a/tests/test1-sav.c b/tests/test1-sav.c
new file mode 100644 (file)
index 0000000..5040767
--- /dev/null
@@ -0,0 +1,715 @@
+
+#include "vke.h"
+#include "vkh.h"
+#include "vkvg.h"
+
+
+VkvgDevice device;
+VkvgSurface surf = NULL;
+
+void vke_swapchain_destroy (vkh_presenter* r);
+void vke_swapchain_create (VkEngine* e);
+
+bool vkeCheckPhyPropBlitSource (VkEngine *e) {
+       VkFormatProperties formatProps;
+       vkGetPhysicalDeviceFormatProperties(e->phy, e->renderer.format, &formatProps);
+       assert((formatProps.linearTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT) && "Format cannot be used as transfer source");
+}
+
+void initPhySurface(VkEngine* e, VkFormat preferedFormat, VkPresentModeKHR presentMode){
+       vkh_presenter* r = &e->renderer;
+
+       uint32_t count;
+       VK_CHECK_RESULT(vkGetPhysicalDeviceSurfaceFormatsKHR (e->phy, r->surface, &count, NULL));
+       assert (count>0);
+       VkSurfaceFormatKHR formats[count];
+       VK_CHECK_RESULT(vkGetPhysicalDeviceSurfaceFormatsKHR (e->phy, r->surface, &count, formats));
+
+       for (int i=0; i<count; i++){
+               if (formats[i].format == preferedFormat) {
+                       r->format = formats[i].format;
+                       r->colorSpace = formats[i].colorSpace;
+                       break;
+               }
+       }
+       assert (r->format != VK_FORMAT_UNDEFINED);
+
+       VK_CHECK_RESULT(vkGetPhysicalDeviceSurfacePresentModesKHR(e->phy, r->surface, &count, NULL));
+       assert (count>0);
+       VkPresentModeKHR presentModes[count];
+       VK_CHECK_RESULT(vkGetPhysicalDeviceSurfacePresentModesKHR(e->phy, r->surface, &count, presentModes));
+       r->presentMode = -1;
+       for (int i=0; i<count; i++){
+               if (presentModes[i] == presentMode) {
+                       r->presentMode = presentModes[i];
+                       break;
+               }
+       }
+       assert (r->presentMode >= 0);
+}
+
+void vke_swapchain_create (VkEngine* e){
+       // Ensure all operations on the device have been finished before destroying resources
+       vkDeviceWaitIdle(e->dev);
+       vkh_presenter* r = &e->renderer;
+
+       VkSurfaceCapabilitiesKHR surfCapabilities;
+       VK_CHECK_RESULT(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(e->phy, r->surface, &surfCapabilities));
+       assert (surfCapabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT);
+
+
+       // width and height are either both 0xFFFFFFFF, or both not 0xFFFFFFFF.
+       if (surfCapabilities.currentExtent.width == 0xFFFFFFFF) {
+               // If the surface size is undefined, the size is set to
+               // the size of the images requested
+               if (r->width < surfCapabilities.minImageExtent.width)
+                       r->width = surfCapabilities.minImageExtent.width;
+               else if (r->width > surfCapabilities.maxImageExtent.width)
+                       r->width = surfCapabilities.maxImageExtent.width;
+               if (r->height < surfCapabilities.minImageExtent.height)
+                       r->height = surfCapabilities.minImageExtent.height;
+               else if (r->height > surfCapabilities.maxImageExtent.height)
+                       r->height = surfCapabilities.maxImageExtent.height;
+       } else {
+               // If the surface size is defined, the swap chain size must match
+               r->width = surfCapabilities.currentExtent.width;
+               r->height= surfCapabilities.currentExtent.height;
+       }
+
+       VkSwapchainKHR newSwapchain;
+       VkSwapchainCreateInfoKHR createInfo = { .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
+                                                                                       .surface = r->surface,
+                                                                                       .minImageCount = surfCapabilities.minImageCount,
+                                                                                       .imageFormat = r->format,
+                                                                                       .imageColorSpace = r->colorSpace,
+                                                                                       .imageExtent = {r->width,r->height},
+                                                                                       .imageArrayLayers = 1,
+                                                                                       .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+                                                                                       .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
+                                                                                       .preTransform = surfCapabilities.currentTransform,
+                                                                                       .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
+                                                                                       .presentMode = r->presentMode,
+                                                                                       .clipped = VK_TRUE,
+                                                                                       .oldSwapchain = r->swapChain};
+
+       VK_CHECK_RESULT(vkCreateSwapchainKHR (e->dev, &createInfo, NULL, &newSwapchain));
+       if (r->swapChain != VK_NULL_HANDLE)
+               vke_swapchain_destroy(r);
+       r->swapChain = newSwapchain;
+
+       VK_CHECK_RESULT(vkGetSwapchainImagesKHR(e->dev, r->swapChain, &r->imgCount, NULL));
+       assert (r->imgCount>0);
+
+       VkImage images[r->imgCount];
+       VK_CHECK_RESULT(vkGetSwapchainImagesKHR(e->dev, r->swapChain, &r->imgCount,images));
+
+       r->ScBuffers = (ImageBuffer*)malloc(sizeof(ImageBuffer)*r->imgCount);
+       r->cmdBuffs = (VkCommandBuffer*)malloc(sizeof(VkCommandBuffer)*r->imgCount);
+
+       for (int i=0; i<r->imgCount; i++) {
+               ImageBuffer sc_buffer = {};
+               VkImageViewCreateInfo createInfo = { .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+                                                                                        .image = images[i],
+                                                                                        .viewType = VK_IMAGE_VIEW_TYPE_2D,
+                                                                                        .format = r->format,
+                                                                                        .components = {VK_COMPONENT_SWIZZLE_R,VK_COMPONENT_SWIZZLE_G,VK_COMPONENT_SWIZZLE_B,VK_COMPONENT_SWIZZLE_A},
+                                                                                        .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT,0,1,0,1}};
+               VK_CHECK_RESULT(vkCreateImageView(e->dev, &createInfo, NULL, &sc_buffer.view));
+               sc_buffer.image = images[i];
+               r->ScBuffers [i] = sc_buffer;
+               r->cmdBuffs [i] = vkh_cmd_buff_create(e->dev, e->renderer.cmdPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+       }
+       r->currentScBufferIndex = 0;
+}
+void vke_swapchain_destroy (vkh_presenter* r){
+       for (uint32_t i = 0; i < r->imgCount; i++)
+       {
+               vkDestroyImageView (r->dev, r->ScBuffers[i].view, NULL);
+               vkFreeCommandBuffers (r->dev, r->cmdPool, 1, &r->cmdBuffs[i]);
+       }
+       vkDestroySwapchainKHR(r->dev, r->swapChain, NULL);
+       free(r->ScBuffers);
+       free(r->cmdBuffs);
+}
+
+VkSampleCountFlagBits getMaxUsableSampleCount(VkSampleCountFlags counts)
+{
+       if (counts & VK_SAMPLE_COUNT_64_BIT) { return VK_SAMPLE_COUNT_64_BIT; }
+       if (counts & VK_SAMPLE_COUNT_32_BIT) { return VK_SAMPLE_COUNT_32_BIT; }
+       if (counts & VK_SAMPLE_COUNT_16_BIT) { return VK_SAMPLE_COUNT_16_BIT; }
+       if (counts & VK_SAMPLE_COUNT_8_BIT) { return VK_SAMPLE_COUNT_8_BIT; }
+       if (counts & VK_SAMPLE_COUNT_4_BIT) { return VK_SAMPLE_COUNT_4_BIT; }
+       if (counts & VK_SAMPLE_COUNT_2_BIT) { return VK_SAMPLE_COUNT_2_BIT; }
+       return VK_SAMPLE_COUNT_1_BIT;
+}
+
+void vkengine_dump_Infos (VkEngine* e){
+       printf("max samples = %d\n", getMaxUsableSampleCount(e->gpu_props.limits.framebufferColorSampleCounts));
+       printf("max tex2d size = %d\n", e->gpu_props.limits.maxImageDimension2D);
+       printf("max tex array layers = %d\n", e->gpu_props.limits.maxImageArrayLayers);
+       printf("max mem alloc count = %d\n", e->gpu_props.limits.maxMemoryAllocationCount);
+
+       for (int i = 0; i < e->memory_properties.memoryHeapCount; i++) {
+               printf("Mem Heap %d\n", i);
+               printf("\tflags= %d\n", e->memory_properties.memoryHeaps[i].flags);
+               printf("\tsize = %d Mo\n", e->memory_properties.memoryHeaps[i].size/ (1024*1024));
+       }
+       for (int i = 0; i < e->memory_properties.memoryTypeCount; i++) {
+               printf("Mem type %d\n", i);
+               printf("\theap %d: ", e->memory_properties.memoryTypes[i].heapIndex);
+               if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
+                       printf("VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|");
+               if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
+                       printf("VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|");
+               if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
+                       printf("VK_MEMORY_PROPERTY_HOST_COHERENT_BIT|");
+               if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT)
+                       printf("VK_MEMORY_PROPERTY_HOST_CACHED_BIT|");
+               if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
+                       printf("VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT|");
+               printf("\n");
+       }
+}
+void vkengine_get_queues_properties (VkEngine* e, VkQueueFamilyProperties** qFamProps, uint32_t* count){
+       vkGetPhysicalDeviceQueueFamilyProperties (e->phy, count, NULL);
+       (*qFamProps) = (VkQueueFamilyProperties*)malloc((*count) * sizeof(VkQueueFamilyProperties));
+       vkGetPhysicalDeviceQueueFamilyProperties (e->phy, count, (*qFamProps));
+}
+void EngineInit (VkEngine* e) {
+       glfwInit();
+       assert (glfwVulkanSupported()==GLFW_TRUE);
+       e->ExtensionNames = glfwGetRequiredInstanceExtensions (&e->EnabledExtensionsCount);
+
+
+       e->infos.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
+       e->infos.pNext = NULL;
+       e->infos.pApplicationName = APP_SHORT_NAME;
+       e->infos.applicationVersion = 1;
+       e->infos.pEngineName = APP_SHORT_NAME;
+       e->infos.engineVersion = 1;
+       e->infos.apiVersion = VK_API_VERSION_1_0;
+       e->renderer.width = 1024;
+       e->renderer.height = 800;
+
+       const uint32_t enabledLayersCount = 1;
+
+       //const char* enabledLayers[] = {"VK_LAYER_LUNARG_core_validation"};
+       const char* enabledExtentions[] = {"VK_KHR_surface", "VK_KHR_swapchain","VK_KHR_xcb_surface"};
+       const char* enabledLayers[] = {"VK_LAYER_LUNARG_standard_validation"};
+
+       VkInstanceCreateInfo inst_info = { .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
+                                                                          .pNext = NULL,
+                                                                          .flags = 0,
+                                                                          .pApplicationInfo = &e->infos,
+                                                                          .enabledExtensionCount = e->EnabledExtensionsCount,
+                                                                          .ppEnabledExtensionNames = e->ExtensionNames,
+                                                                          .enabledLayerCount = 1,
+                                                                          .ppEnabledLayerNames = enabledLayers };
+
+       VK_CHECK_RESULT(vkCreateInstance (&inst_info, NULL, &e->inst));
+
+       e->phy = vkh_find_phy (e->inst, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU);
+
+       vkGetPhysicalDeviceMemoryProperties (e->phy, &e->memory_properties);
+       vkGetPhysicalDeviceProperties       (e->phy, &e->gpu_props);
+
+       /*VkImageFormatProperties imgProps = {};
+       vkGetPhysicalDeviceImageFormatProperties(e->phy,
+                                                                                        VK_FORMAT_R8_UNORM,
+                                                                                        VK_IMAGE_TYPE_2D,
+                                                                                        VK_IMAGE_TILING_OPTIMAL,
+                                                                                        VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+                                                                                        NULL,&imgProps );*/
+
+       int cQueue = -1, gQueue = -1, tQueue = -1;
+       uint32_t queue_family_count = 0;
+       VkQueueFamilyProperties *qfams;
+       vkengine_get_queues_properties(e,&qfams,&queue_family_count);
+
+       //try to find dedicated queues
+       for (int j=0; j<queue_family_count; j++){
+               switch (qfams[j].queueFlags) {
+               case VK_QUEUE_GRAPHICS_BIT:
+                       if (gQueue<0)
+                               gQueue = j;
+                       break;
+               case VK_QUEUE_COMPUTE_BIT:
+                       if (cQueue<0)
+                               cQueue = j;
+                       break;
+               case VK_QUEUE_TRANSFER_BIT:
+                       if (tQueue<0)
+                               tQueue = j;
+                       break;
+               }
+       }
+       //try to find suitable queue if no dedicated one found
+       for (int j=0; j<queue_family_count; j++){
+               if ((qfams[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) && (gQueue < 0))
+                       gQueue = j;
+               if ((qfams[j].queueFlags & VK_QUEUE_COMPUTE_BIT) && (cQueue < 0))
+                       cQueue = j;
+               if ((qfams[j].queueFlags & VK_QUEUE_TRANSFER_BIT) && (tQueue < 0))
+                       tQueue = j;
+       }
+
+       free (qfams);
+
+       if (gQueue<0||cQueue<0||tQueue<0){
+               fprintf (stderr, "Missing Queue type\n");
+               exit (-1);
+       }
+
+       uint32_t qCount = 0;
+       VkDeviceQueueCreateInfo pQueueInfos[3];
+       float queue_priorities[] = {0.0};
+
+       VkDeviceQueueCreateInfo qiG = { .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
+                                                                  .queueCount = 1,
+                                                                  .queueFamilyIndex = gQueue,
+                                                                  .pQueuePriorities = queue_priorities };
+       VkDeviceQueueCreateInfo qiC = { .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
+                                                                  .queueCount = 1,
+                                                                  .queueFamilyIndex = cQueue,
+                                                                  .pQueuePriorities = queue_priorities };
+       VkDeviceQueueCreateInfo qiT = { .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
+                                                                  .queueCount = 1,
+                                                                  .queueFamilyIndex = tQueue,
+                                                                  .pQueuePriorities = queue_priorities };
+
+       if (gQueue == cQueue){
+               if(gQueue == tQueue){
+                       qCount=1;
+                       pQueueInfos[0] = qiG;
+               }else{
+                       qCount=2;
+                       pQueueInfos[0] = qiG;
+                       pQueueInfos[1] = qiT;
+               }
+       }else{
+               if((gQueue == tQueue) || (cQueue==tQueue)){
+                       qCount=2;
+                       pQueueInfos[0] = qiG;
+                       pQueueInfos[1] = qiC;
+               }else{
+                       qCount=3;
+                       pQueueInfos[0] = qiG;
+                       pQueueInfos[1] = qiC;
+                       pQueueInfos[2] = qiT;
+               }
+       }
+
+       VkDeviceCreateInfo device_info = { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
+                                                                          .queueCreateInfoCount = qCount,
+                                                                          .pQueueCreateInfos = &pQueueInfos};
+
+       VK_CHECK_RESULT(vkCreateDevice(e->phy, &device_info, NULL, &e->dev));
+
+       assert (glfwGetPhysicalDevicePresentationSupport (e->inst, e->phy, gQueue)==GLFW_TRUE);
+
+       glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
+       glfwWindowHint(GLFW_RESIZABLE,  GLFW_TRUE);
+       glfwWindowHint(GLFW_FLOATING,   GLFW_FALSE);
+       glfwWindowHint(GLFW_DECORATED,  GLFW_FALSE);
+       //glfwWindowHint(GLFW_SAMPLES, 8);
+
+       vkh_presenter* r = &e->renderer;
+       r->dev = e->dev;
+
+       r->window = glfwCreateWindow(r->width, r->height, "Window Title", NULL, NULL);
+
+       assert (glfwCreateWindowSurface(e->inst, r->window, NULL, &r->surface)==VK_SUCCESS);
+
+       VkBool32 isSupported;
+       vkGetPhysicalDeviceSurfaceSupportKHR(e->phy, gQueue, r->surface, &isSupported);
+       assert (isSupported && "vkGetPhysicalDeviceSurfaceSupportKHR");
+
+       vkGetDeviceQueue(e->dev, gQueue, 0, &e->renderer.queue);
+       e->renderer.qFam = gQueue;
+       vkGetDeviceQueue(e->dev, cQueue, 0, &e->computer.queue);
+       vkGetDeviceQueue(e->dev, tQueue, 0, &e->loader.queue);
+
+       e->renderer.cmdPool = vkh_cmd_pool_create (e->dev, gQueue, 0);
+       e->computer.cmdPool = vkh_cmd_pool_create (e->dev, cQueue, 0);
+       e->loader.cmdPool = vkh_cmd_pool_create (e->dev, tQueue, 0);
+
+       r->semaPresentEnd = vkh_semaphore_create(e->dev);
+       r->semaDrawEnd = vkh_semaphore_create(e->dev);
+
+       initPhySurface(e,VK_FORMAT_B8G8R8A8_UNORM,VK_PRESENT_MODE_FIFO_KHR);
+}
+
+void EngineTerminate (VkEngine* e) {
+       vkDeviceWaitIdle(e->dev);
+       vkh_presenter* r = &e->renderer;
+
+       vkDestroySemaphore(e->dev, r->semaDrawEnd, NULL);
+       vkDestroySemaphore(e->dev, r->semaPresentEnd, NULL);
+
+       vkDestroyCommandPool (e->dev, e->renderer.cmdPool, NULL);
+       vkDestroyCommandPool (e->dev, e->computer.cmdPool, NULL);
+       vkDestroyCommandPool (e->dev, e->loader.cmdPool, NULL);
+
+       vkDestroyDevice (e->dev, NULL);
+       vkDestroySurfaceKHR (e->inst, r->surface, NULL);
+       glfwDestroyWindow (r->window);
+       glfwTerminate ();
+
+       vkDestroyInstance (e->inst, NULL);
+}
+
+static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
+       if (action != GLFW_PRESS)
+               return;
+       switch (key) {
+       case GLFW_KEY_ESCAPE :
+               glfwSetWindowShouldClose(window, GLFW_TRUE);
+               break;
+       }
+}
+static void char_callback (GLFWwindow* window, uint32_t c){}
+static void mouse_move_callback(GLFWwindow* window, double x, double y){}
+static void mouse_button_callback(GLFWwindow* window, int but, int state, int modif){}
+
+
+void setupSimpleBlit(vkh_presenter* r){
+       for (int32_t i = 0; i < r->imgCount; ++i)
+       {
+               VkImage bltDstImage = r->ScBuffers[i].image;
+               VkImage bltSrcImage = vkvg_surface_get_vk_image(surf);
+
+               VkCommandBuffer cb = r->cmdBuffs[i];
+               vkh_cmd_begin(cb,VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT);
+
+               set_image_layout(cb, bltDstImage, VK_IMAGE_ASPECT_COLOR_BIT,
+                               VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                               VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
+
+               set_image_layout(cb, bltSrcImage, VK_IMAGE_ASPECT_COLOR_BIT,
+                               VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                               VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
+
+               VkImageCopy cregion = { .srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
+                                                               .dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
+                                                               .srcOffset = {},
+                                                               .dstOffset = {0,0,0},
+                                                               .extent = {1024,800,1}};
+
+               vkCmdCopyImage(cb, bltSrcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, bltDstImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                                          1, &cregion);
+
+               set_image_layout(cb, bltDstImage, VK_IMAGE_ASPECT_COLOR_BIT,
+                                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+                                                VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
+
+               vkh_cmd_end(cb);
+       }
+}
+void submitCommandBuffer(VkQueue queue, VkCommandBuffer *pCmdBuff, VkSemaphore* pWaitSemaphore, VkSemaphore* pSignalSemaphore){
+       VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+       VkSubmitInfo submit_info = { .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
+                                                                .commandBufferCount = 1,
+                                                                .signalSemaphoreCount = 1,
+                                                                .pSignalSemaphores = pSignalSemaphore,
+                                                                .waitSemaphoreCount = 1,
+                                                                .pWaitSemaphores = pWaitSemaphore,
+                                                                .pWaitDstStageMask = &dstStageMask,
+                                                                .pCommandBuffers = pCmdBuff};
+       VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submit_info, NULL));
+}
+void draw(VkEngine* e) {
+       vkh_presenter* r = &e->renderer;
+       // Get the index of the next available swapchain image:
+       VkResult err = vkAcquireNextImageKHR(e->dev, r->swapChain, UINT64_MAX, r->semaPresentEnd, VK_NULL_HANDLE,
+                                                               &r->currentScBufferIndex);
+       if ((err == VK_ERROR_OUT_OF_DATE_KHR) || (err == VK_SUBOPTIMAL_KHR)){
+               vke_swapchain_create(e);
+               setupSimpleBlit(r);
+       }else{
+               VK_CHECK_RESULT(err);
+               submitCommandBuffer (r->queue, &r->cmdBuffs[r->currentScBufferIndex], &r->semaPresentEnd, &r->semaDrawEnd);
+
+               /* Now present the image in the window */
+               VkPresentInfoKHR present = { .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
+                                                                        .swapchainCount = 1,
+                                                                        .pSwapchains = &r->swapChain,
+                                                                        .waitSemaphoreCount = 1,
+                                                                        .pWaitSemaphores = &r->semaDrawEnd,
+                                                                        .pImageIndices = &r->currentScBufferIndex };
+
+               /* Make sure command buffer is finished before presenting */
+               VK_CHECK_RESULT(vkQueuePresentKHR(r->queue, &present));
+       }
+}
+void vkvg_test_fill(VkvgContext ctx){
+       vkvg_set_rgba(ctx,0.1,0.8,0.8,1.0);
+       vkvg_move_to(ctx,100,100);
+       vkvg_line_to(ctx,400,350);
+       vkvg_line_to(ctx,900,150);
+       vkvg_line_to(ctx,700,450);
+       vkvg_line_to(ctx,900,750);
+       vkvg_line_to(ctx,500,650);
+       vkvg_line_to(ctx,100,800);
+       vkvg_line_to(ctx,150,400);
+       vkvg_close_path(ctx);
+       vkvg_fill(ctx);
+}
+
+void vkvg_test_curves (VkvgContext ctx) {
+       vkvg_set_rgba   (ctx, 1.0,1.0,0.0,0.8);
+       vkvg_set_linewidth(ctx, 10);
+
+       /*
+       vkvg_move_to    (ctx, 100, 400);
+       vkvg_curve_to   (ctx, 100, 100, 600,700,600,400);
+       */
+       //vkvg_move_to    (ctx, 100, 100);
+       //vkvg_curve_to   (ctx, 1000, 100, 100, 800, 1000, 800);
+       vkvg_move_to    (ctx, 100, 100);
+       vkvg_curve_to   (ctx, 1000, 500, 700, 500, 700, 100);
+
+       vkvg_stroke     (ctx);
+}
+
+void vkvg_test_stroke(VkvgContext ctx){
+       vkvg_set_linewidth(ctx, 2);
+       vkvg_set_rgba(ctx,1,0,0,1);
+       vkvg_move_to(ctx,200.5,200.5);
+       vkvg_line_to(ctx,400.5,200.5);
+       vkvg_line_to(ctx,400.5,400.5);
+       vkvg_line_to(ctx,200.5,400.5);
+       vkvg_close_path(ctx);
+       vkvg_save (ctx);
+       vkvg_stroke_preserve(ctx);
+       vkvg_set_rgba(ctx,0,0.2,0.35,1);
+       vkvg_fill(ctx);
+       vkvg_set_rgba(ctx,0.5,1,0,1);
+       vkvg_move_to(ctx,300.5,300.5);
+       vkvg_line_to(ctx,500.5,300.5);
+       vkvg_line_to(ctx,500.5,500.5);
+       vkvg_line_to(ctx,300.5,500.5);
+       vkvg_close_path(ctx);
+       vkvg_stroke(ctx);
+       vkvg_set_linewidth(ctx, 40);
+       vkvg_restore(ctx);
+       vkvg_set_rgba(ctx,0.5,0.6,1,1.0);
+       vkvg_move_to(ctx,700,475);
+       vkvg_line_to(ctx,400,475);
+       vkvg_stroke(ctx);
+       vkvg_set_rgba(ctx,0,0.5,0.5,0.5);
+       vkvg_move_to(ctx,300,200);
+       vkvg_arc(ctx, 200,200,100,0, M_PI);
+       vkvg_stroke(ctx);
+
+       vkvg_set_linewidth(ctx, 20);
+       vkvg_set_rgba(ctx,0.1,0.1,0.1,0.5);
+       vkvg_move_to(ctx,100,60);
+       vkvg_line_to(ctx,400,600);
+       vkvg_stroke(ctx);
+}
+
+void test_text (VkvgContext ctx) {
+       int size = 19;
+       int penY = 50;
+       int penX = 10;
+
+       /*vkvg_rectangle(ctx,30,0,100,400);
+       vkvg_clip(ctx);*/
+
+       //vkvg_select_font_face(ctx, "/usr/local/share/fonts/DroidSansMono.ttf");
+       //vkvg_select_font_face(ctx, "/usr/share/fonts/truetype/unifont/unifont.ttf");
+
+       vkvg_set_font_size(ctx,size-10);
+       vkvg_select_font_face(ctx, "droid");
+       vkvg_move_to(ctx, penX,penY);
+       vkvg_set_rgba(ctx,0.7,0.7,0.7,1);
+       vkvg_show_text (ctx,"abcdefghijk");
+       penY+=size;
+
+
+       vkvg_select_font_face(ctx, "times");
+       vkvg_set_rgba(ctx,0.9,0.7,0.7,1);
+       vkvg_move_to(ctx, penX,penY);
+       vkvg_show_text (ctx,"abcdefghijklmnopqrstuvwxyz");
+       penY+=size;
+
+
+
+       vkvg_select_font_face(ctx, "droid");
+       vkvg_move_to(ctx, penX,penY);
+       vkvg_show_text (ctx,"lmnopqrstuvwxyz123456789");
+       penY+=size;
+
+
+
+       vkvg_select_font_face(ctx, "times:bold");
+       vkvg_move_to(ctx, penX,penY);
+       vkvg_show_text (ctx,"abcdefghijklmnopqrstuvwxyz");
+       penY+=size;
+
+
+       vkvg_select_font_face(ctx, "droid");
+       vkvg_move_to(ctx, penX,penY);
+       vkvg_show_text (ctx,"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+       penY+=size;
+
+
+
+       vkvg_select_font_face(ctx, "arial:italic");
+       vkvg_move_to(ctx, penX,penY);
+       vkvg_show_text (ctx,"abcdefghijklmnopqrstuvwxyz");
+       penY+=size;
+
+
+       vkvg_select_font_face(ctx, "arial");
+       vkvg_move_to(ctx, penX,penY);
+       vkvg_show_text (ctx,"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+       penY+=size;
+       vkvg_move_to(ctx, penX,penY);
+       vkvg_show_text (ctx,"this is a test");
+       penY+=size;
+       vkvg_move_to(ctx, penX,penY);
+       vkvg_show_text (ctx,"this is another test to see if label is working");
+       penY+=size;
+
+       vkvg_select_font_face(ctx, "mono");
+       vkvg_move_to(ctx, penX,penY);
+       vkvg_show_text (ctx,"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+       penY+=size;
+
+       vkvg_move_to(ctx, 80,400);
+       vkvg_show_text (ctx,"Ленивый рыжий кот");
+
+
+       /*vkvg_move_to(ctx, 150,250);
+       vkvg_show_text (ctx,"test string é€");
+       vkvg_move_to(ctx, 150,300);
+       vkvg_show_text (ctx,"كسول الزنجبيل القط");
+       vkvg_move_to(ctx, 150,350);
+       vkvg_show_text (ctx,"懶惰的姜貓");*/
+
+       //vkvg_show_text (ctx,"ABCDABCD");
+       //vkvg_show_text (ctx,"j");
+}
+
+void test_img_surface (VkvgContext ctx) {
+       VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "/mnt/data/images/blason.png");
+       //VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "/mnt/data/images/2000px-Tux.svg.png");
+       //VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "/mnt/data/images/path2674.png");
+       //VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "/mnt/data/images/horse-black-head-shape-of-a-chess-piece_318-52446.jpg");
+
+       vkvg_set_source_surface(ctx, imgSurf, 300, 300);
+       vkvg_paint(ctx);
+       vkvg_flush(ctx);
+       vkvg_surface_destroy(imgSurf);
+}
+void vkvg_test_stroke2(VkvgContext ctx){
+       vkvg_set_linewidth(ctx,20);
+       vkvg_set_rgba(ctx,1,0,0,1);
+       vkvg_move_to(ctx,200,200);
+       vkvg_line_to(ctx,400,200);
+       vkvg_line_to(ctx,400,400);
+       vkvg_line_to(ctx,200,400);
+       vkvg_close_path(ctx);
+       vkvg_stroke(ctx);
+       vkvg_set_rgba(ctx,0.5,1,0,1);
+       vkvg_move_to(ctx,300,300);
+       vkvg_line_to(ctx,500,300);
+       vkvg_line_to(ctx,500,500);
+       vkvg_line_to(ctx,300,500);
+       vkvg_close_path(ctx);
+       vkvg_stroke(ctx);
+       vkvg_set_linewidth(ctx,10);
+       vkvg_set_rgba(ctx,0.5,0.6,1,1);
+       vkvg_move_to(ctx,700,475);
+       vkvg_line_to(ctx,400,475);
+       vkvg_stroke(ctx);
+       vkvg_set_rgba(ctx,1,0,1,1);
+       vkvg_move_to(ctx,700,500);
+
+       vkvg_arc(ctx, 600,500,100,M_PI, 2.0*M_PI);
+       vkvg_stroke(ctx);
+
+
+       vkvg_set_linewidth(ctx,20);
+       vkvg_set_rgba(ctx,1,1,0,1);
+       vkvg_move_to(ctx,100,50);
+       vkvg_line_to(ctx,400,50);
+       vkvg_stroke(ctx);
+}
+void vkvg_test_fill2(VkvgContext ctx){
+       vkvg_set_rgba(ctx,1,0,0,1);
+       vkvg_move_to(ctx,200,200);
+       vkvg_line_to(ctx,250,150);
+       vkvg_line_to(ctx,200,100);
+       vkvg_line_to(ctx,300,150);
+       vkvg_line_to(ctx,700,100);
+       vkvg_line_to(ctx,400,200);
+       vkvg_line_to(ctx,400,400);
+       vkvg_line_to(ctx,200,400);
+       vkvg_line_to(ctx,300,300);
+       vkvg_close_path(ctx);
+       vkvg_fill(ctx);
+}
+int main(int argc, char *argv[]) {
+       dumpLayerExts();
+
+       VkEngine e = {};
+
+       EngineInit(&e);
+
+       device = vkvg_device_create(e.phy, e.dev, e.renderer.queue, e.renderer.qFam);
+
+       surf = vkvg_surface_create (device,1024,800);
+
+       vkeCheckPhyPropBlitSource (&e);
+       glfwSetKeyCallback(e.renderer.window, key_callback);
+
+       vke_swapchain_create(&e);
+
+       VkvgSurface surf2 = vkvg_surface_create (device,1024,800);;
+       VkvgContext ctx = vkvg_create(surf);
+
+       //vkvg_set_rgba(ctx,0.02,0.02,0.1,1);
+       //vkvg_paint(ctx);
+       //vkvg_rectangle (ctx,0,0,1024,800);
+       //vkvg_fill (ctx);
+
+       //vkvg_test_fill(ctx);
+       vkvg_test_stroke2(ctx);
+       vkvg_test_fill2(ctx);
+       //vkvg_test_curves(ctx);
+       //test_text(ctx);
+
+       //test_img_surface(ctx);
+
+       /*vkvg_destroy(ctx);
+       ctx = vkvg_create(surf);
+
+       vkvg_set_rgba(ctx,0.0,0.0,0.0,1);
+       vkvg_paint(ctx);
+
+       vkvg_set_source_surface(ctx, surf2, 0, 0);
+       vkvg_paint(ctx);*/
+
+       vkvg_destroy(ctx);
+
+       setupSimpleBlit(&e.renderer);
+
+       while (!glfwWindowShouldClose(e.renderer.window)) {
+               glfwPollEvents();
+               draw(&e);
+       }
+
+       vkDeviceWaitIdle(e.dev);
+       vke_swapchain_destroy(&e.renderer);
+
+       vkvg_surface_destroy(surf);
+       vkvg_surface_destroy(surf2);
+
+       vkvg_device_destroy(device);
+
+       EngineTerminate (&e);
+
+       return 0;
+}
index 5c10b57cc6e7583b9aa450bf8f9ec650ee56dd59..4dbf7f1f24e915b0fe37a3ba5743753f16897b63 100644 (file)
@@ -594,6 +594,55 @@ void test_text (VkvgContext ctx) {
     //vkvg_show_text (ctx,"j");
 }
 
+void vkvg_test_stroke2(VkvgContext ctx){
+    vkvg_set_linewidth(ctx,20);
+    vkvg_set_rgba(ctx,1,0,0,1);
+    vkvg_move_to(ctx,200,200);
+    vkvg_line_to(ctx,400,200);
+    vkvg_line_to(ctx,400,400);
+    vkvg_line_to(ctx,200,400);
+    vkvg_close_path(ctx);
+    vkvg_stroke(ctx);
+    vkvg_set_rgba(ctx,0.5,1,0,1);
+    vkvg_move_to(ctx,300,300);
+    vkvg_line_to(ctx,500,300);
+    vkvg_line_to(ctx,500,500);
+    vkvg_line_to(ctx,300,500);
+    vkvg_close_path(ctx);
+    vkvg_stroke(ctx);
+    vkvg_set_linewidth(ctx,10);
+    vkvg_set_rgba(ctx,0.5,0.6,1,1);
+    vkvg_move_to(ctx,700,475);
+    vkvg_line_to(ctx,400,475);
+    vkvg_stroke(ctx);
+    vkvg_set_rgba(ctx,1,0,1,1);
+    vkvg_move_to(ctx,700,500);
+
+    vkvg_arc(ctx, 600,500,100,M_PI, 2.0*M_PI);
+    vkvg_stroke(ctx);
+
+
+    vkvg_set_linewidth(ctx,20);
+    vkvg_set_rgba(ctx,1,1,0,1);
+    vkvg_move_to(ctx,100,50);
+    vkvg_line_to(ctx,400,50);
+    vkvg_stroke(ctx);
+}
+void vkvg_test_fill2(VkvgContext ctx){
+    vkvg_set_rgba(ctx,1,0,0,1);
+    vkvg_move_to(ctx,200,200);
+    vkvg_line_to(ctx,250,150);
+    vkvg_line_to(ctx,200,100);
+    vkvg_line_to(ctx,300,150);
+    vkvg_line_to(ctx,700,100);
+    vkvg_line_to(ctx,400,200);
+    vkvg_line_to(ctx,400,400);
+    vkvg_line_to(ctx,200,400);
+    vkvg_line_to(ctx,300,300);
+    vkvg_close_path(ctx);
+    vkvg_fill(ctx);
+}
+
 void test_img_surface (VkvgContext ctx) {
     VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "/mnt/data/images/blason.png");
     //VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "/mnt/data/images/2000px-Tux.svg.png");
@@ -623,28 +672,29 @@ int main(int argc, char *argv[]) {
     vke_swapchain_create(&e);
 
     VkvgSurface surf2 = vkvg_surface_create (device,1024,800);;
-    VkvgContext ctx = vkvg_create(surf);
+    VkvgContext ctx = vkvg_create(surf2);
+
+    //test_img_surface(ctx);
 
     vkvg_set_rgba(ctx,0.02,0.02,0.1,1);
     //vkvg_paint(ctx);
     vkvg_rectangle (ctx,0,0,1024,800);
     vkvg_fill (ctx);
 
+    vkvg_test_fill2(ctx);
     vkvg_test_fill(ctx);
     vkvg_test_stroke(ctx);
     vkvg_test_curves(ctx);
     test_text(ctx);
 
-    //test_img_surface(ctx);
-
-    //vkvg_destroy(ctx);
-    //ctx = vkvg_create(surf);
+    vkvg_destroy(ctx);
+    ctx = vkvg_create(surf);
 
-    //vkvg_set_rgba(ctx,0.0,0.0,0.0,1);
-    //vkvg_paint(ctx);
+    vkvg_set_rgba(ctx,0.0,0.0,0.0,1);
+    vkvg_paint(ctx);
 
-    //vkvg_set_source_surface(ctx, surf2, 0, 0);
-    //vkvg_paint(ctx);
+    vkvg_set_source_surface(ctx, surf2, 0, 0);
+    vkvg_paint(ctx);
 
     vkvg_destroy(ctx);