# HG changeset patch # User Michael Pavone # Date 1589084133 25200 # Node ID f3cca4b3f17aed950bd738b0e1b1714972a1bbd4 # Parent 3dd9c68472fb84844363e2f31c5468c243ff5f58 Allow use of NPOT textures as a config option. Useful for some mobile GPUs diff -r 3dd9c68472fb -r f3cca4b3f17a default.cfg --- a/default.cfg Sat May 09 13:15:49 2020 -0700 +++ b/default.cfg Sat May 09 21:15:33 2020 -0700 @@ -296,6 +296,9 @@ gl on #scaling can be linear (for linear interpolation) or nearest (for nearest neighbor) scaling linear + #When off, a 512x512 texture is used for each field, when turned on a smaller texture is used + #turning this on seems to help performance on certain mobile GPUs like Mali + npot_textures off ntsc { overscan { #these values will result in square pixels in H40 mode diff -r 3dd9c68472fb -r f3cca4b3f17a render_sdl.c --- a/render_sdl.c Sat May 09 13:15:49 2020 -0700 +++ b/render_sdl.c Sat May 09 21:15:33 2020 -0700 @@ -273,7 +273,8 @@ } #ifndef DISABLE_OPENGL -static GLuint textures[3], buffers[2], vshader, fshader, program, un_textures[2], un_width, un_height, at_pos; +static GLuint textures[3], buffers[2], vshader, fshader, program, un_textures[2], un_width, un_height, un_texsize, at_pos; +static int tex_width, tex_height; static GLfloat vertex_data_default[] = { -1.0f, -1.0f, @@ -379,6 +380,15 @@ char *scaling = tern_find_path_default(config, "video\0scaling\0", def, TVAL_PTR).ptrval; GLint filter = strcmp(scaling, "linear") ? GL_NEAREST : GL_LINEAR; glGenTextures(3, textures); + def.ptrval = "off"; + char *npot_textures = tern_find_path_default(config, "video\0npot_textures\0", def, TVAL_PTR).ptrval; + if (!strcmp(npot_textures, "on")) { + tex_width = LINEBUF_SIZE; + tex_height = 294; //PAL height with full borders + } else { + tex_width = tex_height = 512; + } + printf("Using %dx%d textures\n", tex_width, tex_height); for (int i = 0; i < 3; i++) { glBindTexture(GL_TEXTURE_2D, textures[i]); @@ -388,7 +398,7 @@ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if (i < 2) { //TODO: Fixme for PAL + invalid display mode - glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, 512, 512, 0, SRC_FORMAT, GL_UNSIGNED_BYTE, texture_buf); + glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, tex_width, tex_height, 0, SRC_FORMAT, GL_UNSIGNED_BYTE, texture_buf); } else { uint32_t blank = 255 << 24; glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, 1, 1, 0, SRC_FORMAT, GL_UNSIGNED_BYTE, &blank); @@ -417,6 +427,7 @@ un_textures[1] = glGetUniformLocation(program, "textures[1]"); un_width = glGetUniformLocation(program, "width"); un_height = glGetUniformLocation(program, "height"); + un_texsize = glGetUniformLocation(program, "texsize"); at_pos = glGetAttribLocation(program, "pos"); } @@ -1377,7 +1388,7 @@ if (num_buffers) { buffer = frame_buffers[--num_buffers]; } else { - buffer = calloc(512*512, sizeof(uint32_t)); + buffer = calloc(tex_width*(tex_height + 1), sizeof(uint32_t)); } SDL_UnlockMutex(free_buffer_mutex); locked_pixels = buffer; @@ -1733,6 +1744,7 @@ glUniform1f(un_width, render_emulated_width()); glUniform1f(un_height, last_height); + glUniform2f(un_texsize, tex_width, tex_height); glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); glVertexAttribPointer(at_pos, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat[2]), (void *)0); diff -r 3dd9c68472fb -r f3cca4b3f17a shaders/crt.f.glsl --- a/shaders/crt.f.glsl Sat May 09 13:15:49 2020 -0700 +++ b/shaders/crt.f.glsl Sat May 09 21:15:33 2020 -0700 @@ -1,5 +1,3 @@ -#version 110 - /* Subtle CRT shader usable in fullscreen - Anaƫl Seghezzi [anael(at)maratis3d.com] This shader is free software distributed under the terms of the GNU General Public License version 3 or higher. This gives you the right to redistribute and/or @@ -10,63 +8,64 @@ #define M_PI 3.14159265358979323846 uniform sampler2D textures[2]; -uniform float width, height; -varying vec2 texcoord; -varying vec2 screencoord; +uniform mediump float width, height; +uniform mediump vec2 texsize; +varying mediump vec2 texcoord; +varying mediump vec2 screencoord; -float nrand(vec2 n) { +mediump float nrand(vec2 n) { return fract(sin(dot(n.xy, vec2(12.9898, 78.233))) * 43758.5453); } -float scanline(vec2 texco) +mediump float scanline(vec2 texco) { - return (1.0 - abs(cos(texco.y * 512.0 * M_PI))); + return (1.0 - abs(cos(texco.y * texsize.y * M_PI))); } -vec2 sharp_coord(vec2 texco, vec2 dim, vec2 sharpness) +mediump vec2 sharp_coord(mediump vec2 texco, mediump vec2 dim, mediump vec2 sharpness) { - vec2 texcoif = texco * dim; - vec2 texcoi = floor(texcoif); - vec2 mu = (texcoif - 0.5) - texcoi; - vec2 mub = pow(abs(mu) * 2.0, sharpness) * sign(mu) * 0.5; + mediump vec2 texcoif = texco * dim; + mediump vec2 texcoi = floor(texcoif); + mediump vec2 mu = (texcoif - 0.5) - texcoi; + mediump vec2 mub = pow(abs(mu) * 2.0, sharpness) * sign(mu) * 0.5; return (texcoi + mub + 0.5) / dim; } void main() { - float v = 1.0 / 512.0; - float yforce = 0.175; - float vign = length(screencoord); + mediump float v = 1.0 / texsize.y; + mediump float yforce = 0.175; + mediump float vign = length(screencoord); // monitor deformation - vec2 monitorcoord = (screencoord + screencoord * vign * 0.025); + mediump vec2 monitorcoord = (screencoord + screencoord * vign * 0.025); if (monitorcoord.x < -1.0 || monitorcoord.y < -1.0 || monitorcoord.x > 1.0 || monitorcoord.y > 1.0) { gl_FragColor = vec4(0.0); return; } - vec2 texco = monitorcoord * vec2(width/1024.0, height/-1024.0) + vec2(width/1024.0, height/1024.0); + mediump vec2 texco = monitorcoord * vec2(0.5*width/texsize.x, -0.5 * height/texsize.y) + vec2(0.5*width/texsize.x, 0.5*height/texsize.y); // mask - float maskx = 1.0 - pow(abs(monitorcoord.x), 200.0); - float masky = 1.0 - pow(abs(-monitorcoord.y), 200.0); - float mask = clamp(maskx * masky, 0.0, 1.0); + mediump float maskx = 1.0 - pow(abs(monitorcoord.x), 200.0); + mediump float masky = 1.0 - pow(abs(-monitorcoord.y), 200.0); + mediump float mask = clamp(maskx * masky, 0.0, 1.0); // sharp texcoord - vec2 texco_sharp0 = sharp_coord(texco, vec2(512.0, 512.0), vec2(4.0, 8.0)); - vec2 texco_sharp1 = sharp_coord(texco - vec2(0.0, 1.0 / 1024.0), vec2(512.0, 512.0), vec2(4.0, 8.0)); + mediump vec2 texco_sharp0 = sharp_coord(texco, texsize, vec2(4.0, 8.0)); + mediump vec2 texco_sharp1 = sharp_coord(texco - vec2(0.0, 0.5 / texsize.y), texsize, vec2(4.0, 8.0)); - vec4 src0 = texture2D(textures[0], texco_sharp0); - vec4 src1 = texture2D(textures[1], texco_sharp1); + mediump vec4 src0 = texture2D(textures[0], texco_sharp0); + mediump vec4 src1 = texture2D(textures[1], texco_sharp1); // interlace mix - float interlace = cos((texco.y * 1024.0) * M_PI); - vec4 src_mix = mix(src0, src1, interlace * 0.5 + 0.5); + mediump float interlace = cos((texco.y * 2.0 * texsize.y) * M_PI); + mediump vec4 src_mix = mix(src0, src1, interlace * 0.5 + 0.5); // blur - vec4 src_blur = mix(texture2D(textures[0], texco), texture2D(textures[1], texco), 0.5); + mediump vec4 src_blur = mix(texture2D(textures[0], texco), texture2D(textures[1], texco), 0.5); #ifdef NO_SCANLINE @@ -75,11 +74,11 @@ #else // multisample scanline with grain // TODO: offset grain with time (needs a "frame" uniform) - float cosy; - cosy = scanline(texco + vec2(0.125, v * (nrand(texcoord + vec2(0.0, 1.0)) * 0.25) + 0.3333)); - cosy += scanline(texco + vec2(0.25, v * (nrand(texcoord + vec2(0.0, 2.0)) * 0.25) + 0.25)); - cosy += scanline(texco + vec2(0.50, v * (nrand(texcoord + vec2(0.0, 3.0)) * 0.25) + 0.6666)); - cosy += scanline(texco + vec2(0.75, v * (nrand(texcoord + vec2(0.0, 4.0)) * 0.25) + 0.75)); + mediump float cosy; + cosy = scanline(texco + vec2(0.125, v * (nrand(texcoord + vec2(0.0, 512.0/texsize.y)) * 0.25) + 512.0*0.3333/texsize.y)); + cosy += scanline(texco + vec2(0.25, v * (nrand(texcoord + vec2(0.0, 1024.0/texsize.y)) * 0.25) + 512.0*0.25/texsize.y)); + cosy += scanline(texco + vec2(0.50, v * (nrand(texcoord + vec2(0.0, 1536.0/texsize.y)) * 0.25) + 512.0*0.6666/texsize.y)); + cosy += scanline(texco + vec2(0.75, v * (nrand(texcoord + vec2(0.0, 2048.0/texsize.y)) * 0.25) + 512.0*0.75/texsize.y)); cosy *= 0.25; // final scanline + burn diff -r 3dd9c68472fb -r f3cca4b3f17a shaders/crt.v.glsl --- a/shaders/crt.v.glsl Sat May 09 13:15:49 2020 -0700 +++ b/shaders/crt.v.glsl Sat May 09 21:15:33 2020 -0700 @@ -1,13 +1,13 @@ -#version 110 attribute vec2 pos; -varying vec2 texcoord; -varying vec2 screencoord; -uniform float width, height; +varying mediump vec2 texcoord; +varying mediump vec2 screencoord; +uniform mediump float width, height; +uniform mediump vec2 texsize; void main() { gl_Position = vec4(pos, 0.0, 1.0); - texcoord = sign(pos) * vec2(width/1024.0, height/-1024.0) + vec2(width/1024.0, height/1024.0); + texcoord = sign(pos) * vec2(0.5*width/texsize.x, -0.5*height/texsize.y) + vec2(0.5*width/texsize.x, 0.5*height/texsize.y); screencoord = sign(pos); } \ No newline at end of file diff -r 3dd9c68472fb -r f3cca4b3f17a shaders/default.f.glsl --- a/shaders/default.f.glsl Sat May 09 13:15:49 2020 -0700 +++ b/shaders/default.f.glsl Sat May 09 21:15:33 2020 -0700 @@ -1,15 +1,16 @@ uniform sampler2D textures[2]; +uniform mediump vec2 texsize; varying mediump vec2 texcoord; void main() { - mediump vec2 modifiedCoord0 = vec2(texcoord.x, (floor(texcoord.y * 512.0 + 0.25) + 0.5)/512.0); - mediump vec2 modifiedCoord1 = vec2(texcoord.x, (floor(texcoord.y * 512.0 - 0.25) + 0.5)/512.0); + mediump vec2 modifiedCoord0 = vec2(texcoord.x, (floor(texcoord.y * texsize.y + 0.25) + 0.5)/texsize.y); + mediump vec2 modifiedCoord1 = vec2(texcoord.x, (floor(texcoord.y * texsize.y - 0.25) + 0.5)/texsize.y); gl_FragColor = mix( texture2D(textures[1], modifiedCoord1), texture2D(textures[0], modifiedCoord0), - (sin(texcoord.y * 1024.0 * 3.14159265359) + 1.0) * 0.5 + (sin(texcoord.y * texsize.y * 6.283185307) + 1.0) * 0.5 ); } diff -r 3dd9c68472fb -r f3cca4b3f17a shaders/default.v.glsl --- a/shaders/default.v.glsl Sat May 09 13:15:49 2020 -0700 +++ b/shaders/default.v.glsl Sat May 09 21:15:33 2020 -0700 @@ -2,9 +2,10 @@ attribute vec2 pos; varying mediump vec2 texcoord; uniform mediump float width, height; +uniform mediump vec2 texsize; void main() { gl_Position = vec4(pos, 0.0, 1.0); - texcoord = sign(pos) * vec2(width / 1024.0, height / -1024.0) + vec2(width / 1024.0, height / 1024.0); + texcoord = sign(pos) * vec2(0.5 * width / texsize.x, -0.5 * height / texsize.y) + vec2(0.5 * width / texsize.x, 0.5 * height / texsize.y); } diff -r 3dd9c68472fb -r f3cca4b3f17a shaders/sharp.f.glsl --- a/shaders/sharp.f.glsl Sat May 09 13:15:49 2020 -0700 +++ b/shaders/sharp.f.glsl Sat May 09 21:15:33 2020 -0700 @@ -1,20 +1,18 @@ uniform sampler2D textures[2]; +uniform mediump vec2 texsize; varying mediump vec2 texcoord; void main() { - mediump float x0 = (floor(texcoord.x * 512.0 - 0.25) + 0.5)/512.0; - mediump float x1 = (floor(texcoord.x * 512.0 + 0.25) + 0.5)/512.0; - mediump float y0 = (floor(texcoord.y * 512.0 + 0.25) + 0.5)/512.0; - mediump float y1 = (floor(texcoord.y * 512.0 - 0.25) + 0.5)/512.0; + mediump float x0 = (floor(texcoord.x * texsize.x - 0.25) + 0.5)/texsize.x; + mediump float x1 = (floor(texcoord.x * texsize.x + 0.25) + 0.5)/texsize.x; + mediump float y0 = (floor(texcoord.y * texsize.y + 0.25) + 0.5)/texsize.y; + mediump float y1 = (floor(texcoord.y * texsize.y - 0.25) + 0.5)/texsize.y; - - mediump vec2 modifiedCoord0 = vec2(texcoord.x, (floor(texcoord.y * 512.0 + 0.25) + 0.5)/512.0); - mediump vec2 modifiedCoord1 = vec2(texcoord.x, (floor(texcoord.y * 512.0 - 0.25) + 0.5)/512.0); - mediump float ymix = (sin(texcoord.y * 1024.0 * 3.14159265359) + 1.0) * 0.5; - mediump float xmix = (sin(texcoord.x * 1024.0 * 3.14159265359) + 1.0) * 0.5; + mediump float ymix = (sin(texcoord.y * texsize.y * 6.283185307) + 1.0) * 0.5; + mediump float xmix = (sin(texcoord.x * texsize.x * 6.283185307) + 1.0) * 0.5; gl_FragColor = mix( mix( texture2D(textures[1], vec2(x0, y1)),