mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-13 05:20:45 +00:00
Cache expanded views from large immutable D3D12 descriptor heaps
* The principle here is that on D3D12 it's common to have huge descriptor heaps in which only a handful of descriptors are changed. By caching the expanded D3D12Pipe::View results from these unchanging descriptors we don't have to do that over and over. Any descriptors written in the captured frame may have different contents depending on where we've replayed up to, so we don't cache them to keep things simple rather than invalidating the cache.
This commit is contained in:
@@ -269,6 +269,10 @@ struct View
|
||||
|
||||
DOCUMENT("The :class:`ResourceId` of the underlying resource the view refers to.");
|
||||
ResourceId resourceId;
|
||||
DOCUMENT("The :class:`ResourceId` of the resource where the hidden buffer counter is stored.");
|
||||
ResourceId counterResourceId;
|
||||
DOCUMENT("The byte offset in :data:`counterResourceId` where the counter is stored.");
|
||||
uint32_t counterByteOffset = 0;
|
||||
DOCUMENT("The :class:`TextureType` of the view type.");
|
||||
TextureType type;
|
||||
DOCUMENT(R"(The format cast that the view uses.
|
||||
@@ -293,6 +297,14 @@ since single descriptors may only be dynamically skipped by control flow.
|
||||
bool dynamicallyUsed = true;
|
||||
DOCUMENT("The :class:`D3DBufferViewFlags` set for the buffer.");
|
||||
D3DBufferViewFlags bufferFlags = D3DBufferViewFlags::NoFlags;
|
||||
DOCUMENT("Valid for textures - the highest mip that is available through the view.");
|
||||
uint8_t firstMip = 0;
|
||||
DOCUMENT("Valid for textures - the number of mip levels in the view.");
|
||||
uint8_t numMips = 1;
|
||||
DOCUMENT("Valid for texture arrays or 3D textures - the first slice available through the view.");
|
||||
uint16_t firstSlice = 0;
|
||||
DOCUMENT("Valid for texture arrays or 3D textures - the number of slices in the view.");
|
||||
uint16_t numSlices = 1;
|
||||
DOCUMENT("If the view has a hidden counter, this stores the current value of the counter.");
|
||||
uint32_t bufferStructCount = 0;
|
||||
DOCUMENT(R"(The byte size of a single element in the view. Either the byte size of
|
||||
@@ -304,21 +316,6 @@ since single descriptors may only be dynamically skipped by control flow.
|
||||
DOCUMENT("Valid for buffers - the number of elements to be used in the view.");
|
||||
uint32_t numElements = 1;
|
||||
|
||||
DOCUMENT("The :class:`ResourceId` of the resource where the hidden buffer counter is stored.");
|
||||
ResourceId counterResourceId;
|
||||
DOCUMENT("The byte offset in :data:`counterResourceId` where the counter is stored.");
|
||||
uint64_t counterByteOffset = 0;
|
||||
|
||||
DOCUMENT("Valid for textures - the highest mip that is available through the view.");
|
||||
uint32_t firstMip = 0;
|
||||
DOCUMENT("Valid for textures - the number of mip levels in the view.");
|
||||
uint32_t numMips = 1;
|
||||
|
||||
DOCUMENT("Valid for texture arrays or 3D textures - the first slice available through the view.");
|
||||
uint32_t firstSlice = 0;
|
||||
DOCUMENT("Valid for texture arrays or 3D textures - the number of slices in the view.");
|
||||
uint32_t numSlices = 1;
|
||||
|
||||
DOCUMENT("The minimum mip-level clamp applied when sampling this texture.");
|
||||
float minLODClamp = 0.0f;
|
||||
};
|
||||
|
||||
@@ -734,7 +734,7 @@ DOCUMENT(R"(The dimensionality of a texture binding.
|
||||
|
||||
A Cubemap texture array.
|
||||
)");
|
||||
enum class TextureType : uint32_t
|
||||
enum class TextureType : uint16_t
|
||||
{
|
||||
Unknown,
|
||||
First = Unknown,
|
||||
|
||||
@@ -1176,6 +1176,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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2552,7 +2553,10 @@ bool WrappedID3D12Device::Serialise_DynamicDescriptorCopies(
|
||||
{
|
||||
// not optimal, but simple for now. Do a wrapped copy so that internal tracking is also updated
|
||||
for(const DynamicDescriptorCopy © : DescriptorCopies)
|
||||
{
|
||||
CopyDescriptorsSimple(1, *copy.dst, *copy.src, copy.type);
|
||||
copy.dst->GetHeap()->MarkMutableView(copy.dst->GetHeapIndex());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -660,10 +660,19 @@ void D3D12Replay::FillResourceView(D3D12Pipe::View &view, const D3D12Descriptor
|
||||
return;
|
||||
}
|
||||
|
||||
if(desc->GetHeap()->HasValidViewCache(desc->GetHeapIndex()))
|
||||
{
|
||||
desc->GetHeap()->GetFromViewCache(desc->GetHeapIndex(), view);
|
||||
return;
|
||||
}
|
||||
|
||||
view.resourceId = rm->GetOriginalID(desc->GetResResourceId());
|
||||
|
||||
if(view.resourceId == ResourceId())
|
||||
{
|
||||
desc->GetHeap()->SetToViewCache(desc->GetHeapIndex(), view);
|
||||
return;
|
||||
}
|
||||
|
||||
D3D12_RESOURCE_DESC res;
|
||||
|
||||
@@ -690,30 +699,30 @@ void D3D12Replay::FillResourceView(D3D12Pipe::View &view, const D3D12Descriptor
|
||||
}
|
||||
else if(rtv.ViewDimension == D3D12_RTV_DIMENSION_TEXTURE1D)
|
||||
{
|
||||
view.firstMip = rtv.Texture1D.MipSlice;
|
||||
view.firstMip = rtv.Texture1D.MipSlice & 0xff;
|
||||
view.numMips = 1;
|
||||
view.firstSlice = 0;
|
||||
view.numSlices = 1;
|
||||
}
|
||||
else if(rtv.ViewDimension == D3D12_RTV_DIMENSION_TEXTURE1DARRAY)
|
||||
{
|
||||
view.firstMip = rtv.Texture1DArray.MipSlice;
|
||||
view.firstMip = rtv.Texture1DArray.MipSlice & 0xff;
|
||||
view.numMips = 1;
|
||||
view.numSlices = rtv.Texture1DArray.ArraySize;
|
||||
view.firstSlice = rtv.Texture1DArray.FirstArraySlice;
|
||||
view.numSlices = rtv.Texture1DArray.ArraySize & 0xffff;
|
||||
view.firstSlice = rtv.Texture1DArray.FirstArraySlice & 0xffff;
|
||||
}
|
||||
else if(rtv.ViewDimension == D3D12_RTV_DIMENSION_TEXTURE2D)
|
||||
{
|
||||
view.firstMip = rtv.Texture2D.MipSlice;
|
||||
view.firstMip = rtv.Texture2D.MipSlice & 0xff;
|
||||
view.numMips = 1;
|
||||
view.firstSlice = 0;
|
||||
view.numSlices = 1;
|
||||
}
|
||||
else if(rtv.ViewDimension == D3D12_RTV_DIMENSION_TEXTURE2DARRAY)
|
||||
{
|
||||
view.numSlices = rtv.Texture2DArray.ArraySize;
|
||||
view.firstSlice = rtv.Texture2DArray.FirstArraySlice;
|
||||
view.firstMip = rtv.Texture2DArray.MipSlice;
|
||||
view.numSlices = rtv.Texture2DArray.ArraySize & 0xffff;
|
||||
view.firstSlice = rtv.Texture2DArray.FirstArraySlice & 0xffff;
|
||||
view.firstMip = rtv.Texture2DArray.MipSlice & 0xff;
|
||||
view.numMips = 1;
|
||||
}
|
||||
else if(rtv.ViewDimension == D3D12_RTV_DIMENSION_TEXTURE2DMS)
|
||||
@@ -727,14 +736,14 @@ void D3D12Replay::FillResourceView(D3D12Pipe::View &view, const D3D12Descriptor
|
||||
{
|
||||
view.firstMip = 0;
|
||||
view.numMips = 1;
|
||||
view.numSlices = rtv.Texture2DMSArray.ArraySize;
|
||||
view.firstSlice = rtv.Texture2DMSArray.FirstArraySlice;
|
||||
view.numSlices = rtv.Texture2DMSArray.ArraySize & 0xffff;
|
||||
view.firstSlice = rtv.Texture2DMSArray.FirstArraySlice & 0xffff;
|
||||
}
|
||||
else if(rtv.ViewDimension == D3D12_RTV_DIMENSION_TEXTURE3D)
|
||||
{
|
||||
view.numSlices = rtv.Texture3D.WSize;
|
||||
view.firstSlice = rtv.Texture3D.FirstWSlice;
|
||||
view.firstMip = rtv.Texture3D.MipSlice;
|
||||
view.numSlices = rtv.Texture3D.WSize & 0xffff;
|
||||
view.firstSlice = rtv.Texture3D.FirstWSlice & 0xffff;
|
||||
view.firstMip = rtv.Texture3D.MipSlice & 0xff;
|
||||
view.numMips = 1;
|
||||
}
|
||||
}
|
||||
@@ -748,31 +757,31 @@ void D3D12Replay::FillResourceView(D3D12Pipe::View &view, const D3D12Descriptor
|
||||
|
||||
if(dsv.ViewDimension == D3D12_DSV_DIMENSION_TEXTURE1D)
|
||||
{
|
||||
view.firstMip = dsv.Texture1D.MipSlice;
|
||||
view.firstMip = dsv.Texture1D.MipSlice & 0xff;
|
||||
}
|
||||
else if(dsv.ViewDimension == D3D12_DSV_DIMENSION_TEXTURE1DARRAY)
|
||||
{
|
||||
view.numSlices = dsv.Texture1DArray.ArraySize;
|
||||
view.firstSlice = dsv.Texture1DArray.FirstArraySlice;
|
||||
view.firstMip = dsv.Texture1DArray.MipSlice;
|
||||
view.numSlices = dsv.Texture1DArray.ArraySize & 0xffff;
|
||||
view.firstSlice = dsv.Texture1DArray.FirstArraySlice & 0xffff;
|
||||
view.firstMip = dsv.Texture1DArray.MipSlice & 0xff;
|
||||
}
|
||||
else if(dsv.ViewDimension == D3D12_DSV_DIMENSION_TEXTURE2D)
|
||||
{
|
||||
view.firstMip = dsv.Texture2D.MipSlice;
|
||||
view.firstMip = dsv.Texture2D.MipSlice & 0xff;
|
||||
}
|
||||
else if(dsv.ViewDimension == D3D12_DSV_DIMENSION_TEXTURE2DARRAY)
|
||||
{
|
||||
view.numSlices = dsv.Texture2DArray.ArraySize;
|
||||
view.firstSlice = dsv.Texture2DArray.FirstArraySlice;
|
||||
view.firstMip = dsv.Texture2DArray.MipSlice;
|
||||
view.numSlices = dsv.Texture2DArray.ArraySize & 0xffff;
|
||||
view.firstSlice = dsv.Texture2DArray.FirstArraySlice & 0xffff;
|
||||
view.firstMip = dsv.Texture2DArray.MipSlice & 0xff;
|
||||
}
|
||||
else if(dsv.ViewDimension == D3D12_DSV_DIMENSION_TEXTURE2DMS)
|
||||
{
|
||||
}
|
||||
else if(dsv.ViewDimension == D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY)
|
||||
{
|
||||
view.numSlices = dsv.Texture2DMSArray.ArraySize;
|
||||
view.firstSlice = dsv.Texture2DMSArray.FirstArraySlice;
|
||||
view.numSlices = dsv.Texture2DMSArray.ArraySize & 0xffff;
|
||||
view.firstSlice = dsv.Texture2DMSArray.FirstArraySlice & 0xffff;
|
||||
}
|
||||
}
|
||||
else if(desc->GetType() == D3D12DescriptorType::SRV)
|
||||
@@ -806,30 +815,30 @@ void D3D12Replay::FillResourceView(D3D12Pipe::View &view, const D3D12Descriptor
|
||||
}
|
||||
else if(srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE1D)
|
||||
{
|
||||
view.firstMip = srv.Texture1D.MostDetailedMip;
|
||||
view.numMips = srv.Texture1D.MipLevels;
|
||||
view.firstMip = srv.Texture1D.MostDetailedMip & 0xff;
|
||||
view.numMips = srv.Texture1D.MipLevels & 0xff;
|
||||
view.minLODClamp = srv.Texture1D.ResourceMinLODClamp;
|
||||
}
|
||||
else if(srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE1DARRAY)
|
||||
{
|
||||
view.numSlices = srv.Texture1DArray.ArraySize;
|
||||
view.firstSlice = srv.Texture1DArray.FirstArraySlice;
|
||||
view.firstMip = srv.Texture1DArray.MostDetailedMip;
|
||||
view.numMips = srv.Texture1DArray.MipLevels;
|
||||
view.numSlices = srv.Texture1DArray.ArraySize & 0xffff;
|
||||
view.firstSlice = srv.Texture1DArray.FirstArraySlice & 0xffff;
|
||||
view.firstMip = srv.Texture1DArray.MostDetailedMip & 0xff;
|
||||
view.numMips = srv.Texture1DArray.MipLevels & 0xff;
|
||||
view.minLODClamp = srv.Texture1DArray.ResourceMinLODClamp;
|
||||
}
|
||||
else if(srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE2D)
|
||||
{
|
||||
view.firstMip = srv.Texture2D.MostDetailedMip;
|
||||
view.numMips = srv.Texture2D.MipLevels;
|
||||
view.firstMip = srv.Texture2D.MostDetailedMip & 0xff;
|
||||
view.numMips = srv.Texture2D.MipLevels & 0xff;
|
||||
view.minLODClamp = srv.Texture2D.ResourceMinLODClamp;
|
||||
}
|
||||
else if(srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE2DARRAY)
|
||||
{
|
||||
view.numSlices = srv.Texture2DArray.ArraySize;
|
||||
view.firstSlice = srv.Texture2DArray.FirstArraySlice;
|
||||
view.firstMip = srv.Texture2DArray.MostDetailedMip;
|
||||
view.numMips = srv.Texture2DArray.MipLevels;
|
||||
view.numSlices = srv.Texture2DArray.ArraySize & 0xffff;
|
||||
view.firstSlice = srv.Texture2DArray.FirstArraySlice & 0xffff;
|
||||
view.firstMip = srv.Texture2DArray.MostDetailedMip & 0xff;
|
||||
view.numMips = srv.Texture2DArray.MipLevels & 0xff;
|
||||
view.minLODClamp = srv.Texture2DArray.ResourceMinLODClamp;
|
||||
}
|
||||
else if(srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE2DMS)
|
||||
@@ -837,28 +846,28 @@ void D3D12Replay::FillResourceView(D3D12Pipe::View &view, const D3D12Descriptor
|
||||
}
|
||||
else if(srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY)
|
||||
{
|
||||
view.numSlices = srv.Texture2DMSArray.ArraySize;
|
||||
view.firstSlice = srv.Texture2DMSArray.FirstArraySlice;
|
||||
view.numSlices = srv.Texture2DMSArray.ArraySize & 0xffff;
|
||||
view.firstSlice = srv.Texture2DMSArray.FirstArraySlice & 0xffff;
|
||||
}
|
||||
else if(srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE3D)
|
||||
{
|
||||
view.firstMip = srv.Texture3D.MostDetailedMip;
|
||||
view.numMips = srv.Texture3D.MipLevels;
|
||||
view.firstMip = srv.Texture3D.MostDetailedMip & 0xff;
|
||||
view.numMips = srv.Texture3D.MipLevels & 0xff;
|
||||
view.minLODClamp = srv.Texture3D.ResourceMinLODClamp;
|
||||
}
|
||||
else if(srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURECUBE)
|
||||
{
|
||||
view.numSlices = 6;
|
||||
view.firstMip = srv.TextureCube.MostDetailedMip;
|
||||
view.numMips = srv.TextureCube.MipLevels;
|
||||
view.firstMip = srv.TextureCube.MostDetailedMip & 0xff;
|
||||
view.numMips = srv.TextureCube.MipLevels & 0xff;
|
||||
view.minLODClamp = srv.TextureCube.ResourceMinLODClamp;
|
||||
}
|
||||
else if(srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURECUBEARRAY)
|
||||
{
|
||||
view.numSlices = srv.TextureCubeArray.NumCubes * 6;
|
||||
view.firstSlice = srv.TextureCubeArray.First2DArrayFace;
|
||||
view.firstMip = srv.TextureCubeArray.MostDetailedMip;
|
||||
view.numMips = srv.TextureCubeArray.MipLevels;
|
||||
view.numSlices = (srv.TextureCubeArray.NumCubes * 6) & 0xffff;
|
||||
view.firstSlice = srv.TextureCubeArray.First2DArrayFace & 0xffff;
|
||||
view.firstMip = srv.TextureCubeArray.MostDetailedMip & 0xff;
|
||||
view.numMips = srv.TextureCubeArray.MipLevels & 0xff;
|
||||
view.minLODClamp = srv.TextureCube.ResourceMinLODClamp;
|
||||
}
|
||||
}
|
||||
@@ -884,43 +893,44 @@ void D3D12Replay::FillResourceView(D3D12Pipe::View &view, const D3D12Descriptor
|
||||
if(uav.Buffer.StructureByteStride > 0)
|
||||
view.elementByteSize = uav.Buffer.StructureByteStride;
|
||||
|
||||
view.counterByteOffset = uav.Buffer.CounterOffsetInBytes;
|
||||
view.counterByteOffset = uav.Buffer.CounterOffsetInBytes & 0xffffffff;
|
||||
RDCASSERT(uav.Buffer.CounterOffsetInBytes < 0xffffffff);
|
||||
|
||||
if(view.counterResourceId != ResourceId())
|
||||
{
|
||||
bytebuf counterVal;
|
||||
GetDebugManager()->GetBufferData(
|
||||
rm->GetCurrentAs<ID3D12Resource>(desc->GetCounterResourceId()),
|
||||
view.counterByteOffset, 4, counterVal);
|
||||
uav.Buffer.CounterOffsetInBytes, 4, counterVal);
|
||||
uint32_t *val = (uint32_t *)&counterVal[0];
|
||||
view.bufferStructCount = *val;
|
||||
}
|
||||
}
|
||||
else if(uav.ViewDimension == D3D12_UAV_DIMENSION_TEXTURE1D)
|
||||
{
|
||||
view.firstMip = uav.Texture1D.MipSlice;
|
||||
view.firstMip = uav.Texture1D.MipSlice & 0xff;
|
||||
}
|
||||
else if(uav.ViewDimension == D3D12_UAV_DIMENSION_TEXTURE1DARRAY)
|
||||
{
|
||||
view.numSlices = uav.Texture1DArray.ArraySize;
|
||||
view.firstSlice = uav.Texture1DArray.FirstArraySlice;
|
||||
view.firstMip = uav.Texture1DArray.MipSlice;
|
||||
view.numSlices = uav.Texture1DArray.ArraySize & 0xffff;
|
||||
view.firstSlice = uav.Texture1DArray.FirstArraySlice & 0xffff;
|
||||
view.firstMip = uav.Texture1DArray.MipSlice & 0xff;
|
||||
}
|
||||
else if(uav.ViewDimension == D3D12_UAV_DIMENSION_TEXTURE2D)
|
||||
{
|
||||
view.firstMip = uav.Texture2D.MipSlice;
|
||||
view.firstMip = uav.Texture2D.MipSlice & 0xff;
|
||||
}
|
||||
else if(uav.ViewDimension == D3D12_UAV_DIMENSION_TEXTURE2DARRAY)
|
||||
{
|
||||
view.numSlices = uav.Texture2DArray.ArraySize;
|
||||
view.firstSlice = uav.Texture2DArray.FirstArraySlice;
|
||||
view.firstMip = uav.Texture2DArray.MipSlice;
|
||||
view.numSlices = uav.Texture2DArray.ArraySize & 0xffff;
|
||||
view.firstSlice = uav.Texture2DArray.FirstArraySlice & 0xffff;
|
||||
view.firstMip = uav.Texture2DArray.MipSlice & 0xff;
|
||||
}
|
||||
else if(uav.ViewDimension == D3D12_UAV_DIMENSION_TEXTURE3D)
|
||||
{
|
||||
view.numSlices = uav.Texture3D.WSize;
|
||||
view.firstSlice = uav.Texture3D.FirstWSlice;
|
||||
view.firstMip = uav.Texture3D.MipSlice;
|
||||
view.numSlices = uav.Texture3D.WSize & 0xffff;
|
||||
view.firstSlice = uav.Texture3D.FirstWSlice & 0xffff;
|
||||
view.firstMip = uav.Texture3D.MipSlice & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -932,6 +942,8 @@ void D3D12Replay::FillResourceView(D3D12Pipe::View &view, const D3D12Descriptor
|
||||
|
||||
view.viewFormat = MakeResourceFormat(fmt);
|
||||
}
|
||||
|
||||
desc->GetHeap()->SetToViewCache(desc->GetHeapIndex(), view);
|
||||
}
|
||||
|
||||
void D3D12Replay::FillSampler(D3D12Pipe::Sampler &samp, const D3D12_SAMPLER_DESC &sampDesc)
|
||||
|
||||
@@ -350,6 +350,57 @@ rdcarray<ID3D12Resource *> WrappedID3D12Resource::AddRefBuffersBeforeCapture(D3D
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool WrappedID3D12DescriptorHeap::HasValidViewCache(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;
|
||||
|
||||
// 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)
|
||||
{
|
||||
if(!mutableViewBitmask)
|
||||
return;
|
||||
|
||||
mutableViewBitmask[index / 64] |= (1ULL << (index % 64));
|
||||
}
|
||||
|
||||
void WrappedID3D12DescriptorHeap::GetFromViewCache(uint32_t index, D3D12Pipe::View &view)
|
||||
{
|
||||
if(!mutableViewBitmask)
|
||||
return;
|
||||
|
||||
bool dynamicallyUsed = view.dynamicallyUsed;
|
||||
uint32_t bind = view.bind;
|
||||
uint32_t tableIndex = view.tableIndex;
|
||||
view = cachedViews[index];
|
||||
view.dynamicallyUsed = dynamicallyUsed;
|
||||
view.bind = bind;
|
||||
view.tableIndex = tableIndex;
|
||||
}
|
||||
|
||||
void WrappedID3D12DescriptorHeap::SetToViewCache(uint32_t index, const D3D12Pipe::View &view)
|
||||
{
|
||||
if(!mutableViewBitmask)
|
||||
return;
|
||||
|
||||
cachedViews[index] = view;
|
||||
// we re-use bind as the indicator that this view is valid
|
||||
cachedViews[index].bind = 1;
|
||||
mutableViewBitmask[index / 64] |= (1ULL << (index % 64));
|
||||
}
|
||||
|
||||
WrappedID3D12DescriptorHeap::WrappedID3D12DescriptorHeap(ID3D12DescriptorHeap *real,
|
||||
WrappedID3D12Device *device,
|
||||
const D3D12_DESCRIPTOR_HEAP_DESC &desc,
|
||||
@@ -368,12 +419,32 @@ WrappedID3D12DescriptorHeap::WrappedID3D12DescriptorHeap(ID3D12DescriptorHeap *r
|
||||
RDCEraseMem(descriptors, sizeof(D3D12Descriptor) * desc.NumDescriptors);
|
||||
for(UINT i = 0; i < desc.NumDescriptors; i++)
|
||||
descriptors[i].Setup(this, i);
|
||||
|
||||
// only cache views for "large" descriptor heaps where we expect few will actually change
|
||||
// mid-frame
|
||||
if(IsReplayMode(device->GetState()) && desc.NumDescriptors > 1024)
|
||||
{
|
||||
size_t bitmaskSize = AlignUp(desc.NumDescriptors, 64U) / 64;
|
||||
|
||||
cachedViews = new D3D12Pipe::View[desc.NumDescriptors];
|
||||
RDCEraseMem(cachedViews, sizeof(D3D12Pipe::View) * desc.NumDescriptors);
|
||||
|
||||
mutableViewBitmask = new uint64_t[bitmaskSize];
|
||||
RDCEraseMem(mutableViewBitmask, sizeof(uint64_t) * bitmaskSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
cachedViews = NULL;
|
||||
mutableViewBitmask = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
WrappedID3D12DescriptorHeap::~WrappedID3D12DescriptorHeap()
|
||||
{
|
||||
Shutdown();
|
||||
SAFE_DELETE_ARRAY(descriptors);
|
||||
SAFE_DELETE_ARRAY(cachedViews);
|
||||
SAFE_DELETE_ARRAY(mutableViewBitmask);
|
||||
}
|
||||
|
||||
void WrappedID3D12PipelineState::ShaderEntry::BuildReflection()
|
||||
|
||||
@@ -396,6 +396,9 @@ class WrappedID3D12DescriptorHeap : public WrappedDeviceChild12<ID3D12Descriptor
|
||||
|
||||
D3D12Descriptor *descriptors;
|
||||
|
||||
D3D12Pipe::View *cachedViews;
|
||||
uint64_t *mutableViewBitmask;
|
||||
|
||||
public:
|
||||
ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D12DescriptorHeap);
|
||||
|
||||
@@ -410,6 +413,11 @@ public:
|
||||
|
||||
D3D12Descriptor *GetDescriptors() { return descriptors; }
|
||||
UINT GetNumDescriptors() { return numDescriptors; }
|
||||
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);
|
||||
|
||||
//////////////////////////////
|
||||
// implement ID3D12DescriptorHeap
|
||||
|
||||
|
||||
@@ -1424,7 +1424,7 @@ void DoSerialise(SerialiserType &ser, D3D12Pipe::View &el)
|
||||
|
||||
SERIALISE_MEMBER(minLODClamp);
|
||||
|
||||
SIZE_CHECK(96);
|
||||
SIZE_CHECK(72);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
@@ -1565,7 +1565,7 @@ void DoSerialise(SerialiserType &ser, D3D12Pipe::OM &el)
|
||||
SERIALISE_MEMBER(multiSampleCount);
|
||||
SERIALISE_MEMBER(multiSampleQuality);
|
||||
|
||||
SIZE_CHECK(264);
|
||||
SIZE_CHECK(240);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
@@ -1609,7 +1609,7 @@ void DoSerialise(SerialiserType &ser, D3D12Pipe::State &el)
|
||||
|
||||
SERIALISE_MEMBER(resourceStates);
|
||||
|
||||
SIZE_CHECK(1424);
|
||||
SIZE_CHECK(1400);
|
||||
}
|
||||
|
||||
#pragma endregion D3D12 pipeline state
|
||||
|
||||
Reference in New Issue
Block a user