VulkanRenderer/vulkan_util.d
2025-09-15 05:17:35 +10:00

288 lines
3.7 KiB
D

import std.stdio;
import core.stdc.string : memset;
alias i8 = byte;
alias i16 = short;
alias i32 = int;
alias i64 = long;
alias u8 = ubyte;
alias u16 = ushort;
alias u32 = uint;
alias u64 = ulong;
alias f32 = float;
alias f64 = double;
alias b32 = uint;
alias usize = size_t;
alias intptr = i64;
alias uintptr = u64;
const DEFAULT_ALIGNMENT = (void *).sizeof * 2;
version(linux)
{
import core.sys.posix.sys.mman;
import core.sys.posix.dlfcn;
struct Library
{
void* ptr;
};
struct Function
{
void* ptr;
};
Library LoadLibrary(string name)
{
Library lib = {
ptr: null,
};
lib.ptr = dlopen(name.ptr, RTLD_NOW);
return lib;
};
Function LoadFunction(Library lib, string name)
{
Function fn = {
ptr: null,
};
fn.ptr = dlsym(lib.ptr, name.ptr);
return fn;
};
void*
MemAlloc(u64 size)
{
return mmap(null, size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
}
void
MemFree(void* ptr, u64 size)
{
assert(munmap(ptr, size) == 0, "MemFree failure");
}
}
bool
BitEq(u64 l, u64 r)
{
return (l & r) == r;
}
void
Logf(Args...)(string fmt, Args args)
{
try
{
writefln(fmt, args);
}
catch (Exception e)
{
assert(false, "Incompatible format type");
}
}
void
Log(string str)
{
writeln(str);
}
void
Log(char* str)
{
writeln(str);
}
u64
KB(u64 v)
{
return v * 1024;
};
u64
MB(u64 v)
{
return KB(v) * 1024;
};
u64
GB(u64 v)
{
return MB(v) * 1024;
};
struct Node(T)
{
Node!(T)* next;
T value;
}
struct SLList(T)
{
Node!(T)* first;
Node!(T)* last;
}
pragma(inline): void
Push(T)(SLList!(T)*list, Node!(T)* node, Node!(T)* nil)
{
if(CheckNil(nil, list.first))
{
list.first = list.last = node;
node.next = nil;
}
else
{
list.last.next = node;
list.last = node;
node.next = nil;
}
}
pragma(inline): void
PushFront(T)(SLList!(T)*list, Node!(T)* node, Node!(T)* nil)
{
if(CheckNil(nil, list.first))
{
list.first = list.last = node;
node.next = nil;
}
else
{
node.next = list.first;
list.first = node;
}
}
pragma(inline): bool
CheckNil(T)(Node!(T)* nil, Node!(T)* node)
{
return node == null || node == nil;
}
T*
Alloc(T)()
{
void* mem = MemAlloc(T.sizeof);
memset(mem, 0, T.sizeof);
return (cast(T*)mem);
}
T[]
AllocArray(T)(u64 count)
{
void* mem = MemAlloc(T.sizeof * count);
memset(mem, 0, T.sizeof * count);
return (cast(T*)mem)[0 .. count];
}
void
FreeArray(T)(T[] arr)
{
MemFree(cast(void*)arr.ptr, T.sizeof * arr.length);
}
void
Free(T)(T* ptr)
{
MemFree(cast(void*)ptr, T.sizeof);
}
struct Arena
{
u8* mem;
u64 length;
u64 pos;
};
Arena
CreateArena(u64 size)
{
Arena arena = {
mem: cast(u8 *)MemAlloc(size),
length: size,
pos: 0,
};
assert(arena.mem != null, "Unable to allocate memory for arena");
return arena;
};
T[]
AllocArray(T)(Arena* arena, u64 count)
{
void* mem = AllocAlign(arena, T.sizeof * count, DEFAULT_ALIGNMENT);
memset(mem, 0, T.sizeof * count);
return (cast(T*)mem)[0 .. count];
}
T*
Alloc(T)(Arena* arena)
{
void* mem = AllocAlign(arena, T.sizeof, DEFAULT_ALIGNMENT);
memset(mem, 0, T.sizeof);
return cast(T*)mem;
};
void*
AllocAlign(Arena* arena, u64 size, u64 alignment)
{
void* ptr = null;
uintptr mem_pos = cast(uintptr)arena.mem;
uintptr current = mem_pos + arena.pos;
uintptr offset = AlignPow2(current, alignment) - mem_pos;
if(offset+size <= arena.length)
{
ptr = &arena.mem[offset];
arena.pos = offset+size;
}
else
{
writefln("AllocAlign failure: out of memory, size requested: %s", size);
assert(0);
}
return ptr;
};
void
Reset(Arena* arena)
{
memset(arena.mem, 0, arena.pos);
arena.pos = 0;
}
void
Free(Arena* arena)
{
MemFree(arena.mem, arena.length);
}
T
AlignPow2(T)(T v, T a)
{
return (v + a - 1) & ~(a - 1);
}
u8[]
Embed(string file_name)
{
import std.file;
return cast(u8[])read(file_name);
}