mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 05:45:38 +00:00
GPU/HW: Move logic from backend to GPU_HW class
This commit is contained in:
parent
5923129eca
commit
65ca8b9fe0
|
@ -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)
|
||||
|
|
|
@ -121,8 +121,12 @@ protected:
|
|||
static_cast<float>(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);
|
||||
|
|
|
@ -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<u8>(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> GPU::CreateHardwareD3D11Renderer()
|
||||
{
|
||||
return std::make_unique<GPU_HW_D3D11>();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<s32, s32> GPU_HW_OpenGL::ConvertToFramebufferCoordinates(s32 x, s32 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;
|
||||
}
|
||||
|
||||
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<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);
|
||||
}
|
||||
|
||||
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<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()
|
||||
{
|
||||
return std::make_unique<GPU_HW_OpenGL>();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue