Module: Mesa
Branch: main
Commit: 438be4f9a0890fd9afb8c80e9c539f1253708fa8
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=438be4f9a0890fd9afb8c80e9c539f1253708fa8

Author: Jesse Natalie <jenat...@microsoft.com>
Date:   Fri Nov  3 15:29:21 2023 -0700

d3d12: Support ARB_texture_view

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26104>

---

 docs/features.txt                            |   4 +-
 src/gallium/drivers/d3d12/d3d12_blit.cpp     |   4 +
 src/gallium/drivers/d3d12/d3d12_bufmgr.cpp   |   1 +
 src/gallium/drivers/d3d12/d3d12_context.cpp  |  65 ++++++------
 src/gallium/drivers/d3d12/d3d12_format.c     | 149 +++++++++++++++++++++++++++
 src/gallium/drivers/d3d12/d3d12_format.h     |   3 +
 src/gallium/drivers/d3d12/d3d12_resource.cpp | 127 +++++++++++++++++------
 src/gallium/drivers/d3d12/d3d12_screen.cpp   |   9 ++
 src/gallium/drivers/d3d12/d3d12_screen.h     |   2 +
 9 files changed, 298 insertions(+), 66 deletions(-)

diff --git a/docs/features.txt b/docs/features.txt
index 17871d388d8..7242f827b68 100644
--- a/docs/features.txt
+++ b/docs/features.txt
@@ -188,7 +188,7 @@ GL 4.3, GLSL 4.30 -- all DONE: freedreno/a6xx, nvc0, r600, 
radeonsi, llvmpipe, v
   GL_ARB_texture_buffer_range                           DONE (freedreno, nv50, 
softpipe, v3d, d3d12, crocus)
   GL_ARB_texture_query_levels                           DONE (all drivers that 
support GLSL 1.30)
   GL_ARB_texture_storage_multisample                    DONE (all drivers that 
support GL_ARB_texture_multisample)
-  GL_ARB_texture_view                                   DONE (freedreno, nv50, 
softpipe, v3d, asahi, crocus/gen7+)
+  GL_ARB_texture_view                                   DONE (freedreno, nv50, 
softpipe, v3d, asahi, crocus/gen7+, d3d12)
   GL_ARB_vertex_attrib_binding                          DONE (all drivers)
 
 
@@ -347,7 +347,7 @@ Khronos, ARB, and OES extensions that are not part of any 
OpenGL or OpenGL ES ve
   GL_OES_texture_float_linear                           DONE (freedreno, r300, 
r600, radeonsi, nv30, nv50, nvc0, softpipe, llvmpipe, panfrost, zink, asahi, 
iris, crocus)
   GL_OES_texture_half_float                             DONE (freedreno, r300, 
r600, radeonsi, nv30, nv50, nvc0, softpipe, llvmpipe, panfrost, v3d, zink, 
lima, asahi, iris, crocus, etnaviv/HALF_FLOAT)
   GL_OES_texture_half_float_linear                      DONE (freedreno, r300, 
r600, radeonsi, nv30, nv50, nvc0, softpipe, llvmpipe, panfrost, v3d, zink, 
lima, asahi, iris, crocus, etnaviv/HALF_FLOAT)
-  GL_OES_texture_view                                   DONE (freedreno, r600, 
radeonsi, nv50, nvc0, softpipe, llvmpipe, v3d, zink, iris, crocus/gen7+)
+  GL_OES_texture_view                                   DONE (freedreno, r600, 
radeonsi, nv50, nvc0, softpipe, llvmpipe, v3d, zink, iris, crocus/gen7+, d3d12)
   GL_OES_viewport_array                                 DONE (freedreno/a6xx, 
nvc0, r600, radeonsi, softpipe, zink, iris, crocus/gen7.5+)
   GLX_ARB_context_flush_control                         DONE (all drivers)
   GLX_ARB_robustness_application_isolation              not started
