all repos — mgba @ b5ca2b89e22417994edc7754a23452da1f6be647

mGBA Game Boy Advance Emulator

GBA Video: Convert OpenGL VRAM texture to integer
Vicki Pfau vi@endrift.com
Sat, 26 Sep 2020 16:29:47 -0700
commit

b5ca2b89e22417994edc7754a23452da1f6be647

parent

e11dc3fad05bd655228c078147d5af2ec5733c1e

2 files changed, 29 insertions(+), 33 deletions(-)

jump to
M CHANGESCHANGES

@@ -81,6 +81,7 @@ - GB: Allow pausing event loop while CPU is blocked

- GB: Add support for sleep and shutdown callbacks - GBA: Allow pausing event loop while CPU is blocked - GBA BIOS: Division by zero should emit a FATAL error + - GBA Video: Convert OpenGL VRAM texture to integer - Debugger: Keep track of global cycle count - FFmpeg: Add looping option for GIF/APNG - mGUI: Show battery percentage
M src/gba/renderers/gl.csrc/gba/renderers/gl.c

@@ -84,8 +84,8 @@

static const char* const _renderTile16 = "vec4 renderTile(int tile, int paletteId, ivec2 localCoord) {\n" " int address = charBase + tile * 16 + (localCoord.x >> 2) + (localCoord.y << 1);\n" - " vec4 halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0);\n" - " int entry = int(halfrow[3 - (localCoord.x & 3)] * 15.9);\n" + " int halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0).r;\n" + " int entry = (halfrow >> (4 * (localCoord.x & 3))) & 15;\n" " if (entry == 0) {\n" " discard;\n" " }\n"

@@ -97,13 +97,12 @@

static const char* const _renderTile256 = "vec4 renderTile(int tile, int paletteId, ivec2 localCoord) {\n" " int address = charBase + tile * 32 + (localCoord.x >> 1) + (localCoord.y << 2);\n" - " vec4 halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0);\n" - " int entry = int(halfrow[3 - 2 * (localCoord.x & 1)] * 15.9);\n" - " int pal2 = int(halfrow[2 - 2 * (localCoord.x & 1)] * 15.9);\n" - " if ((pal2 | entry) == 0) {\n" + " int halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0).r;\n" + " int entry = (halfrow >> (8 * (localCoord.x & 1))) & 255;\n" + " if (entry == 0) {\n" " discard;\n" " }\n" - " int paletteEntry = palette[pal2 * 16 + entry];\n" + " int paletteEntry = palette[entry];\n" " vec4 color = vec4(PALETTE_ENTRY(paletteEntry), 1.);\n" " return color;\n" "}";

@@ -123,7 +122,7 @@ };

static const char* const _renderMode0 = "in vec2 texCoord;\n" - "uniform sampler2D vram;\n" + "uniform isampler2D vram;\n" "uniform int palette[256];\n" "uniform int screenBase;\n" "uniform int charBase;\n"

@@ -158,16 +157,15 @@ " wrap = coord & 256;\n"

" coord &= 255;\n" " coord.y += wrap.x + wrap.y * doty;\n" " int mapAddress = screenBase + (coord.x >> 3) + (coord.y >> 3) * 32;\n" - " vec4 map = texelFetch(vram, ivec2(mapAddress & 255, mapAddress >> 8), 0);\n" - " int tileFlags = int(map.g * 15.9);\n" - " if ((tileFlags & 4) == 4) {\n" + " int map = texelFetch(vram, ivec2(mapAddress & 255, mapAddress >> 8), 0).r;\n" + " if ((map & 1024) == 1024) {\n" " coord.x ^= 7;\n" " }\n" - " if ((tileFlags & 8) == 8) {\n" + " if ((map & 2048) == 2048) {\n" " coord.y ^= 7;\n" " }\n" - " int tile = int(map.a * 15.9) + int(map.b * 15.9) * 16 + (tileFlags & 0x3) * 256;\n" - " color = renderTile(tile, int(map.r * 15.9), coord & 7);\n" + " int tile = map & 1023;\n" + " color = renderTile(tile, map >> 12, coord & 7);\n" "}"; static const char* const _fetchTileOverflow =

@@ -225,7 +223,7 @@ "}\n";

static const char* const _renderMode2 = "in vec2 texCoord;\n" - "uniform sampler2D vram;\n" + "uniform isampler2D vram;\n" "uniform int palette[256];\n" "uniform int screenBase;\n" "uniform int charBase;\n"

@@ -242,16 +240,15 @@

