all repos — mgba @ 90c656961ebcdae682f52d916189b9672a4edbb8

mGBA Game Boy Advance Emulator

Switch: Update GL code to GLES 3, up frame limiter
Vicki Pfau vi@endrift.com
Wed, 19 Sep 2018 13:31:08 -0700
commit

90c656961ebcdae682f52d916189b9672a4edbb8

parent

bb6ecd41cb8446d1df43b6d7a0cb4638091a5c7b

M CMakeLists.txtCMakeLists.txt

@@ -48,6 +48,7 @@ set(BUILD_SHARED ON CACHE BOOL "Build a shared library")

set(SKIP_LIBRARY OFF CACHE BOOL "Skip building the library (useful for only building libretro or OpenEmu cores)") set(BUILD_GL ON CACHE BOOL "Build with OpenGL") set(BUILD_GLES2 OFF CACHE BOOL "Build with OpenGL|ES 2") +set(BUILD_GLES3 OFF CACHE BOOL "Build with OpenGL|ES 3") set(USE_EPOXY ON CACHE STRING "Build with libepoxy") set(DISABLE_DEPS OFF CACHE BOOL "Build without dependencies") set(DISTBUILD OFF CACHE BOOL "Build distribution packages")

@@ -296,7 +297,7 @@ add_definitions(-DFIXED_ROM_BUFFER)

endif() if(DEFINED SWITCH) - set(BUILD_GLES2 ON CACHE BOOL "Build with OpenGL|ES 2" FORCE) + set(BUILD_GLES3 ON CACHE BOOL "Build with OpenGL|ES 3" FORCE) endif() if(NOT M_CORE_GBA)

@@ -438,6 +439,13 @@ endif()

if(NOT BUILD_GLES2) set(OPENGLES2_LIBRARY "" CACHE PATH "" FORCE) endif() +if(BUILD_GLES3) + find_path(OPENGLES3_INCLUDE_DIR NAMES GLES3/gl3.h) + find_library(OPENGLES3_LIBRARY NAMES GLESv3 GLESv2) + if(NOT OPENGLES3_INCLUDE_DIR OR NOT OPENGLES3_LIBRARY) + set(BUILD_GLES3 OFF CACHE BOOL "OpenGL|ES 3 not found" FORCE) + endif() +endif() set(WANT_ZLIB ${USE_ZLIB}) set(WANT_PNG ${USE_PNG}) set(WANT_LIBZIP ${USE_LIBZIP})

@@ -878,6 +886,10 @@ if(BUILD_GLES2)

add_definitions(-DBUILD_GLES2) endif() +if(BUILD_GLES3) + add_definitions(-DBUILD_GLES3) +endif() + if(DISABLE_FRONTENDS) set(BUILD_SDL OFF) set(BUILD_QT OFF)

@@ -1095,6 +1107,9 @@ list(APPEND SUMMARY_GL_LIST "OpenGL")

endif() if(BUILD_GLES2) list(APPEND SUMMARY_GL_LIST "OpenGL|ES 2") + endif() + if(BUILD_GLES3) + list(APPEND SUMMARY_GL_LIST "OpenGL|ES 3") endif() endif() if(NOT SUMMARY_GL_LIST)
M src/platform/switch/CMakeLists.txtsrc/platform/switch/CMakeLists.txt

@@ -8,7 +8,7 @@ set(OS_DEFINES USE_VFS_FILE IOAPI_NO_64)

list(APPEND CORE_VFS_SRC ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-file.c ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) list(APPEND GUI_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gui-font.c) -include_directories(AFTER ${OPENGLES2_INCLUDE_DIR} ${OPENGL_EGL_INCLUDE_DIR}) +include_directories(AFTER ${OPENGLES3_INCLUDE_DIR} ${OPENGL_EGL_INCLUDE_DIR}) file(GLOB OS_SRC ${CMAKE_SOURCE_DIR}/src/platform/wii/wii-*.c) if(${CMAKE_BUILD_TYPE} STREQUAL Debug OR ${CMAKE_BUILD_TYPE} STREQUAL RelWithDebInfo)

@@ -34,7 +34,7 @@ endif()

add_executable(${BINARY_NAME}.elf ${GUI_SRC} ${PLATFORM_SRC} main.c) set_target_properties(${BINARY_NAME}.elf PROPERTIES COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}") -target_link_libraries(${BINARY_NAME}.elf ${BINARY_NAME} ${M_LIBRARY} ${EGL_LIBRARY} ${OPENGLES2_LIBRARY} ${GLAPI_LIBRARY} ${NOUVEAU_LIBRARY} stdc++ ${OS_LIB}) +target_link_libraries(${BINARY_NAME}.elf ${BINARY_NAME} ${M_LIBRARY} ${EGL_LIBRARY} ${OPENGLES3_LIBRARY} ${GLAPI_LIBRARY} ${NOUVEAU_LIBRARY} stdc++ ${OS_LIB}) add_custom_command(OUTPUT control.nacp COMMAND ${NACPTOOL} --create "${PROJECT_NAME}" "endrift" "${VERSION_STRING}" control.nacp)
M src/platform/switch/gui-font.csrc/platform/switch/gui-font.c

