Add better debug cycle diagnostics API

This commit is contained in:
Doyle Thai 2017-06-01 21:07:44 +10:00
parent 9b4072f5bc
commit 1c1ee6b5e3
5 changed files with 93 additions and 51 deletions

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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;