From f9c692052e271f96036d408942246d1a3cea26a5 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Thu, 14 Aug 2014 21:26:16 +0200 Subject: [PATCH] Try a fix for nvidia and GI --- data/shaders/slicedscreenquad.vert | 6 ----- .../slicedscreenquad_nvworkaround.vert | 11 ++++++++ src/graphics/irr_driver.cpp | 4 +++ src/graphics/irr_driver.hpp | 6 +++++ src/graphics/render_lighting.cpp | 27 ++++++++++++++----- src/graphics/shaders.cpp | 16 +++++++++++ src/graphics/shaders.hpp | 9 +++++++ 7 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 data/shaders/slicedscreenquad_nvworkaround.vert diff --git a/data/shaders/slicedscreenquad.vert b/data/shaders/slicedscreenquad.vert index 4922972f9..b3f828522 100644 --- a/data/shaders/slicedscreenquad.vert +++ b/data/shaders/slicedscreenquad.vert @@ -3,22 +3,16 @@ in vec2 Texcoord; #ifndef VSLayer out int layer; -out vec2 uv_in; #else -out vec2 uv; flat out int slice; #endif - - void main() { #ifdef VSLayer gl_Layer = gl_InstanceID; - uv = Texcoord; slice = gl_InstanceID; #else layer = gl_InstanceID; - uv_in = Texcoord; #endif gl_Position = vec4(Position, 0., 1.); } diff --git a/data/shaders/slicedscreenquad_nvworkaround.vert b/data/shaders/slicedscreenquad_nvworkaround.vert new file mode 100644 index 000000000..fe5127cfa --- /dev/null +++ b/data/shaders/slicedscreenquad_nvworkaround.vert @@ -0,0 +1,11 @@ +uniform int slice; + +in vec2 Position; +in vec2 Texcoord; + +out int layer; + +void main() { + layer = slice; + gl_Position = vec4(Position, 0., 1.); +} diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index dcf55b666..756280e98 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -466,11 +466,15 @@ void IrrDriver::initDevice() Log::info("IrrDriver", "OpenGL version string: %s", glGetString(GL_VERSION)); m_need_ubo_workaround = false; + m_need_rh_workaround = false; #ifdef WIN32 // Fix for Intel Sandy Bridge on Windows which supports GL up to 3.1 only if (strstr((const char *)glGetString(GL_VENDOR), "Intel") != nullptr && (GLMajorVersion == 3 && GLMinorVersion == 1)) m_need_ubo_workaround = true; #endif + // Fix for Nvidia and instanced RH + if (strstr((const char *)glGetString(GL_VENDOR), "NVIDIA") != nullptr) + m_need_rh_workaround = true; } m_glsl = (GLMajorVersion > 3 || (GLMajorVersion == 3 && GLMinorVersion >= 1)); diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 110205de0..e0b9fd614 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -197,6 +197,7 @@ private: int GLMajorVersion, GLMinorVersion; bool hasVSLayer; bool m_need_ubo_workaround; + bool m_need_rh_workaround; /** The irrlicht device. */ IrrlichtDevice *m_device; /** Irrlicht scene manager. */ @@ -284,6 +285,11 @@ public: return m_need_ubo_workaround; } + bool needRHWorkaround() const + { + return m_need_ubo_workaround; + } + bool hasVSLayerExtension() const { return hasVSLayer; diff --git a/src/graphics/render_lighting.cpp b/src/graphics/render_lighting.cpp index 3deb06b3d..d53416f87 100644 --- a/src/graphics/render_lighting.cpp +++ b/src/graphics/render_lighting.cpp @@ -136,13 +136,28 @@ void IrrDriver::renderLights(unsigned pointlightcount) ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_RH)); glDisable(GL_BLEND); m_rtts->getRH().Bind(); - glUseProgram(FullScreenShader::RadianceHintsConstructionShader::getInstance()->Program); glBindVertexArray(SharedObject::FullScreenQuadVAO); - setTexture(FullScreenShader::RadianceHintsConstructionShader::getInstance()->TU_ctex, m_rtts->getRSM().getRTT()[0], GL_LINEAR, GL_LINEAR); - setTexture(FullScreenShader::RadianceHintsConstructionShader::getInstance()->TU_ntex, m_rtts->getRSM().getRTT()[1], GL_LINEAR, GL_LINEAR); - setTexture(FullScreenShader::RadianceHintsConstructionShader::getInstance()->TU_dtex, m_rtts->getRSM().getDepthTexture(), GL_LINEAR, GL_LINEAR); - FullScreenShader::RadianceHintsConstructionShader::getInstance()->setUniforms(rsm_matrix, rh_matrix, rh_extend); - glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 32); + if (irr_driver->needRHWorkaround()) + { + glUseProgram(FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->Program); + setTexture(FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->TU_ctex, m_rtts->getRSM().getRTT()[0], GL_LINEAR, GL_LINEAR); + setTexture(FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->TU_ntex, m_rtts->getRSM().getRTT()[1], GL_LINEAR, GL_LINEAR); + setTexture(FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->TU_dtex, m_rtts->getRSM().getDepthTexture(), GL_LINEAR, GL_LINEAR); + for (unsigned i = 0; i < 32; i++) + { + FullScreenShader::NVWorkaroundRadianceHintsConstructionShader::getInstance()->setUniforms(rsm_matrix, rh_matrix, rh_extend, i); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + } + else + { + glUseProgram(FullScreenShader::RadianceHintsConstructionShader::getInstance()->Program); + setTexture(FullScreenShader::RadianceHintsConstructionShader::getInstance()->TU_ctex, m_rtts->getRSM().getRTT()[0], GL_LINEAR, GL_LINEAR); + setTexture(FullScreenShader::RadianceHintsConstructionShader::getInstance()->TU_ntex, m_rtts->getRSM().getRTT()[1], GL_LINEAR, GL_LINEAR); + setTexture(FullScreenShader::RadianceHintsConstructionShader::getInstance()->TU_dtex, m_rtts->getRSM().getDepthTexture(), GL_LINEAR, GL_LINEAR); + FullScreenShader::RadianceHintsConstructionShader::getInstance()->setUniforms(rsm_matrix, rh_matrix, rh_extend); + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 32); + } } for (unsigned i = 0; i < sun_ortho_matrix.size(); i++) diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index b95e8c502..289a68f76 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -1584,6 +1584,22 @@ namespace FullScreenShader AssignTextureUnit(Program, TexUnit(TU_ctex, "ctex"), TexUnit(TU_ntex, "ntex"), TexUnit(TU_dtex, "dtex")); } + NVWorkaroundRadianceHintsConstructionShader::NVWorkaroundRadianceHintsConstructionShader() + { + if (irr_driver->getGLSLVersion() < 150) + return; + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/slicedscreenquad_nvworkaround.vert").c_str(), + GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/rhpassthrough.geom").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/rh.frag").c_str()); + + AssignUniforms("RSMMatrix", "RHMatrix", "extents", "slice"); + TU_ctex = 0; + TU_ntex = 1; + TU_dtex = 2; + AssignTextureUnit(Program, TexUnit(TU_ctex, "ctex"), TexUnit(TU_ntex, "ntex"), TexUnit(TU_dtex, "dtex")); + } + RHDebug::RHDebug() { Program = LoadProgram( diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index eeeffcfec..606070ff4 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -588,6 +588,15 @@ public: RadianceHintsConstructionShader(); }; +// Workaround for a bug found in kepler nvidia linux and fermi nvidia windows +class NVWorkaroundRadianceHintsConstructionShader : public ShaderHelperSingleton +{ +public: + GLuint TU_ctex, TU_ntex, TU_dtex; + + NVWorkaroundRadianceHintsConstructionShader(); +}; + class RHDebug : public ShaderHelperSingleton { public: