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

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