load files from .pack file
This commit is contained in:
parent
cad2532e04
commit
70fea48b38
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@
|
||||
*.spv
|
||||
*.o
|
||||
main
|
||||
*.pack
|
||||
40
Makefile
40
Makefile
@ -1,6 +1,7 @@
|
||||
CC=$(PREFIX)gcc
|
||||
CXX=$(PREFIX)g++
|
||||
OBJCOPY=$(PREFIX)objcopy
|
||||
AS=$(PREFIX)as
|
||||
|
||||
OBJARCH = elf64-x86-64
|
||||
|
||||
@ -30,44 +31,24 @@ endif
|
||||
|
||||
OBJS = \
|
||||
src/main.o \
|
||||
src/volk/volk.o
|
||||
|
||||
BINS = \
|
||||
index.idx.o \
|
||||
position_normal_texture.vtx.o \
|
||||
sprite.data.o
|
||||
|
||||
SHADERS = \
|
||||
shader/triangle.vs.spv.o \
|
||||
shader/triangle.ps.spv.o
|
||||
src/volk/volk.o \
|
||||
src/file.o \
|
||||
src/pack.o
|
||||
|
||||
LIBS = \
|
||||
../SDL3-dist/lib64/libSDL3.a
|
||||
|
||||
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
|
||||
$(CC) $(ARCH) $(CSTD) $(CFLAGS) $(FLAGS) $(OPT) $(DEBUG) -c $< -o $@
|
||||
|
||||
%.o: %.cpp
|
||||
$(CXX) $(ARCH) $(CXXSTD) $(CFLAGS) $(FLAGS) $(OPT) $(DEBUG) -c $< -o $@
|
||||
|
||||
%.o: %.s
|
||||
$(AS) $< -o $@
|
||||
|
||||
main: $(OBJS) $(LIBS) $(BINS) $(SHADERS)
|
||||
$(CC) $(ARCH) $(LDFLAGS) $(FLAGS) $(OPT) $(DEBUG) $^ -o $@
|
||||
|
||||
@ -77,6 +58,13 @@ main: $(OBJS) $(LIBS) $(BINS) $(SHADERS)
|
||||
%.ps.spv: %.hlsl
|
||||
../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:
|
||||
.INTERMEDIATE:
|
||||
.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 "new.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)
|
||||
#include "file.h"
|
||||
|
||||
#define SDL_CHECK(f) \
|
||||
{ \
|
||||
@ -512,8 +485,13 @@ int main()
|
||||
// mesh
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
VkDeviceSize vtxBufferSize{ vtx_size };
|
||||
VkDeviceSize idxBufferSize{ idx_size };
|
||||
uint32_t vertexSize;
|
||||
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{
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.size = vtxBufferSize + idxBufferSize,
|
||||
@ -538,8 +516,8 @@ int main()
|
||||
|
||||
void * 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) + vtx_size), idx_start, idx_size);
|
||||
memcpy((void *)(((ptrdiff_t)vertexIndexMappedData) + 0), vertexStart, vertexSize);
|
||||
memcpy((void *)(((ptrdiff_t)vertexIndexMappedData) + vertexSize), indexStart, indexSize);
|
||||
vkUnmapMemory(device, vertexIndexBufferMemory);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -673,10 +651,13 @@ int main()
|
||||
|
||||
// texture transfer: source buffer
|
||||
|
||||
uint32_t spriteSize;
|
||||
void const * spriteStart = file::open("sprite.data", &spriteSize);
|
||||
|
||||
VkBuffer textureSourceBuffer{};
|
||||
VkBufferCreateInfo textureSourceBufferCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.size = sprite_size,
|
||||
.size = spriteSize,
|
||||
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
|
||||
};
|
||||
VK_CHECK(vkCreateBuffer(device, &textureSourceBufferCreateInfo, nullptr, &textureSourceBuffer));
|
||||
@ -697,7 +678,7 @@ int main()
|
||||
|
||||
void * 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);
|
||||
|
||||
VkFenceCreateInfo textureFenceCreateInfo{
|
||||
@ -872,18 +853,23 @@ int main()
|
||||
// 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{
|
||||
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
||||
.codeSize = vs_size,
|
||||
.pCode = (uint32_t *)vs_start
|
||||
.codeSize = triangleVSSize,
|
||||
.pCode = (uint32_t *)triangleVSStart
|
||||
};
|
||||
VkShaderModule vertexShaderModule{};
|
||||
VK_CHECK(vkCreateShaderModule(device, &vertexShaderModuleCreateInfo, nullptr, &vertexShaderModule));
|
||||
|
||||
VkShaderModuleCreateInfo pixelShaderModuleCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
||||
.codeSize = ps_size,
|
||||
.pCode = (uint32_t *)ps_start
|
||||
.codeSize = trianglePSSize,
|
||||
.pCode = (uint32_t *)trianglePSStart
|
||||
};
|
||||
VkShaderModule 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