mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-12-11 16:37:02 +00:00
Latte: Instance count minimum is 1
Previously we skipped drawcalls when the instance count was set to zero. But the hardware register enforces a minimum of 1. Fixes black screen in "Cubit The Hardcore Platformer Robot" which does all it's drawcalls with an hardcoded instance count of 0.
This commit is contained in:
parent
5bf58c3d20
commit
47b8d911b9
5 changed files with 15 additions and 28 deletions
|
|
@ -27,11 +27,6 @@ struct LatteGPUState_t
|
|||
uint32 contextControl1;
|
||||
// optional features
|
||||
bool allowFramebufferSizeOptimization{false}; // allow using scissor box as size hint to determine non-padded rendertarget size
|
||||
// draw context
|
||||
struct
|
||||
{
|
||||
uint32 numInstances;
|
||||
}drawContext;
|
||||
// stats
|
||||
uint32 frameCounter;
|
||||
uint32 flipCounter; // increased by one everytime a vsync + flip happens
|
||||
|
|
|
|||
|
|
@ -62,16 +62,7 @@ public:
|
|||
{
|
||||
uint32 baseVertex = LatteGPUState.contextRegister[mmSQ_VTX_BASE_VTX_LOC];
|
||||
uint32 baseInstance = LatteGPUState.contextRegister[mmSQ_VTX_START_INST_LOC];
|
||||
uint32 numInstances = LatteGPUState.drawContext.numInstances;
|
||||
if (numInstances == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
if (GetAsyncKeyState('B'))
|
||||
{
|
||||
cemuLog_force("[executeDraw] {} Count {} BaseVertex {} BaseInstance {}", m_isFirstDraw?"Init":"Fast", count, baseVertex, baseInstance);
|
||||
}
|
||||
*/
|
||||
uint32 numInstances = LatteGPUState.contextNew.VGT_DMA_NUM_INSTANCES.get_NUM_INSTANCES();
|
||||
|
||||
if (!isAutoIndex)
|
||||
{
|
||||
|
|
@ -391,7 +382,10 @@ LatteCMDPtr LatteCP_itIndexType(LatteCMDPtr cmd, uint32 nWords)
|
|||
LatteCMDPtr LatteCP_itNumInstances(LatteCMDPtr cmd, uint32 nWords)
|
||||
{
|
||||
cemu_assert_debug(nWords == 1);
|
||||
LatteGPUState.drawContext.numInstances = LatteReadCMD();
|
||||
uint32 numInstances = LatteReadCMD();
|
||||
if (numInstances == 0)
|
||||
numInstances = 1;
|
||||
LatteGPUState.contextNew.VGT_DMA_NUM_INSTANCES.set_NUM_INSTANCES(numInstances);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
|
@ -690,9 +684,6 @@ LatteCMDPtr LatteCP_itDrawIndexAuto(LatteCMDPtr cmd, uint32 nWords, DrawPassCont
|
|||
cemu_assert_debug(nWords == 2);
|
||||
uint32 count = LatteReadCMD();
|
||||
uint32 ukn = LatteReadCMD();
|
||||
|
||||
if (LatteGPUState.drawContext.numInstances == 0)
|
||||
return cmd;
|
||||
LatteGPUState.currentDrawCallTick = GetTickCount();
|
||||
// todo - better way to identify compute drawcalls
|
||||
if ((LatteGPUState.contextRegister[mmSQ_CONFIG] >> 24) == 0xE4)
|
||||
|
|
@ -750,13 +741,7 @@ LatteCMDPtr LatteCP_itDrawImmediate(LatteCMDPtr cmd, uint32 nWords, DrawPassCont
|
|||
cemuLog_log(LogType::Force, "itDrawImmediate - Unsupported index type");
|
||||
return cmd;
|
||||
}
|
||||
// verify packet size
|
||||
if (nWords != (2 + numIndexU32s))
|
||||
debugBreakpoint();
|
||||
|
||||
uint32 baseVertex = LatteGPUState.contextRegister[mmSQ_VTX_BASE_VTX_LOC];
|
||||
uint32 baseInstance = LatteGPUState.contextRegister[mmSQ_VTX_START_INST_LOC];
|
||||
uint32 numInstances = LatteGPUState.drawContext.numInstances;
|
||||
cemu_assert_debug(nWords == (2 + numIndexU32s)); // verify packet size
|
||||
|
||||
drawPassCtx.executeDraw(count, false, _tempIndexArrayMPTR);
|
||||
return cmd;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ void Latte_LoadInitialRegisters()
|
|||
{
|
||||
LatteGPUState.contextNew.CB_TARGET_MASK.set_MASK(0xFFFFFFFF);
|
||||
LatteGPUState.contextNew.VGT_MULTI_PRIM_IB_RESET_INDX.set_RESTART_INDEX(0xFFFFFFFF);
|
||||
LatteGPUState.contextNew.VGT_DMA_NUM_INSTANCES.set_NUM_INSTANCES(1);
|
||||
LatteGPUState.contextRegister[Latte::REGADDR::PA_CL_CLIP_CNTL] = 0;
|
||||
*(float*)&LatteGPUState.contextRegister[mmDB_DEPTH_CLEAR] = 1.0f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -445,6 +445,7 @@ namespace Latte
|
|||
VGT_DMA_INDEX_TYPE = 0xA29F, // todo - verify offset
|
||||
|
||||
VGT_PRIMITIVEID_EN = 0xA2A1,
|
||||
VGT_DMA_NUM_INSTANCES = 0xA2A2,
|
||||
|
||||
VGT_MULTI_PRIM_IB_RESET_EN = 0xA2A5,
|
||||
|
||||
|
|
@ -977,6 +978,11 @@ float get_##__regname() const \
|
|||
LATTE_BITFIELD_BOOL(PRIMITIVEID_EN, 0);
|
||||
};
|
||||
|
||||
struct LATTE_VGT_DMA_NUM_INSTANCES : LATTEREG // 0xA2A2
|
||||
{
|
||||
LATTE_BITFIELD_FULL_TYPED(NUM_INSTANCES, uint32);
|
||||
};
|
||||
|
||||
struct LATTE_VGT_MULTI_PRIM_IB_RESET_EN : LATTEREG // 0xA2A5
|
||||
{
|
||||
LATTE_BITFIELD_BOOL(RESET_EN, 0);
|
||||
|
|
@ -1541,7 +1547,7 @@ struct LatteContextRegister
|
|||
/* +0x28A7C */ Latte::LATTE_VGT_DMA_INDEX_TYPE VGT_DMA_INDEX_TYPE;
|
||||
/* +0x28A80 */ uint32 ukn28A80;
|
||||
/* +0x28A84 */ Latte::LATTE_VGT_PRIMITIVEID_EN VGT_PRIMITIVEID_EN;
|
||||
/* +0x28A88 */ uint32 ukn28A88;
|
||||
/* +0x28A88 */ Latte::LATTE_VGT_DMA_NUM_INSTANCES VGT_DMA_NUM_INSTANCES;
|
||||
/* +0x28A8C */ uint32 ukn28A8C;
|
||||
/* +0x28A90 */ uint32 ukn28A90;
|
||||
/* +0x28A94 */ Latte::LATTE_VGT_MULTI_PRIM_IB_RESET_EN VGT_MULTI_PRIM_IB_RESET_EN;
|
||||
|
|
@ -1611,6 +1617,7 @@ static_assert(offsetof(LatteContextRegister, PA_SC_GENERIC_SCISSOR_TL) == Latte:
|
|||
static_assert(offsetof(LatteContextRegister, PA_SC_GENERIC_SCISSOR_BR) == Latte::REGADDR::PA_SC_GENERIC_SCISSOR_BR * 4);
|
||||
static_assert(offsetof(LatteContextRegister, VGT_MULTI_PRIM_IB_RESET_INDX) == Latte::REGADDR::VGT_MULTI_PRIM_IB_RESET_INDX * 4);
|
||||
static_assert(offsetof(LatteContextRegister, VGT_PRIMITIVEID_EN) == Latte::REGADDR::VGT_PRIMITIVEID_EN * 4);
|
||||
static_assert(offsetof(LatteContextRegister, VGT_DMA_NUM_INSTANCES) == Latte::REGADDR::VGT_DMA_NUM_INSTANCES * 4);
|
||||
static_assert(offsetof(LatteContextRegister, VGT_MULTI_PRIM_IB_RESET_EN) == Latte::REGADDR::VGT_MULTI_PRIM_IB_RESET_EN * 4);
|
||||
static_assert(offsetof(LatteContextRegister, VGT_INSTANCE_STEP_RATE_0) == Latte::REGADDR::VGT_INSTANCE_STEP_RATE_0 * 4);
|
||||
static_assert(offsetof(LatteContextRegister, VGT_INSTANCE_STEP_RATE_1) == Latte::REGADDR::VGT_INSTANCE_STEP_RATE_1 * 4);
|
||||
|
|
|
|||
|
|
@ -1331,7 +1331,6 @@ void wxGameList::AsyncWorkerThread()
|
|||
else
|
||||
{
|
||||
cemuLog_log(LogType::Force, "Failed to load icon for title {:016x}", titleId);
|
||||
cemu_assert_debug(false);
|
||||
}
|
||||
titleInfo.Unmount(tempMountPath);
|
||||
// notify UI about loaded icon
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue