Add **GPU profiling support to Tracy integration**
This commit is contained in:
@@ -247,7 +247,6 @@ int32 Engine::Main(const Char* cmdLine)
|
|||||||
{
|
{
|
||||||
OnDraw();
|
OnDraw();
|
||||||
Time::OnEndDraw();
|
Time::OnEndDraw();
|
||||||
FrameMark;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,6 +396,11 @@ void Engine::OnLateUpdate()
|
|||||||
|
|
||||||
void Engine::OnDraw()
|
void Engine::OnDraw()
|
||||||
{
|
{
|
||||||
|
#if COMPILE_WITH_PROFILER
|
||||||
|
// Auto-enable GPU events when Tracy got connected
|
||||||
|
if (!ProfilerGPU::EventsEnabled && TracyIsConnected)
|
||||||
|
ProfilerGPU::EventsEnabled = true;
|
||||||
|
#endif
|
||||||
PROFILE_CPU_NAMED("Draw");
|
PROFILE_CPU_NAMED("Draw");
|
||||||
|
|
||||||
// Begin frame rendering
|
// Begin frame rendering
|
||||||
@@ -411,6 +415,7 @@ void Engine::OnDraw()
|
|||||||
device->Draw();
|
device->Draw();
|
||||||
|
|
||||||
// End frame rendering
|
// End frame rendering
|
||||||
|
FrameMark;
|
||||||
#if COMPILE_WITH_PROFILER
|
#if COMPILE_WITH_PROFILER
|
||||||
ProfilerGPU::EndFrame();
|
ProfilerGPU::EndFrame();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -69,6 +69,10 @@ void GPUContext::FrameEnd()
|
|||||||
FlushState();
|
FlushState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPUContext::OnPresent()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void GPUContext::BindSR(int32 slot, GPUTexture* t)
|
void GPUContext::BindSR(int32 slot, GPUTexture* t)
|
||||||
{
|
{
|
||||||
ASSERT_LOW_LAYER(t == nullptr || t->ResidentMipLevels() == 0 || t->IsShaderResource());
|
ASSERT_LOW_LAYER(t == nullptr || t->ResidentMipLevels() == 0 || t->IsShaderResource());
|
||||||
|
|||||||
@@ -148,6 +148,11 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
virtual void FrameEnd();
|
virtual void FrameEnd();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called after performing final swapchain presentation and submitting all GPU commands.
|
||||||
|
/// </summary>
|
||||||
|
virtual void OnPresent();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#if GPU_ALLOW_PROFILE_EVENTS
|
#if GPU_ALLOW_PROFILE_EVENTS
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -646,6 +646,7 @@ void GPUDevice::DrawEnd()
|
|||||||
const double presentEnd = Platform::GetTimeSeconds();
|
const double presentEnd = Platform::GetTimeSeconds();
|
||||||
ProfilerGPU::OnPresentTime((float)((presentEnd - presentStart) * 1000.0));
|
ProfilerGPU::OnPresentTime((float)((presentEnd - presentStart) * 1000.0));
|
||||||
#endif
|
#endif
|
||||||
|
GetMainContext()->OnPresent();
|
||||||
|
|
||||||
_wasVSyncUsed = anyVSync;
|
_wasVSyncUsed = anyVSync;
|
||||||
_isRendering = false;
|
_isRendering = false;
|
||||||
|
|||||||
@@ -20,6 +20,12 @@ public abstract class GraphicsDeviceBaseModule : EngineModule
|
|||||||
// Enables GPU diagnostic tools (debug layer etc.)
|
// Enables GPU diagnostic tools (debug layer etc.)
|
||||||
options.PublicDefinitions.Add("GPU_ENABLE_DIAGNOSTICS");
|
options.PublicDefinitions.Add("GPU_ENABLE_DIAGNOSTICS");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Profiler.Use(options) && tracy.GPU && true)
|
||||||
|
{
|
||||||
|
// Enables GPU profiling with Tracy
|
||||||
|
options.PrivateDefinitions.Add("GPU_ENABLE_TRACY");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -65,10 +65,17 @@ GPUContextDX11::GPUContextDX11(GPUDeviceDX11* device, ID3D11DeviceContext* conte
|
|||||||
_maxUASlots = GPU_MAX_UA_BINDED;
|
_maxUASlots = GPU_MAX_UA_BINDED;
|
||||||
if (_device->GetRendererType() != RendererType::DirectX11)
|
if (_device->GetRendererType() != RendererType::DirectX11)
|
||||||
_maxUASlots = 1;
|
_maxUASlots = 1;
|
||||||
|
|
||||||
|
#if GPU_ENABLE_TRACY
|
||||||
|
_tracyContext = tracy::CreateD3D11Context(device->GetDevice(), context);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUContextDX11::~GPUContextDX11()
|
GPUContextDX11::~GPUContextDX11()
|
||||||
{
|
{
|
||||||
|
#if GPU_ENABLE_TRACY
|
||||||
|
tracy::DestroyD3D11Context(_tracyContext);
|
||||||
|
#endif
|
||||||
#if GPU_ALLOW_PROFILE_EVENTS
|
#if GPU_ALLOW_PROFILE_EVENTS
|
||||||
SAFE_RELEASE(_userDefinedAnnotations);
|
SAFE_RELEASE(_userDefinedAnnotations);
|
||||||
#endif
|
#endif
|
||||||
@@ -139,16 +146,35 @@ void GPUContextDX11::FrameBegin()
|
|||||||
_context->CSSetSamplers(0, ARRAY_COUNT(samplers), samplers);
|
_context->CSSetSamplers(0, ARRAY_COUNT(samplers), samplers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPUContextDX11::OnPresent()
|
||||||
|
{
|
||||||
|
GPUContext::OnPresent();
|
||||||
|
|
||||||
|
#if GPU_ENABLE_TRACY
|
||||||
|
tracy::CollectD3D11Context(_tracyContext);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#if GPU_ALLOW_PROFILE_EVENTS
|
#if GPU_ALLOW_PROFILE_EVENTS
|
||||||
|
|
||||||
void GPUContextDX11::EventBegin(const Char* name)
|
void GPUContextDX11::EventBegin(const Char* name)
|
||||||
{
|
{
|
||||||
if (_userDefinedAnnotations)
|
if (_userDefinedAnnotations)
|
||||||
_userDefinedAnnotations->BeginEvent(name);
|
_userDefinedAnnotations->BeginEvent(name);
|
||||||
|
|
||||||
|
#if GPU_ENABLE_TRACY
|
||||||
|
char buffer[60];
|
||||||
|
int32 bufferSize = StringUtils::Copy(buffer, name, sizeof(buffer));
|
||||||
|
tracy::BeginD3D11ZoneScope(_tracyZone, _tracyContext, buffer, bufferSize);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPUContextDX11::EventEnd()
|
void GPUContextDX11::EventEnd()
|
||||||
{
|
{
|
||||||
|
#if GPU_ENABLE_TRACY
|
||||||
|
tracy::EndD3D11ZoneScope(_tracyZone);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (_userDefinedAnnotations)
|
if (_userDefinedAnnotations)
|
||||||
_userDefinedAnnotations->EndEvent();
|
_userDefinedAnnotations->EndEvent();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "GPUDeviceDX11.h"
|
#include "GPUDeviceDX11.h"
|
||||||
#include "GPUPipelineStateDX11.h"
|
#include "GPUPipelineStateDX11.h"
|
||||||
#include "../IncludeDirectXHeaders.h"
|
#include "../IncludeDirectXHeaders.h"
|
||||||
|
#include <ThirdParty/tracy/tracy/TracyD3D11.hpp>
|
||||||
|
|
||||||
#if GRAPHICS_API_DIRECTX11
|
#if GRAPHICS_API_DIRECTX11
|
||||||
|
|
||||||
@@ -23,6 +24,10 @@ private:
|
|||||||
ID3D11DeviceContext* _context;
|
ID3D11DeviceContext* _context;
|
||||||
#if GPU_ALLOW_PROFILE_EVENTS
|
#if GPU_ALLOW_PROFILE_EVENTS
|
||||||
ID3DUserDefinedAnnotation* _userDefinedAnnotations;
|
ID3DUserDefinedAnnotation* _userDefinedAnnotations;
|
||||||
|
#endif
|
||||||
|
#if COMPILE_WITH_PROFILER
|
||||||
|
void* _tracyContext;
|
||||||
|
byte _tracyZone[TracyD3D11ZoneSize];
|
||||||
#endif
|
#endif
|
||||||
int32 _maxUASlots;
|
int32 _maxUASlots;
|
||||||
|
|
||||||
@@ -110,6 +115,7 @@ public:
|
|||||||
|
|
||||||
// [GPUContext]
|
// [GPUContext]
|
||||||
void FrameBegin() override;
|
void FrameBegin() override;
|
||||||
|
void OnPresent() override;
|
||||||
#if GPU_ALLOW_PROFILE_EVENTS
|
#if GPU_ALLOW_PROFILE_EVENTS
|
||||||
void EventBegin(const Char* name) override;
|
void EventBegin(const Char* name) override;
|
||||||
void EventEnd() override;
|
void EventEnd() override;
|
||||||
|
|||||||
@@ -99,10 +99,16 @@ GPUContextDX12::GPUContextDX12(GPUDeviceDX12* device, D3D12_COMMAND_LIST_TYPE ty
|
|||||||
#if GPU_ENABLE_RESOURCE_NAMING
|
#if GPU_ENABLE_RESOURCE_NAMING
|
||||||
_commandList->SetName(TEXT("GPUContextDX12::CommandList"));
|
_commandList->SetName(TEXT("GPUContextDX12::CommandList"));
|
||||||
#endif
|
#endif
|
||||||
|
#if GPU_ENABLE_TRACY
|
||||||
|
_tracyContext = tracy::CreateD3D12Context(device->GetDevice(), _device->GetCommandQueue()->GetCommandQueue());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUContextDX12::~GPUContextDX12()
|
GPUContextDX12::~GPUContextDX12()
|
||||||
{
|
{
|
||||||
|
#if GPU_ENABLE_TRACY
|
||||||
|
tracy::DestroyD3D12Context(_tracyContext);
|
||||||
|
#endif
|
||||||
DX_SAFE_RELEASE_CHECK(_commandList, 0);
|
DX_SAFE_RELEASE_CHECK(_commandList, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -706,6 +712,15 @@ void GPUContextDX12::FrameEnd()
|
|||||||
FrameFenceValues[0] = Execute(false);
|
FrameFenceValues[0] = Execute(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPUContextDX12::OnPresent()
|
||||||
|
{
|
||||||
|
GPUContext::OnPresent();
|
||||||
|
|
||||||
|
#if GPU_ENABLE_TRACY
|
||||||
|
tracy::CollectD3D12Context(_tracyContext);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#if GPU_ALLOW_PROFILE_EVENTS
|
#if GPU_ALLOW_PROFILE_EVENTS
|
||||||
|
|
||||||
void GPUContextDX12::EventBegin(const Char* name)
|
void GPUContextDX12::EventBegin(const Char* name)
|
||||||
@@ -713,10 +728,22 @@ void GPUContextDX12::EventBegin(const Char* name)
|
|||||||
#if USE_PIX
|
#if USE_PIX
|
||||||
PIXBeginEvent(_commandList, 0, name);
|
PIXBeginEvent(_commandList, 0, name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if GPU_ENABLE_TRACY
|
||||||
|
char buffer[60];
|
||||||
|
int32 bufferSize = StringUtils::Copy(buffer, name, sizeof(buffer));
|
||||||
|
auto& zone = _tracyZones.AddOne();
|
||||||
|
tracy::BeginD3D12ZoneScope(zone.Data, _tracyContext, _commandList, buffer, bufferSize);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPUContextDX12::EventEnd()
|
void GPUContextDX12::EventEnd()
|
||||||
{
|
{
|
||||||
|
#if GPU_ENABLE_TRACY
|
||||||
|
tracy::EndD3D12ZoneScope(_tracyZones.Last().Data);
|
||||||
|
_tracyZones.RemoveLast();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if USE_PIX
|
#if USE_PIX
|
||||||
PIXEndEvent(_commandList);
|
PIXEndEvent(_commandList);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "IShaderResourceDX12.h"
|
#include "IShaderResourceDX12.h"
|
||||||
#include "DescriptorHeapDX12.h"
|
#include "DescriptorHeapDX12.h"
|
||||||
#include "../IncludeDirectXHeaders.h"
|
#include "../IncludeDirectXHeaders.h"
|
||||||
|
#include <ThirdParty/tracy/tracy/TracyD3D12.hpp>
|
||||||
|
|
||||||
#if GRAPHICS_API_DIRECTX12
|
#if GRAPHICS_API_DIRECTX12
|
||||||
|
|
||||||
@@ -71,6 +72,12 @@ private:
|
|||||||
GPUConstantBufferDX12* _cbHandles[GPU_MAX_CB_BINDED];
|
GPUConstantBufferDX12* _cbHandles[GPU_MAX_CB_BINDED];
|
||||||
GPUSamplerDX12* _samplers[GPU_MAX_SAMPLER_BINDED - GPU_STATIC_SAMPLERS_COUNT];
|
GPUSamplerDX12* _samplers[GPU_MAX_SAMPLER_BINDED - GPU_STATIC_SAMPLERS_COUNT];
|
||||||
|
|
||||||
|
#if COMPILE_WITH_PROFILER
|
||||||
|
void* _tracyContext;
|
||||||
|
struct TracyZone { byte Data[TracyD3D12ZoneSize]; };
|
||||||
|
Array<TracyZone, InlinedAllocation<32>> _tracyZones;
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GPUContextDX12(GPUDeviceDX12* device, D3D12_COMMAND_LIST_TYPE type);
|
GPUContextDX12(GPUDeviceDX12* device, D3D12_COMMAND_LIST_TYPE type);
|
||||||
@@ -154,6 +161,7 @@ public:
|
|||||||
// [GPUContext]
|
// [GPUContext]
|
||||||
void FrameBegin() override;
|
void FrameBegin() override;
|
||||||
void FrameEnd() override;
|
void FrameEnd() override;
|
||||||
|
void OnPresent() override;
|
||||||
#if GPU_ALLOW_PROFILE_EVENTS
|
#if GPU_ALLOW_PROFILE_EVENTS
|
||||||
void EventBegin(const Char* name) override;
|
void EventBegin(const Char* name) override;
|
||||||
void EventEnd() override;
|
void EventEnd() override;
|
||||||
|
|||||||
@@ -49,10 +49,19 @@ void CmdBufferVulkan::End()
|
|||||||
PROFILE_CPU();
|
PROFILE_CPU();
|
||||||
ASSERT(IsOutsideRenderPass());
|
ASSERT(IsOutsideRenderPass());
|
||||||
|
|
||||||
#if GPU_ALLOW_PROFILE_EVENTS && VK_EXT_debug_utils
|
#if GPU_ALLOW_PROFILE_EVENTS
|
||||||
// End remaining events
|
// End remaining events
|
||||||
while (_eventsBegin--)
|
while (_eventsBegin--)
|
||||||
vkCmdEndDebugUtilsLabelEXT(GetHandle());
|
{
|
||||||
|
#if VK_EXT_debug_utils
|
||||||
|
if (vkCmdEndDebugUtilsLabelEXT)
|
||||||
|
vkCmdEndDebugUtilsLabelEXT(GetHandle());
|
||||||
|
#endif
|
||||||
|
#if GPU_ENABLE_TRACY
|
||||||
|
tracy::EndVkZoneScope(_tracyZones.Last().Data);
|
||||||
|
_tracyZones.RemoveLast();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VALIDATE_VULKAN_RESULT(vkEndCommandBuffer(GetHandle()));
|
VALIDATE_VULKAN_RESULT(vkEndCommandBuffer(GetHandle()));
|
||||||
@@ -85,39 +94,43 @@ void CmdBufferVulkan::EndRenderPass()
|
|||||||
|
|
||||||
#if GPU_ALLOW_PROFILE_EVENTS
|
#if GPU_ALLOW_PROFILE_EVENTS
|
||||||
|
|
||||||
void CmdBufferVulkan::BeginEvent(const Char* name)
|
void CmdBufferVulkan::BeginEvent(const Char* name, void* tracyContext)
|
||||||
{
|
{
|
||||||
#if VK_EXT_debug_utils
|
|
||||||
if (!vkCmdBeginDebugUtilsLabelEXT)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_eventsBegin++;
|
_eventsBegin++;
|
||||||
|
|
||||||
// Convert to ANSI
|
char buffer[60];
|
||||||
char buffer[101];
|
int32 bufferSize = StringUtils::Copy(buffer, name, sizeof(buffer));
|
||||||
int32 i = 0;
|
|
||||||
while (i < 100 && name[i])
|
|
||||||
{
|
|
||||||
buffer[i] = (char)name[i];
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
buffer[i] = 0;
|
|
||||||
|
|
||||||
VkDebugUtilsLabelEXT label;
|
#if GPU_ENABLE_TRACY
|
||||||
RenderToolsVulkan::ZeroStruct(label, VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT);
|
auto& zone = _tracyZones.AddOne();
|
||||||
label.pLabelName = buffer;
|
tracy::BeginVkZoneScope(zone.Data, tracyContext, GetHandle(), buffer, bufferSize);
|
||||||
vkCmdBeginDebugUtilsLabelEXT(GetHandle(), &label);
|
#endif
|
||||||
|
|
||||||
|
#if VK_EXT_debug_utils
|
||||||
|
if (vkCmdBeginDebugUtilsLabelEXT)
|
||||||
|
{
|
||||||
|
VkDebugUtilsLabelEXT label;
|
||||||
|
RenderToolsVulkan::ZeroStruct(label, VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT);
|
||||||
|
label.pLabelName = buffer;
|
||||||
|
vkCmdBeginDebugUtilsLabelEXT(GetHandle(), &label);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdBufferVulkan::EndEvent()
|
void CmdBufferVulkan::EndEvent()
|
||||||
{
|
{
|
||||||
#if VK_EXT_debug_utils
|
if (_eventsBegin == 0)
|
||||||
if (_eventsBegin == 0 || !vkCmdEndDebugUtilsLabelEXT)
|
|
||||||
return;
|
return;
|
||||||
_eventsBegin--;
|
_eventsBegin--;
|
||||||
|
|
||||||
vkCmdEndDebugUtilsLabelEXT(GetHandle());
|
#if VK_EXT_debug_utils
|
||||||
|
if (vkCmdEndDebugUtilsLabelEXT)
|
||||||
|
vkCmdEndDebugUtilsLabelEXT(GetHandle());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GPU_ENABLE_TRACY
|
||||||
|
tracy::EndVkZoneScope(_tracyZones.Last().Data);
|
||||||
|
_tracyZones.RemoveLast();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "GPUDeviceVulkan.h"
|
#include "GPUDeviceVulkan.h"
|
||||||
#include "Engine/Core/Types/BaseTypes.h"
|
#include "Engine/Core/Types/BaseTypes.h"
|
||||||
#include "Engine/Core/Collections/Array.h"
|
#include "Engine/Core/Collections/Array.h"
|
||||||
|
#include <ThirdParty/tracy/tracy/TracyVulkan.hpp>
|
||||||
|
|
||||||
#if GRAPHICS_API_VULKAN
|
#if GRAPHICS_API_VULKAN
|
||||||
|
|
||||||
@@ -42,6 +43,8 @@ private:
|
|||||||
FenceVulkan* _fence;
|
FenceVulkan* _fence;
|
||||||
#if GPU_ALLOW_PROFILE_EVENTS
|
#if GPU_ALLOW_PROFILE_EVENTS
|
||||||
int32 _eventsBegin = 0;
|
int32 _eventsBegin = 0;
|
||||||
|
struct TracyZone { byte Data[TracyVulkanZoneSize]; };
|
||||||
|
Array<TracyZone, InlinedAllocation<32>> _tracyZones;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// The latest value when command buffer was submitted.
|
// The latest value when command buffer was submitted.
|
||||||
@@ -129,7 +132,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if GPU_ALLOW_PROFILE_EVENTS
|
#if GPU_ALLOW_PROFILE_EVENTS
|
||||||
void BeginEvent(const Char* name);
|
void BeginEvent(const Char* name, void* tracyContext);
|
||||||
void EndEvent();
|
void EndEvent();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "GPUContextVulkan.h"
|
#include "GPUContextVulkan.h"
|
||||||
#include "CmdBufferVulkan.h"
|
#include "CmdBufferVulkan.h"
|
||||||
|
#include "GPUAdapterVulkan.h"
|
||||||
#include "RenderToolsVulkan.h"
|
#include "RenderToolsVulkan.h"
|
||||||
#include "Engine/Core/Math/Color.h"
|
#include "Engine/Core/Math/Color.h"
|
||||||
#include "Engine/Core/Math/Rectangle.h"
|
#include "Engine/Core/Math/Rectangle.h"
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
#include "Engine/Profiler/RenderStats.h"
|
#include "Engine/Profiler/RenderStats.h"
|
||||||
#include "GPUShaderProgramVulkan.h"
|
#include "GPUShaderProgramVulkan.h"
|
||||||
#include "GPUTextureVulkan.h"
|
#include "GPUTextureVulkan.h"
|
||||||
|
#include "QueueVulkan.h"
|
||||||
#include "Engine/Graphics/PixelFormatExtensions.h"
|
#include "Engine/Graphics/PixelFormatExtensions.h"
|
||||||
#include "Engine/Debug/Exceptions/NotImplementedException.h"
|
#include "Engine/Debug/Exceptions/NotImplementedException.h"
|
||||||
|
|
||||||
@@ -107,10 +109,37 @@ GPUContextVulkan::GPUContextVulkan(GPUDeviceVulkan* device, QueueVulkan* queue)
|
|||||||
_handlesSizes[(int32)SpirvShaderResourceBindingType::SRV] = GPU_MAX_SR_BINDED;
|
_handlesSizes[(int32)SpirvShaderResourceBindingType::SRV] = GPU_MAX_SR_BINDED;
|
||||||
_handlesSizes[(int32)SpirvShaderResourceBindingType::UAV] = GPU_MAX_UA_BINDED;
|
_handlesSizes[(int32)SpirvShaderResourceBindingType::UAV] = GPU_MAX_UA_BINDED;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if GPU_ENABLE_TRACY
|
||||||
|
#if VK_EXT_calibrated_timestamps && VK_EXT_host_query_reset
|
||||||
|
// Use calibrated timestamps extension
|
||||||
|
if (vkResetQueryPoolEXT && vkGetCalibratedTimestampsEXT)
|
||||||
|
{
|
||||||
|
_tracyContext = tracy::CreateVkContext(_device->Adapter->Gpu, _device->Device, vkResetQueryPoolEXT, vkGetPhysicalDeviceCalibrateableTimeDomainsEXT, vkGetCalibratedTimestampsEXT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
// Use immediate command buffer for Tracy initialization
|
||||||
|
VkCommandBufferAllocateInfo cmdInfo;
|
||||||
|
RenderToolsVulkan::ZeroStruct(cmdInfo, VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO);
|
||||||
|
cmdInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||||
|
cmdInfo.commandPool = _cmdBufferManager->GetHandle();
|
||||||
|
cmdInfo.commandBufferCount = 1;
|
||||||
|
VkCommandBuffer tracyCmdBuffer;
|
||||||
|
vkAllocateCommandBuffers(_device->Device, &cmdInfo, &tracyCmdBuffer);
|
||||||
|
_tracyContext = tracy::CreateVkContext(_device->Adapter->Gpu, _device->Device, _queue->GetHandle(), tracyCmdBuffer, vkGetPhysicalDeviceCalibrateableTimeDomainsEXT, vkGetCalibratedTimestampsEXT);
|
||||||
|
vkQueueWaitIdle(_queue->GetHandle());
|
||||||
|
vkFreeCommandBuffers(_device->Device, _cmdBufferManager->GetHandle(), 1, &tracyCmdBuffer);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUContextVulkan::~GPUContextVulkan()
|
GPUContextVulkan::~GPUContextVulkan()
|
||||||
{
|
{
|
||||||
|
#if GPU_ENABLE_TRACY
|
||||||
|
tracy::DestroyVkContext(_tracyContext);
|
||||||
|
#endif
|
||||||
for (int32 i = 0; i < _descriptorPools.Count(); i++)
|
for (int32 i = 0; i < _descriptorPools.Count(); i++)
|
||||||
{
|
{
|
||||||
_descriptorPools[i].ClearDelete();
|
_descriptorPools[i].ClearDelete();
|
||||||
@@ -679,15 +708,9 @@ void GPUContextVulkan::OnDrawCall()
|
|||||||
// Bind descriptors sets to the graphics pipeline
|
// Bind descriptors sets to the graphics pipeline
|
||||||
if (pipelineState->HasDescriptorsPerStageMask)
|
if (pipelineState->HasDescriptorsPerStageMask)
|
||||||
{
|
{
|
||||||
vkCmdBindDescriptorSets(
|
auto& descriptorSets = pipelineState->DescriptorSetHandles;
|
||||||
cmdBuffer->GetHandle(),
|
auto& dynamicOffsets = pipelineState->DynamicOffsets;
|
||||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
vkCmdBindDescriptorSets(cmdBuffer->GetHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineState->GetLayout()->Handle, 0, descriptorSets.Count(), descriptorSets.Get(), dynamicOffsets.Count(), dynamicOffsets.Get());
|
||||||
pipelineState->GetLayout()->Handle,
|
|
||||||
0,
|
|
||||||
pipelineState->DescriptorSetHandles.Count(),
|
|
||||||
pipelineState->DescriptorSetHandles.Get(),
|
|
||||||
pipelineState->DynamicOffsets.Count(),
|
|
||||||
pipelineState->DynamicOffsets.Get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_rtDirtyFlag = false;
|
_rtDirtyFlag = false;
|
||||||
@@ -748,6 +771,11 @@ void GPUContextVulkan::FrameEnd()
|
|||||||
// Execute any queued layout transitions that weren't already handled by the render pass
|
// Execute any queued layout transitions that weren't already handled by the render pass
|
||||||
FlushBarriers();
|
FlushBarriers();
|
||||||
|
|
||||||
|
#if GPU_ENABLE_TRACY
|
||||||
|
if (cmdBuffer)
|
||||||
|
tracy::CollectVkContext(_tracyContext, cmdBuffer->GetHandle());
|
||||||
|
#endif
|
||||||
|
|
||||||
// Base
|
// Base
|
||||||
GPUContext::FrameEnd();
|
GPUContext::FrameEnd();
|
||||||
}
|
}
|
||||||
@@ -757,7 +785,12 @@ void GPUContextVulkan::FrameEnd()
|
|||||||
void GPUContextVulkan::EventBegin(const Char* name)
|
void GPUContextVulkan::EventBegin(const Char* name)
|
||||||
{
|
{
|
||||||
const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer();
|
const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer();
|
||||||
cmdBuffer->BeginEvent(name);
|
#if COMPILE_WITH_PROFILER
|
||||||
|
void* tracyContext = _tracyContext;
|
||||||
|
#else
|
||||||
|
void* tracyContext = nullptr;
|
||||||
|
#endif
|
||||||
|
cmdBuffer->BeginEvent(name, tracyContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPUContextVulkan::EventEnd()
|
void GPUContextVulkan::EventEnd()
|
||||||
|
|||||||
@@ -94,6 +94,9 @@ private:
|
|||||||
#if ENABLE_ASSERTION
|
#if ENABLE_ASSERTION
|
||||||
uint32 _handlesSizes[(int32)SpirvShaderResourceBindingType::MAX];
|
uint32 _handlesSizes[(int32)SpirvShaderResourceBindingType::MAX];
|
||||||
#endif
|
#endif
|
||||||
|
#if COMPILE_WITH_PROFILER
|
||||||
|
void* _tracyContext;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef Array<DescriptorPoolVulkan*> DescriptorPoolArray;
|
typedef Array<DescriptorPoolVulkan*> DescriptorPoolArray;
|
||||||
Dictionary<uint32, DescriptorPoolArray> _descriptorPools;
|
Dictionary<uint32, DescriptorPoolArray> _descriptorPools;
|
||||||
|
|||||||
@@ -62,6 +62,10 @@ static const char* GDeviceExtensions[] =
|
|||||||
#endif
|
#endif
|
||||||
#if VK_KHR_sampler_mirror_clamp_to_edge
|
#if VK_KHR_sampler_mirror_clamp_to_edge
|
||||||
VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME,
|
VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME,
|
||||||
|
#endif
|
||||||
|
#if GPU_ENABLE_TRACY && VK_EXT_calibrated_timestamps && VK_EXT_host_query_reset
|
||||||
|
VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME,
|
||||||
|
VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME,
|
||||||
#endif
|
#endif
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -424,6 +424,7 @@ GPUSwapChainVulkan::Status GPUSwapChainVulkan::Present(QueueVulkan* presentQueue
|
|||||||
{
|
{
|
||||||
if (_currentImageIndex == -1)
|
if (_currentImageIndex == -1)
|
||||||
return Status::Ok;
|
return Status::Ok;
|
||||||
|
PROFILE_CPU_NAMED("vkQueuePresentKHR");
|
||||||
|
|
||||||
VkPresentInfoKHR presentInfo;
|
VkPresentInfoKHR presentInfo;
|
||||||
RenderToolsVulkan::ZeroStruct(presentInfo, VK_STRUCTURE_TYPE_PRESENT_INFO_KHR);
|
RenderToolsVulkan::ZeroStruct(presentInfo, VK_STRUCTURE_TYPE_PRESENT_INFO_KHR);
|
||||||
@@ -506,7 +507,7 @@ int32 GPUSwapChainVulkan::TryPresent(Function<int32(GPUSwapChainVulkan*, void*)>
|
|||||||
|
|
||||||
int32 GPUSwapChainVulkan::AcquireNextImage(SemaphoreVulkan*& outSemaphore)
|
int32 GPUSwapChainVulkan::AcquireNextImage(SemaphoreVulkan*& outSemaphore)
|
||||||
{
|
{
|
||||||
PROFILE_CPU();
|
PROFILE_CPU_NAMED("vkAcquireNextImageKHR");
|
||||||
ASSERT(_swapChain && _backBuffers.HasItems());
|
ASSERT(_swapChain && _backBuffers.HasItems());
|
||||||
|
|
||||||
uint32 imageIndex = _currentImageIndex;
|
uint32 imageIndex = _currentImageIndex;
|
||||||
@@ -514,13 +515,7 @@ int32 GPUSwapChainVulkan::AcquireNextImage(SemaphoreVulkan*& outSemaphore)
|
|||||||
_semaphoreIndex = (_semaphoreIndex + 1) % _backBuffers.Count();
|
_semaphoreIndex = (_semaphoreIndex + 1) % _backBuffers.Count();
|
||||||
const auto semaphore = _backBuffers[_semaphoreIndex].ImageAcquiredSemaphore;
|
const auto semaphore = _backBuffers[_semaphoreIndex].ImageAcquiredSemaphore;
|
||||||
|
|
||||||
const VkResult result = vkAcquireNextImageKHR(
|
const VkResult result = vkAcquireNextImageKHR(_device->Device, _swapChain, UINT64_MAX, semaphore->GetHandle(), VK_NULL_HANDLE, &imageIndex);
|
||||||
_device->Device,
|
|
||||||
_swapChain,
|
|
||||||
UINT64_MAX,
|
|
||||||
semaphore->GetHandle(),
|
|
||||||
VK_NULL_HANDLE,
|
|
||||||
&imageIndex);
|
|
||||||
if (result == VK_ERROR_OUT_OF_DATE_KHR)
|
if (result == VK_ERROR_OUT_OF_DATE_KHR)
|
||||||
{
|
{
|
||||||
_semaphoreIndex = prevSemaphoreIndex;
|
_semaphoreIndex = prevSemaphoreIndex;
|
||||||
|
|||||||
@@ -16,6 +16,18 @@ constexpr char DirectorySeparatorChar = '\\';
|
|||||||
constexpr char AltDirectorySeparatorChar = '/';
|
constexpr char AltDirectorySeparatorChar = '/';
|
||||||
constexpr char VolumeSeparatorChar = ':';
|
constexpr char VolumeSeparatorChar = ':';
|
||||||
|
|
||||||
|
int32 StringUtils::Copy(char* dst, const Char* src, int32 count)
|
||||||
|
{
|
||||||
|
int32 i = 0;
|
||||||
|
while (i < count && src[i])
|
||||||
|
{
|
||||||
|
dst[i] = (char)src[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
dst[i] = 0;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
const Char* StringUtils::FindIgnoreCase(const Char* str, const Char* toFind)
|
const Char* StringUtils::FindIgnoreCase(const Char* str, const Char* toFind)
|
||||||
{
|
{
|
||||||
if (toFind == nullptr || str == nullptr)
|
if (toFind == nullptr || str == nullptr)
|
||||||
|
|||||||
@@ -125,6 +125,9 @@ public:
|
|||||||
// Copies the string (count is maximum amount of characters to copy).
|
// Copies the string (count is maximum amount of characters to copy).
|
||||||
static Char* Copy(Char* dst, const Char* src, int32 count);
|
static Char* Copy(Char* dst, const Char* src, int32 count);
|
||||||
|
|
||||||
|
// Copies the string (count is maximum amount of characters to copy). Returns amount of copied elements (excluding null terminator character).
|
||||||
|
static int32 Copy(char* dst, const Char* src, int32 count);
|
||||||
|
|
||||||
// Finds specific sub-string in the input string. Returns the first found position in the input string or nulll if failed.
|
// Finds specific sub-string in the input string. Returns the first found position in the input string or nulll if failed.
|
||||||
static const Char* Find(const Char* str, const Char* toFind);
|
static const Char* Find(const Char* str, const Char* toFind);
|
||||||
|
|
||||||
|
|||||||
@@ -1400,6 +1400,7 @@ TRACY_API LuaZoneState& GetLuaZoneState() { return s_luaZoneState; }
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
TRACY_API bool IsConnected() { return GetProfiler().IsConnected(); }
|
||||||
TRACY_API bool ProfilerAvailable() { return s_instance != nullptr; }
|
TRACY_API bool ProfilerAvailable() { return s_instance != nullptr; }
|
||||||
TRACY_API bool ProfilerAllocatorAvailable() { return !RpThreadShutdown; }
|
TRACY_API bool ProfilerAllocatorAvailable() { return !RpThreadShutdown; }
|
||||||
|
|
||||||
|
|||||||
690
Source/ThirdParty/tracy/common/TracyColor.hpp
vendored
Normal file
690
Source/ThirdParty/tracy/common/TracyColor.hpp
vendored
Normal file
@@ -0,0 +1,690 @@
|
|||||||
|
#ifndef __TRACYCOLOR_HPP__
|
||||||
|
#define __TRACYCOLOR_HPP__
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
struct Color
|
||||||
|
{
|
||||||
|
enum ColorType
|
||||||
|
{
|
||||||
|
Snow = 0xfffafa,
|
||||||
|
GhostWhite = 0xf8f8ff,
|
||||||
|
WhiteSmoke = 0xf5f5f5,
|
||||||
|
Gainsboro = 0xdcdcdc,
|
||||||
|
FloralWhite = 0xfffaf0,
|
||||||
|
OldLace = 0xfdf5e6,
|
||||||
|
Linen = 0xfaf0e6,
|
||||||
|
AntiqueWhite = 0xfaebd7,
|
||||||
|
PapayaWhip = 0xffefd5,
|
||||||
|
BlanchedAlmond = 0xffebcd,
|
||||||
|
Bisque = 0xffe4c4,
|
||||||
|
PeachPuff = 0xffdab9,
|
||||||
|
NavajoWhite = 0xffdead,
|
||||||
|
Moccasin = 0xffe4b5,
|
||||||
|
Cornsilk = 0xfff8dc,
|
||||||
|
Ivory = 0xfffff0,
|
||||||
|
LemonChiffon = 0xfffacd,
|
||||||
|
Seashell = 0xfff5ee,
|
||||||
|
Honeydew = 0xf0fff0,
|
||||||
|
MintCream = 0xf5fffa,
|
||||||
|
Azure = 0xf0ffff,
|
||||||
|
AliceBlue = 0xf0f8ff,
|
||||||
|
Lavender = 0xe6e6fa,
|
||||||
|
LavenderBlush = 0xfff0f5,
|
||||||
|
MistyRose = 0xffe4e1,
|
||||||
|
White = 0xffffff,
|
||||||
|
Black = 0x000000,
|
||||||
|
DarkSlateGray = 0x2f4f4f,
|
||||||
|
DarkSlateGrey = 0x2f4f4f,
|
||||||
|
DimGray = 0x696969,
|
||||||
|
DimGrey = 0x696969,
|
||||||
|
SlateGray = 0x708090,
|
||||||
|
SlateGrey = 0x708090,
|
||||||
|
LightSlateGray = 0x778899,
|
||||||
|
LightSlateGrey = 0x778899,
|
||||||
|
Gray = 0xbebebe,
|
||||||
|
Grey = 0xbebebe,
|
||||||
|
X11Gray = 0xbebebe,
|
||||||
|
X11Grey = 0xbebebe,
|
||||||
|
WebGray = 0x808080,
|
||||||
|
WebGrey = 0x808080,
|
||||||
|
LightGrey = 0xd3d3d3,
|
||||||
|
LightGray = 0xd3d3d3,
|
||||||
|
MidnightBlue = 0x191970,
|
||||||
|
Navy = 0x000080,
|
||||||
|
NavyBlue = 0x000080,
|
||||||
|
CornflowerBlue = 0x6495ed,
|
||||||
|
DarkSlateBlue = 0x483d8b,
|
||||||
|
SlateBlue = 0x6a5acd,
|
||||||
|
MediumSlateBlue = 0x7b68ee,
|
||||||
|
LightSlateBlue = 0x8470ff,
|
||||||
|
MediumBlue = 0x0000cd,
|
||||||
|
RoyalBlue = 0x4169e1,
|
||||||
|
Blue = 0x0000ff,
|
||||||
|
DodgerBlue = 0x1e90ff,
|
||||||
|
DeepSkyBlue = 0x00bfff,
|
||||||
|
SkyBlue = 0x87ceeb,
|
||||||
|
LightSkyBlue = 0x87cefa,
|
||||||
|
SteelBlue = 0x4682b4,
|
||||||
|
LightSteelBlue = 0xb0c4de,
|
||||||
|
LightBlue = 0xadd8e6,
|
||||||
|
PowderBlue = 0xb0e0e6,
|
||||||
|
PaleTurquoise = 0xafeeee,
|
||||||
|
DarkTurquoise = 0x00ced1,
|
||||||
|
MediumTurquoise = 0x48d1cc,
|
||||||
|
Turquoise = 0x40e0d0,
|
||||||
|
Cyan = 0x00ffff,
|
||||||
|
Aqua = 0x00ffff,
|
||||||
|
LightCyan = 0xe0ffff,
|
||||||
|
CadetBlue = 0x5f9ea0,
|
||||||
|
MediumAquamarine = 0x66cdaa,
|
||||||
|
Aquamarine = 0x7fffd4,
|
||||||
|
DarkGreen = 0x006400,
|
||||||
|
DarkOliveGreen = 0x556b2f,
|
||||||
|
DarkSeaGreen = 0x8fbc8f,
|
||||||
|
SeaGreen = 0x2e8b57,
|
||||||
|
MediumSeaGreen = 0x3cb371,
|
||||||
|
LightSeaGreen = 0x20b2aa,
|
||||||
|
PaleGreen = 0x98fb98,
|
||||||
|
SpringGreen = 0x00ff7f,
|
||||||
|
LawnGreen = 0x7cfc00,
|
||||||
|
Green = 0x00ff00,
|
||||||
|
Lime = 0x00ff00,
|
||||||
|
X11Green = 0x00ff00,
|
||||||
|
WebGreen = 0x008000,
|
||||||
|
Chartreuse = 0x7fff00,
|
||||||
|
MediumSpringGreen = 0x00fa9a,
|
||||||
|
GreenYellow = 0xadff2f,
|
||||||
|
LimeGreen = 0x32cd32,
|
||||||
|
YellowGreen = 0x9acd32,
|
||||||
|
ForestGreen = 0x228b22,
|
||||||
|
OliveDrab = 0x6b8e23,
|
||||||
|
DarkKhaki = 0xbdb76b,
|
||||||
|
Khaki = 0xf0e68c,
|
||||||
|
PaleGoldenrod = 0xeee8aa,
|
||||||
|
LightGoldenrodYellow = 0xfafad2,
|
||||||
|
LightYellow = 0xffffe0,
|
||||||
|
Yellow = 0xffff00,
|
||||||
|
Gold = 0xffd700,
|
||||||
|
LightGoldenrod = 0xeedd82,
|
||||||
|
Goldenrod = 0xdaa520,
|
||||||
|
DarkGoldenrod = 0xb8860b,
|
||||||
|
RosyBrown = 0xbc8f8f,
|
||||||
|
IndianRed = 0xcd5c5c,
|
||||||
|
SaddleBrown = 0x8b4513,
|
||||||
|
Sienna = 0xa0522d,
|
||||||
|
Peru = 0xcd853f,
|
||||||
|
Burlywood = 0xdeb887,
|
||||||
|
Beige = 0xf5f5dc,
|
||||||
|
Wheat = 0xf5deb3,
|
||||||
|
SandyBrown = 0xf4a460,
|
||||||
|
Tan = 0xd2b48c,
|
||||||
|
Chocolate = 0xd2691e,
|
||||||
|
Firebrick = 0xb22222,
|
||||||
|
Brown = 0xa52a2a,
|
||||||
|
DarkSalmon = 0xe9967a,
|
||||||
|
Salmon = 0xfa8072,
|
||||||
|
LightSalmon = 0xffa07a,
|
||||||
|
Orange = 0xffa500,
|
||||||
|
DarkOrange = 0xff8c00,
|
||||||
|
Coral = 0xff7f50,
|
||||||
|
LightCoral = 0xf08080,
|
||||||
|
Tomato = 0xff6347,
|
||||||
|
OrangeRed = 0xff4500,
|
||||||
|
Red = 0xff0000,
|
||||||
|
HotPink = 0xff69b4,
|
||||||
|
DeepPink = 0xff1493,
|
||||||
|
Pink = 0xffc0cb,
|
||||||
|
LightPink = 0xffb6c1,
|
||||||
|
PaleVioletRed = 0xdb7093,
|
||||||
|
Maroon = 0xb03060,
|
||||||
|
X11Maroon = 0xb03060,
|
||||||
|
WebMaroon = 0x800000,
|
||||||
|
MediumVioletRed = 0xc71585,
|
||||||
|
VioletRed = 0xd02090,
|
||||||
|
Magenta = 0xff00ff,
|
||||||
|
Fuchsia = 0xff00ff,
|
||||||
|
Violet = 0xee82ee,
|
||||||
|
Plum = 0xdda0dd,
|
||||||
|
Orchid = 0xda70d6,
|
||||||
|
MediumOrchid = 0xba55d3,
|
||||||
|
DarkOrchid = 0x9932cc,
|
||||||
|
DarkViolet = 0x9400d3,
|
||||||
|
BlueViolet = 0x8a2be2,
|
||||||
|
Purple = 0xa020f0,
|
||||||
|
X11Purple = 0xa020f0,
|
||||||
|
WebPurple = 0x800080,
|
||||||
|
MediumPurple = 0x9370db,
|
||||||
|
Thistle = 0xd8bfd8,
|
||||||
|
Snow1 = 0xfffafa,
|
||||||
|
Snow2 = 0xeee9e9,
|
||||||
|
Snow3 = 0xcdc9c9,
|
||||||
|
Snow4 = 0x8b8989,
|
||||||
|
Seashell1 = 0xfff5ee,
|
||||||
|
Seashell2 = 0xeee5de,
|
||||||
|
Seashell3 = 0xcdc5bf,
|
||||||
|
Seashell4 = 0x8b8682,
|
||||||
|
AntiqueWhite1 = 0xffefdb,
|
||||||
|
AntiqueWhite2 = 0xeedfcc,
|
||||||
|
AntiqueWhite3 = 0xcdc0b0,
|
||||||
|
AntiqueWhite4 = 0x8b8378,
|
||||||
|
Bisque1 = 0xffe4c4,
|
||||||
|
Bisque2 = 0xeed5b7,
|
||||||
|
Bisque3 = 0xcdb79e,
|
||||||
|
Bisque4 = 0x8b7d6b,
|
||||||
|
PeachPuff1 = 0xffdab9,
|
||||||
|
PeachPuff2 = 0xeecbad,
|
||||||
|
PeachPuff3 = 0xcdaf95,
|
||||||
|
PeachPuff4 = 0x8b7765,
|
||||||
|
NavajoWhite1 = 0xffdead,
|
||||||
|
NavajoWhite2 = 0xeecfa1,
|
||||||
|
NavajoWhite3 = 0xcdb38b,
|
||||||
|
NavajoWhite4 = 0x8b795e,
|
||||||
|
LemonChiffon1 = 0xfffacd,
|
||||||
|
LemonChiffon2 = 0xeee9bf,
|
||||||
|
LemonChiffon3 = 0xcdc9a5,
|
||||||
|
LemonChiffon4 = 0x8b8970,
|
||||||
|
Cornsilk1 = 0xfff8dc,
|
||||||
|
Cornsilk2 = 0xeee8cd,
|
||||||
|
Cornsilk3 = 0xcdc8b1,
|
||||||
|
Cornsilk4 = 0x8b8878,
|
||||||
|
Ivory1 = 0xfffff0,
|
||||||
|
Ivory2 = 0xeeeee0,
|
||||||
|
Ivory3 = 0xcdcdc1,
|
||||||
|
Ivory4 = 0x8b8b83,
|
||||||
|
Honeydew1 = 0xf0fff0,
|
||||||
|
Honeydew2 = 0xe0eee0,
|
||||||
|
Honeydew3 = 0xc1cdc1,
|
||||||
|
Honeydew4 = 0x838b83,
|
||||||
|
LavenderBlush1 = 0xfff0f5,
|
||||||
|
LavenderBlush2 = 0xeee0e5,
|
||||||
|
LavenderBlush3 = 0xcdc1c5,
|
||||||
|
LavenderBlush4 = 0x8b8386,
|
||||||
|
MistyRose1 = 0xffe4e1,
|
||||||
|
MistyRose2 = 0xeed5d2,
|
||||||
|
MistyRose3 = 0xcdb7b5,
|
||||||
|
MistyRose4 = 0x8b7d7b,
|
||||||
|
Azure1 = 0xf0ffff,
|
||||||
|
Azure2 = 0xe0eeee,
|
||||||
|
Azure3 = 0xc1cdcd,
|
||||||
|
Azure4 = 0x838b8b,
|
||||||
|
SlateBlue1 = 0x836fff,
|
||||||
|
SlateBlue2 = 0x7a67ee,
|
||||||
|
SlateBlue3 = 0x6959cd,
|
||||||
|
SlateBlue4 = 0x473c8b,
|
||||||
|
RoyalBlue1 = 0x4876ff,
|
||||||
|
RoyalBlue2 = 0x436eee,
|
||||||
|
RoyalBlue3 = 0x3a5fcd,
|
||||||
|
RoyalBlue4 = 0x27408b,
|
||||||
|
Blue1 = 0x0000ff,
|
||||||
|
Blue2 = 0x0000ee,
|
||||||
|
Blue3 = 0x0000cd,
|
||||||
|
Blue4 = 0x00008b,
|
||||||
|
DodgerBlue1 = 0x1e90ff,
|
||||||
|
DodgerBlue2 = 0x1c86ee,
|
||||||
|
DodgerBlue3 = 0x1874cd,
|
||||||
|
DodgerBlue4 = 0x104e8b,
|
||||||
|
SteelBlue1 = 0x63b8ff,
|
||||||
|
SteelBlue2 = 0x5cacee,
|
||||||
|
SteelBlue3 = 0x4f94cd,
|
||||||
|
SteelBlue4 = 0x36648b,
|
||||||
|
DeepSkyBlue1 = 0x00bfff,
|
||||||
|
DeepSkyBlue2 = 0x00b2ee,
|
||||||
|
DeepSkyBlue3 = 0x009acd,
|
||||||
|
DeepSkyBlue4 = 0x00688b,
|
||||||
|
SkyBlue1 = 0x87ceff,
|
||||||
|
SkyBlue2 = 0x7ec0ee,
|
||||||
|
SkyBlue3 = 0x6ca6cd,
|
||||||
|
SkyBlue4 = 0x4a708b,
|
||||||
|
LightSkyBlue1 = 0xb0e2ff,
|
||||||
|
LightSkyBlue2 = 0xa4d3ee,
|
||||||
|
LightSkyBlue3 = 0x8db6cd,
|
||||||
|
LightSkyBlue4 = 0x607b8b,
|
||||||
|
SlateGray1 = 0xc6e2ff,
|
||||||
|
SlateGray2 = 0xb9d3ee,
|
||||||
|
SlateGray3 = 0x9fb6cd,
|
||||||
|
SlateGray4 = 0x6c7b8b,
|
||||||
|
LightSteelBlue1 = 0xcae1ff,
|
||||||
|
LightSteelBlue2 = 0xbcd2ee,
|
||||||
|
LightSteelBlue3 = 0xa2b5cd,
|
||||||
|
LightSteelBlue4 = 0x6e7b8b,
|
||||||
|
LightBlue1 = 0xbfefff,
|
||||||
|
LightBlue2 = 0xb2dfee,
|
||||||
|
LightBlue3 = 0x9ac0cd,
|
||||||
|
LightBlue4 = 0x68838b,
|
||||||
|
LightCyan1 = 0xe0ffff,
|
||||||
|
LightCyan2 = 0xd1eeee,
|
||||||
|
LightCyan3 = 0xb4cdcd,
|
||||||
|
LightCyan4 = 0x7a8b8b,
|
||||||
|
PaleTurquoise1 = 0xbbffff,
|
||||||
|
PaleTurquoise2 = 0xaeeeee,
|
||||||
|
PaleTurquoise3 = 0x96cdcd,
|
||||||
|
PaleTurquoise4 = 0x668b8b,
|
||||||
|
CadetBlue1 = 0x98f5ff,
|
||||||
|
CadetBlue2 = 0x8ee5ee,
|
||||||
|
CadetBlue3 = 0x7ac5cd,
|
||||||
|
CadetBlue4 = 0x53868b,
|
||||||
|
Turquoise1 = 0x00f5ff,
|
||||||
|
Turquoise2 = 0x00e5ee,
|
||||||
|
Turquoise3 = 0x00c5cd,
|
||||||
|
Turquoise4 = 0x00868b,
|
||||||
|
Cyan1 = 0x00ffff,
|
||||||
|
Cyan2 = 0x00eeee,
|
||||||
|
Cyan3 = 0x00cdcd,
|
||||||
|
Cyan4 = 0x008b8b,
|
||||||
|
DarkSlateGray1 = 0x97ffff,
|
||||||
|
DarkSlateGray2 = 0x8deeee,
|
||||||
|
DarkSlateGray3 = 0x79cdcd,
|
||||||
|
DarkSlateGray4 = 0x528b8b,
|
||||||
|
Aquamarine1 = 0x7fffd4,
|
||||||
|
Aquamarine2 = 0x76eec6,
|
||||||
|
Aquamarine3 = 0x66cdaa,
|
||||||
|
Aquamarine4 = 0x458b74,
|
||||||
|
DarkSeaGreen1 = 0xc1ffc1,
|
||||||
|
DarkSeaGreen2 = 0xb4eeb4,
|
||||||
|
DarkSeaGreen3 = 0x9bcd9b,
|
||||||
|
DarkSeaGreen4 = 0x698b69,
|
||||||
|
SeaGreen1 = 0x54ff9f,
|
||||||
|
SeaGreen2 = 0x4eee94,
|
||||||
|
SeaGreen3 = 0x43cd80,
|
||||||
|
SeaGreen4 = 0x2e8b57,
|
||||||
|
PaleGreen1 = 0x9aff9a,
|
||||||
|
PaleGreen2 = 0x90ee90,
|
||||||
|
PaleGreen3 = 0x7ccd7c,
|
||||||
|
PaleGreen4 = 0x548b54,
|
||||||
|
SpringGreen1 = 0x00ff7f,
|
||||||
|
SpringGreen2 = 0x00ee76,
|
||||||
|
SpringGreen3 = 0x00cd66,
|
||||||
|
SpringGreen4 = 0x008b45,
|
||||||
|
Green1 = 0x00ff00,
|
||||||
|
Green2 = 0x00ee00,
|
||||||
|
Green3 = 0x00cd00,
|
||||||
|
Green4 = 0x008b00,
|
||||||
|
Chartreuse1 = 0x7fff00,
|
||||||
|
Chartreuse2 = 0x76ee00,
|
||||||
|
Chartreuse3 = 0x66cd00,
|
||||||
|
Chartreuse4 = 0x458b00,
|
||||||
|
OliveDrab1 = 0xc0ff3e,
|
||||||
|
OliveDrab2 = 0xb3ee3a,
|
||||||
|
OliveDrab3 = 0x9acd32,
|
||||||
|
OliveDrab4 = 0x698b22,
|
||||||
|
DarkOliveGreen1 = 0xcaff70,
|
||||||
|
DarkOliveGreen2 = 0xbcee68,
|
||||||
|
DarkOliveGreen3 = 0xa2cd5a,
|
||||||
|
DarkOliveGreen4 = 0x6e8b3d,
|
||||||
|
Khaki1 = 0xfff68f,
|
||||||
|
Khaki2 = 0xeee685,
|
||||||
|
Khaki3 = 0xcdc673,
|
||||||
|
Khaki4 = 0x8b864e,
|
||||||
|
LightGoldenrod1 = 0xffec8b,
|
||||||
|
LightGoldenrod2 = 0xeedc82,
|
||||||
|
LightGoldenrod3 = 0xcdbe70,
|
||||||
|
LightGoldenrod4 = 0x8b814c,
|
||||||
|
LightYellow1 = 0xffffe0,
|
||||||
|
LightYellow2 = 0xeeeed1,
|
||||||
|
LightYellow3 = 0xcdcdb4,
|
||||||
|
LightYellow4 = 0x8b8b7a,
|
||||||
|
Yellow1 = 0xffff00,
|
||||||
|
Yellow2 = 0xeeee00,
|
||||||
|
Yellow3 = 0xcdcd00,
|
||||||
|
Yellow4 = 0x8b8b00,
|
||||||
|
Gold1 = 0xffd700,
|
||||||
|
Gold2 = 0xeec900,
|
||||||
|
Gold3 = 0xcdad00,
|
||||||
|
Gold4 = 0x8b7500,
|
||||||
|
Goldenrod1 = 0xffc125,
|
||||||
|
Goldenrod2 = 0xeeb422,
|
||||||
|
Goldenrod3 = 0xcd9b1d,
|
||||||
|
Goldenrod4 = 0x8b6914,
|
||||||
|
DarkGoldenrod1 = 0xffb90f,
|
||||||
|
DarkGoldenrod2 = 0xeead0e,
|
||||||
|
DarkGoldenrod3 = 0xcd950c,
|
||||||
|
DarkGoldenrod4 = 0x8b6508,
|
||||||
|
RosyBrown1 = 0xffc1c1,
|
||||||
|
RosyBrown2 = 0xeeb4b4,
|
||||||
|
RosyBrown3 = 0xcd9b9b,
|
||||||
|
RosyBrown4 = 0x8b6969,
|
||||||
|
IndianRed1 = 0xff6a6a,
|
||||||
|
IndianRed2 = 0xee6363,
|
||||||
|
IndianRed3 = 0xcd5555,
|
||||||
|
IndianRed4 = 0x8b3a3a,
|
||||||
|
Sienna1 = 0xff8247,
|
||||||
|
Sienna2 = 0xee7942,
|
||||||
|
Sienna3 = 0xcd6839,
|
||||||
|
Sienna4 = 0x8b4726,
|
||||||
|
Burlywood1 = 0xffd39b,
|
||||||
|
Burlywood2 = 0xeec591,
|
||||||
|
Burlywood3 = 0xcdaa7d,
|
||||||
|
Burlywood4 = 0x8b7355,
|
||||||
|
Wheat1 = 0xffe7ba,
|
||||||
|
Wheat2 = 0xeed8ae,
|
||||||
|
Wheat3 = 0xcdba96,
|
||||||
|
Wheat4 = 0x8b7e66,
|
||||||
|
Tan1 = 0xffa54f,
|
||||||
|
Tan2 = 0xee9a49,
|
||||||
|
Tan3 = 0xcd853f,
|
||||||
|
Tan4 = 0x8b5a2b,
|
||||||
|
Chocolate1 = 0xff7f24,
|
||||||
|
Chocolate2 = 0xee7621,
|
||||||
|
Chocolate3 = 0xcd661d,
|
||||||
|
Chocolate4 = 0x8b4513,
|
||||||
|
Firebrick1 = 0xff3030,
|
||||||
|
Firebrick2 = 0xee2c2c,
|
||||||
|
Firebrick3 = 0xcd2626,
|
||||||
|
Firebrick4 = 0x8b1a1a,
|
||||||
|
Brown1 = 0xff4040,
|
||||||
|
Brown2 = 0xee3b3b,
|
||||||
|
Brown3 = 0xcd3333,
|
||||||
|
Brown4 = 0x8b2323,
|
||||||
|
Salmon1 = 0xff8c69,
|
||||||
|
Salmon2 = 0xee8262,
|
||||||
|
Salmon3 = 0xcd7054,
|
||||||
|
Salmon4 = 0x8b4c39,
|
||||||
|
LightSalmon1 = 0xffa07a,
|
||||||
|
LightSalmon2 = 0xee9572,
|
||||||
|
LightSalmon3 = 0xcd8162,
|
||||||
|
LightSalmon4 = 0x8b5742,
|
||||||
|
Orange1 = 0xffa500,
|
||||||
|
Orange2 = 0xee9a00,
|
||||||
|
Orange3 = 0xcd8500,
|
||||||
|
Orange4 = 0x8b5a00,
|
||||||
|
DarkOrange1 = 0xff7f00,
|
||||||
|
DarkOrange2 = 0xee7600,
|
||||||
|
DarkOrange3 = 0xcd6600,
|
||||||
|
DarkOrange4 = 0x8b4500,
|
||||||
|
Coral1 = 0xff7256,
|
||||||
|
Coral2 = 0xee6a50,
|
||||||
|
Coral3 = 0xcd5b45,
|
||||||
|
Coral4 = 0x8b3e2f,
|
||||||
|
Tomato1 = 0xff6347,
|
||||||
|
Tomato2 = 0xee5c42,
|
||||||
|
Tomato3 = 0xcd4f39,
|
||||||
|
Tomato4 = 0x8b3626,
|
||||||
|
OrangeRed1 = 0xff4500,
|
||||||
|
OrangeRed2 = 0xee4000,
|
||||||
|
OrangeRed3 = 0xcd3700,
|
||||||
|
OrangeRed4 = 0x8b2500,
|
||||||
|
Red1 = 0xff0000,
|
||||||
|
Red2 = 0xee0000,
|
||||||
|
Red3 = 0xcd0000,
|
||||||
|
Red4 = 0x8b0000,
|
||||||
|
DeepPink1 = 0xff1493,
|
||||||
|
DeepPink2 = 0xee1289,
|
||||||
|
DeepPink3 = 0xcd1076,
|
||||||
|
DeepPink4 = 0x8b0a50,
|
||||||
|
HotPink1 = 0xff6eb4,
|
||||||
|
HotPink2 = 0xee6aa7,
|
||||||
|
HotPink3 = 0xcd6090,
|
||||||
|
HotPink4 = 0x8b3a62,
|
||||||
|
Pink1 = 0xffb5c5,
|
||||||
|
Pink2 = 0xeea9b8,
|
||||||
|
Pink3 = 0xcd919e,
|
||||||
|
Pink4 = 0x8b636c,
|
||||||
|
LightPink1 = 0xffaeb9,
|
||||||
|
LightPink2 = 0xeea2ad,
|
||||||
|
LightPink3 = 0xcd8c95,
|
||||||
|
LightPink4 = 0x8b5f65,
|
||||||
|
PaleVioletRed1 = 0xff82ab,
|
||||||
|
PaleVioletRed2 = 0xee799f,
|
||||||
|
PaleVioletRed3 = 0xcd6889,
|
||||||
|
PaleVioletRed4 = 0x8b475d,
|
||||||
|
Maroon1 = 0xff34b3,
|
||||||
|
Maroon2 = 0xee30a7,
|
||||||
|
Maroon3 = 0xcd2990,
|
||||||
|
Maroon4 = 0x8b1c62,
|
||||||
|
VioletRed1 = 0xff3e96,
|
||||||
|
VioletRed2 = 0xee3a8c,
|
||||||
|
VioletRed3 = 0xcd3278,
|
||||||
|
VioletRed4 = 0x8b2252,
|
||||||
|
Magenta1 = 0xff00ff,
|
||||||
|
Magenta2 = 0xee00ee,
|
||||||
|
Magenta3 = 0xcd00cd,
|
||||||
|
Magenta4 = 0x8b008b,
|
||||||
|
Orchid1 = 0xff83fa,
|
||||||
|
Orchid2 = 0xee7ae9,
|
||||||
|
Orchid3 = 0xcd69c9,
|
||||||
|
Orchid4 = 0x8b4789,
|
||||||
|
Plum1 = 0xffbbff,
|
||||||
|
Plum2 = 0xeeaeee,
|
||||||
|
Plum3 = 0xcd96cd,
|
||||||
|
Plum4 = 0x8b668b,
|
||||||
|
MediumOrchid1 = 0xe066ff,
|
||||||
|
MediumOrchid2 = 0xd15fee,
|
||||||
|
MediumOrchid3 = 0xb452cd,
|
||||||
|
MediumOrchid4 = 0x7a378b,
|
||||||
|
DarkOrchid1 = 0xbf3eff,
|
||||||
|
DarkOrchid2 = 0xb23aee,
|
||||||
|
DarkOrchid3 = 0x9a32cd,
|
||||||
|
DarkOrchid4 = 0x68228b,
|
||||||
|
Purple1 = 0x9b30ff,
|
||||||
|
Purple2 = 0x912cee,
|
||||||
|
Purple3 = 0x7d26cd,
|
||||||
|
Purple4 = 0x551a8b,
|
||||||
|
MediumPurple1 = 0xab82ff,
|
||||||
|
MediumPurple2 = 0x9f79ee,
|
||||||
|
MediumPurple3 = 0x8968cd,
|
||||||
|
MediumPurple4 = 0x5d478b,
|
||||||
|
Thistle1 = 0xffe1ff,
|
||||||
|
Thistle2 = 0xeed2ee,
|
||||||
|
Thistle3 = 0xcdb5cd,
|
||||||
|
Thistle4 = 0x8b7b8b,
|
||||||
|
Gray0 = 0x000000,
|
||||||
|
Grey0 = 0x000000,
|
||||||
|
Gray1 = 0x030303,
|
||||||
|
Grey1 = 0x030303,
|
||||||
|
Gray2 = 0x050505,
|
||||||
|
Grey2 = 0x050505,
|
||||||
|
Gray3 = 0x080808,
|
||||||
|
Grey3 = 0x080808,
|
||||||
|
Gray4 = 0x0a0a0a,
|
||||||
|
Grey4 = 0x0a0a0a,
|
||||||
|
Gray5 = 0x0d0d0d,
|
||||||
|
Grey5 = 0x0d0d0d,
|
||||||
|
Gray6 = 0x0f0f0f,
|
||||||
|
Grey6 = 0x0f0f0f,
|
||||||
|
Gray7 = 0x121212,
|
||||||
|
Grey7 = 0x121212,
|
||||||
|
Gray8 = 0x141414,
|
||||||
|
Grey8 = 0x141414,
|
||||||
|
Gray9 = 0x171717,
|
||||||
|
Grey9 = 0x171717,
|
||||||
|
Gray10 = 0x1a1a1a,
|
||||||
|
Grey10 = 0x1a1a1a,
|
||||||
|
Gray11 = 0x1c1c1c,
|
||||||
|
Grey11 = 0x1c1c1c,
|
||||||
|
Gray12 = 0x1f1f1f,
|
||||||
|
Grey12 = 0x1f1f1f,
|
||||||
|
Gray13 = 0x212121,
|
||||||
|
Grey13 = 0x212121,
|
||||||
|
Gray14 = 0x242424,
|
||||||
|
Grey14 = 0x242424,
|
||||||
|
Gray15 = 0x262626,
|
||||||
|
Grey15 = 0x262626,
|
||||||
|
Gray16 = 0x292929,
|
||||||
|
Grey16 = 0x292929,
|
||||||
|
Gray17 = 0x2b2b2b,
|
||||||
|
Grey17 = 0x2b2b2b,
|
||||||
|
Gray18 = 0x2e2e2e,
|
||||||
|
Grey18 = 0x2e2e2e,
|
||||||
|
Gray19 = 0x303030,
|
||||||
|
Grey19 = 0x303030,
|
||||||
|
Gray20 = 0x333333,
|
||||||
|
Grey20 = 0x333333,
|
||||||
|
Gray21 = 0x363636,
|
||||||
|
Grey21 = 0x363636,
|
||||||
|
Gray22 = 0x383838,
|
||||||
|
Grey22 = 0x383838,
|
||||||
|
Gray23 = 0x3b3b3b,
|
||||||
|
Grey23 = 0x3b3b3b,
|
||||||
|
Gray24 = 0x3d3d3d,
|
||||||
|
Grey24 = 0x3d3d3d,
|
||||||
|
Gray25 = 0x404040,
|
||||||
|
Grey25 = 0x404040,
|
||||||
|
Gray26 = 0x424242,
|
||||||
|
Grey26 = 0x424242,
|
||||||
|
Gray27 = 0x454545,
|
||||||
|
Grey27 = 0x454545,
|
||||||
|
Gray28 = 0x474747,
|
||||||
|
Grey28 = 0x474747,
|
||||||
|
Gray29 = 0x4a4a4a,
|
||||||
|
Grey29 = 0x4a4a4a,
|
||||||
|
Gray30 = 0x4d4d4d,
|
||||||
|
Grey30 = 0x4d4d4d,
|
||||||
|
Gray31 = 0x4f4f4f,
|
||||||
|
Grey31 = 0x4f4f4f,
|
||||||
|
Gray32 = 0x525252,
|
||||||
|
Grey32 = 0x525252,
|
||||||
|
Gray33 = 0x545454,
|
||||||
|
Grey33 = 0x545454,
|
||||||
|
Gray34 = 0x575757,
|
||||||
|
Grey34 = 0x575757,
|
||||||
|
Gray35 = 0x595959,
|
||||||
|
Grey35 = 0x595959,
|
||||||
|
Gray36 = 0x5c5c5c,
|
||||||
|
Grey36 = 0x5c5c5c,
|
||||||
|
Gray37 = 0x5e5e5e,
|
||||||
|
Grey37 = 0x5e5e5e,
|
||||||
|
Gray38 = 0x616161,
|
||||||
|
Grey38 = 0x616161,
|
||||||
|
Gray39 = 0x636363,
|
||||||
|
Grey39 = 0x636363,
|
||||||
|
Gray40 = 0x666666,
|
||||||
|
Grey40 = 0x666666,
|
||||||
|
Gray41 = 0x696969,
|
||||||
|
Grey41 = 0x696969,
|
||||||
|
Gray42 = 0x6b6b6b,
|
||||||
|
Grey42 = 0x6b6b6b,
|
||||||
|
Gray43 = 0x6e6e6e,
|
||||||
|
Grey43 = 0x6e6e6e,
|
||||||
|
Gray44 = 0x707070,
|
||||||
|
Grey44 = 0x707070,
|
||||||
|
Gray45 = 0x737373,
|
||||||
|
Grey45 = 0x737373,
|
||||||
|
Gray46 = 0x757575,
|
||||||
|
Grey46 = 0x757575,
|
||||||
|
Gray47 = 0x787878,
|
||||||
|
Grey47 = 0x787878,
|
||||||
|
Gray48 = 0x7a7a7a,
|
||||||
|
Grey48 = 0x7a7a7a,
|
||||||
|
Gray49 = 0x7d7d7d,
|
||||||
|
Grey49 = 0x7d7d7d,
|
||||||
|
Gray50 = 0x7f7f7f,
|
||||||
|
Grey50 = 0x7f7f7f,
|
||||||
|
Gray51 = 0x828282,
|
||||||
|
Grey51 = 0x828282,
|
||||||
|
Gray52 = 0x858585,
|
||||||
|
Grey52 = 0x858585,
|
||||||
|
Gray53 = 0x878787,
|
||||||
|
Grey53 = 0x878787,
|
||||||
|
Gray54 = 0x8a8a8a,
|
||||||
|
Grey54 = 0x8a8a8a,
|
||||||
|
Gray55 = 0x8c8c8c,
|
||||||
|
Grey55 = 0x8c8c8c,
|
||||||
|
Gray56 = 0x8f8f8f,
|
||||||
|
Grey56 = 0x8f8f8f,
|
||||||
|
Gray57 = 0x919191,
|
||||||
|
Grey57 = 0x919191,
|
||||||
|
Gray58 = 0x949494,
|
||||||
|
Grey58 = 0x949494,
|
||||||
|
Gray59 = 0x969696,
|
||||||
|
Grey59 = 0x969696,
|
||||||
|
Gray60 = 0x999999,
|
||||||
|
Grey60 = 0x999999,
|
||||||
|
Gray61 = 0x9c9c9c,
|
||||||
|
Grey61 = 0x9c9c9c,
|
||||||
|
Gray62 = 0x9e9e9e,
|
||||||
|
Grey62 = 0x9e9e9e,
|
||||||
|
Gray63 = 0xa1a1a1,
|
||||||
|
Grey63 = 0xa1a1a1,
|
||||||
|
Gray64 = 0xa3a3a3,
|
||||||
|
Grey64 = 0xa3a3a3,
|
||||||
|
Gray65 = 0xa6a6a6,
|
||||||
|
Grey65 = 0xa6a6a6,
|
||||||
|
Gray66 = 0xa8a8a8,
|
||||||
|
Grey66 = 0xa8a8a8,
|
||||||
|
Gray67 = 0xababab,
|
||||||
|
Grey67 = 0xababab,
|
||||||
|
Gray68 = 0xadadad,
|
||||||
|
Grey68 = 0xadadad,
|
||||||
|
Gray69 = 0xb0b0b0,
|
||||||
|
Grey69 = 0xb0b0b0,
|
||||||
|
Gray70 = 0xb3b3b3,
|
||||||
|
Grey70 = 0xb3b3b3,
|
||||||
|
Gray71 = 0xb5b5b5,
|
||||||
|
Grey71 = 0xb5b5b5,
|
||||||
|
Gray72 = 0xb8b8b8,
|
||||||
|
Grey72 = 0xb8b8b8,
|
||||||
|
Gray73 = 0xbababa,
|
||||||
|
Grey73 = 0xbababa,
|
||||||
|
Gray74 = 0xbdbdbd,
|
||||||
|
Grey74 = 0xbdbdbd,
|
||||||
|
Gray75 = 0xbfbfbf,
|
||||||
|
Grey75 = 0xbfbfbf,
|
||||||
|
Gray76 = 0xc2c2c2,
|
||||||
|
Grey76 = 0xc2c2c2,
|
||||||
|
Gray77 = 0xc4c4c4,
|
||||||
|
Grey77 = 0xc4c4c4,
|
||||||
|
Gray78 = 0xc7c7c7,
|
||||||
|
Grey78 = 0xc7c7c7,
|
||||||
|
Gray79 = 0xc9c9c9,
|
||||||
|
Grey79 = 0xc9c9c9,
|
||||||
|
Gray80 = 0xcccccc,
|
||||||
|
Grey80 = 0xcccccc,
|
||||||
|
Gray81 = 0xcfcfcf,
|
||||||
|
Grey81 = 0xcfcfcf,
|
||||||
|
Gray82 = 0xd1d1d1,
|
||||||
|
Grey82 = 0xd1d1d1,
|
||||||
|
Gray83 = 0xd4d4d4,
|
||||||
|
Grey83 = 0xd4d4d4,
|
||||||
|
Gray84 = 0xd6d6d6,
|
||||||
|
Grey84 = 0xd6d6d6,
|
||||||
|
Gray85 = 0xd9d9d9,
|
||||||
|
Grey85 = 0xd9d9d9,
|
||||||
|
Gray86 = 0xdbdbdb,
|
||||||
|
Grey86 = 0xdbdbdb,
|
||||||
|
Gray87 = 0xdedede,
|
||||||
|
Grey87 = 0xdedede,
|
||||||
|
Gray88 = 0xe0e0e0,
|
||||||
|
Grey88 = 0xe0e0e0,
|
||||||
|
Gray89 = 0xe3e3e3,
|
||||||
|
Grey89 = 0xe3e3e3,
|
||||||
|
Gray90 = 0xe5e5e5,
|
||||||
|
Grey90 = 0xe5e5e5,
|
||||||
|
Gray91 = 0xe8e8e8,
|
||||||
|
Grey91 = 0xe8e8e8,
|
||||||
|
Gray92 = 0xebebeb,
|
||||||
|
Grey92 = 0xebebeb,
|
||||||
|
Gray93 = 0xededed,
|
||||||
|
Grey93 = 0xededed,
|
||||||
|
Gray94 = 0xf0f0f0,
|
||||||
|
Grey94 = 0xf0f0f0,
|
||||||
|
Gray95 = 0xf2f2f2,
|
||||||
|
Grey95 = 0xf2f2f2,
|
||||||
|
Gray96 = 0xf5f5f5,
|
||||||
|
Grey96 = 0xf5f5f5,
|
||||||
|
Gray97 = 0xf7f7f7,
|
||||||
|
Grey97 = 0xf7f7f7,
|
||||||
|
Gray98 = 0xfafafa,
|
||||||
|
Grey98 = 0xfafafa,
|
||||||
|
Gray99 = 0xfcfcfc,
|
||||||
|
Grey99 = 0xfcfcfc,
|
||||||
|
Gray100 = 0xffffff,
|
||||||
|
Grey100 = 0xffffff,
|
||||||
|
DarkGrey = 0xa9a9a9,
|
||||||
|
DarkGray = 0xa9a9a9,
|
||||||
|
DarkBlue = 0x00008b,
|
||||||
|
DarkCyan = 0x008b8b,
|
||||||
|
DarkMagenta = 0x8b008b,
|
||||||
|
DarkRed = 0x8b0000,
|
||||||
|
LightGreen = 0x90ee90,
|
||||||
|
Crimson = 0xdc143c,
|
||||||
|
Indigo = 0x4b0082,
|
||||||
|
Olive = 0x808000,
|
||||||
|
RebeccaPurple = 0x663399,
|
||||||
|
Silver = 0xc0c0c0,
|
||||||
|
Teal = 0x008080,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
17
Source/ThirdParty/tracy/common/TracySystem.cpp
vendored
17
Source/ThirdParty/tracy/common/TracySystem.cpp
vendored
@@ -351,3 +351,20 @@ TRACY_API void ___tracy_set_thread_name( const char* name ) { tracy::SetThreadNa
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Inset graphics integration (within Tracy module)
|
||||||
|
#define TRACY_GPU_IMPL 1
|
||||||
|
#if TRACY_GPU_D3D11
|
||||||
|
#include <ThirdParty/tracy/tracy/TracyD3D11.hpp>
|
||||||
|
static_assert(sizeof(tracy::D3D11ZoneScope) <= TracyD3D11ZoneSize, "Invalid zone size");
|
||||||
|
#endif
|
||||||
|
#if TRACY_GPU_D3D12
|
||||||
|
#include <ThirdParty/tracy/tracy/TracyD3D12.hpp>
|
||||||
|
static_assert(sizeof(tracy::D3D12ZoneScope) <= TracyD3D12ZoneSize, "Invalid zone size");
|
||||||
|
#endif
|
||||||
|
#if TRACY_GPU_VULKAN
|
||||||
|
#define GRAPHICS_API_VULKAN 1
|
||||||
|
#include "Engine/GraphicsDevice/Vulkan/IncludeVulkanHeaders.h"
|
||||||
|
#include <ThirdParty/tracy/tracy/TracyVulkan.hpp>
|
||||||
|
static_assert(sizeof(tracy::VkCtxScope) <= TracyVulkanZoneSize, "Invalid zone size");
|
||||||
|
#endif
|
||||||
|
|||||||
22
Source/ThirdParty/tracy/tracy.Build.cs
vendored
22
Source/ThirdParty/tracy/tracy.Build.cs
vendored
@@ -15,6 +15,11 @@ public class tracy : ThirdPartyModule
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static bool OnDemand = true;
|
public static bool OnDemand = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables GPU profiling.
|
||||||
|
/// </summary>
|
||||||
|
public static bool GPU = true;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Init()
|
public override void Init()
|
||||||
{
|
{
|
||||||
@@ -56,8 +61,25 @@ public class tracy : ThirdPartyModule
|
|||||||
options.PrivateDefinitions.Add("TRACY_USE_MALLOC");
|
options.PrivateDefinitions.Add("TRACY_USE_MALLOC");
|
||||||
options.PrivateDefinitions.Add("TRACY_ONLY_IPV4");
|
options.PrivateDefinitions.Add("TRACY_ONLY_IPV4");
|
||||||
options.PrivateDefinitions.Add("TRACY_NO_PIPE");
|
options.PrivateDefinitions.Add("TRACY_NO_PIPE");
|
||||||
|
options.PrivateDefinitions.Add("TRACY_NO_CODE_TRANSFER");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GPU)
|
||||||
|
{
|
||||||
|
// Ask Graphics module which graphics backends are active
|
||||||
|
var graphics = new Graphics();
|
||||||
|
graphics.FilePath = FilePath;
|
||||||
|
graphics.FolderPath = FolderPath;
|
||||||
|
var graphicsOptions = (BuildOptions)options.Clone();
|
||||||
|
graphics.Setup(graphicsOptions);
|
||||||
|
if (graphicsOptions.PrivateDependencies.Contains("GraphicsDeviceDX11"))
|
||||||
|
options.PrivateDefinitions.Add("TRACY_GPU_D3D11");
|
||||||
|
if (graphicsOptions.PrivateDependencies.Contains("GraphicsDeviceDX12"))
|
||||||
|
options.PrivateDefinitions.Add("TRACY_GPU_D3D12");
|
||||||
|
if (graphicsOptions.PrivateDependencies.Contains("GraphicsDeviceVulkan"))
|
||||||
|
options.PrivateDefinitions.Add("TRACY_GPU_VULKAN");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
5
Source/ThirdParty/tracy/tracy/Tracy.hpp
vendored
5
Source/ThirdParty/tracy/tracy/Tracy.hpp
vendored
@@ -119,6 +119,8 @@
|
|||||||
|
|
||||||
namespace tracy
|
namespace tracy
|
||||||
{
|
{
|
||||||
|
TRACY_API bool IsConnected();
|
||||||
|
|
||||||
class TRACY_API Profiler
|
class TRACY_API Profiler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -143,7 +145,6 @@ public:
|
|||||||
static void MemAllocCallstackNamed( const void* ptr, size_t size, int depth, bool secure, const char* name );
|
static void MemAllocCallstackNamed( const void* ptr, size_t size, int depth, bool secure, const char* name );
|
||||||
static void MemFreeCallstackNamed( const void* ptr, int depth, bool secure, const char* name );
|
static void MemFreeCallstackNamed( const void* ptr, int depth, bool secure, const char* name );
|
||||||
static void SendCallstack( int depth );
|
static void SendCallstack( int depth );
|
||||||
static void ParameterRegister( ParameterCallback cb );
|
|
||||||
static void ParameterRegister( ParameterCallback cb, void* data );
|
static void ParameterRegister( ParameterCallback cb, void* data );
|
||||||
static void ParameterSetup( uint32_t idx, const char* name, bool isBool, int32_t val );
|
static void ParameterSetup( uint32_t idx, const char* name, bool isBool, int32_t val );
|
||||||
};
|
};
|
||||||
@@ -255,7 +256,7 @@ public:
|
|||||||
#define TracySourceCallbackRegister( cb, data ) tracy::Profiler::SourceCallbackRegister( cb, data )
|
#define TracySourceCallbackRegister( cb, data ) tracy::Profiler::SourceCallbackRegister( cb, data )
|
||||||
#define TracyParameterRegister( cb, data ) tracy::Profiler::ParameterRegister( cb, data )
|
#define TracyParameterRegister( cb, data ) tracy::Profiler::ParameterRegister( cb, data )
|
||||||
#define TracyParameterSetup( idx, name, isBool, val ) tracy::Profiler::ParameterSetup( idx, name, isBool, val )
|
#define TracyParameterSetup( idx, name, isBool, val ) tracy::Profiler::ParameterSetup( idx, name, isBool, val )
|
||||||
#define TracyIsConnected tracy::GetProfiler().IsConnected()
|
#define TracyIsConnected tracy::IsConnected()
|
||||||
#define TracySetProgramName( name ) tracy::GetProfiler().SetProgramName( name );
|
#define TracySetProgramName( name ) tracy::GetProfiler().SetProgramName( name );
|
||||||
|
|
||||||
#ifdef TRACY_FIBERS
|
#ifdef TRACY_FIBERS
|
||||||
|
|||||||
456
Source/ThirdParty/tracy/tracy/TracyD3D11.hpp
vendored
Normal file
456
Source/ThirdParty/tracy/tracy/TracyD3D11.hpp
vendored
Normal file
@@ -0,0 +1,456 @@
|
|||||||
|
#ifndef __TRACYD3D11_HPP__
|
||||||
|
#define __TRACYD3D11_HPP__
|
||||||
|
|
||||||
|
#define TracyD3D11ZoneSize 16
|
||||||
|
|
||||||
|
#ifndef TRACY_ENABLE
|
||||||
|
|
||||||
|
#define TracyD3D11Context(device,queue) nullptr
|
||||||
|
#define TracyD3D11Destroy(ctx)
|
||||||
|
#define TracyD3D11ContextName(ctx, name, size)
|
||||||
|
|
||||||
|
#define TracyD3D11NewFrame(ctx)
|
||||||
|
|
||||||
|
#define TracyD3D11Zone(ctx, name)
|
||||||
|
#define TracyD3D11ZoneC(ctx, name, color)
|
||||||
|
#define TracyD3D11NamedZone(ctx, varname, name, active)
|
||||||
|
#define TracyD3D11NamedZoneC(ctx, varname, name, color, active)
|
||||||
|
#define TracyD3D11ZoneTransient(ctx, varname, name, active)
|
||||||
|
|
||||||
|
#define TracyD3D11ZoneS(ctx, name, depth)
|
||||||
|
#define TracyD3D11ZoneCS(ctx, name, color, depth)
|
||||||
|
#define TracyD3D11NamedZoneS(ctx, varname, name, depth, active)
|
||||||
|
#define TracyD3D11NamedZoneCS(ctx, varname, name, color, depth, active)
|
||||||
|
#define TracyD3D11ZoneTransientS(ctx, varname, name, depth, active)
|
||||||
|
|
||||||
|
#define TracyD3D11Collect(ctx)
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
class D3D11ZoneScope {};
|
||||||
|
}
|
||||||
|
|
||||||
|
using TracyD3D11Ctx = void*;
|
||||||
|
|
||||||
|
#elif TRACY_GPU_IMPL
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "../client/TracyProfiler.hpp"
|
||||||
|
#include "../client/TracyCallstack.hpp"
|
||||||
|
#include "../common/TracyYield.hpp"
|
||||||
|
#include "../common/TracyColor.hpp"
|
||||||
|
|
||||||
|
#include <d3d11.h>
|
||||||
|
|
||||||
|
#define TRACY_CALLSTACK 0
|
||||||
|
#define TracyMessageLC( txt, color ) tracy::Profiler::MessageColor( txt, color, TRACY_CALLSTACK )
|
||||||
|
#define TracyD3D11Panic(msg, ...) do { assert(false && "TracyD3D11: " msg); TracyMessageLC("TracyD3D11: " msg, tracy::Color::Red4); __VA_ARGS__; } while(false);
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
class D3D11Ctx
|
||||||
|
{
|
||||||
|
friend class D3D11ZoneScope;
|
||||||
|
|
||||||
|
static constexpr uint32_t MaxQueries = 64 * 1024;
|
||||||
|
|
||||||
|
enum CollectMode { POLL, BLOCK };
|
||||||
|
|
||||||
|
public:
|
||||||
|
tracy_force_inline D3D11Ctx( ID3D11Device* device, ID3D11DeviceContext* devicectx )
|
||||||
|
{
|
||||||
|
// TODO: consider calling ID3D11Device::GetImmediateContext() instead of passing it as an argument
|
||||||
|
m_device = device;
|
||||||
|
device->AddRef();
|
||||||
|
m_immediateDevCtx = devicectx;
|
||||||
|
devicectx->AddRef();
|
||||||
|
|
||||||
|
{
|
||||||
|
D3D11_QUERY_DESC desc = { };
|
||||||
|
desc.Query = D3D11_QUERY_TIMESTAMP_DISJOINT;
|
||||||
|
if (FAILED(m_device->CreateQuery(&desc, &m_disjointQuery)))
|
||||||
|
{
|
||||||
|
TracyD3D11Panic("unable to create disjoint timestamp query.", return);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ID3D11Query*& query : m_queries)
|
||||||
|
{
|
||||||
|
D3D11_QUERY_DESC desc = { };
|
||||||
|
desc.Query = D3D11_QUERY_TIMESTAMP;
|
||||||
|
if (FAILED(m_device->CreateQuery(&desc, &query)))
|
||||||
|
{
|
||||||
|
TracyD3D11Panic("unable to create timestamp query.", return);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calibrate CPU and GPU timestamps
|
||||||
|
int64_t tcpu = 0;
|
||||||
|
int64_t tgpu = 0;
|
||||||
|
for (int attempts = 0; attempts < 50; attempts++)
|
||||||
|
{
|
||||||
|
m_immediateDevCtx->Begin(m_disjointQuery);
|
||||||
|
m_immediateDevCtx->End(m_queries[0]);
|
||||||
|
m_immediateDevCtx->End(m_disjointQuery);
|
||||||
|
|
||||||
|
int64_t tcpu0 = Profiler::GetTime();
|
||||||
|
WaitForQuery(m_disjointQuery);
|
||||||
|
// NOTE: one would expect that by waiting for the enclosing disjoint query to finish,
|
||||||
|
// all timestamp queries within would also be readily available, but that does not
|
||||||
|
// seem to be the case here... See https://github.com/wolfpld/tracy/issues/947
|
||||||
|
WaitForQuery(m_queries[0]);
|
||||||
|
int64_t tcpu1 = Profiler::GetTime();
|
||||||
|
|
||||||
|
D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjoint = { };
|
||||||
|
if (m_immediateDevCtx->GetData(m_disjointQuery, &disjoint, sizeof(disjoint), 0) != S_OK)
|
||||||
|
{
|
||||||
|
TracyMessageLC("TracyD3D11: unable to query GPU timestamp; retrying...", tracy::Color::Tomato);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disjoint.Disjoint)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
UINT64 timestamp = 0;
|
||||||
|
if (m_immediateDevCtx->GetData(m_queries[0], ×tamp, sizeof(timestamp), 0) != S_OK)
|
||||||
|
continue; // this should never happen (we waited for the query to finish above)
|
||||||
|
|
||||||
|
tcpu = tcpu0 + (tcpu1 - tcpu0) * 1 / 2;
|
||||||
|
tgpu = timestamp * (1000000000 / disjoint.Frequency);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ready to roll
|
||||||
|
m_contextId = GetGpuCtxCounter().fetch_add(1);
|
||||||
|
m_immediateDevCtx->Begin(m_disjointQuery);
|
||||||
|
m_previousCheckpoint = m_nextCheckpoint = 0;
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuNewContext );
|
||||||
|
MemWrite( &item->gpuNewContext.cpuTime, tcpu );
|
||||||
|
MemWrite( &item->gpuNewContext.gpuTime, tgpu );
|
||||||
|
MemWrite( &item->gpuNewContext.thread, uint32_t(0) ); // #TODO: why not GetThreadHandle()?
|
||||||
|
MemWrite( &item->gpuNewContext.period, 1.0f );
|
||||||
|
MemWrite( &item->gpuNewContext.context, m_contextId);
|
||||||
|
MemWrite( &item->gpuNewContext.flags, uint8_t(0) );
|
||||||
|
MemWrite( &item->gpuNewContext.type, GpuContextType::Direct3D11 );
|
||||||
|
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
GetProfiler().DeferItem( *item );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline ~D3D11Ctx()
|
||||||
|
{
|
||||||
|
// collect all pending timestamps before destroying everything
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Collect(BLOCK);
|
||||||
|
} while (m_previousCheckpoint != m_queryCounter);
|
||||||
|
|
||||||
|
for (ID3D11Query* query : m_queries)
|
||||||
|
{
|
||||||
|
query->Release();
|
||||||
|
}
|
||||||
|
m_immediateDevCtx->End(m_disjointQuery);
|
||||||
|
m_disjointQuery->Release();
|
||||||
|
m_immediateDevCtx->Release();
|
||||||
|
m_device->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void Name( const char* name, uint16_t len )
|
||||||
|
{
|
||||||
|
auto ptr = (char*)tracy_malloc( len );
|
||||||
|
memcpy( ptr, name, len );
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuContextName );
|
||||||
|
MemWrite( &item->gpuContextNameFat.context, m_contextId );
|
||||||
|
MemWrite( &item->gpuContextNameFat.ptr, (uint64_t)ptr );
|
||||||
|
MemWrite( &item->gpuContextNameFat.size, len );
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
GetProfiler().DeferItem( *item );
|
||||||
|
#endif
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Collect(CollectMode mode = POLL)
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if( !GetProfiler().IsConnected() )
|
||||||
|
{
|
||||||
|
m_previousCheckpoint = m_nextCheckpoint = m_queryCounter;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (m_previousCheckpoint == m_nextCheckpoint)
|
||||||
|
{
|
||||||
|
uintptr_t nextCheckpoint = m_queryCounter;
|
||||||
|
if (nextCheckpoint == m_nextCheckpoint)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_nextCheckpoint = nextCheckpoint;
|
||||||
|
m_immediateDevCtx->End(m_disjointQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == CollectMode::BLOCK)
|
||||||
|
{
|
||||||
|
WaitForQuery(m_disjointQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjoint = { };
|
||||||
|
if (m_immediateDevCtx->GetData(m_disjointQuery, &disjoint, sizeof(disjoint), D3D11_ASYNC_GETDATA_DONOTFLUSH) != S_OK)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disjoint.Disjoint == TRUE)
|
||||||
|
{
|
||||||
|
m_previousCheckpoint = m_nextCheckpoint;
|
||||||
|
TracyD3D11Panic("disjoint timestamps detected; dropping.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto begin = m_previousCheckpoint;
|
||||||
|
auto end = m_nextCheckpoint;
|
||||||
|
for (auto i = begin; i != end; ++i)
|
||||||
|
{
|
||||||
|
uint32_t k = RingIndex(i);
|
||||||
|
UINT64 timestamp = 0;
|
||||||
|
if (m_immediateDevCtx->GetData(m_queries[k], ×tamp, sizeof(timestamp), 0) != S_OK)
|
||||||
|
{
|
||||||
|
TracyD3D11Panic("timestamp expected to be ready, but it was not!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
timestamp *= (1000000000ull / disjoint.Frequency);
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
MemWrite(&item->hdr.type, QueueType::GpuTime);
|
||||||
|
MemWrite(&item->gpuTime.gpuTime, static_cast<int64_t>(timestamp));
|
||||||
|
MemWrite(&item->gpuTime.queryId, static_cast<uint16_t>(k));
|
||||||
|
MemWrite(&item->gpuTime.context, m_contextId);
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
// disjoint timestamp queries should only be invoked once per frame or less
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/d3d11/ne-d3d11-d3d11_query
|
||||||
|
m_immediateDevCtx->Begin(m_disjointQuery);
|
||||||
|
m_previousCheckpoint = m_nextCheckpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
tracy_force_inline uint32_t RingIndex(uintptr_t index)
|
||||||
|
{
|
||||||
|
index %= MaxQueries;
|
||||||
|
return static_cast<uint32_t>(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline uint32_t RingCount(uintptr_t begin, uintptr_t end)
|
||||||
|
{
|
||||||
|
// wrap-around safe: all unsigned
|
||||||
|
uintptr_t count = end - begin;
|
||||||
|
return static_cast<uint32_t>(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline uint32_t NextQueryId()
|
||||||
|
{
|
||||||
|
auto id = m_queryCounter++;
|
||||||
|
if (RingCount(m_previousCheckpoint, id) >= MaxQueries)
|
||||||
|
{
|
||||||
|
TracyD3D11Panic("too many pending timestamp queries.");
|
||||||
|
// #TODO: return some sentinel value; ideally a "hidden" query index
|
||||||
|
}
|
||||||
|
return RingIndex(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline ID3D11Query* GetQueryObjectFromId(uint32_t id)
|
||||||
|
{
|
||||||
|
return m_queries[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void WaitForQuery(ID3D11Query* query)
|
||||||
|
{
|
||||||
|
m_immediateDevCtx->Flush();
|
||||||
|
while (m_immediateDevCtx->GetData(query, nullptr, 0, 0) != S_OK)
|
||||||
|
YieldThread(); // busy-wait :-( attempt to reduce power usage with _mm_pause() & friends...
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline uint8_t GetContextId() const
|
||||||
|
{
|
||||||
|
return m_contextId;
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D11Device* m_device = nullptr;
|
||||||
|
ID3D11DeviceContext* m_immediateDevCtx = nullptr;
|
||||||
|
|
||||||
|
ID3D11Query* m_queries[MaxQueries];
|
||||||
|
ID3D11Query* m_disjointQuery = nullptr;
|
||||||
|
|
||||||
|
uint8_t m_contextId = 255; // NOTE: apparently, 255 means invalid id; is this documented anywhere?
|
||||||
|
|
||||||
|
uintptr_t m_queryCounter = 0;
|
||||||
|
|
||||||
|
uintptr_t m_previousCheckpoint = 0;
|
||||||
|
uintptr_t m_nextCheckpoint = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class D3D11ZoneScope
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
tracy_force_inline D3D11ZoneScope( D3D11Ctx* ctx, const SourceLocationData* srcloc, bool active )
|
||||||
|
: D3D11ZoneScope(ctx, active)
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
WriteQueueItem(item, QueueType::GpuZoneBeginSerial, reinterpret_cast<uint64_t>(srcloc));
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline D3D11ZoneScope( D3D11Ctx* ctx, const SourceLocationData* srcloc, int32_t depth, bool active )
|
||||||
|
: D3D11ZoneScope(ctx, active)
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
|
||||||
|
if( depth > 0 && has_callstack() )
|
||||||
|
{
|
||||||
|
auto* item = Profiler::QueueSerialCallstack(Callstack(depth));
|
||||||
|
WriteQueueItem(item, QueueType::GpuZoneBeginCallstackSerial, reinterpret_cast<uint64_t>(srcloc));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
WriteQueueItem(item, QueueType::GpuZoneBeginSerial, reinterpret_cast<uint64_t>(srcloc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline D3D11ZoneScope(D3D11Ctx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, bool active)
|
||||||
|
: D3D11ZoneScope(ctx, active)
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
|
||||||
|
const auto sourceLocation = Profiler::AllocSourceLocation(line, source, sourceSz, function, functionSz, name, nameSz);
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
WriteQueueItem(item, QueueType::GpuZoneBeginAllocSrcLocSerial, sourceLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline D3D11ZoneScope(D3D11Ctx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, int32_t depth, bool active)
|
||||||
|
: D3D11ZoneScope(ctx, active)
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
|
||||||
|
const auto sourceLocation = Profiler::AllocSourceLocation(line, source, sourceSz, function, functionSz, name, nameSz);
|
||||||
|
|
||||||
|
if ( depth > 0 && has_callstack() )
|
||||||
|
{
|
||||||
|
auto* item = Profiler::QueueSerialCallstack(Callstack(depth));
|
||||||
|
WriteQueueItem(item, QueueType::GpuZoneBeginAllocSrcLocCallstackSerial, sourceLocation);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
WriteQueueItem(item, QueueType::GpuZoneBeginAllocSrcLocSerial, sourceLocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline ~D3D11ZoneScope()
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
|
||||||
|
const auto queryId = m_ctx->NextQueryId();
|
||||||
|
m_ctx->m_immediateDevCtx->End(m_ctx->GetQueryObjectFromId(queryId));
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuZoneEndSerial );
|
||||||
|
MemWrite( &item->gpuZoneEnd.cpuTime, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->gpuZoneEnd.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->gpuZoneEnd.queryId, uint16_t( queryId ) );
|
||||||
|
MemWrite( &item->gpuZoneEnd.context, m_ctx->GetContextId() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
tracy_force_inline D3D11ZoneScope( D3D11Ctx* ctx, bool active )
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active( active && GetProfiler().IsConnected() )
|
||||||
|
#else
|
||||||
|
: m_active( active )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
m_ctx = ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteQueueItem(tracy::QueueItem* item, tracy::QueueType queueItemType, uint64_t sourceLocation)
|
||||||
|
{
|
||||||
|
const auto queryId = m_ctx->NextQueryId();
|
||||||
|
m_ctx->m_immediateDevCtx->End(m_ctx->GetQueryObjectFromId(queryId));
|
||||||
|
|
||||||
|
MemWrite( &item->hdr.type, queueItemType);
|
||||||
|
MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.srcloc, sourceLocation );
|
||||||
|
MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) );
|
||||||
|
MemWrite( &item->gpuZoneBegin.context, m_ctx->GetContextId() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool m_active;
|
||||||
|
|
||||||
|
D3D11Ctx* m_ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
void* CreateD3D11Context( ID3D11Device* device, ID3D11DeviceContext* devicectx )
|
||||||
|
{
|
||||||
|
auto ctx = (D3D11Ctx*)tracy_malloc( sizeof( D3D11Ctx ) );
|
||||||
|
new(ctx) D3D11Ctx( device, devicectx );
|
||||||
|
ctx->Name("D3D11", 5);
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollectD3D11Context(void* ctx)
|
||||||
|
{
|
||||||
|
((D3D11Ctx*)ctx)->Collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyD3D11Context(void* ctx )
|
||||||
|
{
|
||||||
|
((D3D11Ctx*)ctx)->~D3D11Ctx();
|
||||||
|
tracy_free( ctx );
|
||||||
|
}
|
||||||
|
|
||||||
|
void BeginD3D11ZoneScope(void* zone, void* ctx, const char* name, size_t nameLen)
|
||||||
|
{
|
||||||
|
new(zone) tracy::D3D11ZoneScope{ (tracy::D3D11Ctx*)ctx, 0, 0, 0, 0, 0, name, nameLen, true };
|
||||||
|
}
|
||||||
|
|
||||||
|
void EndD3D11ZoneScope(void* zone)
|
||||||
|
{
|
||||||
|
((tracy::D3D11ZoneScope*)zone)->~D3D11ZoneScope();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef TracyD3D11Panic
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Forward declarations to be used in engine
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
extern void* CreateD3D11Context(ID3D11Device* device, ID3D11DeviceContext* devicectx);
|
||||||
|
extern void DestroyD3D11Context(void* ctx);
|
||||||
|
extern void CollectD3D11Context(void* ctx);
|
||||||
|
extern void BeginD3D11ZoneScope(void* zone, void* ctx, const char* name, size_t nameLen);
|
||||||
|
extern void EndD3D11ZoneScope(void* zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
529
Source/ThirdParty/tracy/tracy/TracyD3D12.hpp
vendored
Normal file
529
Source/ThirdParty/tracy/tracy/TracyD3D12.hpp
vendored
Normal file
@@ -0,0 +1,529 @@
|
|||||||
|
#ifndef __TRACYD3D12_HPP__
|
||||||
|
#define __TRACYD3D12_HPP__
|
||||||
|
|
||||||
|
#define TracyD3D12ZoneSize 32
|
||||||
|
|
||||||
|
#ifndef TRACY_ENABLE
|
||||||
|
|
||||||
|
#define TracyD3D12Context(device, queue) nullptr
|
||||||
|
#define TracyD3D12Destroy(ctx)
|
||||||
|
#define TracyD3D12ContextName(ctx, name, size)
|
||||||
|
|
||||||
|
#define TracyD3D12NewFrame(ctx)
|
||||||
|
|
||||||
|
#define TracyD3D12Zone(ctx, cmdList, name)
|
||||||
|
#define TracyD3D12ZoneC(ctx, cmdList, name, color)
|
||||||
|
#define TracyD3D12NamedZone(ctx, varname, cmdList, name, active)
|
||||||
|
#define TracyD3D12NamedZoneC(ctx, varname, cmdList, name, color, active)
|
||||||
|
#define TracyD3D12ZoneTransient(ctx, varname, cmdList, name, active)
|
||||||
|
|
||||||
|
#define TracyD3D12ZoneS(ctx, cmdList, name, depth)
|
||||||
|
#define TracyD3D12ZoneCS(ctx, cmdList, name, color, depth)
|
||||||
|
#define TracyD3D12NamedZoneS(ctx, varname, cmdList, name, depth, active)
|
||||||
|
#define TracyD3D12NamedZoneCS(ctx, varname, cmdList, name, color, depth, active)
|
||||||
|
#define TracyD3D12ZoneTransientS(ctx, varname, cmdList, name, depth, active)
|
||||||
|
|
||||||
|
#define TracyD3D12Collect(ctx)
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
class D3D12ZoneScope {};
|
||||||
|
}
|
||||||
|
|
||||||
|
using TracyD3D12Ctx = void*;
|
||||||
|
|
||||||
|
#elif TRACY_GPU_IMPL
|
||||||
|
|
||||||
|
#include "../client/TracyProfiler.hpp"
|
||||||
|
#include "../client/TracyProfiler.hpp"
|
||||||
|
#include "../client/TracyCallstack.hpp"
|
||||||
|
#include "../common/TracyColor.hpp"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cassert>
|
||||||
|
#include <d3d12.h>
|
||||||
|
#include <dxgi.h>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
#define TRACY_CALLSTACK 0
|
||||||
|
#define TracyMessageLC( txt, color ) tracy::Profiler::MessageColor( txt, color, TRACY_CALLSTACK )
|
||||||
|
#define TracyD3D12Panic(msg, ...) do { assert(false && "TracyD3D12: " msg); TracyMessageLC("TracyD3D12: " msg, tracy::Color::Red4); __VA_ARGS__; } while(false);
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
struct D3D12QueryPayload
|
||||||
|
{
|
||||||
|
uint32_t m_queryIdStart = 0;
|
||||||
|
uint32_t m_queryCount = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Command queue context.
|
||||||
|
class D3D12QueueCtx
|
||||||
|
{
|
||||||
|
friend class D3D12ZoneScope;
|
||||||
|
|
||||||
|
ID3D12Device* m_device = nullptr;
|
||||||
|
ID3D12CommandQueue* m_queue = nullptr;
|
||||||
|
uint8_t m_contextId = 255; // TODO: apparently, 255 means "invalid id"; is this documented somewhere?
|
||||||
|
ID3D12QueryHeap* m_queryHeap = nullptr;
|
||||||
|
ID3D12Resource* m_readbackBuffer = nullptr;
|
||||||
|
|
||||||
|
// In-progress payload.
|
||||||
|
uint32_t m_queryLimit = 0;
|
||||||
|
std::atomic<uint32_t> m_queryCounter = 0;
|
||||||
|
uint32_t m_previousQueryCounter = 0;
|
||||||
|
|
||||||
|
uint32_t m_activePayload = 0;
|
||||||
|
ID3D12Fence* m_payloadFence = nullptr;
|
||||||
|
std::queue<D3D12QueryPayload> m_payloadQueue;
|
||||||
|
|
||||||
|
UINT64 m_prevCalibrationTicksCPU = 0;
|
||||||
|
|
||||||
|
void RecalibrateClocks()
|
||||||
|
{
|
||||||
|
UINT64 cpuTimestamp;
|
||||||
|
UINT64 gpuTimestamp;
|
||||||
|
if (FAILED(m_queue->GetClockCalibration(&gpuTimestamp, &cpuTimestamp)))
|
||||||
|
{
|
||||||
|
TracyD3D12Panic("failed to obtain queue clock calibration counters.", return);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t cpuDeltaTicks = cpuTimestamp - m_prevCalibrationTicksCPU;
|
||||||
|
if (cpuDeltaTicks > 0)
|
||||||
|
{
|
||||||
|
static const int64_t nanosecodsPerTick = int64_t(1000000000) / GetFrequencyQpc();
|
||||||
|
int64_t cpuDeltaNS = cpuDeltaTicks * nanosecodsPerTick;
|
||||||
|
// Save the device cpu timestamp, not the Tracy profiler timestamp:
|
||||||
|
m_prevCalibrationTicksCPU = cpuTimestamp;
|
||||||
|
|
||||||
|
cpuTimestamp = Profiler::GetTime();
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
MemWrite(&item->hdr.type, QueueType::GpuCalibration);
|
||||||
|
MemWrite(&item->gpuCalibration.gpuTime, gpuTimestamp);
|
||||||
|
MemWrite(&item->gpuCalibration.cpuTime, cpuTimestamp);
|
||||||
|
MemWrite(&item->gpuCalibration.cpuDelta, cpuDeltaNS);
|
||||||
|
MemWrite(&item->gpuCalibration.context, GetId());
|
||||||
|
SubmitQueueItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void SubmitQueueItem(tracy::QueueItem* item)
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
GetProfiler().DeferItem(*item);
|
||||||
|
#endif
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
D3D12QueueCtx(ID3D12Device* device, ID3D12CommandQueue* queue)
|
||||||
|
: m_device(device)
|
||||||
|
, m_queue(queue)
|
||||||
|
{
|
||||||
|
// Verify we support timestamp queries on this queue.
|
||||||
|
|
||||||
|
if (queue->GetDesc().Type == D3D12_COMMAND_LIST_TYPE_COPY)
|
||||||
|
{
|
||||||
|
D3D12_FEATURE_DATA_D3D12_OPTIONS3 featureData{};
|
||||||
|
|
||||||
|
HRESULT hr = device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS3, &featureData, sizeof(featureData));
|
||||||
|
if (FAILED(hr) || (featureData.CopyQueueTimestampQueriesSupported == FALSE))
|
||||||
|
{
|
||||||
|
TracyD3D12Panic("Platform does not support profiling of copy queues.", return);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint32_t MaxQueries = 64 * 1024; // Must be even, because queries are (begin, end) pairs
|
||||||
|
m_queryLimit = MaxQueries;
|
||||||
|
|
||||||
|
D3D12_QUERY_HEAP_DESC heapDesc{};
|
||||||
|
heapDesc.Type = queue->GetDesc().Type == D3D12_COMMAND_LIST_TYPE_COPY ? D3D12_QUERY_HEAP_TYPE_COPY_QUEUE_TIMESTAMP : D3D12_QUERY_HEAP_TYPE_TIMESTAMP;
|
||||||
|
heapDesc.Count = m_queryLimit;
|
||||||
|
heapDesc.NodeMask = 0; // #TODO: Support multiple adapters.
|
||||||
|
|
||||||
|
while (FAILED(device->CreateQueryHeap(&heapDesc, IID_PPV_ARGS(&m_queryHeap))))
|
||||||
|
{
|
||||||
|
m_queryLimit /= 2;
|
||||||
|
heapDesc.Count = m_queryLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a readback buffer, which will be used as a destination for the query data.
|
||||||
|
|
||||||
|
D3D12_RESOURCE_DESC readbackBufferDesc{};
|
||||||
|
readbackBufferDesc.Alignment = 0;
|
||||||
|
readbackBufferDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||||
|
readbackBufferDesc.Width = m_queryLimit * sizeof(uint64_t);
|
||||||
|
readbackBufferDesc.Height = 1;
|
||||||
|
readbackBufferDesc.DepthOrArraySize = 1;
|
||||||
|
readbackBufferDesc.Format = DXGI_FORMAT_UNKNOWN;
|
||||||
|
readbackBufferDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; // Buffers are always row major.
|
||||||
|
readbackBufferDesc.MipLevels = 1;
|
||||||
|
readbackBufferDesc.SampleDesc.Count = 1;
|
||||||
|
readbackBufferDesc.SampleDesc.Quality = 0;
|
||||||
|
readbackBufferDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||||
|
|
||||||
|
D3D12_HEAP_PROPERTIES readbackHeapProps{};
|
||||||
|
readbackHeapProps.Type = D3D12_HEAP_TYPE_READBACK;
|
||||||
|
readbackHeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||||
|
readbackHeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||||
|
readbackHeapProps.CreationNodeMask = 0;
|
||||||
|
readbackHeapProps.VisibleNodeMask = 0; // #TODO: Support multiple adapters.
|
||||||
|
|
||||||
|
if (FAILED(device->CreateCommittedResource(&readbackHeapProps, D3D12_HEAP_FLAG_NONE, &readbackBufferDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_readbackBuffer))))
|
||||||
|
{
|
||||||
|
TracyD3D12Panic("Failed to create query readback buffer.", return);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_payloadFence))))
|
||||||
|
{
|
||||||
|
TracyD3D12Panic("Failed to create payload fence.", return);
|
||||||
|
}
|
||||||
|
|
||||||
|
float period = [queue]()
|
||||||
|
{
|
||||||
|
uint64_t timestampFrequency;
|
||||||
|
if (FAILED(queue->GetTimestampFrequency(×tampFrequency)))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
return static_cast<float>( 1E+09 / static_cast<double>(timestampFrequency) );
|
||||||
|
}();
|
||||||
|
|
||||||
|
if (period == 0.0f)
|
||||||
|
{
|
||||||
|
TracyD3D12Panic("Failed to get timestamp frequency.", return);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t cpuTimestamp;
|
||||||
|
uint64_t gpuTimestamp;
|
||||||
|
if (FAILED(queue->GetClockCalibration(&gpuTimestamp, &cpuTimestamp)))
|
||||||
|
{
|
||||||
|
TracyD3D12Panic("Failed to get queue clock calibration.", return);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the device cpu timestamp, not the profiler's timestamp.
|
||||||
|
m_prevCalibrationTicksCPU = cpuTimestamp;
|
||||||
|
|
||||||
|
cpuTimestamp = Profiler::GetTime();
|
||||||
|
|
||||||
|
// all checked: ready to roll
|
||||||
|
m_contextId = GetGpuCtxCounter().fetch_add(1);
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
MemWrite(&item->hdr.type, QueueType::GpuNewContext);
|
||||||
|
MemWrite(&item->gpuNewContext.cpuTime, cpuTimestamp);
|
||||||
|
MemWrite(&item->gpuNewContext.gpuTime, gpuTimestamp);
|
||||||
|
MemWrite(&item->gpuNewContext.thread, decltype(item->gpuNewContext.thread)(0)); // #TODO: why 0 instead of GetThreadHandle()?
|
||||||
|
MemWrite(&item->gpuNewContext.period, period);
|
||||||
|
MemWrite(&item->gpuNewContext.context, GetId());
|
||||||
|
MemWrite(&item->gpuNewContext.flags, GpuContextCalibration);
|
||||||
|
MemWrite(&item->gpuNewContext.type, GpuContextType::Direct3D12);
|
||||||
|
SubmitQueueItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
~D3D12QueueCtx()
|
||||||
|
{
|
||||||
|
// collect all pending timestamps
|
||||||
|
while (m_payloadFence->GetCompletedValue() != m_activePayload)
|
||||||
|
/* busy-wait ... */;
|
||||||
|
Collect();
|
||||||
|
m_payloadFence->Release();
|
||||||
|
m_readbackBuffer->Release();
|
||||||
|
m_queryHeap->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NewFrame()
|
||||||
|
{
|
||||||
|
uint32_t queryCounter = m_queryCounter.exchange(0);
|
||||||
|
m_payloadQueue.emplace(D3D12QueryPayload{ m_previousQueryCounter, queryCounter });
|
||||||
|
m_previousQueryCounter += queryCounter;
|
||||||
|
|
||||||
|
if (m_previousQueryCounter >= m_queryLimit)
|
||||||
|
{
|
||||||
|
m_previousQueryCounter -= m_queryLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_queue->Signal(m_payloadFence, ++m_activePayload);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Name( const char* name, uint16_t len )
|
||||||
|
{
|
||||||
|
auto ptr = (char*)tracy_malloc( len );
|
||||||
|
memcpy( ptr, name, len );
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuContextName );
|
||||||
|
MemWrite( &item->gpuContextNameFat.context, GetId());
|
||||||
|
MemWrite( &item->gpuContextNameFat.ptr, (uint64_t)ptr );
|
||||||
|
MemWrite( &item->gpuContextNameFat.size, len );
|
||||||
|
SubmitQueueItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Collect()
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if (!GetProfiler().IsConnected())
|
||||||
|
{
|
||||||
|
m_queryCounter = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Find out what payloads are available.
|
||||||
|
const auto newestReadyPayload = m_payloadFence->GetCompletedValue();
|
||||||
|
const auto payloadCount = m_payloadQueue.size() - (m_activePayload - newestReadyPayload);
|
||||||
|
|
||||||
|
if (!payloadCount)
|
||||||
|
{
|
||||||
|
return; // No payloads are available yet, exit out.
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12_RANGE mapRange{ 0, m_queryLimit * sizeof(uint64_t) };
|
||||||
|
|
||||||
|
// Map the readback buffer so we can fetch the query data from the GPU.
|
||||||
|
void* readbackBufferMapping = nullptr;
|
||||||
|
|
||||||
|
if (FAILED(m_readbackBuffer->Map(0, &mapRange, &readbackBufferMapping)))
|
||||||
|
{
|
||||||
|
TracyD3D12Panic("Failed to map readback buffer.", return);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* timestampData = static_cast<uint64_t*>(readbackBufferMapping);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < payloadCount; ++i)
|
||||||
|
{
|
||||||
|
const auto& payload = m_payloadQueue.front();
|
||||||
|
|
||||||
|
for (uint32_t j = 0; j < payload.m_queryCount; ++j)
|
||||||
|
{
|
||||||
|
const auto counter = (payload.m_queryIdStart + j) % m_queryLimit;
|
||||||
|
const auto timestamp = timestampData[counter];
|
||||||
|
const auto queryId = counter;
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
MemWrite(&item->hdr.type, QueueType::GpuTime);
|
||||||
|
MemWrite(&item->gpuTime.gpuTime, timestamp);
|
||||||
|
MemWrite(&item->gpuTime.queryId, static_cast<uint16_t>(queryId));
|
||||||
|
MemWrite(&item->gpuTime.context, GetId());
|
||||||
|
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_payloadQueue.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_readbackBuffer->Unmap(0, nullptr);
|
||||||
|
|
||||||
|
// Recalibrate to account for drift.
|
||||||
|
RecalibrateClocks();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
tracy_force_inline uint32_t NextQueryId()
|
||||||
|
{
|
||||||
|
uint32_t queryCounter = m_queryCounter.fetch_add(2);
|
||||||
|
if (queryCounter >= m_queryLimit)
|
||||||
|
{
|
||||||
|
TracyD3D12Panic("Submitted too many GPU queries! Consider increasing MaxQueries.");
|
||||||
|
// #TODO: consider returning an invalid id or sentinel value here
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t id = (m_previousQueryCounter + queryCounter) % m_queryLimit;
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline uint8_t GetId() const
|
||||||
|
{
|
||||||
|
return m_contextId;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class D3D12ZoneScope
|
||||||
|
{
|
||||||
|
const bool m_active;
|
||||||
|
D3D12QueueCtx* m_ctx = nullptr;
|
||||||
|
ID3D12GraphicsCommandList* m_cmdList = nullptr;
|
||||||
|
uint32_t m_queryId = 0; // Used for tracking in nested zones.
|
||||||
|
|
||||||
|
tracy_force_inline void WriteQueueItem(QueueItem* item, QueueType type, uint64_t srcLocation)
|
||||||
|
{
|
||||||
|
MemWrite(&item->hdr.type, type);
|
||||||
|
MemWrite(&item->gpuZoneBegin.cpuTime, Profiler::GetTime());
|
||||||
|
MemWrite(&item->gpuZoneBegin.srcloc, srcLocation);
|
||||||
|
MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle());
|
||||||
|
MemWrite(&item->gpuZoneBegin.queryId, static_cast<uint16_t>(m_queryId));
|
||||||
|
MemWrite(&item->gpuZoneBegin.context, m_ctx->GetId());
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, ID3D12GraphicsCommandList* cmdList, bool active)
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active(active&& GetProfiler().IsConnected())
|
||||||
|
#else
|
||||||
|
: m_active(active)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (!m_active) return;
|
||||||
|
|
||||||
|
m_ctx = ctx;
|
||||||
|
m_cmdList = cmdList;
|
||||||
|
|
||||||
|
m_queryId = m_ctx->NextQueryId();
|
||||||
|
m_cmdList->EndQuery(m_ctx->m_queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, m_queryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, ID3D12GraphicsCommandList* cmdList, const SourceLocationData* srcLocation, bool active)
|
||||||
|
: D3D12ZoneScope(ctx, cmdList, active)
|
||||||
|
{
|
||||||
|
if (!m_active) return;
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
WriteQueueItem(item, QueueType::GpuZoneBeginSerial, reinterpret_cast<uint64_t>(srcLocation));
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, ID3D12GraphicsCommandList* cmdList, const SourceLocationData* srcLocation, int32_t depth, bool active)
|
||||||
|
: D3D12ZoneScope(ctx, cmdList, active)
|
||||||
|
{
|
||||||
|
if (!m_active) return;
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerialCallstack(Callstack(depth));
|
||||||
|
WriteQueueItem(item, QueueType::GpuZoneBeginCallstackSerial, reinterpret_cast<uint64_t>(srcLocation));
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, ID3D12GraphicsCommandList* cmdList, bool active)
|
||||||
|
: D3D12ZoneScope(ctx, cmdList, active)
|
||||||
|
{
|
||||||
|
if (!m_active) return;
|
||||||
|
|
||||||
|
const auto sourceLocation = Profiler::AllocSourceLocation(line, source, sourceSz, function, functionSz, name, nameSz);
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
WriteQueueItem(item, QueueType::GpuZoneBeginAllocSrcLocSerial, sourceLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, ID3D12GraphicsCommandList* cmdList, int32_t depth, bool active)
|
||||||
|
: D3D12ZoneScope(ctx, cmdList, active)
|
||||||
|
{
|
||||||
|
if (!m_active) return;
|
||||||
|
|
||||||
|
const auto sourceLocation = Profiler::AllocSourceLocation(line, source, sourceSz, function, functionSz, name, nameSz);
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerialCallstack(Callstack(depth));
|
||||||
|
WriteQueueItem(item, QueueType::GpuZoneBeginAllocSrcLocCallstackSerial, sourceLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline ~D3D12ZoneScope()
|
||||||
|
{
|
||||||
|
if (!m_active) return;
|
||||||
|
|
||||||
|
const auto queryId = m_queryId + 1; // Our end query slot is immediately after the begin slot.
|
||||||
|
m_cmdList->EndQuery(m_ctx->m_queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, queryId);
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
MemWrite(&item->hdr.type, QueueType::GpuZoneEndSerial);
|
||||||
|
MemWrite(&item->gpuZoneEnd.cpuTime, Profiler::GetTime());
|
||||||
|
MemWrite(&item->gpuZoneEnd.thread, GetThreadHandle());
|
||||||
|
MemWrite(&item->gpuZoneEnd.queryId, static_cast<uint16_t>(queryId));
|
||||||
|
MemWrite(&item->gpuZoneEnd.context, m_ctx->GetId());
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
|
||||||
|
m_cmdList->ResolveQueryData(m_ctx->m_queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, m_queryId, 2, m_ctx->m_readbackBuffer, m_queryId * sizeof(uint64_t));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void* CreateD3D12Context(ID3D12Device* device, ID3D12CommandQueue* queue)
|
||||||
|
{
|
||||||
|
auto* ctx = static_cast<D3D12QueueCtx*>(tracy_malloc(sizeof(D3D12QueueCtx)));
|
||||||
|
new (ctx) D3D12QueueCtx{ device, queue };
|
||||||
|
ctx->Name("D3D12", 5);
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollectD3D12Context(void* ctx)
|
||||||
|
{
|
||||||
|
((D3D12QueueCtx*)ctx)->Collect();
|
||||||
|
((D3D12QueueCtx*)ctx)->NewFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyD3D12Context(void* ctx)
|
||||||
|
{
|
||||||
|
((D3D12QueueCtx*)ctx)->~D3D12QueueCtx();
|
||||||
|
tracy_free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BeginD3D12ZoneScope(void* zone, void* ctx, ID3D12GraphicsCommandList* cmdList, const char* name, size_t nameLen)
|
||||||
|
{
|
||||||
|
new(zone) tracy::D3D12ZoneScope{ (tracy::D3D12QueueCtx*)ctx, 0, 0, 0, 0, 0, name, nameLen, cmdList, true };
|
||||||
|
}
|
||||||
|
|
||||||
|
void EndD3D12ZoneScope(void* zone)
|
||||||
|
{
|
||||||
|
((tracy::D3D12ZoneScope*)zone)->~D3D12ZoneScope();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef TracyD3D12Panic
|
||||||
|
|
||||||
|
using TracyD3D12Ctx = tracy::D3D12QueueCtx*;
|
||||||
|
|
||||||
|
#define TracyD3D12Context(device, queue) tracy::CreateD3D12Context(device, queue);
|
||||||
|
#define TracyD3D12Destroy(ctx) tracy::DestroyD3D12Context(ctx);
|
||||||
|
#define TracyD3D12ContextName(ctx, name, size) ctx->Name(name, size);
|
||||||
|
|
||||||
|
#define TracyD3D12NewFrame(ctx) ctx->NewFrame();
|
||||||
|
|
||||||
|
#define TracyD3D12UnnamedZone ___tracy_gpu_d3d12_zone
|
||||||
|
#define TracyD3D12SrcLocSymbol TracyConcat(__tracy_d3d12_source_location,TracyLine)
|
||||||
|
#define TracyD3D12SrcLocObject(name, color) static constexpr tracy::SourceLocationData TracyD3D12SrcLocSymbol { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color };
|
||||||
|
|
||||||
|
#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
|
||||||
|
# define TracyD3D12Zone(ctx, cmdList, name) TracyD3D12NamedZoneS(ctx, TracyD3D12UnnamedZone, cmdList, name, TRACY_CALLSTACK, true)
|
||||||
|
# define TracyD3D12ZoneC(ctx, cmdList, name, color) TracyD3D12NamedZoneCS(ctx, TracyD3D12UnnamedZone, cmdList, name, color, TRACY_CALLSTACK, true)
|
||||||
|
# define TracyD3D12NamedZone(ctx, varname, cmdList, name, active) TracyD3D12SrcLocObject(name, 0); tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyD3D12SrcLocSymbol, TRACY_CALLSTACK, active };
|
||||||
|
# define TracyD3D12NamedZoneC(ctx, varname, cmdList, name, color, active) TracyD3D12SrcLocObject(name, color); tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyD3D12SrcLocSymbol, TRACY_CALLSTACK, active };
|
||||||
|
# define TracyD3D12ZoneTransient(ctx, varname, cmdList, name, active) TracyD3D12ZoneTransientS(ctx, varname, cmdList, name, TRACY_CALLSTACK, active)
|
||||||
|
#else
|
||||||
|
# define TracyD3D12Zone(ctx, cmdList, name) TracyD3D12NamedZone(ctx, TracyD3D12UnnamedZone, cmdList, name, true)
|
||||||
|
# define TracyD3D12ZoneC(ctx, cmdList, name, color) TracyD3D12NamedZoneC(ctx, TracyD3D12UnnamedZone, cmdList, name, color, true)
|
||||||
|
# define TracyD3D12NamedZone(ctx, varname, cmdList, name, active) TracyD3D12SrcLocObject(name, 0); tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyD3D12SrcLocSymbol, active };
|
||||||
|
# define TracyD3D12NamedZoneC(ctx, varname, cmdList, name, color, active) TracyD3D12SrcLocObject(name, color); tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyD3D12SrcLocSymbol, active };
|
||||||
|
# define TracyD3D12ZoneTransient(ctx, varname, cmdList, name, active) tracy::D3D12ZoneScope varname{ ctx, TracyLine, TracyFile, strlen(TracyFile), TracyFunction, strlen(TracyFunction), name, strlen(name), cmdList, active };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TRACY_HAS_CALLSTACK
|
||||||
|
# define TracyD3D12ZoneS(ctx, cmdList, name, depth) TracyD3D12NamedZoneS(ctx, TracyD3D12UnnamedZone, cmdList, name, depth, true)
|
||||||
|
# define TracyD3D12ZoneCS(ctx, cmdList, name, color, depth) TracyD3D12NamedZoneCS(ctx, TracyD3D12UnnamedZone, cmdList, name, color, depth, true)
|
||||||
|
# define TracyD3D12NamedZoneS(ctx, varname, cmdList, name, depth, active) TracyD3D12SrcLocObject(name, 0); tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyD3D12SrcLocSymbol, depth, active };
|
||||||
|
# define TracyD3D12NamedZoneCS(ctx, varname, cmdList, name, color, depth, active) TracyD3D12SrcLocObject(name, color); tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyD3D12SrcLocSymbol, depth, active };
|
||||||
|
# define TracyD3D12ZoneTransientS(ctx, varname, cmdList, name, depth, active) tracy::D3D12ZoneScope varname{ ctx, TracyLine, TracyFile, strlen(TracyFile), TracyFunction, strlen(TracyFunction), name, strlen(name), cmdList, depth, active };
|
||||||
|
#else
|
||||||
|
# define TracyD3D12ZoneS(ctx, cmdList, name, depth) TracyD3D12Zone(ctx, cmdList, name)
|
||||||
|
# define TracyD3D12ZoneCS(ctx, cmdList, name, color, depth) TracyD3D12Zone(ctx, cmdList, name, color)
|
||||||
|
# define TracyD3D12NamedZoneS(ctx, varname, cmdList, name, depth, active) TracyD3D12NamedZone(ctx, varname, cmdList, name, active)
|
||||||
|
# define TracyD3D12NamedZoneCS(ctx, varname, cmdList, name, color, depth, active) TracyD3D12NamedZoneC(ctx, varname, cmdList, name, color, active)
|
||||||
|
# define TracyD3D12ZoneTransientS(ctx, varname, cmdList, name, depth, active) TracyD3D12ZoneTransient(ctx, varname, cmdList, name, active)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TracyD3D12Collect(ctx) ctx->Collect();
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Forward declarations to be used in engine
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
extern void* CreateD3D12Context(ID3D12Device* device, ID3D12CommandQueue* queue);
|
||||||
|
extern void DestroyD3D12Context(void* ctx);
|
||||||
|
extern void CollectD3D12Context(void* ctx);
|
||||||
|
extern void BeginD3D12ZoneScope(void* zone, void* ctx, ID3D12GraphicsCommandList* cmdList, const char* name, size_t nameLen);
|
||||||
|
extern void EndD3D12ZoneScope(void* zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
779
Source/ThirdParty/tracy/tracy/TracyVulkan.hpp
vendored
Normal file
779
Source/ThirdParty/tracy/tracy/TracyVulkan.hpp
vendored
Normal file
@@ -0,0 +1,779 @@
|
|||||||
|
#ifndef __TRACYVULKAN_HPP__
|
||||||
|
#define __TRACYVULKAN_HPP__
|
||||||
|
|
||||||
|
#define TracyVulkanZoneSize 24
|
||||||
|
|
||||||
|
#if !defined TRACY_ENABLE
|
||||||
|
|
||||||
|
#define TracyVkContext(x,y,z,w) nullptr
|
||||||
|
#define TracyVkContextCalibrated(x,y,z,w,a,b) nullptr
|
||||||
|
#if defined VK_EXT_host_query_reset
|
||||||
|
#define TracyVkContextHostCalibrated(x,y,z,w,a) nullptr
|
||||||
|
#endif
|
||||||
|
#define TracyVkDestroy(x)
|
||||||
|
#define TracyVkContextName(c,x,y)
|
||||||
|
#define TracyVkNamedZone(c,x,y,z,w)
|
||||||
|
#define TracyVkNamedZoneC(c,x,y,z,w,a)
|
||||||
|
#define TracyVkZone(c,x,y)
|
||||||
|
#define TracyVkZoneC(c,x,y,z)
|
||||||
|
#define TracyVkZoneTransient(c,x,y,z,w)
|
||||||
|
#define TracyVkCollect(c,x)
|
||||||
|
|
||||||
|
#define TracyVkNamedZoneS(c,x,y,z,w,a)
|
||||||
|
#define TracyVkNamedZoneCS(c,x,y,z,w,v,a)
|
||||||
|
#define TracyVkZoneS(c,x,y,z)
|
||||||
|
#define TracyVkZoneCS(c,x,y,z,w)
|
||||||
|
#define TracyVkZoneTransientS(c,x,y,z,w,a)
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
class VkCtxScope {};
|
||||||
|
}
|
||||||
|
|
||||||
|
using TracyVkCtx = void*;
|
||||||
|
|
||||||
|
#elif TRACY_GPU_VULKAN
|
||||||
|
|
||||||
|
#if !defined VK_NULL_HANDLE
|
||||||
|
# error "You must include Vulkan headers before including TracyVulkan.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "../client/TracyProfiler.hpp"
|
||||||
|
#include "../client/TracyCallstack.hpp"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
#define LoadVkDeviceCoreSymbols(Operation) \
|
||||||
|
Operation(vkBeginCommandBuffer) \
|
||||||
|
Operation(vkCmdResetQueryPool) \
|
||||||
|
Operation(vkCmdWriteTimestamp) \
|
||||||
|
Operation(vkCreateQueryPool) \
|
||||||
|
Operation(vkDestroyQueryPool) \
|
||||||
|
Operation(vkEndCommandBuffer) \
|
||||||
|
Operation(vkGetQueryPoolResults) \
|
||||||
|
Operation(vkQueueSubmit) \
|
||||||
|
Operation(vkQueueWaitIdle) \
|
||||||
|
Operation(vkResetQueryPool)
|
||||||
|
|
||||||
|
#define LoadVkDeviceExtensionSymbols(Operation) \
|
||||||
|
Operation(vkGetCalibratedTimestampsEXT)
|
||||||
|
|
||||||
|
#define LoadVkInstanceExtensionSymbols(Operation) \
|
||||||
|
Operation(vkGetPhysicalDeviceCalibrateableTimeDomainsEXT)
|
||||||
|
|
||||||
|
#define LoadVkInstanceCoreSymbols(Operation) \
|
||||||
|
Operation(vkGetPhysicalDeviceProperties)
|
||||||
|
|
||||||
|
struct VkSymbolTable
|
||||||
|
{
|
||||||
|
#define MAKE_PFN(name) PFN_##name name;
|
||||||
|
LoadVkDeviceCoreSymbols(MAKE_PFN)
|
||||||
|
LoadVkDeviceExtensionSymbols(MAKE_PFN)
|
||||||
|
LoadVkInstanceExtensionSymbols(MAKE_PFN)
|
||||||
|
LoadVkInstanceCoreSymbols(MAKE_PFN)
|
||||||
|
#undef MAKE_PFN
|
||||||
|
};
|
||||||
|
|
||||||
|
#define VK_FUNCTION_WRAPPER(callSignature) m_symbols.callSignature
|
||||||
|
#define CONTEXT_VK_FUNCTION_WRAPPER(callSignature) m_ctx->m_symbols.callSignature
|
||||||
|
#else
|
||||||
|
#define VK_FUNCTION_WRAPPER(callSignature) callSignature
|
||||||
|
#define CONTEXT_VK_FUNCTION_WRAPPER(callSignature) callSignature
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class VkCtx
|
||||||
|
{
|
||||||
|
friend class VkCtxScope;
|
||||||
|
|
||||||
|
enum { QueryCount = 64 * 1024 };
|
||||||
|
|
||||||
|
public:
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
VkCtx( VkInstance instance, VkPhysicalDevice physdev, VkDevice device, VkQueue queue, VkCommandBuffer cmdbuf, PFN_vkGetInstanceProcAddr instanceProcAddr, PFN_vkGetDeviceProcAddr deviceProcAddr, bool calibrated )
|
||||||
|
#else
|
||||||
|
VkCtx( VkPhysicalDevice physdev, VkDevice device, VkQueue queue, VkCommandBuffer cmdbuf, PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT vkGetPhysicalDeviceCalibrateableTimeDomainsEXT, PFN_vkGetCalibratedTimestampsEXT vkGetCalibratedTimestampsEXT)
|
||||||
|
#endif
|
||||||
|
: m_device( device )
|
||||||
|
, m_timeDomain( VK_TIME_DOMAIN_DEVICE_EXT )
|
||||||
|
, m_context( GetGpuCtxCounter().fetch_add( 1, std::memory_order_relaxed ) )
|
||||||
|
, m_head( 0 )
|
||||||
|
, m_tail( 0 )
|
||||||
|
, m_oldCnt( 0 )
|
||||||
|
, m_queryCount( QueryCount )
|
||||||
|
#if !defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
, m_vkGetCalibratedTimestampsEXT( vkGetCalibratedTimestampsEXT )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
assert( m_context != 255 );
|
||||||
|
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
PopulateSymbolTable(instance, instanceProcAddr, deviceProcAddr);
|
||||||
|
if ( calibrated )
|
||||||
|
{
|
||||||
|
m_vkGetCalibratedTimestampsEXT = m_symbols.vkGetCalibratedTimestampsEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( VK_FUNCTION_WRAPPER( vkGetPhysicalDeviceCalibrateableTimeDomainsEXT ) && m_vkGetCalibratedTimestampsEXT )
|
||||||
|
{
|
||||||
|
FindAvailableTimeDomains( physdev, VK_FUNCTION_WRAPPER( vkGetPhysicalDeviceCalibrateableTimeDomainsEXT ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateQueryPool();
|
||||||
|
|
||||||
|
VkCommandBufferBeginInfo beginInfo = {};
|
||||||
|
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
|
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||||
|
|
||||||
|
VkSubmitInfo submitInfo = {};
|
||||||
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
submitInfo.commandBufferCount = 1;
|
||||||
|
submitInfo.pCommandBuffers = &cmdbuf;
|
||||||
|
|
||||||
|
VK_FUNCTION_WRAPPER( vkBeginCommandBuffer( cmdbuf, &beginInfo ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkCmdResetQueryPool( cmdbuf, m_query, 0, m_queryCount ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkEndCommandBuffer( cmdbuf ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkQueueWaitIdle( queue ) );
|
||||||
|
|
||||||
|
int64_t tcpu, tgpu;
|
||||||
|
if( m_timeDomain == VK_TIME_DOMAIN_DEVICE_EXT )
|
||||||
|
{
|
||||||
|
VK_FUNCTION_WRAPPER( vkBeginCommandBuffer( cmdbuf, &beginInfo ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkCmdWriteTimestamp( cmdbuf, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, m_query, 0 ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkEndCommandBuffer( cmdbuf ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkQueueWaitIdle( queue ) );
|
||||||
|
|
||||||
|
tcpu = Profiler::GetTime();
|
||||||
|
VK_FUNCTION_WRAPPER( vkGetQueryPoolResults( device, m_query, 0, 1, sizeof( tgpu ), &tgpu, sizeof( tgpu ), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT ) );
|
||||||
|
|
||||||
|
VK_FUNCTION_WRAPPER( vkBeginCommandBuffer( cmdbuf, &beginInfo ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkCmdResetQueryPool( cmdbuf, m_query, 0, 1 ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkEndCommandBuffer( cmdbuf ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkQueueWaitIdle( queue ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FindCalibratedTimestampDeviation();
|
||||||
|
Calibrate( device, m_prevCalibration, tgpu );
|
||||||
|
tcpu = Profiler::GetTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteInitialItem( physdev, tcpu, tgpu );
|
||||||
|
|
||||||
|
m_res = (int64_t*)tracy_malloc( sizeof( int64_t ) * m_queryCount );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined VK_EXT_host_query_reset
|
||||||
|
/**
|
||||||
|
* This alternative constructor does not use command buffers and instead uses functionality from
|
||||||
|
* VK_EXT_host_query_reset (core with 1.2 and non-optional) and VK_EXT_calibrated_timestamps. This requires
|
||||||
|
* the physical device to have another time domain apart from DEVICE to be calibrateable.
|
||||||
|
*/
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
VkCtx( VkInstance instance, VkPhysicalDevice physdev, VkDevice device, PFN_vkGetInstanceProcAddr instanceProcAddr, PFN_vkGetDeviceProcAddr deviceProcAddr )
|
||||||
|
#else
|
||||||
|
VkCtx( VkPhysicalDevice physdev, VkDevice device, PFN_vkResetQueryPoolEXT vkResetQueryPool, PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT vkGetPhysicalDeviceCalibrateableTimeDomainsEXT, PFN_vkGetCalibratedTimestampsEXT vkGetCalibratedTimestampsEXT )
|
||||||
|
#endif
|
||||||
|
: m_device( device )
|
||||||
|
, m_timeDomain( VK_TIME_DOMAIN_DEVICE_EXT )
|
||||||
|
, m_context( GetGpuCtxCounter().fetch_add(1, std::memory_order_relaxed) )
|
||||||
|
, m_head( 0 )
|
||||||
|
, m_tail( 0 )
|
||||||
|
, m_oldCnt( 0 )
|
||||||
|
, m_queryCount( QueryCount )
|
||||||
|
#if !defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
, m_vkGetCalibratedTimestampsEXT( vkGetCalibratedTimestampsEXT )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
assert( m_context != 255);
|
||||||
|
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
PopulateSymbolTable(instance, instanceProcAddr, deviceProcAddr);
|
||||||
|
m_vkGetCalibratedTimestampsEXT = m_symbols.vkGetCalibratedTimestampsEXT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
assert( VK_FUNCTION_WRAPPER( vkResetQueryPool ) != nullptr );
|
||||||
|
assert( VK_FUNCTION_WRAPPER( vkGetPhysicalDeviceCalibrateableTimeDomainsEXT ) != nullptr );
|
||||||
|
assert( VK_FUNCTION_WRAPPER( vkGetCalibratedTimestampsEXT ) != nullptr );
|
||||||
|
|
||||||
|
FindAvailableTimeDomains( physdev, VK_FUNCTION_WRAPPER( vkGetPhysicalDeviceCalibrateableTimeDomainsEXT ) );
|
||||||
|
|
||||||
|
// We require a host time domain to be available to properly calibrate.
|
||||||
|
FindCalibratedTimestampDeviation();
|
||||||
|
int64_t tgpu;
|
||||||
|
Calibrate( device, m_prevCalibration, tgpu );
|
||||||
|
int64_t tcpu = Profiler::GetTime();
|
||||||
|
|
||||||
|
CreateQueryPool();
|
||||||
|
VK_FUNCTION_WRAPPER( vkResetQueryPool( device, m_query, 0, m_queryCount ) );
|
||||||
|
|
||||||
|
WriteInitialItem( physdev, tcpu, tgpu );
|
||||||
|
|
||||||
|
// We need the buffer to be twice as large for availability values
|
||||||
|
size_t resSize = sizeof( int64_t ) * m_queryCount * 2;
|
||||||
|
m_res = (int64_t*)tracy_malloc( resSize );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
~VkCtx()
|
||||||
|
{
|
||||||
|
tracy_free( m_res );
|
||||||
|
VK_FUNCTION_WRAPPER( vkDestroyQueryPool( m_device, m_query, nullptr ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Name( const char* name, uint16_t len )
|
||||||
|
{
|
||||||
|
auto ptr = (char*)tracy_malloc( len );
|
||||||
|
memcpy( ptr, name, len );
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuContextName );
|
||||||
|
MemWrite( &item->gpuContextNameFat.context, m_context );
|
||||||
|
MemWrite( &item->gpuContextNameFat.ptr, (uint64_t)ptr );
|
||||||
|
MemWrite( &item->gpuContextNameFat.size, len );
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
GetProfiler().DeferItem( *item );
|
||||||
|
#endif
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Collect( VkCommandBuffer cmdbuf )
|
||||||
|
{
|
||||||
|
const uint64_t head = m_head.load(std::memory_order_relaxed);
|
||||||
|
if( m_tail == head ) return;
|
||||||
|
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if( !GetProfiler().IsConnected() )
|
||||||
|
{
|
||||||
|
VK_FUNCTION_WRAPPER( vkCmdResetQueryPool( cmdbuf, m_query, 0, m_queryCount ) );
|
||||||
|
m_tail = head;
|
||||||
|
m_oldCnt = 0;
|
||||||
|
int64_t tgpu;
|
||||||
|
if( m_timeDomain != VK_TIME_DOMAIN_DEVICE_EXT ) Calibrate( m_device, m_prevCalibration, tgpu );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
assert( head > m_tail );
|
||||||
|
|
||||||
|
const unsigned int wrappedTail = (unsigned int)( m_tail % m_queryCount );
|
||||||
|
|
||||||
|
unsigned int cnt;
|
||||||
|
if( m_oldCnt != 0 )
|
||||||
|
{
|
||||||
|
cnt = m_oldCnt;
|
||||||
|
m_oldCnt = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cnt = (unsigned int)( head - m_tail );
|
||||||
|
assert( cnt <= m_queryCount );
|
||||||
|
if( wrappedTail + cnt > m_queryCount )
|
||||||
|
{
|
||||||
|
cnt = m_queryCount - wrappedTail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VK_FUNCTION_WRAPPER( vkGetQueryPoolResults( m_device, m_query, wrappedTail, cnt, sizeof( int64_t ) * m_queryCount * 2, m_res, sizeof( int64_t ) * 2, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT ) );
|
||||||
|
|
||||||
|
for( unsigned int idx=0; idx<cnt; idx++ )
|
||||||
|
{
|
||||||
|
int64_t avail = m_res[idx * 2 + 1];
|
||||||
|
if( avail == 0 )
|
||||||
|
{
|
||||||
|
m_oldCnt = cnt - idx;
|
||||||
|
cnt = idx;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuTime );
|
||||||
|
MemWrite( &item->gpuTime.gpuTime, m_res[idx * 2] );
|
||||||
|
MemWrite( &item->gpuTime.queryId, uint16_t( wrappedTail + idx ) );
|
||||||
|
MemWrite( &item->gpuTime.context, m_context );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_timeDomain != VK_TIME_DOMAIN_DEVICE_EXT )
|
||||||
|
{
|
||||||
|
int64_t tgpu, tcpu;
|
||||||
|
Calibrate( m_device, tcpu, tgpu );
|
||||||
|
const auto refCpu = Profiler::GetTime();
|
||||||
|
const auto delta = tcpu - m_prevCalibration;
|
||||||
|
if( delta > 0 )
|
||||||
|
{
|
||||||
|
m_prevCalibration = tcpu;
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuCalibration );
|
||||||
|
MemWrite( &item->gpuCalibration.gpuTime, tgpu );
|
||||||
|
MemWrite( &item->gpuCalibration.cpuTime, refCpu );
|
||||||
|
MemWrite( &item->gpuCalibration.cpuDelta, delta );
|
||||||
|
MemWrite( &item->gpuCalibration.context, m_context );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VK_FUNCTION_WRAPPER( vkCmdResetQueryPool( cmdbuf, m_query, wrappedTail, cnt ) );
|
||||||
|
|
||||||
|
m_tail += cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline unsigned int NextQueryId()
|
||||||
|
{
|
||||||
|
const uint64_t id = m_head.fetch_add(1, std::memory_order_relaxed);
|
||||||
|
return id % m_queryCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline uint8_t GetId() const
|
||||||
|
{
|
||||||
|
return m_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline VkQueryPool GetQueryPool() const
|
||||||
|
{
|
||||||
|
return m_query;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
tracy_force_inline void Calibrate( VkDevice device, int64_t& tCpu, int64_t& tGpu )
|
||||||
|
{
|
||||||
|
assert( m_timeDomain != VK_TIME_DOMAIN_DEVICE_EXT );
|
||||||
|
VkCalibratedTimestampInfoEXT spec[2] = {
|
||||||
|
{ VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT, nullptr, VK_TIME_DOMAIN_DEVICE_EXT },
|
||||||
|
{ VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT, nullptr, m_timeDomain },
|
||||||
|
};
|
||||||
|
uint64_t ts[2];
|
||||||
|
uint64_t deviation;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
m_vkGetCalibratedTimestampsEXT( device, 2, spec, ts, &deviation );
|
||||||
|
}
|
||||||
|
while( deviation > m_deviation );
|
||||||
|
|
||||||
|
#if defined _WIN32
|
||||||
|
tGpu = ts[0];
|
||||||
|
tCpu = ts[1] * m_qpcToNs;
|
||||||
|
#elif defined __linux__ && defined CLOCK_MONOTONIC_RAW
|
||||||
|
tGpu = ts[0];
|
||||||
|
tCpu = ts[1];
|
||||||
|
#else
|
||||||
|
assert( false );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void CreateQueryPool()
|
||||||
|
{
|
||||||
|
VkQueryPoolCreateInfo poolInfo = {};
|
||||||
|
poolInfo.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
|
||||||
|
poolInfo.queryCount = m_queryCount;
|
||||||
|
poolInfo.queryType = VK_QUERY_TYPE_TIMESTAMP;
|
||||||
|
while ( VK_FUNCTION_WRAPPER( vkCreateQueryPool( m_device, &poolInfo, nullptr, &m_query ) != VK_SUCCESS ) )
|
||||||
|
{
|
||||||
|
m_queryCount /= 2;
|
||||||
|
poolInfo.queryCount = m_queryCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void FindAvailableTimeDomains( VkPhysicalDevice physicalDevice, PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT _vkGetPhysicalDeviceCalibrateableTimeDomainsEXT )
|
||||||
|
{
|
||||||
|
uint32_t num;
|
||||||
|
_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT( physicalDevice, &num, nullptr );
|
||||||
|
if(num > 4) num = 4;
|
||||||
|
VkTimeDomainEXT data[4];
|
||||||
|
_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT( physicalDevice, &num, data );
|
||||||
|
VkTimeDomainEXT supportedDomain = (VkTimeDomainEXT)-1;
|
||||||
|
#if defined _WIN32
|
||||||
|
supportedDomain = VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT;
|
||||||
|
#elif defined __linux__ && defined CLOCK_MONOTONIC_RAW
|
||||||
|
supportedDomain = VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT;
|
||||||
|
#endif
|
||||||
|
for( uint32_t i=0; i<num; i++ ) {
|
||||||
|
if(data[i] == supportedDomain) {
|
||||||
|
m_timeDomain = data[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void FindCalibratedTimestampDeviation()
|
||||||
|
{
|
||||||
|
assert( m_timeDomain != VK_TIME_DOMAIN_DEVICE_EXT );
|
||||||
|
constexpr size_t NumProbes = 32;
|
||||||
|
VkCalibratedTimestampInfoEXT spec[2] = {
|
||||||
|
{ VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT, nullptr, VK_TIME_DOMAIN_DEVICE_EXT },
|
||||||
|
{ VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT, nullptr, m_timeDomain },
|
||||||
|
};
|
||||||
|
uint64_t ts[2];
|
||||||
|
uint64_t deviation[NumProbes];
|
||||||
|
for( size_t i=0; i<NumProbes; i++ ) {
|
||||||
|
m_vkGetCalibratedTimestampsEXT( m_device, 2, spec, ts, deviation + i );
|
||||||
|
}
|
||||||
|
uint64_t minDeviation = deviation[0];
|
||||||
|
for( size_t i=1; i<NumProbes; i++ ) {
|
||||||
|
if ( minDeviation > deviation[i] ) {
|
||||||
|
minDeviation = deviation[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_deviation = minDeviation * 3 / 2;
|
||||||
|
|
||||||
|
#if defined _WIN32
|
||||||
|
m_qpcToNs = int64_t( 1000000000. / GetFrequencyQpc() );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void WriteInitialItem( VkPhysicalDevice physdev, int64_t tcpu, int64_t tgpu )
|
||||||
|
{
|
||||||
|
uint8_t flags = 0;
|
||||||
|
if( m_timeDomain != VK_TIME_DOMAIN_DEVICE_EXT ) flags |= GpuContextCalibration;
|
||||||
|
|
||||||
|
VkPhysicalDeviceProperties prop;
|
||||||
|
VK_FUNCTION_WRAPPER( vkGetPhysicalDeviceProperties( physdev, &prop ) );
|
||||||
|
const float period = prop.limits.timestampPeriod;
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuNewContext );
|
||||||
|
MemWrite( &item->gpuNewContext.cpuTime, tcpu );
|
||||||
|
MemWrite( &item->gpuNewContext.gpuTime, tgpu );
|
||||||
|
memset( &item->gpuNewContext.thread, 0, sizeof( item->gpuNewContext.thread ) );
|
||||||
|
MemWrite( &item->gpuNewContext.period, period );
|
||||||
|
MemWrite( &item->gpuNewContext.context, m_context );
|
||||||
|
MemWrite( &item->gpuNewContext.flags, flags );
|
||||||
|
MemWrite( &item->gpuNewContext.type, GpuContextType::Vulkan );
|
||||||
|
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
GetProfiler().DeferItem( *item );
|
||||||
|
#endif
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
void PopulateSymbolTable( VkInstance instance, PFN_vkGetInstanceProcAddr instanceProcAddr, PFN_vkGetDeviceProcAddr deviceProcAddr )
|
||||||
|
{
|
||||||
|
#define VK_GET_DEVICE_SYMBOL( name ) \
|
||||||
|
(PFN_##name)deviceProcAddr( m_device, #name );
|
||||||
|
#define VK_LOAD_DEVICE_SYMBOL( name ) \
|
||||||
|
m_symbols.name = VK_GET_DEVICE_SYMBOL( name );
|
||||||
|
#define VK_GET_INSTANCE_SYMBOL( name ) \
|
||||||
|
(PFN_##name)instanceProcAddr( instance, #name );
|
||||||
|
#define VK_LOAD_INSTANCE_SYMBOL( name ) \
|
||||||
|
m_symbols.name = VK_GET_INSTANCE_SYMBOL( name );
|
||||||
|
|
||||||
|
LoadVkDeviceCoreSymbols( VK_LOAD_DEVICE_SYMBOL )
|
||||||
|
LoadVkDeviceExtensionSymbols( VK_LOAD_DEVICE_SYMBOL )
|
||||||
|
LoadVkInstanceExtensionSymbols( VK_LOAD_INSTANCE_SYMBOL )
|
||||||
|
LoadVkInstanceCoreSymbols( VK_LOAD_INSTANCE_SYMBOL )
|
||||||
|
#undef VK_GET_DEVICE_SYMBOL
|
||||||
|
#undef VK_LOAD_DEVICE_SYMBOL
|
||||||
|
#undef VK_GET_INSTANCE_SYMBOL
|
||||||
|
#undef VK_LOAD_INSTANCE_SYMBOL
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
VkDevice m_device;
|
||||||
|
VkQueryPool m_query;
|
||||||
|
VkTimeDomainEXT m_timeDomain;
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
VkSymbolTable m_symbols;
|
||||||
|
#endif
|
||||||
|
uint64_t m_deviation;
|
||||||
|
#ifdef _WIN32
|
||||||
|
int64_t m_qpcToNs;
|
||||||
|
#endif
|
||||||
|
int64_t m_prevCalibration;
|
||||||
|
uint8_t m_context;
|
||||||
|
|
||||||
|
std::atomic<uint64_t> m_head;
|
||||||
|
uint64_t m_tail;
|
||||||
|
unsigned int m_oldCnt;
|
||||||
|
unsigned int m_queryCount;
|
||||||
|
|
||||||
|
int64_t* m_res;
|
||||||
|
|
||||||
|
PFN_vkGetCalibratedTimestampsEXT m_vkGetCalibratedTimestampsEXT;
|
||||||
|
};
|
||||||
|
|
||||||
|
class VkCtxScope
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
tracy_force_inline VkCtxScope( VkCtx* ctx, const SourceLocationData* srcloc, VkCommandBuffer cmdbuf, bool is_active )
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active( is_active && GetProfiler().IsConnected() )
|
||||||
|
#else
|
||||||
|
: m_active( is_active )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
m_cmdbuf = cmdbuf;
|
||||||
|
m_ctx = ctx;
|
||||||
|
|
||||||
|
const auto queryId = ctx->NextQueryId();
|
||||||
|
CONTEXT_VK_FUNCTION_WRAPPER( vkCmdWriteTimestamp( cmdbuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, ctx->m_query, queryId ) );
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuZoneBeginSerial );
|
||||||
|
MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.srcloc, (uint64_t)srcloc );
|
||||||
|
MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) );
|
||||||
|
MemWrite( &item->gpuZoneBegin.context, ctx->GetId() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline VkCtxScope( VkCtx* ctx, const SourceLocationData* srcloc, VkCommandBuffer cmdbuf, int32_t depth, bool is_active )
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active( is_active && GetProfiler().IsConnected() )
|
||||||
|
#else
|
||||||
|
: m_active( is_active )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
m_cmdbuf = cmdbuf;
|
||||||
|
m_ctx = ctx;
|
||||||
|
|
||||||
|
const auto queryId = ctx->NextQueryId();
|
||||||
|
CONTEXT_VK_FUNCTION_WRAPPER( vkCmdWriteTimestamp( cmdbuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, ctx->m_query, queryId ) );
|
||||||
|
|
||||||
|
QueueItem *item;
|
||||||
|
if( depth > 0 && has_callstack() )
|
||||||
|
{
|
||||||
|
item = Profiler::QueueSerialCallstack( Callstack( depth ) );
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuZoneBeginCallstackSerial );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuZoneBeginSerial );
|
||||||
|
}
|
||||||
|
MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.srcloc, (uint64_t)srcloc );
|
||||||
|
MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) );
|
||||||
|
MemWrite( &item->gpuZoneBegin.context, ctx->GetId() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline VkCtxScope( VkCtx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, VkCommandBuffer cmdbuf, bool is_active )
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active( is_active && GetProfiler().IsConnected() )
|
||||||
|
#else
|
||||||
|
: m_active( is_active )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
m_cmdbuf = cmdbuf;
|
||||||
|
m_ctx = ctx;
|
||||||
|
|
||||||
|
const auto queryId = ctx->NextQueryId();
|
||||||
|
CONTEXT_VK_FUNCTION_WRAPPER( vkCmdWriteTimestamp( cmdbuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, ctx->m_query, queryId ) );
|
||||||
|
|
||||||
|
const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz );
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuZoneBeginAllocSrcLocSerial );
|
||||||
|
MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.srcloc, srcloc );
|
||||||
|
MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) );
|
||||||
|
MemWrite( &item->gpuZoneBegin.context, ctx->GetId() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline VkCtxScope( VkCtx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, VkCommandBuffer cmdbuf, int32_t depth, bool is_active )
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active( is_active && GetProfiler().IsConnected() )
|
||||||
|
#else
|
||||||
|
: m_active( is_active )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
m_cmdbuf = cmdbuf;
|
||||||
|
m_ctx = ctx;
|
||||||
|
|
||||||
|
const auto queryId = ctx->NextQueryId();
|
||||||
|
CONTEXT_VK_FUNCTION_WRAPPER( vkCmdWriteTimestamp( cmdbuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, ctx->m_query, queryId ) );
|
||||||
|
|
||||||
|
const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz );
|
||||||
|
QueueItem *item;
|
||||||
|
if( depth > 0 && has_callstack() )
|
||||||
|
{
|
||||||
|
item = Profiler::QueueSerialCallstack( Callstack( depth ) );
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuZoneBeginAllocSrcLocCallstackSerial );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuZoneBeginAllocSrcLocSerial );
|
||||||
|
}
|
||||||
|
MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.srcloc, srcloc );
|
||||||
|
MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) );
|
||||||
|
MemWrite( &item->gpuZoneBegin.context, ctx->GetId() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline ~VkCtxScope()
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
|
||||||
|
const auto queryId = m_ctx->NextQueryId();
|
||||||
|
CONTEXT_VK_FUNCTION_WRAPPER( vkCmdWriteTimestamp( m_cmdbuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, m_ctx->m_query, queryId ) );
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuZoneEndSerial );
|
||||||
|
MemWrite( &item->gpuZoneEnd.cpuTime, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->gpuZoneEnd.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->gpuZoneEnd.queryId, uint16_t( queryId ) );
|
||||||
|
MemWrite( &item->gpuZoneEnd.context, m_ctx->GetId() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const bool m_active;
|
||||||
|
|
||||||
|
VkCommandBuffer m_cmdbuf;
|
||||||
|
VkCtx* m_ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
void* CreateVkContext( VkInstance instance, VkPhysicalDevice physdev, VkDevice device, VkQueue queue, VkCommandBuffer cmdbuf, PFN_vkGetInstanceProcAddr instanceProcAddr, PFN_vkGetDeviceProcAddr getDeviceProcAddr, bool calibrated = false )
|
||||||
|
#else
|
||||||
|
void* CreateVkContext( VkPhysicalDevice physdev, VkDevice device, VkQueue queue, VkCommandBuffer cmdbuf, PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT gpdctd, PFN_vkGetCalibratedTimestampsEXT gct )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
auto ctx = (VkCtx*)tracy_malloc( sizeof( VkCtx ) );
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
new(ctx) VkCtx( instance, physdev, device, queue, cmdbuf, instanceProcAddr, getDeviceProcAddr, calibrated );
|
||||||
|
#else
|
||||||
|
new(ctx) VkCtx( physdev, device, queue, cmdbuf, gpdctd, gct );
|
||||||
|
#endif
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined VK_EXT_host_query_reset
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
void* CreateVkContext( VkInstance instance, VkPhysicalDevice physdev, VkDevice device, PFN_vkGetInstanceProcAddr instanceProcAddr, PFN_vkGetDeviceProcAddr getDeviceProcAddr )
|
||||||
|
#else
|
||||||
|
void* CreateVkContext( VkPhysicalDevice physdev, VkDevice device, PFN_vkResetQueryPoolEXT qpreset, PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT gpdctd, PFN_vkGetCalibratedTimestampsEXT gct )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
auto ctx = (VkCtx*)tracy_malloc( sizeof( VkCtx ) );
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
new(ctx) VkCtx( instance, physdev, device, instanceProcAddr, getDeviceProcAddr );
|
||||||
|
#else
|
||||||
|
new(ctx) VkCtx( physdev, device, qpreset, gpdctd, gct );
|
||||||
|
#endif
|
||||||
|
ctx->Name("Vulkan", 6);
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void DestroyVkContext( void* ctx )
|
||||||
|
{
|
||||||
|
((VkCtx*)ctx)->~VkCtx();
|
||||||
|
tracy_free( ctx );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollectVkContext( void* ctx, VkCommandBuffer cmdbuf )
|
||||||
|
{
|
||||||
|
((VkCtx*)ctx)->Collect(cmdbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BeginVkZoneScope(void* zone, void* ctx, VkCommandBuffer cmdbuf, const char* name, size_t nameLen)
|
||||||
|
{
|
||||||
|
new(zone) tracy::VkCtxScope{ (tracy::VkCtx*)ctx, 0, 0, 0, 0, 0, name, nameLen, cmdbuf, true };
|
||||||
|
}
|
||||||
|
|
||||||
|
void EndVkZoneScope(void* zone)
|
||||||
|
{
|
||||||
|
((tracy::VkCtxScope*)zone)->~VkCtxScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
using TracyVkCtx = tracy::VkCtx*;
|
||||||
|
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
#define TracyVkContext( instance, physdev, device, queue, cmdbuf, instanceProcAddr, deviceProcAddr ) tracy::CreateVkContext( instance, physdev, device, queue, cmdbuf, instanceProcAddr, deviceProcAddr );
|
||||||
|
#else
|
||||||
|
#define TracyVkContext( physdev, device, queue, cmdbuf ) tracy::CreateVkContext( physdev, device, queue, cmdbuf, nullptr, nullptr );
|
||||||
|
#endif
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
#define TracyVkContextCalibrated( instance, physdev, device, queue, cmdbuf, instanceProcAddr, deviceProcAddr ) tracy::CreateVkContext( instance, physdev, device, queue, cmdbuf, instanceProcAddr, deviceProcAddr, true );
|
||||||
|
#else
|
||||||
|
#define TracyVkContextCalibrated( physdev, device, queue, cmdbuf, gpdctd, gct ) tracy::CreateVkContext( physdev, device, queue, cmdbuf, gpdctd, gct );
|
||||||
|
#endif
|
||||||
|
#if defined VK_EXT_host_query_reset
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
#define TracyVkContextHostCalibrated( instance, physdev, device, instanceProcAddr, deviceProcAddr ) tracy::CreateVkContext( instance, physdev, device, instanceProcAddr, deviceProcAddr );
|
||||||
|
#else
|
||||||
|
#define TracyVkContextHostCalibrated( physdev, device, qpreset, gpdctd, gct ) tracy::CreateVkContext( physdev, device, qpreset, gpdctd, gct );
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#define TracyVkDestroy( ctx ) tracy::DestroyVkContext( ctx );
|
||||||
|
#define TracyVkContextName( ctx, name, size ) ctx->Name( name, size );
|
||||||
|
#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
|
||||||
|
# define TracyVkNamedZone( ctx, varname, cmdbuf, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), cmdbuf, TRACY_CALLSTACK, active );
|
||||||
|
# define TracyVkNamedZoneC( ctx, varname, cmdbuf, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), cmdbuf, TRACY_CALLSTACK, active );
|
||||||
|
# define TracyVkZone( ctx, cmdbuf, name ) TracyVkNamedZoneS( ctx, ___tracy_gpu_zone, cmdbuf, name, TRACY_CALLSTACK, true )
|
||||||
|
# define TracyVkZoneC( ctx, cmdbuf, name, color ) TracyVkNamedZoneCS( ctx, ___tracy_gpu_zone, cmdbuf, name, color, TRACY_CALLSTACK, true )
|
||||||
|
# define TracyVkZoneTransient( ctx, varname, cmdbuf, name, active ) TracyVkZoneTransientS( ctx, varname, cmdbuf, name, TRACY_CALLSTACK, active )
|
||||||
|
#else
|
||||||
|
# define TracyVkNamedZone( ctx, varname, cmdbuf, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), cmdbuf, active );
|
||||||
|
# define TracyVkNamedZoneC( ctx, varname, cmdbuf, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), cmdbuf, active );
|
||||||
|
# define TracyVkZone( ctx, cmdbuf, name ) TracyVkNamedZone( ctx, ___tracy_gpu_zone, cmdbuf, name, true )
|
||||||
|
# define TracyVkZoneC( ctx, cmdbuf, name, color ) TracyVkNamedZoneC( ctx, ___tracy_gpu_zone, cmdbuf, name, color, true )
|
||||||
|
# define TracyVkZoneTransient( ctx, varname, cmdbuf, name, active ) tracy::VkCtxScope varname( ctx, TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), cmdbuf, active );
|
||||||
|
#endif
|
||||||
|
#define TracyVkCollect( ctx, cmdbuf ) ctx->Collect( cmdbuf );
|
||||||
|
|
||||||
|
#ifdef TRACY_HAS_CALLSTACK
|
||||||
|
# define TracyVkNamedZoneS( ctx, varname, cmdbuf, name, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), cmdbuf, depth, active );
|
||||||
|
# define TracyVkNamedZoneCS( ctx, varname, cmdbuf, name, color, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), cmdbuf, depth, active );
|
||||||
|
# define TracyVkZoneS( ctx, cmdbuf, name, depth ) TracyVkNamedZoneS( ctx, ___tracy_gpu_zone, cmdbuf, name, depth, true )
|
||||||
|
# define TracyVkZoneCS( ctx, cmdbuf, name, color, depth ) TracyVkNamedZoneCS( ctx, ___tracy_gpu_zone, cmdbuf, name, color, depth, true )
|
||||||
|
# define TracyVkZoneTransientS( ctx, varname, cmdbuf, name, depth, active ) tracy::VkCtxScope varname( ctx, TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), cmdbuf, depth, active );
|
||||||
|
#else
|
||||||
|
# define TracyVkNamedZoneS( ctx, varname, cmdbuf, name, depth, active ) TracyVkNamedZone( ctx, varname, cmdbuf, name, active )
|
||||||
|
# define TracyVkNamedZoneCS( ctx, varname, cmdbuf, name, color, depth, active ) TracyVkNamedZoneC( ctx, varname, cmdbuf, name, color, active )
|
||||||
|
# define TracyVkZoneS( ctx, cmdbuf, name, depth ) TracyVkZone( ctx, cmdbuf, name )
|
||||||
|
# define TracyVkZoneCS( ctx, cmdbuf, name, color, depth ) TracyVkZoneC( ctx, cmdbuf, name, color )
|
||||||
|
# define TracyVkZoneTransientS( ctx, varname, cmdbuf, name, depth, active ) TracyVkZoneTransient( ctx, varname, cmdbuf, name, active )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Forward declarations to be used in engine
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
extern void* CreateVkContext(VkInstance instance, VkPhysicalDevice physdev, VkDevice device, VkQueue queue, VkCommandBuffer cmdbuf, PFN_vkGetInstanceProcAddr instanceProcAddr, PFN_vkGetDeviceProcAddr getDeviceProcAddr, bool calibrated = false);
|
||||||
|
#else
|
||||||
|
extern void* CreateVkContext(VkPhysicalDevice physdev, VkDevice device, VkQueue queue, VkCommandBuffer cmdbuf, PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT gpdctd, PFN_vkGetCalibratedTimestampsEXT gct);
|
||||||
|
#endif
|
||||||
|
#if defined VK_EXT_host_query_reset
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
extern void* CreateVkContext(VkInstance instance, VkPhysicalDevice physdev, VkDevice device, PFN_vkGetInstanceProcAddr instanceProcAddr, PFN_vkGetDeviceProcAddr getDeviceProcAddr);
|
||||||
|
#else
|
||||||
|
extern void* CreateVkContext(VkPhysicalDevice physdev, VkDevice device, PFN_vkResetQueryPoolEXT qpreset, PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT gpdctd, PFN_vkGetCalibratedTimestampsEXT gct);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
extern void DestroyVkContext(void* ctx);
|
||||||
|
extern void CollectVkContext(void* ctx, VkCommandBuffer cmdbuf);
|
||||||
|
extern void BeginVkZoneScope(void* zone, void* ctx, VkCommandBuffer cmdbuf, const char* name, size_t nameLen);
|
||||||
|
extern void EndVkZoneScope(void* zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -73,7 +73,7 @@ namespace Flax.Build.NativeCpp
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The native C++ module build settings container.
|
/// The native C++ module build settings container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class BuildOptions
|
public sealed class BuildOptions : ICloneable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The target that builds this module.
|
/// The target that builds this module.
|
||||||
@@ -442,5 +442,26 @@ namespace Flax.Build.NativeCpp
|
|||||||
SourcePaths.Clear();
|
SourcePaths.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public object Clone()
|
||||||
|
{
|
||||||
|
var clone = new BuildOptions
|
||||||
|
{
|
||||||
|
Target = Target,
|
||||||
|
Platform = Platform,
|
||||||
|
Toolchain = Toolchain,
|
||||||
|
Architecture = Architecture,
|
||||||
|
Configuration = Configuration,
|
||||||
|
CompileEnv = (CompileEnvironment)CompileEnv.Clone(),
|
||||||
|
LinkEnv = (LinkEnvironment)LinkEnv.Clone(),
|
||||||
|
IntermediateFolder = IntermediateFolder,
|
||||||
|
OutputFolder = OutputFolder,
|
||||||
|
WorkingDirectory = WorkingDirectory,
|
||||||
|
HotReloadPostfix = HotReloadPostfix,
|
||||||
|
Flags = Flags,
|
||||||
|
};
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user