diff --git a/src/gallium/drivers/d3d12/d3d12_blit.cpp 
b/src/gallium/drivers/d3d12/d3d12_blit.cpp
index 142e33ae5d7..6c0bf15709c 100644
--- a/src/gallium/drivers/d3d12/d3d12_blit.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_blit.cpp
@@ -187,6 +187,10 @@ direct_copy_supported(struct d3d12_screen *screen,
    if (!formats_are_copy_compatible(info->src.format, info->dst.format))
       return false;
 
+   if (info->src.format != info->src.resource->format ||
+       info->dst.format != info->dst.resource->format)
+      return false;
+
    if (util_format_is_depth_or_stencil(info->src.format) && !(info->mask & 
PIPE_MASK_ZS)) {
       return false;
    }
diff --git a/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp 
b/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp
index a9fa0cff278..cf37598dad3 100644
--- a/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp
@@ -100,6 +100,7 @@ d3d12_bo_wrap_res(struct d3d12_screen *screen, 
ID3D12Resource *res, enum d3d12_r
 
    bo->residency_status = residency;
    bo->last_used_timestamp = 0;
+   desc.Flags = D3D12_RESOURCE_FLAG_NONE;
    screen->dev->GetCopyableFootprints(&desc, 0, total_subresources, 0, 
nullptr, nullptr, nullptr, &bo->estimated_size);
    if (residency == d3d12_resident) {
       mtx_lock(&screen->submit_mutex);
diff --git a/src/gallium/drivers/d3d12/d3d12_context.cpp 
b/src/gallium/drivers/d3d12/d3d12_context.cpp
index 4e6cd24fc2b..88fd1d70ccb 100644
--- a/src/gallium/drivers/d3d12/d3d12_context.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_context.cpp
@@ -890,14 +890,15 @@ d3d12_init_sampler_view_descriptor(struct 
d3d12_sampler_view *sampler_view)
    unsigned array_size = state->u.tex.last_layer - state->u.tex.first_layer + 
1;
    switch (desc.ViewDimension) {
    case D3D12_SRV_DIMENSION_TEXTURE1D:
-      if (state->u.tex.first_layer > 0)
-         debug_printf("D3D12: can't create 1D SRV from layer %d\n",
-                      state->u.tex.first_layer);
-
-      desc.Texture1D.MostDetailedMip = state->u.tex.first_level;
-      desc.Texture1D.MipLevels = sampler_view->mip_levels;
-      desc.Texture1D.ResourceMinLODClamp = 0.0f;
-      break;
+      if (state->u.tex.first_layer == 0) {
+         desc.Texture1D.MostDetailedMip = state->u.tex.first_level;
+         desc.Texture1D.MipLevels = sampler_view->mip_levels;
+         desc.Texture1D.ResourceMinLODClamp = 0.0f;
+         break;
+      } else {
+         desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1DARRAY;
+         FALLTHROUGH;
+      }
    case D3D12_SRV_DIMENSION_TEXTURE1DARRAY:
       desc.Texture1DArray.MostDetailedMip = state->u.tex.first_level;
       desc.Texture1DArray.MipLevels = sampler_view->mip_levels;
@@ -906,20 +907,16 @@ d3d12_init_sampler_view_descriptor(struct 
d3d12_sampler_view *sampler_view)
       desc.Texture1DArray.ArraySize = array_size;
       break;
    case D3D12_SRV_DIMENSION_TEXTURE2D:
-      if (state->u.tex.first_layer > 0)
-         debug_printf("D3D12: can't create 2D SRV from layer %d\n",
-                      state->u.tex.first_layer);
-
-      desc.Texture2D.MostDetailedMip = state->u.tex.first_level;
-      desc.Texture2D.MipLevels = sampler_view->mip_levels;
-      desc.Texture2D.PlaneSlice = format_info.plane_slice;
-      desc.Texture2D.ResourceMinLODClamp = 0.0f;
-      break;
-   case D3D12_SRV_DIMENSION_TEXTURE2DMS:
-      if (state->u.tex.first_layer > 0)
-         debug_printf("D3D12: can't create 2DMS SRV from layer %d\n",
-                      state->u.tex.first_layer);
-      break;
+      if (state->u.tex.first_layer == 0) {
+         desc.Texture2D.MostDetailedMip = state->u.tex.first_level;
+         desc.Texture2D.MipLevels = sampler_view->mip_levels;
+         desc.Texture2D.PlaneSlice = format_info.plane_slice;
+         desc.Texture2D.ResourceMinLODClamp = 0.0f;
+         break;
+      } else {
+         desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
+         FALLTHROUGH;
+      }
    case D3D12_SRV_DIMENSION_TEXTURE2DARRAY:
       desc.Texture2DArray.MostDetailedMip = state->u.tex.first_level;
       desc.Texture2DArray.MipLevels = sampler_view->mip_levels;
@@ -928,6 +925,13 @@ d3d12_init_sampler_view_descriptor(struct 
d3d12_sampler_view *sampler_view)
       desc.Texture2DArray.PlaneSlice = format_info.plane_slice;
       desc.Texture2DArray.ArraySize = array_size;
       break;
+   case D3D12_SRV_DIMENSION_TEXTURE2DMS:
+      if (state->u.tex.first_layer == 0) {
+         break;
+      } else {
+         desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY;
+         FALLTHROUGH;
+      }
    case D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY:
       desc.Texture2DMSArray.FirstArraySlice = state->u.tex.first_layer;
       desc.Texture2DMSArray.ArraySize = array_size;
@@ -942,14 +946,15 @@ d3d12_init_sampler_view_descriptor(struct 
d3d12_sampler_view *sampler_view)
       desc.Texture3D.ResourceMinLODClamp = 0.0f;
       break;
    case D3D12_SRV_DIMENSION_TEXTURECUBE:
-      if (state->u.tex.first_layer > 0)
-         debug_printf("D3D12: can't create CUBE SRV from layer %d\n",
-                      state->u.tex.first_layer);
-
-      desc.TextureCube.MostDetailedMip = state->u.tex.first_level;
-      desc.TextureCube.MipLevels = sampler_view->mip_levels;
-      desc.TextureCube.ResourceMinLODClamp = 0.0f;
-      break;
+      if (state->u.tex.first_layer == 0) {
+         desc.TextureCube.MostDetailedMip = state->u.tex.first_level;
+         desc.TextureCube.MipLevels = sampler_view->mip_levels;
+         desc.TextureCube.ResourceMinLODClamp = 0.0f;
+         break;
+      } else {
+         desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBEARRAY;
+         FALLTHROUGH;
+      }
    case D3D12_SRV_DIMENSION_TEXTURECUBEARRAY:
       assert(array_size % 6 == 0);
       desc.TextureCubeArray.MostDetailedMip = state->u.tex.first_level;
diff --git a/src/gallium/drivers/d3d12/d3d12_format.c 
b/src/gallium/drivers/d3d12/d3d12_format.c
index 5ba7add2b88..107395c48c6 100644
--- a/src/gallium/drivers/d3d12/d3d12_format.c
+++ b/src/gallium/drivers/d3d12/d3d12_format.c
@@ -211,6 +211,155 @@ d3d12_get_typeless_format(enum pipe_format format)
    return typeless_formats[format];
 }
 
+const DXGI_FORMAT cast_table_8bit[] = {
+   DXGI_FORMAT_R8_UINT,
+   DXGI_FORMAT_R8_UNORM,
+   DXGI_FORMAT_R8_SINT,
+   DXGI_FORMAT_R8_SNORM,
+   DXGI_FORMAT_A8_UNORM,
+};
+
+const DXGI_FORMAT cast_table_16bit[] = {
+   DXGI_FORMAT_R8G8_UINT,
+   DXGI_FORMAT_R8G8_UNORM,
+   DXGI_FORMAT_R8G8_SINT,
+   DXGI_FORMAT_R8G8_SNORM,
+   DXGI_FORMAT_R16_UINT,
+   DXGI_FORMAT_R16_UNORM,
+   DXGI_FORMAT_R16_SINT,
+   DXGI_FORMAT_R16_SNORM,
+   DXGI_FORMAT_R16_FLOAT,
+};
+
+const DXGI_FORMAT cast_table_32bit[] = {
+   DXGI_FORMAT_R8G8B8A8_UINT,
+   DXGI_FORMAT_R8G8B8A8_UNORM,
+   DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+   DXGI_FORMAT_R8G8B8A8_SINT,
+   DXGI_FORMAT_R8G8B8A8_SNORM,
+   DXGI_FORMAT_B8G8R8A8_UNORM,
+   DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
+   DXGI_FORMAT_B8G8R8X8_UNORM,
+   DXGI_FORMAT_B8G8R8X8_UNORM_SRGB,
+   DXGI_FORMAT_R16G16_UINT,
+   DXGI_FORMAT_R16G16_UNORM,
+   DXGI_FORMAT_R16G16_SINT,
+   DXGI_FORMAT_R16G16_SNORM,
+   DXGI_FORMAT_R16G16_FLOAT,
+   DXGI_FORMAT_R32_UINT,
+   DXGI_FORMAT_R32_SINT,
+   DXGI_FORMAT_R32_FLOAT,
+   DXGI_FORMAT_D32_FLOAT,
+   DXGI_FORMAT_R11G11B10_FLOAT,
+   DXGI_FORMAT_R10G10B10A2_UINT,
+   DXGI_FORMAT_R10G10B10A2_UNORM,
+   DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
+};
+
+const DXGI_FORMAT cast_table_64bit[] = {
+   DXGI_FORMAT_R16G16B16A16_UINT,
+   DXGI_FORMAT_R16G16B16A16_UNORM,
+   DXGI_FORMAT_R16G16B16A16_SINT,
+   DXGI_FORMAT_R16G16B16A16_SNORM,
+   DXGI_FORMAT_R16G16B16A16_FLOAT,
+   DXGI_FORMAT_R32G32_UINT,
+   DXGI_FORMAT_R32G32_SINT,
+   DXGI_FORMAT_R32G32_FLOAT,
+};
+
+const DXGI_FORMAT cast_table_96bit[] = {
+   DXGI_FORMAT_R32G32B32_UINT,
+   DXGI_FORMAT_R32G32B32_SINT,
+   DXGI_FORMAT_R32G32B32_FLOAT,
+};
+
+const DXGI_FORMAT cast_table_128bit[] = {
+   DXGI_FORMAT_R32G32B32A32_UINT,
+   DXGI_FORMAT_R32G32B32A32_SINT,
+   DXGI_FORMAT_R32G32B32A32_FLOAT,
+};
+
+const DXGI_FORMAT cast_table_bc1[] = {
+   DXGI_FORMAT_BC1_UNORM,
+   DXGI_FORMAT_BC1_UNORM_SRGB,
+};
+
+const DXGI_FORMAT cast_table_bc2[] = {
+   DXGI_FORMAT_BC2_UNORM,
+   DXGI_FORMAT_BC2_UNORM_SRGB,
+};
+
+const DXGI_FORMAT cast_table_bc3[] = {
+   DXGI_FORMAT_BC3_UNORM,
+   DXGI_FORMAT_BC3_UNORM_SRGB,
+};
+
+const DXGI_FORMAT cast_table_bc4[] = {
+   DXGI_FORMAT_BC4_SNORM,
+   DXGI_FORMAT_BC4_UNORM,
+};
+
+const DXGI_FORMAT cast_table_bc5[] = {
+   DXGI_FORMAT_BC5_SNORM,
+   DXGI_FORMAT_BC5_UNORM,
+};
+
+const DXGI_FORMAT cast_table_bc6[] = {
+   DXGI_FORMAT_BC6H_SF16,
+   DXGI_FORMAT_BC6H_UF16,
+};
+
+const DXGI_FORMAT cast_table_bc7[] = {
+   DXGI_FORMAT_BC7_UNORM,
+   DXGI_FORMAT_BC7_UNORM_SRGB,
+};
+
+const DXGI_FORMAT *
+d3d12_get_format_cast_list(enum pipe_format format, uint32_t *num_formats)
+{
+   const struct util_format_description *format_desc = 
util_format_description(format);
+   if (util_format_has_depth(format_desc) || 
util_format_has_stencil(format_desc) || util_format_is_yuv(format))
+      return NULL;
+
+#define RET(table) *num_formats = ARRAY_SIZE(table); return table;
+   switch (format) {
+   case PIPE_FORMAT_DXT1_RGB:
+   case PIPE_FORMAT_DXT1_SRGB:
+   case PIPE_FORMAT_DXT1_RGBA:
+   case PIPE_FORMAT_DXT1_SRGBA:
+      RET(cast_table_bc1);
+   case PIPE_FORMAT_DXT3_RGBA:
+   case PIPE_FORMAT_DXT3_SRGBA:
+      RET(cast_table_bc2);
+   case PIPE_FORMAT_DXT5_RGBA:
+   case PIPE_FORMAT_DXT5_SRGBA:
+      RET(cast_table_bc3);
+   case PIPE_FORMAT_RGTC1_SNORM:
+   case PIPE_FORMAT_RGTC1_UNORM:
+      RET(cast_table_bc4);
+   case PIPE_FORMAT_RGTC2_SNORM:
+   case PIPE_FORMAT_RGTC2_UNORM:
+      RET(cast_table_bc5);
+   case PIPE_FORMAT_BPTC_RGBA_UNORM:
+   case PIPE_FORMAT_BPTC_SRGBA:
+      RET(cast_table_bc7);
+   case PIPE_FORMAT_BPTC_RGB_UFLOAT:
+   case PIPE_FORMAT_BPTC_RGB_FLOAT:
+      RET(cast_table_bc6);
+   default:
+      break;
+   }
+   switch (util_format_get_blocksizebits(format)) {
+   case 8: RET(cast_table_8bit);
+   case 16: RET(cast_table_16bit);
+   case 32: RET(cast_table_32bit);
+   case 64: RET(cast_table_64bit);
+   case 96: RET(cast_table_96bit);
+   case 128: RET(cast_table_128bit);
+   }
+   return NULL;
+}
+
 enum pipe_format
 d3d12_get_pipe_format(DXGI_FORMAT format)
 {
diff --git a/src/gallium/drivers/d3d12/d3d12_format.h 
b/src/gallium/drivers/d3d12/d3d12_format.h
index 31b6b15fb83..3fe8528c420 100644
--- a/src/gallium/drivers/d3d12/d3d12_format.h
+++ b/src/gallium/drivers/d3d12/d3d12_format.h
@@ -43,6 +43,9 @@ d3d12_get_format(enum pipe_format format);
 DXGI_FORMAT
 d3d12_get_typeless_format(enum pipe_format format);
 
+const DXGI_FORMAT *
+d3d12_get_format_cast_list(enum pipe_format format, uint32_t *num_formats);
+
 /* These two are only used for importing external resources without a provided 
template */
 enum pipe_format
 d3d12_get_pipe_format(DXGI_FORMAT format);
diff --git a/src/gallium/drivers/d3d12/d3d12_resource.cpp 
b/src/gallium/drivers/d3d12/d3d12_resource.cpp
index 05d035959d9..6b4d398aaf9 100644
--- a/src/gallium/drivers/d3d12/d3d12_resource.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_resource.cpp
@@ -260,23 +260,35 @@ init_texture(struct d3d12_screen *screen,
        */
    }
 
-   /* The VA frontend VaFourccToPipeFormat chooses _UNORM types for RGBx 
formats as typeless formats
-    * such as DXGI_R8G8B8A8_TYPELESS are not supported as Video Processor 
input/output as specified in:
-    * 
https://learn.microsoft.com/en-us/windows/win32/direct3ddxgi/hardware-support-for-direct3d-12-1-formats
-    * PIPE_BIND_CUSTOM is used by the video frontend to hint this resource 
will be used in video and the
-    * original format must be not converted to _TYPELESS
-   */
-   if ( ((templ->bind & PIPE_BIND_CUSTOM) == 0) &&
-      (screen->support_shader_images && templ->nr_samples <= 1)) {
-      /* Ideally, we'd key off of PIPE_BIND_SHADER_IMAGE for this, but it 
doesn't
-       * seem to be set properly. So, all UAV-capable resources need the UAV 
flag.
-       */
-      D3D12_FEATURE_DATA_FORMAT_SUPPORT support = { desc.Format };
-      if 
(SUCCEEDED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, 
&support, sizeof(support))) &&
-         (support.Support2 & (D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD | 
D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE)) ==
-         (D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD | 
D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE)) {
+   const DXGI_FORMAT *format_cast_list = NULL;
+   uint32_t num_castable_formats = 0;
+
+   if (screen->opts12.RelaxedFormatCastingSupported) {
+      /* All formats that fall into a cast set need to be castable and 
accessible as a shader image. */
+      format_cast_list = d3d12_get_format_cast_list(templ->format, 
&num_castable_formats);
+      if (format_cast_list != nullptr && 
!util_format_is_compressed(templ->format) &&
+          screen->support_shader_images && templ->nr_samples <= 1) {
          desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
-         desc.Format = d3d12_get_typeless_format(templ->format);
+      }
+   } else {
+      /* The VA frontend VaFourccToPipeFormat chooses _UNORM types for RGBx 
formats as typeless formats
+       * such as DXGI_R8G8B8A8_TYPELESS are not supported as Video Processor 
input/output as specified in:
+       * 
https://learn.microsoft.com/en-us/windows/win32/direct3ddxgi/hardware-support-for-direct3d-12-1-formats
+       * PIPE_BIND_CUSTOM is used by the video frontend to hint this resource 
will be used in video and the
+       * original format must be not converted to _TYPELESS
+      */
+      if (((templ->bind & PIPE_BIND_CUSTOM) == 0) &&
+          (screen->support_shader_images && templ->nr_samples <= 1)) {
+         /* Ideally, we'd key off of PIPE_BIND_SHADER_IMAGE for this, but it 
doesn't
+          * seem to be set properly. So, all UAV-capable resources need the 
UAV flag.
+          */
+         D3D12_FEATURE_DATA_FORMAT_SUPPORT support = { desc.Format };
+         if 
(SUCCEEDED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, 
&support, sizeof(support))) &&
+             (support.Support2 & (D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD | 
D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE)) ==
+             (D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD | 
D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE)) {
+            desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
+            desc.Format = d3d12_get_typeless_format(templ->format);
+         }
       }
    }
 
@@ -286,27 +298,70 @@ init_texture(struct d3d12_screen *screen,
    HRESULT hres = E_FAIL;
    enum d3d12_residency_status init_residency;
 
-   if (heap) {
-      init_residency = d3d12_permanently_resident;
-      hres = screen->dev->CreatePlacedResource(heap,
-                                               placed_offset,
-                                               &desc,
-                                               D3D12_RESOURCE_STATE_COMMON,
-                                               nullptr,
-                                               IID_PPV_ARGS(&d3d12_res));
+   if (screen->opts12.RelaxedFormatCastingSupported) {
+      D3D12_RESOURCE_DESC1 desc1 = {
+         desc.Dimension,
+         desc.Alignment,
+         desc.Width,
+         desc.Height,
+         desc.DepthOrArraySize,
+         desc.MipLevels,
+         desc.Format,
+         desc.SampleDesc,
+         desc.Layout,
+         desc.Flags,
+      };
+      if (heap) {
+         init_residency = d3d12_permanently_resident;
+         hres = screen->dev10->CreatePlacedResource2(heap,
+                                                     placed_offset,
+                                                     &desc1,
+                                                     
D3D12_BARRIER_LAYOUT_COMMON,
+                                                     nullptr,
+                                                     num_castable_formats,
+                                                     format_cast_list,
+                                                     IID_PPV_ARGS(&d3d12_res));
+      }
+      else {
+         D3D12_HEAP_PROPERTIES heap_pris = 
GetCustomHeapProperties(screen->dev, D3D12_HEAP_TYPE_DEFAULT);
+
+         D3D12_HEAP_FLAGS heap_flags = screen->support_create_not_resident ?
+            D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT : D3D12_HEAP_FLAG_NONE;
+         init_residency = screen->support_create_not_resident ? d3d12_evicted 
: d3d12_resident;
+
+         hres = screen->dev10->CreateCommittedResource3(&heap_pris,
+                                                        heap_flags,
+                                                        &desc1,
+                                                        
D3D12_BARRIER_LAYOUT_COMMON,
+                                                        nullptr,
+                                                        nullptr,
+                                                        num_castable_formats,
+                                                        format_cast_list,
+                                                        
IID_PPV_ARGS(&d3d12_res));
+      }
    } else {
-      D3D12_HEAP_PROPERTIES heap_pris = GetCustomHeapProperties(screen->dev, 
D3D12_HEAP_TYPE_DEFAULT);
-
-      D3D12_HEAP_FLAGS heap_flags = screen->support_create_not_resident ?
-         D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT : D3D12_HEAP_FLAG_NONE;
-      init_residency = screen->support_create_not_resident ? d3d12_evicted : 
d3d12_resident;
-
-      hres = screen->dev->CreateCommittedResource(&heap_pris,
-                                                  heap_flags,
+      if (heap) {
+         init_residency = d3d12_permanently_resident;
+         hres = screen->dev->CreatePlacedResource(heap,
+                                                  placed_offset,
                                                   &desc,
                                                   D3D12_RESOURCE_STATE_COMMON,
-                                                  NULL,
+                                                  nullptr,
                                                   IID_PPV_ARGS(&d3d12_res));
+      } else {
+         D3D12_HEAP_PROPERTIES heap_pris = 
GetCustomHeapProperties(screen->dev, D3D12_HEAP_TYPE_DEFAULT);
+
+         D3D12_HEAP_FLAGS heap_flags = screen->support_create_not_resident ?
+            D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT : D3D12_HEAP_FLAG_NONE;
+         init_residency = screen->support_create_not_resident ? d3d12_evicted 
: d3d12_resident;
+
+         hres = screen->dev->CreateCommittedResource(&heap_pris,
+                                                     heap_flags,
+                                                     &desc,
+                                                     
D3D12_RESOURCE_STATE_COMMON,
+                                                     NULL,
+                                                     IID_PPV_ARGS(&d3d12_res));
+      }
    }
 
    if (FAILED(hres))
@@ -362,6 +417,7 @@ convert_planar_resource(struct d3d12_resource *res)
 #if DEBUG
       struct d3d12_screen *screen = d3d12_screen(res->base.b.screen);
       D3D12_RESOURCE_DESC desc = GetDesc(res->bo->res);
+      desc.Flags = D3D12_RESOURCE_FLAG_NONE;
       D3D12_PLACED_SUBRESOURCE_FOOTPRINT placed_footprint = {};
       D3D12_SUBRESOURCE_FOOTPRINT *footprint = &placed_footprint.Footprint;
       unsigned subresource = plane * desc.MipLevels * desc.DepthOrArraySize;
@@ -541,7 +597,9 @@ d3d12_resource_from_handle(struct pipe_screen *pscreen,
    /* Get a description for this plane */
    if (templ && handle->format != templ->format) {
       unsigned subresource = handle->plane * incoming_res_desc.MipLevels * 
incoming_res_desc.DepthOrArraySize;
-      screen->dev->GetCopyableFootprints(&incoming_res_desc, subresource, 1, 
0, &placed_footprint, nullptr, nullptr, nullptr);
+      auto temp_desc = incoming_res_desc;
+      temp_desc.Flags = D3D12_RESOURCE_FLAG_NONE;
+      screen->dev->GetCopyableFootprints(&temp_desc, subresource, 1, 0, 
&placed_footprint, nullptr, nullptr, nullptr);
    } else {
       footprint->Format = incoming_res_desc.Format;
       footprint->Width = incoming_res_desc.Width;
@@ -1041,6 +1099,7 @@ fill_buffer_location(struct d3d12_context *ctx,
    D3D12_PLACED_SUBRESOURCE_FOOTPRINT footprint;
    uint64_t offset = 0;
    auto descr = GetDesc(d3d12_resource_underlying(res, &offset));
+   descr.Flags = D3D12_RESOURCE_FLAG_NONE;
    struct d3d12_screen *screen = d3d12_screen(ctx->base.screen);
    ID3D12Device* dev = screen->dev;
 
diff --git a/src/gallium/drivers/d3d12/d3d12_screen.cpp 
b/src/gallium/drivers/d3d12/d3d12_screen.cpp
index a2a45e6d7cc..821c16ea922 100644
--- a/src/gallium/drivers/d3d12/d3d12_screen.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_screen.cpp
@@ -346,6 +346,9 @@ d3d12_get_param(struct pipe_screen *pscreen, enum pipe_cap 
param)
        * if an app just creates, initializes, and destroys resources without 
explicitly flushing. */
       return 64 * 1024 * 1024;
 
+   case PIPE_CAP_SAMPLER_VIEW_TARGET:
+      return screen->opts12.RelaxedFormatCastingSupported;
+
    default:
       return u_pipe_screen_get_param_defaults(pscreen, param);
    }
@@ -736,6 +739,10 @@ d3d12_deinit_screen(struct d3d12_screen *screen)
       screen->cmdqueue->Release();
       screen->cmdqueue = nullptr;
    }
+   if (screen->dev10) {
+      screen->dev10->Release();
+      screen->dev10 = nullptr;
+   }
    if (screen->dev) {
       screen->dev->Release();
       screen->dev = nullptr;
@@ -1476,6 +1483,7 @@ d3d12_init_screen(struct d3d12_screen *screen, IUnknown 
*adapter)
       debug_printf("D3D12: failed to get device options\n");
       return false;
    }
+   screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS12, 
&screen->opts12, sizeof(screen->opts12));
    screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS14, 
&screen->opts14, sizeof(screen->opts14));
 #ifndef _GAMING_XBOX
    screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS19, 
&screen->opts19, sizeof(screen->opts19));
@@ -1619,6 +1627,7 @@ d3d12_init_screen(struct d3d12_screen *screen, IUnknown 
*adapter)
       dev8->Release();
       screen->support_create_not_resident = true;
    }
+   screen->dev->QueryInterface(&screen->dev10);
 #endif
 
    static constexpr uint64_t known_good_warp_version = 10ull << 48 | 22000ull 
<< 16;
diff --git a/src/gallium/drivers/d3d12/d3d12_screen.h 
b/src/gallium/drivers/d3d12/d3d12_screen.h
index bf70e879a82..fe8f919228b 100644
--- a/src/gallium/drivers/d3d12/d3d12_screen.h
+++ b/src/gallium/drivers/d3d12/d3d12_screen.h
@@ -67,6 +67,7 @@ struct d3d12_screen {
 
    util_dl_library *d3d12_mod;
    ID3D12Device3 *dev;
+   ID3D12Device10 *dev10;
    ID3D12CommandQueue *cmdqueue;
    bool (*init)(struct d3d12_screen *screen);
    void (*deinit)(struct d3d12_screen *screen);
@@ -116,6 +117,7 @@ struct d3d12_screen {
    D3D12_FEATURE_DATA_D3D12_OPTIONS2 opts2;
    D3D12_FEATURE_DATA_D3D12_OPTIONS3 opts3;
    D3D12_FEATURE_DATA_D3D12_OPTIONS4 opts4;
+   D3D12_FEATURE_DATA_D3D12_OPTIONS12 opts12;
    D3D12_FEATURE_DATA_D3D12_OPTIONS14 opts14;
 #ifndef _GAMING_XBOX
    D3D12_FEATURE_DATA_D3D12_OPTIONS19 opts19;

Reply via email to