D3D11 texture serialisation size estimation fix.

During size estimation phase of serialisation, the row + depth pitch were not conservative enough estimates on some drivers. To remedy this, it's determined exactly at estimation time by attempting to map the resources.
This commit is contained in:
Neil Forbes-Richardson
2017-12-19 13:26:24 +01:00
committed by Baldur Karlsson
parent 82f4e82155
commit a091dea6f8
3 changed files with 52 additions and 4 deletions
+20 -4
View File
@@ -280,12 +280,14 @@ uint32_t WrappedID3D11Device::GetSize_InitialState(ResourceId id, ID3D11DeviceCh
uint32_t ret = 128; // type, Id, plus breathing room
// pessimistic RowPitch alignment since we don't know what will be reported
// pessimistic RowPitch alignment where we can't determine it correctly.
const UINT WorstRowPitchAlign = 256;
// pessimistic DepthPitch alignment
const UINT WorstDepthPitchAlign = 256;
ResourcePitch pitch = {WorstRowPitchAlign, WorstDepthPitchAlign};
D3D11ResourceType type = IdentifyTypeByPtr(res);
if(type == Resource_UnorderedAccessView)
@@ -348,6 +350,8 @@ uint32_t WrappedID3D11Device::GetSize_InitialState(ResourceId id, ID3D11DeviceCh
ret += 4; // number of subresources
ret += 4 * NumSubresources; // RowPitch for each subresource
ID3D11Resource *stage = (ID3D11Resource *)m_ResourceManager->GetInitialContents(id).resource;
// Subresource contents:
for(UINT sub = 0; sub < NumSubresources; sub++)
{
@@ -357,8 +361,13 @@ uint32_t WrappedID3D11Device::GetSize_InitialState(ResourceId id, ID3D11DeviceCh
if(IsBlockFormat(desc.Format))
numRows = AlignUp4(numRows) / 4;
if(stage)
pitch = GetResourcePitchForSubresource(m_pImmediateContext->GetReal(), stage, sub);
else
pitch = {WorstRowPitchAlign, WorstDepthPitchAlign};
const UINT RowPitch = GetByteSize(desc.Width, 1, 1, desc.Format, mip);
const UINT WorstRowPitch = AlignUp(RowPitch, WorstRowPitchAlign);
const UINT WorstRowPitch = AlignUp(RowPitch, pitch.m_RowPitch);
ret += WorstRowPitch * numRows;
ret += (uint32_t)WriteSerialiser::GetChunkAlignment();
@@ -377,20 +386,27 @@ uint32_t WrappedID3D11Device::GetSize_InitialState(ResourceId id, ID3D11DeviceCh
ret += 4; // number of subresources
ret += 8 * NumSubresources; // RowPitch and DepthPitch for each subresource
ID3D11Resource *stage = (ID3D11Resource *)m_ResourceManager->GetInitialContents(id).resource;
// Subresource contents:
for(UINT sub = 0; sub < NumSubresources; sub++)
{
UINT mip = GetMipForSubresource(tex, sub);
if(stage)
pitch = GetResourcePitchForSubresource(m_pImmediateContext->GetReal(), stage, sub);
else
pitch = {WorstRowPitchAlign, WorstDepthPitchAlign};
uint32_t numRows = RDCMAX(1U, desc.Height >> mip);
if(IsBlockFormat(desc.Format))
numRows = AlignUp4(numRows) / 4;
const UINT RowPitch = GetByteSize(desc.Width, 1, 1, desc.Format, mip);
const UINT WorstRowPitch = AlignUp(RowPitch, WorstRowPitchAlign);
const UINT WorstRowPitch = AlignUp(RowPitch, pitch.m_RowPitch);
const UINT DepthPitch = WorstRowPitch * numRows;
const UINT WorstDepthPitch = AlignUp(DepthPitch, WorstDepthPitchAlign);
const UINT WorstDepthPitch = AlignUp(DepthPitch, pitch.m_DepthPitch);
ret += WorstDepthPitch * RDCMAX(1U, desc.Depth >> mip);
ret += (uint32_t)WriteSerialiser::GetChunkAlignment();
@@ -250,6 +250,29 @@ UINT GetMipForSubresource(ID3D11Resource *res, int Subresource)
return mipLevel;
}
ResourcePitch GetResourcePitchForSubresource(ID3D11DeviceContext *ctx, ID3D11Resource *res,
int Subresource)
{
ResourcePitch pitch = {};
D3D11_MAPPED_SUBRESOURCE mapped = {};
HRESULT hr = E_INVALIDARG;
hr = ctx->Map(res, Subresource, D3D11_MAP_READ, 0, &mapped);
if(FAILED(hr))
{
RDCERR("Failed to map while getting resource pitch HRESULT: %s", ToStr(hr).c_str());
}
else
{
pitch.m_RowPitch = mapped.RowPitch;
pitch.m_DepthPitch = mapped.DepthPitch;
ctx->Unmap(res, Subresource);
}
return pitch;
}
UINT GetByteSize(ID3D11Texture1D *tex, int SubResource)
{
D3D11_TEXTURE1D_DESC desc;
+9
View File
@@ -75,6 +75,15 @@ UINT GetByteSize(ID3D11Texture3D *tex, int SubResource);
UINT GetMipForSubresource(ID3D11Resource *res, int Subresource);
struct ResourcePitch
{
UINT m_RowPitch;
UINT m_DepthPitch;
};
ResourcePitch GetResourcePitchForSubresource(ID3D11DeviceContext *ctx, ID3D11Resource *res,
int Subresource);
template <typename derived, typename base>
bool CanQuery(base *b)
{