texture loading and depth buffer
This commit is contained in:
parent
0137d21406
commit
f6276bfdf6
14 changed files with 695 additions and 159 deletions
src
179
src/main.rs
179
src/main.rs
|
@ -27,7 +27,7 @@ use vulkanalia::vk::ExtDebugUtilsExtension;
|
|||
use vulkanalia::vk::KhrSurfaceExtension;
|
||||
use vulkanalia::vk::KhrSwapchainExtension;
|
||||
|
||||
use cgmath::{vec2, vec3};
|
||||
use cgmath::vec3;
|
||||
use std::mem::size_of;
|
||||
use std::ptr::copy_nonoverlapping as memcpy;
|
||||
|
||||
|
@ -39,6 +39,9 @@ pub mod swapchain;
|
|||
pub mod queue_family_indices;
|
||||
pub mod vertex;
|
||||
pub mod buffer;
|
||||
pub mod image;
|
||||
pub mod command_buffer;
|
||||
pub mod depth_buffer;
|
||||
|
||||
const PORTABILITY_MACOS_VERSION: Version = Version::new(1, 3, 216);
|
||||
const VALIDATION_ENABLED: bool =
|
||||
|
@ -123,10 +126,16 @@ impl App {
|
|||
|
||||
buffer::create_descriptor_set_layout(&device, &mut data)?;
|
||||
create_pipeline(&device, &mut data)?;
|
||||
|
||||
|
||||
command_buffer::create_command_pool(&instance, &device, &mut data)?;
|
||||
|
||||
depth_buffer::create_depth_objects(&instance, &device, &mut data)?;
|
||||
create_framebuffers(&device, &mut data)?;
|
||||
|
||||
create_command_pool(&instance, &device, &mut data)?;
|
||||
|
||||
image::create_texture_image(&instance, &device, &mut data)?;
|
||||
image::create_texture_image_view(&device, &mut data)?;
|
||||
image::create_texture_sampler(&device, &mut data)?;
|
||||
|
||||
buffer::create_vertex_buffer(&instance, &device, &mut data)?;
|
||||
buffer::create_index_buffer(&instance, &device, &mut data)?;
|
||||
|
@ -135,7 +144,7 @@ impl App {
|
|||
buffer::create_descriptor_pool(&device, &mut data)?;
|
||||
buffer::create_descriptor_sets(&device, &mut data)?;
|
||||
|
||||
create_command_buffers(&device, &mut data)?;
|
||||
command_buffer::create_command_buffers(&device, &mut data)?;
|
||||
|
||||
create_sync_objects(&device, &mut data)?;
|
||||
|
||||
|
@ -210,6 +219,13 @@ impl App {
|
|||
unsafe fn destroy(&mut self) {
|
||||
self.destroy_swapchain();
|
||||
|
||||
self.device.destroy_sampler(self.data.texture_sampler, None);
|
||||
|
||||
self.device.destroy_image_view(self.data.texture_image_view, None);
|
||||
|
||||
self.device.destroy_image(self.data.texture_image, None);
|
||||
self.device.free_memory(self.data.texture_image_memory, None);
|
||||
|
||||
self.device.destroy_descriptor_set_layout(self.data.descriptor_set_layout, None);
|
||||
|
||||
self.device.destroy_buffer(self.data.index_buffer, None);
|
||||
|
@ -245,11 +261,12 @@ impl App {
|
|||
swapchain::create_swapchain_image_views(&self.device, &mut self.data)?;
|
||||
create_render_pass(&self.instance, &self.device, &mut self.data)?;
|
||||
create_pipeline(&self.device, &mut self.data)?;
|
||||
buffer::create_descriptor_pool(&self.device, &mut self.data)?;
|
||||
depth_buffer::create_depth_objects(&self.instance, &self.device, &mut self.data)?;
|
||||
create_framebuffers(&self.device, &mut self.data)?;
|
||||
buffer::create_uniform_buffers(&self.instance, &self.device, &mut self.data)?;
|
||||
buffer::create_descriptor_pool(&self.device, &mut self.data)?;
|
||||
buffer::create_descriptor_sets(&self.device, &mut self.data)?;
|
||||
create_command_buffers(&self.device, &mut self.data)?;
|
||||
command_buffer::create_command_buffers(&self.device, &mut self.data)?;
|
||||
self.data
|
||||
.images_in_flight
|
||||
.resize(self.data.swapchain_images.len(), vk::Fence::null());
|
||||
|
@ -257,6 +274,11 @@ impl App {
|
|||
}
|
||||
|
||||
unsafe fn destroy_swapchain(&mut self) {
|
||||
self.device.destroy_image_view(self.data.depth_image_view, None);
|
||||
|
||||
self.device.destroy_image(self.data.depth_image, None);
|
||||
self.device.free_memory(self.data.depth_image_memory, None);
|
||||
|
||||
self.device.destroy_descriptor_pool(self.data.descriptor_pool, None);
|
||||
self.data.uniform_buffers
|
||||
.iter()
|
||||
|
@ -292,14 +314,21 @@ impl App {
|
|||
vec3(0.0, 0.0, 1.0),
|
||||
);
|
||||
|
||||
let mut proj = cgmath::perspective(
|
||||
cgmath::Deg(45.0),
|
||||
self.data.swapchain_extent.width as f32 / self.data.swapchain_extent.height as f32,
|
||||
0.1,
|
||||
10.0,
|
||||
let correction = buffer::Mat4::new( //column major order, matrix looks transposed
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
// We're also flipping the Y-axis with this line's `-1.0`.
|
||||
0.0, -1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0 / 2.0, 0.0,
|
||||
0.0, 0.0, 1.0 / 2.0, 1.0,
|
||||
);
|
||||
|
||||
proj[1][1] *= -1.0;
|
||||
|
||||
let proj = correction
|
||||
* cgmath::perspective(
|
||||
cgmath::Deg(45.0),
|
||||
self.data.swapchain_extent.width as f32 / self.data.swapchain_extent.height as f32,
|
||||
0.1,
|
||||
10.0,
|
||||
);
|
||||
|
||||
let ubo = buffer::UniformBufferObject { model, view, proj };
|
||||
|
||||
|
@ -447,6 +476,9 @@ unsafe fn check_physical_device(
|
|||
if features.geometry_shader != vk::TRUE {
|
||||
return Err(anyhow!(errors::SuitabilityError("Missing geometry shader support.")));
|
||||
}
|
||||
if features.sampler_anisotropy != vk::TRUE {
|
||||
return Err(anyhow!(errors::SuitabilityError("No sampler anisotropy.")));
|
||||
}
|
||||
|
||||
queue_family_indices::QueueFamilyIndices::get(instance, data, physical_device)?;
|
||||
check_physical_device_extensions(instance, physical_device)?;
|
||||
|
@ -504,7 +536,8 @@ unsafe fn create_logical_device(
|
|||
extensions.push(vk::KHR_PORTABILITY_SUBSET_EXTENSION.name.as_ptr());
|
||||
};
|
||||
|
||||
let features = vk::PhysicalDeviceFeatures::builder();
|
||||
let features = vk::PhysicalDeviceFeatures::builder()
|
||||
.sampler_anisotropy(true);
|
||||
|
||||
let indices = queue_family_indices::QueueFamilyIndices::get(instance, data, data.physical_device)?;
|
||||
|
||||
|
@ -594,6 +627,15 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
|
|||
.sample_shading_enable(false)
|
||||
.rasterization_samples(vk::SampleCountFlags::_1);
|
||||
|
||||
let depth_stencil_state = vk::PipelineDepthStencilStateCreateInfo::builder()
|
||||
.depth_test_enable(true)
|
||||
.depth_write_enable(true)
|
||||
.depth_compare_op(vk::CompareOp::LESS)
|
||||
.depth_bounds_test_enable(false)
|
||||
.min_depth_bounds(0.0) // Optional.
|
||||
.max_depth_bounds(1.0) // Optional.
|
||||
.stencil_test_enable(false);
|
||||
|
||||
let attachment = vk::PipelineColorBlendAttachmentState::builder()
|
||||
.color_write_mask(vk::ColorComponentFlags::all())
|
||||
.blend_enable(false)
|
||||
|
@ -625,6 +667,7 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
|
|||
.viewport_state(&viewport_state)
|
||||
.rasterization_state(&rasterization_state)
|
||||
.multisample_state(&multisample_state)
|
||||
.depth_stencil_state(&depth_stencil_state)
|
||||
.color_blend_state(&color_blend_state)
|
||||
.layout(data.pipeline_layout)
|
||||
.render_pass(data.render_pass)
|
||||
|
@ -670,20 +713,38 @@ unsafe fn create_render_pass(
|
|||
.attachment(0)
|
||||
.layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
let depth_stencil_attachment = vk::AttachmentDescription::builder()
|
||||
.format(depth_buffer::get_depth_format(instance, data)?)
|
||||
.samples(vk::SampleCountFlags::_1)
|
||||
.load_op(vk::AttachmentLoadOp::CLEAR)
|
||||
.store_op(vk::AttachmentStoreOp::DONT_CARE)
|
||||
.stencil_load_op(vk::AttachmentLoadOp::DONT_CARE)
|
||||
.stencil_store_op(vk::AttachmentStoreOp::DONT_CARE)
|
||||
.initial_layout(vk::ImageLayout::UNDEFINED)
|
||||
.final_layout(vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
|
||||
let depth_stencil_attachment_ref = vk::AttachmentReference::builder()
|
||||
.attachment(1)
|
||||
.layout(vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
|
||||
let color_attachments = &[color_attachment_ref];
|
||||
let subpass = vk::SubpassDescription::builder()
|
||||
.pipeline_bind_point(vk::PipelineBindPoint::GRAPHICS)
|
||||
.color_attachments(color_attachments);
|
||||
.color_attachments(color_attachments)
|
||||
.depth_stencil_attachment(&depth_stencil_attachment_ref);
|
||||
|
||||
let dependency = vk::SubpassDependency::builder()
|
||||
.src_subpass(vk::SUBPASS_EXTERNAL)
|
||||
.dst_subpass(0)
|
||||
.src_stage_mask(vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT)
|
||||
.src_stage_mask(vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT
|
||||
| vk::PipelineStageFlags::EARLY_FRAGMENT_TESTS)
|
||||
.src_access_mask(vk::AccessFlags::empty())
|
||||
.dst_stage_mask(vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT)
|
||||
.dst_access_mask(vk::AccessFlags::COLOR_ATTACHMENT_WRITE);
|
||||
.dst_stage_mask(vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT
|
||||
| vk::PipelineStageFlags::EARLY_FRAGMENT_TESTS)
|
||||
.dst_access_mask(vk::AccessFlags::COLOR_ATTACHMENT_WRITE
|
||||
| vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE);
|
||||
|
||||
let attachments = &[color_attachment];
|
||||
let attachments = &[color_attachment, depth_stencil_attachment];
|
||||
let subpasses = &[subpass];
|
||||
let dependencies = &[dependency];
|
||||
let info = vk::RenderPassCreateInfo::builder()
|
||||
|
@ -701,7 +762,7 @@ unsafe fn create_framebuffers(device: &Device, data: &mut app_data::AppData) ->
|
|||
.swapchain_image_views
|
||||
.iter()
|
||||
.map(|i| {
|
||||
let attachments = &[*i];
|
||||
let attachments = &[*i, data.depth_image_view];
|
||||
let create_info = vk::FramebufferCreateInfo::builder()
|
||||
.render_pass(data.render_pass)
|
||||
.attachments(attachments)
|
||||
|
@ -716,84 +777,6 @@ unsafe fn create_framebuffers(device: &Device, data: &mut app_data::AppData) ->
|
|||
Ok(())
|
||||
}
|
||||
|
||||
unsafe fn create_command_pool(
|
||||
instance: &Instance,
|
||||
device: &Device,
|
||||
data: &mut app_data::AppData,
|
||||
) -> Result<()> {
|
||||
let indices = queue_family_indices::QueueFamilyIndices::get(instance, data, data.physical_device)?;
|
||||
|
||||
let info = vk::CommandPoolCreateInfo::builder()
|
||||
.flags(vk::CommandPoolCreateFlags::empty()) // Optional.
|
||||
.queue_family_index(indices.graphics);
|
||||
|
||||
data.command_pool = device.create_command_pool(&info, None)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
unsafe fn create_command_buffers(device: &Device, data: &mut app_data::AppData) -> Result<()> {
|
||||
let allocate_info = vk::CommandBufferAllocateInfo::builder()
|
||||
.command_pool(data.command_pool)
|
||||
.level(vk::CommandBufferLevel::PRIMARY)
|
||||
.command_buffer_count(data.framebuffers.len() as u32);
|
||||
|
||||
data.command_buffers = device.allocate_command_buffers(&allocate_info)?;
|
||||
|
||||
for (i, command_buffer) in data.command_buffers.iter().enumerate() {
|
||||
let inheritance = vk::CommandBufferInheritanceInfo::builder();
|
||||
|
||||
let info = vk::CommandBufferBeginInfo::builder()
|
||||
.flags(vk::CommandBufferUsageFlags::empty()) // Optional.
|
||||
.inheritance_info(&inheritance); // Optional.
|
||||
|
||||
device.begin_command_buffer(*command_buffer, &info)?;
|
||||
|
||||
let render_area = vk::Rect2D::builder()
|
||||
.offset(vk::Offset2D::default())
|
||||
.extent(data.swapchain_extent);
|
||||
|
||||
let color_clear_value = vk::ClearValue {
|
||||
color: vk::ClearColorValue {
|
||||
float32: [0.0, 0.0, 0.0, 1.0],
|
||||
},
|
||||
};
|
||||
|
||||
let clear_values = &[color_clear_value];
|
||||
let info = vk::RenderPassBeginInfo::builder()
|
||||
.render_pass(data.render_pass)
|
||||
.framebuffer(data.framebuffers[i])
|
||||
.render_area(render_area)
|
||||
.clear_values(clear_values);
|
||||
|
||||
device.cmd_begin_render_pass(
|
||||
*command_buffer, &info, vk::SubpassContents::INLINE);
|
||||
|
||||
device.cmd_bind_pipeline(
|
||||
*command_buffer, vk::PipelineBindPoint::GRAPHICS, data.pipeline);
|
||||
|
||||
device.cmd_bind_vertex_buffers(*command_buffer, 0, &[data.vertex_buffer], &[0]);
|
||||
device.cmd_bind_index_buffer(*command_buffer, data.index_buffer, 0, vk::IndexType::UINT16);
|
||||
|
||||
device.cmd_bind_descriptor_sets(
|
||||
*command_buffer,
|
||||
vk::PipelineBindPoint::GRAPHICS,
|
||||
data.pipeline_layout,
|
||||
0,
|
||||
&[data.descriptor_sets[i]],
|
||||
&[],
|
||||
);
|
||||
|
||||
device.cmd_draw_indexed(*command_buffer, buffer::INDICES.len() as u32, 1, 0, 0, 0);
|
||||
|
||||
device.cmd_end_render_pass(*command_buffer);
|
||||
|
||||
device.end_command_buffer(*command_buffer)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
unsafe fn create_sync_objects(device: &Device, data: &mut app_data::AppData) -> Result<()> {
|
||||
let semaphore_info = vk::SemaphoreCreateInfo::builder();
|
||||
let fence_info = vk::FenceCreateInfo::builder()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue