diff --git a/renderdoc/driver/d3d12/d3d12_common.cpp b/renderdoc/driver/d3d12/d3d12_common.cpp index 6b1ff5541..9697b760b 100644 --- a/renderdoc/driver/d3d12/d3d12_common.cpp +++ b/renderdoc/driver/d3d12/d3d12_common.cpp @@ -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; diff --git a/renderdoc/driver/d3d12/d3d12_common.h b/renderdoc/driver/d3d12/d3d12_common.h index 078676816..3a5463316 100644 --- a/renderdoc/driver/d3d12/d3d12_common.h +++ b/renderdoc/driver/d3d12/d3d12_common.h @@ -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); diff --git a/renderdoc/driver/d3d12/d3d12_dxil_debug.cpp b/renderdoc/driver/d3d12/d3d12_dxil_debug.cpp index 5f3eba460..26149c40e 100644 --- a/renderdoc/driver/d3d12/d3d12_dxil_debug.cpp +++ b/renderdoc/driver/d3d12/d3d12_dxil_debug.cpp @@ -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(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; diff --git a/renderdoc/driver/d3d12/d3d12_manager.cpp b/renderdoc/driver/d3d12/d3d12_manager.cpp index 51b33d24e..74f7f75b7 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.cpp +++ b/renderdoc/driver/d3d12/d3d12_manager.cpp @@ -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 diff --git a/renderdoc/driver/d3d12/d3d12_manager.h b/renderdoc/driver/d3d12/d3d12_manager.h index 0abdeced7..68d44d671 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.h +++ b/renderdoc/driver/d3d12/d3d12_manager.h @@ -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; } diff --git a/renderdoc/driver/d3d12/d3d12_replay.cpp b/renderdoc/driver/d3d12/d3d12_replay.cpp index b1dd3ce5f..4e832f754 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.cpp +++ b/renderdoc/driver/d3d12/d3d12_replay.cpp @@ -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(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; diff --git a/renderdoc/driver/d3d12/d3d12_resources.cpp b/renderdoc/driver/d3d12/d3d12_resources.cpp index a6f30f6ee..95149f9c1 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.cpp +++ b/renderdoc/driver/d3d12/d3d12_resources.cpp @@ -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) { diff --git a/renderdoc/driver/d3d12/d3d12_serialise.cpp b/renderdoc/driver/d3d12/d3d12_serialise.cpp index a5a81e10d..756159ae9 100644 --- a/renderdoc/driver/d3d12/d3d12_serialise.cpp +++ b/renderdoc/driver/d3d12/d3d12_serialise.cpp @@ -1132,6 +1132,15 @@ void DoSerialise(SerialiserType &ser, D3D12_RAYTRACING_ACCELERATION_STRUCTURE_SR SERIALISE_MEMBER_TYPED(D3D12SrcASLocation, Location); } +template +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 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 +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 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; } } diff --git a/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp b/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp index f41971c76..8ab62d0c1 100644 --- a/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp +++ b/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp @@ -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; diff --git a/renderdoc/driver/d3d12/d3d12_shaderdebug.h b/renderdoc/driver/d3d12/d3d12_shaderdebug.h index a37002fd9..69f5bbfc7 100644 --- a/renderdoc/driver/d3d12/d3d12_shaderdebug.h +++ b/renderdoc/driver/d3d12/d3d12_shaderdebug.h @@ -74,4 +74,14 @@ ShaderVariable GetRenderTargetSampleInfo(WrappedID3D12Device *device, DXGI_FORMAT GetUAVResourceFormat(const D3D12_UNORDERED_ACCESS_VIEW_DESC &uavDesc, ID3D12Resource *pResource); + +template +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); +} }; diff --git a/renderdoc/driver/d3d12/d3d12_stringise.cpp b/renderdoc/driver/d3d12/d3d12_stringise.cpp index f13c641ac..e59b4ea04 100644 --- a/renderdoc/driver/d3d12/d3d12_stringise.cpp +++ b/renderdoc/driver/d3d12/d3d12_stringise.cpp @@ -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(); }