zink: emulate optional depth-formats
authorErik Faye-Lund <erik.faye-lund@collabora.com>
Wed, 23 Oct 2019 09:59:03 +0000 (11:59 +0200)
committerErik Faye-Lund <erik.faye-lund@collabora.com>
Mon, 28 Oct 2019 17:57:49 +0000 (17:57 +0000)
The Vulkan spec says that an implementation has to support one of
VK_FORMAT_X8_D24_UNORM_PACK32 and VK_FORMAT_D32_SFLOAT, as well of
one of VK_FORMAT_D24_UNORM_S8_UINT and VK_FORMAT_D32_SFLOAT_S8_UINT.

So let's keep track which one is supported of earch pair, and emulate
one on top of the other one.

This won't give the exact result for comparisons, or when mapping and
unmapping the resources. But it's better than flat out failing to create
the resource, and we can fix the map/unmap issue later if needed.

Tested-by: Duncan Hopkins <duncan@thefoundry.co.uk>
src/gallium/drivers/zink/zink_context.c
src/gallium/drivers/zink/zink_resource.c
src/gallium/drivers/zink/zink_screen.c
src/gallium/drivers/zink/zink_screen.h
src/gallium/drivers/zink/zink_state.c
src/gallium/drivers/zink/zink_surface.c

index 74f94ee988dc3558735268a60c4ce728fd6a22c4..2c253b575e5b7e3ffd2a4f3de12855339357eff7 100644 (file)
@@ -257,7 +257,7 @@ zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres,
    ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
    ivci.image = res->image;
    ivci.viewType = image_view_type(state->target);
-   ivci.format = zink_get_format(state->format);
+   ivci.format = zink_get_format(screen, state->format);
    ivci.components.r = component_mapping(state->swizzle_r);
    ivci.components.g = component_mapping(state->swizzle_g);
    ivci.components.b = component_mapping(state->swizzle_b);
