Start multithreading mesh render

This commit is contained in:
Doyle Thai 2017-06-18 23:07:49 +10:00
parent 079e19b58b
commit 630522f8a3
9 changed files with 376 additions and 207 deletions

View File

@ -11,7 +11,7 @@
PlatformFlags globalDTRPlatformFlags; PlatformFlags globalDTRPlatformFlags;
// #include <algorithm> // #include <algorithm>
void CompAssignment(DTRRenderBuffer *const renderBuffer, PlatformInput *const input, void CompAssignment(DTRRenderContext renderContext, PlatformInput *const input,
PlatformMemory *const memory) PlatformMemory *const memory)
{ {
#if 1 #if 1
@ -835,11 +835,11 @@ void CompAssignment(DTRRenderBuffer *const renderBuffer, PlatformInput *const in
#if 1 #if 1
char pText[32] = {}; char pText[32] = {};
Dqn_sprintf(pText, "(%1.0f, %1.0f)", origP.x, origP.y); Dqn_sprintf(pText, "(%1.0f, %1.0f)", origP.x, origP.y);
DTRRender_Text(renderBuffer, state->font, DTRRender_Text(renderContext, state->font,
DqnV2_2f(p.x + radius.x + 5, p.y - (state->font.sizeInPt * 0.40f)), pText, DqnV2_2f(p.x + radius.x + 5, p.y - (state->font.sizeInPt * 0.40f)), pText,
textColor); textColor);
#endif #endif
DTRRender_Rectangle(renderBuffer, p - radius, p + radius, pColor); DTRRender_Rectangle(renderContext, p - radius, p + radius, pColor);
} }
DqnV2 halfRadius = radius * 0.5f; DqnV2 halfRadius = radius * 0.5f;
@ -851,10 +851,10 @@ void CompAssignment(DTRRenderBuffer *const renderBuffer, PlatformInput *const in
char pText[32] = {}; char pText[32] = {};
Dqn_sprintf(pText, "(%1.0f, %1.0f)", origP.x, origP.y); Dqn_sprintf(pText, "(%1.0f, %1.0f)", origP.x, origP.y);
DTRRender_Text(renderBuffer, state->font, DTRRender_Text(renderContext, state->font,
DqnV2_2f(p.x + radius.x + 5, p.y - (state->font.sizeInPt * 0.40f)), pText, DqnV2_2f(p.x + radius.x + 5, p.y - (state->font.sizeInPt * 0.40f)), pText,
textColor); textColor);
DTRRender_Rectangle(renderBuffer, p - radius, p + radius, pColor); DTRRender_Rectangle(renderContext, p - radius, p + radius, pColor);
if (i + 1 <= skyPIndex && i > 0) if (i + 1 <= skyPIndex && i > 0)
{ {
@ -863,7 +863,7 @@ void CompAssignment(DTRRenderBuffer *const renderBuffer, PlatformInput *const in
DqnV2 pMid = p + halfRadius; DqnV2 pMid = p + halfRadius;
DqnV2 prevPMid = prevP + halfRadius; DqnV2 prevPMid = prevP + halfRadius;
DTRRender_Line(renderBuffer, DqnV2i_V2(prevPMid), DqnV2i_V2(pMid), DTRRender_Line(renderContext, DqnV2i_V2(prevPMid), DqnV2i_V2(pMid),
DqnV4_4f(255, 0, 0, 255)); DqnV4_4f(255, 0, 0, 255));
} }
} }
@ -895,10 +895,25 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
state = (DTRState *)memory->context; state = (DTRState *)memory->context;
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Init Memory Stacks // Init
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
DqnMemStack *const assetStack = &memory->assetStack; DqnMemStack *const assetStack = &memory->assetStack;
DqnMemStack *const tempStack = &memory->tempStack; DqnMemStack *const tempStack = &memory->tempStack;
state->zDepthLock = input->api.LockInit(&memory->mainStack);
if (state->zDepthLock)
{
state->blitLock = input->api.LockInit(&memory->mainStack);
if (!state->blitLock)
{
// TODO(doyle): Not enough memory die gracefully
DQN_ASSERT(DQN_INVALID_CODE_PATH);
}
}
else
{
// TODO(doyle): Not enough memory die gracefully
DQN_ASSERT(DQN_INVALID_CODE_PATH);
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Init Assets // Init Assets
@ -952,6 +967,8 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
renderBuffer.height = platformRenderBuffer->height; renderBuffer.height = platformRenderBuffer->height;
renderBuffer.bytesPerPixel = platformRenderBuffer->bytesPerPixel; renderBuffer.bytesPerPixel = platformRenderBuffer->bytesPerPixel;
renderBuffer.memory = (u8 *)platformRenderBuffer->memory; renderBuffer.memory = (u8 *)platformRenderBuffer->memory;
renderBuffer.zDepthLock = state->zDepthLock;
renderBuffer.blitLock = state->blitLock;
u32 zBufferSize = platformRenderBuffer->width * platformRenderBuffer->height; u32 zBufferSize = platformRenderBuffer->width * platformRenderBuffer->height;
renderBuffer.zBuffer = (f32 *)DqnMemStack_Push(&memory->tempStack, renderBuffer.zBuffer = (f32 *)DqnMemStack_Push(&memory->tempStack,
@ -959,10 +976,15 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
for (u32 i = 0; i < zBufferSize; i++) for (u32 i = 0; i < zBufferSize; i++)
renderBuffer.zBuffer[i] = DQN_F32_MIN; renderBuffer.zBuffer[i] = DQN_F32_MIN;
DTRRenderContext renderContext = {};
renderContext.renderBuffer = &renderBuffer;
renderContext.tempStack = &memory->tempStack;
renderContext.api = &input->api;
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Update and Render // Update and Render
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
DTRRender_Clear(&renderBuffer, DqnV3_3f(0.5f, 0.0f, 1.0f)); DTRRender_Clear(renderContext, DqnV3_3f(0.5f, 0.0f, 1.0f));
#if 1 #if 1
DqnV4 colorRed = DqnV4_4f(0.8f, 0, 0, 1); DqnV4 colorRed = DqnV4_4f(0.8f, 0, 0, 1);
@ -991,12 +1013,12 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
DTRDebug_BeginCycleCount("DTR_Update_RenderPrimitiveTriangles", DTRDebug_BeginCycleCount("DTR_Update_RenderPrimitiveTriangles",
DTRDebugCycleCount_DTR_Update_RenderPrimitiveTriangles); DTRDebugCycleCount_DTR_Update_RenderPrimitiveTriangles);
DTRRender_Triangle(&renderBuffer, t0[0], t0[1], t0[2], colorRed); DTRRender_Triangle(renderContext, t0[0], t0[1], t0[2], colorRed);
DTRRender_Triangle(&renderBuffer, t1[0], t1[1], t1[2], colorRed); DTRRender_Triangle(renderContext, t1[0], t1[1], t1[2], colorRed);
DTRRender_Triangle(&renderBuffer, t3[0], t3[1], t3[2], colorRed, rotatingXform); DTRRender_Triangle(renderContext, t3[0], t3[1], t3[2], colorRed, rotatingXform);
DTRRender_Triangle(&renderBuffer, t2[0], t2[1], t2[2], colorRed); DTRRender_Triangle(renderContext, t2[0], t2[1], t2[2], colorRed);
DTRRender_Triangle(&renderBuffer, t4[0], t4[1], t4[2], colorRed); DTRRender_Triangle(renderContext, t4[0], t4[1], t4[2], colorRed);
DTRRender_Triangle(&renderBuffer, t5[0], t5[1], t5[2], colorRed); DTRRender_Triangle(renderContext, t5[0], t5[1], t5[2], colorRed);
DTRDebug_EndCycleCount(DTRDebugCycleCount_DTR_Update_RenderPrimitiveTriangles); DTRDebug_EndCycleCount(DTRDebugCycleCount_DTR_Update_RenderPrimitiveTriangles);
} }
@ -1033,8 +1055,7 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
lighting.vector = LIGHT; lighting.vector = LIGHT;
lighting.color = DqnV4_4f(1, 1, 1, 1); lighting.color = DqnV4_4f(1, 1, 1, 1);
DTRRender_Mesh(&renderBuffer, &memory->tempStack, &input->api, input->jobQueue, DTRRender_Mesh(renderContext, input->jobQueue, mesh, lighting, modelP, transform);
mesh, lighting, modelP, transform);
DTRDebug_EndCycleCount(DTRDebugCycleCount_DTR_Update_RenderModel); DTRDebug_EndCycleCount(DTRDebugCycleCount_DTR_Update_RenderModel);
} }
} }
@ -1045,7 +1066,7 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
DTRRenderTransform transform = DTRRender_DefaultTransform(); DTRRenderTransform transform = DTRRender_DefaultTransform();
transform.rotation = rotation + 45; transform.rotation = rotation + 45;
DTRRender_Rectangle(&renderBuffer, DqnV2_1f(300.0f), DqnV2_1f(300 + 100.0f), DTRRender_Rectangle(renderContext, DqnV2_1f(300.0f), DqnV2_1f(300 + 100.0f),
DqnV4_4f(0, 1.0f, 1.0f, 1.0f), transform); DqnV4_4f(0, 1.0f, 1.0f, 1.0f), transform);
} }
@ -1061,14 +1082,14 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
f32 cAngle = (f32)input->timeNowInS; f32 cAngle = (f32)input->timeNowInS;
DqnV4 color = DqnV4_4f(0.5f + 0.5f * sinf(cAngle), 0.5f + 0.5f * sinf(2.9f * cAngle), DqnV4 color = DqnV4_4f(0.5f + 0.5f * sinf(cAngle), 0.5f + 0.5f * sinf(2.9f * cAngle),
0.5f + 0.5f * cosf(10.0f * cAngle), 1.0f); 0.5f + 0.5f * cosf(10.0f * cAngle), 1.0f);
DTRRender_Bitmap(&renderBuffer, &state->bitmap, bitmapP, transform, color); DTRRender_Bitmap(renderContext, &state->bitmap, bitmapP, transform, color);
} }
#else #else
// CompAssignment(renderBuffer, input, memory); // CompAssignment(renderBuffer, input, memory);
#endif #endif
DTRDebug_EndCycleCount(DTRDebugCycleCount_DTR_Update); DTRDebug_EndCycleCount(DTRDebugCycleCount_DTR_Update);
DTRDebug_Update(state, &renderBuffer, input, memory); DTRDebug_Update(state, renderContext, input, memory);
} }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////

