diff --git a/CHANGES b/CHANGES index cb24f5ed0..57e84048a 100644 --- a/CHANGES +++ b/CHANGES @@ -101,6 +101,7 @@ Other fixes: - 3DS: Fix screen darkening (fixes mgba.io/i/1562) - Core: Fix uninitialized memory issues with graphics caches - Core: Return null for out of bounds cached tile VRAM querying + - GBA Video: Fix OpenGL fragment data binding - Debugger: Fix tracing skipping instructions (fixes mgba.io/i/1614) - OpenGL: Only invalidate texture if dimensions change (fixes mgba.io/i/1612) - Qt: Fix fast forward mute being reset (fixes mgba.io/i/1574) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 7bc564648..18a689ee3 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -696,7 +696,7 @@ void GBAVideoGLRendererCreate(struct GBAVideoGLRenderer* renderer) { renderer->scale = 1; } -static void _compileShader(struct GBAVideoGLRenderer* glRenderer, struct GBAVideoGLShader* shader, const char** shaderBuffer, int shaderBufferLines, GLuint vs, const struct GBAVideoGLUniform* uniforms, char* log) { +static void _compileShader(struct GBAVideoGLRenderer* glRenderer, struct GBAVideoGLShader* shader, const char** shaderBuffer, int shaderBufferLines, GLuint vs, const struct GBAVideoGLUniform* uniforms, const char* const* outFrags, char* log) { GLuint program = glCreateProgram(); shader->program = program; @@ -709,16 +709,20 @@ static void _compileShader(struct GBAVideoGLRenderer* glRenderer, struct GBAVide if (log[0]) { mLOG(GBA_VIDEO, ERROR, "Fragment shader compilation failure: %s", log); } + size_t i; +#ifndef BUILD_GLES3 + for (i = 0; outFrags[i]; ++i) { + glBindFragDataLocation(program, i, outFrags[i]); + } +#else + UNUSED(outFrags); +#endif glLinkProgram(program); glGetProgramInfoLog(program, 2048, 0, log); if (log[0]) { mLOG(GBA_VIDEO, ERROR, "Program link failure: %s", log); } glDeleteShader(fs); -#ifndef BUILD_GLES3 - glBindFragDataLocation(program, 0, "color"); - glBindFragDataLocation(program, 1, "flags"); -#endif glGenVertexArrays(1, &shader->vao); glBindVertexArray(shader->vao); @@ -727,7 +731,6 @@ static void _compileShader(struct GBAVideoGLRenderer* glRenderer, struct GBAVide glEnableVertexAttribArray(positionLocation); glVertexAttribPointer(positionLocation, 2, GL_INT, GL_FALSE, 0, NULL); - size_t i; for (i = 0; uniforms[i].name; ++i) { shader->uniforms[uniforms[i].type] = glGetUniformLocation(program, uniforms[i].name); } @@ -838,56 +841,52 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { mLOG(GBA_VIDEO, ERROR, "Vertex shader compilation failure: %s", log); } + const char* const noWindow[] = {"color", "flags", NULL}; + const char* const window[] = {"color", "flags", "window", NULL}; + const char* const onlyWindow[] = {"window", NULL}; + const char* const onlyColor[] = {"color", NULL}; + shaderBuffer[1] = _renderMode0; shaderBuffer[2] = _renderTile16; - _compileShader(glRenderer, &glRenderer->bgShader[0], shaderBuffer, 3, vs, _uniformsMode0, log); + _compileShader(glRenderer, &glRenderer->bgShader[0], shaderBuffer, 3, vs, _uniformsMode0, noWindow, log); shaderBuffer[2] = _renderTile256; - _compileShader(glRenderer, &glRenderer->bgShader[1], shaderBuffer, 3, vs, _uniformsMode0, log); + _compileShader(glRenderer, &glRenderer->bgShader[1], shaderBuffer, 3, vs, _uniformsMode0, noWindow, log); shaderBuffer[1] = _renderMode2; shaderBuffer[2] = _interpolate; shaderBuffer[3] = _fetchTileOverflow; - _compileShader(glRenderer, &glRenderer->bgShader[2], shaderBuffer, 4, vs, _uniformsMode2, log); + _compileShader(glRenderer, &glRenderer->bgShader[2], shaderBuffer, 4, vs, _uniformsMode2, noWindow, log); shaderBuffer[3] = _fetchTileNoOverflow; - _compileShader(glRenderer, &glRenderer->bgShader[3], shaderBuffer, 4, vs, _uniformsMode2, log); + _compileShader(glRenderer, &glRenderer->bgShader[3], shaderBuffer, 4, vs, _uniformsMode2, noWindow, log); shaderBuffer[1] = _renderMode4; shaderBuffer[2] = _interpolate; - _compileShader(glRenderer, &glRenderer->bgShader[4], shaderBuffer, 3, vs, _uniformsMode4, log); + _compileShader(glRenderer, &glRenderer->bgShader[4], shaderBuffer, 3, vs, _uniformsMode4, noWindow, log); shaderBuffer[1] = _renderMode35; shaderBuffer[2] = _interpolate; - _compileShader(glRenderer, &glRenderer->bgShader[5], shaderBuffer, 3, vs, _uniformsMode35, log); + _compileShader(glRenderer, &glRenderer->bgShader[5], shaderBuffer, 3, vs, _uniformsMode35, noWindow, log); shaderBuffer[1] = _renderObj; shaderBuffer[2] = _renderTile16; - _compileShader(glRenderer, &glRenderer->objShader[0], shaderBuffer, 3, vs, _uniformsObj, log); -#ifndef BUILD_GLES3 - glBindFragDataLocation(glRenderer->objShader[0].program, 2, "window"); -#endif + _compileShader(glRenderer, &glRenderer->objShader[0], shaderBuffer, 3, vs, _uniformsObj, window, log); shaderBuffer[2] = _renderTile256; - _compileShader(glRenderer, &glRenderer->objShader[1], shaderBuffer, 3, vs, _uniformsObj, log); -#ifndef BUILD_GLES3 - glBindFragDataLocation(glRenderer->objShader[1].program, 2, "window"); -#endif + _compileShader(glRenderer, &glRenderer->objShader[1], shaderBuffer, 3, vs, _uniformsObj, window, log); shaderBuffer[1] = _renderObjPriority; - _compileShader(glRenderer, &glRenderer->objShader[2], shaderBuffer, 2, vs, _uniformsObjPriority, log); + _compileShader(glRenderer, &glRenderer->objShader[2], shaderBuffer, 2, vs, _uniformsObjPriority, noWindow, log); shaderBuffer[1] = _renderWindow; - _compileShader(glRenderer, &glRenderer->windowShader, shaderBuffer, 2, vs, _uniformsWindow, log); -#ifndef BUILD_GLES3 - glBindFragDataLocation(glRenderer->windowShader.program, 0, "window"); -#endif + _compileShader(glRenderer, &glRenderer->windowShader, shaderBuffer, 2, vs, _uniformsWindow, onlyWindow, log); shaderBuffer[1] = _finalize; - _compileShader(glRenderer, &glRenderer->finalizeShader, shaderBuffer, 2, vs, _uniformsFinalize, log); + _compileShader(glRenderer, &glRenderer->finalizeShader, shaderBuffer, 2, vs, _uniformsFinalize, onlyColor, log); glBindVertexArray(0); glDeleteShader(vs);