1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-02 09:03:37 +00:00

Workaround for devices where glBlitFrameBuffer produces output upside

down.
This commit is contained in:
Francisco Zurita 2016-10-29 13:33:05 -04:00 committed by Sergey Lipskiy
parent 478344ab5f
commit 7ca4d0430b
6 changed files with 83 additions and 5 deletions

View File

@ -45,6 +45,7 @@ void Config::resetToDefaults()
#else
generalEmulation.enableFragmentDepthWrite = 1;
#endif
generalEmulation.enableBlitScreenWorkaround = 0;
#ifdef ANDROID
generalEmulation.forcePolygonOffset = 0;
generalEmulation.polygonOffsetFactor = 0.0f;

View File

@ -60,6 +60,7 @@ struct Config
u32 enableNativeResTexrects;
u32 enableLegacyBlending;
u32 enableFragmentDepthWrite;
u32 enableBlitScreenWorkaround;
u32 hacks;
#ifdef ANDROID
u32 forcePolygonOffset;

View File

@ -866,8 +866,9 @@ void FrameBufferList::renderBuffer(u32 _address)
srcY0 = (GLint)(srcY0*yScale);
srcY1 = srcY0 + VI.real_height;
}
FrameBuffer * pFilteredBuffer = PostProcessor::get().doBlur(PostProcessor::get().doGammaCorrection(pBuffer));
PostProcessor & postProcessor = PostProcessor::get();
FrameBuffer * pFilteredBuffer = postProcessor.doBlur(postProcessor.doGammaCorrection(
postProcessor.doOrientationCorrection(pBuffer)));
const bool vi_fsaa = (*REG.VI_STATUS & 512) == 0;
const bool vi_divot = (*REG.VI_STATUS & 16) != 0;
@ -938,7 +939,8 @@ void FrameBufferList::renderBuffer(u32 _address)
const u32 size = *REG.VI_STATUS & 3;
pBuffer = findBuffer(_address + (((*REG.VI_WIDTH)*VI.height)<<size>>1));
if (pBuffer != nullptr) {
pFilteredBuffer = PostProcessor::get().doBlur(PostProcessor::get().doGammaCorrection(pBuffer));
pFilteredBuffer = postProcessor.doBlur(postProcessor.doGammaCorrection(
postProcessor.doOrientationCorrection(pBuffer)));
srcY0 = 0;
srcY1 = srcPartHeight;
dstY0 = dstY1;

View File

@ -242,6 +242,27 @@ FRAGMENT_SHADER_END
"} \n"
;
static const char* orientationCorrectionShader =
SHADER_VERSION
"#if (__VERSION__ > 120) \n"
"# define IN in \n"
"# define OUT out \n"
"# define texture2D texture \n"
"#else \n"
"# define IN varying \n"
"# define OUT \n"
"#endif // __VERSION __ \n"
"IN mediump vec2 vTexCoord; \n"
"uniform sampler2D Sample0; \n"
"OUT lowp vec4 fragColor; \n"
" \n"
"void main() \n"
"{ \n"
" fragColor = texture2D( Sample0, vec2(1.0 - vTexCoord.x, 1.0 - vTexCoord.y)); \n"
FRAGMENT_SHADER_END
"} \n"
;
static
GLuint _createShaderProgram(const char * _strVertex, const char * _strFragment)
{
@ -321,6 +342,7 @@ PostProcessor::PostProcessor()
, m_glowProgram(0)
, m_bloomProgram(0)
, m_gammaCorrectionProgram(0)
, m_orientationCorrectionProgram(0)
, m_pResultBuffer(nullptr)
, m_FBO_glowMap(0)
, m_FBO_blur(0)
@ -405,10 +427,22 @@ void PostProcessor::_initBlur()
glUseProgram(0);
}
void PostProcessor::_initOrientationCorrection()
{
m_orientationCorrectionProgram = _createShaderProgram(vertexShader, orientationCorrectionShader);
glUseProgram(m_orientationCorrectionProgram);
int loc = glGetUniformLocation(m_orientationCorrectionProgram, "Sample0");
assert(loc >= 0);
glUniform1i(loc, 0);
glUseProgram(0);
}
void PostProcessor::init()
{
_initCommon();
_initGammaCorrection();
if (config.generalEmulation.enableBlitScreenWorkaround != 0)
_initOrientationCorrection();
if (config.bloomFilter.enable != 0)
_initBlur();
}
@ -428,6 +462,13 @@ void PostProcessor::_destroyGammaCorrection()
m_gammaCorrectionProgram = 0;
}
void PostProcessor::_destroyOrientationCorrection()
{
if (m_orientationCorrectionProgram != 0)
glDeleteProgram(m_orientationCorrectionProgram);
m_orientationCorrectionProgram = 0;
}
void PostProcessor::_destroyBlur()
{
if (m_extractBloomProgram != 0)
@ -468,6 +509,7 @@ void PostProcessor::destroy()
{
_destroyBlur();
_destroyGammaCorrection();
_destroyOrientationCorrection();
_destroyCommon();
}
@ -591,3 +633,23 @@ FrameBuffer * PostProcessor::doGammaCorrection(FrameBuffer * _pBuffer)
_postDraw();
return m_pResultBuffer;
}
FrameBuffer * PostProcessor::doOrientationCorrection(FrameBuffer * _pBuffer)
{
if (_pBuffer == nullptr)
return nullptr;
if (config.generalEmulation.enableBlitScreenWorkaround == 0)
return _pBuffer;
_preDraw(_pBuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_pResultBuffer->m_FBO);
textureCache().activateTexture(0, m_pTextureOriginal);
glUseProgram(m_orientationCorrectionProgram);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
_postDraw();
return m_pResultBuffer;
}

