diff --git a/code/core/arena.h b/code/core/arena.h index ba65059..534dcd4 100644 --- a/code/core/arena.h +++ b/code/core/arena.h @@ -64,8 +64,8 @@ function void *_M_ArenaPush(M_Arena *arena, U64 esize, M_ArenaPushOpts *opts) function void *_M_ArenaPushCopy(M_Arena *arena, void *src, U64 esize, M_ArenaPushOpts *opts); #define M_ArenaAlloc(limit, ...) _M_ArenaAlloc(limit, &(M_ArenaOpts) { .initial = MB(1), .increment = KB(64), ##__VA_ARGS__ }) -#define M_ArenaPush(arena, T, ...) (T *) _M_ArenaPush(arena, sizeof(T), &(M_ArenaOpts) { .count = 1, .align = Alignof(T), ##__VA_ARGS__ }) -#define M_ArenaPushCopy(arena, T, src, ...) (T *) _M_ArenaPush(arena, src, sizeof(T), &(M_ArenaOpts) { .count = 1, .align = Alignof(T), ##__VA_ARGS__ }) +#define M_ArenaPush(arena, T, ...) (T *) _M_ArenaPush(arena, sizeof(T), &(M_ArenaPushOpts) { .count = 1, .align = Alignof(T), ##__VA_ARGS__ }) +#define M_ArenaPushCopy(arena, T, src, ...) (T *) _M_ArenaPush(arena, src, sizeof(T), &(M_ArenaPushOpts) { .count = 1, .align = Alignof(T), ##__VA_ARGS__ }) function void M_ArenaReset(M_Arena *arena); function void M_ArenaRelease(M_Arena *arena); diff --git a/code/core/types.h b/code/core/types.h index 08436db..73f2a4d 100644 --- a/code/core/types.h +++ b/code/core/types.h @@ -29,4 +29,9 @@ struct Str8 { U8 *data; }; +#define U8_MAX ((U8) -1) +#define U16_MAX ((U16) -1) +#define U32_MAX ((U32) -1) +#define U64_MAX ((U64) -1) + #endif // LD_CORE_TYPES_H_ diff --git a/code/first.c b/code/first.c index 3202aea..a3faef5 100644 --- a/code/first.c +++ b/code/first.c @@ -37,27 +37,6 @@ int main(int argc, char **argv) { Vk_Frame *frame = Vk_FrameBegin(window); VkCommandBuffer cmd = frame->cmd; - VkImageMemoryBarrier2 colour_optimal = { 0 }; - colour_optimal.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2; - colour_optimal.srcStageMask = VK_PIPELINE_STAGE_2_NONE; - colour_optimal.srcAccessMask = VK_ACCESS_2_NONE; - colour_optimal.dstStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; - colour_optimal.dstAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; - colour_optimal.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - colour_optimal.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - colour_optimal.image = vk.swapchain.images[frame->image]; - - colour_optimal.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - colour_optimal.subresourceRange.layerCount = 1; - colour_optimal.subresourceRange.levelCount = 1; - - VkDependencyInfo colour_barrier = { 0 }; - colour_barrier.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO; - colour_barrier.imageMemoryBarrierCount = 1; - colour_barrier.pImageMemoryBarriers = &colour_optimal; - - vk.CmdPipelineBarrier2(cmd, &colour_barrier); - VkClearValue clear_colour; clear_colour.color.float32[0] = 1.0f; clear_colour.color.float32[1] = 0.0f; @@ -83,27 +62,6 @@ int main(int argc, char **argv) { vk.CmdEndRendering(cmd); - VkImageMemoryBarrier2 present_src = { 0 }; - present_src.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2; - present_src.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; - present_src.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; - present_src.dstStageMask = VK_PIPELINE_STAGE_2_NONE; - present_src.dstAccessMask = VK_ACCESS_2_NONE; - present_src.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - present_src.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - present_src.image = vk.swapchain.images[frame->image]; - - present_src.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - present_src.subresourceRange.layerCount = 1; - present_src.subresourceRange.levelCount = 1; - - VkDependencyInfo to_present = { 0 }; - to_present.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO; - to_present.imageMemoryBarrierCount = 1; - to_present.pImageMemoryBarriers = &present_src; - - vk.CmdPipelineBarrier2(cmd, &to_present); - Vk_FrameEnd(); } diff --git a/code/os/core.h b/code/os/core.h index 55ac3b8..efca174 100644 --- a/code/os/core.h +++ b/code/os/core.h @@ -1,6 +1,11 @@ #if !defined(LD_OS_CORE_H_) #define LD_OS_CORE_H_ +typedef struct OS_Handle OS_Handle; +struct OS_Handle { + U64 v[1]; +}; + // Virtual memory function U64 VM_PageSize(); @@ -11,4 +16,6 @@ function B32 VM_Commit(void *base, U64 size); function void VM_Decommit(void *base, U64 size); function void VM_Release(void *base, U64 size); +#include "filesystem.h" + #endif // LD_OS_CORE_H_ diff --git a/code/os/filesystem.h b/code/os/filesystem.h new file mode 100644 index 0000000..20d6d4e --- /dev/null +++ b/code/os/filesystem.h @@ -0,0 +1,16 @@ +#if !defined(LD_OS_FILESYSTEM_H_) +#define LD_OS_FILESYSTEM_H_ + +typedef U32 FS_AccessFlags; +enum { + FS_ACCESS_READ = (1 << 0), + FS_ACCESS_WRITE = (1 << 1) +}; + +function OS_Handle FS_FileOpen(Str8 path, FS_AccessFlags access); +function void FS_FileClose(OS_Handle file); + +function void FS_FileRead(OS_Handle file, void *ptr, U64 size, U64 offset); +function void FS_FileWrite(OS_Handle file, void *ptr, U64 size, U64 offset); + +#endif // LD_OS_FILESYSTEM_H_ diff --git a/code/os/impl/windows/core.c b/code/os/impl/windows/core.c index 7c95e39..7f70845 100644 --- a/code/os/impl/windows/core.c +++ b/code/os/impl/windows/core.c @@ -1,3 +1,19 @@ +// Windows utilities + +internal Str8 Win32_WideStr(M_Arena *arena, Str8 v) { + Str8 result = { 0 }; + + S32 nchars = MultiByteToWideChar(CP_UTF8, 0, (LPCCH) v.data, (int) v.count, 0, 0) + 1; + U64 nbytes = nchars << 1; + + result.count = nbytes - 2; // -2 because we don't include the null-terminator in the count + result.data = M_ArenaPush(arena, U8, .count = nbytes); + + MultiByteToWideChar(CP_UTF8, 0, (LPCCH) v.data, (int) v.count, (LPWSTR) result.data, nchars); + + return result; +} + // Virtual memory U64 VM_PageSize() { @@ -36,3 +52,4 @@ void VM_Release(void *base, U64 size) { VirtualFree(base, 0, MEM_RELEASE); } +#include "filesystem.c" diff --git a/code/os/impl/windows/filesystem.c b/code/os/impl/windows/filesystem.c new file mode 100644 index 0000000..7516caf --- /dev/null +++ b/code/os/impl/windows/filesystem.c @@ -0,0 +1,86 @@ +OS_Handle FS_FileOpen(Str8 path, FS_AccessFlags access) { + OS_Handle result = { 0 }; + + M_TempScope(0, 0) { + Str8 wpath = Win32_WideStr(temp.arena, path); + + DWORD dwAccess = 0; + DWORD dwShare = FILE_SHARE_READ; + DWORD dwCreate = OPEN_EXISTING; + + if (access & FS_ACCESS_WRITE) { + dwCreate = CREATE_ALWAYS; + dwAccess = GENERIC_WRITE; + } + + if (access & FS_ACCESS_READ) { + dwAccess |= GENERIC_READ; + } + + HANDLE hFile = CreateFileW((LPCWSTR) wpath.data, dwAccess, dwShare, 0, dwCreate, 0, 0); + + result.v[0] = (hFile == INVALID_HANDLE_VALUE) ? 0 : ((U64) hFile); + } + return result; +} + +void FS_FileClose(OS_Handle file) { + HANDLE hFile = cast(HANDLE) file.v[0]; + if (hFile) { + CloseHandle(hFile); + } +} + +void FS_FileRead(OS_Handle file, void *ptr, U64 size, U64 offset) { + HANDLE hFile = cast(HANDLE) file.v[0]; + if (hFile) { + U8 *buffer = ptr; + U64 current = offset; + U64 remainder = size; + + while (remainder != 0) { + OVERLAPPED overlapped = { 0 }; + overlapped.Offset = cast(DWORD) (current & 0xFFFFFFFF); + overlapped.OffsetHigh = cast(DWORD) ((current >> 32) & 0xFFFFFFFF); + + DWORD toread = (remainder > U32_MAX) ? U32_MAX : (DWORD) remainder; + DWORD nread = 0; + + if (!ReadFile(hFile, buffer, toread, &nread, &overlapped)) { + break; + } + + buffer += nread; + current += nread; + remainder -= nread; + } + } +} + +void FS_FileWrite(OS_Handle file, void *ptr, U64 size, U64 offset) { + HANDLE hFile = cast(HANDLE) file.v[0]; + if (hFile) { + U8 *buffer = ptr; + U64 current = offset; + U64 remainder = size; + + while (remainder != 0) { + OVERLAPPED overlapped = { 0 }; + overlapped.Offset = cast(DWORD) (current & 0xFFFFFFFF); + overlapped.OffsetHigh = cast(DWORD) ((current >> 32) & 0xFFFFFFFF); + + DWORD towrite = (remainder > U32_MAX) ? U32_MAX : (DWORD) remainder; + DWORD nwritten = 0; + + if (!WriteFile(hFile, buffer, towrite, &nwritten, &overlapped)) { + break; + } + + buffer += nwritten; + current += nwritten; + remainder -= nwritten; + } + } +} + + diff --git a/code/vulkan/core.c b/code/vulkan/core.c index 8b7f8c1..306666f 100644 --- a/code/vulkan/core.c +++ b/code/vulkan/core.c @@ -374,12 +374,54 @@ Vk_Frame *Vk_FrameBegin(SDL_Window *window) { vk.BeginCommandBuffer(frame->cmd, &begin_info); + VkImageMemoryBarrier2 colour_optimal = { 0 }; + colour_optimal.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2; + colour_optimal.srcStageMask = VK_PIPELINE_STAGE_2_NONE; + colour_optimal.srcAccessMask = VK_ACCESS_2_NONE; + colour_optimal.dstStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; + colour_optimal.dstAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; + colour_optimal.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + colour_optimal.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + colour_optimal.image = vk.swapchain.images[frame->image]; + + colour_optimal.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + colour_optimal.subresourceRange.layerCount = 1; + colour_optimal.subresourceRange.levelCount = 1; + + VkDependencyInfo colour_barrier = { 0 }; + colour_barrier.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO; + colour_barrier.imageMemoryBarrierCount = 1; + colour_barrier.pImageMemoryBarriers = &colour_optimal; + + vk.CmdPipelineBarrier2(frame->cmd, &colour_barrier); + return frame; } void Vk_FrameEnd() { Vk_Frame *frame = &vk.frames[vk.n_frames % vk.in_flight]; + VkImageMemoryBarrier2 present_src = { 0 }; + present_src.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2; + present_src.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; + present_src.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; + present_src.dstStageMask = VK_PIPELINE_STAGE_2_NONE; + present_src.dstAccessMask = VK_ACCESS_2_NONE; + present_src.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + present_src.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + present_src.image = vk.swapchain.images[frame->image]; + + present_src.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + present_src.subresourceRange.layerCount = 1; + present_src.subresourceRange.levelCount = 1; + + VkDependencyInfo to_present = { 0 }; + to_present.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO; + to_present.imageMemoryBarrierCount = 1; + to_present.pImageMemoryBarriers = &present_src; + + vk.CmdPipelineBarrier2(frame->cmd, &to_present); + vk.EndCommandBuffer(frame->cmd); VkPipelineStageFlags stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;