dzn: Support >2K samplers with bindless
authorJesse Natalie <jenatali@microsoft.com>
Thu, 6 Apr 2023 20:45:08 +0000 (13:45 -0700)
committerMarge Bot <emma+marge@anholt.net>
Fri, 7 Apr 2023 19:11:11 +0000 (19:11 +0000)
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22346>

src/microsoft/ci/warp-fails.txt
src/microsoft/vulkan/dzn_descriptor_set.c
src/microsoft/vulkan/dzn_device.c
src/microsoft/vulkan/dzn_private.h

index c84958e..2486a09 100644 (file)
@@ -117,6 +117,3 @@ dEQP-VK.image.texel_view_compatible.compute.extended.3d_image.texture.bc5_snorm_
 # This is due to pretending to resolve stencil sample 0 using min
 # This needs to be a blit shader instead, but that runs into problems since shader stencil export is optional
 dEQP-VK.imageless_framebuffer.depth_stencil_resolve,Fail
-
-# This needs D3D API changes to enable sampler heaps >= 4k entries, which is incoming
-dEQP-VK.api.object_management.max_concurrent.sampler,Fail
index c385fc4..8265099 100644 (file)
@@ -188,7 +188,8 @@ dzn_descriptor_set_layout_create(struct dzn_device *device,
          bindings[i].pImmutableSamplers != NULL;
       bool static_sampler = false;
 
-      if (immutable_samplers && bindings[i].descriptorCount == 1) {
+      if (device->support_static_samplers &&
+          immutable_samplers && bindings[i].descriptorCount == 1) {
          VK_FROM_HANDLE(dzn_sampler, sampler, bindings[i].pImmutableSamplers[0]);
 
          if (sampler->static_border_color != -1)
@@ -301,7 +302,8 @@ dzn_descriptor_set_layout_create(struct dzn_device *device,
       bool has_immutable_samplers =
          has_sampler &&
          ordered_bindings[i].pImmutableSamplers != NULL;
-      bool has_static_sampler = has_immutable_samplers && desc_count == 1;
+      bool has_static_sampler = device->support_static_samplers &&
+         has_immutable_samplers && desc_count == 1;
       bool is_dynamic = is_dynamic_desc_type(desc_type);
 
       D3D12_SHADER_VISIBILITY visibility = device->bindless ?
index 0e13db3..e765125 100644 (file)
@@ -458,6 +458,13 @@ dzn_physical_device_cache_caps(struct dzn_physical_device *pdev)
    ID3D12Device1_CheckFeatureSupport(pdev->dev, D3D12_FEATURE_D3D12_OPTIONS13, &pdev->options13, sizeof(pdev->options13));
    ID3D12Device1_CheckFeatureSupport(pdev->dev, D3D12_FEATURE_D3D12_OPTIONS14, &pdev->options14, sizeof(pdev->options14));
    ID3D12Device1_CheckFeatureSupport(pdev->dev, D3D12_FEATURE_D3D12_OPTIONS15, &pdev->options15, sizeof(pdev->options15));
+#if D3D12_SDK_VERSION >= 610
+   if (FAILED(ID3D12Device1_CheckFeatureSupport(pdev->dev, D3D12_FEATURE_D3D12_OPTIONS19, &pdev->options19, sizeof(pdev->options19)))) {
+      pdev->options19.MaxSamplerDescriptorHeapSize = D3D12_MAX_SHADER_VISIBLE_SAMPLER_HEAP_SIZE;
+      pdev->options19.MaxSamplerDescriptorHeapSizeWithStaticSamplers = pdev->options19.MaxSamplerDescriptorHeapSize;
+      pdev->options19.MaxViewDescriptorHeapSize = D3D12_MAX_SHADER_VISIBLE_DESCRIPTOR_HEAP_SIZE_TIER_1;
+   }
+#endif
 
    pdev->queue_families[pdev->queue_family_count++] = (struct dzn_queue_family) {
       .props = {
@@ -2409,15 +2416,28 @@ dzn_device_create(struct dzn_physical_device *pdev,
       device->need_swapchain_blits = true;
    }
 
+   device->support_static_samplers = true;
    device->bindless = (instance->debug_flags & DZN_DEBUG_BINDLESS) != 0 ||
+#if D3D12_SDK_VERSION >= 610
+      /* Enable bindless by default when we can do it and still be in-spec, this is
+       * likely to be more efficient than the "bindful" method of copying descriptors. */
+      (pdev->options19.MaxSamplerDescriptorHeapSize >= 4000 &&
+       pdev->shader_model >= D3D_SHADER_MODEL_6_6) ||
+#endif
       device->vk.enabled_features.descriptorIndexing ||
       device->vk.enabled_extensions.EXT_descriptor_indexing;
 
    if (device->bindless) {
+#if D3D12_SDK_VERSION >= 610
+      uint32_t sampler_count = MIN2(pdev->options19.MaxSamplerDescriptorHeapSize, 4000);
+      device->support_static_samplers = pdev->options19.MaxSamplerDescriptorHeapSizeWithStaticSamplers >= sampler_count;
+#else
+      uint32_t sampler_count = D3D12_MAX_SHADER_VISIBLE_SAMPLER_HEAP_SIZE;
+      device->support_static_samplers = true;
+#endif
       dzn_foreach_pool_type(type) {
          uint32_t descriptor_count = type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER ?
-            D3D12_MAX_SHADER_VISIBLE_SAMPLER_HEAP_SIZE :
-            D3D12_MAX_SHADER_VISIBLE_DESCRIPTOR_HEAP_SIZE_TIER_1;
+            sampler_count : D3D12_MAX_SHADER_VISIBLE_DESCRIPTOR_HEAP_SIZE_TIER_1;
          result = dzn_descriptor_heap_init(&device->device_heaps[type].heap, device, type, descriptor_count, true);
          if (result != VK_SUCCESS) {
             dzn_device_destroy(device, pAllocator);
index 3eb7903..0386bbf 100644 (file)
@@ -218,6 +218,9 @@ struct dzn_physical_device {
    D3D12_FEATURE_DATA_D3D12_OPTIONS13 options13;
    D3D12_FEATURE_DATA_D3D12_OPTIONS14 options14;
    D3D12_FEATURE_DATA_D3D12_OPTIONS15 options15;
+#if D3D12_SDK_VERSION >= 610
+   D3D12_FEATURE_DATA_D3D12_OPTIONS19 options19;
+#endif
    VkPhysicalDeviceMemoryProperties memory;
    D3D12_HEAP_FLAGS heap_flags_for_mem_type[VK_MAX_MEMORY_TYPES];
    const struct vk_sync_type *sync_types[MAX_SYNC_TYPES + 1];
@@ -308,6 +311,7 @@ struct dzn_device {
    struct dzn_queue *swapchain_queue;
 
    bool bindless;
+   bool support_static_samplers;
    struct dzn_device_descriptor_heap device_heaps[NUM_POOL_TYPES];
 };
 
@@ -425,8 +429,8 @@ struct dzn_buffer_desc {
    int *bindless_descriptor_slot;
 };
 
-#define MAX_DESCS_PER_SAMPLER_HEAP 2048u
-#define MAX_DESCS_PER_CBV_SRV_UAV_HEAP 1000000u
+#define MAX_DESCS_PER_SAMPLER_HEAP     D3D12_MAX_SHADER_VISIBLE_SAMPLER_HEAP_SIZE
+#define MAX_DESCS_PER_CBV_SRV_UAV_HEAP D3D12_MAX_SHADER_VISIBLE_DESCRIPTOR_HEAP_SIZE_TIER_1
 
 VkResult
 dzn_descriptor_heap_init(struct dzn_descriptor_heap *heap,