"vec4 renderTile(ivec2 coord) {\n" " int map = (coord.x >> 11) + (((coord.y >> 7) & 0x7F0) << size);\n" " int mapAddress = screenBase + (map >> 1);\n" - " vec4 twomaps = texelFetch(vram, ivec2(mapAddress & 255, mapAddress >> 8), 0);\n" - " int tile = int(twomaps[3 - 2 * (map & 1)] * 15.9) + int(twomaps[2 - 2 * (map & 1)] * 15.9) * 16;\n" + " int twomaps = texelFetch(vram, ivec2(mapAddress & 255, mapAddress >> 8), 0).r;\n" + " int tile = (twomaps >> (8 * (map & 1))) & 255;\n" " int address = charBase + tile * 32 + ((coord.x >> 9) & 3) + ((coord.y >> 6) & 0x1C);\n" - " vec4 halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0);\n" - " int entry = int(halfrow[3 - ((coord.x >> 7) & 2)] * 15.9);\n" - " int pal2 = int(halfrow[2 - ((coord.x >> 7) & 2)] * 15.9);\n" - " if ((pal2 | entry) == 0) {\n" + " int halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0).r;\n" + " int entry = (halfrow >> (8 * ((coord.x >> 8) & 1))) & 255;\n" + " if (entry == 0) {\n" " discard;\n" " }\n" - " int paletteEntry = palette[pal2 * 16 + entry];\n" + " int paletteEntry = palette[entry];\n" " vec4 color = vec4(PALETTE_ENTRY(paletteEntry), 1.);\n" " return color;\n" "}\n"

@@ -294,7 +291,7 @@ };

static const char* const _renderMode35 = "in vec2 texCoord;\n" - "uniform sampler2D vram;\n" + "uniform isampler2D vram;\n" "uniform int charBase;\n" "uniform ivec2 size;\n" "uniform ivec4 transform[160];\n"

@@ -333,9 +330,8 @@ " if (coord.y < 0 || coord.y >= (size.y << 8)) {\n"

" discard;\n" " }\n" " int address = charBase + (coord.x >> 8) + (coord.y >> 8) * size.x;\n" - " ivec4 entry = ivec4(texelFetch(vram, ivec2(address & 255, address >> 8), 0) * 15.9);\n" - " int sixteen = (entry.x << 12) | (entry.y << 8) | (entry.z << 4) | entry.w;\n" - " color = vec4(float(sixteen & 0x1F) / 31., float((sixteen >> 5) & 0x1F) / 31., float((sixteen >> 10) & 0x1F) / 31., 1.);\n" + " int entry = texelFetch(vram, ivec2(address & 255, address >> 8), 0).r;\n" + " color = vec4(float(entry & 0x1F) / 31., float((entry >> 5) & 0x1F) / 31., float((entry >> 10) & 0x1F) / 31., 1.);\n" "}"; static const struct GBAVideoGLUniform _uniformsMode4[] = {

@@ -354,7 +350,7 @@ };

static const char* const _renderMode4 = "in vec2 texCoord;\n" - "uniform sampler2D vram;\n" + "uniform isampler2D vram;\n" "uniform int palette[256];\n" "uniform int charBase;\n" "uniform ivec2 size;\n"

@@ -394,9 +390,8 @@ " if (coord.y < 0 || coord.y >= (size.y << 8)) {\n"

" discard;\n" " }\n" " int address = charBase + (coord.x >> 8) + (coord.y >> 8) * size.x;\n" - " vec4 twoEntries = texelFetch(vram, ivec2((address >> 1) & 255, address >> 9), 0);\n" - " ivec2 entry = ivec2(twoEntries[3 - 2 * (address & 1)] * 15.9, twoEntries[2 - 2 * (address & 1)] * 15.9);\n" - " int paletteEntry = palette[entry.y * 16 + entry.x];\n" + " int twoEntries = texelFetch(vram, ivec2((address >> 1) & 255, address >> 9), 0).r;\n" + " int paletteEntry = palette[(twoEntries >> (8 * (address & 1)) & 255)];\n" " color = vec4(PALETTE_ENTRY(paletteEntry), 1.);\n" "}";

@@ -419,7 +414,7 @@ };

static const char* const _renderObj = "in vec2 texCoord;\n" - "uniform sampler2D vram;\n" + "uniform isampler2D vram;\n" "uniform int palette[256];\n" "uniform int charBase;\n" "uniform int stride;\n"

@@ -781,7 +776,7 @@ glGenTextures(1, &glRenderer->vramTex);

glBindTexture(GL_TEXTURE_2D, glRenderer->vramTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, 256, 192, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, 256, 192, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, 0); glGenBuffers(1, &glRenderer->vbo); glBindBuffer(GL_ARRAY_BUFFER, glRenderer->vbo);

@@ -1355,7 +1350,7 @@ glBindTexture(GL_TEXTURE_2D, glRenderer->vramTex);

for (i = 0; i < 25; ++i) { if (!(glRenderer->vramDirty & (1 << i))) { if (first >= 0) { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 8 * first, 256, 8 * (i - first), GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, &glRenderer->d.vram[2048 * first]); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 8 * first, 256, 8 * (i - first), GL_RED_INTEGER, GL_UNSIGNED_SHORT, &glRenderer->d.vram[2048 * first]); first = -1; } } else if (first < 0) {