start work on pbr pipeline, some clean up/fixes for allocators

This commit is contained in:
Matthew 2025-05-21 22:32:28 +10:00
parent cc759fb5eb
commit 60ca4c06ae
21 changed files with 324 additions and 113 deletions

BIN
assets/test_char.m3d Normal file

Binary file not shown.

BIN
assets/yoda.m3d Normal file

Binary file not shown.

6
external/m3d/m3d.h vendored
View File

@ -44,13 +44,13 @@ extern "C" {
/*** configuration ***/ /*** configuration ***/
#ifndef M3D_MALLOC #ifndef M3D_MALLOC
# define M3D_MALLOC(sz) FLMemAlloc(sz) # define M3D_MALLOC(sz) malloc(sz)
#endif #endif
#ifndef M3D_REALLOC #ifndef M3D_REALLOC
# define M3D_REALLOC(p,nsz) FLMemRealloc(p,nsz) # define M3D_REALLOC(p,nsz) realloc(p,nsz)
#endif #endif
#ifndef M3D_FREE #ifndef M3D_FREE
# define M3D_FREE(p) FLMemFree(p) # define M3D_FREE(p) free(p)
#endif #endif
#ifndef M3D_LOG #ifndef M3D_LOG
# define M3D_LOG(x) # define M3D_LOG(x)

View File

@ -679,9 +679,9 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
#endif #endif
#ifndef STBI_MALLOC #ifndef STBI_MALLOC
#define STBI_MALLOC(sz) FLMemAlloc(sz) #define STBI_MALLOC(sz) malloc(sz)
#define STBI_REALLOC(p,newsz) FLMemRealloc(p,newsz) #define STBI_REALLOC(p,newsz) realloc(p,newsz)
#define STBI_FREE(p) FLMemFree(p) #define STBI_FREE(p) free(p)
#endif #endif
#ifndef STBI_REALLOC_SIZED #ifndef STBI_REALLOC_SIZED

View File

@ -2384,13 +2384,13 @@ static void XXH_free(void* p) { (void)p; }
* @internal * @internal
* @brief Modify this function to use a different routine than malloc(). * @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 * @internal
* @brief Modify this function to use a different routine than free(). * @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 */ #endif /* XXH_NO_STDLIB */

View File

@ -227,11 +227,27 @@ static rawptr FLMemAllocZeroed(usize size)
static rawptr FLMemRealloc(rawptr old_ptr, 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) static void FLMemFree(rawptr ptr)
{ {
if (!FL_GLOBAL_INIT)
{
GlobalFreeListInit(FL_GLOBAL_SIZE);
}
FreeListFree(&FL_ALLOC, ptr); FreeListFree(&FL_ALLOC, ptr);
} }

View File

@ -23,6 +23,8 @@ typedef enum ShaderAsset_e : u32
QUAD_VERT_SPIRV_SHADER, QUAD_VERT_SPIRV_SHADER,
GUI_FRAG_SPIRV_SHADER, GUI_FRAG_SPIRV_SHADER,
GUI_VERT_SPIRV_SHADER, GUI_VERT_SPIRV_SHADER,
PBR_FRAG_SPIRV_SHADER,
PBR_VERT_SPIRV_SHADER,
SHADER_ASSET_MAX, SHADER_ASSET_MAX,
} ShaderAsset; } ShaderAsset;

View File

@ -1,5 +1,10 @@
#ifdef __linux__ #ifdef __linux__
// ::Entry::Linux::Globals::
char *FAILURE_ERROR = "Unknown Error";
int PROGRAM_FAILED = false;
// ::Entry::Linux::Globals::End:: // ::Entry::Linux::Globals::End::
#include "entry_linux.h" #include "entry_linux.h"

View File

@ -102,7 +102,7 @@ static void gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count)
vBufferQueueWait(); vBufferQueueWait();
rPipelineBind(R_PIPELINE_GUI, rPT_GRAPHICS); rPipelineBind(rPIPELINE_GUI, rPT_GRAPHICS);
rPushConstantsSet(&ctx->pc); rPushConstantsSet(&ctx->pc);

View File

