Add support for file includes from custom shaders. Closes #2275

This commit is contained in:
baldurk
2021-05-17 13:47:58 +01:00
parent 331db5b4ba
commit d8d6557feb
24 changed files with 265 additions and 121 deletions
+11 -1
View File
@@ -4326,12 +4326,22 @@ void TextureViewer::reloadCustomShaders(const QString &filter)
fileHandle.close();
rdcarray<rdcstr> 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);
+13
View File
@@ -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<rdcstr> &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.
+4
View File
@@ -169,6 +169,10 @@ public:
{
return m_Proxy->GetCustomShaderEncodings();
}
void SetCustomShaderIncludes(const rdcarray<rdcstr> &directories)
{
m_Proxy->SetCustomShaderIncludes(directories);
}
void BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry,
const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id,
rdcstr &errors)
+5
View File
@@ -405,6 +405,11 @@ public:
return ~0U;
}
void SetCustomShaderIncludes(const rdcarray<rdcstr> &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)
+10 -4
View File
@@ -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<rdcstr> &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<rdcstr> &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)
+5 -2
View File
@@ -247,6 +247,7 @@ public:
ResourceId RenderOverlay(ResourceId texid, FloatVector clearCol, DebugOverlay overlay,
uint32_t eventId, const rdcarray<uint32_t> &passEvents);
void SetCustomShaderIncludes(const rdcarray<rdcstr> &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<rdcstr> &includeDirs,
ShaderStage type, ResourceId &id, rdcstr &errors);
void ClearPostVSCache();
@@ -332,6 +333,8 @@ private:
WrappedID3D11Device *m_pDevice = NULL;
WrappedID3D11DeviceContext *m_pImmediateContext = NULL;
rdcarray<rdcstr> m_CustomShaderIncludes;
// used to track the real state so we can preserve it even across work done to the output windows
struct RealState
{
+16 -35
View File
@@ -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<rdcstr> &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;
}
+1 -1
View File
@@ -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<rdcstr> &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<byte> *blob = NULL);
+31 -30
View File
@@ -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();
+2 -2
View File
@@ -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);
+11 -5
View File
@@ -2878,7 +2878,8 @@ rdcarray<DebugMessage> D3D12Replay::GetDebugMessages()
void D3D12Replay::BuildShader(ShaderEncoding sourceEncoding, const bytebuf &source,
const rdcstr &entry, const ShaderCompileFlags &compileFlags,
ShaderStage type, ResourceId &id, rdcstr &errors)
const rdcarray<rdcstr> &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<rdcstr> &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,
+5 -2
View File
@@ -202,6 +202,7 @@ public:
ResourceId RenderOverlay(ResourceId texid, FloatVector clearCol, DebugOverlay overlay,
uint32_t eventId, const rdcarray<uint32_t> &passEvents);
void SetCustomShaderIncludes(const rdcarray<rdcstr> &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<rdcstr> &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<rdcstr> m_CustomShaderIncludes;
void FillTimersAMD(uint32_t *eventStartID, uint32_t *sampleIndex, rdcarray<uint32_t> *eventIDs);
rdcarray<CounterResult> FetchCountersAMD(const rdcarray<GPUCounter> &counters);
+17 -34
View File
@@ -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<rdcstr> &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<rdcstr> &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)
+2 -2
View File
@@ -39,9 +39,9 @@ public:
~D3D12ShaderCache();
rdcstr GetShaderBlob(const char *source, const char *entry, uint32_t compileFlags,
const char *profile, ID3DBlob **srcblob);
const rdcarray<rdcstr> &includeDirs, const char *profile, ID3DBlob **srcblob);
rdcstr GetShaderBlob(const char *source, const char *entry, const ShaderCompileFlags &compileFlags,
const char *profile, ID3DBlob **srcblob);
const rdcarray<rdcstr> &includeDirs, const char *profile, ID3DBlob **srcblob);
D3D12RootSignature GetRootSig(const void *data, size_t dataSize);
ID3DBlob *MakeRootSig(const rdcarray<D3D12_ROOT_PARAMETER1> &params,
+3 -3
View File
@@ -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");
+82
View File
@@ -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<rdcstr, rdcstr> &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 = {};
+28
View File
@@ -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<rdcpair<rdcstr, rdcstr>> m_FixedFiles;
rdcarray<rdcstr> m_IncludeDirs;
rdcarray<rdcstr *> m_FileStrings;
// use flatmap here to avoid pulling in the <map> header in such a high-profile place
rdcflatmap<const void *, rdcstr> m_StringPaths;
public:
EmbeddedD3DIncluder(const rdcarray<rdcstr> &includeDirs,
const rdcarray<rdcpair<rdcstr, rdcstr>> &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);
+4
View File
@@ -2990,6 +2990,10 @@ void GLReplay::GetTextureData(ResourceId tex, const Subresource &sub,
drv.glDeleteTextures(1, &tempTex);
}
void GLReplay::SetCustomShaderIncludes(const rdcarray<rdcstr> &directories)
{
}
void GLReplay::BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source,
const rdcstr &entry, const ShaderCompileFlags &compileFlags,
ShaderStage type, ResourceId &id, rdcstr &errors)
+1
View File
@@ -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<rdcstr> &directories);
void BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry,
const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id,
rdcstr &errors);
+4
View File
@@ -3823,6 +3823,10 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
}
}
void VulkanReplay::SetCustomShaderIncludes(const rdcarray<rdcstr> &directories)
{
}
void VulkanReplay::BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source,
const rdcstr &entry, const ShaderCompileFlags &compileFlags,
ShaderStage type, ResourceId &id, rdcstr &errors)
+1
View File
@@ -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<rdcstr> &directories);
void BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry,
const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id,
rdcstr &errors);
+7
View File
@@ -1912,6 +1912,13 @@ rdcpair<ResourceId, rdcstr> ReplayController::BuildTargetShader(
return rdcpair<ResourceId, rdcstr>(id, errs);
}
void ReplayController::SetCustomShaderIncludes(const rdcarray<rdcstr> &directories)
{
CHECK_REPLAY_THREAD();
m_pDevice->SetCustomShaderIncludes(directories);
}
rdcpair<ResourceId, rdcstr> ReplayController::BuildCustomShader(
const rdcstr &entry, ShaderEncoding sourceEncoding, bytebuf source,
const ShaderCompileFlags &compileFlags, ShaderStage type)
+1
View File
@@ -145,6 +145,7 @@ public:
rdcarray<rdcstr> GetDisassemblyTargets(bool withPipeline);
rdcstr DisassembleShader(ResourceId pipeline, const ShaderReflection *refl, const rdcstr &target);
void SetCustomShaderIncludes(const rdcarray<rdcstr> &directories);
rdcpair<ResourceId, rdcstr> BuildCustomShader(const rdcstr &entry, ShaderEncoding sourceEncoding,
bytebuf source,
const ShaderCompileFlags &compileFlags,
+1
View File
@@ -263,6 +263,7 @@ public:
const MeshDisplay &cfg) = 0;
virtual bool RenderTexture(TextureDisplay cfg) = 0;
virtual void SetCustomShaderIncludes(const rdcarray<rdcstr> &directories) = 0;
virtual void BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source,
const rdcstr &entry, const ShaderCompileFlags &compileFlags,
ShaderStage type, ResourceId &id, rdcstr &errors) = 0;