From da66daa88e9163569d8a81b70661134d4628346b Mon Sep 17 00:00:00 2001 From: j-p Date: Mon, 11 May 2020 13:38:25 +0200 Subject: [PATCH] Dynamic tiling (#34) * select best tiling for format, throw error on format unsupported * update appveyor --- CMakeLists.txt | 5 - appveyor.yml | 19 +- include/vkvg.h | 216 +++++------ src/vkvg_device.c | 228 +++++------ src/vkvg_device_internal.c | 755 ++++++++++++++++++------------------ src/vkvg_device_internal.h | 87 ++--- src/vkvg_internal.h | 7 +- src/vkvg_surface.c | 670 ++++++++++++++++---------------- src/vkvg_surface_internal.h | 21 +- tests/common/test.c | 396 ++++++++++--------- tests/common/vkengine.c | 382 +++++++++--------- vkh | 2 +- 12 files changed, 1408 insertions(+), 1380 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 02ca420..b21d0b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -268,11 +268,6 @@ MESSAGE(STATUS "Premult Alpha\t= enabled.") ELSE () MESSAGE(STATUS "Premult Alpha\t= disabled.") ENDIF () -IF (VKVG_TILING_OPTIMAL) -MESSAGE(STATUS "Surface tiling\t= VK_IMAGE_TILING_OPTIMAL.") -ELSE () -MESSAGE(STATUS "Surface tiling\t= VK_IMAGE_TILING_LINEAR.") -ENDIF () IF (VKVG_LCD_FONT_FILTER) MESSAGE(STATUS "Font filtering\t= LCD.") ELSE () diff --git a/appveyor.yml b/appveyor.yml index f247897..5cd8204 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -4,11 +4,6 @@ image: - Visual Studio 2019 - Ubuntu -artifacts: - - path: 'vkvg.zip' - name: vkvg - type: zip - for: - matrix: @@ -29,12 +24,16 @@ for: - git submodule update --init --recursive - mkdir build - cd build - - cmake -G "Visual Studio 14 Win64" -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake .. + - cmake -G "Visual Studio 14 Win64" -DCMAKE_BUILD_TYPE=Release -DVKVG_LCD_FONT_FILTER=off -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake .. build_script: - - msbuild vkvg.sln /p:Configuration=Debug /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" + - msbuild vkvg.sln /p:Configuration=Release /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" after_build: - cd .. - 7z a vkvg.zip build + artifacts: + - path: 'vkvg.zip' + name: vkvg + type: zip - matrix: @@ -42,7 +41,7 @@ for: - image: Ubuntu install: - wget -qO - http://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo apt-key add - - - sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-bionic.list https://packages.lunarg.com/vulkan/lunarg-vulkan-bionic.list + - sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-bionic.list https://packages.lunarg.com/vulkan/lunarg-vulkan-bionic.list - sudo apt -qq update - sudo apt -y install vulkan-sdk libharfbuzz-dev libglfw3-dev before_build: @@ -52,10 +51,10 @@ for: - cmake .. build_script: - make + - cpack after_build: - cd .. - - 7z a vkvg.zip build/*.so* build/test_* - + - appveyor PushArtifact build/vkvg_0.1.1.deb diff --git a/include/vkvg.h b/include/vkvg.h index 6c6684c..4345945 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -30,12 +30,6 @@ extern "C" { #include #include -#ifdef VKVG_TILING_OPTIMAL - #define VKVG_TILING VK_IMAGE_TILING_OPTIMAL -#else - #define VKVG_TILING VK_IMAGE_TILING_LINEAR -#endif - #define LOG_ERR 0x00 #define LOG_DEBUG 0x10 #define LOG_INFO 0x20 @@ -51,112 +45,112 @@ static uint8_t log_level = LOG_ERR;// | LOG_INFO | LOG_DEBUG | LOG_INFO_PATH; #endif typedef enum { - VKVG_STATUS_SUCCESS = 0, - VKVG_STATUS_NO_MEMORY, - VKVG_STATUS_INVALID_RESTORE, - VKVG_STATUS_INVALID_POP_GROUP, - VKVG_STATUS_NO_CURRENT_POINT, - VKVG_STATUS_INVALID_MATRIX, - VKVG_STATUS_INVALID_STATUS, - VKVG_STATUS_NULL_POINTER, - VKVG_STATUS_INVALID_STRING, - VKVG_STATUS_INVALID_PATH_DATA, - VKVG_STATUS_READ_ERROR, - VKVG_STATUS_WRITE_ERROR, - VKVG_STATUS_SURFACE_FINISHED, - VKVG_STATUS_SURFACE_TYPE_MISMATCH, - VKVG_STATUS_PATTERN_TYPE_MISMATCH, - VKVG_STATUS_INVALID_CONTENT, - VKVG_STATUS_INVALID_FORMAT, - VKVG_STATUS_INVALID_VISUAL, - VKVG_STATUS_FILE_NOT_FOUND, - VKVG_STATUS_INVALID_DASH + VKVG_STATUS_SUCCESS = 0, + VKVG_STATUS_NO_MEMORY, + VKVG_STATUS_INVALID_RESTORE, + VKVG_STATUS_INVALID_POP_GROUP, + VKVG_STATUS_NO_CURRENT_POINT, + VKVG_STATUS_INVALID_MATRIX, + VKVG_STATUS_INVALID_STATUS, + VKVG_STATUS_NULL_POINTER, + VKVG_STATUS_INVALID_STRING, + VKVG_STATUS_INVALID_PATH_DATA, + VKVG_STATUS_READ_ERROR, + VKVG_STATUS_WRITE_ERROR, + VKVG_STATUS_SURFACE_FINISHED, + VKVG_STATUS_SURFACE_TYPE_MISMATCH, + VKVG_STATUS_PATTERN_TYPE_MISMATCH, + VKVG_STATUS_INVALID_CONTENT, + VKVG_STATUS_INVALID_FORMAT, + VKVG_STATUS_INVALID_VISUAL, + VKVG_STATUS_FILE_NOT_FOUND, + VKVG_STATUS_INVALID_DASH }vkvg_status_t; typedef enum { - VKVG_HORIZONTAL = 0, - VKVG_VERTICAL = 1 + VKVG_HORIZONTAL = 0, + VKVG_VERTICAL = 1 }vkvg_direction_t; typedef enum { - VKVG_FORMAT_ARGB32, - VKVG_FORMAT_RGB24, - VKVG_FORMAT_A8, - VKVG_FORMAT_A1 + VKVG_FORMAT_ARGB32, + VKVG_FORMAT_RGB24, + VKVG_FORMAT_A8, + VKVG_FORMAT_A1 } vkvg_format_t; typedef enum { - VKVG_EXTEND_NONE, - VKVG_EXTEND_REPEAT, - VKVG_EXTEND_REFLECT, - VKVG_EXTEND_PAD + VKVG_EXTEND_NONE, + VKVG_EXTEND_REPEAT, + VKVG_EXTEND_REFLECT, + VKVG_EXTEND_PAD } vkvg_extend_t; typedef enum { - VKVG_FILTER_FAST, - VKVG_FILTER_GOOD, - VKVG_FILTER_BEST, - VKVG_FILTER_NEAREST, - VKVG_FILTER_BILINEAR, - VKVG_FILTER_GAUSSIAN, + VKVG_FILTER_FAST, + VKVG_FILTER_GOOD, + VKVG_FILTER_BEST, + VKVG_FILTER_NEAREST, + VKVG_FILTER_BILINEAR, + VKVG_FILTER_GAUSSIAN, } vkvg_filter_t; typedef enum { - VKVG_PATTERN_TYPE_SOLID, - VKVG_PATTERN_TYPE_SURFACE, - VKVG_PATTERN_TYPE_LINEAR, - VKVG_PATTERN_TYPE_RADIAL, - VKVG_PATTERN_TYPE_MESH, - VKVG_PATTERN_TYPE_RASTER_SOURCE, + VKVG_PATTERN_TYPE_SOLID, + VKVG_PATTERN_TYPE_SURFACE, + VKVG_PATTERN_TYPE_LINEAR, + VKVG_PATTERN_TYPE_RADIAL, + VKVG_PATTERN_TYPE_MESH, + VKVG_PATTERN_TYPE_RASTER_SOURCE, } vkvg_pattern_type_t; typedef enum { - VKVG_LINE_CAP_BUTT, - VKVG_LINE_CAP_ROUND, - VKVG_LINE_CAP_SQUARE + VKVG_LINE_CAP_BUTT, + VKVG_LINE_CAP_ROUND, + VKVG_LINE_CAP_SQUARE } vkvg_line_cap_t; typedef enum { - VKVG_LINE_JOIN_MITER, - VKVG_LINE_JOIN_ROUND, - VKVG_LINE_JOIN_BEVEL + VKVG_LINE_JOIN_MITER, + VKVG_LINE_JOIN_ROUND, + VKVG_LINE_JOIN_BEVEL } vkvg_line_join_t; typedef enum { - VKVG_FILL_RULE_EVEN_ODD, - VKVG_FILL_RULE_NON_ZERO + VKVG_FILL_RULE_EVEN_ODD, + VKVG_FILL_RULE_NON_ZERO } vkvg_fill_rule_t; typedef struct { - float r; - float g; - float b; - float a; + float r; + float g; + float b; + float a; } vkvg_color_t; #define VKVG_IDENTITY_MATRIX {1,0,0,1,0,0} typedef struct { - float xx; float yx; - float xy; float yy; - float x0; float y0; + float xx; float yx; + float xy; float yy; + float x0; float y0; } vkvg_matrix_t; typedef struct { - float ascent; - float descent; - float height; - float max_x_advance; - float max_y_advance; + float ascent; + float descent; + float height; + float max_x_advance; + float max_y_advance; } vkvg_font_extents_t; typedef struct { - float x_bearing; - float y_bearing; - float width; - float height; - float x_advance; - float y_advance; + float x_bearing; + float y_bearing; + float width; + float height; + float x_advance; + float y_advance; } vkvg_text_extents_t; typedef struct _vkvg_text_run_t* VkvgText; @@ -205,39 +199,39 @@ void vkvg_render_svg (VkvgContext ctx, NSVGimage* svg, char* subId); //mimic from cairo, to facilitate usage of vkvg as cairo vulkan backend typedef enum _vkvg_operator { - VKVG_OPERATOR_CLEAR, - - VKVG_OPERATOR_SOURCE, - VKVG_OPERATOR_OVER, - VKVG_OPERATOR_IN, - VKVG_OPERATOR_OUT, - VKVG_OPERATOR_ATOP, - - VKVG_OPERATOR_DEST, - VKVG_OPERATOR_DEST_OVER, - VKVG_OPERATOR_DEST_IN, - VKVG_OPERATOR_DEST_OUT, - VKVG_OPERATOR_DEST_ATOP, - - VKVG_OPERATOR_XOR, - VKVG_OPERATOR_ADD, - VKVG_OPERATOR_SATURATE, - - VKVG_OPERATOR_MULTIPLY, - VKVG_OPERATOR_SCREEN, - VKVG_OPERATOR_OVERLAY, - VKVG_OPERATOR_DARKEN, - VKVG_OPERATOR_LIGHTEN, - VKVG_OPERATOR_COLOR_DODGE, - VKVG_OPERATOR_COLOR_BURN, - VKVG_OPERATOR_HARD_LIGHT, - VKVG_OPERATOR_SOFT_LIGHT, - VKVG_OPERATOR_DIFFERENCE, - VKVG_OPERATOR_EXCLUSION, - VKVG_OPERATOR_HSL_HUE, - VKVG_OPERATOR_HSL_SATURATION, - VKVG_OPERATOR_HSL_COLOR, - VKVG_OPERATOR_HSL_LUMINOSITY + VKVG_OPERATOR_CLEAR, + + VKVG_OPERATOR_SOURCE, + VKVG_OPERATOR_OVER, + VKVG_OPERATOR_IN, + VKVG_OPERATOR_OUT, + VKVG_OPERATOR_ATOP, + + VKVG_OPERATOR_DEST, + VKVG_OPERATOR_DEST_OVER, + VKVG_OPERATOR_DEST_IN, + VKVG_OPERATOR_DEST_OUT, + VKVG_OPERATOR_DEST_ATOP, + + VKVG_OPERATOR_XOR, + VKVG_OPERATOR_ADD, + VKVG_OPERATOR_SATURATE, + + VKVG_OPERATOR_MULTIPLY, + VKVG_OPERATOR_SCREEN, + VKVG_OPERATOR_OVERLAY, + VKVG_OPERATOR_DARKEN, + VKVG_OPERATOR_LIGHTEN, + VKVG_OPERATOR_COLOR_DODGE, + VKVG_OPERATOR_COLOR_BURN, + VKVG_OPERATOR_HARD_LIGHT, + VKVG_OPERATOR_SOFT_LIGHT, + VKVG_OPERATOR_DIFFERENCE, + VKVG_OPERATOR_EXCLUSION, + VKVG_OPERATOR_HSL_HUE, + VKVG_OPERATOR_HSL_SATURATION, + VKVG_OPERATOR_HSL_COLOR, + VKVG_OPERATOR_HSL_LUMINOSITY } vkvg_operator_t; /*Context*/ @@ -322,7 +316,7 @@ VkvgPattern vkvg_pattern_create_rgb (float r, float g, float b); VkvgPattern vkvg_pattern_create_for_surface (VkvgSurface surf); VkvgPattern vkvg_pattern_create_linear (float x0, float y0, float x1, float y1); VkvgPattern vkvg_pattern_create_radial (float cx0, float cy0, float radius0, - float cx1, float cy1, float radius1); + float cx1, float cy1, float radius1); void vkvg_pattern_destroy (VkvgPattern pat); void vkvg_pattern_add_color_stop(VkvgPattern pat, float offset, float r, float g, float b, float a); @@ -335,9 +329,9 @@ vkvg_filter_t vkvg_pattern_get_filter (VkvgPattern pat); //matrix void vkvg_matrix_init_identity (vkvg_matrix_t *matrix); void vkvg_matrix_init (vkvg_matrix_t *matrix, - float xx, float yx, - float xy, float yy, - float x0, float y0); + float xx, float yx, + float xy, float yy, + float x0, float y0); void vkvg_matrix_init_translate (vkvg_matrix_t *matrix, float tx, float ty); void vkvg_matrix_init_scale (vkvg_matrix_t *matrix, float sx, float sy); void vkvg_matrix_init_rotate (vkvg_matrix_t *matrix, float radians); diff --git a/src/vkvg_device.c b/src/vkvg_device.c index 85929bd..2f8eb1d 100644 --- a/src/vkvg_device.c +++ b/src/vkvg_device.c @@ -35,7 +35,7 @@ */ VkvgDevice vkvg_device_create(VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex) { - return vkvg_device_create_multisample (inst,phy,vkdev,qFamIdx,qIndex, VK_SAMPLE_COUNT_1_BIT, false); + return vkvg_device_create_multisample (inst,phy,vkdev,qFamIdx,qIndex, VK_SAMPLE_COUNT_1_BIT, false); } /** * @brief Create VkvgDevice with default multisampling configuration @@ -52,138 +52,146 @@ VkvgDevice vkvg_device_create(VkInstance inst, VkPhysicalDevice phy, VkDevice vk */ VkvgDevice vkvg_device_create_multisample(VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex, VkSampleCountFlags samples, bool deferredResolve) { - LOG(LOG_INFO, "CREATE Device: qFam = %d; qIdx = %d\n", qFamIdx, qIndex); - - VkvgDevice dev = (vkvg_device*)malloc(sizeof(vkvg_device)); - - dev->instance = inst; - dev->hdpi = 96; - dev->vdpi = 96; - dev->samples= samples; - dev->deferredResolve = deferredResolve; - dev->vkDev = vkdev; - dev->phy = phy; - - _init_function_pointers (dev); - - VkhPhyInfo phyInfos = vkh_phyinfo_create (dev->phy, NULL); - - dev->phyMemProps = phyInfos->memProps; - dev->gQueue = vkh_queue_create ((VkhDevice)dev, qFamIdx, qIndex, phyInfos->queues[qFamIdx].queueFlags); - MUTEX_INIT (&dev->gQMutex); - - vkh_phyinfo_destroy (phyInfos); - - VmaAllocatorCreateInfo allocatorInfo = { - .physicalDevice = phy, - .device = vkdev - }; - vmaCreateAllocator(&allocatorInfo, &dev->allocator); - - dev->lastCtx= NULL; - - dev->cmdPool= vkh_cmd_pool_create ((VkhDevice)dev, dev->gQueue->familyIndex, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); - dev->cmd = vkh_cmd_buff_create ((VkhDevice)dev, dev->cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); - dev->fence = vkh_fence_create_signaled ((VkhDevice)dev); - - _create_pipeline_cache (dev); - _init_fonts_cache (dev); - if (dev->deferredResolve || dev->samples == VK_SAMPLE_COUNT_1_BIT){ - dev->renderPass = _createRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD); - dev->renderPass_ClearStencil = _createRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR); - dev->renderPass_ClearAll = _createRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR); - }else{ - dev->renderPass = _createRenderPassMS (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD); - dev->renderPass_ClearStencil = _createRenderPassMS (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR); - dev->renderPass_ClearAll = _createRenderPassMS (dev, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR); - } - _createDescriptorSetLayout (dev); - _setupPipelines (dev); - - _create_empty_texture (dev); - - dev->references = 1; + LOG(LOG_INFO, "CREATE Device: qFam = %d; qIdx = %d\n", qFamIdx, qIndex); + + VkvgDevice dev = (vkvg_device*)malloc(sizeof(vkvg_device)); + + dev->instance = inst; + dev->hdpi = 96; + dev->vdpi = 96; + dev->samples= samples; + dev->deferredResolve = deferredResolve; + dev->vkDev = vkdev; + dev->phy = phy; + + VkFormat format = FB_COLOR_FORMAT; + VkImageTiling tiling; + if (!_get_best_image_tiling (dev, format, &tiling)) { + dev->status = VKVG_STATUS_INVALID_FORMAT; + LOG(LOG_ERR, "vkvg create device failed: image format not supported: %d\n", format); + return dev; + } + + _init_function_pointers (dev); + + VkhPhyInfo phyInfos = vkh_phyinfo_create (dev->phy, NULL); + + dev->phyMemProps = phyInfos->memProps; + dev->gQueue = vkh_queue_create ((VkhDevice)dev, qFamIdx, qIndex, phyInfos->queues[qFamIdx].queueFlags); + MUTEX_INIT (&dev->gQMutex); + + vkh_phyinfo_destroy (phyInfos); + + VmaAllocatorCreateInfo allocatorInfo = { + .physicalDevice = phy, + .device = vkdev + }; + vmaCreateAllocator(&allocatorInfo, &dev->allocator); + + dev->lastCtx= NULL; + + dev->cmdPool= vkh_cmd_pool_create ((VkhDevice)dev, dev->gQueue->familyIndex, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); + dev->cmd = vkh_cmd_buff_create ((VkhDevice)dev, dev->cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); + dev->fence = vkh_fence_create_signaled ((VkhDevice)dev); + + _create_pipeline_cache (dev); + _init_fonts_cache (dev); + if (dev->deferredResolve || dev->samples == VK_SAMPLE_COUNT_1_BIT){ + dev->renderPass = _createRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD); + dev->renderPass_ClearStencil = _createRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR); + dev->renderPass_ClearAll = _createRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR); + }else{ + dev->renderPass = _createRenderPassMS (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD); + dev->renderPass_ClearStencil = _createRenderPassMS (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR); + dev->renderPass_ClearAll = _createRenderPassMS (dev, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR); + } + _createDescriptorSetLayout (dev); + _setupPipelines (dev); + + _create_empty_texture (dev, format, tiling); + + dev->references = 1; #ifdef DEBUG - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_POOL, (uint64_t)dev->cmdPool, "Device Cmd Pool"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)dev->cmd, "Device Cmd Buff"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_FENCE, (uint64_t)dev->fence, "Device Fence"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass, "RP load img/stencil"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass_ClearStencil, "RP clear stencil"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass_ClearAll, "RP clear all"); - - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslSrc, "DSLayout SOURCE"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslFont, "DSLayout FONT"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslGrad, "DSLayout GRADIENT"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE_LAYOUT, (uint64_t)dev->pipelineLayout, "PLLayout dev"); - - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipelinePolyFill, "PL Poly fill"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipelineClipping, "PL Clipping"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_OVER, "PL draw Over"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_SUB, "PL draw Substract"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_CLEAR, "PL draw Clear"); - - vkh_image_set_name(dev->emptyImg, "empty IMG"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)vkh_image_get_view(dev->emptyImg), "empty IMG VIEW"); - vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_SAMPLER, (uint64_t)vkh_image_get_sampler(dev->emptyImg), "empty IMG SAMPLER"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_POOL, (uint64_t)dev->cmdPool, "Device Cmd Pool"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)dev->cmd, "Device Cmd Buff"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_FENCE, (uint64_t)dev->fence, "Device Fence"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass, "RP load img/stencil"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass_ClearStencil, "RP clear stencil"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass_ClearAll, "RP clear all"); + + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslSrc, "DSLayout SOURCE"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslFont, "DSLayout FONT"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslGrad, "DSLayout GRADIENT"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE_LAYOUT, (uint64_t)dev->pipelineLayout, "PLLayout dev"); + + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipelinePolyFill, "PL Poly fill"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipelineClipping, "PL Clipping"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_OVER, "PL draw Over"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_SUB, "PL draw Substract"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_CLEAR, "PL draw Clear"); + + vkh_image_set_name(dev->emptyImg, "empty IMG"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)vkh_image_get_view(dev->emptyImg), "empty IMG VIEW"); + vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_SAMPLER, (uint64_t)vkh_image_get_sampler(dev->emptyImg), "empty IMG SAMPLER"); #endif - return dev; + return dev; } void vkvg_device_destroy (VkvgDevice dev) { - dev->references--; - if (dev->references > 0) - return; + dev->references--; + if (dev->references > 0) + return; - LOG(LOG_INFO, "DESTROY Device\n"); + LOG(LOG_INFO, "DESTROY Device\n"); - vkh_image_destroy (dev->emptyImg); + vkh_image_destroy (dev->emptyImg); - vkDestroyDescriptorSetLayout (dev->vkDev, dev->dslGrad,NULL); - vkDestroyDescriptorSetLayout (dev->vkDev, dev->dslFont,NULL); - vkDestroyDescriptorSetLayout (dev->vkDev, dev->dslSrc, NULL); + vkDestroyDescriptorSetLayout (dev->vkDev, dev->dslGrad,NULL); + vkDestroyDescriptorSetLayout (dev->vkDev, dev->dslFont,NULL); + vkDestroyDescriptorSetLayout (dev->vkDev, dev->dslSrc, NULL); - vkDestroyPipeline (dev->vkDev, dev->pipelinePolyFill, NULL); - vkDestroyPipeline (dev->vkDev, dev->pipelineClipping, NULL); + vkDestroyPipeline (dev->vkDev, dev->pipelinePolyFill, NULL); + vkDestroyPipeline (dev->vkDev, dev->pipelineClipping, 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->pipe_OVER, NULL); + vkDestroyPipeline (dev->vkDev, dev->pipe_SUB, NULL); + vkDestroyPipeline (dev->vkDev, dev->pipe_CLEAR, NULL); #ifdef VKVG_WIRED_DEBUG - vkDestroyPipeline (dev->vkDev, dev->pipelineWired, NULL); - vkDestroyPipeline (dev->vkDev, dev->pipelineLineList, NULL); + vkDestroyPipeline (dev->vkDev, dev->pipelineWired, NULL); + vkDestroyPipeline (dev->vkDev, dev->pipelineLineList, NULL); #endif - vkDestroyPipelineLayout (dev->vkDev, dev->pipelineLayout, NULL); - vkDestroyPipelineCache (dev->vkDev, dev->pipelineCache, NULL); - vkDestroyRenderPass (dev->vkDev, dev->renderPass, NULL); - vkDestroyRenderPass (dev->vkDev, dev->renderPass_ClearStencil, NULL); - vkDestroyRenderPass (dev->vkDev, dev->renderPass_ClearAll, NULL); + vkDestroyPipelineLayout (dev->vkDev, dev->pipelineLayout, NULL); + vkDestroyPipelineCache (dev->vkDev, dev->pipelineCache, NULL); + vkDestroyRenderPass (dev->vkDev, dev->renderPass, NULL); + vkDestroyRenderPass (dev->vkDev, dev->renderPass_ClearStencil, NULL); + vkDestroyRenderPass (dev->vkDev, dev->renderPass_ClearAll, NULL); - vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX); + vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX); - vkDestroyFence (dev->vkDev, dev->fence,NULL); - vkFreeCommandBuffers (dev->vkDev, dev->cmdPool, 1, &dev->cmd); - vkDestroyCommandPool (dev->vkDev, dev->cmdPool, NULL); + vkDestroyFence (dev->vkDev, dev->fence,NULL); + vkFreeCommandBuffers (dev->vkDev, dev->cmdPool, 1, &dev->cmd); + vkDestroyCommandPool (dev->vkDev, dev->cmdPool, NULL); - _destroy_font_cache(dev); + _destroy_font_cache(dev); - vmaDestroyAllocator (dev->allocator); + vmaDestroyAllocator (dev->allocator); - MUTEX_DESTROY (&dev->gQMutex); + MUTEX_DESTROY (&dev->gQMutex); - free(dev); + free(dev); } VkvgDevice vkvg_device_reference (VkvgDevice dev) { - dev->references++; - return dev; + dev->references++; + return dev; } uint32_t vkvg_device_get_reference_count (VkvgDevice dev) { - return dev->references; + return dev->references; } /** * @brief set horizontal and vertical resolution of device in dot per inch @@ -192,10 +200,10 @@ uint32_t vkvg_device_get_reference_count (VkvgDevice dev) { * @param vertical device resolution in dot per inch */ void vkvg_device_set_dpy (VkvgDevice dev, int hdpy, int vdpy) { - dev->hdpi = hdpy; - dev->vdpi = vdpy; + dev->hdpi = hdpy; + dev->vdpi = vdpy; - //TODO: reset font cache + //TODO: reset font cache } /** * @brief get horizontal and vertical resolution of device in dot per inch @@ -204,6 +212,6 @@ void vkvg_device_set_dpy (VkvgDevice dev, int hdpy, int vdpy) { * @param return vertical device resolution in dot per inch */ void vkvg_device_get_dpy (VkvgDevice dev, int* hdpy, int* vdpy) { - *hdpy = dev->hdpi; - *vdpy = dev->vdpi; + *hdpy = dev->hdpi; + *vdpy = dev->vdpi; } diff --git a/src/vkvg_device_internal.c b/src/vkvg_device_internal.c index 4f39143..feeda56 100644 --- a/src/vkvg_device_internal.c +++ b/src/vkvg_device_internal.c @@ -27,425 +27,438 @@ #include "shaders.h" void _flush_all_contexes (VkvgDevice dev){ - VkvgContext next = dev->lastCtx; - while (next != NULL){ - _flush_cmd_buff(next); - next = next->pPrev; - } + VkvgContext next = dev->lastCtx; + while (next != NULL){ + _flush_cmd_buff(next); + next = next->pPrev; + } } void _create_pipeline_cache(VkvgDevice dev){ - VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO}; - VK_CHECK_RESULT(vkCreatePipelineCache(dev->vkDev, &pipelineCacheCreateInfo, NULL, &dev->pipelineCache)); + VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO}; + VK_CHECK_RESULT(vkCreatePipelineCache(dev->vkDev, &pipelineCacheCreateInfo, NULL, &dev->pipelineCache)); } VkRenderPass _createRenderPassNoResolve(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp) { - VkAttachmentDescription attColor = { - .format = FB_COLOR_FORMAT, - .samples = dev->samples, - .loadOp = loadOp, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; - VkAttachmentDescription attDS = { - .format = FB_STENCIL_FORMAT, - .samples = dev->samples, - .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .stencilLoadOp = stencilLoadOp, - .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE, - .initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; - - VkAttachmentDescription attachments[] = {attColor,attDS}; - VkAttachmentReference colorRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - VkAttachmentReference dsRef = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; - - VkSubpassDescription subpassDescription = { .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, - .colorAttachmentCount = 1, - .pColorAttachments = &colorRef, - .pDepthStencilAttachment= &dsRef}; - - VkSubpassDependency dependencies[] = - { - { VK_SUBPASS_EXTERNAL, 0, - VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - VK_ACCESS_MEMORY_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - VK_DEPENDENCY_BY_REGION_BIT}, - { 0, VK_SUBPASS_EXTERNAL, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT, - VK_DEPENDENCY_BY_REGION_BIT}, - }; - - VkRenderPassCreateInfo renderPassInfo = { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, - .attachmentCount = 2, - .pAttachments = attachments, - .subpassCount = 1, - .pSubpasses = &subpassDescription, - .dependencyCount = 2, - .pDependencies = dependencies - }; - VkRenderPass rp; - VK_CHECK_RESULT(vkCreateRenderPass(dev->vkDev, &renderPassInfo, NULL, &rp)); - return rp; + VkAttachmentDescription attColor = { + .format = FB_COLOR_FORMAT, + .samples = dev->samples, + .loadOp = loadOp, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; + VkAttachmentDescription attDS = { + .format = FB_STENCIL_FORMAT, + .samples = dev->samples, + .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .stencilLoadOp = stencilLoadOp, + .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE, + .initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; + + VkAttachmentDescription attachments[] = {attColor,attDS}; + VkAttachmentReference colorRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + VkAttachmentReference dsRef = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; + + VkSubpassDescription subpassDescription = { .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .colorAttachmentCount = 1, + .pColorAttachments = &colorRef, + .pDepthStencilAttachment= &dsRef}; + + VkSubpassDependency dependencies[] = + { + { VK_SUBPASS_EXTERNAL, 0, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_MEMORY_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_DEPENDENCY_BY_REGION_BIT}, + { 0, VK_SUBPASS_EXTERNAL, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT, + VK_DEPENDENCY_BY_REGION_BIT}, + }; + + VkRenderPassCreateInfo renderPassInfo = { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + .attachmentCount = 2, + .pAttachments = attachments, + .subpassCount = 1, + .pSubpasses = &subpassDescription, + .dependencyCount = 2, + .pDependencies = dependencies + }; + VkRenderPass rp; + VK_CHECK_RESULT(vkCreateRenderPass(dev->vkDev, &renderPassInfo, NULL, &rp)); + return rp; } VkRenderPass _createRenderPassMS(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp) { - VkAttachmentDescription attColor = { - .format = FB_COLOR_FORMAT, - .samples = dev->samples, - .loadOp = loadOp, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; - VkAttachmentDescription attColorResolve = { - .format = FB_COLOR_FORMAT, - .samples = VK_SAMPLE_COUNT_1_BIT, - .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; - VkAttachmentDescription attDS = { - .format = FB_STENCIL_FORMAT, - .samples = dev->samples, - .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .stencilLoadOp = stencilLoadOp, - .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE, - .initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; - - VkAttachmentDescription attachments[] = {attColorResolve,attDS,attColor}; - VkAttachmentReference resolveRef= {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - VkAttachmentReference dsRef = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; - VkAttachmentReference colorRef = {2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - - VkSubpassDescription subpassDescription = { .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, - .colorAttachmentCount = 1, - .pColorAttachments = &colorRef, - .pResolveAttachments = &resolveRef, - .pDepthStencilAttachment= &dsRef}; - - VkSubpassDependency dependencies[] = - { - { VK_SUBPASS_EXTERNAL, 0, - VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - VK_ACCESS_MEMORY_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - VK_DEPENDENCY_BY_REGION_BIT}, - { 0, VK_SUBPASS_EXTERNAL, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT, - VK_DEPENDENCY_BY_REGION_BIT}, - }; - - VkRenderPassCreateInfo renderPassInfo = { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, - .attachmentCount = 3, - .pAttachments = attachments, - .subpassCount = 1, - .pSubpasses = &subpassDescription, - .dependencyCount = 2, - .pDependencies = dependencies - }; - VkRenderPass rp; - VK_CHECK_RESULT(vkCreateRenderPass(dev->vkDev, &renderPassInfo, NULL, &rp)); - return rp; + VkAttachmentDescription attColor = { + .format = FB_COLOR_FORMAT, + .samples = dev->samples, + .loadOp = loadOp, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; + VkAttachmentDescription attColorResolve = { + .format = FB_COLOR_FORMAT, + .samples = VK_SAMPLE_COUNT_1_BIT, + .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; + VkAttachmentDescription attDS = { + .format = FB_STENCIL_FORMAT, + .samples = dev->samples, + .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .stencilLoadOp = stencilLoadOp, + .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE, + .initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; + + VkAttachmentDescription attachments[] = {attColorResolve,attDS,attColor}; + VkAttachmentReference resolveRef= {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + VkAttachmentReference dsRef = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; + VkAttachmentReference colorRef = {2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + + VkSubpassDescription subpassDescription = { .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .colorAttachmentCount = 1, + .pColorAttachments = &colorRef, + .pResolveAttachments = &resolveRef, + .pDepthStencilAttachment= &dsRef}; + + VkSubpassDependency dependencies[] = + { + { VK_SUBPASS_EXTERNAL, 0, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_MEMORY_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_DEPENDENCY_BY_REGION_BIT}, + { 0, VK_SUBPASS_EXTERNAL, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT, + VK_DEPENDENCY_BY_REGION_BIT}, + }; + + VkRenderPassCreateInfo renderPassInfo = { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + .attachmentCount = 3, + .pAttachments = attachments, + .subpassCount = 1, + .pSubpasses = &subpassDescription, + .dependencyCount = 2, + .pDependencies = dependencies + }; + VkRenderPass rp; + VK_CHECK_RESULT(vkCreateRenderPass(dev->vkDev, &renderPassInfo, NULL, &rp)); + return rp; } void _setupPipelines(VkvgDevice dev) { - VkGraphicsPipelineCreateInfo pipelineCreateInfo = { .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, - .renderPass = dev->renderPass }; - - VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, - .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN }; - - VkPipelineRasterizationStateCreateInfo rasterizationState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, - .polygonMode = VK_POLYGON_MODE_FILL, - .cullMode = VK_CULL_MODE_NONE, - .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, - .depthClampEnable = VK_FALSE, - .rasterizerDiscardEnable = VK_FALSE, - .depthBiasEnable = VK_FALSE, - .lineWidth = 1.0f }; - - VkPipelineColorBlendAttachmentState blendAttachmentState = - { .colorWriteMask = 0x0, .blendEnable = VK_TRUE, + VkGraphicsPipelineCreateInfo pipelineCreateInfo = { .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + .renderPass = dev->renderPass }; + + VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN }; + + VkPipelineRasterizationStateCreateInfo rasterizationState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + .polygonMode = VK_POLYGON_MODE_FILL, + .cullMode = VK_CULL_MODE_NONE, + .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, + .depthClampEnable = VK_FALSE, + .rasterizerDiscardEnable = VK_FALSE, + .depthBiasEnable = VK_FALSE, + .lineWidth = 1.0f }; + + VkPipelineColorBlendAttachmentState blendAttachmentState = + { .colorWriteMask = 0x0, .blendEnable = VK_TRUE, #ifdef VKVG_PREMULT_ALPHA - .srcColorBlendFactor = VK_BLEND_FACTOR_ONE, - .dstColorBlendFactor= VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, - .colorBlendOp = VK_BLEND_OP_ADD, - .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE, - .dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE, - .alphaBlendOp = VK_BLEND_OP_ADD, + .srcColorBlendFactor = VK_BLEND_FACTOR_ONE, + .dstColorBlendFactor= VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .colorBlendOp = VK_BLEND_OP_ADD, + .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE, + .dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE, + .alphaBlendOp = VK_BLEND_OP_ADD, #else - .srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA, - .dstColorBlendFactor= VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, - .colorBlendOp = VK_BLEND_OP_ADD, - .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE, - .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO, - .alphaBlendOp = VK_BLEND_OP_ADD, + .srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA, + .dstColorBlendFactor= VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .colorBlendOp = VK_BLEND_OP_ADD, + .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE, + .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO, + .alphaBlendOp = VK_BLEND_OP_ADD, #endif - }; - - VkPipelineColorBlendStateCreateInfo colorBlendState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, - .attachmentCount = 1, - .pAttachments = &blendAttachmentState }; - - /*failOp,passOp,depthFailOp,compareOp, compareMask, writeMask, reference;*/ - VkStencilOpState polyFillOpState ={VK_STENCIL_OP_KEEP,VK_STENCIL_OP_INVERT,VK_STENCIL_OP_KEEP,VK_COMPARE_OP_EQUAL,STENCIL_CLIP_BIT,STENCIL_FILL_BIT,0}; - VkStencilOpState clipingOpState = {VK_STENCIL_OP_ZERO,VK_STENCIL_OP_REPLACE,VK_STENCIL_OP_KEEP,VK_COMPARE_OP_EQUAL,STENCIL_FILL_BIT,STENCIL_ALL_BIT,0x2}; - VkStencilOpState stencilOpState = {VK_STENCIL_OP_KEEP,VK_STENCIL_OP_ZERO,VK_STENCIL_OP_KEEP,VK_COMPARE_OP_EQUAL,STENCIL_FILL_BIT,STENCIL_FILL_BIT,0x1}; - - VkPipelineDepthStencilStateCreateInfo dsStateCreateInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, - .depthTestEnable = VK_FALSE, - .depthWriteEnable = VK_FALSE, - .depthCompareOp = VK_COMPARE_OP_ALWAYS, - .stencilTestEnable = VK_TRUE, - .front = polyFillOpState, - .back = polyFillOpState }; - - VkDynamicState dynamicStateEnables[] = { - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR, - VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, - VK_DYNAMIC_STATE_STENCIL_REFERENCE, - VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, - }; - VkPipelineDynamicStateCreateInfo dynamicState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, - .dynamicStateCount = 2, - .pDynamicStates = dynamicStateEnables }; - - VkPipelineViewportStateCreateInfo viewportState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, - .viewportCount = 1, .scissorCount = 1 }; - - VkPipelineMultisampleStateCreateInfo multisampleState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, - .rasterizationSamples = dev->samples }; - /*if (VKVG_SAMPLES != VK_SAMPLE_COUNT_1_BIT){ - multisampleState.sampleShadingEnable = VK_TRUE; - multisampleState.minSampleShading = 0.25f; - //multisampleState.alphaToCoverageEnable = VK_FALSE; - //multisampleState.alphaToOneEnable = VK_FALSE; - }*/ - VkVertexInputBindingDescription vertexInputBinding = { .binding = 0, - .stride = sizeof(Vertex), - .inputRate = VK_VERTEX_INPUT_RATE_VERTEX }; - - VkVertexInputAttributeDescription vertexInputAttributs[2] = { - {0, 0, VK_FORMAT_R32G32_SFLOAT, 0}, - {1, 0, VK_FORMAT_R32G32B32_SFLOAT, sizeof(vec2)} - }; - - VkPipelineVertexInputStateCreateInfo vertexInputState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .vertexBindingDescriptionCount = 1, - .pVertexBindingDescriptions = &vertexInputBinding, - .vertexAttributeDescriptionCount = 2, - .pVertexAttributeDescriptions = vertexInputAttributs }; - - VkShaderModule modVert, modFrag, modFragWired; - VkShaderModuleCreateInfo createInfo = { .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, - .pCode = (uint32_t*)vkvg_main_vert_spv, - .codeSize = vkvg_main_vert_spv_len }; - VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modVert)); + }; + + VkPipelineColorBlendStateCreateInfo colorBlendState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + .attachmentCount = 1, + .pAttachments = &blendAttachmentState }; + + /*failOp,passOp,depthFailOp,compareOp, compareMask, writeMask, reference;*/ + VkStencilOpState polyFillOpState ={VK_STENCIL_OP_KEEP,VK_STENCIL_OP_INVERT,VK_STENCIL_OP_KEEP,VK_COMPARE_OP_EQUAL,STENCIL_CLIP_BIT,STENCIL_FILL_BIT,0}; + VkStencilOpState clipingOpState = {VK_STENCIL_OP_ZERO,VK_STENCIL_OP_REPLACE,VK_STENCIL_OP_KEEP,VK_COMPARE_OP_EQUAL,STENCIL_FILL_BIT,STENCIL_ALL_BIT,0x2}; + VkStencilOpState stencilOpState = {VK_STENCIL_OP_KEEP,VK_STENCIL_OP_ZERO,VK_STENCIL_OP_KEEP,VK_COMPARE_OP_EQUAL,STENCIL_FILL_BIT,STENCIL_FILL_BIT,0x1}; + + VkPipelineDepthStencilStateCreateInfo dsStateCreateInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, + .depthTestEnable = VK_FALSE, + .depthWriteEnable = VK_FALSE, + .depthCompareOp = VK_COMPARE_OP_ALWAYS, + .stencilTestEnable = VK_TRUE, + .front = polyFillOpState, + .back = polyFillOpState }; + + VkDynamicState dynamicStateEnables[] = { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR, + VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, + VK_DYNAMIC_STATE_STENCIL_REFERENCE, + VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, + }; + VkPipelineDynamicStateCreateInfo dynamicState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, + .dynamicStateCount = 2, + .pDynamicStates = dynamicStateEnables }; + + VkPipelineViewportStateCreateInfo viewportState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .viewportCount = 1, .scissorCount = 1 }; + + VkPipelineMultisampleStateCreateInfo multisampleState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + .rasterizationSamples = dev->samples }; + /*if (VKVG_SAMPLES != VK_SAMPLE_COUNT_1_BIT){ + multisampleState.sampleShadingEnable = VK_TRUE; + multisampleState.minSampleShading = 0.25f; + //multisampleState.alphaToCoverageEnable = VK_FALSE; + //multisampleState.alphaToOneEnable = VK_FALSE; + }*/ + VkVertexInputBindingDescription vertexInputBinding = { .binding = 0, + .stride = sizeof(Vertex), + .inputRate = VK_VERTEX_INPUT_RATE_VERTEX }; + + VkVertexInputAttributeDescription vertexInputAttributs[2] = { + {0, 0, VK_FORMAT_R32G32_SFLOAT, 0}, + {1, 0, VK_FORMAT_R32G32B32_SFLOAT, sizeof(vec2)} + }; + + VkPipelineVertexInputStateCreateInfo vertexInputState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + .vertexBindingDescriptionCount = 1, + .pVertexBindingDescriptions = &vertexInputBinding, + .vertexAttributeDescriptionCount = 2, + .pVertexAttributeDescriptions = vertexInputAttributs }; + + VkShaderModule modVert, modFrag, modFragWired; + VkShaderModuleCreateInfo createInfo = { .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + .pCode = (uint32_t*)vkvg_main_vert_spv, + .codeSize = vkvg_main_vert_spv_len }; + VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modVert)); #ifdef VKVG_LCD_FONT_FILTER - createInfo.pCode = (uint32_t*)vkvg_main_lcd_frag_spv; - createInfo.codeSize = vkvg_main_lcd_frag_spv_len; + createInfo.pCode = (uint32_t*)vkvg_main_lcd_frag_spv; + createInfo.codeSize = vkvg_main_lcd_frag_spv_len; #else - createInfo.pCode = (uint32_t*)vkvg_main_frag_spv; - createInfo.codeSize = vkvg_main_frag_spv_len; + createInfo.pCode = (uint32_t*)vkvg_main_frag_spv; + createInfo.codeSize = vkvg_main_frag_spv_len; #endif - VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modFrag)); - - VkPipelineShaderStageCreateInfo vertStage = { .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .stage = VK_SHADER_STAGE_VERTEX_BIT, - .module = modVert, - .pName = "main", - }; - VkPipelineShaderStageCreateInfo fragStage = { .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .stage = VK_SHADER_STAGE_FRAGMENT_BIT, - .module = modFrag, - .pName = "main", - }; - - // Use specialization constants to pass number of samples to the shader (used for MSAA resolve) - /*VkSpecializationMapEntry specializationEntry = { - .constantID = 0, - .offset = 0, - .size = sizeof(uint32_t)}; - uint32_t specializationData = VKVG_SAMPLES; - VkSpecializationInfo specializationInfo = { - .mapEntryCount = 1, - .pMapEntries = &specializationEntry, - .dataSize = sizeof(specializationData), - .pData = &specializationData};*/ - - VkPipelineShaderStageCreateInfo shaderStages[] = {vertStage,fragStage}; - - pipelineCreateInfo.stageCount = 1; - pipelineCreateInfo.pStages = shaderStages; - pipelineCreateInfo.pVertexInputState = &vertexInputState; - pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; - pipelineCreateInfo.pViewportState = &viewportState; - pipelineCreateInfo.pRasterizationState = &rasterizationState; - pipelineCreateInfo.pMultisampleState = &multisampleState; - pipelineCreateInfo.pColorBlendState = &colorBlendState; - pipelineCreateInfo.pDepthStencilState = &dsStateCreateInfo; - pipelineCreateInfo.pDynamicState = &dynamicState; - pipelineCreateInfo.layout = dev->pipelineLayout; - - - VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelinePolyFill)); - - inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - dsStateCreateInfo.back = dsStateCreateInfo.front = clipingOpState; - dynamicState.dynamicStateCount = 5; - VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelineClipping)); - - dsStateCreateInfo.back = dsStateCreateInfo.front = stencilOpState; - blendAttachmentState.colorWriteMask=0xf; - dynamicState.dynamicStateCount = 3; - pipelineCreateInfo.stageCount = 2; - 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->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)); + VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modFrag)); + + VkPipelineShaderStageCreateInfo vertStage = { .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_VERTEX_BIT, + .module = modVert, + .pName = "main", + }; + VkPipelineShaderStageCreateInfo fragStage = { .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_FRAGMENT_BIT, + .module = modFrag, + .pName = "main", + }; + + // Use specialization constants to pass number of samples to the shader (used for MSAA resolve) + /*VkSpecializationMapEntry specializationEntry = { + .constantID = 0, + .offset = 0, + .size = sizeof(uint32_t)}; + uint32_t specializationData = VKVG_SAMPLES; + VkSpecializationInfo specializationInfo = { + .mapEntryCount = 1, + .pMapEntries = &specializationEntry, + .dataSize = sizeof(specializationData), + .pData = &specializationData};*/ + + VkPipelineShaderStageCreateInfo shaderStages[] = {vertStage,fragStage}; + + pipelineCreateInfo.stageCount = 1; + pipelineCreateInfo.pStages = shaderStages; + pipelineCreateInfo.pVertexInputState = &vertexInputState; + pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; + pipelineCreateInfo.pViewportState = &viewportState; + pipelineCreateInfo.pRasterizationState = &rasterizationState; + pipelineCreateInfo.pMultisampleState = &multisampleState; + pipelineCreateInfo.pColorBlendState = &colorBlendState; + pipelineCreateInfo.pDepthStencilState = &dsStateCreateInfo; + pipelineCreateInfo.pDynamicState = &dynamicState; + pipelineCreateInfo.layout = dev->pipelineLayout; + + + VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelinePolyFill)); + + inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + dsStateCreateInfo.back = dsStateCreateInfo.front = clipingOpState; + dynamicState.dynamicStateCount = 5; + VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelineClipping)); + + dsStateCreateInfo.back = dsStateCreateInfo.front = stencilOpState; + blendAttachmentState.colorWriteMask=0xf; + dynamicState.dynamicStateCount = 3; + pipelineCreateInfo.stageCount = 2; + 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->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)); #ifdef VKVG_WIRED_DEBUG - 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)); - - createInfo.pCode = (uint32_t*)wired_frag_spv; - createInfo.codeSize = wired_frag_spv_len; - VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modFragWired)); - - shaderStages[1].module = modFragWired; - 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, modFragWired, NULL); + 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)); + + createInfo.pCode = (uint32_t*)wired_frag_spv; + createInfo.codeSize = wired_frag_spv_len; + VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modFragWired)); + + shaderStages[1].module = modFragWired; + 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, modFragWired, NULL); #endif - vkDestroyShaderModule(dev->vkDev, modVert, NULL); - vkDestroyShaderModule(dev->vkDev, modFrag, NULL); + vkDestroyShaderModule(dev->vkDev, modVert, NULL); + vkDestroyShaderModule(dev->vkDev, modFrag, NULL); } void _createDescriptorSetLayout (VkvgDevice dev) { - VkDescriptorSetLayoutBinding dsLayoutBinding = - {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1,VK_SHADER_STAGE_FRAGMENT_BIT, NULL}; - VkDescriptorSetLayoutCreateInfo dsLayoutCreateInfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .bindingCount = 1, - .pBindings = &dsLayoutBinding }; - VK_CHECK_RESULT(vkCreateDescriptorSetLayout(dev->vkDev, &dsLayoutCreateInfo, NULL, &dev->dslFont)); - VK_CHECK_RESULT(vkCreateDescriptorSetLayout(dev->vkDev, &dsLayoutCreateInfo, NULL, &dev->dslSrc)); - dsLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - VK_CHECK_RESULT(vkCreateDescriptorSetLayout(dev->vkDev, &dsLayoutCreateInfo, NULL, &dev->dslGrad)); - - VkPushConstantRange pushConstantRange[] = { - {VK_SHADER_STAGE_VERTEX_BIT,0,sizeof(push_constants)}, - //{VK_SHADER_STAGE_FRAGMENT_BIT,0,sizeof(push_constants)} - }; - VkDescriptorSetLayout dsls[] = {dev->dslFont,dev->dslSrc,dev->dslGrad}; - - VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, - .pushConstantRangeCount = 1, - .pPushConstantRanges = (VkPushConstantRange*)&pushConstantRange, - .setLayoutCount = 3, - .pSetLayouts = dsls }; - VK_CHECK_RESULT(vkCreatePipelineLayout(dev->vkDev, &pipelineLayoutCreateInfo, NULL, &dev->pipelineLayout)); + VkDescriptorSetLayoutBinding dsLayoutBinding = + {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1,VK_SHADER_STAGE_FRAGMENT_BIT, NULL}; + VkDescriptorSetLayoutCreateInfo dsLayoutCreateInfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .bindingCount = 1, + .pBindings = &dsLayoutBinding }; + VK_CHECK_RESULT(vkCreateDescriptorSetLayout(dev->vkDev, &dsLayoutCreateInfo, NULL, &dev->dslFont)); + VK_CHECK_RESULT(vkCreateDescriptorSetLayout(dev->vkDev, &dsLayoutCreateInfo, NULL, &dev->dslSrc)); + dsLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + VK_CHECK_RESULT(vkCreateDescriptorSetLayout(dev->vkDev, &dsLayoutCreateInfo, NULL, &dev->dslGrad)); + + VkPushConstantRange pushConstantRange[] = { + {VK_SHADER_STAGE_VERTEX_BIT,0,sizeof(push_constants)}, + //{VK_SHADER_STAGE_FRAGMENT_BIT,0,sizeof(push_constants)} + }; + VkDescriptorSetLayout dsls[] = {dev->dslFont,dev->dslSrc,dev->dslGrad}; + + VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .pushConstantRangeCount = 1, + .pPushConstantRanges = (VkPushConstantRange*)&pushConstantRange, + .setLayoutCount = 3, + .pSetLayouts = dsls }; + VK_CHECK_RESULT(vkCreatePipelineLayout(dev->vkDev, &pipelineLayoutCreateInfo, NULL, &dev->pipelineLayout)); } void _wait_idle (VkvgDevice dev) { - vkDeviceWaitIdle (dev->vkDev); + vkDeviceWaitIdle (dev->vkDev); } void _wait_and_reset_device_fence (VkvgDevice dev) { - vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX); - vkResetFences (dev->vkDev, 1, &dev->fence); + vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX); + vkResetFences (dev->vkDev, 1, &dev->fence); } void _submit_cmd (VkvgDevice dev, VkCommandBuffer* cmd, VkFence fence) { - MUTEX_LOCK (&dev->gQMutex); - vkh_cmd_submit (dev->gQueue, cmd, fence); - MUTEX_UNLOCK (&dev->gQMutex); + MUTEX_LOCK (&dev->gQMutex); + vkh_cmd_submit (dev->gQueue, cmd, fence); + MUTEX_UNLOCK (&dev->gQMutex); } void _init_function_pointers (VkvgDevice dev) { - CmdBindPipeline = GetInstProcAddress(dev->instance, vkCmdBindPipeline); - CmdBindDescriptorSets = GetInstProcAddress(dev->instance, vkCmdBindDescriptorSets); - CmdBindIndexBuffer = GetInstProcAddress(dev->instance, vkCmdBindIndexBuffer); - CmdBindVertexBuffers = GetInstProcAddress(dev->instance, vkCmdBindVertexBuffers); - CmdDrawIndexed = GetInstProcAddress(dev->instance, vkCmdDrawIndexed); - CmdDraw = GetInstProcAddress(dev->instance, vkCmdDraw); - CmdSetStencilCompareMask= GetInstProcAddress(dev->instance, vkCmdSetStencilCompareMask); - CmdSetStencilReference = GetInstProcAddress(dev->instance, vkCmdSetStencilReference); - CmdSetStencilWriteMask = GetInstProcAddress(dev->instance, vkCmdSetStencilWriteMask); - CmdBeginRenderPass = GetInstProcAddress(dev->instance, vkCmdBeginRenderPass); - CmdEndRenderPass = GetInstProcAddress(dev->instance, vkCmdEndRenderPass); - CmdSetViewport = GetInstProcAddress(dev->instance, vkCmdSetViewport); - CmdSetScissor = GetInstProcAddress(dev->instance, vkCmdSetScissor); - CmdPushConstants = GetInstProcAddress(dev->instance, vkCmdPushConstants); - CmdPushDescriptorSet = (PFN_vkCmdPushDescriptorSetKHR)vkGetInstanceProcAddr(dev->instance, "vkCmdDescriptorSet"); + CmdBindPipeline = GetInstProcAddress(dev->instance, vkCmdBindPipeline); + CmdBindDescriptorSets = GetInstProcAddress(dev->instance, vkCmdBindDescriptorSets); + CmdBindIndexBuffer = GetInstProcAddress(dev->instance, vkCmdBindIndexBuffer); + CmdBindVertexBuffers = GetInstProcAddress(dev->instance, vkCmdBindVertexBuffers); + CmdDrawIndexed = GetInstProcAddress(dev->instance, vkCmdDrawIndexed); + CmdDraw = GetInstProcAddress(dev->instance, vkCmdDraw); + CmdSetStencilCompareMask= GetInstProcAddress(dev->instance, vkCmdSetStencilCompareMask); + CmdSetStencilReference = GetInstProcAddress(dev->instance, vkCmdSetStencilReference); + CmdSetStencilWriteMask = GetInstProcAddress(dev->instance, vkCmdSetStencilWriteMask); + CmdBeginRenderPass = GetInstProcAddress(dev->instance, vkCmdBeginRenderPass); + CmdEndRenderPass = GetInstProcAddress(dev->instance, vkCmdEndRenderPass); + CmdSetViewport = GetInstProcAddress(dev->instance, vkCmdSetViewport); + CmdSetScissor = GetInstProcAddress(dev->instance, vkCmdSetScissor); + CmdPushConstants = GetInstProcAddress(dev->instance, vkCmdPushConstants); + CmdPushDescriptorSet = (PFN_vkCmdPushDescriptorSetKHR)vkGetInstanceProcAddr(dev->instance, "vkCmdDescriptorSet"); #ifdef DEBUG - vkh_device_init_debug_utils ((VkhDevice)dev); + vkh_device_init_debug_utils ((VkhDevice)dev); #endif } -void _create_empty_texture (VkvgDevice dev) { - //create empty image to bind to context source descriptor when not in use - dev->emptyImg = vkh_image_create((VkhDevice)dev,FB_COLOR_FORMAT,16,16,VKVG_TILING,VMA_MEMORY_USAGE_GPU_ONLY, - VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); - vkh_image_create_descriptor(dev->emptyImg, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE); +void _create_empty_texture (VkvgDevice dev, VkFormat format, VkImageTiling tiling) { + //create empty image to bind to context source descriptor when not in use + dev->emptyImg = vkh_image_create((VkhDevice)dev,format,16,16,tiling,VMA_MEMORY_USAGE_GPU_ONLY, + VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); + vkh_image_create_descriptor(dev->emptyImg, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE); - _wait_and_reset_device_fence (dev); + _wait_and_reset_device_fence (dev); - vkh_cmd_begin (dev->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); - vkh_image_set_layout (dev->cmd, dev->emptyImg, VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); - vkh_cmd_end (dev->cmd); - _submit_cmd (dev, &dev->cmd, dev->fence); + vkh_cmd_begin (dev->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + vkh_image_set_layout (dev->cmd, dev->emptyImg, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); + vkh_cmd_end (dev->cmd); + _submit_cmd (dev, &dev->cmd, dev->fence); +} +bool _get_best_image_tiling (VkvgDevice dev, VkFormat format, VkImageTiling* pTiling) { + VkFormatProperties phyImgProps = {0}; + vkGetPhysicalDeviceFormatProperties(dev->phy, format, &phyImgProps); + if (phyImgProps.optimalTilingFeatures & (VKVG_SURFACE_IMGS_REQUIREMENTS)) + *pTiling = VK_IMAGE_TILING_OPTIMAL; + else if (phyImgProps.linearTilingFeatures & (VKVG_SURFACE_IMGS_REQUIREMENTS)) + *pTiling = VK_IMAGE_TILING_LINEAR; + else { + dev->status = VKVG_STATUS_INVALID_FORMAT; + return false; + } + return true; } -void _dump_image_format_properties (VkvgDevice dev) { - VkImageFormatProperties imgProps; - VK_CHECK_RESULT(vkGetPhysicalDeviceImageFormatProperties(dev->phy, - FB_COLOR_FORMAT, VK_IMAGE_TYPE_2D, VKVG_TILING, - VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT, - 0, &imgProps)); - printf ("tiling = %d\n", VKVG_TILING); - printf ("max extend = (%d, %d, %d)\n", imgProps.maxExtent.width, imgProps.maxExtent.height, imgProps.maxExtent.depth); - printf ("max mip levels = %d\n", imgProps.maxMipLevels); - printf ("max array layers = %d\n", imgProps.maxArrayLayers); - printf ("sample counts = "); - if (imgProps.sampleCounts & VK_SAMPLE_COUNT_1_BIT) - printf ("1,"); - if (imgProps.sampleCounts & VK_SAMPLE_COUNT_2_BIT) - printf ("2,"); - if (imgProps.sampleCounts & VK_SAMPLE_COUNT_4_BIT) - printf ("4,"); - if (imgProps.sampleCounts & VK_SAMPLE_COUNT_8_BIT) - printf ("8,"); - if (imgProps.sampleCounts & VK_SAMPLE_COUNT_16_BIT) - printf ("16,"); - if (imgProps.sampleCounts & VK_SAMPLE_COUNT_32_BIT) - printf ("32,"); - printf ("\n"); - printf ("max resource size= %lu\n", imgProps.maxResourceSize); - +void _dump_image_format_properties (VkvgDevice dev, VkFormat format) { + /*VkImageFormatProperties imgProps; + VK_CHECK_RESULT(vkGetPhysicalDeviceImageFormatProperties(dev->phy, + format, VK_IMAGE_TYPE_2D, VKVG_TILING, + VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT, + 0, &imgProps)); + printf ("tiling = %d\n", VKVG_TILING); + printf ("max extend = (%d, %d, %d)\n", imgProps.maxExtent.width, imgProps.maxExtent.height, imgProps.maxExtent.depth); + printf ("max mip levels = %d\n", imgProps.maxMipLevels); + printf ("max array layers = %d\n", imgProps.maxArrayLayers); + printf ("sample counts = "); + if (imgProps.sampleCounts & VK_SAMPLE_COUNT_1_BIT) + printf ("1,"); + if (imgProps.sampleCounts & VK_SAMPLE_COUNT_2_BIT) + printf ("2,"); + if (imgProps.sampleCounts & VK_SAMPLE_COUNT_4_BIT) + printf ("4,"); + if (imgProps.sampleCounts & VK_SAMPLE_COUNT_8_BIT) + printf ("8,"); + if (imgProps.sampleCounts & VK_SAMPLE_COUNT_16_BIT) + printf ("16,"); + if (imgProps.sampleCounts & VK_SAMPLE_COUNT_32_BIT) + printf ("32,"); + printf ("\n"); + printf ("max resource size= %lu\n", imgProps.maxResourceSize); +*/ } diff --git a/src/vkvg_device_internal.h b/src/vkvg_device_internal.h index 3d27f44..a6b1b3a 100644 --- a/src/vkvg_device_internal.h +++ b/src/vkvg_device_internal.h @@ -51,56 +51,55 @@ PFN_vkCmdPushDescriptorSetKHR CmdPushDescriptorSet; typedef struct _vkvg_device_t{ - VkDevice vkDev; /**< Vulkan Logical Device */ - VkPhysicalDeviceMemoryProperties phyMemProps; /**< Vulkan Physical device memory properties */ - VkPhysicalDevice phy; /**< Vulkan Physical device */ - VmaAllocator allocator; /**< Vulkan Memory allocator */ - VkInstance instance; /**< Vulkan instance */ - - VkhQueue gQueue; /**< Vulkan Queue with Graphic flag */ - MUTEX gQMutex; /**< queue submission has to be externally syncronized */ - VkRenderPass renderPass; /**< Vulkan render pass, common for all surfaces */ - VkRenderPass renderPass_ClearStencil;/**< Vulkan render pass for first draw with context, stencil has to be cleared */ - VkRenderPass renderPass_ClearAll; /**< Vulkan render pass for new surface, clear all attacments*/ - - uint32_t references; /**< Reference count, prevent destroying device if still in use */ - VkCommandPool cmdPool; /**< Global command pool for processing on surfaces without context */ - VkCommandBuffer cmd; /**< Global command buffer */ - VkFence fence; /**< this fence is kept signaled when idle, wait and reset are called before each recording. */ - - VkPipeline pipe_OVER; /**< default operator */ - VkPipeline pipe_SUB; - VkPipeline pipe_CLEAR; /**< clear operator */ - - VkPipeline pipelinePolyFill; /**< even-odd polygon filling first step */ - VkPipeline pipelineClipping; /**< draw on stencil to update clipping regions */ + VkDevice vkDev; /**< Vulkan Logical Device */ + VkPhysicalDeviceMemoryProperties phyMemProps; /**< Vulkan Physical device memory properties */ + VkPhysicalDevice phy; /**< Vulkan Physical device */ + VmaAllocator allocator; /**< Vulkan Memory allocator */ + VkInstance instance; /**< Vulkan instance */ + + VkhQueue gQueue; /**< Vulkan Queue with Graphic flag */ + MUTEX gQMutex; /**< queue submission has to be externally syncronized */ + VkRenderPass renderPass; /**< Vulkan render pass, common for all surfaces */ + VkRenderPass renderPass_ClearStencil;/**< Vulkan render pass for first draw with context, stencil has to be cleared */ + VkRenderPass renderPass_ClearAll; /**< Vulkan render pass for new surface, clear all attacments*/ + + uint32_t references; /**< Reference count, prevent destroying device if still in use */ + VkCommandPool cmdPool; /**< Global command pool for processing on surfaces without context */ + VkCommandBuffer cmd; /**< Global command buffer */ + VkFence fence; /**< this fence is kept signaled when idle, wait and reset are called before each recording. */ + + VkPipeline pipe_OVER; /**< default operator */ + VkPipeline pipe_SUB; + VkPipeline pipe_CLEAR; /**< clear operator */ + + VkPipeline pipelinePolyFill; /**< even-odd polygon filling first step */ + VkPipeline pipelineClipping; /**< draw on stencil to update clipping regions */ #ifdef VKVG_WIRED_DEBUG - VkPipeline pipelineWired; - VkPipeline pipelineLineList; + VkPipeline pipelineWired; + VkPipeline pipelineLineList; #endif - - VkPipelineCache pipelineCache; /**< speed up startup by caching configured pipelines on disk */ - VkPipelineLayout pipelineLayout; /**< layout common to all pipelines */ - VkDescriptorSetLayout dslFont; /**< font cache descriptors layout */ - VkDescriptorSetLayout dslSrc; /**< context source surface descriptors layout */ - VkDescriptorSetLayout dslGrad; /**< context gradient descriptors layout */ - - int hdpi, /**< only used for FreeType fonts and svg loading */ - vdpi; - - VkhImage emptyImg; /**< prevent unbound descriptor to trigger Validation error 61 */ - VkSampleCountFlags samples; /**< samples count common to all surfaces */ - bool deferredResolve; /**< if true, resolve only on context destruction and set as source */ - vkvg_status_t status; /**< Current status of device, affected by last operation */ - - _font_cache_t* fontCache; /**< Store everything relative to common font caching system */ - VkvgContext lastCtx; /**< last element of double linked list of context, used to trigger font caching system update on all contexts*/ + VkPipelineCache pipelineCache; /**< speed up startup by caching configured pipelines on disk */ + VkPipelineLayout pipelineLayout; /**< layout common to all pipelines */ + VkDescriptorSetLayout dslFont; /**< font cache descriptors layout */ + VkDescriptorSetLayout dslSrc; /**< context source surface descriptors layout */ + VkDescriptorSetLayout dslGrad; /**< context gradient descriptors layout */ + + int hdpi, /**< only used for FreeType fonts and svg loading */ + vdpi; + + VkhImage emptyImg; /**< prevent unbound descriptor to trigger Validation error 61 */ + VkSampleCountFlags samples; /**< samples count common to all surfaces */ + bool deferredResolve; /**< if true, resolve only on context destruction and set as source */ + vkvg_status_t status; /**< Current status of device, affected by last operation */ + + _font_cache_t* fontCache; /**< Store everything relative to common font caching system */ + VkvgContext lastCtx; /**< last element of double linked list of context, used to trigger font caching system update on all contexts*/ }vkvg_device; void _init_function_pointers (VkvgDevice dev); -void _create_empty_texture (VkvgDevice dev); -void _check_image_format_properties (VkvgDevice dev); +void _create_empty_texture (VkvgDevice dev, VkFormat format, VkImageTiling tiling); +bool _get_best_image_tiling (VkvgDevice dev, VkFormat format, VkImageTiling* pTiling); void _create_pipeline_cache (VkvgDevice dev); VkRenderPass _createRenderPassMS(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp); VkRenderPass _createRenderPassNoResolve(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp); diff --git a/src/vkvg_internal.h b/src/vkvg_internal.h index a21298e..1922614 100644 --- a/src/vkvg_internal.h +++ b/src/vkvg_internal.h @@ -36,15 +36,15 @@ #define M_PIF_2 1.57079632679489661923f /*#ifndef M_2_PI - #define M_2_PI 0.63661977236758134308 // 2/pi + #define M_2_PI 0.63661977236758134308 // 2/pi #endif*/ #define PATH_CLOSED_BIT 0x80000000 /* most significant bit of path elmts is closed/open path state */ #define PATH_HAS_CURVES_BIT 0x40000000 /* 2d most significant bit of path elmts start = true if curve data are present, - stored to avoid emiting join in curves */ + stored to avoid emiting join in curves */ #define PATH_IS_CURVE_BIT 0x80000000 /* most significant bit of path elmts end mark curves data in path array */ #define PATH_IS_CONCAVE_BIT 0x40000000 /* 2d most significant bit of path elmts end = true if path is simple concave - triangulation for fill may be simplified*/ + triangulation for fill may be simplified*/ #define PATH_ELT_MASK 0x3FFFFFFF /* Bit mask for fetching path element value */ #define ROUNDF(f, c) (((float)((int)((f) * (c))) / (c))) @@ -60,5 +60,6 @@ //used to store clipping bit on context saving. 8 bit stencil will allow 6 save/restore layer #define FB_STENCIL_FORMAT VK_FORMAT_S8_UINT #define FB_COLOR_FORMAT VK_FORMAT_B8G8R8A8_UNORM +#define VKVG_SURFACE_IMGS_REQUIREMENTS VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT #define VKVG_FENCE_TIMEOUT UINT64_MAX #endif diff --git a/src/vkvg_surface.c b/src/vkvg_surface.c index 183df2b..a106618 100644 --- a/src/vkvg_surface.c +++ b/src/vkvg_surface.c @@ -32,453 +32,475 @@ #include "nanosvg.h" void _explicit_ms_resolve (VkvgSurface surf){ - VkvgDevice dev = surf->dev; - VkCommandBuffer cmd = dev->cmd; - - _wait_and_reset_device_fence (dev); - - vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); - vkh_image_set_layout (cmd, surf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - vkh_image_set_layout (cmd, surf->img, VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - - VkImageResolve re = { - .extent = {surf->width, surf->height,1}, - .srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1}, - .dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1} - }; - - vkCmdResolveImage(cmd, - vkh_image_get_vkimage (surf->imgMS), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - vkh_image_get_vkimage (surf->img) ,VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1,&re); - vkh_image_set_layout (cmd, surf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT, - 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); - vkh_cmd_end (cmd); - - _submit_cmd (dev, &cmd, dev->fence); + VkvgDevice dev = surf->dev; + VkCommandBuffer cmd = dev->cmd; + + _wait_and_reset_device_fence (dev); + + vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + vkh_image_set_layout (cmd, surf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + vkh_image_set_layout (cmd, surf->img, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + + VkImageResolve re = { + .extent = {surf->width, surf->height,1}, + .srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1}, + .dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1} + }; + + vkCmdResolveImage(cmd, + vkh_image_get_vkimage (surf->imgMS), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + vkh_image_get_vkimage (surf->img) ,VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1,&re); + vkh_image_set_layout (cmd, surf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT, + 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); + vkh_cmd_end (cmd); + + _submit_cmd (dev, &cmd, dev->fence); } void _clear_surface (VkvgSurface surf, VkImageAspectFlags aspect) { - VkvgDevice dev = surf->dev; - VkCommandBuffer cmd = dev->cmd; + VkvgDevice dev = surf->dev; + VkCommandBuffer cmd = dev->cmd; - _wait_and_reset_device_fence (dev); + _wait_and_reset_device_fence (dev); - vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); - if (aspect & VK_IMAGE_ASPECT_COLOR_BIT) { - VkClearColorValue cclr = {{0,0,0,0}}; - VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT,0,1,0,1}; + if (aspect & VK_IMAGE_ASPECT_COLOR_BIT) { + VkClearColorValue cclr = {{0,0,0,0}}; + VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT,0,1,0,1}; - VkhImage img = surf->imgMS; - if (surf->dev->samples == VK_SAMPLE_COUNT_1_BIT) - img = surf->img; + VkhImage img = surf->imgMS; + if (surf->dev->samples == VK_SAMPLE_COUNT_1_BIT) + img = surf->img; - vkh_image_set_layout (cmd, img, VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + vkh_image_set_layout (cmd, img, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - vkCmdClearColorImage(cmd, vkh_image_get_vkimage (img), - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &cclr, 1, &range); + vkCmdClearColorImage(cmd, vkh_image_get_vkimage (img), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &cclr, 1, &range); - vkh_image_set_layout (cmd, img, VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); - } - if (aspect & VK_IMAGE_ASPECT_STENCIL_BIT) { - VkClearDepthStencilValue clr = {0,0}; - VkImageSubresourceRange range = {VK_IMAGE_ASPECT_STENCIL_BIT,0,1,0,1}; + vkh_image_set_layout (cmd, img, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); + } + if (aspect & VK_IMAGE_ASPECT_STENCIL_BIT) { + VkClearDepthStencilValue clr = {0,0}; + VkImageSubresourceRange range = {VK_IMAGE_ASPECT_STENCIL_BIT,0,1,0,1}; - vkh_image_set_layout (cmd, surf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + vkh_image_set_layout (cmd, surf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - vkCmdClearDepthStencilImage (cmd, vkh_image_get_vkimage (surf->stencil), - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,&clr,1,&range); + vkCmdClearDepthStencilImage (cmd, vkh_image_get_vkimage (surf->stencil), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,&clr,1,&range); - vkh_image_set_layout (cmd, surf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT); - } - vkh_cmd_end (cmd); + vkh_image_set_layout (cmd, surf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT); + } + vkh_cmd_end (cmd); - _submit_cmd (dev, &cmd, dev->fence); + _submit_cmd (dev, &cmd, dev->fence); } void _create_surface_main_image (VkvgSurface surf){ - surf->img = vkh_image_create((VkhDevice)surf->dev,surf->format,surf->width,surf->height,VKVG_TILING,VMA_MEMORY_USAGE_GPU_ONLY, - VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT); - vkh_image_create_descriptor(surf->img, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE); + surf->img = vkh_image_create((VkhDevice)surf->dev,surf->format,surf->width,surf->height,surf->tiling,VMA_MEMORY_USAGE_GPU_ONLY, + VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT); + vkh_image_create_descriptor(surf->img, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE); #ifdef DEBUG - vkh_image_set_name(surf->img, "SURF main color"); - vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)vkh_image_get_view(surf->img), "SURF main color VIEW"); - vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_SAMPLER, (uint64_t)vkh_image_get_sampler(surf->img), "SURF main color SAMPLER"); + vkh_image_set_name(surf->img, "SURF main color"); + vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)vkh_image_get_view(surf->img), "SURF main color VIEW"); + vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_SAMPLER, (uint64_t)vkh_image_get_sampler(surf->img), "SURF main color SAMPLER"); #endif } //create multisample color img if sample count > 1 and the stencil buffer multisampled or not void _create_surface_secondary_images (VkvgSurface surf) { - if (surf->dev->samples > VK_SAMPLE_COUNT_1_BIT){ - surf->imgMS = vkh_image_ms_create((VkhDevice)surf->dev,surf->format,surf->dev->samples,surf->width,surf->height,VMA_MEMORY_USAGE_GPU_ONLY, - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT); - vkh_image_create_descriptor(surf->imgMS, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, VK_FILTER_NEAREST, - VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE); + if (surf->dev->samples > VK_SAMPLE_COUNT_1_BIT){ + surf->imgMS = vkh_image_ms_create((VkhDevice)surf->dev,surf->format,surf->dev->samples,surf->width,surf->height,VMA_MEMORY_USAGE_GPU_ONLY, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT); + vkh_image_create_descriptor(surf->imgMS, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, VK_FILTER_NEAREST, + VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE); #ifdef DEBUG - vkh_image_set_name(surf->imgMS, "SURF MS color IMG"); - vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)vkh_image_get_view(surf->imgMS), "SURF MS color VIEW"); - vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_SAMPLER, (uint64_t)vkh_image_get_sampler(surf->imgMS), "SURF MS color SAMPLER"); + vkh_image_set_name(surf->imgMS, "SURF MS color IMG"); + vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)vkh_image_get_view(surf->imgMS), "SURF MS color VIEW"); + vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_SAMPLER, (uint64_t)vkh_image_get_sampler(surf->imgMS), "SURF MS color SAMPLER"); #endif - } - surf->stencil = vkh_image_ms_create((VkhDevice)surf->dev,FB_STENCIL_FORMAT,surf->dev->samples,surf->width,surf->height,VMA_MEMORY_USAGE_GPU_ONLY, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT); - vkh_image_create_descriptor(surf->stencil, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_STENCIL_BIT, VK_FILTER_NEAREST, - VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE); + } + surf->stencil = vkh_image_ms_create((VkhDevice)surf->dev,FB_STENCIL_FORMAT,surf->dev->samples,surf->width,surf->height,VMA_MEMORY_USAGE_GPU_ONLY, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT); + vkh_image_create_descriptor(surf->stencil, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_STENCIL_BIT, VK_FILTER_NEAREST, + VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE); #ifdef DEBUG - vkh_image_set_name(surf->stencil, "SURF stencil"); - vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)vkh_image_get_view(surf->stencil), "SURF stencil VIEW"); - vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_SAMPLER, (uint64_t)vkh_image_get_sampler(surf->stencil), "SURF stencil SAMPLER"); + vkh_image_set_name(surf->stencil, "SURF stencil"); + vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)vkh_image_get_view(surf->stencil), "SURF stencil VIEW"); + vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_SAMPLER, (uint64_t)vkh_image_get_sampler(surf->stencil), "SURF stencil SAMPLER"); #endif } void _create_framebuffer (VkvgSurface surf) { - VkImageView attachments[] = { - vkh_image_get_view (surf->img), - vkh_image_get_view (surf->stencil), - vkh_image_get_view (surf->imgMS), - }; - VkFramebufferCreateInfo frameBufferCreateInfo = { .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, - .renderPass = surf->dev->renderPass, - .attachmentCount = 3, - .pAttachments = attachments, - .width = surf->width, - .height = surf->height, - .layers = 1 }; - if (surf->dev->samples == VK_SAMPLE_COUNT_1_BIT) - frameBufferCreateInfo.attachmentCount = 2; - else if (surf->dev->deferredResolve) { - attachments[0] = attachments[2]; - frameBufferCreateInfo.attachmentCount = 2; - } - VK_CHECK_RESULT(vkCreateFramebuffer(surf->dev->vkDev, &frameBufferCreateInfo, NULL, &surf->fb)); + VkImageView attachments[] = { + vkh_image_get_view (surf->img), + vkh_image_get_view (surf->stencil), + vkh_image_get_view (surf->imgMS), + }; + VkFramebufferCreateInfo frameBufferCreateInfo = { .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + .renderPass = surf->dev->renderPass, + .attachmentCount = 3, + .pAttachments = attachments, + .width = surf->width, + .height = surf->height, + .layers = 1 }; + if (surf->dev->samples == VK_SAMPLE_COUNT_1_BIT) + frameBufferCreateInfo.attachmentCount = 2; + else if (surf->dev->deferredResolve) { + attachments[0] = attachments[2]; + frameBufferCreateInfo.attachmentCount = 2; + } + VK_CHECK_RESULT(vkCreateFramebuffer(surf->dev->vkDev, &frameBufferCreateInfo, NULL, &surf->fb)); #ifdef DEBUG - vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_FRAMEBUFFER, (uint64_t)surf->fb, "SURF FB"); + vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_FRAMEBUFFER, (uint64_t)surf->fb, "SURF FB"); #endif } -void _init_surface (VkvgSurface surf) { - surf->format = FB_COLOR_FORMAT;//force bgra internally +void _create_surface_images (VkvgSurface surf) { - _create_surface_main_image (surf); - _create_surface_secondary_images (surf); - _create_framebuffer (surf); + _create_surface_main_image (surf); + _create_surface_secondary_images(surf); + _create_framebuffer (surf); - _clear_surface (surf, VK_IMAGE_ASPECT_STENCIL_BIT); + _clear_surface (surf, VK_IMAGE_ASPECT_STENCIL_BIT); #if defined(DEBUG) && defined(ENABLE_VALIDATION) - vkh_image_set_name(surf->img, "surfImg"); - vkh_image_set_name(surf->imgMS, "surfImgMS"); - vkh_image_set_name(surf->stencil, "surfStencil"); + vkh_image_set_name(surf->img, "surfImg"); + vkh_image_set_name(surf->imgMS, "surfImgMS"); + vkh_image_set_name(surf->stencil, "surfStencil"); #endif } +VkvgSurface _create_surface (VkvgDevice dev, VkFormat format) { + VkImageTiling tiling; + if (!_get_best_image_tiling (dev, format, &tiling)) { + dev->status = VKVG_STATUS_INVALID_FORMAT; + return NULL; + } + + VkvgSurface surf = (vkvg_surface*)calloc(1,sizeof(vkvg_surface)); + if (!surf) { + dev->status = VKVG_STATUS_NO_MEMORY; + return NULL; + } + + surf->dev = dev; + surf->format = format; + surf->tiling = tiling; + + dev->status = VKVG_STATUS_SUCCESS; + return surf; +} + void vkvg_surface_clear (VkvgSurface surf) { - _clear_surface(surf, VK_IMAGE_ASPECT_STENCIL_BIT|VK_IMAGE_ASPECT_COLOR_BIT); + _clear_surface(surf, VK_IMAGE_ASPECT_STENCIL_BIT|VK_IMAGE_ASPECT_COLOR_BIT); } VkvgSurface vkvg_surface_create(VkvgDevice dev, uint32_t width, uint32_t height){ - VkvgSurface surf = (vkvg_surface*)calloc(1,sizeof(vkvg_surface)); + VkvgSurface surf = _create_surface(dev, FB_COLOR_FORMAT); + if (!surf) + return NULL; - surf->dev = dev; - surf->width = width; - surf->height = height; - surf->new = true;//used to clear all attacments on first render pass + surf->width = width; + surf->height = height; + surf->new = true;//used to clear all attacments on first render pass - _init_surface (surf); + _create_surface_images (surf); - surf->references = 1; - vkvg_device_reference (surf->dev); + surf->references = 1; + vkvg_device_reference (surf->dev); - return surf; + return surf; } VkvgSurface vkvg_surface_create_for_VkhImage (VkvgDevice dev, void* vkhImg) { - VkhImage img = (VkhImage)vkhImg; - VkvgSurface surf = (vkvg_surface*)calloc(1,sizeof(vkvg_surface)); + VkvgSurface surf = _create_surface(dev, FB_COLOR_FORMAT); + if (!surf) + return NULL; - surf->format = FB_COLOR_FORMAT;//force bgra internally - surf->dev = dev; - surf->width = img->infos.extent.width; - surf->height= img->infos.extent.height; + VkhImage img = (VkhImage)vkhImg; + surf->width = img->infos.extent.width; + surf->height= img->infos.extent.height; - surf->img = img; + surf->img = img; - vkh_image_create_sampler(img, VK_FILTER_NEAREST, VK_FILTER_NEAREST, - VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE); + vkh_image_create_sampler(img, VK_FILTER_NEAREST, VK_FILTER_NEAREST, + VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE); - _create_surface_secondary_images (surf); - _create_framebuffer (surf); - _clear_surface (surf, VK_IMAGE_ASPECT_STENCIL_BIT); + _create_surface_secondary_images (surf); + _create_framebuffer (surf); + _clear_surface (surf, VK_IMAGE_ASPECT_STENCIL_BIT); - surf->references = 1; - vkvg_device_reference (surf->dev); + surf->references = 1; + vkvg_device_reference (surf->dev); - return surf; + return surf; } //TODO: it would be better to blit in original size and create ms final image with dest surf dims VkvgSurface vkvg_surface_create_from_bitmap (VkvgDevice dev, unsigned char* img, uint32_t width, uint32_t height) { - VkvgSurface surf = (vkvg_surface*)calloc(1,sizeof(vkvg_surface)); - - surf->dev = dev; - surf->width = width; - surf->height = height; - - _init_surface (surf); - _clear_surface(surf, VK_IMAGE_ASPECT_COLOR_BIT); - - uint32_t imgSize = width * height * 4; - VkImageSubresourceLayers imgSubResLayers = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1}; - //original format image - VkhImage stagImg= vkh_image_create ((VkhDevice)surf->dev,VK_FORMAT_R8G8B8A8_UNORM,surf->width,surf->height,VK_IMAGE_TILING_LINEAR, - VMA_MEMORY_USAGE_GPU_ONLY, - VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT); - //bgra bliting target - VkhImage tmpImg = vkh_image_create ((VkhDevice)surf->dev,surf->format,surf->width,surf->height,VK_IMAGE_TILING_LINEAR, - VMA_MEMORY_USAGE_GPU_ONLY, - VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT); - vkh_image_create_descriptor (tmpImg, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, - VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER); - //staging buffer - vkvg_buff buff = {0}; - vkvg_buffer_create(dev, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU, imgSize, &buff); - - memcpy (buff.allocInfo.pMappedData, img, imgSize); - - VkCommandBuffer cmd = dev->cmd; - - _wait_and_reset_device_fence (dev); - - vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); - vkh_image_set_layout (cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - - - VkBufferImageCopy bufferCopyRegion = { .imageSubresource = imgSubResLayers, - .imageExtent = {surf->width,surf->height,1}}; - - vkCmdCopyBufferToImage(cmd, buff.buffer, - vkh_image_get_vkimage (stagImg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferCopyRegion); - - vkh_image_set_layout (cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - vkh_image_set_layout (cmd, tmpImg, 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); - - VkImageBlit blit = { - .srcSubresource = imgSubResLayers, - .srcOffsets[1] = {(int32_t)surf->width, (int32_t)surf->height, 1}, - .dstSubresource = imgSubResLayers, - .dstOffsets[1] = {(int32_t)surf->width, (int32_t)surf->height, 1}, - }; - vkCmdBlitImage (cmd, - vkh_image_get_vkimage (stagImg), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - vkh_image_get_vkimage (tmpImg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_LINEAR); - - vkh_image_set_layout (cmd, tmpImg, VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); - - vkh_cmd_end (cmd); - _submit_cmd (dev, &cmd, dev->fence); - - //don't reset fence after completion as this is the last cmd. (signaled idle fence) - vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX); - - vkvg_buffer_destroy (&buff); - vkh_image_destroy (stagImg); - - //create tmp context with rendering pipeline to create the multisample img - VkvgContext ctx = vkvg_create (surf); + VkvgSurface surf = _create_surface(dev, FB_COLOR_FORMAT); + if (!surf) + return NULL; + + surf->width = width; + surf->height = height; + + _create_surface_images (surf); + _clear_surface(surf, VK_IMAGE_ASPECT_COLOR_BIT); + + uint32_t imgSize = width * height * 4; + VkImageSubresourceLayers imgSubResLayers = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1}; + //original format image + VkhImage stagImg= vkh_image_create ((VkhDevice)surf->dev,VK_FORMAT_R8G8B8A8_UNORM,surf->width,surf->height,VK_IMAGE_TILING_LINEAR, + VMA_MEMORY_USAGE_GPU_ONLY, + VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT); + //bgra bliting target + VkhImage tmpImg = vkh_image_create ((VkhDevice)surf->dev,surf->format,surf->width,surf->height,VK_IMAGE_TILING_LINEAR, + VMA_MEMORY_USAGE_GPU_ONLY, + VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT); + vkh_image_create_descriptor (tmpImg, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, + VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER); + //staging buffer + vkvg_buff buff = {0}; + vkvg_buffer_create(dev, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU, imgSize, &buff); + + memcpy (buff.allocInfo.pMappedData, img, imgSize); + + VkCommandBuffer cmd = dev->cmd; + + _wait_and_reset_device_fence (dev); + + vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + vkh_image_set_layout (cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + + + VkBufferImageCopy bufferCopyRegion = { .imageSubresource = imgSubResLayers, + .imageExtent = {surf->width,surf->height,1}}; + + vkCmdCopyBufferToImage(cmd, buff.buffer, + vkh_image_get_vkimage (stagImg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferCopyRegion); + + vkh_image_set_layout (cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + vkh_image_set_layout (cmd, tmpImg, 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); + + VkImageBlit blit = { + .srcSubresource = imgSubResLayers, + .srcOffsets[1] = {(int32_t)surf->width, (int32_t)surf->height, 1}, + .dstSubresource = imgSubResLayers, + .dstOffsets[1] = {(int32_t)surf->width, (int32_t)surf->height, 1}, + }; + vkCmdBlitImage (cmd, + vkh_image_get_vkimage (stagImg), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + vkh_image_get_vkimage (tmpImg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_LINEAR); + + vkh_image_set_layout (cmd, tmpImg, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + + vkh_cmd_end (cmd); + _submit_cmd (dev, &cmd, dev->fence); + + //don't reset fence after completion as this is the last cmd. (signaled idle fence) + vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX); + + vkvg_buffer_destroy (&buff); + vkh_image_destroy (stagImg); + + //create tmp context with rendering pipeline to create the multisample img + VkvgContext ctx = vkvg_create (surf); /* VkClearAttachment ca = {VK_IMAGE_ASPECT_COLOR_BIT,0, { 0.0f, 0.0f, 0.0f, 0.0f }}; - VkClearRect cr = {{{0,0},{surf->width,surf->height}},0,1}; - vkCmdClearAttachments(ctx->cmd, 1, &ca, 1, &cr);*/ + VkClearRect cr = {{{0,0},{surf->width,surf->height}},0,1}; + vkCmdClearAttachments(ctx->cmd, 1, &ca, 1, &cr);*/ - vec4 srcRect = {.x=0,.y=0,.width=surf->width,.height=surf->height}; - ctx->pushConsts.source = srcRect; - ctx->pushConsts.patternType = VKVG_PATTERN_TYPE_SURFACE; + vec4 srcRect = {.x=0,.y=0,.width=surf->width,.height=surf->height}; + ctx->pushConsts.source = srcRect; + ctx->pushConsts.patternType = VKVG_PATTERN_TYPE_SURFACE; - //_update_push_constants (ctx); - _update_descriptor_set (ctx, tmpImg, ctx->dsSrc); - _check_cmd_buff_state (ctx); + //_update_push_constants (ctx); + _update_descriptor_set (ctx, tmpImg, ctx->dsSrc); + _check_cmd_buff_state (ctx); - vkvg_paint (ctx); - vkvg_destroy (ctx); + vkvg_paint (ctx); + vkvg_destroy (ctx); - vkh_image_destroy (tmpImg); + vkh_image_destroy (tmpImg); - surf->references = 1; - vkvg_device_reference (surf->dev); + surf->references = 1; + vkvg_device_reference (surf->dev); - return surf; + return surf; } VkvgSurface vkvg_surface_create_from_image (VkvgDevice dev, const char* filePath) { - int w = 0, - h = 0, - channels = 0; - unsigned char *img = stbi_load(filePath, &w, &h, &channels, 4);//force 4 components per pixel - if (img == NULL){ - fprintf (stderr, "Could not load texture from %s, %s\n", filePath, stbi_failure_reason()); - return NULL; - } + int w = 0, + h = 0, + channels = 0; + unsigned char *img = stbi_load(filePath, &w, &h, &channels, 4);//force 4 components per pixel + if (img == NULL){ + fprintf (stderr, "Could not load texture from %s, %s\n", filePath, stbi_failure_reason()); + return NULL; + } - VkvgSurface surf = vkvg_surface_create_from_bitmap(dev, img, (uint32_t)w, (uint32_t)h); + VkvgSurface surf = vkvg_surface_create_from_bitmap(dev, img, (uint32_t)w, (uint32_t)h); - stbi_image_free (img); + stbi_image_free (img); - return surf; + return surf; } void _svg_set_color (VkvgContext ctx, uint32_t c, float alpha) { - float a = (c >> 24 & 255) / 255.f; - float b = (c >> 16 & 255) / 255.f; - float g = (c >> 8 & 255) / 255.f; - float r = (c & 255) / 255.f; - vkvg_set_source_rgba(ctx,r,g,b,a*alpha); + float a = (c >> 24 & 255) / 255.f; + float b = (c >> 16 & 255) / 255.f; + float g = (c >> 8 & 255) / 255.f; + float r = (c & 255) / 255.f; + vkvg_set_source_rgba(ctx,r,g,b,a*alpha); } VkvgSurface _svg_load (VkvgDevice dev, NSVGimage* svg) { + VkvgSurface surf = _create_surface(dev, FB_COLOR_FORMAT); + if (!surf) + return NULL; - VkvgSurface surf = (vkvg_surface*)calloc(1,sizeof(vkvg_surface)); - - surf->dev = dev; - surf->width = (uint32_t)svg->width; - surf->height = (uint32_t)svg->height; - surf->new = true; + surf->width = (uint32_t)svg->width; + surf->height = (uint32_t)svg->height; + surf->new = true; - _init_surface (surf); + _create_surface_images (surf); - VkvgContext ctx = vkvg_create(surf); - vkvg_render_svg(ctx, svg, NULL); - vkvg_destroy(ctx); + VkvgContext ctx = vkvg_create(surf); + vkvg_render_svg(ctx, svg, NULL); + vkvg_destroy(ctx); - nsvgDelete(svg); + nsvgDelete(svg); - surf->references = 1; - vkvg_device_reference (surf->dev); + surf->references = 1; + vkvg_device_reference (surf->dev); - return surf; + return surf; } VkvgSurface vkvg_surface_create_from_svg (VkvgDevice dev, const char* filePath) { - return _svg_load(dev, nsvgParseFromFile(filePath, "px", dev->hdpi)); + return _svg_load(dev, nsvgParseFromFile(filePath, "px", dev->hdpi)); } VkvgSurface vkvg_surface_create_from_svg_fragment (VkvgDevice dev, char* fragment) { - return _svg_load(dev, nsvgParse(fragment, "px", dev->hdpi)); + return _svg_load(dev, nsvgParse(fragment, "px", dev->hdpi)); } NSVGimage* nsvg_load_file (VkvgDevice dev, const char* filePath) { - return nsvgParseFromFile(filePath, "px", dev->hdpi); + return nsvgParseFromFile(filePath, "px", dev->hdpi); } NSVGimage* nsvg_load (VkvgDevice dev, char* fragment) { - return nsvgParse (fragment, "px", dev->hdpi); + return nsvgParse (fragment, "px", dev->hdpi); } void nsvg_destroy (NSVGimage* svg) { - nsvgDelete(svg); + nsvgDelete(svg); } void nsvg_get_size (NSVGimage* svg, int* width, int* height) { - *width = (int)svg->width; - *height = (int)svg->height; + *width = (int)svg->width; + *height = (int)svg->height; } void vkvg_surface_destroy(VkvgSurface surf) { - surf->references--; - if (surf->references > 0) - return; - vkDestroyFramebuffer(surf->dev->vkDev, surf->fb, NULL); + surf->references--; + if (surf->references > 0) + return; + vkDestroyFramebuffer(surf->dev->vkDev, surf->fb, NULL); - if (!surf->img->imported) - vkh_image_destroy(surf->img); + if (!surf->img->imported) + vkh_image_destroy(surf->img); - vkh_image_destroy(surf->imgMS); - vkh_image_destroy(surf->stencil); + vkh_image_destroy(surf->imgMS); + vkh_image_destroy(surf->stencil); - vkvg_device_destroy (surf->dev); - free(surf); + vkvg_device_destroy (surf->dev); + free(surf); } VkvgSurface vkvg_surface_reference (VkvgSurface surf) { - surf->references++; - return surf; + surf->references++; + return surf; } uint32_t vkvg_surface_get_reference_count (VkvgSurface surf) { - return surf->references; + return surf->references; } VkImage vkvg_surface_get_vk_image(VkvgSurface surf) { - if (surf->dev->deferredResolve) - _explicit_ms_resolve(surf); - return vkh_image_get_vkimage (surf->img); + if (surf->dev->deferredResolve) + _explicit_ms_resolve(surf); + return vkh_image_get_vkimage (surf->img); } void vkvg_multisample_surface_resolve (VkvgSurface surf){ - _explicit_ms_resolve(surf); + _explicit_ms_resolve(surf); } VkFormat vkvg_surface_get_vk_format(VkvgSurface surf) { - return surf->format; + return surf->format; } uint32_t vkvg_surface_get_width (VkvgSurface surf) { - return surf->width; + return surf->width; } uint32_t vkvg_surface_get_height (VkvgSurface surf) { - return surf->height; + return surf->height; } void vkvg_surface_write_to_png (VkvgSurface surf, const char* path){ - uint32_t stride = surf->width * 4; - VkImageSubresourceLayers imgSubResLayers = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1}; - VkvgDevice dev = surf->dev; - - //RGBA to blit to, surf img is bgra - VkhImage stagImg= vkh_image_create ((VkhDevice)surf->dev,VK_FORMAT_R8G8B8A8_UNORM,surf->width,surf->height,VK_IMAGE_TILING_LINEAR, - VMA_MEMORY_USAGE_GPU_TO_CPU, - VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT); - - VkCommandBuffer cmd = dev->cmd; - _wait_and_reset_device_fence (dev); - - vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); - vkh_image_set_layout (cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - vkh_image_set_layout (cmd, surf->img, VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - - VkImageBlit blit = { - .srcSubresource = imgSubResLayers, - .srcOffsets[1] = {(int32_t)surf->width, (int32_t)surf->height, 1}, - .dstSubresource = imgSubResLayers, - .dstOffsets[1] = {(int32_t)surf->width, (int32_t)surf->height, 1}, - }; - vkCmdBlitImage (cmd, - vkh_image_get_vkimage (surf->img), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - vkh_image_get_vkimage (stagImg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_NEAREST); - - vkh_cmd_end (cmd); - _submit_cmd (dev, &cmd, dev->fence); - vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX); - - void* img = vkh_image_map (stagImg); - - stbi_write_png (path, (int32_t)surf->width, (int32_t)surf->height, 4, img, (int32_t)stride); - - vkh_image_unmap (stagImg); - vkh_image_destroy (stagImg); + uint32_t stride = surf->width * 4; + VkImageSubresourceLayers imgSubResLayers = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1}; + VkvgDevice dev = surf->dev; + + //RGBA to blit to, surf img is bgra + VkhImage stagImg= vkh_image_create ((VkhDevice)surf->dev,VK_FORMAT_R8G8B8A8_UNORM,surf->width,surf->height,VK_IMAGE_TILING_LINEAR, + VMA_MEMORY_USAGE_GPU_TO_CPU, + VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT); + + VkCommandBuffer cmd = dev->cmd; + _wait_and_reset_device_fence (dev); + + vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + vkh_image_set_layout (cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + vkh_image_set_layout (cmd, surf->img, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + + VkImageBlit blit = { + .srcSubresource = imgSubResLayers, + .srcOffsets[1] = {(int32_t)surf->width, (int32_t)surf->height, 1}, + .dstSubresource = imgSubResLayers, + .dstOffsets[1] = {(int32_t)surf->width, (int32_t)surf->height, 1}, + }; + vkCmdBlitImage (cmd, + vkh_image_get_vkimage (surf->img), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + vkh_image_get_vkimage (stagImg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_NEAREST); + + vkh_cmd_end (cmd); + _submit_cmd (dev, &cmd, dev->fence); + vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX); + + void* img = vkh_image_map (stagImg); + + stbi_write_png (path, (int32_t)surf->width, (int32_t)surf->height, 4, img, (int32_t)stride); + + vkh_image_unmap (stagImg); + vkh_image_destroy (stagImg); } /*VkhImage vkvg_surface_get_vkh_image(VkvgSurface surf) { - return surf->img; + return surf->img; }*/ diff --git a/src/vkvg_surface_internal.h b/src/vkvg_surface_internal.h index c3fe682..935c132 100644 --- a/src/vkvg_surface_internal.h +++ b/src/vkvg_surface_internal.h @@ -27,16 +27,17 @@ #include "vkh.h" typedef struct _vkvg_surface_t { - VkvgDevice dev; - uint32_t width; - uint32_t height; - VkFormat format; - VkFramebuffer fb; - VkhImage img; - VkhImage imgMS; - VkhImage stencil; - uint32_t references; - bool new; + VkvgDevice dev; + uint32_t width; + uint32_t height; + VkFormat format; + VkImageTiling tiling; /**< optimal is prefered if supported */ + VkFramebuffer fb; + VkhImage img; + VkhImage imgMS; + VkhImage stencil; + uint32_t references; + bool new; }vkvg_surface; void _clear_surface (VkvgSurface surf, VkImageAspectFlags aspect); diff --git a/tests/common/test.c b/tests/common/test.c index 85c9df0..b62c3d1 100644 --- a/tests/common/test.c +++ b/tests/common/test.c @@ -3,22 +3,22 @@ #if defined(_WIN32) || defined(_WIN64) int gettimeofday(struct timeval * tp, struct timezone * tzp) { - // FILETIME Jan 1 1970 00:00:00 - // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's - static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL); - - SYSTEMTIME nSystemTime; - FILETIME nFileTime; - uint64_t nTime; - - GetSystemTime( &nSystemTime ); - SystemTimeToFileTime( &nSystemTime, &nFileTime ); - nTime = ((uint64_t)nFileTime.dwLowDateTime ) ; - nTime += ((uint64_t)nFileTime.dwHighDateTime) << 32; - - tp->tv_sec = (long) ((nTime - EPOCH) / 10000000L); - tp->tv_usec = (long) (nSystemTime.wMilliseconds * 1000); - return 0; + // FILETIME Jan 1 1970 00:00:00 + // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's + static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL); + + SYSTEMTIME nSystemTime; + FILETIME nFileTime; + uint64_t nTime; + + GetSystemTime( &nSystemTime ); + SystemTimeToFileTime( &nSystemTime, &nFileTime ); + nTime = ((uint64_t)nFileTime.dwLowDateTime ) ; + nTime += ((uint64_t)nFileTime.dwHighDateTime) << 32; + + tp->tv_sec = (long) ((nTime - EPOCH) / 10000000L); + tp->tv_usec = (long) (nSystemTime.wMilliseconds * 1000); + return 0; } #endif @@ -40,170 +40,168 @@ static VkSampleCountFlags samples = VK_SAMPLE_COUNT_8_BIT; 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; - } + if (action != GLFW_PRESS) + return; + switch (key) { + case GLFW_KEY_SPACE: + paused = !paused; + break; + 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){ - if (mouseDown) { - panX += ((float)x-lastX); - panY += ((float)y-lastY); - } - lastX = (float)x; - lastY = (float)y; + if (mouseDown) { + panX += ((float)x-lastX); + panY += ((float)y-lastY); + } + lastX = (float)x; + lastY = (float)y; } static void scroll_callback(GLFWwindow* window, double x, double y){ - if (y<0.f) - zoom *= 0.5f; - else - zoom *= 2.0f; + if (y<0.f) + zoom *= 0.5f; + else + zoom *= 2.0f; } static void mouse_button_callback(GLFWwindow* window, int but, int state, int modif){ - if (but != GLFW_MOUSE_BUTTON_1) - return; - if (state == GLFW_TRUE) - mouseDown = true; - else - mouseDown = false; + if (but != GLFW_MOUSE_BUTTON_1) + return; + if (state == GLFW_TRUE) + mouseDown = true; + else + mouseDown = false; } double time_diff(struct timeval x , struct timeval y) { - double x_ms , y_ms , diff; + double x_ms , y_ms , diff; - x_ms = (double)x.tv_sec*1000000 + (double)x.tv_usec; - y_ms = (double)y.tv_sec*1000000 + (double)y.tv_usec; + x_ms = (double)x.tv_sec*1000000 + (double)x.tv_usec; + y_ms = (double)y.tv_sec*1000000 + (double)y.tv_usec; - diff = (double)y_ms - (double)x_ms; + diff = (double)y_ms - (double)x_ms; - return diff; + return diff; } void randomize_color (VkvgContext ctx) { - vkvg_set_source_rgba(ctx, - (float)rand()/RAND_MAX, - (float)rand()/RAND_MAX, - (float)rand()/RAND_MAX, - (float)rand()/RAND_MAX - ); + vkvg_set_source_rgba(ctx, + (float)rand()/RAND_MAX, + (float)rand()/RAND_MAX, + (float)rand()/RAND_MAX, + (float)rand()/RAND_MAX + ); } /* from caskbench */ double get_tick (void) { - struct timeval now; - gettimeofday (&now, NULL); - return (double)now.tv_sec + (double)now.tv_usec / 1000000.0; + 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 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); + 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 (uint32_t width, uint32_t height){ - e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_MAILBOX_KHR, width, height); - VkhPresenter r = e->renderer; - vkengine_set_key_callback (e, key_callback); - vkengine_set_mouse_but_callback(e, mouse_button_callback); - vkengine_set_cursor_pos_callback(e, mouse_move_callback); - vkengine_set_scroll_callback(e, scroll_callback); + e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_MAILBOX_KHR, width, height); + VkhPresenter r = e->renderer; + vkengine_set_key_callback (e, key_callback); + vkengine_set_mouse_but_callback(e, mouse_button_callback); + vkengine_set_cursor_pos_callback(e, mouse_move_callback); + vkengine_set_scroll_callback(e, scroll_callback); - bool deferredResolve = false; + bool deferredResolve = false; - device = vkvg_device_create_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0, samples, deferredResolve); + device = vkvg_device_create_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0, samples, deferredResolve); - vkvg_device_set_dpy(device, 96, 96); + vkvg_device_set_dpy(device, 96, 96); - surf = vkvg_surface_create(device, width, height); + surf = vkvg_surface_create(device, width, height); - vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height); + vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height); } void run_test_func (void(*testfunc)(void),uint32_t width, uint32_t height) { - bool deferredResolve = false; - VkhPresenter r = e->renderer; + bool deferredResolve = false; + VkhPresenter r = e->renderer; - double start_time, stop_time, run_time, run_total = 0.0, min_run_time = -1, max_run_time; - double* run_time_values = (double*)malloc(iterations*sizeof(double)); + double start_time, stop_time, run_time, run_total = 0.0, min_run_time = -1, max_run_time; + double* run_time_values = (double*)malloc(iterations*sizeof(double)); - int i = 0; + int i = 0; - while (!vkengine_should_close (e) && i < iterations) { - glfwPollEvents(); + while (!vkengine_should_close (e) && i < iterations) { + glfwPollEvents(); - start_time = get_tick(); + start_time = get_tick(); - if (!paused) - testfunc(); + if (!paused) + testfunc(); - if (deferredResolve) - vkvg_multisample_surface_resolve(surf); - if (!vkh_presenter_draw (r)) - vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height); + if (deferredResolve) + vkvg_multisample_surface_resolve(surf); + if (!vkh_presenter_draw (r)) + vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height); - vkDeviceWaitIdle(e->dev->dev); + stop_time = get_tick(); + run_time = stop_time - start_time; + run_time_values[i] = run_time; - 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++; + } - 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++; - } + double avg_run_time = run_total / (double)i; + double med_run_time = median_run_time (run_time_values, i); + double standard_dev = standard_deviation (run_time_values, i, 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; - double avg_run_time = run_total / (double)i; - double med_run_time = median_run_time (run_time_values, i); - double standard_dev = standard_deviation (run_time_values, i, 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; + free (run_time_values); - free (run_time_values); - - printf ("size:%d iter:%d avgFps: %f avg: %4.2f%% med: %4.2f%% sd: %4.2f%% \n", test_size, i, avg_frames_per_second, avg_run_time, med_run_time, standard_dev); + printf ("size:%d iter:%d avgFps: %f avg: %4.2f%% med: %4.2f%% sd: %4.2f%% \n", test_size, i, avg_frames_per_second, avg_run_time, med_run_time, standard_dev); } void clear_test () { - vkDeviceWaitIdle(e->dev->dev); + vkDeviceWaitIdle(e->dev->dev); - vkvg_surface_destroy (surf); - vkvg_device_destroy (device); + vkvg_surface_destroy (surf); + vkvg_device_destroy (device); - vkengine_destroy (e); + vkengine_destroy (e); } #ifdef VKVG_TEST_DIRECT_DRAW @@ -211,118 +209,116 @@ VkvgSurface* surfaces; #endif void perform_test (void(*testfunc)(void), const char *testName, uint32_t width, uint32_t height) { - //dumpLayerExts(); + //dumpLayerExts(); - e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_MAILBOX_KHR, width, height); - VkhPresenter r = e->renderer; - vkengine_set_key_callback (e, key_callback); - vkengine_set_mouse_but_callback(e, mouse_button_callback); - vkengine_set_cursor_pos_callback(e, mouse_move_callback); - vkengine_set_scroll_callback(e, scroll_callback); + e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_MAILBOX_KHR, width, height); + VkhPresenter r = e->renderer; + vkengine_set_key_callback (e, key_callback); + vkengine_set_mouse_but_callback(e, mouse_button_callback); + vkengine_set_cursor_pos_callback(e, mouse_move_callback); + vkengine_set_scroll_callback(e, scroll_callback); - bool deferredResolve = false; + bool deferredResolve = false; - device = vkvg_device_create_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0, samples, deferredResolve); + device = vkvg_device_create_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0, samples, deferredResolve); - vkvg_device_set_dpy(device, 96, 96); + vkvg_device_set_dpy(device, 96, 96); #ifdef VKVG_TEST_DIRECT_DRAW - surfaces = (VkvgSurface*)malloc(r->imgCount * sizeof (VkvgSurface)); - for (uint32_t i=0; i < r->imgCount;i++) - surfaces[i] = vkvg_surface_create_for_VkhImage (device, r->ScBuffers[i]); + surfaces = (VkvgSurface*)malloc(r->imgCount * sizeof (VkvgSurface)); + for (uint32_t i=0; i < r->imgCount;i++) + surfaces[i] = vkvg_surface_create_for_VkhImage (device, r->ScBuffers[i]); #else - surf = vkvg_surface_create(device, width, height); - vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height); + surf = vkvg_surface_create(device, width, height); + vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height); #endif - double start_time, stop_time, run_time, run_total = 0.0, min_run_time = -1, max_run_time; - double* run_time_values = (double*)malloc(iterations*sizeof(double)); + double start_time, stop_time, run_time, run_total = 0.0, min_run_time = -1, max_run_time; + double* run_time_values = (double*)malloc(iterations*sizeof(double)); - int i = 0; + int i = 0; - vkengine_set_title(e, testName); + vkengine_set_title(e, testName); - while (!vkengine_should_close (e) && i < iterations) { - glfwPollEvents(); + while (!vkengine_should_close (e) && i < iterations) { + glfwPollEvents(); - start_time = get_tick(); + start_time = get_tick(); #ifdef VKVG_TEST_DIRECT_DRAW - if (!vkh_presenter_acquireNextImage(r, NULL, NULL)) { - for (uint32_t i=0; i < r->imgCount;i++) - vkvg_surface_destroy (surfaces[i]); + if (!vkh_presenter_acquireNextImage(r, NULL, NULL)) { + for (uint32_t i=0; i < r->imgCount;i++) + vkvg_surface_destroy (surfaces[i]); - vkh_presenter_create_swapchain (r); + vkh_presenter_create_swapchain (r); - for (uint32_t i=0; i < r->imgCount;i++) - surfaces[i] = vkvg_surface_create_for_VkhImage (device, r->ScBuffers[i]); - }else{ - surf = surfaces[r->currentScBufferIndex]; + for (uint32_t i=0; i < r->imgCount;i++) + surfaces[i] = vkvg_surface_create_for_VkhImage (device, r->ScBuffers[i]); + }else{ + surf = surfaces[r->currentScBufferIndex]; - testfunc(); + testfunc(); - if (deferredResolve) - vkvg_multisample_surface_resolve(surf); + if (deferredResolve) + vkvg_multisample_surface_resolve(surf); - VkPresentInfoKHR present = { .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, - .swapchainCount = 1, - .pSwapchains = &r->swapChain, - .pImageIndices = &r->currentScBufferIndex }; + VkPresentInfoKHR present = { .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, + .swapchainCount = 1, + .pSwapchains = &r->swapChain, + .pImageIndices = &r->currentScBufferIndex }; - vkQueuePresentKHR(r->queue, &present); - } + vkQueuePresentKHR(r->queue, &present); + } #else - if (!paused) - testfunc(); + if (!paused) + testfunc(); - if (deferredResolve) - vkvg_multisample_surface_resolve(surf); - if (!vkh_presenter_draw (r)) - vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height); + if (deferredResolve) + vkvg_multisample_surface_resolve(surf); + if (!vkh_presenter_draw (r)) + vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height); #endif - vkDeviceWaitIdle(e->dev->dev); - - if (paused) - continue; + if (paused) + continue; - stop_time = get_tick(); - run_time = stop_time - start_time; - run_time_values[i] = run_time; + 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++; - } + 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++; + } - double avg_run_time = run_total / (double)i; - double med_run_time = median_run_time (run_time_values, i); - double standard_dev = standard_deviation (run_time_values, i, 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; + double avg_run_time = run_total / (double)i; + double med_run_time = median_run_time (run_time_values, i); + double standard_dev = standard_deviation (run_time_values, i, 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; - free (run_time_values); + free (run_time_values); - printf ("size:%d iter:%d avgFps: %f avg: %4.2f%% med: %4.2f%% sd: %4.2f%% \n", test_size, i, avg_frames_per_second, avg_run_time, med_run_time, standard_dev); + printf ("size:%d iter:%d avgFps: %f avg: %4.2f%% med: %4.2f%% sd: %4.2f%% \n", test_size, i, avg_frames_per_second, avg_run_time, med_run_time, standard_dev); - vkDeviceWaitIdle(e->dev->dev); + vkDeviceWaitIdle(e->dev->dev); #ifdef VKVG_TEST_DIRECT_DRAW - for (uint32_t i=0; iimgCount;i++) - vkvg_surface_destroy (surfaces[i]); + for (uint32_t i=0; iimgCount;i++) + vkvg_surface_destroy (surfaces[i]); - free (surfaces); + free (surfaces); #else - vkvg_surface_destroy (surf); + vkvg_surface_destroy (surf); #endif - vkvg_device_destroy (device); + vkvg_device_destroy (device); - vkengine_destroy (e); + vkengine_destroy (e); } diff --git a/tests/common/vkengine.c b/tests/common/vkengine.c index f1a5c62..4c126c6 100644 --- a/tests/common/vkengine.c +++ b/tests/common/vkengine.c @@ -29,264 +29,264 @@ #include "vkh_device.h" bool vkeCheckPhyPropBlitSource (VkEngine e) { - VkFormatProperties formatProps; - vkGetPhysicalDeviceFormatProperties(e->dev->phy, e->renderer->format, &formatProps); + VkFormatProperties formatProps; + vkGetPhysicalDeviceFormatProperties(e->dev->phy, e->renderer->format, &formatProps); #ifdef VKVG_TILING_OPTIMAL - assert((formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT) && "Format cannot be used as transfer source"); + assert((formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT) && "Format cannot be used as transfer source"); #else - assert((formatProps.linearTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT) && "Format cannot be used as transfer source"); + assert((formatProps.linearTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT) && "Format cannot be used as transfer source"); #endif } 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; + 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 (uint32_t 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 = %lu Mo\n", e->memory_properties.memoryHeaps[i].size/ (uint32_t)(1024*1024)); - } - for (uint32_t 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"); - } + 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 (uint32_t 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 = %lu Mo\n", e->memory_properties.memoryHeaps[i].size/ (uint32_t)(1024*1024)); + } + for (uint32_t 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_dump_available_layers () { - uint32_t layerCount; - vkEnumerateInstanceLayerProperties(&layerCount, NULL); - - VkLayerProperties* availableLayers = (VkLayerProperties*)malloc(layerCount*sizeof(VkLayerProperties)); - vkEnumerateInstanceLayerProperties(&layerCount, availableLayers); - - printf("Available Layers:\n"); - printf("-----------------\n"); - for (uint32_t i=0; iapp = vkh_app_create("vkvgTest", enabledLayersCount, enabledLayers, enabledExtsCount, enabledExts); + e->app = vkh_app_create("vkvgTest", enabledLayersCount, enabledLayers, enabledExtsCount, enabledExts); #ifdef DEBUG - vkh_app_enable_debug_messenger(e->app - , VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT - | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT - | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT - , VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT - | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT - //| VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT - //| VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT - , NULL); + vkh_app_enable_debug_messenger(e->app + , VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT + , VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT + //| VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT + //| VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT + , NULL); #endif - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); - glfwWindowHint(GLFW_FLOATING, GLFW_FALSE); - glfwWindowHint(GLFW_DECORATED, GLFW_TRUE); - - e->window = glfwCreateWindow ((int)width, (int)height, "Window Title", NULL, NULL); - - VkSurfaceKHR surf; - VkResult res = glfwCreateWindowSurface(e->app->inst, e->window, NULL, &surf); - - VkhPhyInfo* phys = vkh_app_get_phyinfos (e->app, &phyCount, surf); - - VkhPhyInfo pi = NULL; - for (int i=0; iproperties.deviceType == preferedGPU) - break; - } - - e->memory_properties = pi->memProps; - e->gpu_props = pi->properties; - - 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 = pi->gQueue, - .pQueuePriorities = queue_priorities }; - VkDeviceQueueCreateInfo qiC = { .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, - .queueCount = 1, - .queueFamilyIndex = pi->cQueue, - .pQueuePriorities = queue_priorities }; - VkDeviceQueueCreateInfo qiT = { .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, - .queueCount = 1, - .queueFamilyIndex = pi->tQueue, - .pQueuePriorities = queue_priorities }; - - if (pi->gQueue == pi->cQueue){ - if(pi->gQueue == pi->tQueue){ - qCount=1; - pQueueInfos[0] = qiG; - }else{ - qCount=2; - pQueueInfos[0] = qiG; - pQueueInfos[1] = qiT; - } - }else{ - if((pi->gQueue == pi->tQueue) || (pi->cQueue==pi->tQueue)){ - qCount=2; - pQueueInfos[0] = qiG; - pQueueInfos[1] = qiC; - }else{ - qCount=3; - pQueueInfos[0] = qiG; - pQueueInfos[1] = qiC; - pQueueInfos[2] = qiT; - } - } - - char const * dex [] = {"VK_KHR_swapchain"}; - enabledExtsCount = 1; - - VkPhysicalDeviceFeatures enabledFeatures = { - .fillModeNonSolid = true, - //.sampleRateShading = true - }; - - VkDeviceCreateInfo device_info = { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, - .queueCreateInfoCount = qCount, - .pQueueCreateInfos = (VkDeviceQueueCreateInfo*)&pQueueInfos, - .enabledExtensionCount = enabledExtsCount, - .ppEnabledExtensionNames = dex, - .pEnabledFeatures = &enabledFeatures - }; - - e->dev = vkh_device_create(e->app, pi, &device_info); - - e->renderer = vkh_presenter_create - (e->dev, (uint32_t) pi->pQueue, surf, width, height, VK_FORMAT_B8G8R8A8_UNORM, presentMode); - - vkh_app_free_phyinfos (phyCount, phys); - - vkeCheckPhyPropBlitSource (e); - - return e; + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); + glfwWindowHint(GLFW_FLOATING, GLFW_FALSE); + glfwWindowHint(GLFW_DECORATED, GLFW_TRUE); + + e->window = glfwCreateWindow ((int)width, (int)height, "Window Title", NULL, NULL); + + VkSurfaceKHR surf; + VkResult res = glfwCreateWindowSurface(e->app->inst, e->window, NULL, &surf); + + VkhPhyInfo* phys = vkh_app_get_phyinfos (e->app, &phyCount, surf); + + VkhPhyInfo pi = NULL; + for (int i=0; iproperties.deviceType == preferedGPU) + break; + } + + e->memory_properties = pi->memProps; + e->gpu_props = pi->properties; + + 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 = pi->gQueue, + .pQueuePriorities = queue_priorities }; + VkDeviceQueueCreateInfo qiC = { .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, + .queueCount = 1, + .queueFamilyIndex = pi->cQueue, + .pQueuePriorities = queue_priorities }; + VkDeviceQueueCreateInfo qiT = { .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, + .queueCount = 1, + .queueFamilyIndex = pi->tQueue, + .pQueuePriorities = queue_priorities }; + + if (pi->gQueue == pi->cQueue){ + if(pi->gQueue == pi->tQueue){ + qCount=1; + pQueueInfos[0] = qiG; + }else{ + qCount=2; + pQueueInfos[0] = qiG; + pQueueInfos[1] = qiT; + } + }else{ + if((pi->gQueue == pi->tQueue) || (pi->cQueue==pi->tQueue)){ + qCount=2; + pQueueInfos[0] = qiG; + pQueueInfos[1] = qiC; + }else{ + qCount=3; + pQueueInfos[0] = qiG; + pQueueInfos[1] = qiC; + pQueueInfos[2] = qiT; + } + } + + char const * dex [] = {"VK_KHR_swapchain"}; + enabledExtsCount = 1; + + VkPhysicalDeviceFeatures enabledFeatures = { + .fillModeNonSolid = true, + //.sampleRateShading = true + }; + + VkDeviceCreateInfo device_info = { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, + .queueCreateInfoCount = qCount, + .pQueueCreateInfos = (VkDeviceQueueCreateInfo*)&pQueueInfos, + .enabledExtensionCount = enabledExtsCount, + .ppEnabledExtensionNames = dex, + .pEnabledFeatures = &enabledFeatures + }; + + e->dev = vkh_device_create(e->app, pi, &device_info); + + e->renderer = vkh_presenter_create + (e->dev, (uint32_t) pi->pQueue, surf, width, height, VK_FORMAT_B8G8R8A8_UNORM, presentMode); + + vkh_app_free_phyinfos (phyCount, phys); + + vkeCheckPhyPropBlitSource (e); + + return e; } void vkengine_destroy (VkEngine e) { - vkDeviceWaitIdle(e->dev->dev); + vkDeviceWaitIdle(e->dev->dev); - VkSurfaceKHR surf = e->renderer->surface; + VkSurfaceKHR surf = e->renderer->surface; - vkh_presenter_destroy (e->renderer); - vkDestroySurfaceKHR (e->app->inst, surf, NULL); + vkh_presenter_destroy (e->renderer); + vkDestroySurfaceKHR (e->app->inst, surf, NULL); - vkh_device_destroy (e->dev); + vkh_device_destroy (e->dev); - glfwDestroyWindow (e->window); - glfwTerminate (); + glfwDestroyWindow (e->window); + glfwTerminate (); - vkh_app_destroy (e->app); + vkh_app_destroy (e->app); - free(e); + free(e); } void vkengine_close (VkEngine e) { - glfwSetWindowShouldClose(e->window, GLFW_TRUE); + glfwSetWindowShouldClose(e->window, GLFW_TRUE); } void vkengine_blitter_run (VkEngine e, VkImage img, uint32_t width, uint32_t height) { - VkhPresenter p = e->renderer; - vkh_presenter_build_blit_cmd (p, img, width, height); - - while (!vkengine_should_close (e)) { - glfwPollEvents(); - if (!vkh_presenter_draw (p)) - vkh_presenter_build_blit_cmd (p, img, width, height); - } + VkhPresenter p = e->renderer; + vkh_presenter_build_blit_cmd (p, img, width, height); + + while (!vkengine_should_close (e)) { + glfwPollEvents(); + if (!vkh_presenter_draw (p)) + vkh_presenter_build_blit_cmd (p, img, width, height); + } } bool vkengine_should_close (VkEngine e) { - return glfwWindowShouldClose (e->window); + return glfwWindowShouldClose (e->window); } void vkengine_set_title (VkEngine e, const char* title) { - glfwSetWindowTitle(e->window, title); + glfwSetWindowTitle(e->window, title); } VkDevice vkengine_get_device (VkEngine e){ - return e->dev->dev; + return e->dev->dev; } VkPhysicalDevice vkengine_get_physical_device (VkEngine e){ - return e->dev->phy; + return e->dev->phy; } VkQueue vkengine_get_queue (VkEngine e){ - return e->renderer->queue; + return e->renderer->queue; } uint32_t vkengine_get_queue_fam_idx (VkEngine e){ - return e->renderer->qFam; + return e->renderer->qFam; } void vkengine_set_key_callback (VkEngine e, GLFWkeyfun key_callback){ - glfwSetKeyCallback (e->window, key_callback); + glfwSetKeyCallback (e->window, key_callback); } void vkengine_set_mouse_but_callback (VkEngine e, GLFWmousebuttonfun onMouseBut){ - glfwSetMouseButtonCallback(e->window, onMouseBut); + glfwSetMouseButtonCallback(e->window, onMouseBut); } void vkengine_set_cursor_pos_callback (VkEngine e, GLFWcursorposfun onMouseMove){ - glfwSetCursorPosCallback(e->window, onMouseMove); + glfwSetCursorPosCallback(e->window, onMouseMove); } void vkengine_set_scroll_callback (VkEngine e, GLFWscrollfun onScroll){ - glfwSetScrollCallback(e->window, onScroll); + glfwSetScrollCallback(e->window, onScroll); } void vkengine_set_char_callback (VkEngine e, GLFWcharfun onChar){ - glfwSetCharCallback(e->window, onChar); + glfwSetCharCallback(e->window, onChar); } diff --git a/vkh b/vkh index 1fcee82..bc156f3 160000 --- a/vkh +++ b/vkh @@ -1 +1 @@ -Subproject commit 1fcee8223df65d87742bfe5ec36562bfaccecc11 +Subproject commit bc156f3b64bea8f5c3734e9d63f2c03a39150063 -- 2.47.3