GPU/HW: Move logic from backend to GPU_HW class

This commit is contained in:
Connor McLaughlin 2020-04-18 15:30:46 +10:00
parent 5923129eca
commit 65ca8b9fe0
6 changed files with 86 additions and 108 deletions

View file

@ -577,6 +577,42 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
LoadVertices(rc, num_vertices, command_ptr); LoadVertices(rc, num_vertices, command_ptr);
} }
void GPU_HW::FlushRender()
{
if (!m_batch_current_vertex_ptr)
return;
const u32 vertex_count = GetBatchVertexCount();
UnmapBatchVertexPointer(vertex_count);
if (vertex_count == 0)
return;
if (m_drawing_area_changed)
{
m_drawing_area_changed = false;
SetScissorFromDrawingArea();
}
if (m_batch_ubo_dirty)
{
UploadUniformBuffer(&m_batch_ubo_data, sizeof(m_batch_ubo_data));
m_batch_ubo_dirty = false;
}
if (m_batch.NeedsTwoPassRendering())
{
m_renderer_stats.num_batches += 2;
DrawBatchVertices(BatchRenderMode::OnlyTransparent, m_batch_base_vertex, vertex_count);
DrawBatchVertices(BatchRenderMode::OnlyOpaque, m_batch_base_vertex, vertex_count);
}
else
{
m_renderer_stats.num_batches++;
DrawBatchVertices(m_batch.GetRenderMode(), m_batch_base_vertex, vertex_count);
}
}
void GPU_HW::DrawRendererStats(bool is_idle_frame) void GPU_HW::DrawRendererStats(bool is_idle_frame)
{ {
if (!is_idle_frame) if (!is_idle_frame)

View file

@ -121,8 +121,12 @@ protected:
static_cast<float>(rgba >> 24) * (1.0f / 255.0f)); static_cast<float>(rgba >> 24) * (1.0f / 255.0f));
} }
virtual void MapBatchVertexPointer(u32 required_vertices) = 0;
virtual void UpdateVRAMReadTexture() = 0; virtual void UpdateVRAMReadTexture() = 0;
virtual void SetScissorFromDrawingArea() = 0;
virtual void MapBatchVertexPointer(u32 required_vertices) = 0;
virtual void UnmapBatchVertexPointer(u32 used_vertices) = 0;
virtual void UploadUniformBuffer(const void* uniforms, u32 uniforms_size) = 0;
virtual void DrawBatchVertices(BatchRenderMode render_mode, u32 base_vertex, u32 num_vertices) = 0;
void SetFullVRAMDirtyRectangle() void SetFullVRAMDirtyRectangle()
{ {
@ -142,6 +146,7 @@ protected:
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 DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32* command_ptr) override; void DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32* command_ptr) override;
void FlushRender() override;
void DrawRendererStats(bool is_idle_frame) override; void DrawRendererStats(bool is_idle_frame) override;
void CalcScissorRect(int* left, int* top, int* right, int* bottom); void CalcScissorRect(int* left, int* top, int* right, int* bottom);

View file

