Add rendering stats for Data Upload
This commit is contained in:
@@ -49,7 +49,7 @@ namespace FlaxEditor.Windows.Profiler
|
||||
{
|
||||
Title = "Draw (GPU)",
|
||||
AnchorPreset = AnchorPresets.HorizontalStretchTop,
|
||||
Offsets = new Margin(0, 0, _drawTimeCPU.Height + 2, 0),
|
||||
Offsets = new Margin(0, 0, _drawTimeCPU.Height + 2, SingleChart.DefaultHeight),
|
||||
FormatSample = v => (Mathf.RoundToInt(v * 10.0f) / 10.0f) + " ms",
|
||||
Parent = mainPanel,
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "Engine/Graphics/GPUPass.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Profiler/ProfilerGPU.h"
|
||||
|
||||
DefaultGPUTasksExecutor::DefaultGPUTasksExecutor()
|
||||
: _context(nullptr)
|
||||
@@ -33,6 +34,7 @@ void DefaultGPUTasksExecutor::FrameBegin()
|
||||
const int32 count = GPUDevice::Instance->GetTasksManager()->RequestWork(buffer, 32);
|
||||
if (count == 0)
|
||||
return;
|
||||
PROFILE_GPU("GPUTasks");
|
||||
GPUMemoryPass pass(_context->GPU);
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
|
||||
@@ -499,6 +499,7 @@ void GPUContextDX11::UpdateCB(GPUConstantBuffer* cb, const void* data)
|
||||
return;
|
||||
|
||||
_context->UpdateSubresource(cbDX11->GetBuffer(), 0, nullptr, data, size, 1);
|
||||
RENDER_STAT_DATA_UPLOAD(size);
|
||||
}
|
||||
|
||||
void GPUContextDX11::Dispatch(GPUShaderProgramCS* shader, uint32 threadGroupCountX, uint32 threadGroupCountY, uint32 threadGroupCountZ)
|
||||
@@ -904,6 +905,7 @@ void GPUContextDX11::UpdateBuffer(GPUBuffer* buffer, const void* data, uint32 si
|
||||
box.bottom = 1;
|
||||
_context->UpdateSubresource(bufferDX11->GetResource(), 0, &box, data, size, 0);
|
||||
}
|
||||
RENDER_STAT_DATA_UPLOAD(size);
|
||||
}
|
||||
|
||||
void GPUContextDX11::CopyBuffer(GPUBuffer* dstBuffer, GPUBuffer* srcBuffer, uint32 size, uint32 dstOffset, uint32 srcOffset)
|
||||
@@ -934,6 +936,7 @@ void GPUContextDX11::UpdateTexture(GPUTexture* texture, int32 arrayIndex, int32
|
||||
if (texture->IsVolume())
|
||||
depthPitch /= Math::Max(1, texture->Depth() >> mipIndex);
|
||||
_context->UpdateSubresource(textureDX11->GetResource(), subresourceIndex, nullptr, data, (UINT)rowPitch, (UINT)depthPitch);
|
||||
RENDER_STAT_DATA_UPLOAD(slicePitch);
|
||||
|
||||
//D3D11_MAPPED_SUBRESOURCE mapped;
|
||||
//_device->GetIM()->Map(_resource, textureMipIndex, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
|
||||
|
||||
@@ -1131,6 +1131,7 @@ void GPUContextDX12::UpdateCB(GPUConstantBuffer* cb, const void* data)
|
||||
|
||||
// Allocate bytes for the buffer
|
||||
auto allocation = _device->UploadBuffer.Allocate(size, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT);
|
||||
RENDER_STAT_DATA_UPLOAD(size);
|
||||
|
||||
// Copy data
|
||||
Platform::MemoryCopy(allocation.CPUAddress, data, allocation.Size);
|
||||
@@ -1388,6 +1389,7 @@ void GPUContextDX12::UpdateBuffer(GPUBuffer* buffer, const void* data, uint32 si
|
||||
flushRBs();
|
||||
|
||||
_device->UploadBuffer.UploadBuffer(GetCommandList(), bufferDX12->GetResource(), offset, data, size);
|
||||
RENDER_STAT_DATA_UPLOAD(size);
|
||||
}
|
||||
|
||||
void GPUContextDX12::CopyBuffer(GPUBuffer* dstBuffer, GPUBuffer* srcBuffer, uint32 size, uint32 dstOffset, uint32 srcOffset)
|
||||
@@ -1414,6 +1416,7 @@ void GPUContextDX12::UpdateTexture(GPUTexture* texture, int32 arrayIndex, int32
|
||||
flushRBs();
|
||||
|
||||
_device->UploadBuffer.UploadTexture(GetCommandList(), textureDX12->GetResource(), data, rowPitch, slicePitch, mipIndex, arrayIndex);
|
||||
RENDER_STAT_DATA_UPLOAD(slicePitch);
|
||||
}
|
||||
|
||||
void GPUContextDX12::CopyTexture(GPUTexture* dstResource, uint32 dstSubresource, uint32 dstX, uint32 dstY, uint32 dstZ, GPUTexture* srcResource, uint32 srcSubresource)
|
||||
@@ -1469,6 +1472,7 @@ void GPUContextDX12::ResetCounter(GPUBuffer* buffer)
|
||||
|
||||
uint32 value = 0;
|
||||
_device->UploadBuffer.UploadBuffer(GetCommandList(), counter->GetResource(), 0, &value, 4);
|
||||
RENDER_STAT_DATA_UPLOAD(4);
|
||||
|
||||
SetResourceState(counter, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ namespace D3D12MA
|
||||
}
|
||||
class GPUResource;
|
||||
class GPUContextDX12;
|
||||
class GPUAsyncContextDX12;
|
||||
|
||||
/// <summary>
|
||||
/// Default amount of frames to wait until resource delete.
|
||||
@@ -59,7 +58,6 @@ public:
|
||||
class ResourceOwnerDX12
|
||||
{
|
||||
friend GPUContextDX12;
|
||||
friend GPUAsyncContextDX12;
|
||||
|
||||
protected:
|
||||
D3D12MA::Allocation* _allocation = nullptr;
|
||||
|
||||
@@ -682,6 +682,7 @@ void GPUContextVulkan::UpdateDescriptorSets(const SpirvShaderDescriptorInfo& des
|
||||
auto cb = (GPUConstantBufferVulkan*)_device->HelperResources.GetDummyConstantBuffer();
|
||||
// TODO: cache this allocation within a frame
|
||||
const auto allocation = _device->UniformBufferUploader->Allocate(cb->GetSize(), 0, this);
|
||||
RENDER_STAT_DATA_UPLOAD(allocation.Size);
|
||||
Platform::MemoryClear(allocation.CPUAddress, allocation.Size);
|
||||
cb->Allocation = allocation;
|
||||
handle = cb;
|
||||
@@ -1187,6 +1188,7 @@ void GPUContextVulkan::UpdateCB(GPUConstantBuffer* cb, const void* data)
|
||||
|
||||
// Allocate bytes for the buffer
|
||||
const auto allocation = _device->UniformBufferUploader->Allocate(size, 0, this);
|
||||
RENDER_STAT_DATA_UPLOAD(size);
|
||||
|
||||
// Copy data
|
||||
Platform::MemoryCopy(allocation.CPUAddress, data, allocation.Size);
|
||||
@@ -1538,6 +1540,7 @@ void GPUContextVulkan::UpdateBuffer(GPUBuffer* buffer, const void* data, uint32
|
||||
region.dstOffset = offset;
|
||||
vkCmdCopyBuffer(cmdBuffer->GetHandle(), allocation.Buffer, ((GPUBufferVulkan*)buffer)->GetHandle(), 1, ®ion);
|
||||
}
|
||||
RENDER_STAT_DATA_UPLOAD(size);
|
||||
|
||||
// Memory transfer barrier to ensure buffer is ready to read (eg. by Draw or Dispatch)
|
||||
if (_pass == 0)
|
||||
@@ -1586,6 +1589,7 @@ void GPUContextVulkan::UpdateTexture(GPUTexture* texture, int32 arrayIndex, int3
|
||||
FlushBarriers();
|
||||
|
||||
auto allocation = _device->UploadBuffer.Upload(data, slicePitch, 512);
|
||||
RENDER_STAT_DATA_UPLOAD(slicePitch);
|
||||
|
||||
// Setup buffer copy region
|
||||
int32 mipWidth, mipHeight, mipDepth;
|
||||
|
||||
@@ -364,6 +364,7 @@ void GPUContextWebGPU::UpdateCB(GPUConstantBuffer* cb, const void* data)
|
||||
cbWebGPU->AllocationSize = alignedSize;
|
||||
// TODO: consider holding CPU-side staging buffer and copying data to the GPU buffer in a single batch for all uniforms (before flushing the active command encoder)
|
||||
wgpuQueueWriteBuffer(_device->Queue, allocation.Buffer, allocation.Offset, data, size);
|
||||
RENDER_STAT_DATA_UPLOAD(size);
|
||||
_bindGroupDirty = true;
|
||||
}
|
||||
}
|
||||
@@ -593,6 +594,7 @@ void GPUContextWebGPU::UpdateBuffer(GPUBuffer* buffer, const void* data, uint32
|
||||
// Efficient upload via queue
|
||||
wgpuQueueWriteBuffer(_device->Queue, bufferWebGPU->Buffer, offset, data, size);
|
||||
}
|
||||
RENDER_STAT_DATA_UPLOAD(size);
|
||||
}
|
||||
|
||||
void GPUContextWebGPU::CopyBuffer(GPUBuffer* dstBuffer, GPUBuffer* srcBuffer, uint32 size, uint32 dstOffset, uint32 srcOffset)
|
||||
@@ -633,6 +635,7 @@ void GPUContextWebGPU::UpdateTexture(GPUTexture* texture, int32 arrayIndex, int3
|
||||
dataLayout.rowsPerImage = mipHeight;
|
||||
WGPUExtent3D writeSize = { (uint32_t)mipWidth, (uint32_t)mipHeight, (uint32_t)mipDepth };
|
||||
wgpuQueueWriteTexture(_device->Queue, ©Info, data, slicePitch, &dataLayout, &writeSize);
|
||||
RENDER_STAT_DATA_UPLOAD(slicePitch);
|
||||
}
|
||||
|
||||
void GPUContextWebGPU::CopyTexture(GPUTexture* dstResource, uint32 dstSubresource, uint32 dstX, uint32 dstY, uint32 dstZ, GPUTexture* srcResource, uint32 srcSubresource)
|
||||
|
||||
@@ -439,6 +439,8 @@ void GraphicsDumping::Print()
|
||||
sb.AppendFormat(TEXT(", 1 tri, {} verts"), FormatValue(NameBuffers[0], item.Stats.Vertices));
|
||||
else if (item.Stats.Triangles != 0)
|
||||
sb.AppendFormat(TEXT(", {} tris, {} verts"), FormatValue(NameBuffers[0], item.Stats.Triangles), FormatValue(NameBuffers[1], item.Stats.Vertices));
|
||||
if (item.Stats.DataUpload > 4096)
|
||||
sb.AppendFormat(TEXT(", {} sent"), Utilities::BytesToText(item.Stats.DataUpload));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -16,39 +16,32 @@ API_STRUCT() struct RenderStatsData
|
||||
/// <summary>
|
||||
/// The draw calls count.
|
||||
/// </summary>
|
||||
API_FIELD() int64 DrawCalls;
|
||||
API_FIELD() int64 DrawCalls = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The compute shader dispatch calls count.
|
||||
/// </summary>
|
||||
API_FIELD() int64 DispatchCalls;
|
||||
API_FIELD() int64 DispatchCalls = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The vertices drawn count.
|
||||
/// </summary>
|
||||
API_FIELD() int64 Vertices;
|
||||
API_FIELD() int64 Vertices = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The triangles drawn count.
|
||||
/// </summary>
|
||||
API_FIELD() int64 Triangles;
|
||||
API_FIELD() int64 Triangles = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The pipeline state changes count.
|
||||
/// </summary>
|
||||
API_FIELD() int64 PipelineStateChanges;
|
||||
API_FIELD() int64 PipelineStateChanges = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RenderStatsData"/> struct.
|
||||
/// The amount of bytes uploaded to GPU (to buffers and textures).
|
||||
/// </summary>
|
||||
RenderStatsData()
|
||||
: DrawCalls(0)
|
||||
, DispatchCalls(0)
|
||||
, Vertices(0)
|
||||
, Triangles(0)
|
||||
, PipelineStateChanges(0)
|
||||
{
|
||||
}
|
||||
API_FIELD() int64 DataUpload = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The global rendering stats counter.
|
||||
@@ -67,6 +60,7 @@ API_STRUCT() struct RenderStatsData
|
||||
MIX(Vertices);
|
||||
MIX(Triangles);
|
||||
MIX(PipelineStateChanges);
|
||||
MIX(DataUpload);
|
||||
#undef MIX
|
||||
}
|
||||
|
||||
@@ -78,6 +72,7 @@ API_STRUCT() struct RenderStatsData
|
||||
MIX(Vertices);
|
||||
MIX(Triangles);
|
||||
MIX(PipelineStateChanges);
|
||||
MIX(DataUpload);
|
||||
#undef MIX
|
||||
return *this;
|
||||
}
|
||||
@@ -90,6 +85,7 @@ API_STRUCT() struct RenderStatsData
|
||||
MIX(Vertices);
|
||||
MIX(Triangles);
|
||||
MIX(PipelineStateChanges);
|
||||
MIX(DataUpload);
|
||||
#undef MIX
|
||||
return *this;
|
||||
}
|
||||
@@ -97,6 +93,7 @@ API_STRUCT() struct RenderStatsData
|
||||
|
||||
#define RENDER_STAT_DISPATCH_CALL() Platform::InterlockedIncrement(&RenderStatsData::Counter.DispatchCalls)
|
||||
#define RENDER_STAT_PS_STATE_CHANGE() Platform::InterlockedIncrement(&RenderStatsData::Counter.PipelineStateChanges)
|
||||
#define RENDER_STAT_DATA_UPLOAD(bytes) Platform::InterlockedAdd(&RenderStatsData::Counter.DataUpload, bytes)
|
||||
#define RENDER_STAT_DRAW_CALL(vertices, triangles) \
|
||||
Platform::InterlockedIncrement(&RenderStatsData::Counter.DrawCalls); \
|
||||
Platform::InterlockedAdd(&RenderStatsData::Counter.Vertices, vertices); \
|
||||
@@ -106,6 +103,7 @@ API_STRUCT() struct RenderStatsData
|
||||
|
||||
#define RENDER_STAT_DISPATCH_CALL()
|
||||
#define RENDER_STAT_PS_STATE_CHANGE()
|
||||
#define RENDER_STAT_DATA_UPLOAD(bytes)
|
||||
#define RENDER_STAT_DRAW_CALL(vertices, primitives)
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user