Implemented depth buffering
This commit is contained in:
parent
09799eaa9b
commit
444a4586ea
6 changed files with 154 additions and 20 deletions
|
|
@ -143,10 +143,15 @@ pub const Sampler = struct {
|
|||
|
||||
pub const RenderPass = struct {
|
||||
handle: c.VkRenderPass,
|
||||
depth_image: c.VkImage,
|
||||
depth_memory: c.VkDeviceMemory,
|
||||
depth_view: c.VkImageView,
|
||||
|
||||
const Self = @This();
|
||||
|
||||
pub fn init(allocator: Allocator, device: Device, surface: Surface, physical_device: PhysicalDevice) !Self {
|
||||
const depth_image, const depth_view , const depth_memory, const depth_format = try createDepthResources(device, physical_device);
|
||||
|
||||
const color_attachment: c.VkAttachmentDescription = .{
|
||||
.format = (try Swapchain.pickFormat(allocator, surface, physical_device)).format,
|
||||
.samples = c.VK_SAMPLE_COUNT_1_BIT,
|
||||
|
|
@ -163,25 +168,44 @@ pub const RenderPass = struct {
|
|||
.layout = c.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
};
|
||||
|
||||
const depth_attachment: c.VkAttachmentDescription = .{
|
||||
.format = depth_format,
|
||||
.samples = c.VK_SAMPLE_COUNT_1_BIT,
|
||||
.loadOp = c.VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.storeOp = c.VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||
.stencilLoadOp = c.VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
.stencilStoreOp = c.VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||
.initialLayout = c.VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.finalLayout = c.VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
};
|
||||
|
||||
const depth_attachment_reference: c.VkAttachmentReference = .{
|
||||
.attachment = 1,
|
||||
.layout = c.VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
};
|
||||
|
||||
const subpass: c.VkSubpassDescription = .{
|
||||
.pipelineBindPoint = c.VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
.colorAttachmentCount = 1,
|
||||
.pColorAttachments = &color_attachment_reference,
|
||||
.pDepthStencilAttachment = &depth_attachment_reference,
|
||||
};
|
||||
|
||||
const dependency: c.VkSubpassDependency = .{
|
||||
.srcSubpass = c.VK_SUBPASS_EXTERNAL,
|
||||
.dstSubpass = 0,
|
||||
.srcStageMask = c.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
.srcAccessMask = 0,
|
||||
.dstStageMask = c.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
.dstAccessMask = c.VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
.srcStageMask = c.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | c.VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
.srcAccessMask = c.VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstStageMask = c.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | c.VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||
.dstAccessMask = c.VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | c.VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
};
|
||||
|
||||
const attachments = &[_]c.VkAttachmentDescription { color_attachment, depth_attachment };
|
||||
|
||||
const render_pass_info: c.VkRenderPassCreateInfo = .{
|
||||
.sType = c.VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
|
||||
.attachmentCount = 1,
|
||||
.pAttachments = &color_attachment,
|
||||
.attachmentCount = 2,
|
||||
.pAttachments = attachments[0..].ptr,
|
||||
.subpassCount = 1,
|
||||
.pSubpasses = &subpass,
|
||||
.dependencyCount = 1,
|
||||
|
|
@ -194,12 +218,18 @@ pub const RenderPass = struct {
|
|||
|
||||
return Self{
|
||||
.handle = render_pass,
|
||||
.depth_image = depth_image,
|
||||
.depth_view = depth_view,
|
||||
.depth_memory = depth_memory,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn begin(self: Self, swapchain: Swapchain, device: Device, image: usize, frame: usize) void {
|
||||
std.debug.assert(frame < frames_in_flight);
|
||||
const clear_color: c.VkClearValue = .{ .color = .{ .float32 = .{ 0.0, 0.0, 0.0, 1.0 } } };
|
||||
const depth_stencil: c.VkClearValue = .{ .depthStencil = .{ .depth = 1.0, .stencil = 0 } };
|
||||
|
||||
const clear_values = &[_]c.VkClearValue { clear_color, depth_stencil };
|
||||
|
||||
const begin_info: c.VkRenderPassBeginInfo = .{
|
||||
.sType = c.VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
|
|
@ -209,8 +239,8 @@ pub const RenderPass = struct {
|
|||
.offset = .{ .x = 0, .y = 0 },
|
||||
.extent = swapchain.extent,
|
||||
},
|
||||
.clearValueCount = 1,
|
||||
.pClearValues = &clear_color,
|
||||
.clearValueCount = 2,
|
||||
.pClearValues = clear_values[0..].ptr,
|
||||
};
|
||||
|
||||
c.vkCmdBeginRenderPass(device.command_buffers[frame], &begin_info, c.VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
|
@ -222,6 +252,88 @@ pub const RenderPass = struct {
|
|||
c.vkCmdEndRenderPass(device.command_buffers[frame]);
|
||||
}
|
||||
|
||||
fn findSupportedFormat(physical_device: PhysicalDevice, candidates: []c.VkFormat, tiling: c.VkImageTiling, features: c.VkFormatFeatureFlags) ?c.VkFormat {
|
||||
for (candidates) |format| {
|
||||
var format_properties: c.VkFormatProperties = undefined;
|
||||
c.vkGetPhysicalDeviceFormatProperties(physical_device.handle, format, &format_properties);
|
||||
if (tiling == c.VK_IMAGE_TILING_LINEAR and (format_properties.linearTilingFeatures & features) == features) {
|
||||
return format;
|
||||
} else if (tiling == c.VK_IMAGE_TILING_OPTIMAL and (format_properties.optimalTilingFeatures & features) == features) {
|
||||
return format;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
fn createDepthResources(device: Device, physical_device: PhysicalDevice) !struct { c.VkImage, c.VkImageView, c.VkDeviceMemory, c.VkFormat } {
|
||||
const candidates = &[_]u32 {
|
||||
c.VK_FORMAT_D32_SFLOAT,
|
||||
c.VK_FORMAT_D32_SFLOAT_S8_UINT,
|
||||
c.VK_FORMAT_D24_UNORM_S8_UINT,
|
||||
};
|
||||
|
||||
if (findSupportedFormat(physical_device, @constCast(candidates), c.VK_IMAGE_TILING_OPTIMAL, c.VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) |format| {
|
||||
const create_info: c.VkImageCreateInfo = .{
|
||||
.sType = c.VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||
.imageType = c.VK_IMAGE_TYPE_2D,
|
||||
.extent = .{
|
||||
.width = @intCast(800),
|
||||
.height = @intCast(600),
|
||||
.depth = 1,
|
||||
},
|
||||
.mipLevels = 1,
|
||||
.arrayLayers = 1,
|
||||
.format = format,
|
||||
.tiling = c.VK_IMAGE_TILING_OPTIMAL,
|
||||
.initialLayout = c.VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.usage = c.VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
||||
.sharingMode = c.VK_SHARING_MODE_EXCLUSIVE,
|
||||
.samples = c.VK_SAMPLE_COUNT_1_BIT,
|
||||
.flags = 0,
|
||||
};
|
||||
|
||||
var image: c.VkImage = undefined;
|
||||
var image_memory: c.VkDeviceMemory = undefined;
|
||||
try mapError(c.vkCreateImage(device.handle, &create_info, null, &image));
|
||||
|
||||
var memory_requirements: c.VkMemoryRequirements = undefined;
|
||||
c.vkGetImageMemoryRequirements(device.handle, image, &memory_requirements);
|
||||
|
||||
const alloc_info: c.VkMemoryAllocateInfo = .{
|
||||
.sType = c.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||
.allocationSize = memory_requirements.size,
|
||||
.memoryTypeIndex = try device.findMemoryType(memory_requirements.memoryTypeBits, c.VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT),
|
||||
};
|
||||
|
||||
try mapError(c.vkAllocateMemory(device.handle, &alloc_info, null, &image_memory));
|
||||
try mapError(c.vkBindImageMemory(device.handle, image, image_memory, 0));
|
||||
|
||||
const view_create_info: c.VkImageViewCreateInfo = .{
|
||||
.sType = c.VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
.image = image,
|
||||
.viewType = c.VK_IMAGE_VIEW_TYPE_2D,
|
||||
.format = format,
|
||||
.subresourceRange = .{
|
||||
.aspectMask = c.VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
};
|
||||
|
||||
var image_view: c.VkImageView = undefined;
|
||||
|
||||
try mapError(c.vkCreateImageView(device.handle, &view_create_info, null, &image_view));
|
||||
|
||||
return .{ image, image_view, image_memory, format };
|
||||
} else {
|
||||
return error.UnsupportedDepthFormat;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn deinit(self: Self, device: Device) void {
|
||||
c.vkDestroyRenderPass(device.handle, self.handle, null);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue