GPU/HW: Track dirty area of VRAM shadow texture via drawing area
This commit is contained in:
parent
65197d4350
commit
afbec85f89
|
@ -38,8 +38,10 @@ void GPU::Reset()
|
||||||
void GPU::SoftReset()
|
void GPU::SoftReset()
|
||||||
{
|
{
|
||||||
m_GPUSTAT.bits = 0x14802000;
|
m_GPUSTAT.bits = 0x14802000;
|
||||||
m_drawing_area = {};
|
m_drawing_area.Set(0, 0, 0, 0);
|
||||||
|
m_drawing_area_changed = true;
|
||||||
m_drawing_offset = {};
|
m_drawing_offset = {};
|
||||||
|
m_drawing_offset_changed = true;
|
||||||
std::memset(&m_crtc_state, 0, sizeof(m_crtc_state));
|
std::memset(&m_crtc_state, 0, sizeof(m_crtc_state));
|
||||||
m_crtc_state.regs.display_address_start = 0;
|
m_crtc_state.regs.display_address_start = 0;
|
||||||
m_crtc_state.regs.horizontal_display_range = 0xC60260;
|
m_crtc_state.regs.horizontal_display_range = 0xC60260;
|
||||||
|
@ -50,8 +52,6 @@ void GPU::SoftReset()
|
||||||
m_render_state.texture_page_changed = true;
|
m_render_state.texture_page_changed = true;
|
||||||
UpdateGPUSTAT();
|
UpdateGPUSTAT();
|
||||||
UpdateCRTCConfig();
|
UpdateCRTCConfig();
|
||||||
UpdateDrawingArea();
|
|
||||||
UpdateDrawingOffset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GPU::DoState(StateWrapper& sw)
|
bool GPU::DoState(StateWrapper& sw)
|
||||||
|
@ -115,8 +115,8 @@ bool GPU::DoState(StateWrapper& sw)
|
||||||
{
|
{
|
||||||
m_render_state.texture_page_changed = true;
|
m_render_state.texture_page_changed = true;
|
||||||
m_render_state.texture_window_changed = true;
|
m_render_state.texture_window_changed = true;
|
||||||
UpdateDrawingArea();
|
m_drawing_area_changed = true;
|
||||||
UpdateDrawingOffset();
|
m_drawing_offset_changed = true;
|
||||||
UpdateGPUSTAT();
|
UpdateGPUSTAT();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -665,10 +665,6 @@ void GPU::HandleGetGPUInfoCommand(u32 value)
|
||||||
|
|
||||||
void GPU::UpdateDisplay() {}
|
void GPU::UpdateDisplay() {}
|
||||||
|
|
||||||
void GPU::UpdateDrawingArea() {}
|
|
||||||
|
|
||||||
void GPU::UpdateDrawingOffset() {}
|
|
||||||
|
|
||||||
void GPU::ReadVRAM(u32 x, u32 y, u32 width, u32 height, void* buffer) {}
|
void GPU::ReadVRAM(u32 x, u32 y, u32 width, u32 height, void* buffer) {}
|
||||||
|
|
||||||
void GPU::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) {}
|
void GPU::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) {}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "common/bitfield.h"
|
#include "common/bitfield.h"
|
||||||
|
#include "common/rectangle.h"
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
|
@ -289,8 +290,6 @@ protected:
|
||||||
|
|
||||||
// Rendering in the backend
|
// Rendering in the backend
|
||||||
virtual void UpdateDisplay();
|
virtual void UpdateDisplay();
|
||||||
virtual void UpdateDrawingArea();
|
|
||||||
virtual void UpdateDrawingOffset();
|
|
||||||
virtual void ReadVRAM(u32 x, u32 y, u32 width, u32 height, void* buffer);
|
virtual void ReadVRAM(u32 x, u32 y, u32 width, u32 height, void* buffer);
|
||||||
virtual void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color);
|
virtual void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color);
|
||||||
virtual void UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data);
|
virtual void UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data);
|
||||||
|
@ -370,6 +369,21 @@ protected:
|
||||||
(static_cast<u8>(TextureMode::Palette4Bit) | static_cast<u8>(TextureMode::Palette8Bit))) != 0;
|
(static_cast<u8>(TextureMode::Palette4Bit) | static_cast<u8>(TextureMode::Palette8Bit))) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a rectangle comprising the texture page area.
|
||||||
|
Common::Rectangle<u32> GetTexturePageRectangle() const
|
||||||
|
{
|
||||||
|
return Common::Rectangle<u32>::FromExtents(texture_page_x, texture_page_y, TEXTURE_PAGE_WIDTH,
|
||||||
|
TEXTURE_PAGE_HEIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a rectangle comprising the texture palette area.
|
||||||
|
Common::Rectangle<u32> GetTexturePaletteRectangle() const
|
||||||
|
{
|
||||||
|
static constexpr std::array<u32, 4> palette_widths = {{16, 256, 0, 0}};
|
||||||
|
return Common::Rectangle<u32>::FromExtents(texture_palette_x, texture_palette_y,
|
||||||
|
palette_widths[static_cast<u8>(texture_mode) & 3], 1);
|
||||||
|
}
|
||||||
|
|
||||||
bool IsTexturePageChanged() const { return texture_page_changed; }
|
bool IsTexturePageChanged() const { return texture_page_changed; }
|
||||||
void ClearTexturePageChangedFlag() { texture_page_changed = false; }
|
void ClearTexturePageChangedFlag() { texture_page_changed = false; }
|
||||||
|
|
||||||
|
@ -384,11 +398,7 @@ protected:
|
||||||
void SetTextureWindow(u32 value);
|
void SetTextureWindow(u32 value);
|
||||||
} m_render_state = {};
|
} m_render_state = {};
|
||||||
|
|
||||||
struct DrawingArea
|
Common::Rectangle<u32> m_drawing_area;
|
||||||
{
|
|
||||||
u32 left, top;
|
|
||||||
u32 right, bottom;
|
|
||||||
} m_drawing_area = {};
|
|
||||||
|
|
||||||
struct DrawingOffset
|
struct DrawingOffset
|
||||||
{
|
{
|
||||||
|
@ -396,6 +406,9 @@ protected:
|
||||||
s32 y;
|
s32 y;
|
||||||
} m_drawing_offset = {};
|
} m_drawing_offset = {};
|
||||||
|
|
||||||
|
bool m_drawing_area_changed = false;
|
||||||
|
bool m_drawing_offset_changed = false;
|
||||||
|
|
||||||
struct CRTCState
|
struct CRTCState
|
||||||
{
|
{
|
||||||
struct Regs
|
struct Regs
|
||||||
|
|
|
@ -110,11 +110,9 @@ bool GPU::HandleSetDrawingAreaTopLeftCommand(const u32*& command_ptr, u32 comman
|
||||||
Log_DebugPrintf("Set drawing area top-left: (%u, %u)", left, top);
|
Log_DebugPrintf("Set drawing area top-left: (%u, %u)", left, top);
|
||||||
if (m_drawing_area.left != left || m_drawing_area.top != top)
|
if (m_drawing_area.left != left || m_drawing_area.top != top)
|
||||||
{
|
{
|
||||||
FlushRender();
|
|
||||||
|
|
||||||
m_drawing_area.left = left;
|
m_drawing_area.left = left;
|
||||||
m_drawing_area.top = top;
|
m_drawing_area.top = top;
|
||||||
UpdateDrawingArea();
|
m_drawing_area_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -129,11 +127,9 @@ bool GPU::HandleSetDrawingAreaBottomRightCommand(const u32*& command_ptr, u32 co
|
||||||
Log_DebugPrintf("Set drawing area bottom-right: (%u, %u)", m_drawing_area.right, m_drawing_area.bottom);
|
Log_DebugPrintf("Set drawing area bottom-right: (%u, %u)", m_drawing_area.right, m_drawing_area.bottom);
|
||||||
if (m_drawing_area.right != right || m_drawing_area.bottom != bottom)
|
if (m_drawing_area.right != right || m_drawing_area.bottom != bottom)
|
||||||
{
|
{
|
||||||
FlushRender();
|
|
||||||
|
|
||||||
m_drawing_area.right = right;
|
m_drawing_area.right = right;
|
||||||
m_drawing_area.bottom = bottom;
|
m_drawing_area.bottom = bottom;
|
||||||
UpdateDrawingArea();
|
m_drawing_area_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -147,11 +143,9 @@ bool GPU::HandleSetDrawingOffsetCommand(const u32*& command_ptr, u32 command_siz
|
||||||
Log_DebugPrintf("Set drawing offset (%d, %d)", m_drawing_offset.x, m_drawing_offset.y);
|
Log_DebugPrintf("Set drawing offset (%d, %d)", m_drawing_offset.x, m_drawing_offset.y);
|
||||||
if (m_drawing_offset.x != x || m_drawing_offset.y != y)
|
if (m_drawing_offset.x != x || m_drawing_offset.y != y)
|
||||||
{
|
{
|
||||||
FlushRender();
|
|
||||||
|
|
||||||
m_drawing_offset.x = x;
|
m_drawing_offset.x = x;
|
||||||
m_drawing_offset.y = y;
|
m_drawing_offset.y = y;
|
||||||
UpdateDrawingOffset();
|
m_drawing_offset_changed = true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,15 +41,6 @@ void GPU_HW::UpdateSettings()
|
||||||
m_true_color = m_system->GetSettings().gpu_true_color;
|
m_true_color = m_system->GetSettings().gpu_true_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW::UpdateDrawingOffset()
|
|
||||||
{
|
|
||||||
GPU::UpdateDrawingOffset();
|
|
||||||
|
|
||||||
m_batch_ubo_data.u_pos_offset[0] = m_drawing_offset.x;
|
|
||||||
m_batch_ubo_data.u_pos_offset[1] = m_drawing_offset.y;
|
|
||||||
m_batch_ubo_dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPU_HW::LoadVertices(RenderCommand rc, u32 num_vertices, const u32* command_ptr)
|
void GPU_HW::LoadVertices(RenderCommand rc, u32 num_vertices, const u32* command_ptr)
|
||||||
{
|
{
|
||||||
const u32 texpage =
|
const u32 texpage =
|
||||||
|
@ -231,28 +222,14 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
|
||||||
if (m_render_state.IsTexturePageChanged())
|
if (m_render_state.IsTexturePageChanged())
|
||||||
{
|
{
|
||||||
m_render_state.ClearTexturePageChangedFlag();
|
m_render_state.ClearTexturePageChangedFlag();
|
||||||
|
if (m_vram_dirty_rect.Valid() && (m_render_state.GetTexturePageRectangle().Intersects(m_vram_dirty_rect) ||
|
||||||
const u32 texture_page_left = m_render_state.texture_page_x;
|
m_render_state.GetTexturePaletteRectangle().Intersects(m_vram_dirty_rect)))
|
||||||
const u32 texture_page_right = m_render_state.texture_page_y + TEXTURE_PAGE_WIDTH;
|
|
||||||
const u32 texture_page_top = m_render_state.texture_page_y;
|
|
||||||
const u32 texture_page_bottom = texture_page_top + TEXTURE_PAGE_HEIGHT;
|
|
||||||
const bool texture_page_overlaps =
|
|
||||||
(texture_page_left < m_drawing_area.right && texture_page_right > m_drawing_area.left &&
|
|
||||||
texture_page_top > m_drawing_area.bottom && texture_page_bottom < m_drawing_area.top);
|
|
||||||
const u32 texture_palette_left = m_render_state.texture_palette_x;
|
|
||||||
const u32 texture_palette_right = m_render_state.texture_palette_x + 256;
|
|
||||||
const bool texture_palette_overlaps =
|
|
||||||
m_render_state.IsUsingPalette() && texture_palette_left < m_drawing_area.right &&
|
|
||||||
texture_palette_right > m_drawing_area.left && m_render_state.texture_palette_y < m_drawing_area.bottom &&
|
|
||||||
m_render_state.texture_palette_y >= m_drawing_area.top;
|
|
||||||
|
|
||||||
// we only need to update the copy texture if the render area intersects with the texture page
|
|
||||||
if (texture_page_overlaps || texture_palette_overlaps)
|
|
||||||
{
|
{
|
||||||
Log_WarningPrintf("Invalidating VRAM read cache due to drawing area overlap");
|
|
||||||
if (!IsFlushed())
|
if (!IsFlushed())
|
||||||
FlushRender();
|
FlushRender();
|
||||||
InvalidateVRAMReadCache();
|
|
||||||
|
Log_WarningPrintf("Invalidating VRAM read cache due to drawing area overlap");
|
||||||
|
m_vram_read_texture_dirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +244,8 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
|
||||||
const bool buffer_overflow = GetBatchVertexSpace() < max_added_vertices;
|
const bool buffer_overflow = GetBatchVertexSpace() < max_added_vertices;
|
||||||
if (buffer_overflow || rc_primitive == BatchPrimitive::LineStrip || m_batch.texture_mode != texture_mode ||
|
if (buffer_overflow || rc_primitive == BatchPrimitive::LineStrip || m_batch.texture_mode != texture_mode ||
|
||||||
m_batch.transparency_mode != transparency_mode || m_batch.primitive != rc_primitive ||
|
m_batch.transparency_mode != transparency_mode || m_batch.primitive != rc_primitive ||
|
||||||
dithering_enable != m_batch.dithering || m_render_state.IsTextureWindowChanged())
|
dithering_enable != m_batch.dithering || m_drawing_area_changed || m_drawing_offset_changed ||
|
||||||
|
m_render_state.IsTextureWindowChanged())
|
||||||
{
|
{
|
||||||
FlushRender();
|
FlushRender();
|
||||||
}
|
}
|
||||||
|
@ -282,6 +260,14 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
|
||||||
m_batch_ubo_dirty = true;
|
m_batch_ubo_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_drawing_offset_changed)
|
||||||
|
{
|
||||||
|
m_drawing_offset_changed = false;
|
||||||
|
m_batch_ubo_data.u_pos_offset[0] = m_drawing_offset.x;
|
||||||
|
m_batch_ubo_data.u_pos_offset[1] = m_drawing_offset.y;
|
||||||
|
m_batch_ubo_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
// map buffer if it's not already done
|
// map buffer if it's not already done
|
||||||
if (!m_batch_current_vertex_ptr)
|
if (!m_batch_current_vertex_ptr)
|
||||||
MapBatchVertexPointer(max_added_vertices);
|
MapBatchVertexPointer(max_added_vertices);
|
||||||
|
|
|
@ -102,12 +102,10 @@ protected:
|
||||||
static_cast<float>(rgba >> 24) * (1.0f / 255.0f));
|
static_cast<float>(rgba >> 24) * (1.0f / 255.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void UpdateDrawingOffset() override;
|
|
||||||
|
|
||||||
virtual void InvalidateVRAMReadCache() = 0;
|
|
||||||
|
|
||||||
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); }
|
||||||
|
|
||||||
|
@ -135,6 +133,10 @@ protected:
|
||||||
BatchUBOData m_batch_ubo_data = {};
|
BatchUBOData m_batch_ubo_data = {};
|
||||||
bool m_batch_ubo_dirty = true;
|
bool m_batch_ubo_dirty = true;
|
||||||
|
|
||||||
|
// Bounding box of VRAM area that the GPU has drawn into.
|
||||||
|
Common::Rectangle<u32> m_vram_dirty_rect;
|
||||||
|
bool m_vram_read_texture_dirty = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static BatchPrimitive GetPrimitiveForCommand(RenderCommand rc);
|
static BatchPrimitive GetPrimitiveForCommand(RenderCommand rc);
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ void GPU_HW_D3D11::RestoreGraphicsAPIState()
|
||||||
m_context->OMSetRenderTargets(1, m_vram_texture.GetD3DRTVArray(), nullptr);
|
m_context->OMSetRenderTargets(1, m_vram_texture.GetD3DRTVArray(), nullptr);
|
||||||
m_context->RSSetState(m_cull_none_rasterizer_state.Get());
|
m_context->RSSetState(m_cull_none_rasterizer_state.Get());
|
||||||
SetViewport(0, 0, m_vram_texture.GetWidth(), m_vram_texture.GetHeight());
|
SetViewport(0, 0, m_vram_texture.GetWidth(), m_vram_texture.GetHeight());
|
||||||
m_drawing_area_changed = true;
|
SetScissorFromDrawingArea();
|
||||||
m_batch_ubo_dirty = true;
|
m_batch_ubo_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,11 +172,6 @@ void GPU_HW_D3D11::DrawRendererStatsWindow()
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_D3D11::InvalidateVRAMReadCache()
|
|
||||||
{
|
|
||||||
m_vram_read_texture_dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPU_HW_D3D11::MapBatchVertexPointer(u32 required_vertices)
|
void GPU_HW_D3D11::MapBatchVertexPointer(u32 required_vertices)
|
||||||
{
|
{
|
||||||
Assert(!m_batch_start_vertex_ptr);
|
Assert(!m_batch_start_vertex_ptr);
|
||||||
|
@ -536,12 +531,8 @@ void GPU_HW_D3D11::SetDrawState(BatchRenderMode render_mode)
|
||||||
if (m_drawing_area_changed)
|
if (m_drawing_area_changed)
|
||||||
{
|
{
|
||||||
m_drawing_area_changed = false;
|
m_drawing_area_changed = false;
|
||||||
|
m_vram_dirty_rect.Include(m_drawing_area);
|
||||||
int left, top, right, bottom;
|
SetScissorFromDrawingArea();
|
||||||
CalcScissorRect(&left, &top, &right, &bottom);
|
|
||||||
|
|
||||||
CD3D11_RECT rc(left, top, right, bottom);
|
|
||||||
m_context->RSSetScissorRects(1, &rc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_batch_ubo_dirty)
|
if (m_batch_ubo_dirty)
|
||||||
|
@ -549,11 +540,18 @@ void GPU_HW_D3D11::SetDrawState(BatchRenderMode render_mode)
|
||||||
UploadUniformBlock(&m_batch_ubo_data, sizeof(m_batch_ubo_data));
|
UploadUniformBlock(&m_batch_ubo_data, sizeof(m_batch_ubo_data));
|
||||||
m_batch_ubo_dirty = false;
|
m_batch_ubo_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_vram_read_texture_dirty)
|
||||||
|
UpdateVRAMReadTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_D3D11::UpdateDrawingArea()
|
void GPU_HW_D3D11::SetScissorFromDrawingArea()
|
||||||
{
|
{
|
||||||
m_drawing_area_changed = true;
|
int left, top, right, bottom;
|
||||||
|
CalcScissorRect(&left, &top, &right, &bottom);
|
||||||
|
|
||||||
|
CD3D11_RECT rc(left, top, right, bottom);
|
||||||
|
m_context->RSSetScissorRects(1, &rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_D3D11::UpdateDisplay()
|
void GPU_HW_D3D11::UpdateDisplay()
|
||||||
|
@ -659,7 +657,7 @@ 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();
|
||||||
InvalidateVRAMReadCache();
|
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)
|
||||||
|
@ -678,7 +676,7 @@ 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();
|
||||||
InvalidateVRAMReadCache();
|
InvalidateVRAMReadTexture();
|
||||||
m_stats.num_vram_writes++;
|
m_stats.num_vram_writes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,13 +691,14 @@ 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);
|
||||||
InvalidateVRAMReadCache();
|
InvalidateVRAMReadTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_D3D11::UpdateVRAMReadTexture()
|
void GPU_HW_D3D11::UpdateVRAMReadTexture()
|
||||||
{
|
{
|
||||||
m_stats.num_vram_read_texture_updates++;
|
m_stats.num_vram_read_texture_updates++;
|
||||||
m_vram_read_texture_dirty = false;
|
m_vram_read_texture_dirty = false;
|
||||||
|
m_vram_dirty_rect.SetInvalid();
|
||||||
|
|
||||||
const CD3D11_BOX src_box(0, 0, 0, m_vram_texture.GetWidth(), m_vram_texture.GetHeight(), 1);
|
const CD3D11_BOX src_box(0, 0, 0, m_vram_texture.GetWidth(), m_vram_texture.GetHeight(), 1);
|
||||||
m_context->CopySubresourceRegion(m_vram_read_texture, 0, 0, 0, 0, m_vram_texture, 0, &src_box);
|
m_context->CopySubresourceRegion(m_vram_read_texture, 0, 0, 0, 0, m_vram_texture, 0, &src_box);
|
||||||
|
@ -711,9 +710,6 @@ void GPU_HW_D3D11::FlushRender()
|
||||||
if (vertex_count == 0)
|
if (vertex_count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_vram_read_texture_dirty)
|
|
||||||
UpdateVRAMReadTexture();
|
|
||||||
|
|
||||||
m_stats.num_batches++;
|
m_stats.num_batches++;
|
||||||
m_stats.num_vertices += vertex_count;
|
m_stats.num_vertices += vertex_count;
|
||||||
|
|
||||||
|
|
|
@ -30,13 +30,11 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void UpdateDisplay() override;
|
void UpdateDisplay() override;
|
||||||
void UpdateDrawingArea() override;
|
|
||||||
void ReadVRAM(u32 x, u32 y, u32 width, u32 height, void* buffer) override;
|
void ReadVRAM(u32 x, u32 y, u32 width, u32 height, void* buffer) override;
|
||||||
void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) override;
|
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 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 CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) override;
|
||||||
void FlushRender() override;
|
void FlushRender() override;
|
||||||
void InvalidateVRAMReadCache() override;
|
|
||||||
void MapBatchVertexPointer(u32 required_vertices) override;
|
void MapBatchVertexPointer(u32 required_vertices) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -64,6 +62,7 @@ private:
|
||||||
|
|
||||||
bool CompileShaders();
|
bool CompileShaders();
|
||||||
void SetDrawState(BatchRenderMode render_mode);
|
void SetDrawState(BatchRenderMode render_mode);
|
||||||
|
void SetScissorFromDrawingArea();
|
||||||
void UploadUniformBlock(const void* data, u32 data_size);
|
void UploadUniformBlock(const void* data, u32 data_size);
|
||||||
void SetViewport(u32 x, u32 y, u32 width, u32 height);
|
void SetViewport(u32 x, u32 y, u32 width, u32 height);
|
||||||
void SetScissor(u32 x, u32 y, u32 width, u32 height);
|
void SetScissor(u32 x, u32 y, u32 width, u32 height);
|
||||||
|
@ -117,7 +116,5 @@ private:
|
||||||
GLStats m_stats = {};
|
GLStats m_stats = {};
|
||||||
GLStats m_last_stats = {};
|
GLStats m_last_stats = {};
|
||||||
|
|
||||||
bool m_vram_read_texture_dirty = true;
|
|
||||||
bool m_drawing_area_changed = true;
|
|
||||||
bool m_show_renderer_statistics = false;
|
bool m_show_renderer_statistics = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -73,9 +73,10 @@ void GPU_HW_OpenGL::RestoreGraphicsAPIState()
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
glDepthMask(GL_FALSE);
|
glDepthMask(GL_FALSE);
|
||||||
glLineWidth(static_cast<float>(m_resolution_scale));
|
glLineWidth(static_cast<float>(m_resolution_scale));
|
||||||
UpdateDrawingArea();
|
|
||||||
|
|
||||||
glBindVertexArray(m_vao_id);
|
glBindVertexArray(m_vao_id);
|
||||||
|
|
||||||
|
SetScissorFromDrawingArea();
|
||||||
|
m_batch_ubo_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_OpenGL::UpdateSettings()
|
void GPU_HW_OpenGL::UpdateSettings()
|
||||||
|
@ -139,11 +140,6 @@ void GPU_HW_OpenGL::DrawRendererStatsWindow()
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_OpenGL::InvalidateVRAMReadCache()
|
|
||||||
{
|
|
||||||
m_vram_read_texture_dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPU_HW_OpenGL::MapBatchVertexPointer(u32 required_vertices)
|
void GPU_HW_OpenGL::MapBatchVertexPointer(u32 required_vertices)
|
||||||
{
|
{
|
||||||
Assert(!m_batch_start_vertex_ptr);
|
Assert(!m_batch_start_vertex_ptr);
|
||||||
|
@ -397,7 +393,22 @@ void GPU_HW_OpenGL::SetDrawState(BatchRenderMode render_mode)
|
||||||
if (m_drawing_area_changed)
|
if (m_drawing_area_changed)
|
||||||
{
|
{
|
||||||
m_drawing_area_changed = false;
|
m_drawing_area_changed = false;
|
||||||
|
m_vram_dirty_rect.Include(m_drawing_area);
|
||||||
|
SetScissorFromDrawingArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_batch_ubo_dirty)
|
||||||
|
{
|
||||||
|
UploadUniformBlock(&m_batch_ubo_data, sizeof(m_batch_ubo_data));
|
||||||
|
m_batch_ubo_dirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_vram_read_texture_dirty)
|
||||||
|
UpdateVRAMReadTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GPU_HW_OpenGL::SetScissorFromDrawingArea()
|
||||||
|
{
|
||||||
int left, top, right, bottom;
|
int left, top, right, bottom;
|
||||||
CalcScissorRect(&left, &top, &right, &bottom);
|
CalcScissorRect(&left, &top, &right, &bottom);
|
||||||
|
|
||||||
|
@ -408,13 +419,6 @@ void GPU_HW_OpenGL::SetDrawState(BatchRenderMode render_mode)
|
||||||
|
|
||||||
Log_DebugPrintf("SetScissor: (%d-%d, %d-%d)", x, x + width, y, y + height);
|
Log_DebugPrintf("SetScissor: (%d-%d, %d-%d)", x, x + width, y, y + height);
|
||||||
glScissor(x, y, width, height);
|
glScissor(x, y, width, height);
|
||||||
}
|
|
||||||
|
|
||||||
if (m_batch_ubo_dirty)
|
|
||||||
{
|
|
||||||
UploadUniformBlock(&m_batch_ubo_data, sizeof(m_batch_ubo_data));
|
|
||||||
m_batch_ubo_dirty = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_OpenGL::UploadUniformBlock(const void* data, u32 data_size)
|
void GPU_HW_OpenGL::UploadUniformBlock(const void* data, u32 data_size)
|
||||||
|
@ -428,11 +432,6 @@ void GPU_HW_OpenGL::UploadUniformBlock(const void* data, u32 data_size)
|
||||||
m_stats.num_uniform_buffer_updates++;
|
m_stats.num_uniform_buffer_updates++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_OpenGL::UpdateDrawingArea()
|
|
||||||
{
|
|
||||||
m_drawing_area_changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPU_HW_OpenGL::UpdateDisplay()
|
void GPU_HW_OpenGL::UpdateDisplay()
|
||||||
{
|
{
|
||||||
GPU_HW::UpdateDisplay();
|
GPU_HW::UpdateDisplay();
|
||||||
|
@ -616,8 +615,8 @@ void GPU_HW_OpenGL::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
||||||
glClearColor(r, g, b, a);
|
glClearColor(r, g, b, a);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
UpdateDrawingArea();
|
SetScissorFromDrawingArea();
|
||||||
InvalidateVRAMReadCache();
|
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)
|
||||||
|
@ -700,10 +699,10 @@ void GPU_HW_OpenGL::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void*
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
|
|
||||||
UpdateDrawingArea();
|
SetScissorFromDrawingArea();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
InvalidateVRAMReadCache();
|
InvalidateVRAMReadTexture();
|
||||||
m_stats.num_vram_writes++;
|
m_stats.num_vram_writes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -726,13 +725,14 @@ void GPU_HW_OpenGL::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 wid
|
||||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
InvalidateVRAMReadCache();
|
InvalidateVRAMReadTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_OpenGL::UpdateVRAMReadTexture()
|
void GPU_HW_OpenGL::UpdateVRAMReadTexture()
|
||||||
{
|
{
|
||||||
m_stats.num_vram_read_texture_updates++;
|
m_stats.num_vram_read_texture_updates++;
|
||||||
m_vram_read_texture_dirty = false;
|
m_vram_read_texture_dirty = false;
|
||||||
|
m_vram_dirty_rect.SetInvalid();
|
||||||
|
|
||||||
// TODO: Fallback blit path, and partial updates.
|
// TODO: Fallback blit path, and partial updates.
|
||||||
glCopyImageSubData(m_vram_texture->GetGLId(), GL_TEXTURE_2D, 0, 0, 0, 0, m_vram_read_texture->GetGLId(),
|
glCopyImageSubData(m_vram_texture->GetGLId(), GL_TEXTURE_2D, 0, 0, 0, 0, m_vram_read_texture->GetGLId(),
|
||||||
|
@ -745,9 +745,6 @@ void GPU_HW_OpenGL::FlushRender()
|
||||||
if (vertex_count == 0)
|
if (vertex_count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_vram_read_texture_dirty)
|
|
||||||
UpdateVRAMReadTexture();
|
|
||||||
|
|
||||||
m_stats.num_batches++;
|
m_stats.num_batches++;
|
||||||
m_stats.num_vertices += vertex_count;
|
m_stats.num_vertices += vertex_count;
|
||||||
|
|
||||||
|
|
|
@ -26,13 +26,11 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void UpdateDisplay() override;
|
void UpdateDisplay() override;
|
||||||
void UpdateDrawingArea() override;
|
|
||||||
void ReadVRAM(u32 x, u32 y, u32 width, u32 height, void* buffer) override;
|
void ReadVRAM(u32 x, u32 y, u32 width, u32 height, void* buffer) override;
|
||||||
void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) override;
|
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 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 CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) override;
|
||||||
void FlushRender() override;
|
void FlushRender() override;
|
||||||
void InvalidateVRAMReadCache() override;
|
|
||||||
void MapBatchVertexPointer(u32 required_vertices) override;
|
void MapBatchVertexPointer(u32 required_vertices) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -60,6 +58,7 @@ private:
|
||||||
|
|
||||||
bool CompilePrograms();
|
bool CompilePrograms();
|
||||||
void SetDrawState(BatchRenderMode render_mode);
|
void SetDrawState(BatchRenderMode render_mode);
|
||||||
|
void SetScissorFromDrawingArea();
|
||||||
void UploadUniformBlock(const void* data, u32 data_size);
|
void UploadUniformBlock(const void* data, u32 data_size);
|
||||||
|
|
||||||
// downsample texture - used for readbacks at >1xIR.
|
// downsample texture - used for readbacks at >1xIR.
|
||||||
|
@ -86,7 +85,5 @@ private:
|
||||||
GLStats m_stats = {};
|
GLStats m_stats = {};
|
||||||
GLStats m_last_stats = {};
|
GLStats m_last_stats = {};
|
||||||
|
|
||||||
bool m_vram_read_texture_dirty = true;
|
|
||||||
bool m_drawing_area_changed = true;
|
|
||||||
bool m_show_renderer_statistics = false;
|
bool m_show_renderer_statistics = false;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue