diff --git a/assets/test_char.m3d b/assets/test_char.m3d new file mode 100644 index 0000000..ecb623b Binary files /dev/null and b/assets/test_char.m3d differ diff --git a/assets/yoda.m3d b/assets/yoda.m3d new file mode 100644 index 0000000..de34cb5 Binary files /dev/null and b/assets/yoda.m3d differ diff --git a/external/m3d/m3d.h b/external/m3d/m3d.h index b0f6025..8bba183 100644 --- a/external/m3d/m3d.h +++ b/external/m3d/m3d.h @@ -44,13 +44,13 @@ extern "C" { /*** configuration ***/ #ifndef M3D_MALLOC -# define M3D_MALLOC(sz) FLMemAlloc(sz) +# define M3D_MALLOC(sz) malloc(sz) #endif #ifndef M3D_REALLOC -# define M3D_REALLOC(p,nsz) FLMemRealloc(p,nsz) +# define M3D_REALLOC(p,nsz) realloc(p,nsz) #endif #ifndef M3D_FREE -# define M3D_FREE(p) FLMemFree(p) +# define M3D_FREE(p) free(p) #endif #ifndef M3D_LOG # define M3D_LOG(x) diff --git a/external/stb/stb_image.h b/external/stb/stb_image.h index a03ba60..9eedabe 100644 --- a/external/stb/stb_image.h +++ b/external/stb/stb_image.h @@ -679,9 +679,9 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; #endif #ifndef STBI_MALLOC -#define STBI_MALLOC(sz) FLMemAlloc(sz) -#define STBI_REALLOC(p,newsz) FLMemRealloc(p,newsz) -#define STBI_FREE(p) FLMemFree(p) +#define STBI_MALLOC(sz) malloc(sz) +#define STBI_REALLOC(p,newsz) realloc(p,newsz) +#define STBI_FREE(p) free(p) #endif #ifndef STBI_REALLOC_SIZED diff --git a/external/xxhash/xxhash.h b/external/xxhash/xxhash.h index 07d2164..1ad2ddb 100644 --- a/external/xxhash/xxhash.h +++ b/external/xxhash/xxhash.h @@ -2384,13 +2384,13 @@ static void XXH_free(void* p) { (void)p; } * @internal * @brief Modify this function to use a different routine than malloc(). */ -static XXH_MALLOCF void* XXH_malloc(size_t s) { return FLMemAlloc(s); } +static XXH_MALLOCF void* XXH_malloc(size_t s) { return malloc(s); } /*! * @internal * @brief Modify this function to use a different routine than free(). */ -static void XXH_free(void* p) { FLMemFree(p); } +static void XXH_free(void* p) { free(p); } #endif /* XXH_NO_STDLIB */ diff --git a/src/allocators.c b/src/allocators.c index 393d9a8..1871923 100644 --- a/src/allocators.c +++ b/src/allocators.c @@ -227,11 +227,27 @@ static rawptr FLMemAllocZeroed(usize size) static rawptr FLMemRealloc(rawptr old_ptr, usize size) { - return FreeListRealloc(&FL_ALLOC, old_ptr, size); + if (!FL_GLOBAL_INIT) + { + GlobalFreeListInit(FL_GLOBAL_SIZE); + } + + rawptr ptr = NULL; + if (old_ptr == NULL) + ptr = FLMemAlloc(size); + else + ptr = FreeListRealloc(&FL_ALLOC, old_ptr, size); + + return ptr; } static void FLMemFree(rawptr ptr) { + if (!FL_GLOBAL_INIT) + { + GlobalFreeListInit(FL_GLOBAL_SIZE); + } + FreeListFree(&FL_ALLOC, ptr); } diff --git a/src/assets.h b/src/assets.h index f6327a2..4524d50 100644 --- a/src/assets.h +++ b/src/assets.h @@ -23,6 +23,8 @@ typedef enum ShaderAsset_e : u32 QUAD_VERT_SPIRV_SHADER, GUI_FRAG_SPIRV_SHADER, GUI_VERT_SPIRV_SHADER, + PBR_FRAG_SPIRV_SHADER, + PBR_VERT_SPIRV_SHADER, SHADER_ASSET_MAX, } ShaderAsset; diff --git a/src/entry_linux.c b/src/entry_linux.c index b8854aa..12f45be 100644 --- a/src/entry_linux.c +++ b/src/entry_linux.c @@ -1,5 +1,10 @@ #ifdef __linux__ +// ::Entry::Linux::Globals:: + +char *FAILURE_ERROR = "Unknown Error"; +int PROGRAM_FAILED = false; + // ::Entry::Linux::Globals::End:: #include "entry_linux.h" diff --git a/src/game.c b/src/game.c index edd001c..349881b 100644 --- a/src/game.c +++ b/src/game.c @@ -102,7 +102,7 @@ static void gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count) vBufferQueueWait(); - rPipelineBind(R_PIPELINE_GUI, rPT_GRAPHICS); + rPipelineBind(rPIPELINE_GUI, rPT_GRAPHICS); rPushConstantsSet(&ctx->pc); diff --git a/src/packer.c b/src/packer.c index dbb4302..f304732 100644 --- a/src/packer.c +++ b/src/packer.c @@ -28,6 +28,8 @@ const FileMapping g_Shader_File_Map[] = { { .file_name = "quad.vert.spv", .ix = QUAD_VERT_SPIRV_SHADER }, { .file_name = "gui.frag.spv", .ix = GUI_FRAG_SPIRV_SHADER }, { .file_name = "gui.vert.spv", .ix = GUI_VERT_SPIRV_SHADER }, + { .file_name = "pbr.frag.spv", .ix = PBR_FRAG_SPIRV_SHADER }, + { .file_name = "pbr.vert.spv", .ix = PBR_VERT_SPIRV_SHADER }, }; const FileMapping g_Texture_File_Map[] = { @@ -47,45 +49,6 @@ c8 *g_Texture_File_Names[TEXTURE_ASSET_MAX] = {0}; -// ::Packer::Files::Functions::Start:: - -u64 FileLength(FILE *file) -{ - Assert(fseek(file, 0, SEEK_END) == 0, "fseek failure"); - return (u64)ftell(file); -} - -u64 WriteData(void *buf, u64 pos, u64 size, FILE *file) -{ - Assert(fseek(file, pos, SEEK_SET) == 0, "WriteData fseek failure"); - u64 written = (u64)FWrite(buf, size, 1, file); - fflush(file); - return written; -} - -u64 ReadData(void *buf, u64 pos, u64 size, FILE *file) -{ - Assert(fseek(file, pos, SEEK_SET) == 0, "ReadData fseek failure"); - return FRead(buf, size, 1, file); -} - -FILE *pOpenFile(c8 *name, c8 *mode) -{ - FILE *file = fopen(name, mode); - Assert(file != NULL, "pOpenFile: file is null"); - return file; -} - -void CloseFile(FILE *file) -{ - fflush(file); - Assert(fclose(file) != EOF, "Error closing file"); -} - -// ::Packer::Files::Functions::End:: - - - // ::Packer::Packing::Functions::Start:: void SetArrayLookups() @@ -113,7 +76,7 @@ void SetArrayLookups() } } -i32 WriteHeader(FILE *file, FileHeader *header) +i32 WriteHeader(pFile file, FileHeader *header) { i32 offset = 0; @@ -195,9 +158,9 @@ void InitHeader(FileHeader *header) void PackFiles(Arena *arena, FileHeader *header) { - FILE *file = pOpenFile("assets.sgp", "w+"); + pFile file = pFileOpen("assets.sgp", pFS_WRITE | pFS_TRUNC); - u64 file_pos = WriteData(header, 0, sizeof(FileHeader), file); + u64 file_pos = pFileWrite(file, 0, header, sizeof(FileHeader)); u64 data_offset = 0; for (u32 i = 0; i < ASSET_TYPE_MAX; i++) @@ -222,21 +185,21 @@ void PackFiles(Arena *arena, FileHeader *header) Printfln("Packing file: %s...", asset_name); - FILE *asset_file = pOpenFile(asset_name, "r"); - u64 file_size = FileLength(asset_file); + pFile asset_file = pFileOpen(asset_name, pFS_READ); + u64 file_size = pFileLength(asset_file); u8 *file_data = MakeArray(arena, u8, file_size); - ReadData(file_data, 0, file_size, asset_file); + pFileRead(asset_file, 0, file_data, file_size); u64 prev_offset = data_offset; - data_offset += WriteData(file_data, data_offset, file_size, file); + data_offset += pFileWrite(file, data_offset, file_data, file_size); Assert((data_offset - prev_offset) == file_size, "File write size invalid"); shader_assets[i].data_offset = prev_offset; shader_assets[i].len = file_size; - CloseFile(asset_file); + pFileClose(asset_file); } Assert(pDirNavigate(return_dir) == 0, "Unable to return to previous directory"); @@ -249,21 +212,25 @@ void PackFiles(Arena *arena, FileHeader *header) Printfln("Packing file: %s...", asset_name); - FILE *asset_file = pOpenFile(asset_name, "r"); - u64 file_size = FileLength(asset_file); + pFile asset_file = pFileOpen(asset_name, pFS_READ); + u64 file_size = pFileLength(asset_file); u8 *file_data = MakeArray(arena, u8, file_size); - ReadData(file_data, 0, file_size, asset_file); + pFileRead(asset_file, 0, file_data, file_size); int ch = 4; int w, h, has_ch; u8 *image_bytes = stbi_load_from_memory(file_data, file_size, &w, &h, &has_ch, ch); - Assert(w > 0 && h > 0 && has_ch > 0, "stbi_load_from_memory failure"); + if (w <= 0 || h <= 0 || has_ch <= 0) + { + Printfln("%s", stbi_failure_reason()); + Assert(0, "stbi_load_from_memory failure"); + } u64 loaded_length = u64(w * h * ch); u64 prev_offset = data_offset; - data_offset += WriteData(image_bytes, data_offset, loaded_length, file); + data_offset += pFileWrite(file, data_offset, image_bytes, loaded_length); Assert((data_offset - prev_offset) == loaded_length, "File write size invalid"); @@ -275,11 +242,11 @@ void PackFiles(Arena *arena, FileHeader *header) stbi_image_free(image_bytes); - CloseFile(asset_file); + pFileClose(asset_file); } - WriteData(shader_assets, header->asset_offsets[SHADER_ASSET], sizeof(AssetFile)*SHADER_ASSET_MAX, file); - WriteData(texture_assets, header->asset_offsets[TEXTURE_ASSET], sizeof(AssetFile)*TEXTURE_ASSET_MAX, file); + pFileWrite(file, header->asset_offsets[SHADER_ASSET], shader_assets, sizeof(AssetFile)*SHADER_ASSET_MAX); + pFileWrite(file, header->asset_offsets[TEXTURE_ASSET], texture_assets, sizeof(AssetFile)*TEXTURE_ASSET_MAX); pDirNavigate(return_dir); } @@ -290,18 +257,18 @@ void PackFiles(Arena *arena, FileHeader *header) // ::Packer::Tests::Functions::Start:: -static inline void TestAssetIsCorrect(Arena *arena, c8 *file_name, AssetFile *file_info, AssetType type, FILE *file) +static inline void TestAssetIsCorrect(Arena *arena, c8 *file_name, AssetFile *file_info, AssetType type, pFile file) { - FILE *asset_file = pOpenFile(file_name, "r"); - u64 size = FileLength(asset_file); + pFile asset_file = pFileOpen(file_name, pFS_READ); + u64 size = pFileLength(asset_file); u8 *file_data = MakeArray(arena, u8, size); - u64 write_count = ReadData(file_data, 0, size, asset_file); + u64 write_count = pFileRead(asset_file, 0, file_data, size); Assert(write_count == size, "Incorrect asset size retrieved"); u8 *packed_asset = MakeArray(arena, u8, file_info->len); - ReadData(packed_asset, file_info->data_offset, file_info->len, file); + pFileRead(file, file_info->data_offset, packed_asset, file_info->len); u8 *image_bytes; u64 image_length; @@ -331,15 +298,15 @@ static inline void TestAssetIsCorrect(Arena *arena, c8 *file_name, AssetFile *fi } } - CloseFile(asset_file); + pFileClose(asset_file); } void TestAssetPack(Arena *arena) { - FILE *file = pOpenFile("assets.sgp", "r"); + pFile file = pFileOpen("assets.sgp", pFS_READ); FileHeader header; - i64 offset = FRead(&header, sizeof(FileHeader), 1, file); + i64 offset = pFileRead(file, 0, &header, sizeof(FileHeader)); Assert(header.magic_num == CreateMagicValue('s', 't', 'e', 'g'), "Magic number is incorrect"); Assert(header.version == FILE_VERSION, "File version is incorrect"); @@ -364,13 +331,13 @@ void TestAssetPack(Arena *arena) if (header.tag_counts[i] > 0) { tags[i] = MakeArray(arena, AssetTag, header.tag_counts[i]); - ReadData(tags[i], header.tag_offsets[i], sizeof(AssetTag)*header.tag_counts[i], file); + pFileRead(file, header.tag_offsets[i], tags[i], sizeof(AssetTag)*header.tag_counts[i]); } if (header.asset_counts[i] > 0) { files[i] = MakeArray(arena, AssetFile, header.asset_counts[i]); - ReadData(files[i], header.asset_offsets[i], sizeof(AssetFile)*header.asset_counts[i], file); + pFileRead(file, header.asset_offsets[i], files[i], sizeof(AssetFile)*header.asset_counts[i]); } } @@ -410,15 +377,15 @@ int main(int argc, c8 **argv) void *mem = pMemAllocZeroed(GB(1)); Arena *arena = ArenaInitDebug(mem, GB(1), __LINE__); - FILE *file = fopen("assets.sgp", "w+"); - Assert(file != NULL, "File is null"); + pFile file = pFileOpen("assets.sgp", pFS_WRITE | pFS_TRUNC); + Assert(file > 0, "File is null"); FileHeader header = {0}; InitHeader(&header); PackFiles(arena, &header); - CloseFile(file); + pFileClose(file); TestAssetPack(arena); } diff --git a/src/packer.h b/src/packer.h index c5621fb..a33ac44 100644 --- a/src/packer.h +++ b/src/packer.h @@ -14,17 +14,19 @@ #define STB_IMAGE_IMPLEMENTATION +#include "shared_types.h" +#include "platform/platform.h" +#include "util.h" +#include "assets.h" +#include "ds.h" +#include "allocators.h" + +// ::ThirdParty::Include::Header:: #include "stb/stb_sprintf.h" #include "stb/stb_image.h" #include "xxhash/xxhash.h" #include "fastlz/fastlz.h" -#include "shared_types.h" -#include "assets.h" -#include "util.h" -#include "ds.h" -#include "platform/platform.h" -#include "allocators.h" #include "renderer.h" #include "game.h" @@ -43,19 +45,11 @@ typedef struct FileMapping u32 ix; } FileMapping; -// ::Packer::Files::Functions::Header:: - -FILE *pOpenFile(c8 *name, c8 *mode); -void CloseFile(FILE *file); -u64 FileLength(FILE *file); -u64 WriteData(void *buf, u64 pos, u64 size, FILE *file); -u64 ReadData(void *buf, u64 pos, u64 size, FILE *file); - // ::Packer::Packing::Functions::Header:: void SetArrayLookups(); void InitHeader(FileHeader *header); -i32 WriteHeader(FILE *file, FileHeader *header); +i32 WriteHeader(pFile file, FileHeader *header); void PackFiles(Arena *arena, FileHeader *header); void MoveToTextureDir(c8 **return_dir); void MoveToShaderDir(c8 **return_dir); @@ -63,7 +57,7 @@ void MoveToShaderDir(c8 **return_dir); // ::Packer::Tests::Functions::Header:: void TestAssetPack(Arena *arena); -static inline void TestAssetIsCorrect(Arena *arena, c8 *file_name, AssetFile *file_info, AssetType type, FILE *file); +static inline void TestAssetIsCorrect(Arena *arena, c8 *file_name, AssetFile *file_info, AssetType type, pFile file); // ::Packer::Main::Functions::Header:: diff --git a/src/platform/platform.h b/src/platform/platform.h index 072e47f..aeb4afe 100644 --- a/src/platform/platform.h +++ b/src/platform/platform.h @@ -117,9 +117,26 @@ pPlatformWindow *pWindowGet(); // ::Platform::FileSystem::Functions::Header:: +typedef enum e_pFSAccess +{ + pFS_READ = 0x01, + pFS_WRITE = 0x02, + pFS_TRUNC = 0x04, + pFS_APPEND = 0x08, +} pFSAccess; + b32 pDirNavigate(c8 *dir); c8 **pDirGetFileNames(Arena *arena, u32 *count); -static b8 pDirIsVisible(c8 *dir_name); +static pFile pFileOpen(c8 *file_name, pFSAccess access); +static void pFileClose(pFile file); +static u64 pFileRead(pFile file, u64 offset, rawptr buf, u64 len); +static u64 pFileWrite(pFile file, u64 offset, rawptr buf, u64 len); +static u64 pFileSeek(pFile file, u64 pos); +static u64 pFileLength(pFile file); +static b32 pFSIsVisible(c8 *name, b32 is_dir); +static b32 pDirIsVisible(c8 *dir_name); +static b32 pFileIsVisible(c8 *file_name); +static b32 pFileCanAccess(c8 *file_name, pFSAccess access); // ::Platform::Profiling::Functions::Header:: diff --git a/src/platform/platform_linux.h b/src/platform/platform_linux.h index 356025f..80af75a 100644 --- a/src/platform/platform_linux.h +++ b/src/platform/platform_linux.h @@ -25,6 +25,7 @@ #include #include #include +#include // ::Platform::Linux::Defines::Header:: @@ -52,6 +53,8 @@ // ::Platform::Linux::Types::Header +typedef int pFile; + typedef struct pThread { pthread_t handle; @@ -79,6 +82,8 @@ typedef struct pFunction void *fn; } pFunction; +typedef int pFile; + // ::Platform::Linux::Print::Functions::Header:: i32 pWrite(int fd, void const *str, isize count); diff --git a/src/platform/platform_linux_public.c b/src/platform/platform_linux_public.c index 1e7f18f..e5e8492 100644 --- a/src/platform/platform_linux_public.c +++ b/src/platform/platform_linux_public.c @@ -225,13 +225,66 @@ b32 pWindowShouldQuit() -// ::Platform::Functions::Directory::Start:: +// ::Platform::FileSystem::Functions::Start:: b32 pDirNavigate(c8 *dir) { return chdir(dir); } +static pFile pFileOpen(c8 *file_name, pFSAccess acc) +{ + int flags = 0; + if (BitEq(acc, pFS_READ) && BitEq(acc, pFS_WRITE)) + flags = O_RDWR; + else if (BitEq(acc, pFS_READ)) + flags = O_RDONLY; + else if (BitEq(acc, pFS_WRITE)) + flags = O_WRONLY; + + if (BitEq(acc, pFS_TRUNC)) + flags |= O_TRUNC; + else if (BitEq(acc, pFS_APPEND)) + flags |= O_APPEND; + + return open(file_name, flags); +} + +static void pFileClose(pFile file) +{ + close(file); +} + +// TODO: make these more resilient +static u64 pFileRead(pFile file, u64 offset, rawptr buf, u64 len) +{ + lseek(file, (isize)offset, SEEK_SET); + return read(file, buf, (usize)len); +} + +static u64 pFileWrite(pFile file, u64 offset, rawptr buf, u64 len) +{ + lseek(file, (isize)offset, SEEK_SET); + return write(file, buf, (usize)len); +} + +static u64 pFileSeek(pFile file, u64 pos) +{ + return (u64)lseek(file, (isize)pos, SEEK_SET); +} + +static u64 pFileLength(pFile file) +{ + isize offset = lseek(file, 0, SEEK_CUR); + isize size = lseek(file, 0, SEEK_END); + lseek(file, offset, SEEK_SET); + + if (size == -1) + size = UINT64_MAX; + + return (u64)size; +} + c8 **pDirGetFileNames(Arena *arena, u32 *count) { struct dirent *dir; @@ -269,18 +322,19 @@ c8 **pDirGetFileNames(Arena *arena, u32 *count) return (c8 **)file_names; } -static b8 pDirIsVisible(c8 *dir_name) +static b32 pFSIsVisible(c8 *name, b32 is_dir) { - b8 found = false; + b32 found = false; struct dirent *dir; DIR *d = opendir("."); + u8 type = is_dir ? DT_DIR : DT_REG; if (d) { while ((dir = readdir(d)) != NULL) { - if (StrEq(dir_name, dir->d_name) && dir->d_type == DT_DIR) + if (StrEq(name, dir->d_name) && dir->d_type == type) { found = true; break; @@ -291,7 +345,28 @@ static b8 pDirIsVisible(c8 *dir_name) return found; } -// ::Platform::Functions::Directory::End:: +static b32 pDirIsVisible(c8 *dir_name) +{ + return pFSIsVisible(dir_name, true); +} + +static b32 pFileIsVisible(c8 *file_name) +{ + return pFSIsVisible(file_name, false); +} + +static b32 pFileCanAccess(c8 *file_name, pFSAccess file_access) +{ + int a = 0; + if (BitEq(file_access, pFS_READ)) + a |= R_OK; + if (BitEq(file_access, pFS_WRITE)) + a |= W_OK; + + return access(file_name, a) == 0; +} + +// ::Platform::FileSystem::Functions::End:: diff --git a/src/renderer.h b/src/renderer.h index 5480c89..9f6bff4 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -22,10 +22,11 @@ typedef struct rShaderGlobals rShaderGlobals; typedef enum Pipeline_e { - R_PIPELINE_CUBE, - R_PIPELINE_GUI, + rPIPELINE_CUBE, + rPIPELINE_GUI, + rPIPELINE_PBR, - R_PIPELINE_MAX, + rPIPELINE_MAX, } rPipelineHandle; typedef enum PipelineType_e @@ -72,6 +73,12 @@ typedef struct rUIVertex u32 tex_idx; } rUIVertex; +typedef struct rPBRVertex +{ + Vec4 pos; + Vec4 col; +} rPBRVertex; + typedef struct rUploadQueue { union diff --git a/src/renderer_vulkan.c b/src/renderer_vulkan.c index 83e713b..51ee4da 100644 --- a/src/renderer_vulkan.c +++ b/src/renderer_vulkan.c @@ -1534,12 +1534,9 @@ static b32 vPipelinesInit() VkResult result; VkDevice device = v_Renderer.handles.device; - Asset quad_vert_shader = apLoadShader(QUAD_VERT_SPIRV_SHADER); - Asset quad_frag_shader = apLoadShader(QUAD_FRAG_SPIRV_SHADER); - - VkShaderModule cube_vert, cube_frag; - success &= vShaderModuleInit(quad_vert_shader.bytes, quad_vert_shader.len, &cube_vert); - success &= vShaderModuleInit(quad_frag_shader.bytes, quad_frag_shader.len, &cube_frag); + /* + * SHARED + */ VkPipelineRenderingCreateInfo pipeline_render_info = { .sType = STYPE(PIPELINE_RENDERING_CREATE_INFO), @@ -1548,6 +1545,17 @@ static b32 vPipelinesInit() .depthAttachmentFormat = v_Renderer.images.depth.image.format, }; + /* + * QUAD PIPELINE START + */ + + Asset quad_vert_shader = apLoadShader(QUAD_VERT_SPIRV_SHADER); + Asset quad_frag_shader = apLoadShader(QUAD_FRAG_SPIRV_SHADER); + + VkShaderModule cube_vert, cube_frag; + success &= vShaderModuleInit(quad_vert_shader.bytes, quad_vert_shader.len, &cube_vert); + success &= vShaderModuleInit(quad_frag_shader.bytes, quad_frag_shader.len, &cube_frag); + VkPipelineShaderStageCreateInfo cube_shader_stages[] = { { .sType = STYPE(PIPELINE_SHADER_STAGE_CREATE_INFO), @@ -1568,7 +1576,7 @@ static b32 vPipelinesInit() cube_create_info.layout = v_Renderer.handles.pipeline_layout; cube_create_info.pNext = &pipeline_render_info; - result = vkCreateGraphicsPipelines(device, 0, 1, &cube_create_info, NULL, &v_Renderer.handles.pipelines[R_PIPELINE_CUBE]); + result = vkCreateGraphicsPipelines(device, 0, 1, &cube_create_info, NULL, &v_Renderer.handles.pipelines[rPIPELINE_CUBE]); if (result != VK_SUCCESS) { Printf("vkCreateGraphicsPipelines failure: %s", vVkResultStr(result)); @@ -1581,6 +1589,10 @@ static b32 vPipelinesInit() apUnloadShader(QUAD_VERT_SPIRV_SHADER); apUnloadShader(QUAD_FRAG_SPIRV_SHADER); + /* + * GUI PIPELINE START + */ + Asset gui_vert_shader = apLoadShader(GUI_VERT_SPIRV_SHADER); Asset gui_frag_shader = apLoadShader(GUI_FRAG_SPIRV_SHADER); @@ -1608,7 +1620,7 @@ static b32 vPipelinesInit() gui_create_info.layout = v_Renderer.handles.pipeline_layout; gui_create_info.pNext = &pipeline_render_info; - result = vkCreateGraphicsPipelines(device, 0, 1, &gui_create_info, NULL, &v_Renderer.handles.pipelines[R_PIPELINE_GUI]); + result = vkCreateGraphicsPipelines(device, 0, 1, &gui_create_info, NULL, &v_Renderer.handles.pipelines[rPIPELINE_GUI]); if (result != VK_SUCCESS) { Printfln("vkCreateGraphicsPipelines failure: %s", vVkResultStr(result)); @@ -1621,6 +1633,50 @@ static b32 vPipelinesInit() apUnloadShader(GUI_VERT_SPIRV_SHADER); apUnloadShader(GUI_FRAG_SPIRV_SHADER); + /* + * PBR PIPELINE START + */ + + Asset pbr_vert_shader = apLoadShader(PBR_VERT_SPIRV_SHADER); + Asset pbr_frag_shader = apLoadShader(PBR_FRAG_SPIRV_SHADER); + + VkShaderModule pbr_vert, pbr_frag; + success &= vShaderModuleInit(pbr_vert_shader.bytes, pbr_vert_shader.len, &pbr_vert); + success &= vShaderModuleInit(pbr_frag_shader.bytes, pbr_frag_shader.len, &pbr_frag); + + VkPipelineShaderStageCreateInfo pbr_shader_stages[] = { + { + .sType = STYPE(PIPELINE_SHADER_STAGE_CREATE_INFO), + .stage = VK_SHADER_STAGE_VERTEX_BIT, + .module = pbr_vert, + .pName = "main", + }, + { + .sType = STYPE(PIPELINE_SHADER_STAGE_CREATE_INFO), + .stage = VK_SHADER_STAGE_FRAGMENT_BIT, + .module = pbr_frag, + .pName = "main", + }, + }; + + pbr_create_info.pStages = pbr_shader_stages; + pbr_create_info.stageCount = Len(pbr_shader_stages); + pbr_create_info.layout = v_Renderer.handles.pipeline_layout; + pbr_create_info.pNext = &pipeline_render_info; + + result = vkCreateGraphicsPipelines(device, 0, 1, &pbr_create_info, NULL, &v_Renderer.handles.pipelines[rPIPELINE_PBR]); + if (result != VK_SUCCESS) + { + Printfln("vkCreateGraphicsPipelineFailure: %s", vVkResultStr(result)); + success = false; + } + + vkDestroyShaderModule(device, pbr_vert, NULL); + vkDestroyShaderModule(device, pbr_frag, NULL); + + apUnloadShader(PBR_VERT_SPIRV_SHADER); + apUnloadShader(PBR_FRAG_SPIRV_SHADER); + return success; } diff --git a/src/renderer_vulkan.h b/src/renderer_vulkan.h index 8d8b93a..00a9747 100644 --- a/src/renderer_vulkan.h +++ b/src/renderer_vulkan.h @@ -312,7 +312,7 @@ typedef struct vRHandles VkSwapchainKHR swapchain; VmaAllocator vma_alloc; VkDescriptorPool desc_pool; - VkPipeline pipelines[R_PIPELINE_MAX]; + VkPipeline pipelines[rPIPELINE_MAX]; VkPipelineLayout pipeline_layout; VkDescriptorSetLayout desc_layouts[vDT_MAX]; VkDescriptorSet desc_sets[vDT_MAX]; diff --git a/src/renderer_vulkan_public.c b/src/renderer_vulkan_public.c index 45a29d8..0eff72a 100644 --- a/src/renderer_vulkan_public.c +++ b/src/renderer_vulkan_public.c @@ -53,7 +53,7 @@ void rDestroy() vkDestroySampler(device, nearest_sampler, NULL); - for (u32 i = R_PIPELINE_CUBE; i < R_PIPELINE_MAX; i++) + for (u32 i = rPIPELINE_CUBE; i < rPIPELINE_MAX; i++) vkDestroyPipeline(device, pipelines[i], NULL); vkDestroyPipelineLayout(device, pipeline_layout, NULL); diff --git a/src/shaders/glsl/pbr.frag.glsl b/src/shaders/glsl/pbr.frag.glsl new file mode 100644 index 0000000..8f686c6 --- /dev/null +++ b/src/shaders/glsl/pbr.frag.glsl @@ -0,0 +1,16 @@ +#version 460 + +#extension GL_EXT_buffer_reference : require +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_nonuniform_qualifier : require + +#include "structures.glsl" + +layout (location = 0) in vec4 in_col; + +layout (location = 0) out vec4 out_frag_col; + +void main() +{ + out_frag_col = in_col; +} diff --git a/src/shaders/glsl/pbr.vert.glsl b/src/shaders/glsl/pbr.vert.glsl new file mode 100644 index 0000000..0b3848d --- /dev/null +++ b/src/shaders/glsl/pbr.vert.glsl @@ -0,0 +1,18 @@ +#version 460 + +#extension GL_EXT_buffer_reference : require +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_nonuniform_qualifier : require + +#include "structures.glsl" + +layout (location = 0) in vec4 in_pos; +layout (location = 1) in vec4 in_col; + +layout (location = 0) out vec4 out_col; + +void main() +{ + out_col = in_col; + gl_Position = in_pos; +} diff --git a/src/vulkan_config.c b/src/vulkan_config.c index a307e4d..cb31429 100644 --- a/src/vulkan_config.c +++ b/src/vulkan_config.c @@ -451,8 +451,41 @@ VkPipelineInputAssemblyStateCreateInfo gui_assembly_info = { .primitiveRestartEnable = VK_FALSE, }; +// PBR Pipeline +INIT_PIPELINE_DEFAULTS(pbr); + +VkVertexInputBindingDescription pbr_input_bind_desc = { + .binding = 0, + .stride = sizeof(rPBRVertex), + .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, +}; + +VkVertexInputAttributeDescription pbr_input_descriptions[] = { + { .binding = 0, .location = 0, .format = VK_FORMAT_R32G32B32A32_SFLOAT, .offset = 0 }, + { .binding = 1, .location = 1, .format = VK_FORMAT_R32G32B32A32_SFLOAT, .offset = offsetof(rPBRVertex, col) }, +}; + +VkPipelineVertexInputStateCreationInfo pbr_vertex_input_info = { + .sType = STYPE(PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO), + .vertexBindingDescriptionCount = 1, + .pVertexBindingDescriptions = &pbr_vertex_bind_desc, + .vertexAttributeDescriptionCount = Len(pbr_input_descriptions), + .pVertexAttributeDescriptions = pbr_input_descriptions, +}; + +VkPipelineInputAssemblyStateCreateInfo pbr_assembly_info = { + .sType = STYPE(PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO), + .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + .primitiveRestartEnable = VK_FALSE, +}; + static void vCustomizePipelines() { + // GUI gui_create_info.pVertexInputState = &gui_vertex_input_info; gui_create_info.pInputAssemblyState = &gui_assembly_info; + + // PBR + pbr_create_info.pVertexInputState = &pbr_vertex_input_info; + pbr_create_info.pInputAssemblyState = &pbr_assembly_info; }