- Portable DEPRECATED macro
- Deprecate os_compare_and_swap and replace with more portable compare_and_swap - Fixed a bug where the wrong image would be drawn
This commit is contained in:
parent
e54897432b
commit
9842834065
11 changed files with 126 additions and 17 deletions
|
@ -6,6 +6,6 @@ mkdir build
|
|||
|
||||
pushd build
|
||||
|
||||
clang -g -o cgame.exe ../build.c -O0 -std=c11 -Wextra -Wno-incompatible-library-redeclaration -Wno-sign-compare -Wno-unused-parameter -Wno-builtin-requires-header -Wno-deprecated-declarations -lkernel32 -lgdi32 -luser32 -lwinmm -ld3d11 -ldxguid -ld3dcompiler -lshlwapi -femit-all-decls
|
||||
clang -g -o cgame.exe ../build.c -O0 -std=c11 -D_CRT_SECURE_NO_WARNINGS -Wextra -Wno-incompatible-library-redeclaration -Wno-sign-compare -Wno-unused-parameter -Wno-builtin-requires-header -lkernel32 -lgdi32 -luser32 -lwinmm -ld3d11 -ldxguid -ld3dcompiler -lshlwapi -femit-all-decls
|
||||
|
||||
popd
|
|
@ -12,7 +12,7 @@ pushd build
|
|||
mkdir dissassembly
|
||||
pushd dissassembly
|
||||
|
||||
clang -o cgame.asm ../../build.c -Ofast -std=c11 -Wextra -Wno-incompatible-library-redeclaration -Wno-sign-compare -Wno-unused-parameter -Wno-builtin-requires-header -Wno-deprecated-declarations -finline-functions -ffast-math -fno-math-errno -funsafe-math-optimizations -freciprocal-math -ffinite-math-only -fassociative-math -fno-signed-zeros -fno-trapping-math -ftree-vectorize -fomit-frame-pointer -funroll-loops -fno-rtti -fno-exceptions -S -masm=intel
|
||||
clang -o cgame.asm ../../build.c -Ofast -std=c11 -D_CRT_SECURE_NO_WARNINGS -Wextra -Wno-incompatible-library-redeclaration -Wno-sign-compare -Wno-unused-parameter -Wno-builtin-requires-header -Wno-deprecated-declarations -finline-functions -ffast-math -fno-math-errno -funsafe-math-optimizations -freciprocal-math -ffinite-math-only -fassociative-math -fno-signed-zeros -fno-trapping-math -ftree-vectorize -fomit-frame-pointer -funroll-loops -fno-rtti -fno-exceptions -S -masm=intel
|
||||
|
||||
popd
|
||||
popd
|
|
@ -9,7 +9,7 @@ pushd build
|
|||
mkdir release
|
||||
pushd release
|
||||
|
||||
clang -o cgame.exe ../../build.c -Ofast -DNDEBUG -std=c11 -Wextra -Wno-incompatible-library-redeclaration -Wno-sign-compare -Wno-unused-parameter -Wno-builtin-requires-header -Wno-deprecated-declarations -lgdi32 -luser32 -lwinmm -ld3d11 -ldxguid -ld3dcompiler -lshlwapi -finline-functions -finline-hint-functions -ffast-math -fno-math-errno -funsafe-math-optimizations -freciprocal-math -ffinite-math-only -fassociative-math -fno-signed-zeros -fno-trapping-math -ftree-vectorize -fomit-frame-pointer -funroll-loops -fno-rtti -fno-exceptions
|
||||
clang -o cgame.exe ../../build.c -Ofast -DNDEBUG -std=c11 -D_CRT_SECURE_NO_WARNINGS -Wextra -Wno-incompatible-library-redeclaration -Wno-sign-compare -Wno-unused-parameter -Wno-builtin-requires-header -Wno-deprecated-declarations -lgdi32 -luser32 -lwinmm -ld3d11 -ldxguid -ld3dcompiler -lshlwapi -finline-functions -finline-hint-functions -ffast-math -fno-math-errno -funsafe-math-optimizations -freciprocal-math -ffinite-math-only -fassociative-math -fno-signed-zeros -fno-trapping-math -ftree-vectorize -fomit-frame-pointer -funroll-loops -fno-rtti -fno-exceptions
|
||||
|
||||
popd
|
||||
popd
|
|
@ -1,4 +1,4 @@
|
|||
## v0.00.003 -
|
||||
## v0.00.003 - Fixes
|
||||
|
||||
Random:
|
||||
- get_random_float64()
|
||||
|
@ -24,6 +24,9 @@ Misc:
|
|||
- Fixed Y placement of window when changing the window rect
|
||||
- Fixed window sizing when setting scaled_width or scaled_height
|
||||
- Updated readme
|
||||
- Portable DEPRECATED macro
|
||||
- Deprecate os_compare_and_swap and replace with more portable compare_and_swap
|
||||
- Fixed a bug where the wrong image would be drawn
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -67,6 +67,34 @@ typedef struct Cpu_Capabilities {
|
|||
#else
|
||||
#define COMPILER_CAN_DO_AVX512 0
|
||||
#endif
|
||||
|
||||
#define DEPRECATED(proc, msg) __declspec(deprecated(msg)) func
|
||||
|
||||
#pragma intrinsic(_InterlockedCompareExchange8)
|
||||
#pragma intrinsic(_InterlockedCompareExchange16)
|
||||
#pragma intrinsic(_InterlockedCompareExchange)
|
||||
#pragma intrinsic(_InterlockedCompareExchange64)
|
||||
|
||||
inline bool compare_and_swap_8(uint8_t *a, uint8_t b, uint8_t old) {
|
||||
return _InterlockedCompareExchange8((volatile char*)a, (char)b, (char)old) == old;
|
||||
}
|
||||
|
||||
inline bool compare_and_swap_16(uint16_t *a, uint16_t b, uint16_t old) {
|
||||
return _InterlockedCompareExchange16((volatile short*)a, (short)b, (short)old) == old;
|
||||
}
|
||||
|
||||
inline bool compare_and_swap_32(uint32_t *a, uint32_t b, uint32_t old) {
|
||||
return _InterlockedCompareExchange((volatile long*)a, (long)b, (long)old) == old;
|
||||
}
|
||||
|
||||
inline bool compare_and_swap_64(uint64_t *a, uint64_t b, uint64_t old) {
|
||||
return _InterlockedCompareExchange64((volatile long long*)a, (long long)b, (long long)old) == old;
|
||||
}
|
||||
|
||||
inline bool compare_and_swap_bool(bool *a, bool b, bool old) {
|
||||
return compare_and_swap_8((uint8_t*)a, (uint8_t)b, (uint8_t)old);
|
||||
}
|
||||
|
||||
#elif COMPILER_GCC || COMPILER_CLANG
|
||||
#define inline __attribute__((always_inline)) inline
|
||||
#define alignat(x) __attribute__((aligned(x)))
|
||||
|
@ -115,6 +143,57 @@ typedef struct Cpu_Capabilities {
|
|||
#else
|
||||
#define COMPILER_CAN_DO_AVX512 0
|
||||
#endif
|
||||
|
||||
#define DEPRECATED(proc, msg) proc __attribute__((deprecated(msg)))
|
||||
|
||||
inline bool compare_and_swap_8(uint8_t *a, uint8_t b, uint8_t old) {
|
||||
unsigned char result;
|
||||
__asm__ __volatile__(
|
||||
"lock; cmpxchgb %2, %1"
|
||||
: "=a" (result), "=m" (*a)
|
||||
: "r" (b), "m" (*a), "a" (old)
|
||||
: "memory"
|
||||
);
|
||||
return result == old;
|
||||
}
|
||||
|
||||
inline bool compare_and_swap_16(uint16_t *a, uint16_t b, uint16_t old) {
|
||||
unsigned short result;
|
||||
__asm__ __volatile__(
|
||||
"lock; cmpxchgw %2, %1"
|
||||
: "=a" (result), "=m" (*a)
|
||||
: "r" (b), "m" (*a), "a" (old)
|
||||
: "memory"
|
||||
);
|
||||
return result == old;
|
||||
}
|
||||
|
||||
inline bool compare_and_swap_32(uint32_t *a, uint32_t b, uint32_t old) {
|
||||
unsigned int result;
|
||||
__asm__ __volatile__(
|
||||
"lock; cmpxchgl %2, %1"
|
||||
: "=a" (result), "=m" (*a)
|
||||
: "r" (b), "m" (*a), "a" (old)
|
||||
: "memory"
|
||||
);
|
||||
return result == old;
|
||||
}
|
||||
|
||||
inline bool compare_and_swap_64(uint64_t *a, uint64_t b, uint64_t old) {
|
||||
unsigned long long result;
|
||||
__asm__ __volatile__(
|
||||
"lock; cmpxchgq %2, %1"
|
||||
: "=a" (result), "=m" (*a)
|
||||
: "r" (b), "m" (*a), "a" (old)
|
||||
: "memory"
|
||||
);
|
||||
return result == old;
|
||||
}
|
||||
|
||||
inline bool compare_and_swap_bool(bool *a, bool b, bool old) {
|
||||
return compare_and_swap_8((uint8_t*)a, (uint8_t)b, (uint8_t)old);
|
||||
}
|
||||
|
||||
#else
|
||||
#define inline inline
|
||||
#define COMPILER_HAS_MEMCPY_INTRINSICS 0
|
||||
|
@ -126,6 +205,8 @@ typedef struct Cpu_Capabilities {
|
|||
#define COMPILER_CAN_DO_AVX2 0
|
||||
#define COMPILER_CAN_DO_AVX512 0
|
||||
|
||||
#define deprecated(msg)
|
||||
|
||||
#warning "Compiler is not explicitly supported, some things will probably not work as expected"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ Usage:
|
|||
|
||||
|
||||
|
||||
#define QUADS_PER_BLOCK 16
|
||||
#define QUADS_PER_BLOCK 256
|
||||
typedef struct Draw_Quad {
|
||||
Vector2 bottom_left, top_left, top_right, bottom_right;
|
||||
// r, g, b, a
|
||||
|
@ -82,6 +82,8 @@ typedef struct Draw_Quad {
|
|||
Gfx_Filter_Mode image_min_filter;
|
||||
Gfx_Filter_Mode image_mag_filter;
|
||||
|
||||
float32 z;
|
||||
|
||||
} Draw_Quad;
|
||||
|
||||
|
||||
|
@ -89,6 +91,8 @@ typedef struct Draw_Quad_Block {
|
|||
Draw_Quad quad_buffer[QUADS_PER_BLOCK];
|
||||
u64 num_quads;
|
||||
|
||||
float32 low_z, high_z;
|
||||
|
||||
struct Draw_Quad_Block *next;
|
||||
} Draw_Quad_Block;
|
||||
|
||||
|
@ -103,6 +107,8 @@ typedef struct Draw_Frame {
|
|||
|
||||
Matrix4 projection;
|
||||
Matrix4 view;
|
||||
|
||||
bool enable_z_sorting;
|
||||
} Draw_Frame;
|
||||
// This frame is passed to the platform layer and rendered in os_update.
|
||||
// Resets every frame.
|
||||
|
@ -129,7 +135,11 @@ Draw_Quad *draw_quad_projected(Draw_Quad quad, Matrix4 world_to_clip) {
|
|||
quad.image_min_filter = GFX_FILTER_MODE_NEAREST;
|
||||
quad.image_min_filter = GFX_FILTER_MODE_NEAREST;
|
||||
|
||||
if (!draw_frame.current) draw_frame.current = &first_block;
|
||||
if (!draw_frame.current) {
|
||||
draw_frame.current = &first_block;
|
||||
draw_frame.current->low_z = F32_MAX;
|
||||
draw_frame.current->high_z = F32_MIN;
|
||||
}
|
||||
|
||||
if (draw_frame.current == &first_block) draw_frame.num_blocks = 1;
|
||||
|
||||
|
@ -146,6 +156,9 @@ Draw_Quad *draw_quad_projected(Draw_Quad quad, Matrix4 world_to_clip) {
|
|||
draw_frame.current->num_quads = 0;
|
||||
|
||||
draw_frame.num_blocks += 1;
|
||||
|
||||
draw_frame.current->low_z = F32_MAX;
|
||||
draw_frame.current->high_z = F32_MIN;
|
||||
}
|
||||
|
||||
draw_frame.current->quad_buffer[draw_frame.current->num_quads] = quad;
|
||||
|
|
|
@ -575,6 +575,7 @@ void d3d11_process_draw_frame() {
|
|||
ID3D11ShaderResourceView *textures[32];
|
||||
ID3D11ShaderResourceView *last_texture = 0;
|
||||
u64 num_textures = 0;
|
||||
s8 last_texture_index = 0;
|
||||
|
||||
D3D11_Vertex* head = (D3D11_Vertex*)d3d11_staging_quad_buffer;
|
||||
D3D11_Vertex* pointer = head;
|
||||
|
@ -592,7 +593,7 @@ void d3d11_process_draw_frame() {
|
|||
if (q->image) {
|
||||
|
||||
if (last_texture == q->image->gfx_handle) {
|
||||
texture_index = (s8)(num_textures-1);
|
||||
texture_index = last_texture_index;
|
||||
} else {
|
||||
// First look if texture is already bound
|
||||
for (u64 j = 0; j < num_textures; j++) {
|
||||
|
@ -623,6 +624,7 @@ void d3d11_process_draw_frame() {
|
|||
}
|
||||
textures[texture_index] = q->image->gfx_handle;
|
||||
last_texture = q->image->gfx_handle;
|
||||
last_texture_index = texture_index;
|
||||
}
|
||||
|
||||
if (q->type == QUAD_TYPE_TEXT) {
|
||||
|
|
|
@ -135,10 +135,14 @@ typedef double f64;
|
|||
typedef f32 float32;
|
||||
typedef f64 float64;
|
||||
|
||||
#define F32_MAX 3.402823466e+38F
|
||||
#define F32_MIN 1.175494351e-38F
|
||||
|
||||
typedef u8 bool;
|
||||
#define false 0
|
||||
#define true 1
|
||||
|
||||
|
||||
// Determine what compiler we are on
|
||||
#ifdef __clang__
|
||||
#define COMPILER_CLANG 1
|
||||
|
|
|
@ -440,7 +440,7 @@ Spinlock *os_make_spinlock(Allocator allocator) {
|
|||
void os_spinlock_lock(Spinlock *l) {
|
||||
while (true) {
|
||||
bool expected = false;
|
||||
if (os_compare_and_swap_bool(&l->locked, true, expected)) {
|
||||
if (compare_and_swap_bool(&l->locked, true, expected)) {
|
||||
return;
|
||||
}
|
||||
while (l->locked) {
|
||||
|
@ -451,7 +451,7 @@ void os_spinlock_lock(Spinlock *l) {
|
|||
|
||||
void os_spinlock_unlock(Spinlock *l) {
|
||||
bool expected = true;
|
||||
bool success = os_compare_and_swap_bool(&l->locked, false, expected);
|
||||
bool success = compare_and_swap_bool(&l->locked, false, expected);
|
||||
assert(success, "This thread should have acquired the spinlock but compare_and_swap failed");
|
||||
}
|
||||
|
||||
|
|
|
@ -124,11 +124,17 @@ void os_spinlock_unlock(Spinlock* l);
|
|||
///
|
||||
// Concurrency utilities
|
||||
|
||||
bool os_compare_and_swap_8 (u8 *a, u8 b, u8 old);
|
||||
bool os_compare_and_swap_16 (u16 *a, u16 b, u16 old);
|
||||
bool os_compare_and_swap_32 (u32 *a, u32 b, u32 old);
|
||||
bool os_compare_and_swap_64 (u64 *a, u64 b, u64 old);
|
||||
bool os_compare_and_swap_bool(bool *a, bool b, bool old);
|
||||
// #Cleanup
|
||||
// In retrospect, I'm not sure why I choose to implement this per OS.
|
||||
// I think Win32 InterlockedCompareExchange just generates the cmpxchg
|
||||
// instruction anyways, so may as well just inline asm it (or Win32
|
||||
// if we're compiling with msvc) (LDREX/STREX on ARM)
|
||||
// - CharlieM July 8th 2024
|
||||
DEPRECATED(bool os_compare_and_swap_8 (u8 *a, u8 b, u8 old), "use compare_and_swap instead");
|
||||
DEPRECATED(bool os_compare_and_swap_16 (u16 *a, u16 b, u16 old), "use compare_and_swap instead");
|
||||
DEPRECATED(bool os_compare_and_swap_32 (u32 *a, u32 b, u32 old), "use compare_and_swap instead");
|
||||
DEPRECATED(bool os_compare_and_swap_64 (u64 *a, u64 b, u64 old), "use compare_and_swap instead");
|
||||
DEPRECATED(bool os_compare_and_swap_bool(bool *a, bool b, bool old), "use compare_and_swap instead");
|
||||
|
||||
void os_sleep(u32 ms);
|
||||
void os_yield_thread();
|
||||
|
|
|
@ -1098,12 +1098,12 @@ void oogabooga_run_tests() {
|
|||
|
||||
#if CONFIGURATION != RELEASE
|
||||
print("Thread bombing allocator... ");
|
||||
Thread* threads[100];
|
||||
for (int i = 0; i < 100; i++) {
|
||||
Thread* threads[300];
|
||||
for (int i = 0; i < 300; i++) {
|
||||
threads[i] = os_make_thread(test_allocator_threaded, get_heap_allocator());
|
||||
os_start_thread(threads[i]);
|
||||
}
|
||||
for (int i = 0; i < 100; i++) {
|
||||
for (int i = 0; i < 300; i++) {
|
||||
os_join_thread(threads[i]);
|
||||
}
|
||||
print("OK!\n");
|
||||
|
|
Reference in a new issue