d3d12: Support ARB_texture_view

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26104>
This commit is contained in:
Jesse Natalie 2023-11-03 15:29:21 -07:00 committed by Marge Bot
parent 56589cb02c
commit 438be4f9a0
9 changed files with 298 additions and 66 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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);

View file

@ -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;

View file

@ -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)
{

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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;