starting work on being able to load assets into vulkan

This commit is contained in:
matthew 2025-07-14 08:29:22 +10:00
parent 82df45e488
commit 0e03058714
4 changed files with 273 additions and 75 deletions

View File

@ -4,6 +4,13 @@ import aliases;
import core.memory; import core.memory;
import p = platform; import p = platform;
import r = renderer; import r = renderer;
import util;
import core.simd;
struct Floats
{
f32 r = 0.0, g = 0.0, b = 0.0, a = 0.0;
}
void main() void main()
{ {

View File

@ -2,13 +2,15 @@ import aliases;
import includes; import includes;
import assets; import assets;
import util; import util;
import ap = assets; import alloc;
import vk = vulkan; import vulkan;
import vulkan : Destroy, Init, Draw, DrawIndexed, Bind, BindUIBuffers, BeginRender, SetUniform, PrepCompute, Dispatch, FinishFrame, BeginFrame;
import assets;
import u = util; import u = util;
import p = platform; import p = platform;
alias Shader = VkShaderModule; alias Shader = VkShaderModule;
alias Pipeline = vk.PipelineHandle; alias Pipeline = PipelineHandle;
alias Attribute = VkVertexInputAttributeDescription; alias Attribute = VkVertexInputAttributeDescription;
alias Buffer = VkBuffer; alias Buffer = VkBuffer;
@ -20,7 +22,7 @@ enum InputRate : int
alias IR = InputRate; alias IR = InputRate;
enum Format: VkFormat enum Format : VkFormat
{ {
UINT = VK_FORMAT_R32_UINT, UINT = VK_FORMAT_R32_UINT,
R_F32 = VK_FORMAT_R32_SFLOAT, R_F32 = VK_FORMAT_R32_SFLOAT,
@ -62,7 +64,10 @@ struct GfxPipelineInfo
struct Renderer struct Renderer
{ {
vk.Vulkan vulkan; Arena arena;
Arena temp_arena;
Vulkan vk;
p.Window* window; p.Window* window;
GlobalUniforms globals; GlobalUniforms globals;
@ -113,19 +118,29 @@ struct Model
Buffer vertex_buffer; Buffer vertex_buffer;
Buffer index_buffer; Buffer index_buffer;
MeshPart[] parts; MeshPart[] parts;
string name;
Buffer[] materials;
u32[] m_indices;
ImageView[] textures;
u32[] t_indices;
} }
Renderer Renderer
Init(p.Window* window) Init(p.Window* window)
{ {
u.Result!(vk.Vulkan) vk_result = vk.Init(window, u.MB(24), u.MB(32)); u.Result!(Vulkan) vk_result = Init(window, u.MB(24), u.MB(32));
assert(vk_result.ok, "Init failure: Unable to initialize Vulkan"); assert(vk_result.ok, "Init failure: Unable to initialize Vulkan");
Renderer rd = { Renderer rd = {
vulkan: vk_result.value, arena: CreateArena(u.MB(16)),
temp_arena: CreateArena(u.MB(16)),
vk: vk_result.value,
window: window, window: window,
ui_vertex_buf: vk.GetUIVertexBuffer(&vk_result.value), ui_vertex_buf: GetUIVertexBuffer(&vk_result.value),
ui_index_buf: vk.GetUIIndexBuffer(&vk_result.value), ui_index_buf: GetUIIndexBuffer(&vk_result.value),
}; };
GfxPipelineInfo triangle_info = { GfxPipelineInfo triangle_info = {
@ -156,40 +171,112 @@ Init(p.Window* window)
bool bool
Cycle(Renderer* rd) Cycle(Renderer* rd)
{ {
bool success = vk.BeginFrame(&rd.vulkan);
rd.ui_count = 0; rd.ui_count = 0;
bool success = BeginFrame(rd);
if (success) if (success)
{ {
vk.Bind(&rd.vulkan, rd.compute_pipeline); Bind(rd, &rd.compute_pipeline);
vk.SetUniform(&rd.vulkan, &rd.globals); SetUniform(rd, &rd.globals);
DrawRect(rd, 150.0, 300.0, 200.0, 350.0, Vec4(r: 0.0, g: 0.0, b: 1.0, a: 1.0)); DrawRect(rd, 150.0, 300.0, 500.0, 700.0, Vec4(r: 0.0, g: 0.0, b: 1.0, a: 1.0));
vk.PrepCompute(&rd.vulkan); PrepCompute(rd);
vk.Dispatch(&rd.vulkan); Dispatch(rd);
vk.BeginRender(&rd.vulkan); BeginRender(rd);
vk.Bind(&rd.vulkan, rd.ui_pipeline); Bind(rd, &rd.ui_pipeline);
vk.BindUIBuffers(&rd.vulkan); BindUIBuffers(rd);
vk.DrawIndexed(&rd.vulkan, 6, rd.ui_count); DrawIndexed(rd, 6, rd.ui_count);
vk.Bind(&rd.vulkan, rd.triangle_pipeline); Bind(rd, &rd.triangle_pipeline);
vk.Draw(&rd.vulkan, 3, 1); Draw(rd, 3, 1);
success = vk.FinishFrame(&rd.vulkan); success = FinishFrame(rd);
} }
return success; return success;
} }
Model
LoadModel(Renderer* rd, string name)
{
Model model = {
name: name,
};
u8[] data = LoadAssetData(&rd.temp_arena, name);
m3d_t* m3d = m3d_load(data.ptr, null, null, null);
return model;
}
bool
BeginFrame(Renderer* rd)
{
return BeginFrame(&rd.vk);
}
bool
FinishFrame(Renderer* rd)
{
return FinishFrame(&rd.vk);
}
void
Dispatch(Renderer* rd)
{
Dispatch(&rd.vk);
}
void
PrepCompute(Renderer* rd)
{
PrepCompute(&rd.vk);
}
void
SetUniform(Renderer* rd, GlobalUniforms* uniforms)
{
SetUniform(&rd.vk, uniforms);
}
void
BeginRender(Renderer* rd)
{
BeginRender(&rd.vk);
}
void
BindUIBuffers(Renderer* rd)
{
BindUIBuffers(&rd.vk);
}
void
DrawIndexed(Renderer* rd, u32 index_count, u32 instance_count)
{
DrawIndexed(&rd.vk, index_count, instance_count);
}
void
Draw(Renderer* rd, u32 index_count, u32 instance_count)
{
Draw(&rd.vk, index_count, instance_count);
}
void Bind(Renderer* rd, Pipeline* pipeline)
{
Bind(&rd.vk, pipeline);
}
void void
DrawRect(Renderer* rd, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, Vec4 col) DrawRect(Renderer* rd, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, Vec4 col)
{ {
@ -214,21 +301,21 @@ DrawRect(Renderer* rd, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, Vec4 col)
Pipeline Pipeline
BuildGfxPipeline(Renderer* rd, GfxPipelineInfo* info) BuildGfxPipeline(Renderer* rd, GfxPipelineInfo* info)
{ {
return vk.CreateGraphicsPipeline(&rd.vulkan, info); return CreateGraphicsPipeline(&rd.vk, info);
} }
Pipeline Pipeline
BuildCompPipeline(Renderer* rd, string compute) BuildCompPipeline(Renderer* rd, string compute)
{ {
return vk.CreateComputePipeline(&rd.vulkan, compute); return CreateComputePipeline(&rd.vk, compute);
} }
void void
Destroy(Renderer* rd) Destroy(Renderer* rd)
{ {
vk.Destroy(&rd.vulkan, rd.triangle_pipeline); Destroy(&rd.vk, rd.triangle_pipeline);
vk.Destroy(&rd.vulkan, rd.compute_pipeline); Destroy(&rd.vk, rd.compute_pipeline);
vk.Destroy(&rd.vulkan); Destroy(&rd.vk);
} }

View File

@ -6,7 +6,7 @@ import std.algorithm.comparison;
import core.stdc.string : strcmp; import core.stdc.string : strcmp;
import std.format : sformat; import std.format : sformat;
import u = util : HashTable, Result, Logf, Log, MB; import u = util : HashTable, Result, Logf, Log, MB;
import a = alloc; import alloc;
import p = platform; import p = platform;
import ap = assets; import ap = assets;
import renderer; import renderer;
@ -134,8 +134,8 @@ struct DescBindings
struct Vulkan struct Vulkan
{ {
a.Arena arena; Arena arena;
a.Arena[FRAME_OVERLAP] frame_arenas; Arena[FRAME_OVERLAP] frame_arenas;
u32 frame_index; u32 frame_index;
u32 semaphore_index; u32 semaphore_index;
@ -212,10 +212,10 @@ Init(p.Window* window, u64 permanent_mem, u64 frame_mem)
bool success = true; bool success = true;
Vulkan vk = { Vulkan vk = {
arena: a.CreateArena(permanent_mem), arena: CreateArena(permanent_mem),
frame_arenas: [ frame_arenas: [
a.CreateArena(frame_mem), CreateArena(frame_mem),
a.CreateArena(frame_mem), CreateArena(frame_mem),
], ],
window: window, window: window,
}; };
@ -604,9 +604,82 @@ ImmSubmit(Vulkan* vk, void delegate() fn)
return success; return success;
} }
void bool
TransferAssets(Vulkan* vk)
{
return true;
}
ImageView
CreateImageView(Vulkan* vk, u32 w, u32 h, u32 ch)
{
VmaAllocationCreateInfo alloc_info = {
usage: VMA_MEMORY_USAGE_GPU_ONLY,
requiredFlags: VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
};
VkImageCreateInfo image_info = {
sType: VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
imageType: VK_IMAGE_TYPE_2D,
mipLevels: 1,
arrayLayers: 1,
format: VK_FORMAT_R8G8B8A8_SRGB,
tiling: VK_IMAGE_TILING_OPTIMAL,
initialLayout: VK_IMAGE_LAYOUT_UNDEFINED,
usage: VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
samples: VK_SAMPLE_COUNT_1_BIT,
extent: {
width: w,
height: h,
depth: 1,
},
};
if (vk.gfx_index != vk.tfer_index)
{
image_info.sharingMode = VK_SHARING_MODE_CONCURRENT;
image_info.queueFamilyIndexCount = 2;
image_info.pQueueFamilyIndices = cast(const u32*)[vk.gfx_index, vk.tfer_index];
}
ImageView view = {
format: VK_IMAGE_LAYOUT_UNDEFINED,
};
VkResult result = vmaCreateImage(vk.vma, &image_info, &alloc_info, &view.image, *view.alloc, null);
// TODO: handle errors and realloc
assert(VkCheck("CreateImageView failure: vmaCreateImage error", result), "CreateImageView failure");
VkImageViewCreateInfo view_info = {
sType: VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
image: view.image,
viewType: VK_IMAGE_VIEW_TYPE_2D,
format: VK_FORMAT_R8G8B8A8_SRGB,
subresourceRange: {
aspectMask: VK_IMAGE_ASPECT_COLOR_BIT,
levelCount: 1,
layerCount: 1,
},
};
result = vkCreateImageView(vk.device, &view_info, null, &view.view);
// TODO: also handle here
assert(VkCheck("CreateImageView failure: vkCreateImageView error", result), "CreateImageView failure");
return view;
}
u32
Push(Vulkan* vk, ImageView* view)
{
}
bool
Transfer(Vulkan* vk, Buffer* buf, u8[] data) Transfer(Vulkan* vk, Buffer* buf, u8[] data)
{ {
bool success = true;
u64 copied = 0; u64 copied = 0;
while(copied != data.length) while(copied != data.length)
{ {
@ -627,15 +700,19 @@ Transfer(Vulkan* vk, Buffer* buf, u8[] data)
vkCmdCopyBuffer(vk.imm_cmd, vk.transfer_buf.buffer, buf.buffer, 1, &copy); vkCmdCopyBuffer(vk.imm_cmd, vk.transfer_buf.buffer, buf.buffer, 1, &copy);
}; };
ImmSubmit(vk, fn); success = ImmSubmit(vk, fn);
copied += copy_length; copied += copy_length;
} }
return success;
} }
void bool
Transfer(Vulkan* vk, Image* image, u8[] data, u32 w, u32 h) Transfer(Vulkan* vk, Image* image, u8[] data, u32 w, u32 h)
{ {
bool success = true;
u64 copied = 0; u64 copied = 0;
while(copied != data.length) while(copied != data.length)
{ {
@ -669,10 +746,12 @@ Transfer(Vulkan* vk, Image* image, u8[] data, u32 w, u32 h)
Transition(vk.imm_cmd, image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); Transition(vk.imm_cmd, image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
}; };
ImmSubmit(vk, fn); success = ImmSubmit(vk, fn);
copied += copy_length; copied += copy_length;
} }
return success;
} }
pragma(inline): void pragma(inline): void
@ -717,7 +796,7 @@ Copy(VkCommandBuffer cmd, VkImage src, VkImage dst, VkExtent2D src_ext, VkExtent
} }
void void
Bind(Vulkan* vk, PipelineHandle pipeline) Bind(Vulkan* vk, PipelineHandle* pipeline)
{ {
vkCmdBindPipeline(vk.cmds[vk.frame_index], pipeline.type, pipeline.handle); vkCmdBindPipeline(vk.cmds[vk.frame_index], pipeline.type, pipeline.handle);
@ -907,14 +986,10 @@ CreateGraphicsPipeline(Vulkan* vk, GfxPipelineInfo* build_info)
}, },
]; ];
u8[] vert_bytes = ap.LoadAssetData(build_info.vertex_shader); Arena* arena = &vk.frame_arenas[0];
u8[] frag_bytes = ap.LoadAssetData(build_info.frag_shader);
scope(exit) u8[] vert_bytes = ap.LoadAssetData(arena, build_info.vertex_shader);
{ u8[] frag_bytes = ap.LoadAssetData(arena, build_info.frag_shader);
ap.UnloadAssetData(build_info.vertex_shader);
ap.UnloadAssetData(build_info.frag_shader);
}
assert(vert_bytes && frag_bytes, "Unable to load shaders"); assert(vert_bytes && frag_bytes, "Unable to load shaders");
@ -969,9 +1044,8 @@ CreateComputePipeline(Vulkan* vk, string shader)
}, },
}; };
u8[] comp_bytes = ap.LoadAssetData(shader); u8[] comp_bytes = ap.LoadAssetData(&vk.frame_arenas[0], shader);
assert(comp_bytes != null, "Unable to load compute shader data"); assert(comp_bytes != null, "Unable to load compute shader data");
scope(exit) ap.UnloadAssetData(shader);
Result!(Shader) comp_module = BuildShader(vk, comp_bytes); Result!(Shader) comp_module = BuildShader(vk, comp_bytes);
assert(comp_module.ok, "Unable to build compute shader"); assert(comp_module.ok, "Unable to build compute shader");
@ -1221,7 +1295,7 @@ InitDescriptors(Vulkan* vk)
vk.desc_bindings[i].lookup_table = u.CreateHashTable!(string, u32)(8); vk.desc_bindings[i].lookup_table = u.CreateHashTable!(string, u32)(8);
u32 DESC_MAX_BINDINGS = 512; u32 DESC_MAX_BINDINGS = 512;
vk.desc_bindings[i].free = a.AllocArray!(u32)(&vk.arena, DESC_MAX_BINDINGS); vk.desc_bindings[i].free = AllocArray!(u32)(&vk.arena, DESC_MAX_BINDINGS);
u32 free_count = 0; u32 free_count = 0;
for(i32 j = DESC_MAX_BINDINGS-1; j >= 0; j -= 1) for(i32 j = DESC_MAX_BINDINGS-1; j >= 0; j -= 1)
@ -1323,7 +1397,7 @@ InitFrameStructures(Vulkan* vk)
Push(vk, SI.FrameStructures); Push(vk, SI.FrameStructures);
bool success = true; bool success = true;
a.Arena* arena = &vk.frame_arenas[0]; Arena* arena = &vk.frame_arenas[0];
VkSemaphoreCreateInfo sem_info = { sType: VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; VkSemaphoreCreateInfo sem_info = { sType: VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
@ -1344,7 +1418,7 @@ InitFrameStructures(Vulkan* vk)
}; };
u32 sem_count = cast(u32)vk.present_images.length; u32 sem_count = cast(u32)vk.present_images.length;
vk.submit_sems = a.AllocArray!(VkSemaphore)(arena, sem_count); vk.submit_sems = AllocArray!(VkSemaphore)(arena, sem_count);
foreach(i; 0 .. sem_count) foreach(i; 0 .. sem_count)
{ {
@ -1537,16 +1611,16 @@ CreateDrawImages(Vulkan* vk)
void void
SelectSwapchainFormats(Vulkan* vk) SelectSwapchainFormats(Vulkan* vk)
{ {
a.Arena* arena = &vk.frame_arenas[0]; Arena* arena = &vk.frame_arenas[0];
u32 format_count; u32 format_count;
vkGetPhysicalDeviceSurfaceFormatsKHR(vk.physical_device, vk.surface, &format_count, null); vkGetPhysicalDeviceSurfaceFormatsKHR(vk.physical_device, vk.surface, &format_count, null);
VkSurfaceFormatKHR[] formats = a.AllocArray!(VkSurfaceFormatKHR)(arena, format_count); VkSurfaceFormatKHR[] formats = AllocArray!(VkSurfaceFormatKHR)(arena, format_count);
vkGetPhysicalDeviceSurfaceFormatsKHR(vk.physical_device, vk.surface, &format_count, formats.ptr); vkGetPhysicalDeviceSurfaceFormatsKHR(vk.physical_device, vk.surface, &format_count, formats.ptr);
u32 mode_count; u32 mode_count;
vkGetPhysicalDeviceSurfacePresentModesKHR(vk.physical_device, vk.surface, &mode_count, null); vkGetPhysicalDeviceSurfacePresentModesKHR(vk.physical_device, vk.surface, &mode_count, null);
VkPresentModeKHR[] modes = a.AllocArray!(VkPresentModeKHR)(arena, mode_count); VkPresentModeKHR[] modes = AllocArray!(VkPresentModeKHR)(arena, mode_count);
vkGetPhysicalDeviceSurfacePresentModesKHR(vk.physical_device, vk.surface, &mode_count, modes.ptr); vkGetPhysicalDeviceSurfacePresentModesKHR(vk.physical_device, vk.surface, &mode_count, modes.ptr);
VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR; VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR;
@ -1569,7 +1643,7 @@ CreateSwapchain(Vulkan* vk)
Push(vk, SI.Swapchain); Push(vk, SI.Swapchain);
bool success = true; bool success = true;
a.Arena* arena = &vk.frame_arenas[0]; Arena* arena = &vk.frame_arenas[0];
VkSurfaceCapabilitiesKHR cap; VkSurfaceCapabilitiesKHR cap;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vk.physical_device, vk.surface, &cap); vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vk.physical_device, vk.surface, &cap);
@ -1604,11 +1678,11 @@ CreateSwapchain(Vulkan* vk)
u32 count; u32 count;
vkGetSwapchainImagesKHR(vk.device, vk.swapchain, &count, null); vkGetSwapchainImagesKHR(vk.device, vk.swapchain, &count, null);
VkImage[] images = a.AllocArray!(VkImage)(arena, count); VkImage[] images = AllocArray!(VkImage)(arena, count);
vkGetSwapchainImagesKHR(vk.device, vk.swapchain, &count, images.ptr); vkGetSwapchainImagesKHR(vk.device, vk.swapchain, &count, images.ptr);
VkImageView[] views = a.AllocArray!(VkImageView)(arena, count); VkImageView[] views = AllocArray!(VkImageView)(arena, count);
vk.present_images = a.AllocArray!(ImageView)(&vk.arena, count); vk.present_images = AllocArray!(ImageView)(&vk.arena, count);
VkImageViewCreateInfo view_info = { VkImageViewCreateInfo view_info = {
sType: VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, sType: VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
@ -1693,11 +1767,11 @@ InitDevice(Vulkan* vk)
Push(vk, SI.Device); Push(vk, SI.Device);
bool success = false; bool success = false;
a.Arena* arena = &vk.frame_arenas[0]; Arena* arena = &vk.frame_arenas[0];
u32 count; u32 count;
vkEnumeratePhysicalDevices(vk.instance, &count, null); vkEnumeratePhysicalDevices(vk.instance, &count, null);
VkPhysicalDevice[] devices = a.AllocArray!(VkPhysicalDevice)(arena, count); VkPhysicalDevice[] devices = AllocArray!(VkPhysicalDevice)(arena, count);
vkEnumeratePhysicalDevices(vk.instance, &count, devices.ptr); vkEnumeratePhysicalDevices(vk.instance, &count, devices.ptr);
VkPhysicalDevice physical_device = null; VkPhysicalDevice physical_device = null;
@ -1882,7 +1956,7 @@ CheckDeviceFeatures(VkPhysicalDevice device)
} }
bool bool
CheckDeviceProperties(a.Arena *arena, VkPhysicalDevice device, VkSurfaceKHR surface, b32* discrete) CheckDeviceProperties(Arena *arena, VkPhysicalDevice device, VkSurfaceKHR surface, b32* discrete)
{ {
bool success = false; bool success = false;
@ -1893,7 +1967,7 @@ CheckDeviceProperties(a.Arena *arena, VkPhysicalDevice device, VkSurfaceKHR surf
{ {
u32 ext_count; u32 ext_count;
vkEnumerateDeviceExtensionProperties(device, null, &ext_count, null); vkEnumerateDeviceExtensionProperties(device, null, &ext_count, null);
VkExtensionProperties[] ext_props = a.AllocArray!(VkExtensionProperties)(arena, ext_count); VkExtensionProperties[] ext_props = AllocArray!(VkExtensionProperties)(arena, ext_count);
vkEnumerateDeviceExtensionProperties(device, null, &ext_count, ext_props.ptr); vkEnumerateDeviceExtensionProperties(device, null, &ext_count, ext_props.ptr);
i32 matched = 0; i32 matched = 0;
@ -1924,7 +1998,7 @@ CheckDeviceProperties(a.Arena *arena, VkPhysicalDevice device, VkSurfaceKHR surf
} }
QueueInfo QueueInfo
CheckQueueProperties(a.Arena *arena, VkPhysicalDevice device, VkSurfaceKHR surface) CheckQueueProperties(Arena *arena, VkPhysicalDevice device, VkSurfaceKHR surface)
{ {
const u32 T_BIT = VK_QUEUE_TRANSFER_BIT; const u32 T_BIT = VK_QUEUE_TRANSFER_BIT;
const u32 C_BIT = VK_QUEUE_COMPUTE_BIT; const u32 C_BIT = VK_QUEUE_COMPUTE_BIT;
@ -1939,7 +2013,7 @@ CheckQueueProperties(a.Arena *arena, VkPhysicalDevice device, VkSurfaceKHR surfa
u32 count; u32 count;
vkGetPhysicalDeviceQueueFamilyProperties(device, &count, null); vkGetPhysicalDeviceQueueFamilyProperties(device, &count, null);
VkQueueFamilyProperties[] properties = a.AllocArray!(VkQueueFamilyProperties)(arena, count); VkQueueFamilyProperties[] properties = AllocArray!(VkQueueFamilyProperties)(arena, count);
vkGetPhysicalDeviceQueueFamilyProperties(device, &count, properties.ptr); vkGetPhysicalDeviceQueueFamilyProperties(device, &count, properties.ptr);
if (count == 1 && properties[0].queueCount == 1 && u.BitEq(properties[0].queueFlags, T_BIT | C_BIT | G_BIT)) if (count == 1 && properties[0].queueCount == 1 && u.BitEq(properties[0].queueFlags, T_BIT | C_BIT | G_BIT))
@ -2002,7 +2076,7 @@ CheckQueueProperties(a.Arena *arena, VkPhysicalDevice device, VkSurfaceKHR surfa
pragma(inline): void pragma(inline): void
Push(Vulkan* vk, StepInitialized step) Push(Vulkan* vk, StepInitialized step)
{ {
u.Node!(SI)* node = a.Alloc!(u.Node!(SI)); u.Node!(SI)* node = Alloc!(u.Node!(SI));
node.value = step; node.value = step;
u.PushFront(&vk.cleanup_list, node, null); u.PushFront(&vk.cleanup_list, node, null);
} }
@ -2012,10 +2086,10 @@ DestroyRenderer(Vulkan* vk)
{ {
foreach(i, arena; vk.frame_arenas) foreach(i, arena; vk.frame_arenas)
{ {
a.Free(vk.frame_arenas.ptr + i); Free(vk.frame_arenas.ptr + i);
} }
a.Free(&vk.arena); Free(&vk.arena);
} }
void void
@ -2187,11 +2261,11 @@ InitInstance(Vulkan* vk)
Push(vk, SI.Instance); Push(vk, SI.Instance);
bool success = true; bool success = true;
a.Arena* arena = &vk.frame_arenas[0]; Arena* arena = &vk.frame_arenas[0];
u32 count; u32 count;
vkEnumerateInstanceLayerProperties(&count, null); vkEnumerateInstanceLayerProperties(&count, null);
VkLayerProperties[] layers = a.AllocArray!(VkLayerProperties)(arena, count); VkLayerProperties[] layers = AllocArray!(VkLayerProperties)(arena, count);
vkEnumerateInstanceLayerProperties(&count, layers.ptr); vkEnumerateInstanceLayerProperties(&count, layers.ptr);
foreach(i, layer; layers) foreach(i, layer; layers)

View File

@ -103,13 +103,43 @@ OpenAssetPack()
} }
} }
u8[] pragma(inline): void
LoadAssetData(string name) CheckAssetPack()
{ {
if (!Asset_Pack_Opened) if (!Asset_Pack_Opened)
{ {
OpenAssetPack(); OpenAssetPack();
} }
}
u8[]
LoadAssetData(Arena* arena, string name)
{
CheckAssetPack();
u64 hash = Hash(name);
u8[] data = null;
foreach(i, info; Asset_Info)
{
if (info.hash == hash)
{
data = AllocArray!(u8)(arena, info.length);
Asset_File.seek(info.offset);
Asset_File.rawRead(data);
assert(data != null && data.length == info.length, "LoadAssetData failure: Asset data loaded incorrectly");
break;
}
}
return data;
}
u8[]
LoadAssetData(string name)
{
CheckAssetPack();
u64 hash = Hash(name); u64 hash = Hash(name);
u8[] data = null; u8[] data = null;