mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-12-27 10:11:52 +01:00
Latte: Add support for shader instructions MIN_UINT and MAX_UINT
Seen in the eShop version of Fatal Frame Also made some warnings less spammy since this game seems to trigger it a lot
This commit is contained in:
parent
2065ac5f63
commit
c3e29fb619
@ -370,6 +370,8 @@ bool LatteDecompiler_IsALUTransInstruction(bool isOP3, uint32 opcode)
|
|||||||
opcode == ALU_OP2_INST_LSHR_INT ||
|
opcode == ALU_OP2_INST_LSHR_INT ||
|
||||||
opcode == ALU_OP2_INST_MAX_INT ||
|
opcode == ALU_OP2_INST_MAX_INT ||
|
||||||
opcode == ALU_OP2_INST_MIN_INT ||
|
opcode == ALU_OP2_INST_MIN_INT ||
|
||||||
|
opcode == ALU_OP2_INST_MAX_UINT ||
|
||||||
|
opcode == ALU_OP2_INST_MIN_UINT ||
|
||||||
opcode == ALU_OP2_INST_MOVA_FLOOR ||
|
opcode == ALU_OP2_INST_MOVA_FLOOR ||
|
||||||
opcode == ALU_OP2_INST_MOVA_INT ||
|
opcode == ALU_OP2_INST_MOVA_INT ||
|
||||||
opcode == ALU_OP2_INST_SETE_DX10 ||
|
opcode == ALU_OP2_INST_SETE_DX10 ||
|
||||||
|
@ -140,6 +140,8 @@ bool _isIntegerInstruction(const LatteDecompilerALUInstruction& aluInstruction)
|
|||||||
case ALU_OP2_INST_SUB_INT:
|
case ALU_OP2_INST_SUB_INT:
|
||||||
case ALU_OP2_INST_MAX_INT:
|
case ALU_OP2_INST_MAX_INT:
|
||||||
case ALU_OP2_INST_MIN_INT:
|
case ALU_OP2_INST_MIN_INT:
|
||||||
|
case ALU_OP2_INST_MAX_UINT:
|
||||||
|
case ALU_OP2_INST_MIN_UINT:
|
||||||
case ALU_OP2_INST_SETE_INT:
|
case ALU_OP2_INST_SETE_INT:
|
||||||
case ALU_OP2_INST_SETGT_INT:
|
case ALU_OP2_INST_SETGT_INT:
|
||||||
case ALU_OP2_INST_SETGE_INT:
|
case ALU_OP2_INST_SETGE_INT:
|
||||||
|
@ -1415,19 +1415,23 @@ void _emitALUOP2InstructionCode(LatteDecompilerShaderContext* shaderContext, Lat
|
|||||||
}
|
}
|
||||||
else if( aluInstruction->opcode == ALU_OP2_INST_ADD_INT )
|
else if( aluInstruction->opcode == ALU_OP2_INST_ADD_INT )
|
||||||
_emitALUOperationBinary<LATTE_DECOMPILER_DTYPE_SIGNED_INT>(shaderContext, aluInstruction, " + ");
|
_emitALUOperationBinary<LATTE_DECOMPILER_DTYPE_SIGNED_INT>(shaderContext, aluInstruction, " + ");
|
||||||
else if( aluInstruction->opcode == ALU_OP2_INST_MAX_INT || aluInstruction->opcode == ALU_OP2_INST_MIN_INT )
|
else if( aluInstruction->opcode == ALU_OP2_INST_MAX_INT || aluInstruction->opcode == ALU_OP2_INST_MIN_INT ||
|
||||||
|
aluInstruction->opcode == ALU_OP2_INST_MAX_UINT || aluInstruction->opcode == ALU_OP2_INST_MIN_UINT)
|
||||||
{
|
{
|
||||||
// not verified
|
// not verified
|
||||||
|
bool isUnsigned = aluInstruction->opcode == ALU_OP2_INST_MAX_UINT || aluInstruction->opcode == ALU_OP2_INST_MIN_UINT;
|
||||||
|
auto opType = isUnsigned ? LATTE_DECOMPILER_DTYPE_UNSIGNED_INT : LATTE_DECOMPILER_DTYPE_SIGNED_INT;
|
||||||
_emitInstructionOutputVariableName(shaderContext, aluInstruction);
|
_emitInstructionOutputVariableName(shaderContext, aluInstruction);
|
||||||
if( aluInstruction->opcode == ALU_OP2_INST_MAX_INT )
|
src->add(" = ");
|
||||||
src->add(" = max(");
|
_emitTypeConversionPrefix(shaderContext, opType, outputType);
|
||||||
|
if( aluInstruction->opcode == ALU_OP2_INST_MAX_INT || aluInstruction->opcode == ALU_OP2_INST_MAX_UINT )
|
||||||
|
src->add("max(");
|
||||||
else
|
else
|
||||||
src->add(" = min(");
|
src->add("min(");
|
||||||
_emitTypeConversionPrefix(shaderContext, LATTE_DECOMPILER_DTYPE_SIGNED_INT, outputType);
|
_emitOperandInputCode(shaderContext, aluInstruction, 0, opType);
|
||||||
_emitOperandInputCode(shaderContext, aluInstruction, 0, LATTE_DECOMPILER_DTYPE_SIGNED_INT);
|
|
||||||
src->add(", ");
|
src->add(", ");
|
||||||
_emitOperandInputCode(shaderContext, aluInstruction, 1, LATTE_DECOMPILER_DTYPE_SIGNED_INT);
|
_emitOperandInputCode(shaderContext, aluInstruction, 1, opType);
|
||||||
_emitTypeConversionSuffix(shaderContext, LATTE_DECOMPILER_DTYPE_SIGNED_INT, outputType);
|
_emitTypeConversionSuffix(shaderContext, opType, outputType);
|
||||||
src->add(");" _CRLF);
|
src->add(");" _CRLF);
|
||||||
}
|
}
|
||||||
else if( aluInstruction->opcode == ALU_OP2_INST_SUB_INT )
|
else if( aluInstruction->opcode == ALU_OP2_INST_SUB_INT )
|
||||||
|
@ -60,6 +60,8 @@
|
|||||||
#define ALU_OP2_INST_SUB_INT (0x035) // integer instruction
|
#define ALU_OP2_INST_SUB_INT (0x035) // integer instruction
|
||||||
#define ALU_OP2_INST_MAX_INT (0x036) // integer instruction
|
#define ALU_OP2_INST_MAX_INT (0x036) // integer instruction
|
||||||
#define ALU_OP2_INST_MIN_INT (0x037) // integer instruction
|
#define ALU_OP2_INST_MIN_INT (0x037) // integer instruction
|
||||||
|
#define ALU_OP2_INST_MAX_UINT (0x038) // integer instruction
|
||||||
|
#define ALU_OP2_INST_MIN_UINT (0x039) // integer instruction
|
||||||
#define ALU_OP2_INST_SETE_INT (0x03A) // integer instruction
|
#define ALU_OP2_INST_SETE_INT (0x03A) // integer instruction
|
||||||
#define ALU_OP2_INST_SETGT_INT (0x03B) // integer instruction
|
#define ALU_OP2_INST_SETGT_INT (0x03B) // integer instruction
|
||||||
#define ALU_OP2_INST_SETGE_INT (0x03C) // integer instruction
|
#define ALU_OP2_INST_SETGE_INT (0x03C) // integer instruction
|
||||||
|
@ -421,7 +421,7 @@ namespace GX2
|
|||||||
{
|
{
|
||||||
if(aluRegisterOffset&0x8000)
|
if(aluRegisterOffset&0x8000)
|
||||||
{
|
{
|
||||||
cemuLog_logDebug(LogType::Force, "_GX2SubmitUniformReg(): Unhandled loop const special case or invalid offset");
|
cemuLog_logDebugOnce(LogType::Force, "_GX2SubmitUniformReg(): Unhandled loop const special case or invalid offset");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if((aluRegisterOffset+sizeInU32s) > 0x400)
|
if((aluRegisterOffset+sizeInU32s) > 0x400)
|
||||||
|
@ -408,7 +408,7 @@ bool VPADController::push_rumble(uint8* pattern, uint8 length)
|
|||||||
std::scoped_lock lock(m_rumble_mutex);
|
std::scoped_lock lock(m_rumble_mutex);
|
||||||
if (m_rumble_queue.size() >= 5)
|
if (m_rumble_queue.size() >= 5)
|
||||||
{
|
{
|
||||||
cemuLog_logDebug(LogType::Force, "too many cmds");
|
cemuLog_logDebugOnce(LogType::Force, "VPADControlMotor(): Pattern too long");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user