Add debug name for PSO catching on D3D12/Vulkan during profiling incl. Development builds
This commit is contained in:
@@ -75,10 +75,39 @@ GPUPipelineState::GPUPipelineState()
|
||||
{
|
||||
}
|
||||
|
||||
#if !BUILD_RELEASE
|
||||
|
||||
void GPUPipelineState::GetDebugName(DebugName& name) const
|
||||
{
|
||||
#define GET_NAME(e) \
|
||||
if (DebugDesc.e) \
|
||||
{ \
|
||||
GPUShaderProgram::DebugName n; \
|
||||
DebugDesc.e->GetDebugName(n); \
|
||||
name.Add(n.Get(), n.Count() - 1); \
|
||||
name.Add('+'); \
|
||||
}
|
||||
GET_NAME(VS);
|
||||
#if GPU_ALLOW_TESSELLATION_SHADERS
|
||||
GET_NAME(HS);
|
||||
GET_NAME(DS);
|
||||
#endif
|
||||
#if GPU_ALLOW_GEOMETRY_SHADERS
|
||||
GET_NAME(GS);
|
||||
#endif
|
||||
GET_NAME(PS);
|
||||
#undef GET_NAME
|
||||
if (name.Count() != 0 && name[name.Count() - 1] == '+')
|
||||
name.RemoveLast();
|
||||
name.Add('\0');
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool GPUPipelineState::Init(const Description& desc)
|
||||
{
|
||||
// Cache description in debug builds
|
||||
#if BUILD_DEBUG
|
||||
// Cache description in development builds
|
||||
#if !BUILD_RELEASE
|
||||
DebugDesc = desc;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -172,11 +172,14 @@ protected:
|
||||
GPUPipelineState();
|
||||
|
||||
public:
|
||||
#if BUILD_DEBUG
|
||||
#if !BUILD_RELEASE
|
||||
/// <summary>
|
||||
/// The description of the pipeline state cached on creation in debug builds. Can be used to help with rendering crashes or issues and validation.
|
||||
/// </summary>
|
||||
Description DebugDesc;
|
||||
|
||||
typedef Array<char, InlinedAllocation<200>> DebugName;
|
||||
void GetDebugName(DebugName& name) const;
|
||||
#endif
|
||||
#if USE_EDITOR
|
||||
int32 Complexity;
|
||||
|
||||
@@ -25,6 +25,25 @@ void GPUShaderProgram::Init(const GPUShaderProgramInitializer& initializer)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !BUILD_RELEASE
|
||||
|
||||
void GPUShaderProgram::GetDebugName(DebugName& name) const
|
||||
{
|
||||
StringView ownerName = StringUtils::GetFileNameWithoutExtension(_owner->GetName());
|
||||
name.AddUninitialized(ownerName.Length() + _name.Length() + 2);
|
||||
char* dst = name.Get();
|
||||
for (int32 i = 0; i < ownerName.Length(); i++)
|
||||
dst[i] = (char)ownerName.Get()[i];
|
||||
dst += ownerName.Length();
|
||||
*dst = ':';
|
||||
dst++;
|
||||
for (int32 i = 0; i < _name.Length(); i++)
|
||||
dst[i] = _name.Get()[i];
|
||||
dst[_name.Length()] = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
GPUShader::GPUShader()
|
||||
: GPUResource(SpawnParams(Guid::New(), TypeInitializer))
|
||||
{
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
|
||||
#include "Engine/Core/Types/BaseTypes.h"
|
||||
#include "Engine/Core/Types/String.h"
|
||||
#if !BUILD_RELEASE
|
||||
#include "Engine/Core/Collections/Array.h"
|
||||
#endif
|
||||
#include "Config.h"
|
||||
|
||||
class GPUShader;
|
||||
@@ -93,6 +96,11 @@ public:
|
||||
return _flags;
|
||||
}
|
||||
|
||||
#if !BUILD_RELEASE
|
||||
typedef Array<char, InlinedAllocation<60>> DebugName;
|
||||
void GetDebugName(DebugName& name) const;
|
||||
#endif
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Gets shader program stage type.
|
||||
|
||||
@@ -73,7 +73,12 @@ ID3D12PipelineState* GPUPipelineStateDX12::GetState(GPUTextureViewDX12* depth, i
|
||||
#endif
|
||||
return state;
|
||||
}
|
||||
PROFILE_CPU_NAMED("Create Pipeline State");
|
||||
PROFILE_CPU();
|
||||
#if !BUILD_RELEASE
|
||||
DebugName name;
|
||||
GetDebugName(name);
|
||||
ZoneText(name.Get(), name.Count() - 1);
|
||||
#endif
|
||||
|
||||
// Update description to match the pipeline
|
||||
_desc.NumRenderTargets = key.RTsCount;
|
||||
@@ -103,41 +108,13 @@ ID3D12PipelineState* GPUPipelineStateDX12::GetState(GPUTextureViewDX12* depth, i
|
||||
const HRESULT result = _device->GetDevice()->CreateGraphicsPipelineState(&_desc, IID_PPV_ARGS(&state));
|
||||
LOG_DIRECTX_RESULT(result);
|
||||
if (FAILED(result))
|
||||
{
|
||||
#if !BUILD_RELEASE
|
||||
LOG(Error, "CreateGraphicsPipelineState failed for {}", String(name.Get(), name.Count() - 1));
|
||||
#endif
|
||||
return nullptr;
|
||||
#if GPU_ENABLE_RESOURCE_NAMING && BUILD_DEBUG
|
||||
Array<char, InlinedAllocation<200>> name;
|
||||
if (DebugDesc.VS)
|
||||
{
|
||||
name.Add(*DebugDesc.VS->GetName(), DebugDesc.VS->GetName().Length());
|
||||
name.Add('+');
|
||||
}
|
||||
#if GPU_ALLOW_TESSELLATION_SHADERS
|
||||
if (DebugDesc.HS)
|
||||
{
|
||||
name.Add(*DebugDesc.HS->GetName(), DebugDesc.HS->GetName().Length());
|
||||
name.Add('+');
|
||||
}
|
||||
if (DebugDesc.DS)
|
||||
{
|
||||
name.Add(*DebugDesc.DS->GetName(), DebugDesc.DS->GetName().Length());
|
||||
name.Add('+');
|
||||
}
|
||||
#endif
|
||||
#if GPU_ALLOW_GEOMETRY_SHADERS
|
||||
if (DebugDesc.GS)
|
||||
{
|
||||
name.Add(*DebugDesc.GS->GetName(), DebugDesc.GS->GetName().Length());
|
||||
name.Add('+');
|
||||
}
|
||||
#endif
|
||||
if (DebugDesc.PS)
|
||||
{
|
||||
name.Add(*DebugDesc.PS->GetName(), DebugDesc.PS->GetName().Length());
|
||||
name.Add('+');
|
||||
}
|
||||
if (name.Count() != 0 && name[name.Count() - 1] == '+')
|
||||
name.RemoveLast();
|
||||
name.Add('\0');
|
||||
#if GPU_ENABLE_RESOURCE_NAMING && !BUILD_RELEASE
|
||||
SetDebugObjectName(state, name.Get(), name.Count() - 1);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "GPUShaderDX12.h"
|
||||
#include "Engine/Serialization/MemoryReadStream.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "GPUShaderProgramDX12.h"
|
||||
#include "Types.h"
|
||||
#include "../RenderToolsDX.h"
|
||||
@@ -70,6 +71,12 @@ ID3D12PipelineState* GPUShaderProgramCSDX12::GetOrCreateState()
|
||||
{
|
||||
if (_state)
|
||||
return _state;
|
||||
PROFILE_CPU();
|
||||
#if !BUILD_RELEASE
|
||||
DebugName name;
|
||||
GetDebugName(name);
|
||||
ZoneText(name.Get(), name.Count() - 1);
|
||||
#endif
|
||||
|
||||
// Create description
|
||||
D3D12_COMPUTE_PIPELINE_STATE_DESC psDesc;
|
||||
|
||||
@@ -238,14 +238,14 @@ static VKAPI_ATTR VkBool32 VKAPI_PTR DebugUtilsCallback(VkDebugUtilsMessageSever
|
||||
LOG(Info, "[Vulkan] {0} {1}:{2} {3}", type, severity, callbackData->messageIdNumber, message);
|
||||
}
|
||||
|
||||
#if BUILD_DEBUG
|
||||
#if !BUILD_RELEASE
|
||||
if (auto* context = (GPUContextVulkan*)GPUDevice::Instance->GetMainContext())
|
||||
{
|
||||
if (auto* state = (GPUPipelineStateVulkan*)context->GetState())
|
||||
{
|
||||
const StringAnsi vsName = state->DebugDesc.VS ? state->DebugDesc.VS->GetName() : StringAnsi::Empty;
|
||||
const StringAnsi psName = state->DebugDesc.PS ? state->DebugDesc.PS->GetName() : StringAnsi::Empty;
|
||||
LOG(Warning, "[Vulkan] Error during rendering with VS={}, PS={}", String(vsName), String(psName));
|
||||
GPUPipelineState::DebugName name;
|
||||
state->GetDebugName(name);
|
||||
LOG(Warning, "[Vulkan] Error during rendering with {}", String(name.Get(), name.Count() - 1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -90,6 +90,8 @@ ComputePipelineStateVulkan* GPUShaderProgramCSVulkan::GetOrCreateState()
|
||||
{
|
||||
if (_pipelineState)
|
||||
return _pipelineState;
|
||||
PROFILE_CPU();
|
||||
ZoneText(*_name, _name.Length());
|
||||
|
||||
// Create pipeline layout
|
||||
DescriptorSetLayoutInfoVulkan descriptorSetLayoutInfo;
|
||||
@@ -110,7 +112,7 @@ ComputePipelineStateVulkan* GPUShaderProgramCSVulkan::GetOrCreateState()
|
||||
|
||||
// Create pipeline object
|
||||
VkPipeline pipeline;
|
||||
const VkResult result = vkCreateComputePipelines(_device->Device, _device->PipelineCache, 1, &desc, nullptr, &pipeline);
|
||||
VkResult result = vkCreateComputePipelines(_device->Device, _device->PipelineCache, 1, &desc, nullptr, &pipeline);
|
||||
LOG_VULKAN_RESULT(result);
|
||||
if (result != VK_SUCCESS)
|
||||
return nullptr;
|
||||
@@ -220,7 +222,12 @@ VkPipeline GPUPipelineStateVulkan::GetState(RenderPassVulkan* renderPass, GPUVer
|
||||
#endif
|
||||
return pipeline;
|
||||
}
|
||||
PROFILE_CPU_NAMED("Create Pipeline");
|
||||
PROFILE_CPU();
|
||||
#if !BUILD_RELEASE
|
||||
DebugName name;
|
||||
GetDebugName(name);
|
||||
ZoneText(name.Get(), name.Count() - 1);
|
||||
#endif
|
||||
|
||||
// Bind vertex input
|
||||
VkPipelineVertexInputStateCreateInfo vertexInputCreateInfo;
|
||||
@@ -310,10 +317,8 @@ VkPipeline GPUPipelineStateVulkan::GetState(RenderPassVulkan* renderPass, GPUVer
|
||||
LOG_VULKAN_RESULT(result);
|
||||
if (result != VK_SUCCESS)
|
||||
{
|
||||
#if BUILD_DEBUG
|
||||
const StringAnsi vsName = DebugDesc.VS ? DebugDesc.VS->GetName() : StringAnsi::Empty;
|
||||
const StringAnsi psName = DebugDesc.PS ? DebugDesc.PS->GetName() : StringAnsi::Empty;
|
||||
LOG(Error, "vkCreateGraphicsPipelines failed for VS={0}, PS={1}", String(vsName), String(psName));
|
||||
#if !BUILD_RELEASE
|
||||
LOG(Error, "vkCreateGraphicsPipelines failed for {}", String(name.Get(), name.Count() - 1));
|
||||
#endif
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user