triangle drawn
This commit is contained in:
parent
9c5ad29f78
commit
42bef67206
3
dub.json
3
dub.json
@ -13,7 +13,7 @@
|
||||
"sourcePaths": ["src/gears", "src/shared", "src/generated", "external/xxhash"],
|
||||
"libs-linux": ["xcb", "X11", "X11-xcb", "vulkan", "stdc++"],
|
||||
"libs-windows": [],
|
||||
"preGenerateCommands-linux": ["./build-vma.sh", "build/Codegen", "dub main:packer", "build/Packer"],
|
||||
"preGenerateCommands-linux": ["./build-vma.sh", "build/Codegen", "dub main:packer"],
|
||||
"preGenerateCommands-windows": [],
|
||||
"dflags-dmd": ["-P=-DSTBI_NO_SIMD"]
|
||||
},
|
||||
@ -26,6 +26,7 @@
|
||||
"sourcePaths": ["src/packer", "src/shared", "src/generated", "external/xxhash"],
|
||||
"sourceFiles-linux": ["build/libstb_image.a", "build/libm3d.a"],
|
||||
"preGenerateCommands-linux": ["./build-vma.sh"],
|
||||
"postGenerateCommands-linux": ["build/Packer"],
|
||||
"preGenerateCommands-windows": [],
|
||||
"dflags-dmd": ["-P=-DSTBI_NO_SIMD"],
|
||||
},
|
||||
|
||||
@ -2,54 +2,19 @@ public import includes;
|
||||
import std.stdio;
|
||||
import aliases;
|
||||
import core.memory;
|
||||
import u = util : Result;
|
||||
import p = platform;
|
||||
import a = alloc;
|
||||
import vk = vulkan : Vulkan;
|
||||
import ap = assets;
|
||||
import r = renderer;
|
||||
|
||||
void main()
|
||||
{
|
||||
p.Window window = p.CreateWindow("Video Game", 1920, 1080);
|
||||
|
||||
assert(ap.OpenAssetPack(), "OpenAssetPack failure");
|
||||
r.Renderer rd = r.Init(&window);
|
||||
scope(exit) r.Destroy(&rd);
|
||||
|
||||
Result!(Vulkan) result = vk.Init(&window, u.MB(24), u.MB(32));
|
||||
Vulkan vulkan = result.value;
|
||||
|
||||
u8[] vert_bytes = ap.LoadAssetData("shaders/triangle.vert");
|
||||
u8[] frag_bytes = ap.LoadAssetData("shaders/triangle.frag");
|
||||
|
||||
assert(vert_bytes != null && frag_bytes != null, "Unable to load shader data");
|
||||
|
||||
auto vert_module = vk.BuildShader(&vulkan, vert_bytes);
|
||||
auto frag_module = vk.BuildShader(&vulkan, frag_bytes);
|
||||
|
||||
assert(vert_module.ok && frag_module.ok, "Unable to build vulkan shaders");
|
||||
|
||||
r.GfxPipelineInfo pipeline_info = {
|
||||
vertex_shader: vert_module.value,
|
||||
frag_shader: frag_module.value,
|
||||
};
|
||||
|
||||
auto pipeline = vk.CreateGraphicsPipeline(&vulkan, &pipeline_info);
|
||||
|
||||
u8[] comp_bytes = ap.LoadAssetData("shaders/gradient.comp");
|
||||
assert(comp_bytes != null, "Unable to load compute shader data");
|
||||
|
||||
auto comp_module = vk.BuildShader(&vulkan, comp_bytes);
|
||||
assert(comp_module.ok, "Unable to build compute shader");
|
||||
|
||||
auto comp_pipeline = vk.CreateComputePipeline(&vulkan, comp_module.value);
|
||||
|
||||
vk.Destroy(&vulkan, comp_module.value);
|
||||
vk.Destroy(&vulkan, comp_pipeline);
|
||||
|
||||
vk.Destroy(&vulkan, vert_module.value);
|
||||
vk.Destroy(&vulkan, frag_module.value);
|
||||
vk.Destroy(&vulkan, pipeline);
|
||||
|
||||
vk.Destroy(&vulkan);
|
||||
while (true)
|
||||
{
|
||||
r.Cycle(&rd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,8 +1,14 @@
|
||||
import aliases;
|
||||
import includes;
|
||||
import assets;
|
||||
import util;
|
||||
import ap = assets;
|
||||
import vk = vulkan;
|
||||
import u = util;
|
||||
import p = platform;
|
||||
|
||||
alias Shader = VkShaderModule;
|
||||
alias Pipeline = VkPipeline;
|
||||
alias Pipeline = vk.PipelineHandle;
|
||||
alias Attribute = VkVertexInputAttributeDescription;
|
||||
|
||||
enum InputRate : int
|
||||
@ -20,6 +26,14 @@ enum Format: int
|
||||
RGBA_F32 = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
}
|
||||
|
||||
enum PipelineType : int
|
||||
{
|
||||
Graphics,
|
||||
Compute,
|
||||
}
|
||||
|
||||
alias PT = PipelineType;
|
||||
|
||||
struct GfxPipelineInfo
|
||||
{
|
||||
Shader vertex_shader;
|
||||
@ -29,4 +43,99 @@ struct GfxPipelineInfo
|
||||
Attribute[] vertex_attributes;
|
||||
}
|
||||
|
||||
struct Renderer
|
||||
{
|
||||
vk.Vulkan vulkan;
|
||||
p.Window* window;
|
||||
Pipeline triangle_pipeline;
|
||||
Pipeline compute_pipeline;
|
||||
}
|
||||
|
||||
Renderer
|
||||
Init(p.Window* window)
|
||||
{
|
||||
u.Result!(vk.Vulkan) vk_result = vk.Init(window, u.MB(24), u.MB(32));
|
||||
assert(vk_result.ok, "Init failure: Unable to initialize Vulkan");
|
||||
|
||||
Renderer rd = {
|
||||
vulkan: vk_result.value,
|
||||
window: window,
|
||||
};
|
||||
|
||||
rd.triangle_pipeline = BuildGfxPipeline(&rd, "shaders/triangle.vert", "shaders/triangle.frag");
|
||||
rd.compute_pipeline = BuildCompPipeline(&rd, "shaders/gradient.comp");
|
||||
|
||||
return rd;
|
||||
}
|
||||
|
||||
bool
|
||||
Cycle(Renderer* rd)
|
||||
{
|
||||
bool success = vk.BeginFrame(&rd.vulkan);
|
||||
|
||||
if (success)
|
||||
{
|
||||
vk.Bind(&rd.vulkan, rd.triangle_pipeline);
|
||||
|
||||
vk.Draw(&rd.vulkan, 3, 1);
|
||||
|
||||
success = vk.FinishFrame(&rd.vulkan);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
Pipeline
|
||||
BuildGfxPipeline(Renderer* rd, string vertex, string fragment)
|
||||
{
|
||||
u8[] vert_bytes = ap.LoadAssetData(vertex);
|
||||
u8[] frag_bytes = ap.LoadAssetData(fragment);
|
||||
|
||||
scope(exit)
|
||||
{
|
||||
ap.UnloadAssetData(vertex);
|
||||
ap.UnloadAssetData(fragment);
|
||||
}
|
||||
|
||||
assert(vert_bytes && frag_bytes, "Unable to load shaders");
|
||||
|
||||
Result!(Shader) vert_module = vk.BuildShader(&rd.vulkan, vert_bytes);
|
||||
Result!(Shader) frag_module = vk.BuildShader(&rd.vulkan, frag_bytes);
|
||||
|
||||
assert(vert_module.ok && frag_module.ok, "Unable to build vulkan shaders");
|
||||
|
||||
scope(exit)
|
||||
{
|
||||
vk.Destroy(&rd.vulkan, vert_module.value);
|
||||
vk.Destroy(&rd.vulkan, frag_module.value);
|
||||
}
|
||||
|
||||
GfxPipelineInfo pipeline_info = {
|
||||
vertex_shader: vert_module.value,
|
||||
frag_shader: frag_module.value,
|
||||
};
|
||||
|
||||
return vk.CreateGraphicsPipeline(&rd.vulkan, &pipeline_info);
|
||||
}
|
||||
|
||||
Pipeline
|
||||
BuildCompPipeline(Renderer* rd, string compute)
|
||||
{
|
||||
u8[] comp_bytes = ap.LoadAssetData(compute);
|
||||
assert(comp_bytes != null, "Unable to load compute shader data");
|
||||
scope(exit) ap.UnloadAssetData(compute);
|
||||
|
||||
Result!(Shader) comp_module = vk.BuildShader(&rd.vulkan, comp_bytes);
|
||||
assert(comp_module.ok, "Unable to build compute shader");
|
||||
scope(exit) vk.Destroy(&rd.vulkan, comp_module.value);
|
||||
|
||||
return vk.CreateComputePipeline(&rd.vulkan, comp_module.value);
|
||||
}
|
||||
|
||||
void
|
||||
Destroy(Renderer* rd)
|
||||
{
|
||||
vk.Destroy(&rd.vulkan, rd.triangle_pipeline);
|
||||
vk.Destroy(&rd.vulkan, rd.compute_pipeline);
|
||||
vk.Destroy(&rd.vulkan);
|
||||
}
|
||||
|
||||
@ -119,6 +119,8 @@ struct Vulkan
|
||||
a.Arena arena;
|
||||
a.Arena[FRAME_OVERLAP] frame_arenas;
|
||||
|
||||
u64 frame_no;
|
||||
|
||||
u.SLList!(SI) cleanup_list;
|
||||
|
||||
p.Window* window;
|
||||
@ -136,6 +138,8 @@ struct Vulkan
|
||||
VkExtent3D swapchain_extent;
|
||||
|
||||
ImageView[] present_images;
|
||||
u32 image_index;
|
||||
|
||||
ImageView draw_image;
|
||||
ImageView depth_image;
|
||||
|
||||
@ -162,6 +166,12 @@ struct Vulkan
|
||||
QueueInfo queues;
|
||||
}
|
||||
|
||||
struct PipelineHandle
|
||||
{
|
||||
VkPipeline handle;
|
||||
VkPipelineBindPoint type;
|
||||
}
|
||||
|
||||
struct QueueInfo
|
||||
{
|
||||
i32 gfx_index, tfer_index;
|
||||
@ -211,6 +221,338 @@ Init(p.Window* window, u64 permanent_mem, u64 frame_mem)
|
||||
return result;
|
||||
}
|
||||
|
||||
u64
|
||||
FrameIndex(Vulkan* vk)
|
||||
{
|
||||
return vk.frame_no % FRAME_OVERLAP;
|
||||
}
|
||||
|
||||
u64
|
||||
SemIndex(Vulkan* vk)
|
||||
{
|
||||
return vk.frame_no % vk.present_images.length;
|
||||
}
|
||||
|
||||
VkImage
|
||||
CurrentImage(Vulkan* vk)
|
||||
{
|
||||
return vk.present_images[vk.image_index].base.image;
|
||||
}
|
||||
|
||||
bool
|
||||
BeginFrame(Vulkan* vk)
|
||||
{
|
||||
u64 index = FrameIndex(vk);
|
||||
u64 sem_index = SemIndex(vk);
|
||||
|
||||
// TODO: move vkWaitForFences so it no longer holds up the frame, will need to change how fences are handled in regards to images though
|
||||
VkResult result = vkWaitForFences(vk.device, 1, vk.render_fences.ptr + index, VK_TRUE, 1000000000);
|
||||
bool success = VkCheck("BeginFrame failure: vkWaitForFences error", result);
|
||||
|
||||
if (success)
|
||||
{
|
||||
result = vkResetFences(vk.device, 1, vk.render_fences.ptr + index);
|
||||
success = VkCheck("BeginFrame failure: vkResetFences error", result);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
result = vkAcquireNextImageKHR(vk.device, vk.swapchain, 1000000000, vk.swapchain_sems[sem_index], null, &vk.image_index);
|
||||
if (result == VK_ERROR_OUT_OF_DATE_KHR)
|
||||
{
|
||||
RecreateSwapchain(vk);
|
||||
}
|
||||
else
|
||||
{
|
||||
success = VkCheck("BeginFrame failure: vkAcquireNextImageKHR error", result);
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
result = vkResetCommandBuffer(vk.cmds[index], 0);
|
||||
success = VkCheck("BeginFrame failure: vkResetCommandBuffer failure", result);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
VkCommandBufferBeginInfo cmd_info = {
|
||||
sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
flags: VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
||||
};
|
||||
|
||||
result = vkBeginCommandBuffer(vk.cmds[index], &cmd_info);
|
||||
success = VkCheck("BeginFrame failure: vkBeginCommandBuffer error", result);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
Transition(vk.cmds[index], &vk.draw_image.base, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
Transition(vk.cmds[index], &vk.depth_image.base, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL);
|
||||
|
||||
VkImage image = CurrentImage(vk);
|
||||
Transition(vk.cmds[index], image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
f32[4] clear_col;
|
||||
clear_col[] = 0.2;
|
||||
|
||||
VkRenderingAttachmentInfo col_attach = {
|
||||
sType: VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
imageView: vk.draw_image.view,
|
||||
imageLayout: vk.draw_image.base.layout,
|
||||
loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
storeOp: VK_ATTACHMENT_STORE_OP_STORE,
|
||||
clearValue: { color: { clear_col } },
|
||||
};
|
||||
|
||||
VkRenderingAttachmentInfo depth_attach = {
|
||||
sType: VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
imageView: vk.depth_image.view,
|
||||
imageLayout: vk.depth_image.base.layout,
|
||||
loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
storeOp: VK_ATTACHMENT_STORE_OP_STORE,
|
||||
};
|
||||
|
||||
VkRenderingInfo render_info = {
|
||||
sType: VK_STRUCTURE_TYPE_RENDERING_INFO,
|
||||
layerCount: 1,
|
||||
colorAttachmentCount: 1,
|
||||
pColorAttachments: &col_attach,
|
||||
pDepthAttachment: &depth_attach,
|
||||
renderArea: {
|
||||
extent: {
|
||||
width: vk.swapchain_extent.width,
|
||||
height: vk.swapchain_extent.height,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
vkCmdBeginRendering(vk.cmds[index], &render_info);
|
||||
vkCmdBindDescriptorSets(
|
||||
vk.cmds[index],
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
vk.pipeline_layout,
|
||||
0,
|
||||
cast(u32)vk.desc_sets.length,
|
||||
vk.desc_sets.ptr,
|
||||
0,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool
|
||||
FinishFrame(Vulkan* vk)
|
||||
{
|
||||
scope(exit) vk.frame_no += 1;
|
||||
|
||||
bool success = true;
|
||||
|
||||
u64 index = FrameIndex(vk);
|
||||
u64 sem_index = SemIndex(vk);
|
||||
VkImage image = CurrentImage(vk);
|
||||
|
||||
vkCmdEndRendering(vk.cmds[index]);
|
||||
|
||||
Transition(vk.cmds[index], &vk.draw_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
|
||||
VkExtent2D extent = {
|
||||
width: vk.swapchain_extent.width,
|
||||
height: vk.swapchain_extent.height,
|
||||
};
|
||||
|
||||
// TODO: Find out how to copy from same dimension images
|
||||
Copy(vk.cmds[index], vk.draw_image.base.image, image, extent, extent);
|
||||
|
||||
Transition(vk.cmds[index], image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||
|
||||
VkResult result = vkEndCommandBuffer(vk.cmds[index]);
|
||||
success = VkCheck("FinishFrame failure: vkEndCommandBuffer error", result);
|
||||
|
||||
if (success)
|
||||
{
|
||||
VkCommandBufferSubmitInfo cmd_info = {
|
||||
sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO,
|
||||
commandBuffer: vk.cmds[index],
|
||||
};
|
||||
|
||||
VkSemaphoreSubmitInfo wait_info = {
|
||||
sType: VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
|
||||
semaphore: vk.swapchain_sems[sem_index],
|
||||
stageMask: VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
value: 1,
|
||||
};
|
||||
|
||||
VkSemaphoreSubmitInfo signal_info = {
|
||||
sType: VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
|
||||
semaphore: vk.render_sems[index],
|
||||
stageMask: VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT,
|
||||
value: 1,
|
||||
};
|
||||
|
||||
VkSubmitInfo2 submit_info = {
|
||||
sType: VK_STRUCTURE_TYPE_SUBMIT_INFO_2,
|
||||
waitSemaphoreInfoCount: 1,
|
||||
pWaitSemaphoreInfos: &wait_info,
|
||||
signalSemaphoreInfoCount: 1,
|
||||
pSignalSemaphoreInfos: &signal_info,
|
||||
commandBufferInfoCount: 1,
|
||||
pCommandBufferInfos: &cmd_info,
|
||||
};
|
||||
|
||||
result = vkQueueSubmit2(vk.queues.gfx_queue, 1, &submit_info, vk.render_fences[index]);
|
||||
success = VkCheck("FinishFrame failure: vkQueueSubmit2 error", result);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
VkPresentInfoKHR present_info = {
|
||||
sType: VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
||||
swapchainCount: 1,
|
||||
pSwapchains: &vk.swapchain,
|
||||
waitSemaphoreCount: 1,
|
||||
pWaitSemaphores: vk.render_sems.ptr + index,
|
||||
pImageIndices: &vk.image_index,
|
||||
};
|
||||
|
||||
result = vkQueuePresentKHR(vk.queues.gfx_queue, &present_info);
|
||||
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
|
||||
{
|
||||
RecreateSwapchain(vk);
|
||||
}
|
||||
else
|
||||
{
|
||||
success = VkCheck("FinishFrame failure: vkQueuePresentKHR failure", result);
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void
|
||||
Draw(Vulkan* vk, u32 index_count, u32 instance_count)
|
||||
{
|
||||
vkCmdDraw(vk.cmds[FrameIndex(vk)], index_count, instance_count, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
DrawIndexed(Vulkan* vk, u32 index_count, u32 instance_count)
|
||||
{
|
||||
vkCmdDrawIndexed(vk.cmds[FrameIndex(vk)], index_count, instance_count, 0, 0, 0);
|
||||
}
|
||||
|
||||
pragma(inline): void
|
||||
Copy(VkCommandBuffer cmd, VkImage src, VkImage dst, VkExtent2D src_ext, VkExtent2D dst_ext)
|
||||
{
|
||||
VkImageBlit2 blit = {
|
||||
sType: VK_STRUCTURE_TYPE_IMAGE_BLIT_2,
|
||||
srcOffsets: [
|
||||
{},
|
||||
{ x: cast(i32)src_ext.width, y: cast(i32)src_ext.height, z: 1 },
|
||||
],
|
||||
dstOffsets: [
|
||||
{},
|
||||
{ x: cast(i32)dst_ext.width, y: cast(i32)dst_ext.height, z: 1 },
|
||||
],
|
||||
srcSubresource: {
|
||||
aspectMask: VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
baseArrayLayer: 0,
|
||||
layerCount: 1,
|
||||
mipLevel: 0,
|
||||
},
|
||||
dstSubresource: {
|
||||
aspectMask: VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
baseArrayLayer: 0,
|
||||
layerCount: 1,
|
||||
mipLevel: 0,
|
||||
},
|
||||
};
|
||||
|
||||
VkBlitImageInfo2 blit_info = {
|
||||
sType: VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2,
|
||||
srcImage: src,
|
||||
srcImageLayout: VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
dstImage: dst,
|
||||
dstImageLayout: VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
filter: VK_FILTER_LINEAR,
|
||||
regionCount: 1,
|
||||
pRegions: &blit,
|
||||
};
|
||||
|
||||
vkCmdBlitImage2(cmd, &blit_info);
|
||||
}
|
||||
|
||||
void
|
||||
Bind(Vulkan* vk, PipelineHandle pipeline)
|
||||
{
|
||||
u64 index = FrameIndex(vk);
|
||||
|
||||
vkCmdBindPipeline(vk.cmds[index], pipeline.type, pipeline.handle);
|
||||
|
||||
VkViewport viewport = {
|
||||
width: cast(f32)vk.swapchain_extent.width,
|
||||
height: cast(f32)vk.swapchain_extent.height,
|
||||
maxDepth: 1.0F,
|
||||
};
|
||||
|
||||
vkCmdSetViewport(vk.cmds[index], 0, 1, &viewport);
|
||||
|
||||
VkRect2D scissor = {
|
||||
extent: {
|
||||
width: vk.swapchain_extent.width,
|
||||
height: vk.swapchain_extent.height,
|
||||
},
|
||||
};
|
||||
|
||||
vkCmdSetScissor(vk.cmds[index], 0, 1, &scissor);
|
||||
}
|
||||
|
||||
pragma(inline): void
|
||||
Transition(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout)
|
||||
{
|
||||
VkImageMemoryBarrier2 barrier = {
|
||||
sType: VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||
srcStageMask: VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
|
||||
srcAccessMask: VK_ACCESS_2_MEMORY_WRITE_BIT,
|
||||
dstStageMask: VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
|
||||
dstAccessMask: VK_ACCESS_2_MEMORY_WRITE_BIT | VK_ACCESS_2_MEMORY_READ_BIT,
|
||||
oldLayout: current_layout,
|
||||
newLayout: new_layout,
|
||||
image: image,
|
||||
subresourceRange: {
|
||||
aspectMask: new_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
baseMipLevel: 0,
|
||||
levelCount: VK_REMAINING_MIP_LEVELS,
|
||||
baseArrayLayer: 0,
|
||||
layerCount: VK_REMAINING_ARRAY_LAYERS,
|
||||
},
|
||||
};
|
||||
|
||||
VkDependencyInfo dep_info = {
|
||||
sType: VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
|
||||
imageMemoryBarrierCount: 1,
|
||||
pImageMemoryBarriers: &barrier,
|
||||
};
|
||||
|
||||
vkCmdPipelineBarrier2(cmd, &dep_info);
|
||||
}
|
||||
|
||||
pragma(inline): void
|
||||
Transition(VkCommandBuffer cmd, ImageView* view, VkImageLayout new_layout)
|
||||
{
|
||||
Transition(cmd, view.base.image, view.base.layout, new_layout);
|
||||
view.base.layout = new_layout;
|
||||
}
|
||||
|
||||
pragma(inline): void
|
||||
Transition(VkCommandBuffer cmd, Image* image, VkImageLayout new_layout)
|
||||
{
|
||||
Transition(cmd, image.image, image.layout, new_layout);
|
||||
image.layout = new_layout;
|
||||
}
|
||||
|
||||
Result!(Shader)
|
||||
BuildShader(Vulkan* vk, u8[] bytes)
|
||||
{
|
||||
@ -343,9 +685,9 @@ CreateGraphicsPipeline(Vulkan* vk, GfxPipelineInfo* build_info)
|
||||
layout: vk.pipeline_layout,
|
||||
};
|
||||
|
||||
VkPipeline pipeline;
|
||||
PipelineHandle pipeline = { type: VK_PIPELINE_BIND_POINT_GRAPHICS };
|
||||
|
||||
VkResult result = vkCreateGraphicsPipelines(vk.device, null, 1, &create_info, null, &pipeline);
|
||||
VkResult result = vkCreateGraphicsPipelines(vk.device, null, 1, &create_info, null, &pipeline.handle);
|
||||
assert(VkCheck("CreateGraphicsPipeline failure", result), "Unable to build pipeline");
|
||||
|
||||
return pipeline;
|
||||
@ -367,8 +709,8 @@ CreateComputePipeline(Vulkan* vk, Shader shader)
|
||||
|
||||
__traits(getMember, &info.stage, "module") = shader;
|
||||
|
||||
VkPipeline pipeline;
|
||||
VkResult result = vkCreateComputePipelines(vk.device, null, 1, &info, null, &pipeline);
|
||||
PipelineHandle pipeline = { type: VK_PIPELINE_BIND_POINT_COMPUTE };
|
||||
VkResult result = vkCreateComputePipelines(vk.device, null, 1, &info, null, &pipeline.handle);
|
||||
assert(VkCheck("CreateComputePipeline failure", result), "Unable to build pipeline");
|
||||
|
||||
return pipeline;
|
||||
@ -383,7 +725,7 @@ Destroy(Vulkan* vk, Shader shader)
|
||||
void
|
||||
Destroy(Vulkan* vk, Pipeline pipeline)
|
||||
{
|
||||
vkDestroyPipeline(vk.device, pipeline, null);
|
||||
vkDestroyPipeline(vk.device, pipeline.handle, null);
|
||||
}
|
||||
|
||||
void
|
||||
@ -971,6 +1313,16 @@ CreateSwapchain(Vulkan* vk)
|
||||
return success;
|
||||
}
|
||||
|
||||
void
|
||||
RecreateSwapchain(Vulkan* vk)
|
||||
{
|
||||
vkDeviceWaitIdle(vk.device);
|
||||
|
||||
Destroy(vk.swapchain, vk.present_images, vk.device);
|
||||
|
||||
CreateSwapchain(vk);
|
||||
}
|
||||
|
||||
bool
|
||||
InitVMA(Vulkan* vk)
|
||||
{
|
||||
|
||||
@ -5,7 +5,7 @@ import std.conv;
|
||||
import std.string;
|
||||
import core.stdc.string : strlen;
|
||||
|
||||
VkBool32
|
||||
extern(System) VkBool32
|
||||
DebugCallback(
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT message_type,
|
||||
|
||||
@ -61,41 +61,49 @@ struct AssetInfo
|
||||
AssetType type;
|
||||
}
|
||||
|
||||
bool
|
||||
bool Asset_Pack_Opened = false;
|
||||
|
||||
void
|
||||
OpenAssetPack()
|
||||
{
|
||||
bool success = true;
|
||||
string file_path = isFile("build/assets.sgp") ? "build/assets.sgp" : "assets.sgp";
|
||||
|
||||
// TODO: replace this with something that doesn't throw an exception and figure out if this is the best way to handle thing (probably isnt)
|
||||
try
|
||||
if (!Asset_Pack_Opened)
|
||||
{
|
||||
Asset_File = File(file_path, "rb");
|
||||
bool success = true;
|
||||
string file_path = isFile("build/assets.sgp") ? "build/assets.sgp" : "assets.sgp";
|
||||
|
||||
// TODO: replace this with something that doesn't throw an exception and figure out if this is the best way to handle thing (probably isnt)
|
||||
try
|
||||
{
|
||||
Asset_File = File(file_path, "rb");
|
||||
}
|
||||
catch (ErrnoException e)
|
||||
{
|
||||
Logf("OpenAssetPack failure: Unable to open file %s", file_path);
|
||||
assert(false, "Unable to open asset pack file");
|
||||
}
|
||||
|
||||
FileHeader[1] header_arr;
|
||||
|
||||
Asset_File.rawRead(header_arr);
|
||||
|
||||
Asset_Header = header_arr[0];
|
||||
|
||||
assert(Asset_Header.file_version == FILE_VERSION, "OpenAssetPack failure: file version incorrect");
|
||||
|
||||
Asset_File.seek(Asset_Header.asset_info_offset);
|
||||
|
||||
Asset_File.rawRead(Asset_Info);
|
||||
}
|
||||
catch (ErrnoException e)
|
||||
{
|
||||
success = false;
|
||||
Logf("OpenAssetPack failure: Unable to open file %s", file_path);
|
||||
}
|
||||
|
||||
FileHeader[1] header_arr;
|
||||
|
||||
Asset_File.rawRead(header_arr);
|
||||
|
||||
Asset_Header = header_arr[0];
|
||||
|
||||
assert(Asset_Header.file_version == FILE_VERSION, "OpenAssetPack failure: file version incorrect");
|
||||
|
||||
Asset_File.seek(Asset_Header.asset_info_offset);
|
||||
|
||||
Asset_File.rawRead(Asset_Info);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
u8[]
|
||||
LoadAssetData(string name)
|
||||
{
|
||||
if (!Asset_Pack_Opened)
|
||||
{
|
||||
OpenAssetPack();
|
||||
}
|
||||
|
||||
u64 hash = Hash(name);
|
||||
u8[] data = null;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user