@ -131,7 +131,7 @@ void GPU_HW_D3D11::UpdateSettings()
void GPU_HW_D3D11::MapBatchVertexPointer(u32 required_vertices) void GPU_HW_D3D11::MapBatchVertexPointer(u32 required_vertices)
{ {
Assert(!m_batch_start_vertex_ptr); DebugAssert(!m_batch_start_vertex_ptr);
const D3D11::StreamBuffer::MappingResult res = const D3D11::StreamBuffer::MappingResult res =
m_vertex_stream_buffer.Map(m_context.Get(), sizeof(BatchVertex), required_vertices * sizeof(BatchVertex)); m_vertex_stream_buffer.Map(m_context.Get(), sizeof(BatchVertex), required_vertices * sizeof(BatchVertex));
@ -142,6 +142,15 @@ void GPU_HW_D3D11::MapBatchVertexPointer(u32 required_vertices)
m_batch_base_vertex = res.index_aligned; m_batch_base_vertex = res.index_aligned;
} }
void GPU_HW_D3D11::UnmapBatchVertexPointer(u32 used_vertices)
{
DebugAssert(m_batch_start_vertex_ptr);
m_vertex_stream_buffer.Unmap(m_context.Get(), used_vertices * sizeof(BatchVertex));
m_batch_start_vertex_ptr = nullptr;
m_batch_end_vertex_ptr = nullptr;
m_batch_current_vertex_ptr = nullptr;
}
void GPU_HW_D3D11::SetCapabilities() void GPU_HW_D3D11::SetCapabilities()
{ {
const u32 max_texture_size = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; const u32 max_texture_size = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
@ -410,7 +419,7 @@ bool GPU_HW_D3D11::CompileShaders()
return true; return true;
} }
void GPU_HW_D3D11::UploadUniformBlock(const void* data, u32 data_size) void GPU_HW_D3D11::UploadUniformBuffer(const void* data, u32 data_size)
{ {
Assert(data_size <= MAX_UNIFORM_BUFFER_SIZE); Assert(data_size <= MAX_UNIFORM_BUFFER_SIZE);
@ -465,7 +474,7 @@ void GPU_HW_D3D11::DrawUtilityShader(ID3D11PixelShader* shader, const void* unif
{ {
if (uniforms) if (uniforms)
{ {
UploadUniformBlock(uniforms, uniforms_size); UploadUniformBuffer(uniforms, uniforms_size);
m_batch_ubo_dirty = true; m_batch_ubo_dirty = true;
} }
@ -478,7 +487,7 @@ void GPU_HW_D3D11::DrawUtilityShader(ID3D11PixelShader* shader, const void* unif
m_context->Draw(3, 0); m_context->Draw(3, 0);
} }
void GPU_HW_D3D11::SetDrawState(BatchRenderMode render_mode) void GPU_HW_D3D11::DrawBatchVertices(BatchRenderMode render_mode, u32 base_vertex, u32 num_vertices)
{ {
const bool textured = (m_batch.texture_mode != TextureMode::Disabled); const bool textured = (m_batch.texture_mode != TextureMode::Disabled);
@ -503,18 +512,7 @@ void GPU_HW_D3D11::SetDrawState(BatchRenderMode render_mode)
(render_mode == BatchRenderMode::OnlyOpaque) ? TransparencyMode::Disabled : m_batch.transparency_mode; (render_mode == BatchRenderMode::OnlyOpaque) ? TransparencyMode::Disabled : m_batch.transparency_mode;
m_context->OMSetBlendState(m_batch_blend_states[static_cast<u8>(transparency_mode)].Get(), nullptr, 0xFFFFFFFFu); m_context->OMSetBlendState(m_batch_blend_states[static_cast<u8>(transparency_mode)].Get(), nullptr, 0xFFFFFFFFu);
if (m_drawing_area_changed) m_context->Draw(num_vertices, base_vertex);
{
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;
}
} }
void GPU_HW_D3D11::SetScissorFromDrawingArea() void GPU_HW_D3D11::SetScissorFromDrawingArea()
@ -729,36 +727,6 @@ void GPU_HW_D3D11::UpdateVRAMReadTexture()
&src_box); &src_box);
} }
void GPU_HW_D3D11::FlushRender()
{
if (!m_batch_current_vertex_ptr)
return;
const u32 vertex_count = GetBatchVertexCount();
m_vertex_stream_buffer.Unmap(m_context.Get(), vertex_count * sizeof(BatchVertex));
m_batch_start_vertex_ptr = nullptr;
m_batch_end_vertex_ptr = nullptr;
m_batch_current_vertex_ptr = nullptr;
if (vertex_count == 0)
return;
m_renderer_stats.num_batches++;
if (m_batch.NeedsTwoPassRendering())
{
SetDrawState(BatchRenderMode::OnlyTransparent);
m_context->Draw(vertex_count, m_batch_base_vertex);
SetDrawState(BatchRenderMode::OnlyOpaque);
m_context->Draw(vertex_count, m_batch_base_vertex);
}
else
{
SetDrawState(m_batch.GetRenderMode());
m_context->Draw(vertex_count, m_batch_base_vertex);
}
}
std::unique_ptr<GPU> GPU::CreateHardwareD3D11Renderer() std::unique_ptr<GPU> GPU::CreateHardwareD3D11Renderer()
{ {
return std::make_unique<GPU_HW_D3D11>(); return std::make_unique<GPU_HW_D3D11>();

View file

@ -33,9 +33,12 @@ protected:
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 MapBatchVertexPointer(u32 required_vertices) override;
void UpdateVRAMReadTexture() override; void UpdateVRAMReadTexture() override;
void SetScissorFromDrawingArea() override;
void MapBatchVertexPointer(u32 required_vertices) override;
void UnmapBatchVertexPointer(u32 used_vertices) override;
void UploadUniformBuffer(const void* data, u32 data_size) override;
void DrawBatchVertices(BatchRenderMode render_mode, u32 base_vertex, u32 num_vertices) override;
private: private:
enum : u32 enum : u32
@ -56,9 +59,6 @@ private:
bool CreateStateObjects(); bool CreateStateObjects();
bool CompileShaders(); bool CompileShaders();
void SetDrawState(BatchRenderMode render_mode);
void SetScissorFromDrawingArea();
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);
void SetViewportAndScissor(u32 x, u32 y, u32 width, u32 height); void SetViewportAndScissor(u32 x, u32 y, u32 width, u32 height);

View file

@ -124,7 +124,7 @@ void GPU_HW_OpenGL::UpdateSettings()
void GPU_HW_OpenGL::MapBatchVertexPointer(u32 required_vertices) void GPU_HW_OpenGL::MapBatchVertexPointer(u32 required_vertices)
{ {
Assert(!m_batch_start_vertex_ptr); DebugAssert(!m_batch_start_vertex_ptr);
const GL::StreamBuffer::MappingResult res = const GL::StreamBuffer::MappingResult res =
m_vertex_stream_buffer->Map(sizeof(BatchVertex), required_vertices * sizeof(BatchVertex)); m_vertex_stream_buffer->Map(sizeof(BatchVertex), required_vertices * sizeof(BatchVertex));
@ -135,6 +135,17 @@ void GPU_HW_OpenGL::MapBatchVertexPointer(u32 required_vertices)
m_batch_base_vertex = res.index_aligned; m_batch_base_vertex = res.index_aligned;
} }
void GPU_HW_OpenGL::UnmapBatchVertexPointer(u32 used_vertices)
{
DebugAssert(m_batch_start_vertex_ptr);
m_vertex_stream_buffer->Unmap(used_vertices * sizeof(BatchVertex));
m_vertex_stream_buffer->Bind();
m_batch_start_vertex_ptr = nullptr;
m_batch_end_vertex_ptr = nullptr;
m_batch_current_vertex_ptr = nullptr;
}
std::tuple<s32, s32> GPU_HW_OpenGL::ConvertToFramebufferCoordinates(s32 x, s32 y) std::tuple<s32, s32> GPU_HW_OpenGL::ConvertToFramebufferCoordinates(s32 x, s32 y)
{ {
return std::make_tuple(x, static_cast<s32>(static_cast<s32>(VRAM_HEIGHT) - y)); return std::make_tuple(x, static_cast<s32>(static_cast<s32>(VRAM_HEIGHT) - y));
@ -439,7 +450,7 @@ bool GPU_HW_OpenGL::CompilePrograms()
return true; return true;
} }
void GPU_HW_OpenGL::SetDrawState(BatchRenderMode render_mode) void GPU_HW_OpenGL::DrawBatchVertices(BatchRenderMode render_mode, u32 base_vertex, u32 num_vertices)
{ {
const GL::Program& prog = const GL::Program& prog =
((m_batch.primitive < BatchPrimitive::Triangles && m_supports_geometry_shaders && m_resolution_scale > 1) ? ((m_batch.primitive < BatchPrimitive::Triangles && m_supports_geometry_shaders && m_resolution_scale > 1) ?
@ -465,18 +476,8 @@ void GPU_HW_OpenGL::SetDrawState(BatchRenderMode render_mode)
glBlendFuncSeparate(GL_ONE, m_supports_dual_source_blend ? GL_SRC1_ALPHA : GL_SRC_ALPHA, GL_ONE, GL_ZERO); glBlendFuncSeparate(GL_ONE, m_supports_dual_source_blend ? GL_SRC1_ALPHA : GL_SRC_ALPHA, GL_ONE, GL_ZERO);
} }
if (m_drawing_area_changed) static constexpr std::array<GLenum, 4> gl_primitives = {{GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP}};
{ glDrawArrays(gl_primitives[static_cast<u8>(m_batch.primitive)], m_batch_base_vertex, num_vertices);
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;
}
} }
void GPU_HW_OpenGL::SetScissorFromDrawingArea() void GPU_HW_OpenGL::SetScissorFromDrawingArea()
@ -493,7 +494,7 @@ void GPU_HW_OpenGL::SetScissorFromDrawingArea()
glScissor(x, y, width, height); glScissor(x, y, width, height);
} }
void GPU_HW_OpenGL::UploadUniformBlock(const void* data, u32 data_size) void GPU_HW_OpenGL::UploadUniformBuffer(const void* data, u32 data_size)
{ {
const GL::StreamBuffer::MappingResult res = m_uniform_stream_buffer->Map(m_uniform_buffer_alignment, data_size); const GL::StreamBuffer::MappingResult res = m_uniform_stream_buffer->Map(m_uniform_buffer_alignment, data_size);
std::memcpy(res.pointer, data, data_size); std::memcpy(res.pointer, data, data_size);
@ -558,7 +559,7 @@ void GPU_HW_OpenGL::UpdateDisplay()
const u32 reinterpret_start_x = m_crtc_state.regs.X * m_resolution_scale; const u32 reinterpret_start_x = m_crtc_state.regs.X * m_resolution_scale;
const u32 reinterpret_width = scaled_display_width + (m_crtc_state.display_vram_left - m_crtc_state.regs.X); const u32 reinterpret_width = scaled_display_width + (m_crtc_state.display_vram_left - m_crtc_state.regs.X);
const u32 uniforms[4] = {reinterpret_start_x, scaled_flipped_vram_offset_y, reinterpret_field_offset}; const u32 uniforms[4] = {reinterpret_start_x, scaled_flipped_vram_offset_y, reinterpret_field_offset};
UploadUniformBlock(uniforms, sizeof(uniforms)); UploadUniformBuffer(uniforms, sizeof(uniforms));
m_batch_ubo_dirty = true; m_batch_ubo_dirty = true;
glViewport(0, reinterpret_field_offset, reinterpret_width, scaled_display_height); glViewport(0, reinterpret_field_offset, reinterpret_width, scaled_display_height);
@ -595,7 +596,7 @@ void GPU_HW_OpenGL::ReadVRAM(u32 x, u32 y, u32 width, u32 height)
m_vram_encoding_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER); m_vram_encoding_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER);
m_vram_texture.Bind(); m_vram_texture.Bind();
m_vram_read_program.Bind(); m_vram_read_program.Bind();
UploadUniformBlock(uniforms, sizeof(uniforms)); UploadUniformBuffer(uniforms, sizeof(uniforms));
glDisable(GL_BLEND); glDisable(GL_BLEND);
glDisable(GL_SCISSOR_TEST); glDisable(GL_SCISSOR_TEST);
glViewport(0, 0, encoded_width, encoded_height); glViewport(0, 0, encoded_width, encoded_height);
@ -659,7 +660,7 @@ void GPU_HW_OpenGL::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
uniforms.u_interlaced_displayed_field = GetInterlacedField(); uniforms.u_interlaced_displayed_field = GetInterlacedField();
m_vram_interlaced_fill_program.Bind(); m_vram_interlaced_fill_program.Bind();
UploadUniformBlock(&uniforms, sizeof(uniforms)); UploadUniformBuffer(&uniforms, sizeof(uniforms));
glDrawArrays(GL_TRIANGLES, 0, 3); glDrawArrays(GL_TRIANGLES, 0, 3);
RestoreGraphicsAPIState(); RestoreGraphicsAPIState();
@ -703,7 +704,7 @@ void GPU_HW_OpenGL::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void*
glBindTexture(GL_TEXTURE_BUFFER, m_texture_buffer_r16ui_texture); glBindTexture(GL_TEXTURE_BUFFER, m_texture_buffer_r16ui_texture);
const u32 uniforms[5] = {x, flipped_y, width, height, map_result.index_aligned}; const u32 uniforms[5] = {x, flipped_y, width, height, map_result.index_aligned};
UploadUniformBlock(uniforms, sizeof(uniforms)); UploadUniformBuffer(uniforms, sizeof(uniforms));
glDrawArrays(GL_TRIANGLES, 0, 3); glDrawArrays(GL_TRIANGLES, 0, 3);
@ -842,38 +843,6 @@ void GPU_HW_OpenGL::UpdateVRAMReadTexture()
} }
} }
void GPU_HW_OpenGL::FlushRender()
{
static constexpr std::array<GLenum, 4> gl_primitives = {{GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP}};
if (!m_batch_current_vertex_ptr)
return;
const u32 vertex_count = GetBatchVertexCount();
m_vertex_stream_buffer->Unmap(vertex_count * sizeof(BatchVertex));
m_batch_start_vertex_ptr = nullptr;
m_batch_end_vertex_ptr = nullptr;
m_batch_current_vertex_ptr = nullptr;
if (vertex_count == 0)
return;
m_vertex_stream_buffer->Bind();
m_renderer_stats.num_batches++;
if (m_batch.NeedsTwoPassRendering())
{
SetDrawState(BatchRenderMode::OnlyTransparent);
glDrawArrays(gl_primitives[static_cast<u8>(m_batch.primitive)], m_batch_base_vertex, vertex_count);
SetDrawState(BatchRenderMode::OnlyOpaque);
glDrawArrays(gl_primitives[static_cast<u8>(m_batch.primitive)], m_batch_base_vertex, vertex_count);
}
else
{
SetDrawState(m_batch.GetRenderMode());
glDrawArrays(gl_primitives[static_cast<u8>(m_batch.primitive)], m_batch_base_vertex, vertex_count);
}
}
std::unique_ptr<GPU> GPU::CreateHardwareOpenGLRenderer() std::unique_ptr<GPU> GPU::CreateHardwareOpenGLRenderer()
{ {
return std::make_unique<GPU_HW_OpenGL>(); return std::make_unique<GPU_HW_OpenGL>();

View file

@ -29,9 +29,12 @@ protected:
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 MapBatchVertexPointer(u32 required_vertices) override;
void UpdateVRAMReadTexture() override; void UpdateVRAMReadTexture() override;
void SetScissorFromDrawingArea() override;
void MapBatchVertexPointer(u32 required_vertices) override;
void UnmapBatchVertexPointer(u32 used_vertices) override;
void UploadUniformBuffer(const void* data, u32 data_size) override;
void DrawBatchVertices(BatchRenderMode render_mode, u32 base_vertex, u32 num_vertices) override;
private: private:
struct GLStats struct GLStats
@ -55,9 +58,6 @@ private:
bool CreateTextureBuffer(); bool CreateTextureBuffer();
bool CompilePrograms(); bool CompilePrograms();
void SetDrawState(BatchRenderMode render_mode);
void SetScissorFromDrawingArea();
void UploadUniformBlock(const void* data, u32 data_size);
GL::ShaderCache m_shader_cache; GL::ShaderCache m_shader_cache;