mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-13 05:20:45 +00:00
Use special GetRowPitch calculation when pitch is needed on D3D
* GetByteSize(width, 1, 1) is normally the right thing except for planar YUV formats, where the planes messes up the calculation.
This commit is contained in:
@@ -303,7 +303,7 @@ bool WrappedID3D11DeviceContext::Serialise_UpdateSubresource1(
|
||||
subHeight = RDCMAX(1U, desc.Height >> mipLevel);
|
||||
}
|
||||
|
||||
UINT SourceRowPitch = GetByteSize(subWidth, 1, 1, fmt, 0);
|
||||
UINT SourceRowPitch = GetRowPitch(subWidth, fmt, 0);
|
||||
UINT SourceDepthPitch = GetByteSize(subWidth, subHeight, 1, fmt, 0);
|
||||
|
||||
if(IsReplayingAndReading() && m_CurEventID > 0)
|
||||
|
||||
@@ -6079,8 +6079,8 @@ void WrappedID3D11DeviceContext::UpdateSubresource(ID3D11Resource *pDstResource,
|
||||
|
||||
UINT boxTop = pDstBox ? pDstBox->top : 0;
|
||||
|
||||
UINT DstRowPitch = GetByteSize(subWidth, 1, 1, fmt, 0);
|
||||
UINT DstBoxRowPitch = GetByteSize(boxWidth, 1, 1, fmt, 0);
|
||||
UINT DstRowPitch = GetRowPitch(subWidth, fmt, 0);
|
||||
UINT DstBoxRowPitch = GetRowPitch(boxWidth, fmt, 0);
|
||||
UINT DstSlicePitch = GetByteSize(subWidth, subHeight, 1, fmt, 0);
|
||||
|
||||
// for block formats, rows are in blocks (so height is squished essentially)
|
||||
@@ -7192,7 +7192,7 @@ void MapIntercept::Init(ID3D11Texture1D *tex, UINT sub, void *appMemory)
|
||||
if(IsYUVPlanarFormat(fmt))
|
||||
numRows = GetYUVNumRows(fmt, numRows);
|
||||
|
||||
app.RowPitch = GetByteSize(width, 1, 1, fmt, mip);
|
||||
app.RowPitch = GetRowPitch(width, fmt, mip);
|
||||
app.DepthPitch = GetByteSize(width, height, 1, fmt, mip);
|
||||
|
||||
if(d3d.DepthPitch == 0)
|
||||
@@ -7227,7 +7227,7 @@ void MapIntercept::Init(ID3D11Texture2D *tex, UINT sub, void *appMemory)
|
||||
if(IsYUVPlanarFormat(fmt))
|
||||
numRows = GetYUVNumRows(fmt, numRows);
|
||||
|
||||
app.RowPitch = GetByteSize(width, 1, 1, fmt, mip);
|
||||
app.RowPitch = GetRowPitch(width, fmt, mip);
|
||||
app.DepthPitch = GetByteSize(width, height, 1, fmt, mip);
|
||||
|
||||
if(d3d.DepthPitch == 0)
|
||||
@@ -7261,7 +7261,7 @@ void MapIntercept::Init(ID3D11Texture3D *tex, UINT sub, void *appMemory)
|
||||
if(IsYUVPlanarFormat(fmt))
|
||||
numRows = GetYUVNumRows(fmt, numRows);
|
||||
|
||||
app.RowPitch = GetByteSize(width, 1, 1, fmt, mip);
|
||||
app.RowPitch = GetRowPitch(width, fmt, mip);
|
||||
app.DepthPitch = GetByteSize(width, height, 1, fmt, mip);
|
||||
}
|
||||
|
||||
|
||||
@@ -350,7 +350,7 @@ std::vector<D3D11_SUBRESOURCE_DATA> WrappedID3D11Device::Serialise_CreateTexture
|
||||
SubresourceContents = NULL;
|
||||
|
||||
// calculate tightly packed pitches
|
||||
descs[i].SysMemPitch = GetByteSize(w, 1, 1, fmt, mip);
|
||||
descs[i].SysMemPitch = GetRowPitch(w, fmt, mip);
|
||||
descs[i].SysMemSlicePitch = GetByteSize(w, h, 1, fmt, mip);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,7 +301,7 @@ uint32_t WrappedID3D11Device::GetSize_InitialState(ResourceId id, ID3D11DeviceCh
|
||||
{
|
||||
UINT mip = GetMipForSubresource(tex, sub);
|
||||
|
||||
const UINT RowPitch = GetByteSize(desc.Width, 1, 1, desc.Format, mip);
|
||||
const UINT RowPitch = GetRowPitch(desc.Width, desc.Format, mip);
|
||||
|
||||
ret += RowPitch;
|
||||
ret += (uint32_t)WriteSerialiser::GetChunkAlignment();
|
||||
@@ -760,7 +760,7 @@ bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId
|
||||
// use the RowPitch provided when we mapped in the first place, since we read the whole
|
||||
// buffer including padding
|
||||
subData[sub].SysMemPitch = RowPitch;
|
||||
subData[sub].SysMemSlicePitch = ContentsLength;
|
||||
subData[sub].SysMemSlicePitch = RowPitch * numRows;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -311,6 +311,99 @@ UINT GetByteSize(int Width, int Height, int Depth, DXGI_FORMAT Format, int mip)
|
||||
return ret;
|
||||
}
|
||||
|
||||
UINT GetRowPitch(int Width, DXGI_FORMAT Format, int mip)
|
||||
{
|
||||
// only YUV formats can have different rowpitch to their actual width
|
||||
if(!IsYUVFormat(Format))
|
||||
return GetByteSize(Width, 1, 1, Format, mip);
|
||||
|
||||
UINT ret = RDCMAX(Width >> mip, 1);
|
||||
|
||||
switch(Format)
|
||||
{
|
||||
case DXGI_FORMAT_AYUV:
|
||||
// 4:4:4 lossless packed, 8-bit. Equivalent size to R8G8B8A8
|
||||
ret *= 4;
|
||||
break;
|
||||
case DXGI_FORMAT_Y410:
|
||||
// 4:4:4 lossless packed. Equivalent size to R10G10B10A2, unlike most 10-bit/16-bit formats is
|
||||
// not equivalent to the 16-bit format.
|
||||
ret *= 4;
|
||||
break;
|
||||
case DXGI_FORMAT_Y416:
|
||||
// 4:4:4 lossless packed. Equivalent size to R16G16B16A16
|
||||
ret *= 8;
|
||||
break;
|
||||
case DXGI_FORMAT_NV12:
|
||||
// 4:2:0 planar. Since we can assume even width and height, resulting row pitch is 1 byte per
|
||||
// pixel - 1 byte luma each, and half subsampled chroma U/V in 1 byte total per pixel.
|
||||
break;
|
||||
case DXGI_FORMAT_P010:
|
||||
// 10-bit formats are stored identically to 16-bit formats
|
||||
// deliberate fallthrough
|
||||
case DXGI_FORMAT_P016:
|
||||
// Similar to NV12 but 16-bit elements
|
||||
ret *= 2;
|
||||
break;
|
||||
case DXGI_FORMAT_420_OPAQUE:
|
||||
// same size as NV12 - planar 4:2:0 but opaque layout
|
||||
break;
|
||||
case DXGI_FORMAT_YUY2:
|
||||
// 4:2:2 packed 8-bit, so 1 byte per pixel for luma and 1 byte per pixel for chroma (2 chroma
|
||||
// samples, with 50% subsampling = 1 byte per pixel)
|
||||
ret *= 2;
|
||||
break;
|
||||
case DXGI_FORMAT_Y210:
|
||||
// 10-bit formats are stored identically to 16-bit formats
|
||||
// deliberate fallthrough
|
||||
case DXGI_FORMAT_Y216:
|
||||
// 4:2:2 packed 16-bit
|
||||
ret *= 4;
|
||||
break;
|
||||
case DXGI_FORMAT_NV11:
|
||||
// similar to NV12 - planar 4:1:1 4 horizontal downsampling but no vertical downsampling. For
|
||||
// row pitch calculation amounts to the same result.
|
||||
ret = ret;
|
||||
break;
|
||||
case DXGI_FORMAT_AI44:
|
||||
// special format, 1 byte per pixel, palletised values in 4 most significant bits, alpha in 4
|
||||
// least significant bits.
|
||||
// deliberate fallthrough
|
||||
case DXGI_FORMAT_IA44:
|
||||
// same as above but swapped MSB/LSB
|
||||
break;
|
||||
case DXGI_FORMAT_P8:
|
||||
// 8 bits of palletised data
|
||||
break;
|
||||
case DXGI_FORMAT_A8P8:
|
||||
// 8 bits palletised data, 8 bits alpha data. Seems to be packed (no indication in docs of
|
||||
// planar)
|
||||
ret *= 2;
|
||||
break;
|
||||
case DXGI_FORMAT_P208:
|
||||
// 4:2:2 planar 8-bit. 1 byte per pixel of luma, then separately 1 byte per pixel of chroma.
|
||||
// Identical pitch to 4:2:0, just more rows in second plane
|
||||
break;
|
||||
case DXGI_FORMAT_V208:
|
||||
// unclear, seems to be packed 4:4:0 8-bit. Thus 1 byte per pixel for luma, 2 chroma samples
|
||||
// every 2 rows = 1 byte per pixel for chroma
|
||||
ret *= 2;
|
||||
break;
|
||||
case DXGI_FORMAT_V408:
|
||||
// unclear, seems to be packed 4:4:4 8-bit
|
||||
ret *= 4;
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_UNKNOWN:
|
||||
RDCERR("Getting row pitch of unknown DXGI format");
|
||||
ret = 0;
|
||||
break;
|
||||
default: RDCERR("Unrecognised DXGI Format: %d", Format); break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool IsBlockFormat(DXGI_FORMAT f)
|
||||
{
|
||||
switch(f)
|
||||
|
||||
@@ -32,6 +32,7 @@ ResourceFormat MakeResourceFormat(DXGI_FORMAT fmt);
|
||||
DXGI_FORMAT MakeDXGIFormat(ResourceFormat fmt);
|
||||
|
||||
UINT GetByteSize(int Width, int Height, int Depth, DXGI_FORMAT Format, int mip);
|
||||
UINT GetRowPitch(int Width, DXGI_FORMAT Format, int mip);
|
||||
|
||||
DXGI_FORMAT GetTypelessFormat(DXGI_FORMAT f);
|
||||
DXGI_FORMAT GetTypedFormat(DXGI_FORMAT f);
|
||||
|
||||
Reference in New Issue
Block a user