diff --git a/src/gba/core.c b/src/gba/core.c index e753971e6..53925cc52 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -18,7 +18,7 @@ #ifndef DISABLE_THREADING #include #endif -#ifdef BUILD_GLES2 +#if defined(BUILD_GLES2) || defined(BUILD_GLES3) #include #endif #include @@ -130,7 +130,7 @@ struct mVideoLogContext; struct GBACore { struct mCore d; struct GBAVideoSoftwareRenderer renderer; -#ifdef BUILD_GLES2 +#if defined(BUILD_GLES2) || defined(BUILD_GLES3) struct GBAVideoGLRenderer glRenderer; #endif struct GBAVideoProxyRenderer proxyRenderer; @@ -180,7 +180,7 @@ static bool _GBACoreInit(struct mCore* core) { GBAVideoSoftwareRendererCreate(&gbacore->renderer); gbacore->renderer.outputBuffer = NULL; -#ifdef BUILD_GLES2 +#if defined(BUILD_GLES2) || defined(BUILD_GLES3) GBAVideoGLRendererCreate(&gbacore->glRenderer); gbacore->glRenderer.outputTex = -1; #endif @@ -229,7 +229,7 @@ static bool _GBACoreSupportsFeature(const struct mCore* core, enum mCoreFeature UNUSED(core); switch (feature) { case mCORE_FEATURE_OPENGL: -#ifdef BUILD_GLES2 +#if defined(BUILD_GLES2) || defined(BUILD_GLES3) return true; #else return false; @@ -289,7 +289,7 @@ static void _GBACoreLoadConfig(struct mCore* core, const struct mCoreConfig* con } static void _GBACoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) { -#ifdef BUILD_GLES2 +#if defined(BUILD_GLES2) || defined(BUILD_GLES3) struct GBACore* gbacore = (struct GBACore*) core; int scale = gbacore->glRenderer.scale; #else @@ -308,7 +308,7 @@ static void _GBACoreSetVideoBuffer(struct mCore* core, color_t* buffer, size_t s } static void _GBACoreSetVideoGLTex(struct mCore* core, unsigned texid) { -#ifdef BUILD_GLES2 +#if defined(BUILD_GLES2) || defined(BUILD_GLES3) struct GBACore* gbacore = (struct GBACore*) core; gbacore->glRenderer.outputTex = texid; #else @@ -442,7 +442,7 @@ static void _GBACoreReset(struct mCore* core) { struct GBACore* gbacore = (struct GBACore*) core; struct GBA* gba = (struct GBA*) core->board; if (gbacore->renderer.outputBuffer -#ifdef BUILD_GLES2 +#if defined(BUILD_GLES2) || defined(BUILD_GLES3) || gbacore->glRenderer.outputTex != (unsigned) -1 #endif ) { @@ -451,7 +451,7 @@ static void _GBACoreReset(struct mCore* core) { renderer = &gbacore->renderer.d; } int fakeBool; -#ifdef BUILD_GLES2 +#if defined(BUILD_GLES2) || defined(BUILD_GLES3) if (gbacore->glRenderer.outputTex != (unsigned) -1 && mCoreConfigGetIntValue(&core->config, "hwaccelVideo", &fakeBool) && fakeBool) { renderer = &gbacore->glRenderer.d; mCoreConfigGetIntValue(&core->config, "videoScale", &gbacore->glRenderer.scale); diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index cde839743..f8b635788 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -46,7 +46,7 @@ static const char* const _vertexShader = "varying vec2 texCoord;\n" "void main() {\n" - " vec2 ratio = insize / 256.0;\n" + " vec2 ratio = insize;\n" " vec2 scaledOffset = offset * dims;\n" " gl_Position = vec4(scaledOffset.x * 2.0 - dims.x, scaledOffset.y * -2.0 + dims.y, 0.0, 1.0);\n" " texCoord = offset * ratio;\n" @@ -91,6 +91,7 @@ static unsigned framecount = 0; static unsigned framecap = 10; static u32 vibrationDeviceHandles[4]; static HidVibrationValue vibrationStop = { .freq_low = 160.f, .freq_high = 320.f }; +static bool usePbo = true; static enum ScreenMode { SM_PA, @@ -110,9 +111,9 @@ static bool initEgl() { EGLConfig config; EGLint numConfigs; static const EGLint attributeList[] = { - EGL_RED_SIZE, 1, - EGL_GREEN_SIZE, 1, - EGL_BLUE_SIZE, 1, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, EGL_NONE }; eglChooseConfig(s_display, attributeList, &config, 1, &numConfigs); @@ -165,6 +166,7 @@ static void _mapKey(struct mInputMap* map, uint32_t binding, int nativeKey, enum } static void _drawStart(void) { + glClearColor(0.f, 0.f, 0.f, 1.f); glClear(GL_COLOR_BUFFER_BIT); } @@ -242,7 +244,15 @@ static void _setup(struct mGUIRunner* runner) { _mapKey(&runner->core->inputMap, AUTO_INPUT, KEY_L, GBA_KEY_L); _mapKey(&runner->core->inputMap, AUTO_INPUT, KEY_R, GBA_KEY_R); - runner->core->setVideoBuffer(runner->core, frameBuffer, 256); + int fakeBool; + if (mCoreConfigGetIntValue(&runner->config, "hwaccelVideo", &fakeBool) && fakeBool && runner->core->supportsFeature(runner->core, mCORE_FEATURE_OPENGL)) { + runner->core->setVideoGLTex(runner->core, tex); + usePbo = false; + } else { + runner->core->setVideoBuffer(runner->core, frameBuffer, 256); + usePbo = true; + } + runner->core->setPeripheral(runner->core, mPERIPH_RUMBLE, &rumble.d); runner->core->setPeripheral(runner->core, mPERIPH_ROTATION, &rotation); runner->core->setAVStream(runner->core, &stream); @@ -281,6 +291,8 @@ static void _gameUnloaded(struct mGUIRunner* runner) { } static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, bool faded) { + glViewport(0, 0, 1280, 720); + glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -315,26 +327,33 @@ static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, glUniform1i(texLocation, 0); glUniform2f(dimsLocation, aspectX, aspectY); - glUniform2f(insizeLocation, width, height); + if (usePbo) { + glUniform2f(insizeLocation, width / 256.f, height / 256.f); + } else { + glUniform2f(insizeLocation, 1, 1); + } if (!faded) { glUniform4f(colorLocation, 1.0f, 1.0f, 1.0f, 1.0f); } else { - glUniform4f(colorLocation, 0.8f, 0.8f, 0.8f, 0.8f); + glUniform4f(colorLocation, 0.8f, 0.8f, 0.8f, 0.8f); } glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glBindVertexArray(0); glUseProgram(0); + glDisable(GL_BLEND); } static void _prepareForFrame(struct mGUIRunner* runner) { - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); - frameBuffer = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, 256 * 256 * 4, GL_MAP_WRITE_BIT); - if (frameBuffer) { - runner->core->setVideoBuffer(runner->core, frameBuffer, 256); + if (usePbo) { + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); + frameBuffer = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, 256 * 256 * 4, GL_MAP_WRITE_BIT); + if (frameBuffer) { + runner->core->setVideoBuffer(runner->core, frameBuffer, 256); + } + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); } - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); } static void _drawFrame(struct mGUIRunner* runner, bool faded) { @@ -346,13 +365,17 @@ static void _drawFrame(struct mGUIRunner* runner, bool faded) { unsigned width, height; runner->core->desiredVideoDimensions(runner->core, &width, &height); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, tex); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, height, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + if (usePbo) { + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + + glBindTexture(GL_TEXTURE_2D, tex); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, height, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + } else { + glBindTexture(GL_TEXTURE_2D, tex); + } _drawTex(runner, width, height, faded); @@ -689,8 +712,42 @@ int main(int argc, char* argv[]) { }, .nStates = 16 }, + { + .title = "GPU-accelerated renderer (experimental, requires game reload)", + .data = "hwaccelVideo", + .submenu = 0, + .state = 0, + .validStates = (const char*[]) { + "Off", + "On", + }, + .nStates = 2 + }, + { + .title = "Hi-res scaling (requires GPU rendering)", + .data = "videoScale", + .submenu = 0, + .state = 0, + .validStates = (const char*[]) { + "1x", + "2x", + "3x", + "4x", + "5x", + "6x", + }, + .stateMappings = (const struct GUIVariant[]) { + GUI_V_U(1), + GUI_V_U(2), + GUI_V_U(3), + GUI_V_U(4), + GUI_V_U(5), + GUI_V_U(6), + }, + .nStates = 6 + }, }, - .nConfigExtra = 2, + .nConfigExtra = 4, .setup = _setup, .teardown = NULL, .gameLoaded = _gameLoaded,