GPU: Add host/hardware stats

This commit is contained in:
Stenzek
2024-01-21 19:37:29 +10:00
parent 884c851079
commit 150ab8f4af
24 changed files with 350 additions and 156 deletions

View File

@ -513,6 +513,8 @@ void D3D11Device::CopyTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32 d
src11->CommitClear(m_context.Get());
s_stats.num_copies++;
const CD3D11_BOX src_box(static_cast<LONG>(src_x), static_cast<LONG>(src_y), 0, static_cast<LONG>(src_x + width),
static_cast<LONG>(src_y + height), 1);
m_context->CopySubresourceRegion(dst11->GetD3DTexture(), D3D11CalcSubresource(dst_level, dst_layer, dst->GetLevels()),
@ -531,6 +533,8 @@ void D3D11Device::ResolveTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u3
DebugAssert((dst_y + height) <= dst->GetMipHeight(dst_level));
DebugAssert(!dst->IsMultisampled() && src->IsMultisampled());
s_stats.num_copies++;
// DX11 can't resolve partial rects.
Assert(src_x == 0 && src_y == 0 && width == src->GetWidth() && height == src->GetHeight() && dst_x == 0 &&
dst_y == 0 && width == dst->GetMipWidth(dst_level) && height == dst->GetMipHeight(dst_level));
@ -635,6 +639,7 @@ bool D3D11Device::BeginPresent(bool skip_present)
static constexpr float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
m_context->ClearRenderTargetView(m_swap_chain_rtv.Get(), clear_color);
m_context->OMSetRenderTargets(1, m_swap_chain_rtv.GetAddressOf(), nullptr);
s_stats.num_render_passes++;
m_num_current_render_targets = 0;
std::memset(m_current_render_targets.data(), 0, sizeof(m_current_render_targets));
m_current_depth_target = nullptr;
@ -852,7 +857,9 @@ void D3D11Device::MapVertexBuffer(u32 vertex_size, u32 vertex_count, void** map_
void D3D11Device::UnmapVertexBuffer(u32 vertex_size, u32 vertex_count)
{
m_vertex_buffer.Unmap(m_context.Get(), vertex_size * vertex_count);
const u32 upload_size = vertex_size * vertex_count;
s_stats.buffer_streamed += upload_size;
m_vertex_buffer.Unmap(m_context.Get(), upload_size);
}
void D3D11Device::MapIndexBuffer(u32 index_count, DrawIndex** map_ptr, u32* map_space, u32* map_base_index)
@ -865,6 +872,7 @@ void D3D11Device::MapIndexBuffer(u32 index_count, DrawIndex** map_ptr, u32* map_
void D3D11Device::UnmapIndexBuffer(u32 used_index_count)
{
s_stats.buffer_streamed += sizeof(DrawIndex) * used_index_count;
m_index_buffer.Unmap(m_context.Get(), sizeof(DrawIndex) * used_index_count);
}
@ -874,6 +882,7 @@ void D3D11Device::PushUniformBuffer(const void* data, u32 data_size)
const auto res = m_uniform_buffer.Map(m_context.Get(), UNIFORM_BUFFER_ALIGNMENT, used_space);
std::memcpy(res.pointer, data, data_size);
m_uniform_buffer.Unmap(m_context.Get(), data_size);
s_stats.buffer_streamed += data_size;
const UINT first_constant = (res.index_aligned * UNIFORM_BUFFER_ALIGNMENT) / 16u;
const UINT num_constants = (used_space * UNIFORM_BUFFER_ALIGNMENT) / 16u;
@ -895,6 +904,8 @@ void D3D11Device::UnmapUniformBuffer(u32 size)
const UINT num_constants = used_space / 16u;
m_uniform_buffer.Unmap(m_context.Get(), used_space);
s_stats.buffer_streamed += size;
m_context->VSSetConstantBuffers1(0, 1, m_uniform_buffer.GetD3DBufferArray(), &first_constant, &num_constants);
m_context->PSSetConstantBuffers1(0, 1, m_uniform_buffer.GetD3DBufferArray(), &first_constant, &num_constants);
}
@ -944,6 +955,7 @@ void D3D11Device::SetRenderTargets(GPUTexture* const* rts, u32 num_rts, GPUTextu
if (!changed)
return;
s_stats.num_render_passes++;
m_context->OMSetRenderTargets(num_rts, rtvs, ds ? static_cast<D3D11Texture*>(ds)->GetD3DDSV() : nullptr);
}
@ -1035,10 +1047,12 @@ void D3D11Device::SetScissor(s32 x, s32 y, s32 width, s32 height)
void D3D11Device::Draw(u32 vertex_count, u32 base_vertex)
{
s_stats.num_draws++;
m_context->Draw(vertex_count, base_vertex);
}
void D3D11Device::DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex)
{
s_stats.num_draws++;
m_context->DrawIndexed(index_count, base_index, base_vertex);
}

View File

@ -45,6 +45,8 @@ bool D3D11Device::DownloadTexture(GPUTexture* texture, u32 x, u32 y, u32 width,
return false;
}
s_stats.num_downloads++;
const u32 copy_size = tex->GetPixelSize() * width;
StringUtil::StrideMemCpy(out_data, out_data_stride, sr.pData, sr.RowPitch, copy_size, height);
m_context->Unmap(m_readback_staging_texture.Get(), 0);
@ -218,6 +220,10 @@ bool D3D11Texture::Update(u32 x, u32 y, u32 width, u32 height, const void* data,
ID3D11DeviceContext1* context = D3D11Device::GetD3DContext();
CommitClear(context);
GPUDevice::GetStatistics().buffer_streamed += height * pitch;
GPUDevice::GetStatistics().num_uploads++;
context->UpdateSubresource(m_texture.Get(), srnum, &box, data, pitch, 0);
m_state = GPUTexture::State::Dirty;
return true;
@ -246,6 +252,9 @@ bool D3D11Texture::Map(void** map, u32* map_stride, u32 x, u32 y, u32 width, u32
return false;
}
GPUDevice::GetStatistics().buffer_streamed += height * sr.RowPitch;
GPUDevice::GetStatistics().num_uploads++;
*map = static_cast<u8*>(sr.pData) + (y * sr.RowPitch) + (x * GetPixelSize());
*map_stride = sr.RowPitch;
m_mapped_subresource = srnum;
@ -323,6 +332,12 @@ std::unique_ptr<D3D11Texture> D3D11Texture::Create(ID3D11Device* device, u32 wid
return nullptr;
}
if (initial_data)
{
GPUDevice::GetStatistics().buffer_streamed += height * initial_data_stride;
GPUDevice::GetStatistics().num_uploads++;
}
ComPtr<ID3D11ShaderResourceView> srv;
if (bind_flags & D3D11_BIND_SHADER_RESOURCE)
{
@ -412,7 +427,10 @@ void* D3D11TextureBuffer::Map(u32 required_elements)
void D3D11TextureBuffer::Unmap(u32 used_elements)
{
m_buffer.Unmap(D3D11Device::GetD3DContext(), used_elements * GetElementSize(m_format));
const u32 size = used_elements * GetElementSize(m_format);
GPUDevice::GetStatistics().buffer_streamed += size;
GPUDevice::GetStatistics().num_uploads++;
m_buffer.Unmap(D3D11Device::GetD3DContext(), size);
}
void D3D11TextureBuffer::SetDebugName(const std::string_view& name)

View File

@ -118,7 +118,8 @@ D3D12Device::ComPtr<ID3D12RootSignature> D3D12Device::CreateRootSignature(const
}
bool D3D12Device::CreateDevice(const std::string_view& adapter, bool threaded_presentation,
std::optional<bool> exclusive_fullscreen_control, FeatureMask disabled_features, Error* error)
std::optional<bool> exclusive_fullscreen_control, FeatureMask disabled_features,
Error* error)
{
std::unique_lock lock(s_instance_mutex);
@ -1256,6 +1257,8 @@ void D3D12Device::CopyTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32 d
D->CommitClear();
}
s_stats.num_copies++;
// *now* we can do a normal image copy.
if (InRenderPass())
EndRenderPass();
@ -1297,6 +1300,8 @@ void D3D12Device::ResolveTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u3
if (InRenderPass())
EndRenderPass();
s_stats.num_copies++;
D3D12Texture* D = static_cast<D3D12Texture*>(dst);
D3D12Texture* S = static_cast<D3D12Texture*>(src);
ID3D12GraphicsCommandList4* cmdlist = GetCommandList();
@ -1401,7 +1406,9 @@ void D3D12Device::MapVertexBuffer(u32 vertex_size, u32 vertex_count, void** map_
void D3D12Device::UnmapVertexBuffer(u32 vertex_size, u32 vertex_count)
{
m_vertex_buffer.CommitMemory(vertex_size * vertex_count);
const u32 upload_size = vertex_size * vertex_count;
s_stats.buffer_streamed += upload_size;
m_vertex_buffer.CommitMemory(upload_size);
}
void D3D12Device::MapIndexBuffer(u32 index_count, DrawIndex** map_ptr, u32* map_space, u32* map_base_index)
@ -1421,7 +1428,9 @@ void D3D12Device::MapIndexBuffer(u32 index_count, DrawIndex** map_ptr, u32* map_
void D3D12Device::UnmapIndexBuffer(u32 used_index_count)
{
m_index_buffer.CommitMemory(sizeof(DrawIndex) * used_index_count);
const u32 upload_size = sizeof(DrawIndex) * used_index_count;
s_stats.buffer_streamed += upload_size;
m_index_buffer.CommitMemory(upload_size);
}
void D3D12Device::PushUniformBuffer(const void* data, u32 data_size)
@ -1441,6 +1450,7 @@ void D3D12Device::PushUniformBuffer(const void* data, u32 data_size)
UpdateRootSignature();
}
s_stats.buffer_streamed += data_size;
GetCommandList()->SetGraphicsRoot32BitConstants(push_parameter[static_cast<u8>(m_current_pipeline_layout)],
data_size / 4u, data, 0);
}
@ -1462,6 +1472,7 @@ void* D3D12Device::MapUniformBuffer(u32 size)
void D3D12Device::UnmapUniformBuffer(u32 size)
{
s_stats.buffer_streamed += size;
m_uniform_buffer_position = m_uniform_buffer.GetCurrentOffset();
m_uniform_buffer.CommitMemory(size);
m_dirty_flags |= DIRTY_FLAG_CONSTANT_BUFFER;
@ -1681,6 +1692,7 @@ void D3D12Device::BeginRenderPass()
// TODO: Stats
m_in_render_pass = true;
s_stats.num_render_passes++;
// If this is a new command buffer, bind the pipeline and such.
if (m_dirty_flags & DIRTY_FLAG_INITIAL)
@ -1715,6 +1727,7 @@ void D3D12Device::BeginSwapChainRenderPass()
m_num_current_render_targets = 0;
m_current_depth_target = nullptr;
m_in_render_pass = true;
s_stats.num_render_passes++;
// Clear pipeline, it's likely incompatible.
m_current_pipeline = nullptr;
@ -2119,11 +2132,13 @@ bool D3D12Device::UpdateRootParameters(u32 dirty)
void D3D12Device::Draw(u32 vertex_count, u32 base_vertex)
{
PreDrawCheck();
s_stats.num_draws++;
GetCommandList()->DrawInstanced(vertex_count, 1, base_vertex, 0);
}
void D3D12Device::DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex)
{
PreDrawCheck();
s_stats.num_draws++;
GetCommandList()->DrawIndexedInstanced(index_count, 1, base_index, base_vertex, 0);
}

View File

@ -443,6 +443,9 @@ bool D3D12Texture::Update(u32 x, u32 y, u32 width, u32 height, const void* data,
m_state = State::Dirty;
}
GPUDevice::GetStatistics().buffer_streamed += required_size;
GPUDevice::GetStatistics().num_uploads++;
// first time the texture is used? don't leave it undefined
if (m_resource_state == D3D12_RESOURCE_STATE_COMMON)
TransitionToState(cmdlist, D3D12_RESOURCE_STATE_COPY_DEST);
@ -511,6 +514,9 @@ void D3D12Texture::Unmap()
const u32 offset = sb.GetCurrentOffset();
sb.CommitMemory(req_size);
GPUDevice::GetStatistics().buffer_streamed += req_size;
GPUDevice::GetStatistics().num_uploads++;
ID3D12GraphicsCommandList4* cmdlist = GetCommandBufferForUpdate();
// first time the texture is used? don't leave it undefined
@ -907,7 +913,10 @@ void* D3D12TextureBuffer::Map(u32 required_elements)
void D3D12TextureBuffer::Unmap(u32 used_elements)
{
m_buffer.CommitMemory(GetElementSize(m_format) * used_elements);
const u32 size = GetElementSize(m_format) * used_elements;
GPUDevice::GetStatistics().buffer_streamed += size;
GPUDevice::GetStatistics().num_uploads++;
m_buffer.CommitMemory(size);
}
void D3D12TextureBuffer::SetDebugName(const std::string_view& name)

View File

@ -40,6 +40,7 @@ std::unique_ptr<GPUDevice> g_gpu_device;
static std::string s_pipeline_cache_path;
size_t GPUDevice::s_total_vram_usage = 0;
GPUDevice::Statistics GPUDevice::s_stats = {};
GPUSampler::GPUSampler() = default;
@ -206,6 +207,11 @@ size_t GPUFramebufferManagerBase::KeyHash::operator()(const Key& key) const
return XXH32(&key, sizeof(key), 0x1337);
}
GPUDevice::GPUDevice()
{
ResetStatistics();
}
GPUDevice::~GPUDevice() = default;
RenderAPI GPUDevice::GetPreferredAPI()
@ -993,6 +999,11 @@ float GPUDevice::GetAndResetAccumulatedGPUTime()
return 0.0f;
}
void GPUDevice::ResetStatistics()
{
s_stats = {};
}
std::unique_ptr<GPUDevice> GPUDevice::CreateDeviceForAPI(RenderAPI api)
{
switch (api)

View File

@ -458,6 +458,16 @@ public:
bool prefer_unused_textures : 1;
};
struct Statistics
{
size_t buffer_streamed;
u32 num_draws;
u32 num_render_passes;
u32 num_copies;
u32 num_downloads;
u32 num_uploads;
};
struct AdapterAndModeList
{
std::vector<std::string> adapter_names;
@ -474,6 +484,7 @@ public:
static constexpr u32 MAX_RENDER_TARGETS = 4;
static_assert(sizeof(GPUPipeline::GraphicsConfig::color_formats) == sizeof(GPUTexture::Format) * MAX_RENDER_TARGETS);
GPUDevice();
virtual ~GPUDevice();
/// Returns the default/preferred API for the system.
@ -652,6 +663,9 @@ public:
/// Returns the amount of GPU time utilized since the last time this method was called.
virtual float GetAndResetAccumulatedGPUTime();
ALWAYS_INLINE static Statistics& GetStatistics() { return s_stats; }
static void ResetStatistics();
protected:
virtual bool CreateDevice(const std::string_view& adapter, bool threaded_presentation,
std::optional<bool> exclusive_fullscreen_control, FeatureMask disabled_features,
@ -738,6 +752,8 @@ private:
float m_display_frame_interval = 0.0f;
protected:
static Statistics s_stats;
bool m_gpu_timing_enabled = false;
bool m_vsync_enabled = false;
bool m_debug_device = false;

View File

@ -890,6 +890,9 @@ bool MetalTexture::Update(u32 x, u32 y, u32 width, u32 height, const void* data,
const u32 aligned_pitch = Common::AlignUpPow2(width * GetPixelSize(), TEXTURE_UPLOAD_PITCH_ALIGNMENT);
const u32 req_size = height * aligned_pitch;
GPUDevice::GetStatistics().buffer_streamed += req_size;
GPUDevice::GetStatistics().num_uploads++;
MetalDevice& dev = MetalDevice::GetInstance();
MetalStreamBuffer& sb = dev.GetTextureStreamBuffer();
id<MTLBuffer> actual_buffer;
@ -989,6 +992,9 @@ void MetalTexture::Unmap()
const u32 aligned_pitch = Common::AlignUpPow2(m_map_width * GetPixelSize(), TEXTURE_UPLOAD_PITCH_ALIGNMENT);
const u32 req_size = m_map_height * aligned_pitch;
GPUDevice::GetStatistics().buffer_streamed += req_size;
GPUDevice::GetStatistics().num_uploads++;
MetalDevice& dev = MetalDevice::GetInstance();
MetalStreamBuffer& sb = dev.GetTextureStreamBuffer();
const u32 offset = sb.GetCurrentOffset();
@ -1206,6 +1212,8 @@ bool MetalDevice::DownloadTexture(GPUTexture* texture, u32 x, u32 y, u32 width,
MetalTexture* T = static_cast<MetalTexture*>(texture);
CommitClear(T);
s_stats.num_downloads++;
@autoreleasepool
{
id<MTLBlitCommandEncoder> encoder = GetBlitEncoder(true);
@ -1303,6 +1311,8 @@ void MetalDevice::CopyTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32 d
S->SetUseFenceCounter(m_current_fence_counter);
D->SetUseFenceCounter(m_current_fence_counter);
s_stats.num_copies++;
@autoreleasepool
{
id<MTLBlitCommandEncoder> encoder = GetBlitEncoder(true);
@ -1365,6 +1375,8 @@ void MetalDevice::ResolveTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u3
if (InRenderPass())
EndRenderPass();
s_stats.num_copies++;
const u32 threadgroupHeight = resolve_pipeline.maxTotalThreadsPerThreadgroup / resolve_pipeline.threadExecutionWidth;
const MTLSize intrinsicThreadgroupSize = MTLSizeMake(resolve_pipeline.threadExecutionWidth, threadgroupHeight, 1);
const MTLSize threadgroupsInGrid =
@ -1472,7 +1484,10 @@ void* MetalTextureBuffer::Map(u32 required_elements)
void MetalTextureBuffer::Unmap(u32 used_elements)
{
m_buffer.CommitMemory(GetElementSize(m_format) * used_elements);
const u32 size = GetElementSize(m_format) * used_elements;
GPUDevice::GetStatistics().buffer_streamed += size;
GPUDevice::GetStatistics().num_uploads++;
m_buffer.CommitMemory(size);
}
void MetalTextureBuffer::SetDebugName(const std::string_view& name)
@ -1523,7 +1538,9 @@ void MetalDevice::MapVertexBuffer(u32 vertex_size, u32 vertex_count, void** map_
void MetalDevice::UnmapVertexBuffer(u32 vertex_size, u32 vertex_count)
{
m_vertex_buffer.CommitMemory(vertex_size * vertex_count);
const u32 size = vertex_size * vertex_count;
s_stats.buffer_streamed += size;
m_vertex_buffer.CommitMemory(size);
}
void MetalDevice::MapIndexBuffer(u32 index_count, DrawIndex** map_ptr, u32* map_space, u32* map_base_index)
@ -1543,11 +1560,14 @@ void MetalDevice::MapIndexBuffer(u32 index_count, DrawIndex** map_ptr, u32* map_
void MetalDevice::UnmapIndexBuffer(u32 used_index_count)
{
m_index_buffer.CommitMemory(sizeof(DrawIndex) * used_index_count);
const u32 size = sizeof(DrawIndex) * used_index_count;
s_stats.buffer_streamed += size;
m_index_buffer.CommitMemory(size);
}
void MetalDevice::PushUniformBuffer(const void* data, u32 data_size)
{
s_stats.buffer_streamed += data_size;
void* map = MapUniformBuffer(data_size);
std::memcpy(map, data, data_size);
UnmapUniformBuffer(data_size);
@ -1568,6 +1588,7 @@ void* MetalDevice::MapUniformBuffer(u32 size)
void MetalDevice::UnmapUniformBuffer(u32 size)
{
s_stats.buffer_streamed += size;
m_current_uniform_buffer_position = m_uniform_buffer.GetCurrentOffset();
m_uniform_buffer.CommitMemory(size);
if (InRenderPass())
@ -1758,6 +1779,8 @@ void MetalDevice::BeginRenderPass()
m_inline_upload_encoder = nil;
}
s_stats.num_render_passes++;
@autoreleasepool
{
MTLRenderPassDescriptor* desc = [MTLRenderPassDescriptor renderPassDescriptor];
@ -1927,6 +1950,7 @@ void MetalDevice::PreDrawCheck()
void MetalDevice::Draw(u32 vertex_count, u32 base_vertex)
{
PreDrawCheck();
s_stats.num_draws++;
[m_render_encoder drawPrimitives:m_current_pipeline->GetPrimitive() vertexStart:base_vertex vertexCount:vertex_count];
}
@ -1934,6 +1958,8 @@ void MetalDevice::DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex)
{
PreDrawCheck();
s_stats.num_draws++;
const u32 index_offset = base_index * sizeof(u16);
[m_render_encoder drawIndexedPrimitives:m_current_pipeline->GetPrimitive()
indexCount:index_count
@ -2000,6 +2026,7 @@ bool MetalDevice::BeginPresent(bool skip_present)
m_layer_pass_desc.colorAttachments[0].texture = layer_texture;
m_layer_pass_desc.colorAttachments[0].loadAction = MTLLoadActionClear;
m_render_encoder = [[m_render_cmdbuf renderCommandEncoderWithDescriptor:m_layer_pass_desc] retain];
s_stats.num_render_passes++;
std::memset(m_current_render_targets.data(), 0, sizeof(m_current_render_targets));
m_num_current_render_targets = 0;
m_current_depth_target = nullptr;

View File

@ -76,6 +76,8 @@ bool OpenGLDevice::DownloadTexture(GPUTexture* texture, u32 x, u32 y, u32 width,
const u32 layer = 0;
const u32 level = 0;
s_stats.num_downloads++;
if (GLAD_GL_VERSION_4_5 || GLAD_GL_ARB_get_texture_sub_image)
{
glGetTextureSubImage(T->GetGLId(), level, x, y, layer, width, height, 1, gl_format, gl_type,
@ -116,6 +118,8 @@ void OpenGLDevice::CopyTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32
CommitClear(D);
CommitClear(S);
s_stats.num_copies++;
const GLuint sid = S->GetGLId();
const GLuint did = D->GetGLId();
if (GLAD_GL_VERSION_4_3 || GLAD_GL_ARB_copy_image)
@ -192,6 +196,8 @@ void OpenGLDevice::ResolveTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u
CommitClear(D);
}
s_stats.num_copies++;
glDisable(GL_SCISSOR_TEST);
glBlitFramebuffer(src_x, src_y, src_x + width, src_y + height, dst_x, dst_y, dst_x + width, dst_y + height,
GL_COLOR_BUFFER_BIT, GL_LINEAR);
@ -307,7 +313,8 @@ bool OpenGLDevice::HasSurface() const
}
bool OpenGLDevice::CreateDevice(const std::string_view& adapter, bool threaded_presentation,
std::optional<bool> exclusive_fullscreen_control, FeatureMask disabled_features, Error* error)
std::optional<bool> exclusive_fullscreen_control, FeatureMask disabled_features,
Error* error)
{
m_gl_context = GL::Context::Create(m_window_info, error);
if (!m_gl_context)
@ -1030,6 +1037,8 @@ ALWAYS_INLINE_RELEASE void OpenGLDevice::SetVertexBufferOffsets(u32 base_vertex)
void OpenGLDevice::Draw(u32 vertex_count, u32 base_vertex)
{
s_stats.num_draws++;
if (glDrawElementsBaseVertex) [[likely]]
{
glDrawArrays(m_current_pipeline->GetTopology(), base_vertex, vertex_count);
@ -1042,6 +1051,8 @@ void OpenGLDevice::Draw(u32 vertex_count, u32 base_vertex)
void OpenGLDevice::DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex)
{
s_stats.num_draws++;
if (glDrawElementsBaseVertex) [[likely]]
{
const void* indices = reinterpret_cast<const void*>(static_cast<uintptr_t>(base_index) * sizeof(u16));
@ -1066,7 +1077,9 @@ void OpenGLDevice::MapVertexBuffer(u32 vertex_size, u32 vertex_count, void** map
void OpenGLDevice::UnmapVertexBuffer(u32 vertex_size, u32 vertex_count)
{
m_vertex_buffer->Unmap(vertex_size * vertex_count);
const u32 size = vertex_size * vertex_count;
s_stats.buffer_streamed += size;
m_vertex_buffer->Unmap(size);
}
void OpenGLDevice::MapIndexBuffer(u32 index_count, DrawIndex** map_ptr, u32* map_space, u32* map_base_index)
@ -1079,7 +1092,9 @@ void OpenGLDevice::MapIndexBuffer(u32 index_count, DrawIndex** map_ptr, u32* map
void OpenGLDevice::UnmapIndexBuffer(u32 used_index_count)
{
m_index_buffer->Unmap(sizeof(DrawIndex) * used_index_count);
const u32 size = sizeof(DrawIndex) * used_index_count;
s_stats.buffer_streamed += size;
m_index_buffer->Unmap(size);
}
void OpenGLDevice::PushUniformBuffer(const void* data, u32 data_size)
@ -1087,6 +1102,7 @@ void OpenGLDevice::PushUniformBuffer(const void* data, u32 data_size)
const auto res = m_uniform_buffer->Map(m_uniform_buffer_alignment, data_size);
std::memcpy(res.pointer, data, data_size);
m_uniform_buffer->Unmap(data_size);
s_stats.buffer_streamed += data_size;
glBindBufferRange(GL_UNIFORM_BUFFER, 1, m_uniform_buffer->GetGLBufferId(), res.buffer_offset, data_size);
}
@ -1099,6 +1115,7 @@ void* OpenGLDevice::MapUniformBuffer(u32 size)
void OpenGLDevice::UnmapUniformBuffer(u32 size)
{
const u32 pos = m_uniform_buffer->Unmap(size);
s_stats.buffer_streamed += pos;
glBindBufferRange(GL_UNIFORM_BUFFER, 1, m_uniform_buffer->GetGLBufferId(), pos, size);
}
@ -1135,6 +1152,7 @@ void OpenGLDevice::SetRenderTargets(GPUTexture* const* rts, u32 num_rts, GPUText
}
}
s_stats.num_render_passes++;
m_current_fbo = fbo;
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
}

View File

@ -166,6 +166,9 @@ std::unique_ptr<OpenGLTexture> OpenGLTexture::Create(u32 width, u32 height, u32
const u32 alignment = ((data_pitch % 4) == 0) ? 4 : (((data_pitch % 2) == 0) ? 2 : 1);
if (data)
{
GPUDevice::GetStatistics().buffer_streamed += data_pitch * height;
GPUDevice::GetStatistics().num_uploads++;
glPixelStorei(GL_UNPACK_ROW_LENGTH, data_pitch / pixel_size);
if (alignment != 4)
glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
@ -248,6 +251,9 @@ bool OpenGLTexture::Update(u32 x, u32 y, u32 width, u32 height, const void* data
CommitClear();
GPUDevice::GetStatistics().buffer_streamed += map_size;
GPUDevice::GetStatistics().num_uploads++;
OpenGLDevice::BindUpdateTextureUnit();
glBindTexture(target, m_id);
@ -309,6 +315,10 @@ void OpenGLTexture::Unmap()
const u32 pitch = Common::AlignUpPow2(static_cast<u32>(m_map_width) * GetPixelSize(), TEXTURE_UPLOAD_PITCH_ALIGNMENT);
const u32 upload_size = pitch * static_cast<u32>(m_map_height);
GPUDevice::GetStatistics().buffer_streamed += upload_size;
GPUDevice::GetStatistics().num_uploads++;
OpenGLStreamBuffer* sb = OpenGLDevice::GetTextureStreamBuffer();
sb->Unmap(upload_size);
sb->Bind();
@ -627,7 +637,10 @@ void* OpenGLTextureBuffer::Map(u32 required_elements)
void OpenGLTextureBuffer::Unmap(u32 used_elements)
{
m_buffer->Unmap(used_elements * GetElementSize(m_format));
const u32 size = used_elements * GetElementSize(m_format);
GPUDevice::GetStatistics().buffer_streamed += size;
GPUDevice::GetStatistics().num_uploads++;
m_buffer->Unmap(size);
}
void OpenGLTextureBuffer::SetDebugName(const std::string_view& name)

View File

@ -2568,6 +2568,8 @@ void VulkanDevice::CopyTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32
if (InRenderPass())
EndRenderPass();
s_stats.num_copies++;
S->SetUseFenceCounter(GetCurrentFenceCounter());
D->SetUseFenceCounter(GetCurrentFenceCounter());
S->TransitionToLayout((D == S) ? VulkanTexture::Layout::TransferSelf : VulkanTexture::Layout::TransferSrc);
@ -2592,6 +2594,8 @@ void VulkanDevice::ResolveTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u
if (InRenderPass())
EndRenderPass();
s_stats.num_copies++;
VulkanTexture* D = static_cast<VulkanTexture*>(dst);
VulkanTexture* S = static_cast<VulkanTexture*>(src);
const VkCommandBuffer cmdbuf = GetCurrentCommandBuffer();
@ -2699,7 +2703,9 @@ void VulkanDevice::MapVertexBuffer(u32 vertex_size, u32 vertex_count, void** map
void VulkanDevice::UnmapVertexBuffer(u32 vertex_size, u32 vertex_count)
{
m_vertex_buffer.CommitMemory(vertex_size * vertex_count);
const u32 size = vertex_size * vertex_count;
s_stats.buffer_streamed += size;
m_vertex_buffer.CommitMemory(size);
}
void VulkanDevice::MapIndexBuffer(u32 index_count, DrawIndex** map_ptr, u32* map_space, u32* map_base_index)
@ -2719,12 +2725,15 @@ void VulkanDevice::MapIndexBuffer(u32 index_count, DrawIndex** map_ptr, u32* map
void VulkanDevice::UnmapIndexBuffer(u32 used_index_count)
{
m_index_buffer.CommitMemory(sizeof(DrawIndex) * used_index_count);
const u32 size = sizeof(DrawIndex) * used_index_count;
s_stats.buffer_streamed += size;
m_index_buffer.CommitMemory(size);
}
void VulkanDevice::PushUniformBuffer(const void* data, u32 data_size)
{
DebugAssert(data_size < UNIFORM_PUSH_CONSTANTS_SIZE);
s_stats.buffer_streamed += data_size;
vkCmdPushConstants(GetCurrentCommandBuffer(), GetCurrentVkPipelineLayout(), UNIFORM_PUSH_CONSTANTS_STAGES, 0,
data_size, data);
}
@ -2745,6 +2754,7 @@ void* VulkanDevice::MapUniformBuffer(u32 size)
void VulkanDevice::UnmapUniformBuffer(u32 size)
{
s_stats.buffer_streamed += size;
m_uniform_buffer_position = m_uniform_buffer.GetCurrentOffset();
m_uniform_buffer.CommitMemory(size);
m_dirty_flags |= DIRTY_FLAG_DYNAMIC_OFFSETS;
@ -3147,6 +3157,8 @@ void VulkanDevice::BeginRenderPass()
vkCmdBeginRenderPass(GetCurrentCommandBuffer(), &bi, VK_SUBPASS_CONTENTS_INLINE);
}
s_stats.num_render_passes++;
// If this is a new command buffer, bind the pipeline and such.
if (m_dirty_flags & DIRTY_FLAG_INITIAL)
SetInitialPipelineState();
@ -3212,6 +3224,7 @@ void VulkanDevice::BeginSwapChainRenderPass()
vkCmdBeginRenderPass(GetCurrentCommandBuffer(), &rp, VK_SUBPASS_CONTENTS_INLINE);
}
s_stats.num_render_passes++;
m_num_current_render_targets = 0;
std::memset(m_current_render_targets.data(), 0, sizeof(m_current_render_targets));
m_current_depth_target = nullptr;
@ -3568,11 +3581,13 @@ bool VulkanDevice::UpdateDescriptorSets(u32 dirty)
void VulkanDevice::Draw(u32 vertex_count, u32 base_vertex)
{
PreDrawCheck();
s_stats.num_draws++;
vkCmdDraw(GetCurrentCommandBuffer(), vertex_count, 1, base_vertex, 0);
}
void VulkanDevice::DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex)
{
PreDrawCheck();
s_stats.num_draws++;
vkCmdDrawIndexed(GetCurrentCommandBuffer(), index_count, 1, base_index, base_vertex, 0);
}

View File

@ -339,6 +339,9 @@ bool VulkanTexture::Update(u32 x, u32 y, u32 width, u32 height, const void* data
sbuffer.CommitMemory(required_size);
}
GPUDevice::GetStatistics().buffer_streamed += required_size;
GPUDevice::GetStatistics().num_uploads++;
const VkCommandBuffer cmdbuf = GetCommandBufferForUpdate();
// if we're an rt and have been cleared, and the full rect isn't being uploaded, do the clear
@ -407,6 +410,9 @@ void VulkanTexture::Unmap()
const u32 offset = sb.GetCurrentOffset();
sb.CommitMemory(req_size);
GPUDevice::GetStatistics().buffer_streamed += req_size;
GPUDevice::GetStatistics().num_uploads++;
// first time the texture is used? don't leave it undefined
const VkCommandBuffer cmdbuf = GetCommandBufferForUpdate();
if (m_layout == Layout::Undefined)
@ -745,6 +751,8 @@ bool VulkanDevice::DownloadTexture(GPUTexture* texture, u32 x, u32 y, u32 width,
return false;
}
s_stats.num_downloads++;
if (InRenderPass())
EndRenderPass();
@ -1015,7 +1023,10 @@ void* VulkanTextureBuffer::Map(u32 required_elements)
void VulkanTextureBuffer::Unmap(u32 used_elements)
{
m_buffer.CommitMemory(GetElementSize(m_format) * used_elements);
const u32 size = GetElementSize(m_format) * used_elements;
GPUDevice::GetStatistics().buffer_streamed += size;
GPUDevice::GetStatistics().num_uploads++;
m_buffer.CommitMemory(size);
}
void VulkanTextureBuffer::SetDebugName(const std::string_view& name)