Read & Serialise D3D12 CPU descriptor contents immediately

* For Clear*View and OMSetRenderTargetViews, the CPU descriptor handles
  used are read immediately, the heap can be modified or even deleted
  after the call.
* So we save the contents of the descriptor, ignore the heap, and then
  fill a temporary heap with the descriptor whenever it's needed.
This commit is contained in:
baldurk
2018-05-10 15:17:54 +01:00
parent 2019c82d68
commit a77e6a0acd
12 changed files with 264 additions and 204 deletions
@@ -343,6 +343,7 @@ bool WrappedID3D12GraphicsCommandList::Serialise_Reset(SerialiserType &ser,
// reset state
D3D12RenderState &state = m_Cmd->m_BakedCmdListInfo[BakedCommandList].state;
state.m_ResourceManager = GetResourceManager();
state.m_DebugManager = m_pDevice->GetReplay()->GetDebugManager();
state.pipe = GetResID(pInitialState);
}
}
@@ -1238,72 +1239,116 @@ bool WrappedID3D12GraphicsCommandList::Serialise_OMSetRenderTargets(
UINT numHandles = RTsSingleHandleToDescriptorRange ? RDCMIN(1U, NumRenderTargetDescriptors)
: NumRenderTargetDescriptors;
SERIALISE_ELEMENT_ARRAY(pRenderTargetDescriptors, numHandles);
std::vector<D3D12Descriptor> RTVs;
if(ser.VersionCheck(0x5))
{
if(ser.IsWriting())
{
if(RTsSingleHandleToDescriptorRange)
{
const D3D12Descriptor *descs = GetWrapped(pRenderTargetDescriptors[0]);
RTVs.insert(RTVs.begin(), descs, descs + NumRenderTargetDescriptors);
}
else
{
for(UINT i = 0; i < NumRenderTargetDescriptors; i++)
RTVs.push_back(*GetWrapped(pRenderTargetDescriptors[i]));
}
}
// read and serialise the D3D12Descriptor contents directly, as the call has semantics of
// consuming the descriptor immediately
SERIALISE_ELEMENT(RTVs).Named("pRenderTargetDescriptors");
}
else
{
SERIALISE_ELEMENT_ARRAY(pRenderTargetDescriptors, numHandles);
if(IsReplayingAndReading())
{
for(UINT h = 0; h < numHandles; h++)
RTVs.push_back(*GetWrapped(pRenderTargetDescriptors[h]));
}
}
SERIALISE_ELEMENT_TYPED(bool, RTsSingleHandleToDescriptorRange);
SERIALISE_ELEMENT_OPT(pDepthStencilDescriptor);
D3D12Descriptor DSV = {};
if(ser.VersionCheck(0x5))
{
// read and serialise the D3D12Descriptor contents directly, as the call has semantics of
// consuming the descriptor immediately.
const D3D12Descriptor *pDSV = NULL;
if(ser.IsWriting())
pDSV = pDepthStencilDescriptor ? GetWrapped(*pDepthStencilDescriptor) : NULL;
SERIALISE_ELEMENT_OPT(pDSV).Named("pDepthStencilDescriptor");
if(pDSV)
DSV = *pDSV;
}
else
{
SERIALISE_ELEMENT_OPT(pDepthStencilDescriptor);
if(IsReplayingAndReading())
{
if(pDepthStencilDescriptor)
DSV = *GetWrapped(*pDepthStencilDescriptor);
}
}
SERIALISE_CHECK_READ_ERRORS();
if(IsReplayingAndReading())
{
// recalculate here during read
numHandles = RTsSingleHandleToDescriptorRange ? RDCMIN(1U, NumRenderTargetDescriptors)
: NumRenderTargetDescriptors;
m_Cmd->m_LastCmdListID = GetResourceManager()->GetOriginalID(GetResID(pCommandList));
std::vector<D3D12_CPU_DESCRIPTOR_HANDLE> unwrappedRTs;
unwrappedRTs.resize(numHandles);
for(UINT i = 0; i < numHandles; i++)
unwrappedRTs[i] = Unwrap(pRenderTargetDescriptors[i]);
unwrappedRTs.resize(RTVs.size());
for(size_t i = 0; i < RTVs.size(); i++)
{
unwrappedRTs[i] =
Unwrap(m_pDevice->GetReplay()->GetDebugManager()->GetTempDescriptor(RTVs[i], i));
}
D3D12_CPU_DESCRIPTOR_HANDLE unwrappedDSV;
if(pDepthStencilDescriptor)
unwrappedDSV = Unwrap(*pDepthStencilDescriptor);
D3D12_CPU_DESCRIPTOR_HANDLE unwrappedDSV = {};
if(DSV.nonsamp.resource)
{
unwrappedDSV = Unwrap(m_pDevice->GetReplay()->GetDebugManager()->GetTempDescriptor(DSV));
}
if(IsActiveReplaying(m_State))
{
if(m_Cmd->InRerecordRange(m_Cmd->m_LastCmdListID))
{
Unwrap(m_Cmd->RerecordCmdList(m_Cmd->m_LastCmdListID))
->OMSetRenderTargets(NumRenderTargetDescriptors, unwrappedRTs.data(),
RTsSingleHandleToDescriptorRange,
pDepthStencilDescriptor ? &unwrappedDSV : NULL);
->OMSetRenderTargets((UINT)unwrappedRTs.size(), unwrappedRTs.data(), FALSE,
unwrappedDSV.ptr ? &unwrappedDSV : NULL);
if(m_Cmd->IsPartialCmdList(m_Cmd->m_LastCmdListID))
{
m_Cmd->m_RenderState.rts.resize(numHandles);
for(UINT i = 0; i < numHandles; i++)
m_Cmd->m_RenderState.rts[i] = pRenderTargetDescriptors[i];
m_Cmd->m_RenderState.rtSingle = RTsSingleHandleToDescriptorRange != FALSE;
m_Cmd->m_RenderState.dsv =
pDepthStencilDescriptor ? *pDepthStencilDescriptor : D3D12_CPU_DESCRIPTOR_HANDLE();
m_Cmd->m_RenderState.rts = RTVs;
m_Cmd->m_RenderState.dsv = DSV;
}
}
}
else
{
Unwrap(pCommandList)
->OMSetRenderTargets(NumRenderTargetDescriptors, unwrappedRTs.data(),
RTsSingleHandleToDescriptorRange,
pDepthStencilDescriptor ? &unwrappedDSV : NULL);
GetCrackedList()->OMSetRenderTargets(NumRenderTargetDescriptors, unwrappedRTs.data(),
RTsSingleHandleToDescriptorRange,
pDepthStencilDescriptor ? &unwrappedDSV : NULL);
->OMSetRenderTargets((UINT)unwrappedRTs.size(), unwrappedRTs.data(), FALSE,
unwrappedDSV.ptr ? &unwrappedDSV : NULL);
GetCrackedList()->OMSetRenderTargets((UINT)unwrappedRTs.size(), unwrappedRTs.data(), FALSE,
unwrappedDSV.ptr ? &unwrappedDSV : NULL);
D3D12RenderState &state = m_Cmd->m_BakedCmdListInfo[m_Cmd->m_LastCmdListID].state;
state.rts.resize(numHandles);
for(UINT i = 0; i < numHandles; i++)
state.rts[i] = pRenderTargetDescriptors[i];
state.rtSingle = RTsSingleHandleToDescriptorRange != FALSE;
state.dsv = pDepthStencilDescriptor ? *pDepthStencilDescriptor : D3D12_CPU_DESCRIPTOR_HANDLE();
state.rts = RTVs;
state.dsv = DSV;
}
}
@@ -4279,7 +4324,19 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ClearDepthStencilView(
{
ID3D12GraphicsCommandList *pCommandList = this;
SERIALISE_ELEMENT(pCommandList);
SERIALISE_ELEMENT(DepthStencilView);
if(ser.VersionCheck(0x5))
{
// read and serialise the D3D12Descriptor contents directly, as the call has semantics of
// consuming the descriptor immediately
SERIALISE_ELEMENT_LOCAL(DSV, *GetWrapped(DepthStencilView)).Named("DepthStencilView");
if(IsReplayingAndReading())
DepthStencilView = m_pDevice->GetReplay()->GetDebugManager()->GetTempDescriptor(DSV);
}
else
{
SERIALISE_ELEMENT(DepthStencilView);
}
SERIALISE_ELEMENT(ClearFlags);
SERIALISE_ELEMENT(Depth);
SERIALISE_ELEMENT(Stencil);
@@ -4366,7 +4423,19 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ClearRenderTargetView(
{
ID3D12GraphicsCommandList *pCommandList = this;
SERIALISE_ELEMENT(pCommandList);
SERIALISE_ELEMENT(RenderTargetView);
if(ser.VersionCheck(0x5))
{
// read and serialise the D3D12Descriptor contents directly, as the call has semantics of
// consuming the descriptor immediately
SERIALISE_ELEMENT_LOCAL(RTV, *GetWrapped(RenderTargetView)).Named("RenderTargetView");
if(IsReplayingAndReading())
RenderTargetView = m_pDevice->GetReplay()->GetDebugManager()->GetTempDescriptor(RTV);
}
else
{
SERIALISE_ELEMENT(RenderTargetView);
}
SERIALISE_ELEMENT_ARRAY(ColorRGBA, 4);
SERIALISE_ELEMENT(NumRects);
SERIALISE_ELEMENT_ARRAY(pRects, NumRects);
@@ -4449,7 +4518,19 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ClearUnorderedAccessViewUint(
ID3D12GraphicsCommandList *pCommandList = this;
SERIALISE_ELEMENT(pCommandList);
SERIALISE_ELEMENT(ViewGPUHandleInCurrentHeap);
SERIALISE_ELEMENT(ViewCPUHandle);
if(ser.VersionCheck(0x5))
{
// read and serialise the D3D12Descriptor contents directly, as the call has semantics of
// consuming the descriptor immediately. This is only true for the CPU-side handle
SERIALISE_ELEMENT_LOCAL(UAV, *GetWrapped(ViewCPUHandle)).Named("ViewCPUHandle");
if(IsReplayingAndReading())
ViewCPUHandle = m_pDevice->GetReplay()->GetDebugManager()->GetTempDescriptor(UAV);
}
else
{
SERIALISE_ELEMENT(ViewCPUHandle);
}
SERIALISE_ELEMENT(pResource);
SERIALISE_ELEMENT_ARRAY(Values, 4);
SERIALISE_ELEMENT(NumRects);
@@ -4542,7 +4623,19 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ClearUnorderedAccessViewFloat(
ID3D12GraphicsCommandList *pCommandList = this;
SERIALISE_ELEMENT(pCommandList);
SERIALISE_ELEMENT(ViewGPUHandleInCurrentHeap);
SERIALISE_ELEMENT(ViewCPUHandle);
if(ser.VersionCheck(0x5))
{
// read and serialise the D3D12Descriptor contents directly, as the call has semantics of
// consuming the descriptor immediately. This is only true for the CPU-side handle
SERIALISE_ELEMENT_LOCAL(UAV, *GetWrapped(ViewCPUHandle)).Named("ViewCPUHandle");
if(IsReplayingAndReading())
ViewCPUHandle = m_pDevice->GetReplay()->GetDebugManager()->GetTempDescriptor(UAV);
}
else
{
SERIALISE_ELEMENT(ViewCPUHandle);
}
SERIALISE_ELEMENT(pResource);
SERIALISE_ELEMENT_ARRAY(Values, 4);
SERIALISE_ELEMENT(NumRects);
+3 -1
View File
@@ -108,7 +108,9 @@ bool D3D12InitParams::IsSupportedVersion(uint64_t ver)
if(ver == CurrentVersion)
return true;
// we can check other older versions we support here.
// see header for explanation of version changes
if(ver == 0x4)
return true;
return false;
}
+35
View File
@@ -426,6 +426,41 @@ D3D12_GPU_DESCRIPTOR_HANDLE D3D12DebugManager::GetGPUHandle(SamplerSlot slot)
return ret;
}
D3D12_CPU_DESCRIPTOR_HANDLE D3D12DebugManager::GetTempDescriptor(const D3D12Descriptor &desc,
size_t idx)
{
D3D12_CPU_DESCRIPTOR_HANDLE ret = {};
if(desc.GetType() == D3D12DescriptorType::RTV)
{
ret = GetCPUHandle(FIRST_TMP_RTV);
ret.ptr += idx * sizeof(D3D12Descriptor);
m_pDevice->CreateRenderTargetView(desc.nonsamp.resource, &desc.nonsamp.rtv, ret);
}
else if(desc.GetType() == D3D12DescriptorType::DSV)
{
ret = GetCPUHandle(TMP_DSV);
m_pDevice->CreateDepthStencilView(desc.nonsamp.resource, &desc.nonsamp.dsv, ret);
}
else if(desc.GetType() == D3D12DescriptorType::UAV)
{
// need a non-shader visible heap for this one
ret = GetCPUHandle(TMP_UAV);
D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = desc.nonsamp.uav.desc.AsDesc();
m_pDevice->CreateUnorderedAccessView(desc.nonsamp.resource, desc.nonsamp.uav.counterResource,
&uavDesc, ret);
}
else
{
RDCERR("Unexpected descriptor type %s for temp descriptor!", ToStr(desc.GetType()).c_str());
}
return ret;
}
void D3D12DebugManager::SetDescriptorHeaps(ID3D12GraphicsCommandList *list, bool cbvsrvuav,
bool samplers)
{
+8
View File
@@ -32,6 +32,7 @@
class WrappedID3D12Device;
class D3D12ResourceManager;
struct D3D12Descriptor;
#define D3D12_MSAA_SAMPLECOUNT 4
@@ -53,6 +54,8 @@ enum CBVUAVSRVSlot
PICK_VB_SRV,
PICK_RESULT_UAV,
PICK_RESULT_CLEAR_UAV,
TMP_UAV,
};
enum RTVSlot
@@ -61,6 +64,8 @@ enum RTVSlot
CUSTOM_SHADER_RTV,
OVERLAY_RTV,
GET_TEX_RTV,
FIRST_TMP_RTV,
LAST_TMP_RTV = FIRST_TMP_RTV + 16,
FIRST_WIN_RTV,
};
@@ -74,6 +79,7 @@ enum SamplerSlot
enum DSVSlot
{
OVERLAY_DSV,
TMP_DSV,
FIRST_WIN_DSV,
};
@@ -117,6 +123,8 @@ public:
D3D12_GPU_DESCRIPTOR_HANDLE GetGPUHandle(DSVSlot slot);
D3D12_GPU_DESCRIPTOR_HANDLE GetGPUHandle(SamplerSlot slot);
D3D12_CPU_DESCRIPTOR_HANDLE GetTempDescriptor(const D3D12Descriptor &desc, size_t idx = 0);
void SetDescriptorHeaps(ID3D12GraphicsCommandList *list, bool cbvsrvuav, bool samplers);
D3D12_CPU_DESCRIPTOR_HANDLE GetUAVClearHandle(CBVUAVSRVSlot slot);
+1
View File
@@ -2711,6 +2711,7 @@ void WrappedID3D12Device::ReplayLog(uint32_t startEventID, uint32_t endEventID,
cmd.m_Partial[D3D12CommandData::Secondary].Reset();
cmd.m_RenderState = D3D12RenderState();
cmd.m_RenderState.m_ResourceManager = GetResourceManager();
cmd.m_RenderState.m_DebugManager = m_Replay.GetDebugManager();
}
// we'll need our own command list if we're replaying just a subsection
+5 -1
View File
@@ -46,7 +46,11 @@ struct D3D12InitParams
D3D_FEATURE_LEVEL MinimumFeatureLevel;
// check if a frame capture section version is supported
static const uint64_t CurrentVersion = 0x4;
static const uint64_t CurrentVersion = 0x5;
// 0x4 -> 0x5 - CPU_DESCRIPTOR_HANDLE serialised inline as D3D12Descriptor in appropriate
// list-recording functions
static bool IsSupportedVersion(uint64_t ver);
};
+12 -24
View File
@@ -918,10 +918,8 @@ void WrappedID3D12Device::CreateConstantBufferView(const D3D12_CONSTANT_BUFFER_V
GetResourceManager()->MarkResourceFrameReferenced(
WrappedID3D12Resource::GetResIDFromAddr(pDesc->BufferLocation), eFrameRef_Read);
}
else
{
GetWrapped(DestDescriptor)->Init(pDesc);
}
GetWrapped(DestDescriptor)->Init(pDesc);
}
void WrappedID3D12Device::CreateShaderResourceView(ID3D12Resource *pResource,
@@ -964,10 +962,8 @@ void WrappedID3D12Device::CreateShaderResourceView(ID3D12Resource *pResource,
GetResourceManager()->MarkResourceFrameReferenced(GetResID(pResource), eFrameRef_Read);
}
else
{
GetWrapped(DestDescriptor)->Init(pResource, pDesc);
}
GetWrapped(DestDescriptor)->Init(pResource, pDesc);
if(IsReplayMode(m_State) && pDesc)
{
@@ -1020,10 +1016,8 @@ void WrappedID3D12Device::CreateUnorderedAccessView(ID3D12Resource *pResource,
if(pCounterResource)
GetResourceManager()->MarkResourceFrameReferenced(GetResID(pCounterResource), eFrameRef_Write);
}
else
{
GetWrapped(DestDescriptor)->Init(pResource, pCounterResource, pDesc);
}
GetWrapped(DestDescriptor)->Init(pResource, pCounterResource, pDesc);
}
void WrappedID3D12Device::CreateRenderTargetView(ID3D12Resource *pResource,
@@ -1066,10 +1060,8 @@ void WrappedID3D12Device::CreateRenderTargetView(ID3D12Resource *pResource,
GetResourceManager()->MarkResourceFrameReferenced(GetResID(pResource), eFrameRef_Write);
}
else
{
GetWrapped(DestDescriptor)->Init(pResource, pDesc);
}
GetWrapped(DestDescriptor)->Init(pResource, pDesc);
}
void WrappedID3D12Device::CreateDepthStencilView(ID3D12Resource *pResource,
@@ -1110,10 +1102,8 @@ void WrappedID3D12Device::CreateDepthStencilView(ID3D12Resource *pResource,
GetResourceManager()->MarkResourceFrameReferenced(GetResID(pResource), eFrameRef_Write);
}
else
{
GetWrapped(DestDescriptor)->Init(pResource, pDesc);
}
GetWrapped(DestDescriptor)->Init(pResource, pDesc);
}
void WrappedID3D12Device::CreateSampler(const D3D12_SAMPLER_DESC *pDesc,
@@ -1150,10 +1140,8 @@ void WrappedID3D12Device::CreateSampler(const D3D12_SAMPLER_DESC *pDesc,
m_FrameCaptureRecord->AddChunk(scope.Get());
}
}
else
{
GetWrapped(DestDescriptor)->Init(pDesc);
}
GetWrapped(DestDescriptor)->Init(pDesc);
}
template <typename SerialiserType>
+25 -28
View File
@@ -330,15 +330,15 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeHint, Debug
ID3D12Resource *renderDepth = NULL;
D3D12Descriptor *dsView = GetWrapped(rs.dsv);
D3D12Descriptor dsView = rs.dsv;
D3D12_RESOURCE_DESC depthTexDesc = {};
D3D12_DEPTH_STENCIL_VIEW_DESC dsViewDesc = {};
if(dsView)
if(dsView.nonsamp.resource)
{
ID3D12Resource *realDepth = dsView->nonsamp.resource;
ID3D12Resource *realDepth = dsView.nonsamp.resource;
dsViewDesc = dsView->nonsamp.dsv;
dsViewDesc = dsView.nonsamp.dsv;
depthTexDesc = realDepth->GetDesc();
depthTexDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
@@ -513,10 +513,9 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeHint, Debug
D3D12RenderState prev = rs;
rs.pipe = GetResID(pso);
rs.rtSingle = true;
rs.rts.resize(1);
rs.rts[0] = rtv;
rs.dsv = D3D12_CPU_DESCRIPTOR_HANDLE();
rs.rts[0] = *GetWrapped(rtv);
RDCEraseEl(rs.dsv);
m_pDevice->ReplayLog(0, eventId, eReplay_OnlyDraw);
@@ -605,10 +604,9 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeHint, Debug
D3D12RenderState prev = rs;
rs.pipe = GetResID(redPSO);
rs.rtSingle = true;
rs.rts.resize(1);
rs.rts[0] = rtv;
rs.dsv = D3D12_CPU_DESCRIPTOR_HANDLE();
rs.rts[0] = *GetWrapped(rtv);
RDCEraseEl(rs.dsv);
m_pDevice->ReplayLog(0, eventId, eReplay_OnlyDraw);
@@ -684,10 +682,9 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeHint, Debug
D3D12RenderState prev = rs;
rs.pipe = GetResID(pso);
rs.rtSingle = true;
rs.rts.resize(1);
rs.rts[0] = rtv;
rs.dsv = dsv;
rs.rts[0] = *GetWrapped(rtv);
RDCEraseEl(rs.dsv);
m_pDevice->ReplayLog(0, eventId, eReplay_OnlyDraw);
@@ -714,8 +711,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeHint, Debug
list->Close();
list = NULL;
bool rtSingle = rs.rtSingle;
std::vector<D3D12_CPU_DESCRIPTOR_HANDLE> rts = rs.rts;
std::vector<D3D12Descriptor> rts = rs.rts;
if(overlay == DebugOverlay::ClearBeforePass)
m_pDevice->ReplayLog(0, events[0], eReplay_WithoutDraw);
@@ -724,15 +720,11 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeHint, Debug
for(size_t i = 0; i < rts.size(); i++)
{
D3D12Descriptor *desc = rtSingle ? GetWrapped(rts[0]) : GetWrapped(rts[i]);
const D3D12Descriptor &desc = rts[i];
if(desc)
{
if(rtSingle)
desc += i;
Unwrap(list)->ClearRenderTargetView(UnwrapCPU(desc), black, 0, NULL);
}
if(desc.nonsamp.resource)
Unwrap(list)->ClearRenderTargetView(Unwrap(GetDebugManager()->GetTempDescriptor(desc)),
black, 0, NULL);
}
list->Close();
@@ -889,8 +881,11 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeHint, Debug
Vec4f viewport(rs.views[0].Width, rs.views[0].Height);
if(rs.dsv.ptr)
list->OMSetRenderTargets(1, &rtv, TRUE, &rs.dsv);
if(rs.dsv.nonsamp.resource)
{
D3D12_CPU_DESCRIPTOR_HANDLE tmpdsv = GetDebugManager()->GetTempDescriptor(rs.dsv);
list->OMSetRenderTargets(1, &rtv, TRUE, &tmpdsv);
}
list->RSSetViewports(1, &rs.views[0]);
@@ -1225,10 +1220,12 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeHint, Debug
D3D12RenderState prev = rs;
rs.pipe = GetResID(redPSO);
rs.rtSingle = true;
rs.rts.resize(1);
rs.rts[0] = rtv;
rs.dsv = dsv;
rs.rts[0] = *GetWrapped(rtv);
if(dsv.ptr)
rs.dsv = *GetWrapped(dsv);
else
RDCEraseEl(rs.dsv);
m_pDevice->ReplayLog(0, eventId, eReplay_OnlyDraw);
+10 -30
View File
@@ -567,7 +567,7 @@ vector<EventUsage> D3D12Replay::GetUsage(ResourceId id)
return m_pDevice->GetQueue()->GetUsage(id);
}
void D3D12Replay::FillResourceView(D3D12Pipe::View &view, D3D12Descriptor *desc)
void D3D12Replay::FillResourceView(D3D12Pipe::View &view, const D3D12Descriptor *desc)
{
D3D12ResourceManager *rm = m_pDevice->GetResourceManager();
@@ -1324,17 +1324,14 @@ void D3D12Replay::SavePipelineState()
{
D3D12Pipe::View &view = state.outputMerger.renderTargets[i];
D3D12Descriptor *desc = rs.rtSingle ? GetWrapped(rs.rts[0]) : GetWrapped(rs.rts[i]);
const D3D12Descriptor &desc = rs.rts[i];
if(desc)
if(desc.nonsamp.resource)
{
if(rs.rtSingle)
desc += i;
view.rootElement = (uint32_t)i;
view.immediate = false;
FillResourceView(view, desc);
FillResourceView(view, &desc);
}
else
{
@@ -1345,14 +1342,12 @@ void D3D12Replay::SavePipelineState()
{
D3D12Pipe::View &view = state.outputMerger.depthTarget;
if(rs.dsv.ptr)
if(rs.dsv.nonsamp.resource)
{
D3D12Descriptor *desc = GetWrapped(rs.dsv);
view.rootElement = 0;
view.immediate = false;
FillResourceView(view, desc);
FillResourceView(view, &rs.dsv);
}
else
{
@@ -2476,26 +2471,11 @@ bool D3D12Replay::IsRenderOutput(ResourceId id)
id = m_pDevice->GetResourceManager()->GetLiveID(id);
for(size_t i = 0; i < rs.rts.size(); i++)
{
D3D12Descriptor *desc = rs.rtSingle ? GetWrapped(rs.rts[0]) : GetWrapped(rs.rts[i]);
if(desc)
{
if(rs.rtSingle)
desc += i;
if(id == GetResID(desc->nonsamp.resource))
return true;
}
}
if(rs.dsv.ptr)
{
D3D12Descriptor *desc = GetWrapped(rs.dsv);
if(id == GetResID(desc->nonsamp.resource))
if(id == GetResID(rs.rts[i].nonsamp.resource))
return true;
}
if(id == GetResID(rs.dsv.nonsamp.resource))
return true;
return false;
}
+1 -1
View File
@@ -194,7 +194,7 @@ private:
void FillRegisterSpaces(const D3D12RenderState::RootSignature &rootSig,
rdcarray<D3D12Pipe::RegisterSpace> &spaces,
D3D12_SHADER_VISIBILITY visibility);
void FillResourceView(D3D12Pipe::View &view, D3D12Descriptor *desc);
void FillResourceView(D3D12Pipe::View &view, const D3D12Descriptor *desc);
void ClearPostVSCache();
+13 -66
View File
@@ -24,42 +24,16 @@
#include "d3d12_state.h"
#include "d3d12_command_list.h"
#include "d3d12_debug.h"
#include "d3d12_manager.h"
#include "d3d12_resources.h"
D3D12RenderState::D3D12RenderState()
{
views.clear();
scissors.clear();
rts.clear();
rtSingle = false;
dsv = D3D12_CPU_DESCRIPTOR_HANDLE();
m_ResourceManager = NULL;
heaps.clear();
pipe = graphics.rootsig = compute.rootsig = ResourceId();
graphics.sigelems.clear();
compute.sigelems.clear();
topo = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
stencilRef = 0;
RDCEraseEl(blendFactor);
RDCEraseEl(ibuffer);
vbuffers.clear();
}
D3D12RenderState &D3D12RenderState::operator=(const D3D12RenderState &o)
{
views = o.views;
scissors = o.scissors;
rts = o.rts;
rtSingle = o.rtSingle;
dsv = o.dsv;
pipe = o.pipe;
@@ -85,28 +59,10 @@ vector<ResourceId> D3D12RenderState::GetRTVIDs() const
{
vector<ResourceId> ret;
if(rtSingle)
for(UINT i = 0; i < rts.size(); i++)
{
if(!rts.empty())
{
const D3D12Descriptor *descs = GetWrapped(rts[0]);
for(UINT i = 0; i < rts.size(); i++)
{
RDCASSERT(descs[i].GetType() == D3D12DescriptorType::RTV);
ret.push_back(GetResID(descs[i].nonsamp.resource));
}
}
}
else
{
for(UINT i = 0; i < rts.size(); i++)
{
const D3D12Descriptor *desc = GetWrapped(rts[i]);
RDCASSERT(desc->GetType() == D3D12DescriptorType::RTV);
ret.push_back(GetResID(desc->nonsamp.resource));
}
RDCASSERT(rts[i].GetType() == D3D12DescriptorType::RTV);
ret.push_back(GetResID(rts[i].nonsamp.resource));
}
return ret;
@@ -114,16 +70,7 @@ vector<ResourceId> D3D12RenderState::GetRTVIDs() const
ResourceId D3D12RenderState::GetDSVID() const
{
if(dsv.ptr)
{
const D3D12Descriptor *desc = GetWrapped(dsv);
RDCASSERT(desc->GetType() == D3D12DescriptorType::DSV);
return GetResID(desc->nonsamp.resource);
}
return ResourceId();
return GetResID(dsv.nonsamp.resource);
}
void D3D12RenderState::ApplyState(ID3D12GraphicsCommandList *cmd) const
@@ -183,20 +130,20 @@ void D3D12RenderState::ApplyState(ID3D12GraphicsCommandList *cmd) const
}
}
if(!rts.empty() || dsv.ptr)
if(!rts.empty() || dsv.nonsamp.resource)
{
D3D12_CPU_DESCRIPTOR_HANDLE rtHandles[8];
D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = Unwrap(dsv);
D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = {};
UINT rtCount = (UINT)rts.size();
UINT numActualHandles = rtSingle ? RDCMIN(1U, rtCount) : rtCount;
if(dsv.nonsamp.resource)
dsvHandle = Unwrap(GetDebugManager()->GetTempDescriptor(dsv));
for(UINT i = 0; i < numActualHandles; i++)
rtHandles[i] = Unwrap(rts[i]);
for(size_t i = 0; i < rts.size(); i++)
rtHandles[i] = Unwrap(GetDebugManager()->GetTempDescriptor(rts[i], i));
// need to unwrap here, as FromPortableHandle unwraps too.
Unwrap(cmd)->OMSetRenderTargets((UINT)rts.size(), rtHandles, rtSingle ? TRUE : FALSE,
dsv.ptr ? &dsvHandle : NULL);
Unwrap(cmd)->OMSetRenderTargets((UINT)rts.size(), rtHandles, FALSE,
dsvHandle.ptr ? &dsvHandle : NULL);
}
}
+16 -11
View File
@@ -29,6 +29,7 @@
#include "d3d12_manager.h"
class D3D12ResourceManager;
class D3D12DebugManager;
enum SignatureElementType
{
@@ -42,7 +43,7 @@ enum SignatureElementType
struct D3D12RenderState
{
D3D12RenderState();
D3D12RenderState() = default;
D3D12RenderState &operator=(const D3D12RenderState &o);
void ApplyState(ID3D12GraphicsCommandList *list) const;
@@ -52,9 +53,10 @@ struct D3D12RenderState
vector<D3D12_VIEWPORT> views;
vector<D3D12_RECT> scissors;
vector<D3D12_CPU_DESCRIPTOR_HANDLE> rts;
bool rtSingle;
D3D12_CPU_DESCRIPTOR_HANDLE dsv;
// these are D3D12Descriptor copies since the values of the descriptors are read during
// OMSetRenderTargets and may not exist anywhere after that if they are immediately overwritten.
vector<D3D12Descriptor> rts;
D3D12Descriptor dsv = {};
vector<ResourceId> GetRTVIDs() const;
ResourceId GetDSVID() const;
@@ -163,16 +165,16 @@ struct D3D12RenderState
ResourceId pipe;
D3D12_PRIMITIVE_TOPOLOGY topo;
UINT stencilRef;
float blendFactor[4];
D3D12_PRIMITIVE_TOPOLOGY topo = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
UINT stencilRef = 0;
float blendFactor[4] = {};
struct IdxBuffer
{
ResourceId buf;
UINT64 offs;
int bytewidth;
UINT size;
UINT64 offs = 0;
int bytewidth = 0;
UINT size = 0;
} ibuffer;
struct VertBuffer
@@ -185,5 +187,8 @@ struct D3D12RenderState
vector<VertBuffer> vbuffers;
D3D12ResourceManager *GetResourceManager() const { return m_ResourceManager; }
D3D12ResourceManager *m_ResourceManager;
D3D12ResourceManager *m_ResourceManager = NULL;
D3D12DebugManager *GetDebugManager() const { return m_DebugManager; }
D3D12DebugManager *m_DebugManager = NULL;
};