GPU/HW: Fix possible VRAM corruption when live switching resolutions
Mask bit was getting lost based on guest state.
This commit is contained in:
parent
cc5df71af9
commit
7b6d30a994
|
@ -213,18 +213,10 @@ bool GPU::DoState(StateWrapper& sw, bool update_display)
|
|||
|
||||
if (sw.IsReading())
|
||||
{
|
||||
// Need to clear the mask bits since we want to pull it in from the copy.
|
||||
const u32 old_GPUSTAT = m_GPUSTAT.bits;
|
||||
m_GPUSTAT.check_mask_before_draw = false;
|
||||
m_GPUSTAT.set_mask_while_drawing = false;
|
||||
|
||||
// Still need a temporary here.
|
||||
HeapArray<u16, VRAM_WIDTH * VRAM_HEIGHT> temp;
|
||||
sw.DoBytes(temp.data(), VRAM_WIDTH * VRAM_HEIGHT * sizeof(u16));
|
||||
UpdateVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT, temp.data());
|
||||
|
||||
// Restore mask setting.
|
||||
m_GPUSTAT.bits = old_GPUSTAT;
|
||||
UpdateVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT, temp.data(), false, false);
|
||||
|
||||
UpdateCRTCConfig();
|
||||
if (update_display)
|
||||
|
@ -1224,10 +1216,10 @@ void GPU::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
|||
}
|
||||
}
|
||||
|
||||
void GPU::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data)
|
||||
void GPU::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask)
|
||||
{
|
||||
// Fast path when the copy is not oversized.
|
||||
if ((x + width) <= VRAM_WIDTH && (y + height) <= VRAM_HEIGHT && !m_GPUSTAT.IsMaskingEnabled())
|
||||
if ((x + width) <= VRAM_WIDTH && (y + height) <= VRAM_HEIGHT && !set_mask && !check_mask)
|
||||
{
|
||||
const u16* src_ptr = static_cast<const u16*>(data);
|
||||
u16* dst_ptr = &m_vram_ptr[y * VRAM_WIDTH + x];
|
||||
|
@ -1241,9 +1233,10 @@ void GPU::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data)
|
|||
else
|
||||
{
|
||||
// Slow path when we need to handle wrap-around.
|
||||
// During transfer/render operations, if ((dst_pixel & mask_and) == 0) { pixel = src_pixel | mask_or }
|
||||
const u16* src_ptr = static_cast<const u16*>(data);
|
||||
const u16 mask_and = m_GPUSTAT.GetMaskAND();
|
||||
const u16 mask_or = m_GPUSTAT.GetMaskOR();
|
||||
const u16 mask_and = check_mask ? 0x8000 : 0;
|
||||
const u16 mask_or = set_mask ? 0x8000 : 0;
|
||||
|
||||
for (u32 row = 0; row < height;)
|
||||
{
|
||||
|
|
|
@ -273,7 +273,7 @@ protected:
|
|||
// Rendering in the backend
|
||||
virtual void ReadVRAM(u32 x, u32 y, u32 width, u32 height);
|
||||
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, bool set_mask, bool check_mask);
|
||||
virtual void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height);
|
||||
virtual void DispatchRenderCommand();
|
||||
virtual void FlushRender();
|
||||
|
|
|
@ -512,7 +512,7 @@ void GPU::FinishVRAMWrite()
|
|||
if (m_blit_remaining_words == 0)
|
||||
{
|
||||
UpdateVRAM(m_vram_transfer.x, m_vram_transfer.y, m_vram_transfer.width, m_vram_transfer.height,
|
||||
m_blit_buffer.data());
|
||||
m_blit_buffer.data(), m_GPUSTAT.set_mask_while_drawing, m_GPUSTAT.check_mask_before_draw);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -530,12 +530,14 @@ void GPU::FinishVRAMWrite()
|
|||
const u8* blit_ptr = reinterpret_cast<const u8*>(m_blit_buffer.data());
|
||||
if (transferred_full_rows > 0)
|
||||
{
|
||||
UpdateVRAM(m_vram_transfer.x, m_vram_transfer.y, m_vram_transfer.width, transferred_full_rows, blit_ptr);
|
||||
UpdateVRAM(m_vram_transfer.x, m_vram_transfer.y, m_vram_transfer.width, transferred_full_rows, blit_ptr,
|
||||
m_GPUSTAT.set_mask_while_drawing, m_GPUSTAT.check_mask_before_draw);
|
||||
blit_ptr += (ZeroExtend32(m_vram_transfer.width) * transferred_full_rows) * sizeof(u16);
|
||||
}
|
||||
if (transferred_width_last_row > 0)
|
||||
{
|
||||
UpdateVRAM(m_vram_transfer.x, m_vram_transfer.y + transferred_full_rows, transferred_width_last_row, 1, blit_ptr);
|
||||
UpdateVRAM(m_vram_transfer.x, m_vram_transfer.y + transferred_full_rows, transferred_width_last_row, 1, blit_ptr,
|
||||
m_GPUSTAT.set_mask_while_drawing, m_GPUSTAT.check_mask_before_draw);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -780,17 +780,12 @@ Common::Rectangle<u32> GPU_HW::GetVRAMTransferBounds(u32 x, u32 y, u32 width, u3
|
|||
return out_rc;
|
||||
}
|
||||
|
||||
GPU_HW::VRAMWriteUBOData GPU_HW::GetVRAMWriteUBOData(u32 x, u32 y, u32 width, u32 height, u32 buffer_offset) const
|
||||
GPU_HW::VRAMWriteUBOData GPU_HW::GetVRAMWriteUBOData(u32 x, u32 y, u32 width, u32 height, u32 buffer_offset,
|
||||
bool set_mask, bool check_mask) const
|
||||
{
|
||||
const VRAMWriteUBOData uniforms = {(x % VRAM_WIDTH),
|
||||
(y % VRAM_HEIGHT),
|
||||
((x + width) % VRAM_WIDTH),
|
||||
((y + height) % VRAM_HEIGHT),
|
||||
width,
|
||||
height,
|
||||
buffer_offset,
|
||||
m_GPUSTAT.set_mask_while_drawing ? 0x8000u : 0x00,
|
||||
GetCurrentNormalizedVertexDepth()};
|
||||
const VRAMWriteUBOData uniforms = {
|
||||
(x % VRAM_WIDTH), (y % VRAM_HEIGHT), ((x + width) % VRAM_WIDTH), ((y + height) % VRAM_HEIGHT), width,
|
||||
height, buffer_offset, (set_mask) ? 0x8000u : 0x00, GetCurrentNormalizedVertexDepth()};
|
||||
return uniforms;
|
||||
}
|
||||
|
||||
|
@ -897,12 +892,12 @@ void GPU_HW::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
|||
Common::Rectangle<u32>::FromExtents(x, y, width, height).Clamped(0, 0, VRAM_WIDTH, VRAM_HEIGHT));
|
||||
}
|
||||
|
||||
void GPU_HW::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data)
|
||||
void GPU_HW::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask)
|
||||
{
|
||||
DebugAssert((x + width) <= VRAM_WIDTH && (y + height) <= VRAM_HEIGHT);
|
||||
IncludeVRAMDityRectangle(Common::Rectangle<u32>::FromExtents(x, y, width, height));
|
||||
|
||||
if (m_GPUSTAT.check_mask_before_draw)
|
||||
if (check_mask)
|
||||
{
|
||||
// set new vertex counter since we want this to take into consideration previous masked pixels
|
||||
m_current_depth++;
|
||||
|
|
|
@ -248,7 +248,7 @@ 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 UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask) override;
|
||||
void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) override;
|
||||
void DispatchRenderCommand() override;
|
||||
void FlushRender() override;
|
||||
|
@ -268,7 +268,8 @@ protected:
|
|||
bool UseVRAMCopyShader(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) const;
|
||||
|
||||
VRAMFillUBOData GetVRAMFillUBOData(u32 x, u32 y, u32 width, u32 height, u32 color) const;
|
||||
VRAMWriteUBOData GetVRAMWriteUBOData(u32 x, u32 y, u32 width, u32 height, u32 buffer_offset) const;
|
||||
VRAMWriteUBOData GetVRAMWriteUBOData(u32 x, u32 y, u32 width, u32 height, u32 buffer_offset, bool set_mask,
|
||||
bool check_mask) const;
|
||||
VRAMCopyUBOData GetVRAMCopyUBOData(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) const;
|
||||
|
||||
/// Expands a line into two triangles.
|
||||
|
|
|
@ -142,7 +142,7 @@ void GPU_HW_D3D11::UpdateSettings()
|
|||
if (framebuffer_changed)
|
||||
{
|
||||
RestoreGraphicsAPIState();
|
||||
UpdateVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT, m_vram_ptr);
|
||||
UpdateVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT, m_vram_ptr, false, false);
|
||||
UpdateDepthBufferFromMaskBit();
|
||||
UpdateDisplay();
|
||||
ResetGraphicsAPIState();
|
||||
|
@ -767,7 +767,7 @@ void GPU_HW_D3D11::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
|||
Log_WarningPrintf("Oversized VRAM fill (%u-%u, %u-%u), CPU round trip", x, x + width, y, y + height);
|
||||
ReadVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT);
|
||||
GPU::FillVRAM(x, y, width, height, color);
|
||||
UpdateVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT, m_vram_shadow.data());
|
||||
UpdateVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT, m_vram_shadow.data(), false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -786,19 +786,19 @@ void GPU_HW_D3D11::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
|||
RestoreGraphicsAPIState();
|
||||
}
|
||||
|
||||
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, bool set_mask, bool check_mask)
|
||||
{
|
||||
const Common::Rectangle<u32> bounds = GetVRAMTransferBounds(x, y, width, height);
|
||||
GPU_HW::UpdateVRAM(bounds.left, bounds.top, bounds.GetWidth(), bounds.GetHeight(), data);
|
||||
GPU_HW::UpdateVRAM(bounds.left, bounds.top, bounds.GetWidth(), bounds.GetHeight(), data, set_mask, check_mask);
|
||||
|
||||
const u32 num_pixels = width * height;
|
||||
const auto map_result = m_texture_stream_buffer.Map(m_context.Get(), sizeof(u16), num_pixels * sizeof(u16));
|
||||
std::memcpy(map_result.pointer, data, num_pixels * sizeof(u16));
|
||||
m_texture_stream_buffer.Unmap(m_context.Get(), num_pixels * sizeof(u16));
|
||||
|
||||
const VRAMWriteUBOData uniforms = GetVRAMWriteUBOData(x, y, width, height, map_result.index_aligned);
|
||||
m_context->OMSetDepthStencilState(
|
||||
m_GPUSTAT.check_mask_before_draw ? m_depth_test_less_state.Get() : m_depth_test_always_state.Get(), 0);
|
||||
const VRAMWriteUBOData uniforms =
|
||||
GetVRAMWriteUBOData(x, y, width, height, map_result.index_aligned, set_mask, check_mask);
|
||||
m_context->OMSetDepthStencilState(check_mask ? m_depth_test_less_state.Get() : m_depth_test_always_state.Get(), 0);
|
||||
m_context->PSSetShaderResources(0, 1, m_texture_stream_buffer_srv_r16ui.GetAddressOf());
|
||||
|
||||
// the viewport should already be set to the full vram, so just adjust the scissor
|
||||
|
|
|
@ -31,7 +31,7 @@ protected:
|
|||
void UpdateDisplay() override;
|
||||
void ReadVRAM(u32 x, u32 y, u32 width, u32 height) 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, bool set_mask, bool check_mask) override;
|
||||
void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) override;
|
||||
void UpdateVRAMReadTexture() override;
|
||||
void UpdateDepthBufferFromMaskBit() override;
|
||||
|
|
|
@ -150,7 +150,7 @@ void GPU_HW_OpenGL::UpdateSettings()
|
|||
if (framebuffer_changed)
|
||||
{
|
||||
RestoreGraphicsAPIState();
|
||||
UpdateVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT, m_vram_ptr);
|
||||
UpdateVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT, m_vram_ptr, false, false);
|
||||
UpdateDepthBufferFromMaskBit();
|
||||
UpdateDisplay();
|
||||
ResetGraphicsAPIState();
|
||||
|
@ -258,7 +258,8 @@ void GPU_HW_OpenGL::SetCapabilities(HostDisplay* host_display)
|
|||
if (!m_supports_dual_source_blend)
|
||||
Log_WarningPrintf("Dual-source blending is not supported, this may break some mask effects.");
|
||||
|
||||
m_supports_geometry_shaders = GLAD_GL_VERSION_3_2 || GLAD_GL_ARB_geometry_shader4 || GLAD_GL_OES_geometry_shader || GLAD_GL_ES_VERSION_3_2;
|
||||
m_supports_geometry_shaders =
|
||||
GLAD_GL_VERSION_3_2 || GLAD_GL_ARB_geometry_shader4 || GLAD_GL_OES_geometry_shader || GLAD_GL_ES_VERSION_3_2;
|
||||
if (!m_supports_geometry_shaders)
|
||||
{
|
||||
Log_WarningPrintf("Geometry shaders are not supported, line rendering at higher resolutions may be incorrect. We "
|
||||
|
@ -799,7 +800,7 @@ void GPU_HW_OpenGL::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
|||
Log_WarningPrintf("Oversized VRAM fill (%u-%u, %u-%u), CPU round trip", x, x + width, y, y + height);
|
||||
ReadVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT);
|
||||
GPU::FillVRAM(x, y, width, height, color);
|
||||
UpdateVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT, m_vram_shadow.data());
|
||||
UpdateVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT, m_vram_shadow.data(), false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -837,13 +838,13 @@ 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)
|
||||
void GPU_HW_OpenGL::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask)
|
||||
{
|
||||
const u32 num_pixels = width * height;
|
||||
if (num_pixels < m_max_texture_buffer_size || m_use_ssbo_for_vram_writes)
|
||||
{
|
||||
const Common::Rectangle<u32> bounds = GetVRAMTransferBounds(x, y, width, height);
|
||||
GPU_HW::UpdateVRAM(bounds.left, bounds.top, bounds.GetWidth(), bounds.GetHeight(), data);
|
||||
GPU_HW::UpdateVRAM(bounds.left, bounds.top, bounds.GetWidth(), bounds.GetHeight(), data, set_mask, check_mask);
|
||||
|
||||
const auto map_result = m_texture_stream_buffer->Map(sizeof(u16), num_pixels * sizeof(u16));
|
||||
std::memcpy(map_result.pointer, data, num_pixels * sizeof(u16));
|
||||
|
@ -851,7 +852,7 @@ void GPU_HW_OpenGL::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void*
|
|||
m_texture_stream_buffer->Unbind();
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glDepthFunc(m_GPUSTAT.check_mask_before_draw ? GL_GEQUAL : GL_ALWAYS);
|
||||
glDepthFunc(check_mask ? GL_GEQUAL : GL_ALWAYS);
|
||||
|
||||
m_vram_write_program.Bind();
|
||||
if (m_use_ssbo_for_vram_writes)
|
||||
|
@ -859,7 +860,8 @@ void GPU_HW_OpenGL::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void*
|
|||
else
|
||||
glBindTexture(GL_TEXTURE_BUFFER, m_texture_buffer_r16ui_texture);
|
||||
|
||||
const VRAMWriteUBOData uniforms = GetVRAMWriteUBOData(x, y, width, height, map_result.index_aligned);
|
||||
const VRAMWriteUBOData uniforms =
|
||||
GetVRAMWriteUBOData(x, y, width, height, map_result.index_aligned, set_mask, check_mask);
|
||||
UploadUniformBuffer(&uniforms, sizeof(uniforms));
|
||||
|
||||
// the viewport should already be set to the full vram, so just adjust the scissor
|
||||
|
@ -879,12 +881,12 @@ void GPU_HW_OpenGL::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void*
|
|||
// CPU round trip if oversized for now.
|
||||
Log_WarningPrintf("Oversized VRAM update (%u-%u, %u-%u), CPU round trip", x, x + width, y, y + height);
|
||||
ReadVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT);
|
||||
GPU::UpdateVRAM(x, y, width, height, data);
|
||||
UpdateVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT, m_vram_shadow.data());
|
||||
GPU::UpdateVRAM(x, y, width, height, data, set_mask, check_mask);
|
||||
UpdateVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT, m_vram_shadow.data(), false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
GPU_HW::UpdateVRAM(x, y, width, height, data);
|
||||
GPU_HW::UpdateVRAM(x, y, width, height, data, set_mask, check_mask);
|
||||
|
||||
const auto map_result = m_texture_stream_buffer->Map(sizeof(u32), num_pixels * sizeof(u32));
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ protected:
|
|||
void UpdateDisplay() override;
|
||||
void ReadVRAM(u32 x, u32 y, u32 width, u32 height) 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, bool set_mask, bool check_mask) override;
|
||||
void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) override;
|
||||
void UpdateVRAMReadTexture() override;
|
||||
void UpdateDepthBufferFromMaskBit() override;
|
||||
|
|
|
@ -147,7 +147,7 @@ void GPU_HW_Vulkan::UpdateSettings()
|
|||
if (framebuffer_changed)
|
||||
{
|
||||
RestoreGraphicsAPIState();
|
||||
UpdateVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT, m_vram_ptr);
|
||||
UpdateVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT, m_vram_ptr, false, false);
|
||||
UpdateDepthBufferFromMaskBit();
|
||||
UpdateDisplay();
|
||||
ResetGraphicsAPIState();
|
||||
|
@ -705,7 +705,8 @@ bool GPU_HW_Vulkan::CompilePipelines()
|
|||
gpbuilder.SetBlendAttachment(
|
||||
0, true, VK_BLEND_FACTOR_ONE,
|
||||
m_supports_dual_source_blend ? VK_BLEND_FACTOR_SRC1_ALPHA : VK_BLEND_FACTOR_SRC_ALPHA,
|
||||
(static_cast<GPUTransparencyMode>(transparency_mode) == GPUTransparencyMode::BackgroundMinusForeground &&
|
||||
(static_cast<GPUTransparencyMode>(transparency_mode) ==
|
||||
GPUTransparencyMode::BackgroundMinusForeground &&
|
||||
static_cast<BatchRenderMode>(render_mode) != BatchRenderMode::TransparencyDisabled &&
|
||||
static_cast<BatchRenderMode>(render_mode) != BatchRenderMode::OnlyOpaque) ?
|
||||
VK_BLEND_OP_REVERSE_SUBTRACT :
|
||||
|
@ -1115,7 +1116,7 @@ void GPU_HW_Vulkan::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
|||
Log_WarningPrintf("Oversized VRAM fill (%u-%u, %u-%u), CPU round trip", x, x + width, y, y + height);
|
||||
ReadVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT);
|
||||
GPU::FillVRAM(x, y, width, height, color);
|
||||
UpdateVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT, m_vram_shadow.data());
|
||||
UpdateVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT, m_vram_shadow.data(), false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1140,10 +1141,10 @@ void GPU_HW_Vulkan::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
|||
RestoreGraphicsAPIState();
|
||||
}
|
||||
|
||||
void GPU_HW_Vulkan::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data)
|
||||
void GPU_HW_Vulkan::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask)
|
||||
{
|
||||
const Common::Rectangle<u32> bounds = GetVRAMTransferBounds(x, y, width, height);
|
||||
GPU_HW::UpdateVRAM(bounds.left, bounds.top, bounds.GetWidth(), bounds.GetHeight(), data);
|
||||
GPU_HW::UpdateVRAM(bounds.left, bounds.top, bounds.GetWidth(), bounds.GetHeight(), data, set_mask, check_mask);
|
||||
|
||||
const u32 data_size = width * height * sizeof(u16);
|
||||
const u32 alignment = std::max<u32>(sizeof(u16), static_cast<u32>(g_vulkan_context->GetTexelBufferAlignment()));
|
||||
|
@ -1167,11 +1168,10 @@ void GPU_HW_Vulkan::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void*
|
|||
BeginVRAMRenderPass();
|
||||
|
||||
VkCommandBuffer cmdbuf = g_vulkan_context->GetCurrentCommandBuffer();
|
||||
const VRAMWriteUBOData uniforms = GetVRAMWriteUBOData(x, y, width, height, start_index);
|
||||
const VRAMWriteUBOData uniforms = GetVRAMWriteUBOData(x, y, width, height, start_index, set_mask, check_mask);
|
||||
vkCmdPushConstants(cmdbuf, m_vram_write_pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(uniforms),
|
||||
&uniforms);
|
||||
vkCmdBindPipeline(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
m_vram_write_pipelines[BoolToUInt8(m_GPUSTAT.check_mask_before_draw)]);
|
||||
vkCmdBindPipeline(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_vram_write_pipelines[BoolToUInt8(check_mask)]);
|
||||
vkCmdBindDescriptorSets(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_vram_write_pipeline_layout, 0, 1,
|
||||
&m_vram_write_descriptor_set, 0, nullptr);
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ protected:
|
|||
void UpdateDisplay() override;
|
||||
void ReadVRAM(u32 x, u32 y, u32 width, u32 height) 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, bool set_mask, bool check_mask) override;
|
||||
void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) override;
|
||||
void UpdateVRAMReadTexture() override;
|
||||
void UpdateDepthBufferFromMaskBit() override;
|
||||
|
|
|
@ -848,11 +848,13 @@ void GPU_SW::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
|||
m_backend.PushCommand(cmd);
|
||||
}
|
||||
|
||||
void GPU_SW::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data)
|
||||
void GPU_SW::UpdateVRAM(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_backend.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<u16>(x);
|
||||
cmd->y = static_cast<u16>(y);
|
||||
cmd->width = static_cast<u16>(width);
|
||||
|
|
|
@ -24,7 +24,7 @@ public:
|
|||
protected:
|
||||
void ReadVRAM(u32 x, u32 y, u32 width, u32 height) 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, bool set_mask, bool check_mask) override;
|
||||
void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) override;
|
||||
|
||||
template<HostDisplayPixelFormat display_format>
|
||||
|
|
Loading…
Reference in New Issue