From fb3c29362126b9ac3690ef5099dd6f2e5ade30bc Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 4 Sep 2020 23:23:31 +0100 Subject: [PATCH] Create a default SRV/UAV descriptor when needed. Closes #2040 * In D3D12 if the user passes NULL for the UAV or SRV descriptor when calling Create*View we don't have the runtime to generate a default one for us when we query, we'll just have nothing stored. So instead when we need to generate a default "whole resource" descriptor to look up. --- renderdoc/driver/d3d12/d3d12_replay.cpp | 6 ++ renderdoc/driver/d3d12/d3d12_resources.cpp | 102 +++++++++++++++++++ renderdoc/driver/d3d12/d3d12_resources.h | 3 + renderdoc/driver/d3d12/d3d12_shaderdebug.cpp | 20 ++++ 4 files changed, 131 insertions(+) diff --git a/renderdoc/driver/d3d12/d3d12_replay.cpp b/renderdoc/driver/d3d12/d3d12_replay.cpp index ebbbd35c2..ea2364579 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.cpp +++ b/renderdoc/driver/d3d12/d3d12_replay.cpp @@ -746,6 +746,9 @@ void D3D12Replay::FillResourceView(D3D12Pipe::View &view, const D3D12Descriptor { D3D12_SHADER_RESOURCE_VIEW_DESC srv = desc->GetSRV(); + if(srv.ViewDimension == D3D12_SRV_DIMENSION_UNKNOWN) + srv = MakeSRVDesc(res); + fmt = srv.Format; view.type = MakeTextureDim(srv.ViewDimension); @@ -830,6 +833,9 @@ void D3D12Replay::FillResourceView(D3D12Pipe::View &view, const D3D12Descriptor { D3D12_UNORDERED_ACCESS_VIEW_DESC uav = desc->GetUAV(); + if(uav.ViewDimension == D3D12_UAV_DIMENSION_UNKNOWN) + uav = MakeUAVDesc(res); + fmt = uav.Format; view.counterResourceId = rm->GetOriginalID(desc->GetCounterResourceId()); diff --git a/renderdoc/driver/d3d12/d3d12_resources.cpp b/renderdoc/driver/d3d12/d3d12_resources.cpp index b8da6fc03..29ab6704b 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.cpp +++ b/renderdoc/driver/d3d12/d3d12_resources.cpp @@ -516,3 +516,105 @@ UINT GetSliceForRtv(const D3D12_RENDER_TARGET_VIEW_DESC &view) default: return 0; } } + +D3D12_SHADER_RESOURCE_VIEW_DESC MakeSRVDesc(const D3D12_RESOURCE_DESC &desc) +{ + D3D12_SHADER_RESOURCE_VIEW_DESC ret = {}; + + ret.Format = desc.Format; + ret.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + + bool arrayed = desc.DepthOrArraySize > 1; + + if(desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + // I don't think it's possible to create a SRV/SRV of a buffer with a NULL desc, but the docs + // and debug layer are quite hard to be sure. Put in something sensible. + + ret.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; + ret.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE; + ret.Buffer.StructureByteStride = 0; + ret.Buffer.FirstElement = 0; + ret.Buffer.NumElements = (UINT)desc.Width; + } + else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D) + { + ret.ViewDimension = arrayed ? D3D12_SRV_DIMENSION_TEXTURE1DARRAY : D3D12_SRV_DIMENSION_TEXTURE1D; + + // shared between arrayed and not + ret.Texture1D.MipLevels = desc.MipLevels; + + if(arrayed) + ret.Texture1DArray.ArraySize = desc.DepthOrArraySize; + } + else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D) + { + if(desc.SampleDesc.Count > 1) + { + ret.ViewDimension = + arrayed ? D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY : D3D12_SRV_DIMENSION_TEXTURE2DMS; + + if(arrayed) + ret.Texture2DMSArray.ArraySize = desc.DepthOrArraySize; + } + else + { + ret.ViewDimension = + arrayed ? D3D12_SRV_DIMENSION_TEXTURE2DARRAY : D3D12_SRV_DIMENSION_TEXTURE2D; + + // shared between arrayed and not + ret.Texture2D.MipLevels = desc.MipLevels; + + if(arrayed) + ret.Texture2DArray.ArraySize = desc.DepthOrArraySize; + } + } + else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) + { + ret.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D; + + ret.Texture3D.MipLevels = desc.MipLevels; + } + + return ret; +} + +D3D12_UNORDERED_ACCESS_VIEW_DESC MakeUAVDesc(const D3D12_RESOURCE_DESC &desc) +{ + D3D12_UNORDERED_ACCESS_VIEW_DESC ret = {}; + + ret.Format = desc.Format; + + bool arrayed = desc.DepthOrArraySize > 1; + + if(desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + // I don't think it's possible to create a UAV/SRV of a buffer with a NULL desc, but the docs + // and debug layer are quite hard to be sure. Put in something sensible. + + ret.ViewDimension = D3D12_UAV_DIMENSION_BUFFER; + ret.Buffer.NumElements = (UINT)desc.Width; + } + else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D) + { + ret.ViewDimension = arrayed ? D3D12_UAV_DIMENSION_TEXTURE1DARRAY : D3D12_UAV_DIMENSION_TEXTURE1D; + + if(arrayed) + ret.Texture1DArray.ArraySize = desc.DepthOrArraySize; + } + else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D) + { + ret.ViewDimension = arrayed ? D3D12_UAV_DIMENSION_TEXTURE2DARRAY : D3D12_UAV_DIMENSION_TEXTURE2D; + + if(arrayed) + ret.Texture2DArray.ArraySize = desc.DepthOrArraySize; + } + else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) + { + ret.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE3D; + + ret.Texture3D.WSize = desc.DepthOrArraySize; + } + + return ret; +} diff --git a/renderdoc/driver/d3d12/d3d12_resources.h b/renderdoc/driver/d3d12/d3d12_resources.h index 98072e853..c34238609 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.h +++ b/renderdoc/driver/d3d12/d3d12_resources.h @@ -37,6 +37,9 @@ UINT GetSliceForDsv(const D3D12_DEPTH_STENCIL_VIEW_DESC &dsv); UINT GetMipForRtv(const D3D12_RENDER_TARGET_VIEW_DESC &rtv); UINT GetSliceForRtv(const D3D12_RENDER_TARGET_VIEW_DESC &rtv); +D3D12_SHADER_RESOURCE_VIEW_DESC MakeSRVDesc(const D3D12_RESOURCE_DESC &desc); +D3D12_UNORDERED_ACCESS_VIEW_DESC MakeUAVDesc(const D3D12_RESOURCE_DESC &desc); + class TrackedResource12 { public: diff --git a/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp b/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp index f42fbcde2..c277e99ee 100644 --- a/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp +++ b/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp @@ -215,6 +215,9 @@ bool D3D12DebugAPIWrapper::FetchSRV(const DXBCDebug::BindingSlot &slot) ID3D12Resource *pResource = rm->GetCurrentAs(srvId); D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = desc->GetSRV(); + if(srvDesc.ViewDimension == D3D12_SRV_DIMENSION_UNKNOWN) + srvDesc = MakeSRVDesc(pResource->GetDesc()); + if(srvDesc.Format != DXGI_FORMAT_UNKNOWN) { DXBCDebug::FillViewFmt(srvDesc.Format, srvData.format); @@ -358,6 +361,10 @@ bool D3D12DebugAPIWrapper::FetchUAV(const DXBCDebug::BindingSlot &slot) // TODO: Need to fetch counter resource if applicable D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = desc->GetUAV(); + + if(uavDesc.ViewDimension == D3D12_UAV_DIMENSION_UNKNOWN) + uavDesc = MakeUAVDesc(pResource->GetDesc()); + if(uavDesc.Format != DXGI_FORMAT_UNKNOWN) { DXBCDebug::FillViewFmt(uavDesc.Format, uavData.format); @@ -569,6 +576,9 @@ ShaderVariable D3D12DebugAPIWrapper::GetSampleInfo(DXBCBytecode::OperandType typ ID3D12Resource *pResource = rm->GetCurrentAs(srvId); D3D12_RESOURCE_DESC resDesc = pResource->GetDesc(); D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = desc->GetSRV(); + if(srvDesc.ViewDimension == D3D12_SRV_DIMENSION_UNKNOWN) + srvDesc = MakeSRVDesc(resDesc); + if(srvDesc.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE2DMS || srvDesc.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY) { @@ -712,6 +722,9 @@ ShaderVariable D3D12DebugAPIWrapper::GetBufferInfo(DXBCBytecode::OperandType typ D3D12_RESOURCE_DESC resDesc = pResource->GetDesc(); D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = desc->GetUAV(); + if(uavDesc.ViewDimension == D3D12_UAV_DIMENSION_UNKNOWN) + uavDesc = MakeUAVDesc(resDesc); + if(uavDesc.ViewDimension == D3D12_UAV_DIMENSION_BUFFER) { result.value.u.x = result.value.u.y = result.value.u.z = result.value.u.w = @@ -726,6 +739,8 @@ ShaderVariable D3D12DebugAPIWrapper::GetBufferInfo(DXBCBytecode::OperandType typ ID3D12Resource *pResource = rm->GetCurrentAs(srvId); D3D12_RESOURCE_DESC resDesc = pResource->GetDesc(); D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = desc->GetSRV(); + if(srvDesc.ViewDimension == D3D12_SRV_DIMENSION_UNKNOWN) + srvDesc = MakeSRVDesc(resDesc); if(srvDesc.ViewDimension == D3D12_SRV_DIMENSION_BUFFER) { @@ -832,6 +847,9 @@ ShaderVariable D3D12DebugAPIWrapper::GetResourceInfo(DXBCBytecode::OperandType t D3D12_RESOURCE_DESC resDesc = pResource->GetDesc(); D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = desc->GetUAV(); + if(uavDesc.ViewDimension == D3D12_UAV_DIMENSION_UNKNOWN) + uavDesc = MakeUAVDesc(resDesc); + switch(uavDesc.ViewDimension) { case D3D12_UAV_DIMENSION_UNKNOWN: @@ -907,6 +925,8 @@ ShaderVariable D3D12DebugAPIWrapper::GetResourceInfo(DXBCBytecode::OperandType t ID3D12Resource *pResource = rm->GetCurrentAs(srvId); D3D12_RESOURCE_DESC resDesc = pResource->GetDesc(); D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = desc->GetSRV(); + if(srvDesc.ViewDimension == D3D12_SRV_DIMENSION_UNKNOWN) + srvDesc = MakeSRVDesc(resDesc); switch(srvDesc.ViewDimension) { case D3D12_SRV_DIMENSION_UNKNOWN: