diff --git a/src/core/gpu_hw.cpp b/src/core/gpu_hw.cpp index 1e6d11455..585ecd0a8 100644 --- a/src/core/gpu_hw.cpp +++ b/src/core/gpu_hw.cpp @@ -577,6 +577,42 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32 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) { if (!is_idle_frame) diff --git a/src/core/gpu_hw.h b/src/core/gpu_hw.h index 58ba08581..06100d957 100644 --- a/src/core/gpu_hw.h +++ b/src/core/gpu_hw.h @@ -121,8 +121,12 @@ protected: static_cast(rgba >> 24) * (1.0f / 255.0f)); } - virtual void MapBatchVertexPointer(u32 required_vertices) = 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() { @@ -142,6 +146,7 @@ protected: 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 FlushRender() override; void DrawRendererStats(bool is_idle_frame) override; void CalcScissorRect(int* left, int* top, int* right, int* bottom); diff --git a/src/core/gpu_hw_d3d11.cpp b/src/core/gpu_hw_d3d11.cpp index d1d243948..af8234ff4 100644 --- a/src/core/gpu_hw_d3d11.cpp +++ b/src/core/gpu_hw_d3d11.cpp @@ -131,7 +131,7 @@ void GPU_HW_D3D11::UpdateSettings() 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 = 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; } +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() { const u32 max_texture_size = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; @@ -410,7 +419,7 @@ bool GPU_HW_D3D11::CompileShaders() 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); @@ -465,7 +474,7 @@ void GPU_HW_D3D11::DrawUtilityShader(ID3D11PixelShader* shader, const void* unif { if (uniforms) { - UploadUniformBlock(uniforms, uniforms_size); + UploadUniformBuffer(uniforms, uniforms_size); m_batch_ubo_dirty = true; } @@ -478,7 +487,7 @@ void GPU_HW_D3D11::DrawUtilityShader(ID3D11PixelShader* shader, const void* unif 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); @@ -503,18 +512,7 @@ void GPU_HW_D3D11::SetDrawState(BatchRenderMode render_mode) (render_mode == BatchRenderMode::OnlyOpaque) ? TransparencyMode::Disabled : m_batch.transparency_mode; m_context->OMSetBlendState(m_batch_blend_states[static_cast(transparency_mode)].Get(), nullptr, 0xFFFFFFFFu); - if (m_drawing_area_changed) - { - 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; - } + m_context->Draw(num_vertices, base_vertex); } void GPU_HW_D3D11::SetScissorFromDrawingArea() @@ -729,36 +727,6 @@ void GPU_HW_D3D11::UpdateVRAMReadTexture() &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::CreateHardwareD3D11Renderer() { return std::make_unique(); diff --git a/src/core/gpu_hw_d3d11.h b/src/core/gpu_hw_d3d11.h index 9452ec328..7e8c2ba54 100644 --- a/src/core/gpu_hw_d3d11.h +++ b/src/core/gpu_hw_d3d11.h @@ -33,9 +33,12 @@ protected: 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 FlushRender() override; - void MapBatchVertexPointer(u32 required_vertices) 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: enum : u32 @@ -56,9 +59,6 @@ private: bool CreateStateObjects(); 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 SetScissor(u32 x, u32 y, u32 width, u32 height); void SetViewportAndScissor(u32 x, u32 y, u32 width, u32 height); diff --git a/src/core/gpu_hw_opengl.cpp b/src/core/gpu_hw_opengl.cpp index 9da7ad434..32f08d560 100644 --- a/src/core/gpu_hw_opengl.cpp +++ b/src/core/gpu_hw_opengl.cpp @@ -124,7 +124,7 @@ void GPU_HW_OpenGL::UpdateSettings() 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 = 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; } +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 GPU_HW_OpenGL::ConvertToFramebufferCoordinates(s32 x, s32 y) { return std::make_tuple(x, static_cast(static_cast(VRAM_HEIGHT) - y)); @@ -439,7 +450,7 @@ bool GPU_HW_OpenGL::CompilePrograms() 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 = ((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); } - if (m_drawing_area_changed) - { - 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; - } + static constexpr std::array gl_primitives = {{GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP}}; + glDrawArrays(gl_primitives[static_cast(m_batch.primitive)], m_batch_base_vertex, num_vertices); } void GPU_HW_OpenGL::SetScissorFromDrawingArea() @@ -493,7 +494,7 @@ void GPU_HW_OpenGL::SetScissorFromDrawingArea() 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); 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_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}; - UploadUniformBlock(uniforms, sizeof(uniforms)); + UploadUniformBuffer(uniforms, sizeof(uniforms)); m_batch_ubo_dirty = true; 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_texture.Bind(); m_vram_read_program.Bind(); - UploadUniformBlock(uniforms, sizeof(uniforms)); + UploadUniformBuffer(uniforms, sizeof(uniforms)); glDisable(GL_BLEND); glDisable(GL_SCISSOR_TEST); 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(); m_vram_interlaced_fill_program.Bind(); - UploadUniformBlock(&uniforms, sizeof(uniforms)); + UploadUniformBuffer(&uniforms, sizeof(uniforms)); glDrawArrays(GL_TRIANGLES, 0, 3); 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); 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); @@ -842,38 +843,6 @@ void GPU_HW_OpenGL::UpdateVRAMReadTexture() } } -void GPU_HW_OpenGL::FlushRender() -{ - static constexpr std::array 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(m_batch.primitive)], m_batch_base_vertex, vertex_count); - SetDrawState(BatchRenderMode::OnlyOpaque); - glDrawArrays(gl_primitives[static_cast(m_batch.primitive)], m_batch_base_vertex, vertex_count); - } - else - { - SetDrawState(m_batch.GetRenderMode()); - glDrawArrays(gl_primitives[static_cast(m_batch.primitive)], m_batch_base_vertex, vertex_count); - } -} - std::unique_ptr GPU::CreateHardwareOpenGLRenderer() { return std::make_unique(); diff --git a/src/core/gpu_hw_opengl.h b/src/core/gpu_hw_opengl.h index 0538f0ebb..bdbb5a650 100644 --- a/src/core/gpu_hw_opengl.h +++ b/src/core/gpu_hw_opengl.h @@ -29,9 +29,12 @@ protected: 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 FlushRender() override; - void MapBatchVertexPointer(u32 required_vertices) 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: struct GLStats @@ -55,9 +58,6 @@ private: bool CreateTextureBuffer(); bool CompilePrograms(); - void SetDrawState(BatchRenderMode render_mode); - void SetScissorFromDrawingArea(); - void UploadUniformBlock(const void* data, u32 data_size); GL::ShaderCache m_shader_cache;