1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-02 09:03:37 +00:00

Delay texture coordinate normalization. Adapt texture filter to texture engine.

This commit is contained in:
S2S 2020-04-18 18:20:17 +02:00 committed by Sergey Lipskiy
parent a405ad8659
commit 4834359ec1
8 changed files with 248 additions and 324 deletions

View File

@ -45,6 +45,9 @@ void RDRAMtoColorBuffer::init()
m_pTexture->height = 580;
m_pTexture->textureBytes = m_pTexture->width * m_pTexture->height * fbTexFormats.colorFormatBytes;
m_pTexture->hdRatioS = 1.0f;
m_pTexture->hdRatioT = 1.0f;
Context::InitTextureParams initParams;
initParams.handle = m_pTexture->name;
initParams.width = m_pTexture->width;

View File

@ -106,6 +106,8 @@ void _initFrameBufferTexture(u32 _address, u16 _width, u16 _height, f32 _scale,
_pTexture->mirrorS = 0;
_pTexture->mirrorT = 0;
_pTexture->textureBytes = _pTexture->width * _pTexture->height;
_pTexture->hdRatioS = _scale;
_pTexture->hdRatioT = _scale;
if (_size > G_IM_SIZ_8b)
_pTexture->textureBytes *= fbTexFormats.colorFormatBytes;
else
@ -385,6 +387,8 @@ bool FrameBuffer::_initSubTexture(u32 _t)
m_pSubTexture->clampT = pTile->clampt;
m_pSubTexture->offsetS = 0.0f;
m_pSubTexture->offsetT = 0.0f;
m_pSubTexture->hdRatioS = m_pTexture->hdRatioS;
m_pSubTexture->hdRatioT = m_pTexture->hdRatioT;
_setAndAttachTexture(m_SubFBO, m_pSubTexture, _t, false);

View File

@ -308,9 +308,9 @@ public:
" vec2 texCoordOut = texCoord*uCacheShiftScale[idx]; \n"
" texCoordOut -= uTexOffset[idx]; \n"
" texCoordOut += uCacheOffset[idx]; \n"
" if (uTextureFilterMode != 0 && uCacheFrameBuffer[idx] == 0)\n"
" texCoordOut += vec2(0.5); \n"
" return texCoordOut* uCacheScale[idx]; \n"
" if (uTextureFilterMode != 0 && uCacheFrameBuffer[idx] != 0) \n"
" texCoordOut -= vec2(0.5); \n"
" return texCoordOut * uCacheScale[idx]; \n"
"} \n"
" \n"
"void main() \n"
@ -856,14 +856,16 @@ public:
"uniform lowp int uDepthSource; \n"
"uniform highp float uPrimDepth; \n"
"uniform mediump vec2 uScreenScale; \n"
"uniform highp vec4 uTexClamp0; \n"
"uniform highp vec4 uTexClamp1; \n"
"uniform highp vec2 uTexClamp0; \n"
"uniform highp vec2 uTexClamp1; \n"
"uniform highp vec2 uTexWrap0; \n"
"uniform highp vec2 uTexWrap1; \n"
"uniform lowp vec2 uTexMirror0; \n"
"uniform lowp vec2 uTexMirror1; \n"
"uniform highp vec2 uTexScale0; \n"
"uniform highp vec2 uTexScale1; \n"
"uniform lowp vec2 uTexWrapEn0; \n"
"uniform lowp vec2 uTexWrapEn1; \n"
"uniform lowp vec2 uTexMirrorEn0; \n"
"uniform lowp vec2 uTexMirrorEn1; \n"
"uniform lowp vec2 uTexClampEn0; \n"
"uniform lowp vec2 uTexClampEn1; \n"
"uniform lowp int uScreenSpaceTriangle; \n"
"highp vec2 texCoord0; \n"
"highp vec2 texCoord1; \n"
@ -1072,25 +1074,15 @@ public:
}
};
class ShaderFragmentHeaderClampWrapMirror : public ShaderPart
{
public:
ShaderFragmentHeaderClampWrapMirror(const opengl::GLInfo & _glinfo)
{
m_part =
"highp vec2 clampWrapMirror(in highp vec2 vTexCoord, \n"
" in highp vec4 vClamp, in highp vec2 vWrap, \n"
" in lowp vec2 vMirror, in highp vec2 vOffset); \n"
;
}
};
class ShaderFragmentHeaderTextureEngine : public ShaderPart
{
public:
ShaderFragmentHeaderTextureEngine(const opengl::GLInfo & _glinfo)
{
m_part =
"highp vec2 clampWrapMirror(in highp vec2 vTexCoord, \n"
" in highp vec2 vWrap, in highp vec2 vClamp, \n"
" in lowp vec2 vClampEn, in lowp vec2 vMirrorEn ); \n"
"lowp vec2[5] textureEngine0(in highp vec2 texCoord); \n"
"lowp vec2[5] textureEngine1(in highp vec2 texCoord); \n"
;
@ -1111,7 +1103,7 @@ public:
(g_cycleType == G_CYC_COPY || g_textureConvert.useTextureFiltering()))
{
shader <<
"lowp vec4 readTexMS(in lowp sampler2DMS mstex, in highp vec2 texCoord, in lowp int fbMonochrome, in lowp int fbFixedAlpha);\n";
"lowp vec4 readTexMS(in lowp sampler2DMS mstex, in highp vec2[5] tcData, in lowp int fbMonochrome, in lowp int fbFixedAlpha);\n";
}
}
@ -1166,50 +1158,45 @@ public:
void write(std::stringstream & shader) const override
{
std::string shaderPart;
if (!m_glinfo.isGLES2) {
if (g_textureConvert.useTextureFiltering()) {
shaderPart += "uniform lowp int uTextureFilterMode; \n";
shaderPart += "#define TEX_NEAREST(name, tex, tcData) \\\n"
"{ \\\n"
" name = texelFetch(tex, ivec2(tcData[0]), 0); \\\n"
"} \n"
;
switch (config.texture.bilinearMode + config.texture.enableHalosRemoval * 2) {
case BILINEAR_3POINT:
// 3 point texture filtering.
// Original author: ArthurCarvalho
// GLSL implementation: twinaphex, mupen64plus-libretro project.
shaderPart +=
"#define TEX_OFFSET(off, tex, texCoord) texture(tex, texCoord - (off)/texSize) \n"
"#define TEX_FILTER(name, tex, texCoord) \\\n"
"#define TEX_FILTER(name, tex, tcData) \\\n"
" { \\\n"
" mediump vec2 texSize = vec2(textureSize(tex,0)); \\\n"
" mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \\\n"
" offset -= step(1.0, offset.x + offset.y); \\\n"
" lowp vec4 c0 = TEX_OFFSET(offset, tex, texCoord); \\\n"
" lowp vec4 c1 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y), tex, texCoord); \\\n"
" lowp vec4 c2 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y)), tex, texCoord); \\\n"
" name = c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0); \\\n"
" lowp float bottomRightTri = step(1.0, tcData[4].s + tcData[4].t); \\\n"
" lowp vec4 c00 = texelFetch(tex, ivec2(tcData[0]), 0); \\\n"
" lowp vec4 c01 = texelFetch(tex, ivec2(tcData[1]), 0); \\\n"
" lowp vec4 c10 = texelFetch(tex, ivec2(tcData[2]), 0); \\\n"
" lowp vec4 c11 = texelFetch(tex, ivec2(tcData[3]), 0); \\\n"
" lowp vec4 c0 = c00 + tcData[4].s*(c10-c00) + tcData[4].t*(c01-c00); \\\n"
" lowp vec4 c1 = c11 + (1.0-tcData[4].s)*(c01-c11) + (1.0-tcData[4].t)*(c10-c11); \\\n"
" name = c0 + bottomRightTri * (c1-c0); \\\n"
" } \n"
;
break;
case BILINEAR_STANDARD:
shaderPart +=
"#define TEX_OFFSET(off, tex, texCoord) texture(tex, texCoord - (off)/texSize) \n"
"#define TEX_FILTER(name, tex, texCoord) \\\n"
"#define TEX_FILTER(name, tex, tcData) \\\n"
"{ \\\n"
" mediump vec2 texSize = vec2(textureSize(tex,0)); \\\n"
" mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \\\n"
" offset -= step(1.0, offset.x + offset.y); \\\n"
" lowp vec4 zero = vec4(0.0); \\\n"
" \\\n"
" lowp vec4 p0q0 = TEX_OFFSET(offset, tex, texCoord); \\\n"
" lowp vec4 p1q0 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y), tex, texCoord); \\\n"
" \\\n"
" lowp vec4 p0q1 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y)), tex, texCoord); \\\n"
" lowp vec4 p1q1 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y - sign(offset.y)), tex, texCoord); \\\n"
" \\\n"
" mediump vec2 interpolationFactor = abs(offset); \\\n"
" lowp vec4 pInterp_q0 = mix( p0q0, p1q0, interpolationFactor.x ); \\\n" // Interpolates top row in X direction.
" lowp vec4 pInterp_q1 = mix( p0q1, p1q1, interpolationFactor.x ); \\\n" // Interpolates bottom row in X direction.
" name = mix( pInterp_q0, pInterp_q1, interpolationFactor.y ); \\\n" // Interpolate in Y direction.
" lowp vec4 c00 = texelFetch(tex, ivec2(tcData[0]), 0); \\\n"
" lowp vec4 c01 = texelFetch(tex, ivec2(tcData[1]), 0); \\\n"
" lowp vec4 c10 = texelFetch(tex, ivec2(tcData[2]), 0); \\\n"
" lowp vec4 c11 = texelFetch(tex, ivec2(tcData[3]), 0); \\\n"
" lowp vec4 c0 = c00 + tcData[4].s * (c10-c00); \\\n"
" lowp vec4 c1 = c01 + tcData[4].s * (c11-c01); \\\n"
" name = c0 + tcData[4].t * (c1-c0); \\\n"
"} \n"
;
break;
@ -1218,89 +1205,60 @@ public:
// Original author: ArthurCarvalho
// GLSL implementation: twinaphex, mupen64plus-libretro project.
shaderPart +=
"#define TEX_OFFSET(off, tex, texCoord) texture(tex, texCoord - (off)/texSize) \n"
"#define TEX_FILTER(name, tex, texCoord) \\\n"
"#define TEX_FILTER(name, tex, tcData) \\\n"
"{ \\\n"
" mediump vec2 texSize = vec2(textureSize(tex,0)); \\\n"
" mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \\\n"
" offset -= step(1.0, offset.x + offset.y); \\\n"
" lowp vec4 c0 = TEX_OFFSET(offset, tex, texCoord); \\\n"
" lowp vec4 c1 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y), tex, texCoord); \\\n"
" lowp vec4 c2 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y)), tex, texCoord); \\\n"
" \\\n"
" lowp float bottomRightTri = step(1.0, tcData[4].s + tcData[4].t); \\\n"
" lowp vec4 c00 = texelFetch(tex, ivec2(tcData[0]), 0); \\\n"
" lowp vec4 c01 = texelFetch(tex, ivec2(tcData[1]), 0); \\\n"
" lowp vec4 c10 = texelFetch(tex, ivec2(tcData[2]), 0); \\\n"
" lowp vec4 c11 = texelFetch(tex, ivec2(tcData[3]), 0); \\\n"
" if(uEnableAlphaTest == 1 ){ \\\n" // Calculate premultiplied color values
" c0.rgb *= c0.a; \\\n"
" c1.rgb *= c1.a; \\\n"
" c2.rgb *= c2.a; \\\n"
" name = c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0); \\\n"
" name.rgb /= name.a; \\\n" // Divide alpha to get actual color value
" c00.rgb *= c00.a; \\\n"
" c01.rgb *= c01.a; \\\n"
" c10.rgb *= c10.a; \\\n"
" c11.rgb *= c11.a; \\\n"
" } \\\n"
" else name = c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0); \\\n"
" lowp vec4 c0 = c00 + tcData[4].s*(c10-c00) + tcData[4].t*(c01-c00); \\\n"
" lowp vec4 c1 = c11 + (1.0-tcData[4].s)*(c01-c11) + (1.0-tcData[4].t)*(c10-c11); \\\n"
" name = c0 + bottomRightTri * (c1-c0); \\\n"
" if(uEnableAlphaTest == 1 ) name.rgb /= name.a; \\\n" // Divide alpha to get actual color value
"} \n"
;
break;
case BILINEAR_STANDARD_WITH_COLOR_BLEEDING_AND_PREMULTIPLIED_ALPHA:
shaderPart +=
"#define TEX_OFFSET(off, tex, texCoord) texture(tex, texCoord - (off)/texSize) \n"
"#define TEX_FILTER(name, tex, texCoord) \\\n"
"{ \\\n"
" mediump vec2 texSize = vec2(textureSize(tex,0)); \\\n"
" mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \\\n"
" offset -= step(1.0, offset.x + offset.y); \\\n"
" lowp vec4 zero = vec4(0.0); \\\n"
" \\\n"
" lowp vec4 p0q0 = TEX_OFFSET(offset, tex, texCoord); \\\n"
" lowp vec4 p1q0 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y), tex, texCoord); \\\n"
" \\\n"
" lowp vec4 p0q1 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y)), tex, texCoord); \\\n"
" lowp vec4 p1q1 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y - sign(offset.y)), tex, texCoord); \\\n"
" \\\n"
" if(uEnableAlphaTest == 1){ \\\n" // Calculate premultiplied color values
" p0q0.rgb *= p0q0.a; \\\n"
" p1q0.rgb *= p1q0.a; \\\n"
" p0q1.rgb *= p0q1.a; \\\n"
" p1q1.rgb *= p1q1.a; \\\n"
" \\\n"
" mediump vec2 interpolationFactor = abs(offset); \\\n"
" lowp vec4 pInterp_q0 = mix( p0q0, p1q0, interpolationFactor.x ); \\\n" // Interpolates top row in X direction.
" lowp vec4 pInterp_q1 = mix( p0q1, p1q1, interpolationFactor.x ); \\\n" // Interpolates bottom row in X direction.
" name = mix( pInterp_q0, pInterp_q1, interpolationFactor.y ); \\\n" // Interpolate in Y direction.
" name.rgb /= name.a; \\\n" // Divide alpha to get actual color value
" } \\\n"
" else if(uCvgXAlpha == 1){ \\\n" // Use texture bleeding for mk64
" if(p0q0.a > p1q0.a) p1q0.rgb = p0q0.rgb; \\\n"
" if(p1q0.a > p0q0.a) p0q0.rgb = p1q0.rgb; \\\n"
" if(p0q1.a > p1q1.a) p1q1.rgb = p0q1.rgb; \\\n"
" if(p1q1.a > p0q1.a) p0q1.rgb = p1q1.rgb; \\\n"
" if(p0q0.a > p0q1.a) p0q1.rgb = p0q0.rgb; \\\n"
" if(p0q1.a > p0q0.a) p0q0.rgb = p0q1.rgb; \\\n"
" if(p1q0.a > p1q1.a) p1q1.rgb = p1q0.rgb; \\\n"
" if(p1q1.a > p1q0.a) p1q0.rgb = p1q1.rgb; \\\n"
" \\\n"
" mediump vec2 interpolationFactor = abs(offset); \\\n"
" lowp vec4 pInterp_q0 = mix( p0q0, p1q0, interpolationFactor.x ); \\\n" // Interpolates top row in X direction.
" lowp vec4 pInterp_q1 = mix( p0q1, p1q1, interpolationFactor.x ); \\\n" // Interpolates bottom row in X direction.
" name = mix( pInterp_q0, pInterp_q1, interpolationFactor.y ); \\\n"
" } \\\n"
" else{ \\\n"
" mediump vec2 interpolationFactor = abs(offset); \\\n"
" lowp vec4 pInterp_q0 = mix( p0q0, p1q0, interpolationFactor.x ); \\\n" // Interpolates top row in X direction.
" lowp vec4 pInterp_q1 = mix( p0q1, p1q1, interpolationFactor.x ); \\\n" // Interpolates bottom row in X direction.
" name = mix( pInterp_q0, pInterp_q1, interpolationFactor.y ); \\\n" // Interpolate in Y direction.
" } \\\n"
"} \n"
"#define TEX_FILTER(name, tex, tcData) \\\n"
"{ \\\n"
" lowp vec4 c00 = texelFetch(tex, ivec2(tcData[0]), 0); \\\n"
" lowp vec4 c01 = texelFetch(tex, ivec2(tcData[1]), 0); \\\n"
" lowp vec4 c10 = texelFetch(tex, ivec2(tcData[2]), 0); \\\n"
" lowp vec4 c11 = texelFetch(tex, ivec2(tcData[3]), 0); \\\n"
" if(uEnableAlphaTest == 1){ \\\n" // Calculate premultiplied color values
" c00.rgb *= c00.a; \\\n"
" c01.rgb *= c01.a; \\\n"
" c10.rgb *= c10.a; \\\n"
" c11.rgb *= c11.a; \\\n"
" } \\\n"
" lowp vec4 c0 = c00 + tcData[4].s * (c10-c00); \\\n"
" lowp vec4 c1 = c01 + tcData[4].s * (c11-c01); \\\n"
" name = c0 + tcData[4].t * (c1-c0); \\\n"
" if(uEnableAlphaTest == 1) name.rgb /= name.a; \\\n"
"} \n"
;
break;
}
shaderPart +=
"#define READ_TEX(name, tex, texCoord, fbMonochrome, fbFixedAlpha) \\\n"
"#define READ_TEX(name, tex, tcData, fbMonochrome, fbFixedAlpha) \\\n"
" { \\\n"
" if (fbMonochrome == 3) { \\\n"
" mediump ivec2 coord = ivec2(gl_FragCoord.xy); \\\n"
" name = texelFetch(tex, coord, 0); \\\n"
" } else { \\\n"
" if (uTextureFilterMode == 0) name = texture(tex, texCoord); \\\n"
" else TEX_FILTER(name, tex, texCoord); \\\n"
" if (uTextureFilterMode == 0) \\\n"
" { \\\n"
" TEX_NEAREST(name, tex, tcData); \\\n"
" } \\\n"
" else TEX_FILTER(name, tex, tcData); \\\n"
" } \\\n"
" if (fbMonochrome == 1) name = vec4(name.r); \\\n"
" else if (fbMonochrome == 2) \\\n"
@ -1329,15 +1287,15 @@ public:
" iconvert.b = icolor.b + (uConvertParams[3]*icolor.r + 128)/256; \\\n"
" iconvert.a = icolor.b; \\\n"
" name = vec4(iconvert)/255.0; \n"
"#define YUVCONVERT_TEX0(name, tex, texCoord, format) \\\n"
"#define YUVCONVERT_TEX0(name, tex, tcData, format) \\\n"
" { \\\n"
" name = texture(tex, texCoord); \\\n"
" name = texelFetch(tex, ivec2(tcData[0]), 0); \\\n"
" YUVCONVERT(name, format) \\\n"
" } \n"
"#define YUVCONVERT_TEX1(name, tex, texCoord, format, prev) \\\n"
"#define YUVCONVERT_TEX1(name, tex, tcData, format, prev) \\\n"
" { \\\n"
" if (uTextureConvert != 0) name = prev; \\\n"
" else name = texture(tex, texCoord); \\\n"
" else name = texelFetch(tex, ivec2(tcData[0]), 0); \\\n"
" YUVCONVERT(name, format) \\\n"
" } \n"
;
@ -1374,13 +1332,13 @@ public:
{
if (!_glinfo.isGLES2) {
m_part =
"#define READ_TEX(name, tex, texCoord, fbMonochrome, fbFixedAlpha) \\\n"
"#define READ_TEX(name, tex, tcData, fbMonochrome, fbFixedAlpha) \\\n"
" { \\\n"
" if (fbMonochrome == 3) { \\\n"
" mediump ivec2 coord = ivec2(gl_FragCoord.xy); \\\n"
" name = texelFetch(tex, coord, 0); \\\n"
" } else { \\\n"
" name = texture(tex, texCoord); \\\n"
" name = texelFetch(tex, ivec2(tcData[0]),0); \\\n"
" } \\\n"
" if (fbMonochrome == 1) name = vec4(name.r); \\\n"
" else if (fbMonochrome == 2) \\\n"
@ -1468,28 +1426,6 @@ public:
}
};
class ShaderFragmentClampWrapMirrorTex0 : public ShaderPart
{
public:
ShaderFragmentClampWrapMirrorTex0(const opengl::GLInfo & _glinfo)
{
m_part =
" texCoord0 = clampWrapMirror(vTexCoord0, uTexClamp0, uTexWrap0, uTexMirror0, uTexScale0); \n"
;
}
};
class ShaderFragmentClampWrapMirrorTex1 : public ShaderPart
{
public:
ShaderFragmentClampWrapMirrorTex1(const opengl::GLInfo & _glinfo)
{
m_part =
" texCoord1 = clampWrapMirror(vTexCoord1, uTexClamp1, uTexWrap1, uTexMirror1, uTexScale1); \n"
;
}
};
class ShaderFragmentReadTexMipmap : public ShaderPart
{
public:
@ -1517,13 +1453,13 @@ public:
m_part =
" lowp vec4 readtex0; \n"
" if (uMSTexEnabled[0] == 0) { \n"
" READ_TEX(readtex0, uTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n"
" } else readtex0 = readTexMS(uMSTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]);\n"
" READ_TEX(readtex0, uTex0, tcData0, uFbMonochrome[0], uFbFixedAlpha[0]) \n"
" } else readtex0 = readTexMS(uMSTex0, tcData0, uFbMonochrome[0], uFbFixedAlpha[0]);\n"
;
} else {
m_part =
" lowp vec4 readtex0; \n"
" READ_TEX(readtex0, uTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n"
" READ_TEX(readtex0, uTex0, tcData0, uFbMonochrome[0], uFbFixedAlpha[0]) \n"
;
}
}
@ -1555,17 +1491,17 @@ public:
if (!g_textureConvert.getBilerp0()) {
shaderPart = " lowp vec4 readtex0; \n"
" YUVCONVERT_TEX0(readtex0, uTex0, texCoord0, uTextureFormat[0]) \n";
" YUVCONVERT_TEX0(readtex0, uTex0, tcData0, uTextureFormat[0]) \n";
} else {
if (config.video.multisampling > 0) {
shaderPart =
" lowp vec4 readtex0; \n"
" if (uMSTexEnabled[0] == 0) { \n"
" READ_TEX(readtex0, uTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n"
" } else readtex0 = readTexMS(uMSTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n";
" READ_TEX(readtex0, uTex0, tcData0, uFbMonochrome[0], uFbFixedAlpha[0]) \n"
" } else readtex0 = readTexMS(uMSTex0, tcData0, uFbMonochrome[0], uFbFixedAlpha[0]); \n";
} else {
shaderPart = " lowp vec4 readtex0; \n"
" READ_TEX(readtex0, uTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n";
" READ_TEX(readtex0, uTex0, tcData0, uFbMonochrome[0], uFbFixedAlpha[0]) \n";
}
}
@ -1604,17 +1540,18 @@ public:
if (!g_textureConvert.getBilerp1()) {
shaderPart =
" lowp vec4 readtex1; \n"
" YUVCONVERT_TEX1(readtex1, uTex1, texCoord1, uTextureFormat[1], readtex0) \n";
" YUVCONVERT_TEX1(readtex1, uTex1, tcData1, uTextureFormat[1], readtex0) \n";
} else {
if (config.video.multisampling > 0) {
shaderPart =
" lowp vec4 readtex1; \n"
" if (uMSTexEnabled[1] == 0) { \n"
" READ_TEX(readtex1, uTex1, texCoord1, uFbMonochrome[1], uFbFixedAlpha[1]) \n"
" } else readtex1 = readTexMS(uMSTex1, texCoord1, uFbMonochrome[1], uFbFixedAlpha[1]); \n";
" READ_TEX(readtex1, uTex1, tcData1, uFbMonochrome[1], uFbFixedAlpha[1]) \n"
" } else readtex1 = readTexMS(uMSTex1, tcData1, uFbMonochrome[1], uFbFixedAlpha[1]); \n";
} else {
shaderPart = " lowp vec4 readtex1; \n"
" READ_TEX(readtex1, uTex1, texCoord1, uFbMonochrome[1], uFbFixedAlpha[1]) \n";
" READ_TEX(readtex1, uTex1, tcData1, uFbMonochrome[1], uFbFixedAlpha[1]) \n";
}
}
@ -1964,52 +1901,49 @@ public:
}
}
else {
if (config.texture.bilinearMode == BILINEAR_3POINT)
m_part =
"#define READ_TEX_MIPMAP(name, tex, tcData, lod) \\\n"
"{ \\\n"
" lowp float bottomRightTri = step(1.0, tcData[4].s + tcData[4].t); \\\n"
" lowp vec2 lod_scale = vec2(textureSize(tex,int(lod))) / vec2(textureSize(tex,0)); \\\n"
" lowp vec4 c00 = texelFetch(tex, ivec2(tcData[0]*lod_scale), int(lod)); \\\n"
" lowp vec4 c01 = texelFetch(tex, ivec2(tcData[1]*lod_scale), int(lod)); \\\n"
" lowp vec4 c10 = texelFetch(tex, ivec2(tcData[2]*lod_scale), int(lod)); \\\n"
" lowp vec4 c11 = texelFetch(tex, ivec2(tcData[3]*lod_scale), int(lod)); \\\n"
" lowp vec4 c0 = c00 + tcData[4].s*(c10-c00) + tcData[4].t*(c01-c00); \\\n"
" lowp vec4 c1 = c11 + (1.0-tcData[4].s)*(c01-c11) + (1.0-tcData[4].t)*(c10-c11); \\\n"
" name = c0 + bottomRightTri * (c1-c0); \\\n"
"} \n"
;
else
m_part =
"#define READ_TEX_MIPMAP(name, tex, tcData, lod) \\\n"
"{ \\\n"
" lowp vec2 lod_scale = vec2(textureSize(tex,int(lod))) / vec2(textureSize(tex,0)); \\\n"
" lowp vec4 c00 = texelFetch(tex, ivec2(tcData[0]*lod_scale), int(lod)); \\\n"
" lowp vec4 c01 = texelFetch(tex, ivec2(tcData[1]*lod_scale), int(lod)); \\\n"
" lowp vec4 c10 = texelFetch(tex, ivec2(tcData[2]*lod_scale), int(lod)); \\\n"
" lowp vec4 c11 = texelFetch(tex, ivec2(tcData[3]*lod_scale), int(lod)); \\\n"
" lowp vec4 c0 = c00 + tcData[4].s * (c10-c00); \\\n"
" lowp vec4 c1 = c01 + tcData[4].s * (c11-c01); \\\n"
" name = c0 + tcData[4].t * (c1-c0); \\\n"
"} \n"
;
if (config.generalEmulation.enableLOD == 0) {
// Fake mipmap
m_part =
m_part +=
"uniform lowp int uMaxTile; \n"
"uniform mediump float uMinLod; \n"
" \n"
"mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n"
" readtex0 = texture(uTex0, texCoord0); \n"
" readtex1 = texture(uTex1, texCoord1); \n"
" if (uMaxTile == 0) return 1.0; \n"
" return uMinLod; \n"
"} \n"
" READ_TEX_MIPMAP(readtex0, uTex0, tcData0, 0); \n"
" READ_TEX_MIPMAP(readtex1, uTex1, tcData1, 0); \n"
" if (uMaxTile == 0) return 1.0; \n"
" return uMinLod; \n"
"} \n"
;
} else {
if (config.texture.bilinearMode == BILINEAR_3POINT)
m_part =
"#define TEX_OFFSET_NORMAL(off, tex, texCoord, lod) texture(tex, texCoord - (off)/texSize) \n"
"#define TEX_OFFSET_MIPMAP(off, tex, texCoord, lod) textureLod(tex, texCoord - (off)/texSize, lod) \n"
"#define READ_TEX_NORMAL(name, tex, texCoord, lod) \\\n"
" { \\\n"
" mediump vec2 texSize = vec2(textureSize(tex, int(lod))); \\\n"
" mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \\\n"
" offset -= step(1.0, offset.x + offset.y); \\\n"
" lowp vec4 c0 = TEX_OFFSET_NORMAL(offset, tex, texCoord, lod); \\\n"
" lowp vec4 c1 = TEX_OFFSET_NORMAL(vec2(offset.x - sign(offset.x), offset.y), tex, texCoord, lod); \\\n"
" lowp vec4 c2 = TEX_OFFSET_NORMAL(vec2(offset.x, offset.y - sign(offset.y)), tex, texCoord, lod); \\\n"
" name = c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0); \\\n"
" } \n"
"#define READ_TEX_MIPMAP(name, tex, texCoord, lod) \\\n"
" { \\\n"
" mediump vec2 texSize = vec2(textureSize(tex, int(lod))); \\\n"
" mediump vec2 offset = fract(texCoord*texSize - vec2(0.5)); \\\n"
" offset -= step(1.0, offset.x + offset.y); \\\n"
" lowp vec4 c0 = TEX_OFFSET_MIPMAP(offset, tex, texCoord, lod); \\\n"
" lowp vec4 c1 = TEX_OFFSET_MIPMAP(vec2(offset.x - sign(offset.x), offset.y), tex, texCoord, lod); \\\n"
" lowp vec4 c2 = TEX_OFFSET_MIPMAP(vec2(offset.x, offset.y - sign(offset.y)), tex, texCoord, lod); \\\n"
" name = c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0); \\\n"
" } \n"
;
else
m_part =
"#define TEX_FETCH_NORMAL(tex, texCoord, lod) texture(tex, texCoord) \n"
"#define TEX_FETCH_MIPMAP(tex, texCoord, lod) textureLod(tex, texCoord, lod) \n"
"#define READ_TEX_NORMAL(name, tex, texCoord, lod) name = TEX_FETCH_NORMAL(tex, texCoord, lod) \n"
"#define READ_TEX_MIPMAP(name, tex, texCoord, lod) name = TEX_FETCH_MIPMAP(tex, texCoord, lod) \n"
;
m_part +=
"uniform lowp int uEnableLod; \n"
"uniform mediump float uMinLod; \n"
@ -2017,8 +1951,8 @@ public:
"uniform lowp int uTextureDetail; \n"
" \n"
"mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n"
" READ_TEX_NORMAL(readtex0, uTex0, texCoord0, 0.0); \n"
" READ_TEX_MIPMAP(readtex1, uTex1, texCoord1, 0.0); \n"
" READ_TEX_MIPMAP(readtex0, uTex0, tcData0, 0); \n"
" READ_TEX_MIPMAP(readtex1, uTex1, tcData1, 0); \n"
" \n"
" mediump float fMaxTile = float(uMaxTile); \n"
" mediump vec2 dx = abs(dFdx(vLodTexCoord)); \n"
@ -2048,9 +1982,9 @@ public:
" lowp float lod_tile_m1 = max(0.0, lod_tile - 1.0); \n"
" lowp float lod_tile_p1 = min(fMaxTile - 1.0, lod_tile + 1.0); \n"
" lowp vec4 lodT, lodT_m1, lodT_p1; \n"
" READ_TEX_MIPMAP(lodT, uTex1, texCoord1, lod_tile); \n"
" READ_TEX_MIPMAP(lodT_m1, uTex1, texCoord1, lod_tile_m1); \n"
" READ_TEX_MIPMAP(lodT_p1, uTex1, texCoord1, lod_tile_p1); \n"
" READ_TEX_MIPMAP(lodT, uTex1, tcData1, lod_tile); \n"
" READ_TEX_MIPMAP(lodT_m1, uTex1, tcData1, lod_tile_m1); \n"
" READ_TEX_MIPMAP(lodT_p1, uTex1, tcData1, lod_tile_p1); \n"
" if (lod_tile < 1.0) { \n"
" if (magnify) { \n"
// !sharpen && !detail
@ -2212,14 +2146,13 @@ public:
" return texel / float(uMSAASamples); \n"
"} \n"
" \n"
"lowp vec4 readTexMS(in lowp sampler2DMS mstex, in highp vec2 texCoord, in lowp int fbMonochrome, in lowp int fbFixedAlpha) \n"
"lowp vec4 readTexMS(in lowp sampler2DMS mstex, in highp vec2[5] tcData, in lowp int fbMonochrome, in lowp int fbFixedAlpha) \n"
"{ \n"
" mediump ivec2 itexCoord; \n"
" if (fbMonochrome == 3) { \n"
" itexCoord = ivec2(gl_FragCoord.xy); \n"
" } else { \n"
" mediump vec2 msTexSize = vec2(textureSize(mstex)); \n"
" itexCoord = ivec2(msTexSize * texCoord); \n"
" itexCoord = ivec2(tcData[0]); \n"
" } \n"
" lowp vec4 texColor = sampleMS(mstex, itexCoord); \n"
" if (fbMonochrome == 1) texColor = vec4(texColor.r); \n"
@ -2272,14 +2205,13 @@ public:
" return texel / float(uMSAASamples); \n"
"} \n"
" \n"
"lowp vec4 readTexMS(in lowp sampler2DMS mstex, in highp vec2 texCoord, in lowp int fbMonochrome, in lowp int fbFixedAlpha) \n"
"lowp vec4 readTexMS(in lowp sampler2DMS mstex, in highp vec2[5] tcData, in lowp int fbMonochrome, in lowp int fbFixedAlpha) \n"
"{ \n"
" mediump ivec2 itexCoord; \n"
" if (fbMonochrome == 3) { \n"
" itexCoord = ivec2(gl_FragCoord.xy); \n"
" } else { \n"
" mediump vec2 msTexSize = vec2(textureSize(mstex)); \n"
" itexCoord = ivec2(msTexSize * texCoord); \n"
" itexCoord = ivec2(tcData[0]); \n"
" } \n"
" lowp vec4 texColor = sampleMS(mstex, itexCoord); \n"
" if (fbMonochrome == 1) texColor = vec4(texColor.r); \n"
@ -2414,58 +2346,44 @@ public:
}
};
class ShaderClampWrapMirror : public ShaderPart
{
public:
ShaderClampWrapMirror(const opengl::GLInfo & _glinfo)
{
m_part =
"highp vec2 clampWrapMirror(in highp vec2 vTexCoord, in highp vec4 vClamp, \n"
" in highp vec2 vWrap, in lowp vec2 vMirror, in highp vec2 vScale) \n"
"{ \n"
" highp vec2 texCoord = clamp(vTexCoord, vClamp.xy, vClamp.zw); \n"
" lowp vec2 one = vec2(1.0); \n"
" lowp vec2 clamped = step(vClamp.zw, texCoord); \n"
" lowp vec2 notClamped = one - clamped; \n"
" lowp vec2 wrapped = step(vWrap , texCoord); \n"
" lowp vec2 notWrapped = one - wrapped; \n"
" texCoord = clamped * texCoord + notClamped * (wrapped*mod(texCoord, vWrap) + notWrapped*texCoord); \n"
" highp vec2 intPart = floor(texCoord); \n"
" highp vec2 fractPart = fract(texCoord); \n"
" lowp vec2 needMirror = step(vec2(0.5), mod(intPart, vWrap)) * vMirror; \n"
" texCoord = clamped * texCoord + notClamped * fractPart; \n"
" texCoord = (one - vMirror) * texCoord + vMirror * fractPart; \n"
" texCoord = (one - texCoord) * needMirror + texCoord * (one - needMirror); \n"
" texCoord *= vScale; \n"
" return texCoord; \n"
"} \n"
;
}
};
class ShaderTextureEngine : public ShaderPart
{
public:
ShaderTextureEngine(const opengl::GLInfo _glinfo) {
m_part =
"highp vec2 clampWrapMirror(in highp vec2 vTexCoord, in highp vec2 vWrap, \n"
" in highp vec2 vClamp, in lowp vec2 vWrapEn, in lowp vec2 vClampEn, in lowp vec2 vMirrorEn) \n"
"{ \n"
" highp vec2 texCoord = vTexCoord; \n"
" highp vec2 clampedCoord = clamp(texCoord, vec2(0.0), vClamp); \n"
" texCoord += vClampEn*(clampedCoord-texCoord); \n"
" lowp vec2 needMirror = step(vWrap, mod(texCoord, 2.0*vWrap)); \n"
" highp vec2 invertedCoord = mod(-texCoord-vec2(1.0), vWrap); \n"
" texCoord += vMirrorEn*needMirror*(invertedCoord-texCoord); \n"
" highp vec2 wrappedCoord = mod(texCoord,vWrap); \n"
" texCoord += vWrapEn*(wrappedCoord-texCoord); \n"
" return texCoord; \n"
"} \n"
"highp vec2[5] textureEngine0(in highp vec2 texCoord) \n"
"{ \n"
" highp vec2[5] tcData; \n" // {tc00, tc01, tc10, tc11, frPart}
" mediump vec2 intPart = floor(texCoord); \n"
" tcData[0] = clampWrapMirror(intPart, uTexWrap0, uTexClamp0, uTexClampEn0, uTexMirrorEn0); \n"
" tcData[3] = clampWrapMirror(intPart + vec2(1.0,1.0), uTexWrap0, uTexClamp0, uTexClampEn0, uTexMirrorEn0); \n"
" tcData[0] = clampWrapMirror(intPart, uTexWrap0, uTexClamp0, uTexWrapEn0, uTexClampEn0, uTexMirrorEn0); \n"
" tcData[3] = clampWrapMirror(intPart + vec2(1.0,1.0), uTexWrap0, uTexClamp0, uTexWrapEn0, uTexClampEn0, uTexMirrorEn0); \n"
" tcData[1] = vec2(tcData[0].s, tcData[3].t); \n"
" tcData[2] = vec2(tcData[3].s, tcData[0].t); \n"
" tcData[4] = texCoord - intPart; \n"
" return tcData;"
"} \n"
"highp vec2[5] textureEngine1(in highp vec2 texCoord) \n"
"{ \n"
" highp vec2[5] tcData; \n" // {tc00, tc01, tc10, tc11, frPart}
" mediump vec2 intPart = floor(texCoord); \n"
" tcData[0] = clampWrapMirror(intPart, uTexWrap1, uTexClamp1, uTexClampEn1, uTexMirrorEn1); \n"
" tcData[3] = clampWrapMirror(intPart + vec2(1.0,1.0), uTexWrap1, uTexClamp1, uTexClampEn1, uTexMirrorEn1); \n"
" tcData[0] = clampWrapMirror(intPart, uTexWrap1, uTexClamp1, uTexWrapEn1, uTexClampEn1, uTexMirrorEn1); \n"
" tcData[3] = clampWrapMirror(intPart + vec2(1.0,1.0), uTexWrap1, uTexClamp1, uTexWrapEn1, uTexClampEn1, uTexMirrorEn1); \n"
" tcData[1] = vec2(tcData[0].s, tcData[3].t); \n"
" tcData[2] = vec2(tcData[3].s, tcData[0].t); \n"
" tcData[4] = texCoord - intPart; \n"
@ -2664,7 +2582,6 @@ graphics::CombinerProgram * CombinerProgramBuilder::buildCombinerProgram(Combine
m_fragmentHeaderWriteDepth->write(ssShader);
m_fragmentHeaderDepthCompare->write(ssShader);
m_fragmentHeaderReadMSTex->write(ssShader);
m_fragmentHeaderClampWrapMirror->write(ssShader);
m_fragmentHeaderTextureEngine->write(ssShader);
if (bUseLod)
m_fragmentHeaderMipMap->write(ssShader);
@ -2700,12 +2617,10 @@ graphics::CombinerProgram * CombinerProgramBuilder::buildCombinerProgram(Combine
if (bUseTextures) {
if (combinerInputs.usesTile(0))
{
m_fragmentClampWrapMirrorTex0->write(ssShader);
m_fragmentTextureEngineTex0->write(ssShader);
}
if (combinerInputs.usesTile(1))
{
m_fragmentClampWrapMirrorTex1->write(ssShader);
m_fragmentTextureEngineTex1->write(ssShader);
}
@ -2746,7 +2661,6 @@ graphics::CombinerProgram * CombinerProgramBuilder::buildCombinerProgram(Combine
m_shaderCalcLight->write(ssShader);
if (bUseTextures) {
m_shaderClampWrapMirror->write(ssShader);
m_shaderTextureEngine->write(ssShader);
if (bUseLod)
m_shaderMipmap->write(ssShader);
@ -2858,7 +2772,6 @@ CombinerProgramBuilder::CombinerProgramBuilder(const opengl::GLInfo & _glinfo, o
, m_fragmentHeaderWriteDepth(new ShaderFragmentHeaderWriteDepth(_glinfo))
, m_fragmentHeaderCalcLight(new ShaderFragmentHeaderCalcLight(_glinfo))
, m_fragmentHeaderMipMap(new ShaderFragmentHeaderMipMap(_glinfo))
, m_fragmentHeaderClampWrapMirror(new ShaderFragmentHeaderClampWrapMirror(_glinfo))
, m_fragmentHeaderTextureEngine(new ShaderFragmentHeaderTextureEngine(_glinfo))
, m_fragmentHeaderReadMSTex(new ShaderFragmentHeaderReadMSTex(_glinfo))
, m_fragmentHeaderDither(new ShaderFragmentHeaderDither(_glinfo))
@ -2870,8 +2783,6 @@ CombinerProgramBuilder::CombinerProgramBuilder(const opengl::GLInfo & _glinfo, o
, m_fragmentBlendMux(new ShaderFragmentBlendMux(_glinfo))
, m_fragmentReadTex0(new ShaderFragmentReadTex0(_glinfo))
, m_fragmentReadTex1(new ShaderFragmentReadTex1(_glinfo))
, m_fragmentClampWrapMirrorTex0(new ShaderFragmentClampWrapMirrorTex0(_glinfo))
, m_fragmentClampWrapMirrorTex1(new ShaderFragmentClampWrapMirrorTex1(_glinfo))
, m_fragmentTextureEngineTex0(new ShaderFragmentTextureEngineTex0(_glinfo))
, m_fragmentTextureEngineTex1(new ShaderFragmentTextureEngineTex1(_glinfo))
, m_fragmentReadTexCopyMode(new ShaderFragmentReadTexCopyMode(_glinfo))
@ -2888,7 +2799,6 @@ CombinerProgramBuilder::CombinerProgramBuilder(const opengl::GLInfo & _glinfo, o
, m_shaderReadtexCopyMode(new ShaderReadtexCopyMode(_glinfo))
, m_shaderN64DepthCompare(new ShaderN64DepthCompare(_glinfo))
, m_shaderN64DepthRender(new ShaderN64DepthRender(_glinfo))
, m_shaderClampWrapMirror(new ShaderClampWrapMirror(_glinfo))
, m_shaderTextureEngine(new ShaderTextureEngine(_glinfo))
, m_useProgram(_useProgram)
, m_combinerOptionsBits(graphics::CombinerProgram::getShaderCombinerOptionsBits())

View File

@ -62,7 +62,6 @@ namespace glsl {
ShaderPartPtr m_fragmentHeaderWriteDepth;
ShaderPartPtr m_fragmentHeaderCalcLight;
ShaderPartPtr m_fragmentHeaderMipMap;
ShaderPartPtr m_fragmentHeaderClampWrapMirror;
ShaderPartPtr m_fragmentHeaderTextureEngine;
ShaderPartPtr m_fragmentHeaderReadMSTex;
ShaderPartPtr m_fragmentHeaderDither;
@ -74,8 +73,6 @@ namespace glsl {
ShaderPartPtr m_fragmentBlendMux;
ShaderPartPtr m_fragmentReadTex0;
ShaderPartPtr m_fragmentReadTex1;
ShaderPartPtr m_fragmentClampWrapMirrorTex0;
ShaderPartPtr m_fragmentClampWrapMirrorTex1;
ShaderPartPtr m_fragmentTextureEngineTex0;
ShaderPartPtr m_fragmentTextureEngineTex1;
ShaderPartPtr m_fragmentReadTexCopyMode;
@ -93,7 +90,6 @@ namespace glsl {
ShaderPartPtr m_shaderReadtexCopyMode;
ShaderPartPtr m_shaderN64DepthCompare;
ShaderPartPtr m_shaderN64DepthRender;
ShaderPartPtr m_shaderClampWrapMirror;
ShaderPartPtr m_shaderTextureEngine;
std::unique_ptr<CombinerProgramUniformFactory> m_uniformFactory;

View File

@ -914,7 +914,7 @@ public:
f32 shiftScaleT = 1.0f;
getTextureShiftScale(t, cache, shiftScaleS, shiftScaleT);
uCacheShiftScale[t].set(shiftScaleS, shiftScaleT, _force);
uCacheScale[t].set(_pTexture->scaleS, _pTexture->scaleT, _force);
uCacheScale[t].set(_pTexture->hdRatioS, _pTexture->hdRatioT, _force);
uCacheOffset[t].set(_pTexture->offsetS, _pTexture->offsetT, _force);
nFB[t] = _pTexture->frameBufferTexture;
}
@ -934,30 +934,33 @@ private:
iv2Uniform uCacheFrameBuffer;
};
class UClampWrapMirrorTex : public UniformGroup
class UTextureEngine : public UniformGroup
{
public:
UClampWrapMirrorTex(GLuint _program, bool _useT0, bool _useT1)
UTextureEngine(GLuint _program, bool _useT0, bool _useT1)
{
m_useTile[0] = _useT0;
m_useTile[1] = _useT1;
LocateUniform(uTexClamp0);
LocateUniform(uTexClamp1);
LocateUniform(uTexWrap0);
LocateUniform(uTexWrap1);
LocateUniform(uTexMirror0);
LocateUniform(uTexMirror1);
LocateUniform(uTexScale0);
LocateUniform(uTexScale1);
LocateUniform(uTexClamp0);
LocateUniform(uTexClamp1);
LocateUniform(uTexWrapEn0);
LocateUniform(uTexWrapEn1);
LocateUniform(uTexClampEn0);
LocateUniform(uTexClampEn1);
LocateUniform(uTexMirrorEn0);
LocateUniform(uTexMirrorEn1);
}
void update(bool _force) override
{
std::array<f32, 4> aTexClamp[2] = { { -10000.0f, -10000.0f, 10000.0f, 10000.0f },
{ -10000.0f, -10000.0f, 10000.0f, 10000.0f } };
std::array<f32, 2> aTexWrap[2] = { { 10000.0f, 10000.0f }, { 10000.0f, 10000.0f } };
std::array<f32, 2> aTexMirror[2] = { { 0.0f, 0.0f}, { 0.0f, 0.0f } };
std::array<f32, 2> aTexScale[2] = { { 1.0f, 1.0f },{ 1.0f, 1.0f } };
std::array<f32, 2> aTexWrap[2] = { {0.0f,0.0f}, {0.0f,0.0f} };
std::array<f32, 2> aTexClamp[2] = { { 0.0f,0.0f },{ 0.0f,0.0f } };
std::array<f32, 2> aTexWrapEn[2] = { { 0.0f,0.0f },{ 0.0f,0.0f } };
std::array<f32, 2> aTexClampEn[2] = { { 0.0f,0.0f },{ 0.0f,0.0f } };
std::array<f32, 2> aTexMirrorEn[2] = { { 0.0f,0.0f },{ 0.0f,0.0f } };
TextureCache & cache = textureCache();
const bool replaceTex1ByTex0 = needReplaceTex1ByTex0();
for (u32 t = 0; t < 2; ++t) {
@ -969,75 +972,62 @@ public:
CachedTexture * pTexture = cache.current[tile];
if (pTile == nullptr || pTexture == nullptr)
continue;
/* Not sure if special treatment of framebuffer textures is correct */
if (pTexture->frameBufferTexture != CachedTexture::fbNone)
{
aTexWrap[t][0] = 1.0;
aTexWrap[t][1] = 1.0;
aTexClamp[t][0] = f32(pTexture->width) - 1.0;
aTexClamp[t][1] = f32(pTexture->height) - 1.0;
aTexWrapEn[t][0] = 0.0;
aTexWrapEn[t][1] = 0.0;
aTexClampEn[t][0] = 1.0;
aTexClampEn[t][1] = 1.0;
aTexMirrorEn[t][0] = 0.0;
aTexMirrorEn[t][1] = 0.0;
if (gDP.otherMode.cycleType != G_CYC_COPY) {
if (pTexture->clampS) {
aTexClamp[t][0] = 0.0f; // S lower bound
if (pTexture->frameBufferTexture != CachedTexture::fbNone ||
pTile->textureMode == TEXTUREMODE_BGIMAGE)
aTexClamp[t][2] = 1.0f;
else {
u32 tileWidth = ((pTile->lrs - pTile->uls) & 0x03FF) + 1;
if (pTile->size > pTexture->size)
tileWidth <<= pTile->size - pTexture->size;
// aTexClamp[t][2] = f32(tileWidth) / (pTexture->mirrorS ? f32(pTexture->width) : f32(pTexture->clampWidth)); // S upper bound
aTexClamp[t][2] = f32(tileWidth) / f32(pTexture->width); // S upper bound
}
}
if (pTexture->clampT) {
aTexClamp[t][1] = 0.0f; // T lower bound
if (pTexture->frameBufferTexture != CachedTexture::fbNone ||
pTile->textureMode == TEXTUREMODE_BGIMAGE)
aTexClamp[t][3] = 1.0f;
else {
const u32 tileHeight = ((pTile->lrt - pTile->ult) & 0x03FF) + 1;
// aTexClamp[t][3] = f32(tileHeight) / (pTexture->mirrorT ? f32(pTexture->height) : f32(pTexture->clampHeight)); // T upper bound
aTexClamp[t][3] = f32(tileHeight) / f32(pTexture->height); // T upper bound
}
}
}
if (pTexture->maskS) {
const f32 wrapWidth = static_cast<f32>(1 << pTile->originalMaskS);
const f32 pow2Width = static_cast<f32>(pow2(pTexture->width));
aTexWrap[t][0] = wrapWidth / pow2Width;
aTexScale[t][0] = pow2Width / f32(pTexture->width);
}
if (pTexture->maskT) {
const f32 wrapHeight = static_cast<f32>(1 << pTile->originalMaskT);
const f32 pow2Height = static_cast<f32>(pow2(pTexture->height));
aTexWrap[t][1] = wrapHeight / pow2Height;
aTexScale[t][1] = pow2Height / f32(pTexture->height);
}
if (pTexture->mirrorS) {
aTexMirror[t][0] = 1.0f;
aTexWrap[t][0] *= 2.0f;
}
if (pTexture->mirrorT) {
aTexMirror[t][1] = 1.0f;
aTexWrap[t][1] *= 2.0f;
else
{
aTexWrap[t][0] = f32(1 << pTile->masks) * pTexture->hdRatioS;
aTexWrap[t][1] = f32(1 << pTile->maskt) * pTexture->hdRatioT;
aTexClamp[t][0] = (pTile->flrs - pTile->fuls + 1.0) * pTexture->hdRatioS - 1.0;
aTexClamp[t][1] = (pTile->flrt - pTile->fult + 1.0) * pTexture->hdRatioT - 1.0;
aTexWrapEn[t][0] = f32(pTile->masks == 0 ? 0 : 1);
aTexWrapEn[t][1] = f32(pTile->maskt == 0 ? 0 : 1);
aTexClampEn[t][0] = f32(pTile->masks == 0 ? 1 : pTile->clamps);
aTexClampEn[t][1] = f32(pTile->maskt == 0 ? 1 : pTile->clampt);
aTexMirrorEn[t][0] = f32(pTile->masks == 0 ? 0 : pTile->mirrors);
aTexMirrorEn[t][1] = f32(pTile->maskt == 0 ? 0 : pTile->mirrort);
}
}
uTexClamp0.set(aTexClamp[0].data(), _force);
uTexClamp1.set(aTexClamp[1].data(), _force);
uTexWrap0.set(aTexWrap[0][0], aTexWrap[0][1], _force);
uTexWrap1.set(aTexWrap[1][0], aTexWrap[1][1], _force);
uTexMirror0.set(aTexMirror[0][0], aTexMirror[0][1], _force);
uTexMirror1.set(aTexMirror[1][0], aTexMirror[1][1], _force);
uTexScale0.set(aTexScale[0][0], aTexScale[0][1], _force);
uTexScale1.set(aTexScale[1][0], aTexScale[1][1], _force);
uTexClamp0.set(aTexClamp[0][0], aTexClamp[0][1], _force);
uTexClamp1.set(aTexClamp[1][0], aTexClamp[1][1], _force);
uTexWrapEn0.set(aTexWrapEn[0][0], aTexWrapEn[0][1], _force);
uTexWrapEn1.set(aTexWrapEn[1][0], aTexWrapEn[1][1], _force);
uTexClampEn0.set(aTexClampEn[0][0], aTexClampEn[0][1], _force);
uTexClampEn1.set(aTexClampEn[1][0], aTexClampEn[1][1], _force);
uTexMirrorEn0.set(aTexMirrorEn[0][0], aTexMirrorEn[0][1], _force);
uTexMirrorEn1.set(aTexMirrorEn[1][0], aTexMirrorEn[1][1], _force);
}
private:
bool m_useTile[2];
fv4Uniform uTexClamp0;
fv4Uniform uTexClamp1;
fv2Uniform uTexWrap0;
fv2Uniform uTexWrap1;
fv2Uniform uTexMirror0;
fv2Uniform uTexMirror1;
fv2Uniform uTexScale0;
fv2Uniform uTexScale1;
fv2Uniform uTexClamp0;
fv2Uniform uTexClamp1;
fv2Uniform uTexWrapEn0;
fv2Uniform uTexWrapEn1;
fv2Uniform uTexClampEn0;
fv2Uniform uTexClampEn1;
fv2Uniform uTexMirrorEn0;
fv2Uniform uTexMirrorEn1;
};
class ULights : public UniformGroup
@ -1107,7 +1097,7 @@ void CombinerProgramUniformFactory::buildUniforms(GLuint _program,
if (!_key.isRectKey())
_uniforms.emplace_back(new UTextureParams(_program, _inputs.usesTile(0), _inputs.usesTile(1)));
_uniforms.emplace_back(new UClampWrapMirrorTex(_program, _inputs.usesTile(0), _inputs.usesTile(1)));
_uniforms.emplace_back(new UTextureEngine(_program, _inputs.usesTile(0), _inputs.usesTile(1)));
}
_uniforms.emplace_back(new UFog(_program));

View File

@ -1342,10 +1342,19 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params)
}
}
texST[t].s0 *= cache.current[t]->scaleS;
texST[t].t0 *= cache.current[t]->scaleT;
texST[t].s1 *= cache.current[t]->scaleS;
texST[t].t1 *= cache.current[t]->scaleT;
if (gDP.otherMode.textureFilter != G_TF_POINT && gDP.otherMode.cycleType != G_CYC_COPY) {
texST[t].s0 -= 0.5f;
texST[t].t0 -= 0.5f;
texST[t].s1 -= 0.5f;
texST[t].t1 -= 0.5f;
}
texST[t].s0 *= cache.current[t]->hdRatioS;
texST[t].t0 *= cache.current[t]->hdRatioT;
texST[t].s1 *= cache.current[t]->hdRatioS;
texST[t].t1 *= cache.current[t]->hdRatioT;
}
}

View File

@ -446,6 +446,8 @@ void TextureCache::_initDummyTexture(CachedTexture * _pDummy)
_pDummy->maskT = 0;
_pDummy->scaleS = 0.5f;
_pDummy->scaleT = 0.5f;
_pDummy->hdRatioS = 1.0f;
_pDummy->hdRatioT = 1.0f;
_pDummy->shiftScaleS = 1.0f;
_pDummy->shiftScaleT = 1.0f;
_pDummy->textureBytes = 2 * 2 * 4;
@ -670,6 +672,9 @@ void _updateCachedTexture(const GHQTexInfo & _info, CachedTexture *_pTexture, u1
_pTexture->scaleS = 1.0f / (_pTexture->maskS ? f32(pow2(widthOrg)) : f32(widthOrg));
_pTexture->scaleT = 1.0f / (_pTexture->maskT ? f32(pow2(heightOrg)) : f32(heightOrg));
_pTexture->hdRatioS = f32(_info.width / _pTexture->width);
_pTexture->hdRatioT = f32(_info.height / _pTexture->height);
_pTexture->bHDTexture = true;
}
@ -1416,6 +1421,9 @@ void TextureCache::_updateBackground()
pCurrent->scaleS = 1.0f / (f32)(pCurrent->width);
pCurrent->scaleT = 1.0f / (f32)(pCurrent->height);
pCurrent->hdRatioS = 1.0f;
pCurrent->hdRatioT = 1.0f;
pCurrent->shiftScaleS = 1.0f;
pCurrent->shiftScaleT = 1.0f;
@ -1571,6 +1579,9 @@ void TextureCache::update(u32 _t)
pCurrent->scaleS = 1.0f / (pCurrent->maskS ? f32(pow2(pCurrent->width)) : f32(pCurrent->width));
pCurrent->scaleT = 1.0f / (pCurrent->maskT ? f32(pow2(pCurrent->height)) : f32(pCurrent->height));
pCurrent->hdRatioS = 1.0f;
pCurrent->hdRatioT = 1.0f;
pCurrent->offsetS = 0.0f;
pCurrent->offsetT = 0.0f;

View File

@ -33,6 +33,7 @@ struct CachedTexture
u16 width, height; // N64 width and height
u16 clampWidth, clampHeight; // Size to clamp to
f32 scaleS, scaleT; // Scale to map to 0.0-1.0
f32 hdRatioS, hdRatioT; // HD / N64 width and height
f32 shiftScaleS, shiftScaleT; // Scale to shift
u32 textureBytes;