Skip to content

Commit

Permalink
GPU: Eliminate heap allocation on state load
Browse files Browse the repository at this point in the history
  • Loading branch information
stenzek committed Jul 2, 2024
1 parent f9bf2e8 commit 044d7a4
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 14 deletions.
13 changes: 1 addition & 12 deletions src/core/gpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,18 +359,7 @@ bool GPU::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_displ
if (!sw.DoMarker("GPU-VRAM"))
return false;

if (sw.IsReading())
{
// Still need a temporary here.
FixedHeapArray<u16, VRAM_WIDTH * VRAM_HEIGHT> temp;
sw.DoBytes(temp.data(), VRAM_WIDTH * VRAM_HEIGHT * sizeof(u16));
UpdateVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT, temp.data(), false, false);
}
else
{
ReadVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT);
sw.DoBytes(g_vram, VRAM_WIDTH * VRAM_HEIGHT * sizeof(u16));
}
sw.DoBytes(g_vram, VRAM_WIDTH * VRAM_HEIGHT * sizeof(u16));
}

if (sw.IsReading())
Expand Down
24 changes: 22 additions & 2 deletions src/core/gpu_hw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,12 @@ void GPU_HW::Reset(bool clear_vram)

bool GPU_HW::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display)
{
// Need to download local VRAM copy before calling the base class, because it serializes this.
if (m_sw_renderer)
m_sw_renderer->Sync(true);
else if (sw.IsWriting() && !host_texture)
ReadVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT);

if (!GPU::DoState(sw, host_texture, update_display))
return false;

Expand Down Expand Up @@ -308,11 +314,18 @@ bool GPU_HW::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_di
tex->GetHeight());
}
}
else if (sw.IsReading())
{
// Need to update the VRAM copy on the GPU with the state data.
UpdateVRAMOnGPU(0, 0, VRAM_WIDTH, VRAM_HEIGHT, g_vram, VRAM_WIDTH * sizeof(u16), false, false,
Common::Rectangle<u32>(0, 0, VRAM_WIDTH, VRAM_HEIGHT));
}

// invalidate the whole VRAM read texture when loading state
if (sw.IsReading())
{
DebugAssert(!m_batch_vertex_ptr && !m_batch_index_ptr);
ClearVRAMDirtyRectangle();
SetFullVRAMDirtyRectangle();
ResetBatchVertexDepth();
}
Expand Down Expand Up @@ -2954,14 +2967,20 @@ void GPU_HW::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, b
}
}

UpdateVRAMOnGPU(x, y, width, height, data, sizeof(u16) * width, set_mask, check_mask, bounds);
}

void GPU_HW::UpdateVRAMOnGPU(u32 x, u32 y, u32 width, u32 height, const void* data, u32 data_pitch, bool set_mask,
bool check_mask, const Common::Rectangle<u32>& bounds)
{
std::unique_ptr<GPUTexture> upload_texture;
u32 map_index;

if (!g_gpu_device->GetFeatures().supports_texture_buffers)
{
map_index = 0;
upload_texture = g_gpu_device->FetchTexture(width, height, 1, 1, 1, GPUTexture::Type::Texture,
GPUTexture::Format::R16U, data, width * sizeof(u16));
GPUTexture::Format::R16U, data, data_pitch);
if (!upload_texture)
{
ERROR_LOG("Failed to get {}x{} upload texture. Things are gonna break.", width, height);
Expand All @@ -2971,9 +2990,10 @@ void GPU_HW::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, b
else
{
const u32 num_pixels = width * height;
const u32 dst_pitch = width * sizeof(u16);
void* map = m_vram_upload_buffer->Map(num_pixels);
map_index = m_vram_upload_buffer->GetCurrentPosition();
std::memcpy(map, data, num_pixels * sizeof(u16));
StringUtil::StrideMemCpy(map, dst_pitch, data, data_pitch, dst_pitch, height);
m_vram_upload_buffer->Unmap(num_pixels);
}

Expand Down
2 changes: 2 additions & 0 deletions src/core/gpu_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ class GPU_HW final : public GPU
void DrawRendererStats() override;
void OnBufferSwapped() override;

void UpdateVRAMOnGPU(u32 x, u32 y, u32 width, u32 height, const void* data, u32 data_pitch, bool set_mask,
bool check_mask, const Common::Rectangle<u32>& bounds);
bool BlitVRAMReplacementTexture(const TextureReplacementTexture* tex, u32 dst_x, u32 dst_y, u32 width, u32 height);

/// Expands a line into two triangles.
Expand Down
3 changes: 3 additions & 0 deletions src/core/gpu_sw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ bool GPU_SW::Initialize()

bool GPU_SW::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display)
{
// need to ensure the worker thread is done
m_backend.Sync(true);

// ignore the host texture for software mode, since we want to save vram here
return GPU::DoState(sw, nullptr, update_display);
}
Expand Down

0 comments on commit 044d7a4

Please sign in to comment.