From 0482212f109b87261d019758274fdd1eee084896 Mon Sep 17 00:00:00 2001 From: Sergey Lipskiy Date: Thu, 8 Oct 2015 22:29:55 +0600 Subject: [PATCH] Add shaderStorage config option. Support it for mupen64plus. --- src/Combiner.cpp | 63 +++++++++++++++++++++++------- src/Config.cpp | 1 + src/Config.h | 10 ++++- src/mupenplus/Config_mupenplus.cpp | 3 ++ 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/src/Combiner.cpp b/src/Combiner.cpp index 2c0bf4d1..f1303d60 100644 --- a/src/Combiner.cpp +++ b/src/Combiner.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include "OpenGL.h" #include "Combiner.h" @@ -6,7 +8,9 @@ #include "UniformCollection.h" #include "Debug.h" #include "gDP.h" +#include "Config.h" #include "PluginAPI.h" +#include "RSP.h" static int saRGBExpanded[] = { @@ -92,10 +96,10 @@ void CombinerInfo::init() { m_pCurrent = NULL; m_pUniformCollection = createUniformCollection(); - m_bShaderCacheSupported = OGLVideo::isExtensionSupported("GL_ARB_get_program_binary"); + m_bShaderCacheSupported = config.generalEmulation.shaderStorage != Config::ssDoNotUse && OGLVideo::isExtensionSupported("GL_ARB_get_program_binary"); m_shadersLoaded = 0; - if (!_loadCombinersCache()) { + if (m_bShaderCacheSupported && !_loadCombinersCache()) { for (Combiners::iterator cur = m_combiners.begin(); cur != m_combiners.end(); ++cur) delete cur->second; m_combiners.clear(); @@ -107,7 +111,9 @@ void CombinerInfo::destroy() delete m_pUniformCollection; m_pUniformCollection = NULL; m_pCurrent = NULL; - _saveCombinersCache(); + if (m_bShaderCacheSupported) + _saveCombinersCache(); + m_shadersLoaded = 0; for (Combiners::iterator cur = m_combiners.begin(); cur != m_combiners.end(); ++cur) delete cur->second; m_combiners.clear(); @@ -315,6 +321,15 @@ void CombinerInfo::updateParameters(OGLRender::RENDER_STATE _renderState) m_pUniformCollection->updateUniforms(m_pCurrent, _renderState); } +#ifndef GLES2 +static +void getStorageFileName(wchar_t * _fileName) +{ + wchar_t strIniFolderPath[PLUGIN_PATH_SIZE]; + api().GetUserCachePath(strIniFolderPath); + swprintf(_fileName, PLUGIN_PATH_SIZE, L"%ls/GLideN64.%08lx.shaders", strIniFolderPath, config.generalEmulation.shaderStorage == Config::ssUseOneCommon ? 0 : std::hash()(RSP.romname)); +} + /* Storage format: uint32 - format version; @@ -328,26 +343,34 @@ Storage format: static const u32 CombinersCacheFormatVersion = 0x01U; void CombinerInfo::_saveCombinersCache() const { - if (!m_bShaderCacheSupported || m_shadersLoaded >= m_combiners.size()) + if (m_shadersLoaded >= m_combiners.size()) return; - wchar_t strIniFolderPath[PLUGIN_PATH_SIZE]; - api().FindPluginPath(strIniFolderPath); - std::wstring fileName(strIniFolderPath); - fileName += L"/GLideN64.shaders.bin"; + wchar_t fileName[PLUGIN_PATH_SIZE]; + getStorageFileName(fileName); + +#ifdef OS_WINDOWS std::ofstream fout(fileName, std::ofstream::binary | std::ofstream::trunc); +#else + char fileName_c[PATH_MAX]; + wcstombs(fileName_c, fileName, PATH_MAX); + std::ofstream fout(fileName_c, std::ofstream::binary | std::ofstream::trunc); +#endif if (!fout) return; fout.write((char*)&CombinersCacheFormatVersion, sizeof(CombinersCacheFormatVersion)); + const char * strRenderer = reinterpret_cast(glGetString(GL_RENDERER)); u32 len = strlen(strRenderer); fout.write((char*)&len, sizeof(len)); fout.write(strRenderer, len); + const char * strGLVersion = reinterpret_cast(glGetString(GL_VERSION)); len = strlen(strGLVersion); fout.write((char*)&len, sizeof(len)); fout.write(strGLVersion, len); + len = m_combiners.size(); fout.write((char*)&len, sizeof(len)); for (Combiners::const_iterator cur = m_combiners.begin(); cur != m_combiners.end(); ++cur) @@ -358,14 +381,16 @@ void CombinerInfo::_saveCombinersCache() const bool CombinerInfo::_loadCombinersCache() { - if (!m_bShaderCacheSupported) - return false; + wchar_t fileName[PLUGIN_PATH_SIZE]; + getStorageFileName(fileName); - wchar_t strIniFolderPath[PLUGIN_PATH_SIZE]; - api().FindPluginPath(strIniFolderPath); - std::wstring fileName(strIniFolderPath); - fileName += L"/GLideN64.shaders.bin"; +#ifdef OS_WINDOWS std::ifstream fin(fileName, std::ofstream::binary); +#else + char fileName_c[PATH_MAX]; + wcstombs(fileName_c, fileName, PATH_MAX); + std::ifstream fin(fileName_c, std::ofstream::binary); +#endif if (!fin) return false; @@ -397,7 +422,17 @@ bool CombinerInfo::_loadCombinersCache() m_pUniformCollection->bindWithShaderCombiner(m_pCurrent); m_combiners[m_pCurrent->getMux()] = m_pCurrent; } + m_shadersLoaded = m_combiners.size(); fin.close(); return !isGLError(); } +#else // GLES2 +void CombinerInfo::_saveCombinersCache() const +{} + +bool CombinerInfo::_loadCombinersCache() +{ + return true; +} +#endif //GLES2 diff --git a/src/Config.cpp b/src/Config.cpp index ec45d269..75d922f9 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -34,6 +34,7 @@ void Config::resetToDefaults() generalEmulation.enableNoise = 1; generalEmulation.enableHWLighting = 0; generalEmulation.enableCustomSettings = 1; + generalEmulation.shaderStorage = ssDoNotUse; generalEmulation.hacks = 0; #ifdef ANDROID generalEmulation.forcePolygonOffset = 0; diff --git a/src/Config.h b/src/Config.h index 918b0606..1bf7cf43 100644 --- a/src/Config.h +++ b/src/Config.h @@ -8,7 +8,8 @@ #define CONFIG_VERSION_TWO 2U #define CONFIG_VERSION_THREE 3U #define CONFIG_VERSION_FOUR 4U // Remove ValidityCheckMethod setting -#define CONFIG_VERSION_CURRENT CONFIG_VERSION_FOUR +#define CONFIG_VERSION_FIVE 5U // Add shader storage option +#define CONFIG_VERSION_CURRENT CONFIG_VERSION_FIVE #define BILINEAR_3POINT 0 #define BILINEAR_STANDARD 1 @@ -39,12 +40,19 @@ struct Config u32 screenShotFormat; } texture; + enum ShaderStorage { + ssDoNotUse = 0, // Do not use shaders storage + ssUseOneCommon, // Use one shader storage for all games + ssUseOnePerGame // Use shader storage per game. + }; + struct { u32 enableFog; u32 enableNoise; u32 enableLOD; u32 enableHWLighting; u32 enableCustomSettings; + u32 shaderStorage; u32 hacks; #ifdef ANDROID u32 forcePolygonOffset; diff --git a/src/mupenplus/Config_mupenplus.cpp b/src/mupenplus/Config_mupenplus.cpp index c4bea129..b7507340 100644 --- a/src/mupenplus/Config_mupenplus.cpp +++ b/src/mupenplus/Config_mupenplus.cpp @@ -66,6 +66,8 @@ bool Config_SetDefault() assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableHWLighting", config.generalEmulation.enableHWLighting, "Enable hardware per-pixel lighting."); assert(res == M64ERR_SUCCESS); + res = ConfigSetDefaultInt(g_configVideoGliden64, "ShaderStorage", config.generalEmulation.shaderStorage, "Use persistent storage for compiled shaders (0=not use, 1=use one for all, 2=use one per game)"); + assert(res == M64ERR_SUCCESS); #ifdef ANDROID res = ConfigSetDefaultBool(g_configVideoGliden64, "ForcePolygonOffset", config.generalEmulation.forcePolygonOffset, "If true, use polygon offset values specified below"); assert(res == M64ERR_SUCCESS); @@ -179,6 +181,7 @@ void Config_LoadConfig() config.generalEmulation.enableNoise = ConfigGetParamBool(g_configVideoGliden64, "EnableNoise"); config.generalEmulation.enableLOD = ConfigGetParamBool(g_configVideoGliden64, "EnableLOD"); config.generalEmulation.enableHWLighting = ConfigGetParamBool(g_configVideoGliden64, "EnableHWLighting"); + config.generalEmulation.shaderStorage = ConfigGetParamInt(g_configVideoGliden64, "ShaderStorage"); #ifdef ANDROID config.generalEmulation.forcePolygonOffset = ConfigGetParamBool(g_configVideoGliden64, "ForcePolygonOffset"); config.generalEmulation.polygonOffsetFactor = ConfigGetParamFloat(g_configVideoGliden64, "PolygonOffsetFactor");