@@ -9,7 +9,7 @@ #include <mgba-util/png-io.h>

#include <mgba-util/string.h> #include <mgba-util/vfs.h> -#include <GLES2/gl2.h> +#include <GLES3/gl3.h> #define GLYPH_HEIGHT 24 #define CELL_HEIGHT 32

@@ -58,7 +58,7 @@ struct GUIFont {

GLuint font; GLuint program; GLuint vbo; - GLuint offsetLocation; + GLuint vao; GLuint texLocation; GLuint dimsLocation; GLuint transformLocation;

@@ -166,12 +166,16 @@ font->transformLocation = glGetUniformLocation(font->program, "transform");

font->originLocation = glGetUniformLocation(font->program, "origin"); font->glyphLocation = glGetUniformLocation(font->program, "glyph"); font->cutoffLocation = glGetUniformLocation(font->program, "cutoff"); - font->offsetLocation = glGetAttribLocation(font->program, "offset"); + GLuint offsetLocation = glGetAttribLocation(font->program, "offset"); glGenBuffers(1, &font->vbo); + glGenVertexArrays(1, &font->vao); + glBindVertexArray(font->vao); glBindBuffer(GL_ARRAY_BUFFER, font->vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(_offsets), _offsets, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); + glVertexAttribPointer(offsetLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(offsetLocation); + glBindVertexArray(0); return font; }

@@ -180,6 +184,7 @@ void GUIFontDestroy(struct GUIFont* font) {

glDeleteBuffers(1, &font->vbo); glDeleteProgram(font->program); glDeleteTextures(1, &font->font); + glDeleteVertexArrays(1, &font->vao); free(font); }

@@ -222,9 +227,9 @@ }

struct GUIFontGlyphMetric metric = defaultFontMetrics[glyph]; glUseProgram(font->program); + glBindVertexArray(font->vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, font->font); - glBindBuffer(GL_ARRAY_BUFFER, font->vbo); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

@@ -235,9 +240,6 @@ glUniform2f(font->dimsLocation, CELL_WIDTH - (metric.padding.left + metric.padding.right) * 2, CELL_HEIGHT - (metric.padding.top + metric.padding.bottom) * 2);

glUniform3f(font->originLocation, x, y - GLYPH_HEIGHT + metric.padding.top * 2, 0); glUniformMatrix2fv(font->transformLocation, 1, GL_FALSE, (float[4]) {1.0, 0.0, 0.0, 1.0}); - glVertexAttribPointer(font->offsetLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); - glEnableVertexAttribArray(font->offsetLocation); - glUniform1f(font->cutoffLocation, 0.1f); glUniform4f(font->colorLocation, 0.0, 0.0, 0.0, ((color >> 24) & 0xFF) / 128.0f); glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

@@ -246,8 +248,7 @@ glUniform1f(font->cutoffLocation, 0.7f);

glUniform4f(font->colorLocation, (color & 0xFF) / 255.0f, ((color >> 8) & 0xFF) / 255.0f, ((color >> 16) & 0xFF) / 255.0f, ((color >> 24) & 0xFF) / 255.0f); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisableVertexAttribArray(font->offsetLocation); - glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); glUseProgram(0); }

@@ -291,9 +292,9 @@ break;

} glUseProgram(font->program); + glBindVertexArray(font->vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, font->font); - glBindBuffer(GL_ARRAY_BUFFER, font->vbo); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

@@ -304,9 +305,6 @@ glUniform2f(font->dimsLocation, metric.width * 2, metric.height * 2);

glUniform3f(font->originLocation, x, y, 0); glUniformMatrix2fv(font->transformLocation, 1, GL_FALSE, (float[4]) {hFlip, 0.0, 0.0, vFlip}); - glVertexAttribPointer(font->offsetLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); - glEnableVertexAttribArray(font->offsetLocation); - glUniform1f(font->cutoffLocation, 0.1f); glUniform4f(font->colorLocation, 0.0, 0.0, 0.0, ((color >> 24) & 0xFF) / 128.0f); glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

@@ -315,8 +313,7 @@ glUniform1f(font->cutoffLocation, 0.7f);

glUniform4f(font->colorLocation, (color & 0xFF) / 255.0f, ((color >> 8) & 0xFF) / 255.0f, ((color >> 16) & 0xFF) / 255.0f, ((color >> 24) & 0xFF) / 255.0f); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisableVertexAttribArray(font->offsetLocation); - glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); glUseProgram(0); }

@@ -334,9 +331,9 @@ h = metric.height * 2;

} glUseProgram(font->program); + glBindVertexArray(font->vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, font->font); - glBindBuffer(GL_ARRAY_BUFFER, font->vbo); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