View File

@ -12,6 +12,7 @@ public:
FrameBuffer * doBlur(FrameBuffer * _pBuffer);
FrameBuffer * doGammaCorrection(FrameBuffer * _pBuffer);
FrameBuffer * doOrientationCorrection(FrameBuffer * _pBuffer);
static PostProcessor & get();
@ -23,6 +24,8 @@ private:
void _destroyCommon();
void _initGammaCorrection();
void _destroyGammaCorrection();
void _initOrientationCorrection();
void _destroyOrientationCorrection();
void _initBlur();
void _destroyBlur();
void _setGLState();
@ -36,6 +39,8 @@ private:
GLuint m_gammaCorrectionProgram;
GLuint m_orientationCorrectionProgram;
FrameBuffer * m_pResultBuffer;
GLuint m_FBO_glowMap;

View File

@ -86,7 +86,11 @@ bool Config_SetDefault()
#ifndef GLES2
res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableFragmentDepthWrite", config.generalEmulation.enableFragmentDepthWrite, "Enable writing of fragment depth. Some mobile GPUs do not support it, thus it made optional. Leave enabled.");
assert(res == M64ERR_SUCCESS);
#endif
#ifdef GLESX
res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableBlitScreenWorkaround", config.generalEmulation.enableBlitScreenWorkaround, "Enable to render everything upside down");
assert(res == M64ERR_SUCCESS);
#endif //GLESX
#endif //GLES2
#ifdef ANDROID
res = ConfigSetDefaultBool(g_configVideoGliden64, "ForcePolygonOffset", config.generalEmulation.forcePolygonOffset, "If true, use polygon offset values specified below");
assert(res == M64ERR_SUCCESS);
@ -237,7 +241,10 @@ void Config_LoadConfig()
config.generalEmulation.enableLegacyBlending = ConfigGetParamBool(g_configVideoGliden64, "EnableLegacyBlending");
#ifndef GLES2
config.generalEmulation.enableFragmentDepthWrite = ConfigGetParamBool(g_configVideoGliden64, "EnableFragmentDepthWrite");
#endif
#ifdef GLESX
config.generalEmulation.enableBlitScreenWorkaround = ConfigGetParamBool(g_configVideoGliden64, "EnableBlitScreenWorkaround");
#endif //GLESX
#endif //GLES2
#ifdef ANDROID
config.generalEmulation.forcePolygonOffset = ConfigGetParamBool(g_configVideoGliden64, "ForcePolygonOffset");
config.generalEmulation.polygonOffsetFactor = ConfigGetParamFloat(g_configVideoGliden64, "PolygonOffsetFactor");