Merge pull request #2934 from Sonicadvance1/GLES_proper_SSAA

Properly support MSAA and SSAA as separate features(+GLES)
This commit is contained in:
Ryan Houdek 2015-09-05 05:31:04 -05:00
commit 1773f6a2df
13 changed files with 144 additions and 43 deletions

View File

@ -418,6 +418,16 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con
szr_enh->Add(CreateCheckBox(page_enh, _("Widescreen Hack"), wxGetTranslation(ws_hack_desc), vconfig.bWidescreenHack));
szr_enh->Add(CreateCheckBox(page_enh, _("Disable Fog"), wxGetTranslation(disable_fog_desc), vconfig.bDisableFog));
if (vconfig.backend_info.bSupportsSSAA)
{
ssaa_checkbox = CreateCheckBox(page_enh, _("SSAA"), wxGetTranslation(aa_desc), vconfig.bSSAA);
szr_enh->Add(ssaa_checkbox);
}
else
{
ssaa_checkbox = nullptr;
}
wxStaticBoxSizer* const group_enh = new wxStaticBoxSizer(wxVERTICAL, page_enh, _("Enhancements"));
group_enh->Add(szr_enh, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
szr_enh_main->Add(group_enh, 0, wxEXPAND | wxALL, 5);

View File

@ -193,6 +193,8 @@ protected:
// Anti-aliasing
choice_aamode->Enable(vconfig.backend_info.AAModes.size() > 1);
text_aamode->Enable(vconfig.backend_info.AAModes.size() > 1);
if (vconfig.backend_info.bSupportsSSAA && ssaa_checkbox)
ssaa_checkbox->Enable(vconfig.iMultisampleMode > 0);
// XFB
virtual_xfb->Enable(vconfig.bUseXFB);
@ -253,6 +255,7 @@ protected:
wxStaticText* text_aamode;
SettingChoice* choice_aamode;
wxCheckBox* ssaa_checkbox;
wxStaticText* label_display_resolution;

View File

@ -84,6 +84,7 @@ void InitBackendInfo()
g_Config.backend_info.bSupportsPostProcessing = false;
g_Config.backend_info.bSupportsPaletteConversion = true;
g_Config.backend_info.bSupportsClipControl = true;
g_Config.backend_info.bSupportsSSAA = false;
IDXGIFactory* factory;
IDXGIAdapter* ad;

View File

@ -107,6 +107,21 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
{
m_textureType = GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
if (g_ogl_config.bSupports3DTextureStorage)
{
glBindTexture(m_textureType, m_efbColor);
glTexStorage3DMultisample(m_textureType, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight, m_EFBLayers, false);
glBindTexture(m_textureType, m_efbDepth);
glTexStorage3DMultisample(m_textureType, m_msaaSamples, GL_DEPTH_COMPONENT32F, m_targetWidth, m_targetHeight, m_EFBLayers, false);
glBindTexture(m_textureType, m_efbColorSwap);
glTexStorage3DMultisample(m_textureType, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight, m_EFBLayers, false);
glBindTexture(m_textureType, 0);
}
else
{
glBindTexture(m_textureType, m_efbColor);
glTexImage3DMultisample(m_textureType, m_msaaSamples, GL_RGBA, m_targetWidth, m_targetHeight, m_EFBLayers, false);
@ -117,10 +132,25 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
glTexImage3DMultisample(m_textureType, m_msaaSamples, GL_RGBA, m_targetWidth, m_targetHeight, m_EFBLayers, false);
glBindTexture(m_textureType, 0);
}
}
else
{
m_textureType = GL_TEXTURE_2D_MULTISAMPLE;
if (g_ogl_config.bSupports2DTextureStorage)
{
glBindTexture(m_textureType, m_efbColor);
glTexStorage2DMultisample(m_textureType, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight, false);
glBindTexture(m_textureType, m_efbDepth);
glTexStorage2DMultisample(m_textureType, m_msaaSamples, GL_DEPTH_COMPONENT32F, m_targetWidth, m_targetHeight, false);
glBindTexture(m_textureType, m_efbColorSwap);
glTexStorage2DMultisample(m_textureType, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight, false);
glBindTexture(m_textureType, 0);
}
else
{
glBindTexture(m_textureType, m_efbColor);
glTexImage2DMultisample(m_textureType, m_msaaSamples, GL_RGBA, m_targetWidth, m_targetHeight, false);
@ -131,6 +161,7 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
glTexImage2DMultisample(m_textureType, m_msaaSamples, GL_RGBA, m_targetWidth, m_targetHeight, false);
glBindTexture(m_textureType, 0);
}
}
// Although we are able to access the multisampled texture directly, we don't do it everywhere.
// The old way is to "resolve" this multisampled texture by copying it into a non-sampled texture.
@ -213,7 +244,7 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
" return texelFetch(samp9, pos, 0);\n"
"}\n";
}
else if (g_ogl_config.bSupportSampleShading)
else if (g_ActiveConfig.backend_info.bSupportsSSAA)
{
// msaa + sample shading available, so just fetch the sample
// This will lead to sample shading, but it's the only way to not loose

View File

@ -0,0 +1,11 @@
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include "VideoBackends/OGL/GLExtensions/gl_common.h"
typedef void (*PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
typedef void (*PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
extern PFNGLTEXSTORAGE2DMULTISAMPLEPROC glTexStorage2DMultisample;
extern PFNGLTEXSTORAGE3DMULTISAMPLEPROC glTexStorage3DMultisample;

View File

@ -718,6 +718,10 @@ PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
PFNGLSAMPLEMASKIPROC glSampleMaski;
// ARB_texture_storage_multisample
PFNGLTEXSTORAGE2DMULTISAMPLEPROC glTexStorage2DMultisample;
PFNGLTEXSTORAGE3DMULTISAMPLEPROC glTexStorage3DMultisample;
// ARB_ES2_compatibility
PFNGLCLEARDEPTHFPROC glClearDepthf;
PFNGLDEPTHRANGEFPROC glDepthRangef;
@ -1183,6 +1187,11 @@ const GLFunc gl_function_array[] =
GLFUNC_REQUIRES(glGetMultisamplefv, "GL_ARB_texture_multisample"),
GLFUNC_REQUIRES(glSampleMaski, "GL_ARB_texture_multisample"),
// ARB_texture_storage_multisample
GLFUNC_REQUIRES(glTexStorage2DMultisample, "GL_ARB_texture_storage_multisample"),
GLFUNC_REQUIRES(glTexStorage3DMultisample, "GL_ARB_texture_storage_multisample"),
GLFUNC_SUFFIX(glTexStorage3DMultisample, OES, "GL_OES_texture_storage_multisample_2d_array !VERSION_GLES_3_2"),
// ARB_ES2_compatibility
GLFUNC_REQUIRES(glClearDepthf, "GL_ARB_ES2_compatibility"),
GLFUNC_REQUIRES(glDepthRangef, "GL_ARB_ES2_compatibility"),
@ -1231,6 +1240,9 @@ const GLFunc gl_function_array[] =
// ARB_sample_shading
GLFUNC_SUFFIX(glMinSampleShading, ARB, "GL_ARB_sample_shading"),
// OES_sample_shading
GLFUNC_SUFFIX(glMinSampleShading, OES, "GL_OES_sample_shading !VERSION_GLES_3_2"),
// ARB_debug_output
GLFUNC_REQUIRES(glDebugMessageCallbackARB, "GL_ARB_debug_output"),
GLFUNC_REQUIRES(glDebugMessageControlARB, "GL_ARB_debug_output"),
@ -1298,6 +1310,8 @@ const GLFunc gl_function_array[] =
// EXT_texture_buffer
GLFUNC_SUFFIX(glTexBuffer, EXT, "GL_EXT_texture_buffer !GL_OES_texture_buffer !VERSION_GLES_3_2"),
// GLES 3.1
GLFUNC_REQUIRES(glTexStorage2DMultisample, "VERSION_GLES_3_1"),
// EXT_blend_func_extended
GLFUNC_SUFFIX(glBindFragDataLocationIndexed, EXT, "GL_EXT_blend_func_extended"),
@ -1317,6 +1331,7 @@ const GLFunc gl_function_array[] =
GLFUNC_REQUIRES(glPushDebugGroup, "VERSION_GLES_3_2"),
GLFUNC_REQUIRES(glCopyImageSubData, "VERSION_GLES_3_2"),
GLFUNC_REQUIRES(glTexBuffer, "VERSION_GLES_3_2"),
GLFUNC_REQUIRES(glTexStorage3DMultisample, "VERSION_GLES_3_2"),
// gl_1_1
// OpenGL 1.1 is at the end due to a bug in Android's EGL stack.
@ -1702,6 +1717,14 @@ namespace GLExtensions
m_extension_list[it] = true;
}
case 310:
{
std::string gles310exts[] = {
"GL_ARB_texture_storage_multisample",
"VERSION_GLES_3_1",
};
for (auto it : gles310exts)
m_extension_list[it] = true;
}
case 300:
{
std::string gles3exts[] = {

View File

@ -20,6 +20,7 @@
#include "VideoBackends/OGL/GLExtensions/ARB_sampler_objects.h"
#include "VideoBackends/OGL/GLExtensions/ARB_sync.h"
#include "VideoBackends/OGL/GLExtensions/ARB_texture_multisample.h"
#include "VideoBackends/OGL/GLExtensions/ARB_texture_storage_multisample.h"
#include "VideoBackends/OGL/GLExtensions/ARB_uniform_buffer_object.h"
#include "VideoBackends/OGL/GLExtensions/ARB_vertex_array_object.h"
#include "VideoBackends/OGL/GLExtensions/ARB_viewport_array.h"

View File

@ -567,6 +567,7 @@ void ProgramShaderCache::CreateHeader()
"%s\n"
"%s\n"
"%s\n"
"%s\n"
// Silly differences
"#define float2 vec2\n"
@ -588,7 +589,7 @@ void ProgramShaderCache::CreateHeader()
, !is_glsles && g_ActiveConfig.backend_info.bSupportsEarlyZ ? "#extension GL_ARB_shader_image_load_store : enable" : ""
, (g_ActiveConfig.backend_info.bSupportsBindingLayout && v < GLSLES_310) ? "#extension GL_ARB_shading_language_420pack : enable" : ""
, (g_ogl_config.bSupportsMSAA && v < GLSL_150) ? "#extension GL_ARB_texture_multisample : enable" : ""
, (g_ogl_config.bSupportSampleShading) ? "#extension GL_ARB_sample_shading : enable" : ""
, (v < GLSLES_300 && g_ActiveConfig.backend_info.bSupportsSSAA) ? "#extension GL_ARB_sample_shading : enable" : ""
, g_ActiveConfig.backend_info.bSupportsBindingLayout ? "#define SAMPLER_BINDING(x) layout(binding = x)" : "#define SAMPLER_BINDING(x)"
, g_ActiveConfig.backend_info.bSupportsBBox ? "#extension GL_ARB_shader_storage_buffer_object : enable" : ""
, !is_glsles && g_ActiveConfig.backend_info.bSupportsGSInstancing ? "#extension GL_ARB_gpu_shader5 : enable" : ""
@ -602,6 +603,7 @@ void ProgramShaderCache::CreateHeader()
, is_glsles ? "precision highp int;" : ""
, is_glsles ? "precision highp sampler2DArray;" : ""
, (is_glsles && g_ActiveConfig.backend_info.bSupportsPaletteConversion) ? "precision highp usamplerBuffer;" : ""
, v > GLSLES_300 ? "precision highp sampler2DMS;" : ""
);
}

View File

@ -73,10 +73,8 @@ enum MultisampleMode
MULTISAMPLE_2X,
MULTISAMPLE_4X,
MULTISAMPLE_8X,
MULTISAMPLE_SSAA_4X,
};
VideoConfig g_ogl_config;
// Declarations and definitions
@ -90,6 +88,7 @@ static RasterFont* s_pfont = nullptr;
// 1 for no MSAA. Use s_MSAASamples > 1 to check for MSAA.
static int s_MSAASamples = 1;
static int s_last_multisample_mode = 0;
static bool s_last_ssaa_mode = false;
static bool s_last_stereo_mode = false;
static bool s_last_xfb_mode = false;
@ -119,14 +118,12 @@ static int GetNumMSAASamples(int MSAAMode)
break;
case MULTISAMPLE_4X:
case MULTISAMPLE_SSAA_4X:
samples = 4;
break;
case MULTISAMPLE_8X:
samples = 8;
break;
default:
samples = 1;
}
@ -141,16 +138,12 @@ static int GetNumMSAASamples(int MSAAMode)
static void ApplySSAASettings()
{
// GLES3 doesn't support SSAA
if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGL)
if (g_ActiveConfig.bSSAA)
{
if (g_ActiveConfig.iMultisampleMode == MULTISAMPLE_SSAA_4X)
{
if (g_ogl_config.bSupportSampleShading)
if (g_ActiveConfig.backend_info.bSupportsSSAA)
{
glEnable(GL_SAMPLE_SHADING_ARB);
GLfloat min_sample_shading_value = static_cast<GLfloat>(s_MSAASamples);
glMinSampleShading(min_sample_shading_value);
glMinSampleShading(1.0f);
}
else
{
@ -158,11 +151,10 @@ static void ApplySSAASettings()
OSD::AddMessage("SSAA Anti Aliasing isn't supported by your GPU.", 10000);
}
}
else if (g_ogl_config.bSupportSampleShading)
else if (g_ActiveConfig.backend_info.bSupportsSSAA)
{
glDisable(GL_SAMPLE_SHADING_ARB);
}
}
}
static void GLAPIENTRY ErrorCallback( GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* message, const void* userParam)
@ -491,11 +483,15 @@ Renderer::Renderer()
g_ogl_config.bSupportsGLBufferStorage = GLExtensions::Supports("GL_ARB_buffer_storage") ||
GLExtensions::Supports("GL_EXT_buffer_storage");
g_ogl_config.bSupportsMSAA = GLExtensions::Supports("GL_ARB_texture_multisample");
g_ogl_config.bSupportSampleShading = GLExtensions::Supports("GL_ARB_sample_shading");
g_ActiveConfig.backend_info.bSupportsSSAA = GLExtensions::Supports("GL_ARB_sample_shading") ||
GLExtensions::Supports("GL_OES_sample_shading");
g_ogl_config.bSupportOGL31 = GLExtensions::Version() >= 310;
g_ogl_config.bSupportViewportFloat = GLExtensions::Supports("GL_ARB_viewport_array");
g_ogl_config.bSupportsDebug = GLExtensions::Supports("GL_KHR_debug") ||
GLExtensions::Supports("GL_ARB_debug_output");
g_ogl_config.bSupports3DTextureStorage = GLExtensions::Supports("GL_ARB_texture_storage_multisample") ||
GLExtensions::Supports("GL_OES_texture_storage_multisample_2d_array");
g_ogl_config.bSupports2DTextureStorage = GLExtensions::Supports("GL_ARB_texture_storage_multisample");
if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGLES3)
{
@ -518,6 +514,14 @@ Renderer::Renderer()
g_Config.backend_info.bSupportsEarlyZ = true;
g_Config.backend_info.bSupportsGeometryShaders = g_ogl_config.bSupportsAEP;
g_Config.backend_info.bSupportsGSInstancing = g_Config.backend_info.bSupportsGeometryShaders && g_ogl_config.SupportedESPointSize > 0;
g_ogl_config.bSupportsMSAA = true;
g_ogl_config.bSupports2DTextureStorage = true;
if (g_ActiveConfig.iStereoMode > 0 && g_ActiveConfig.iMultisampleMode > 1 && !g_ogl_config.bSupports3DTextureStorage)
{
// GLES 3.1 can't support stereo rendering and MSAA
OSD::AddMessage("MSAA Stereo rendering isn't supported by your GPU.", 10000);
g_ActiveConfig.iMultisampleMode = 1;
}
}
else
{
@ -528,10 +532,13 @@ Renderer::Renderer()
g_Config.backend_info.bSupportsGeometryShaders = true;
g_Config.backend_info.bSupportsGSInstancing = g_ogl_config.SupportedESPointSize > 0;
g_Config.backend_info.bSupportsPaletteConversion = true;
g_Config.backend_info.bSupportsSSAA = true;
g_ogl_config.bSupportsCopySubImage = true;
g_ogl_config.bSupportsGLBaseVertex = true;
g_ogl_config.bSupportSampleShading = true;
g_ogl_config.bSupportsDebug = true;
g_ogl_config.bSupportsMSAA = true;
g_ogl_config.bSupports2DTextureStorage = true;
g_ogl_config.bSupports3DTextureStorage = true;
}
}
else
@ -624,13 +631,14 @@ Renderer::Renderer()
g_ogl_config.bSupportsGLBufferStorage ? "" : "BufferStorage ",
g_ogl_config.bSupportsGLSync ? "" : "Sync ",
g_ogl_config.bSupportsMSAA ? "" : "MSAA ",
g_ogl_config.bSupportSampleShading ? "" : "SSAA ",
g_ActiveConfig.backend_info.bSupportsSSAA ? "" : "SSAA ",
g_ActiveConfig.backend_info.bSupportsGSInstancing ? "" : "GSInstancing ",
g_ActiveConfig.backend_info.bSupportsClipControl ? "" : "ClipControl ",
g_ogl_config.bSupportsCopySubImage ? "" : "CopyImageSubData "
);
s_last_multisample_mode = g_ActiveConfig.iMultisampleMode;
s_last_ssaa_mode = g_ActiveConfig.bSSAA;
s_MSAASamples = GetNumMSAASamples(s_last_multisample_mode);
ApplySSAASettings();
@ -1683,16 +1691,19 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
{
TargetSizeChanged = true;
}
if (TargetSizeChanged || xfbchanged || WindowResized || (s_last_multisample_mode != g_ActiveConfig.iMultisampleMode) || (s_last_stereo_mode != (g_ActiveConfig.iStereoMode > 0)))
if (TargetSizeChanged || xfbchanged || WindowResized || s_last_ssaa_mode != g_ActiveConfig.bSSAA ||
(s_last_multisample_mode != g_ActiveConfig.iMultisampleMode) || (s_last_stereo_mode != (g_ActiveConfig.iStereoMode > 0)))
{
s_last_xfb_mode = g_ActiveConfig.bUseRealXFB;
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);
if (TargetSizeChanged || s_last_multisample_mode != g_ActiveConfig.iMultisampleMode || s_last_stereo_mode != (g_ActiveConfig.iStereoMode > 0))
if (TargetSizeChanged || s_last_ssaa_mode != g_ActiveConfig.bSSAA ||
s_last_multisample_mode != g_ActiveConfig.iMultisampleMode || s_last_stereo_mode != (g_ActiveConfig.iStereoMode > 0))
{
s_last_stereo_mode = g_ActiveConfig.iStereoMode > 0;
s_last_multisample_mode = g_ActiveConfig.iMultisampleMode;
s_last_ssaa_mode = g_ActiveConfig.bSSAA;
s_MSAASamples = GetNumMSAASamples(s_last_multisample_mode);
ApplySSAASettings();

View File

@ -38,7 +38,6 @@ struct VideoConfig
bool bSupportsGLBaseVertex;
bool bSupportsGLBufferStorage;
bool bSupportsMSAA;
bool bSupportSampleShading;
GLSL_VERSION eSupportedGLSLVersion;
bool bSupportOGL31;
bool bSupportViewportFloat;
@ -47,6 +46,8 @@ struct VideoConfig
bool bSupportsCopySubImage;
u8 SupportedESPointSize;
ES_TEXBUF_TYPE SupportedESTextureBuffer;
bool bSupports2DTextureStorage;
bool bSupports3DTextureStorage;
const char* gl_vendor;
const char* gl_renderer;

View File

@ -117,11 +117,12 @@ static void InitBackendInfo()
g_Config.backend_info.bSupportsGeometryShaders = true;
g_Config.backend_info.bSupports3DVision = false;
g_Config.backend_info.bSupportsPostProcessing = true;
g_Config.backend_info.bSupportsSSAA = true;
g_Config.backend_info.Adapters.clear();
// aamodes
const char* caamodes[] = {_trans("None"), "2x MSAA", "4x MSAA", "8x MSAA", "4x SSAA"};
const char* caamodes[] = {_trans("None"), "2x MSAA", "4x MSAA", "8x MSAA"};
g_Config.backend_info.AAModes.assign(caamodes, caamodes + sizeof(caamodes)/sizeof(*caamodes));
// pp shaders

View File

@ -78,6 +78,7 @@ void VideoConfig::Load(const std::string& ini_file)
settings->Get("EnablePixelLighting", &bEnablePixelLighting, 0);
settings->Get("FastDepthCalc", &bFastDepthCalc, true);
settings->Get("MSAA", &iMultisampleMode, 0);
settings->Get("SSAA", &bSSAA, false);
settings->Get("EFBScale", &iEFBScale, (int)SCALE_1X); // native
settings->Get("DstAlphaPass", &bDstAlphaPass, false);
settings->Get("TexFmtOverlayEnable", &bTexFmtOverlayEnable, 0);
@ -161,6 +162,8 @@ void VideoConfig::GameIniLoad()
CHECK_SETTING("Video_Settings", "EnablePixelLighting", bEnablePixelLighting);
CHECK_SETTING("Video_Settings", "FastDepthCalc", bFastDepthCalc);
CHECK_SETTING("Video_Settings", "MSAA", iMultisampleMode);
CHECK_SETTING("Video_Settings", "SSAA", bSSAA);
int tmp = -9000;
CHECK_SETTING("Video_Settings", "EFBScale", tmp); // integral
if (tmp != -9000)
@ -274,6 +277,7 @@ void VideoConfig::Save(const std::string& ini_file)
settings->Set("FastDepthCalc", bFastDepthCalc);
settings->Set("ShowEFBCopyRegions", bShowEFBCopyRegions);
settings->Set("MSAA", iMultisampleMode);
settings->Set("SSAA", bSSAA);
settings->Set("EFBScale", iEFBScale);
settings->Set("TexFmtOverlayEnable", bTexFmtOverlayEnable);
settings->Set("TexFmtOverlayCenter", bTexFmtOverlayCenter);

View File

@ -75,6 +75,7 @@ struct VideoConfig final
// Enhancements
int iMultisampleMode;
bool bSSAA;
int iEFBScale;
bool bForceFiltering;
int iMaxAnisotropy;
@ -161,6 +162,7 @@ struct VideoConfig final
bool bSupportsPostProcessing;
bool bSupportsPaletteConversion;
bool bSupportsClipControl; // Needed by VertexShaderGen, so must stay in VideoCommon
bool bSupportsSSAA;
} backend_info;
// Utility