mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-25 18:46:55 +01:00
Latte: Small refactor for GLSL texture coord handling
Also adds support for 2D textures coordinates with source as 0.0 or 1.0 literals instead of GPRs. Seen in shaders generated by CafeGLSL
This commit is contained in:
parent
e7fa8ec0c6
commit
dee764473d
@ -507,7 +507,7 @@ void _emitRegisterAccessCode(LatteDecompilerShaderContext* shaderContext, sint32
|
|||||||
{
|
{
|
||||||
_emitTypeConversionPrefix(shaderContext, registerElementDataType, dataType);
|
_emitTypeConversionPrefix(shaderContext, registerElementDataType, dataType);
|
||||||
}
|
}
|
||||||
if(shaderContext->typeTracker.useArrayGPRs )
|
if (shaderContext->typeTracker.useArrayGPRs)
|
||||||
src->add("R");
|
src->add("R");
|
||||||
else
|
else
|
||||||
src->addFmt("R{}", gprIndex);
|
src->addFmt("R{}", gprIndex);
|
||||||
@ -540,6 +540,26 @@ void _emitRegisterAccessCode(LatteDecompilerShaderContext* shaderContext, sint32
|
|||||||
_emitTypeConversionSuffix(shaderContext, registerElementDataType, dataType);
|
_emitTypeConversionSuffix(shaderContext, registerElementDataType, dataType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// optimized variant of _emitRegisterAccessCode for raw one channel reads
|
||||||
|
void _emitRegisterChannelAccessCode(LatteDecompilerShaderContext* shaderContext, sint32 gprIndex, sint32 channel, sint32 dataType)
|
||||||
|
{
|
||||||
|
cemu_assert_debug(gprIndex >= 0 && gprIndex <= 127);
|
||||||
|
cemu_assert_debug(channel >= 0 && channel < 4);
|
||||||
|
StringBuf* src = shaderContext->shaderSource;
|
||||||
|
sint32 registerElementDataType = shaderContext->typeTracker.defaultDataType;
|
||||||
|
_emitTypeConversionPrefix(shaderContext, registerElementDataType, dataType);
|
||||||
|
if (shaderContext->typeTracker.useArrayGPRs)
|
||||||
|
src->add("R");
|
||||||
|
else
|
||||||
|
src->addFmt("R{}", gprIndex);
|
||||||
|
_appendRegisterTypeSuffix(src, registerElementDataType);
|
||||||
|
if (shaderContext->typeTracker.useArrayGPRs)
|
||||||
|
src->addFmt("[{}]", gprIndex);
|
||||||
|
src->add(".");
|
||||||
|
src->add(_getElementStrByIndex(channel));
|
||||||
|
_emitTypeConversionSuffix(shaderContext, registerElementDataType, dataType);
|
||||||
|
}
|
||||||
|
|
||||||
void _emitALURegisterInputAccessCode(LatteDecompilerShaderContext* shaderContext, LatteDecompilerALUInstruction* aluInstruction, sint32 operandIndex)
|
void _emitALURegisterInputAccessCode(LatteDecompilerShaderContext* shaderContext, LatteDecompilerALUInstruction* aluInstruction, sint32 operandIndex)
|
||||||
{
|
{
|
||||||
StringBuf* src = shaderContext->shaderSource;
|
StringBuf* src = shaderContext->shaderSource;
|
||||||
@ -2129,63 +2149,31 @@ void _emitALUClauseCode(LatteDecompilerShaderContext* shaderContext, LatteDecomp
|
|||||||
/*
|
/*
|
||||||
* Emits code to access one component (xyzw) of the texture coordinate input vector
|
* Emits code to access one component (xyzw) of the texture coordinate input vector
|
||||||
*/
|
*/
|
||||||
void _emitTEXSampleCoordInputComponent(LatteDecompilerShaderContext* shaderContext, LatteDecompilerTEXInstruction* texInstruction, sint32 componentIndex, sint32 varType)
|
void _emitTEXSampleCoordInputComponent(LatteDecompilerShaderContext* shaderContext, LatteDecompilerTEXInstruction* texInstruction, sint32 componentIndex, sint32 interpretSrcAsType)
|
||||||
{
|
{
|
||||||
|
cemu_assert(componentIndex >= 0 && componentIndex < 4);
|
||||||
|
cemu_assert_debug(interpretSrcAsType == LATTE_DECOMPILER_DTYPE_SIGNED_INT || interpretSrcAsType == LATTE_DECOMPILER_DTYPE_FLOAT);
|
||||||
StringBuf* src = shaderContext->shaderSource;
|
StringBuf* src = shaderContext->shaderSource;
|
||||||
if( componentIndex >= 4 )
|
sint32 elementSel = texInstruction->textureFetch.srcSel[componentIndex];
|
||||||
|
if (elementSel < 4)
|
||||||
{
|
{
|
||||||
debugBreakpoint();
|
_emitRegisterChannelAccessCode(shaderContext, texInstruction->srcGpr, elementSel, interpretSrcAsType);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sint32 elementSel = texInstruction->textureFetch.srcSel[componentIndex];
|
|
||||||
const char* resultElemTable[4] = {"x","y","z","w"};
|
const char* resultElemTable[4] = {"x","y","z","w"};
|
||||||
if( varType == LATTE_DECOMPILER_DTYPE_SIGNED_INT )
|
if(interpretSrcAsType == LATTE_DECOMPILER_DTYPE_SIGNED_INT )
|
||||||
{
|
{
|
||||||
if (elementSel < 4)
|
if( elementSel == 4 )
|
||||||
{
|
|
||||||
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
|
||||||
src->addFmt("{}.{}", _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[elementSel]);
|
|
||||||
else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
|
||||||
src->addFmt("floatBitsToInt({}.{})", _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[elementSel]);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cemu_assert_unimplemented();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( elementSel == 4 )
|
|
||||||
src->add("floatBitsToInt(0.0)");
|
src->add("floatBitsToInt(0.0)");
|
||||||
else if( elementSel == 5 )
|
else if( elementSel == 5 )
|
||||||
src->add("floatBitsToInt(1.0)");
|
src->add("floatBitsToInt(1.0)");
|
||||||
else
|
|
||||||
{
|
|
||||||
cemu_assert_unimplemented();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if( varType == LATTE_DECOMPILER_DTYPE_FLOAT )
|
else if(interpretSrcAsType == LATTE_DECOMPILER_DTYPE_FLOAT )
|
||||||
{
|
{
|
||||||
if (elementSel < 4)
|
if( elementSel == 4 )
|
||||||
{
|
src->add("0.0");
|
||||||
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
|
||||||
src->addFmt("intBitsToFloat({}.{})", _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[elementSel]);
|
|
||||||
else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
|
||||||
src->addFmt("{}.{}", _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[elementSel]);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cemu_assert_unimplemented();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( elementSel == 4 )
|
|
||||||
src->addFmt("0.0");
|
|
||||||
else if( elementSel == 5 )
|
else if( elementSel == 5 )
|
||||||
src->addFmt("1.0");
|
src->add("1.0");
|
||||||
else
|
|
||||||
{
|
|
||||||
cemu_assert_unimplemented();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cemu_assert_unimplemented();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2430,10 +2418,6 @@ void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContext, Latt
|
|||||||
cemu_assert_unimplemented();
|
cemu_assert_unimplemented();
|
||||||
src->add("texture(");
|
src->add("texture(");
|
||||||
}
|
}
|
||||||
if( texInstruction->textureFetch.srcSel[0] >= 4 )
|
|
||||||
cemu_assert_unimplemented();
|
|
||||||
if( texInstruction->textureFetch.srcSel[1] >= 4 )
|
|
||||||
cemu_assert_unimplemented();
|
|
||||||
src->addFmt("{}{}, ", _getTextureUnitVariablePrefixName(shaderContext->shader->shaderType), texInstruction->textureFetch.textureIndex);
|
src->addFmt("{}{}, ", _getTextureUnitVariablePrefixName(shaderContext->shader->shaderType), texInstruction->textureFetch.textureIndex);
|
||||||
|
|
||||||
// for textureGather() add shift (todo: depends on rounding mode set in sampler registers?)
|
// for textureGather() add shift (todo: depends on rounding mode set in sampler registers?)
|
||||||
@ -2455,7 +2439,7 @@ void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContext, Latt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sint32 texCoordDataType = (texOpcode == GPU7_TEX_INST_LD) ? LATTE_DECOMPILER_DTYPE_SIGNED_INT : LATTE_DECOMPILER_DTYPE_FLOAT;
|
||||||
if(useTexelCoordinates)
|
if(useTexelCoordinates)
|
||||||
{
|
{
|
||||||
// handle integer coordinates for texelFetch
|
// handle integer coordinates for texelFetch
|
||||||
@ -2463,9 +2447,9 @@ void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContext, Latt
|
|||||||
{
|
{
|
||||||
src->add("ivec2(");
|
src->add("ivec2(");
|
||||||
src->add("vec2(");
|
src->add("vec2(");
|
||||||
_emitTEXSampleCoordInputComponent(shaderContext, texInstruction, 0, (texOpcode == GPU7_TEX_INST_LD) ? LATTE_DECOMPILER_DTYPE_SIGNED_INT : LATTE_DECOMPILER_DTYPE_FLOAT);
|
_emitTEXSampleCoordInputComponent(shaderContext, texInstruction, 0, texCoordDataType);
|
||||||
src->addFmt(", ");
|
src->addFmt(", ");
|
||||||
_emitTEXSampleCoordInputComponent(shaderContext, texInstruction, 1, (texOpcode == GPU7_TEX_INST_LD) ? LATTE_DECOMPILER_DTYPE_SIGNED_INT : LATTE_DECOMPILER_DTYPE_FLOAT);
|
_emitTEXSampleCoordInputComponent(shaderContext, texInstruction, 1, texCoordDataType);
|
||||||
|
|
||||||
src->addFmt(")*uf_tex{}Scale", texInstruction->textureFetch.textureIndex); // close vec2 and scale
|
src->addFmt(")*uf_tex{}Scale", texInstruction->textureFetch.textureIndex); // close vec2 and scale
|
||||||
|
|
||||||
@ -2485,7 +2469,7 @@ void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContext, Latt
|
|||||||
else
|
else
|
||||||
cemu_assert_debug(false);
|
cemu_assert_debug(false);
|
||||||
}
|
}
|
||||||
else
|
else /* useTexelCoordinates == false */
|
||||||
{
|
{
|
||||||
// float coordinates
|
// float coordinates
|
||||||
if ( (texOpcode == GPU7_TEX_INST_SAMPLE_C || texOpcode == GPU7_TEX_INST_SAMPLE_C_L || texOpcode == GPU7_TEX_INST_SAMPLE_C_LZ) )
|
if ( (texOpcode == GPU7_TEX_INST_SAMPLE_C || texOpcode == GPU7_TEX_INST_SAMPLE_C_L || texOpcode == GPU7_TEX_INST_SAMPLE_C_LZ) )
|
||||||
@ -2549,10 +2533,8 @@ void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContext, Latt
|
|||||||
else if( texDim == Latte::E_DIM::DIM_CUBEMAP )
|
else if( texDim == Latte::E_DIM::DIM_CUBEMAP )
|
||||||
{
|
{
|
||||||
// 2 coords + faceId
|
// 2 coords + faceId
|
||||||
if( texInstruction->textureFetch.srcSel[0] >= 4 || texInstruction->textureFetch.srcSel[1] >= 4 )
|
cemu_assert_debug(texInstruction->textureFetch.srcSel[0] < 4);
|
||||||
{
|
cemu_assert_debug(texInstruction->textureFetch.srcSel[1] < 4);
|
||||||
debugBreakpoint();
|
|
||||||
}
|
|
||||||
src->add("vec4(");
|
src->add("vec4(");
|
||||||
src->addFmt("redcCUBEReverse({},", _getTexGPRAccess(shaderContext, texInstruction->srcGpr, LATTE_DECOMPILER_DTYPE_FLOAT, texInstruction->textureFetch.srcSel[0], texInstruction->textureFetch.srcSel[1], -1, -1, tempBuffer0));
|
src->addFmt("redcCUBEReverse({},", _getTexGPRAccess(shaderContext, texInstruction->srcGpr, LATTE_DECOMPILER_DTYPE_FLOAT, texInstruction->textureFetch.srcSel[0], texInstruction->textureFetch.srcSel[1], -1, -1, tempBuffer0));
|
||||||
_emitTEXSampleCoordInputComponent(shaderContext, texInstruction, 2, LATTE_DECOMPILER_DTYPE_SIGNED_INT);
|
_emitTEXSampleCoordInputComponent(shaderContext, texInstruction, 2, LATTE_DECOMPILER_DTYPE_SIGNED_INT);
|
||||||
@ -2567,8 +2549,11 @@ void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContext, Latt
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 2 coords
|
// 2 coords
|
||||||
src->add(_getTexGPRAccess(shaderContext, texInstruction->srcGpr, LATTE_DECOMPILER_DTYPE_FLOAT, texInstruction->textureFetch.srcSel[0], texInstruction->textureFetch.srcSel[1], -1, -1, tempBuffer0));
|
src->add("vec2(");
|
||||||
|
_emitTEXSampleCoordInputComponent(shaderContext, texInstruction, 0, LATTE_DECOMPILER_DTYPE_FLOAT);
|
||||||
|
src->add(",");
|
||||||
|
_emitTEXSampleCoordInputComponent(shaderContext, texInstruction, 1, LATTE_DECOMPILER_DTYPE_FLOAT);
|
||||||
|
src->add(")");
|
||||||
// avoid truncate to effectively round downwards on texel edges
|
// avoid truncate to effectively round downwards on texel edges
|
||||||
if (ActiveSettings::ForceSamplerRoundToPrecision())
|
if (ActiveSettings::ForceSamplerRoundToPrecision())
|
||||||
src->addFmt("+ vec2(1.0)/vec2(textureSize({}{}, 0))/512.0", _getTextureUnitVariablePrefixName(shaderContext->shader->shaderType), texInstruction->textureFetch.textureIndex);
|
src->addFmt("+ vec2(1.0)/vec2(textureSize({}{}, 0))/512.0", _getTextureUnitVariablePrefixName(shaderContext->shader->shaderType), texInstruction->textureFetch.textureIndex);
|
||||||
@ -2576,9 +2561,8 @@ void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContext, Latt
|
|||||||
// lod or lod bias parameter
|
// lod or lod bias parameter
|
||||||
if( texOpcode == GPU7_TEX_INST_SAMPLE_L || texOpcode == GPU7_TEX_INST_SAMPLE_LB || texOpcode == GPU7_TEX_INST_SAMPLE_C_L)
|
if( texOpcode == GPU7_TEX_INST_SAMPLE_L || texOpcode == GPU7_TEX_INST_SAMPLE_LB || texOpcode == GPU7_TEX_INST_SAMPLE_C_L)
|
||||||
{
|
{
|
||||||
if( texInstruction->textureFetch.srcSel[3] >= 4 )
|
src->add(",");
|
||||||
debugBreakpoint();
|
_emitTEXSampleCoordInputComponent(shaderContext, texInstruction, 3, LATTE_DECOMPILER_DTYPE_FLOAT);
|
||||||
src->addFmt(",{}", _getTexGPRAccess(shaderContext, texInstruction->srcGpr, LATTE_DECOMPILER_DTYPE_FLOAT, texInstruction->textureFetch.srcSel[3], -1, -1, -1, tempBuffer0));
|
|
||||||
}
|
}
|
||||||
else if( texOpcode == GPU7_TEX_INST_SAMPLE_LZ || texOpcode == GPU7_TEX_INST_SAMPLE_C_LZ )
|
else if( texOpcode == GPU7_TEX_INST_SAMPLE_LZ || texOpcode == GPU7_TEX_INST_SAMPLE_C_LZ )
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user