@ -28,6 +28,8 @@ const FileMapping g_Shader_File_Map[] = {
{ .file_name = "quad.vert.spv", .ix = QUAD_VERT_SPIRV_SHADER }, { .file_name = "quad.vert.spv", .ix = QUAD_VERT_SPIRV_SHADER },
{ .file_name = "gui.frag.spv", .ix = GUI_FRAG_SPIRV_SHADER }, { .file_name = "gui.frag.spv", .ix = GUI_FRAG_SPIRV_SHADER },
{ .file_name = "gui.vert.spv", .ix = GUI_VERT_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[] = { 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:: // ::Packer::Packing::Functions::Start::
void SetArrayLookups() void SetArrayLookups()
@ -113,7 +76,7 @@ void SetArrayLookups()
} }
} }
i32 WriteHeader(FILE *file, FileHeader *header) i32 WriteHeader(pFile file, FileHeader *header)
{ {
i32 offset = 0; i32 offset = 0;
@ -195,9 +158,9 @@ void InitHeader(FileHeader *header)
void PackFiles(Arena *arena, 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; u64 data_offset = 0;
for (u32 i = 0; i < ASSET_TYPE_MAX; i++) 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); Printfln("Packing file: %s...", asset_name);
FILE *asset_file = pOpenFile(asset_name, "r"); pFile asset_file = pFileOpen(asset_name, pFS_READ);
u64 file_size = FileLength(asset_file); u64 file_size = pFileLength(asset_file);
u8 *file_data = MakeArray(arena, u8, file_size); 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; 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"); Assert((data_offset - prev_offset) == file_size, "File write size invalid");
shader_assets[i].data_offset = prev_offset; shader_assets[i].data_offset = prev_offset;
shader_assets[i].len = file_size; shader_assets[i].len = file_size;
CloseFile(asset_file); pFileClose(asset_file);
} }
Assert(pDirNavigate(return_dir) == 0, "Unable to return to previous directory"); 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); Printfln("Packing file: %s...", asset_name);
FILE *asset_file = pOpenFile(asset_name, "r"); pFile asset_file = pFileOpen(asset_name, pFS_READ);
u64 file_size = FileLength(asset_file); u64 file_size = pFileLength(asset_file);
u8 *file_data = MakeArray(arena, u8, file_size); 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 ch = 4;
int w, h, has_ch; int w, h, has_ch;
u8 *image_bytes = stbi_load_from_memory(file_data, file_size, &w, &h, &has_ch, 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 loaded_length = u64(w * h * ch);
u64 prev_offset = data_offset; 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"); 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); 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); pFileWrite(file, header->asset_offsets[SHADER_ASSET], shader_assets, sizeof(AssetFile)*SHADER_ASSET_MAX);
WriteData(texture_assets, header->asset_offsets[TEXTURE_ASSET], sizeof(AssetFile)*TEXTURE_ASSET_MAX, file); pFileWrite(file, header->asset_offsets[TEXTURE_ASSET], texture_assets, sizeof(AssetFile)*TEXTURE_ASSET_MAX);
pDirNavigate(return_dir); pDirNavigate(return_dir);
} }
@ -290,18 +257,18 @@ void PackFiles(Arena *arena, FileHeader *header)
// ::Packer::Tests::Functions::Start:: // ::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"); pFile asset_file = pFileOpen(file_name, pFS_READ);
u64 size = FileLength(asset_file); u64 size = pFileLength(asset_file);
u8 *file_data = MakeArray(arena, u8, size); 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"); Assert(write_count == size, "Incorrect asset size retrieved");
u8 *packed_asset = MakeArray(arena, u8, file_info->len); 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; u8 *image_bytes;
u64 image_length; 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) void TestAssetPack(Arena *arena)
{ {
FILE *file = pOpenFile("assets.sgp", "r"); pFile file = pFileOpen("assets.sgp", pFS_READ);
FileHeader header; 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.magic_num == CreateMagicValue('s', 't', 'e', 'g'), "Magic number is incorrect");
Assert(header.version == FILE_VERSION, "File version 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) if (header.tag_counts[i] > 0)
{ {
tags[i] = MakeArray(arena, AssetTag, header.tag_counts[i]); 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) if (header.asset_counts[i] > 0)
{ {
files[i] = MakeArray(arena, AssetFile, header.asset_counts[i]); 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)); void *mem = pMemAllocZeroed(GB(1));
Arena *arena = ArenaInitDebug(mem, GB(1), __LINE__); Arena *arena = ArenaInitDebug(mem, GB(1), __LINE__);
FILE *file = fopen("assets.sgp", "w+"); pFile file = pFileOpen("assets.sgp", pFS_WRITE | pFS_TRUNC);
Assert(file != NULL, "File is null"); Assert(file > 0, "File is null");
FileHeader header = {0}; FileHeader header = {0};
InitHeader(&header); InitHeader(&header);
PackFiles(arena, &header); PackFiles(arena, &header);
CloseFile(file); pFileClose(file);
TestAssetPack(arena); TestAssetPack(arena);
} }

View File

@ -14,17 +14,19 @@
#define STB_IMAGE_IMPLEMENTATION #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_sprintf.h"
#include "stb/stb_image.h" #include "stb/stb_image.h"
#include "xxhash/xxhash.h" #include "xxhash/xxhash.h"
#include "fastlz/fastlz.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 "renderer.h"
#include "game.h" #include "game.h"
@ -43,19 +45,11 @@ typedef struct FileMapping
u32 ix; u32 ix;
} FileMapping; } 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:: // ::Packer::Packing::Functions::Header::
void SetArrayLookups(); void SetArrayLookups();
void InitHeader(FileHeader *header); void InitHeader(FileHeader *header);
i32 WriteHeader(FILE *file, FileHeader *header); i32 WriteHeader(pFile file, FileHeader *header);
void PackFiles(Arena *arena, FileHeader *header); void PackFiles(Arena *arena, FileHeader *header);
void MoveToTextureDir(c8 **return_dir); void MoveToTextureDir(c8 **return_dir);
void MoveToShaderDir(c8 **return_dir); void MoveToShaderDir(c8 **return_dir);
@ -63,7 +57,7 @@ void MoveToShaderDir(c8 **return_dir);
// ::Packer::Tests::Functions::Header:: // ::Packer::Tests::Functions::Header::
void TestAssetPack(Arena *arena); 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:: // ::Packer::Main::Functions::Header::

