transitioned to render passes and vulkan 1.2, works but has a bug

This commit is contained in:
matthew 2025-08-07 07:25:17 +10:00
parent 8e35be5c62
commit 0c8aaa4b8c
14 changed files with 99 additions and 99 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -4,7 +4,7 @@ set -eu
# SHADERS # SHADERS
shader_compiler="glslc" shader_compiler="glslc"
shader_flags="--target-spv=spv1.6 -std=460 --target-env=vulkan1.3" shader_flags="--target-spv=spv1.5 -std=460 --target-env=vulkan1.3"
shader_out="-oassets/shaders/" shader_out="-oassets/shaders/"
mkdir -p assets/shaders mkdir -p assets/shaders

View File

@ -108,22 +108,16 @@ InitGame(PlatformWindow* window)
UVec2 ext = GetExtent(&g.rd); UVec2 ext = GetExtent(&g.rd);
CreateImageView(&g.rd, &g.draw_image, ext.x, ext.y, GetDrawImageFormat(&g.rd), IU.Draw, false);
CreateImageView(&g.rd, &g.depth_image, ext.x, ext.y, FMT.D_SF32, IU.Depth, true);
CreateImageView(&g.rd, &g.aux_image, ext.x, ext.y, FMT.R_U32, IU.Storage); CreateImageView(&g.rd, &g.aux_image, ext.x, ext.y, FMT.R_U32, IU.Storage);
GfxPipelineInfo triangle_info = { GfxPipelineInfo triangle_info = {
vertex_shader: "shaders/triangle.vert.spv", vertex_shader: "shaders/triangle.vert.spv",
frag_shader: "shaders/triangle.frag.spv", frag_shader: "shaders/triangle.frag.spv",
draw_image: &g.draw_image,
depth_image: &g.depth_image,
}; };
GfxPipelineInfo ui_info = { GfxPipelineInfo ui_info = {
vertex_shader: "shaders/gui.vert.spv", vertex_shader: "shaders/gui.vert.spv",
frag_shader: "shaders/gui.frag.spv", frag_shader: "shaders/gui.frag.spv",
draw_image: &g.draw_image,
depth_image: &g.depth_image,
input_rate: IR.Instance, input_rate: IR.Instance,
input_rate_stride: UIVertex.sizeof, input_rate_stride: UIVertex.sizeof,
vertex_attributes: [ vertex_attributes: [
@ -137,8 +131,6 @@ InitGame(PlatformWindow* window)
GfxPipelineInfo pbr_info = { GfxPipelineInfo pbr_info = {
vertex_shader: "shaders/pbr.vert.spv", vertex_shader: "shaders/pbr.vert.spv",
frag_shader: "shaders/pbr.frag.spv", frag_shader: "shaders/pbr.frag.spv",
draw_image: &g.draw_image,
depth_image: &g.depth_image,
input_rate_stride: Vertex.sizeof, input_rate_stride: Vertex.sizeof,
vertex_attributes: [ vertex_attributes: [
{ binding: 0, location: 0, format: FMT.RGBA_F32, offset: 0 }, { binding: 0, location: 0, format: FMT.RGBA_F32, offset: 0 },
@ -152,8 +144,6 @@ InitGame(PlatformWindow* window)
GfxPipelineInfo oit_info = { GfxPipelineInfo oit_info = {
vertex_shader: "shaders/full_screen_triangle.vert.spv", vertex_shader: "shaders/full_screen_triangle.vert.spv",
frag_shader: "shaders/oit.frag.spv", frag_shader: "shaders/oit.frag.spv",
draw_image: &g.draw_image,
depth_image: &g.depth_image,
}; };
CompPipelineInfo gradient_info = { CompPipelineInfo gradient_info = {
@ -250,8 +240,6 @@ Cycle(Game* g)
ProcessInputs(g, &g.camera); ProcessInputs(g, &g.camera);
ResizeDrawImageIfNeeded(&g.rd, &g.draw_image);
ResizeDrawImageIfNeeded(&g.rd, &g.depth_image);
ResizeDrawImageIfNeeded(&g.rd, &g.aux_image); ResizeDrawImageIfNeeded(&g.rd, &g.aux_image);
UpdateAuxImage(&g.rd, &g.aux_image); UpdateAuxImage(&g.rd, &g.aux_image);
@ -282,7 +270,7 @@ Cycle(Game* g)
g.globals.res.y = ext.y; g.globals.res.y = ext.y;
SetUniform(&g.rd, &g.globals); SetUniform(&g.rd, &g.globals);
BeginRendering(&g.rd, &g.draw_image, &g.depth_image); BeginRendering(&g.rd);
Bind(&g.rd, &g.ui_pipeline); Bind(&g.rd, &g.ui_pipeline);
@ -323,7 +311,7 @@ Cycle(Game* g)
//FinishRendering(&g.rd); //FinishRendering(&g.rd);
SubmitAndPresent(&g.rd, &g.draw_image); SubmitAndPresent(&g.rd);
} }
pragma(inline): void pragma(inline): void

View File

@ -61,6 +61,7 @@ const char*[] VK_BASE_DEVICE_EXTENSIONS = [
cast(char*)VK_KHR_SWAPCHAIN_EXTENSION_NAME, cast(char*)VK_KHR_SWAPCHAIN_EXTENSION_NAME,
cast(char*)VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, cast(char*)VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME,
cast(char*)VK_KHR_8BIT_STORAGE_EXTENSION_NAME, cast(char*)VK_KHR_8BIT_STORAGE_EXTENSION_NAME,
cast(char*)VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME,
]; ];
const char*[] VK_AMD_DEVICE_EXTENSIONS = [ const char*[] VK_AMD_DEVICE_EXTENSIONS = [
@ -150,9 +151,9 @@ struct GlobalUniforms
Mat4 projection_view = Mat4Identity(); Mat4 projection_view = Mat4Identity();
Vec4 light_color; Vec4 light_color;
Vec4 ambient_color; Vec4 ambient_color;
vec3 light_direction; Vec3 light_direction;
f32 padding; f32 padding;
vec2 res; Vec2 res;
} }
struct Image struct Image
@ -219,8 +220,6 @@ struct GfxPipelineInfo
Attribute[] vertex_attributes; Attribute[] vertex_attributes;
Specialization vert_spec; Specialization vert_spec;
Specialization frag_spec; Specialization frag_spec;
ImageView* draw_image;
ImageView* depth_image;
bool self_dependency; bool self_dependency;
} }
@ -307,7 +306,7 @@ struct Vulkan
VkExtent3D swapchain_extent; VkExtent3D swapchain_extent;
VkRenderPass render_pass; VkRenderPass render_pass;
VkFramebuffer[] framebuffers; VkFramebuffer framebuffer;
ImageView[] present_images; ImageView[] present_images;
u32 image_index; u32 image_index;
@ -418,6 +417,7 @@ Init(PlatformWindow* window, u64 permanent_mem, u64 frame_mem)
if (success) success = InitDescriptors(&vk); if (success) success = InitDescriptors(&vk);
if (success) InitBuffers(&vk); if (success) InitBuffers(&vk);
if (success) success = InitConversionPipeline(&vk); if (success) success = InitConversionPipeline(&vk);
if (success) InitFramebufferAndRenderPass(&vk);
assert(success, "Error initializing vulkan"); assert(success, "Error initializing vulkan");
@ -671,6 +671,12 @@ BeginFrame(Vulkan* vk)
void void
BeginRendering(Vulkan* vk) BeginRendering(Vulkan* vk)
{ {
Transition(vk.cmds[vk.frame_index], &vk.draw_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
Transition(vk.cmds[vk.frame_index], &vk.depth_image, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL);
VkImage image = CurrentImage(vk);
Transition(vk.cmds[vk.frame_index], image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkClearValue clear_color = { VkClearValue clear_color = {
color: { color: {
float32: [0.0, 0.0, 0.0, 1.0], float32: [0.0, 0.0, 0.0, 1.0],
@ -680,13 +686,16 @@ BeginRendering(Vulkan* vk)
VkRenderPassBeginInfo pass_info = { VkRenderPassBeginInfo pass_info = {
sType: VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, sType: VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
renderPass: vk.render_pass, renderPass: vk.render_pass,
framebuffer: vk.framebuffers[vk.image_index], framebuffer: vk.framebuffer,
renderArea: { renderArea: {
offset: { offset: {
x: 0, x: 0,
y: 0, y: 0,
}, },
extent: vk.swapchain_extent, extent: {
width: vk.swapchain_extent.width,
height: vk.swapchain_extent.height,
},
}, },
clearValueCount: 1, clearValueCount: 1,
pClearValues: &clear_color, pClearValues: &clear_color,
@ -738,7 +747,7 @@ FinishRendering(Vulkan* vk)
} }
void void
SubmitAndPresent(Vulkan* vk, ImageView* draw_image) SubmitAndPresent(Vulkan* vk)
{ {
scope(exit) scope(exit)
{ {
@ -750,7 +759,7 @@ SubmitAndPresent(Vulkan* vk, ImageView* draw_image)
VkSemaphore acquire_sem = vk.acquire_sems[vk.frame_index]; VkSemaphore acquire_sem = vk.acquire_sems[vk.frame_index];
VkSemaphore submit_sem = vk.submit_sems[vk.image_index]; VkSemaphore submit_sem = vk.submit_sems[vk.image_index];
Transition(vk.cmds[vk.frame_index], draw_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); Transition(vk.cmds[vk.frame_index], &vk.draw_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
VkExtent2D extent = { VkExtent2D extent = {
width: vk.swapchain_extent.width, width: vk.swapchain_extent.width,
@ -758,27 +767,43 @@ SubmitAndPresent(Vulkan* vk, ImageView* draw_image)
}; };
// TODO: Find out how to copy from same dimension images (pretty sure its not blitting) // TODO: Find out how to copy from same dimension images (pretty sure its not blitting)
Copy(vk.cmds[vk.frame_index], &draw_image.base, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, extent, extent); Copy(vk.cmds[vk.frame_index], &vk.draw_image.base, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, extent, extent);
Transition(vk.cmds[vk.frame_index], image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); Transition(vk.cmds[vk.frame_index], image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
VkResult result = vkEndCommandBuffer(vk.cmds[vk.frame_index]); VkResult result = vkEndCommandBuffer(vk.cmds[vk.frame_index]);
VkCheckA("FinishFrame failure: vkEndCommandBuffer error", result); VkCheckA("FinishFrame failure: vkEndCommandBuffer error", result);
VkPipelineStage stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkCommandBufferSubmitInfo cmd_info = {
sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO,
VkSubmitInfo submit_info = { commandBuffer: vk.cmds[vk.frame_index],
sType: VK_STRUCTURE_TYPE_SUBMIT_INFO,
waitSemaphoreCount: 1,
pWaitSemaphores: &acquire_sem,
pWaitDstStageMask: &stage,
commandBufferCount: 1,
pCommandBuffers: vk.cmds.ptr + vk.frame_index,
signalSemaphoreCount: 1,
pSignalSemaphores: &submit_sem,
}; };
result = vkQueueSubmit(vk.queues.gfx_queue, 1, &submit_info, vk.render_fences[vk.frame_index]); VkSemaphoreSubmitInfo wait_info = {
sType: VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
semaphore: acquire_sem,
stageMask: VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
value: 1,
};
VkSemaphoreSubmitInfo signal_info = {
sType: VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
semaphore: submit_sem,
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[vk.frame_index]);
VkCheckA("FinishFrame failure: vkQueueSubmit2 error", result); VkCheckA("FinishFrame failure: vkQueueSubmit2 error", result);
VkPresentInfoKHR present_info = { VkPresentInfoKHR present_info = {
@ -1146,18 +1171,22 @@ PushConstants(Vulkan* vk, PushConst* pc)
void void
ImageBarrier(Vulkan* vk) ImageBarrier(Vulkan* vk)
{ {
vkCmdPipelineBarrier( VkMemoryBarrier2 barrier = {
vk.cmds[vk.frame_index], sType: VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
VK_PIPELINE_STAGE_2_TRANSFER_BIT, srcStageMask: VK_PIPELINE_STAGE_2_TRANSFER_BIT,
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, srcAccessMask: VK_ACCESS_2_TRANSFER_WRITE_BIT,
VK_DEPENDENCY_BY_REGION_BIT, dstStageMask: VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
1, dstAccessMask: VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT,
&barrier, };
0,
null, VkDependencyInfo dependency = {
0, sType: VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
null dependencyFlags: VK_DEPENDENCY_BY_REGION_BIT,
); memoryBarrierCount: 1,
pMemoryBarriers: &barrier,
};
vkCmdPipelineBarrier2(vk.cmds[vk.frame_index], &dependency);
} }
bool bool
@ -1311,8 +1340,7 @@ Copy(VkCommandBuffer cmd, Image* src, VkImage dst, VkImageLayout dst_layout, VkE
pragma(inline): void pragma(inline): void
Copy(VkCommandBuffer cmd, VkImage src, VkImage dst, VkImageLayout src_layout, VkImageLayout dst_layout, VkExtent2D src_ext, VkExtent2D dst_ext) Copy(VkCommandBuffer cmd, VkImage src, VkImage dst, VkImageLayout src_layout, VkImageLayout dst_layout, VkExtent2D src_ext, VkExtent2D dst_ext)
{ {
VkImageBlit2 blit = { VkImageBlit blit = {
sType: VK_STRUCTURE_TYPE_IMAGE_BLIT_2,
srcOffsets: [ srcOffsets: [
{ x: 0, y: 0 }, { x: 0, y: 0 },
{ x: cast(i32)src_ext.width, y: cast(i32)src_ext.height, z: 1 }, { x: cast(i32)src_ext.width, y: cast(i32)src_ext.height, z: 1 },
@ -1335,18 +1363,16 @@ Copy(VkCommandBuffer cmd, VkImage src, VkImage dst, VkImageLayout src_layout, Vk
}, },
}; };
VkBlitImageInfo2 blit_info = { vkCmdBlitImage(
sType: VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2, cmd,
srcImage: src, src,
srcImageLayout: src_layout, src_layout,
dstImage: dst, dst,
dstImageLayout: dst_layout, dst_layout,
filter: VK_FILTER_LINEAR, 1,
regionCount: 1, &blit,
pRegions: &blit, VK_FILTER_LINEAR
}; );
vkCmdBlitImage2(cmd, &blit_info);
} }
void void
@ -1393,23 +1419,6 @@ Bind(Vulkan* vk, PipelineHandle* pipeline)
pragma(inline): void pragma(inline): void
Transition(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout) Transition(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout)
{ {
// TODO: continue from here
VkPipelineStageFlags src_stage, dst_stage;
VkAccessFlagBits src_access, dst_access;
switch(current_layout)
{
case VK_IMAGE_LAYOUT_UNDEFINED:
{
src_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
} break;
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
{
src_stage = VK_PIPELINE_STAGE_TRANSFER_BIT;
src_mask = VK_ACCESS_FLAG_TRANSFER_WRITE_BIT;
} break;
}
VkImageMemoryBarrier2 barrier = { VkImageMemoryBarrier2 barrier = {
sType: VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, sType: VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
srcStageMask: VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, srcStageMask: VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
@ -1469,11 +1478,11 @@ BuildShader(Vulkan* vk, u8[] bytes)
} }
void void
InitFramebufferAndRenderpass(Vulkan* vk, ImageView* draw_image, ImageView* depth_image) InitFramebufferAndRenderPass(Vulkan* vk)
{ {
VkAttachmentDescription[] attach_descriptions = [ VkAttachmentDescription[] attach_descriptions = [
{ {
format: draw_image.format, format: vk.draw_image.format,
samples: VK_SAMPLE_COUNT_1_BIT, samples: VK_SAMPLE_COUNT_1_BIT,
loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR, loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR,
storeOp: VK_ATTACHMENT_STORE_OP_STORE, storeOp: VK_ATTACHMENT_STORE_OP_STORE,
@ -1483,7 +1492,8 @@ InitFramebufferAndRenderpass(Vulkan* vk, ImageView* draw_image, ImageView* depth
finalLayout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, finalLayout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
}, },
{ {
format: depth_image.format, samples: VK_SAMPLE_COUNT_1_BIT,
format: vk.depth_image.format,
initialLayout: VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, initialLayout: VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
finalLayout: VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, finalLayout: VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
}, },
@ -1532,21 +1542,15 @@ InitFramebufferAndRenderpass(Vulkan* vk, ImageView* draw_image, ImageView* depth
VkFramebufferCreateInfo framebuffer_info = { VkFramebufferCreateInfo framebuffer_info = {
sType: VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, sType: VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
renderPass: vk.render_pass, renderPass: vk.render_pass,
attachmentCount: 1, attachmentCount: 2,
pAttachments: [vk.draw_image.view, vk.depth_image.view],
width: vk.swapchain_extent.width, width: vk.swapchain_extent.width,
height: vk.swapchain_extent.height, height: vk.swapchain_extent.height,
layers: 1, layers: 1,
}; };
vk.framebuffers = AllocArray!(VkFramebuffer)(&vk.arena, vk.present_images.length); result = vkCreateFramebuffer(vk.device, &framebuffer_info, null, &vk.framebuffer);
foreach(i, image; vk.present_images)
{
framebuffer_info.pAttachments = &image.view;
result = vkCreateFramebuffer(vk.device, &framebuffer_info, null, &vk.framebuffers[i]);
VkCheckA("vkCreateFramebuffer failure", result); VkCheckA("vkCreateFramebuffer failure", result);
}
} }
Pipeline Pipeline
@ -1713,6 +1717,7 @@ CreateGraphicsPipeline(Vulkan* vk, GfxPipelineInfo* build_info)
stageCount: cast(u32)shader_info.length, stageCount: cast(u32)shader_info.length,
pStages: shader_info.ptr, pStages: shader_info.ptr,
layout: vk.pipeline_layout, layout: vk.pipeline_layout,
renderPass: vk.render_pass,
}; };
VkResult result = vkCreateGraphicsPipelines(vk.device, null, 1, &create_info, null, &pipeline.handle); VkResult result = vkCreateGraphicsPipelines(vk.device, null, 1, &create_info, null, &pipeline.handle);
@ -2625,6 +2630,7 @@ CreateSwapchain(Vulkan* vk)
foreach(i, image; vk.present_images) foreach(i, image; vk.present_images)
{ {
vk.present_images[i].image = images[i]; vk.present_images[i].image = images[i];
vk.present_images[i].format = cast(Format)vk.surface_format.format;
view_info.image = images[i]; view_info.image = images[i];
view_info.format = vk.surface_format.format; view_info.format = vk.surface_format.format;
@ -2751,8 +2757,14 @@ InitDevice(Vulkan* vk)
count += 1; count += 1;
} }
VkPhysicalDeviceSynchronization2Features synchronization2 = {
sType: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES,
synchronization2: VK_TRUE,
};
VkPhysicalDeviceVulkan12Features features_12 = { VkPhysicalDeviceVulkan12Features features_12 = {
sType: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, sType: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
pNext: &synchronization2,
descriptorIndexing: VK_TRUE, descriptorIndexing: VK_TRUE,
bufferDeviceAddress: VK_TRUE, bufferDeviceAddress: VK_TRUE,
descriptorBindingUniformBufferUpdateAfterBind: VK_TRUE, descriptorBindingUniformBufferUpdateAfterBind: VK_TRUE,
@ -2841,12 +2853,9 @@ CheckDeviceFeatures(VkPhysicalDevice device)
{ {
VkPhysicalDeviceFeatures2 features2 = { sType: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 }; VkPhysicalDeviceFeatures2 features2 = { sType: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 };
VkPhysicalDeviceVulkan12Features features_12 = { sType: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES }; VkPhysicalDeviceVulkan12Features features_12 = { sType: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES };
VkPhysicalDeviceVulkan13Features features_13 = { sType: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES };
features2.pNext = &features_12; features2.pNext = &features_12;
vkGetPhysicalDeviceFeatures2(device, &features2); vkGetPhysicalDeviceFeatures2(device, &features2);
features2.pNext = &features_13;
vkGetPhysicalDeviceFeatures2(device, &features2);
VkPhysicalDeviceFeatures features = features2.features; VkPhysicalDeviceFeatures features = features2.features;
bool result = true; bool result = true;
@ -2872,9 +2881,6 @@ CheckDeviceFeatures(VkPhysicalDevice device)
result &= cast(bool)features_12.timelineSemaphore; result &= cast(bool)features_12.timelineSemaphore;
result &= cast(bool)features_12.storageBuffer8BitAccess; result &= cast(bool)features_12.storageBuffer8BitAccess;
result &= cast(bool)features_13.synchronization2;
result &= cast(bool)features_13.dynamicRendering;
return result; return result;
} }

View File

@ -83,13 +83,16 @@ PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets = null;
PFN_vkDestroyDevice vkDestroyDevice = null; PFN_vkDestroyDevice vkDestroyDevice = null;
PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool = null; PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool = null;
PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR = null; PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR = null;
PFN_vkQueueSubmit2 vkQueueSubmit2 = null;
PFN_vkDestroyImage vkDestroyImage = null; PFN_vkDestroyImage vkDestroyImage = null;
PFN_vkCmdBlitImage vkCmdBlitImage = null;
PFN_vkDestroyImageView vkDestroyImageView = null; PFN_vkDestroyImageView vkDestroyImageView = null;
PFN_vkDestroyCommandPool vkDestroyCommandPool = null; PFN_vkDestroyCommandPool vkDestroyCommandPool = null;
PFN_vkDestroySemaphore vkDestroySemaphore = null; PFN_vkDestroySemaphore vkDestroySemaphore = null;
PFN_vkDestroyFence vkDestroyFence = null; PFN_vkDestroyFence vkDestroyFence = null;
PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout = null; PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout = null;
PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier = null; PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier = null;
PFN_vkCmdPipelineBarrier2 vkCmdPipelineBarrier2 = null;
PFN_vkDestroyPipeline vkDestroyPipeline = null; PFN_vkDestroyPipeline vkDestroyPipeline = null;
PFN_vkWaitForFences vkWaitForFences = null; PFN_vkWaitForFences vkWaitForFences = null;
PFN_vkBeginCommandBuffer vkBeginCommandBuffer = null; PFN_vkBeginCommandBuffer vkBeginCommandBuffer = null;
@ -163,6 +166,7 @@ LoadDeviceFunctions(Vulkan* vk)
vkDestroyRenderPass = cast(PFN_vkDestroyRenderPass)vkGetDeviceProcAddr(vk.device, "vkDestroyRenderPass"); vkDestroyRenderPass = cast(PFN_vkDestroyRenderPass)vkGetDeviceProcAddr(vk.device, "vkDestroyRenderPass");
vkCreateImage = cast(PFN_vkCreateImage)vkGetDeviceProcAddr(vk.device, "vkCreateImage"); vkCreateImage = cast(PFN_vkCreateImage)vkGetDeviceProcAddr(vk.device, "vkCreateImage");
vkCreateImageView = cast(PFN_vkCreateImageView)vkGetDeviceProcAddr(vk.device, "vkCreateImageView"); vkCreateImageView = cast(PFN_vkCreateImageView)vkGetDeviceProcAddr(vk.device, "vkCreateImageView");
vkQueueSubmit2 = cast(PFN_vkQueueSubmit2KHR)vkGetDeviceProcAddr(vk.device, "vkQueueSubmit2KHR");
vkCreateBufferView = cast(PFN_vkCreateBufferView)vkGetDeviceProcAddr(vk.device, "vkCreateBufferView"); vkCreateBufferView = cast(PFN_vkCreateBufferView)vkGetDeviceProcAddr(vk.device, "vkCreateBufferView");
vkGetSwapchainImagesKHR = cast(PFN_vkGetSwapchainImagesKHR)vkGetDeviceProcAddr(vk.device, "vkGetSwapchainImagesKHR"); vkGetSwapchainImagesKHR = cast(PFN_vkGetSwapchainImagesKHR)vkGetDeviceProcAddr(vk.device, "vkGetSwapchainImagesKHR");
vkGetDeviceQueue = cast(PFN_vkGetDeviceQueue)vkGetDeviceProcAddr(vk.device, "vkGetDeviceQueue"); vkGetDeviceQueue = cast(PFN_vkGetDeviceQueue)vkGetDeviceProcAddr(vk.device, "vkGetDeviceQueue");
@ -170,6 +174,7 @@ LoadDeviceFunctions(Vulkan* vk)
vkAllocateCommandBuffers = cast(PFN_vkAllocateCommandBuffers)vkGetDeviceProcAddr(vk.device, "vkAllocateCommandBuffers"); vkAllocateCommandBuffers = cast(PFN_vkAllocateCommandBuffers)vkGetDeviceProcAddr(vk.device, "vkAllocateCommandBuffers");
vkCreateCommandPool = cast(PFN_vkCreateCommandPool)vkGetDeviceProcAddr(vk.device, "vkCreateCommandPool"); vkCreateCommandPool = cast(PFN_vkCreateCommandPool)vkGetDeviceProcAddr(vk.device, "vkCreateCommandPool");
vkCmdPipelineBarrier = cast(PFN_vkCmdPipelineBarrier)vkGetDeviceProcAddr(vk.device, "vkCmdPipelineBarrier"); vkCmdPipelineBarrier = cast(PFN_vkCmdPipelineBarrier)vkGetDeviceProcAddr(vk.device, "vkCmdPipelineBarrier");
vkCmdPipelineBarrier2 = cast(PFN_vkCmdPipelineBarrier2KHR)vkGetDeviceProcAddr(vk.device, "vkCmdPipelineBarrier2KHR");
vkCreateFence = cast(PFN_vkCreateFence)vkGetDeviceProcAddr(vk.device, "vkCreateFence"); vkCreateFence = cast(PFN_vkCreateFence)vkGetDeviceProcAddr(vk.device, "vkCreateFence");
vkCreateDescriptorPool = cast(PFN_vkCreateDescriptorPool)vkGetDeviceProcAddr(vk.device, "vkCreateDescriptorPool"); vkCreateDescriptorPool = cast(PFN_vkCreateDescriptorPool)vkGetDeviceProcAddr(vk.device, "vkCreateDescriptorPool");
vkCreateDescriptorSetLayout = cast(PFN_vkCreateDescriptorSetLayout)vkGetDeviceProcAddr(vk.device, "vkCreateDescriptorSetLayout"); vkCreateDescriptorSetLayout = cast(PFN_vkCreateDescriptorSetLayout)vkGetDeviceProcAddr(vk.device, "vkCreateDescriptorSetLayout");
@ -203,6 +208,7 @@ LoadDeviceFunctions(Vulkan* vk)
vkCmdBindIndexBuffer = cast(PFN_vkCmdBindIndexBuffer)vkGetDeviceProcAddr(vk.device, "vkCmdBindIndexBuffer"); vkCmdBindIndexBuffer = cast(PFN_vkCmdBindIndexBuffer)vkGetDeviceProcAddr(vk.device, "vkCmdBindIndexBuffer");
vkCmdBindVertexBuffers = cast(PFN_vkCmdBindVertexBuffers)vkGetDeviceProcAddr(vk.device, "vkCmdBindVertexBuffers"); vkCmdBindVertexBuffers = cast(PFN_vkCmdBindVertexBuffers)vkGetDeviceProcAddr(vk.device, "vkCmdBindVertexBuffers");
vkCmdDrawIndexed = cast(PFN_vkCmdDrawIndexed)vkGetDeviceProcAddr(vk.device, "vkCmdDrawIndexed"); vkCmdDrawIndexed = cast(PFN_vkCmdDrawIndexed)vkGetDeviceProcAddr(vk.device, "vkCmdDrawIndexed");
vkCmdBlitImage = cast(PFN_vkCmdBlitImage)vkGetDeviceProcAddr(vk.device, "vkCmdBlitImage");
vkCmdCopyBufferToImage = cast(PFN_vkCmdCopyBufferToImage)vkGetDeviceProcAddr(vk.device, "vkCmdCopyBufferToImage"); vkCmdCopyBufferToImage = cast(PFN_vkCmdCopyBufferToImage)vkGetDeviceProcAddr(vk.device, "vkCmdCopyBufferToImage");
vkCmdCopyBuffer = cast(PFN_vkCmdCopyBuffer)vkGetDeviceProcAddr(vk.device, "vkCmdCopyBuffer"); vkCmdCopyBuffer = cast(PFN_vkCmdCopyBuffer)vkGetDeviceProcAddr(vk.device, "vkCmdCopyBuffer");
vkResetFences = cast(PFN_vkResetFences)vkGetDeviceProcAddr(vk.device, "vkResetFences"); vkResetFences = cast(PFN_vkResetFences)vkGetDeviceProcAddr(vk.device, "vkResetFences");