diff --git a/renderdoc/driver/d3d12/d3d12_dxil_debug.cpp b/renderdoc/driver/d3d12/d3d12_dxil_debug.cpp index d14d0cdc4..97ab915f5 100644 --- a/renderdoc/driver/d3d12/d3d12_dxil_debug.cpp +++ b/renderdoc/driver/d3d12/d3d12_dxil_debug.cpp @@ -60,79 +60,60 @@ static bool IsShaderParameterVisible(DXBC::ShaderType shaderType, return false; } -static void FillViewFmt(DXGI_FORMAT format, GlobalState::ViewFmt &viewFmt) +static void FillViewFmtFromResourceFormat(DXGI_FORMAT format, GlobalState::ViewFmt &viewFmt) { - if(format != DXGI_FORMAT_UNKNOWN) - { - ResourceFormat fmt = MakeResourceFormat(format); + RDCASSERT(format != DXGI_FORMAT_UNKNOWN); + ResourceFormat fmt = MakeResourceFormat(format); - viewFmt.byteWidth = fmt.compByteWidth; - viewFmt.numComps = fmt.compCount; - viewFmt.fmt = fmt.compType; + viewFmt.byteWidth = fmt.compByteWidth; + viewFmt.numComps = fmt.compCount; + viewFmt.compType = fmt.compType; - if(format == DXGI_FORMAT_R11G11B10_FLOAT) - viewFmt.byteWidth = 11; - else if(format == DXGI_FORMAT_R10G10B10A2_UINT || format == DXGI_FORMAT_R10G10B10A2_UNORM) - viewFmt.byteWidth = 10; - } + if(format == DXGI_FORMAT_R11G11B10_FLOAT) + viewFmt.byteWidth = 11; + else if(format == DXGI_FORMAT_R10G10B10A2_UINT || format == DXGI_FORMAT_R10G10B10A2_UNORM) + viewFmt.byteWidth = 10; + + if(viewFmt.byteWidth == 10 || viewFmt.byteWidth == 11) + viewFmt.stride = 4; // 10 10 10 2 or 11 11 10 + else + viewFmt.stride = viewFmt.byteWidth * viewFmt.numComps; } -static void LookupUAVFormatFromShaderReflection(const DXBC::Reflection &reflection, - const BindingSlot &slot, - GlobalState::ViewFmt &viewFmt) +// Only valid/used fo root descriptors +// Root descriptors only have RawBuffer and StructuredBuffer types +static uint32_t GetUAVBufferStrideFromShaderMetadata(const DXIL::EntryPointInterface *reflection, + const BindingSlot &slot) { - for(const DXBC::ShaderInputBind &bind : reflection.UAVs) + for(const DXIL::EntryPointInterface::ResourceBase &bind : reflection->uavs) { - if(bind.reg == slot.shaderRegister && bind.space == slot.registerSpace && - bind.dimension == DXBC::ShaderInputBind::DIM_BUFFER && - bind.retType < DXBC::RETURN_TYPE_MIXED && bind.retType != DXBC::RETURN_TYPE_UNKNOWN) + if(bind.MatchesBinding(slot.shaderRegister, slot.shaderRegister, slot.registerSpace)) { - viewFmt.byteWidth = 4; - viewFmt.numComps = bind.numComps; - - if(bind.retType == DXBC::RETURN_TYPE_UNORM) - viewFmt.fmt = CompType::UNorm; - else if(bind.retType == DXBC::RETURN_TYPE_SNORM) - viewFmt.fmt = CompType::SNorm; - else if(bind.retType == DXBC::RETURN_TYPE_UINT) - viewFmt.fmt = CompType::UInt; - else if(bind.retType == DXBC::RETURN_TYPE_SINT) - viewFmt.fmt = CompType::SInt; - else - viewFmt.fmt = CompType::Float; - - break; + if(bind.uavData.shape == ResourceKind::RawBuffer || + bind.uavData.shape == ResourceKind::StructuredBuffer) + { + return bind.uavData.elementStride; + } } } + return 0; } -static void LookupSRVFormatFromShaderReflection(const DXBC::Reflection &reflection, - const BindingSlot &slot, - GlobalState::ViewFmt &viewFmt) +static uint32_t GetSRVBufferStrideFromShaderMetadata(const DXIL::EntryPointInterface *reflection, + const BindingSlot &slot) { - for(const DXBC::ShaderInputBind &bind : reflection.SRVs) + for(const DXIL::EntryPointInterface::ResourceBase &bind : reflection->srvs) { - if(bind.reg == slot.shaderRegister && bind.space == slot.registerSpace && - bind.dimension == DXBC::ShaderInputBind::DIM_BUFFER && - bind.retType < DXBC::RETURN_TYPE_MIXED && bind.retType != DXBC::RETURN_TYPE_UNKNOWN) + if(bind.MatchesBinding(slot.shaderRegister, slot.shaderRegister, slot.registerSpace)) { - viewFmt.byteWidth = 4; - viewFmt.numComps = bind.numComps; - - if(bind.retType == DXBC::RETURN_TYPE_UNORM) - viewFmt.fmt = CompType::UNorm; - else if(bind.retType == DXBC::RETURN_TYPE_SNORM) - viewFmt.fmt = CompType::SNorm; - else if(bind.retType == DXBC::RETURN_TYPE_UINT) - viewFmt.fmt = CompType::UInt; - else if(bind.retType == DXBC::RETURN_TYPE_SINT) - viewFmt.fmt = CompType::SInt; - else - viewFmt.fmt = CompType::Float; - - break; + if(bind.srvData.shape == ResourceKind::RawBuffer || + bind.srvData.shape == ResourceKind::StructuredBuffer) + { + return bind.srvData.elementStride; + } } } + return 0; } static void FlattenSingleVariable(const rdcstr &cbufferName, uint32_t byteOffset, @@ -150,9 +131,8 @@ static void FlattenSingleVariable(const rdcstr &cbufferName, uint32_t byteOffset if(outvars[outIdx].columns > 0) { - // if we already have a variable in this slot, just copy the data for this variable and add the - // source mapping. - // We should not overlap into the next register as that's not allowed. + // if we already have a variable in this slot, just copy the data for this variable and add + // the source mapping. We should not overlap into the next register as that's not allowed. memcpy(&outvars[outIdx].value.u32v[outComp], &v.value.u32v[0], sizeof(uint32_t) * v.columns); SourceVariableMapping mapping; @@ -507,13 +487,12 @@ void GetInterpolationModeForInputParams(const rdcarray &inputSig, } } -D3D12APIWrapper::D3D12APIWrapper(WrappedID3D12Device *device, - const DXBC::DXBCContainer *dxbcContainer, GlobalState &globalState, - uint32_t eventId) +D3D12APIWrapper::D3D12APIWrapper(WrappedID3D12Device *device, const DXIL::Program &dxilProgram, + GlobalState &globalState, uint32_t eventId) : m_Device(device), - m_DXBC(dxbcContainer), + m_EntryPointInterface(dxilProgram.GetEntryPointInterface()), m_GlobalState(globalState), - m_ShaderType(dxbcContainer->m_Type), + m_ShaderType(dxilProgram.GetShaderType()), m_EventId(eventId) { } @@ -574,32 +553,31 @@ void D3D12APIWrapper::FetchSRV(const BindingSlot &slot) { D3D12_RESOURCE_DESC resDesc = pResource->GetDesc(); - // DXBC allows root buffers to have a stride of up to 16 bytes in the shader, which - // means encoding the byte offset into the first element here is wrong without knowing - // what the actual accessed stride is. Instead we only fetch the data from that offset - // onwards. + // DXC allows root buffers to have a stride of up to 16 bytes in the shader, which + // means encoding the byte offset into the first element here is wrong without + // knowing what the actual accessed stride is. Instead we only fetch the data from + // that offset onwards. // Root buffers are typeless, try with the resource desc format // The debugger code will handle DXGI_FORMAT_UNKNOWN - if(resDesc.Format == DXGI_FORMAT_UNKNOWN) - { - // If we didn't get a format from the resource, try to pull it from the - // shader reflection info - DXILDebug::LookupSRVFormatFromShaderReflection(*m_DXBC->GetReflection(), slot, - srvData.format); - } - else - { - DXILDebug::FillViewFmt(resDesc.Format, srvData.format); - } - srvData.firstElement = 0; - // root arguments have no bounds checking, so use the most conservative number of - // elements - srvData.numElements = uint32_t(resDesc.Width - element.offset); + if(resDesc.Format != DXGI_FORMAT_UNKNOWN) + DXILDebug::FillViewFmtFromResourceFormat(resDesc.Format, srvData.resInfo.format); + + srvData.resInfo.isRootDescriptor = true; + srvData.resInfo.firstElement = 0; + // root arguments have no bounds checking, so use the most conservative number of elements + srvData.resInfo.numElements = uint32_t(resDesc.Width - element.offset); if(resDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + // 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, element.offset, 0, srvData.data); + } } return; } @@ -658,26 +636,26 @@ void D3D12APIWrapper::FetchSRV(const BindingSlot &slot) if(srvDesc.Format != DXGI_FORMAT_UNKNOWN) { - DXILDebug::FillViewFmt(srvDesc.Format, srvData.format); + DXILDebug::FillViewFmtFromResourceFormat(srvDesc.Format, srvData.resInfo.format); } else { D3D12_RESOURCE_DESC resDesc = pResource->GetDesc(); if(resDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - srvData.format.stride = srvDesc.Buffer.StructureByteStride; - - // If we didn't get a type from the SRV description, try to pull it from the - // shader reflection info - DXILDebug::LookupSRVFormatFromShaderReflection(*m_DXBC->GetReflection(), slot, - srvData.format); - } + srvData.resInfo.format.stride = srvDesc.Buffer.StructureByteStride; } if(srvDesc.ViewDimension == D3D12_SRV_DIMENSION_BUFFER) { - srvData.firstElement = (uint32_t)srvDesc.Buffer.FirstElement; - srvData.numElements = srvDesc.Buffer.NumElements; + srvData.resInfo.firstElement = (uint32_t)srvDesc.Buffer.FirstElement; + srvData.resInfo.numElements = srvDesc.Buffer.NumElements; + srvData.resInfo.isByteBuffer = + ((srvDesc.Buffer.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, 0, 0, srvData.data); } @@ -853,31 +831,33 @@ void D3D12APIWrapper::FetchUAV(const BindingSlot &slot) if(pResource) { D3D12_RESOURCE_DESC resDesc = pResource->GetDesc(); - // DXBC allows root buffers to have a stride of up to 16 bytes in the shader, which - // means encoding the byte offset into the first element here is wrong without knowing - // what the actual accessed stride is. Instead we only fetch the data from that offset - // onwards. + // DXC allows root buffers to have a stride of up to 16 bytes in the shader, which + // means encoding the byte offset into the first element here is wrong without + // knowing what the actual accessed stride is. Instead we only fetch the data from + // that offset onwards. // Root buffers are typeless, try with the resource desc format // The debugger code will handle DXGI_FORMAT_UNKNOWN - if(resDesc.Format == DXGI_FORMAT_UNKNOWN) + if(resDesc.Format != DXGI_FORMAT_UNKNOWN) { - // If we didn't get a format from the resource, try to pull it from the - // shader reflection info - DXILDebug::LookupUAVFormatFromShaderReflection(*m_DXBC->GetReflection(), slot, - uavData.format); + DXILDebug::FillViewFmtFromResourceFormat(resDesc.Format, uavData.resInfo.format); } - else - { - DXILDebug::FillViewFmt(resDesc.Format, uavData.format); - } - uavData.firstElement = 0; + + uavData.resInfo.isRootDescriptor = true; + uavData.resInfo.firstElement = 0; // root arguments have no bounds checking, use the most conservative number of elements - uavData.numElements = uint32_t(resDesc.Width - element.offset); + uavData.resInfo.numElements = uint32_t(resDesc.Width - element.offset); if(resDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + // 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, element.offset, 0, uavData.data); + } } return; @@ -941,23 +921,20 @@ void D3D12APIWrapper::FetchUAV(const BindingSlot &slot) if(uavDesc.Format != DXGI_FORMAT_UNKNOWN) { - DXILDebug::FillViewFmt(uavDesc.Format, uavData.format); - } - else - { - D3D12_RESOURCE_DESC resDesc = pResource->GetDesc(); - if(resDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - uavData.format.stride = uavDesc.Buffer.StructureByteStride; - - // TODO: Try looking up UAV from shader reflection info? - } + DXILDebug::FillViewFmtFromResourceFormat(uavDesc.Format, uavData.resInfo.format); } if(uavDesc.ViewDimension == D3D12_UAV_DIMENSION_BUFFER) { - uavData.firstElement = (uint32_t)uavDesc.Buffer.FirstElement; - uavData.numElements = uavDesc.Buffer.NumElements; + uavData.resInfo.firstElement = (uint32_t)uavDesc.Buffer.FirstElement; + uavData.resInfo.numElements = uavDesc.Buffer.NumElements; + uavData.resInfo.isByteBuffer = + ((uavDesc.Buffer.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, 0, 0, uavData.data); } @@ -1225,5 +1202,4 @@ bool D3D12APIWrapper::IsResourceBound(DXIL::ResourceClass resClass, const DXDebu } return false; } - }; diff --git a/renderdoc/driver/d3d12/d3d12_dxil_debug.h b/renderdoc/driver/d3d12/d3d12_dxil_debug.h index 407362f19..41ee8cbb7 100644 --- a/renderdoc/driver/d3d12/d3d12_dxil_debug.h +++ b/renderdoc/driver/d3d12/d3d12_dxil_debug.h @@ -41,7 +41,7 @@ void FetchConstantBufferData(WrappedID3D12Device *device, const DXIL::Program *p class D3D12APIWrapper : public DebugAPIWrapper { public: - D3D12APIWrapper(WrappedID3D12Device *device, const DXBC::DXBCContainer *dxbcContainer, + D3D12APIWrapper(WrappedID3D12Device *device, const DXIL::Program &dxilProgram, GlobalState &globalState, uint32_t eventId); ~D3D12APIWrapper(); @@ -67,7 +67,7 @@ private: bool IsUAVBound(const BindingSlot &slot); WrappedID3D12Device *m_Device; - const DXBC::DXBCContainer *m_DXBC; + const DXIL::EntryPointInterface *m_EntryPointInterface; GlobalState &m_GlobalState; DXBC::ShaderType m_ShaderType; const uint32_t m_EventId; diff --git a/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp b/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp index e5f7c3efd..c0a6b368b 100644 --- a/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp +++ b/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp @@ -3393,7 +3393,7 @@ rdcarray D3D12Replay::ContinueDebug(ShaderDebugger *debugger) if(((DXBCContainerDebugger *)debugger)->isDXIL) { DXILDebug::Debugger *dxilDebugger = (DXILDebug::Debugger *)debugger; - DXILDebug::D3D12APIWrapper apiWrapper(m_pDevice, dxilDebugger->GetDXBCContainer(), + DXILDebug::D3D12APIWrapper apiWrapper(m_pDevice, dxilDebugger->GetProgram(), dxilDebugger->GetGlobalState(), dxilDebugger->GetEventId()); D3D12MarkerRegion region(m_pDevice->GetQueue()->GetReal(), "ContinueDebug Simulation Loop"); return dxilDebugger->ContinueDebug(&apiWrapper); diff --git a/renderdoc/driver/shaders/dxil/dxil_debug.cpp b/renderdoc/driver/shaders/dxil/dxil_debug.cpp index 5c2d67028..9c958e705 100644 --- a/renderdoc/driver/shaders/dxil/dxil_debug.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_debug.cpp @@ -875,14 +875,14 @@ static void TypedUAVStore(DXILDebug::GlobalState::ViewFmt &fmt, byte *d, const S { uint32_t u = 0; - if(fmt.fmt == CompType::UInt) + if(fmt.compType == CompType::UInt) { u |= (value.u32v[0] & 0x3ff) << 0; u |= (value.u32v[1] & 0x3ff) << 10; u |= (value.u32v[2] & 0x3ff) << 20; u |= (value.u32v[3] & 0x3) << 30; } - else if(fmt.fmt == CompType::UNorm) + else if(fmt.compType == CompType::UNorm) { u = ConvertToR10G10B10A2(Vec4f(value.f32v[0], value.f32v[1], value.f32v[2], value.f32v[3])); } @@ -906,28 +906,28 @@ static void TypedUAVStore(DXILDebug::GlobalState::ViewFmt &fmt, byte *d, const S } else if(fmt.byteWidth == 2) { - if(fmt.fmt == CompType::Float) + if(fmt.compType == CompType::Float) { uint16_t *u = (uint16_t *)d; for(int c = 0; c < fmt.numComps; c++) u[c] = ConvertToHalf(value.f32v[c]); } - else if(fmt.fmt == CompType::UInt) + else if(fmt.compType == CompType::UInt) { uint16_t *u = (uint16_t *)d; for(int c = 0; c < fmt.numComps; c++) u[c] = value.u32v[c] & 0xffff; } - else if(fmt.fmt == CompType::SInt) + else if(fmt.compType == CompType::SInt) { int16_t *i = (int16_t *)d; for(int c = 0; c < fmt.numComps; c++) i[c] = (int16_t)RDCCLAMP(value.s32v[c], (int32_t)INT16_MIN, (int32_t)INT16_MAX); } - else if(fmt.fmt == CompType::UNorm || fmt.fmt == CompType::UNormSRGB) + else if(fmt.compType == CompType::UNorm || fmt.compType == CompType::UNormSRGB) { uint16_t *u = (uint16_t *)d; @@ -937,7 +937,7 @@ static void TypedUAVStore(DXILDebug::GlobalState::ViewFmt &fmt, byte *d, const S u[c] = uint16_t(f); } } - else if(fmt.fmt == CompType::SNorm) + else if(fmt.compType == CompType::SNorm) { int16_t *i = (int16_t *)d; @@ -958,21 +958,21 @@ static void TypedUAVStore(DXILDebug::GlobalState::ViewFmt &fmt, byte *d, const S } else if(fmt.byteWidth == 1) { - if(fmt.fmt == CompType::UInt) + if(fmt.compType == CompType::UInt) { uint8_t *u = (uint8_t *)d; for(int c = 0; c < fmt.numComps; c++) u[c] = value.u32v[c] & 0xff; } - else if(fmt.fmt == CompType::SInt) + else if(fmt.compType == CompType::SInt) { int8_t *i = (int8_t *)d; for(int c = 0; c < fmt.numComps; c++) i[c] = (int8_t)RDCCLAMP(value.s32v[c], (int32_t)INT8_MIN, (int32_t)INT8_MAX); } - else if(fmt.fmt == CompType::UNorm || fmt.fmt == CompType::UNormSRGB) + else if(fmt.compType == CompType::UNorm || fmt.compType == CompType::UNormSRGB) { uint8_t *u = (uint8_t *)d; @@ -982,7 +982,7 @@ static void TypedUAVStore(DXILDebug::GlobalState::ViewFmt &fmt, byte *d, const S u[c] = uint8_t(f); } } - else if(fmt.fmt == CompType::SNorm) + else if(fmt.compType == CompType::SNorm) { int8_t *i = (int8_t *)d; @@ -1016,14 +1016,14 @@ static ShaderValue TypedUAVLoad(DXILDebug::GlobalState::ViewFmt &fmt, const byte uint32_t u; memcpy(&u, d, sizeof(uint32_t)); - if(fmt.fmt == CompType::UInt) + if(fmt.compType == CompType::UInt) { result.u32v[0] = (u >> 0) & 0x3ff; result.u32v[1] = (u >> 10) & 0x3ff; result.u32v[2] = (u >> 20) & 0x3ff; result.u32v[3] = (u >> 30) & 0x003; } - else if(fmt.fmt == CompType::UNorm) + else if(fmt.compType == CompType::UNorm) { Vec4f res = ConvertFromR10G10B10A2(u); result.f32v[0] = res.x; @@ -1058,35 +1058,35 @@ static ShaderValue TypedUAVLoad(DXILDebug::GlobalState::ViewFmt &fmt, const byte } else if(fmt.byteWidth == 2) { - if(fmt.fmt == CompType::Float) + if(fmt.compType == CompType::Float) { const uint16_t *u = (const uint16_t *)d; for(int c = 0; c < fmt.numComps; c++) result.f32v[c] = ConvertFromHalf(u[c]); } - else if(fmt.fmt == CompType::UInt) + else if(fmt.compType == CompType::UInt) { const uint16_t *u = (const uint16_t *)d; for(int c = 0; c < fmt.numComps; c++) result.u32v[c] = u[c]; } - else if(fmt.fmt == CompType::SInt) + else if(fmt.compType == CompType::SInt) { const int16_t *in = (const int16_t *)d; for(int c = 0; c < fmt.numComps; c++) result.s32v[c] = in[c]; } - else if(fmt.fmt == CompType::UNorm || fmt.fmt == CompType::UNormSRGB) + else if(fmt.compType == CompType::UNorm || fmt.compType == CompType::UNormSRGB) { const uint16_t *u = (const uint16_t *)d; for(int c = 0; c < fmt.numComps; c++) result.f32v[c] = float(u[c]) / float(0xffff); } - else if(fmt.fmt == CompType::SNorm) + else if(fmt.compType == CompType::SNorm) { const int16_t *in = (const int16_t *)d; @@ -1106,28 +1106,28 @@ static ShaderValue TypedUAVLoad(DXILDebug::GlobalState::ViewFmt &fmt, const byte } else if(fmt.byteWidth == 1) { - if(fmt.fmt == CompType::UInt) + if(fmt.compType == CompType::UInt) { const uint8_t *u = (const uint8_t *)d; for(int c = 0; c < fmt.numComps; c++) result.u32v[c] = u[c]; } - else if(fmt.fmt == CompType::SInt) + else if(fmt.compType == CompType::SInt) { const int8_t *in = (const int8_t *)d; for(int c = 0; c < fmt.numComps; c++) result.s32v[c] = in[c]; } - else if(fmt.fmt == CompType::UNorm || fmt.fmt == CompType::UNormSRGB) + else if(fmt.compType == CompType::UNorm || fmt.compType == CompType::UNormSRGB) { const uint8_t *u = (const uint8_t *)d; for(int c = 0; c < fmt.numComps; c++) result.f32v[c] = float(u[c]) / float(0xff); } - else if(fmt.fmt == CompType::SNorm) + else if(fmt.compType == CompType::SNorm) { const int8_t *in = (const int8_t *)d; @@ -1149,8 +1149,8 @@ static ShaderValue TypedUAVLoad(DXILDebug::GlobalState::ViewFmt &fmt, const byte // fill in alpha with 1.0 or 1 as appropriate if(fmt.numComps < 4) { - if(fmt.fmt == CompType::UNorm || fmt.fmt == CompType::UNormSRGB || - fmt.fmt == CompType::SNorm || fmt.fmt == CompType::Float) + if(fmt.compType == CompType::UNorm || fmt.compType == CompType::UNormSRGB || + fmt.compType == CompType::SNorm || fmt.compType == CompType::Float) result.f32v[3] = 1.0f; else result.u32v[3] = 1; @@ -1186,7 +1186,7 @@ void ConvertTypeToViewFormat(const DXIL::Type *type, DXILDebug::GlobalState::Vie resType = resType->inner; } - fmt.fmt = CompType::Typeless; + fmt.compType = CompType::Typeless; if(resType->type == Type::Scalar) { fmt.numComps = compCount; @@ -1195,12 +1195,12 @@ void ConvertTypeToViewFormat(const DXIL::Type *type, DXILDebug::GlobalState::Vie if(resType->scalarType == Type::ScalarKind::Int) { if(resType->bitWidth == 32) - fmt.fmt = CompType::SInt; + fmt.compType = CompType::SInt; } else if(resType->scalarType == Type::ScalarKind::Float) { if(resType->bitWidth == 32) - fmt.fmt = CompType::Float; + fmt.compType = CompType::Float; } } else if(resType->type == Type::Struct) @@ -1211,53 +1211,53 @@ void ConvertTypeToViewFormat(const DXIL::Type *type, DXILDebug::GlobalState::Vie } } -static void FillViewFmt(VarType type, DXILDebug::GlobalState::ViewFmt &fmt) +static void FillViewFmtFromVarType(VarType type, DXILDebug::GlobalState::ViewFmt &fmt) { switch(type) { case VarType::Float: fmt.byteWidth = 4; - fmt.fmt = CompType::Float; + fmt.compType = CompType::Float; break; case VarType::Double: fmt.byteWidth = 8; - fmt.fmt = CompType::Float; + fmt.compType = CompType::Float; break; case VarType::Half: fmt.byteWidth = 2; - fmt.fmt = CompType::Float; + fmt.compType = CompType::Float; break; case VarType::SInt: fmt.byteWidth = 4; - fmt.fmt = CompType::SInt; + fmt.compType = CompType::SInt; break; case VarType::UInt: fmt.byteWidth = 4; - fmt.fmt = CompType::UInt; + fmt.compType = CompType::UInt; break; case VarType::SShort: fmt.byteWidth = 2; - fmt.fmt = CompType::SInt; + fmt.compType = CompType::SInt; break; case VarType::UShort: fmt.byteWidth = 2; - fmt.fmt = CompType::UInt; + fmt.compType = CompType::UInt; break; case VarType::SLong: fmt.byteWidth = 8; - fmt.fmt = CompType::SInt; + fmt.compType = CompType::SInt; break; case VarType::ULong: fmt.byteWidth = 2; - fmt.fmt = CompType::UInt; + fmt.compType = CompType::UInt; break; case VarType::SByte: fmt.byteWidth = 1; - fmt.fmt = CompType::SInt; + fmt.compType = CompType::SInt; break; case VarType::UByte: fmt.byteWidth = 1; - fmt.fmt = CompType::UInt; + fmt.compType = CompType::UInt; break; default: RDCERR("Unhandled Result Type %s", ToStr(type).c_str()); break; } @@ -1831,7 +1831,6 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper, const bool raw = (dxOpCode == DXOp::RawBufferLoad) || (dxOpCode == DXOp::RawBufferStore); const bool buffer = (dxOpCode == DXOp::BufferLoad) || (dxOpCode == DXOp::BufferStore) || (dxOpCode == DXOp::TextureLoad) || (dxOpCode == DXOp::TextureStore); - bool byteAddress = raw; const bool load = (dxOpCode == DXOp::TextureLoad) || (dxOpCode == DXOp::BufferLoad) || (dxOpCode == DXOp::RawBufferLoad); @@ -1864,21 +1863,6 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper, } uint32_t structOffset = 0; - uint32_t stride = 0; - - if(buffer) - { - // Default for BufferLoad, BufferStore - // ByteAddressBuffer will have a stride of one - stride = 4; - } - else if(raw) - { - stride = 1; - } - - RDCASSERT(stride != 0); - const byte *data = NULL; size_t dataSize = 0; bool texData = false; @@ -1890,6 +1874,7 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper, BindingSlot resourceBinding(resRef->resourceBase.regBase, resRef->resourceBase.space); RDCASSERT((resClass == ResourceClass::SRV || resClass == ResourceClass::UAV), resClass); + GlobalState::ResourceInfo resInfo; switch(resClass) { case ResourceClass::UAV: @@ -1901,15 +1886,12 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper, uavIter = m_GlobalState.uavs.find(resourceBinding); } const GlobalState::UAVData &uav = uavIter->second; + resInfo = uav.resInfo; data = uav.data.data(); dataSize = uav.data.size(); texData = uav.tex; rowPitch = uav.rowPitch; depthPitch = uav.depthPitch; - firstElem = uav.firstElement; - numElems = uav.numElements; - fmt = uav.format; - stride = fmt.Stride(); break; } case ResourceClass::SRV: @@ -1921,17 +1903,13 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper, srvIter = m_GlobalState.srvs.find(resourceBinding); } const GlobalState::SRVData &srv = srvIter->second; + resInfo = srv.resInfo; data = srv.data.data(); dataSize = srv.data.size(); - firstElem = srv.firstElement; - numElems = srv.numElements; - fmt = srv.format; - stride = fmt.Stride(); break; } default: RDCERR("Unexpected ResourceClass %s", ToStr(resClass).c_str()); break; } - // Unbound resource if(data == NULL) { @@ -1945,32 +1923,23 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper, break; } - // Update the format if it is Typeless - // See FetchUAV() comment about root buffers being typeless - if(fmt.fmt == CompType::Typeless) + firstElem = resInfo.firstElement; + numElems = resInfo.numElements; + fmt = resInfo.format; + + bool byteAddress = resInfo.isByteBuffer; + + // If the format is unknown, guess it using the result type + // See FetchSRV(), FetchUAV() comment about root buffers being typeless + // The stride should have been computed from the shader metadata + if(fmt.compType == CompType::Typeless) { - FillViewFmt(result.type, fmt); + FillViewFmtFromVarType(result.type, fmt); fmt.numComps = result.columns; - if(fmt.stride == 0) - { - fmt.stride = 1; - stride = 1; - } - else - { - byteAddress = false; - stride = fmt.stride; - } - } - else - { - if(fmt.stride == 0) - fmt.stride = fmt.Stride(); - stride = fmt.stride; } - if(stride == 1) - byteAddress = true; + if(byteAddress) + fmt.stride = 1; if(annotatedHandle) { @@ -1983,12 +1952,13 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper, fmt.stride = props.structStride; byteAddress = false; } - stride = fmt.stride; - RDCASSERTNOTEQUAL(stride, 0); } + uint32_t stride = fmt.stride; + RDCASSERT(!((stride == 1) ^ byteAddress)); + RDCASSERTNOTEQUAL(stride, 0); - RDCASSERTNOTEQUAL(fmt.fmt, CompType::Typeless); + RDCASSERTNOTEQUAL(fmt.compType, CompType::Typeless); uint32_t texCoords[3] = {0, 0, 0}; uint32_t elemIdx = 0; @@ -2031,7 +2001,7 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper, if(texData) { - dataOffset += texCoords[0] * fmt.Stride(); + dataOffset += texCoords[0] * stride; dataOffset += texCoords[1] * rowPitch; dataOffset += texCoords[2] * depthPitch; } @@ -2286,7 +2256,7 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper, GlobalState::ViewFmt cbufferFmt; cbufferFmt.byteWidth = byteWidth; cbufferFmt.numComps = numComps; - cbufferFmt.fmt = CompType::Float; + cbufferFmt.compType = CompType::Float; cbufferFmt.stride = 16; result.value = TypedUAVLoad(cbufferFmt, data); @@ -6044,8 +6014,7 @@ ShaderDebugTrace *Debugger::BeginDebug(uint32_t eventId, const DXBC::DXBCContain { ShaderStage shaderStage = reflection.stage; - m_DXBC = dxbcContainer; - m_Program = m_DXBC->GetDXILByteCode(); + m_Program = dxbcContainer->GetDXILByteCode(); m_EventId = eventId; m_ActiveLaneIndex = activeLaneIndex; m_Steps = 0; diff --git a/renderdoc/driver/shaders/dxil/dxil_debug.h b/renderdoc/driver/shaders/dxil/dxil_debug.h index 980fb4682..e26ecd0ed 100644 --- a/renderdoc/driver/shaders/dxil/dxil_debug.h +++ b/renderdoc/driver/shaders/dxil/dxil_debug.h @@ -292,50 +292,47 @@ struct GlobalState { int byteWidth = 0; int numComps = 0; - CompType fmt = CompType::Typeless; + CompType compType = CompType::Typeless; int stride = 0; + }; - int Stride() const + struct ResourceInfo + { + ResourceInfo() : firstElement(0), numElements(0), isByteBuffer(false), isRootDescriptor(false) { - if(stride != 0) - return stride; - - if(byteWidth == 10 || byteWidth == 11) - return 4; // 10 10 10 2 or 11 11 10 - - return byteWidth * numComps; } + + uint32_t firstElement; + uint32_t numElements; + + bool isByteBuffer; + bool isRootDescriptor; + // Buffer stride is stored in format.stride + ViewFmt format; }; struct UAVData { - UAVData() - : firstElement(0), numElements(0), tex(false), rowPitch(0), depthPitch(0), hiddenCounter(0) - { - } + UAVData() : tex(false), rowPitch(0), depthPitch(0), hiddenCounter(0) {} + + ResourceInfo resInfo; bytebuf data; - uint32_t firstElement; - uint32_t numElements; - bool tex; uint32_t rowPitch, depthPitch; - ViewFmt format; - uint32_t hiddenCounter; }; + std::map uavs; typedef std::map::const_iterator UAVIterator; struct SRVData { - SRVData() : firstElement(0), numElements(0) {} - bytebuf data; - uint32_t firstElement; - uint32_t numElements; + SRVData() {} - ViewFmt format; + ResourceInfo resInfo; + bytebuf data; }; std::map srvs; @@ -467,7 +464,6 @@ public: static rdcstr GetResourceReferenceName(const DXIL::Program *program, DXIL::ResourceClass resClass, const BindingSlot &slot); const DXIL::Program &GetProgram() const { return *m_Program; } - const DXBC::DXBCContainer *const GetDXBCContainer() { return m_DXBC; } uint32_t GetEventId() { return m_EventId; } const FunctionInfo *GetFunctionInfo(const DXIL::Function *function) const; const rdcarray &GetDXILEntryPointInputs(void) const @@ -503,7 +499,6 @@ private: std::map types; } m_DebugInfo; - const DXBC::DXBCContainer *m_DXBC = NULL; const DXIL::Program *m_Program = NULL; const DXIL::Function *m_EntryPointFunction = NULL; const DXIL::EntryPointInterface *m_EntryPointInterface = NULL; diff --git a/renderdoc/driver/shaders/dxil/dxil_reflect.cpp b/renderdoc/driver/shaders/dxil/dxil_reflect.cpp index f217fc134..63b7067df 100644 --- a/renderdoc/driver/shaders/dxil/dxil_reflect.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_reflect.cpp @@ -306,6 +306,8 @@ EntryPointInterface::ResourceBase::ResourceBase(ResourceClass resourceClass, con SRV &srv = srvData; srv.shape = getival(md->children[(size_t)ResField::SRVShape]); srv.sampleCount = getival(md->children[(size_t)ResField::SRVSampleCount]); + srv.compType = ComponentType::Invalid; + srv.elementStride = ~0U; const Metadata *tags = md->children[(size_t)ResField::SRVTags]; for(size_t t = 0; tags && t < tags->children.size(); t += 2) { @@ -332,6 +334,11 @@ EntryPointInterface::ResourceBase::ResourceBase(ResourceClass resourceClass, con uav.hasCounter = (getival(md->children[(size_t)ResField::UAVHiddenCounter]) == 1); uav.rasterizerOrderedView = (getival(md->children[(size_t)ResField::UAVRasterOrder]) == 1); + uav.compType = ComponentType::Invalid; + uav.elementStride = ~0U; + uav.samplerFeedback = SamplerFeedbackType::LastEntry; + uav.atomic64Use = false; + const Metadata *tags = md->children[(size_t)ResField::UAVTags]; for(size_t t = 0; tags && t < tags->children.size(); t += 2) { @@ -360,6 +367,7 @@ EntryPointInterface::ResourceBase::ResourceBase(ResourceClass resourceClass, con CBuffer &cbuffer = cbufferData; cbuffer.sizeInBytes = getival(md->children[(size_t)ResField::CBufferByteSize]); const Metadata *tags = md->children[(size_t)ResField::CBufferTags]; + cbuffer.isTBuffer = false; for(size_t t = 0; tags && t < tags->children.size(); t += 2) { RDCASSERT(tags->children[t]->isConstant);