index fe4097e9f0ce62c8d6518c9f6cfd10e2a2d9ab43..dccbe827f6396c7a59443db1ba2931ad8e4c76e5 100644 (file)
@@ -133,7 +133,7 @@ resource_create(struct pipe_screen *pscreen,
       vkGetBufferMemoryRequirements(screen->dev, res->buffer, &reqs);
       flags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
    } else {
-      res->format = zink_get_format(templ->format);
+      res->format = zink_get_format(screen, templ->format);
 
       VkImageCreateInfo ici = {};
       ici.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
index 667f242091c7eda11ecc6824790b975b09654f05..a75389257af7ba53bf277df3f7dc8abe5d735e0a 100644 (file)
@@ -569,10 +569,33 @@ static const VkFormat formats[PIPE_FORMAT_COUNT] = {
    [PIPE_FORMAT_BPTC_RGB_UFLOAT] = VK_FORMAT_BC6H_UFLOAT_BLOCK,
 };
 
+static bool
+is_depth_format_supported(struct zink_screen *screen, VkFormat format)
+{
+   VkFormatProperties props;
+   vkGetPhysicalDeviceFormatProperties(screen->pdev, format, &props);
+   return (props.linearTilingFeatures | props.optimalTilingFeatures) &
+          VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
+}
+
 VkFormat
-zink_get_format(enum pipe_format format)
+zink_get_format(struct zink_screen *screen, enum pipe_format format)
 {
-   return formats[format];
+   VkFormat ret = formats[format];
+
+   if (ret == VK_FORMAT_X8_D24_UNORM_PACK32 &&
+       !screen->have_X8_D24_UNORM_PACK32) {
+      assert(is_depth_format_supported(screen, VK_FORMAT_D32_SFLOAT));
+      return VK_FORMAT_D32_SFLOAT;
+   }
+
+   if (ret == VK_FORMAT_D24_UNORM_S8_UINT &&
+       !screen->have_D24_UNORM_S8_UINT) {
+      assert(is_depth_format_supported(screen, VK_FORMAT_D32_SFLOAT_S8_UINT));
+      return VK_FORMAT_D32_SFLOAT_S8_UINT;
+   }
+
+   return ret;
 }
 
 static VkSampleCountFlagBits
@@ -605,7 +628,7 @@ zink_is_format_supported(struct pipe_screen *pscreen,
       return screen->props.limits.framebufferNoAttachmentsSampleCounts &
              vk_sample_count_flags(sample_count);
 
-   VkFormat vkformat = formats[format];
+   VkFormat vkformat = zink_get_format(screen, format);
    if (vkformat == VK_FORMAT_UNDEFINED)
       return FALSE;
 
@@ -830,6 +853,11 @@ zink_internal_create_screen(struct sw_winsys *winsys, int fd)
    vkGetPhysicalDeviceFeatures(screen->pdev, &screen->feats);
    vkGetPhysicalDeviceMemoryProperties(screen->pdev, &screen->mem_props);
 
+   screen->have_X8_D24_UNORM_PACK32 = is_depth_format_supported(screen,
+                                         VK_FORMAT_X8_D24_UNORM_PACK32);
+   screen->have_D24_UNORM_S8_UINT = is_depth_format_supported(screen,
+                                         VK_FORMAT_D24_UNORM_S8_UINT);
+
    uint32_t num_extensions = 0;
    if (vkEnumerateDeviceExtensionProperties(screen->pdev, NULL,
        &num_extensions, NULL) == VK_SUCCESS && num_extensions > 0) {
index 38ade554cccdfc2d4f817c5b892efe45f715f7b3..0b0ee210abba9450a13354fa50c20c2448b7d919 100644 (file)
@@ -48,8 +48,12 @@ struct zink_screen {
    VkPhysicalDeviceProperties props;
    VkPhysicalDeviceFeatures feats;
    VkPhysicalDeviceMemoryProperties mem_props;
+
    bool have_KHR_maintenance1;
 
+   bool have_X8_D24_UNORM_PACK32;
+   bool have_D24_UNORM_S8_UINT;
+
    uint32_t gfx_queue;
    VkDevice dev;
 
@@ -63,6 +67,6 @@ zink_screen(struct pipe_screen *pipe)
 }
 
 VkFormat
-zink_get_format(enum pipe_format format);
+zink_get_format(struct zink_screen *screen, enum pipe_format format);
 
 #endif
index 07da1be2bf8ab1c763499f3beb99bd2c9a28d079..dba85ef43e84bb35c85261a4eea382dac047fb6d 100644 (file)
@@ -35,6 +35,7 @@ zink_create_vertex_elements_state(struct pipe_context *pctx,
                                   unsigned num_elements,
                                   const struct pipe_vertex_element *elements)
 {
+   struct zink_screen *screen = zink_screen(pctx->screen);
    unsigned int i;
    struct zink_vertex_elements_state *ves = CALLOC_STRUCT(zink_vertex_elements_state);
    if (!ves)
@@ -62,7 +63,8 @@ zink_create_vertex_elements_state(struct pipe_context *pctx,
 
       ves->hw_state.attribs[i].binding = binding;
       ves->hw_state.attribs[i].location = i; // TODO: unsure
-      ves->hw_state.attribs[i].format = zink_get_format(elem->src_format);
+      ves->hw_state.attribs[i].format = zink_get_format(screen,
+                                                        elem->src_format);
       assert(ves->hw_state.attribs[i].format != VK_FORMAT_UNDEFINED);
       ves->hw_state.attribs[i].offset = elem->src_offset;
    }
index 0b480643b1b3303ecb560aa6c1f070a6ed375554..3c1fc4e7216e3dbd1ec6f3569e5814c724de9d98 100644 (file)
@@ -93,7 +93,7 @@ zink_create_surface(struct pipe_context *pctx,
       unreachable("unsupported target");
    }
 
-   ivci.format = zink_get_format(templ->format);
+   ivci.format = zink_get_format(screen, templ->format);
 
    // TODO: format swizzles
    ivci.components.r = VK_COMPONENT_SWIZZLE_R;