@@ -347,9 +344,6 @@ glUniform2f(font->dimsLocation, metric.width * 2, metric.height * 2);

glUniform3f(font->originLocation, x + w / 2 - metric.width, y + h / 2 - metric.height, 0); glUniformMatrix2fv(font->transformLocation, 1, GL_FALSE, (float[4]) {w * 0.5f / metric.width, 0.0, 0.0, h * 0.5f / metric.height}); - glVertexAttribPointer(font->offsetLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); - glEnableVertexAttribArray(font->offsetLocation); - glUniform1f(font->cutoffLocation, 0.1f); glUniform4f(font->colorLocation, 0.0, 0.0, 0.0, ((color >> 24) & 0xFF) / 128.0f); glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

@@ -358,7 +352,6 @@ glUniform1f(font->cutoffLocation, 0.7f);

glUniform4f(font->colorLocation, ((color >> 16) & 0xFF) / 255.0f, ((color >> 8) & 0xFF) / 255.0f, (color & 0xFF) / 255.0f, ((color >> 24) & 0xFF) / 255.0f); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisableVertexAttribArray(font->offsetLocation); - glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); glUseProgram(0); }
M src/platform/switch/main.csrc/platform/switch/main.c

@@ -13,12 +13,13 @@ #include <mgba-util/gui/font.h>

#include <switch.h> #include <EGL/egl.h> -#include <GLES2/gl2.h> +#include <GLES3/gl3.h> #define AUTO_INPUT 0x4E585031 #define SAMPLES 0x400 #define BUFFER_SIZE 0x1000 #define N_BUFFERS 4 +#define FRAME_LIMIT 10 TimeType __nx_time_type = TimeType_UserSystemClock;

@@ -63,7 +64,7 @@ "}";

static GLuint program; static GLuint vbo; -static GLuint offsetLocation; +static GLuint vao; static GLuint texLocation; static GLuint dimsLocation; static GLuint insizeLocation;

@@ -106,7 +107,7 @@ goto _fail1;

} EGLint contextAttributeList[] = { - EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE }; s_context = eglCreateContext(s_display, config, EGL_NO_CONTEXT, contextAttributeList);

@@ -144,11 +145,11 @@ mInputBindKey(map, binding, __builtin_ctz(nativeKey), key);

} static void _drawStart(void) { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT); } static void _drawEnd(void) { - if (frameLimiter || (framecount & 3) == 0) { + if (frameLimiter || (framecount % FRAME_LIMIT) == 0) { eglSwapBuffers(s_display, s_surface); } }

@@ -199,12 +200,11 @@ blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), samplerate * ratio);

} static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, bool faded) { - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glUseProgram(program); + glBindVertexArray(vao); float aspectX = width / (float) runner->params.width; float aspectY = height / (float) runner->params.height; float max;

@@ -226,26 +226,25 @@ } else {

glUniform4f(colorLocation, 0.8f, 0.8f, 0.8f, 0.8f); } - glVertexAttribPointer(offsetLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); - glEnableVertexAttribArray(offsetLocation); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisableVertexAttribArray(offsetLocation); - glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); glUseProgram(0); } static void _drawFrame(struct mGUIRunner* runner, bool faded) { + ++framecount; + if (!frameLimiter && (framecount % FRAME_LIMIT) != 0) { + return; + } + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, frameBuffer); unsigned width, height; runner->core->desiredVideoDimensions(runner->core, &width, &height); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, height, GL_RGBA, GL_UNSIGNED_BYTE, frameBuffer); _drawTex(runner, width, height, faded); - - ++framecount; } static void _drawScreenshot(struct mGUIRunner* runner, const color_t* pixels, unsigned width, unsigned height, bool faded) {

@@ -342,6 +341,7 @@ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); program = glCreateProgram(); GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);

@@ -386,12 +386,16 @@ texLocation = glGetUniformLocation(program, "tex");

colorLocation = glGetUniformLocation(program, "color"); dimsLocation = glGetUniformLocation(program, "dims"); insizeLocation = glGetUniformLocation(program, "insize"); - offsetLocation = glGetAttribLocation(program, "offset"); + GLuint offsetLocation = glGetAttribLocation(program, "offset"); glGenBuffers(1, &vbo); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(_offsets), _offsets, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); + glVertexAttribPointer(offsetLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(offsetLocation); + glBindVertexArray(0); stream.videoDimensionsChanged = NULL; stream.postVideoFrame = NULL;

@@ -482,6 +486,11 @@ _mapKey(&runner.params.keyMap, AUTO_INPUT, KEY_DRIGHT, GUI_INPUT_RIGHT);

audoutStartAudioOut(); mGUIRunloop(&runner); + + glDeleteTextures(1, &tex); + glDeleteBuffers(1, &vbo); + glDeleteProgram(program); + glDeleteVertexArrays(1, &vao); psmExit(); audoutExit();