Reland "Support depth32float sampling on D3D12"
This is a reland of 071fe56ffe
It creates textures as TYPELESS if they may need reinterpretation
of the bit layout. Right now only sampled Depth32Float needs this
so it is special-cased.
Original change's description:
> Support depth32float sampling on D3D12
>
> Bug: dawn:367
> Change-Id: I026e718130cbd92427c6292045fd041c878d4f77
> Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/20840
> Commit-Queue: Austin Eng <enga@chromium.org>
> Reviewed-by: Stephen White <senorblanco@chromium.org>
Bug: dawn:367
Change-Id: I8b0ad465915c4476099fc1097e0cd02b23bd21b6
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/21640
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Rafael Cintron <rafael.cintron@microsoft.com>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
75ef5963b4
commit
983211974b
|
@ -36,48 +36,52 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
Sampler::Sampler(Device* device, const SamplerDescriptor* descriptor)
|
||||
: SamplerBase(device, descriptor) {
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/dn770367(v=vs.85).aspx
|
||||
// hex value, decimal value, min linear, mag linear, mip linear
|
||||
// D3D12_FILTER_MIN_MAG_MIP_POINT = 0 0 0 0 0
|
||||
// D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR = 0x1 1 0 0 1
|
||||
// D3D12_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x4 4 0 1 0
|
||||
// D3D12_FILTER_MIN_POINT_MAG_MIP_LINEAR = 0x5 5 0 1 1
|
||||
// D3D12_FILTER_MIN_LINEAR_MAG_MIP_POINT = 0x10 16 1 0 0
|
||||
// D3D12_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x11 17 1 0 1
|
||||
// D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT = 0x14 20 1 1 0
|
||||
// D3D12_FILTER_MIN_MAG_MIP_LINEAR = 0x15 21 1 1 1
|
||||
|
||||
// if mip mode is linear, add 1
|
||||
// if mag mode is linear, add 4
|
||||
// if min mode is linear, add 16
|
||||
|
||||
uint8_t mode = 0;
|
||||
|
||||
D3D12_FILTER_TYPE minFilter;
|
||||
switch (descriptor->minFilter) {
|
||||
case wgpu::FilterMode::Nearest:
|
||||
minFilter = D3D12_FILTER_TYPE_POINT;
|
||||
break;
|
||||
case wgpu::FilterMode::Linear:
|
||||
mode += 16;
|
||||
minFilter = D3D12_FILTER_TYPE_LINEAR;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
|
||||
D3D12_FILTER_TYPE magFilter;
|
||||
switch (descriptor->magFilter) {
|
||||
case wgpu::FilterMode::Nearest:
|
||||
magFilter = D3D12_FILTER_TYPE_POINT;
|
||||
break;
|
||||
case wgpu::FilterMode::Linear:
|
||||
mode += 4;
|
||||
magFilter = D3D12_FILTER_TYPE_LINEAR;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
|
||||
D3D12_FILTER_TYPE mipmapFilter;
|
||||
switch (descriptor->mipmapFilter) {
|
||||
case wgpu::FilterMode::Nearest:
|
||||
mipmapFilter = D3D12_FILTER_TYPE_POINT;
|
||||
break;
|
||||
case wgpu::FilterMode::Linear:
|
||||
mode += 1;
|
||||
mipmapFilter = D3D12_FILTER_TYPE_LINEAR;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
|
||||
mSamplerDesc.Filter = static_cast<D3D12_FILTER>(mode);
|
||||
D3D12_FILTER_REDUCTION_TYPE reduction =
|
||||
descriptor->compare == wgpu::CompareFunction::Undefined
|
||||
? D3D12_FILTER_REDUCTION_TYPE_STANDARD
|
||||
: D3D12_FILTER_REDUCTION_TYPE_COMPARISON;
|
||||
|
||||
mSamplerDesc.Filter =
|
||||
D3D12_ENCODE_BASIC_FILTER(minFilter, magFilter, mipmapFilter, reduction);
|
||||
mSamplerDesc.AddressU = AddressMode(descriptor->addressModeU);
|
||||
mSamplerDesc.AddressV = AddressMode(descriptor->addressModeV);
|
||||
mSamplerDesc.AddressW = AddressMode(descriptor->addressModeW);
|
||||
|
|
|
@ -105,6 +105,108 @@ namespace dawn_native { namespace d3d12 {
|
|||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
DXGI_FORMAT D3D12TypelessTextureFormat(wgpu::TextureFormat format) {
|
||||
switch (format) {
|
||||
case wgpu::TextureFormat::R8Unorm:
|
||||
case wgpu::TextureFormat::R8Snorm:
|
||||
case wgpu::TextureFormat::R8Uint:
|
||||
case wgpu::TextureFormat::R8Sint:
|
||||
return DXGI_FORMAT_R8_TYPELESS;
|
||||
|
||||
case wgpu::TextureFormat::R16Uint:
|
||||
case wgpu::TextureFormat::R16Sint:
|
||||
case wgpu::TextureFormat::R16Float:
|
||||
return DXGI_FORMAT_R16_TYPELESS;
|
||||
|
||||
case wgpu::TextureFormat::RG8Unorm:
|
||||
case wgpu::TextureFormat::RG8Snorm:
|
||||
case wgpu::TextureFormat::RG8Uint:
|
||||
case wgpu::TextureFormat::RG8Sint:
|
||||
return DXGI_FORMAT_R8G8_TYPELESS;
|
||||
|
||||
case wgpu::TextureFormat::R32Uint:
|
||||
case wgpu::TextureFormat::R32Sint:
|
||||
case wgpu::TextureFormat::R32Float:
|
||||
return DXGI_FORMAT_R32_TYPELESS;
|
||||
|
||||
case wgpu::TextureFormat::RG16Uint:
|
||||
case wgpu::TextureFormat::RG16Sint:
|
||||
case wgpu::TextureFormat::RG16Float:
|
||||
return DXGI_FORMAT_R16G16_TYPELESS;
|
||||
|
||||
case wgpu::TextureFormat::RGBA8Unorm:
|
||||
case wgpu::TextureFormat::RGBA8UnormSrgb:
|
||||
case wgpu::TextureFormat::RGBA8Snorm:
|
||||
case wgpu::TextureFormat::RGBA8Uint:
|
||||
case wgpu::TextureFormat::RGBA8Sint:
|
||||
return DXGI_FORMAT_R8G8B8A8_TYPELESS;
|
||||
|
||||
case wgpu::TextureFormat::BGRA8Unorm:
|
||||
case wgpu::TextureFormat::BGRA8UnormSrgb:
|
||||
return DXGI_FORMAT_B8G8R8A8_TYPELESS;
|
||||
|
||||
case wgpu::TextureFormat::RGB10A2Unorm:
|
||||
return DXGI_FORMAT_R10G10B10A2_TYPELESS;
|
||||
|
||||
case wgpu::TextureFormat::RG11B10Float:
|
||||
return DXGI_FORMAT_R11G11B10_FLOAT;
|
||||
|
||||
case wgpu::TextureFormat::RG32Uint:
|
||||
case wgpu::TextureFormat::RG32Sint:
|
||||
case wgpu::TextureFormat::RG32Float:
|
||||
return DXGI_FORMAT_R32G32_TYPELESS;
|
||||
|
||||
case wgpu::TextureFormat::RGBA16Uint:
|
||||
case wgpu::TextureFormat::RGBA16Sint:
|
||||
case wgpu::TextureFormat::RGBA16Float:
|
||||
return DXGI_FORMAT_R16G16B16A16_TYPELESS;
|
||||
|
||||
case wgpu::TextureFormat::RGBA32Uint:
|
||||
case wgpu::TextureFormat::RGBA32Sint:
|
||||
case wgpu::TextureFormat::RGBA32Float:
|
||||
return DXGI_FORMAT_R32G32B32A32_TYPELESS;
|
||||
|
||||
case wgpu::TextureFormat::Depth32Float:
|
||||
case wgpu::TextureFormat::Depth24Plus:
|
||||
return DXGI_FORMAT_R32_TYPELESS;
|
||||
|
||||
case wgpu::TextureFormat::Depth24PlusStencil8:
|
||||
return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT;
|
||||
|
||||
case wgpu::TextureFormat::BC1RGBAUnorm:
|
||||
case wgpu::TextureFormat::BC1RGBAUnormSrgb:
|
||||
return DXGI_FORMAT_BC1_TYPELESS;
|
||||
|
||||
case wgpu::TextureFormat::BC2RGBAUnorm:
|
||||
case wgpu::TextureFormat::BC2RGBAUnormSrgb:
|
||||
return DXGI_FORMAT_BC2_TYPELESS;
|
||||
|
||||
case wgpu::TextureFormat::BC3RGBAUnorm:
|
||||
case wgpu::TextureFormat::BC3RGBAUnormSrgb:
|
||||
return DXGI_FORMAT_BC3_TYPELESS;
|
||||
|
||||
case wgpu::TextureFormat::BC4RSnorm:
|
||||
case wgpu::TextureFormat::BC4RUnorm:
|
||||
return DXGI_FORMAT_BC4_TYPELESS;
|
||||
|
||||
case wgpu::TextureFormat::BC5RGSnorm:
|
||||
case wgpu::TextureFormat::BC5RGUnorm:
|
||||
return DXGI_FORMAT_BC5_TYPELESS;
|
||||
|
||||
case wgpu::TextureFormat::BC6HRGBSfloat:
|
||||
case wgpu::TextureFormat::BC6HRGBUfloat:
|
||||
return DXGI_FORMAT_BC6H_TYPELESS;
|
||||
|
||||
case wgpu::TextureFormat::BC7RGBAUnorm:
|
||||
case wgpu::TextureFormat::BC7RGBAUnormSrgb:
|
||||
return DXGI_FORMAT_BC7_TYPELESS;
|
||||
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
DXGI_FORMAT D3D12TextureFormat(wgpu::TextureFormat format) {
|
||||
|
@ -347,9 +449,18 @@ namespace dawn_native { namespace d3d12 {
|
|||
resourceDescriptor.Width = size.width;
|
||||
resourceDescriptor.Height = size.height;
|
||||
|
||||
// This will need to be much more nuanced when WebGPU has
|
||||
// texture view compatibility rules.
|
||||
bool needsTypelessFormat = GetFormat().format == wgpu::TextureFormat::Depth32Float &&
|
||||
(GetUsage() & wgpu::TextureUsage::Sampled) != 0;
|
||||
|
||||
DXGI_FORMAT dxgiFormat = needsTypelessFormat
|
||||
? D3D12TypelessTextureFormat(GetFormat().format)
|
||||
: D3D12TextureFormat(GetFormat().format);
|
||||
|
||||
resourceDescriptor.DepthOrArraySize = GetDepthOrArraySize();
|
||||
resourceDescriptor.MipLevels = static_cast<UINT16>(GetNumMipLevels());
|
||||
resourceDescriptor.Format = D3D12TextureFormat(GetFormat().format);
|
||||
resourceDescriptor.Format = dxgiFormat;
|
||||
resourceDescriptor.SampleDesc.Count = GetSampleCount();
|
||||
// TODO(bryan.bernhart@intel.com): investigate how to specify standard MSAA sample pattern.
|
||||
resourceDescriptor.SampleDesc.Quality = 0;
|
||||
|
@ -772,6 +883,11 @@ namespace dawn_native { namespace d3d12 {
|
|||
TextureView::TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor)
|
||||
: TextureViewBase(texture, descriptor) {
|
||||
mSrvDesc.Format = D3D12TextureFormat(descriptor->format);
|
||||
if (descriptor->format == wgpu::TextureFormat::Depth32Float) {
|
||||
// TODO(enga): This will need to be much more nuanced when WebGPU has
|
||||
// texture view compatibility rules.
|
||||
mSrvDesc.Format = DXGI_FORMAT_R32_FLOAT;
|
||||
}
|
||||
mSrvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
|
||||
// Currently we always use D3D12_TEX2D_ARRAY_SRV because we cannot specify base array layer
|
||||
|
|
|
@ -505,7 +505,8 @@ TEST_P(DepthSamplingTest, CompareFunctionsNonNormalizedContentsCompute) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO(crbug.com/dawn/367): Does not work on D3D12 because we need to reinterpret the texture view
|
||||
// as R32Float to sample it. See tables here:
|
||||
// https://docs.microsoft.com/en-us/windows/win32/direct3ddxgi/hardware-support-for-direct3d-12-1-formats
|
||||
DAWN_INSTANTIATE_TEST(DepthSamplingTest, MetalBackend(), OpenGLBackend(), VulkanBackend());
|
||||
DAWN_INSTANTIATE_TEST(DepthSamplingTest,
|
||||
D3D12Backend(),
|
||||
MetalBackend(),
|
||||
OpenGLBackend(),
|
||||
VulkanBackend());
|
||||
|
|
Loading…
Reference in New Issue