mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 11:36:13 +00: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();
|
||||
}
|
||||
|
||||
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
|
||||
// Alpha values generate a coverage mask for order independent blending
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include "../rsx_methods.h"
|
||||
#include "../Common/BufferUtils.h"
|
||||
|
||||
#include "Emu/RSX/NV47/HW/context_accessors.define.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
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[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)
|
||||
|
@ -307,12 +335,6 @@ void GLGSRender::update_draw_state()
|
|||
// Clip planes
|
||||
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
|
||||
//NV4097_SET_ANISO_SPREAD
|
||||
//NV4097_SET_SPECULAR_ENABLE
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "GLCommonDecompiler.h"
|
||||
#include "../GCM.h"
|
||||
#include "../Program/GLSLCommon.h"
|
||||
#include "../RSXThread.h"
|
||||
|
||||
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_linear_to_srgb = properties.has_pkg;
|
||||
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.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;
|
||||
|
|
|
@ -47,8 +47,6 @@ GLGSRender::GLGSRender(utils::serial* ar) noexcept : GSRender(ar)
|
|||
else
|
||||
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_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_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
|
||||
OPENGL_PROC(PFNGLTEXSTORAGE2DMULTISAMPLEPROC, TexStorage2DMultisample);
|
||||
OPENGL_PROC(PFNGLTEXSTORAGE3DMULTISAMPLEPROC, TexStorage3DMultisample);
|
||||
OPENGL_PROC(PFNGLSAMPLEMASKIPROC, SampleMaski);
|
||||
OPENGL_PROC(PFNGLMINSAMPLESHADINGPROC, MinSampleShading);
|
||||
OPENGL_PROC(PFNGLSAMPLECOVERAGEPROC, SampleCoverage);
|
||||
|
||||
// Texture_View
|
||||
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)
|
||||
{
|
||||
if (!test_and_set_property(CLIP_PLANES, mask))
|
||||
|
|
|
@ -87,6 +87,7 @@ namespace rsx
|
|||
{
|
||||
bool supports_multidraw; // Draw call batching
|
||||
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_msaa; // MSAA support
|
||||
bool supports_hw_a2one; // Alpha to one
|
||||
|
@ -466,4 +467,9 @@ namespace rsx
|
|||
{
|
||||
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_a2c = true;
|
||||
backend_config.supports_hw_a2c_1spp = true;
|
||||
backend_config.supports_hw_a2one = m_device->get_alpha_to_one_support();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue