From 4d427c9d2dea9ff0b965c3ffbbecc5e1cb40a01b Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 14 May 2019 17:45:16 +0200 Subject: BAHAHAHAHAHA --- src/GPU3D_OpenGL43.cpp | 408 +++++++++++++++++++++++++++++-------------------- 1 file changed, 242 insertions(+), 166 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index d792030..57a80f1 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -168,206 +168,221 @@ flat in uvec3 fPolygonAttr; layout(location=0) out vec4 oColor; layout(location=1) out uvec3 oAttr; -vec4 TextureLookup(ivec2 st) +int TexcoordWrap(int c, int maxc, uint mode) { - uint attr = fPolygonAttr.y; - uint paladdr = fPolygonAttr.z; - - float alpha0; - if ((attr & (1<<29)) != 0) alpha0 = 0.0; - else alpha0 = 1.0; - - int tw = 8 << int((attr >> 20) & 0x7); - int th = 8 << int((attr >> 23) & 0x7); - - int vramaddr = int(attr & 0xFFFF) << 3; - - if ((attr & (1<<16)) != 0) + if ((mode & (1<<0)) != 0) { - if ((attr & (1<<18)) != 0) - { - if ((st.x & tw) != 0) - st.x = (tw-1) - (st.x & (tw-1)); - else - st.x = (st.x & (tw-1)); - } + if ((mode & (1<<2)) != 0 && (c & maxc) != 0) + return (maxc-1) - (c & (maxc-1)); else - st.x &= (tw-1); + return (c & (maxc-1)); } else - st.x = clamp(st.x, 0, tw-1); + return clamp(c, 0, maxc-1); +} - if ((attr & (1<<17)) != 0) - { - if ((attr & (1<<19)) != 0) - { - if ((st.y & th) != 0) - st.y = (th-1) - (st.y & (th-1)); - else - st.y = (st.y & (th-1)); - } - else - st.y &= (th-1); - } - else - st.y = clamp(st.y, 0, th-1); +vec4 TextureFetch_A3I5(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - uint type = (attr >> 26) & 0x7; - if (type == 1) - { - vramaddr += ((st.y * tw) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); + addr.x += ((st.y * st.z) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - pixel.a = (pixel.r & 0xE0); - pixel.a = (pixel.a >> 3) + (pixel.a >> 6); - pixel.r &= 0x1F; + pixel.a = (pixel.r & 0xE0); + pixel.a = (pixel.a >> 3) + (pixel.a >> 6); + pixel.r &= 0x1F; - paladdr = (paladdr << 3) + pixel.r; - vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, float(pixel.a)/31.0); - } - else if (type == 2) - { - vramaddr += ((st.y * tw) + st.x) >> 2; - uvec4 pixel = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); - pixel.r >>= (2 * (st.x & 3)); - pixel.r &= 0x03; + return vec4(color.rgb, float(pixel.a)/31.0); +} - paladdr = (paladdr << 2) + pixel.r; - vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); +vec4 TextureFetch_I2(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); - } - else if (type == 3) - { - vramaddr += ((st.y * tw) + st.x) >> 1; - uvec4 pixel = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); - if ((st.x & 1) != 0) pixel.r >>= 4; - else pixel.r &= 0x0F; + addr.x += ((st.y * st.z) + st.x) >> 2; + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + pixel.r >>= (2 * (st.x & 3)); + pixel.r &= 0x03; - paladdr = (paladdr << 3) + pixel.r; - vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + addr.y = (addr.y << 2) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); - } - else if (type == 4) - { - vramaddr += ((st.y * tw) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); +} - paladdr = (paladdr << 3) + pixel.r; - vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); +vec4 TextureFetch_I4(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); - } - else if (type == 5) - { - vramaddr += ((st.y & 0x3FC) * (tw>>2)) + (st.x & 0x3FC) + (st.y & 0x3); - uvec4 p = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); - uint val = (p.r >> (2 * (st.x & 0x3))) & 0x3; + addr.x += ((st.y * st.z) + st.x) >> 1; + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + if ((st.x & 1) != 0) pixel.r >>= 4; + else pixel.r &= 0x0F; + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); +} + +vec4 TextureFetch_I8(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); +} + +vec4 TextureFetch_Compressed(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y & 0x3FC) * (st.z>>2)) + (st.x & 0x3FC) + (st.y & 0x3); + uvec4 p = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + uint val = (p.r >> (2 * (st.x & 0x3))) & 0x3; - int slot1addr = 0x20000 + ((vramaddr & 0x1FFFC) >> 1); - if (vramaddr >= 0x40000) slot1addr += 0x10000; + int slot1addr = 0x20000 + ((addr.x & 0x1FFFC) >> 1); + if (addr.x >= 0x40000) slot1addr += 0x10000; - uint palinfo; - p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); - palinfo = p.r; - slot1addr++; - p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); - palinfo |= (p.r << 8); + uint palinfo; + p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); + palinfo = p.r; + slot1addr++; + p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); + palinfo |= (p.r << 8); - paladdr = (paladdr << 3) + ((palinfo & 0x3FFF) << 1); - palinfo >>= 14; + addr.y = (addr.y << 3) + ((int(palinfo) & 0x3FFF) << 1); + palinfo >>= 14; - if (val == 0) + if (val == 0) + { + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (val == 1) + { + addr.y++; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (val == 2) + { + if (palinfo == 1) { - vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb + color1.rgb) / 2.0, 1.0); + } + else if (palinfo == 3) + { + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb*5.0 + color1.rgb*3.0) / 8.0, 1.0); + } + else + { + addr.y += 2; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); return vec4(color.rgb, 1.0); } - else if (val == 1) + } + else + { + if (palinfo == 2) { - paladdr++; - vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + addr.y += 3; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); return vec4(color.rgb, 1.0); } - else if (val == 2) + else if (palinfo == 3) { - if (palinfo == 1) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - paladdr++; - vec4 color1 = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - return vec4((color0.rgb + color1.rgb) / 2.0, 1.0); - } - else if (palinfo == 3) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - paladdr++; - vec4 color1 = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - return vec4((color0.rgb*5.0 + color1.rgb*3.0) / 8.0, 1.0); - } - else - { - paladdr += 2; - vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - return vec4(color.rgb, 1.0); - } + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb*3.0 + color1.rgb*5.0) / 8.0, 1.0); } else { - if (palinfo == 2) - { - paladdr += 3; - vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - return vec4(color.rgb, 1.0); - } - else if (palinfo == 3) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - paladdr++; - vec4 color1 = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - return vec4((color0.rgb*3.0 + color1.rgb*5.0) / 8.0, 1.0); - } - else - { - return vec4(0.0); - } + return vec4(0.0); } } - else if (type == 6) - { - vramaddr += ((st.y * tw) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); +} - pixel.a = (pixel.r & 0xF8) >> 3; - pixel.r &= 0x07; +vec4 TextureFetch_A5I3(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - paladdr = (paladdr << 3) + pixel.r; - vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + addr.x += ((st.y * st.z) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - return vec4(color.rgb, float(pixel.a)/31.0); - } - else - { - vramaddr += ((st.y * tw) + st.x) << 1; - uvec4 pixelL = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); - vramaddr++; - uvec4 pixelH = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); - - vec4 color; - color.r = float(pixelL.r & 0x1F) / 31.0; - color.g = float((pixelL.r >> 5) | ((pixelH.r & 0x03) << 3)) / 31.0; - color.b = float((pixelH.r & 0x7C) >> 2) / 31.0; - color.a = float(pixelH.r >> 7); - - return color; - } + pixel.a = (pixel.r & 0xF8) >> 3; + pixel.r &= 0x07; + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, float(pixel.a)/31.0); } -vec4 TextureLookup_Nearest(vec2 texcoord) +vec4 TextureFetch_Direct(ivec2 addr, ivec4 st, uint wrapmode) { - return TextureLookup(ivec2(texcoord)); + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x) << 1; + uvec4 pixelL = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + addr.x++; + uvec4 pixelH = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + + vec4 color; + color.r = float(pixelL.r & 0x1F) / 31.0; + color.g = float((pixelL.r >> 5) | ((pixelH.r & 0x03) << 3)) / 31.0; + color.b = float((pixelH.r & 0x7C) >> 2) / 31.0; + color.a = float(pixelH.r >> 7); + + return color; +} + +vec4 TextureLookup_Nearest(vec2 st) +{ + uint attr = fPolygonAttr.y; + uint paladdr = fPolygonAttr.z; + + float alpha0; + if ((attr & (1<<29)) != 0) alpha0 = 0.0; + else alpha0 = 1.0; + + int tw = 8 << int((attr >> 20) & 0x7); + int th = 8 << int((attr >> 23) & 0x7); + ivec4 st_full = ivec4(ivec2(st), tw, th); + + ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); + uint wrapmode = attr >> 16; + + uint type = (attr >> 26) & 0x7; + if (type == 5) return TextureFetch_Compressed(vramaddr, st_full, wrapmode); + else if (type == 2) return TextureFetch_I2 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 3) return TextureFetch_I4 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 4) return TextureFetch_I8 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 1) return TextureFetch_A3I5 (vramaddr, st_full, wrapmode); + else if (type == 6) return TextureFetch_A5I3 (vramaddr, st_full, wrapmode); + else return TextureFetch_Direct (vramaddr, st_full, wrapmode); } vec4 TextureLookup_Linear(vec2 texcoord) @@ -375,10 +390,71 @@ vec4 TextureLookup_Linear(vec2 texcoord) ivec2 intpart = ivec2(texcoord); vec2 fracpart = fract(texcoord); - vec4 A = TextureLookup(intpart); - vec4 B = TextureLookup(intpart + ivec2(1,0)); - vec4 C = TextureLookup(intpart + ivec2(0,1)); - vec4 D = TextureLookup(intpart + ivec2(1,1)); + uint attr = fPolygonAttr.y; + uint paladdr = fPolygonAttr.z; + + float alpha0; + if ((attr & (1<<29)) != 0) alpha0 = 0.0; + else alpha0 = 1.0; + + int tw = 8 << int((attr >> 20) & 0x7); + int th = 8 << int((attr >> 23) & 0x7); + ivec4 st_full = ivec4(intpart, tw, th); + + ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); + uint wrapmode = attr >> 16; + + vec4 A, B, C, D; + uint type = (attr >> 26) & 0x7; + if (type == 5) + { + A = TextureFetch_Compressed(vramaddr, st_full , wrapmode); + B = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_Compressed(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else if (type == 2) + { + A = TextureFetch_I2(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I2(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I2(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I2(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 3) + { + A = TextureFetch_I4(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I4(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I4(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I4(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 4) + { + A = TextureFetch_I8(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I8(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I8(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I8(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 1) + { + A = TextureFetch_A3I5(vramaddr, st_full , wrapmode); + B = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_A3I5(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else if (type == 6) + { + A = TextureFetch_A5I3(vramaddr, st_full , wrapmode); + B = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_A5I3(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else + { + A = TextureFetch_Direct(vramaddr, st_full , wrapmode); + B = TextureFetch_Direct(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_Direct(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_Direct(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } float fx = fracpart.x; vec4 AB; -- cgit v1.2.3