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;
|
m_batch_ubo_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_batch.NeedsTwoPassRendering())
|
if (NeedsTwoPassRendering())
|
||||||
{
|
{
|
||||||
m_renderer_stats.num_batches += 2;
|
m_renderer_stats.num_batches += 2;
|
||||||
DrawBatchVertices(BatchRenderMode::OnlyOpaque, m_batch_base_vertex, vertex_count);
|
DrawBatchVertices(BatchRenderMode::OnlyOpaque, m_batch_base_vertex, vertex_count);
|
||||||
|
|
|
@ -102,14 +102,6 @@ protected:
|
||||||
bool check_mask_before_draw;
|
bool check_mask_before_draw;
|
||||||
bool use_depth_buffer;
|
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.
|
// Returns the render mode for this batch.
|
||||||
BatchRenderMode GetRenderMode() const
|
BatchRenderMode GetRenderMode() const
|
||||||
{
|
{
|
||||||
|
@ -254,6 +246,15 @@ protected:
|
||||||
return true;
|
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 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 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 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 =
|
m_supports_dual_source_blend =
|
||||||
(max_dual_source_draw_buffers > 0) &&
|
(max_dual_source_draw_buffers > 0) &&
|
||||||
(GLAD_GL_VERSION_3_3 || GLAD_GL_ARB_blend_func_extended || GLAD_GL_EXT_blend_func_extended);
|
(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 =
|
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;
|
GLAD_GL_VERSION_3_2 || GLAD_GL_ARB_geometry_shader4 || GLAD_GL_OES_geometry_shader || GLAD_GL_ES_VERSION_3_2;
|
||||||
|
@ -754,7 +752,17 @@ void GPU_HW_OpenGL::SetBlendMode()
|
||||||
GL_FUNC_REVERSE_SUBTRACT :
|
GL_FUNC_REVERSE_SUBTRACT :
|
||||||
GL_FUNC_ADD,
|
GL_FUNC_ADD,
|
||||||
GL_FUNC_ADD);
|
GL_FUNC_ADD);
|
||||||
glBlendFuncSeparate(GL_ONE, m_supports_dual_source_blend ? GL_SRC1_ALPHA : GL_SRC_ALPHA, GL_ONE, GL_ZERO);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -939,12 +939,12 @@ float4 SampleFromVRAM(uint4 texpage, float2 coords)
|
||||||
o_col0 = float4(color, oalpha);
|
o_col0 = float4(color, oalpha);
|
||||||
o_col1 = float4(0.0, 0.0, 0.0, u_dst_alpha_factor / ialpha);
|
o_col1 = float4(0.0, 0.0, 0.0, u_dst_alpha_factor / ialpha);
|
||||||
#else
|
#else
|
||||||
o_col0 = float4(color, u_dst_alpha_factor / ialpha);
|
o_col0 = float4(color, oalpha);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !PGXP_DEPTH
|
#if !PGXP_DEPTH
|
||||||
o_depth = oalpha * v_pos.z;
|
o_depth = oalpha * v_pos.z;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -952,24 +952,16 @@ float4 SampleFromVRAM(uint4 texpage, float2 coords)
|
||||||
discard;
|
discard;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if TRANSPARENCY_ONLY_OPAQUE
|
#if USE_DUAL_SOURCE
|
||||||
// We don't output the second color here because it's not used (except for filtering).
|
|
||||||
o_col0 = float4(color, oalpha);
|
o_col0 = float4(color, oalpha);
|
||||||
#if USE_DUAL_SOURCE
|
o_col1 = float4(0.0, 0.0, 0.0, 1.0 - ialpha);
|
||||||
o_col1 = float4(0.0, 0.0, 0.0, 1.0 - ialpha);
|
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
#if USE_DUAL_SOURCE
|
o_col0 = float4(color, oalpha);
|
||||||
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
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !PGXP_DEPTH
|
#if !PGXP_DEPTH
|
||||||
o_depth = oalpha * v_pos.z;
|
o_depth = oalpha * v_pos.z;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// Non-transparency won't enable blending so we can write the mask here regardless.
|
// 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);
|
o_col1 = float4(0.0, 0.0, 0.0, 1.0 - ialpha);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !PGXP_DEPTH
|
#if !PGXP_DEPTH
|
||||||
o_depth = oalpha * v_pos.z;
|
o_depth = oalpha * v_pos.z;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
|
@ -174,7 +174,8 @@ void GPU_HW_Vulkan::ResetGraphicsAPIState()
|
||||||
EndRenderPass();
|
EndRenderPass();
|
||||||
|
|
||||||
if (m_host_display->GetDisplayTextureHandle() == &m_vram_texture)
|
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()
|
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,
|
!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_VIEW_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
|
||||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT) ||
|
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT) ||
|
||||||
!m_display_texture.Create(GPU_MAX_DISPLAY_WIDTH * m_resolution_scale,
|
!m_display_texture.Create(GPU_MAX_DISPLAY_WIDTH * m_resolution_scale, GPU_MAX_DISPLAY_HEIGHT * m_resolution_scale,
|
||||||
GPU_MAX_DISPLAY_HEIGHT * m_resolution_scale, 1, 1, texture_format,
|
1, 1, texture_format, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_VIEW_TYPE_2D,
|
||||||
VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
|
VK_IMAGE_TILING_OPTIMAL,
|
||||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
|
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
|
||||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_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,
|
!m_vram_readback_texture.Create(VRAM_WIDTH, VRAM_HEIGHT, 1, 1, texture_format, VK_SAMPLE_COUNT_1_BIT,
|
||||||
|
@ -924,16 +925,35 @@ bool GPU_HW_Vulkan::CompilePipelines()
|
||||||
static_cast<BatchRenderMode>(render_mode) != BatchRenderMode::OnlyOpaque)) ||
|
static_cast<BatchRenderMode>(render_mode) != BatchRenderMode::OnlyOpaque)) ||
|
||||||
m_texture_filtering != GPUTextureFilter::Nearest)
|
m_texture_filtering != GPUTextureFilter::Nearest)
|
||||||
{
|
{
|
||||||
gpbuilder.SetBlendAttachment(
|
if (m_supports_dual_source_blend)
|
||||||
0, true, VK_BLEND_FACTOR_ONE,
|
{
|
||||||
m_supports_dual_source_blend ? VK_BLEND_FACTOR_SRC1_ALPHA : VK_BLEND_FACTOR_SRC_ALPHA,
|
gpbuilder.SetBlendAttachment(
|
||||||
(static_cast<GPUTransparencyMode>(transparency_mode) ==
|
0, true, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_SRC1_ALPHA,
|
||||||
GPUTransparencyMode::BackgroundMinusForeground &&
|
(static_cast<GPUTransparencyMode>(transparency_mode) ==
|
||||||
static_cast<BatchRenderMode>(render_mode) != BatchRenderMode::TransparencyDisabled &&
|
GPUTransparencyMode::BackgroundMinusForeground &&
|
||||||
static_cast<BatchRenderMode>(render_mode) != BatchRenderMode::OnlyOpaque) ?
|
static_cast<BatchRenderMode>(render_mode) != BatchRenderMode::TransparencyDisabled &&
|
||||||
VK_BLEND_OP_REVERSE_SUBTRACT :
|
static_cast<BatchRenderMode>(render_mode) != BatchRenderMode::OnlyOpaque) ?
|
||||||
VK_BLEND_OP_ADD,
|
VK_BLEND_OP_REVERSE_SUBTRACT :
|
||||||
VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD);
|
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();
|
gpbuilder.SetDynamicViewportAndScissorState();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
static constexpr u32 SHADER_CACHE_VERSION = 1;
|
static constexpr u32 SHADER_CACHE_VERSION = 2;
|
Loading…
Reference in New Issue