diff --git a/ash/src/instance.rs b/ash/src/instance.rs index 239c1c9..3f0c40d 100644 --- a/ash/src/instance.rs +++ b/ash/src/instance.rs @@ -195,6 +195,12 @@ impl Device { } } + pub fn destroy_pipeline_layout(&self, pipeline_layout: vk::PipelineLayout) { + unsafe { + self.device_fn.destroy_pipeline_layout(self.handle, pipeline_layout, ptr::null()); + } + } + pub fn destroy_buffer(&self, buffer: vk::Buffer) { unsafe { self.device_fn.destroy_buffer(self.handle, buffer, ptr::null()); @@ -206,6 +212,33 @@ impl Device { self.device_fn.destroy_shader_module(self.handle, shader, ptr::null()); } } + + pub fn destroy_pipeline(&self, pipeline: vk::Pipeline) { + unsafe { + self.device_fn.destroy_pipeline(self.handle, pipeline, ptr::null()); + } + } + + pub fn create_graphics_pipelines(&self, + pipeline_cache: vk::PipelineCache, + create_infos: &[vk::GraphicsPipelineCreateInfo]) + -> VkResult> { + unsafe { + let mut pipelines = Vec::with_capacity(create_infos.len()); + let err_code = self.device_fn + .create_graphics_pipelines(self.handle, + pipeline_cache, + create_infos.len() as u32, + create_infos.as_ptr(), + ptr::null(), + pipelines.as_mut_ptr()); + pipelines.set_len(create_infos.len()); + match err_code { + vk::Result::Success => Ok(pipelines), + _ => Err(err_code), + } + } + } pub fn create_buffer(&self, create_info: &vk::BufferCreateInfo) -> VkResult { unsafe { let mut buffer = mem::uninitialized(); @@ -218,6 +251,22 @@ impl Device { } } + pub fn create_pipeline_layout(&self, + create_info: &vk::PipelineLayoutCreateInfo) + -> VkResult { + unsafe { + let mut pipeline_layout = mem::uninitialized(); + let err_code = self.device_fn + .create_pipeline_layout(self.handle, + create_info, + ptr::null(), + &mut pipeline_layout); + match err_code { + vk::Result::Success => Ok(pipeline_layout), + _ => Err(err_code), + } + } + } pub fn map_memory(&self, memory: vk::DeviceMemory, offset: vk::DeviceSize, diff --git a/examples/src/main.rs b/examples/src/main.rs index 9a7d3e3..c8e736f 100644 --- a/examples/src/main.rs +++ b/examples/src/main.rs @@ -509,7 +509,6 @@ fn main() { }]; slice.copy_from_slice(&vertices); - printlndb!((slice)); device.unmap_memory(vertex_input_buffer_memory); device.bind_buffer_memory(vertex_input_buffer, vertex_input_buffer_memory, 0).unwrap(); let vertex_spv_file = File::open(Path::new("vert.spv")).expect("Could not find vert.spv."); @@ -533,13 +532,207 @@ fn main() { }; let vertex_shader_module = device.create_shader_module(&vertex_shader_info) .expect("Vertex shader module error"); - let frag_shader_module = device.create_shader_module(&frag_shader_info) + + let fragment_shader_module = device.create_shader_module(&frag_shader_info) .expect("Fragment shader module error"); + let layout_create_info = vk::PipelineLayoutCreateInfo { + s_type: vk::StructureType::PipelineLayoutCreateInfo, + p_next: ptr::null(), + flags: 0, + set_layout_count: 0, + p_set_layouts: ptr::null(), + push_constant_range_count: 0, + p_push_constant_ranges: ptr::null(), + }; + let pipeline_layout = device.create_pipeline_layout(&layout_create_info).unwrap(); + let shader_entry_name = CString::new("main").unwrap(); + let shader_stage_create_infos = [vk::PipelineShaderStageCreateInfo { + s_type: vk::StructureType::PipelineShaderStageCreateInfo, + p_next: ptr::null(), + flags: 0, + module: vertex_shader_module, + p_name: shader_entry_name.as_ptr(), + p_specialization_info: ptr::null(), + stage: vk::SHADER_STAGE_VERTEX_BIT, + }, + vk::PipelineShaderStageCreateInfo { + s_type: vk::StructureType::PipelineShaderStageCreateInfo, + p_next: ptr::null(), + flags: 0, + module: fragment_shader_module, + p_name: shader_entry_name.as_ptr(), + p_specialization_info: ptr::null(), + stage: vk::SHADER_STAGE_FRAGMENT_BIT, + }]; + let vertex_input_binding_descriptions = [vk::VertexInputBindingDescription { + binding: 0, + stride: mem::size_of::() as u32, + input_rate: vk::VertexInputRate::Vertex, + }]; + let vertex_input_attribute_descriptions = [vk::VertexInputAttributeDescription { + location: 0, + binding: 0, + format: vk::Format::R32g32b32a32Sfloat, + offset: 0, + }]; + let vertex_input_state_info = vk::PipelineVertexInputStateCreateInfo { + s_type: vk::StructureType::PipelineVertexInputStateCreateInfo, + p_next: ptr::null(), + flags: 0, + vertex_attribute_description_count: vertex_input_attribute_descriptions.len() as u32, + p_vertex_attribute_descriptions: vertex_input_attribute_descriptions.as_ptr(), + vertex_binding_description_count: vertex_input_binding_descriptions.len() as u32, + p_vertex_binding_descriptions: vertex_input_binding_descriptions.as_ptr(), + }; + let vertex_input_assembly_state_info = vk::PipelineInputAssemblyStateCreateInfo { + s_type: vk::StructureType::PipelineInputAssemblyStateCreateInfo, + flags: 0, + p_next: ptr::null(), + primitive_restart_enable: 0, + topology: vk::PrimitiveTopology::TriangleList, + }; + let viewports = [vk::Viewport { + x: 0.0, + y: 0.0, + width: surface_resoultion.width as f32, + height: surface_resoultion.height as f32, + min_depth: 0.0, + max_depth: 1.0, + }]; + let scissors = [vk::Rect2D { + offset: vk::Offset2D { x: 0, y: 0 }, + extent: surface_resoultion.clone(), + }]; + let viewport_state_info = vk::PipelineViewportStateCreateInfo { + s_type: vk::StructureType::PipelineViewportStateCreateInfo, + p_next: ptr::null(), + flags: 0, + scissor_count: scissors.len() as u32, + p_scissors: scissors.as_ptr(), + viewport_count: viewports.len() as u32, + p_viewports: viewports.as_ptr(), + }; + let rasterization_info = vk::PipelineRasterizationStateCreateInfo { + s_type: vk::StructureType::PipelineRasterizationStateCreateInfo, + p_next: ptr::null(), + flags: 0, + cull_mode: vk::CULL_MODE_NONE, + depth_bias_clamp: 0.0, + depth_bias_constant_factor: 0.0, + depth_bias_enable: 0, + depth_bias_slope_factor: 0.0, + depth_clamp_enable: 0, + front_face: vk::FrontFace::CounterClockwise, + line_width: 1.0, + polygon_mode: vk::PolygonMode::Fill, + rasterizer_discard_enable: 0, + }; + let multisample_state_info = vk::PipelineMultisampleStateCreateInfo { + s_type: vk::StructureType::PipelineMultisampleStateCreateInfo, + flags: 0, + p_next: ptr::null(), + rasterization_samples: vk::SAMPLE_COUNT_1_BIT, + sample_shading_enable: 0, + min_sample_shading: 0.0, + p_sample_mask: ptr::null(), + alpha_to_one_enable: 0, + alpha_to_coverage_enable: 0, + }; + let noop_stencil_state = vk::StencilOpState { + fail_op: vk::StencilOp::Keep, + pass_op: vk::StencilOp::Keep, + depth_fail_op: vk::StencilOp::Keep, + compare_op: vk::CompareOp::Always, + compare_mask: 0, + write_mask: 0, + reference: 0, + }; + let depth_state_info = vk::PipelineDepthStencilStateCreateInfo { + s_type: vk::StructureType::PipelineDepthStencilStateCreateInfo, + p_next: ptr::null(), + flags: 0, + depth_test_enable: 1, + depth_write_enable: 1, + depth_compare_op: vk::CompareOp::LessOrEqual, + depth_bounds_test_enable: 0, + stencil_test_enable: 0, + front: noop_stencil_state.clone(), + back: noop_stencil_state.clone(), + // TODO: correct? + max_depth_bounds: 0.0, + min_depth_bounds: 0.0, + }; + let color_blend_attachment_states = [vk::PipelineColorBlendAttachmentState { + blend_enable: 0, + src_color_blend_factor: vk::BlendFactor::SrcColor, + dst_color_blend_factor: + vk::BlendFactor::OneMinusDstColor, + color_blend_op: vk::BlendOp::Add, + src_alpha_blend_factor: vk::BlendFactor::Zero, + dst_alpha_blend_factor: vk::BlendFactor::Zero, + alpha_blend_op: vk::BlendOp::Add, + color_write_mask: vk::ColorComponentFlags::all(), + }]; + let color_blend_state = vk::PipelineColorBlendStateCreateInfo { + s_type: vk::StructureType::PipelineColorBlendStateCreateInfo, + p_next: ptr::null(), + flags: 0, + logic_op_enable: 0, + logic_op: vk::LogicOp::Clear, + attachment_count: color_blend_attachment_states.len() as u32, + p_attachments: color_blend_attachment_states.as_ptr(), + blend_constants: [0.0, 0.0, 0.0, 0.0], + }; + // VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo; + // dynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + // dynamicStateCreateInfo.dynamicStateCount = 2; + // dynamicStateCreateInfo.pDynamicStates = dynamicState.ptr; + let dynamic_state = [vk::DynamicState::Viewport, vk::DynamicState::Scissor]; + let dynamic_state_info = vk::PipelineDynamicStateCreateInfo { + s_type: vk::StructureType::PipelineDynamicStateCreateInfo, + p_next: ptr::null(), + flags: 0, + dynamic_state_count: dynamic_state.len() as u32, + p_dynamic_states: dynamic_state.as_ptr(), + }; + let graphic_pipeline_info = vk::GraphicsPipelineCreateInfo { + s_type: vk::StructureType::GraphicsPipelineCreateInfo, + p_next: ptr::null(), + flags: vk::PipelineCreateFlags::empty(), + stage_count: shader_stage_create_infos.len() as u32, + p_stages: shader_stage_create_infos.as_ptr(), + p_vertex_input_state: &vertex_input_state_info, + p_input_assembly_state: &vertex_input_assembly_state_info, + p_tessellation_state: ptr::null(), + p_viewport_state: &viewport_state_info, + p_rasterization_state: &rasterization_info, + p_multisample_state: &multisample_state_info, + p_depth_stencil_state: &depth_state_info, + p_color_blend_state: &color_blend_state, + p_dynamic_state: &dynamic_state_info, + layout: pipeline_layout, + render_pass: renderpass, + subpass: 0, + base_pipeline_handle: vk::Pipeline::null(), + base_pipeline_index: 0, + }; + + let graphics_pipelines = + device.create_graphics_pipelines(vk::PipelineCache::null(), &[graphic_pipeline_info]) + .unwrap(); + + let graphic_pipeline = graphics_pipelines[0]; + printlndb!(graphic_pipeline); + + for pipeline in graphics_pipelines { + device.destroy_pipeline(pipeline); + } + device.destroy_pipeline_layout(pipeline_layout); device.destroy_shader_module(vertex_shader_module); - device.destroy_shader_module(frag_shader_module); + device.destroy_shader_module(fragment_shader_module); device.free_memory(vertex_input_buffer_memory); device.destroy_buffer(vertex_input_buffer); for framebuffer in framebuffers {