mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-03 21:41:26 +12:00
gl: Implement MSAA transparency (sample-to-coverage)
This commit is contained in:
parent
485927ed0d
commit
0f3d2c7085
8 changed files with 85 additions and 10 deletions
|
@ -667,7 +667,23 @@ namespace rsx
|
||||||
rop_control.enable_polygon_stipple();
|
rop_control.enable_polygon_stipple();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (REGS(m_ctx)->msaa_alpha_to_coverage_enabled() && !RSX(m_ctx)->get_backend_config().supports_hw_a2c)
|
auto can_use_hw_a2c = [&]() -> bool
|
||||||
|
{
|
||||||
|
const auto& config = RSX(m_ctx)->get_backend_config();
|
||||||
|
if (!config.supports_hw_a2c)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.supports_hw_a2c_1spp)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return REGS(m_ctx)->surface_antialias() != rsx::surface_antialiasing::center_1_sample;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (REGS(m_ctx)->msaa_alpha_to_coverage_enabled() && !can_use_hw_a2c())
|
||||||
{
|
{
|
||||||
// TODO: Properly support alpha-to-coverage and alpha-to-one behavior in shaders
|
// TODO: Properly support alpha-to-coverage and alpha-to-one behavior in shaders
|
||||||
// Alpha values generate a coverage mask for order independent blending
|
// Alpha values generate a coverage mask for order independent blending
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include "../rsx_methods.h"
|
#include "../rsx_methods.h"
|
||||||
#include "../Common/BufferUtils.h"
|
#include "../Common/BufferUtils.h"
|
||||||
|
|
||||||
|
#include "Emu/RSX/NV47/HW/context_accessors.define.h"
|
||||||
|
|
||||||
namespace gl
|
namespace gl
|
||||||
{
|
{
|
||||||
GLenum comparison_op(rsx::comparison_function op)
|
GLenum comparison_op(rsx::comparison_function op)
|
||||||
|
@ -256,6 +258,32 @@ void GLGSRender::update_draw_state()
|
||||||
gl_state.enablei(mrt_blend_enabled[2], GL_BLEND, 2);
|
gl_state.enablei(mrt_blend_enabled[2], GL_BLEND, 2);
|
||||||
gl_state.enablei(mrt_blend_enabled[3], GL_BLEND, 3);
|
gl_state.enablei(mrt_blend_enabled[3], GL_BLEND, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Antialias control
|
||||||
|
if (backend_config.supports_hw_msaa)
|
||||||
|
{
|
||||||
|
gl_state.enable(/*REGS(m_ctx)->msaa_enabled()*/GL_MULTISAMPLE);
|
||||||
|
|
||||||
|
gl_state.enable(GL_SAMPLE_MASK);
|
||||||
|
gl_state.sample_mask(REGS(m_ctx)->msaa_sample_mask());
|
||||||
|
|
||||||
|
gl_state.enable(GL_SAMPLE_SHADING);
|
||||||
|
gl_state.min_sample_shading_rate(1.f);
|
||||||
|
|
||||||
|
gl_state.enable(GL_SAMPLE_COVERAGE);
|
||||||
|
gl_state.sample_coverage(1.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backend_config.supports_hw_a2c)
|
||||||
|
{
|
||||||
|
const bool hw_enable = backend_config.supports_hw_a2c_1spp || REGS(m_ctx)->surface_antialias() != rsx::surface_antialiasing::center_1_sample;
|
||||||
|
gl_state.enable(hw_enable && REGS(m_ctx)->msaa_alpha_to_coverage_enabled(), GL_SAMPLE_ALPHA_TO_COVERAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backend_config.supports_hw_a2one)
|
||||||
|
{
|
||||||
|
gl_state.enable(REGS(m_ctx)->msaa_alpha_to_one_enabled(), GL_SAMPLE_ALPHA_TO_ONE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (rsx::method_registers.current_draw_clause.primitive)
|
switch (rsx::method_registers.current_draw_clause.primitive)
|
||||||
|
@ -307,12 +335,6 @@ void GLGSRender::update_draw_state()
|
||||||
// Clip planes
|
// Clip planes
|
||||||
gl_state.clip_planes((current_vertex_program.output_mask >> CELL_GCM_ATTRIB_OUTPUT_UC0) & 0x3F);
|
gl_state.clip_planes((current_vertex_program.output_mask >> CELL_GCM_ATTRIB_OUTPUT_UC0) & 0x3F);
|
||||||
|
|
||||||
// Sample control
|
|
||||||
// TODO: MinSampleShading
|
|
||||||
//gl_state.enable(rsx::method_registers.msaa_enabled(), GL_MULTISAMPLE);
|
|
||||||
//gl_state.enable(rsx::method_registers.msaa_alpha_to_coverage_enabled(), GL_SAMPLE_ALPHA_TO_COVERAGE);
|
|
||||||
//gl_state.enable(rsx::method_registers.msaa_alpha_to_one_enabled(), GL_SAMPLE_ALPHA_TO_ONE);
|
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
//NV4097_SET_ANISO_SPREAD
|
//NV4097_SET_ANISO_SPREAD
|
||||||
//NV4097_SET_SPECULAR_ENABLE
|
//NV4097_SET_SPECULAR_ENABLE
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "GLCommonDecompiler.h"
|
#include "GLCommonDecompiler.h"
|
||||||
#include "../GCM.h"
|
#include "../GCM.h"
|
||||||
#include "../Program/GLSLCommon.h"
|
#include "../Program/GLSLCommon.h"
|
||||||
|
#include "../RSXThread.h"
|
||||||
|
|
||||||
std::string GLFragmentDecompilerThread::getFloatTypeName(usz elementCount)
|
std::string GLFragmentDecompilerThread::getFloatTypeName(usz elementCount)
|
||||||
{
|
{
|
||||||
|
@ -218,7 +219,7 @@ void GLFragmentDecompilerThread::insertGlobalFunctions(std::stringstream &OS)
|
||||||
m_shader_props.require_srgb_to_linear = properties.has_upg;
|
m_shader_props.require_srgb_to_linear = properties.has_upg;
|
||||||
m_shader_props.require_linear_to_srgb = properties.has_pkg;
|
m_shader_props.require_linear_to_srgb = properties.has_pkg;
|
||||||
m_shader_props.require_fog_read = properties.in_register_mask & in_fogc;
|
m_shader_props.require_fog_read = properties.in_register_mask & in_fogc;
|
||||||
m_shader_props.emulate_coverage_tests = true; // g_cfg.video.antialiasing_level == msaa_level::none;
|
m_shader_props.emulate_coverage_tests = !rsx::get_renderer_backend_config().supports_hw_a2c_1spp;
|
||||||
m_shader_props.emulate_shadow_compare = device_props.emulate_depth_compare;
|
m_shader_props.emulate_shadow_compare = device_props.emulate_depth_compare;
|
||||||
m_shader_props.low_precision_tests = ::gl::get_driver_caps().vendor_NVIDIA && !(m_prog.ctrl & RSX_SHADER_CONTROL_ATTRIBUTE_INTERPOLATION);
|
m_shader_props.low_precision_tests = ::gl::get_driver_caps().vendor_NVIDIA && !(m_prog.ctrl & RSX_SHADER_CONTROL_ATTRIBUTE_INTERPOLATION);
|
||||||
m_shader_props.disable_early_discard = !::gl::get_driver_caps().vendor_NVIDIA;
|
m_shader_props.disable_early_discard = !::gl::get_driver_caps().vendor_NVIDIA;
|
||||||
|
|
|
@ -47,8 +47,6 @@ GLGSRender::GLGSRender(utils::serial* ar) noexcept : GSRender(ar)
|
||||||
else
|
else
|
||||||
m_vertex_cache = std::make_unique<gl::weak_vertex_cache>();
|
m_vertex_cache = std::make_unique<gl::weak_vertex_cache>();
|
||||||
|
|
||||||
backend_config.supports_hw_a2c = false;
|
|
||||||
backend_config.supports_hw_a2one = false;
|
|
||||||
backend_config.supports_multidraw = true;
|
backend_config.supports_multidraw = true;
|
||||||
backend_config.supports_normalized_barycentrics = true;
|
backend_config.supports_normalized_barycentrics = true;
|
||||||
|
|
||||||
|
@ -56,6 +54,8 @@ GLGSRender::GLGSRender(utils::serial* ar) noexcept : GSRender(ar)
|
||||||
{
|
{
|
||||||
backend_config.supports_hw_msaa = true;
|
backend_config.supports_hw_msaa = true;
|
||||||
backend_config.supports_hw_a2c = true;
|
backend_config.supports_hw_a2c = true;
|
||||||
|
backend_config.supports_hw_a2c_1spp = false; // In OGL A2C is implicitly disabled at 1spp
|
||||||
|
backend_config.supports_hw_a2one = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -262,6 +262,9 @@ OPENGL_PROC(PFNGLTEXSTORAGE3DPROC, TexStorage3D);
|
||||||
// ARB_texture_multisample
|
// ARB_texture_multisample
|
||||||
OPENGL_PROC(PFNGLTEXSTORAGE2DMULTISAMPLEPROC, TexStorage2DMultisample);
|
OPENGL_PROC(PFNGLTEXSTORAGE2DMULTISAMPLEPROC, TexStorage2DMultisample);
|
||||||
OPENGL_PROC(PFNGLTEXSTORAGE3DMULTISAMPLEPROC, TexStorage3DMultisample);
|
OPENGL_PROC(PFNGLTEXSTORAGE3DMULTISAMPLEPROC, TexStorage3DMultisample);
|
||||||
|
OPENGL_PROC(PFNGLSAMPLEMASKIPROC, SampleMaski);
|
||||||
|
OPENGL_PROC(PFNGLMINSAMPLESHADINGPROC, MinSampleShading);
|
||||||
|
OPENGL_PROC(PFNGLSAMPLECOVERAGEPROC, SampleCoverage);
|
||||||
|
|
||||||
// Texture_View
|
// Texture_View
|
||||||
OPENGL_PROC(PFNGLTEXTUREVIEWPROC, TextureView);
|
OPENGL_PROC(PFNGLTEXTUREVIEWPROC, TextureView);
|
||||||
|
|
|
@ -309,6 +309,32 @@ namespace gl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sample_mask(GLbitfield mask)
|
||||||
|
{
|
||||||
|
if (!test_and_set_property(GL_SAMPLE_MASK_VALUE, mask))
|
||||||
|
{
|
||||||
|
glSampleMaski(0, mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sample_coverage(GLclampf coverage)
|
||||||
|
{
|
||||||
|
const u32 value = std::bit_cast<u32>(coverage);
|
||||||
|
if (!test_and_set_property(GL_SAMPLE_COVERAGE_VALUE, value))
|
||||||
|
{
|
||||||
|
glSampleCoverage(coverage, GL_FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void min_sample_shading_rate(GLclampf rate)
|
||||||
|
{
|
||||||
|
const u32 value = std::bit_cast<u32>(rate);
|
||||||
|
if (!test_and_set_property(GL_MIN_SAMPLE_SHADING_VALUE, value))
|
||||||
|
{
|
||||||
|
glMinSampleShading(rate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void clip_planes(GLuint mask)
|
void clip_planes(GLuint mask)
|
||||||
{
|
{
|
||||||
if (!test_and_set_property(CLIP_PLANES, mask))
|
if (!test_and_set_property(CLIP_PLANES, mask))
|
||||||
|
|
|
@ -87,6 +87,7 @@ namespace rsx
|
||||||
{
|
{
|
||||||
bool supports_multidraw; // Draw call batching
|
bool supports_multidraw; // Draw call batching
|
||||||
bool supports_hw_a2c; // Alpha to coverage
|
bool supports_hw_a2c; // Alpha to coverage
|
||||||
|
bool supports_hw_a2c_1spp; // Alpha to coverage at 1 sample per pixel
|
||||||
bool supports_hw_renormalization; // Should be true on NV hardware which matches PS3 texture renormalization behaviour
|
bool supports_hw_renormalization; // Should be true on NV hardware which matches PS3 texture renormalization behaviour
|
||||||
bool supports_hw_msaa; // MSAA support
|
bool supports_hw_msaa; // MSAA support
|
||||||
bool supports_hw_a2one; // Alpha to one
|
bool supports_hw_a2one; // Alpha to one
|
||||||
|
@ -466,4 +467,9 @@ namespace rsx
|
||||||
{
|
{
|
||||||
return g_fxo->try_get<rsx::thread>();
|
return g_fxo->try_get<rsx::thread>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const backend_configuration& get_renderer_backend_config()
|
||||||
|
{
|
||||||
|
return g_fxo->get<rsx::thread>().get_backend_config();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -630,6 +630,7 @@ VKGSRender::VKGSRender(utils::serial* ar) noexcept : GSRender(ar)
|
||||||
{
|
{
|
||||||
backend_config.supports_hw_msaa = true;
|
backend_config.supports_hw_msaa = true;
|
||||||
backend_config.supports_hw_a2c = true;
|
backend_config.supports_hw_a2c = true;
|
||||||
|
backend_config.supports_hw_a2c_1spp = true;
|
||||||
backend_config.supports_hw_a2one = m_device->get_alpha_to_one_support();
|
backend_config.supports_hw_a2one = m_device->get_alpha_to_one_support();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue