GPU/HW: Track VRAM fills/writes in dirty rectangle instead of invalidating
This commit is contained in:
parent
2578f34a7c
commit
da51d49d18
|
@ -178,6 +178,21 @@ GPU_HW::BatchPrimitive GPU_HW::GetPrimitiveForCommand(RenderCommand rc)
|
||||||
return BatchPrimitive::Triangles;
|
return BatchPrimitive::Triangles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPU_HW::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
||||||
|
{
|
||||||
|
m_vram_dirty_rect.Include(Common::Rectangle<u32>::FromExtents(x, y, width, height));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GPU_HW::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data)
|
||||||
|
{
|
||||||
|
m_vram_dirty_rect.Include(Common::Rectangle<u32>::FromExtents(x, y, width, height));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GPU_HW::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height)
|
||||||
|
{
|
||||||
|
m_vram_dirty_rect.Include(Common::Rectangle<u32>::FromExtents(dst_x, dst_y, width, height));
|
||||||
|
}
|
||||||
|
|
||||||
void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32* command_ptr)
|
void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32* command_ptr)
|
||||||
{
|
{
|
||||||
TextureMode texture_mode;
|
TextureMode texture_mode;
|
||||||
|
@ -206,6 +221,21 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// texture page changed - check that the new page doesn't intersect the drawing area
|
||||||
|
if (m_render_state.IsTexturePageChanged())
|
||||||
|
{
|
||||||
|
m_render_state.ClearTexturePageChangedFlag();
|
||||||
|
if (m_vram_dirty_rect.Valid() && (m_render_state.GetTexturePageRectangle().Intersects(m_vram_dirty_rect) ||
|
||||||
|
m_render_state.GetTexturePaletteRectangle().Intersects(m_vram_dirty_rect)))
|
||||||
|
{
|
||||||
|
if (!IsFlushed())
|
||||||
|
FlushRender();
|
||||||
|
|
||||||
|
Log_WarningPrintf("Invalidating VRAM read cache due to drawing area overlap");
|
||||||
|
m_vram_read_texture_dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
texture_mode = m_render_state.texture_mode;
|
texture_mode = m_render_state.texture_mode;
|
||||||
if (rc.raw_texture_enable)
|
if (rc.raw_texture_enable)
|
||||||
{
|
{
|
||||||
|
@ -219,21 +249,6 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
|
||||||
texture_mode = TextureMode::Disabled;
|
texture_mode = TextureMode::Disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
// texture page changed - check that the new page doesn't intersect the drawing area
|
|
||||||
if (m_render_state.IsTexturePageChanged())
|
|
||||||
{
|
|
||||||
m_render_state.ClearTexturePageChangedFlag();
|
|
||||||
if (m_vram_dirty_rect.Valid() && (m_render_state.GetTexturePageRectangle().Intersects(m_vram_dirty_rect) ||
|
|
||||||
m_render_state.GetTexturePaletteRectangle().Intersects(m_vram_dirty_rect)))
|
|
||||||
{
|
|
||||||
if (!IsFlushed())
|
|
||||||
FlushRender();
|
|
||||||
|
|
||||||
Log_WarningPrintf("Invalidating VRAM read cache due to drawing area overlap");
|
|
||||||
m_vram_read_texture_dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// has any state changed which requires a new batch?
|
// has any state changed which requires a new batch?
|
||||||
const TransparencyMode transparency_mode =
|
const TransparencyMode transparency_mode =
|
||||||
rc.transparency_enable ? m_render_state.transparency_mode : TransparencyMode::Disabled;
|
rc.transparency_enable ? m_render_state.transparency_mode : TransparencyMode::Disabled;
|
||||||
|
|
|
@ -112,13 +112,14 @@ protected:
|
||||||
|
|
||||||
virtual void MapBatchVertexPointer(u32 required_vertices) = 0;
|
virtual void MapBatchVertexPointer(u32 required_vertices) = 0;
|
||||||
|
|
||||||
void InvalidateVRAMReadTexture() { m_vram_read_texture_dirty = true; }
|
|
||||||
|
|
||||||
u32 GetBatchVertexSpace() const { return static_cast<u32>(m_batch_end_vertex_ptr - m_batch_current_vertex_ptr); }
|
u32 GetBatchVertexSpace() const { return static_cast<u32>(m_batch_end_vertex_ptr - m_batch_current_vertex_ptr); }
|
||||||
u32 GetBatchVertexCount() const { return static_cast<u32>(m_batch_current_vertex_ptr - m_batch_start_vertex_ptr); }
|
u32 GetBatchVertexCount() const { return static_cast<u32>(m_batch_current_vertex_ptr - m_batch_start_vertex_ptr); }
|
||||||
|
|
||||||
bool IsFlushed() const { return m_batch_current_vertex_ptr == m_batch_start_vertex_ptr; }
|
bool IsFlushed() const { return m_batch_current_vertex_ptr == m_batch_start_vertex_ptr; }
|
||||||
|
|
||||||
|
void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) override;
|
||||||
|
void UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data) override;
|
||||||
|
void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) override;
|
||||||
void DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32* command_ptr) override;
|
void DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32* command_ptr) override;
|
||||||
void DrawRendererStats(bool is_idle_frame) override;
|
void DrawRendererStats(bool is_idle_frame) override;
|
||||||
|
|
||||||
|
|
|
@ -595,6 +595,8 @@ void GPU_HW_D3D11::ReadVRAM(u32 x, u32 y, u32 width, u32 height, void* buffer)
|
||||||
|
|
||||||
void GPU_HW_D3D11::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
void GPU_HW_D3D11::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
||||||
{
|
{
|
||||||
|
GPU_HW::FillVRAM(x, y, width, height, color);
|
||||||
|
|
||||||
// drop precision unless true colour is enabled
|
// drop precision unless true colour is enabled
|
||||||
if (!m_true_color)
|
if (!m_true_color)
|
||||||
color = RGBA5551ToRGBA8888(RGBA8888ToRGBA5551(color));
|
color = RGBA5551ToRGBA8888(RGBA8888ToRGBA5551(color));
|
||||||
|
@ -607,11 +609,12 @@ void GPU_HW_D3D11::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
||||||
DrawUtilityShader(m_fill_pixel_shader.Get(), uniforms, sizeof(uniforms));
|
DrawUtilityShader(m_fill_pixel_shader.Get(), uniforms, sizeof(uniforms));
|
||||||
|
|
||||||
RestoreGraphicsAPIState();
|
RestoreGraphicsAPIState();
|
||||||
InvalidateVRAMReadTexture();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_D3D11::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data)
|
void GPU_HW_D3D11::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data)
|
||||||
{
|
{
|
||||||
|
GPU_HW::UpdateVRAM(x, y, width, height, data);
|
||||||
|
|
||||||
const u32 num_pixels = width * height;
|
const u32 num_pixels = width * height;
|
||||||
const auto map_result = m_texture_stream_buffer.Map(m_context.Get(), sizeof(u16), num_pixels * sizeof(u16));
|
const auto map_result = m_texture_stream_buffer.Map(m_context.Get(), sizeof(u16), num_pixels * sizeof(u16));
|
||||||
std::memcpy(map_result.pointer, data, num_pixels * sizeof(u16));
|
std::memcpy(map_result.pointer, data, num_pixels * sizeof(u16));
|
||||||
|
@ -626,11 +629,12 @@ void GPU_HW_D3D11::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* d
|
||||||
DrawUtilityShader(m_vram_write_pixel_shader.Get(), uniforms, sizeof(uniforms));
|
DrawUtilityShader(m_vram_write_pixel_shader.Get(), uniforms, sizeof(uniforms));
|
||||||
|
|
||||||
RestoreGraphicsAPIState();
|
RestoreGraphicsAPIState();
|
||||||
InvalidateVRAMReadTexture();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_D3D11::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height)
|
void GPU_HW_D3D11::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height)
|
||||||
{
|
{
|
||||||
|
GPU_HW::CopyVRAM(src_x, src_y, dst_x, dst_y, width, height);
|
||||||
|
|
||||||
src_x *= m_resolution_scale;
|
src_x *= m_resolution_scale;
|
||||||
src_y *= m_resolution_scale;
|
src_y *= m_resolution_scale;
|
||||||
dst_x *= m_resolution_scale;
|
dst_x *= m_resolution_scale;
|
||||||
|
@ -640,7 +644,6 @@ void GPU_HW_D3D11::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 widt
|
||||||
|
|
||||||
const CD3D11_BOX src_box(src_x, src_y, 0, src_x + width, src_y + height, 1);
|
const CD3D11_BOX src_box(src_x, src_y, 0, src_x + width, src_y + height, 1);
|
||||||
m_context->CopySubresourceRegion(m_vram_texture, 0, dst_x, dst_y, 0, m_vram_texture, 0, &src_box);
|
m_context->CopySubresourceRegion(m_vram_texture, 0, dst_x, dst_y, 0, m_vram_texture, 0, &src_box);
|
||||||
InvalidateVRAMReadTexture();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_D3D11::UpdateVRAMReadTexture()
|
void GPU_HW_D3D11::UpdateVRAMReadTexture()
|
||||||
|
|
|
@ -547,6 +547,8 @@ void GPU_HW_OpenGL::ReadVRAM(u32 x, u32 y, u32 width, u32 height, void* buffer)
|
||||||
|
|
||||||
void GPU_HW_OpenGL::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
void GPU_HW_OpenGL::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
||||||
{
|
{
|
||||||
|
GPU_HW::FillVRAM(x, y, width, height, color);
|
||||||
|
|
||||||
// scale coordinates
|
// scale coordinates
|
||||||
x *= m_resolution_scale;
|
x *= m_resolution_scale;
|
||||||
y *= m_resolution_scale;
|
y *= m_resolution_scale;
|
||||||
|
@ -564,11 +566,12 @@ void GPU_HW_OpenGL::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
SetScissorFromDrawingArea();
|
SetScissorFromDrawingArea();
|
||||||
InvalidateVRAMReadTexture();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_OpenGL::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data)
|
void GPU_HW_OpenGL::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data)
|
||||||
{
|
{
|
||||||
|
GPU_HW::UpdateVRAM(x, y, width, height, data);
|
||||||
|
|
||||||
const u32 num_pixels = width * height;
|
const u32 num_pixels = width * height;
|
||||||
#if 0
|
#if 0
|
||||||
const auto map_result = m_texture_stream_buffer->Map(sizeof(u32), num_pixels * sizeof(u32));
|
const auto map_result = m_texture_stream_buffer->Map(sizeof(u32), num_pixels * sizeof(u32));
|
||||||
|
@ -649,12 +652,12 @@ void GPU_HW_OpenGL::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void*
|
||||||
|
|
||||||
SetScissorFromDrawingArea();
|
SetScissorFromDrawingArea();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
InvalidateVRAMReadTexture();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_OpenGL::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height)
|
void GPU_HW_OpenGL::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height)
|
||||||
{
|
{
|
||||||
|
GPU_HW::CopyVRAM(src_x, src_y, dst_x, dst_y, width, height);
|
||||||
|
|
||||||
src_x *= m_resolution_scale;
|
src_x *= m_resolution_scale;
|
||||||
src_y *= m_resolution_scale;
|
src_y *= m_resolution_scale;
|
||||||
dst_x *= m_resolution_scale;
|
dst_x *= m_resolution_scale;
|
||||||
|
@ -671,8 +674,6 @@ void GPU_HW_OpenGL::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 wid
|
||||||
glBlitFramebuffer(src_x, src_y, src_x + width, src_y + height, dst_x, dst_y, dst_x + width, dst_y + height,
|
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_NEAREST);
|
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
InvalidateVRAMReadTexture();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_OpenGL::UpdateVRAMReadTexture()
|
void GPU_HW_OpenGL::UpdateVRAMReadTexture()
|
||||||
|
|
Loading…
Reference in New Issue