Improve assert with variadic macro for user msg
This commit is contained in:
parent
5397cdd9b9
commit
eeb773747a
@ -4,6 +4,8 @@
|
|||||||
#include "dqn.h"
|
#include "dqn.h"
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
|
|
||||||
|
typedef void PlatformAPI_DieGracefully();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Platform File I/O
|
// Platform File I/O
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -85,6 +87,8 @@ typedef struct PlatformAPI
|
|||||||
PlatformAPI_LockAcquire *LockAcquire;
|
PlatformAPI_LockAcquire *LockAcquire;
|
||||||
PlatformAPI_LockRelease *LockRelease;
|
PlatformAPI_LockRelease *LockRelease;
|
||||||
PlatformAPI_LockDelete *LockDelete;
|
PlatformAPI_LockDelete *LockDelete;
|
||||||
|
|
||||||
|
PlatformAPI_DieGracefully *DieGracefully;
|
||||||
} PlatformAPI;
|
} PlatformAPI;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1068,192 +1068,6 @@ FILE_SCOPE void SIMDTriangle(DTRRenderContext context, const DqnV3 p1, const Dqn
|
|||||||
DEBUG_SIMD_AUTO_CHOOSE_END_CYCLE_COUNT(Triangle);
|
DEBUG_SIMD_AUTO_CHOOSE_END_CYCLE_COUNT(Triangle);
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE_SCOPE void SIMDBetterTriangle(DTRRenderContext context, const DqnV3 p1, const DqnV3 p2,
|
|
||||||
const DqnV3 p3, const DqnV2 uv1, const DqnV2 uv2,
|
|
||||||
const DqnV2 uv3, const f32 lightIntensity1,
|
|
||||||
const f32 lightIntensity2, const f32 lightIntensity3,
|
|
||||||
const bool ignoreLight, DTRBitmap *const texture, DqnV4 color,
|
|
||||||
const DqnV2i min, const DqnV2i max)
|
|
||||||
|
|
||||||
{
|
|
||||||
DTR_DEBUG_EP_TIMED_FUNCTION();
|
|
||||||
DEBUG_SIMD_AUTO_CHOOSE_BEGIN_CYCLE_COUNT(Triangle);
|
|
||||||
|
|
||||||
DEBUG_SIMD_AUTO_CHOOSE_BEGIN_CYCLE_COUNT(Triangle_Preamble);
|
|
||||||
|
|
||||||
DTRRenderBuffer *const renderBuffer = context.renderBuffer;
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Convert color
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
__m128 simdColor = _mm_set_ps(color.a, color.b, color.g, color.r);
|
|
||||||
simdColor = SIMDSRGB1ToLinearSpace(simdColor);
|
|
||||||
simdColor = SIMDPreMultiplyAlpha1(simdColor);
|
|
||||||
f32 preserveAlpha = ((f32 *)&simdColor)[3];
|
|
||||||
|
|
||||||
const __m128 ZERO_4X = _mm_set_ps1(0.0f);
|
|
||||||
__m128 simdLightIntensity1 = _mm_set_ps1(lightIntensity1);
|
|
||||||
__m128 simdLightIntensity2 = _mm_set_ps1(lightIntensity2);
|
|
||||||
__m128 simdLightIntensity3 = _mm_set_ps1(lightIntensity3);
|
|
||||||
|
|
||||||
simdLightIntensity1 = _mm_max_ps(simdLightIntensity1, ZERO_4X);
|
|
||||||
simdLightIntensity2 = _mm_max_ps(simdLightIntensity2, ZERO_4X);
|
|
||||||
simdLightIntensity3 = _mm_max_ps(simdLightIntensity3, ZERO_4X);
|
|
||||||
|
|
||||||
__m128 p1Light = _mm_mul_ps(simdColor, simdLightIntensity1);
|
|
||||||
__m128 p2Light = _mm_mul_ps(simdColor, simdLightIntensity2);
|
|
||||||
__m128 p3Light = _mm_mul_ps(simdColor, simdLightIntensity3);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Setup SIMD data
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
const u32 NUM_X_PIXELS_TO_SIMD = 1;
|
|
||||||
const u32 NUM_Y_PIXELS_TO_SIMD = 1;
|
|
||||||
|
|
||||||
// SignedArea: _mm_set_ps(unused, p3, p2, p1) ie 0=p1, 1=p1, 2=p3, 3=unused
|
|
||||||
__m128 signedAreaPixel1 = _mm_set_ps1(0);
|
|
||||||
// __m128 signedAreaPixel2 = _mm_set_ps1(0);
|
|
||||||
|
|
||||||
__m128 signedAreaPixelDeltaX = _mm_set_ps1(0);
|
|
||||||
__m128 signedAreaPixelDeltaY = _mm_set_ps1(0);
|
|
||||||
__m128 invSignedAreaParallelogram_4x = _mm_set_ps1(0);
|
|
||||||
|
|
||||||
__m128 triangleZ = _mm_set_ps(0, p3.z, p2.z, p1.z);
|
|
||||||
{
|
|
||||||
DEBUG_SIMD_AUTO_CHOOSE_BEGIN_CYCLE_COUNT(Triangle_Preamble_SArea);
|
|
||||||
DTR_DEBUG_EP_TIMED_BLOCK("SIMDTriangle_Preamble_SArea");
|
|
||||||
DqnV2 startP = DqnV2_V2i(min);
|
|
||||||
f32 signedArea1Start = Triangle2TimesSignedArea(p2.xy, p3.xy, startP);
|
|
||||||
f32 signedArea1DeltaX = p2.y - p3.y;
|
|
||||||
f32 signedArea1DeltaY = p3.x - p2.x;
|
|
||||||
|
|
||||||
f32 signedArea2Start = Triangle2TimesSignedArea(p3.xy, p1.xy, startP);
|
|
||||||
f32 signedArea2DeltaX = p3.y - p1.y;
|
|
||||||
f32 signedArea2DeltaY = p1.x - p3.x;
|
|
||||||
|
|
||||||
f32 signedArea3Start = Triangle2TimesSignedArea(p1.xy, p2.xy, startP);
|
|
||||||
f32 signedArea3DeltaX = p1.y - p2.y;
|
|
||||||
f32 signedArea3DeltaY = p2.x - p1.x;
|
|
||||||
DTR_DEBUG_EP_TIMED_END_BLOCK();
|
|
||||||
DEBUG_SIMD_AUTO_CHOOSE_END_CYCLE_COUNT(Triangle_Preamble_SArea);
|
|
||||||
|
|
||||||
DEBUG_SIMD_AUTO_CHOOSE_BEGIN_CYCLE_COUNT(Triangle_Preamble_SIMDStep);
|
|
||||||
f32 signedAreaParallelogram = signedArea1Start + signedArea2Start + signedArea3Start;
|
|
||||||
if (signedAreaParallelogram == 0) return;
|
|
||||||
|
|
||||||
f32 invSignedAreaParallelogram = 1.0f / signedAreaParallelogram;
|
|
||||||
invSignedAreaParallelogram_4x = _mm_set_ps1(invSignedAreaParallelogram);
|
|
||||||
|
|
||||||
// NOTE: Order is important here!
|
|
||||||
signedAreaPixelDeltaX = _mm_set_ps(0, signedArea3DeltaX, signedArea2DeltaX, signedArea1DeltaX);
|
|
||||||
signedAreaPixelDeltaY = _mm_set_ps(0, signedArea3DeltaY, signedArea2DeltaY, signedArea1DeltaY);
|
|
||||||
|
|
||||||
signedAreaPixel1 = _mm_set_ps(0, signedArea3Start, signedArea2Start, signedArea1Start);
|
|
||||||
// signedAreaPixel2 = _mm_add_ps(signedAreaPixel1, signedAreaPixelDeltaX);
|
|
||||||
|
|
||||||
// NOTE: Increase step size to the number of pixels rasterised with SIMD
|
|
||||||
{
|
|
||||||
const __m128 STEP_X_4X = _mm_set_ps1((f32)NUM_X_PIXELS_TO_SIMD);
|
|
||||||
const __m128 STEP_Y_4X = _mm_set_ps1((f32)NUM_Y_PIXELS_TO_SIMD);
|
|
||||||
|
|
||||||
signedAreaPixelDeltaX = _mm_mul_ps(signedAreaPixelDeltaX, STEP_X_4X);
|
|
||||||
signedAreaPixelDeltaY = _mm_mul_ps(signedAreaPixelDeltaY, STEP_Y_4X);
|
|
||||||
}
|
|
||||||
DEBUG_SIMD_AUTO_CHOOSE_END_CYCLE_COUNT(Triangle_Preamble_SIMDStep);
|
|
||||||
}
|
|
||||||
|
|
||||||
const DqnV2 uv2SubUv1 = uv2 - uv1;
|
|
||||||
const DqnV2 uv3SubUv1 = uv3 - uv1;
|
|
||||||
|
|
||||||
DEBUG_SIMD_AUTO_CHOOSE_END_CYCLE_COUNT(Triangle_Preamble);
|
|
||||||
const u32 IS_GREATER_MASK = 0xF;
|
|
||||||
const u32 zBufferPitch = renderBuffer->width;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Scan and Render
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
DEBUG_SIMD_AUTO_CHOOSE_BEGIN_CYCLE_COUNT(Triangle_Rasterise);
|
|
||||||
for (i32 bufferY = min.y; bufferY < max.y; bufferY += NUM_Y_PIXELS_TO_SIMD)
|
|
||||||
{
|
|
||||||
__m128 signedArea1 = signedAreaPixel1;
|
|
||||||
// __m128 signedArea2 = signedAreaPixel2;
|
|
||||||
|
|
||||||
for (i32 bufferX = min.x; bufferX < max.x; bufferX += NUM_X_PIXELS_TO_SIMD)
|
|
||||||
{
|
|
||||||
// Rasterise buffer(X, Y) pixel
|
|
||||||
{
|
|
||||||
__m128 checkArea = signedArea1;
|
|
||||||
__m128 isGreater = _mm_cmpge_ps(checkArea, ZERO_4X);
|
|
||||||
i32 isGreaterResult = _mm_movemask_ps(isGreater);
|
|
||||||
i32 posX = bufferX;
|
|
||||||
i32 posY = bufferY;
|
|
||||||
|
|
||||||
if ((isGreaterResult & IS_GREATER_MASK) == IS_GREATER_MASK)
|
|
||||||
{
|
|
||||||
DEBUG_SIMD_AUTO_CHOOSE_BEGIN_CYCLE_COUNT(Triangle_RasterisePixel);
|
|
||||||
__m128 barycentric = _mm_mul_ps(checkArea, invSignedAreaParallelogram_4x);
|
|
||||||
__m128 barycentricZ = _mm_mul_ps(triangleZ, barycentric);
|
|
||||||
|
|
||||||
f32 pixelZDepth = ((f32 *)&barycentricZ)[0] +
|
|
||||||
((f32 *)&barycentricZ)[1] +
|
|
||||||
((f32 *)&barycentricZ)[2];
|
|
||||||
|
|
||||||
i32 zBufferIndex = posX + (posY * zBufferPitch);
|
|
||||||
if (context.multithread)
|
|
||||||
{
|
|
||||||
bool currLockValue;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
currLockValue = (bool)context.api->AtomicCompareSwap(
|
|
||||||
(u32 *)&renderBuffer->pixelLockTable[zBufferIndex], (u32) true,
|
|
||||||
(u32) false);
|
|
||||||
} while (currLockValue != false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pixelZDepth > renderBuffer->zBuffer[zBufferIndex])
|
|
||||||
{
|
|
||||||
__m128 finalColor = simdColor;
|
|
||||||
renderBuffer->zBuffer[zBufferIndex] = pixelZDepth;
|
|
||||||
if (!ignoreLight)
|
|
||||||
{
|
|
||||||
__m128 barycentricA_4x = _mm_set_ps1(((f32 *)&barycentric)[0]);
|
|
||||||
__m128 barycentricB_4x = _mm_set_ps1(((f32 *)&barycentric)[1]);
|
|
||||||
__m128 barycentricC_4x = _mm_set_ps1(((f32 *)&barycentric)[2]);
|
|
||||||
|
|
||||||
__m128 barycentricLight1 = _mm_mul_ps(p1Light, barycentricA_4x);
|
|
||||||
__m128 barycentricLight2 = _mm_mul_ps(p2Light, barycentricB_4x);
|
|
||||||
__m128 barycentricLight3 = _mm_mul_ps(p3Light, barycentricC_4x);
|
|
||||||
|
|
||||||
__m128 light =
|
|
||||||
_mm_add_ps(barycentricLight3,
|
|
||||||
_mm_add_ps(barycentricLight1, barycentricLight2));
|
|
||||||
|
|
||||||
finalColor = _mm_mul_ps(finalColor, light);
|
|
||||||
((f32 *)&finalColor)[3] = preserveAlpha;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (texture)
|
|
||||||
{
|
|
||||||
__m128 texSampledColor = SIMDSampleTextureForTriangle(
|
|
||||||
texture, uv1, uv2SubUv1, uv3SubUv1, barycentric);
|
|
||||||
finalColor = _mm_mul_ps(texSampledColor, finalColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
SIMDSetPixel(context, posX, posY, finalColor, ColorSpace_Linear);
|
|
||||||
}
|
|
||||||
renderBuffer->pixelLockTable[zBufferIndex] = false;
|
|
||||||
DEBUG_SIMD_AUTO_CHOOSE_END_CYCLE_COUNT(Triangle_RasterisePixel);
|
|
||||||
}
|
|
||||||
signedArea1 = _mm_add_ps(signedArea1, signedAreaPixelDeltaX);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
signedAreaPixel1 = _mm_add_ps(signedAreaPixel1, signedAreaPixelDeltaY);
|
|
||||||
// signedAreaPixel2 = _mm_add_ps(signedAreaPixel2, signedAreaPixelDeltaY);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_SIMD_AUTO_CHOOSE_END_CYCLE_COUNT(Triangle_Rasterise);
|
|
||||||
DEBUG_SIMD_AUTO_CHOOSE_END_CYCLE_COUNT(Triangle);
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE_SCOPE void SlowTriangle(DTRRenderContext context, 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,
|
||||||
|
@ -8,6 +8,11 @@
|
|||||||
#define UNICODE
|
#define UNICODE
|
||||||
#define _UNICODE
|
#define _UNICODE
|
||||||
|
|
||||||
|
FILE_SCOPE PlatformMemory globalPlatformMemory;
|
||||||
|
FILE_SCOPE bool globalRunning;
|
||||||
|
|
||||||
|
void Platform_DieGracefully() { globalRunning = false; }
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Platform Atomics
|
// Platform Atomics
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -267,8 +272,6 @@ typedef struct Win32RenderBitmap
|
|||||||
} Win32RenderBitmap;
|
} Win32RenderBitmap;
|
||||||
|
|
||||||
FILE_SCOPE Win32RenderBitmap globalRenderBitmap;
|
FILE_SCOPE Win32RenderBitmap globalRenderBitmap;
|
||||||
FILE_SCOPE PlatformMemory globalPlatformMemory;
|
|
||||||
FILE_SCOPE bool globalRunning;
|
|
||||||
|
|
||||||
typedef struct Win32ExternalCode
|
typedef struct Win32ExternalCode
|
||||||
{
|
{
|
||||||
@ -659,37 +662,41 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi
|
|||||||
{
|
{
|
||||||
char exeDir[MAX_PATH] = {};
|
char exeDir[MAX_PATH] = {};
|
||||||
i32 lastSlashIndex = DqnWin32_GetEXEDirectory(exeDir, DQN_ARRAY_COUNT(exeDir));
|
i32 lastSlashIndex = DqnWin32_GetEXEDirectory(exeDir, DQN_ARRAY_COUNT(exeDir));
|
||||||
if (lastSlashIndex != -1)
|
if (DQN_ASSERT_MSG(lastSlashIndex != -1, "Not enough space in buffer for exe path"))
|
||||||
{
|
{
|
||||||
DQN_ASSERT(lastSlashIndex + 1 < DQN_ARRAY_COUNT(exeDir));
|
|
||||||
|
|
||||||
exeDir[lastSlashIndex + 1] = 0;
|
exeDir[lastSlashIndex + 1] = 0;
|
||||||
u32 numCopied = Dqn_sprintf(dllPath, "%s%s", exeDir, DLL_NAME);
|
u32 dllNumCopied = Dqn_sprintf(dllPath, "%s%s", exeDir, DLL_NAME);
|
||||||
DQN_ASSERT(numCopied < DQN_ARRAY_COUNT(dllPath));
|
u32 dllTmpNumCopied = Dqn_sprintf(dllTmpPath, "%s%s", exeDir, DLL_TMP_NAME);
|
||||||
|
|
||||||
numCopied = Dqn_sprintf(dllTmpPath, "%s%s", exeDir, DLL_TMP_NAME);
|
if (!DQN_ASSERT_MSG((dllNumCopied < DQN_ARRAY_COUNT(dllPath)) &&
|
||||||
DQN_ASSERT(numCopied < DQN_ARRAY_COUNT(dllTmpPath));
|
(dllTmpNumCopied < DQN_ARRAY_COUNT(dllPath)),
|
||||||
}
|
"Out of space to form DLL path"))
|
||||||
else
|
{
|
||||||
{
|
Platform_DieGracefully();
|
||||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Platform Data Pre-amble
|
// Platform Data Pre-amble
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
DQN_ASSERT(DqnMemStack_Init(&globalPlatformMemory.mainStack, DQN_MEGABYTE(4), true, 4) &&
|
bool memoryInitResult =
|
||||||
DqnMemStack_Init(&globalPlatformMemory.tempStack, DQN_MEGABYTE(4), true, 4) &&
|
DqnMemStack_Init(&globalPlatformMemory.mainStack, DQN_MEGABYTE(4), true, 4) |
|
||||||
DqnMemStack_Init(&globalPlatformMemory.assetStack, DQN_MEGABYTE(4), true, 4)
|
DqnMemStack_Init(&globalPlatformMemory.tempStack, DQN_MEGABYTE(4), true, 4) |
|
||||||
);
|
DqnMemStack_Init(&globalPlatformMemory.assetStack, DQN_MEGABYTE(4), true, 4);
|
||||||
|
if (!DQN_ASSERT_MSG(memoryInitResult, "Unable to allocate DTRenderer globalPlatformMemory stacks"))
|
||||||
|
{
|
||||||
|
Platform_DieGracefully();
|
||||||
|
}
|
||||||
|
|
||||||
PlatformAPI platformAPI = {};
|
PlatformAPI platformAPI = {};
|
||||||
platformAPI.FileOpen = Platform_FileOpen;
|
platformAPI.DieGracefully = Platform_DieGracefully;
|
||||||
platformAPI.FileRead = Platform_FileRead;
|
|
||||||
platformAPI.FileWrite = Platform_FileWrite;
|
platformAPI.FileOpen = Platform_FileOpen;
|
||||||
platformAPI.FileClose = Platform_FileClose;
|
platformAPI.FileRead = Platform_FileRead;
|
||||||
platformAPI.Print = Platform_Print;
|
platformAPI.FileWrite = Platform_FileWrite;
|
||||||
|
platformAPI.FileClose = Platform_FileClose;
|
||||||
|
platformAPI.Print = Platform_Print;
|
||||||
|
|
||||||
platformAPI.QueueAddJob = Platform_QueueAddJob;
|
platformAPI.QueueAddJob = Platform_QueueAddJob;
|
||||||
platformAPI.QueueTryExecuteNextJob = Platform_QueueTryExecuteNextJob;
|
platformAPI.QueueTryExecuteNextJob = Platform_QueueTryExecuteNextJob;
|
||||||
@ -714,11 +721,8 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi
|
|||||||
PlatformJob jobQueueMemory[512] = {};
|
PlatformJob jobQueueMemory[512] = {};
|
||||||
{
|
{
|
||||||
DqnMemStackTempRegion memRegion;
|
DqnMemStackTempRegion memRegion;
|
||||||
if (!DqnMemStackTempRegion_Begin(&memRegion, &globalPlatformMemory.tempStack))
|
if (!DQN_ASSERT(DqnMemStackTempRegion_Begin(&memRegion, &globalPlatformMemory.tempStack)))
|
||||||
{
|
Platform_DieGracefully();
|
||||||
DQN_WIN32_ERROR_BOX("DqnMemStackTempRegion_Begin() failed", NULL);
|
|
||||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// Query CPU Cores
|
// Query CPU Cores
|
||||||
@ -737,8 +741,7 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi
|
|||||||
|
|
||||||
// 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) * numThreadsPerCore;
|
i32 availableThreads = (numCores - 1) * numThreadsPerCore;
|
||||||
// TODO(doyle): Logic for single core/thread processors
|
if (availableThreads <= 0) availableThreads = 1;
|
||||||
DQN_ASSERT(availableThreads > 0);
|
|
||||||
|
|
||||||
jobQueue.win32Semaphore = CreateSemaphore(NULL, 0, availableThreads, NULL);
|
jobQueue.win32Semaphore = CreateSemaphore(NULL, 0, availableThreads, NULL);
|
||||||
if (jobQueue.win32Semaphore)
|
if (jobQueue.win32Semaphore)
|
||||||
|
@ -16,6 +16,11 @@ if %errorlevel%==0 (
|
|||||||
ctags -R
|
ctags -R
|
||||||
)
|
)
|
||||||
|
|
||||||
|
where /q gtags
|
||||||
|
if %errorlevel%==0 (
|
||||||
|
gtags
|
||||||
|
)
|
||||||
|
|
||||||
set ProjectName=dtrenderer
|
set ProjectName=dtrenderer
|
||||||
ctime -begin ..\src\%ProjectName%.ctm
|
ctime -begin ..\src\%ProjectName%.ctm
|
||||||
|
|
||||||
@ -56,7 +61,7 @@ goto :ReleaseFlags
|
|||||||
|
|
||||||
:DebugFlags
|
:DebugFlags
|
||||||
REM Od disables optimisations
|
REM Od disables optimisations
|
||||||
REM RTC1 runtime error checks
|
REM RTC1 runtime error checks, only possible with optimisations disabled
|
||||||
set CompileFlags=%CompileFlags% -Od -RTC1
|
set CompileFlags=%CompileFlags% -Od -RTC1
|
||||||
goto compile
|
goto compile
|
||||||
|
|
||||||
|
189
src/dqn.h
189
src/dqn.h
@ -64,16 +64,40 @@ typedef float f32;
|
|||||||
#define DQN_SWAP(type, a, b) do { type tmp = a; a = b; b = tmp; } while(0)
|
#define DQN_SWAP(type, a, b) do { type tmp = a; a = b; b = tmp; } while(0)
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Dqn Error
|
// DqnAssert
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
#define DQN_ASSERT_HARD(expr) if (!(expr)) { *((int *)0) = 0; }
|
// DQN_ASSERT() & DQN_ASSERT_MSG() will hard break the program but it can be
|
||||||
|
// disabled in DqnAssertInternal() for release whilst still allowing the assert
|
||||||
|
// expressions to be evaluated and instead send diagnostics to console.
|
||||||
|
|
||||||
#define DQN_ASSERT(expr) DqnAssertInternal(expr, __FILE__, __LINE__, #expr, NULL)
|
// NOTE: "## __VA_ARGS__" is a GCC hack. Zero variadic arguments won't compile
|
||||||
#define DQN_ASSERT_MSG(expr, msg) DqnAssertInternal(expr, __FILE__, __LINE__, #expr, msg)
|
// because there will be a trailing ',' at the end. Pasting it swallows it. MSVC
|
||||||
|
// implicitly swallows the trailing comma.
|
||||||
|
|
||||||
|
// Macro returns if the result was true or not.
|
||||||
|
#define DQN_ASSERT(expr) DqnAssertInternal(expr, __FILE__, __LINE__, #expr, NULL)
|
||||||
|
#define DQN_ASSERT_MSG(expr, msg, ...) DqnAssertInternal(expr, __FILE__, __LINE__, #expr, msg, ## __VA_ARGS__)
|
||||||
|
|
||||||
|
// Usage example. This protects code against asserts that should fire in release
|
||||||
|
// mode by still letting the expression evaluate and the ability to redirect
|
||||||
|
// the code flow to some recovery path.
|
||||||
|
#if 0
|
||||||
|
int *mem = (int *)malloc(sizeof(*mem));
|
||||||
|
if (DQN_ASSERT_MSG(mem, "Not enough memory for malloc")) {
|
||||||
|
// success
|
||||||
|
} else {
|
||||||
|
// failed
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Internal implementation should not be used as the macro above will handle it,
|
||||||
|
// but is required in header for visibility to external functions calling it.
|
||||||
DQN_FILE_SCOPE bool DqnAssertInternal(const bool result, const char *const file, const i32 lineNum,
|
DQN_FILE_SCOPE bool DqnAssertInternal(const bool result, const char *const file, const i32 lineNum,
|
||||||
const char *const expr, const char *const msg);
|
const char *const expr, const char *const msg, ...);
|
||||||
|
|
||||||
|
|
||||||
|
// Hard assert causes an immediate program break at point of assertion by trying
|
||||||
|
// to modify the 0th mem-address.
|
||||||
|
#define DQN_ASSERT_HARD(expr) if (!(expr)) { *((int *)0) = 0; }
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// DqnMem - Memory
|
// DqnMem - Memory
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -286,6 +310,9 @@ bool DqnArray_Remove (DqnArray<T> *array, u64 index);
|
|||||||
bool DqnArray_RemoveStable(DqnArray<T> *array, u64 index);
|
bool DqnArray_RemoveStable(DqnArray<T> *array, u64 index);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
FILE_SCOPE const char *const DQN_MEM_API_CALLBACK_RESULT_TYPE_INCORRECT =
|
||||||
|
"DqnMemAPICallbackResult type is incorrect";
|
||||||
|
|
||||||
// Implementation taken from Milton, developed by Serge at
|
// Implementation taken from Milton, developed by Serge at
|
||||||
// https://github.com/serge-rgb/milton#license
|
// https://github.com/serge-rgb/milton#license
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -321,7 +348,10 @@ bool DqnArray_Init(DqnArray<T> *array, size_t capacity,
|
|||||||
DqnMemAPICallbackResult memResult = {0};
|
DqnMemAPICallbackResult memResult = {0};
|
||||||
DqnMemAPICallbackInfo info = DqnMemAPICallback_InfoAskAllocInternal(array->memAPI, allocateSize);
|
DqnMemAPICallbackInfo info = DqnMemAPICallback_InfoAskAllocInternal(array->memAPI, allocateSize);
|
||||||
array->memAPI.callback(info, &memResult);
|
array->memAPI.callback(info, &memResult);
|
||||||
DQN_ASSERT(memResult.type == DqnMemAPICallbackType_Alloc);
|
if (!DQN_ASSERT_MSG(memResult.type == DqnMemAPICallbackType_Alloc, DQN_MEM_API_CALLBACK_RESULT_TYPE_INCORRECT))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
array->data = (T *)memResult.newMemPtr;
|
array->data = (T *)memResult.newMemPtr;
|
||||||
if (!array->data) return false;
|
if (!array->data) return false;
|
||||||
@ -348,7 +378,11 @@ bool DqnArray_Grow(DqnArray<T> *array)
|
|||||||
array->memAPI, array->data, oldSize, newSize);
|
array->memAPI, array->data, oldSize, newSize);
|
||||||
|
|
||||||
array->memAPI.callback(info, &memResult);
|
array->memAPI.callback(info, &memResult);
|
||||||
DQN_ASSERT(memResult.type == DqnMemAPICallbackType_Realloc);
|
if (!DQN_ASSERT_MSG(memResult.type == DqnMemAPICallbackType_Realloc,
|
||||||
|
DQN_MEM_API_CALLBACK_RESULT_TYPE_INCORRECT))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (memResult.newMemPtr)
|
if (memResult.newMemPtr)
|
||||||
{
|
{
|
||||||
@ -1410,17 +1444,30 @@ STBSP__PUBLICDEF void STB_SPRINTF_DECORATE(set_separators)(char comma, char peri
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
DQN_FILE_SCOPE bool DqnAssertInternal(const bool result, const char *const file, const i32 lineNum,
|
DQN_FILE_SCOPE bool DqnAssertInternal(const bool result, const char *const file, const i32 lineNum,
|
||||||
const char *const expr, const char *const msg)
|
const char *const expr, const char *const msg, ...)
|
||||||
{
|
{
|
||||||
if (!result)
|
if (!(result))
|
||||||
{
|
{
|
||||||
const char *const formatStrNoMsg = "DqnAssert() failed: %s|%d| (%s)\n";
|
const char *const formatStrNoMsg = "DqnAssert() failed: %s|%d| (%s)\n";
|
||||||
const char *const formatStrWithMsg = "DqnAssert() failed: %s|%d| (%s): %s\n";
|
const char *const formatStrWithMsg = "DqnAssert() failed: %s|%d| (%s): %s\n";
|
||||||
const char *const formatStr = (msg) ? formatStrWithMsg : formatStrNoMsg;
|
const char *const formatStr = (msg) ? formatStrWithMsg : formatStrNoMsg;
|
||||||
|
|
||||||
|
char userMsg[512] = {};
|
||||||
|
if (msg)
|
||||||
|
{
|
||||||
|
va_list argList;
|
||||||
|
va_start(argList, msg);
|
||||||
|
{
|
||||||
|
i32 numCopied = Dqn_vsprintf(userMsg, msg, argList);
|
||||||
|
DQN_ASSERT_HARD(numCopied < DQN_ARRAY_COUNT(userMsg));
|
||||||
|
}
|
||||||
|
va_end(argList);
|
||||||
|
}
|
||||||
|
|
||||||
#if (defined(_WIN32) || defined(_WIN64)) && defined(DQN_WIN32_IMPLEMENTATION)
|
#if (defined(_WIN32) || defined(_WIN64)) && defined(DQN_WIN32_IMPLEMENTATION)
|
||||||
DqnWin32_OutputDebugString(formatStr, file, lineNum, expr, msg);
|
DqnWin32_OutputDebugString(formatStr, file, lineNum, expr, userMsg);
|
||||||
#else
|
#else
|
||||||
printf(formatStr, file, lineNum, expr, msg);
|
printf(formatStr, file, lineNum, expr, userMsg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
(*((i32 *)0)) = 0;
|
(*((i32 *)0)) = 0;
|
||||||
@ -1547,9 +1594,13 @@ DQN_FILE_SCOPE bool DqnMemStack_InitWithFixedMem(DqnMemStack *const stack,
|
|||||||
{
|
{
|
||||||
if (!stack || !mem) return false;
|
if (!stack || !mem) return false;
|
||||||
|
|
||||||
// TODO(doyle): Better logging
|
if (!DQN_ASSERT_MSG(
|
||||||
if (memSize < sizeof(DqnMemStackBlock))
|
memSize > sizeof(DqnMemStackBlock),
|
||||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
"memSize is insufficient to initialise a memstack, memSize: %d, requiredSize: %d",
|
||||||
|
memSize, sizeof(DqnMemStackBlock)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
stack->block = (DqnMemStackBlock *)mem;
|
stack->block = (DqnMemStackBlock *)mem;
|
||||||
stack->block->memory = mem + sizeof(DqnMemStackBlock);
|
stack->block->memory = mem + sizeof(DqnMemStackBlock);
|
||||||
@ -1569,10 +1620,12 @@ DQN_FILE_SCOPE bool DqnMemStack_Init(DqnMemStack *const stack, size_t size,
|
|||||||
const u32 byteAlign)
|
const u32 byteAlign)
|
||||||
{
|
{
|
||||||
if (!stack || size <= 0) return false;
|
if (!stack || size <= 0) return false;
|
||||||
DQN_ASSERT(!stack->block);
|
if (!DQN_ASSERT_MSG(!stack->block, "MemStack has pre-existing block already attached"))
|
||||||
|
return false;
|
||||||
|
|
||||||
stack->block = DqnMemStack_AllocateBlockInternal(byteAlign, size);
|
stack->block = DqnMemStack_AllocateBlockInternal(byteAlign, size);
|
||||||
if (!stack->block) return false;
|
if (!DQN_ASSERT_MSG(stack->block, "MemStack failed to allocate block, not enough memory"))
|
||||||
|
return false;
|
||||||
|
|
||||||
stack->tempRegionCount = 0;
|
stack->tempRegionCount = 0;
|
||||||
stack->byteAlign = byteAlign;
|
stack->byteAlign = byteAlign;
|
||||||
@ -1613,17 +1666,14 @@ DQN_FILE_SCOPE void *DqnMemStack_Push(DqnMemStack *const stack, size_t size)
|
|||||||
DqnMemStackBlock *newBlock = DqnMemStack_AllocateCompatibleBlock(stack, newBlockSize);
|
DqnMemStackBlock *newBlock = DqnMemStack_AllocateCompatibleBlock(stack, newBlockSize);
|
||||||
if (newBlock)
|
if (newBlock)
|
||||||
{
|
{
|
||||||
if (!DqnMemStack_AttachBlock(stack, newBlock))
|
bool blockAttachResult = DqnMemStack_AttachBlock(stack, newBlock);
|
||||||
{
|
// IMPORTANT(doyle): This should be impossible, considering that
|
||||||
// IMPORTANT(doyle): This should be impossible, considering that
|
// AllocateCompatibleBlock checks the preconditions that the new
|
||||||
// AllocateCompatibleBlock checks the preconditions that the new
|
// block should be able to be attached.
|
||||||
// block should be able to be attached.
|
|
||||||
|
|
||||||
// But if we somehow reach this, we need to free the block
|
// But if we somehow reach this, we need to free the block
|
||||||
// otherwise memory is leaked.
|
// otherwise memory is leaked.
|
||||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
DQN_ASSERT_HARD(blockAttachResult);
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1642,11 +1692,11 @@ DQN_FILE_SCOPE void *DqnMemStack_Push(DqnMemStack *const stack, size_t size)
|
|||||||
// subsequent allocations should also be aligned automatically.
|
// subsequent allocations should also be aligned automatically.
|
||||||
// TODO(doyle): In the future, do we want to allow arbitrary alignment PER
|
// TODO(doyle): In the future, do we want to allow arbitrary alignment PER
|
||||||
// allocation, not per MemStack?
|
// allocation, not per MemStack?
|
||||||
DQN_ASSERT(alignmentOffset == 0);
|
DQN_ASSERT_HARD(alignmentOffset == 0);
|
||||||
|
|
||||||
void *result = alignedResult;
|
void *result = alignedResult;
|
||||||
stack->block->used += (alignedSize + alignmentOffset);
|
stack->block->used += (alignedSize + alignmentOffset);
|
||||||
DQN_ASSERT(stack->block->used <= stack->block->size);
|
DQN_ASSERT_HARD(stack->block->used <= stack->block->size);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1655,14 +1705,18 @@ DQN_FILE_SCOPE bool DqnMemStack_Pop(DqnMemStack *const stack, void *ptr, size_t
|
|||||||
if (!stack || !stack->block) return false;
|
if (!stack || !stack->block) return false;
|
||||||
|
|
||||||
u8 *currPtr = stack->block->memory + stack->block->used;
|
u8 *currPtr = stack->block->memory + stack->block->used;
|
||||||
DQN_ASSERT((u8 *)ptr >= stack->block->memory && ptr < currPtr);
|
if (DQN_ASSERT_MSG((u8 *)ptr >= stack->block->memory && ptr < currPtr,
|
||||||
|
"'ptr' to pop does not belong to current memStack attached block"))
|
||||||
|
{
|
||||||
|
size_t calcSize = (size_t)currPtr - (size_t)ptr;
|
||||||
|
if (DQN_ASSERT_MSG(calcSize == size, "'ptr' was not the last item allocated to memStack"))
|
||||||
|
{
|
||||||
|
stack->block->used -= size;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
size_t calcSize = (size_t)currPtr - (size_t)ptr;
|
return false;
|
||||||
DQN_ASSERT(calcSize == size);
|
|
||||||
|
|
||||||
stack->block->used -= size;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE bool DqnMemStack_FreeStackBlock(DqnMemStack *const stack, DqnMemStackBlock *block)
|
DQN_FILE_SCOPE bool DqnMemStack_FreeStackBlock(DqnMemStack *const stack, DqnMemStackBlock *block)
|
||||||
@ -1682,7 +1736,7 @@ DQN_FILE_SCOPE bool DqnMemStack_FreeStackBlock(DqnMemStack *const stack, DqnMemS
|
|||||||
DqnMem_Free(blockToFree);
|
DqnMem_Free(blockToFree);
|
||||||
|
|
||||||
// No more blocks, then last block has been freed
|
// No more blocks, then last block has been freed
|
||||||
if (!stack->block) DQN_ASSERT(stack->tempRegionCount == 0);
|
if (!stack->block) DQN_ASSERT_HARD(stack->tempRegionCount == 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1704,7 +1758,7 @@ DQN_FILE_SCOPE void DqnMemStack_Free(DqnMemStack *stack)
|
|||||||
// do is clear the block.
|
// do is clear the block.
|
||||||
if (stack->flags & DqnMemStackFlag_IsFixedMemoryFromUser)
|
if (stack->flags & DqnMemStackFlag_IsFixedMemoryFromUser)
|
||||||
{
|
{
|
||||||
DQN_ASSERT(!stack->block->prevBlock);
|
DQN_ASSERT_HARD(!stack->block->prevBlock);
|
||||||
DqnMemStack_ClearCurrBlock(stack, false);
|
DqnMemStack_ClearCurrBlock(stack, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1752,12 +1806,12 @@ DQN_FILE_SCOPE void DqnMemStackTempRegion_End(DqnMemStackTempRegion region)
|
|||||||
|
|
||||||
if (stack->block)
|
if (stack->block)
|
||||||
{
|
{
|
||||||
DQN_ASSERT(stack->block->used >= region.used);
|
DQN_ASSERT_HARD(stack->block->used >= region.used);
|
||||||
stack->block->used = region.used;
|
stack->block->used = region.used;
|
||||||
}
|
}
|
||||||
|
|
||||||
stack->tempRegionCount--;
|
stack->tempRegionCount--;
|
||||||
DQN_ASSERT(stack->tempRegionCount >= 0);
|
DQN_ASSERT_HARD(stack->tempRegionCount >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DQN_CPP_MODE
|
#ifdef DQN_CPP_MODE
|
||||||
@ -1769,15 +1823,7 @@ DqnMemStackTempRegionScoped::DqnMemStackTempRegionScoped(DqnMemStack *const stac
|
|||||||
|
|
||||||
DqnMemStackTempRegionScoped::~DqnMemStackTempRegionScoped()
|
DqnMemStackTempRegionScoped::~DqnMemStackTempRegionScoped()
|
||||||
{
|
{
|
||||||
if (this->isInit)
|
DqnMemStackTempRegion_End(this->tempMemStack);
|
||||||
{
|
|
||||||
DqnMemStackTempRegion_End(this->tempMemStack);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO(doyle): Report error
|
|
||||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -1820,23 +1866,23 @@ FILE_SCOPE DqnMemAPICallbackInfo DqnMemAPICallback_InfoAskFreeInternal(
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DqnMemAPI_ValidateCallbackInfo(DqnMemAPICallbackInfo info)
|
void DqnMemAPI_ValidateCallbackInfoInternal(DqnMemAPICallbackInfo info)
|
||||||
{
|
{
|
||||||
DQN_ASSERT(info.type != DqnMemAPICallbackType_Invalid);
|
DQN_ASSERT_HARD(info.type != DqnMemAPICallbackType_Invalid);
|
||||||
|
|
||||||
switch(info.type)
|
switch(info.type)
|
||||||
{
|
{
|
||||||
case DqnMemAPICallbackType_Alloc:
|
case DqnMemAPICallbackType_Alloc:
|
||||||
{
|
{
|
||||||
DQN_ASSERT(info.requestSize > 0);
|
DQN_ASSERT_HARD(info.requestSize > 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DqnMemAPICallbackType_Realloc:
|
case DqnMemAPICallbackType_Realloc:
|
||||||
{
|
{
|
||||||
DQN_ASSERT(info.oldSize > 0);
|
DQN_ASSERT_HARD(info.oldSize > 0);
|
||||||
DQN_ASSERT(info.requestSize > 0);
|
DQN_ASSERT_HARD(info.requestSize > 0);
|
||||||
DQN_ASSERT(info.oldMemPtr);
|
DQN_ASSERT_HARD(info.oldMemPtr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1852,8 +1898,9 @@ FILE_SCOPE void
|
|||||||
DqnMemAPI_DefaultUseCallocCallbackInternal(DqnMemAPICallbackInfo info,
|
DqnMemAPI_DefaultUseCallocCallbackInternal(DqnMemAPICallbackInfo info,
|
||||||
DqnMemAPICallbackResult *result)
|
DqnMemAPICallbackResult *result)
|
||||||
{
|
{
|
||||||
DQN_ASSERT(!info.userContext);
|
DQN_ASSERT_HARD(!info.userContext);
|
||||||
DqnMemAPI_ValidateCallbackInfo(info);
|
|
||||||
|
DqnMemAPI_ValidateCallbackInfoInternal(info);
|
||||||
switch(info.type)
|
switch(info.type)
|
||||||
{
|
{
|
||||||
case DqnMemAPICallbackType_Alloc:
|
case DqnMemAPICallbackType_Alloc:
|
||||||
@ -2859,7 +2906,7 @@ DQN_FILE_SCOPE i32 Dqn_I64ToStr(i64 value, char *const buf, const i32 bufSize)
|
|||||||
// it is for positives, so ABS will fail.
|
// it is for positives, so ABS will fail.
|
||||||
lastDigitDecremented = true;
|
lastDigitDecremented = true;
|
||||||
val = DQN_ABS(val - 1);
|
val = DQN_ABS(val - 1);
|
||||||
DQN_ASSERT(val >= 0);
|
DQN_ASSERT_HARD(val >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (validBuffer)
|
if (validBuffer)
|
||||||
@ -2971,7 +3018,7 @@ DQN_FILE_SCOPE f32 Dqn_StrToF32(const char *const buf, const i32 bufSize)
|
|||||||
if (i < bufSize)
|
if (i < bufSize)
|
||||||
{
|
{
|
||||||
if (buf[i + 1] == '-') digitShiftIsPositive = false;
|
if (buf[i + 1] == '-') digitShiftIsPositive = false;
|
||||||
DQN_ASSERT(buf[i + 1] == '-' || buf[i + 1] == '+');
|
DQN_ASSERT_HARD(buf[i + 1] == '-' || buf[i + 1] == '+');
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2997,7 +3044,7 @@ DQN_FILE_SCOPE f32 Dqn_StrToF32(const char *const buf, const i32 bufSize)
|
|||||||
// NOTE(doyle): If exponent not specified but this branch occurred,
|
// NOTE(doyle): If exponent not specified but this branch occurred,
|
||||||
// the float string has a malformed scientific notation in the
|
// the float string has a malformed scientific notation in the
|
||||||
// string, i.e. "e" followed by no number.
|
// string, i.e. "e" followed by no number.
|
||||||
DQN_ASSERT(scientificNotation);
|
DQN_ASSERT_HARD(scientificNotation);
|
||||||
|
|
||||||
numDigitsAfterDecimal += exponentPow;
|
numDigitsAfterDecimal += exponentPow;
|
||||||
if (digitShiftIsPositive) digitShiftMultiplier = 10.0f;
|
if (digitShiftIsPositive) digitShiftMultiplier = 10.0f;
|
||||||
@ -3443,10 +3490,8 @@ DQN_FILE_SCOPE void DqnWin32_GetNumThreadsAndCores(i32 *const numCores, i32 *con
|
|||||||
&requiredSize);
|
&requiredSize);
|
||||||
|
|
||||||
u8 *rawProcInfoArray = (u8 *)DqnMem_Calloc(requiredSize);
|
u8 *rawProcInfoArray = (u8 *)DqnMem_Calloc(requiredSize);
|
||||||
if (!rawProcInfoArray)
|
if (!DQN_ASSERT_MSG(rawProcInfoArray, "Calloc failed, could not allocate memory"))
|
||||||
{
|
{
|
||||||
DQN_WIN32_ERROR_BOX("DqnMem_Calloc() failed", NULL);
|
|
||||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3464,8 +3509,8 @@ DQN_FILE_SCOPE void DqnWin32_GetNumThreadsAndCores(i32 *const numCores, i32 *con
|
|||||||
PROCESSOR_RELATIONSHIP *procInfo = &logicalProcInfo->Processor;
|
PROCESSOR_RELATIONSHIP *procInfo = &logicalProcInfo->Processor;
|
||||||
u32 efficiency = procInfo->EfficiencyClass;
|
u32 efficiency = procInfo->EfficiencyClass;
|
||||||
(*numCores)++;
|
(*numCores)++;
|
||||||
DQN_ASSERT(logicalProcInfo->Relationship == RelationProcessorCore);
|
DQN_ASSERT_HARD(logicalProcInfo->Relationship == RelationProcessorCore);
|
||||||
DQN_ASSERT(procInfo->GroupCount == 1);
|
DQN_ASSERT_HARD(procInfo->GroupCount == 1);
|
||||||
|
|
||||||
bytesRead += logicalProcInfo->Size;
|
bytesRead += logicalProcInfo->Size;
|
||||||
logicalProcInfo =
|
logicalProcInfo =
|
||||||
@ -3595,7 +3640,7 @@ DQN_FILE_SCOPE size_t DqnFile_Write(const DqnFile *const file,
|
|||||||
{
|
{
|
||||||
size_t numBytesWritten = 0;
|
size_t numBytesWritten = 0;
|
||||||
// TODO(doyle): Implement when it's needed
|
// TODO(doyle): Implement when it's needed
|
||||||
DQN_ASSERT(fileOffset == 0);
|
if (DQN_ASSERT_MSG(fileOffset != 0, "'fileOffset' not implemented yet")) return 0;
|
||||||
if (!file || !buffer) return numBytesToWrite;
|
if (!file || !buffer) return numBytesToWrite;
|
||||||
|
|
||||||
#ifdef DQN_WIN32_IMPLEMENTATION
|
#ifdef DQN_WIN32_IMPLEMENTATION
|
||||||
@ -3612,7 +3657,7 @@ DQN_FILE_SCOPE size_t DqnFile_Write(const DqnFile *const file,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
DQN_ASSERT_MSG(DQN_INVALID_CODE_PATH, "Non Win32 path not implemented");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return numBytesWritten;
|
return numBytesWritten;
|
||||||
@ -3630,7 +3675,7 @@ DQN_FILE_SCOPE void DqnFile_Close(DqnFile *const file)
|
|||||||
file->permissionFlags = 0;
|
file->permissionFlags = 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
DQN_ASSERT_MSG(DQN_INVALID_CODE_PATH, "Non Win32 path not implemented");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3757,7 +3802,7 @@ FILE_SCOPE f64 DqnWin32_QueryPerfCounterTimeInSInternal()
|
|||||||
if (queryPerformanceFrequency.QuadPart == 0)
|
if (queryPerformanceFrequency.QuadPart == 0)
|
||||||
{
|
{
|
||||||
QueryPerformanceFrequency(&queryPerformanceFrequency);
|
QueryPerformanceFrequency(&queryPerformanceFrequency);
|
||||||
DQN_ASSERT(queryPerformanceFrequency.QuadPart != 0);
|
DQN_ASSERT_HARD(queryPerformanceFrequency.QuadPart != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
LARGE_INTEGER qpcResult;
|
LARGE_INTEGER qpcResult;
|
||||||
@ -3777,7 +3822,7 @@ f64 DqnTime_NowInS()
|
|||||||
result = DQN_MAX(DqnWin32_QueryPerfCounterTimeInSInternal(), 0);
|
result = DQN_MAX(DqnWin32_QueryPerfCounterTimeInSInternal(), 0);
|
||||||
#else
|
#else
|
||||||
result = 0;
|
result = 0;
|
||||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
DQN_ASSERT_MSG(DQN_INVALID_CODE_PATH, "Non Win32 path not implemented yet");
|
||||||
#endif
|
#endif
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
@ -3817,13 +3862,13 @@ FILE_SCOPE u32 DqnRnd_MakeSeedInternal()
|
|||||||
__int64 numClockCycles = __rdtsc();
|
__int64 numClockCycles = __rdtsc();
|
||||||
return (u32)numClockCycles;
|
return (u32)numClockCycles;
|
||||||
#elif __ANDROID__
|
#elif __ANDROID__
|
||||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
DQN_ASSERT_MSG(DQN_INVALID_CODE_PATH, "Android path not implemented yet");
|
||||||
return 0;
|
return 0;
|
||||||
#elif __linux__
|
#elif __linux__
|
||||||
unsigned long long numClockCycles = rdtsc();
|
unsigned long long numClockCycles = rdtsc();
|
||||||
return (u32)numClockCycles;
|
return (u32)numClockCycles;
|
||||||
#else
|
#else
|
||||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
DQN_ASSERT_MSG(DQN_INVALID_CODE_PATH, "Non Win32 path not implemented yet");
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user