mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Implement D3D12 descriptor fetching contents directly from heaps
This commit is contained in:
@@ -932,6 +932,12 @@ struct State
|
||||
DOCUMENT("The :class:`ResourceId` of the root signature object.");
|
||||
ResourceId rootSignatureResourceId;
|
||||
|
||||
DOCUMENT(R"(The descriptor heaps currently bound.
|
||||
|
||||
:type: List[ResourceId]
|
||||
)");
|
||||
rdcarray<ResourceId> descriptorHeaps;
|
||||
|
||||
DOCUMENT(R"(The root signature, as a range per element.
|
||||
|
||||
:type: List[D3D12RootSignatureRange]
|
||||
|
||||
@@ -680,6 +680,26 @@ D3DBufferViewFlags MakeBufferFlags(D3D12_BUFFER_UAV_FLAGS flags)
|
||||
return ret;
|
||||
}
|
||||
|
||||
DescriptorFlags MakeDescriptorFlags(D3D12_BUFFER_SRV_FLAGS flags)
|
||||
{
|
||||
DescriptorFlags ret = DescriptorFlags::NoFlags;
|
||||
|
||||
if(flags & D3D12_BUFFER_SRV_FLAG_RAW)
|
||||
ret |= DescriptorFlags::RawBuffer;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
DescriptorFlags MakeDescriptorFlags(D3D12_BUFFER_UAV_FLAGS flags)
|
||||
{
|
||||
DescriptorFlags ret = DescriptorFlags::NoFlags;
|
||||
|
||||
if(flags & D3D12_BUFFER_UAV_FLAG_RAW)
|
||||
ret |= DescriptorFlags::RawBuffer;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
LogicOperation MakeLogicOp(D3D12_LOGIC_OP op)
|
||||
{
|
||||
switch(op)
|
||||
|
||||
@@ -120,6 +120,8 @@ CompareFunction MakeCompareFunc(D3D12_COMPARISON_FUNC func);
|
||||
TextureFilter MakeFilter(D3D12_FILTER filter);
|
||||
D3DBufferViewFlags MakeBufferFlags(D3D12_BUFFER_SRV_FLAGS flags);
|
||||
D3DBufferViewFlags MakeBufferFlags(D3D12_BUFFER_UAV_FLAGS flags);
|
||||
DescriptorFlags MakeDescriptorFlags(D3D12_BUFFER_SRV_FLAGS flags);
|
||||
DescriptorFlags MakeDescriptorFlags(D3D12_BUFFER_UAV_FLAGS flags);
|
||||
LogicOperation MakeLogicOp(D3D12_LOGIC_OP op);
|
||||
BlendMultiplier MakeBlendMultiplier(D3D12_BLEND blend, bool alpha);
|
||||
BlendOperation MakeBlendOp(D3D12_BLEND_OP op);
|
||||
|
||||
@@ -1209,7 +1209,7 @@ bool WrappedID3D12Device::Serialise_DynamicDescriptorWrite(SerialiserType &ser,
|
||||
// be undefined
|
||||
RDCASSERT(desc.GetType() != D3D12DescriptorType::Undefined);
|
||||
desc.Create(D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES, this, *handle);
|
||||
handle->GetHeap()->MarkMutableView(handle->GetHeapIndex());
|
||||
handle->GetHeap()->MarkMutableIndex(handle->GetHeapIndex());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1939,7 +1939,7 @@ bool WrappedID3D12Device::Serialise_DynamicDescriptorCopies(
|
||||
for(const DynamicDescriptorCopy © : DescriptorCopies)
|
||||
{
|
||||
CopyDescriptorsSimple(1, *copy.dst, *copy.src, copy.type);
|
||||
copy.dst->GetHeap()->MarkMutableView(copy.dst->GetHeapIndex());
|
||||
copy.dst->GetHeap()->MarkMutableIndex(copy.dst->GetHeapIndex());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1029,6 +1029,264 @@ void D3D12Replay::FillSampler(D3D12Pipe::Sampler &samp, const D3D12_SAMPLER_DESC
|
||||
samp.mipLODBias = sampDesc.MipLODBias;
|
||||
}
|
||||
|
||||
void D3D12Replay::FillDescriptor(Descriptor &dst, const D3D12Descriptor *src)
|
||||
{
|
||||
D3D12ResourceManager *rm = m_pDevice->GetResourceManager();
|
||||
|
||||
if(src->GetType() == D3D12DescriptorType::Sampler || src->GetType() == D3D12DescriptorType::CBV)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(src->GetHeap()->HasValidDescriptorCache(src->GetHeapIndex()))
|
||||
{
|
||||
src->GetHeap()->GetFromDescriptorCache(src->GetHeapIndex(), dst);
|
||||
return;
|
||||
}
|
||||
|
||||
dst.resource = rm->GetOriginalID(src->GetResResourceId());
|
||||
|
||||
if(dst.resource == ResourceId())
|
||||
{
|
||||
src->GetHeap()->GetFromDescriptorCache(src->GetHeapIndex(), dst);
|
||||
return;
|
||||
}
|
||||
|
||||
D3D12_RESOURCE_DESC res;
|
||||
|
||||
{
|
||||
ID3D12Resource *r = rm->GetCurrentAs<ID3D12Resource>(src->GetResResourceId());
|
||||
res = r->GetDesc();
|
||||
}
|
||||
|
||||
{
|
||||
DXGI_FORMAT fmt = DXGI_FORMAT_UNKNOWN;
|
||||
|
||||
uint64_t firstElement = UINT64_MAX;
|
||||
uint32_t numElements = UINT32_MAX;
|
||||
|
||||
if(src->GetType() == D3D12DescriptorType::SRV)
|
||||
{
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC srv = src->GetSRV();
|
||||
|
||||
if(srv.ViewDimension == D3D12_SRV_DIMENSION_UNKNOWN)
|
||||
srv = MakeSRVDesc(res);
|
||||
|
||||
if(srv.ViewDimension == D3D12_SRV_DIMENSION_BUFFER)
|
||||
dst.type = DescriptorType::TypedBuffer;
|
||||
else
|
||||
dst.type = DescriptorType::Image;
|
||||
|
||||
fmt = srv.Format;
|
||||
|
||||
dst.textureType = MakeTextureDim(srv.ViewDimension);
|
||||
|
||||
dst.swizzle.red =
|
||||
(TextureSwizzle)D3D12_DECODE_SHADER_4_COMPONENT_MAPPING(0, srv.Shader4ComponentMapping);
|
||||
dst.swizzle.green =
|
||||
(TextureSwizzle)D3D12_DECODE_SHADER_4_COMPONENT_MAPPING(1, srv.Shader4ComponentMapping);
|
||||
dst.swizzle.blue =
|
||||
(TextureSwizzle)D3D12_DECODE_SHADER_4_COMPONENT_MAPPING(2, srv.Shader4ComponentMapping);
|
||||
dst.swizzle.alpha =
|
||||
(TextureSwizzle)D3D12_DECODE_SHADER_4_COMPONENT_MAPPING(3, srv.Shader4ComponentMapping);
|
||||
|
||||
if(srv.ViewDimension == D3D12_SRV_DIMENSION_BUFFER)
|
||||
{
|
||||
firstElement = srv.Buffer.FirstElement;
|
||||
numElements = srv.Buffer.NumElements;
|
||||
|
||||
dst.flags = MakeDescriptorFlags(srv.Buffer.Flags);
|
||||
if(srv.Buffer.StructureByteStride > 0)
|
||||
{
|
||||
dst.elementByteSize = srv.Buffer.StructureByteStride;
|
||||
dst.type = DescriptorType::Buffer;
|
||||
}
|
||||
}
|
||||
else if(srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE1D)
|
||||
{
|
||||
dst.firstMip = srv.Texture1D.MostDetailedMip & 0xff;
|
||||
dst.numMips = srv.Texture1D.MipLevels & 0xff;
|
||||
dst.minLODClamp = srv.Texture1D.ResourceMinLODClamp;
|
||||
}
|
||||
else if(srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE1DARRAY)
|
||||
{
|
||||
dst.numSlices = srv.Texture1DArray.ArraySize & 0xffff;
|
||||
dst.firstSlice = srv.Texture1DArray.FirstArraySlice & 0xffff;
|
||||
dst.firstMip = srv.Texture1DArray.MostDetailedMip & 0xff;
|
||||
dst.numMips = srv.Texture1DArray.MipLevels & 0xff;
|
||||
dst.minLODClamp = srv.Texture1DArray.ResourceMinLODClamp;
|
||||
}
|
||||
else if(srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE2D)
|
||||
{
|
||||
dst.firstMip = srv.Texture2D.MostDetailedMip & 0xff;
|
||||
dst.numMips = srv.Texture2D.MipLevels & 0xff;
|
||||
dst.minLODClamp = srv.Texture2D.ResourceMinLODClamp;
|
||||
}
|
||||
else if(srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE2DARRAY)
|
||||
{
|
||||
dst.numSlices = srv.Texture2DArray.ArraySize & 0xffff;
|
||||
dst.firstSlice = srv.Texture2DArray.FirstArraySlice & 0xffff;
|
||||
dst.firstMip = srv.Texture2DArray.MostDetailedMip & 0xff;
|
||||
dst.numMips = srv.Texture2DArray.MipLevels & 0xff;
|
||||
dst.minLODClamp = srv.Texture2DArray.ResourceMinLODClamp;
|
||||
}
|
||||
else if(srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE2DMS)
|
||||
{
|
||||
}
|
||||
else if(srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY)
|
||||
{
|
||||
dst.numSlices = srv.Texture2DMSArray.ArraySize & 0xffff;
|
||||
dst.firstSlice = srv.Texture2DMSArray.FirstArraySlice & 0xffff;
|
||||
}
|
||||
else if(srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE3D)
|
||||
{
|
||||
dst.firstMip = srv.Texture3D.MostDetailedMip & 0xff;
|
||||
dst.numMips = srv.Texture3D.MipLevels & 0xff;
|
||||
dst.minLODClamp = srv.Texture3D.ResourceMinLODClamp;
|
||||
}
|
||||
else if(srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURECUBE)
|
||||
{
|
||||
dst.numSlices = 6;
|
||||
dst.firstMip = srv.TextureCube.MostDetailedMip & 0xff;
|
||||
dst.numMips = srv.TextureCube.MipLevels & 0xff;
|
||||
dst.minLODClamp = srv.TextureCube.ResourceMinLODClamp;
|
||||
}
|
||||
else if(srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURECUBEARRAY)
|
||||
{
|
||||
dst.numSlices = (srv.TextureCubeArray.NumCubes * 6) & 0xffff;
|
||||
dst.firstSlice = srv.TextureCubeArray.First2DArrayFace & 0xffff;
|
||||
dst.firstMip = srv.TextureCubeArray.MostDetailedMip & 0xff;
|
||||
dst.numMips = srv.TextureCubeArray.MipLevels & 0xff;
|
||||
dst.minLODClamp = srv.TextureCube.ResourceMinLODClamp;
|
||||
}
|
||||
}
|
||||
else if(src->GetType() == D3D12DescriptorType::UAV)
|
||||
{
|
||||
D3D12_UNORDERED_ACCESS_VIEW_DESC uav = src->GetUAV();
|
||||
|
||||
if(uav.ViewDimension == D3D12_UAV_DIMENSION_UNKNOWN)
|
||||
uav = MakeUAVDesc(res);
|
||||
|
||||
if(uav.ViewDimension == D3D12_UAV_DIMENSION_BUFFER)
|
||||
dst.type = uav.Format != DXGI_FORMAT_UNKNOWN ? DescriptorType::ReadWriteTypedBuffer
|
||||
: DescriptorType::ReadWriteBuffer;
|
||||
else
|
||||
dst.type = DescriptorType::ReadWriteImage;
|
||||
|
||||
fmt = uav.Format;
|
||||
|
||||
dst.secondary = rm->GetOriginalID(src->GetCounterResourceId());
|
||||
|
||||
dst.textureType = MakeTextureDim(uav.ViewDimension);
|
||||
|
||||
if(uav.ViewDimension == D3D12_UAV_DIMENSION_BUFFER)
|
||||
{
|
||||
firstElement = uav.Buffer.FirstElement;
|
||||
numElements = uav.Buffer.NumElements;
|
||||
|
||||
dst.flags = MakeDescriptorFlags(uav.Buffer.Flags);
|
||||
if(uav.Buffer.StructureByteStride > 0)
|
||||
dst.elementByteSize = uav.Buffer.StructureByteStride;
|
||||
|
||||
dst.counterByteOffset = uav.Buffer.CounterOffsetInBytes & 0xffffffff;
|
||||
RDCASSERT(uav.Buffer.CounterOffsetInBytes < 0xffffffff);
|
||||
|
||||
if(dst.secondary != ResourceId())
|
||||
{
|
||||
bytebuf counterVal;
|
||||
GetDebugManager()->GetBufferData(
|
||||
rm->GetCurrentAs<ID3D12Resource>(src->GetCounterResourceId()),
|
||||
uav.Buffer.CounterOffsetInBytes, 4, counterVal);
|
||||
uint32_t *val = (uint32_t *)&counterVal[0];
|
||||
dst.bufferStructCount = *val;
|
||||
}
|
||||
}
|
||||
else if(uav.ViewDimension == D3D12_UAV_DIMENSION_TEXTURE1D)
|
||||
{
|
||||
dst.firstMip = uav.Texture1D.MipSlice & 0xff;
|
||||
}
|
||||
else if(uav.ViewDimension == D3D12_UAV_DIMENSION_TEXTURE1DARRAY)
|
||||
{
|
||||
dst.numSlices = uav.Texture1DArray.ArraySize & 0xffff;
|
||||
dst.firstSlice = uav.Texture1DArray.FirstArraySlice & 0xffff;
|
||||
dst.firstMip = uav.Texture1DArray.MipSlice & 0xff;
|
||||
}
|
||||
else if(uav.ViewDimension == D3D12_UAV_DIMENSION_TEXTURE2D)
|
||||
{
|
||||
dst.firstMip = uav.Texture2D.MipSlice & 0xff;
|
||||
}
|
||||
else if(uav.ViewDimension == D3D12_UAV_DIMENSION_TEXTURE2DARRAY)
|
||||
{
|
||||
dst.numSlices = uav.Texture2DArray.ArraySize & 0xffff;
|
||||
dst.firstSlice = uav.Texture2DArray.FirstArraySlice & 0xffff;
|
||||
dst.firstMip = uav.Texture2DArray.MipSlice & 0xff;
|
||||
}
|
||||
else if(uav.ViewDimension == D3D12_UAV_DIMENSION_TEXTURE2DMS)
|
||||
{
|
||||
}
|
||||
else if(uav.ViewDimension == D3D12_UAV_DIMENSION_TEXTURE2DMSARRAY)
|
||||
{
|
||||
dst.numSlices = uav.Texture2DMSArray.ArraySize & 0xffff;
|
||||
dst.firstSlice = uav.Texture2DMSArray.FirstArraySlice & 0xffff;
|
||||
}
|
||||
else if(uav.ViewDimension == D3D12_UAV_DIMENSION_TEXTURE3D)
|
||||
{
|
||||
dst.numSlices = uav.Texture3D.WSize & 0xffff;
|
||||
dst.firstSlice = uav.Texture3D.FirstWSlice & 0xffff;
|
||||
dst.firstMip = uav.Texture3D.MipSlice & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
if(fmt == DXGI_FORMAT_UNKNOWN)
|
||||
fmt = res.Format;
|
||||
|
||||
if(dst.elementByteSize == 0)
|
||||
dst.elementByteSize = fmt == DXGI_FORMAT_UNKNOWN ? 1 : GetByteSize(1, 1, 1, fmt, 0);
|
||||
|
||||
// decode elements into byte offsets
|
||||
if(firstElement != UINT64_MAX)
|
||||
{
|
||||
dst.byteOffset = firstElement * dst.elementByteSize;
|
||||
dst.byteSize = numElements * dst.elementByteSize;
|
||||
}
|
||||
|
||||
if(res.MipLevels == 0 && res.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||
res.MipLevels = (uint16_t)CalcNumMips(
|
||||
(uint32_t)res.Width, res.Height,
|
||||
res.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? res.DepthOrArraySize : 1);
|
||||
dst.numMips = RDCMIN(dst.numMips, uint8_t(res.MipLevels & 0xff));
|
||||
dst.numSlices = RDCMIN(dst.numSlices, res.DepthOrArraySize);
|
||||
|
||||
dst.format = MakeResourceFormat(fmt);
|
||||
}
|
||||
|
||||
src->GetHeap()->SetToDescriptorCache(src->GetHeapIndex(), dst);
|
||||
}
|
||||
|
||||
void D3D12Replay::FillSamplerDescriptor(SamplerDescriptor &dst, const D3D12_SAMPLER_DESC2 &src)
|
||||
{
|
||||
dst.type = DescriptorType::Sampler;
|
||||
|
||||
dst.addressU = MakeAddressMode(src.AddressU);
|
||||
dst.addressV = MakeAddressMode(src.AddressV);
|
||||
dst.addressW = MakeAddressMode(src.AddressW);
|
||||
|
||||
dst.borderColorValue.uintValue = src.UintBorderColor;
|
||||
dst.borderColorType =
|
||||
((src.Flags & D3D12_SAMPLER_FLAG_UINT_BORDER_COLOR) != 0 ? CompType::UInt : CompType::Float);
|
||||
|
||||
dst.unnormalized = (src.Flags & D3D12_SAMPLER_FLAG_NON_NORMALIZED_COORDINATES) != 0;
|
||||
|
||||
dst.compareFunction = MakeCompareFunc(src.ComparisonFunc);
|
||||
dst.filter = MakeFilter(src.Filter);
|
||||
dst.maxAnisotropy = 0;
|
||||
if(dst.filter.minify == FilterMode::Anisotropic)
|
||||
dst.maxAnisotropy = (float)src.MaxAnisotropy;
|
||||
dst.maxLOD = src.MaxLOD;
|
||||
dst.minLOD = src.MinLOD;
|
||||
dst.mipBias = src.MipLODBias;
|
||||
}
|
||||
|
||||
ShaderStageMask ToShaderStageMask(D3D12_SHADER_VISIBILITY vis)
|
||||
{
|
||||
switch(vis)
|
||||
@@ -1818,6 +2076,10 @@ void D3D12Replay::SavePipelineState(uint32_t eventId)
|
||||
}
|
||||
}
|
||||
|
||||
state.descriptorHeaps.clear();
|
||||
for(ResourceId id : rs.heaps)
|
||||
state.descriptorHeaps.push_back(rm->GetOriginalID(id));
|
||||
|
||||
if(pipe && pipe->IsGraphics())
|
||||
{
|
||||
/////////////////////////////////////////////////
|
||||
@@ -2071,22 +2333,97 @@ void D3D12Replay::SavePipelineState(uint32_t eventId)
|
||||
rdcarray<Descriptor> D3D12Replay::GetDescriptors(ResourceId descriptorStore,
|
||||
const rdcarray<DescriptorRange> &ranges)
|
||||
{
|
||||
if(descriptorStore == ResourceId())
|
||||
return {};
|
||||
|
||||
size_t count = 0;
|
||||
for(const DescriptorRange &r : ranges)
|
||||
count += r.count;
|
||||
rdcarray<Descriptor> ret;
|
||||
ret.resize(count);
|
||||
|
||||
D3D12ResourceManager *rm = m_pDevice->GetResourceManager();
|
||||
|
||||
WrappedID3D12DescriptorHeap *heap =
|
||||
(WrappedID3D12DescriptorHeap *)rm->GetCurrentAs<ID3D12DescriptorHeap>(descriptorStore);
|
||||
|
||||
size_t dst = 0;
|
||||
for(const DescriptorRange &r : ranges)
|
||||
{
|
||||
D3D12Descriptor *desc = (D3D12Descriptor *)heap->GetCPUDescriptorHandleForHeapStart().ptr;
|
||||
D3D12Descriptor *end = desc + heap->GetNumDescriptors();
|
||||
|
||||
desc += r.offset;
|
||||
|
||||
for(uint32_t i = 0; i < r.count; i++)
|
||||
{
|
||||
if(desc >= end)
|
||||
{
|
||||
// silently drop out of bounds descriptor reads
|
||||
}
|
||||
else if(desc->GetType() == D3D12DescriptorType::CBV)
|
||||
{
|
||||
const D3D12_CONSTANT_BUFFER_VIEW_DESC &cbv = desc->GetCBV();
|
||||
WrappedID3D12Resource::GetResIDFromAddr(cbv.BufferLocation, ret[dst].resource,
|
||||
ret[dst].byteOffset);
|
||||
|
||||
ret[dst].resource = rm->GetOriginalID(ret[dst].resource);
|
||||
ret[dst].byteSize = cbv.SizeInBytes;
|
||||
}
|
||||
else if(desc->GetType() != D3D12DescriptorType::Sampler)
|
||||
{
|
||||
D3D12Pipe::View view;
|
||||
FillDescriptor(ret[dst], desc);
|
||||
}
|
||||
dst++;
|
||||
desc++;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
rdcarray<SamplerDescriptor> D3D12Replay::GetSamplerDescriptors(ResourceId descriptorStore,
|
||||
const rdcarray<DescriptorRange> &ranges)
|
||||
{
|
||||
if(descriptorStore == ResourceId())
|
||||
return {};
|
||||
|
||||
size_t count = 0;
|
||||
for(const DescriptorRange &r : ranges)
|
||||
count += r.count;
|
||||
rdcarray<SamplerDescriptor> ret;
|
||||
ret.resize(count);
|
||||
|
||||
D3D12ResourceManager *rm = m_pDevice->GetResourceManager();
|
||||
|
||||
WrappedID3D12DescriptorHeap *heap =
|
||||
(WrappedID3D12DescriptorHeap *)rm->GetCurrentAs<ID3D12DescriptorHeap>(descriptorStore);
|
||||
|
||||
size_t dst = 0;
|
||||
for(const DescriptorRange &r : ranges)
|
||||
{
|
||||
D3D12Descriptor *desc = (D3D12Descriptor *)heap->GetCPUDescriptorHandleForHeapStart().ptr;
|
||||
D3D12Descriptor *end = desc + heap->GetNumDescriptors();
|
||||
|
||||
desc += r.offset;
|
||||
|
||||
for(uint32_t i = 0; i < r.count; i++)
|
||||
{
|
||||
if(desc >= end)
|
||||
{
|
||||
// silently drop out of bounds descriptor reads
|
||||
}
|
||||
else if(desc->GetType() == D3D12DescriptorType::Sampler)
|
||||
{
|
||||
const D3D12_SAMPLER_DESC2 &sampDesc = desc->GetSampler();
|
||||
FillSamplerDescriptor(ret[dst], sampDesc);
|
||||
}
|
||||
dst++;
|
||||
desc++;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -270,6 +270,8 @@ private:
|
||||
rdcarray<D3D12Pipe::RootSignatureRange> &rootElements);
|
||||
void FillResourceView(D3D12Pipe::View &view, const D3D12Descriptor *desc);
|
||||
void FillSampler(D3D12Pipe::Sampler &view, const D3D12_SAMPLER_DESC2 &desc);
|
||||
void FillDescriptor(Descriptor &dst, const D3D12Descriptor *src);
|
||||
void FillSamplerDescriptor(SamplerDescriptor &dst, const D3D12_SAMPLER_DESC2 &src);
|
||||
|
||||
bool CreateSOBuffers();
|
||||
void ClearPostVSCache();
|
||||
|
||||
@@ -499,13 +499,15 @@ bool WrappedID3D12DescriptorHeap::HasValidViewCache(uint32_t index)
|
||||
if((mutableViewBitmask[index / 64] & (1ULL << (index % 64))) != 0)
|
||||
return false;
|
||||
|
||||
EnsureViewCache();
|
||||
|
||||
// anything that's not mutable is valid once it's been set at least once. Since we
|
||||
// zero-initialise, we use bind as a flag (it isn't retrieved from the cache since it depends on
|
||||
// the binding)
|
||||
return cachedViews[index].bind == 1;
|
||||
}
|
||||
|
||||
void WrappedID3D12DescriptorHeap::MarkMutableView(uint32_t index)
|
||||
void WrappedID3D12DescriptorHeap::MarkMutableIndex(uint32_t index)
|
||||
{
|
||||
if(!mutableViewBitmask)
|
||||
return;
|
||||
@@ -518,6 +520,8 @@ void WrappedID3D12DescriptorHeap::GetFromViewCache(uint32_t index, D3D12Pipe::Vi
|
||||
if(!mutableViewBitmask)
|
||||
return;
|
||||
|
||||
EnsureViewCache();
|
||||
|
||||
bool dynamicallyUsed = view.dynamicallyUsed;
|
||||
uint32_t bind = view.bind;
|
||||
uint32_t tableIndex = view.tableIndex;
|
||||
@@ -532,11 +536,73 @@ void WrappedID3D12DescriptorHeap::SetToViewCache(uint32_t index, const D3D12Pipe
|
||||
if(!mutableViewBitmask)
|
||||
return;
|
||||
|
||||
EnsureViewCache();
|
||||
|
||||
cachedViews[index] = view;
|
||||
// we re-use bind as the indicator that this view is valid
|
||||
cachedViews[index].bind = 1;
|
||||
}
|
||||
|
||||
void WrappedID3D12DescriptorHeap::EnsureViewCache()
|
||||
{
|
||||
if(!cachedViews)
|
||||
{
|
||||
D3D12_DESCRIPTOR_HEAP_DESC desc = GetDesc();
|
||||
cachedViews = new D3D12Pipe::View[desc.NumDescriptors];
|
||||
RDCEraseMem(cachedViews, sizeof(D3D12Pipe::View) * desc.NumDescriptors);
|
||||
}
|
||||
}
|
||||
|
||||
bool WrappedID3D12DescriptorHeap::HasValidDescriptorCache(uint32_t index)
|
||||
{
|
||||
if(!mutableViewBitmask)
|
||||
return false;
|
||||
|
||||
// don't cache mutable views. In theory we could but we'd need to know which ones were modified
|
||||
// mid-frame, to mark the cache as stale when initial contents are re-applied. This optimisation
|
||||
// is aimed at the assumption of a huge number of descriptors that don't change so we just don't
|
||||
// cache ones that change mid-frame
|
||||
if((mutableViewBitmask[index / 64] & (1ULL << (index % 64))) != 0)
|
||||
return false;
|
||||
|
||||
EnsureDescriptorCache();
|
||||
|
||||
// anything that's not mutable is valid once it's been set at least once. Since we
|
||||
// zero-initialise, we use bind as a flag (it isn't retrieved from the cache since it depends on
|
||||
// the binding)
|
||||
return cachedDescriptors[index].type != DescriptorType::Unknown;
|
||||
}
|
||||
|
||||
void WrappedID3D12DescriptorHeap::GetFromDescriptorCache(uint32_t index, Descriptor &view)
|
||||
{
|
||||
if(!mutableViewBitmask)
|
||||
return;
|
||||
|
||||
EnsureDescriptorCache();
|
||||
|
||||
view = cachedDescriptors[index];
|
||||
}
|
||||
|
||||
void WrappedID3D12DescriptorHeap::EnsureDescriptorCache()
|
||||
{
|
||||
if(!cachedDescriptors)
|
||||
{
|
||||
D3D12_DESCRIPTOR_HEAP_DESC desc = GetDesc();
|
||||
cachedDescriptors = new Descriptor[desc.NumDescriptors];
|
||||
RDCEraseMem(cachedDescriptors, sizeof(Descriptor) * desc.NumDescriptors);
|
||||
}
|
||||
}
|
||||
|
||||
void WrappedID3D12DescriptorHeap::SetToDescriptorCache(uint32_t index, const Descriptor &view)
|
||||
{
|
||||
if(!mutableViewBitmask)
|
||||
return;
|
||||
|
||||
EnsureDescriptorCache();
|
||||
|
||||
cachedDescriptors[index] = view;
|
||||
}
|
||||
|
||||
WrappedID3D12DescriptorHeap::WrappedID3D12DescriptorHeap(ID3D12DescriptorHeap *real,
|
||||
WrappedID3D12Device *device,
|
||||
const D3D12_DESCRIPTOR_HEAP_DESC &desc,
|
||||
@@ -562,8 +628,8 @@ WrappedID3D12DescriptorHeap::WrappedID3D12DescriptorHeap(ID3D12DescriptorHeap *r
|
||||
{
|
||||
size_t bitmaskSize = AlignUp(desc.NumDescriptors, 64U) / 64;
|
||||
|
||||
cachedViews = new D3D12Pipe::View[desc.NumDescriptors];
|
||||
RDCEraseMem(cachedViews, sizeof(D3D12Pipe::View) * desc.NumDescriptors);
|
||||
cachedViews = NULL;
|
||||
cachedDescriptors = NULL;
|
||||
|
||||
mutableViewBitmask = new uint64_t[bitmaskSize];
|
||||
RDCEraseMem(mutableViewBitmask, sizeof(uint64_t) * bitmaskSize);
|
||||
@@ -571,6 +637,7 @@ WrappedID3D12DescriptorHeap::WrappedID3D12DescriptorHeap(ID3D12DescriptorHeap *r
|
||||
else
|
||||
{
|
||||
cachedViews = NULL;
|
||||
cachedDescriptors = NULL;
|
||||
mutableViewBitmask = NULL;
|
||||
}
|
||||
}
|
||||
@@ -580,6 +647,7 @@ WrappedID3D12DescriptorHeap::~WrappedID3D12DescriptorHeap()
|
||||
Shutdown();
|
||||
SAFE_DELETE_ARRAY(descriptors);
|
||||
SAFE_DELETE_ARRAY(cachedViews);
|
||||
SAFE_DELETE_ARRAY(cachedDescriptors);
|
||||
SAFE_DELETE_ARRAY(mutableViewBitmask);
|
||||
}
|
||||
|
||||
|
||||
@@ -396,6 +396,7 @@ class WrappedID3D12DescriptorHeap : public WrappedDeviceChild12<ID3D12Descriptor
|
||||
D3D12Descriptor *descriptors;
|
||||
|
||||
D3D12Pipe::View *cachedViews;
|
||||
Descriptor *cachedDescriptors;
|
||||
uint64_t *mutableViewBitmask;
|
||||
|
||||
public:
|
||||
@@ -412,11 +413,19 @@ public:
|
||||
|
||||
D3D12Descriptor *GetDescriptors() { return descriptors; }
|
||||
UINT GetNumDescriptors() { return numDescriptors; }
|
||||
|
||||
void MarkMutableIndex(uint32_t index);
|
||||
|
||||
void EnsureViewCache();
|
||||
bool HasValidViewCache(uint32_t index);
|
||||
void MarkMutableView(uint32_t index);
|
||||
void GetFromViewCache(uint32_t index, D3D12Pipe::View &view);
|
||||
void SetToViewCache(uint32_t index, const D3D12Pipe::View &view);
|
||||
|
||||
void EnsureDescriptorCache();
|
||||
bool HasValidDescriptorCache(uint32_t index);
|
||||
void GetFromDescriptorCache(uint32_t index, Descriptor &view);
|
||||
void SetToDescriptorCache(uint32_t index, const Descriptor &view);
|
||||
|
||||
//////////////////////////////
|
||||
// implement ID3D12DescriptorHeap
|
||||
|
||||
|
||||
@@ -1710,6 +1710,7 @@ void DoSerialise(SerialiserType &ser, D3D12Pipe::State &el)
|
||||
{
|
||||
SERIALISE_MEMBER(pipelineResourceId);
|
||||
SERIALISE_MEMBER(rootSignatureResourceId);
|
||||
SERIALISE_MEMBER(descriptorHeaps);
|
||||
SERIALISE_MEMBER(rootElements);
|
||||
|
||||
SERIALISE_MEMBER(inputAssembly);
|
||||
@@ -1731,7 +1732,7 @@ void DoSerialise(SerialiserType &ser, D3D12Pipe::State &el)
|
||||
|
||||
SERIALISE_MEMBER(resourceStates);
|
||||
|
||||
SIZE_CHECK(1680);
|
||||
SIZE_CHECK(1704);
|
||||
}
|
||||
|
||||
#pragma endregion D3D12 pipeline state
|
||||
|
||||
Reference in New Issue
Block a user