From 1c1ee6b5e326a323912cc82da0311ab763f41924 Mon Sep 17 00:00:00 2001 From: Doyle Thai Date: Thu, 1 Jun 2017 21:07:44 +1000 Subject: [PATCH] Add better debug cycle diagnostics API --- src/DTRenderer.cpp | 76 +++++++++++++++++++++++++--------------- src/DTRendererDebug.cpp | 23 +++++++++--- src/DTRendererDebug.h | 14 +++++--- src/DTRendererRender.cpp | 19 +++++----- src/dqn.h | 12 +++---- 5 files changed, 93 insertions(+), 51 deletions(-) diff --git a/src/DTRenderer.cpp b/src/DTRenderer.cpp index f01c4f6..e682aa2 100644 --- a/src/DTRenderer.cpp +++ b/src/DTRenderer.cpp @@ -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"); } - DTRDebug_TestMeshFaceAndVertexParser(&state->mesh); + //////////////////////////////////////////////////////////////////////// + // 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; - 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); + 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); } diff --git a/src/DTRendererDebug.cpp b/src/DTRendererDebug.cpp index b96ba89..45d557e 100644 --- a/src/DTRendererDebug.cpp +++ b/src/DTRendererDebug.cpp @@ -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; } diff --git a/src/DTRendererDebug.h b/src/DTRendererDebug.h index 3103969..6a9098f 100644 --- a/src/DTRendererDebug.h +++ b/src/DTRendererDebug.h @@ -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); diff --git a/src/DTRendererRender.cpp b/src/DTRendererRender.cpp index c147051..0a098dd 100644 --- a/src/DTRendererRender.cpp +++ b/src/DTRendererRender.cpp @@ -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 diff --git a/src/dqn.h b/src/dqn.h index 9478203..07719e6 100644 --- a/src/dqn.h +++ b/src/dqn.h @@ -1439,17 +1439,17 @@ 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)) DQN_ASSERT(DQN_INVALID_CODE_PATH); - stack->block = (DqnMemStackBlock *)mem; - stack->block->memory = mem + sizeof(DqnMemStackBlock); - stack->block->used = 0; - stack->block->size = memSize - sizeof(DqnMemStackBlock); - stack->flags = (DqnMemStackFlag_IsFixedMemoryFromUser | DqnMemStackFlag_IsNotExpandable); + stack->block = (DqnMemStackBlock *)mem; + 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; stack->tempStackCount = 0;