Add better debug cycle diagnostics API
This commit is contained in:
parent
9b4072f5bc
commit
1c1ee6b5e3
@ -959,41 +959,56 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
|
||||
DTR_DEBUG_EP_TIMED_FUNCTION();
|
||||
if (!memory->isInit)
|
||||
{
|
||||
DebugTestStrToF32Converter();
|
||||
DTR_DEBUG_EP_TIMED_BLOCK("DTR_Update Memory Initialisation");
|
||||
|
||||
DTRAsset_InitGlobalState();
|
||||
|
||||
memory->isInit = true;
|
||||
memory->context = DqnMemStack_Push(&memory->mainStack, sizeof(DTRState));
|
||||
memory->isInit = (memory->context) ? true : false;
|
||||
|
||||
if (!memory->isInit) return;
|
||||
state = (DTRState *)memory->context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Init Memory Stacks
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
DqnMemStack *const assetStack = &memory->assetStack;
|
||||
DqnMemStack *const tempStack = &memory->tempStack;
|
||||
DQN_ASSERT(memory->context);
|
||||
state = (DTRState *)memory->context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Init Assets
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
DTRAsset_InitGlobalState();
|
||||
DTRAsset_LoadFontToBitmap(input->api, &memory->mainStack, tempStack, &state->font,
|
||||
"Roboto-bold.ttf", DqnV2i_2i(256, 256), DqnV2i_2i(' ', '~'), 12);
|
||||
DTRAsset_LoadBitmap(input->api, assetStack,
|
||||
tempStack, &state->bitmap, "tree00.bmp");
|
||||
|
||||
if (DTR_DEBUG)
|
||||
{
|
||||
DTRBitmap test = {};
|
||||
DqnTempMemStack tmp = DqnMemStack_BeginTempRegion(&memory->tempStack);
|
||||
DTRAsset_LoadBitmap(input->api, assetStack, &memory->tempStack, &test, "byte_read_check.bmp");
|
||||
DqnMemStack_EndTempRegion(tmp);
|
||||
}
|
||||
|
||||
if (DTRAsset_LoadWavefrontObj(input->api, assetStack, &state->mesh, "african_head.obj"))
|
||||
{
|
||||
DTRAsset_LoadBitmap(input->api, assetStack, tempStack, &state->mesh.tex,
|
||||
"african_head_diffuse.tga");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Init Debug
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
if (DTR_DEBUG)
|
||||
{
|
||||
DebugTestStrToF32Converter();
|
||||
DTRDebug_TestMeshFaceAndVertexParser(&state->mesh);
|
||||
|
||||
DqnTempMemStack tmp = DqnMemStack_BeginTempRegion(&memory->tempStack);
|
||||
DTRBitmap test = {};
|
||||
DTRAsset_LoadBitmap(input->api, assetStack, &memory->tempStack, &test, "byte_read_check.bmp");
|
||||
DqnMemStack_EndTempRegion(tmp);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
DqnTempMemStack transMemTmpRegion = DqnMemStack_BeginTempRegion(&memory->tempStack);
|
||||
DqnTempMemStack tempStackMemRegion = DqnMemStack_BeginTempRegion(&memory->tempStack);
|
||||
|
||||
size_t debugSize = DQN_MEGABYTE(1);
|
||||
u8 *debugMemory = (u8 *)DqnMemStack_Push(&memory->tempStack, debugSize);
|
||||
DqnMemStack_InitWithFixedMem(&globalDebug.memStack, debugMemory, debugSize);
|
||||
DTRDebug_BeginCycleCount("DTR_Update", DTRDebugCycleCount_DTR_Update);
|
||||
|
||||
DTRRenderBuffer renderBuffer = {};
|
||||
renderBuffer.width = platformRenderBuffer->width;
|
||||
@ -1006,7 +1021,6 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
|
||||
zBufferSize * sizeof(*renderBuffer.zBuffer));
|
||||
|
||||
for (u32 i = 0; i < zBufferSize; i++) renderBuffer.zBuffer[i] = DQN_F32_MIN;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Update and Render
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@ -1034,15 +1048,22 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
|
||||
DTRRenderTransform rotatingXform = DTRRender_DefaultTriangleTransform();
|
||||
rotatingXform.rotation = rotation;
|
||||
|
||||
if (0)
|
||||
{
|
||||
DTRDebug_BeginCycleCount("DTR_Update_RenderPrimitiveTriangles",
|
||||
DTRDebugCycleCount_DTR_Update_RenderPrimitiveTriangles);
|
||||
DTRRender_Triangle(&renderBuffer, t0[0], t0[1], t0[2], colorRed);
|
||||
DTRRender_Triangle(&renderBuffer, t1[0], t1[1], t1[2], colorRed);
|
||||
DTRRender_Triangle(&renderBuffer, t3[0], t3[1], t3[2], colorRed, rotatingXform);
|
||||
DTRRender_Triangle(&renderBuffer, t2[0], t2[1], t2[2], colorRed);
|
||||
DTRRender_Triangle(&renderBuffer, t4[0], t4[1], t4[2], colorRed);
|
||||
DTRRender_Triangle(&renderBuffer, t5[0], t5[1], t5[2], colorRed);
|
||||
DTRDebug_EndCycleCount(DTRDebugCycleCount_DTR_Update_RenderPrimitiveTriangles);
|
||||
}
|
||||
|
||||
if (1)
|
||||
{
|
||||
DTRDebug_BeginCycleCount("DTR_Update_RenderModel", DTRDebugCycleCount_DTR_Update_RenderModel);
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Draw Loaded Model
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@ -1052,6 +1073,7 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
|
||||
DqnV3 modelP = DqnV3_3f(renderBuffer.width * 0.5f, renderBuffer.height * 0.5f, 0);
|
||||
|
||||
DTRRender_Mesh(&renderBuffer, mesh, modelP, MODEL_SCALE, LIGHT);
|
||||
DTRDebug_EndCycleCount(DTRDebugCycleCount_DTR_Update_RenderModel);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1083,14 +1105,12 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
|
||||
#else
|
||||
// CompAssignment(renderBuffer, input, memory);
|
||||
#endif
|
||||
|
||||
DTRDebug_EndCycleCount(DTRDebugCycleCount_DTR_Update);
|
||||
DTRDebug_Update(state, &renderBuffer, input, memory);
|
||||
DqnMemStack_EndTempRegion(tempStackMemRegion);
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// End Update
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
DqnMemStack_EndTempRegion(transMemTmpRegion);
|
||||
DqnMemStack_ClearCurrBlock(&memory->tempStack, true);
|
||||
|
||||
for (i32 i = 0; i < DQN_ARRAY_COUNT(memory->stacks); i++)
|
||||
DQN_ASSERT(memory->stacks[i].tempStackCount == 0);
|
||||
}
|
||||
|
@ -115,22 +115,30 @@ void DTRDebug_PushText(const char *const formatStr, ...)
|
||||
}
|
||||
}
|
||||
|
||||
void inline DTRDebug_BeginCycleCount(enum DTRDebugCycleCount tag)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4127)
|
||||
void inline DTRDebug_BeginCycleCount(char *title, enum DTRDebugCycleCount tag)
|
||||
{
|
||||
if (DTR_DEBUG_PROFILING)
|
||||
if (DTR_DEBUG && DTR_DEBUG_PROFILING)
|
||||
{
|
||||
if (globalDTRPlatformFlags.canUseRdtsc)
|
||||
{
|
||||
DTRDebugCycles *const cycles = &globalDebug.cycles[tag];
|
||||
cycles->tmpStartCycles = __rdtsc();
|
||||
cycles->numInvokes++;
|
||||
|
||||
if (!cycles->name)
|
||||
{
|
||||
cycles->name = (char *)DqnMemStack_Push(&globalDebug.memStack, 128 * sizeof(char));
|
||||
if (cycles->name) Dqn_sprintf(cycles->name, "%s", title);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void inline DTRDebug_EndCycleCount(enum DTRDebugCycleCount tag)
|
||||
{
|
||||
if (DTR_DEBUG_PROFILING)
|
||||
if (DTR_DEBUG && DTR_DEBUG_PROFILING)
|
||||
{
|
||||
if (globalDTRPlatformFlags.canUseRdtsc)
|
||||
{
|
||||
@ -139,6 +147,7 @@ void inline DTRDebug_EndCycleCount(enum DTRDebugCycleCount tag)
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning(pop)
|
||||
|
||||
FILE_SCOPE void PushMemStackText(const char *const name, const DqnMemStack *const stack)
|
||||
{
|
||||
@ -201,6 +210,7 @@ void DTRDebug_Update(DTRState *const state,
|
||||
PushMemStackText("MainStack", &memory->mainStack);
|
||||
PushMemStackText("TempStack", &memory->tempStack);
|
||||
PushMemStackText("AssetStack", &memory->assetStack);
|
||||
PushMemStackText("DebugStack", &debug->memStack);
|
||||
}
|
||||
|
||||
DTRDebug_PushText("Mouse: %d, %d", input->mouse.x, input->mouse.y);
|
||||
@ -224,7 +234,12 @@ void DTRDebug_Update(DTRState *const state,
|
||||
|
||||
u64 invocations = (cycles->numInvokes == 0) ? 1 : cycles->numInvokes;
|
||||
u64 avgCycles = cycles->totalCycles / invocations;
|
||||
DTRDebug_PushText("%d: %'lld avg cycles", i, avgCycles);
|
||||
|
||||
if (avgCycles > 0)
|
||||
{
|
||||
DTRDebug_PushText("%d:%s: %'lld avg cycles", i, cycles->name, avgCycles);
|
||||
}
|
||||
cycles->name = NULL;
|
||||
|
||||
// *cycles = emptyDebugCycles;
|
||||
}
|
||||
|
@ -43,10 +43,13 @@ enum DTRDebugCounter
|
||||
|
||||
enum DTRDebugCycleCount
|
||||
{
|
||||
DTRDebugCycleCount_RenderTexturedTriangle_Rasterise,
|
||||
DTRDebugCycleCount_RenderTexturedTriangle_SampleTextureFunction,
|
||||
DTRDebugCycleCount_RenderTexturedTriangle_SampleTexture,
|
||||
DTRDebugCycleCount_RenderTriangle_Rasterise,
|
||||
DTRDebugCycleCount_DTR_Update,
|
||||
DTRDebugCycleCount_DTR_Update_RenderModel,
|
||||
DTRDebugCycleCount_DTR_Update_RenderPrimitiveTriangles,
|
||||
DTRDebugCycleCount_SIMD_TexturedTriangle,
|
||||
DTRDebugCycleCount_SIMD_TexturedTriangle_Rasterise,
|
||||
DTRDebugCycleCount_SIMD_TexturedTriangle_RasterisePixel,
|
||||
DTRDebugCycleCount_SIMD_TexturedTriangle_SampleTexture,
|
||||
DTRDebugCycleCount_Count,
|
||||
};
|
||||
|
||||
@ -64,6 +67,7 @@ typedef struct DTRDebug
|
||||
struct DTRFont *font;
|
||||
struct DTRRenderBuffer *renderBuffer;
|
||||
struct PlatformInput *input;
|
||||
DqnMemStack memStack;
|
||||
|
||||
DqnV4 displayColor;
|
||||
DqnV2 displayP;
|
||||
@ -80,7 +84,7 @@ void DTRDebug_TestMeshFaceAndVertexParser(struct DTRMesh *const mesh);
|
||||
void DTRDebug_DumpZBuffer (struct DTRRenderBuffer *const renderBuffer, struct DqnMemStack *const transMemStack);
|
||||
void DTRDebug_PushText (const char *const formatStr, ...);
|
||||
void DTRDebug_Update (struct DTRState *const state, struct DTRRenderBuffer *const renderBuffer, struct PlatformInput *const input, struct PlatformMemory *const memory);
|
||||
void inline DTRDebug_BeginCycleCount (enum DTRDebugCycleCount tag);
|
||||
void inline DTRDebug_BeginCycleCount (char *title, enum DTRDebugCycleCount tag);
|
||||
void inline DTRDebug_EndCycleCount (enum DTRDebugCycleCount tag);
|
||||
void inline DTRDebug_CounterIncrement (enum DTRDebugCounter tag);
|
||||
|
||||
|
@ -1002,7 +1002,9 @@ FILE_SCOPE __m128 SIMD_SampleTextureForTriangle(DTRBitmap *const texture, const
|
||||
const DqnV2 uv2SubUv1, const DqnV2 uv3SubUv1,
|
||||
const __m128 barycentric)
|
||||
{
|
||||
DTRDebug_BeginCycleCount(DTRDebugCycleCount_RenderTexturedTriangle_SampleTextureFunction);
|
||||
DTRDebug_BeginCycleCount("SIMD_TexturedTriangle_SampleTexture",
|
||||
DTRDebugCycleCount_SIMD_TexturedTriangle_SampleTexture);
|
||||
|
||||
LOCAL_PERSIST const __m128 INV255_4X = _mm_set_ps1(1.0f / 255.0f);
|
||||
|
||||
const f32 barycentricP2 = ((f32 *)&barycentric)[1];
|
||||
@ -1033,7 +1035,7 @@ FILE_SCOPE __m128 SIMD_SampleTextureForTriangle(DTRBitmap *const texture, const
|
||||
(f32)((texel1 >> 0) & 0xFF));
|
||||
|
||||
color = SIMD_SRGB255ToLinearSpace1(color);
|
||||
DTRDebug_EndCycleCount(DTRDebugCycleCount_RenderTexturedTriangle_SampleTextureFunction);
|
||||
DTRDebug_EndCycleCount(DTRDebugCycleCount_SIMD_TexturedTriangle_SampleTexture);
|
||||
return color;
|
||||
}
|
||||
|
||||
@ -1043,6 +1045,7 @@ FILE_SCOPE void SIMD_TexturedTriangle(DTRRenderBuffer *const renderBuffer, DqnV3
|
||||
const DTRRenderTransform transform)
|
||||
{
|
||||
DTR_DEBUG_EP_TIMED_FUNCTION();
|
||||
DTRDebug_BeginCycleCount("SIMD_TexturedTriangle", DTRDebugCycleCount_SIMD_TexturedTriangle);
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Convert color
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@ -1066,7 +1069,6 @@ FILE_SCOPE void SIMD_TexturedTriangle(DTRRenderBuffer *const renderBuffer, DqnV3
|
||||
p3.xy = pList[2];
|
||||
}
|
||||
|
||||
DTRDebug_BeginCycleCount(DTRDebugCycleCount_RenderTexturedTriangle_Rasterise);
|
||||
DqnV2i max = DqnV2i_2f(DQN_MAX(DQN_MAX(p1.x, p2.x), p3.x),
|
||||
DQN_MAX(DQN_MAX(p1.y, p2.y), p3.y));
|
||||
DqnV2i min = DqnV2i_2f(DQN_MIN(DQN_MIN(p1.x, p2.x), p3.x),
|
||||
@ -1143,6 +1145,7 @@ FILE_SCOPE void SIMD_TexturedTriangle(DTRRenderBuffer *const renderBuffer, DqnV3
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Scan and Render
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
DTRDebug_BeginCycleCount("SIMD_TexturedTriangle_Rasterise", DTRDebugCycleCount_SIMD_TexturedTriangle_Rasterise);
|
||||
for (i32 bufferY = min.y; bufferY < max.y; bufferY += NUM_Y_PIXELS_TO_SIMD)
|
||||
{
|
||||
__m128 signedArea1 = signedAreaPixel1;
|
||||
@ -1151,6 +1154,8 @@ FILE_SCOPE void SIMD_TexturedTriangle(DTRRenderBuffer *const renderBuffer, DqnV3
|
||||
for (i32 bufferX = min.x; bufferX < max.x; bufferX += NUM_X_PIXELS_TO_SIMD)
|
||||
{
|
||||
|
||||
DTRDebug_BeginCycleCount("SIMD_TexturedTriangle_RasterisePixel",
|
||||
DTRDebugCycleCount_SIMD_TexturedTriangle_RasterisePixel);
|
||||
// Rasterise buffer(X, Y) pixel
|
||||
{
|
||||
__m128 checkArea = signedArea1;
|
||||
@ -1179,6 +1184,7 @@ FILE_SCOPE void SIMD_TexturedTriangle(DTRRenderBuffer *const renderBuffer, DqnV3
|
||||
}
|
||||
signedArea1 = _mm_add_ps(signedArea1, signedAreaPixelDeltaX);
|
||||
}
|
||||
DTRDebug_EndCycleCount(DTRDebugCycleCount_SIMD_TexturedTriangle_RasterisePixel);
|
||||
|
||||
// Rasterise buffer(X + 1, Y) pixel
|
||||
{
|
||||
@ -1213,7 +1219,7 @@ FILE_SCOPE void SIMD_TexturedTriangle(DTRRenderBuffer *const renderBuffer, DqnV3
|
||||
signedAreaPixel1 = _mm_add_ps(signedAreaPixel1, signedAreaPixelDeltaY);
|
||||
signedAreaPixel2 = _mm_add_ps(signedAreaPixel2, signedAreaPixelDeltaY);
|
||||
}
|
||||
DTRDebug_EndCycleCount(DTRDebugCycleCount_RenderTexturedTriangle_Rasterise);
|
||||
DTRDebug_EndCycleCount(DTRDebugCycleCount_SIMD_TexturedTriangle_Rasterise);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Debug
|
||||
@ -1254,6 +1260,7 @@ FILE_SCOPE void SIMD_TexturedTriangle(DTRRenderBuffer *const renderBuffer, DqnV3
|
||||
DTRRender_Rectangle(renderBuffer, p3.xy - DqnV2_1f(5), p3.xy + DqnV2_1f(5), purple);
|
||||
}
|
||||
}
|
||||
DTRDebug_EndCycleCount(DTRDebugCycleCount_SIMD_TexturedTriangle);
|
||||
}
|
||||
|
||||
|
||||
@ -1299,9 +1306,7 @@ void DTRRender_TexturedTriangle(DTRRenderBuffer *const renderBuffer, DqnV3 p1, D
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Scan and Render
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
DTRDebug_BeginCycleCount(DTRDebugCycleCount_RenderTexturedTriangle_Rasterise);
|
||||
RasteriseTexturedTriangle(renderBuffer, p1, p2, p3, uv1, uv2, uv3, texture, color);
|
||||
DTRDebug_EndCycleCount(DTRDebugCycleCount_RenderTexturedTriangle_Rasterise);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Debug
|
||||
@ -1537,7 +1542,6 @@ void DTRRender_Triangle(DTRRenderBuffer *const renderBuffer, DqnV3 p1, DqnV3 p2,
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Scan and Render
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
DTRDebug_BeginCycleCount(DTRDebugCycleCount_RenderTriangle_Rasterise);
|
||||
const u32 zBufferPitch = renderBuffer->width;
|
||||
if (globalDTRPlatformFlags.canUseSSE2)
|
||||
{
|
||||
@ -1663,7 +1667,6 @@ void DTRRender_Triangle(DTRRenderBuffer *const renderBuffer, DqnV3 p1, DqnV3 p2,
|
||||
signedArea3 += signedArea3DeltaY;
|
||||
}
|
||||
}
|
||||
DTRDebug_EndCycleCount(DTRDebugCycleCount_RenderTriangle_Rasterise);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Debug
|
||||
|
@ -1439,7 +1439,6 @@ DQN_FILE_SCOPE bool DqnMemStack_InitWithFixedMem(DqnMemStack *const stack,
|
||||
const u32 byteAlign)
|
||||
{
|
||||
if (!stack || !mem) return false;
|
||||
DQN_ASSERT(!stack->block);
|
||||
|
||||
// TODO(doyle): Better logging
|
||||
if (memSize < sizeof(DqnMemStackBlock))
|
||||
@ -1449,6 +1448,7 @@ DQN_FILE_SCOPE bool DqnMemStack_InitWithFixedMem(DqnMemStack *const stack,
|
||||
stack->block->memory = mem + sizeof(DqnMemStackBlock);
|
||||
stack->block->used = 0;
|
||||
stack->block->size = memSize - sizeof(DqnMemStackBlock);
|
||||
stack->block->prevBlock = NULL;
|
||||
stack->flags = (DqnMemStackFlag_IsFixedMemoryFromUser | DqnMemStackFlag_IsNotExpandable);
|
||||
|
||||
const u32 DEFAULT_ALIGNMENT = 4;
|
||||
|
Loading…
Reference in New Issue
Block a user