From d8d6557feb6f7c2fa11fbfd6520933bbd48b6c4b Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 17 May 2021 13:46:01 +0100 Subject: [PATCH] Add support for file includes from custom shaders. Closes #2275 --- qrenderdoc/Windows/TextureViewer.cpp | 12 ++- renderdoc/api/replay/renderdoc_replay.h | 13 +++ renderdoc/core/image_viewer.cpp | 4 + renderdoc/core/replay_proxy.h | 5 ++ renderdoc/driver/d3d11/d3d11_replay.cpp | 14 +++- renderdoc/driver/d3d11/d3d11_replay.h | 7 +- renderdoc/driver/d3d11/d3d11_shader_cache.cpp | 51 ++++-------- renderdoc/driver/d3d11/d3d11_shader_cache.h | 2 +- renderdoc/driver/d3d12/d3d12_debug.cpp | 61 +++++++------- renderdoc/driver/d3d12/d3d12_rendertext.cpp | 4 +- renderdoc/driver/d3d12/d3d12_replay.cpp | 16 ++-- renderdoc/driver/d3d12/d3d12_replay.h | 7 +- renderdoc/driver/d3d12/d3d12_shader_cache.cpp | 51 ++++-------- renderdoc/driver/d3d12/d3d12_shader_cache.h | 4 +- renderdoc/driver/d3d12/d3d12_shaderdebug.cpp | 6 +- renderdoc/driver/dxgi/dxgi_common.cpp | 82 +++++++++++++++++++ renderdoc/driver/dxgi/dxgi_common.h | 28 +++++++ renderdoc/driver/gl/gl_replay.cpp | 4 + renderdoc/driver/gl/gl_replay.h | 1 + renderdoc/driver/vulkan/vk_replay.cpp | 4 + renderdoc/driver/vulkan/vk_replay.h | 1 + renderdoc/replay/replay_controller.cpp | 7 ++ renderdoc/replay/replay_controller.h | 1 + renderdoc/replay/replay_driver.h | 1 + 24 files changed, 265 insertions(+), 121 deletions(-) diff --git a/qrenderdoc/Windows/TextureViewer.cpp b/qrenderdoc/Windows/TextureViewer.cpp index 1c434e72a..3f013aa3a 100644 --- a/qrenderdoc/Windows/TextureViewer.cpp +++ b/qrenderdoc/Windows/TextureViewer.cpp @@ -4326,12 +4326,22 @@ void TextureViewer::reloadCustomShaders(const QString &filter) fileHandle.close(); + rdcarray dirs; + + for(QDir d : getShaderDirectories()) + { + if(d.exists()) + dirs.push_back(d.absolutePath()); + } + m_CustomShaders[key] = ResourceId(); m_CustomShadersBusy.push_back(key); m_Ctx.Replay().AsyncInvoke( - [this, fn, key, shaderBytes, encoding, errors](IReplayController *r) { + [this, fn, dirs, key, shaderBytes, encoding, errors](IReplayController *r) { rdcstr buildErrors; + r->SetCustomShaderIncludes(dirs); + ResourceId id; rdctie(id, buildErrors) = r->BuildCustomShader( "main", encoding, shaderBytes, ShaderCompileFlags(), ShaderStage::Pixel); diff --git a/renderdoc/api/replay/renderdoc_replay.h b/renderdoc/api/replay/renderdoc_replay.h index 43bb9f816..87e935023 100644 --- a/renderdoc/api/replay/renderdoc_replay.h +++ b/renderdoc/api/replay/renderdoc_replay.h @@ -552,8 +552,21 @@ or hardware-specific ISA formats. virtual rdcstr DisassembleShader(ResourceId pipeline, const ShaderReflection *refl, const rdcstr &target) = 0; + DOCUMENT(R"(Sets a list of directories to search for include files when compiling custom shaders +with the internal shader compiler. + +.. note:: + This is currently only supported for D3D11 and D3D12. For Vulkan includes can be supported via + configuring an external compiler to SPIR-V which is ingested. + +:param List[str] directories: The absolute paths of the directories. +)"); + virtual void SetCustomShaderIncludes(const rdcarray &directories) = 0; + DOCUMENT(R"(Builds a shader suitable for running on the local replay instance as a custom shader. +System-level include directories can be set up via SetCustomShaderIncludes. + See :data:`TextureDisplay.customShaderId`. :param str entry: The entry point to use when compiling. diff --git a/renderdoc/core/image_viewer.cpp b/renderdoc/core/image_viewer.cpp index e1e0f7cfd..c6376104f 100644 --- a/renderdoc/core/image_viewer.cpp +++ b/renderdoc/core/image_viewer.cpp @@ -169,6 +169,10 @@ public: { return m_Proxy->GetCustomShaderEncodings(); } + void SetCustomShaderIncludes(const rdcarray &directories) + { + m_Proxy->SetCustomShaderIncludes(directories); + } void BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id, rdcstr &errors) diff --git a/renderdoc/core/replay_proxy.h b/renderdoc/core/replay_proxy.h index da112b96c..a5bd464b4 100644 --- a/renderdoc/core/replay_proxy.h +++ b/renderdoc/core/replay_proxy.h @@ -405,6 +405,11 @@ public: return ~0U; } + void SetCustomShaderIncludes(const rdcarray &directories) + { + if(m_Proxy) + m_Proxy->SetCustomShaderIncludes(directories); + } void BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id, rdcstr &errors) diff --git a/renderdoc/driver/d3d11/d3d11_replay.cpp b/renderdoc/driver/d3d11/d3d11_replay.cpp index 7979e16ac..1a82faf58 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.cpp +++ b/renderdoc/driver/d3d11/d3d11_replay.cpp @@ -2545,7 +2545,8 @@ D3D11DebugManager *D3D11Replay::GetDebugManager() void D3D11Replay::BuildShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry, const ShaderCompileFlags &compileFlags, - ShaderStage type, ResourceId &id, rdcstr &errors) + const rdcarray &includeDirs, ShaderStage type, ResourceId &id, + rdcstr &errors) { bytebuf compiledDXBC; @@ -2580,7 +2581,7 @@ void D3D11Replay::BuildShader(ShaderEncoding sourceEncoding, const bytebuf &sour ID3DBlob *blob = NULL; errors = m_pDevice->GetShaderCache()->GetShaderBlob(hlsl.c_str(), entry.c_str(), flags, - profile.c_str(), &blob); + includeDirs, profile.c_str(), &blob); if(blob == NULL) { @@ -2708,14 +2709,19 @@ void D3D11Replay::BuildTargetShader(ShaderEncoding sourceEncoding, const bytebuf ShaderCompileFlags debugCompileFlags = DXBC::EncodeFlags( DXBC::DecodeFlags(compileFlags) | D3DCOMPILE_DEBUG, DXBC::GetProfile(compileFlags)); - BuildShader(sourceEncoding, source, entry, debugCompileFlags, type, id, errors); + BuildShader(sourceEncoding, source, entry, debugCompileFlags, {}, type, id, errors); +} + +void D3D11Replay::SetCustomShaderIncludes(const rdcarray &directories) +{ + m_CustomShaderIncludes = directories; } void D3D11Replay::BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id, rdcstr &errors) { - BuildTargetShader(sourceEncoding, source, entry, compileFlags, type, id, errors); + BuildShader(sourceEncoding, source, entry, compileFlags, m_CustomShaderIncludes, type, id, errors); } bool D3D11Replay::RenderTexture(TextureDisplay cfg) diff --git a/renderdoc/driver/d3d11/d3d11_replay.h b/renderdoc/driver/d3d11/d3d11_replay.h index e50ed11e3..a9a35fe32 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.h +++ b/renderdoc/driver/d3d11/d3d11_replay.h @@ -247,6 +247,7 @@ public: ResourceId RenderOverlay(ResourceId texid, FloatVector clearCol, DebugOverlay overlay, uint32_t eventId, const rdcarray &passEvents); + void SetCustomShaderIncludes(const rdcarray &directories); void BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id, rdcstr &errors); @@ -263,8 +264,8 @@ private: D3D11DebugManager *GetDebugManager(); // shared by BuildCustomShader and BuildTargetShader void BuildShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry, - const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id, - rdcstr &errors); + const ShaderCompileFlags &compileFlags, const rdcarray &includeDirs, + ShaderStage type, ResourceId &id, rdcstr &errors); void ClearPostVSCache(); @@ -332,6 +333,8 @@ private: WrappedID3D11Device *m_pDevice = NULL; WrappedID3D11DeviceContext *m_pImmediateContext = NULL; + rdcarray m_CustomShaderIncludes; + // used to track the real state so we can preserve it even across work done to the output windows struct RealState { diff --git a/renderdoc/driver/d3d11/d3d11_shader_cache.cpp b/renderdoc/driver/d3d11/d3d11_shader_cache.cpp index 97c1015ce..497797a60 100644 --- a/renderdoc/driver/d3d11/d3d11_shader_cache.cpp +++ b/renderdoc/driver/d3d11/d3d11_shader_cache.cpp @@ -25,6 +25,7 @@ #include "d3d11_shader_cache.h" #include "common/shader_cache.h" #include "driver/dx/official/d3dcompiler.h" +#include "driver/dxgi/dxgi_common.h" #include "driver/shaders/dxbc/dxbc_container.h" #include "strings/string_utils.h" #include "d3d11_device.h" @@ -80,33 +81,6 @@ struct D3DBlobShaderCallbacks pD3DCreateBlob m_BlobCreate = NULL; } D3D11ShaderCacheCallbacks; -struct EmbeddedD3D11Includer : public ID3DInclude -{ - rdcstr texsample = GetEmbeddedResource(hlsl_texsample_h); - rdcstr cbuffers = GetEmbeddedResource(hlsl_cbuffers_h); - - virtual HRESULT STDMETHODCALLTYPE Open(D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, - LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) override - { - rdcstr *str; - - if(!strcmp(pFileName, "hlsl_texsample.h")) - str = &texsample; - else if(!strcmp(pFileName, "hlsl_cbuffers.h")) - str = &cbuffers; - else - return E_FAIL; - - if(ppData) - *ppData = str->c_str(); - if(pBytes) - *pBytes = (uint32_t)str->size(); - - return S_OK; - } - virtual HRESULT STDMETHODCALLTYPE Close(LPCVOID pData) override { return S_OK; } -}; - D3D11ShaderCache::D3D11ShaderCache(WrappedID3D11Device *wrapper) { m_pDevice = wrapper; @@ -133,16 +107,23 @@ D3D11ShaderCache::~D3D11ShaderCache() } rdcstr D3D11ShaderCache::GetShaderBlob(const char *source, const char *entry, - const uint32_t compileFlags, const char *profile, + const uint32_t compileFlags, + const rdcarray &includeDirs, const char *profile, ID3DBlob **srcblob) { - EmbeddedD3D11Includer includer; + rdcstr cbuffers = GetEmbeddedResource(hlsl_cbuffers_h); + rdcstr texsample = GetEmbeddedResource(hlsl_texsample_h); + + EmbeddedD3DIncluder includer(includeDirs, + { + {"hlsl_texsample.h", texsample}, {"hlsl_cbuffers.h", cbuffers}, + }); uint32_t hash = strhash(source); hash = strhash(entry, hash); hash = strhash(profile, hash); - hash = strhash(includer.cbuffers.c_str(), hash); - hash = strhash(includer.texsample.c_str(), hash); + hash = strhash(cbuffers.c_str(), hash); + hash = strhash(texsample.c_str(), hash); hash ^= compileFlags; if(m_ShaderCache.find(hash) != m_ShaderCache.end()) @@ -217,7 +198,7 @@ ID3D11VertexShader *D3D11ShaderCache::MakeVShader(const char *source, const char { ID3DBlob *byteBlob = NULL; - if(GetShaderBlob(source, entry, D3DCOMPILE_WARNINGS_ARE_ERRORS, profile, &byteBlob) != "") + if(GetShaderBlob(source, entry, D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, profile, &byteBlob) != "") { RDCERR("Couldn't get shader blob for %s", entry); return NULL; @@ -265,7 +246,7 @@ ID3D11GeometryShader *D3D11ShaderCache::MakeGShader(const char *source, const ch { ID3DBlob *byteBlob = NULL; - if(GetShaderBlob(source, entry, D3DCOMPILE_WARNINGS_ARE_ERRORS, profile, &byteBlob) != "") + if(GetShaderBlob(source, entry, D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, profile, &byteBlob) != "") { return NULL; } @@ -293,7 +274,7 @@ ID3D11PixelShader *D3D11ShaderCache::MakePShader(const char *source, const char { ID3DBlob *byteBlob = NULL; - if(GetShaderBlob(source, entry, D3DCOMPILE_WARNINGS_ARE_ERRORS, profile, &byteBlob) != "") + if(GetShaderBlob(source, entry, D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, profile, &byteBlob) != "") { return NULL; } @@ -321,7 +302,7 @@ ID3D11ComputeShader *D3D11ShaderCache::MakeCShader(const char *source, const cha { ID3DBlob *byteBlob = NULL; - if(GetShaderBlob(source, entry, D3DCOMPILE_WARNINGS_ARE_ERRORS, profile, &byteBlob) != "") + if(GetShaderBlob(source, entry, D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, profile, &byteBlob) != "") { return NULL; } diff --git a/renderdoc/driver/d3d11/d3d11_shader_cache.h b/renderdoc/driver/d3d11/d3d11_shader_cache.h index 42844b676..258344f2a 100644 --- a/renderdoc/driver/d3d11/d3d11_shader_cache.h +++ b/renderdoc/driver/d3d11/d3d11_shader_cache.h @@ -38,7 +38,7 @@ public: ~D3D11ShaderCache(); rdcstr GetShaderBlob(const char *source, const char *entry, const uint32_t compileFlags, - const char *profile, ID3DBlob **srcblob); + const rdcarray &includeDirs, const char *profile, ID3DBlob **srcblob); ID3D11VertexShader *MakeVShader(const char *source, const char *entry, const char *profile, int numInputDescs = 0, D3D11_INPUT_ELEMENT_DESC *inputs = NULL, ID3D11InputLayout **ret = NULL, rdcarray *blob = NULL); diff --git a/renderdoc/driver/d3d12/d3d12_debug.cpp b/renderdoc/driver/d3d12/d3d12_debug.cpp index 206c8c988..4a086a511 100644 --- a/renderdoc/driver/d3d12/d3d12_debug.cpp +++ b/renderdoc/driver/d3d12/d3d12_debug.cpp @@ -272,38 +272,38 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper) rdcstr meshhlsl = GetEmbeddedResource(mesh_hlsl); shaderCache->GetShaderBlob(meshhlsl.c_str(), "RENDERDOC_MeshVS", D3DCOMPILE_WARNINGS_ARE_ERRORS, - "vs_5_0", &m_MeshVS); + {}, "vs_5_0", &m_MeshVS); shaderCache->GetShaderBlob(meshhlsl.c_str(), "RENDERDOC_MeshGS", D3DCOMPILE_WARNINGS_ARE_ERRORS, - "gs_5_0", &m_MeshGS); + {}, "gs_5_0", &m_MeshGS); shaderCache->GetShaderBlob(meshhlsl.c_str(), "RENDERDOC_MeshPS", D3DCOMPILE_WARNINGS_ARE_ERRORS, - "ps_5_0", &m_MeshPS); + {}, "ps_5_0", &m_MeshPS); } { rdcstr hlsl = GetEmbeddedResource(misc_hlsl); shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_FullscreenVS", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "vs_5_0", &m_FullscreenVS); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "vs_5_0", &m_FullscreenVS); shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_DiscardPS", D3DCOMPILE_WARNINGS_ARE_ERRORS, - "ps_5_0", &m_DiscardPS); + {}, "ps_5_0", &m_DiscardPS); } { rdcstr multisamplehlsl = GetEmbeddedResource(multisample_hlsl); shaderCache->GetShaderBlob(multisamplehlsl.c_str(), "RENDERDOC_CopyMSToArray", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "ps_5_0", &m_IntMS2Array); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "ps_5_0", &m_IntMS2Array); shaderCache->GetShaderBlob(multisamplehlsl.c_str(), "RENDERDOC_FloatCopyMSToArray", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "ps_5_0", &m_FloatMS2Array); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "ps_5_0", &m_FloatMS2Array); shaderCache->GetShaderBlob(multisamplehlsl.c_str(), "RENDERDOC_DepthCopyMSToArray", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "ps_5_0", &m_DepthMS2Array); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "ps_5_0", &m_DepthMS2Array); shaderCache->GetShaderBlob(multisamplehlsl.c_str(), "RENDERDOC_CopyArrayToMS", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "ps_5_0", &m_IntArray2MS); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "ps_5_0", &m_IntArray2MS); shaderCache->GetShaderBlob(multisamplehlsl.c_str(), "RENDERDOC_FloatCopyArrayToMS", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "ps_5_0", &m_FloatArray2MS); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "ps_5_0", &m_FloatArray2MS); shaderCache->GetShaderBlob(multisamplehlsl.c_str(), "RENDERDOC_DepthCopyArrayToMS", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "ps_5_0", &m_DepthArray2MS); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "ps_5_0", &m_DepthArray2MS); } shaderCache->SetCaching(false); @@ -499,7 +499,7 @@ bool D3D12DebugManager::CreateMathIntrinsicsResources() ID3DBlob *csBlob = NULL; UINT flags = D3DCOMPILE_DEBUG | D3DCOMPILE_WARNINGS_ARE_ERRORS; - if(m_pDevice->GetShaderCache()->GetShaderBlob(csProgram.c_str(), "main", flags, "cs_5_0", + if(m_pDevice->GetShaderCache()->GetShaderBlob(csProgram.c_str(), "main", flags, {}, "cs_5_0", &csBlob) != "") { RDCERR("Failed to create shader to calculate math intrinsic"); @@ -1406,9 +1406,9 @@ void D3D12Replay::GeneralMisc::Init(WrappedID3D12Device *device, D3D12DebugManag ID3DBlob *CheckerboardPS = NULL; shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_FullscreenVS", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "vs_5_0", &FullscreenVS); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "vs_5_0", &FullscreenVS); shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_CheckerboardPS", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "ps_5_0", &CheckerboardPS); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "ps_5_0", &CheckerboardPS); RDCASSERT(CheckerboardPS); RDCASSERT(FullscreenVS); @@ -1538,11 +1538,11 @@ void D3D12Replay::TextureRendering::Init(WrappedID3D12Device *device, D3D12Debug ID3DBlob *TexDisplayPS = NULL; shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_TexDisplayVS", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "vs_5_0", &VS); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "vs_5_0", &VS); RDCASSERT(VS); shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_TexDisplayPS", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "ps_5_0", &TexDisplayPS); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "ps_5_0", &TexDisplayPS); RDCASSERT(TexDisplayPS); D3D12_GRAPHICS_PIPELINE_STATE_DESC pipeDesc = {}; @@ -1628,13 +1628,13 @@ void D3D12Replay::TextureRendering::Init(WrappedID3D12Device *device, D3D12Debug }; shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_TexRemapFloat", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "ps_5_0", &TexRemap[0]); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "ps_5_0", &TexRemap[0]); RDCASSERT(TexRemap[0]); shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_TexRemapUInt", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "ps_5_0", &TexRemap[1]); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "ps_5_0", &TexRemap[1]); RDCASSERT(TexRemap[1]); shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_TexRemapSInt", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "ps_5_0", &TexRemap[2]); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "ps_5_0", &TexRemap[2]); RDCASSERT(TexRemap[2]); for(int f = 0; f < 3; f++) @@ -1699,24 +1699,25 @@ void D3D12Replay::OverlayRendering::Init(WrappedID3D12Device *device, D3D12Debug rdcstr meshhlsl = GetEmbeddedResource(mesh_hlsl); shaderCache->GetShaderBlob(meshhlsl.c_str(), "RENDERDOC_TriangleSizeGS", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "gs_5_0", &TriangleSizeGS); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "gs_5_0", &TriangleSizeGS); shaderCache->GetShaderBlob(meshhlsl.c_str(), "RENDERDOC_TriangleSizePS", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "ps_5_0", &TriangleSizePS); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "ps_5_0", &TriangleSizePS); shaderCache->GetShaderBlob(meshhlsl.c_str(), "RENDERDOC_MeshVS", D3DCOMPILE_WARNINGS_ARE_ERRORS, - "vs_5_0", &MeshVS); + {}, "vs_5_0", &MeshVS); rdcstr hlsl = GetEmbeddedResource(quadoverdraw_hlsl); shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_QuadOverdrawPS", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "ps_5_0", &QuadOverdrawWritePS); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "ps_5_0", &QuadOverdrawWritePS); // only create DXIL shaders if DXIL was used by the application, since dxc/dxcompiler is really // flakey. if(device->UsedDXIL()) { shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_QuadOverdrawPS", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "ps_6_0", &QuadOverdrawWriteDXILPS); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "ps_6_0", + &QuadOverdrawWriteDXILPS); if(QuadOverdrawWriteDXILPS == NULL) { @@ -1752,14 +1753,14 @@ void D3D12Replay::OverlayRendering::Init(WrappedID3D12Device *device, D3D12Debug ID3DBlob *FullscreenVS = NULL; shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_FullscreenVS", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "vs_5_0", &FullscreenVS); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "vs_5_0", &FullscreenVS); RDCASSERT(FullscreenVS); hlsl = GetEmbeddedResource(quadoverdraw_hlsl); ID3DBlob *QOResolvePS = NULL; shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_QOResolvePS", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "ps_5_0", &QOResolvePS); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "ps_5_0", &QOResolvePS); RDCASSERT(QOResolvePS); D3D12_GRAPHICS_PIPELINE_STATE_DESC pipeDesc = {}; @@ -1858,7 +1859,7 @@ void D3D12Replay::VertexPicking::Init(WrappedID3D12Device *device, D3D12DebugMan ID3DBlob *meshPickCS; shaderCache->GetShaderBlob(meshhlsl.c_str(), "RENDERDOC_MeshPickCS", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "cs_5_0", &meshPickCS); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "cs_5_0", &meshPickCS); RDCASSERT(meshPickCS); @@ -2050,7 +2051,7 @@ void D3D12Replay::HistogramMinMax::Init(WrappedID3D12Device *device, D3D12DebugM hlsl += histogramhlsl; shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_TileMinMaxCS", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "cs_5_0", &tile); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "cs_5_0", &tile); compPipeDesc.CS.BytecodeLength = tile->GetBufferSize(); compPipeDesc.CS.pShaderBytecode = tile->GetBufferPointer(); @@ -2064,7 +2065,7 @@ void D3D12Replay::HistogramMinMax::Init(WrappedID3D12Device *device, D3D12DebugM } shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_HistogramCS", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "cs_5_0", &histogram); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "cs_5_0", &histogram); compPipeDesc.CS.BytecodeLength = histogram->GetBufferSize(); compPipeDesc.CS.pShaderBytecode = histogram->GetBufferPointer(); @@ -2080,7 +2081,7 @@ void D3D12Replay::HistogramMinMax::Init(WrappedID3D12Device *device, D3D12DebugM if(t == 1) { shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_ResultMinMaxCS", - D3DCOMPILE_WARNINGS_ARE_ERRORS, "cs_5_0", &result); + D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "cs_5_0", &result); compPipeDesc.CS.BytecodeLength = result->GetBufferSize(); compPipeDesc.CS.pShaderBytecode = result->GetBufferPointer(); diff --git a/renderdoc/driver/d3d12/d3d12_rendertext.cpp b/renderdoc/driver/d3d12/d3d12_rendertext.cpp index 173113359..6f66d3879 100644 --- a/renderdoc/driver/d3d12/d3d12_rendertext.cpp +++ b/renderdoc/driver/d3d12/d3d12_rendertext.cpp @@ -363,9 +363,9 @@ D3D12TextRenderer::D3D12TextRenderer(WrappedID3D12Device *wrapper) ID3DBlob *TextVS = NULL; ID3DBlob *TextPS = NULL; - shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_TextVS", D3DCOMPILE_WARNINGS_ARE_ERRORS, + shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_TextVS", D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "vs_5_0", &TextVS); - shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_TextPS", D3DCOMPILE_WARNINGS_ARE_ERRORS, + shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_TextPS", D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "ps_5_0", &TextPS); RDCASSERT(TextVS); diff --git a/renderdoc/driver/d3d12/d3d12_replay.cpp b/renderdoc/driver/d3d12/d3d12_replay.cpp index 9902f6db0..c41f6da8d 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.cpp +++ b/renderdoc/driver/d3d12/d3d12_replay.cpp @@ -2878,7 +2878,8 @@ rdcarray D3D12Replay::GetDebugMessages() void D3D12Replay::BuildShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry, const ShaderCompileFlags &compileFlags, - ShaderStage type, ResourceId &id, rdcstr &errors) + const rdcarray &includeDirs, ShaderStage type, ResourceId &id, + rdcstr &errors) { bytebuf compiledDXBC; @@ -2911,13 +2912,13 @@ void D3D12Replay::BuildShader(ShaderEncoding sourceEncoding, const bytebuf &sour ID3DBlob *blob = NULL; errors = m_pDevice->GetShaderCache()->GetShaderBlob(hlsl.c_str(), entry.c_str(), compileFlags, - profile.c_str(), &blob); + includeDirs, profile.c_str(), &blob); if(m_D3D12On7 && blob == NULL && errors.contains("unrecognized compiler target")) { profile.back() = '0'; errors = m_pDevice->GetShaderCache()->GetShaderBlob(hlsl.c_str(), entry.c_str(), compileFlags, - profile.c_str(), &blob); + includeDirs, profile.c_str(), &blob); } if(blob == NULL) @@ -2952,7 +2953,7 @@ void D3D12Replay::BuildTargetShader(ShaderEncoding sourceEncoding, const bytebuf ShaderCompileFlags debugCompileFlags = DXBC::EncodeFlags( DXBC::DecodeFlags(compileFlags) | D3DCOMPILE_DEBUG, DXBC::GetProfile(compileFlags)); - BuildShader(sourceEncoding, source, entry, debugCompileFlags, type, id, errors); + BuildShader(sourceEncoding, source, entry, debugCompileFlags, {}, type, id, errors); } void D3D12Replay::ReplaceResource(ResourceId from, ResourceId to) @@ -3711,11 +3712,16 @@ void D3D12Replay::GetTextureData(ResourceId tex, const Subresource &sub, SAFE_RELEASE(tmpTexture); } +void D3D12Replay::SetCustomShaderIncludes(const rdcarray &directories) +{ + m_CustomShaderIncludes = directories; +} + void D3D12Replay::BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id, rdcstr &errors) { - BuildShader(sourceEncoding, source, entry, compileFlags, type, id, errors); + BuildShader(sourceEncoding, source, entry, compileFlags, m_CustomShaderIncludes, type, id, errors); } ResourceId D3D12Replay::ApplyCustomShader(ResourceId shader, ResourceId texid, diff --git a/renderdoc/driver/d3d12/d3d12_replay.h b/renderdoc/driver/d3d12/d3d12_replay.h index 5aaae90d1..0b3e1b784 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.h +++ b/renderdoc/driver/d3d12/d3d12_replay.h @@ -202,6 +202,7 @@ public: ResourceId RenderOverlay(ResourceId texid, FloatVector clearCol, DebugOverlay overlay, uint32_t eventId, const rdcarray &passEvents); + void SetCustomShaderIncludes(const rdcarray &directories); void BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id, rdcstr &errors); @@ -225,8 +226,8 @@ private: void RefreshDerivedReplacements(); void BuildShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry, - const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id, - rdcstr &errors); + const ShaderCompileFlags &compileFlags, const rdcarray &includeDirs, + ShaderStage type, ResourceId &id, rdcstr &errors); bool RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, TextureDisplay cfg, TexDisplayFlags flags); @@ -438,6 +439,8 @@ private: D3D12AMDDrawCallback *m_pAMDDrawCallback = NULL; + rdcarray m_CustomShaderIncludes; + void FillTimersAMD(uint32_t *eventStartID, uint32_t *sampleIndex, rdcarray *eventIDs); rdcarray FetchCountersAMD(const rdcarray &counters); diff --git a/renderdoc/driver/d3d12/d3d12_shader_cache.cpp b/renderdoc/driver/d3d12/d3d12_shader_cache.cpp index 17a2b0f2b..b9c9d3913 100644 --- a/renderdoc/driver/d3d12/d3d12_shader_cache.cpp +++ b/renderdoc/driver/d3d12/d3d12_shader_cache.cpp @@ -27,6 +27,7 @@ #include "core/plugins.h" #include "driver/dx/official/d3dcompiler.h" #include "driver/dx/official/dxcapi.h" +#include "driver/dxgi/dxgi_common.h" #include "driver/shaders/dxbc/dxbc_container.h" #include "strings/string_utils.h" @@ -274,33 +275,6 @@ struct D3D12BlobShaderCallbacks const byte *GetData(ID3DBlob *blob) const { return (const byte *)blob->GetBufferPointer(); } } D3D12ShaderCacheCallbacks; -struct EmbeddedD3D12Includer : public ID3DInclude -{ - rdcstr texsample = GetEmbeddedResource(hlsl_texsample_h); - rdcstr cbuffers = GetEmbeddedResource(hlsl_cbuffers_h); - - virtual HRESULT STDMETHODCALLTYPE Open(D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, - LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) override - { - rdcstr *str; - - if(!strcmp(pFileName, "hlsl_texsample.h")) - str = &texsample; - else if(!strcmp(pFileName, "hlsl_cbuffers.h")) - str = &cbuffers; - else - return E_FAIL; - - if(ppData) - *ppData = str->c_str(); - if(pBytes) - *pBytes = (uint32_t)str->size(); - - return S_OK; - } - virtual HRESULT STDMETHODCALLTYPE Close(LPCVOID pData) override { return S_OK; } -}; - D3D12ShaderCache::D3D12ShaderCache() { bool success = LoadShaderCache("d3dshaders.cache", m_ShaderCacheMagic, m_ShaderCacheVersion, @@ -325,16 +299,23 @@ D3D12ShaderCache::~D3D12ShaderCache() } rdcstr D3D12ShaderCache::GetShaderBlob(const char *source, const char *entry, - const ShaderCompileFlags &compileFlags, const char *profile, + const ShaderCompileFlags &compileFlags, + const rdcarray &includeDirs, const char *profile, ID3DBlob **srcblob) { - EmbeddedD3D12Includer includer; + rdcstr cbuffers = GetEmbeddedResource(hlsl_cbuffers_h); + rdcstr texsample = GetEmbeddedResource(hlsl_texsample_h); + + EmbeddedD3DIncluder includer(includeDirs, + { + {"hlsl_texsample.h", texsample}, {"hlsl_cbuffers.h", cbuffers}, + }); uint32_t hash = strhash(source); hash = strhash(entry, hash); hash = strhash(profile, hash); - hash = strhash(includer.cbuffers.c_str(), hash); - hash = strhash(includer.texsample.c_str(), hash); + hash = strhash(cbuffers.c_str(), hash); + hash = strhash(texsample.c_str(), hash); for(const ShaderCompileFlag &f : compileFlags.flags) { hash = strhash(f.name.c_str(), hash); @@ -512,9 +493,11 @@ rdcstr D3D12ShaderCache::GetShaderBlob(const char *source, const char *entry, } rdcstr D3D12ShaderCache::GetShaderBlob(const char *source, const char *entry, uint32_t compileFlags, - const char *profile, ID3DBlob **srcblob) + const rdcarray &includeDirs, const char *profile, + ID3DBlob **srcblob) { - return GetShaderBlob(source, entry, DXBC::EncodeFlags(compileFlags, profile), profile, srcblob); + return GetShaderBlob(source, entry, DXBC::EncodeFlags(compileFlags, profile), includeDirs, + profile, srcblob); } D3D12RootSignature D3D12ShaderCache::GetRootSig(const void *data, size_t dataSize) @@ -806,7 +789,7 @@ ID3DBlob *D3D12ShaderCache::MakeFixedColShader(FixedColVariant variant, bool dxi StringFormat::Fmt("#define VARIANT %u\n\n", variant) + GetEmbeddedResource(fixedcol_hlsl); bool wasCaching = m_CacheShaders; m_CacheShaders = true; - GetShaderBlob(hlsl.c_str(), "main", ShaderCompileFlags(), dxil ? "ps_6_0" : "ps_5_0", &ret); + GetShaderBlob(hlsl.c_str(), "main", ShaderCompileFlags(), {}, dxil ? "ps_6_0" : "ps_5_0", &ret); m_CacheShaders = wasCaching; if(!ret) diff --git a/renderdoc/driver/d3d12/d3d12_shader_cache.h b/renderdoc/driver/d3d12/d3d12_shader_cache.h index e4b927c11..22051ecf9 100644 --- a/renderdoc/driver/d3d12/d3d12_shader_cache.h +++ b/renderdoc/driver/d3d12/d3d12_shader_cache.h @@ -39,9 +39,9 @@ public: ~D3D12ShaderCache(); rdcstr GetShaderBlob(const char *source, const char *entry, uint32_t compileFlags, - const char *profile, ID3DBlob **srcblob); + const rdcarray &includeDirs, const char *profile, ID3DBlob **srcblob); rdcstr GetShaderBlob(const char *source, const char *entry, const ShaderCompileFlags &compileFlags, - const char *profile, ID3DBlob **srcblob); + const rdcarray &includeDirs, const char *profile, ID3DBlob **srcblob); D3D12RootSignature GetRootSig(const void *data, size_t dataSize); ID3DBlob *MakeRootSig(const rdcarray ¶ms, diff --git a/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp b/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp index 42b376482..33fae47ab 100644 --- a/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp +++ b/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp @@ -1561,13 +1561,13 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather( ID3DBlob *vsBlob = NULL; ID3DBlob *psBlob = NULL; UINT flags = D3DCOMPILE_DEBUG | D3DCOMPILE_WARNINGS_ARE_ERRORS; - if(m_pDevice->GetShaderCache()->GetShaderBlob(vsProgram.c_str(), "main", flags, "vs_5_1", + if(m_pDevice->GetShaderCache()->GetShaderBlob(vsProgram.c_str(), "main", flags, {}, "vs_5_1", &vsBlob) != "") { RDCERR("Failed to create shader to extract inputs"); return false; } - if(m_pDevice->GetShaderCache()->GetShaderBlob(psProgram.c_str(), "main", flags, "ps_5_1", + if(m_pDevice->GetShaderCache()->GetShaderBlob(psProgram.c_str(), "main", flags, {}, "ps_5_1", &psBlob) != "") { RDCERR("Failed to create shader to extract inputs"); @@ -2521,7 +2521,7 @@ void ExtractInputsPS(PSInput IN, float4 debug_pixelPos : SV_Position, // Create pixel shader to get initial values from previous stage output ID3DBlob *psBlob = NULL; UINT flags = D3DCOMPILE_DEBUG | D3DCOMPILE_WARNINGS_ARE_ERRORS; - if(m_pDevice->GetShaderCache()->GetShaderBlob(extractHlsl.c_str(), "ExtractInputsPS", flags, + if(m_pDevice->GetShaderCache()->GetShaderBlob(extractHlsl.c_str(), "ExtractInputsPS", flags, {}, "ps_5_0", &psBlob) != "") { RDCERR("Failed to create shader to extract inputs"); diff --git a/renderdoc/driver/dxgi/dxgi_common.cpp b/renderdoc/driver/dxgi/dxgi_common.cpp index d85db1d86..6e2eb2790 100644 --- a/renderdoc/driver/dxgi/dxgi_common.cpp +++ b/renderdoc/driver/dxgi/dxgi_common.cpp @@ -1661,6 +1661,88 @@ void WarnUnknownGUID(const char *name, REFIID riid) } } +HRESULT STDMETHODCALLTYPE EmbeddedD3DIncluder::Open(D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, + LPCVOID pParentData, LPCVOID *ppData, + UINT *pBytes) +{ + const rdcstr *str = NULL; + + rdcstr filename = pFileName; + + for(const rdcpair &f : m_FixedFiles) + { + if(filename == f.first) + { + str = &f.second; + break; + } + } + + auto readFile = [this](rdcstr filename) { + rdcstr *filestr = new rdcstr; + FileIO::ReadAll(filename, *filestr); + m_FileStrings.push_back(filestr); + + // this will be used to look up by pParentData later + m_StringPaths[filestr->c_str()] = get_dirname(filename); + + return filestr; + }; + + // if it's an absolute path that exists, read it + if(!str && !FileIO::IsRelativePath(filename) && FileIO::exists(filename)) + { + str = readFile(filename); + } + + // if it's relative and we have a parent, check relative to the parent's file + if(!str && IncludeType == D3D_INCLUDE_LOCAL && pParentData) + { + auto it = m_StringPaths.find(pParentData); + if(it != m_StringPaths.end()) + { + rdcstr base = it->second; + filename = base + "/" + filename; + + if(FileIO::exists(filename)) + str = readFile(filename); + + // don't need to handle the else here, it becomes E_FAIL below which the compiler then throws + // an error for + } + else + { + RDCERR("Unrecognised parent file when opening %s", filename.c_str()); + } + } + + // if it's a system include, check relative to the include dirs + if(IncludeType == D3D_INCLUDE_SYSTEM && !m_IncludeDirs.empty()) + { + rdcstr fn = filename; + for(rdcstr base : m_IncludeDirs) + { + filename = base + "/" + fn; + + if(FileIO::exists(filename)) + { + str = readFile(filename); + break; + } + } + } + + if(!str) + return E_FAIL; + + if(ppData) + *ppData = str->c_str(); + if(pBytes) + *pBytes = (uint32_t)str->size(); + + return S_OK; +} + static rdcstr GetDeviceProperty(HDEVINFO devs, PSP_DEVINFO_DATA data, const DEVPROPKEY *key) { DEVPROPTYPE type = {}; diff --git a/renderdoc/driver/dxgi/dxgi_common.h b/renderdoc/driver/dxgi/dxgi_common.h index ea1228062..82a54857a 100644 --- a/renderdoc/driver/dxgi/dxgi_common.h +++ b/renderdoc/driver/dxgi/dxgi_common.h @@ -25,6 +25,7 @@ #pragma once #include "api/replay/data_types.h" +#include "api/replay/rdcflatmap.h" #include "api/replay/replay_enums.h" #include "api/replay/stringise.h" #include "driver/dx/official/d3dcommon.h" @@ -77,6 +78,33 @@ void ChooseBestMatchingAdapter(GraphicsAPI api, IDXGIFactory *factory, const DXGI_ADAPTER_DESC &AdapterDesc, const ReplayOptions &opts, bool *useWarp, IDXGIAdapter **adapter); +struct EmbeddedD3DIncluder : public ID3DInclude +{ +private: + rdcarray> m_FixedFiles; + rdcarray m_IncludeDirs; + + rdcarray m_FileStrings; + // use flatmap here to avoid pulling in the header in such a high-profile place + rdcflatmap m_StringPaths; + +public: + EmbeddedD3DIncluder(const rdcarray &includeDirs, + const rdcarray> &fixed_files) + : m_IncludeDirs(includeDirs), m_FixedFiles(fixed_files) + { + } + ~EmbeddedD3DIncluder() + { + for(rdcstr *s : m_FileStrings) + delete s; + } + virtual HRESULT STDMETHODCALLTYPE Open(D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, + LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) override; + // we just 'leak' all handles we don't track open/close at fine-grained detail. + virtual HRESULT STDMETHODCALLTYPE Close(LPCVOID pData) override { return S_OK; } +}; + DECLARE_REFLECTION_STRUCT(DXGI_SAMPLE_DESC); DECLARE_REFLECTION_STRUCT(DXGI_ADAPTER_DESC); DECLARE_REFLECTION_STRUCT(IID); diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index 1a0398bc7..17fe0980a 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -2990,6 +2990,10 @@ void GLReplay::GetTextureData(ResourceId tex, const Subresource &sub, drv.glDeleteTextures(1, &tempTex); } +void GLReplay::SetCustomShaderIncludes(const rdcarray &directories) +{ +} + void GLReplay::BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id, rdcstr &errors) diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index bba676f25..1d5de7990 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -203,6 +203,7 @@ public: void BuildTargetShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id, rdcstr &errors); + void SetCustomShaderIncludes(const rdcarray &directories); void BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id, rdcstr &errors); diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index 701b50473..97b6b7e37 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -3823,6 +3823,10 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub, } } +void VulkanReplay::SetCustomShaderIncludes(const rdcarray &directories) +{ +} + void VulkanReplay::BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id, rdcstr &errors) diff --git a/renderdoc/driver/vulkan/vk_replay.h b/renderdoc/driver/vulkan/vk_replay.h index cf1978e98..7a935f0a9 100644 --- a/renderdoc/driver/vulkan/vk_replay.h +++ b/renderdoc/driver/vulkan/vk_replay.h @@ -373,6 +373,7 @@ public: void BuildTargetShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id, rdcstr &errors); + void SetCustomShaderIncludes(const rdcarray &directories); void BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id, rdcstr &errors); diff --git a/renderdoc/replay/replay_controller.cpp b/renderdoc/replay/replay_controller.cpp index 4753d7889..fea439804 100644 --- a/renderdoc/replay/replay_controller.cpp +++ b/renderdoc/replay/replay_controller.cpp @@ -1912,6 +1912,13 @@ rdcpair ReplayController::BuildTargetShader( return rdcpair(id, errs); } +void ReplayController::SetCustomShaderIncludes(const rdcarray &directories) +{ + CHECK_REPLAY_THREAD(); + + m_pDevice->SetCustomShaderIncludes(directories); +} + rdcpair ReplayController::BuildCustomShader( const rdcstr &entry, ShaderEncoding sourceEncoding, bytebuf source, const ShaderCompileFlags &compileFlags, ShaderStage type) diff --git a/renderdoc/replay/replay_controller.h b/renderdoc/replay/replay_controller.h index 708060fa5..3aa4cc2ab 100644 --- a/renderdoc/replay/replay_controller.h +++ b/renderdoc/replay/replay_controller.h @@ -145,6 +145,7 @@ public: rdcarray GetDisassemblyTargets(bool withPipeline); rdcstr DisassembleShader(ResourceId pipeline, const ShaderReflection *refl, const rdcstr &target); + void SetCustomShaderIncludes(const rdcarray &directories); rdcpair BuildCustomShader(const rdcstr &entry, ShaderEncoding sourceEncoding, bytebuf source, const ShaderCompileFlags &compileFlags, diff --git a/renderdoc/replay/replay_driver.h b/renderdoc/replay/replay_driver.h index 5b2b874fe..ceccd9c23 100644 --- a/renderdoc/replay/replay_driver.h +++ b/renderdoc/replay/replay_driver.h @@ -263,6 +263,7 @@ public: const MeshDisplay &cfg) = 0; virtual bool RenderTexture(TextureDisplay cfg) = 0; + virtual void SetCustomShaderIncludes(const rdcarray &directories) = 0; virtual void BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id, rdcstr &errors) = 0;