From e0e45019eb2abed1820f0840cc230da752bb3792 Mon Sep 17 00:00:00 2001 From: hrydgard Date: Sun, 8 Mar 2009 20:04:40 +0000 Subject: [PATCH] UI for multisample antialiasing. NVidia CSAA support added. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2619 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Plugins/Plugin_VideoOGL/Src/Config.cpp | 4 +- Source/Plugins/Plugin_VideoOGL/Src/Config.h | 11 ++++ .../Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp | 50 ++++++++----------- .../Plugin_VideoOGL/Src/GUI/ConfigDlg.h | 14 +++--- Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 40 +++++++++++++-- 5 files changed, 76 insertions(+), 43 deletions(-) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Config.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Config.cpp index 29a6115e18..5c10f10a78 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Config.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Config.cpp @@ -60,7 +60,7 @@ void Config::Load() iniFile.Get("Settings", "DumpTextures", &bDumpTextures, 0); iniFile.Get("Settings", "DumpEFBTarget", &bDumpEFBTarget, 0); iniFile.Get("Settings", "ShowShaderErrors", &bShowShaderErrors, 0); - iniFile.Get("Settings", "Multisample", &iMultisampleMode, 0); + iniFile.Get("Settings", "MSAA", &iMultisampleMode, 0); if (iMultisampleMode == 0) iMultisampleMode = 1; @@ -105,7 +105,7 @@ void Config::Save() iniFile.Set("Settings", "DumpTextures", bDumpTextures); iniFile.Set("Settings", "DumpEFBTarget", bDumpEFBTarget); iniFile.Set("Settings", "ShowShaderErrors", bShowShaderErrors); - iniFile.Set("Settings", "Multisample", iMultisampleMode); + iniFile.Set("Settings", "MSAA", iMultisampleMode); iniFile.Set("Settings", "TexFmtOverlayEnable", bTexFmtOverlayEnable); iniFile.Set("Settings", "TexFmtOverlayCenter", bTexFmtOverlayCenter); iniFile.Set("Settings", "Wireframe", bWireFrame); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Config.h b/Source/Plugins/Plugin_VideoOGL/Src/Config.h index 3a16478601..880164a987 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Config.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/Config.h @@ -27,6 +27,17 @@ #define CONF_SAVETARGETS 8 #define CONF_SAVESHADERS 16 +enum MultisampleMode { + MULTISAMPLE_OFF, + MULTISAMPLE_2X, + MULTISAMPLE_4X, + MULTISAMPLE_8X, + MULTISAMPLE_CSAA_8X, + MULTISAMPLE_CSAA_8XQ, + MULTISAMPLE_CSAA_16X, + MULTISAMPLE_CSAA_16XQ, +}; + // NEVER inherit from this class. struct Config { diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp index 536bd1b837..e2761150c4 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp @@ -31,9 +31,8 @@ BEGIN_EVENT_TABLE(ConfigDialog,wxDialog) EVT_CHECKBOX(ID_RENDERTOMAINWINDOW, ConfigDialog::GeneralSettingsChanged) EVT_COMBOBOX(ID_FULLSCREENCB, ConfigDialog::GeneralSettingsChanged) EVT_COMBOBOX(ID_WINDOWRESOLUTIONCB, ConfigDialog::GeneralSettingsChanged) - EVT_COMBOBOX(ID_ALIASMODECB, ConfigDialog::GeneralSettingsChanged) EVT_CHOICE(ID_MAXANISOTROPY, ConfigDialog::GeneralSettingsChanged) - EVT_CHECKBOX(ID_FORCEFILTERING, ConfigDialog::GeneralSettingsChanged) + EVT_CHOICE(ID_MSAAMODECB, ConfigDialog::GeneralSettingsChanged) EVT_CHECKBOX(ID_NATIVERESOLUTION, ConfigDialog::GeneralSettingsChanged) EVT_CHECKBOX(ID_USEXFB, ConfigDialog::GeneralSettingsChanged) EVT_CHECKBOX(ID_AUTOSCALE, ConfigDialog::GeneralSettingsChanged) @@ -107,7 +106,7 @@ void ConfigDialog::CloseClick(wxCommandEvent& WXUNUSED (event)) /////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// -// Add avaliable redolutions and other settings +// Add avaliable resolutions and other settings // --------------- void ConfigDialog::AddFSReso(char *reso) { @@ -119,12 +118,6 @@ void ConfigDialog::AddWindowReso(char *reso) arrayStringFor_WindowResolutionCB.Add(wxString::FromAscii(reso)); } -void ConfigDialog::AddAAMode(int mode) -{ - wxString tmp; - tmp<Append(tmp); -} /////////////////////////////////////// @@ -193,6 +186,18 @@ void ConfigDialog::CreateGUIControls() m_WindowResolutionCB = new wxComboBox(m_PageGeneral, ID_WINDOWRESOLUTIONCB, arrayStringFor_WindowResolutionCB[0], wxDefaultPosition, wxDefaultSize, arrayStringFor_WindowResolutionCB, wxCB_READONLY, wxDefaultValidator); m_WindowResolutionCB->SetValue(wxString::FromAscii(g_Config.iWindowedRes)); + wxStaticText *MSAAText = new wxStaticText(m_PageGeneral, ID_MSAAMODETEXT, wxT("Antialias (MSAA):"), wxDefaultPosition, wxDefaultSize, 0); + m_MSAAModeCB = new wxChoice(m_PageGeneral, ID_MSAAMODECB, wxDefaultPosition, wxDefaultSize, arrayStringFor_MSAAModeCB, 0, wxDefaultValidator); + m_MSAAModeCB->Append(wxT("(off)")); + m_MSAAModeCB->Append(wxT("2x")); + m_MSAAModeCB->Append(wxT("4x")); + m_MSAAModeCB->Append(wxT("8x")); + m_MSAAModeCB->Append(wxT("8x CSAA")); + m_MSAAModeCB->Append(wxT("8xQ CSAA")); + m_MSAAModeCB->Append(wxT("16x CSAA")); + m_MSAAModeCB->Append(wxT("16xQ CSAA")); + m_MSAAModeCB->SetSelection(g_Config.iMultisampleMode); + // Tool tips m_Fullscreen->SetToolTip(wxT( "This option use a separate rendering window and can only be used when" @@ -216,8 +221,6 @@ void ConfigDialog::CreateGUIControls() // Enhancements sbEnhancements = new wxStaticBoxSizer(wxVERTICAL, m_PageGeneral, wxT("Enhancements")); - m_ForceFiltering = new wxCheckBox(m_PageGeneral, ID_FORCEFILTERING, wxT("Force bi/trilinear filtering (May cause small glitches)"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); - m_ForceFiltering->SetValue(g_Config.bForceFiltering); wxStaticText *AnisoText = new wxStaticText(m_PageGeneral, ID_WMTEXT, wxT("Anisotropic filter:"), wxDefaultPosition, wxDefaultSize, 0); m_MaxAnisotropyCB = new wxChoice(m_PageGeneral, ID_MAXANISOTROPY, wxDefaultPosition, wxDefaultSize, arrayStringFor_MaxAnisotropyCB, 0, wxDefaultValidator); m_MaxAnisotropyCB->Append(wxT("1x")); @@ -227,15 +230,6 @@ void ConfigDialog::CreateGUIControls() m_MaxAnisotropyCB->Append(wxT("16x")); m_MaxAnisotropyCB->SetSelection(g_Config.iMaxAnisotropy - 1); - wxStaticText *AAText = new wxStaticText(m_PageGeneral, ID_AATEXT, wxT("Anti-alias mode:"), wxDefaultPosition, wxDefaultSize, 0); - wxArrayString arrayStringFor_AliasModeCB; - m_AliasModeCB = new wxComboBox(m_PageGeneral, ID_ALIASMODECB, wxEmptyString, wxDefaultPosition, wxDefaultSize, arrayStringFor_AliasModeCB, 0, wxDefaultValidator); - wxString tmp; - tmp << g_Config.iMultisampleMode; - m_AliasModeCB->SetValue(tmp); - AAText->Hide(); - m_AliasModeCB->Hide(); - // Usage: The wxGBPosition() must have a column and row sGeneral = new wxBoxSizer(wxVERTICAL); sBasic = new wxGridBagSizer(0, 0); @@ -263,11 +257,10 @@ void ConfigDialog::CreateGUIControls() sGeneral->Add(sbBasic, 0, wxEXPAND|wxALL, 5); sEnhancements = new wxGridBagSizer(0, 0); - sEnhancements->Add(m_ForceFiltering, wxGBPosition(0, 0), wxGBSpan(1, 2), wxALL, 5); - sEnhancements->Add(AnisoText, wxGBPosition(1, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5); - sEnhancements->Add(m_MaxAnisotropyCB, wxGBPosition(1, 1), wxGBSpan(1, 2), wxALL, 5); - //sEnhancements->Add(AAText, wxGBPosition(2, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5); - //sEnhancements->Add(m_AliasModeCB, wxGBPosition(2, 1), wxGBSpan(1, 2), wxALL, 5); + sEnhancements->Add(AnisoText, wxGBPosition(0, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5); + sEnhancements->Add(m_MaxAnisotropyCB, wxGBPosition(0, 1), wxGBSpan(1, 2), wxALL, 5); + sEnhancements->Add(MSAAText, wxGBPosition(1, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5); + sEnhancements->Add(m_MSAAModeCB, wxGBPosition(1, 1), wxGBSpan(1, 2), wxALL, 5); sbEnhancements->Add(sEnhancements); sGeneral->Add(sbEnhancements, 0, wxEXPAND|wxALL, 5); m_PageGeneral->SetSizer(sGeneral); @@ -459,14 +452,11 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event) case ID_WINDOWRESOLUTIONCB: strcpy(g_Config.iWindowedRes, m_WindowResolutionCB->GetValue().mb_str() ); break; - case ID_FORCEFILTERING: - g_Config.bForceFiltering = m_ForceFiltering->IsChecked(); - break; case ID_MAXANISOTROPY: g_Config.iMaxAnisotropy = m_MaxAnisotropyCB->GetSelection() + 1; break; - case ID_ALIASMODECB: - g_Config.iMultisampleMode = atoi(m_AliasModeCB->GetValue().mb_str()); + case ID_MSAAMODECB: + g_Config.iMultisampleMode = m_MSAAModeCB->GetSelection(); break; } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h index c9b925a152..1931a0281f 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h @@ -45,7 +45,6 @@ class ConfigDialog : public wxDialog void AddFSReso(char *reso); void AddWindowReso(char *reso); - void AddAAMode(int mode); void CreateGUIControls(); // Combo box lists, this one needs to be public @@ -87,11 +86,11 @@ class ConfigDialog : public wxDialog wxComboBox *m_FullscreenCB; wxArrayString arrayStringFor_WindowResolutionCB; wxComboBox *m_WindowResolutionCB; - - wxCheckBox *m_ForceFiltering; // advanced - wxChoice *m_MaxAnisotropyCB; wxArrayString arrayStringFor_MaxAnisotropyCB; - wxComboBox *m_AliasModeCB; + wxChoice *m_MaxAnisotropyCB; + wxArrayString arrayStringFor_MSAAModeCB; + wxChoice *m_MSAAModeCB; + wxCheckBox *m_ShowFPS; wxCheckBox *m_ShaderErrors; wxCheckBox *m_Statistics; @@ -138,10 +137,9 @@ class ConfigDialog : public wxDialog ID_WMTEXT, ID_WINDOWRESOLUTIONCB, - ID_FORCEFILTERING, ID_MAXANISOTROPY, - ID_AATEXT, - ID_ALIASMODECB, + ID_MSAAMODECB, + ID_MSAAMODETEXT, ID_SHOWFPS, ID_SHADERERRORS, diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index d6d4b78241..edbdb817b5 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -75,6 +75,7 @@ static int nZBufferRender = 0; // if > 0, then use zbuffer render, and count do // 1 for no MSAA. Use s_MSAASamples > 1 to check for MSAA. static int s_MSAASamples = 1; +static int s_MSAACoverageSamples = 0; // Normal Mode // s_RenderTarget is a texture_rect @@ -109,6 +110,7 @@ static GLuint s_ResolvedDepthTarget = 0; static bool s_bATIDrawBuffers = false; static bool s_bHaveStencilBuffer = false; static bool s_bHaveFramebufferBlit = false; +static bool s_bHaveCoverageMSAA = false; static bool g_bBlendSeparate = false; static u32 s_blendMode; @@ -170,6 +172,20 @@ bool Renderer::Init() { bool bSuccess = true; s_blendMode = 0; + s_MSAACoverageSamples = 0; + switch (g_Config.iMultisampleMode) + { + case MULTISAMPLE_OFF: s_MSAASamples = 1; break; + case MULTISAMPLE_2X: s_MSAASamples = 2; break; + case MULTISAMPLE_4X: s_MSAASamples = 4; break; + case MULTISAMPLE_8X: s_MSAASamples = 8; break; + case MULTISAMPLE_CSAA_8X: s_MSAASamples = 4; s_MSAACoverageSamples = 8; break; + case MULTISAMPLE_CSAA_8XQ: s_MSAASamples = 8; s_MSAACoverageSamples = 8; break; + case MULTISAMPLE_CSAA_16X: s_MSAASamples = 4; s_MSAACoverageSamples = 16; break; + case MULTISAMPLE_CSAA_16XQ: s_MSAASamples = 8; s_MSAACoverageSamples = 16; break; + default: + s_MSAASamples = 1; + } GLint numvertexattribs = 0; GLenum err = GL_NO_ERROR; g_cgcontext = cgCreateContext(); @@ -223,6 +239,12 @@ bool Renderer::Init() // MSAA ain't gonna work. turn it off if enabled. s_MSAASamples = 1; } + s_bHaveCoverageMSAA = strstr(ptoken, "GL_NV_framebuffer_multisample_coverage") != NULL; + if (!s_bHaveCoverageMSAA) + { + s_MSAACoverageSamples = 0; + } + if (!bSuccess) return false; @@ -327,13 +349,25 @@ bool Renderer::Init() // First set up the boring multisampled rendertarget. glGenRenderbuffersEXT(1, &s_RenderTarget); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_RenderTarget); - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, s_MSAASamples, GL_RGBA, s_targetwidth, s_targetheight); + if (s_MSAACoverageSamples) { + glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, s_MSAACoverageSamples, s_MSAASamples, GL_RGBA, s_targetwidth, s_targetheight); + } else { + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, s_MSAASamples, GL_RGBA, s_targetwidth, s_targetheight); + } glGenRenderbuffersEXT(1, &s_FakeZTarget); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_FakeZTarget); - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, s_MSAASamples, GL_RGBA, s_targetwidth, s_targetheight); + if (s_MSAACoverageSamples) { + glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, s_MSAACoverageSamples, s_MSAASamples, GL_RGBA, s_targetwidth, s_targetheight); + } else { + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, s_MSAASamples, GL_RGBA, s_targetwidth, s_targetheight); + } glGenRenderbuffersEXT(1, &s_DepthTarget); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_DepthTarget); - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, s_MSAASamples, GL_DEPTH24_STENCIL8_EXT, s_targetwidth, s_targetheight); + if (s_MSAACoverageSamples) { + glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, s_MSAACoverageSamples, s_MSAASamples, GL_DEPTH24_STENCIL8_EXT, s_targetwidth, s_targetheight); + } else { + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, s_MSAASamples, GL_DEPTH24_STENCIL8_EXT, s_targetwidth, s_targetheight); + } glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); // Attach them to our multisampled FBO. The multisampled FBO is still bound here.