View File

@ -13,6 +13,9 @@ typedef struct DTRState
DTRFont font; DTRFont font;
DTRBitmap bitmap; DTRBitmap bitmap;
DTRMesh mesh; DTRMesh mesh;
struct PlatformLock *zDepthLock;
struct PlatformLock *blitLock;
} DTRState; } DTRState;
extern PlatformFlags globalDTRPlatformFlags; extern PlatformFlags globalDTRPlatformFlags;

View File

@ -118,7 +118,7 @@ void DTRDebug_PushText(const char *const formatStr, ...)
if (DTR_DEBUG) if (DTR_DEBUG)
{ {
DTRDebug *const debug = &globalDebug; DTRDebug *const debug = &globalDebug;
if (!debug->renderBuffer) return; if (!debug->renderContext->renderBuffer) return;
char str[1024] = {}; char str[1024] = {};
@ -130,7 +130,7 @@ void DTRDebug_PushText(const char *const formatStr, ...)
} }
va_end(argList); va_end(argList);
DTRRender_Text(debug->renderBuffer, *debug->font, debug->displayP, str, DTRRender_Text(*debug->renderContext, *debug->font, debug->displayP, str,
debug->displayColor); debug->displayColor);
debug->displayP.y += globalDebug.displayYOffset; debug->displayP.y += globalDebug.displayYOffset;
} }
@ -199,25 +199,25 @@ FILE_SCOPE void PushMemStackText(const char *const name, const DqnMemStack *cons
Dqn_sprintf(str, "%s: %d block(s): %_$lld/%_$lld: wasted: %_$lld", name, numBlocks, Dqn_sprintf(str, "%s: %d block(s): %_$lld/%_$lld: wasted: %_$lld", name, numBlocks,
totalUsed, totalSize, totalWastedKb); totalUsed, totalSize, totalWastedKb);
DTRRender_Text(globalDebug.renderBuffer, *globalDebug.font, DTRRender_Text(*globalDebug.renderContext, *globalDebug.font,
globalDebug.displayP, str, globalDebug.displayColor); globalDebug.displayP, str, globalDebug.displayColor);
globalDebug.displayP.y += globalDebug.displayYOffset; globalDebug.displayP.y += globalDebug.displayYOffset;
} }
} }
void DTRDebug_Update(DTRState *const state, void DTRDebug_Update(DTRState *const state,
DTRRenderBuffer *const renderBuffer, DTRRenderContext renderContext,
PlatformInput *const input, PlatformMemory *const memory) PlatformInput *const input, PlatformMemory *const memory)
{ {
if (DTR_DEBUG) if (DTR_DEBUG)
{ {
DTRDebug *const debug = &globalDebug; DTRDebug *const debug = &globalDebug;
debug->renderBuffer = renderBuffer; debug->renderContext = &renderContext;
debug->input = input; debug->input = input;
debug->font = &state->font; debug->font = &state->font;
debug->displayColor = DqnV4_4f(1, 1, 1, 1); debug->displayColor = DqnV4_4f(1, 1, 1, 1);
if (debug->font->bitmap && debug->renderBuffer) if (debug->font->bitmap && debug->renderContext)
{ {
debug->displayYOffset = -(i32)(state->font.sizeInPt + 0.5f); debug->displayYOffset = -(i32)(state->font.sizeInPt + 0.5f);
DQN_ASSERT(globalDebug.displayYOffset < 0); DQN_ASSERT(globalDebug.displayYOffset < 0);
@ -270,7 +270,7 @@ void DTRDebug_Update(DTRState *const state,
// End Debug Update // End Debug Update
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
debug->displayP = debug->displayP =
DqnV2_2i(0, debug->renderBuffer->height + globalDebug.displayYOffset); DqnV2_2i(0, debug->renderContext->renderBuffer->height + globalDebug.displayYOffset);
for (i32 i = 0; i < DQN_ARRAY_COUNT(debug->counter); i++) for (i32 i = 0; i < DQN_ARRAY_COUNT(debug->counter); i++)
debug->counter[i] = 0; debug->counter[i] = 0;

View File

@ -89,7 +89,7 @@ typedef struct DTRDebugCycles
typedef struct DTRDebug typedef struct DTRDebug
{ {
struct DTRFont *font; struct DTRFont *font;
struct DTRRenderBuffer *renderBuffer; struct DTRRenderContext *renderContext;
struct PlatformInput *input; struct PlatformInput *input;
DqnMemStack memStack; DqnMemStack memStack;

View File

@ -52,6 +52,16 @@ typedef struct PlatformJob
typedef bool PlatformAPI_QueueAddJob (PlatformJobQueue *const queue, const PlatformJob job); typedef bool PlatformAPI_QueueAddJob (PlatformJobQueue *const queue, const PlatformJob job);
typedef bool PlatformAPI_QueueTryExecuteNextJob(PlatformJobQueue *const queue); typedef bool PlatformAPI_QueueTryExecuteNextJob(PlatformJobQueue *const queue);
////////////////////////////////////////////////////////////////////////////////
// Platform Locks
////////////////////////////////////////////////////////////////////////////////
typedef struct PlatformLock PlatformLock;
typedef PlatformLock *PlatformAPI_LockInit (DqnMemStack *const stack);
typedef void PlatformAPI_LockAcquire(PlatformLock *const lock);
typedef void PlatformAPI_LockRelease(PlatformLock *const lock);
typedef void PlatformAPI_LockDelete (PlatformLock *const lock);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Platform API for Game to Use // Platform API for Game to Use
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -65,6 +75,11 @@ typedef struct PlatformAPI
PlatformAPI_QueueAddJob *QueueAddJob; PlatformAPI_QueueAddJob *QueueAddJob;
PlatformAPI_QueueTryExecuteNextJob *QueueTryExecuteNextJob; PlatformAPI_QueueTryExecuteNextJob *QueueTryExecuteNextJob;
PlatformAPI_LockInit *LockInit;
PlatformAPI_LockAcquire *LockAcquire;
PlatformAPI_LockRelease *LockRelease;
PlatformAPI_LockDelete *LockDelete;
} PlatformAPI; } PlatformAPI;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -121,9 +121,10 @@ inline DqnV4 DTRRender_PreMultiplyAlphaSRGB1WithLinearConversion(DqnV4 color)
} }
// IMPORTANT(doyle): Color is expected to be premultiplied already // IMPORTANT(doyle): Color is expected to be premultiplied already
FILE_SCOPE inline void SetPixel(DTRRenderBuffer *const renderBuffer, const i32 x, const i32 y, FILE_SCOPE inline void SetPixel(DTRRenderContext context, const i32 x, const i32 y,
DqnV4 color, const enum ColorSpace colorSpace = ColorSpace_SRGB) DqnV4 color, const enum ColorSpace colorSpace = ColorSpace_SRGB)
{ {
DTRRenderBuffer *renderBuffer = context.renderBuffer;
if (!renderBuffer) return; if (!renderBuffer) return;
if (x < 0 || x > (renderBuffer->width - 1)) return; if (x < 0 || x > (renderBuffer->width - 1)) return;
if (y < 0 || y > (renderBuffer->height - 1)) return; if (y < 0 || y > (renderBuffer->height - 1)) return;
@ -189,14 +190,17 @@ FILE_SCOPE inline void SetPixel(DTRRenderBuffer *const renderBuffer, const i32 x
DTRDebug_CounterIncrement(DTRDebugCounter_SetPixels); DTRDebug_CounterIncrement(DTRDebugCounter_SetPixels);
} }
void DTRRender_Text(DTRRenderBuffer *const renderBuffer, void DTRRender_Text(DTRRenderContext context,
const DTRFont font, DqnV2 pos, const char *const text, const DTRFont font, DqnV2 pos, const char *const text,
DqnV4 color, i32 len) DqnV4 color, i32 len)
{ {
if (!text) return; if (!text) return;
DTRRenderBuffer *renderBuffer = context.renderBuffer;
if (!font.bitmap || !font.atlas || !renderBuffer) return; if (!font.bitmap || !font.atlas || !renderBuffer) return;
DTR_DEBUG_EP_TIMED_FUNCTION(); DTR_DEBUG_EP_TIMED_FUNCTION();
if (len == -1) len = Dqn_strlen(text); if (len == -1) len = Dqn_strlen(text);
i32 index = 0; i32 index = 0;
@ -262,7 +266,7 @@ void DTRRender_Text(DTRRenderBuffer *const renderBuffer,
i32 actualX = (i32)(screenRect.min.x + x); i32 actualX = (i32)(screenRect.min.x + x);
i32 actualY = (i32)(screenRect.min.y + y - fontHeightOffset); i32 actualY = (i32)(screenRect.min.y + y - fontHeightOffset);
SetPixel(renderBuffer, actualX, actualY, resultColor, ColorSpace_Linear); SetPixel(context, actualX, actualY, resultColor, ColorSpace_Linear);
} }
} }
} }
@ -287,9 +291,10 @@ FILE_SCOPE void TransformPoints(const DqnV2 origin, DqnV2 *const pList,
} }
} }
void DTRRender_Line(DTRRenderBuffer *const renderBuffer, DqnV2i a, void DTRRender_Line(DTRRenderContext context, DqnV2i a,
DqnV2i b, DqnV4 color) DqnV2i b, DqnV4 color)
{ {
DTRRenderBuffer *renderBuffer = context.renderBuffer;
if (!renderBuffer) return; if (!renderBuffer) return;
DTR_DEBUG_EP_TIMED_FUNCTION(); DTR_DEBUG_EP_TIMED_FUNCTION();
@ -339,7 +344,7 @@ void DTRRender_Line(DTRRenderBuffer *const renderBuffer, DqnV2i a,
for (i32 iterateX = 0; iterateX < numIterations; iterateX++) for (i32 iterateX = 0; iterateX < numIterations; iterateX++)
{ {
newX = a.x + iterateX; newX = a.x + iterateX;
SetPixel(renderBuffer, *plotX, *plotY, color, ColorSpace_Linear); SetPixel(context, *plotX, *plotY, color, ColorSpace_Linear);
distAccumulator += distFromPixelOrigin; distAccumulator += distFromPixelOrigin;
if (distAccumulator > run) if (distAccumulator > run)
@ -407,10 +412,13 @@ FILE_SCOPE DqnRect GetBoundingBox(const DqnV2 *const pList, const i32 numP)
return result; return result;
} }
void DTRRender_Rectangle(DTRRenderBuffer *const renderBuffer, DqnV2 min, DqnV2 max, void DTRRender_Rectangle(DTRRenderContext context, DqnV2 min, DqnV2 max,
DqnV4 color, const DTRRenderTransform transform) DqnV4 color, const DTRRenderTransform transform)
{ {
DTR_DEBUG_EP_TIMED_FUNCTION(); DTR_DEBUG_EP_TIMED_FUNCTION();
DTRRenderBuffer *renderBuffer = context.renderBuffer;
if (!renderBuffer) return;
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Transform vertexes // Transform vertexes
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@ -461,7 +469,7 @@ void DTRRender_Rectangle(DTRRenderBuffer *const renderBuffer, DqnV2 min, DqnV2 m
} }
} }
if (pIsInside) SetPixel(renderBuffer, bufferX, bufferY, color, ColorSpace_Linear); if (pIsInside) SetPixel(context, bufferX, bufferY, color, ColorSpace_Linear);
} }
} }
} }
@ -473,7 +481,7 @@ void DTRRender_Rectangle(DTRRenderBuffer *const renderBuffer, DqnV2 min, DqnV2 m
for (i32 x = 0; x < clippedSize.w; x++) for (i32 x = 0; x < clippedSize.w; x++)
{ {
i32 bufferX = (i32)clippedRect.min.x + x; i32 bufferX = (i32)clippedRect.min.x + x;
SetPixel(renderBuffer, bufferX, bufferY, color, ColorSpace_Linear); SetPixel(context, bufferX, bufferY, color, ColorSpace_Linear);
} }
} }
} }
@ -485,20 +493,20 @@ void DTRRender_Rectangle(DTRRenderBuffer *const renderBuffer, DqnV2 min, DqnV2 m
{ {
// Draw Bounding box // Draw Bounding box
{ {
DTRRender_Line(renderBuffer, DqnV2i_2f(min.x, min.y), DqnV2i_2f(min.x, max.y), color); DTRRender_Line(context, DqnV2i_2f(min.x, min.y), DqnV2i_2f(min.x, max.y), color);
DTRRender_Line(renderBuffer, DqnV2i_2f(min.x, max.y), DqnV2i_2f(max.x, max.y), color); DTRRender_Line(context, DqnV2i_2f(min.x, max.y), DqnV2i_2f(max.x, max.y), color);
DTRRender_Line(renderBuffer, DqnV2i_2f(max.x, max.y), DqnV2i_2f(max.x, min.y), color); DTRRender_Line(context, DqnV2i_2f(max.x, max.y), DqnV2i_2f(max.x, min.y), color);
DTRRender_Line(renderBuffer, DqnV2i_2f(max.x, min.y), DqnV2i_2f(min.x, min.y), color); DTRRender_Line(context, DqnV2i_2f(max.x, min.y), DqnV2i_2f(min.x, min.y), color);
} }
// Draw rotating outline // Draw rotating outline
if (transform.rotation > 0) if (transform.rotation > 0)
{ {
DqnV4 green = DqnV4_4f(0, 1, 0, 1); DqnV4 green = DqnV4_4f(0, 1, 0, 1);
DTRRender_Line(renderBuffer, DqnV2i_V2(pList[0]), DqnV2i_V2(pList[1]), green); DTRRender_Line(context, DqnV2i_V2(pList[0]), DqnV2i_V2(pList[1]), green);
DTRRender_Line(renderBuffer, DqnV2i_V2(pList[1]), DqnV2i_V2(pList[2]), green); DTRRender_Line(context, DqnV2i_V2(pList[1]), DqnV2i_V2(pList[2]), green);
DTRRender_Line(renderBuffer, DqnV2i_V2(pList[2]), DqnV2i_V2(pList[3]), green); DTRRender_Line(context, DqnV2i_V2(pList[2]), DqnV2i_V2(pList[3]), green);
DTRRender_Line(renderBuffer, DqnV2i_V2(pList[3]), DqnV2i_V2(pList[0]), green); DTRRender_Line(context, DqnV2i_V2(pList[3]), DqnV2i_V2(pList[0]), green);
} }
} }
@ -609,10 +617,12 @@ FILE_SCOPE inline DqnV2 Get2DOriginFromTransformAnchor(const DqnV2 p1, const Dqn
} }
// color: _mm_set_ps(a, b, g, r) ie. 0=r, 1=g, 2=b, 3=a // color: _mm_set_ps(a, b, g, r) ie. 0=r, 1=g, 2=b, 3=a
FILE_SCOPE inline void SIMDSetPixel(DTRRenderBuffer *const renderBuffer, const i32 x, const i32 y, FILE_SCOPE inline void SIMDSetPixel(DTRRenderContext context, const i32 x, const i32 y,
__m128 color, __m128 color,
const enum ColorSpace colorSpace = ColorSpace_SRGB) const enum ColorSpace colorSpace = ColorSpace_SRGB)
{ {
DTRRenderBuffer *renderBuffer = context.renderBuffer;
if (!renderBuffer) return; if (!renderBuffer) return;
if (x < 0 || x > (renderBuffer->width - 1)) return; if (x < 0 || x > (renderBuffer->width - 1)) return;
if (y < 0 || y > (renderBuffer->height - 1)) return; if (y < 0 || y > (renderBuffer->height - 1)) return;
@ -631,6 +641,7 @@ FILE_SCOPE inline void SIMDSetPixel(DTRRenderBuffer *const renderBuffer, const i
if (needGammaFix) color = SIMDSRGB1ToLinearSpace(color); if (needGammaFix) color = SIMDSRGB1ToLinearSpace(color);
// Format: u32 == (XX, RR, GG, BB) // Format: u32 == (XX, RR, GG, BB)
context.api->LockAcquire(renderBuffer->blitLock);
u32 srcPixel = bitmapPtr[x + (y * pitchInU32)]; u32 srcPixel = bitmapPtr[x + (y * pitchInU32)];
__m128 src = _mm_set_ps(0, __m128 src = _mm_set_ps(0,
(f32)((srcPixel >> 0) & 0xFF), (f32)((srcPixel >> 0) & 0xFF),
@ -658,6 +669,7 @@ FILE_SCOPE inline void SIMDSetPixel(DTRRenderBuffer *const renderBuffer, const i
(u32)(destG) << 8 | (u32)(destG) << 8 |
(u32)(destB) << 0; (u32)(destB) << 0;
bitmapPtr[x + (y * pitchInU32)] = pixel; bitmapPtr[x + (y * pitchInU32)] = pixel;
context.api->LockRelease(renderBuffer->blitLock);
DTRDebug_CounterIncrement(DTRDebugCounter_SetPixels); DTRDebug_CounterIncrement(DTRDebugCounter_SetPixels);
} }
@ -708,7 +720,7 @@ FILE_SCOPE __m128 SIMDSampleTextureForTriangle(const DTRBitmap *const texture, c
// IMPORTANT: Debug Markers can _NOT_ be used in primitive rendering functions, // IMPORTANT: Debug Markers can _NOT_ be used in primitive rendering functions,
// ie. any render function that is used in this call because it'll call into // ie. any render function that is used in this call because it'll call into
// itself infinitely. // itself infinitely.
FILE_SCOPE void DebugRenderMarkers(DTRRenderBuffer *const renderBuffer, const DqnV2 *const pList, FILE_SCOPE void DebugRenderMarkers(DTRRenderContext context, const DqnV2 *const pList,
const i32 pListSize, const DTRRenderTransform transform, const i32 pListSize, const DTRRenderTransform transform,
bool drawBoundingBox, bool drawBasis, bool drawVertexMarkers) bool drawBoundingBox, bool drawBasis, bool drawVertexMarkers)
{ {
@ -725,10 +737,10 @@ FILE_SCOPE void DebugRenderMarkers(DTRRenderBuffer *const renderBuffer, const Dq
{ {
DqnRect bounds = GetBoundingBox(pList, pListSize); DqnRect bounds = GetBoundingBox(pList, pListSize);
DTRRender_Line(renderBuffer, DqnV2i_2f(bounds.min.x, bounds.min.y), DqnV2i_2f(bounds.min.x, bounds.max.y), red); DTRRender_Line(context, DqnV2i_2f(bounds.min.x, bounds.min.y), DqnV2i_2f(bounds.min.x, bounds.max.y), red);
DTRRender_Line(renderBuffer, DqnV2i_2f(bounds.min.x, bounds.max.y), DqnV2i_2f(bounds.max.x, bounds.max.y), red); DTRRender_Line(context, DqnV2i_2f(bounds.min.x, bounds.max.y), DqnV2i_2f(bounds.max.x, bounds.max.y), red);
DTRRender_Line(renderBuffer, DqnV2i_2f(bounds.max.x, bounds.max.y), DqnV2i_2f(bounds.max.x, bounds.min.y), red); DTRRender_Line(context, DqnV2i_2f(bounds.max.x, bounds.max.y), DqnV2i_2f(bounds.max.x, bounds.min.y), red);
DTRRender_Line(renderBuffer, DqnV2i_2f(bounds.max.x, bounds.min.y), DqnV2i_2f(bounds.min.x, bounds.min.y), red); DTRRender_Line(context, DqnV2i_2f(bounds.max.x, bounds.min.y), DqnV2i_2f(bounds.min.x, bounds.min.y), red);
} }
// Draw Coordinate Basis // Draw Coordinate Basis
@ -743,9 +755,9 @@ FILE_SCOPE void DebugRenderMarkers(DTRRenderBuffer *const renderBuffer, const Dq
DqnV2 yAxis = DqnV2_2f(-xAxis.y, xAxis.x) * transform.scale.y; DqnV2 yAxis = DqnV2_2f(-xAxis.y, xAxis.x) * transform.scale.y;
DqnV4 coordSysColor = DqnV4_4f(0, 1, 1, 1); DqnV4 coordSysColor = DqnV4_4f(0, 1, 1, 1);
i32 axisLen = 50; i32 axisLen = 50;
DTRRender_Line(renderBuffer, DqnV2i_V2(origin), DTRRender_Line(context, DqnV2i_V2(origin),
DqnV2i_V2(origin) + DqnV2i_V2(xAxis * axisLen), coordSysColor); DqnV2i_V2(origin) + DqnV2i_V2(xAxis * axisLen), coordSysColor);
DTRRender_Line(renderBuffer, DqnV2i_V2(origin), DTRRender_Line(context, DqnV2i_V2(origin),
DqnV2i_V2(origin) + DqnV2i_V2(yAxis * axisLen), coordSysColor); DqnV2i_V2(origin) + DqnV2i_V2(yAxis * axisLen), coordSysColor);
} }
} }
@ -757,11 +769,40 @@ FILE_SCOPE void DebugRenderMarkers(DTRRenderBuffer *const renderBuffer, const Dq
for (i32 i = 0; i < pListSize; i++) for (i32 i = 0; i < pListSize; i++)
{ {
DqnV2 p = pList[i]; DqnV2 p = pList[i];
DTRRender_Rectangle(renderBuffer, p - DqnV2_1f(5), p + DqnV2_1f(5), colorList[i]); DTRRender_Rectangle(context, p - DqnV2_1f(5), p + DqnV2_1f(5), colorList[i]);
} }
} }
} }
FILE_SCOPE inline f32 GetCurrZDepth(DTRRenderContext context, i32 posX, i32 posY)
{
DTRRenderBuffer *renderBuffer = context.renderBuffer;
DQN_ASSERT(renderBuffer);
const u32 zBufferPitch = renderBuffer->width;
i32 zBufferIndex = posX + (posY * zBufferPitch);
DQN_ASSERT(zBufferIndex < (renderBuffer->width * renderBuffer->height));
context.api->LockAcquire(renderBuffer->zDepthLock);
f32 currZDepth = renderBuffer->zBuffer[zBufferIndex];
context.api->LockRelease(renderBuffer->zDepthLock);
return currZDepth;
}
FILE_SCOPE inline void SetCurrZDepth(DTRRenderContext context, i32 posX, i32 posY, f32 newZDepth)
{
DTRRenderBuffer *renderBuffer = context.renderBuffer;
DQN_ASSERT(renderBuffer);
const u32 zBufferPitch = renderBuffer->width;
i32 zBufferIndex = posX + (posY * zBufferPitch);
DQN_ASSERT(zBufferIndex < (renderBuffer->width * renderBuffer->height));
context.api->LockAcquire(renderBuffer->zDepthLock);
renderBuffer->zBuffer[zBufferIndex] = newZDepth;
context.api->LockRelease(renderBuffer->zDepthLock);
}
#define DEBUG_SIMD_AUTO_CHOOSE_BEGIN_CYCLE_COUNT(type) \ #define DEBUG_SIMD_AUTO_CHOOSE_BEGIN_CYCLE_COUNT(type) \
do \ do \
{ \ { \
@ -780,7 +821,7 @@ FILE_SCOPE void DebugRenderMarkers(DTRRenderBuffer *const renderBuffer, const Dq
DTRDebug_EndCycleCount(DTRDebugCycleCount_SIMD##type); \ DTRDebug_EndCycleCount(DTRDebugCycleCount_SIMD##type); \
} while (0) } while (0)
FILE_SCOPE void SIMDRasteriseTrianglePixel(DTRRenderBuffer *const renderBuffer, FILE_SCOPE void SIMDRasteriseTrianglePixel(DTRRenderContext context,
const DTRBitmap *const texture, const i32 posX, const DTRBitmap *const texture, const i32 posX,
const i32 posY, const i32 maxX, const DqnV2 uv1, const i32 posY, const i32 maxX, const DqnV2 uv1,
const DqnV2 uv2SubUv1, const DqnV2 uv3SubUv1, const DqnV2 uv2SubUv1, const DqnV2 uv3SubUv1,
@ -790,7 +831,8 @@ FILE_SCOPE void SIMDRasteriseTrianglePixel(DTRRenderBuffer *const renderBuffer,
{ {
const __m128 ZERO_4X = _mm_set_ps1(0.0f); const __m128 ZERO_4X = _mm_set_ps1(0.0f);
const u32 IS_GREATER_MASK = 0xF; const u32 IS_GREATER_MASK = 0xF;
const u32 zBufferPitch = renderBuffer->width;
DTRRenderBuffer *renderBuffer = context.renderBuffer;
// TODO(doyle): Copy lighting work over. But not important since using this // TODO(doyle): Copy lighting work over. But not important since using this
// function causes performance problems. // function causes performance problems.
@ -806,13 +848,12 @@ FILE_SCOPE void SIMDRasteriseTrianglePixel(DTRRenderBuffer *const renderBuffer,
__m128 barycentric = _mm_mul_ps(signedArea, invSignedAreaParallelogram_4x); __m128 barycentric = _mm_mul_ps(signedArea, invSignedAreaParallelogram_4x);
__m128 barycentricZ = _mm_mul_ps(triangleZ, barycentric); __m128 barycentricZ = _mm_mul_ps(triangleZ, barycentric);
i32 zBufferIndex = posX + (posY * zBufferPitch); f32 pixelZDepth =
f32 pixelZValue =
((f32 *)&barycentricZ)[0] + ((f32 *)&barycentricZ)[1] + ((f32 *)&barycentricZ)[2]; ((f32 *)&barycentricZ)[0] + ((f32 *)&barycentricZ)[1] + ((f32 *)&barycentricZ)[2];
f32 currZValue = renderBuffer->zBuffer[zBufferIndex]; f32 currZDepth = GetCurrZDepth(context, posX, posY);
if (pixelZValue > currZValue) if (pixelZDepth > currZDepth)
{ {
renderBuffer->zBuffer[zBufferIndex] = pixelZValue; SetCurrZDepth(context, posX, posY, pixelZDepth);
__m128 finalColor = simdColor; __m128 finalColor = simdColor;
if (texture) if (texture)
@ -821,25 +862,27 @@ FILE_SCOPE void SIMDRasteriseTrianglePixel(DTRRenderBuffer *const renderBuffer,
uv3SubUv1, barycentric); uv3SubUv1, barycentric);
finalColor = _mm_mul_ps(texSampledColor, simdColor); finalColor = _mm_mul_ps(texSampledColor, simdColor);
} }
SIMDSetPixel(renderBuffer, posX, posY, finalColor, ColorSpace_Linear); SIMDSetPixel(context, posX, posY, finalColor, ColorSpace_Linear);
} }
DEBUG_SIMD_AUTO_CHOOSE_END_CYCLE_COUNT(Triangle_RasterisePixel); DEBUG_SIMD_AUTO_CHOOSE_END_CYCLE_COUNT(Triangle_RasterisePixel);
} }
} }
} }
FILE_SCOPE void SIMDTriangle(DTRRenderBuffer *const renderBuffer, const DqnV3 p1, const DqnV3 p2, FILE_SCOPE void SIMDTriangle(DTRRenderContext context,
const DqnV3 p3, const DqnV2 uv1, const DqnV2 uv2, const DqnV2 uv3, const DqnV3 p1, const DqnV3 p2, const DqnV3 p3, const DqnV2 uv1,
const f32 lightIntensity1, const f32 lightIntensity2, const DqnV2 uv2, const DqnV2 uv3, const f32 lightIntensity1,
const f32 lightIntensity3, const bool ignoreLight, const f32 lightIntensity2, const f32 lightIntensity3,
DTRBitmap *const texture, DqnV4 color, const DqnV2i min, const bool ignoreLight, DTRBitmap *const texture, DqnV4 color,
const DqnV2i max) const DqnV2i min, const DqnV2i max)
{ {
DTR_DEBUG_EP_TIMED_FUNCTION(); DTR_DEBUG_EP_TIMED_FUNCTION();
DEBUG_SIMD_AUTO_CHOOSE_BEGIN_CYCLE_COUNT(Triangle); DEBUG_SIMD_AUTO_CHOOSE_BEGIN_CYCLE_COUNT(Triangle);
DEBUG_SIMD_AUTO_CHOOSE_BEGIN_CYCLE_COUNT(Triangle_Preamble); DEBUG_SIMD_AUTO_CHOOSE_BEGIN_CYCLE_COUNT(Triangle_Preamble);
DTRRenderBuffer *renderBuffer = context.renderBuffer;
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Convert color // Convert color
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@ -956,14 +999,27 @@ FILE_SCOPE void SIMDTriangle(DTRRenderBuffer *const renderBuffer, const DqnV3 p1
__m128 barycentric = _mm_mul_ps(checkArea, invSignedAreaParallelogram_4x); __m128 barycentric = _mm_mul_ps(checkArea, invSignedAreaParallelogram_4x);
__m128 barycentricZ = _mm_mul_ps(triangleZ, barycentric); __m128 barycentricZ = _mm_mul_ps(triangleZ, barycentric);
i32 zBufferIndex = posX + (posY * zBufferPitch); f32 pixelZDepth = ((f32 *)&barycentricZ)[0] +
f32 pixelZValue = ((f32 *)&barycentricZ)[0] +
((f32 *)&barycentricZ)[1] + ((f32 *)&barycentricZ)[1] +
((f32 *)&barycentricZ)[2]; ((f32 *)&barycentricZ)[2];
f32 currZValue = renderBuffer->zBuffer[zBufferIndex];
if (pixelZValue > currZValue) #if 0
// f32 currZDepth = GetCurrZDepth(context, posX, posY);
#else
DQN_ASSERT(renderBuffer);
i32 zBufferIndex = posX + (posY * zBufferPitch);
context.api->LockAcquire(renderBuffer->zDepthLock);
f32 currZDepth = renderBuffer->zBuffer[zBufferIndex];
context.api->LockRelease(renderBuffer->zDepthLock);
#endif
if (pixelZDepth > currZDepth)
{ {
// renderBuffer->zBuffer[zBufferIndex] = pixelZValue;
context.api->LockAcquire(renderBuffer->zDepthLock);
renderBuffer->zBuffer[zBufferIndex] = pixelZDepth;
context.api->LockRelease(renderBuffer->zDepthLock);
__m128 finalColor = simdColor; __m128 finalColor = simdColor;
if (!ignoreLight) if (!ignoreLight)
{ {
@ -988,7 +1044,7 @@ FILE_SCOPE void SIMDTriangle(DTRRenderBuffer *const renderBuffer, const DqnV3 p1
__m128 texSampledColor = SIMDSampleTextureForTriangle(texture, uv1, uv2SubUv1, uv3SubUv1, barycentric); __m128 texSampledColor = SIMDSampleTextureForTriangle(texture, uv1, uv2SubUv1, uv3SubUv1, barycentric);
finalColor = _mm_mul_ps(texSampledColor, finalColor); finalColor = _mm_mul_ps(texSampledColor, finalColor);
} }
// SIMDSetPixel(renderBuffer, posX, posY, finalColor, ColorSpace_Linear); SIMDSetPixel(context, posX, posY, finalColor, ColorSpace_Linear);
} }
DEBUG_SIMD_AUTO_CHOOSE_END_CYCLE_COUNT(Triangle_RasterisePixel); DEBUG_SIMD_AUTO_CHOOSE_END_CYCLE_COUNT(Triangle_RasterisePixel);
} }
@ -1007,16 +1063,22 @@ FILE_SCOPE void SIMDTriangle(DTRRenderBuffer *const renderBuffer, const DqnV3 p1
__m128 barycentric = _mm_mul_ps(checkArea, invSignedAreaParallelogram_4x); __m128 barycentric = _mm_mul_ps(checkArea, invSignedAreaParallelogram_4x);
__m128 barycentricZ = _mm_mul_ps(triangleZ, barycentric); __m128 barycentricZ = _mm_mul_ps(triangleZ, barycentric);
i32 zBufferIndex = posX + (posY * zBufferPitch); f32 pixelZDepth = ((f32 *)&barycentricZ)[0] +
f32 pixelZValue = ((f32 *)&barycentricZ)[0] +
((f32 *)&barycentricZ)[1] + ((f32 *)&barycentricZ)[1] +
((f32 *)&barycentricZ)[2]; ((f32 *)&barycentricZ)[2];
f32 currZValue = renderBuffer->zBuffer[zBufferIndex]; i32 zBufferIndex = posX + (posY * zBufferPitch);
if (pixelZValue > currZValue)
{
// renderBuffer->zBuffer[zBufferIndex] = pixelZValue;
__m128 finalColor = simdColor;
context.api->LockAcquire(renderBuffer->zDepthLock);
f32 currZDepth = renderBuffer->zBuffer[zBufferIndex];
context.api->LockRelease(renderBuffer->zDepthLock);
if (pixelZDepth > currZDepth)
{
context.api->LockAcquire(renderBuffer->zDepthLock);
renderBuffer->zBuffer[zBufferIndex] = pixelZDepth;
context.api->LockRelease(renderBuffer->zDepthLock);
__m128 finalColor = simdColor;
if (!ignoreLight) if (!ignoreLight)
{ {
__m128 barycentricA_4x = _mm_set_ps1(((f32 *)&barycentric)[0]); __m128 barycentricA_4x = _mm_set_ps1(((f32 *)&barycentric)[0]);
@ -1040,7 +1102,7 @@ FILE_SCOPE void SIMDTriangle(DTRRenderBuffer *const renderBuffer, const DqnV3 p1
__m128 texSampledColor = SIMDSampleTextureForTriangle(texture, uv1, uv2SubUv1, uv3SubUv1, barycentric); __m128 texSampledColor = SIMDSampleTextureForTriangle(texture, uv1, uv2SubUv1, uv3SubUv1, barycentric);
finalColor = _mm_mul_ps(texSampledColor, finalColor); finalColor = _mm_mul_ps(texSampledColor, finalColor);
} }
// SIMDSetPixel(renderBuffer, posX, posY, finalColor, ColorSpace_Linear); SIMDSetPixel(context, posX, posY, finalColor, ColorSpace_Linear);
} }
} }
signedArea2 = _mm_add_ps(signedArea2, signedAreaPixelDeltaX); signedArea2 = _mm_add_ps(signedArea2, signedAreaPixelDeltaX);
@ -1063,7 +1125,7 @@ FILE_SCOPE void SIMDTriangle(DTRRenderBuffer *const renderBuffer, const DqnV3 p1
DEBUG_SIMD_AUTO_CHOOSE_END_CYCLE_COUNT(Triangle); DEBUG_SIMD_AUTO_CHOOSE_END_CYCLE_COUNT(Triangle);
} }
FILE_SCOPE void SlowTriangle(DTRRenderBuffer *const renderBuffer, const DqnV3 p1, const DqnV3 p2, FILE_SCOPE void SlowTriangle(DTRRenderContext context, const DqnV3 p1, const DqnV3 p2,
const DqnV3 p3, const DqnV2 uv1, const DqnV2 uv2, const DqnV2 uv3, const DqnV3 p3, const DqnV2 uv1, const DqnV2 uv2, const DqnV2 uv3,
const f32 lightIntensity1, const f32 lightIntensity2, const f32 lightIntensity1, const f32 lightIntensity2,
const f32 lightIntensity3, const bool ignoreLight, const f32 lightIntensity3, const bool ignoreLight,
@ -1071,7 +1133,6 @@ FILE_SCOPE void SlowTriangle(DTRRenderBuffer *const renderBuffer, const DqnV3 p1
const DqnV2i max) const DqnV2i max)
{ {
DTR_DEBUG_EP_TIMED_FUNCTION(); DTR_DEBUG_EP_TIMED_FUNCTION();
#define DEBUG_SLOW_AUTO_CHOOSE_BEGIN_CYCLE_COUNT(type) \ #define DEBUG_SLOW_AUTO_CHOOSE_BEGIN_CYCLE_COUNT(type) \
do \ do \
{ \ { \
@ -1091,8 +1152,9 @@ FILE_SCOPE void SlowTriangle(DTRRenderBuffer *const renderBuffer, const DqnV3 p1
} while (0) } while (0)
DEBUG_SLOW_AUTO_CHOOSE_BEGIN_CYCLE_COUNT(Triangle); DEBUG_SLOW_AUTO_CHOOSE_BEGIN_CYCLE_COUNT(Triangle);
DEBUG_SLOW_AUTO_CHOOSE_BEGIN_CYCLE_COUNT(Triangle_Preamble); DEBUG_SLOW_AUTO_CHOOSE_BEGIN_CYCLE_COUNT(Triangle_Preamble);
DTRRenderBuffer *renderBuffer = context.renderBuffer;
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Convert Color // Convert Color
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@ -1153,14 +1215,12 @@ FILE_SCOPE void SlowTriangle(DTRRenderBuffer *const renderBuffer, const DqnV3 p1
f32 barycentricB = signedArea2 * invSignedAreaParallelogram; f32 barycentricB = signedArea2 * invSignedAreaParallelogram;
f32 barycentricC = signedArea3 * invSignedAreaParallelogram; f32 barycentricC = signedArea3 * invSignedAreaParallelogram;
i32 zBufferIndex = bufferX + (bufferY * zBufferPitch); f32 pixelZDepth = p1.z + (barycentricB * (p2SubP1.z)) + (barycentricC * (p3SubP1.z));
f32 pixelZValue = p1.z + (barycentricB * (p2SubP1.z)) + (barycentricC * (p3SubP1.z)); f32 currZDepth = GetCurrZDepth(context, bufferX, bufferY);
f32 currZValue = renderBuffer->zBuffer[zBufferIndex];
DQN_ASSERT(zBufferIndex < (renderBuffer->width * renderBuffer->height));
if (pixelZValue > currZValue) if (pixelZDepth > currZDepth)
{ {
renderBuffer->zBuffer[zBufferIndex] = pixelZValue; SetCurrZDepth(context, bufferX, bufferY, pixelZDepth);
DqnV4 finalColor = color; DqnV4 finalColor = color;
if (!ignoreLight) if (!ignoreLight)
@ -1202,7 +1262,7 @@ FILE_SCOPE void SlowTriangle(DTRRenderBuffer *const renderBuffer, const DqnV3 p1
finalColor *= color1; finalColor *= color1;
} }
SetPixel(renderBuffer, bufferX, bufferY, finalColor, ColorSpace_Linear); SetPixel(context, bufferX, bufferY, finalColor, ColorSpace_Linear);
} }
DEBUG_SLOW_AUTO_CHOOSE_END_CYCLE_COUNT(Triangle_RasterisePixel); DEBUG_SLOW_AUTO_CHOOSE_END_CYCLE_COUNT(Triangle_RasterisePixel);
} }
@ -1247,11 +1307,14 @@ DqnMat4 GLViewport(f32 x, f32 y, f32 width, f32 height)
return result; return result;
} }
FILE_SCOPE void TexturedTriangleInternal(DTRRenderBuffer *const renderBuffer, FILE_SCOPE void
RenderLightInternal lighting, DqnV3 p1, DqnV3 p2, DqnV3 p3, TexturedTriangleInternal(DTRRenderContext context, RenderLightInternal lighting, DqnV3 p1, DqnV3 p2,
DqnV2 uv1, DqnV2 uv2, DqnV2 uv3, DTRBitmap *const texture, DqnV3 p3, DqnV2 uv1, DqnV2 uv2, DqnV2 uv3, DTRBitmap *const texture,
DqnV4 color, const DTRRenderTransform transform = DTRRender_DefaultTriangleTransform()) DqnV4 color,
const DTRRenderTransform transform = DTRRender_DefaultTriangleTransform())
{ {
DTRRenderBuffer *renderBuffer = context.renderBuffer;
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Transform vertexes p1, p2, p3 inplace // Transform vertexes p1, p2, p3 inplace
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@ -1308,12 +1371,12 @@ FILE_SCOPE void TexturedTriangleInternal(DTRRenderBuffer *const renderBuffer,
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
if (globalDTRPlatformFlags.canUseSSE2) if (globalDTRPlatformFlags.canUseSSE2)
{ {
SIMDTriangle(renderBuffer, p1, p2, p3, uv1, uv2, uv3, lightIntensity1, lightIntensity2, SIMDTriangle(context, p1, p2, p3, uv1, uv2, uv3, lightIntensity1, lightIntensity2,
lightIntensity3, ignoreLight, texture, color, min, max); lightIntensity3, ignoreLight, texture, color, min, max);
} }
else else
{ {
SlowTriangle(renderBuffer, p1, p2, p3, uv1, uv2, uv3, lightIntensity1, lightIntensity2, SlowTriangle(context, p1, p2, p3, uv1, uv2, uv3, lightIntensity1, lightIntensity2,
lightIntensity3, ignoreLight, texture, color, min, max); lightIntensity3, ignoreLight, texture, color, min, max);
} }
@ -1326,7 +1389,7 @@ FILE_SCOPE void TexturedTriangleInternal(DTRRenderBuffer *const renderBuffer,
bool drawBasis = false; bool drawBasis = false;
bool drawVertexMarkers = false; bool drawVertexMarkers = false;
DebugRenderMarkers(renderBuffer, pList, DQN_ARRAY_COUNT(pList), transform, drawBoundingBox, DebugRenderMarkers(context, pList, DQN_ARRAY_COUNT(pList), transform, drawBoundingBox,
drawBasis, drawVertexMarkers); drawBasis, drawVertexMarkers);
} }
} }
@ -1337,18 +1400,18 @@ FILE_SCOPE RenderLightInternal NullRenderLightInternal()
return result; return result;
} }
void DTRRender_TexturedTriangle(DTRRenderBuffer *const renderBuffer, void DTRRender_TexturedTriangle(DTRRenderContext context,
DqnV3 p1, DqnV3 p2, DqnV3 p3, DqnV2 uv1, DqnV2 uv2, DqnV2 uv3, DqnV3 p1, DqnV3 p2, DqnV3 p3, DqnV2 uv1, DqnV2 uv2, DqnV2 uv3,
DTRBitmap *const texture, DqnV4 color, DTRBitmap *const texture, DqnV4 color,
const DTRRenderTransform transform) const DTRRenderTransform transform)
{ {
TexturedTriangleInternal(renderBuffer, NullRenderLightInternal(), p1, p2, p3, uv1, uv2, uv3, texture, TexturedTriangleInternal(context, NullRenderLightInternal(), p1, p2, p3, uv1, uv2, uv3, texture,
color, transform); color, transform);
} }
typedef struct RenderMeshJob typedef struct RenderMeshJob
{ {
DTRRenderBuffer *renderBuffer; DTRRenderContext context;
DTRBitmap *tex; DTRBitmap *tex;
RenderLightInternal lighting; RenderLightInternal lighting;
@ -1371,15 +1434,18 @@ void MultiThreadedRenderMesh(struct PlatformJobQueue *const queue, void *const u
RenderMeshJob *job = (RenderMeshJob *)userData; RenderMeshJob *job = (RenderMeshJob *)userData;
#if 1 #if 1
TexturedTriangleInternal(job->renderBuffer, job->lighting, job->v1, job->v2, job->v3, job->uv1, TexturedTriangleInternal(job->context, job->lighting, job->v1, job->v2, job->v3, job->uv1,
job->uv2, job->uv3, job->tex, job->color); job->uv2, job->uv3, job->tex, job->color);
#endif #endif
} }
void DTRRender_Mesh(DTRRenderBuffer *const renderBuffer, DqnMemStack *const tempStack, void DTRRender_Mesh(DTRRenderContext context, PlatformJobQueue *const jobQueue, DTRMesh *const mesh,
PlatformAPI *const api, PlatformJobQueue *const jobQueue, DTRMesh *const mesh,
DTRRenderLight lighting, const DqnV3 pos, const DTRRenderTransform transform) DTRRenderLight lighting, const DqnV3 pos, const DTRRenderTransform transform)
{ {
DqnMemStack *tempStack = context.tempStack;
DTRRenderBuffer *renderBuffer = context.renderBuffer;
PlatformAPI *api = context.api;
if (!mesh || !renderBuffer || !tempStack || !api || !jobQueue) return; if (!mesh || !renderBuffer || !tempStack || !api || !jobQueue) return;
DqnMat4 viewPModelViewProjection = {}; DqnMat4 viewPModelViewProjection = {};
@ -1411,6 +1477,7 @@ void DTRRender_Mesh(DTRRenderBuffer *const renderBuffer, DqnMemStack *const temp
viewPModelViewProjection = DqnMat4_Mul(viewport, modelViewProjection); viewPModelViewProjection = DqnMat4_Mul(viewport, modelViewProjection);
} }
bool RUN_MULTITHREADED = false;
for (u32 i = 0; i < mesh->numFaces; i++) for (u32 i = 0; i < mesh->numFaces; i++)
{ {
DTRMeshFace face = mesh->faces[i]; DTRMeshFace face = mesh->faces[i];
@ -1492,7 +1559,6 @@ void DTRRender_Mesh(DTRRenderBuffer *const renderBuffer, DqnMemStack *const temp
lightingInternal.numNormals = 3; lightingInternal.numNormals = 3;
bool DEBUG_NO_TEX = false; bool DEBUG_NO_TEX = false;
bool RUN_MULTITHREADED = true;
if (RUN_MULTITHREADED) if (RUN_MULTITHREADED)
{ {
@ -1506,8 +1572,8 @@ void DTRRender_Mesh(DTRRenderBuffer *const renderBuffer, DqnMemStack *const temp
jobData->uv2 = uv2; jobData->uv2 = uv2;
jobData->uv3 = uv3; jobData->uv3 = uv3;
jobData->color = color; jobData->color = color;
jobData->renderBuffer = renderBuffer;
jobData->lighting = lightingInternal; jobData->lighting = lightingInternal;
jobData->context = context;
if (DTR_DEBUG && DEBUG_NO_TEX) if (DTR_DEBUG && DEBUG_NO_TEX)
{ {
@ -1537,12 +1603,12 @@ void DTRRender_Mesh(DTRRenderBuffer *const renderBuffer, DqnMemStack *const temp
{ {
if (DTR_DEBUG && DEBUG_NO_TEX) if (DTR_DEBUG && DEBUG_NO_TEX)
{ {
TexturedTriangleInternal(renderBuffer, lightingInternal, v1.xyz, v2.xyz, v3.xyz, TexturedTriangleInternal(context, lightingInternal, v1.xyz, v2.xyz, v3.xyz,
uv1, uv2, uv3, NULL, color); uv1, uv2, uv3, NULL, color);
} }
else else
{ {
TexturedTriangleInternal(renderBuffer, lightingInternal, v1.xyz, v2.xyz, v3.xyz, TexturedTriangleInternal(context, lightingInternal, v1.xyz, v2.xyz, v3.xyz,
uv1, uv2, uv3, &mesh->tex, color); uv1, uv2, uv3, &mesh->tex, color);
} }
} }
@ -1550,28 +1616,33 @@ void DTRRender_Mesh(DTRRenderBuffer *const renderBuffer, DqnMemStack *const temp
if (DTR_DEBUG && DEBUG_WIREFRAME) if (DTR_DEBUG && DEBUG_WIREFRAME)
{ {
DqnV4 wireColor = DqnV4_4f(1.0f, 1.0f, 1.0f, 0.01f); DqnV4 wireColor = DqnV4_4f(1.0f, 1.0f, 1.0f, 0.01f);
DTRRender_Line(renderBuffer, DqnV2i_V2(v1.xy), DqnV2i_V2(v2.xy), wireColor); DTRRender_Line(context, DqnV2i_V2(v1.xy), DqnV2i_V2(v2.xy), wireColor);
DTRRender_Line(renderBuffer, DqnV2i_V2(v2.xy), DqnV2i_V2(v3.xy), wireColor); DTRRender_Line(context, DqnV2i_V2(v2.xy), DqnV2i_V2(v3.xy), wireColor);
DTRRender_Line(renderBuffer, DqnV2i_V2(v3.xy), DqnV2i_V2(v1.xy), wireColor); DTRRender_Line(context, DqnV2i_V2(v3.xy), DqnV2i_V2(v1.xy), wireColor);
} }
} }
if (RUN_MULTITHREADED)
{
while (api->QueueTryExecuteNextJob(jobQueue)) while (api->QueueTryExecuteNextJob(jobQueue))
; ;
}
} }
void DTRRender_Triangle(DTRRenderBuffer *const renderBuffer, DqnV3 p1, DqnV3 p2, DqnV3 p3, void DTRRender_Triangle(DTRRenderContext context, DqnV3 p1, DqnV3 p2, DqnV3 p3, DqnV4 color,
DqnV4 color, const DTRRenderTransform transform) const DTRRenderTransform transform)
{ {
const DqnV2 NO_UV = {}; const DqnV2 NO_UV = {};
DTRBitmap *const NO_TEX = NULL; DTRBitmap *const NO_TEX = NULL;
TexturedTriangleInternal(renderBuffer, NullRenderLightInternal(), p1, p2, p3, NO_UV, NO_UV, TexturedTriangleInternal(context, NullRenderLightInternal(), p1, p2, p3, NO_UV, NO_UV,
NO_UV, NO_TEX, color, transform); NO_UV, NO_TEX, color, transform);
} }
void DTRRender_Bitmap(DTRRenderBuffer *const renderBuffer, DTRBitmap *const bitmap, DqnV2 pos, void DTRRender_Bitmap(DTRRenderContext context, DTRBitmap *const bitmap, DqnV2 pos,
const DTRRenderTransform transform, DqnV4 color) const DTRRenderTransform transform, DqnV4 color)
{ {
DTRRenderBuffer *renderBuffer = context.renderBuffer;
if (!bitmap || !bitmap->memory || !renderBuffer) return; if (!bitmap || !bitmap->memory || !renderBuffer) return;
DTR_DEBUG_EP_TIMED_FUNCTION(); DTR_DEBUG_EP_TIMED_FUNCTION();
@ -1745,7 +1816,7 @@ void DTRRender_Bitmap(DTRRenderBuffer *const renderBuffer, DTRBitmap *const bitm
blend.g *= color.g; blend.g *= color.g;
blend.b *= color.b; blend.b *= color.b;
SetPixel(renderBuffer, bufferX, bufferY, blend, ColorSpace_Linear); SetPixel(context, bufferX, bufferY, blend, ColorSpace_Linear);
} }
} }
} }
@ -1759,14 +1830,14 @@ void DTRRender_Bitmap(DTRRenderBuffer *const renderBuffer, DTRBitmap *const bitm
bool drawBasis = true; bool drawBasis = true;
bool drawVertexMarkers = true; bool drawVertexMarkers = true;
DebugRenderMarkers(renderBuffer, pList, RECT_PLIST_SIZE, transform, drawBoundingBox, DebugRenderMarkers(context, pList, RECT_PLIST_SIZE, transform, drawBoundingBox,
drawBasis, drawVertexMarkers); drawBasis, drawVertexMarkers);
} }
} }
void DTRRender_Clear(DTRRenderBuffer *const renderBuffer, void DTRRender_Clear(DTRRenderContext context, DqnV3 color)
DqnV3 color)
{ {
DTRRenderBuffer *renderBuffer = context.renderBuffer;
if (!renderBuffer) return; if (!renderBuffer) return;
DQN_ASSERT(color.r >= 0.0f && color.r <= 1.0f); DQN_ASSERT(color.r >= 0.0f && color.r <= 1.0f);

View File

@ -17,6 +17,9 @@ typedef struct DTRRenderBuffer
i32 height; i32 height;
i32 bytesPerPixel; i32 bytesPerPixel;
PlatformLock *volatile zDepthLock;
PlatformLock *volatile blitLock;
u8 *memory; // Format: XX RR GG BB, and has (width * height * bytesPerPixels) elements u8 *memory; // Format: XX RR GG BB, and has (width * height * bytesPerPixels) elements
f32 *zBuffer; // zBuffer has (width * height) elements f32 *zBuffer; // zBuffer has (width * height) elements
@ -74,15 +77,22 @@ typedef struct DTRRenderLight
DqnV4 color; DqnV4 color;
} DTRRenderLight; } DTRRenderLight;
typedef struct DTRRenderContext
{
DTRRenderBuffer *renderBuffer;
DqnMemStack *tempStack;
PlatformAPI *api;
} DTRRenderContext;
// NOTE: All colors should be in the range of [0->1] where DqnV4 is a struct with 4 floats, rgba // NOTE: All colors should be in the range of [0->1] where DqnV4 is a struct with 4 floats, rgba
// Leaving len = -1 for text will make the system use strlen to determine len. // Leaving len = -1 for text will make the system use strlen to determine len.
void DTRRender_Text (DTRRenderBuffer *const renderBuffer, const DTRFont font, DqnV2 pos, const char *const text, DqnV4 color = DqnV4_1f(1), i32 len = -1); void DTRRender_Text (DTRRenderContext context, const DTRFont font, DqnV2 pos, const char *const text, DqnV4 color = DqnV4_1f(1), i32 len = -1);
void DTRRender_Line (DTRRenderBuffer *const renderBuffer, DqnV2i a, DqnV2i b, DqnV4 color); void DTRRender_Line (DTRRenderContext context, DqnV2i a, DqnV2i b, DqnV4 color);
void DTRRender_Rectangle (DTRRenderBuffer *const renderBuffer, DqnV2 min, DqnV2 max, DqnV4 color, const DTRRenderTransform transform = DTRRender_DefaultTransform()); void DTRRender_Rectangle (DTRRenderContext context, DqnV2 min, DqnV2 max, DqnV4 color, const DTRRenderTransform transform = DTRRender_DefaultTransform());
void DTRRender_Mesh (DTRRenderBuffer *const renderBuffer, DqnMemStack *const tempStack, PlatformAPI *const api, PlatformJobQueue *const jobQueue, DTRMesh *const mesh, DTRRenderLight lighting, const DqnV3 pos, const DTRRenderTransform transform); void DTRRender_Mesh (DTRRenderContext context, PlatformJobQueue *const jobQueue, DTRMesh *const mesh, DTRRenderLight lighting, const DqnV3 pos, const DTRRenderTransform transform);
void DTRRender_Triangle (DTRRenderBuffer *const renderBuffer, DqnV3 p1, DqnV3 p2, DqnV3 p3, DqnV4 color, const DTRRenderTransform transform = DTRRender_DefaultTriangleTransform()); void DTRRender_Triangle (DTRRenderContext context, DqnV3 p1, DqnV3 p2, DqnV3 p3, DqnV4 color, const DTRRenderTransform transform = DTRRender_DefaultTriangleTransform());
void DTRRender_TexturedTriangle(DTRRenderBuffer *const renderBuffer, DqnV3 p1, DqnV3 p2, DqnV3 p3, DqnV2 uv1, DqnV2 uv2, DqnV2 uv3, DTRBitmap *const texture, DqnV4 color, const DTRRenderTransform transform = DTRRender_DefaultTriangleTransform()); void DTRRender_TexturedTriangle(DTRRenderContext context, DqnV3 p1, DqnV3 p2, DqnV3 p3, DqnV2 uv1, DqnV2 uv2, DqnV2 uv3, DTRBitmap *const texture, DqnV4 color, const DTRRenderTransform transform = DTRRender_DefaultTriangleTransform());
void DTRRender_Bitmap (DTRRenderBuffer *const renderBuffer, DTRBitmap *const bitmap, DqnV2 pos, const DTRRenderTransform transform = DTRRender_DefaultTransform(), DqnV4 color = DqnV4_4f(1, 1, 1, 1)); void DTRRender_Bitmap (DTRRenderContext context, DTRBitmap *const bitmap, DqnV2 pos, const DTRRenderTransform transform = DTRRender_DefaultTransform(), DqnV4 color = DqnV4_4f(1, 1, 1, 1));
void DTRRender_Clear (DTRRenderBuffer *const renderBuffer, DqnV3 color); void DTRRender_Clear (DTRRenderContext context, DqnV3 color);
#endif #endif

View File

@ -8,15 +8,57 @@
#define UNICODE #define UNICODE
#define _UNICODE #define _UNICODE
const char *const DLL_NAME = "dtrenderer.dll"; ////////////////////////////////////////////////////////////////////////////////
const char *const DLL_TMP_NAME = "dtrenderer_temp.dll"; // Platform Mutex/Lock
////////////////////////////////////////////////////////////////////////////////
typedef struct PlatformLock
{
CRITICAL_SECTION critSection;
} PlatformLock;
PlatformLock *Platform_LockInit(DqnMemStack *const stack)
{
const u32 DEFAULT_SPIN_COUNT = 16000;
PlatformLock *lock = (PlatformLock *)DqnMemStack_Push(stack, sizeof(*lock));
if (lock)
{
if (InitializeCriticalSectionEx(&lock->critSection, DEFAULT_SPIN_COUNT, 0))
{
return lock;
}
else
{
DqnMemStack_Pop(stack, lock, sizeof(*lock));
}
}
return NULL;
}
void Platform_LockAcquire(PlatformLock *const lock)
{
if (lock) EnterCriticalSection(&lock->critSection);
}
void Platform_LockRelease(PlatformLock *const lock)
{
if (lock) LeaveCriticalSection(&lock->critSection);
}
void Platform_LockDelete(PlatformLock *const lock)
{
if (lock)
{
DeleteCriticalSection(&lock->critSection);
}
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Platform Multi Threading // Platform Multi Threading
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
struct PlatformJobQueue struct PlatformJobQueue
{ {
PlatformJob volatile *jobList; PlatformJob *volatile jobList;
LONG size; LONG size;
// NOTE: Modified by main+worker threads // NOTE: Modified by main+worker threads
@ -43,6 +85,13 @@ bool Platform_QueueAddJob(PlatformJobQueue *const queue, const PlatformJob job)
return true; return true;
} }
FILE_SCOPE void DebugWin32JobPrintNumber(PlatformJobQueue *const queue, void *const userData)
{
i32 numberToPrint = *((i32 *)userData);
DqnWin32_OutputDebugString("Thread %d: Printing number: %d\n", GetCurrentThreadId(),
numberToPrint);
}
bool Platform_QueueTryExecuteNextJob(PlatformJobQueue *const queue) bool Platform_QueueTryExecuteNextJob(PlatformJobQueue *const queue)
{ {
LONG originalJobToExecute = queue->jobToExecuteIndex; LONG originalJobToExecute = queue->jobToExecuteIndex;
@ -167,6 +216,10 @@ void Platform_FileClose(PlatformFile *const file)
#include <Windows.h> #include <Windows.h>
#include <Windowsx.h> // For GET_X|Y_LPARAM(), mouse input #include <Windowsx.h> // For GET_X|Y_LPARAM(), mouse input
#include <Psapi.h> // For win32 GetProcessMemoryInfo() #include <Psapi.h> // For win32 GetProcessMemoryInfo()
const char *const DLL_NAME = "dtrenderer.dll";
const char *const DLL_TMP_NAME = "dtrenderer_temp.dll";
typedef struct Win32RenderBitmap typedef struct Win32RenderBitmap
{ {
BITMAPINFO info; BITMAPINFO info;
@ -510,13 +563,6 @@ i32 Win32GetModuleDirectory(char *const buf, const u32 bufLen)
return lastSlashIndex; return lastSlashIndex;
} }
FILE_SCOPE void DebugWin32JobPrintNumber(PlatformJobQueue *const queue, void *const userData)
{
i32 numberToPrint = *((i32 *)userData);
DqnWin32_OutputDebugString("Thread %d: Printing number: %d\n", GetCurrentThreadId(),
numberToPrint);
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd) int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
{ {
@ -637,6 +683,11 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi
platformAPI.QueueAddJob = Platform_QueueAddJob; platformAPI.QueueAddJob = Platform_QueueAddJob;
platformAPI.QueueTryExecuteNextJob = Platform_QueueTryExecuteNextJob; platformAPI.QueueTryExecuteNextJob = Platform_QueueTryExecuteNextJob;
platformAPI.LockInit = Platform_LockInit;
platformAPI.LockAcquire = Platform_LockAcquire;
platformAPI.LockRelease = Platform_LockRelease;
platformAPI.LockDelete = Platform_LockDelete;
PlatformJobQueue jobQueue = {}; PlatformJobQueue jobQueue = {};
PlatformInput platformInput = {}; PlatformInput platformInput = {};
@ -646,6 +697,7 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi
platformInput.flags.canUseRdtsc = IsProcessorFeaturePresent(PF_RDTSC_INSTRUCTION_AVAILABLE); platformInput.flags.canUseRdtsc = IsProcessorFeaturePresent(PF_RDTSC_INSTRUCTION_AVAILABLE);
// Threading // Threading
PlatformJob jobQueueMemory[512] = {};
{ {
DqnMemStackTempRegion memRegion; DqnMemStackTempRegion memRegion;
if (!DqnMemStackTempRegion_Begin(&memRegion, &globalPlatformMemory.tempStack)) if (!DqnMemStackTempRegion_Begin(&memRegion, &globalPlatformMemory.tempStack))
@ -717,15 +769,12 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Threading // Threading
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
const i32 QUEUE_SIZE = 512; jobQueue.jobList = jobQueueMemory;
jobQueue.jobList = (PlatformJob *)DqnMemStack_Push(&globalPlatformMemory.mainStack, jobQueue.size = DQN_ARRAY_COUNT(jobQueueMemory);
sizeof(*jobQueue.jobList) * QUEUE_SIZE);
// NOTE: InterlockedIncrement requires things to be on 32bit boundaries. // NOTE: InterlockedIncrement requires things to be on 32bit boundaries.
DQN_ASSERT(((size_t)&jobQueue.jobToExecuteIndex) % 4 == 0); DQN_ASSERT(((size_t)&jobQueue.jobToExecuteIndex) % 4 == 0);
if (jobQueue.jobList)
{
// NOTE: (numCores - 1), 1 core is already exclusively for main thread // NOTE: (numCores - 1), 1 core is already exclusively for main thread
i32 availableThreads = (numCores - 1) * numLogicalCores; i32 availableThreads = (numCores - 1) * numLogicalCores;
@ -745,8 +794,8 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi
CloseHandle(handle); CloseHandle(handle);
} }
// Create jobs #if 0
jobQueue.size = QUEUE_SIZE; // DEBUG Create jobs
for (i32 i = 0; i < 20; i++) for (i32 i = 0; i < 20; i++)
{ {
PlatformJob job = {}; PlatformJob job = {};
@ -761,6 +810,7 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi
while (Platform_QueueTryExecuteNextJob(&jobQueue)) while (Platform_QueueTryExecuteNextJob(&jobQueue))
; ;
#endif
} }
else else
{ {
@ -768,7 +818,6 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi
DqnWin32_DisplayLastError("CreateSemaphore() failed"); DqnWin32_DisplayLastError("CreateSemaphore() failed");
} }
} }
}
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Update Loop // Update Loop

View File

@ -39,7 +39,7 @@ REM wd4100 unused argument parameters
REM wd4201 nonstandard extension used: nameless struct/union REM wd4201 nonstandard extension used: nameless struct/union
REM wd4189 local variable is initialised but not referenced REM wd4189 local variable is initialised but not referenced
REM wd4505 unreferenced local function not used will be removed REM wd4505 unreferenced local function not used will be removed
set CompileFlags=-EHsc -GR- -Oi -MT -Z7 -W4 -wd4100 -wd4201 -wd4189 -wd4505 -Od -FAsc /I..\src\external\ set CompileFlags=-EHsc -GR- -Oi -MT -Z7 -W4 -wd4100 -wd4201 -wd4189 -wd4505 -O2 -FAsc /I..\src\external\
set DLLFlags=/Fm%ProjectName% /Fo%ProjectName% /Fa%ProjectName% /Fe%ProjectName% set DLLFlags=/Fm%ProjectName% /Fo%ProjectName% /Fa%ProjectName% /Fe%ProjectName%
set Win32Flags=/FmWin32DTRenderer /FeWin32DTRenderer set Win32Flags=/FmWin32DTRenderer /FeWin32DTRenderer