mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-06 23:11:25 +12:00
rssx" Halfplement alpha-to-coverage AA transparency
This commit is contained in:
parent
2dce55d036
commit
f00d9a7c7f
3 changed files with 84 additions and 21 deletions
|
@ -1187,7 +1187,7 @@ void GLGSRender::update_draw_state()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool mrt_blend_enabled[] =
|
bool mrt_blend_enabled[] =
|
||||||
{
|
{
|
||||||
rsx::method_registers.blend_enabled(),
|
rsx::method_registers.blend_enabled(),
|
||||||
rsx::method_registers.blend_enabled_surface_1(),
|
rsx::method_registers.blend_enabled_surface_1(),
|
||||||
|
@ -1195,18 +1195,38 @@ void GLGSRender::update_draw_state()
|
||||||
rsx::method_registers.blend_enabled_surface_3()
|
rsx::method_registers.blend_enabled_surface_3()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool blend_equation_override = false;
|
||||||
|
if (rsx::method_registers.msaa_alpha_to_coverage_enabled() &&
|
||||||
|
!rsx::method_registers.alpha_test_enabled())
|
||||||
|
{
|
||||||
|
if (rsx::method_registers.msaa_enabled() &&
|
||||||
|
rsx::method_registers.msaa_sample_mask() &&
|
||||||
|
rsx::method_registers.surface_antialias() != rsx::surface_antialiasing::center_1_sample)
|
||||||
|
{
|
||||||
|
//fake alpha-to-coverage
|
||||||
|
//blend used in conjunction with alpha test to fake order-independent edge transparency
|
||||||
|
mrt_blend_enabled[0] = mrt_blend_enabled[1] = mrt_blend_enabled[2] = mrt_blend_enabled[3] = true;
|
||||||
|
blend_equation_override = true;
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
glBlendEquation(GL_FUNC_ADD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mrt_blend_enabled[0] || mrt_blend_enabled[1] || mrt_blend_enabled[2] || mrt_blend_enabled[3])
|
if (mrt_blend_enabled[0] || mrt_blend_enabled[1] || mrt_blend_enabled[2] || mrt_blend_enabled[3])
|
||||||
{
|
{
|
||||||
glBlendFuncSeparate(blend_factor(rsx::method_registers.blend_func_sfactor_rgb()),
|
if (!blend_equation_override)
|
||||||
blend_factor(rsx::method_registers.blend_func_dfactor_rgb()),
|
{
|
||||||
blend_factor(rsx::method_registers.blend_func_sfactor_a()),
|
glBlendFuncSeparate(blend_factor(rsx::method_registers.blend_func_sfactor_rgb()),
|
||||||
blend_factor(rsx::method_registers.blend_func_dfactor_a()));
|
blend_factor(rsx::method_registers.blend_func_dfactor_rgb()),
|
||||||
|
blend_factor(rsx::method_registers.blend_func_sfactor_a()),
|
||||||
|
blend_factor(rsx::method_registers.blend_func_dfactor_a()));
|
||||||
|
|
||||||
auto blend_colors = rsx::get_constant_blend_colors();
|
auto blend_colors = rsx::get_constant_blend_colors();
|
||||||
glBlendColor(blend_colors[0], blend_colors[1], blend_colors[2], blend_colors[3]);
|
glBlendColor(blend_colors[0], blend_colors[1], blend_colors[2], blend_colors[3]);
|
||||||
|
|
||||||
glBlendEquationSeparate(blend_equation(rsx::method_registers.blend_equation_rgb()),
|
glBlendEquationSeparate(blend_equation(rsx::method_registers.blend_equation_rgb()),
|
||||||
blend_equation(rsx::method_registers.blend_equation_a()));
|
blend_equation(rsx::method_registers.blend_equation_a()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_state.enablei(mrt_blend_enabled[0], GL_BLEND, 0);
|
gl_state.enablei(mrt_blend_enabled[0], GL_BLEND, 0);
|
||||||
|
|
|
@ -543,8 +543,11 @@ namespace rsx
|
||||||
performance_counters.FIFO_idle_timestamp = get_system_time();
|
performance_counters.FIFO_idle_timestamp = get_system_time();
|
||||||
performance_counters.FIFO_is_idle = true;
|
performance_counters.FIFO_is_idle = true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
do_internal_task();
|
||||||
|
}
|
||||||
|
|
||||||
do_internal_task();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -950,11 +953,28 @@ namespace rsx
|
||||||
|
|
||||||
void thread::fill_fragment_state_buffer(void *buffer, const RSXFragmentProgram &fragment_program)
|
void thread::fill_fragment_state_buffer(void *buffer, const RSXFragmentProgram &fragment_program)
|
||||||
{
|
{
|
||||||
const u32 is_alpha_tested = rsx::method_registers.alpha_test_enabled();
|
//TODO: Properly support alpha-to-coverage and alpha-to-one behavior in shaders
|
||||||
const f32 alpha_ref = rsx::method_registers.alpha_ref() / 255.f;
|
auto fragment_alpha_func = rsx::method_registers.alpha_func();
|
||||||
|
auto alpha_ref = rsx::method_registers.alpha_ref() / 255.f;
|
||||||
|
auto is_alpha_tested = (u32)rsx::method_registers.alpha_test_enabled();
|
||||||
|
|
||||||
|
if (rsx::method_registers.msaa_alpha_to_coverage_enabled() && !is_alpha_tested)
|
||||||
|
{
|
||||||
|
if (rsx::method_registers.msaa_enabled() &&
|
||||||
|
rsx::method_registers.surface_antialias() != rsx::surface_antialiasing::center_1_sample)
|
||||||
|
{
|
||||||
|
//alpha values generate a coverage mask for order independent blending
|
||||||
|
//requires hardware AA to work properly (or just fragment sample stage in fragment shaders)
|
||||||
|
//simulated using combined alpha blend and alpha test
|
||||||
|
fragment_alpha_func = rsx::comparison_function::greater;
|
||||||
|
alpha_ref = rsx::method_registers.msaa_sample_mask()? 0.25f : 0.f;
|
||||||
|
is_alpha_tested |= (1 << 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const f32 fog0 = rsx::method_registers.fog_params_0();
|
const f32 fog0 = rsx::method_registers.fog_params_0();
|
||||||
const f32 fog1 = rsx::method_registers.fog_params_1();
|
const f32 fog1 = rsx::method_registers.fog_params_1();
|
||||||
const u32 alpha_func = static_cast<u32>(rsx::method_registers.alpha_func());
|
const u32 alpha_func = static_cast<u32>(fragment_alpha_func);
|
||||||
const u32 fog_mode = static_cast<u32>(rsx::method_registers.fog_equation());
|
const u32 fog_mode = static_cast<u32>(rsx::method_registers.fog_equation());
|
||||||
|
|
||||||
// Generate wpos coeffecients
|
// Generate wpos coeffecients
|
||||||
|
|
|
@ -2165,7 +2165,7 @@ void VKGSRender::load_program(const vk::vertex_upload_info& vertex_info)
|
||||||
properties.att_state[idx].colorWriteMask = mask;
|
properties.att_state[idx].colorWriteMask = mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool mrt_blend_enabled[] =
|
bool mrt_blend_enabled[] =
|
||||||
{
|
{
|
||||||
rsx::method_registers.blend_enabled(),
|
rsx::method_registers.blend_enabled(),
|
||||||
rsx::method_registers.blend_enabled_surface_1(),
|
rsx::method_registers.blend_enabled_surface_1(),
|
||||||
|
@ -2173,15 +2173,38 @@ void VKGSRender::load_program(const vk::vertex_upload_info& vertex_info)
|
||||||
rsx::method_registers.blend_enabled_surface_3()
|
rsx::method_registers.blend_enabled_surface_3()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool blend_equation_override = false;
|
||||||
|
VkBlendFactor sfactor_rgb, sfactor_a, dfactor_rgb, dfactor_a;
|
||||||
|
VkBlendOp equation_rgb, equation_a;
|
||||||
|
|
||||||
|
if (rsx::method_registers.msaa_alpha_to_coverage_enabled() &&
|
||||||
|
!rsx::method_registers.alpha_test_enabled())
|
||||||
|
{
|
||||||
|
if (rsx::method_registers.msaa_enabled() &&
|
||||||
|
rsx::method_registers.msaa_sample_mask() &&
|
||||||
|
rsx::method_registers.surface_antialias() != rsx::surface_antialiasing::center_1_sample)
|
||||||
|
{
|
||||||
|
//fake alpha-to-coverage
|
||||||
|
//blend used in conjunction with alpha test to fake order-independent edge transparency
|
||||||
|
mrt_blend_enabled[0] = mrt_blend_enabled[1] = mrt_blend_enabled[2] = mrt_blend_enabled[3] = true;
|
||||||
|
blend_equation_override = true;
|
||||||
|
sfactor_rgb = sfactor_a = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||||
|
dfactor_rgb = dfactor_a = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||||
|
equation_rgb = equation_a = VK_BLEND_OP_ADD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mrt_blend_enabled[0] || mrt_blend_enabled[1] || mrt_blend_enabled[2] || mrt_blend_enabled[3])
|
if (mrt_blend_enabled[0] || mrt_blend_enabled[1] || mrt_blend_enabled[2] || mrt_blend_enabled[3])
|
||||||
{
|
{
|
||||||
VkBlendFactor sfactor_rgb = vk::get_blend_factor(rsx::method_registers.blend_func_sfactor_rgb());
|
if (!blend_equation_override)
|
||||||
VkBlendFactor sfactor_a = vk::get_blend_factor(rsx::method_registers.blend_func_sfactor_a());
|
{
|
||||||
VkBlendFactor dfactor_rgb = vk::get_blend_factor(rsx::method_registers.blend_func_dfactor_rgb());
|
sfactor_rgb = vk::get_blend_factor(rsx::method_registers.blend_func_sfactor_rgb());
|
||||||
VkBlendFactor dfactor_a = vk::get_blend_factor(rsx::method_registers.blend_func_dfactor_a());
|
sfactor_a = vk::get_blend_factor(rsx::method_registers.blend_func_sfactor_a());
|
||||||
|
dfactor_rgb = vk::get_blend_factor(rsx::method_registers.blend_func_dfactor_rgb());
|
||||||
VkBlendOp equation_rgb = vk::get_blend_op(rsx::method_registers.blend_equation_rgb());
|
dfactor_a = vk::get_blend_factor(rsx::method_registers.blend_func_dfactor_a());
|
||||||
VkBlendOp equation_a = vk::get_blend_op(rsx::method_registers.blend_equation_a());
|
equation_rgb = vk::get_blend_op(rsx::method_registers.blend_equation_rgb());
|
||||||
|
equation_a = vk::get_blend_op(rsx::method_registers.blend_equation_a());
|
||||||
|
}
|
||||||
|
|
||||||
for (u8 idx = 0; idx < m_draw_buffers_count; ++idx)
|
for (u8 idx = 0; idx < m_draw_buffers_count; ++idx)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue