From e7b2d4db430db92acb27bcf5e9f64caae3b7fe5d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Sun, 22 Nov 2020 08:42:43 +0100 Subject: [PATCH] dynamic depthStencil image format selection --- src/vkvg_context.c | 2 +- src/vkvg_device.c | 16 ++++++------- src/vkvg_device_internal.c | 46 +++++++++++++++++++++++++++---------- src/vkvg_device_internal.h | 5 +++- src/vkvg_internal.h | 1 - src/vkvg_surface.c | 1 + src/vkvg_surface_internal.c | 12 ++++------ src/vkvg_surface_internal.h | 1 - 8 files changed, 51 insertions(+), 33 deletions(-) diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 7a99356..bc47d44 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -951,7 +951,7 @@ void vkvg_save (VkvgContext ctx){ return; } ctx->savedStencils = savedStencilsPtr; - VkhImage savStencil = vkh_image_ms_create ((VkhDevice)dev,FB_STENCIL_FORMAT, dev->samples, ctx->pSurf->width, ctx->pSurf->height, + VkhImage savStencil = vkh_image_ms_create ((VkhDevice)dev, dev->stencilFormat, dev->samples, ctx->pSurf->width, ctx->pSurf->height, VMA_MEMORY_USAGE_GPU_ONLY, VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT); ctx->savedStencils[curSaveStencil-1] = savStencil; diff --git a/src/vkvg_device.c b/src/vkvg_device.c index f71b48d..00de9d5 100644 --- a/src/vkvg_device.c +++ b/src/vkvg_device.c @@ -33,7 +33,7 @@ VkvgDevice vkvg_device_create_multisample(VkInstance inst, VkPhysicalDevice phy, { LOG(VKVG_LOG_INFO, "CREATE Device: qFam = %d; qIdx = %d\n", qFamIdx, qIndex); - VkvgDevice dev = (vkvg_device*)malloc(sizeof(vkvg_device)); + VkvgDevice dev = (vkvg_device*)calloc(1,sizeof(vkvg_device)); dev->instance = inst; dev->hdpi = 96; @@ -45,15 +45,13 @@ VkvgDevice vkvg_device_create_multisample(VkInstance inst, VkPhysicalDevice phy, #if VKVG_DBG_STATS dev->debug_stats = (vkvg_debug_stats_t) {0}; -#endif +#endif VkFormat format = FB_COLOR_FORMAT; - VkImageTiling tiling; - if (!_get_best_image_tiling (dev, format, &tiling)) { - dev->status = VKVG_STATUS_INVALID_FORMAT; - LOG(VKVG_LOG_ERR, "vkvg create device failed: image format not supported: %d\n", format); - return dev; - } + + _check_best_image_tiling(dev, format); + if (dev->status != VKVG_STATUS_SUCCESS) + return dev; if (!_init_function_pointers (dev)){ dev->status = VKVG_STATUS_NULL_POINTER; @@ -94,7 +92,7 @@ VkvgDevice vkvg_device_create_multisample(VkInstance inst, VkPhysicalDevice phy, _createDescriptorSetLayout (dev); _setupPipelines (dev); - _create_empty_texture (dev, format, tiling); + _create_empty_texture (dev, format, dev->supportedTiling); dev->references = 1; diff --git a/src/vkvg_device_internal.c b/src/vkvg_device_internal.c index 55b5050..8fef5bd 100644 --- a/src/vkvg_device_internal.c +++ b/src/vkvg_device_internal.c @@ -75,7 +75,7 @@ VkRenderPass _createRenderPassNoResolve(VkvgDevice dev, VkAttachmentLoadOp loadO .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; VkAttachmentDescription attDS = { - .format = FB_STENCIL_FORMAT, + .format = dev->stencilFormat, .samples = dev->samples, .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, @@ -138,7 +138,7 @@ VkRenderPass _createRenderPassMS(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAt .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; VkAttachmentDescription attDS = { - .format = FB_STENCIL_FORMAT, + .format = dev->stencilFormat, .samples = dev->samples, .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, @@ -452,18 +452,40 @@ void _create_empty_texture (VkvgDevice dev, VkFormat format, VkImageTiling tilin 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}; + +void _check_best_image_tiling (VkvgDevice dev, VkFormat format) { + VkFlags stencilFormats[] = { VK_FORMAT_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT }; + VkFormatProperties phyStencilProps = { 0 }, phyImgProps = { 0 }; + + dev->stencilFormat = VK_FORMAT_UNDEFINED; + dev->supportedTiling = 0xff; + 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; + + if (phyImgProps.optimalTilingFeatures & (VKVG_SURFACE_IMGS_REQUIREMENTS)) { + for (int i = 0; i < 4; i++) + { + vkGetPhysicalDeviceFormatProperties(dev->phy, stencilFormats[i], &phyStencilProps); + if (phyStencilProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) { + dev->stencilFormat = stencilFormats[i]; + dev->supportedTiling = VK_IMAGE_TILING_OPTIMAL; + return; + } + } } - return true; + if (phyImgProps.linearTilingFeatures & (VKVG_SURFACE_IMGS_REQUIREMENTS)) { + for (int i = 0; i < 4; i++) + { + vkGetPhysicalDeviceFormatProperties(dev->phy, stencilFormats[i], &phyStencilProps); + if (phyStencilProps.linearTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) { + dev->stencilFormat = stencilFormats[i]; + dev->supportedTiling = VK_IMAGE_TILING_LINEAR; + return; + } + } + } + dev->status = VKVG_STATUS_INVALID_FORMAT; + LOG(VKVG_LOG_ERR, "vkvg create device failed: image format not supported: %d\n", format); } void _dump_image_format_properties (VkvgDevice dev, VkFormat format) { diff --git a/src/vkvg_device_internal.h b/src/vkvg_device_internal.h index ff5378d..ea14831 100644 --- a/src/vkvg_device_internal.h +++ b/src/vkvg_device_internal.h @@ -56,6 +56,9 @@ typedef struct _vkvg_device_t{ VmaAllocator allocator; /**< Vulkan Memory allocator */ VkInstance instance; /**< Vulkan instance */ + VkImageTiling supportedTiling; /**< Supported image tiling for surface, 0xFF=no support */ + VkFormat stencilFormat; /**< Supported vulkan image format for stencil */ + 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 */ @@ -101,7 +104,7 @@ typedef struct _vkvg_device_t{ bool _init_function_pointers (VkvgDevice dev); void _create_empty_texture (VkvgDevice dev, VkFormat format, VkImageTiling tiling); -bool _get_best_image_tiling (VkvgDevice dev, VkFormat format, VkImageTiling* pTiling); +void _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 3fc4647..8ff0177 100644 --- a/src/vkvg_internal.h +++ b/src/vkvg_internal.h @@ -65,7 +65,6 @@ //width of the stencil buffer will determine the number of context saving/restore layers //the two first bits of the stencil are the FILL and the CLIP bits, all other bits are //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|VK_FORMAT_FEATURE_BLIT_SRC_BIT diff --git a/src/vkvg_surface.c b/src/vkvg_surface.c index adc11cb..593a582 100644 --- a/src/vkvg_surface.c +++ b/src/vkvg_surface.c @@ -194,6 +194,7 @@ void vkvg_surface_destroy(VkvgSurface surf) surf->references--; if (surf->references > 0) return; + vkDestroyFramebuffer(surf->dev->vkDev, surf->fb, NULL); if (!surf->img->imported) diff --git a/src/vkvg_surface_internal.c b/src/vkvg_surface_internal.c index fb05367..6f8a651 100644 --- a/src/vkvg_surface_internal.c +++ b/src/vkvg_surface_internal.c @@ -105,7 +105,7 @@ void _clear_surface (VkvgSurface surf, VkImageAspectFlags aspect) } void _create_surface_main_image (VkvgSurface surf){ - surf->img = vkh_image_create((VkhDevice)surf->dev,surf->format,surf->width,surf->height,surf->tiling,VMA_MEMORY_USAGE_GPU_ONLY, + surf->img = vkh_image_create((VkhDevice)surf->dev,surf->format,surf->width,surf->height,surf->dev->supportedTiling,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); #if defined(DEBUG) && defined (VKVG_DBG_UTILS) @@ -127,7 +127,7 @@ void _create_surface_secondary_images (VkvgSurface surf) { 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); + surf->stencil = vkh_image_ms_create((VkhDevice)surf->dev,surf->dev->stencilFormat,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); #if defined(DEBUG) && defined (VKVG_DBG_UTILS) @@ -173,12 +173,9 @@ void _create_surface_images (VkvgSurface surf) { 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; +VkvgSurface _create_surface (VkvgDevice dev, VkFormat format) { + if (dev->status != VKVG_STATUS_SUCCESS) return NULL; - } VkvgSurface surf = (vkvg_surface*)calloc(1,sizeof(vkvg_surface)); if (!surf) { @@ -188,7 +185,6 @@ VkvgSurface _create_surface (VkvgDevice dev, VkFormat format) { surf->dev = dev; surf->format = format; - surf->tiling = tiling; dev->status = VKVG_STATUS_SUCCESS; return surf; diff --git a/src/vkvg_surface_internal.h b/src/vkvg_surface_internal.h index ce89586..5919cbc 100644 --- a/src/vkvg_surface_internal.h +++ b/src/vkvg_surface_internal.h @@ -31,7 +31,6 @@ typedef struct _vkvg_surface_t { uint32_t width; uint32_t height; VkFormat format; - VkImageTiling tiling; /**< optimal is prefered if supported */ VkFramebuffer fb; VkhImage img; VkhImage imgMS; -- 2.47.3