load files from .pack file
This commit is contained in:
parent
cad2532e04
commit
70fea48b38
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,4 +1,5 @@
|
|||||||
.gdb_history
|
.gdb_history
|
||||||
*.spv
|
*.spv
|
||||||
*.o
|
*.o
|
||||||
main
|
main
|
||||||
|
*.pack
|
||||||
40
Makefile
40
Makefile
@ -1,6 +1,7 @@
|
|||||||
CC=$(PREFIX)gcc
|
CC=$(PREFIX)gcc
|
||||||
CXX=$(PREFIX)g++
|
CXX=$(PREFIX)g++
|
||||||
OBJCOPY=$(PREFIX)objcopy
|
OBJCOPY=$(PREFIX)objcopy
|
||||||
|
AS=$(PREFIX)as
|
||||||
|
|
||||||
OBJARCH = elf64-x86-64
|
OBJARCH = elf64-x86-64
|
||||||
|
|
||||||
@ -30,44 +31,24 @@ endif
|
|||||||
|
|
||||||
OBJS = \
|
OBJS = \
|
||||||
src/main.o \
|
src/main.o \
|
||||||
src/volk/volk.o
|
src/volk/volk.o \
|
||||||
|
src/file.o \
|
||||||
BINS = \
|
src/pack.o
|
||||||
index.idx.o \
|
|
||||||
position_normal_texture.vtx.o \
|
|
||||||
sprite.data.o
|
|
||||||
|
|
||||||
SHADERS = \
|
|
||||||
shader/triangle.vs.spv.o \
|
|
||||||
shader/triangle.ps.spv.o
|
|
||||||
|
|
||||||
LIBS = \
|
LIBS = \
|
||||||
../SDL3-dist/lib64/libSDL3.a
|
../SDL3-dist/lib64/libSDL3.a
|
||||||
|
|
||||||
all: main
|
all: main
|
||||||
|
|
||||||
define BUILD_BINARY_O
|
|
||||||
$(OBJCOPY) -I binary -O $(OBJARCH) $< $@
|
|
||||||
endef
|
|
||||||
|
|
||||||
%.vtx.o: %.vtx
|
|
||||||
$(BUILD_BINARY_O)
|
|
||||||
|
|
||||||
%.idx.o: %.idx
|
|
||||||
$(BUILD_BINARY_O)
|
|
||||||
|
|
||||||
%.spv.o: %.spv
|
|
||||||
$(BUILD_BINARY_O)
|
|
||||||
|
|
||||||
%.data.o: %.data
|
|
||||||
$(BUILD_BINARY_O)
|
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) $(ARCH) $(CSTD) $(CFLAGS) $(FLAGS) $(OPT) $(DEBUG) -c $< -o $@
|
$(CC) $(ARCH) $(CSTD) $(CFLAGS) $(FLAGS) $(OPT) $(DEBUG) -c $< -o $@
|
||||||
|
|
||||||
%.o: %.cpp
|
%.o: %.cpp
|
||||||
$(CXX) $(ARCH) $(CXXSTD) $(CFLAGS) $(FLAGS) $(OPT) $(DEBUG) -c $< -o $@
|
$(CXX) $(ARCH) $(CXXSTD) $(CFLAGS) $(FLAGS) $(OPT) $(DEBUG) -c $< -o $@
|
||||||
|
|
||||||
|
%.o: %.s
|
||||||
|
$(AS) $< -o $@
|
||||||
|
|
||||||
main: $(OBJS) $(LIBS) $(BINS) $(SHADERS)
|
main: $(OBJS) $(LIBS) $(BINS) $(SHADERS)
|
||||||
$(CC) $(ARCH) $(LDFLAGS) $(FLAGS) $(OPT) $(DEBUG) $^ -o $@
|
$(CC) $(ARCH) $(LDFLAGS) $(FLAGS) $(OPT) $(DEBUG) $^ -o $@
|
||||||
|
|
||||||
@ -77,6 +58,13 @@ main: $(OBJS) $(LIBS) $(BINS) $(SHADERS)
|
|||||||
%.ps.spv: %.hlsl
|
%.ps.spv: %.hlsl
|
||||||
../dxc/bin/dxc -spirv -T ps_6_1 -E PSMain -fspv-target-env=vulkan1.3 $< -Fo $@
|
../dxc/bin/dxc -spirv -T ps_6_1 -E PSMain -fspv-target-env=vulkan1.3 $< -Fo $@
|
||||||
|
|
||||||
|
tool/pack_file: tool/pack_file.cpp
|
||||||
|
make -C tool pack_file
|
||||||
|
|
||||||
|
PACK_FILENAMES = $(shell cat filenames.txt)
|
||||||
|
files.pack: tool/pack_file $(PACK_FILENAMES) filenames.txt
|
||||||
|
./tool/pack_file $@ $(PACK_FILENAMES)
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
.INTERMEDIATE:
|
.INTERMEDIATE:
|
||||||
.SECONDARY:
|
.SECONDARY:
|
||||||
|
|||||||
5
filenames.txt
Normal file
5
filenames.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
shader/triangle.vs.spv
|
||||||
|
shader/triangle.ps.spv
|
||||||
|
index.idx
|
||||||
|
position_normal_texture.vtx
|
||||||
|
sprite.data
|
||||||
5
include/file.h
Normal file
5
include/file.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace file {
|
||||||
|
void const * open(const char * r_filename, uint32_t * out_size);
|
||||||
|
}
|
||||||
19
include/pack.h
Normal file
19
include/pack.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace pack {
|
||||||
|
struct file_entry {
|
||||||
|
char filename[128];
|
||||||
|
uint32_t offset;
|
||||||
|
uint32_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct header {
|
||||||
|
uint32_t magic;
|
||||||
|
uint32_t header_size;
|
||||||
|
uint32_t entry_count;
|
||||||
|
file_entry entry[0];
|
||||||
|
};
|
||||||
|
static_assert((sizeof (header)) == 12);
|
||||||
|
|
||||||
|
const uint32_t magic_value = 0x037c2dc0;
|
||||||
|
}
|
||||||
39
src/file.cpp
Normal file
39
src/file.cpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "pack.h"
|
||||||
|
#include "file.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
extern uint8_t const _files_pack_start[];
|
||||||
|
extern uint8_t const _files_pack_end[];
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace file {
|
||||||
|
|
||||||
|
void const * open(const char * r_filename, uint32_t * out_size)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "(pack) filename: %s\n", r_filename);
|
||||||
|
|
||||||
|
pack::header const * header = (pack::header const *)&_files_pack_start[0];
|
||||||
|
if (header->magic != pack::magic_value) {
|
||||||
|
fprintf(stderr, "invalid header magic: %08x expected magic value: %08x\n", header->magic, pack::magic_value);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
ptrdiff_t data = (ptrdiff_t)&_files_pack_start[header->header_size];
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < header->entry_count; i++) {
|
||||||
|
if (strcmp(header->entry[i].filename, r_filename) == 0) {
|
||||||
|
*out_size = header->entry[i].size;
|
||||||
|
return (void const *)(data + header->entry[i].offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "filename not found in pack file %s\n", r_filename);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
62
src/main.cpp
62
src/main.cpp
@ -8,34 +8,7 @@
|
|||||||
#include "directxmath/directxmath.h"
|
#include "directxmath/directxmath.h"
|
||||||
|
|
||||||
#include "new.h"
|
#include "new.h"
|
||||||
|
#include "file.h"
|
||||||
extern "C" {
|
|
||||||
extern uint8_t const _binary_position_normal_texture_vtx_start[];
|
|
||||||
extern void * const _binary_position_normal_texture_vtx_size;
|
|
||||||
extern uint8_t const _binary_index_idx_start[];
|
|
||||||
extern void * const _binary_index_idx_size;
|
|
||||||
|
|
||||||
extern uint8_t const _binary_shader_triangle_vs_spv_start[];
|
|
||||||
extern void * const _binary_shader_triangle_vs_spv_size;
|
|
||||||
extern uint8_t const _binary_shader_triangle_ps_spv_start[];
|
|
||||||
extern void * const _binary_shader_triangle_ps_spv_size;
|
|
||||||
|
|
||||||
extern uint8_t const _binary_sprite_data_start[];
|
|
||||||
extern void * const _binary_sprite_data_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define vtx_start _binary_position_normal_texture_vtx_start
|
|
||||||
#define vtx_size (size_t)(&_binary_position_normal_texture_vtx_size)
|
|
||||||
#define idx_start _binary_index_idx_start
|
|
||||||
#define idx_size (size_t)(&_binary_index_idx_size)
|
|
||||||
|
|
||||||
#define vs_start _binary_shader_triangle_vs_spv_start
|
|
||||||
#define vs_size (size_t)(&_binary_shader_triangle_vs_spv_size)
|
|
||||||
#define ps_start _binary_shader_triangle_ps_spv_start
|
|
||||||
#define ps_size (size_t)(&_binary_shader_triangle_ps_spv_size)
|
|
||||||
|
|
||||||
#define sprite_start _binary_sprite_data_start
|
|
||||||
#define sprite_size (size_t)(&_binary_sprite_data_size)
|
|
||||||
|
|
||||||
#define SDL_CHECK(f) \
|
#define SDL_CHECK(f) \
|
||||||
{ \
|
{ \
|
||||||
@ -512,8 +485,13 @@ int main()
|
|||||||
// mesh
|
// mesh
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
VkDeviceSize vtxBufferSize{ vtx_size };
|
uint32_t vertexSize;
|
||||||
VkDeviceSize idxBufferSize{ idx_size };
|
void const * vertexStart = file::open("position_normal_texture.vtx", &vertexSize);
|
||||||
|
uint32_t indexSize;
|
||||||
|
void const * indexStart = file::open("index.idx", &indexSize);
|
||||||
|
|
||||||
|
VkDeviceSize vtxBufferSize{ vertexSize };
|
||||||
|
VkDeviceSize idxBufferSize{ indexSize };
|
||||||
VkBufferCreateInfo vertexIndexBufferCreateInfo{
|
VkBufferCreateInfo vertexIndexBufferCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||||
.size = vtxBufferSize + idxBufferSize,
|
.size = vtxBufferSize + idxBufferSize,
|
||||||
@ -538,8 +516,8 @@ int main()
|
|||||||
|
|
||||||
void * vertexIndexMappedData;
|
void * vertexIndexMappedData;
|
||||||
VK_CHECK(vkMapMemory(device, vertexIndexBufferMemory, 0, vertexIndexBufferCreateInfo.size, 0, &vertexIndexMappedData));
|
VK_CHECK(vkMapMemory(device, vertexIndexBufferMemory, 0, vertexIndexBufferCreateInfo.size, 0, &vertexIndexMappedData));
|
||||||
memcpy((void *)(((ptrdiff_t)vertexIndexMappedData) + 0), vtx_start, vtx_size);
|
memcpy((void *)(((ptrdiff_t)vertexIndexMappedData) + 0), vertexStart, vertexSize);
|
||||||
memcpy((void *)(((ptrdiff_t)vertexIndexMappedData) + vtx_size), idx_start, idx_size);
|
memcpy((void *)(((ptrdiff_t)vertexIndexMappedData) + vertexSize), indexStart, indexSize);
|
||||||
vkUnmapMemory(device, vertexIndexBufferMemory);
|
vkUnmapMemory(device, vertexIndexBufferMemory);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@ -673,10 +651,13 @@ int main()
|
|||||||
|
|
||||||
// texture transfer: source buffer
|
// texture transfer: source buffer
|
||||||
|
|
||||||
|
uint32_t spriteSize;
|
||||||
|
void const * spriteStart = file::open("sprite.data", &spriteSize);
|
||||||
|
|
||||||
VkBuffer textureSourceBuffer{};
|
VkBuffer textureSourceBuffer{};
|
||||||
VkBufferCreateInfo textureSourceBufferCreateInfo{
|
VkBufferCreateInfo textureSourceBufferCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||||
.size = sprite_size,
|
.size = spriteSize,
|
||||||
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
|
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
|
||||||
};
|
};
|
||||||
VK_CHECK(vkCreateBuffer(device, &textureSourceBufferCreateInfo, nullptr, &textureSourceBuffer));
|
VK_CHECK(vkCreateBuffer(device, &textureSourceBufferCreateInfo, nullptr, &textureSourceBuffer));
|
||||||
@ -697,7 +678,7 @@ int main()
|
|||||||
|
|
||||||
void * textureSourceMappedData;
|
void * textureSourceMappedData;
|
||||||
VK_CHECK(vkMapMemory(device, textureSourceBufferMemory, 0, textureSourceBufferCreateInfo.size, 0, &textureSourceMappedData));
|
VK_CHECK(vkMapMemory(device, textureSourceBufferMemory, 0, textureSourceBufferCreateInfo.size, 0, &textureSourceMappedData));
|
||||||
memcpy((void *)(((ptrdiff_t)textureSourceMappedData) + 0), sprite_start, sprite_size);
|
memcpy((void *)(((ptrdiff_t)textureSourceMappedData) + 0), spriteStart, spriteSize);
|
||||||
vkUnmapMemory(device, textureSourceBufferMemory);
|
vkUnmapMemory(device, textureSourceBufferMemory);
|
||||||
|
|
||||||
VkFenceCreateInfo textureFenceCreateInfo{
|
VkFenceCreateInfo textureFenceCreateInfo{
|
||||||
@ -872,18 +853,23 @@ int main()
|
|||||||
// shaders
|
// shaders
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
uint32_t triangleVSSize;
|
||||||
|
void const * triangleVSStart = file::open("shader/triangle.vs.spv", &triangleVSSize);
|
||||||
|
uint32_t trianglePSSize;
|
||||||
|
void const * trianglePSStart = file::open("shader/triangle.ps.spv", &trianglePSSize);
|
||||||
|
|
||||||
VkShaderModuleCreateInfo vertexShaderModuleCreateInfo{
|
VkShaderModuleCreateInfo vertexShaderModuleCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
||||||
.codeSize = vs_size,
|
.codeSize = triangleVSSize,
|
||||||
.pCode = (uint32_t *)vs_start
|
.pCode = (uint32_t *)triangleVSStart
|
||||||
};
|
};
|
||||||
VkShaderModule vertexShaderModule{};
|
VkShaderModule vertexShaderModule{};
|
||||||
VK_CHECK(vkCreateShaderModule(device, &vertexShaderModuleCreateInfo, nullptr, &vertexShaderModule));
|
VK_CHECK(vkCreateShaderModule(device, &vertexShaderModuleCreateInfo, nullptr, &vertexShaderModule));
|
||||||
|
|
||||||
VkShaderModuleCreateInfo pixelShaderModuleCreateInfo{
|
VkShaderModuleCreateInfo pixelShaderModuleCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
||||||
.codeSize = ps_size,
|
.codeSize = trianglePSSize,
|
||||||
.pCode = (uint32_t *)ps_start
|
.pCode = (uint32_t *)trianglePSStart
|
||||||
};
|
};
|
||||||
VkShaderModule pixelShaderModule{};
|
VkShaderModule pixelShaderModule{};
|
||||||
VK_CHECK(vkCreateShaderModule(device, &pixelShaderModuleCreateInfo, nullptr, &pixelShaderModule));
|
VK_CHECK(vkCreateShaderModule(device, &pixelShaderModuleCreateInfo, nullptr, &pixelShaderModule));
|
||||||
|
|||||||
5
src/pack.s
Normal file
5
src/pack.s
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.global _files_pack_start
|
||||||
|
.global _files_pack_end
|
||||||
|
_files_pack_start:
|
||||||
|
.incbin "files.pack"
|
||||||
|
_files_pack_end:
|
||||||
5
tool/Makefile
Normal file
5
tool/Makefile
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
OPT = -O2
|
||||||
|
CFLAGS = -I../include
|
||||||
|
|
||||||
|
pack_file: pack_file.cpp
|
||||||
|
g++ -o $@ $(OPT) $(CFLAGS) $^
|
||||||
112
tool/pack_file.cpp
Normal file
112
tool/pack_file.cpp
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "pack.h"
|
||||||
|
|
||||||
|
static uint8_t copy_buffer[1024 * 1024];
|
||||||
|
static int const copy_buffer_size = (sizeof (copy_buffer));
|
||||||
|
|
||||||
|
void copy_file(FILE * output, FILE * input, size_t size)
|
||||||
|
{
|
||||||
|
size_t written = 0;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
size_t read_size = fread(copy_buffer, 1, copy_buffer_size, input);
|
||||||
|
if (read_size == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
size_t write_size = fwrite(copy_buffer, 1, read_size, output);
|
||||||
|
assert(write_size == read_size);
|
||||||
|
|
||||||
|
written += write_size;
|
||||||
|
|
||||||
|
if (read_size < copy_buffer_size)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(written == size);
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE * file_size(const char * filename, uint32_t * out_size)
|
||||||
|
{
|
||||||
|
FILE * f = fopen(filename, "rb");
|
||||||
|
if (f == nullptr) {
|
||||||
|
fprintf(stderr, "fopen(%s): %s\n", filename, strerror(errno));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fseek_end_ret = fseek(f, 0, SEEK_END);
|
||||||
|
if (fseek_end_ret < 0) {
|
||||||
|
fprintf(stderr, "fseek(%s, SEEK_END): %s\n", filename, strerror(errno));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
long size = ftell(f);
|
||||||
|
if (size < 0) {
|
||||||
|
fprintf(stderr, "ftell(%s): %s\n", filename, strerror(errno));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fseek_set_ret = fseek(f, 0, SEEK_SET);
|
||||||
|
if (fseek_set_ret < 0) {
|
||||||
|
fprintf(stderr, "fseek(%s, SEEK_SET): %s\n", filename, strerror(errno));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_size = size;
|
||||||
|
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char const * argv[])
|
||||||
|
{
|
||||||
|
assert(argc >= 3);
|
||||||
|
|
||||||
|
int files_count = argc - 2;
|
||||||
|
char const * output_filename = argv[1];
|
||||||
|
char const * const * filenames = &argv[2];
|
||||||
|
FILE * files[files_count];
|
||||||
|
|
||||||
|
int header_size = (sizeof (pack::header)) + (sizeof (pack::file_entry)) * files_count;
|
||||||
|
pack::header * header = (pack::header *)malloc(header_size);
|
||||||
|
memset(header, 0, header_size);
|
||||||
|
|
||||||
|
header->magic = pack::magic_value;
|
||||||
|
header->header_size = header_size;
|
||||||
|
header->entry_count = files_count;
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < files_count; i++) {
|
||||||
|
char const * filename = filenames[i];
|
||||||
|
uint32_t size;
|
||||||
|
FILE * file = file_size(filename, &size);
|
||||||
|
assert(file != nullptr);
|
||||||
|
files[i] = file;
|
||||||
|
int filename_length = strlen(filename);
|
||||||
|
assert(filename_length <= 127);
|
||||||
|
memcpy(header->entry[i].filename, filename, filename_length);
|
||||||
|
header->entry[i].offset = offset;
|
||||||
|
header->entry[i].size = size;
|
||||||
|
offset += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE * fout = fopen(output_filename, "wb");
|
||||||
|
if (fout == nullptr) {
|
||||||
|
fprintf(stderr, "fopen(%s): %s\n", output_filename, strerror(errno));
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite((void *)header, 1, header_size, fout);
|
||||||
|
|
||||||
|
for (int i = 0; i < files_count; i++) {
|
||||||
|
copy_file(fout, files[i], header->entry[i].size);
|
||||||
|
int fclose_ret = fclose(files[i]);
|
||||||
|
assert(fclose_ret == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fclose_ret = fclose(fout);
|
||||||
|
assert(fclose_ret == 0);
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user