View File

@ -117,9 +117,26 @@ pPlatformWindow *pWindowGet();
// ::Platform::FileSystem::Functions::Header:: // ::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); b32 pDirNavigate(c8 *dir);
c8 **pDirGetFileNames(Arena *arena, u32 *count); 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:: // ::Platform::Profiling::Functions::Header::

View File

@ -25,6 +25,7 @@
#include <dirent.h> #include <dirent.h>
#include <x86intrin.h> #include <x86intrin.h>
#include <sys/time.h> #include <sys/time.h>
#include <fcntl.h>
// ::Platform::Linux::Defines::Header:: // ::Platform::Linux::Defines::Header::
@ -52,6 +53,8 @@
// ::Platform::Linux::Types::Header // ::Platform::Linux::Types::Header
typedef int pFile;
typedef struct pThread typedef struct pThread
{ {
pthread_t handle; pthread_t handle;
@ -79,6 +82,8 @@ typedef struct pFunction
void *fn; void *fn;
} pFunction; } pFunction;
typedef int pFile;
// ::Platform::Linux::Print::Functions::Header:: // ::Platform::Linux::Print::Functions::Header::
i32 pWrite(int fd, void const *str, isize count); i32 pWrite(int fd, void const *str, isize count);

View File

@ -225,13 +225,66 @@ b32 pWindowShouldQuit()
// ::Platform::Functions::Directory::Start:: // ::Platform::FileSystem::Functions::Start::
b32 pDirNavigate(c8 *dir) b32 pDirNavigate(c8 *dir)
{ {
return chdir(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) c8 **pDirGetFileNames(Arena *arena, u32 *count)
{ {
struct dirent *dir; struct dirent *dir;
@ -269,18 +322,19 @@ c8 **pDirGetFileNames(Arena *arena, u32 *count)
return (c8 **)file_names; 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; struct dirent *dir;
DIR *d = opendir("."); DIR *d = opendir(".");
u8 type = is_dir ? DT_DIR : DT_REG;
if (d) if (d)
{ {
while ((dir = readdir(d)) != NULL) 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; found = true;
break; break;
@ -291,7 +345,28 @@ static b8 pDirIsVisible(c8 *dir_name)
return found; 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::

View File

@ -22,10 +22,11 @@ typedef struct rShaderGlobals rShaderGlobals;
typedef enum Pipeline_e typedef enum Pipeline_e
{ {
R_PIPELINE_CUBE, rPIPELINE_CUBE,
R_PIPELINE_GUI, rPIPELINE_GUI,
rPIPELINE_PBR,
R_PIPELINE_MAX, rPIPELINE_MAX,
} rPipelineHandle; } rPipelineHandle;
typedef enum PipelineType_e typedef enum PipelineType_e
@ -72,6 +73,12 @@ typedef struct rUIVertex
u32 tex_idx; u32 tex_idx;
} rUIVertex; } rUIVertex;
typedef struct rPBRVertex
{
Vec4 pos;
Vec4 col;
} rPBRVertex;
typedef struct rUploadQueue typedef struct rUploadQueue
{ {
union union

View File

@ -1534,12 +1534,9 @@ static b32 vPipelinesInit()
VkResult result; VkResult result;
VkDevice device = v_Renderer.handles.device; VkDevice device = v_Renderer.handles.device;
Asset quad_vert_shader = apLoadShader(QUAD_VERT_SPIRV_SHADER); /*
Asset quad_frag_shader = apLoadShader(QUAD_FRAG_SPIRV_SHADER); * SHARED
*/
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);
VkPipelineRenderingCreateInfo pipeline_render_info = { VkPipelineRenderingCreateInfo pipeline_render_info = {
.sType = STYPE(PIPELINE_RENDERING_CREATE_INFO), .sType = STYPE(PIPELINE_RENDERING_CREATE_INFO),
@ -1548,6 +1545,17 @@ static b32 vPipelinesInit()
.depthAttachmentFormat = v_Renderer.images.depth.image.format, .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[] = { VkPipelineShaderStageCreateInfo cube_shader_stages[] = {
{ {
.sType = STYPE(PIPELINE_SHADER_STAGE_CREATE_INFO), .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.layout = v_Renderer.handles.pipeline_layout;
cube_create_info.pNext = &pipeline_render_info; 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) if (result != VK_SUCCESS)
{ {
Printf("vkCreateGraphicsPipelines failure: %s", vVkResultStr(result)); Printf("vkCreateGraphicsPipelines failure: %s", vVkResultStr(result));
@ -1581,6 +1589,10 @@ static b32 vPipelinesInit()
apUnloadShader(QUAD_VERT_SPIRV_SHADER); apUnloadShader(QUAD_VERT_SPIRV_SHADER);
apUnloadShader(QUAD_FRAG_SPIRV_SHADER); apUnloadShader(QUAD_FRAG_SPIRV_SHADER);
/*
* GUI PIPELINE START
*/
Asset gui_vert_shader = apLoadShader(GUI_VERT_SPIRV_SHADER); Asset gui_vert_shader = apLoadShader(GUI_VERT_SPIRV_SHADER);
Asset gui_frag_shader = apLoadShader(GUI_FRAG_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.layout = v_Renderer.handles.pipeline_layout;
gui_create_info.pNext = &pipeline_render_info; 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) if (result != VK_SUCCESS)
{ {
Printfln("vkCreateGraphicsPipelines failure: %s", vVkResultStr(result)); Printfln("vkCreateGraphicsPipelines failure: %s", vVkResultStr(result));
@ -1621,6 +1633,50 @@ static b32 vPipelinesInit()
apUnloadShader(GUI_VERT_SPIRV_SHADER); apUnloadShader(GUI_VERT_SPIRV_SHADER);
apUnloadShader(GUI_FRAG_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; return success;
} }

View File

@ -312,7 +312,7 @@ typedef struct vRHandles
VkSwapchainKHR swapchain; VkSwapchainKHR swapchain;
VmaAllocator vma_alloc; VmaAllocator vma_alloc;
VkDescriptorPool desc_pool; VkDescriptorPool desc_pool;
VkPipeline pipelines[R_PIPELINE_MAX]; VkPipeline pipelines[rPIPELINE_MAX];
VkPipelineLayout pipeline_layout; VkPipelineLayout pipeline_layout;
VkDescriptorSetLayout desc_layouts[vDT_MAX]; VkDescriptorSetLayout desc_layouts[vDT_MAX];
VkDescriptorSet desc_sets[vDT_MAX]; VkDescriptorSet desc_sets[vDT_MAX];

View File

@ -53,7 +53,7 @@ void rDestroy()
vkDestroySampler(device, nearest_sampler, NULL); 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); vkDestroyPipeline(device, pipelines[i], NULL);
vkDestroyPipelineLayout(device, pipeline_layout, NULL); vkDestroyPipelineLayout(device, pipeline_layout, NULL);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -451,8 +451,41 @@ VkPipelineInputAssemblyStateCreateInfo gui_assembly_info = {
.primitiveRestartEnable = VK_FALSE, .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() static void vCustomizePipelines()
{ {
// GUI
gui_create_info.pVertexInputState = &gui_vertex_input_info; gui_create_info.pVertexInputState = &gui_vertex_input_info;
gui_create_info.pInputAssemblyState = &gui_assembly_info; gui_create_info.pInputAssemblyState = &gui_assembly_info;
// PBR
pbr_create_info.pVertexInputState = &pbr_vertex_input_info;
pbr_create_info.pInputAssemblyState = &pbr_assembly_info;
} }