Store and lookup shader data for aftermath dumps

This commit is contained in:
baldurk
2026-02-16 15:45:13 +00:00
parent edbcd6d592
commit d1ec8ad622
5 changed files with 72 additions and 14 deletions
@@ -27,6 +27,7 @@
#include "driver/dxgi/dxgi_common.h"
#include "driver/ihv/amd/official/DXExt/AmdExtD3D.h"
#include "driver/ihv/amd/official/DXExt/AmdExtD3DCommandListMarkerApi.h"
#include "driver/ihv/nv/nv_aftermath.h"
#include "d3d12_command_list.h"
#include "d3d12_command_queue.h"
#include "d3d12_replay.h"
@@ -596,6 +597,9 @@ bool WrappedID3D12Device::Serialise_CreateGraphicsPipelineState(
WrappedID3D12Shader::AddShader(InlineShaderIDs[i], *shaders[i], this);
entry->AddRef();
NVAftermath_Shader(ShaderEncoding::DXBC, shaders[i]->pShaderBytecode,
shaders[i]->BytecodeLength);
shaders[i]->pShaderBytecode = entry;
if(m_GlobalEXTUAV != ~0U)
@@ -894,6 +898,9 @@ bool WrappedID3D12Device::Serialise_CreateComputePipelineState(
WrappedID3D12Shader::AddShader(InlineShaderID, wrapped->compute->CS, this);
entry->AddRef();
NVAftermath_Shader(ShaderEncoding::DXBC, wrapped->compute->CS.pShaderBytecode,
wrapped->compute->CS.BytecodeLength);
if(m_GlobalEXTUAV != ~0U)
entry->SetShaderExtSlot(m_GlobalEXTUAV, m_GlobalEXTUAVSpace);
@@ -25,6 +25,7 @@
#include "d3d12_device.h"
#include "core/settings.h"
#include "driver/dxgi/dxgi_common.h"
#include "driver/ihv/nv/nv_aftermath.h"
#include "d3d12_resources.h"
RDOC_EXTERN_CONFIG(bool, Replay_Debug_SingleThreadedCompilation);
@@ -164,6 +165,9 @@ bool WrappedID3D12Device::Serialise_CreatePipelineState(SerialiserType &ser,
WrappedID3D12Shader::AddShader(InlineShaderIDs[i], *shaders[i], this);
entry->AddRef();
NVAftermath_Shader(ShaderEncoding::DXBC, shaders[i]->pShaderBytecode,
shaders[i]->BytecodeLength);
shaders[i]->pShaderBytecode = entry;
if(m_GlobalEXTUAV != ~0U)
+55 -14
View File
@@ -24,6 +24,7 @@
#include "nv_aftermath.h"
#include <map>
#include <unordered_map>
#include "common/formatting.h"
#include "common/threading.h"
@@ -46,6 +47,8 @@ RDOC_CONFIG(bool, Replay_Debug_EnableNVRTValidation, false,
#endif
#include "driver/vulkan/official/vulkan.h"
#include "driver/ihv/nv/official/aftermath/GFSDK_Aftermath.h"
#include "driver/ihv/nv/official/aftermath/GFSDK_Aftermath_GpuCrashDump.h"
#include "driver/ihv/nv/official/aftermath/GFSDK_Aftermath_GpuCrashDumpDecoding.h"
@@ -55,8 +58,6 @@ RDOC_CONFIG(bool, Replay_Debug_EnableNVRTValidation, false,
#include "official/nvapi/nvapi.h"
#include "driver/vulkan/official/vulkan_core.h"
namespace
{
#include "official/nvapi/nvapi_interface.h"
@@ -78,12 +79,14 @@ typedef void *(*PFN_nvapi_QueryInterface)(NvU32 id);
namespace
{
#define AFTERMATH_FUNCS(x) \
x(DX12_Initialize); \
x(DisableGpuCrashDumps); \
x(EnableGpuCrashDumps); \
x(GetCrashDumpStatus); \
x(GetShaderDebugInfoIdentifier);
#define AFTERMATH_FUNCS(x) \
x(DX12_Initialize); \
x(DisableGpuCrashDumps); \
x(EnableGpuCrashDumps); \
x(GetCrashDumpStatus); \
x(GetShaderDebugInfoIdentifier); \
x(GetShaderHashSpirv); \
x(GetShaderHash);
struct aftermath_table
{
@@ -105,24 +108,39 @@ struct aftermath_table
aftermath_table table = {};
uint32_t dumpNumber = 0;
std::unordered_map<uint64_t, bytebuf> spvShaders;
std::unordered_map<uint64_t, bytebuf> dxShaders;
void GpuCrashDumpCallback(const void *pGpuCrashDump, const uint32_t gpuCrashDumpSize, void *)
{
FileIO::WriteAll(StringFormat::sntimef(Timing::GetUTCTime(), "aftermath_dump-%y%m%d%H%M%S-") +
StringFormat::Fmt("%u-%u.nv-gpudmp", Process::GetCurrentPID(), dumpNumber++),
pGpuCrashDump, gpuCrashDumpSize);
rdcstr outName = StringFormat::sntimef(Timing::GetUTCTime(), "aftermath_dump-%y%m%d%H%M%S-") +
StringFormat::Fmt("%u-%u", Process::GetCurrentPID(), dumpNumber++);
FileIO::WriteAll(outName + ".nv-gpudmp", pGpuCrashDump, gpuCrashDumpSize);
}
void GpuShaderDebugInfoCallback(const void *pShaderDebugInfo, const uint32_t shaderDebugInfoSize,
void *)
{
RDCLOG("shader info %p %zu", pShaderDebugInfo, shaderDebugInfoSize);
GFSDK_Aftermath_ShaderDebugInfoIdentifier ident;
table.GetShaderDebugInfoIdentifier(GFSDK_Aftermath_Version_API, pShaderDebugInfo,
shaderDebugInfoSize, &ident);
FileIO::WriteAll(StringFormat::Fmt("shader-%08x-%08x.nvdbg", ident.id[0], ident.id[1]),
FileIO::WriteAll(StringFormat::Fmt("shader-%016llx-%016llx.nvdbg", ident.id[0], ident.id[1]),
pShaderDebugInfo, shaderDebugInfoSize);
{
auto it = spvShaders.find(ident.id[0]);
if(it != spvShaders.end())
FileIO::WriteAll(StringFormat::Fmt("shader-%016llx.spv", ident.id[0]), it->second.data(),
it->second.size());
}
{
auto it = dxShaders.find(ident.id[0]);
if(it != dxShaders.end())
FileIO::WriteAll(StringFormat::Fmt("shader-%016llx.cso", ident.id[0]), it->second.data(),
it->second.size());
}
}
void DescriptionCB(PFN_GFSDK_Aftermath_AddGpuCrashDumpDescription addDescription, void *pUserData)
@@ -187,6 +205,25 @@ void NVAftermath_Init()
}
// on shutdown we could call GFSDK_Aftermath_DisableGpuCrashDumps
void NVAftermath_Shader(ShaderEncoding encoding, const void *shader, size_t len)
{
GFSDK_Aftermath_ShaderBinaryHash shaderHash;
if(encoding == ShaderEncoding::SPIRV && table.GetShaderHashSpirv)
{
GFSDK_Aftermath_SpirvCode spv_data = {shader, (uint32_t)len};
table.GetShaderHashSpirv(GFSDK_Aftermath_Version_API, &spv_data, &shaderHash);
spvShaders[shaderHash.hash] = bytebuf((const byte *)shader, len);
}
else if(table.GetShaderHash)
{
D3D12_SHADER_BYTECODE shad_data = {shader, (uint32_t)len};
table.GetShaderHash(GFSDK_Aftermath_Version_API, &shad_data, &shaderHash);
dxShaders[shaderHash.hash] = bytebuf((const byte *)shader, len);
}
}
void NVAftermath_EnableVK(const std::set<rdcstr> &supportedExtensions, rdcarray<rdcstr> &Extensions,
const void **deviceCreateNext)
@@ -463,6 +500,10 @@ void NVAftermath_Init()
}
}
void NVAftermath_Shader(ShaderEncoding encoding, const void *shader, size_t len)
{
}
void NVAftermath_EnableVK(const std::set<rdcstr> &supportedExtensions, rdcarray<rdcstr> &Extensions,
const void **deviceCreateNext)
{
+1
View File
@@ -34,5 +34,6 @@ void NVAftermath_Init();
void NVAftermath_EnableVK(const std::set<rdcstr> &supportedExtensions, rdcarray<rdcstr> &Extensions,
const void **deviceCreateNext);
void NVAftermath_EnableD3D12(ID3D12Device *dev);
void NVAftermath_Shader(ShaderEncoding encoding, const void *shader, size_t len);
void NVAftermath_DumpCrash();
void NVAftermath_DumpRTValidation(ID3D12Device5 *dev5);
@@ -25,6 +25,7 @@
#include "../vk_core.h"
#include "../vk_replay.h"
#include "core/settings.h"
#include "driver/ihv/nv/nv_aftermath.h"
#include "driver/shaders/spirv/spirv_reflect.h"
RDOC_EXTERN_CONFIG(bool, Replay_Debug_SingleThreadedCompilation);
@@ -401,6 +402,8 @@ bool WrappedVulkan::Serialise_vkCreateShaderModule(SerialiserType &ser, VkDevice
VkShaderModuleCreateInfo patched = CreateInfo;
NVAftermath_Shader(ShaderEncoding::SPIRV, CreateInfo.pCode, CreateInfo.codeSize);
byte *tempMem = GetTempMemory(GetNextPatchSize(patched.pNext));
UnwrapNextChain(m_State, "VkShaderModuleCreateInfo", tempMem, (VkBaseInStructure *)&patched);
@@ -698,6 +701,8 @@ VkShaderModule WrappedVulkan::CreateFakeInlineShaderModule(ResourceId id, VkDevi
{
RDCASSERT(IsLoading(m_State));
NVAftermath_Shader(ShaderEncoding::SPIRV, pCreateInfo->pCode, pCreateInfo->codeSize);
VkShaderModule module = VK_NULL_HANDLE;
VkResult ret = ObjDisp(device)->CreateShaderModule(Unwrap(device), pCreateInfo, NULL, &module);