mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-01-07 15:48:15 +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 )
|
||||
{
|
||||
// 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 )
|
||||
{
|
||||
@ -872,7 +872,7 @@ static void _emitOperandInputCode(LatteDecompilerShaderContext* shaderContext, L
|
||||
src->add(_FormatFloatAsConstant(*(float*)&constVal));
|
||||
}
|
||||
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) )
|
||||
@ -919,11 +919,11 @@ void _emitTypeConversionPrefixMSL(LatteDecompilerShaderContext* shaderContext, s
|
||||
return;
|
||||
StringBuf* src = shaderContext->shaderSource;
|
||||
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)
|
||||
src->add("as_type<uint>(");
|
||||
src->add("bitCast<uint>(");
|
||||
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 )
|
||||
src->add("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(" = ");
|
||||
if( outputType != LATTE_DECOMPILER_DTYPE_SIGNED_INT )
|
||||
debugBreakpoint(); // todo
|
||||
src->add("as_type<int>(tempResultf)");
|
||||
src->add("bitCast<int>(tempResultf)");
|
||||
src->add(";" _CRLF);
|
||||
}
|
||||
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);
|
||||
src->add(");" _CRLF);
|
||||
// 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
|
||||
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
|
||||
_emitInstructionOutputVariableName(shaderContext, aluInstruction);
|
||||
src->add(" = ");
|
||||
@ -1145,14 +1145,14 @@ static void _emitALUOP2InstructionCode(LatteDecompilerShaderContext* shaderConte
|
||||
if (aluInstruction->opcode == ALU_OP2_INST_RECIPSQRT_CLAMPED)
|
||||
{
|
||||
// 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("else 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 && (bitCast<int>(tempResultf)&0x80000000) == 0 ) tempResultf = 3.40282347E+38F;" _CRLF);
|
||||
}
|
||||
else if (aluInstruction->opcode == ALU_OP2_INST_RECIPSQRT_FF)
|
||||
{
|
||||
// untested (BotW bombs)
|
||||
src->add("if( isinf(tempResultf) == true && (as_type<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("if( isinf(tempResultf) == true && (bitCast<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
|
||||
_emitInstructionOutputVariableName(shaderContext, aluInstruction);
|
||||
@ -2002,7 +2002,7 @@ static void _emitALUClauseCode(LatteDecompilerShaderContext* shaderContext, Latt
|
||||
{
|
||||
_emitInstructionOutputVariableName(shaderContext, &aluInstruction);
|
||||
src->add(" = ");
|
||||
src->add("as_type<int>(as_type<float>(");
|
||||
src->add("bitCast<int>(bitCast<float>(");
|
||||
_emitInstructionOutputVariableName(shaderContext, &aluInstruction);
|
||||
src->add(")");
|
||||
if( aluInstruction.omod == 1 )
|
||||
@ -2099,9 +2099,9 @@ static void _emitTEXSampleCoordInputComponent(LatteDecompilerShaderContext* shad
|
||||
if(interpretSrcAsType == LATTE_DECOMPILER_DTYPE_SIGNED_INT )
|
||||
{
|
||||
if( elementSel == 4 )
|
||||
src->add("as_type<int>(0.0)");
|
||||
src->add("bitCast<int>(0.0)");
|
||||
else if( elementSel == 5 )
|
||||
src->add("as_type<int>(1.0)");
|
||||
src->add("bitCast<int>(1.0)");
|
||||
}
|
||||
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)
|
||||
{
|
||||
// as_type<float>(R{}i.w)
|
||||
// bitCast<float>(R{}i.w)
|
||||
*tempBuffer = '\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)
|
||||
@ -2124,7 +2124,7 @@ static char* _getTexGPRAccess(LatteDecompilerShaderContext* shaderContext, sint3
|
||||
if (dataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
||||
; // no conversion
|
||||
else if (dataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
||||
strcat(tempBuffer, "as_type<float>(");
|
||||
strcat(tempBuffer, "bitCast<float>(");
|
||||
else
|
||||
cemu_assert_unimplemented();
|
||||
strcat(tempBuffer, _getRegisterVarName(shaderContext, gprIndex));
|
||||
@ -2233,13 +2233,13 @@ static void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContex
|
||||
shaderContext->shaderSource->addFmt(" = int{}(", numWrittenElements);
|
||||
}
|
||||
else if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
||||
src->add(" = as_type<float>(");
|
||||
src->add(" = bitCast<float>(");
|
||||
}
|
||||
else
|
||||
{
|
||||
// float samplers
|
||||
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)
|
||||
src->add(" = (");
|
||||
}
|
||||
@ -2665,14 +2665,14 @@ static void _emitTEXGetCompTexLodCode(LatteDecompilerShaderContext* shaderContex
|
||||
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]]);
|
||||
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
|
||||
{
|
||||
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]]);
|
||||
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();
|
||||
}
|
||||
|
||||
@ -2706,7 +2706,7 @@ static void _emitTEXSetCubemapIndexCode(LatteDecompilerShaderContext* shaderCont
|
||||
const char* resultElemTable[4] = {"x","y","z","w"};
|
||||
|
||||
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)
|
||||
src->addFmt(" = R{}f.{};" _CRLF, texInstruction->srcGpr, resultElemTable[texInstruction->textureFetch.srcSel[0]]);
|
||||
else
|
||||
@ -2880,7 +2880,7 @@ static void _emitTEXVFetchCode(LatteDecompilerShaderContext* shaderContext, Latt
|
||||
src->add(" = ");
|
||||
|
||||
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
||||
src->add("as_type<int>(");
|
||||
src->add("bitCast<int>(");
|
||||
else
|
||||
src->add("(");
|
||||
|
||||
@ -2889,7 +2889,7 @@ static void _emitTEXVFetchCode(LatteDecompilerShaderContext* shaderContext, Latt
|
||||
if( shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT )
|
||||
src->addFmt("{}.{}", _getRegisterVarName(shaderContext, texInstruction->srcGpr), resultElemTable[texInstruction->textureFetch.srcSel[0]]);
|
||||
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("].");
|
||||
|
||||
|
||||
@ -2921,7 +2921,7 @@ static void _emitTEXReadMemCode(LatteDecompilerShaderContext* shaderContext, Lat
|
||||
src->add(" = ");
|
||||
|
||||
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
||||
src->add("as_type<int>(");
|
||||
src->add("bitCast<int>(");
|
||||
else
|
||||
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"
|
||||
"}\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)
|
||||
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(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){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)); }
|
||||
|
||||
@ -3978,7 +3994,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext,
|
||||
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_SIGNED_INT)
|
||||
src->addFmt("{} = int4(vid, 0, 0, iid);" _CRLF, _getRegisterVarName(shaderContext, 0));
|
||||
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
|
||||
cemu_assert_unimplemented();
|
||||
}
|
||||
@ -4021,7 +4037,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext,
|
||||
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
||||
src->addFmt("{} = in.position.xyxy;" _CRLF, _getRegisterVarName(shaderContext, paramGenGPRIndex));
|
||||
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++)
|
||||
@ -4038,7 +4054,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext,
|
||||
if (shaderContext->typeTracker.defaultDataType == LATTE_DECOMPILER_DTYPE_FLOAT)
|
||||
src->addFmt("{} = GET_FRAGCOORD();" _CRLF, _getRegisterVarName(shaderContext, gprIndex));
|
||||
else
|
||||
src->addFmt("{} = as_type<int4>(GET_FRAGCOORD());" _CRLF, _getRegisterVarName(shaderContext, gprIndex));
|
||||
src->addFmt("{} = bitCast<int>(GET_FRAGCOORD());" _CRLF, _getRegisterVarName(shaderContext, gprIndex));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -4056,7 +4072,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext,
|
||||
{
|
||||
// import from vertex shader
|
||||
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)
|
||||
src->addFmt("{} = in.passParameterSem{};" _CRLF, _getRegisterVarName(shaderContext, gprIndex), psInputSemanticId);
|
||||
else
|
||||
@ -4071,7 +4087,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext,
|
||||
if (frontFace_allBits)
|
||||
cemu_assert_debug(false);
|
||||
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)
|
||||
src->addFmt("{}.{} = frontFacing ? 1.0 : 0.0;" _CRLF, _getRegisterVarName(shaderContext, frontFace_regIndex), _getElementStrByIndex(frontFace_chan));
|
||||
else
|
||||
|
@ -255,7 +255,8 @@ void LatteDecompiler_emitAttributeDecodeMSL(LatteDecompilerShader* shaderContext
|
||||
{
|
||||
// seen in Giana Sisters: Twisted Dreams
|
||||
_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)
|
||||
{
|
||||
@ -305,7 +306,8 @@ void LatteDecompiler_emitAttributeDecodeMSL(LatteDecompilerShader* shaderContext
|
||||
else if( attrib->format == FMT_8_8_8_8 && attrib->nfa == 2 && attrib->isSigned == 0 )
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
@ -391,7 +393,8 @@ void LatteDecompiler_emitAttributeDecodeMSL(LatteDecompilerShader* shaderContext
|
||||
if( attrib->format == FMT_16_16_16_16_FLOAT && attrib->nfa == 2 )
|
||||
{
|
||||
_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)
|
||||
{
|
||||
|
@ -161,7 +161,7 @@ void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutput
|
||||
MTL::Texture* colorRenderTargets[8] = {nullptr};
|
||||
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
|
||||
auto renderCommandEncoder = GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr, false);
|
||||
auto renderCommandEncoder = GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr, false, false);
|
||||
|
||||
// Draw to Metal layer
|
||||
renderCommandEncoder->setRenderPipelineState(m_presentPipeline);
|
||||
@ -393,7 +393,7 @@ void MetalRenderer::texture_clearColorSlice(LatteTexture* hostTexture, sint32 sl
|
||||
|
||||
MTL::Texture* colorRenderTargets[8] = {nullptr};
|
||||
colorRenderTargets[0] = mtlTexture;
|
||||
GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr);
|
||||
GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr, true);
|
||||
}
|
||||
|
||||
// TODO: use sliceIndex and mipIndex
|
||||
@ -420,7 +420,7 @@ void MetalRenderer::texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sl
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -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();
|
||||
|
||||
// Check if we need to begin a new render pass
|
||||
if (m_commandEncoder)
|
||||
{
|
||||
if (m_encoderType == MetalEncoderType::Render)
|
||||
if (!forceRecreate)
|
||||
{
|
||||
bool needsNewRenderPass = false;
|
||||
for (uint8 i = 0; i < 8; i++)
|
||||
if (m_encoderType == MetalEncoderType::Render)
|
||||
{
|
||||
if (colorRenderTargets[i] && (colorRenderTargets[i] != m_state.colorRenderTargets[i]))
|
||||
bool needsNewRenderPass = false;
|
||||
for (uint8 i = 0; i < 8; i++)
|
||||
{
|
||||
needsNewRenderPass = true;
|
||||
break;
|
||||
if (colorRenderTargets[i] && (colorRenderTargets[i] != m_state.colorRenderTargets[i]))
|
||||
{
|
||||
needsNewRenderPass = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!needsNewRenderPass)
|
||||
{
|
||||
if (depthRenderTarget && (depthRenderTarget != m_state.depthRenderTarget))
|
||||
if (!needsNewRenderPass)
|
||||
{
|
||||
needsNewRenderPass = true;
|
||||
if (depthRenderTarget && (depthRenderTarget != m_state.depthRenderTarget))
|
||||
{
|
||||
needsNewRenderPass = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!needsNewRenderPass)
|
||||
{
|
||||
return (MTL::RenderCommandEncoder*)m_commandEncoder;
|
||||
if (!needsNewRenderPass)
|
||||
{
|
||||
return (MTL::RenderCommandEncoder*)m_commandEncoder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user