GPU/HW: Fix mask bit when rendering with transparency and no DSB
Fixes some sprites in Bloody Roar on Mali GPUs.
This commit is contained in:
parent
011df33fc4
commit
837fb6128b
|
@ -1168,7 +1168,7 @@ void GPU_HW::FlushRender()
|
|||
m_batch_ubo_dirty = false;
|
||||
}
|
||||
|
||||
if (m_batch.NeedsTwoPassRendering())
|
||||
if (NeedsTwoPassRendering())
|
||||
{
|
||||
m_renderer_stats.num_batches += 2;
|
||||
DrawBatchVertices(BatchRenderMode::OnlyOpaque, m_batch_base_vertex, vertex_count);
|
||||
|
|
|
@ -102,14 +102,6 @@ protected:
|
|||
bool check_mask_before_draw;
|
||||
bool use_depth_buffer;
|
||||
|
||||
// We need two-pass rendering when using BG-FG blending and texturing, as the transparency can be enabled
|
||||
// on a per-pixel basis, and the opaque pixels shouldn't be blended at all.
|
||||
bool NeedsTwoPassRendering() const
|
||||
{
|
||||
return transparency_mode == GPUTransparencyMode::BackgroundMinusForeground &&
|
||||
texture_mode != GPUTextureMode::Disabled;
|
||||
}
|
||||
|
||||
// Returns the render mode for this batch.
|
||||
BatchRenderMode GetRenderMode() const
|
||||
{
|
||||
|
@ -254,6 +246,15 @@ protected:
|
|||
return true;
|
||||
}
|
||||
|
||||
/// We need two-pass rendering when using BG-FG blending and texturing, as the transparency can be enabled
|
||||
/// on a per-pixel basis, and the opaque pixels shouldn't be blended at all.
|
||||
bool NeedsTwoPassRendering() const
|
||||
{
|
||||
return (m_batch.transparency_mode == GPUTransparencyMode::BackgroundMinusForeground &&
|
||||
m_batch.texture_mode != GPUTextureMode::Disabled) ||
|
||||
(m_batch.transparency_mode != GPUTransparencyMode::Disabled && !m_supports_dual_source_blend);
|
||||
}
|
||||
|
||||
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;
|
||||
void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) override;
|
||||
|
|
|
@ -361,8 +361,6 @@ void GPU_HW_OpenGL::SetCapabilities(HostDisplay* host_display)
|
|||
m_supports_dual_source_blend =
|
||||
(max_dual_source_draw_buffers > 0) &&
|
||||
(GLAD_GL_VERSION_3_3 || GLAD_GL_ARB_blend_func_extended || GLAD_GL_EXT_blend_func_extended);
|
||||
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;
|
||||
|
@ -754,9 +752,19 @@ void GPU_HW_OpenGL::SetBlendMode()
|
|||
GL_FUNC_REVERSE_SUBTRACT :
|
||||
GL_FUNC_ADD,
|
||||
GL_FUNC_ADD);
|
||||
if (m_supports_dual_source_blend)
|
||||
{
|
||||
glBlendFuncSeparate(GL_ONE, m_supports_dual_source_blend ? GL_SRC1_ALPHA : GL_SRC_ALPHA, GL_ONE, GL_ZERO);
|
||||
}
|
||||
else
|
||||
{
|
||||
const float factor =
|
||||
(m_current_transparency_mode == GPUTransparencyMode::HalfBackgroundPlusHalfForeground) ? 0.5f : 1.0f;
|
||||
glBlendFuncSeparate(GL_ONE, GL_CONSTANT_ALPHA, GL_ONE, GL_ZERO);
|
||||
glBlendColor(0.0f, 0.0f, 0.0f, factor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
|
|
@ -939,12 +939,12 @@ float4 SampleFromVRAM(uint4 texpage, float2 coords)
|
|||
o_col0 = float4(color, oalpha);
|
||||
o_col1 = float4(0.0, 0.0, 0.0, u_dst_alpha_factor / ialpha);
|
||||
#else
|
||||
o_col0 = float4(color, u_dst_alpha_factor / ialpha);
|
||||
o_col0 = float4(color, oalpha);
|
||||
#endif
|
||||
|
||||
#if !PGXP_DEPTH
|
||||
#if !PGXP_DEPTH
|
||||
o_depth = oalpha * v_pos.z;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -952,24 +952,16 @@ float4 SampleFromVRAM(uint4 texpage, float2 coords)
|
|||
discard;
|
||||
#endif
|
||||
|
||||
#if TRANSPARENCY_ONLY_OPAQUE
|
||||
// We don't output the second color here because it's not used (except for filtering).
|
||||
o_col0 = float4(color, oalpha);
|
||||
#if USE_DUAL_SOURCE
|
||||
o_col1 = float4(0.0, 0.0, 0.0, 1.0 - ialpha);
|
||||
#endif
|
||||
#else
|
||||
#if USE_DUAL_SOURCE
|
||||
o_col0 = float4(color, oalpha);
|
||||
o_col1 = float4(0.0, 0.0, 0.0, 1.0 - ialpha);
|
||||
#else
|
||||
o_col0 = float4(color, 1.0 - ialpha);
|
||||
#endif
|
||||
o_col0 = float4(color, oalpha);
|
||||
#endif
|
||||
|
||||
#if !PGXP_DEPTH
|
||||
#if !PGXP_DEPTH
|
||||
o_depth = oalpha * v_pos.z;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
// Non-transparency won't enable blending so we can write the mask here regardless.
|
||||
|
@ -979,9 +971,9 @@ float4 SampleFromVRAM(uint4 texpage, float2 coords)
|
|||
o_col1 = float4(0.0, 0.0, 0.0, 1.0 - ialpha);
|
||||
#endif
|
||||
|
||||
#if !PGXP_DEPTH
|
||||
#if !PGXP_DEPTH
|
||||
o_depth = oalpha * v_pos.z;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
)";
|
||||
|
|
|
@ -174,7 +174,8 @@ void GPU_HW_Vulkan::ResetGraphicsAPIState()
|
|||
EndRenderPass();
|
||||
|
||||
if (m_host_display->GetDisplayTextureHandle() == &m_vram_texture)
|
||||
m_vram_texture.TransitionToLayout(g_vulkan_context->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
m_vram_texture.TransitionToLayout(g_vulkan_context->GetCurrentCommandBuffer(),
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
}
|
||||
|
||||
void GPU_HW_Vulkan::RestoreGraphicsAPIState()
|
||||
|
@ -522,9 +523,9 @@ bool GPU_HW_Vulkan::CreateFramebuffer()
|
|||
!m_vram_read_texture.Create(texture_width, texture_height, 1, 1, texture_format, VK_SAMPLE_COUNT_1_BIT,
|
||||
VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT) ||
|
||||
!m_display_texture.Create(GPU_MAX_DISPLAY_WIDTH * m_resolution_scale,
|
||||
GPU_MAX_DISPLAY_HEIGHT * m_resolution_scale, 1, 1, texture_format,
|
||||
VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
|
||||
!m_display_texture.Create(GPU_MAX_DISPLAY_WIDTH * m_resolution_scale, GPU_MAX_DISPLAY_HEIGHT * m_resolution_scale,
|
||||
1, 1, texture_format, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_VIEW_TYPE_2D,
|
||||
VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT) ||
|
||||
!m_vram_readback_texture.Create(VRAM_WIDTH, VRAM_HEIGHT, 1, 1, texture_format, VK_SAMPLE_COUNT_1_BIT,
|
||||
|
@ -923,10 +924,11 @@ bool GPU_HW_Vulkan::CompilePipelines()
|
|||
(static_cast<BatchRenderMode>(render_mode) != BatchRenderMode::TransparencyDisabled &&
|
||||
static_cast<BatchRenderMode>(render_mode) != BatchRenderMode::OnlyOpaque)) ||
|
||||
m_texture_filtering != GPUTextureFilter::Nearest)
|
||||
{
|
||||
if (m_supports_dual_source_blend)
|
||||
{
|
||||
gpbuilder.SetBlendAttachment(
|
||||
0, true, VK_BLEND_FACTOR_ONE,
|
||||
m_supports_dual_source_blend ? VK_BLEND_FACTOR_SRC1_ALPHA : VK_BLEND_FACTOR_SRC_ALPHA,
|
||||
0, true, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_SRC1_ALPHA,
|
||||
(static_cast<GPUTransparencyMode>(transparency_mode) ==
|
||||
GPUTransparencyMode::BackgroundMinusForeground &&
|
||||
static_cast<BatchRenderMode>(render_mode) != BatchRenderMode::TransparencyDisabled &&
|
||||
|
@ -935,6 +937,24 @@ bool GPU_HW_Vulkan::CompilePipelines()
|
|||
VK_BLEND_OP_ADD,
|
||||
VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD);
|
||||
}
|
||||
else
|
||||
{
|
||||
const float factor = (static_cast<GPUTransparencyMode>(transparency_mode) ==
|
||||
GPUTransparencyMode::HalfBackgroundPlusHalfForeground) ?
|
||||
0.5f :
|
||||
1.0f;
|
||||
gpbuilder.SetBlendAttachment(
|
||||
0, true, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_CONSTANT_ALPHA,
|
||||
(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 :
|
||||
VK_BLEND_OP_ADD,
|
||||
VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD);
|
||||
gpbuilder.SetBlendConstants(0.0f, 0.0f, 0.0f, factor);
|
||||
}
|
||||
}
|
||||
|
||||
gpbuilder.SetDynamicViewportAndScissorState();
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#pragma once
|
||||
#include "types.h"
|
||||
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 1;
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 2;
|
Loading…
Reference in New Issue