Switch: Experimental support for hi-res mode

This commit is contained in:
Vicki Pfau 2019-05-26 19:44:21 -07:00
parent a64c38d314
commit 585563eed7
2 changed files with 84 additions and 27 deletions

View File

@ -18,7 +18,7 @@
#ifndef DISABLE_THREADING
#include <mgba/feature/thread-proxy.h>
#endif
#ifdef BUILD_GLES2
#if defined(BUILD_GLES2) || defined(BUILD_GLES3)
#include <mgba/internal/gba/renderers/gl.h>
#endif
#include <mgba/internal/gba/renderers/proxy.h>
@ -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);

View File

@ -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,