minecraft: load per-world data

This commit is contained in:
Zack Buhman 2026-04-29 22:20:24 -05:00
parent 759006dd2f
commit 8102ad7870
6 changed files with 97 additions and 23 deletions

View File

@ -0,0 +1,23 @@
static const short index_buffer_configuration_offsets[] = {
0, 0, 6, 12, 24, 30, 42, 54,
72, 78, 90, 102, 120, 132, 150, 168,
192, 198, 210, 222, 240, 252, 270, 288,
312, 324, 342, 360, 384, 402, 426, 450,
480, 486, 498, 510, 528, 540, 558, 576,
600, 612, 630, 648, 672, 690, 714, 738,
768, 780, 798, 816, 840, 858, 882, 906,
936, 954, 978, 1002, 1032, 1056, 1086, 1116,
};
// generated from
static const struct {
short offset;
short count;
} index_buffer_custom_offsets[] = {
{1152, 3180}, // candle.obj
{4332, 1584}, // custom_mushroom.obj
{5916, 36}, // fence.obj
{5952, 24}, // slab.obj
{5976, 24}, // stair.obj
{6000, 12}, // tall_grass.obj
{6012, 2082}, // wall_torch.obj
};

View File

@ -2,7 +2,9 @@
#include "volk/volk.h"
namespace minecraft {
#include "minecraft/vulkan/per_world.h"
namespace minecraft::vulkan {
struct vulkan {
struct {
@ -31,11 +33,14 @@ namespace minecraft {
VkShaderModule shaderModule;
VkPipeline pipeline;
per_world * worlds;
void init();
void load_vertex_index_buffer(char const * vertex_filename,
char const * index_filename);
void load_shader();
void create_pipeline();
void draw();
void load_worlds();
void draw(VkCommandBuffer commandBuffer);
};
}

View File

@ -0,0 +1,27 @@
#pragma once
#include "minecraft/world.h"
namespace minecraft::vulkan {
struct region {
VkBuffer vertexBuffer;
world::instance_cfg_entry * instanceCFG;
};
struct per_world {
world::descriptor const * descriptor;
region * regions; // malloc region_count
VkDeviceMemory regionVertexMemory;
entry_table::global_entry_t * entry_table;
int entry_table_length;
void load_regions(VkDevice device,
VkPhysicalDeviceProperties const & physicalDeviceProperties,
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
world::descriptor const * const descriptor);
void load(VkDevice device,
VkPhysicalDeviceProperties const & physicalDeviceProperties,
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
world::descriptor const * const descriptor);
};
}

View File

@ -26,28 +26,14 @@ namespace minecraft::world {
};
// also update index_buffer_custom_offsets in include/minecraft_data.inc
const int custom_block_types = 7;
const int instance_cfg_length = 64 + custom_block_types;
constexpr int custom_block_types = 7;
constexpr int instance_cfg_length = 64 + custom_block_types;
struct instance_cfg_entry {
int count;
int offset;
};
struct region {
unsigned int per_instance_vertex_buffer;
instance_cfg_entry instance_cfg[instance_cfg_length];
};
struct state {
world::descriptor const * descriptor;
world::region * region; // malloc region_count
entry_table::global_entry_t * entry_table;
unsigned int light_uniform_buffer;
int light_count;
int entry_table_length;
};
extern descriptor const descriptors[];
extern int const descriptors_length;
}

6
include/popcount.h Normal file
View File

@ -0,0 +1,6 @@
#pragma once
#ifdef _MSC_VER
#include <intrin.h>
#define __builtin_popcount __popcnt
#endif

View File

@ -7,10 +7,18 @@
#include "file.h"
#include "check.h"
#include "vulkan_helper.h"
#include "new.h"
#include "popcount.h"
#include "minecraft/vulkan.h"
#include "minecraft/data.inc"
namespace minecraft {
namespace minecraft::vulkan {
static inline int popcount(int x)
{
return __builtin_popcount(x);
}
void vulkan::init()
{
@ -253,19 +261,19 @@ namespace minecraft {
.format = VK_FORMAT_R16_SINT,
.offset = 8,
},
{ // block id
{ // data
.location = 5,
.binding = 1,
.format = VK_FORMAT_R16_SINT,
.offset = 10,
},
{ // block id
{ // texture id
.location = 6,
.binding = 1,
.format = VK_FORMAT_R16_SINT,
.offset = 12,
},
{ // block id
{ // special
.location = 7,
.binding = 1,
.format = VK_FORMAT_R16_SINT,
@ -302,12 +310,31 @@ namespace minecraft {
VK_CHECK(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, pipelineCreateInfos, nullptr, &pipeline));
}
//////////////////////////////////////////////////////////////////////
// load worlds
//////////////////////////////////////////////////////////////////////
void vulkan::load_worlds()
{
worlds = NewM<per_world>(minecraft::world::descriptors_length);
for (int i = 0; i < minecraft::world::descriptors_length; i++) {
worlds[i].load(device, physicalDeviceProperties, physicalDeviceMemoryProperties, &minecraft::world::descriptors[i]);
}
}
//////////////////////////////////////////////////////////////////////
// draw
//////////////////////////////////////////////////////////////////////
void vulkan::draw()
void vulkan::draw(VkCommandBuffer commandBuffer)
{
vkCmdBindIndexBuffer(commandBuffer, vertexIndex.buffer, vertexIndex.indexOffset, VK_INDEX_TYPE_UINT16);
for (int configuration = 1; configuration < 64; configuration++) {
int element_count = 6 * popcount(configuration);
int index_offset = 2 * index_buffer_configuration_offsets[configuration];
int instance_count = worlds[;
};
}
}