mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-01-09 08:29:21 +01:00
implement proper bit cast in shaders
This commit is contained in:
parent
4173675f03
commit
4022755a33
@ -802,7 +802,7 @@ static void _emitOperandInputCode(LatteDecompilerShaderContext* shaderContext, L
|
|||||||
if( currentRegisterElementType == LATTE_DECOMPILER_DTYPE_SIGNED_INT )
|
if( currentRegisterElementType == LATTE_DECOMPILER_DTYPE_SIGNED_INT )
|
||||||
{
|
{
|
||||||
// need to convert (not cast) from int bits to float
|
// need to convert (not cast) from int bits to float
|
||||||
src->add("as_type<float>(");
|
src->add("bitCast<float>(");
|
||||||
}
|
}
|
||||||
else if( currentRegisterElementType == LATTE_DECOMPILER_DTYPE_FLOAT )
|
else if( currentRegisterElementType == LATTE_DECOMPILER_DTYPE_FLOAT )
|
||||||
{
|
{
|
||||||
@ -872,7 +872,7 @@ static void _emitOperandInputCode(LatteDecompilerShaderContext* shaderContext, L
|
|||||||
src->add(_FormatFloatAsConstant(*(float*)&constVal));
|
src->add(_FormatFloatAsConstant(*(float*)&constVal));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
src->addFmt("as_type<float>(0x{:08x})", constVal);
|
src->addFmt("bitCast<float>(0x{:08x})", constVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( GPU7_ALU_SRC_IS_CFILE(aluInstruction->sourceOperand[operandIndex].sel) )
|
else if( GPU7_ALU_SRC_IS_CFILE(aluInstruction->sourceOperand[operandIndex].sel) )
|
||||||
@ -919,11 +919,11 @@ void _emitTypeConversionPrefixMSL(LatteDecompilerShaderContext* shaderContext, s
|
|||||||
return;
|
return;
|
||||||
StringBuf* src = shaderContext->shaderSource;
|
StringBuf* src = shaderContext->shaderSource;
|
||||||
if (sourceType == LATTE_DECOMPILER_DTYPE_FLOAT && destinationType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
if (sourceType == LATTE_DECOMPILER_DTYPE_FLOAT && destinationType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
||||||
src->add("as_type<int>(");
|
src->add("bitCast<int>(");
|
||||||
else if (sourceType == LATTE_DECOMPILER_DTYPE_FLOAT && destinationType == LATTE_DECOMPILER_DTYPE_UNSIGNED_INT)
|
else if (sourceType == LATTE_DECOMPILER_DTYPE_FLOAT && destinationType == LATTE_DECOMPILER_DTYPE_UNSIGNED_INT)
|
||||||
src->add("as_type<uint>(");
|
src->add("bitCast<uint>(");
|
||||||
else if( sourceType == LATTE_DECOMPILER_DTYPE_SIGNED_INT && destinationType == LATTE_DECOMPILER_DTYPE_FLOAT )
|
else if( sourceType == LATTE_DECOMPILER_DTYPE_SIGNED_INT && destinationType == LATTE_DECOMPILER_DTYPE_FLOAT )
|
||||||
src->add("as_type<float>(");
|
src->add("bitCast<float>(");
|
||||||
else if( sourceType == LATTE_DECOMPILER_DTYPE_UNSIGNED_INT && destinationType == LATTE_DECOMPILER_DTYPE_SIGNED_INT )
|
else if( sourceType == LATTE_DECOMPILER_DTYPE_UNSIGNED_INT && destinationType == LATTE_DECOMPILER_DTYPE_SIGNED_INT )
|
||||||
src->add("int(");
|
src->add("int(");
|
||||||
else if( sourceType == LATTE_DECOMPILER_DTYPE_SIGNED_INT && destinationType == LATTE_DECOMPILER_DTYPE_UNSIGNED_INT )
|
else if( sourceType == LATTE_DECOMPILER_DTYPE_SIGNED_INT && destinationType == LATTE_DECOMPILER_DTYPE_UNSIGNED_INT )
|
||||||
@ -1026,7 +1026,7 @@ static void _emitALUOP2InstructionCode(LatteDecompilerShaderContext* shaderConte
|
|||||||
src->add(" = ");
|
src->add(" = ");
|
||||||
if( outputType != LATTE_DECOMPILER_DTYPE_SIGNED_INT )
|
if( outputType != LATTE_DECOMPILER_DTYPE_SIGNED_INT )
|
||||||
debugBreakpoint(); // todo
|
debugBreakpoint(); // todo
|
||||||
src->add("as_type<int>(tempResultf)");
|
src->add("bitCast<int>(tempResultf)");
|
||||||
src->add(";" _CRLF);
|
src->add(";" _CRLF);
|
||||||
}
|
}
|
||||||
else if( aluInstruction->opcode == ALU_OP2_INST_MOVA_INT )
|
else if( aluInstruction->opcode == ALU_OP2_INST_MOVA_INT )
|
||||||
@ -1123,9 +1123,9 @@ static void _emitALUOP2InstructionCode(LatteDecompilerShaderContext* shaderConte
|
|||||||
_emitOperandInputCode(shaderContext, aluInstruction, 0, LATTE_DECOMPILER_DTYPE_FLOAT);
|
_emitOperandInputCode(shaderContext, aluInstruction, 0, LATTE_DECOMPILER_DTYPE_FLOAT);
|
||||||
src->add(");" _CRLF);
|
src->add(");" _CRLF);
|
||||||
// INF becomes 0.0
|
// INF becomes 0.0
|
||||||
src->add("if( isinf(tempResultf) == true && (as_type<int>(tempResultf)&0x80000000) == 0 ) tempResultf = 0.0;" _CRLF);
|
src->add("if( isinf(tempResultf) == true && (bitCast<int>(tempResultf)&0x80000000) == 0 ) tempResultf = 0.0;" _CRLF);
|
||||||
// -INF becomes -0.0
|
// -INF becomes -0.0
|
||||||
src->add("else if( isinf(tempResultf) == true && (as_type<int>(tempResultf)&0x80000000) != 0 ) tempResultf = -0.0;" _CRLF);
|
src->add("else if( isinf(tempResultf) == true && (bitCast<int>(tempResultf)&0x80000000) != 0 ) tempResultf = -0.0;" _CRLF);
|
||||||
// assign result to output
|
// assign result to output
|
||||||
_emitInstructionOutputVariableName(shaderContext, aluInstruction);
|
_emitInstructionOutputVariableName(shaderContext, aluInstruction);
|
||||||
src->add(" = ");
|
src->add(" = ");
|
||||||
@ -1145,14 +1145,14 @@ static void _emitALUOP2InstructionCode(LatteDecompilerShaderContext* shaderConte
|
|||||||
if (aluInstruction->opcode == ALU_OP2_INST_RECIPSQRT_CLAMPED)
|
if (aluInstruction->opcode == ALU_OP2_INST_RECIPSQRT_CLAMPED)
|
||||||
{
|
{
|
||||||
// note: if( -INF < 0.0 ) does not resolve to true
|
// note: if( -INF < 0.0 ) does not resolve to true
|
||||||
src->add("if( isinf(tempResultf) == true && (as_type<int>(tempResultf)&0x80000000) != 0 ) tempResultf = -3.40282347E+38F;" _CRLF);
|
src->add("if( isinf(tempResultf) == true && (bitCast<int>(tempResultf)&0x80000000) != 0 ) tempResultf = -3.40282347E+38F;" _CRLF);
|
||||||
src->add("else if( isinf(tempResultf) == true && (as_type<int>(tempResultf)&0x80000000) == 0 ) tempResultf = 3.40282347E+38F;" _CRLF);
|
src->add("else if( isinf(tempResultf) == true && (bitCast<int>(tempResultf)&0x80000000) == 0 ) tempResultf = 3.40282347E+38F;" _CRLF);
|
||||||
}
|
}
|
||||||
else if (aluInstruction->opcode == ALU_OP2_INST_RECIPSQRT_FF)
|
else if (aluInstruction->opcode == ALU_OP2_INST_RECIPSQRT_FF)
|
||||||
{
|
{
|
||||||
// untested (BotW bombs)
|
// untested (BotW bombs)
|
||||||
src->add("if( isinf(tempResultf) == true && (as_type<int>(tempResultf)&0x80000000) != 0 ) tempResultf = -0.0;" _CRLF);
|
src->add("if( isinf(tempResultf) == true && (bitCast<int>(tempResultf)&0x80000000) != 0 ) tempResultf = -0.0;" _CRLF);
|
||||||
src->add("else if( isinf(tempResultf) == true && (as_type<int>(tempResultf)&0x80000000) == 0 ) tempResultf = 0.0;" _CRLF);
|
src->add("else if( isinf(tempResultf) == true && (bitCast<int>(tempResultf)&0x80000000) == 0 ) tempResultf = 0.0;" _CRLF);
|
||||||
}
|
}
|
||||||
// assign result to output
|
// assign result to output
|
||||||
_emitInstructionOutputVariableName(shaderContext, aluInstruction);
|
_emitInstructionOutputVariableName(shaderContext, aluInstruction);
|
||||||
@ -2002,7 +2002,7 @@ static void _emitALUClauseCode(LatteDecompilerShaderContext* shaderContext, Latt
|
|||||||
{
|
{
|
||||||
_emitInstructionOutputVariableName(shaderContext, &aluInstruction);
|
_emitInstructionOutputVariableName(shaderContext, &aluInstruction);
|
||||||
src->add(" = ");
|
src->add(" = ");
|
||||||
src->add("as_type<int>(as_type<float>(");
|
src->add("bitCast<int>(bitCast<float>(");
|
||||||
_emitInstructionOutputVariableName(shaderContext, &aluInstruction);
|
_emitInstructionOutputVariableName(shaderContext, &aluInstruction);
|
||||||
src->add(")");
|
src->add(")");
|
||||||
if( aluInstruction.omod == 1 )
|
if( aluInstruction.omod == 1 )
|
||||||
@ -2099,9 +2099,9 @@ static void _emitTEXSampleCoordInputComponent(LatteDecompilerShaderContext* shad
|
|||||||
if(interpretSrcAsType == LATTE_DECOMPILER_DTYPE_SIGNED_INT )
|
if(interpretSrcAsType == LATTE_DECOMPILER_DTYPE_SIGNED_INT )
|
||||||
{
|
{
|
||||||
if( elementSel == 4 )
|
if( elementSel == 4 )
|
||||||
src->add("as_type<int>(0.0)");
|
src->add("bitCast<int>(0.0)");
|
||||||
else if( elementSel == 5 )
|
else if( elementSel == 5 )
|
||||||
src->add("as_type<int>(1.0)");
|
src->add("bitCast<int>(1.0)");
|
||||||
}
|
}
|
||||||
else if(interpretSrcAsType == LATTE_DECOMPILER_DTYPE_FLOAT )
|
else if(interpretSrcAsType == LATTE_DECOMPILER_DTYPE_FLOAT )
|
||||||
{
|
{
|
||||||
@ -2116,7 +2116,7 @@ static const char* _texGprAccessElemTable[8] = {"x","y","z","w","_","_","_","_"}
|
|||||||
|
|
||||||
static char* _getTexGPRAccess(LatteDecompilerShaderContext* shaderContext, sint32 gprIndex, uint32 dataType, sint8 selX, sint8 selY, sint8 selZ, sint8 selW, char* tempBuffer)
|
static char* _getTexGPRAccess(LatteDecompilerShaderContext* shaderContext, sint32 gprIndex, uint32 dataType, sint8 selX, sint8 selY, sint8 selZ, sint8 selW, char* tempBuffer)
|
||||||
{
|
{
|
||||||
// as_type<float>(R{}i.w)
|
// bitCast<float>(R{}i.w)
|
||||||
*tempBuffer = '\0';
|
*tempBuffer = '\0';
|
||||||
uint8 elemCount = (selX > 0 ? 1 : 0) + (selY > 0 ? 1 : 0) + (selZ > 0 ? 1 : 0) + (selW > 0 ? 1 : 0);
|
uint8 elemCount = (selX > 0 ? 1 : 0) + (selY > 0 ? 1 : 0) + (selZ > 0 ? 1 : 0) + (selW > 0 ? 1 : 0);
|
||||||
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
||||||
@ -2124,7 +2124,7 @@ static char* _getTexGPRAccess(LatteDecompilerShaderContext* shaderContext, sint3
|
|||||||
if (dataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
if (dataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
||||||
; // no conversion
|
; // no conversion
|
||||||
else if (dataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
else if (dataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
||||||
strcat(tempBuffer, "as_type<float>(");
|
strcat(tempBuffer, "bitCast<float>(");
|
||||||
else
|
else
|
||||||
cemu_assert_unimplemented();
|
cemu_assert_unimplemented();
|
||||||
strcat(tempBuffer, _getRegisterVarName(shaderContext, gprIndex));
|
strcat(tempBuffer, _getRegisterVarName(shaderContext, gprIndex));
|
||||||
@ -2233,13 +2233,13 @@ static void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContex
|
|||||||
shaderContext->shaderSource->addFmt(" = int{}(", numWrittenElements);
|
shaderContext->shaderSource->addFmt(" = int{}(", numWrittenElements);
|
||||||
}
|
}
|
||||||
else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
||||||
src->add(" = as_type<float>(");
|
src->add(" = bitCast<float>(");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// float samplers
|
// float samplers
|
||||||
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
||||||
src->add(" = as_type<int>(");
|
src->add(" = bitCast<int>(");
|
||||||
else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
||||||
src->add(" = (");
|
src->add(" = (");
|
||||||
}
|
}
|
||||||
@ -2665,14 +2665,14 @@ static void _emitTEXGetCompTexLodCode(LatteDecompilerShaderContext* shaderContex
|
|||||||
if(shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
if(shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
||||||
src->addFmt("float4(textureQueryLod(tex{}, {}.{}{}{}),0.0,0.0)", texInstruction->textureFetch.textureIndex, _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]], resultElemTable[texInstruction->textureFetch.srcSel[1]], resultElemTable[texInstruction->textureFetch.srcSel[2]]);
|
src->addFmt("float4(textureQueryLod(tex{}, {}.{}{}{}),0.0,0.0)", texInstruction->textureFetch.textureIndex, _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]], resultElemTable[texInstruction->textureFetch.srcSel[1]], resultElemTable[texInstruction->textureFetch.srcSel[2]]);
|
||||||
else
|
else
|
||||||
src->addFmt("float4(textureQueryLod(tex{}, as_type<float>({}.{}{}{})),0.0,0.0)", texInstruction->textureFetch.textureIndex, _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]], resultElemTable[texInstruction->textureFetch.srcSel[1]], resultElemTable[texInstruction->textureFetch.srcSel[2]]);
|
src->addFmt("float4(textureQueryLod(tex{}, bitCast<float>({}.{}{}{})),0.0,0.0)", texInstruction->textureFetch.textureIndex, _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]], resultElemTable[texInstruction->textureFetch.srcSel[1]], resultElemTable[texInstruction->textureFetch.srcSel[2]]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
||||||
src->addFmt("float4(textureQueryLod(tex{}, {}.{}{}),0.0,0.0)", texInstruction->textureFetch.textureIndex, _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]], resultElemTable[texInstruction->textureFetch.srcSel[1]]);
|
src->addFmt("float4(textureQueryLod(tex{}, {}.{}{}),0.0,0.0)", texInstruction->textureFetch.textureIndex, _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]], resultElemTable[texInstruction->textureFetch.srcSel[1]]);
|
||||||
else
|
else
|
||||||
src->addFmt("float4(textureQueryLod(tex{}, as_type<float>({}.{}{})),0.0,0.0)", texInstruction->textureFetch.textureIndex, _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]], resultElemTable[texInstruction->textureFetch.srcSel[1]]);
|
src->addFmt("float4(textureQueryLod(tex{}, bitCast<float>({}.{}{})),0.0,0.0)", texInstruction->textureFetch.textureIndex, _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]], resultElemTable[texInstruction->textureFetch.srcSel[1]]);
|
||||||
debugBreakpoint();
|
debugBreakpoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2706,7 +2706,7 @@ static void _emitTEXSetCubemapIndexCode(LatteDecompilerShaderContext* shaderCont
|
|||||||
const char* resultElemTable[4] = {"x","y","z","w"};
|
const char* resultElemTable[4] = {"x","y","z","w"};
|
||||||
|
|
||||||
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
||||||
src->addFmt(" = as_type<float>(R{}i.{});" _CRLF, texInstruction->srcGpr, resultElemTable[texInstruction->textureFetch.srcSel[0]]);
|
src->addFmt(" = bitCast<float>(R{}i.{});" _CRLF, texInstruction->srcGpr, resultElemTable[texInstruction->textureFetch.srcSel[0]]);
|
||||||
else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
||||||
src->addFmt(" = R{}f.{};" _CRLF, texInstruction->srcGpr, resultElemTable[texInstruction->textureFetch.srcSel[0]]);
|
src->addFmt(" = R{}f.{};" _CRLF, texInstruction->srcGpr, resultElemTable[texInstruction->textureFetch.srcSel[0]]);
|
||||||
else
|
else
|
||||||
@ -2880,7 +2880,7 @@ static void _emitTEXVFetchCode(LatteDecompilerShaderContext* shaderContext, Latt
|
|||||||
src->add(" = ");
|
src->add(" = ");
|
||||||
|
|
||||||
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
||||||
src->add("as_type<int>(");
|
src->add("bitCast<int>(");
|
||||||
else
|
else
|
||||||
src->add("(");
|
src->add("(");
|
||||||
|
|
||||||
@ -2889,7 +2889,7 @@ static void _emitTEXVFetchCode(LatteDecompilerShaderContext* shaderContext, Latt
|
|||||||
if( shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT )
|
if( shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT )
|
||||||
src->addFmt("{}.{}", _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]]);
|
src->addFmt("{}.{}", _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]]);
|
||||||
else
|
else
|
||||||
src->addFmt("as_type<int>({}.{})", _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]]);
|
src->addFmt("bitCast<int>({}.{})", _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]]);
|
||||||
src->add("].");
|
src->add("].");
|
||||||
|
|
||||||
|
|
||||||
@ -2921,7 +2921,7 @@ static void _emitTEXReadMemCode(LatteDecompilerShaderContext* shaderContext, Lat
|
|||||||
src->add(" = ");
|
src->add(" = ");
|
||||||
|
|
||||||
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
||||||
src->add("as_type<int>(");
|
src->add("bitCast<int>(");
|
||||||
else
|
else
|
||||||
src->add("(");
|
src->add("(");
|
||||||
|
|
||||||
@ -3735,6 +3735,22 @@ void LatteDecompiler_emitHelperFunctions(LatteDecompilerShaderContext* shaderCon
|
|||||||
"return float2(as_type<half>(ushort(as_type<uint>(x) & 0x00FF)), as_type<half>(ushort((as_type<uint>(x) & 0xFF00) >> 16)));\r\n"
|
"return float2(as_type<half>(ushort(as_type<uint>(x) & 0x00FF)), as_type<half>(ushort((as_type<uint>(x) & 0xFF00) >> 16)));\r\n"
|
||||||
"}\r\n");
|
"}\r\n");
|
||||||
|
|
||||||
|
// Bit cast
|
||||||
|
|
||||||
|
// Scalar
|
||||||
|
fCStr_shaderSource->add(""
|
||||||
|
"template<typename ResultT, typename T>\r\n"
|
||||||
|
"ResultT bitCast(T x) {\r\n"
|
||||||
|
"return as_type<ResultT>(x);\r\n"
|
||||||
|
"}\r\n");
|
||||||
|
|
||||||
|
// Vector
|
||||||
|
fCStr_shaderSource->add(""
|
||||||
|
"template<typename ResultComponentT, typename ComponentT, unsigned int componentCount>\r\n"
|
||||||
|
"vec<ResultComponentT, componentCount> bitCast(vec<ComponentT, componentCount> x) {\r\n"
|
||||||
|
"return as_type<vec<ResultComponentT, componentCount>>(x);\r\n"
|
||||||
|
"}\r\n");
|
||||||
|
|
||||||
// mul non-ieee way (0*NaN/INF => 0.0)
|
// mul non-ieee way (0*NaN/INF => 0.0)
|
||||||
if (shaderContext->options->strictMul)
|
if (shaderContext->options->strictMul)
|
||||||
{
|
{
|
||||||
@ -3742,7 +3758,7 @@ void LatteDecompiler_emitHelperFunctions(LatteDecompilerShaderContext* shaderCon
|
|||||||
//fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){ return mix(a*b,0.0,a==0.0||b==0.0); }" STR_LINEBREAK);
|
//fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){ return mix(a*b,0.0,a==0.0||b==0.0); }" STR_LINEBREAK);
|
||||||
//fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){ return mix(vec2(a*b,0.0),vec2(0.0,0.0),(equal(vec2(a),vec2(0.0,0.0))||equal(vec2(b),vec2(0.0,0.0)))).x; }" STR_LINEBREAK);
|
//fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){ return mix(vec2(a*b,0.0),vec2(0.0,0.0),(equal(vec2(a),vec2(0.0,0.0))||equal(vec2(b),vec2(0.0,0.0)))).x; }" STR_LINEBREAK);
|
||||||
//fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){ if( a == 0.0 || b == 0.0 ) return 0.0; return a*b; }" STR_LINEBREAK);
|
//fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){ if( a == 0.0 || b == 0.0 ) return 0.0; return a*b; }" STR_LINEBREAK);
|
||||||
//fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){float r = a*b;r = as_type<float>(floatBitsToInt(r)&(((floatBitsToInt(a) != 0) && (floatBitsToInt(b) != 0))?0xFFFFFFFF:0));return r;}" STR_LINEBREAK); works
|
//fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){float r = a*b;r = bitCast<float>(floatBitsToInt(r)&(((floatBitsToInt(a) != 0) && (floatBitsToInt(b) != 0))?0xFFFFFFFF:0));return r;}" STR_LINEBREAK); works
|
||||||
|
|
||||||
// for "min" it used to be: float mul_nonIEEE(float a, float b){ return min(a*b,min(abs(a)*3.40282347E+38F,abs(b)*3.40282347E+38F)); }
|
// for "min" it used to be: float mul_nonIEEE(float a, float b){ return min(a*b,min(abs(a)*3.40282347E+38F,abs(b)*3.40282347E+38F)); }
|
||||||
|
|
||||||
@ -3978,7 +3994,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext,
|
|||||||
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
||||||
src->addFmt("{} = int4(vid, 0, 0, iid);" _CRLF, _getRegisterVarName(shaderContext, 0));
|
src->addFmt("{} = int4(vid, 0, 0, iid);" _CRLF, _getRegisterVarName(shaderContext, 0));
|
||||||
else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
||||||
src->addFmt("{} = float4(vid, 0, 0, iid);" _CRLF, _getRegisterVarName(shaderContext, 0)); // TODO: as_type<int4>(float4(vid, 0, 0, iid))?
|
src->addFmt("{} = float4(vid, 0, 0, iid);" _CRLF, _getRegisterVarName(shaderContext, 0)); // TODO: bitCast<int4>(float4(vid, 0, 0, iid))?
|
||||||
else
|
else
|
||||||
cemu_assert_unimplemented();
|
cemu_assert_unimplemented();
|
||||||
}
|
}
|
||||||
@ -4021,7 +4037,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext,
|
|||||||
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
||||||
src->addFmt("{} = in.position.xyxy;" _CRLF, _getRegisterVarName(shaderContext, paramGenGPRIndex));
|
src->addFmt("{} = in.position.xyxy;" _CRLF, _getRegisterVarName(shaderContext, paramGenGPRIndex));
|
||||||
else
|
else
|
||||||
src->addFmt("{} = as_type<int4>(gl_PointCoord.xyxy);" _CRLF, _getRegisterVarName(shaderContext, paramGenGPRIndex));
|
src->addFmt("{} = bitCast<int>(gl_PointCoord.xyxy);" _CRLF, _getRegisterVarName(shaderContext, paramGenGPRIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (sint32 i = 0; i < psInputTable->count; i++)
|
for (sint32 i = 0; i < psInputTable->count; i++)
|
||||||
@ -4038,7 +4054,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext,
|
|||||||
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
||||||
src->addFmt("{} = GET_FRAGCOORD();" _CRLF, _getRegisterVarName(shaderContext, gprIndex));
|
src->addFmt("{} = GET_FRAGCOORD();" _CRLF, _getRegisterVarName(shaderContext, gprIndex));
|
||||||
else
|
else
|
||||||
src->addFmt("{} = as_type<int4>(GET_FRAGCOORD());" _CRLF, _getRegisterVarName(shaderContext, gprIndex));
|
src->addFmt("{} = bitCast<int>(GET_FRAGCOORD());" _CRLF, _getRegisterVarName(shaderContext, gprIndex));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4056,7 +4072,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext,
|
|||||||
{
|
{
|
||||||
// import from vertex shader
|
// import from vertex shader
|
||||||
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
||||||
src->addFmt("{} = as_type<int4>(in.passParameterSem{});" _CRLF, _getRegisterVarName(shaderContext, gprIndex), psInputSemanticId);
|
src->addFmt("{} = bitCast<int>(in.passParameterSem{});" _CRLF, _getRegisterVarName(shaderContext, gprIndex), psInputSemanticId);
|
||||||
else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
||||||
src->addFmt("{} = in.passParameterSem{};" _CRLF, _getRegisterVarName(shaderContext, gprIndex), psInputSemanticId);
|
src->addFmt("{} = in.passParameterSem{};" _CRLF, _getRegisterVarName(shaderContext, gprIndex), psInputSemanticId);
|
||||||
else
|
else
|
||||||
@ -4071,7 +4087,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext,
|
|||||||
if (frontFace_allBits)
|
if (frontFace_allBits)
|
||||||
cemu_assert_debug(false);
|
cemu_assert_debug(false);
|
||||||
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
||||||
src->addFmt("{}.{} = as_type<int4>(frontFacing?1.0:0.0);" _CRLF, _getRegisterVarName(shaderContext, frontFace_regIndex), _getElementStrByIndex(frontFace_chan));
|
src->addFmt("{}.{} = bitCast<int>(frontFacing?1.0:0.0);" _CRLF, _getRegisterVarName(shaderContext, frontFace_regIndex), _getElementStrByIndex(frontFace_chan));
|
||||||
else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
||||||
src->addFmt("{}.{} = frontFacing ? 1.0 : 0.0;" _CRLF, _getRegisterVarName(shaderContext, frontFace_regIndex), _getElementStrByIndex(frontFace_chan));
|
src->addFmt("{}.{} = frontFacing ? 1.0 : 0.0;" _CRLF, _getRegisterVarName(shaderContext, frontFace_regIndex), _getElementStrByIndex(frontFace_chan));
|
||||||
else
|
else
|
||||||
|
@ -255,7 +255,8 @@ void LatteDecompiler_emitAttributeDecodeMSL(LatteDecompilerShader* shaderContext
|
|||||||
{
|
{
|
||||||
// seen in Giana Sisters: Twisted Dreams
|
// seen in Giana Sisters: Twisted Dreams
|
||||||
_readLittleEndianAttributeU16x4(shaderContext, src, attributeInputIndex);
|
_readLittleEndianAttributeU16x4(shaderContext, src, attributeInputIndex);
|
||||||
src->add("attrDecoder.xyzw = as_type<int4>(float4(unpackHalf2x16(attrDecoder.x|(attrDecoder.y<<16)),unpackHalf2x16(attrDecoder.z|(attrDecoder.w<<16))));" _CRLF);
|
// TODO: uint4?
|
||||||
|
src->add("attrDecoder.xyzw = as_type<uint4>(float4(unpackHalf2x16(attrDecoder.x|(attrDecoder.y<<16)),unpackHalf2x16(attrDecoder.z|(attrDecoder.w<<16))));" _CRLF);
|
||||||
}
|
}
|
||||||
else if (attrib->format == FMT_16_16 && attrib->nfa == 0 && attrib->isSigned != 0)
|
else if (attrib->format == FMT_16_16 && attrib->nfa == 0 && attrib->isSigned != 0)
|
||||||
{
|
{
|
||||||
@ -305,7 +306,8 @@ void LatteDecompiler_emitAttributeDecodeMSL(LatteDecompilerShader* shaderContext
|
|||||||
else if( attrib->format == FMT_8_8_8_8 && attrib->nfa == 2 && attrib->isSigned == 0 )
|
else if( attrib->format == FMT_8_8_8_8 && attrib->nfa == 2 && attrib->isSigned == 0 )
|
||||||
{
|
{
|
||||||
// seen in One Piece
|
// seen in One Piece
|
||||||
src->addFmt("attrDecoder.xyzw = as_type<int4>(float4(in.attrDataSem{}.xyzw));" _CRLF, attributeInputIndex);
|
// TODO: uint4?
|
||||||
|
src->addFmt("attrDecoder.xyzw = as_type<uint4>(float4(in.attrDataSem{}.xyzw));" _CRLF, attributeInputIndex);
|
||||||
}
|
}
|
||||||
else if (attrib->format == FMT_8_8 && attrib->nfa == 0 && attrib->isSigned == 0)
|
else if (attrib->format == FMT_8_8 && attrib->nfa == 0 && attrib->isSigned == 0)
|
||||||
{
|
{
|
||||||
@ -391,7 +393,8 @@ void LatteDecompiler_emitAttributeDecodeMSL(LatteDecompilerShader* shaderContext
|
|||||||
if( attrib->format == FMT_16_16_16_16_FLOAT && attrib->nfa == 2 )
|
if( attrib->format == FMT_16_16_16_16_FLOAT && attrib->nfa == 2 )
|
||||||
{
|
{
|
||||||
_readBigEndianAttributeU16x4(shaderContext, src, attributeInputIndex);
|
_readBigEndianAttributeU16x4(shaderContext, src, attributeInputIndex);
|
||||||
src->add("attrDecoder.xyzw = as_type<int4>(float4(unpackHalf2x16(attrDecoder.x|(attrDecoder.y<<16)),unpackHalf2x16(attrDecoder.z|(attrDecoder.w<<16))));" _CRLF);
|
// TODO: uint4?
|
||||||
|
src->add("attrDecoder.xyzw = as_type<uint4>(float4(unpackHalf2x16(attrDecoder.x|(attrDecoder.y<<16)),unpackHalf2x16(attrDecoder.z|(attrDecoder.w<<16))));" _CRLF);
|
||||||
}
|
}
|
||||||
else if (attrib->format == FMT_16_16_16_16 && attrib->nfa == 0 && attrib->isSigned != 0)
|
else if (attrib->format == FMT_16_16_16_16 && attrib->nfa == 0 && attrib->isSigned != 0)
|
||||||
{
|
{
|
||||||
|
@ -161,7 +161,7 @@ void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutput
|
|||||||
MTL::Texture* colorRenderTargets[8] = {nullptr};
|
MTL::Texture* colorRenderTargets[8] = {nullptr};
|
||||||
colorRenderTargets[0] = m_drawable->texture();
|
colorRenderTargets[0] = m_drawable->texture();
|
||||||
// If there was already an encoder with these attachment, we should set the viewport and scissor to default, but that shouldn't happen
|
// If there was already an encoder with these attachment, we should set the viewport and scissor to default, but that shouldn't happen
|
||||||
auto renderCommandEncoder = GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr, false);
|
auto renderCommandEncoder = GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr, false, false);
|
||||||
|
|
||||||
// Draw to Metal layer
|
// Draw to Metal layer
|
||||||
renderCommandEncoder->setRenderPipelineState(m_presentPipeline);
|
renderCommandEncoder->setRenderPipelineState(m_presentPipeline);
|
||||||
@ -393,7 +393,7 @@ void MetalRenderer::texture_clearColorSlice(LatteTexture* hostTexture, sint32 sl
|
|||||||
|
|
||||||
MTL::Texture* colorRenderTargets[8] = {nullptr};
|
MTL::Texture* colorRenderTargets[8] = {nullptr};
|
||||||
colorRenderTargets[0] = mtlTexture;
|
colorRenderTargets[0] = mtlTexture;
|
||||||
GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr);
|
GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: use sliceIndex and mipIndex
|
// TODO: use sliceIndex and mipIndex
|
||||||
@ -420,7 +420,7 @@ void MetalRenderer::texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sl
|
|||||||
}
|
}
|
||||||
|
|
||||||
MTL::Texture* colorRenderTargets[8] = {nullptr};
|
MTL::Texture* colorRenderTargets[8] = {nullptr};
|
||||||
GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, mtlTexture);
|
GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, mtlTexture, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
LatteTexture* MetalRenderer::texture_createTextureEx(Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels, uint32 swizzle, Latte::E_HWTILEMODE tileMode, bool isDepth)
|
LatteTexture* MetalRenderer::texture_createTextureEx(Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels, uint32 swizzle, Latte::E_HWTILEMODE tileMode, bool isDepth)
|
||||||
|
@ -232,36 +232,40 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MTL::RenderCommandEncoder* GetRenderCommandEncoder(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* colorRenderTargets[8], MTL::Texture* depthRenderTarget, bool rebindStateIfNewEncoder = true)
|
// Some render passes clear the attachments, forceRecreate is supposed to be used in those cases
|
||||||
|
MTL::RenderCommandEncoder* GetRenderCommandEncoder(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* colorRenderTargets[8], MTL::Texture* depthRenderTarget, bool forceRecreate = false, bool rebindStateIfNewEncoder = true)
|
||||||
{
|
{
|
||||||
EnsureCommandBuffer();
|
EnsureCommandBuffer();
|
||||||
|
|
||||||
// Check if we need to begin a new render pass
|
// Check if we need to begin a new render pass
|
||||||
if (m_commandEncoder)
|
if (m_commandEncoder)
|
||||||
{
|
{
|
||||||
if (m_encoderType == MetalEncoderType::Render)
|
if (!forceRecreate)
|
||||||
{
|
{
|
||||||
bool needsNewRenderPass = false;
|
if (m_encoderType == MetalEncoderType::Render)
|
||||||
for (uint8 i = 0; i < 8; i++)
|
|
||||||
{
|
{
|
||||||
if (colorRenderTargets[i] && (colorRenderTargets[i] != m_state.colorRenderTargets[i]))
|
bool needsNewRenderPass = false;
|
||||||
|
for (uint8 i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
needsNewRenderPass = true;
|
if (colorRenderTargets[i] && (colorRenderTargets[i] != m_state.colorRenderTargets[i]))
|
||||||
break;
|
{
|
||||||
|
needsNewRenderPass = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!needsNewRenderPass)
|
if (!needsNewRenderPass)
|
||||||
{
|
|
||||||
if (depthRenderTarget && (depthRenderTarget != m_state.depthRenderTarget))
|
|
||||||
{
|
{
|
||||||
needsNewRenderPass = true;
|
if (depthRenderTarget && (depthRenderTarget != m_state.depthRenderTarget))
|
||||||
|
{
|
||||||
|
needsNewRenderPass = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!needsNewRenderPass)
|
if (!needsNewRenderPass)
|
||||||
{
|
{
|
||||||
return (MTL::RenderCommandEncoder*)m_commandEncoder;
|
return (MTL::RenderCommandEncoder*)m_commandEncoder;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user