diff --git a/src/core/gpu_hw.cpp b/src/core/gpu_hw.cpp index 1cee4c9a3..b2be7883f 100644 --- a/src/core/gpu_hw.cpp +++ b/src/core/gpu_hw.cpp @@ -1092,30 +1092,6 @@ void GPU_HW::ResetBatchVertexDepth() m_current_depth = 1; } -void GPU_HW::FillBackendCommandParameters(GPUBackendCommand* cmd) const -{ - cmd->params.bits = 0; - cmd->params.check_mask_before_draw = m_GPUSTAT.check_mask_before_draw; - cmd->params.set_mask_while_drawing = m_GPUSTAT.set_mask_while_drawing; - cmd->params.active_line_lsb = m_crtc_state.active_line_lsb; - cmd->params.interlaced_rendering = m_GPUSTAT.SkipDrawingToActiveField(); -} - -void GPU_HW::FillDrawCommand(GPUBackendDrawCommand* cmd, GPURenderCommand rc) const -{ - FillBackendCommandParameters(cmd); - cmd->rc.bits = rc.bits; - cmd->draw_mode.bits = m_draw_mode.mode_reg.bits; - cmd->palette.bits = m_draw_mode.palette_reg; - cmd->window = m_draw_mode.texture_window; -} - -void GPU_HW::HandleVRAMReadWithSoftwareRenderer(u32 x, u32 y, u32 width, u32 height) -{ - DebugAssert(m_sw_renderer); - m_sw_renderer->Sync(false); -} - void GPU_HW::UpdateSoftwareRenderer(bool copy_vram_from_hw) { const bool current_enabled = (m_sw_renderer != nullptr); @@ -1154,22 +1130,75 @@ void GPU_HW::UpdateSoftwareRenderer(bool copy_vram_from_hw) m_vram_ptr = m_sw_renderer->GetVRAM(); } +void GPU_HW::FillBackendCommandParameters(GPUBackendCommand* cmd) const +{ + cmd->params.bits = 0; + cmd->params.check_mask_before_draw = m_GPUSTAT.check_mask_before_draw; + cmd->params.set_mask_while_drawing = m_GPUSTAT.set_mask_while_drawing; + cmd->params.active_line_lsb = m_crtc_state.active_line_lsb; + cmd->params.interlaced_rendering = m_GPUSTAT.SkipDrawingToActiveField(); +} + +void GPU_HW::FillDrawCommand(GPUBackendDrawCommand* cmd, GPURenderCommand rc) const +{ + FillBackendCommandParameters(cmd); + cmd->rc.bits = rc.bits; + cmd->draw_mode.bits = m_draw_mode.mode_reg.bits; + cmd->palette.bits = m_draw_mode.palette_reg; + cmd->window = m_draw_mode.texture_window; +} + +void GPU_HW::ReadSoftwareRendererVRAM(u32 x, u32 y, u32 width, u32 height) +{ + DebugAssert(m_sw_renderer); + m_sw_renderer->Sync(false); +} + +void GPU_HW::UpdateSoftwareRendererVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, + bool check_mask) +{ + const u32 num_words = width * height; + GPUBackendUpdateVRAMCommand* cmd = m_sw_renderer->NewUpdateVRAMCommand(num_words); + FillBackendCommandParameters(cmd); + cmd->params.set_mask_while_drawing = set_mask; + cmd->params.check_mask_before_draw = check_mask; + cmd->x = static_cast(x); + cmd->y = static_cast(y); + cmd->width = static_cast(width); + cmd->height = static_cast(height); + std::memcpy(cmd->data, data, sizeof(u16) * num_words); + m_sw_renderer->PushCommand(cmd); +} + +void GPU_HW::FillSoftwareRendererVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) +{ + GPUBackendFillVRAMCommand* cmd = m_sw_renderer->NewFillVRAMCommand(); + FillBackendCommandParameters(cmd); + cmd->x = static_cast(x); + cmd->y = static_cast(y); + cmd->width = static_cast(width); + cmd->height = static_cast(height); + cmd->color = color; + m_sw_renderer->PushCommand(cmd); +} + +void GPU_HW::CopySoftwareRendererVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) +{ + GPUBackendCopyVRAMCommand* cmd = m_sw_renderer->NewCopyVRAMCommand(); + FillBackendCommandParameters(cmd); + cmd->src_x = static_cast(src_x); + cmd->src_y = static_cast(src_y); + cmd->dst_x = static_cast(dst_x); + cmd->dst_y = static_cast(dst_y); + cmd->width = static_cast(width); + cmd->height = static_cast(height); + m_sw_renderer->PushCommand(cmd); +} + void GPU_HW::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) { IncludeVRAMDirtyRectangle( Common::Rectangle::FromExtents(x, y, width, height).Clamped(0, 0, VRAM_WIDTH, VRAM_HEIGHT)); - - if (m_sw_renderer) - { - GPUBackendFillVRAMCommand* cmd = m_sw_renderer->NewFillVRAMCommand(); - FillBackendCommandParameters(cmd); - cmd->x = static_cast(x); - cmd->y = static_cast(y); - cmd->width = static_cast(width); - cmd->height = static_cast(height); - cmd->color = color; - m_sw_renderer->PushCommand(cmd); - } } void GPU_HW::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask) @@ -1182,21 +1211,6 @@ void GPU_HW::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, b // set new vertex counter since we want this to take into consideration previous masked pixels m_current_depth++; } - - if (m_sw_renderer) - { - const u32 num_words = width * height; - GPUBackendUpdateVRAMCommand* cmd = m_sw_renderer->NewUpdateVRAMCommand(num_words); - FillBackendCommandParameters(cmd); - cmd->params.set_mask_while_drawing = set_mask; - cmd->params.check_mask_before_draw = check_mask; - cmd->x = static_cast(x); - cmd->y = static_cast(y); - cmd->width = static_cast(width); - cmd->height = static_cast(height); - std::memcpy(cmd->data, data, sizeof(u16) * num_words); - m_sw_renderer->PushCommand(cmd); - } } void GPU_HW::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) @@ -1209,19 +1223,6 @@ void GPU_HW::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 // set new vertex counter since we want this to take into consideration previous masked pixels m_current_depth++; } - - if (m_sw_renderer) - { - GPUBackendCopyVRAMCommand* cmd = m_sw_renderer->NewCopyVRAMCommand(); - FillBackendCommandParameters(cmd); - cmd->src_x = static_cast(src_x); - cmd->src_y = static_cast(src_y); - cmd->dst_x = static_cast(dst_x); - cmd->dst_y = static_cast(dst_y); - cmd->width = static_cast(width); - cmd->height = static_cast(height); - m_sw_renderer->PushCommand(cmd); - } } void GPU_HW::DispatchRenderCommand() diff --git a/src/core/gpu_hw.h b/src/core/gpu_hw.h index c077ee5f5..2fbfe8da1 100644 --- a/src/core/gpu_hw.h +++ b/src/core/gpu_hw.h @@ -262,8 +262,12 @@ protected: void FillBackendCommandParameters(GPUBackendCommand* cmd) const; void FillDrawCommand(GPUBackendDrawCommand* cmd, GPURenderCommand rc) const; - void HandleVRAMReadWithSoftwareRenderer(u32 x, u32 y, u32 width, u32 height); void UpdateSoftwareRenderer(bool copy_vram_from_hw); + void ReadSoftwareRendererVRAM(u32 x, u32 y, u32 width, u32 height); + void UpdateSoftwareRendererVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, + bool check_mask); + void FillSoftwareRendererVRAM(u32 x, u32 y, u32 width, u32 height, u32 color); + void CopySoftwareRendererVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height); 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, bool set_mask, bool check_mask) override; diff --git a/src/core/gpu_hw_d3d11.cpp b/src/core/gpu_hw_d3d11.cpp index 7cfc01e49..09ba7e78b 100644 --- a/src/core/gpu_hw_d3d11.cpp +++ b/src/core/gpu_hw_d3d11.cpp @@ -949,7 +949,7 @@ void GPU_HW_D3D11::ReadVRAM(u32 x, u32 y, u32 width, u32 height) { if (IsUsingSoftwareRendererForReadbacks()) { - HandleVRAMReadWithSoftwareRenderer(x, y, width, height); + ReadSoftwareRendererVRAM(x, y, width, height); return; } @@ -988,6 +988,9 @@ void GPU_HW_D3D11::ReadVRAM(u32 x, u32 y, u32 width, u32 height) void GPU_HW_D3D11::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) { + if (IsUsingSoftwareRendererForReadbacks()) + FillSoftwareRendererVRAM(x, y, width, height, color); + if ((x + width) > VRAM_WIDTH || (y + height) > VRAM_HEIGHT) { // CPU round trip if oversized for now. @@ -1015,6 +1018,9 @@ void GPU_HW_D3D11::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) void GPU_HW_D3D11::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask) { + if (IsUsingSoftwareRendererForReadbacks()) + UpdateSoftwareRendererVRAM(x, y, width, height, data, set_mask, check_mask); + const Common::Rectangle bounds = GetVRAMTransferBounds(x, y, width, height); GPU_HW::UpdateVRAM(bounds.left, bounds.top, bounds.GetWidth(), bounds.GetHeight(), data, set_mask, check_mask); @@ -1050,11 +1056,11 @@ void GPU_HW_D3D11::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* d void GPU_HW_D3D11::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) { + if (IsUsingSoftwareRendererForReadbacks()) + CopySoftwareRendererVRAM(src_x, src_y, dst_x, dst_y, width, height); + if (UseVRAMCopyShader(src_x, src_y, dst_x, dst_y, width, height) || IsUsingMultisampling()) { - if (IsUsingSoftwareRendererForReadbacks()) - GPU_HW::CopyVRAM(src_x, src_y, dst_x, dst_y, width, height); - const Common::Rectangle src_bounds = GetVRAMTransferBounds(src_x, src_y, width, height); const Common::Rectangle dst_bounds = GetVRAMTransferBounds(dst_x, dst_y, width, height); if (m_vram_dirty_rect.Intersects(src_bounds)) diff --git a/src/core/gpu_hw_opengl.cpp b/src/core/gpu_hw_opengl.cpp index 739bd401a..290f08665 100644 --- a/src/core/gpu_hw_opengl.cpp +++ b/src/core/gpu_hw_opengl.cpp @@ -984,7 +984,7 @@ void GPU_HW_OpenGL::ReadVRAM(u32 x, u32 y, u32 width, u32 height) { if (IsUsingSoftwareRendererForReadbacks()) { - HandleVRAMReadWithSoftwareRenderer(x, y, width, height); + ReadSoftwareRendererVRAM(x, y, width, height); return; } @@ -1019,6 +1019,9 @@ void GPU_HW_OpenGL::ReadVRAM(u32 x, u32 y, u32 width, u32 height) void GPU_HW_OpenGL::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) { + if (IsUsingSoftwareRendererForReadbacks()) + FillSoftwareRendererVRAM(x, y, width, height, color); + if ((x + width) > VRAM_WIDTH || (y + height) > VRAM_HEIGHT) { // CPU round trip if oversized for now. @@ -1066,6 +1069,9 @@ void GPU_HW_OpenGL::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) void GPU_HW_OpenGL::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask) { + if (IsUsingSoftwareRendererForReadbacks()) + UpdateSoftwareRendererVRAM(x, y, width, height, data, set_mask, check_mask); + const Common::Rectangle bounds = GetVRAMTransferBounds(x, y, width, height); GPU_HW::UpdateVRAM(bounds.left, bounds.top, bounds.GetWidth(), bounds.GetHeight(), data, set_mask, check_mask); @@ -1182,15 +1188,15 @@ void GPU_HW_OpenGL::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* void GPU_HW_OpenGL::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) { + if (IsUsingSoftwareRendererForReadbacks()) + CopySoftwareRendererVRAM(src_x, src_y, dst_x, dst_y, width, height); + const Common::Rectangle dst_bounds = GetVRAMTransferBounds(dst_x, dst_y, width, height); const Common::Rectangle src_bounds = GetVRAMTransferBounds(src_x, src_y, width, height); const bool src_dirty = m_vram_dirty_rect.Intersects(src_bounds); if (UseVRAMCopyShader(src_x, src_y, dst_x, dst_y, width, height)) { - if (IsUsingSoftwareRendererForReadbacks()) - GPU_HW::CopyVRAM(src_x, src_y, dst_x, dst_y, width, height); - if (src_dirty) UpdateVRAMReadTexture(); IncludeVRAMDirtyRectangle(dst_bounds); diff --git a/src/core/gpu_hw_vulkan.cpp b/src/core/gpu_hw_vulkan.cpp index 3503b5bfa..f70c786c1 100644 --- a/src/core/gpu_hw_vulkan.cpp +++ b/src/core/gpu_hw_vulkan.cpp @@ -1440,7 +1440,7 @@ void GPU_HW_Vulkan::ReadVRAM(u32 x, u32 y, u32 width, u32 height) { if (IsUsingSoftwareRendererForReadbacks()) { - HandleVRAMReadWithSoftwareRenderer(x, y, width, height); + ReadSoftwareRendererVRAM(x, y, width, height); return; } @@ -1489,6 +1489,9 @@ void GPU_HW_Vulkan::ReadVRAM(u32 x, u32 y, u32 width, u32 height) void GPU_HW_Vulkan::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) { + if (IsUsingSoftwareRendererForReadbacks()) + FillSoftwareRendererVRAM(x, y, width, height, color); + if ((x + width) > VRAM_WIDTH || (y + height) > VRAM_HEIGHT) { // CPU round trip if oversized for now. @@ -1522,6 +1525,9 @@ void GPU_HW_Vulkan::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) void GPU_HW_Vulkan::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask) { + if (IsUsingSoftwareRendererForReadbacks()) + UpdateSoftwareRendererVRAM(x, y, width, height, data, set_mask, check_mask); + const Common::Rectangle bounds = GetVRAMTransferBounds(x, y, width, height); GPU_HW::UpdateVRAM(bounds.left, bounds.top, bounds.GetWidth(), bounds.GetHeight(), data, set_mask, check_mask); @@ -1576,11 +1582,11 @@ void GPU_HW_Vulkan::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* void GPU_HW_Vulkan::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) { + if (IsUsingSoftwareRendererForReadbacks()) + CopySoftwareRendererVRAM(src_x, src_y, dst_x, dst_y, width, height); + if (UseVRAMCopyShader(src_x, src_y, dst_x, dst_y, width, height) || IsUsingMultisampling()) { - if (IsUsingSoftwareRendererForReadbacks()) - GPU_HW::CopyVRAM(src_x, src_y, dst_x, dst_y, width, height); - const Common::Rectangle src_bounds = GetVRAMTransferBounds(src_x, src_y, width, height); const Common::Rectangle dst_bounds = GetVRAMTransferBounds(dst_x, dst_y, width, height); if (m_vram_dirty_rect.Intersects(src_bounds))