From 365838eddcb88914056624e0f3b9e9bce4f8377e Mon Sep 17 00:00:00 2001 From: Sergey Lipskiy Date: Sun, 29 Oct 2017 15:49:44 +0700 Subject: [PATCH] Fixed problem with combiners shaders generation: Parts of shaders code created on start. Some parts depend on config options. When config changed with GUI shaders updated but code parts not updated. Thus new shaders do not correspond to current state of config. --- src/Combiner.cpp | 1 + src/Graphics/CombinerProgram.cpp | 24 ++++++++++------- src/Graphics/CombinerProgram.h | 2 +- src/Graphics/Context.cpp | 11 ++++++++ src/Graphics/Context.h | 4 +++ src/Graphics/ContextImpl.h | 2 ++ .../GLSL/glsl_CombinerProgramBuilder.cpp | 6 +++++ .../GLSL/glsl_CombinerProgramBuilder.h | 3 +++ .../OpenGLContext/GLSL/glsl_ShaderStorage.cpp | 19 +++++--------- .../OpenGLContext/opengl_ContextImpl.cpp | 26 ++++++++++++++----- .../OpenGLContext/opengl_ContextImpl.h | 4 +++ 11 files changed, 73 insertions(+), 29 deletions(-) diff --git a/src/Combiner.cpp b/src/Combiner.cpp index df2065d8..f724cc06 100644 --- a/src/Combiner.cpp +++ b/src/Combiner.cpp @@ -92,6 +92,7 @@ CombinerInfo & CombinerInfo::get() void CombinerInfo::init() { + gfxContext.resetCombinerProgramBuilder(); m_pCurrent = nullptr; m_shadersLoaded = 0; diff --git a/src/Graphics/CombinerProgram.cpp b/src/Graphics/CombinerProgram.cpp index a73eb338..a4aafb44 100644 --- a/src/Graphics/CombinerProgram.cpp +++ b/src/Graphics/CombinerProgram.cpp @@ -1,19 +1,25 @@ +#include #include "CombinerProgram.h" #include namespace graphics { - void CombinerProgram::getShaderCombinerOptionsSet(std::vector & _vecOptions) + u32 CombinerProgram::getShaderCombinerOptionsBits() { // WARNING: Shader Storage format version must be increased after any change in this function. - _vecOptions.push_back(config.video.multisampling > 0 ? 1 : 0); - _vecOptions.push_back(config.texture.bilinearMode); - _vecOptions.push_back(config.generalEmulation.enableHWLighting); - _vecOptions.push_back(config.generalEmulation.enableNoise); - _vecOptions.push_back(config.generalEmulation.enableLOD); - _vecOptions.push_back(config.frameBufferEmulation.N64DepthCompare); - _vecOptions.push_back(config.generalEmulation.enableLegacyBlending); - _vecOptions.push_back(config.generalEmulation.enableFragmentDepthWrite); + std::vector vecOptions; + vecOptions.push_back(config.video.multisampling > 0 ? 1 : 0); + vecOptions.push_back(config.texture.bilinearMode); + vecOptions.push_back(config.generalEmulation.enableHWLighting); + vecOptions.push_back(config.generalEmulation.enableNoise); + vecOptions.push_back(config.generalEmulation.enableLOD); + vecOptions.push_back(config.frameBufferEmulation.N64DepthCompare); + vecOptions.push_back(config.generalEmulation.enableLegacyBlending); + vecOptions.push_back(config.generalEmulation.enableFragmentDepthWrite); + u32 optionsSet = 0; + for (u32 i = 0; i < vecOptions.size(); ++i) + optionsSet |= vecOptions[i] << i; + return optionsSet; } } diff --git a/src/Graphics/CombinerProgram.h b/src/Graphics/CombinerProgram.h index 098ae43a..dcf47d9b 100644 --- a/src/Graphics/CombinerProgram.h +++ b/src/Graphics/CombinerProgram.h @@ -22,7 +22,7 @@ namespace graphics { virtual bool getBinaryForm(std::vector & _buffer) = 0; - static void getShaderCombinerOptionsSet(std::vector & _vecOptions); + static u32 getShaderCombinerOptionsBits(); }; typedef std::map Combiners; diff --git a/src/Graphics/Context.cpp b/src/Graphics/Context.cpp index 14870e17..8f4ae0c9 100644 --- a/src/Graphics/Context.cpp +++ b/src/Graphics/Context.cpp @@ -199,6 +199,17 @@ ColorBufferReader * Context::createColorBufferReader(CachedTexture * _pTexture) /*---------------Shaders-------------*/ +bool Context::isCombinerProgramBuilderObsolete() +{ + return m_impl->isCombinerProgramBuilderObsolete(); + +} + +void Context::resetCombinerProgramBuilder() +{ + m_impl->resetCombinerProgramBuilder(); +} + CombinerProgram * Context::createCombinerProgram(Combiner & _color, Combiner & _alpha, const CombinerKey & _key) { return m_impl->createCombinerProgram(_color, _alpha, _key); diff --git a/src/Graphics/Context.h b/src/Graphics/Context.h index 8840980d..197fe8d6 100644 --- a/src/Graphics/Context.h +++ b/src/Graphics/Context.h @@ -200,6 +200,10 @@ namespace graphics { /*---------------Shaders-------------*/ + bool isCombinerProgramBuilderObsolete(); + + void resetCombinerProgramBuilder(); + CombinerProgram * createCombinerProgram(Combiner & _color, Combiner & _alpha, const CombinerKey & _key); bool saveShadersStorage(const Combiners & _combiners); diff --git a/src/Graphics/ContextImpl.h b/src/Graphics/ContextImpl.h index 124c1bc1..7cf5c027 100644 --- a/src/Graphics/ContextImpl.h +++ b/src/Graphics/ContextImpl.h @@ -45,6 +45,8 @@ namespace graphics { virtual PixelWriteBuffer * createPixelWriteBuffer(size_t _sizeInBytes) = 0; virtual PixelReadBuffer * createPixelReadBuffer(size_t _sizeInBytes) = 0; virtual ColorBufferReader * createColorBufferReader(CachedTexture * _pTexture) = 0; + virtual bool isCombinerProgramBuilderObsolete() = 0; + virtual void resetCombinerProgramBuilder() = 0; virtual CombinerProgram * createCombinerProgram(Combiner & _color, Combiner & _alpha, const CombinerKey & _key) = 0; virtual bool saveShadersStorage(const Combiners & _combiners) = 0; virtual bool loadShadersStorage(Combiners & _combiners) = 0; diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp index b6afc3d2..7e009851 100644 --- a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp +++ b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp @@ -1990,6 +1990,7 @@ CombinerProgramBuilder::CombinerProgramBuilder(const opengl::GLInfo & _glinfo, o , m_shaderN64DepthCompare(new ShaderN64DepthCompare(_glinfo)) , m_shaderN64DepthRender(new ShaderN64DepthRender(_glinfo)) , m_useProgram(_useProgram) +, m_combinerOptionsBits(graphics::CombinerProgram::getShaderCombinerOptionsBits()) { m_vertexShaderRect = _createVertexShader(m_vertexHeader.get(), m_vertexRect.get()); m_vertexShaderTriangle = _createVertexShader(m_vertexHeader.get(), m_vertexTriangle.get()); @@ -2005,3 +2006,8 @@ CombinerProgramBuilder::~CombinerProgramBuilder() glDeleteShader(m_vertexShaderTexturedRect); glDeleteShader(m_vertexShaderTexturedTriangle); } + +bool CombinerProgramBuilder::isObsolete() const +{ + return m_combinerOptionsBits != graphics::CombinerProgram::getShaderCombinerOptionsBits(); +} diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.h b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.h index 839052c5..e8163ea0 100644 --- a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.h +++ b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.h @@ -31,6 +31,8 @@ namespace glsl { const ShaderPart * getFragmentShaderEnd() const; + bool isObsolete() const; + private: CombinerInputs compileCombiner(const CombinerKey & _key, Combiner & _color, Combiner & _alpha, std::string & _strShader); @@ -89,6 +91,7 @@ namespace glsl { GLuint m_vertexShaderTexturedRect; GLuint m_vertexShaderTexturedTriangle; opengl::CachedUseProgram * m_useProgram; + u32 m_combinerOptionsBits; }; } diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_ShaderStorage.cpp b/src/Graphics/OpenGLContext/GLSL/glsl_ShaderStorage.cpp index 821bd3b9..a18920cc 100644 --- a/src/Graphics/OpenGLContext/GLSL/glsl_ShaderStorage.cpp +++ b/src/Graphics/OpenGLContext/GLSL/glsl_ShaderStorage.cpp @@ -47,17 +47,6 @@ void getStorageFileName(const opengl::GLInfo & _glinfo, wchar_t * _shadersFileNa swprintf(_shadersFileName, PLUGIN_PATH_SIZE, L"%ls/GLideN64.%08lx.%ls.%ls", pPath, std::hash()(RSP.romname), strOpenGLType.c_str(), _fileExtension); } -static -u32 _getConfigOptionsBitSet() -{ - std::vector vecOptions; - graphics::CombinerProgram::getShaderCombinerOptionsSet(vecOptions); - u32 optionsSet = 0; - for (u32 i = 0; i < vecOptions.size(); ++i) - optionsSet |= vecOptions[i] << i; - return optionsSet; -} - /* Storage has text format: line_1 Version in hex form @@ -114,6 +103,10 @@ bool ShaderStorage::saveShadersStorage(const graphics::Combiners & _combiners) c if (!_saveCombinerKeys(_combiners)) return false; + if (gfxContext.isCombinerProgramBuilderObsolete()) + // Created shaders are obsolete due to changes in config, but we saved combiners keys. + return true; + if (!gfxContext.isSupported(graphics::SpecialFeatures::ShaderProgramBinary)) // Shaders storage is not supported, but we saved combiners keys. return true; @@ -135,7 +128,7 @@ bool ShaderStorage::saveShadersStorage(const graphics::Combiners & _combiners) c shadersOut.write((char*)&m_formatVersion, sizeof(m_formatVersion)); - const u32 configOptionsBitSet = _getConfigOptionsBitSet(); + const u32 configOptionsBitSet = graphics::CombinerProgram::getShaderCombinerOptionsBits(); shadersOut.write((char*)&configOptionsBitSet, sizeof(configOptionsBitSet)); const char * strRenderer = reinterpret_cast(glGetString(GL_RENDERER)); @@ -279,7 +272,7 @@ bool ShaderStorage::loadShadersStorage(graphics::Combiners & _combiners) wchar_t shadersFileName[PLUGIN_PATH_SIZE]; getStorageFileName(m_glinfo, shadersFileName, L"shaders"); - const u32 configOptionsBitSet = _getConfigOptionsBitSet(); + const u32 configOptionsBitSet = graphics::CombinerProgram::getShaderCombinerOptionsBits(); #if defined(OS_WINDOWS) && !defined(MINGW) std::ifstream fin(shadersFileName, std::ofstream::binary); diff --git a/src/Graphics/OpenGLContext/opengl_ContextImpl.cpp b/src/Graphics/OpenGLContext/opengl_ContextImpl.cpp index bfb4bcd9..52cdf50a 100644 --- a/src/Graphics/OpenGLContext/opengl_ContextImpl.cpp +++ b/src/Graphics/OpenGLContext/opengl_ContextImpl.cpp @@ -66,12 +66,7 @@ void ContextImpl::init() m_graphicsDrawer.reset(new UnbufferedDrawer(m_glInfo, m_cachedFunctions->getCachedVertexAttribArray())); } - m_combinerProgramBuilder.reset(new glsl::CombinerProgramBuilder(m_glInfo, m_cachedFunctions->getCachedUseProgram())); - m_specialShadersFactory.reset(new glsl::SpecialShadersFactory(m_glInfo, - m_cachedFunctions->getCachedUseProgram(), - m_combinerProgramBuilder->getVertexShaderHeader(), - m_combinerProgramBuilder->getFragmentShaderHeader(), - m_combinerProgramBuilder->getFragmentShaderEnd())); + resetCombinerProgramBuilder(); } void ContextImpl::destroy() @@ -319,6 +314,25 @@ graphics::ColorBufferReader * ContextImpl::createColorBufferReader(CachedTexture /*---------------Shaders-------------*/ +bool ContextImpl::isCombinerProgramBuilderObsolete() +{ + if (!m_combinerProgramBuilder) + return true; + return m_combinerProgramBuilder->isObsolete(); +} + +void ContextImpl::resetCombinerProgramBuilder() +{ + if (!isCombinerProgramBuilderObsolete()) + return; + m_combinerProgramBuilder.reset(new glsl::CombinerProgramBuilder(m_glInfo, m_cachedFunctions->getCachedUseProgram())); + m_specialShadersFactory.reset(new glsl::SpecialShadersFactory(m_glInfo, + m_cachedFunctions->getCachedUseProgram(), + m_combinerProgramBuilder->getVertexShaderHeader(), + m_combinerProgramBuilder->getFragmentShaderHeader(), + m_combinerProgramBuilder->getFragmentShaderEnd())); +} + graphics::CombinerProgram * ContextImpl::createCombinerProgram(Combiner & _color, Combiner & _alpha, const CombinerKey & _key) { return m_combinerProgramBuilder->buildCombinerProgram(_color, _alpha, _key); diff --git a/src/Graphics/OpenGLContext/opengl_ContextImpl.h b/src/Graphics/OpenGLContext/opengl_ContextImpl.h index 76b61a3d..b05a6228 100644 --- a/src/Graphics/OpenGLContext/opengl_ContextImpl.h +++ b/src/Graphics/OpenGLContext/opengl_ContextImpl.h @@ -98,6 +98,10 @@ namespace opengl { /*---------------Shaders-------------*/ + bool isCombinerProgramBuilderObsolete() override; + + void resetCombinerProgramBuilder() override; + graphics::CombinerProgram * createCombinerProgram(Combiner & _color, Combiner & _alpha, const CombinerKey & _key) override; bool saveShadersStorage(const graphics::Combiners & _combiners) override;