diff --git a/renderdoc/driver/d3d11/d3d11_common.h b/renderdoc/driver/d3d11/d3d11_common.h index a3cf01e5a..f6842ed9c 100644 --- a/renderdoc/driver/d3d11/d3d11_common.h +++ b/renderdoc/driver/d3d11/d3d11_common.h @@ -295,6 +295,8 @@ enum D3D11ChunkType CONTEXT_CAPTURE_HEADER, // chunk at beginning of context's chunk stream CONTEXT_CAPTURE_FOOTER, // chunk at end of context's chunk stream + SET_SHADER_DEBUG_PATH, + NUM_D3D11_CHUNKS, }; diff --git a/renderdoc/driver/d3d11/d3d11_device.cpp b/renderdoc/driver/d3d11/d3d11_device.cpp index d3217e913..cca7f5b85 100644 --- a/renderdoc/driver/d3d11/d3d11_device.cpp +++ b/renderdoc/driver/d3d11/d3d11_device.cpp @@ -181,6 +181,8 @@ const char *D3D11ChunkNames[] = "ContextBegin", "ContextEnd", + + "SetShaderDebugPath", }; WRAPPED_POOL_INST(WrappedID3D11Device); @@ -959,6 +961,9 @@ void WrappedID3D11Device::ProcessChunk(uint64_t offset, D3D11ChunkType context) case CAPTURE_SCOPE: Serialise_CaptureScope(offset); break; + case SET_SHADER_DEBUG_PATH: + Serialise_SetShaderDebugPath(NULL, NULL); + break; default: // ignore system chunks if(context == INITIAL_CONTENTS) @@ -3199,6 +3204,50 @@ void WrappedID3D11Device::RemoveDeferredContext(WrappedID3D11DeviceContext *defc m_DeferredContexts.erase(defctx); } +bool WrappedID3D11Device::Serialise_SetShaderDebugPath(ID3D11DeviceChild *res, const char *p) +{ + SERIALISE_ELEMENT(ResourceId, resource, GetIDForResource(res)); + string debugPath = p ? p : ""; + m_pSerialiser->Serialise("debugPath", debugPath); + + if(m_State < WRITING && GetResourceManager()->HasLiveResource(resource)) + { + auto it = WrappedShader::m_ShaderList.find(GetResourceManager()->GetLiveID(resource)); + + if(it != WrappedShader::m_ShaderList.end()) + it->second->SetDebugInfoPath(debugPath); + } + + return true; +} + +HRESULT WrappedID3D11Device::SetShaderDebugPath(ID3D11DeviceChild *res, const char *path) +{ + if(m_State >= WRITING) + { + ResourceId idx = GetIDForResource(res); + D3D11ResourceRecord *record = GetResourceManager()->GetResourceRecord(idx); + + if(record == NULL) + { + RDCERR("Setting shader debug path on object %p of type %d that has no resource record.", res, IdentifyTypeByPtr(res)); + return E_INVALIDARG; + } + + RDCASSERT(idx != ResourceId()); + + { + SCOPED_SERIALISE_CONTEXT(SET_SHADER_DEBUG_PATH); + Serialise_SetShaderDebugPath(res, path); + record->AddChunk(scope.Get()); + } + + return S_OK; + } + + return S_OK; +} + bool WrappedID3D11Device::Serialise_SetResourceName(ID3D11DeviceChild *res, const char *nm) { SERIALISE_ELEMENT(ResourceId, resource, GetIDForResource(res)); diff --git a/renderdoc/driver/d3d11/d3d11_device.h b/renderdoc/driver/d3d11/d3d11_device.h index c8bada3ed..b8f3cff7b 100644 --- a/renderdoc/driver/d3d11/d3d11_device.h +++ b/renderdoc/driver/d3d11/d3d11_device.h @@ -329,6 +329,7 @@ public: // Resource IMPLEMENT_FUNCTION_SERIALISED(void, SetResourceName(ID3D11DeviceChild *res, const char *name)); + IMPLEMENT_FUNCTION_SERIALISED(HRESULT, SetShaderDebugPath(ID3D11DeviceChild *res, const char *name)); IMPLEMENT_FUNCTION_SERIALISED(void, ReleaseResource(ID3D11DeviceChild *res)); // Class Linkage diff --git a/renderdoc/driver/d3d11/d3d11_resources.cpp b/renderdoc/driver/d3d11/d3d11_resources.cpp index 576918a93..17a751083 100644 --- a/renderdoc/driver/d3d11/d3d11_resources.cpp +++ b/renderdoc/driver/d3d11/d3d11_resources.cpp @@ -23,7 +23,7 @@ * THE SOFTWARE. ******************************************************************************/ - +#include "api/app/renderdoc_app.h" #include "driver/dxgi/dxgi_wrapped.h" #include "driver/d3d11/d3d11_context.h" #include "driver/d3d11/d3d11_resources.h" @@ -62,11 +62,17 @@ map WrappedID3D11Buffer::m_BufferLi map WrappedShader::m_ShaderList; Threading::CriticalSection WrappedShader::m_ShaderListLock; +const GUID RENDERDOC_ID3D11ShaderGUID_ShaderDebugMagicValue = RENDERDOC_ShaderDebugMagicValue_struct; + void WrappedShader::ShaderEntry::TryReplaceOriginalByteCode() { if(!DXBC::DXBCFile::CheckForDebugInfo((const void *)&m_Bytecode[0], m_Bytecode.size())) { - string originalPath = DXBC::DXBCFile::GetDebugBinaryPath((const void *)&m_Bytecode[0], m_Bytecode.size()); + string originalPath = m_DebugInfoPath; + + if(originalPath.empty()) + originalPath = DXBC::DXBCFile::GetDebugBinaryPath((const void *)&m_Bytecode[0], m_Bytecode.size()); + if(!originalPath.empty()) { FILE* originalShaderFile = FileIO::fopen(originalPath.c_str(), "rb"); diff --git a/renderdoc/driver/d3d11/d3d11_resources.h b/renderdoc/driver/d3d11/d3d11_resources.h index 94c494833..d419c3910 100644 --- a/renderdoc/driver/d3d11/d3d11_resources.h +++ b/renderdoc/driver/d3d11/d3d11_resources.h @@ -450,6 +450,8 @@ public: } }; +extern const GUID RENDERDOC_ID3D11ShaderGUID_ShaderDebugMagicValue; + template class WrappedDeviceChild : public RefCounter, public NestedType, public TrackedResource { @@ -603,8 +605,12 @@ public: /* [annotation] */ __in_bcount_opt( DataSize ) const void *pData) { + if(guid == RENDERDOC_ID3D11ShaderGUID_ShaderDebugMagicValue) + return m_pDevice->SetShaderDebugPath(this, (const char *)pData); + if(guid == WKPDID_D3DDebugObjectName) m_pDevice->SetResourceName(this, (const char *)pData); + return m_pReal->SetPrivateData(guid, DataSize, pData); } @@ -1086,6 +1092,11 @@ public: SAFE_DELETE(m_Details); } + void SetDebugInfoPath(const std::string &path) + { + m_DebugInfoPath = path; + } + DXBC::DXBCFile *GetDXBC() { if(m_DXBCFile == NULL && !m_Bytecode.empty()) @@ -1106,6 +1117,8 @@ public: void TryReplaceOriginalByteCode(); ShaderEntry &operator =(const ShaderEntry &e); + std::string m_DebugInfoPath; + vector m_Bytecode; DXBC::DXBCFile *m_DXBCFile;