mirror of
https://github.com/cemu-project/Cemu.git
synced 2026-07-10 01:24:41 -06:00
Latte: Widen conditions for fast draw mode
This commit is contained in:
parent
1c7fbafb00
commit
038781a05e
@ -330,19 +330,18 @@ LatteCMDPtr LatteCP_itSetRegistersGeneric(LatteCMDPtr cmd, uint32 nWords)
|
|||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// similar to LatteCP_itSetRegistersGeneric, but calls a callback for every register range checked and returns true ONLY if any register value has actually changed (e.g. not updated to the same value as before)
|
||||||
template<uint32 TRegisterBase, typename TRegRangeCallback>
|
template<uint32 TRegisterBase, typename TRegRangeCallback>
|
||||||
LatteCMDPtr LatteCP_itSetRegistersGeneric(LatteCMDPtr cmd, uint32 nWords, TRegRangeCallback cbRegRange)
|
bool LatteCP_itSetRegistersGeneric2(LatteCMDPtr cmd, uint32 nWords, TRegRangeCallback cbRegRange)
|
||||||
{
|
{
|
||||||
uint32 registerOffset = LatteReadCMD();
|
const uint32 registerOffset = LatteReadCMD();
|
||||||
uint32 registerIndex = TRegisterBase + registerOffset;
|
const uint32 registerIndex = TRegisterBase + registerOffset;
|
||||||
uint32 registerStartIndex = registerIndex;
|
const uint32 registerStartIndex = registerIndex;
|
||||||
uint32 registerEndIndex = registerStartIndex + nWords;
|
const uint32 registerEndIndex = registerStartIndex + nWords;
|
||||||
#ifdef CEMU_DEBUG_ASSERT
|
|
||||||
cemu_assert_debug((registerIndex + nWords) <= LATTE_MAX_REGISTER);
|
cemu_assert_debug((registerIndex + nWords) <= LATTE_MAX_REGISTER);
|
||||||
#endif
|
|
||||||
cbRegRange(registerStartIndex, registerEndIndex);
|
|
||||||
|
|
||||||
uint32* outputReg = (uint32*)(LatteGPUState.contextRegister + registerIndex);
|
uint32* outputReg = (uint32*)(LatteGPUState.contextRegister + registerIndex);
|
||||||
|
bool hasRegChange = false;
|
||||||
if (LatteGPUState.contextControl0 == 0x80000077)
|
if (LatteGPUState.contextControl0 == 0x80000077)
|
||||||
{
|
{
|
||||||
// state shadowing enabled
|
// state shadowing enabled
|
||||||
@ -354,6 +353,7 @@ LatteCMDPtr LatteCP_itSetRegistersGeneric(LatteCMDPtr cmd, uint32 nWords, TRegRa
|
|||||||
MPTR regShadowAddr = shadowAddrs[indexCounter];
|
MPTR regShadowAddr = shadowAddrs[indexCounter];
|
||||||
if (regShadowAddr)
|
if (regShadowAddr)
|
||||||
*(uint32*)(memory_base + regShadowAddr) = _swapEndianU32(dataWord);
|
*(uint32*)(memory_base + regShadowAddr) = _swapEndianU32(dataWord);
|
||||||
|
hasRegChange |= (outputReg[indexCounter] != dataWord);
|
||||||
outputReg[indexCounter] = dataWord;
|
outputReg[indexCounter] = dataWord;
|
||||||
indexCounter++;
|
indexCounter++;
|
||||||
}
|
}
|
||||||
@ -364,13 +364,17 @@ LatteCMDPtr LatteCP_itSetRegistersGeneric(LatteCMDPtr cmd, uint32 nWords, TRegRa
|
|||||||
sint32 indexCounter = 0;
|
sint32 indexCounter = 0;
|
||||||
while (--nWords)
|
while (--nWords)
|
||||||
{
|
{
|
||||||
*outputReg = LatteReadCMD();
|
uint32 dataWord = LatteReadCMD();
|
||||||
|
hasRegChange |= (*outputReg != dataWord);
|
||||||
|
*outputReg = dataWord;
|
||||||
outputReg++;
|
outputReg++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// some register writes trigger special behavior
|
// some register writes trigger special behavior
|
||||||
LatteCP_itSetRegistersGeneric_handleSpecialRanges<TRegisterBase>(registerStartIndex, registerEndIndex);
|
LatteCP_itSetRegistersGeneric_handleSpecialRanges<TRegisterBase>(registerStartIndex, registerEndIndex);
|
||||||
return cmd;
|
// callback
|
||||||
|
cbRegRange(registerStartIndex, registerEndIndex, hasRegChange);
|
||||||
|
return hasRegChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
LatteCMDPtr LatteCP_itIndexType(LatteCMDPtr cmd, uint32 nWords)
|
LatteCMDPtr LatteCP_itIndexType(LatteCMDPtr cmd, uint32 nWords)
|
||||||
@ -973,6 +977,7 @@ void LatteCP_processCommandBuffer_continuousDrawPass(DrawPassContext& drawPassCt
|
|||||||
LatteCMDPtr cmd, cmdStart, cmdEnd;
|
LatteCMDPtr cmd, cmdStart, cmdEnd;
|
||||||
if (!drawPassCtx.PopCurrentCommandQueuePos(cmd, cmdStart, cmdEnd))
|
if (!drawPassCtx.PopCurrentCommandQueuePos(cmd, cmdStart, cmdEnd))
|
||||||
{
|
{
|
||||||
|
// cemuLog_log(LogType::Force, "[FastDrawMode] End due running out of commands");
|
||||||
drawPassCtx.endDrawPass();
|
drawPassCtx.endDrawPass();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -992,16 +997,28 @@ void LatteCP_processCommandBuffer_continuousDrawPass(DrawPassContext& drawPassCt
|
|||||||
{
|
{
|
||||||
case IT_SET_RESOURCE: // attribute buffers, uniform buffers or texture units
|
case IT_SET_RESOURCE: // attribute buffers, uniform buffers or texture units
|
||||||
{
|
{
|
||||||
LatteCP_itSetRegistersGeneric<LATTE_REG_BASE_RESOURCE>(cmdData, nWords, [&drawPassCtx](uint32 registerStart, uint32 registerEnd)
|
LatteCP_itSetRegistersGeneric2<LATTE_REG_BASE_RESOURCE>(cmdData, nWords, [&drawPassCtx](uint32 registerStart, uint32 registerEnd, bool regValuesChanged)
|
||||||
{
|
{
|
||||||
if ((registerStart >= Latte::REGADDR::SQ_TEX_RESOURCE_WORD0_N_PS && registerStart < (Latte::REGADDR::SQ_TEX_RESOURCE_WORD0_N_PS + Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 7)) ||
|
if ((registerStart >= Latte::REGADDR::SQ_TEX_RESOURCE_WORD0_N_PS && registerStart < (Latte::REGADDR::SQ_TEX_RESOURCE_WORD0_N_PS + Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 7)) ||
|
||||||
(registerStart >= Latte::REGADDR::SQ_TEX_RESOURCE_WORD0_N_VS && registerStart < (Latte::REGADDR::SQ_TEX_RESOURCE_WORD0_N_VS + Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 7)) ||
|
(registerStart >= Latte::REGADDR::SQ_TEX_RESOURCE_WORD0_N_VS && registerStart < (Latte::REGADDR::SQ_TEX_RESOURCE_WORD0_N_VS + Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 7)) ||
|
||||||
(registerStart >= Latte::REGADDR::SQ_TEX_RESOURCE_WORD0_N_GS && registerStart < (Latte::REGADDR::SQ_TEX_RESOURCE_WORD0_N_GS + Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 7)))
|
(registerStart >= Latte::REGADDR::SQ_TEX_RESOURCE_WORD0_N_GS && registerStart < (Latte::REGADDR::SQ_TEX_RESOURCE_WORD0_N_GS + Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 7)))
|
||||||
drawPassCtx.endDrawPass(); // texture updates end the current draw sequence
|
{
|
||||||
|
if (regValuesChanged)
|
||||||
|
{
|
||||||
|
// cemuLog_log(LogType::Force, "[FastDrawMode] End due to texture change");
|
||||||
|
drawPassCtx.endDrawPass(); // texture updates end the current draw sequence
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (registerStart >= mmSQ_VTX_ATTRIBUTE_BLOCK_START && registerEnd <= mmSQ_VTX_ATTRIBUTE_BLOCK_END)
|
else if (registerStart >= mmSQ_VTX_ATTRIBUTE_BLOCK_START && registerEnd <= mmSQ_VTX_ATTRIBUTE_BLOCK_END)
|
||||||
drawPassCtx.notifyModifiedVertexBuffer();
|
{
|
||||||
|
if (regValuesChanged)
|
||||||
|
drawPassCtx.notifyModifiedVertexBuffer();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
drawPassCtx.notifyModifiedUniformBuffer();
|
{
|
||||||
|
if (regValuesChanged)
|
||||||
|
drawPassCtx.notifyModifiedUniformBuffer();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
if (!drawPassCtx.isWithinDrawPass())
|
if (!drawPassCtx.isWithinDrawPass())
|
||||||
{
|
{
|
||||||
@ -1042,9 +1059,18 @@ void LatteCP_processCommandBuffer_continuousDrawPass(DrawPassContext& drawPassCt
|
|||||||
}
|
}
|
||||||
case IT_SET_CONTEXT_REG:
|
case IT_SET_CONTEXT_REG:
|
||||||
{
|
{
|
||||||
drawPassCtx.endDrawPass();
|
// LatteCP_itSetRegistersGeneric<LATTE_REG_BASE_CONTEXT>(cmd, nWords);
|
||||||
drawPassCtx.PushCurrentCommandQueuePos(cmdBeforeCommand, cmdStart, cmdEnd);
|
bool hasChanged = LatteCP_itSetRegistersGeneric2<LATTE_REG_BASE_CONTEXT>(cmdData, nWords, [](uint32 registerStart, uint32 registerEnd, bool regValuesChanged){});
|
||||||
return;
|
//cemuLog_log(LogType::Force, "[FastDrawMode] Potential end due to SetContextReg (itHeader {:08x} data {:08x}) -> HasChanged {}", itHeader, (uint32)cmdData[0], hasChanged);
|
||||||
|
// drawPassCtx.endDrawPass();
|
||||||
|
// drawPassCtx.PushCurrentCommandQueuePos(cmdBeforeCommand, cmdStart, cmdEnd);
|
||||||
|
if (hasChanged)
|
||||||
|
{
|
||||||
|
drawPassCtx.endDrawPass();
|
||||||
|
drawPassCtx.PushCurrentCommandQueuePos(cmd, cmdStart, cmdEnd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case IT_INDIRECT_BUFFER_PRIV:
|
case IT_INDIRECT_BUFFER_PRIV:
|
||||||
{
|
{
|
||||||
@ -1052,13 +1078,25 @@ void LatteCP_processCommandBuffer_continuousDrawPass(DrawPassContext& drawPassCt
|
|||||||
LatteCP_itIndirectBuffer(cmdData, nWords, drawPassCtx);
|
LatteCP_itIndirectBuffer(cmdData, nWords, drawPassCtx);
|
||||||
if (!drawPassCtx.PopCurrentCommandQueuePos(cmd, cmdStart, cmdEnd)) // switch to sub buffer
|
if (!drawPassCtx.PopCurrentCommandQueuePos(cmd, cmdStart, cmdEnd)) // switch to sub buffer
|
||||||
cemu_assert_debug(false);
|
cemu_assert_debug(false);
|
||||||
|
break;
|
||||||
//if (!drawPassCtx.isWithinDrawPass())
|
}
|
||||||
// return cmdData;
|
case IT_SET_SAMPLER:
|
||||||
|
{
|
||||||
|
bool hasChanged = LatteCP_itSetRegistersGeneric2<LATTE_REG_BASE_SAMPLER>(cmdData, nWords, [](uint32 registerStart, uint32 registerEnd, bool regValuesChanged){});
|
||||||
|
//cemuLog_log(LogType::Force, "[FastDrawMode] Set sampler (reg change = {} - filtered)", hasChanged);
|
||||||
|
if (hasChanged)
|
||||||
|
{
|
||||||
|
//cemuLog_log(LogType::Force, "[FastDrawMode] End due to sampler change");
|
||||||
|
drawPassCtx.endDrawPass();
|
||||||
|
drawPassCtx.PushCurrentCommandQueuePos(cmd, cmdStart, cmdEnd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
// unsupported command for fast draw
|
// unsupported command for fast draw
|
||||||
|
//cemuLog_log(LogType::Force, "[FastDrawMode] Unallowed command. Data: {:08x} {:08x} {:08x} {:08x} {:08x} {:08x}", (uint32)itHeader, (uint32)cmdData[0], (uint32)cmdData[1], (uint32)cmdData[2], (uint32)cmdData[3], (uint32)cmdData[4], (uint32)cmdData[5]);
|
||||||
|
//cemuLog_log(LogType::Force, "[FastDrawMode] End due to unallowed packet 0x{:08x}", itHeader);
|
||||||
drawPassCtx.endDrawPass();
|
drawPassCtx.endDrawPass();
|
||||||
drawPassCtx.PushCurrentCommandQueuePos(cmdBeforeCommand, cmdStart, cmdEnd);
|
drawPassCtx.PushCurrentCommandQueuePos(cmdBeforeCommand, cmdStart, cmdEnd);
|
||||||
return;
|
return;
|
||||||
@ -1071,6 +1109,7 @@ void LatteCP_processCommandBuffer_continuousDrawPass(DrawPassContext& drawPassCt
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// unsupported command for fast draw
|
// unsupported command for fast draw
|
||||||
|
//cemuLog_log(LogType::Force, "[FastDrawMode] End due to uknown packet 0x{:08x}", itHeader);
|
||||||
drawPassCtx.endDrawPass();
|
drawPassCtx.endDrawPass();
|
||||||
drawPassCtx.PushCurrentCommandQueuePos(cmdBeforeCommand, cmdStart, cmdEnd);
|
drawPassCtx.PushCurrentCommandQueuePos(cmdBeforeCommand, cmdStart, cmdEnd);
|
||||||
return;
|
return;
|
||||||
@ -1167,6 +1206,7 @@ void LatteCP_processCommandBuffer(DrawPassContext& drawPassCtx)
|
|||||||
case IT_DRAW_INDEX_2:
|
case IT_DRAW_INDEX_2:
|
||||||
{
|
{
|
||||||
drawPassCtx.beginDrawPass();
|
drawPassCtx.beginDrawPass();
|
||||||
|
//cemuLog_log(LogType::Force, "[CmdBuf] DrawIndex2");
|
||||||
LatteCP_itDrawIndex2(cmdData, nWords, drawPassCtx);
|
LatteCP_itDrawIndex2(cmdData, nWords, drawPassCtx);
|
||||||
// enter fast draw mode
|
// enter fast draw mode
|
||||||
drawPassCtx.PushCurrentCommandQueuePos(cmd, cmdStart, cmdEnd);
|
drawPassCtx.PushCurrentCommandQueuePos(cmd, cmdStart, cmdEnd);
|
||||||
@ -1179,6 +1219,7 @@ void LatteCP_processCommandBuffer(DrawPassContext& drawPassCtx)
|
|||||||
case IT_DRAW_INDEX_AUTO:
|
case IT_DRAW_INDEX_AUTO:
|
||||||
{
|
{
|
||||||
drawPassCtx.beginDrawPass();
|
drawPassCtx.beginDrawPass();
|
||||||
|
//cemuLog_log(LogType::Force, "[CmdBuf] DrawIndexAuto");
|
||||||
LatteCP_itDrawIndexAuto(cmdData, nWords, drawPassCtx);
|
LatteCP_itDrawIndexAuto(cmdData, nWords, drawPassCtx);
|
||||||
// enter fast draw mode
|
// enter fast draw mode
|
||||||
drawPassCtx.PushCurrentCommandQueuePos(cmd, cmdStart, cmdEnd);
|
drawPassCtx.PushCurrentCommandQueuePos(cmd, cmdStart, cmdEnd);
|
||||||
@ -1192,6 +1233,7 @@ void LatteCP_processCommandBuffer(DrawPassContext& drawPassCtx)
|
|||||||
{
|
{
|
||||||
DrawPassContext drawPassCtx;
|
DrawPassContext drawPassCtx;
|
||||||
drawPassCtx.beginDrawPass();
|
drawPassCtx.beginDrawPass();
|
||||||
|
//cemuLog_log(LogType::Force, "[CmdBuf] DrawIndexImm");
|
||||||
LatteCP_itDrawImmediate(cmdData, nWords, drawPassCtx);
|
LatteCP_itDrawImmediate(cmdData, nWords, drawPassCtx);
|
||||||
drawPassCtx.endDrawPass();
|
drawPassCtx.endDrawPass();
|
||||||
break;
|
break;
|
||||||
@ -1448,6 +1490,7 @@ void LatteCP_ProcessRingbuffer()
|
|||||||
{
|
{
|
||||||
DrawPassContext drawPassCtx;
|
DrawPassContext drawPassCtx;
|
||||||
drawPassCtx.beginDrawPass();
|
drawPassCtx.beginDrawPass();
|
||||||
|
cemuLog_log(LogType::Force, "[TopLevel] DrawIndex2");
|
||||||
LatteCP_itDrawIndex2(cmd, nWords, drawPassCtx);
|
LatteCP_itDrawIndex2(cmd, nWords, drawPassCtx);
|
||||||
drawPassCtx.endDrawPass();
|
drawPassCtx.endDrawPass();
|
||||||
timerRecheck += CP_TIMER_RECHECK / 64;
|
timerRecheck += CP_TIMER_RECHECK / 64;
|
||||||
@ -1457,6 +1500,7 @@ void LatteCP_ProcessRingbuffer()
|
|||||||
{
|
{
|
||||||
DrawPassContext drawPassCtx;
|
DrawPassContext drawPassCtx;
|
||||||
drawPassCtx.beginDrawPass();
|
drawPassCtx.beginDrawPass();
|
||||||
|
cemuLog_log(LogType::Force, "[TopLevel] DrawIndexAuto");
|
||||||
LatteCP_itDrawIndexAuto(cmd, nWords, drawPassCtx);
|
LatteCP_itDrawIndexAuto(cmd, nWords, drawPassCtx);
|
||||||
drawPassCtx.endDrawPass();
|
drawPassCtx.endDrawPass();
|
||||||
timerRecheck += CP_TIMER_RECHECK / 512;
|
timerRecheck += CP_TIMER_RECHECK / 512;
|
||||||
@ -1466,6 +1510,7 @@ void LatteCP_ProcessRingbuffer()
|
|||||||
{
|
{
|
||||||
DrawPassContext drawPassCtx;
|
DrawPassContext drawPassCtx;
|
||||||
drawPassCtx.beginDrawPass();
|
drawPassCtx.beginDrawPass();
|
||||||
|
cemuLog_log(LogType::Force, "[TopLevel] DrawIndexImm");
|
||||||
LatteCP_itDrawImmediate(cmd, nWords, drawPassCtx);
|
LatteCP_itDrawImmediate(cmd, nWords, drawPassCtx);
|
||||||
drawPassCtx.endDrawPass();
|
drawPassCtx.endDrawPass();
|
||||||
timerRecheck += CP_TIMER_RECHECK / 64;
|
timerRecheck += CP_TIMER_RECHECK / 64;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user