From 155571eecfa3db7a1e449a6cfaafa4ba024a19a0 Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 25 Oct 2017 00:22:40 +0100 Subject: [PATCH] Ensure descriptors for multi-plane images are valid on replay --- renderdoc/driver/d3d12/d3d12_manager.cpp | 132 +++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/renderdoc/driver/d3d12/d3d12_manager.cpp b/renderdoc/driver/d3d12/d3d12_manager.cpp index 76a2b2ea4..1ff1e717f 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.cpp +++ b/renderdoc/driver/d3d12/d3d12_manager.cpp @@ -217,6 +217,50 @@ void D3D12Descriptor::Create(D3D12_DESCRIPTOR_HEAP_TYPE heapType, WrappedID3D12D } } + D3D12_SHADER_RESOURCE_VIEW_DESC planeDesc; + // ensure that multi-plane formats have a valid plane slice specified. This shouldn't be + // possible as it should be the application's responsibility to be valid too, but we fix it up + // here anyway. + if(nonsamp.resource) + { + D3D12_FEATURE_DATA_FORMAT_INFO formatInfo = {}; + formatInfo.Format = desc->Format; + dev->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO, &formatInfo, sizeof(formatInfo)); + + // if this format is multi-plane + if(formatInfo.PlaneCount > 1) + { + planeDesc = *desc; + desc = &planeDesc; + + // detect formats that only read plane 1 and set the planeslice to 1 + if(desc->Format == DXGI_FORMAT_X24_TYPELESS_G8_UINT || + desc->Format == DXGI_FORMAT_X32_TYPELESS_G8X24_UINT) + { + switch(planeDesc.ViewDimension) + { + case D3D12_SRV_DIMENSION_TEXTURE2D: planeDesc.Texture2D.PlaneSlice = 1; break; + case D3D12_SRV_DIMENSION_TEXTURE2DARRAY: + planeDesc.Texture2DArray.PlaneSlice = 1; + break; + default: break; + } + } + else + { + // otherwise set it to 0 + switch(planeDesc.ViewDimension) + { + case D3D12_SRV_DIMENSION_TEXTURE2D: planeDesc.Texture2D.PlaneSlice = 0; break; + case D3D12_SRV_DIMENSION_TEXTURE2DARRAY: + planeDesc.Texture2DArray.PlaneSlice = 0; + break; + default: break; + } + } + } + } + dev->CreateShaderResourceView(nonsamp.resource, desc, handle); break; } @@ -275,6 +319,50 @@ void D3D12Descriptor::Create(D3D12_DESCRIPTOR_HEAP_TYPE heapType, WrappedID3D12D } } + D3D12_RENDER_TARGET_VIEW_DESC planeDesc; + // ensure that multi-plane formats have a valid plane slice specified. This shouldn't be + // possible as it should be the application's responsibility to be valid too, but we fix it up + // here anyway. + if(nonsamp.resource) + { + D3D12_FEATURE_DATA_FORMAT_INFO formatInfo = {}; + formatInfo.Format = desc->Format; + dev->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO, &formatInfo, sizeof(formatInfo)); + + // if this format is multi-plane + if(formatInfo.PlaneCount > 1) + { + planeDesc = *desc; + desc = &planeDesc; + + // detect formats that only read plane 1 and set the planeslice to 1 + if(desc->Format == DXGI_FORMAT_X24_TYPELESS_G8_UINT || + desc->Format == DXGI_FORMAT_X32_TYPELESS_G8X24_UINT) + { + switch(planeDesc.ViewDimension) + { + case D3D12_RTV_DIMENSION_TEXTURE2D: planeDesc.Texture2D.PlaneSlice = 1; break; + case D3D12_RTV_DIMENSION_TEXTURE2DARRAY: + planeDesc.Texture2DArray.PlaneSlice = 1; + break; + default: break; + } + } + else + { + // otherwise set it to 0 + switch(planeDesc.ViewDimension) + { + case D3D12_RTV_DIMENSION_TEXTURE2D: planeDesc.Texture2D.PlaneSlice = 0; break; + case D3D12_RTV_DIMENSION_TEXTURE2DARRAY: + planeDesc.Texture2DArray.PlaneSlice = 0; + break; + default: break; + } + } + } + } + dev->CreateRenderTargetView(nonsamp.resource, desc, handle); break; } @@ -389,6 +477,50 @@ void D3D12Descriptor::Create(D3D12_DESCRIPTOR_HEAP_TYPE heapType, WrappedID3D12D } } + D3D12_UNORDERED_ACCESS_VIEW_DESC planeDesc; + // ensure that multi-plane formats have a valid plane slice specified. This shouldn't be + // possible as it should be the application's responsibility to be valid too, but we fix it up + // here anyway. + if(nonsamp.resource) + { + D3D12_FEATURE_DATA_FORMAT_INFO formatInfo = {}; + formatInfo.Format = desc->Format; + dev->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO, &formatInfo, sizeof(formatInfo)); + + // if this format is multi-plane + if(formatInfo.PlaneCount > 1) + { + planeDesc = *desc; + desc = &planeDesc; + + // detect formats that only read plane 1 and set the planeslice to 1 + if(desc->Format == DXGI_FORMAT_X24_TYPELESS_G8_UINT || + desc->Format == DXGI_FORMAT_X32_TYPELESS_G8X24_UINT) + { + switch(planeDesc.ViewDimension) + { + case D3D12_UAV_DIMENSION_TEXTURE2D: planeDesc.Texture2D.PlaneSlice = 1; break; + case D3D12_UAV_DIMENSION_TEXTURE2DARRAY: + planeDesc.Texture2DArray.PlaneSlice = 1; + break; + default: break; + } + } + else + { + // otherwise set it to 0 + switch(planeDesc.ViewDimension) + { + case D3D12_UAV_DIMENSION_TEXTURE2D: planeDesc.Texture2D.PlaneSlice = 0; break; + case D3D12_UAV_DIMENSION_TEXTURE2DARRAY: + planeDesc.Texture2DArray.PlaneSlice = 0; + break; + default: break; + } + } + } + } + dev->CreateUnorderedAccessView(nonsamp.resource, counter, desc, handle); break; }