mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-12-24 00:31:52 +01:00
Latte: Add support for LOOP_START_NO_AL shader instruction
This instruction is used by Injustice: Gods Among Us and Project Zero Also improved robustness of rendering to be less prone to crashing when a game tries to draw with broken shaders
This commit is contained in:
parent
60adc38205
commit
fa8bab2f39
@ -340,7 +340,7 @@ uint8 LatteMRT::GetActiveColorBufferMask(const LatteDecompilerShader* pixelShade
|
||||
return 0;
|
||||
cemu_assert_debug(colorControlReg.get_DEGAMMA_ENABLE() == false); // not supported
|
||||
// combine color buffer mask with pixel output mask from pixel shader
|
||||
colorBufferMask &= pixelShader->pixelColorOutputMask;
|
||||
colorBufferMask &= (pixelShader ? pixelShader->pixelColorOutputMask : 0);
|
||||
// combine color buffer mask with color channel mask from mmCB_TARGET_MASK (disable render buffer if all colors are blocked)
|
||||
uint32 channelTargetMask = lcr.CB_TARGET_MASK.get_MASK();
|
||||
for (uint32 i = 0; i < 8; i++)
|
||||
|
@ -12,7 +12,7 @@
|
||||
#define GPU7_CF_INST_VTX (0x02) // used only in GS copy program?
|
||||
#define GPU7_CF_INST_LOOP_END (0x05)
|
||||
#define GPU7_CF_INST_LOOP_START_DX10 (0x06)
|
||||
#define GPU7_CF_INST_LOOP_START_NO_AL (0x07) // (Seen in Project Zero)
|
||||
#define GPU7_CF_INST_LOOP_START_NO_AL (0x07) // (Seen in Project Zero, Injustice: Gods Among Us)
|
||||
|
||||
#define GPU7_CF_INST_LOOP_BREAK (0x09)
|
||||
#define GPU7_CF_INST_JUMP (0x0A)
|
||||
|
@ -101,7 +101,8 @@ bool LatteDecompiler_ParseCFInstruction(LatteDecompilerShaderContext* shaderCont
|
||||
// ignored (we use ALU/IF/ELSE/PUSH/POP clauses to determine code flow)
|
||||
return true;
|
||||
}
|
||||
else if (cf_inst23_7 == GPU7_CF_INST_LOOP_START_DX10 || cf_inst23_7 == GPU7_CF_INST_LOOP_END)
|
||||
else if (cf_inst23_7 == GPU7_CF_INST_LOOP_START_DX10 || cf_inst23_7 == GPU7_CF_INST_LOOP_END ||
|
||||
cf_inst23_7 == GPU7_CF_INST_LOOP_START_NO_AL)
|
||||
{
|
||||
LatteDecompilerCFInstruction& cfInstruction = instructionList.emplace_back();
|
||||
// set type and address
|
||||
@ -966,7 +967,8 @@ void LatteDecompiler_ParseClauses(LatteDecompilerShaderContext* decompilerContex
|
||||
{
|
||||
// no sub-instructions
|
||||
}
|
||||
else if (cfInstruction.type == GPU7_CF_INST_LOOP_START_DX10 || cfInstruction.type == GPU7_CF_INST_LOOP_END)
|
||||
else if (cfInstruction.type == GPU7_CF_INST_LOOP_START_DX10 || cfInstruction.type == GPU7_CF_INST_LOOP_END ||
|
||||
cfInstruction.type == GPU7_CF_INST_LOOP_START_NO_AL)
|
||||
{
|
||||
// no sub-instructions
|
||||
}
|
||||
|
@ -441,7 +441,8 @@ void LatteDecompiler_analyzeSubroutine(LatteDecompilerShaderContext* shaderConte
|
||||
{
|
||||
shaderContext->analyzer.modifiesPixelActiveState = true;
|
||||
}
|
||||
else if (cfInstruction.type == GPU7_CF_INST_LOOP_START_DX10 || cfInstruction.type == GPU7_CF_INST_LOOP_END)
|
||||
else if (cfInstruction.type == GPU7_CF_INST_LOOP_START_DX10 || cfInstruction.type == GPU7_CF_INST_LOOP_END ||
|
||||
cfInstruction.type == GPU7_CF_INST_LOOP_START_NO_AL)
|
||||
{
|
||||
shaderContext->analyzer.modifiesPixelActiveState = true;
|
||||
}
|
||||
@ -685,7 +686,8 @@ void LatteDecompiler_analyze(LatteDecompilerShaderContext* shaderContext, LatteD
|
||||
{
|
||||
shaderContext->analyzer.modifiesPixelActiveState = true;
|
||||
}
|
||||
else if (cfInstruction.type == GPU7_CF_INST_LOOP_START_DX10 || cfInstruction.type == GPU7_CF_INST_LOOP_END)
|
||||
else if (cfInstruction.type == GPU7_CF_INST_LOOP_START_DX10 || cfInstruction.type == GPU7_CF_INST_LOOP_END ||
|
||||
cfInstruction.type == GPU7_CF_INST_LOOP_START_NO_AL)
|
||||
{
|
||||
shaderContext->analyzer.modifiesPixelActiveState = true;
|
||||
shaderContext->analyzer.hasLoops = true;
|
||||
@ -929,7 +931,8 @@ void LatteDecompiler_analyze(LatteDecompilerShaderContext* shaderContext, LatteD
|
||||
if (cfCurrentStackDepth < 0)
|
||||
debugBreakpoint();
|
||||
}
|
||||
else if (cfInstruction.type == GPU7_CF_INST_LOOP_START_DX10 || cfInstruction.type == GPU7_CF_INST_LOOP_END)
|
||||
else if (cfInstruction.type == GPU7_CF_INST_LOOP_START_DX10 || cfInstruction.type == GPU7_CF_INST_LOOP_END ||
|
||||
cfInstruction.type == GPU7_CF_INST_LOOP_START_NO_AL)
|
||||
{
|
||||
// no effect on stack depth
|
||||
cfInstruction.activeStackDepth = cfCurrentStackDepth;
|
||||
|
@ -3662,7 +3662,8 @@ void LatteDecompiler_emitClauseCode(LatteDecompilerShaderContext* shaderContext,
|
||||
{
|
||||
src->addFmt("{} = {} == true && {} == true;" _CRLF, _getActiveMaskCVarName(shaderContext, cfInstruction->activeStackDepth + 1 - cfInstruction->popCount), _getActiveMaskVarName(shaderContext, cfInstruction->activeStackDepth - cfInstruction->popCount), _getActiveMaskCVarName(shaderContext, cfInstruction->activeStackDepth - cfInstruction->popCount));
|
||||
}
|
||||
else if( cfInstruction->type == GPU7_CF_INST_LOOP_START_DX10 )
|
||||
else if( cfInstruction->type == GPU7_CF_INST_LOOP_START_DX10 ||
|
||||
cfInstruction->type == GPU7_CF_INST_LOOP_START_NO_AL)
|
||||
{
|
||||
// start of loop
|
||||
// if pixel is disabled, then skip loop
|
||||
|
@ -1285,9 +1285,9 @@ void VulkanRenderer::draw_beginSequence()
|
||||
|
||||
// update shader state
|
||||
LatteSHRC_UpdateActiveShaders();
|
||||
if (m_state.drawSequenceSkip)
|
||||
if (LatteGPUState.activeShaderHasError)
|
||||
{
|
||||
debug_printf("Skipping drawcalls due to shader error\n");
|
||||
cemuLog_logDebugOnce(LogType::Force, "Skipping drawcalls due to shader error");
|
||||
m_state.drawSequenceSkip = true;
|
||||
cemu_assert_debug(false);
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user