Handle byte-offset buffer descriptors on D3D12

This commit is contained in:
baldurk
2026-07-17 16:14:28 +01:00
parent 01c543634d
commit 65694c13a9
11 changed files with 290 additions and 44 deletions
+2 -6
View File
@@ -647,7 +647,7 @@ TextureType MakeTextureDim(D3D12_SRV_DIMENSION dim)
case D3D12_SRV_DIMENSION_TEXTURE3D: return TextureType::Texture3D;
case D3D12_SRV_DIMENSION_TEXTURECUBE: return TextureType::TextureCube;
case D3D12_SRV_DIMENSION_TEXTURECUBEARRAY: return TextureType::TextureCubeArray;
default: break;
case D3D12_SRV_DIMENSION_BUFFER_BYTE_OFFSET: return TextureType::Buffer;
}
return TextureType::Unknown;
@@ -666,7 +666,6 @@ TextureType MakeTextureDim(D3D12_RTV_DIMENSION dim)
case D3D12_RTV_DIMENSION_TEXTURE2DMS: return TextureType::Texture2DMS;
case D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY: return TextureType::Texture2DMSArray;
case D3D12_RTV_DIMENSION_TEXTURE3D: return TextureType::Texture3D;
default: break;
}
return TextureType::Unknown;
@@ -683,7 +682,6 @@ TextureType MakeTextureDim(D3D12_DSV_DIMENSION dim)
case D3D12_DSV_DIMENSION_TEXTURE2DARRAY: return TextureType::Texture2DArray;
case D3D12_DSV_DIMENSION_TEXTURE2DMS: return TextureType::Texture2DMS;
case D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY: return TextureType::Texture2DMSArray;
default: break;
}
return TextureType::Unknown;
@@ -702,7 +700,7 @@ TextureType MakeTextureDim(D3D12_UAV_DIMENSION dim)
case D3D12_UAV_DIMENSION_TEXTURE2DMS: return TextureType::Texture2DMS;
case D3D12_UAV_DIMENSION_TEXTURE2DMSARRAY: return TextureType::Texture2DMSArray;
case D3D12_UAV_DIMENSION_TEXTURE3D: return TextureType::Texture3D;
default: break;
case D3D12_UAV_DIMENSION_BUFFER_BYTE_OFFSET: return TextureType::Buffer;
}
return TextureType::Unknown;
@@ -717,7 +715,6 @@ AddressMode MakeAddressMode(D3D12_TEXTURE_ADDRESS_MODE addr)
case D3D12_TEXTURE_ADDRESS_MODE_CLAMP: return AddressMode::ClampEdge;
case D3D12_TEXTURE_ADDRESS_MODE_BORDER: return AddressMode::ClampBorder;
case D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE: return AddressMode::MirrorOnce;
default: break;
}
return AddressMode::Wrap;
@@ -736,7 +733,6 @@ CompareFunction MakeCompareFunc(D3D12_COMPARISON_FUNC func)
case D3D12_COMPARISON_FUNC_NOT_EQUAL: return CompareFunction::NotEqual;
case D3D12_COMPARISON_FUNC_GREATER_EQUAL: return CompareFunction::GreaterEqual;
case D3D12_COMPARISON_FUNC_ALWAYS: return CompareFunction::AlwaysTrue;
default: break;
}
return CompareFunction::AlwaysTrue;
+2
View File
@@ -1062,6 +1062,7 @@ DECLARE_REFLECTION_STRUCT(D3D12_TEX2DMS_ARRAY_SRV);
DECLARE_REFLECTION_STRUCT(D3D12_TEXCUBE_SRV);
DECLARE_REFLECTION_STRUCT(D3D12_TEXCUBE_ARRAY_SRV);
DECLARE_REFLECTION_STRUCT(D3D12_TEX3D_SRV);
DECLARE_REFLECTION_STRUCT(D3D12_BUFFER_SRV_BYTE_OFFSET);
DECLARE_REFLECTION_STRUCT(D3D12_SHADER_RESOURCE_VIEW_DESC);
DECLARE_REFLECTION_STRUCT(D3D12_BUFFER_RTV);
DECLARE_REFLECTION_STRUCT(D3D12_TEX1D_RTV);
@@ -1087,6 +1088,7 @@ DECLARE_REFLECTION_STRUCT(D3D12_TEX2D_ARRAY_UAV);
DECLARE_REFLECTION_STRUCT(D3D12_TEX2DMS_UAV);
DECLARE_REFLECTION_STRUCT(D3D12_TEX2DMS_ARRAY_UAV);
DECLARE_REFLECTION_STRUCT(D3D12_TEX3D_UAV);
DECLARE_REFLECTION_STRUCT(D3D12_BUFFER_UAV_BYTE_OFFSET);
DECLARE_REFLECTION_STRUCT(D3D12_UNORDERED_ACCESS_VIEW_DESC);
DECLARE_REFLECTION_STRUCT(D3D12_DEPTH_STENCIL_VALUE);
DECLARE_REFLECTION_STRUCT(D3D12_CLEAR_VALUE);
+83 -10
View File
@@ -351,11 +351,10 @@ static DXBC::ResourceRetType ConvertCompTypeToResourceRetType(const CompType com
case CompType::Typeless:
case CompType::UScaled:
case CompType::SScaled:
case CompType::Depth:
default:
RDCERR("Unexpected component type %s", ToStr(compType).c_str());
return DXBC::ResourceRetType ::RETURN_TYPE_UNKNOWN;
case CompType::Depth: break;
}
RDCERR("Unexpected component type %s", ToStr(compType).c_str());
return DXBC::ResourceRetType ::RETURN_TYPE_UNKNOWN;
}
static DXBCBytecode::ResourceDimension ConvertSRVResourceDimensionToResourceDimension(
@@ -366,7 +365,7 @@ static DXBCBytecode::ResourceDimension ConvertSRVResourceDimensionToResourceDime
case D3D12_SRV_DIMENSION_UNKNOWN:
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_UNKNOWN;
case D3D12_SRV_DIMENSION_BUFFER:
return DXBCBytecode::ResourceDimension ::RESOURCE_DIMENSION_BUFFER;
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_BUFFER;
case D3D12_SRV_DIMENSION_TEXTURE1D:
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_TEXTURE1D;
case D3D12_SRV_DIMENSION_TEXTURE1DARRAY:
@@ -385,10 +384,12 @@ static DXBCBytecode::ResourceDimension ConvertSRVResourceDimensionToResourceDime
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_TEXTURECUBE;
case D3D12_SRV_DIMENSION_TEXTURECUBEARRAY:
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_TEXTURECUBEARRAY;
default:
RDCERR("Unexpected SRV dimension %s", ToStr(dim).c_str());
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_UNKNOWN;
case D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE: break;
case D3D12_SRV_DIMENSION_BUFFER_BYTE_OFFSET:
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_BUFFER;
}
RDCERR("Unexpected SRV dimension %s", ToStr(dim).c_str());
return DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_UNKNOWN;
}
static DXDebug::SamplerMode ConvertSamplerFilterToSamplerMode(D3D12_FILTER filter)
@@ -406,7 +407,6 @@ static DXDebug::SamplerMode ConvertSamplerFilterToSamplerMode(D3D12_FILTER filte
case D3D12_FILTER_COMPARISON_MIN_MAG_ANISOTROPIC_MIP_POINT:
case D3D12_FILTER_COMPARISON_ANISOTROPIC:
return DXBCBytecode::SamplerMode::SAMPLER_MODE_COMPARISON;
break;
default: break;
}
return DXBCBytecode::SamplerMode::SAMPLER_MODE_DEFAULT;
@@ -1115,6 +1115,25 @@ SRVInfo D3D12APIWrapper::FetchSRV(const D3D12Descriptor *resDescriptor, const Bi
m_Device->GetDebugManager()->GetBufferData(pResource, 0, 0, data);
}
else if(srvDesc.ViewDimension == D3D12_SRV_DIMENSION_BUFFER_BYTE_OFFSET)
{
// apply the offset/size immediately by fetching only that data rather than it
// being in addressing calculations. Then all we need to do is fake numElements
// so it doesn't cause clamps
srvData.resInfo.firstElement = 0;
srvData.resInfo.numElements = D3D12ShaderDebug::GetBufferByteOffsetNumElements(srvDesc);
srvData.resInfo.isByteBuffer =
((srvDesc.BufferByteOffset.Flags & D3D12_BUFFER_SRV_FLAG_RAW) != 0) ? true : false;
// Get the buffer stride from the shader metadata (for StructuredBuffer, RawBuffer)
uint32_t mdStride =
DXILDebug::GetSRVBufferStrideFromShaderMetadata(m_EntryPointInterface, slot);
if(mdStride != 0)
srvData.resInfo.format.stride = mdStride;
m_Device->GetDebugManager()->GetBufferData(pResource, srvDesc.BufferByteOffset.Offset,
srvDesc.BufferByteOffset.Size, data);
}
// Textures are sampled via a pixel shader, so there's no need to copy their data
}
}
@@ -1477,6 +1496,53 @@ UAVInfo D3D12APIWrapper::FetchUAV(const D3D12Descriptor *resDescriptor, const Bi
}
}
}
else if(uavDesc.ViewDimension == D3D12_UAV_DIMENSION_BUFFER_BYTE_OFFSET)
{
// apply the offset/size immediately by fetching only that data rather than it
// being in addressing calculations. Then all we need to do is fake numElements
// so it doesn't cause clamps
uavData.resInfo.firstElement = 0;
uavData.resInfo.numElements = D3D12ShaderDebug::GetBufferByteOffsetNumElements(uavDesc);
uavData.resInfo.isByteBuffer =
((uavDesc.BufferByteOffset.Flags & D3D12_BUFFER_UAV_FLAG_RAW) != 0) ? true : false;
// Get the buffer stride from the shader metadata (for StructuredBuffer, RawBuffer)
uint32_t mdStride =
DXILDebug::GetUAVBufferStrideFromShaderMetadata(m_EntryPointInterface, slot);
if(mdStride != 0)
uavData.resInfo.format.stride = mdStride;
m_Device->GetDebugManager()->GetBufferData(pResource, uavDesc.BufferByteOffset.Offset,
uavDesc.BufferByteOffset.Size, data);
ResourceId counterId = resDescriptor->GetCounterResourceId();
if(counterId != ResourceId())
{
uint64_t counterByteOffset = uavDesc.BufferByteOffset.CounterOffsetInBytes;
ID3D12Resource *pCounterResource = rm->GetResAs<ID3D12Resource>(counterId);
if(pCounterResource)
{
bytebuf counterData;
m_Device->GetDebugManager()->GetBufferData(pCounterResource, counterByteOffset, 4,
counterData);
// Initialise the UAV counter from the buffer
if(counterData.size() == 4)
uavData.hiddenCounter = *((uint32_t *)counterData.data());
else
m_Device->AddDebugMessage(
MessageCategory::Execution, MessageSeverity::High, MessageSource::RuntimeWarning,
StringFormat::Fmt("Couldn't read UAV counter data for UAV in slot %u space %u",
slot.shaderRegister, slot.registerSpace));
}
else
{
m_Device->AddDebugMessage(
MessageCategory::Execution, MessageSeverity::High, MessageSource::RuntimeWarning,
StringFormat::Fmt("NULL counter resource for UAV in slot %u space %u",
slot.shaderRegister, slot.registerSpace));
}
}
}
else
{
uavData.tex = true;
@@ -2097,6 +2163,12 @@ ResourceReferenceInfo D3D12APIWrapper::FetchResourceReferenceInfo(const DXDebug:
resRefInfo.descType = DescriptorType::Buffer;
else if(srvDesc.ViewDimension == D3D12_SRV_DIMENSION_BUFFER)
resRefInfo.descType = DescriptorType::TypedBuffer;
else if(srvDesc.ViewDimension == D3D12_SRV_DIMENSION_BUFFER_BYTE_OFFSET &&
(srvDesc.BufferByteOffset.StructureByteStride > 0 ||
srvDesc.Format == DXGI_FORMAT_UNKNOWN))
resRefInfo.descType = DescriptorType::Buffer;
else if(srvDesc.ViewDimension == D3D12_SRV_DIMENSION_BUFFER_BYTE_OFFSET)
resRefInfo.descType = DescriptorType::TypedBuffer;
else
resRefInfo.descType = DescriptorType::Image;
@@ -2107,7 +2179,8 @@ ResourceReferenceInfo D3D12APIWrapper::FetchResourceReferenceInfo(const DXDebug:
D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = desc.GetUAV();
resRefInfo.resClass = DXIL::ResourceClass::UAV;
resRefInfo.varType = VarType::ReadWriteResource;
if(uavDesc.ViewDimension == D3D12_UAV_DIMENSION_BUFFER)
if(uavDesc.ViewDimension == D3D12_UAV_DIMENSION_BUFFER ||
uavDesc.ViewDimension == D3D12_UAV_DIMENSION_BUFFER_BYTE_OFFSET)
resRefInfo.descType = uavDesc.Format != DXGI_FORMAT_UNKNOWN
? DescriptorType::ReadWriteTypedBuffer
: DescriptorType::ReadWriteBuffer;
+7 -2
View File
@@ -467,8 +467,13 @@ void D3D12Descriptor::Create(D3D12_DESCRIPTOR_HEAP_TYPE heapType, WrappedID3D12D
}
}
if(countRes == NULL && desc && desc->ViewDimension == D3D12_UAV_DIMENSION_BUFFER)
desc->Buffer.CounterOffsetInBytes = 0;
if(countRes == NULL && desc)
{
if(desc->ViewDimension == D3D12_UAV_DIMENSION_BUFFER)
desc->Buffer.CounterOffsetInBytes = 0;
if(desc->ViewDimension == D3D12_UAV_DIMENSION_BUFFER_BYTE_OFFSET)
desc->BufferByteOffset.CounterOffsetInBytes = 0;
}
D3D12_UNORDERED_ACCESS_VIEW_DESC planeDesc;
// ensure that multi-plane formats have a valid plane slice specified. This shouldn't be
+63 -22
View File
@@ -67,7 +67,9 @@ struct D3D12_UNORDERED_ACCESS_VIEW_DESC_SQUEEZED
uint8_t ViewDimension;
uint8_t BufferFlags;
// 5 more bytes here - below union is 8-byte aligned
// 1 more bytes here
uint32_t BufferStride;
union
{
@@ -75,9 +77,14 @@ struct D3D12_UNORDERED_ACCESS_VIEW_DESC_SQUEEZED
{
UINT64 FirstElement;
UINT NumElements;
UINT StructureByteStride;
UINT64 CounterOffsetInBytes;
} Buffer;
struct D3D12_BUFFER_UAV_BYTE_OFFSET_SQUEEZED
{
UINT64 Offset;
UINT64 Size;
UINT64 CounterOffsetInBytes;
} BufferByteOffset;
D3D12_TEX1D_UAV Texture1D;
D3D12_TEX1D_ARRAY_UAV Texture1DArray;
D3D12_TEX2D_UAV Texture2D;
@@ -90,21 +97,39 @@ struct D3D12_UNORDERED_ACCESS_VIEW_DESC_SQUEEZED
Format = (uint8_t)desc.Format;
ViewDimension = (uint8_t)desc.ViewDimension;
// all but buffer elements should fit in 4 UINTs, so we can copy the Buffer (minus the flags we
// moved) and still cover them.
RDCCOMPILE_ASSERT(sizeof(Texture1D) <= 4 * sizeof(UINT), "Buffer isn't largest union member!");
RDCCOMPILE_ASSERT(sizeof(Texture1DArray) <= 4 * sizeof(UINT),
"Buffer isn't largest union member!");
RDCCOMPILE_ASSERT(sizeof(Texture2D) <= 4 * sizeof(UINT), "Buffer isn't largest union member!");
RDCCOMPILE_ASSERT(sizeof(Texture2DArray) <= 4 * sizeof(UINT),
"Buffer isn't largest union member!");
RDCCOMPILE_ASSERT(sizeof(Texture3D) <= 4 * sizeof(UINT), "Buffer isn't largest union member!");
// all but buffer elements should fit in 2 UINT64s, so when we copy Offset and Size (first two
// elements in BufferByteOffset) we will cover them
RDCCOMPILE_ASSERT(sizeof(Texture1D) <= sizeof(UINT64) * 2,
"BufferByteOffset isn't largest union member!");
RDCCOMPILE_ASSERT(sizeof(Texture1DArray) <= sizeof(UINT64) * 2,
"BufferByteOffset isn't largest union member!");
RDCCOMPILE_ASSERT(sizeof(Texture2D) <= sizeof(UINT64) * 2,
"BufferByteOffset isn't largest union member!");
RDCCOMPILE_ASSERT(sizeof(Texture2DArray) <= sizeof(UINT64) * 2,
"BufferByteOffset isn't largest union member!");
RDCCOMPILE_ASSERT(sizeof(Texture3D) <= sizeof(UINT64) * 2,
"BufferByteOffset isn't largest union member!");
RDCCOMPILE_ASSERT(sizeof(Texture3D) <= sizeof(UINT64) * 2,
"BufferByteOffset isn't largest union member!");
Buffer.FirstElement = desc.Buffer.FirstElement;
Buffer.NumElements = desc.Buffer.NumElements;
Buffer.StructureByteStride = desc.Buffer.StructureByteStride;
Buffer.CounterOffsetInBytes = desc.Buffer.CounterOffsetInBytes;
BufferFlags = (uint8_t)desc.Buffer.Flags;
if(desc.ViewDimension == D3D12_UAV_DIMENSION_BUFFER)
{
BufferStride = desc.Buffer.StructureByteStride;
BufferFlags = (uint8_t)desc.Buffer.Flags;
Buffer.FirstElement = desc.Buffer.FirstElement;
Buffer.NumElements = desc.Buffer.NumElements;
Buffer.CounterOffsetInBytes = desc.Buffer.CounterOffsetInBytes;
}
else
{
BufferStride = desc.BufferByteOffset.StructureByteStride;
BufferFlags = (uint8_t)desc.Buffer.Flags;
BufferByteOffset.Offset = desc.BufferByteOffset.Offset;
BufferByteOffset.Size = desc.BufferByteOffset.Size;
BufferByteOffset.CounterOffsetInBytes = desc.BufferByteOffset.CounterOffsetInBytes;
}
}
D3D12_UNORDERED_ACCESS_VIEW_DESC AsDesc() const
@@ -114,11 +139,24 @@ struct D3D12_UNORDERED_ACCESS_VIEW_DESC_SQUEEZED
desc.Format = (DXGI_FORMAT)Format;
desc.ViewDimension = (D3D12_UAV_DIMENSION)ViewDimension;
desc.Buffer.FirstElement = Buffer.FirstElement;
desc.Buffer.NumElements = Buffer.NumElements;
desc.Buffer.StructureByteStride = Buffer.StructureByteStride;
desc.Buffer.CounterOffsetInBytes = Buffer.CounterOffsetInBytes;
desc.Buffer.Flags = (D3D12_BUFFER_UAV_FLAGS)BufferFlags;
if(desc.ViewDimension == D3D12_UAV_DIMENSION_BUFFER)
{
desc.Buffer.StructureByteStride = BufferStride;
desc.Buffer.Flags = (D3D12_BUFFER_UAV_FLAGS)BufferFlags;
desc.Buffer.FirstElement = Buffer.FirstElement;
desc.Buffer.NumElements = Buffer.NumElements;
desc.Buffer.CounterOffsetInBytes = Buffer.CounterOffsetInBytes;
}
else
{
desc.BufferByteOffset.StructureByteStride = BufferStride;
desc.BufferByteOffset.Flags = (D3D12_BUFFER_UAV_FLAGS)BufferFlags;
desc.BufferByteOffset.Offset = BufferByteOffset.Offset;
desc.BufferByteOffset.Size = BufferByteOffset.Size;
desc.BufferByteOffset.CounterOffsetInBytes = BufferByteOffset.CounterOffsetInBytes;
}
return desc;
}
@@ -138,7 +176,6 @@ struct D3D12_SHADER_RESOURCE_VIEW_DESC_SQUEEZED
union
{
D3D12_BUFFER_SRV Buffer;
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_SRV AS;
D3D12_TEX1D_SRV Texture1D;
D3D12_TEX1D_ARRAY_SRV Texture1DArray;
D3D12_TEX2D_SRV Texture2D;
@@ -148,6 +185,8 @@ struct D3D12_SHADER_RESOURCE_VIEW_DESC_SQUEEZED
D3D12_TEX3D_SRV Texture3D;
D3D12_TEXCUBE_SRV TextureCube;
D3D12_TEXCUBE_ARRAY_SRV TextureCubeArray;
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_SRV AS;
D3D12_BUFFER_SRV_BYTE_OFFSET BufferByteOffset;
};
void Init(const D3D12_SHADER_RESOURCE_VIEW_DESC &desc)
@@ -178,6 +217,8 @@ struct D3D12_SHADER_RESOURCE_VIEW_DESC_SQUEEZED
"Texture2DArray isn't largest union member!");
RDCCOMPILE_ASSERT(sizeof(TextureCubeArray) <= sizeof(Texture2DArray),
"Texture2DArray isn't largest union member!");
RDCCOMPILE_ASSERT(sizeof(BufferByteOffset) <= sizeof(Texture2DArray),
"Texture2DArray isn't largest union member!");
Texture2DArray = desc.Texture2DArray;
}
+35 -2
View File
@@ -789,7 +789,8 @@ void D3D12Replay::FillDescriptor(Descriptor &dst, const D3D12Descriptor *src)
if(srv.ViewDimension == D3D12_SRV_DIMENSION_UNKNOWN)
srv = MakeSRVDesc(res);
if(srv.ViewDimension == D3D12_SRV_DIMENSION_BUFFER)
if(srv.ViewDimension == D3D12_SRV_DIMENSION_BUFFER ||
srv.ViewDimension == D3D12_SRV_DIMENSION_BUFFER_BYTE_OFFSET)
dst.type = DescriptorType::TypedBuffer;
else
dst.type = DescriptorType::Image;
@@ -819,6 +820,17 @@ void D3D12Replay::FillDescriptor(Descriptor &dst, const D3D12Descriptor *src)
dst.type = DescriptorType::Buffer;
}
}
else if(srv.ViewDimension == D3D12_SRV_DIMENSION_BUFFER_BYTE_OFFSET)
{
dst.byteOffset = srv.BufferByteOffset.Offset;
dst.byteSize = srv.BufferByteOffset.Size;
dst.flags = MakeDescriptorFlags(srv.BufferByteOffset.Flags);
if(srv.BufferByteOffset.StructureByteStride > 0)
{
dst.elementByteSize = srv.BufferByteOffset.StructureByteStride;
dst.type = DescriptorType::Buffer;
}
}
else if(srv.ViewDimension == D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE)
{
dst.type = DescriptorType::AccelerationStructure;
@@ -914,7 +926,8 @@ void D3D12Replay::FillDescriptor(Descriptor &dst, const D3D12Descriptor *src)
if(uav.ViewDimension == D3D12_UAV_DIMENSION_UNKNOWN)
uav = MakeUAVDesc(res);
if(uav.ViewDimension == D3D12_UAV_DIMENSION_BUFFER)
if(uav.ViewDimension == D3D12_UAV_DIMENSION_BUFFER ||
uav.ViewDimension == D3D12_UAV_DIMENSION_BUFFER_BYTE_OFFSET)
dst.type = uav.Format != DXGI_FORMAT_UNKNOWN ? DescriptorType::ReadWriteTypedBuffer
: DescriptorType::ReadWriteBuffer;
else
@@ -947,6 +960,26 @@ void D3D12Replay::FillDescriptor(Descriptor &dst, const D3D12Descriptor *src)
dst.bufferStructCount = *val;
}
}
else if(uav.ViewDimension == D3D12_UAV_DIMENSION_BUFFER_BYTE_OFFSET)
{
dst.byteOffset = uav.BufferByteOffset.Offset;
dst.byteSize = uav.BufferByteOffset.Size;
dst.flags = MakeDescriptorFlags(uav.BufferByteOffset.Flags);
if(uav.BufferByteOffset.StructureByteStride > 0)
dst.elementByteSize = uav.BufferByteOffset.StructureByteStride;
dst.counterByteOffset = uav.BufferByteOffset.CounterOffsetInBytes & 0xffffffff;
RDCASSERT(uav.BufferByteOffset.CounterOffsetInBytes < 0xffffffff);
if(dst.secondary != ResourceId())
{
bytebuf counterVal;
GetDebugManager()->GetBufferData(rm->GetResAs<ID3D12Resource>(src->GetCounterResourceId()),
uav.BufferByteOffset.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;
+2 -2
View File
@@ -1604,9 +1604,9 @@ D3D12_SHADER_RESOURCE_VIEW_DESC MakeSRVDesc(const D3D12_RESOURCE_DESC &desc)
ret.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
ret.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
ret.Buffer.StructureByteStride = 0;
ret.Buffer.StructureByteStride = 16;
ret.Buffer.FirstElement = 0;
ret.Buffer.NumElements = (UINT)desc.Width;
ret.Buffer.NumElements = (UINT)desc.Width / 16;
}
else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D)
{
@@ -1132,6 +1132,15 @@ void DoSerialise(SerialiserType &ser, D3D12_RAYTRACING_ACCELERATION_STRUCTURE_SR
SERIALISE_MEMBER_TYPED(D3D12SrcASLocation, Location);
}
template <class SerialiserType>
void DoSerialise(SerialiserType &ser, D3D12_BUFFER_SRV_BYTE_OFFSET &el)
{
SERIALISE_MEMBER(Offset).OffsetOrSize();
SERIALISE_MEMBER(Size).OffsetOrSize();
SERIALISE_MEMBER(StructureByteStride).OffsetOrSize();
SERIALISE_MEMBER(Flags);
}
template <class SerialiserType>
void DoSerialise(SerialiserType &ser, D3D12_SHADER_RESOURCE_VIEW_DESC &el)
{
@@ -1158,6 +1167,7 @@ void DoSerialise(SerialiserType &ser, D3D12_SHADER_RESOURCE_VIEW_DESC &el)
case D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE:
SERIALISE_MEMBER(RaytracingAccelerationStructure);
break;
case D3D12_SRV_DIMENSION_BUFFER_BYTE_OFFSET: SERIALISE_MEMBER(BufferByteOffset); break;
default: RDCERR("Unrecognised SRV Dimension %d", el.ViewDimension); break;
}
}
@@ -1364,6 +1374,16 @@ void DoSerialise(SerialiserType &ser, D3D12_TEX3D_UAV &el)
SERIALISE_MEMBER(WSize);
}
template <class SerialiserType>
void DoSerialise(SerialiserType &ser, D3D12_BUFFER_UAV_BYTE_OFFSET &el)
{
SERIALISE_MEMBER(Offset).OffsetOrSize();
SERIALISE_MEMBER(Size).OffsetOrSize();
SERIALISE_MEMBER(StructureByteStride).OffsetOrSize();
SERIALISE_MEMBER(CounterOffsetInBytes).OffsetOrSize();
SERIALISE_MEMBER(Flags);
}
template <class SerialiserType>
void DoSerialise(SerialiserType &ser, D3D12_UNORDERED_ACCESS_VIEW_DESC &el)
{
@@ -1383,6 +1403,7 @@ void DoSerialise(SerialiserType &ser, D3D12_UNORDERED_ACCESS_VIEW_DESC &el)
case D3D12_UAV_DIMENSION_TEXTURE2DMS: SERIALISE_MEMBER(Texture2DMS); break;
case D3D12_UAV_DIMENSION_TEXTURE2DMSARRAY: SERIALISE_MEMBER(Texture2DMSArray); break;
case D3D12_UAV_DIMENSION_TEXTURE3D: SERIALISE_MEMBER(Texture3D); break;
case D3D12_UAV_DIMENSION_BUFFER_BYTE_OFFSET: SERIALISE_MEMBER(BufferByteOffset); break;
default: RDCERR("Unrecognised RTV Dimension %d", el.ViewDimension); break;
}
}
@@ -688,8 +688,24 @@ ShaderVariable D3D12ShaderDebug::GetResourceInfo(WrappedID3D12Device *device,
result.value.u32v[3] = (uint32_t)uavDesc.Buffer.NumElements;
break;
}
// DXBC does not allow resinfo on buffers:
// srcResource must be a t# or u# register that is not a Buffer (but it is a Texture*).
DELIBERATE_FALLTHROUGH();
}
case D3D12_UAV_DIMENSION_BUFFER_BYTE_OFFSET:
{
if(isDXIL)
{
result.value.u32v[0] = result.value.u32v[1] = result.value.u32v[2] =
result.value.u32v[3] = GetBufferByteOffsetNumElements(uavDesc);
break;
}
// DXBC does not allow resinfo on buffers:
// srcResource must be a t# or u# register that is not a Buffer (but it is a Texture*).
DELIBERATE_FALLTHROUGH();
}
case D3D12_UAV_DIMENSION_UNKNOWN:
{
RDCWARN("Invalid view dimension for GetResourceInfo");
@@ -798,8 +814,24 @@ ShaderVariable D3D12ShaderDebug::GetResourceInfo(WrappedID3D12Device *device,
result.value.u32v[3] = (uint32_t)srvDesc.Buffer.NumElements;
break;
}
// DXBC does not allow resinfo on buffers:
// srcResource must be a t# or u# register that is not a Buffer (but it is a Texture*).
DELIBERATE_FALLTHROUGH();
}
case D3D12_SRV_DIMENSION_BUFFER_BYTE_OFFSET:
{
if(isDXIL)
{
result.value.u32v[0] = result.value.u32v[1] = result.value.u32v[2] =
result.value.u32v[3] = GetBufferByteOffsetNumElements(srvDesc);
break;
}
// DXBC does not allow resinfo on buffers:
// srcResource must be a t# or u# register that is not a Buffer (but it is a Texture*).
DELIBERATE_FALLTHROUGH();
}
case D3D12_SRV_DIMENSION_UNKNOWN:
{
RDCWARN("Invalid view dimension for GetResourceInfo");
@@ -1235,6 +1267,16 @@ void D3D12DebugAPIWrapper::FetchSRV(const DXBCDebug::BindingSlot &slot)
m_pDevice->GetDebugManager()->GetBufferData(pResource, 0, 0, srvData.data);
}
else if(srvDesc.ViewDimension == D3D12_SRV_DIMENSION_BUFFER_BYTE_OFFSET)
{
// apply the offset/size immediately by fetching only that data rather than it
// being in addressing calculations. Then all we need to do is set numElements
srvData.numElements = D3D12ShaderDebug::GetBufferByteOffsetNumElements(srvDesc);
m_pDevice->GetDebugManager()->GetBufferData(
pResource, srvDesc.BufferByteOffset.Offset, srvDesc.BufferByteOffset.Size,
srvData.data);
}
// Textures are sampled via a pixel shader, so there's no need to copy their data
}
@@ -1406,6 +1448,17 @@ void D3D12DebugAPIWrapper::FetchUAV(const DXBCDebug::BindingSlot &slot)
m_pDevice->GetDebugManager()->GetBufferData(pResource, 0, 0, uavData.data);
}
else if(uavDesc.ViewDimension == D3D12_UAV_DIMENSION_BUFFER_BYTE_OFFSET)
{
// apply the offset/size immediately by fetching only that data rather than it
// being in addressing calculations. Then all we need to do is fake numElements
// so it doesn't cause clamps
uavData.numElements = D3D12ShaderDebug::GetBufferByteOffsetNumElements(uavDesc);
m_pDevice->GetDebugManager()->GetBufferData(
pResource, uavDesc.BufferByteOffset.Offset, uavDesc.BufferByteOffset.Size,
uavData.data);
}
else
{
uavData.tex = true;
@@ -1532,6 +1585,11 @@ ShaderVariable D3D12DebugAPIWrapper::GetBufferInfo(DXBCBytecode::OperandType typ
result.value.u32v[0] = result.value.u32v[1] = result.value.u32v[2] = result.value.u32v[3] =
(uint32_t)srvDesc.Buffer.NumElements;
}
else if(srvDesc.ViewDimension == D3D12_SRV_DIMENSION_BUFFER_BYTE_OFFSET)
{
result.value.u32v[0] = result.value.u32v[1] = result.value.u32v[2] = result.value.u32v[3] =
D3D12ShaderDebug::GetBufferByteOffsetNumElements(srvDesc);
}
}
if(descriptor.GetType() == D3D12DescriptorType::UAV &&
@@ -1552,6 +1610,11 @@ ShaderVariable D3D12DebugAPIWrapper::GetBufferInfo(DXBCBytecode::OperandType typ
result.value.u32v[0] = result.value.u32v[1] = result.value.u32v[2] = result.value.u32v[3] =
(uint32_t)uavDesc.Buffer.NumElements;
}
else if(uavDesc.ViewDimension == D3D12_UAV_DIMENSION_BUFFER_BYTE_OFFSET)
{
result.value.u32v[0] = result.value.u32v[1] = result.value.u32v[2] = result.value.u32v[3] =
D3D12ShaderDebug::GetBufferByteOffsetNumElements(uavDesc);
}
}
return result;
@@ -74,4 +74,14 @@ ShaderVariable GetRenderTargetSampleInfo(WrappedID3D12Device *device,
DXGI_FORMAT GetUAVResourceFormat(const D3D12_UNORDERED_ACCESS_VIEW_DESC &uavDesc,
ID3D12Resource *pResource);
template <typename VIEW_DESC>
uint32_t GetBufferByteOffsetNumElements(const VIEW_DESC &viewDesc)
{
uint32_t elemSize = viewDesc.BufferByteOffset.StructureByteStride;
if(elemSize == 0)
elemSize = GetByteSize(1, 1, 1, viewDesc.Format, 0);
return uint32_t(viewDesc.BufferByteOffset.Size / elemSize);
}
};
@@ -419,6 +419,7 @@ rdcstr DoStringise(const D3D12_SRV_DIMENSION &el)
STRINGISE_ENUM(D3D12_SRV_DIMENSION_TEXTURECUBE)
STRINGISE_ENUM(D3D12_SRV_DIMENSION_TEXTURECUBEARRAY)
STRINGISE_ENUM(D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE)
STRINGISE_ENUM(D3D12_SRV_DIMENSION_BUFFER_BYTE_OFFSET)
}
END_ENUM_STRINGISE();
}
@@ -454,6 +455,7 @@ rdcstr DoStringise(const D3D12_UAV_DIMENSION &el)
STRINGISE_ENUM(D3D12_UAV_DIMENSION_TEXTURE2DMS)
STRINGISE_ENUM(D3D12_UAV_DIMENSION_TEXTURE2DMSARRAY)
STRINGISE_ENUM(D3D12_UAV_DIMENSION_TEXTURE3D)
STRINGISE_ENUM(D3D12_UAV_DIMENSION_BUFFER_BYTE_OFFSET)
}
END_ENUM_STRINGISE();
}