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)
|
bool GPUPipelineState::Init(const Description& desc)
|
||||||
{
|
{
|
||||||
// Cache description in debug builds
|
// Cache description in development builds
|
||||||
#if BUILD_DEBUG
|
#if !BUILD_RELEASE
|
||||||
DebugDesc = desc;
|
DebugDesc = desc;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -172,11 +172,14 @@ protected:
|
|||||||
GPUPipelineState();
|
GPUPipelineState();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#if BUILD_DEBUG
|
#if !BUILD_RELEASE
|
||||||
/// <summary>
|
/// <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.
|
/// 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>
|
/// </summary>
|
||||||
Description DebugDesc;
|
Description DebugDesc;
|
||||||
|
|
||||||
|
typedef Array<char, InlinedAllocation<200>> DebugName;
|
||||||
|
void GetDebugName(DebugName& name) const;
|
||||||
#endif
|
#endif
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
int32 Complexity;
|
int32 Complexity;
|
||||||
|
|||||||
@@ -25,6 +25,25 @@ void GPUShaderProgram::Init(const GPUShaderProgramInitializer& initializer)
|
|||||||
#endif
|
#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()
|
GPUShader::GPUShader()
|
||||||
: GPUResource(SpawnParams(Guid::New(), TypeInitializer))
|
: GPUResource(SpawnParams(Guid::New(), TypeInitializer))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
|
|
||||||
#include "Engine/Core/Types/BaseTypes.h"
|
#include "Engine/Core/Types/BaseTypes.h"
|
||||||
#include "Engine/Core/Types/String.h"
|
#include "Engine/Core/Types/String.h"
|
||||||
|
#if !BUILD_RELEASE
|
||||||
|
#include "Engine/Core/Collections/Array.h"
|
||||||
|
#endif
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
|
|
||||||
class GPUShader;
|
class GPUShader;
|
||||||
@@ -93,6 +96,11 @@ public:
|
|||||||
return _flags;
|
return _flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !BUILD_RELEASE
|
||||||
|
typedef Array<char, InlinedAllocation<60>> DebugName;
|
||||||
|
void GetDebugName(DebugName& name) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets shader program stage type.
|
/// Gets shader program stage type.
|
||||||
|
|||||||
@@ -73,7 +73,12 @@ ID3D12PipelineState* GPUPipelineStateDX12::GetState(GPUTextureViewDX12* depth, i
|
|||||||
#endif
|
#endif
|
||||||
return state;
|
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
|
// Update description to match the pipeline
|
||||||
_desc.NumRenderTargets = key.RTsCount;
|
_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));
|
const HRESULT result = _device->GetDevice()->CreateGraphicsPipelineState(&_desc, IID_PPV_ARGS(&state));
|
||||||
LOG_DIRECTX_RESULT(result);
|
LOG_DIRECTX_RESULT(result);
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
|
{
|
||||||
|
#if !BUILD_RELEASE
|
||||||
|
LOG(Error, "CreateGraphicsPipelineState failed for {}", String(name.Get(), name.Count() - 1));
|
||||||
|
#endif
|
||||||
return nullptr;
|
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 GPU_ENABLE_RESOURCE_NAMING && !BUILD_RELEASE
|
||||||
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');
|
|
||||||
SetDebugObjectName(state, name.Get(), name.Count() - 1);
|
SetDebugObjectName(state, name.Get(), name.Count() - 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "GPUShaderDX12.h"
|
#include "GPUShaderDX12.h"
|
||||||
#include "Engine/Serialization/MemoryReadStream.h"
|
#include "Engine/Serialization/MemoryReadStream.h"
|
||||||
|
#include "Engine/Profiler/ProfilerCPU.h"
|
||||||
#include "GPUShaderProgramDX12.h"
|
#include "GPUShaderProgramDX12.h"
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
#include "../RenderToolsDX.h"
|
#include "../RenderToolsDX.h"
|
||||||
@@ -70,6 +71,12 @@ ID3D12PipelineState* GPUShaderProgramCSDX12::GetOrCreateState()
|
|||||||
{
|
{
|
||||||
if (_state)
|
if (_state)
|
||||||
return _state;
|
return _state;
|
||||||
|
PROFILE_CPU();
|
||||||
|
#if !BUILD_RELEASE
|
||||||
|
DebugName name;
|
||||||
|
GetDebugName(name);
|
||||||
|
ZoneText(name.Get(), name.Count() - 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Create description
|
// Create description
|
||||||
D3D12_COMPUTE_PIPELINE_STATE_DESC psDesc;
|
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);
|
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* context = (GPUContextVulkan*)GPUDevice::Instance->GetMainContext())
|
||||||
{
|
{
|
||||||
if (auto* state = (GPUPipelineStateVulkan*)context->GetState())
|
if (auto* state = (GPUPipelineStateVulkan*)context->GetState())
|
||||||
{
|
{
|
||||||
const StringAnsi vsName = state->DebugDesc.VS ? state->DebugDesc.VS->GetName() : StringAnsi::Empty;
|
GPUPipelineState::DebugName name;
|
||||||
const StringAnsi psName = state->DebugDesc.PS ? state->DebugDesc.PS->GetName() : StringAnsi::Empty;
|
state->GetDebugName(name);
|
||||||
LOG(Warning, "[Vulkan] Error during rendering with VS={}, PS={}", String(vsName), String(psName));
|
LOG(Warning, "[Vulkan] Error during rendering with {}", String(name.Get(), name.Count() - 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -90,6 +90,8 @@ ComputePipelineStateVulkan* GPUShaderProgramCSVulkan::GetOrCreateState()
|
|||||||
{
|
{
|
||||||
if (_pipelineState)
|
if (_pipelineState)
|
||||||
return _pipelineState;
|
return _pipelineState;
|
||||||
|
PROFILE_CPU();
|
||||||
|
ZoneText(*_name, _name.Length());
|
||||||
|
|
||||||
// Create pipeline layout
|
// Create pipeline layout
|
||||||
DescriptorSetLayoutInfoVulkan descriptorSetLayoutInfo;
|
DescriptorSetLayoutInfoVulkan descriptorSetLayoutInfo;
|
||||||
@@ -110,7 +112,7 @@ ComputePipelineStateVulkan* GPUShaderProgramCSVulkan::GetOrCreateState()
|
|||||||
|
|
||||||
// Create pipeline object
|
// Create pipeline object
|
||||||
VkPipeline pipeline;
|
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);
|
LOG_VULKAN_RESULT(result);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -220,7 +222,12 @@ VkPipeline GPUPipelineStateVulkan::GetState(RenderPassVulkan* renderPass, GPUVer
|
|||||||
#endif
|
#endif
|
||||||
return pipeline;
|
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
|
// Bind vertex input
|
||||||
VkPipelineVertexInputStateCreateInfo vertexInputCreateInfo;
|
VkPipelineVertexInputStateCreateInfo vertexInputCreateInfo;
|
||||||
@@ -310,10 +317,8 @@ VkPipeline GPUPipelineStateVulkan::GetState(RenderPassVulkan* renderPass, GPUVer
|
|||||||
LOG_VULKAN_RESULT(result);
|
LOG_VULKAN_RESULT(result);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
{
|
{
|
||||||
#if BUILD_DEBUG
|
#if !BUILD_RELEASE
|
||||||
const StringAnsi vsName = DebugDesc.VS ? DebugDesc.VS->GetName() : StringAnsi::Empty;
|
LOG(Error, "vkCreateGraphicsPipelines failed for {}", String(name.Get(), name.Count() - 1));
|
||||||
const StringAnsi psName = DebugDesc.PS ? DebugDesc.PS->GetName() : StringAnsi::Empty;
|
|
||||||
LOG(Error, "vkCreateGraphicsPipelines failed for VS={0}, PS={1}", String(vsName), String(psName));
|
|
||||||
#endif
|
#endif
|
||||||
return VK_NULL_HANDLE;
|
return VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user