GPU/HW: Implement oversized VRAM fills in hardware
Fixes downscaling in Bugs and Taz PAL.
This commit is contained in:
@ -840,7 +840,7 @@ bool GPU_HW_Vulkan::CompilePipelines()
|
||||
m_pgxp_depth_buffer, m_supports_dual_source_blend);
|
||||
|
||||
ShaderCompileProgressTracker progress("Compiling Pipelines", 2 + (4 * 9 * 2 * 2) + (3 * 4 * 5 * 9 * 2 * 2) + 1 + 2 +
|
||||
2 + 2 + 1 + 1 + (2 * 3) + 1);
|
||||
(2 * 2) + 2 + 1 + 1 + (2 * 3) + 1);
|
||||
|
||||
// vertex shaders - [textured]
|
||||
// fragment shaders - [render_mode][texture_mode][dithering][interlacing]
|
||||
@ -1010,11 +1010,12 @@ bool GPU_HW_Vulkan::CompilePipelines()
|
||||
gpbuilder.SetMultisamples(m_multisamples, false);
|
||||
|
||||
// VRAM fill
|
||||
for (u8 wrapped = 0; wrapped < 2; wrapped++)
|
||||
{
|
||||
for (u8 interlaced = 0; interlaced < 2; interlaced++)
|
||||
{
|
||||
VkShaderModule fs = g_vulkan_shader_cache->GetFragmentShader(
|
||||
(interlaced == 0) ? shadergen.GenerateFillFragmentShader() : shadergen.GenerateInterlacedFillFragmentShader());
|
||||
shadergen.GenerateVRAMFillFragmentShader(ConvertToBoolUnchecked(wrapped), ConvertToBoolUnchecked(interlaced)));
|
||||
if (fs == VK_NULL_HANDLE)
|
||||
return false;
|
||||
|
||||
@ -1022,9 +1023,9 @@ bool GPU_HW_Vulkan::CompilePipelines()
|
||||
gpbuilder.SetFragmentShader(fs);
|
||||
gpbuilder.SetDepthState(true, true, VK_COMPARE_OP_ALWAYS);
|
||||
|
||||
m_vram_fill_pipelines[interlaced] = gpbuilder.Create(device, pipeline_cache, false);
|
||||
m_vram_fill_pipelines[wrapped][interlaced] = gpbuilder.Create(device, pipeline_cache, false);
|
||||
vkDestroyShaderModule(device, fs, nullptr);
|
||||
if (m_vram_fill_pipelines[interlaced] == VK_NULL_HANDLE)
|
||||
if (m_vram_fill_pipelines[wrapped][interlaced] == VK_NULL_HANDLE)
|
||||
return false;
|
||||
|
||||
progress.Increment();
|
||||
@ -1249,8 +1250,7 @@ void GPU_HW_Vulkan::DestroyPipelines()
|
||||
{
|
||||
m_batch_pipelines.enumerate(Vulkan::Util::SafeDestroyPipeline);
|
||||
|
||||
for (VkPipeline& p : m_vram_fill_pipelines)
|
||||
Vulkan::Util::SafeDestroyPipeline(p);
|
||||
m_vram_fill_pipelines.enumerate(Vulkan::Util::SafeDestroyPipeline);
|
||||
|
||||
for (VkPipeline& p : m_vram_write_pipelines)
|
||||
Vulkan::Util::SafeDestroyPipeline(p);
|
||||
@ -1482,23 +1482,8 @@ 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.
|
||||
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_ptr, false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
GPU_HW::FillVRAM(x, y, width, height, color);
|
||||
|
||||
x *= m_resolution_scale;
|
||||
y *= m_resolution_scale;
|
||||
width *= m_resolution_scale;
|
||||
height *= m_resolution_scale;
|
||||
|
||||
BeginVRAMRenderPass();
|
||||
|
||||
VkCommandBuffer cmdbuf = g_vulkan_context->GetCurrentCommandBuffer();
|
||||
@ -1506,8 +1491,12 @@ void GPU_HW_Vulkan::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
||||
vkCmdPushConstants(cmdbuf, m_no_samplers_pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(uniforms),
|
||||
&uniforms);
|
||||
vkCmdBindPipeline(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
m_vram_fill_pipelines[BoolToUInt8(IsInterlacedRenderingEnabled())]);
|
||||
Vulkan::Util::SetViewportAndScissor(cmdbuf, x, y, width, height);
|
||||
m_vram_fill_pipelines[BoolToUInt8(IsVRAMFillOversized(x, y, width, height))]
|
||||
[BoolToUInt8(IsInterlacedRenderingEnabled())]);
|
||||
|
||||
const Common::Rectangle<u32> bounds(GetVRAMTransferBounds(x, y, width, height));
|
||||
Vulkan::Util::SetViewportAndScissor(cmdbuf, bounds.left * m_resolution_scale, bounds.top * m_resolution_scale,
|
||||
bounds.GetWidth() * m_resolution_scale, bounds.GetHeight() * m_resolution_scale);
|
||||
vkCmdDraw(cmdbuf, 3, 1, 0, 0);
|
||||
|
||||
RestoreGraphicsAPIState();
|
||||
|
||||
Reference in New Issue
Block a user