Me again, still trying to figure out some bugs that came up after I have updated my local code base to day 242.
For some reason, introduction of the DEBUG_IF(Renderer_UseSoftware) macro call to the platform layer makes the debug system go bananas. During the cutscene mode the GroundChunks submenu (with the RecomputeOnEXEChange variable) never gets drawn on screen. However, all is well when I remove the macro call at platform level.
It doesn't happen at Day 239 and earlier. After 240-241 the renderer was moved into the third tier and the actual DisplayBufferInWindow call (where Renderer_UseSoftware is used to determine which render path to take) happens after calling DEBUGGameFrameEnd and collating the debug records. So my reasoning is something weird happens to the debug event table during this.
From what I understand, the DEBUGGameFrameEnd function swaps current event array index on the debug event table:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | extern "C" DEBUG_GAME_FRAME_END(DEBUGGameFrameEnd)
{
GlobalDebugTable->CurrentEventArrayIndex = !GlobalDebugTable->CurrentEventArrayIndex;
u64 ArrayIndex_EventIndex = AtomicExchangeU64(&GlobalDebugTable->EventArrayIndex_EventIndex,
(u64)GlobalDebugTable->CurrentEventArrayIndex << 32);
u32 EventArrayIndex = ArrayIndex_EventIndex >> 32;
Assert(EventArrayIndex <= 1);
u32 EventCount = ArrayIndex_EventIndex & 0xFFFFFFFF;
// ... collate stuff
return GlobalDebugTable;
}
|
However, this is how the call to the function looks in the platform layer:
| BEGIN_BLOCK(DebugCollation);
if (Game.DEBUGFrameEnd)
{
GlobalDebugTable = Game.DEBUGFrameEnd(&GameMemory, &Input, &RenderCommands);
}
GlobalDebugTable_.EventArrayIndex_EventIndex = 0;
END_BLOCK(DebugCollation);
|
Why does the EventArrayIndex_EventIndex gets reset when CurrentEventArrayIndex doesn't? GlobalDebugTable_.EventArrayIndex_EventIndex >> 32 would return zero but CurrentEventArrayIndex might be set to one. What am I missing?
The only other reference to EventArrayIndex_EventIndex that I've found in the code base is the AtomicAddU64 in the RecordDebugEvent macro. Code listed below:
| #define RecordDebugEvent(EventType, Block) \
u64 ArrayIndex_EventIndex = AtomicAddU64(&GlobalDebugTable->EventArrayIndex_EventIndex, 1); \
u32 EventIndex = ArrayIndex_EventIndex & 0xFFFFFFFF; \
Assert(EventIndex < ArrayCount(GlobalDebugTable->Events[0])); \
debug_event *Event = GlobalDebugTable->Events[ArrayIndex_EventIndex >> 32] + EventIndex; \
Event->Clock = __rdtsc(); \
Event->Type = (u8)EventType; \
Event->CoreIndex = 0; \
Event->ThreadID = (u16)GetThreadID(); \
Event->GUID = UniqueFileCounterString(); \
Event->BlockName = Block; \
|
I feel like calling RecordDebugEvent on the platform layer messes something up. Why do we even bother with the GlobalDebugTable->CurrentEventArrayIndex if it never gets encoded into EventArrayIndex_EventIndex?
Hopefully, someone familiar with HH's codebase might give me some hints.