Advertisement
Guest User

main.rs

a guest
Nov 15th, 2018
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 15.84 KB | None | 0 0
  1. extern crate gfx_backend_vulkan as back;
  2. extern crate gfx_hal;
  3. extern crate glsl_to_spirv;
  4. extern crate winit;
  5.  
  6. #[macro_use]
  7. extern crate memoffset;
  8.  
  9. use std::io::Read;
  10. use std::mem;
  11. use std::path::Path;
  12.  
  13. use gfx_hal::adapter::{MemoryType, MemoryTypeId, PhysicalDevice};
  14. use gfx_hal::command::{ClearColor, ClearValue, BufferCopy};
  15. use gfx_hal::format::{Aspects, ChannelType, Format, Swizzle};
  16. use gfx_hal::image::{Access, Extent, Layout, SubresourceRange, ViewKind};
  17. use gfx_hal::memory::Properties;
  18. use gfx_hal::pass::{
  19.     Attachment, AttachmentLoadOp, AttachmentOps, AttachmentStoreOp, Subpass, SubpassDependency,
  20.     SubpassDesc, SubpassRef,
  21. };
  22. use gfx_hal::pool::{CommandPool, CommandPoolCreateFlags};
  23. use gfx_hal::pso::{
  24.     AttributeDesc, ColorBlendDesc, Element, EntryPoint, GraphicsPipelineDesc, GraphicsShaderSet,
  25.     PipelineStage, Rasterizer, Rect, VertexBufferDesc, Viewport,
  26. };
  27. use gfx_hal::queue::submission::Submission;
  28. use gfx_hal::queue::CommandQueue;
  29. use gfx_hal::window::{Backbuffer, FrameSync, PresentMode, Swapchain, SwapchainConfig};
  30. use gfx_hal::{buffer, Backend, Device, Instance, Primitive, Surface, Graphics};
  31.  
  32. use glsl_to_spirv::ShaderType;
  33.  
  34. #[derive(Debug, Copy, Clone)]
  35. pub struct Vertex {
  36.     pos: [f32; 2],
  37.     color: [f32; 3],
  38. }
  39.  
  40. impl Vertex {
  41.     pub fn new(pos: [f32; 2], color: [f32; 3]) -> Vertex {
  42.         Vertex { pos, color }
  43.     }
  44. }
  45.  
  46. fn main() {
  47.     let instance = back::Instance::create("hell", 1);
  48.     let mut adapters = instance.enumerate_adapters();
  49.  
  50.     println!("Extensions: {:?}", instance.extensions);
  51.     println!("Adapters: ");
  52.     for (i, adapter) in adapters.iter().enumerate() {
  53.         println!("  {}: {:?}", i, adapter.info);
  54.     }
  55.  
  56.     let mut adapter = adapters.remove(0);
  57.  
  58.     let memory_properties = adapter.physical_device.memory_properties();
  59.     let memory_types = memory_properties.memory_types;
  60.  
  61.     let mut events_loop = winit::EventsLoop::new();
  62.     let window = winit::WindowBuilder::new()
  63.         .with_dimensions((800, 600).into())
  64.         .with_resizable(false)
  65.         .with_title("Hell")
  66.         .build(&events_loop)
  67.         .expect("Failed to create window");
  68.  
  69.     let mut surface = instance.create_surface(&window);
  70.  
  71.     let (device, mut queues) = adapter
  72.         .open_with::<_, Graphics>(1, |f| surface.supports_queue_family(f))
  73.         .expect("Failed to create logical device");
  74.  
  75.     let (caps, formats, _) = surface.compatibility(&adapter.physical_device);
  76.  
  77.     let formats = formats.unwrap_or(vec![Format::Rgba8Srgb]);
  78.     let format = formats
  79.         .iter()
  80.         .find(|f| f.base_format().1 == ChannelType::Srgb)
  81.         .cloned()
  82.         .unwrap_or(formats[0]);
  83.  
  84.     let present_mode = PresentMode::Immediate;
  85.  
  86.     let mut swapchain_config = SwapchainConfig::from_caps(&caps, format);
  87.     swapchain_config.present_mode = present_mode;
  88.     let extent = swapchain_config.extent.to_extent();
  89.  
  90.     let (mut swapchain, mut backbuffer) = device
  91.         .create_swapchain(&mut surface, swapchain_config, None)
  92.         .expect("Failed to create swapchain");
  93.  
  94.     let attachment = Attachment {
  95.         format: Some(format),
  96.         samples: 1,
  97.         ops: AttachmentOps::new(AttachmentLoadOp::Clear, AttachmentStoreOp::Store),
  98.         stencil_ops: AttachmentOps::DONT_CARE,
  99.         layouts: Layout::Undefined..Layout::Present,
  100.     };
  101.  
  102.     let subpass_desc = SubpassDesc {
  103.         colors: &[(0, Layout::ColorAttachmentOptimal)],
  104.         depth_stencil: None,
  105.         inputs: &[],
  106.         resolves: &[],
  107.         preserves: &[],
  108.     };
  109.  
  110.     let dependency = SubpassDependency {
  111.         passes: SubpassRef::External..SubpassRef::Pass(0),
  112.         stages: PipelineStage::COLOR_ATTACHMENT_OUTPUT..PipelineStage::COLOR_ATTACHMENT_OUTPUT,
  113.         accesses: Access::empty()..(Access::COLOR_ATTACHMENT_READ | Access::COLOR_ATTACHMENT_WRITE),
  114.     };
  115.  
  116.     let render_pass = device
  117.         .create_render_pass(&[attachment], &[subpass_desc], &[dependency])
  118.         .expect("Failed to create render pass");
  119.  
  120.     let pipeline_layout = device
  121.         .create_pipeline_layout(&[], &[])
  122.         .expect("Failed to create pipeline layout");
  123.  
  124.     let vert_shader = load_shader::<back::Backend, _>(&device, "shader.vert", ShaderType::Vertex);
  125.     let frag_shader = load_shader::<back::Backend, _>(&device, "shader.frag", ShaderType::Fragment);
  126.  
  127.     let pipeline = {
  128.         let vert_entry = EntryPoint::<back::Backend> {
  129.             entry: "main",
  130.             module: &vert_shader,
  131.             specialization: Default::default(),
  132.         };
  133.  
  134.         let frag_entry = EntryPoint::<back::Backend> {
  135.             entry: "main",
  136.             module: &frag_shader,
  137.             specialization: Default::default(),
  138.         };
  139.  
  140.         let shader_set = GraphicsShaderSet {
  141.             vertex: vert_entry,
  142.             fragment: Some(frag_entry),
  143.             hull: None,
  144.             domain: None,
  145.             geometry: None,
  146.         };
  147.  
  148.         let subpass = Subpass {
  149.             index: 0,
  150.             main_pass: &render_pass,
  151.         };
  152.  
  153.         let mut pipeline_desc = GraphicsPipelineDesc::new(
  154.             shader_set,
  155.             Primitive::TriangleList,
  156.             Rasterizer::FILL,
  157.             &pipeline_layout,
  158.             subpass,
  159.         );
  160.  
  161.         pipeline_desc.blender.targets.push(ColorBlendDesc::EMPTY);
  162.  
  163.         pipeline_desc.vertex_buffers.push(VertexBufferDesc {
  164.             binding: 0,
  165.             stride: mem::size_of::<Vertex>() as _,
  166.             rate: 0,
  167.         });
  168.  
  169.         pipeline_desc.attributes.push(AttributeDesc {
  170.             location: 0,
  171.             binding: 0,
  172.             element: Element {
  173.                 format: Format::Rg32Float,
  174.                 offset: offset_of!(Vertex, pos) as _,
  175.             },
  176.         });
  177.  
  178.         pipeline_desc.attributes.push(AttributeDesc {
  179.             location: 1,
  180.             binding: 0,
  181.             element: Element {
  182.                 format: Format::Rgb32Float,
  183.                 offset: offset_of!(Vertex, color) as _,
  184.             },
  185.         });
  186.  
  187.         let pipeline = device
  188.             .create_graphics_pipeline(&pipeline_desc, None)
  189.             .expect("Failed to create graphics pipeline");
  190.  
  191.         pipeline
  192.     };
  193.  
  194.     device.destroy_shader_module(vert_shader);
  195.     device.destroy_shader_module(frag_shader);
  196.  
  197.     let (mut frameviews, mut framebuffers) =
  198.         expand_backbuffer(&device, backbuffer, format, &render_pass, extent);
  199.  
  200.     let mut command_pool = device
  201.         .create_command_pool_typed(&queues, CommandPoolCreateFlags::empty(), 16)
  202.         .expect("Failed to create command pool");
  203.  
  204.     let vertices = &[
  205.         Vertex::new([-0.5, -0.5], [1.0, 0.0, 0.0]),
  206.         Vertex::new([0.5, -0.5], [0.0, 1.0, 0.0]),
  207.         Vertex::new([-0.5, 0.5], [0.0, 0.0, 1.0]),
  208.         Vertex::new([-0.5, 0.5], [0.0, 0.0, 1.0]),
  209.         Vertex::new([0.5, -0.5], [0.0, 1.0, 0.0]),
  210.         Vertex::new([0.5, 0.5], [1.0, 1.0, 0.0]),
  211.     ];
  212.  
  213.     let (vbuf, vbuf_memory) =
  214.         create_vertex_buffer::<back::Backend, _>(&device, &memory_types, vertices, &mut command_pool, &mut queues.queues[0]);
  215.  
  216.     let mut viewport = Viewport {
  217.         rect: Rect {
  218.             x: 0,
  219.             y: 0,
  220.             w: extent.width as _,
  221.             h: extent.height as _,
  222.         },
  223.         depth: 0.0..1.0,
  224.     };
  225.  
  226.     let mut frame_semaphore = device
  227.         .create_semaphore()
  228.         .expect("Failed to create semaphore");
  229.     let mut frame_fence = device.create_fence(false).expect("Failed to create fence");
  230.  
  231.     let mut running = true;
  232.     let mut recreate_swapchain = false;
  233.  
  234.     let mut frames = 0;
  235.     let mut instant = std::time::Instant::now();
  236.  
  237.     while running {
  238.         events_loop.poll_events(|event| {
  239.             if let winit::Event::WindowEvent { event, .. } = event {
  240.                 match event {
  241.                     winit::WindowEvent::CloseRequested => running = false,
  242.                     winit::WindowEvent::Resized(_) => recreate_swapchain = true,
  243.                     _ => {}
  244.                 }
  245.             }
  246.         });
  247.  
  248.         if recreate_swapchain {
  249.             device.wait_idle().unwrap();
  250.             let (caps, ..) = surface.compatibility(&mut adapter.physical_device);
  251.  
  252.             let mut swapchain_config = SwapchainConfig::from_caps(&caps, format);
  253.             swapchain_config.present_mode = present_mode;
  254.  
  255.             let extent = swapchain_config.extent.to_extent();
  256.  
  257.             let (new_swapchain, new_backbuffer) = device
  258.                 .create_swapchain(&mut surface, swapchain_config, Some(swapchain))
  259.                 .expect("Failed to recreate swapchain");
  260.  
  261.             for framebuffer in framebuffers {
  262.                 device.destroy_framebuffer(framebuffer);
  263.             }
  264.  
  265.             for view in frameviews {
  266.                 device.destroy_image_view(view);
  267.             }
  268.  
  269.             swapchain = new_swapchain;
  270.             backbuffer = new_backbuffer;
  271.  
  272.             let (new_frameviews, new_framebuffers) =
  273.                 expand_backbuffer(&device, backbuffer, format, &render_pass, extent);
  274.             frameviews = new_frameviews;
  275.             framebuffers = new_framebuffers;
  276.  
  277.             viewport.rect.w = extent.width as _;
  278.             viewport.rect.h = extent.height as _;
  279.  
  280.             recreate_swapchain = false;
  281.         }
  282.  
  283.         device.reset_fence(&frame_fence).unwrap();
  284.         command_pool.reset();
  285.  
  286.         let frame = match swapchain.acquire_image(!0, FrameSync::Semaphore(&mut frame_semaphore)) {
  287.             Ok(v) => v,
  288.             Err(_) => {
  289.                 recreate_swapchain = true;
  290.                 continue;
  291.             }
  292.         };
  293.  
  294.         let mut command_buffer = command_pool.acquire_command_buffer(false);
  295.  
  296.         command_buffer.set_viewports(0, &[viewport.clone()]);
  297.         command_buffer.set_scissors(0, &[viewport.rect]);
  298.         command_buffer.bind_graphics_pipeline(&pipeline);
  299.         command_buffer.bind_vertex_buffers(0, Some((&vbuf, 0)));
  300.  
  301.         {
  302.             let mut encoder = command_buffer.begin_render_pass_inline(
  303.                 &render_pass,
  304.                 &framebuffers[frame as usize],
  305.                 viewport.rect,
  306.                 &[ClearValue::Color(ClearColor::Float([0.0, 0.0, 0.0, 1.0]))],
  307.             );
  308.  
  309.             encoder.draw(0..6, 0..1);
  310.         }
  311.  
  312.         let submit = command_buffer.finish();
  313.  
  314.         let submission = Submission::new()
  315.             .wait_on(&[(&frame_semaphore, PipelineStage::BOTTOM_OF_PIPE)])
  316.             .submit(Some(submit));
  317.  
  318.         queues.queues[0].submit(submission, Some(&mut frame_fence));
  319.  
  320.         device.wait_for_fence(&frame_fence, !0).unwrap();
  321.  
  322.         if swapchain.present(&mut queues.queues[0], frame, &[]).is_err() {
  323.             recreate_swapchain = true;
  324.         }
  325.  
  326.         frames += 1;
  327.         if instant.elapsed() > std::time::Duration::from_secs(5) {
  328.             let t = instant.elapsed();
  329.             println!(
  330.                 "{} frames in {:?} @ {} fps",
  331.                 frames,
  332.                 t,
  333.                 frames as f32 / (t.as_secs() as f32 + t.subsec_nanos() as f32 / 1_000_000_000.0)
  334.             );
  335.             frames = 0;
  336.             instant = std::time::Instant::now();
  337.         }
  338.     }
  339.  
  340.     device.wait_idle().unwrap();
  341.  
  342.     device.destroy_command_pool(command_pool.into_raw());
  343.  
  344.     for framebuffer in framebuffers {
  345.         device.destroy_framebuffer(framebuffer);
  346.     }
  347.  
  348.     for view in frameviews {
  349.         device.destroy_image_view(view);
  350.     }
  351.  
  352.     device.destroy_buffer(vbuf);
  353.     device.free_memory(vbuf_memory);
  354.  
  355.     device.destroy_fence(frame_fence);
  356.     device.destroy_semaphore(frame_semaphore);
  357.     device.destroy_render_pass(render_pass);
  358.     device.destroy_graphics_pipeline(pipeline);
  359.     device.destroy_pipeline_layout(pipeline_layout);
  360.     device.destroy_swapchain(swapchain);
  361. }
  362.  
  363. fn expand_backbuffer<B: Backend>(
  364.     device: &B::Device,
  365.     backbuffer: Backbuffer<B>,
  366.     format: Format,
  367.     render_pass: &B::RenderPass,
  368.     extent: Extent,
  369. ) -> (Vec<B::ImageView>, Vec<B::Framebuffer>) {
  370.     match backbuffer {
  371.         Backbuffer::Images(images) => {
  372.             let range = SubresourceRange {
  373.                 aspects: Aspects::COLOR,
  374.                 levels: 0..1,
  375.                 layers: 0..1,
  376.             };
  377.  
  378.             let views = images
  379.                 .iter()
  380.                 .map(|image| {
  381.                     device
  382.                         .create_image_view(&image, ViewKind::D2, format, Swizzle::NO, range.clone())
  383.                         .expect("Failed to create image view")
  384.                 })
  385.                 .collect::<Vec<_>>();
  386.  
  387.             let framebuffers = views
  388.                 .iter()
  389.                 .map(|view| {
  390.                     device
  391.                         .create_framebuffer(&render_pass, Some(view), extent)
  392.                         .expect("Failed to create framebuffer")
  393.                 })
  394.                 .collect::<Vec<_>>();
  395.  
  396.             (views, framebuffers)
  397.         }
  398.  
  399.         Backbuffer::Framebuffer(framebuffer) => (vec![], vec![framebuffer]),
  400.     }
  401. }
  402.  
  403. fn load_shader<B: Backend, P: AsRef<Path>>(
  404.     device: &B::Device,
  405.     path: P,
  406.     ty: ShaderType,
  407. ) -> B::ShaderModule {
  408.     let source = std::fs::read_to_string(path).expect("Failed to read shader source");
  409.     let code = glsl_to_spirv::compile(&source, ty)
  410.         .expect("Failed to compile shader")
  411.         .bytes()
  412.         .map(|b| b.unwrap())
  413.         .collect::<Vec<_>>();
  414.  
  415.     device
  416.         .create_shader_module(&code)
  417.         .expect("Failed to create shader module")
  418. }
  419.  
  420. fn select_heap(types: &[MemoryType], mask: u64, props: Properties) -> MemoryTypeId {
  421.     types
  422.         .iter()
  423.         .enumerate()
  424.         .position(|(id, ty)| mask & (1 << id) != 0 && ty.properties.contains(props))
  425.         .expect("No suitable memory heap")
  426.         .into()
  427. }
  428.  
  429. fn create_buffer<B: Backend>(
  430.     device: &B::Device,
  431.     types: &[MemoryType],
  432.     size: u64,
  433.     usage: buffer::Usage,
  434.     props: Properties,
  435. ) -> (B::Buffer, B::Memory) {
  436.     let unbounded = device
  437.         .create_buffer(size, usage)
  438.         .expect("Failed to create vertex buffer");
  439.  
  440.     let req = device.get_buffer_requirements(&unbounded);
  441.     let heap = select_heap(&types, req.type_mask, props);
  442.  
  443.     let memory = device
  444.         .allocate_memory(heap, req.size)
  445.         .expect("Failed to allocate memory");
  446.  
  447.     let buffer = device
  448.         .bind_buffer_memory(&memory, 0, unbounded)
  449.         .expect("Failed to bind memory");
  450.  
  451.     (buffer, memory)
  452. }
  453.  
  454. fn create_vertex_buffer<B: Backend, V: Copy>(
  455.     device: &B::Device,
  456.     types: &[MemoryType],
  457.     vertices: &[V],
  458.     command_pool: &mut CommandPool<B, Graphics>,
  459.     queue: &mut CommandQueue<B, Graphics>
  460. ) -> (B::Buffer, B::Memory) {
  461.     use buffer::Usage;
  462.  
  463.     let len = (vertices.len() * mem::size_of::<V>()) as _;
  464.  
  465.     let (vertex_buffer, vertex_memory) =
  466.         create_buffer::<B>(device, types, len, Usage::VERTEX, Properties::DEVICE_LOCAL);
  467.  
  468.     let (staging_buffer, staging_memory) =
  469.         create_buffer::<B>(device, types, len, Usage::VERTEX, Properties::CPU_VISIBLE);
  470.  
  471.     {
  472.         let mut writer = device
  473.             .acquire_mapping_writer(&staging_memory, 0..len)
  474.             .expect("Failed to map memory for writing");
  475.  
  476.         writer.copy_from_slice(vertices);
  477.         device.release_mapping_writer(writer).unwrap();
  478.     }
  479.  
  480.     let mut command_buffer = command_pool.acquire_command_buffer(false);
  481.  
  482.     command_buffer.copy_buffer(
  483.         &staging_buffer,
  484.         &vertex_buffer,
  485.         Some(BufferCopy {
  486.             src: 0,
  487.             dst: 0,
  488.             size: len
  489.         })
  490.     );
  491.  
  492.     let submit = command_buffer.finish();
  493.  
  494.     let submission = Submission::new()
  495.         .submit(Some(submit));
  496.  
  497.     queue.submit(submission, None);
  498.  
  499.     device.wait_idle().unwrap();
  500.  
  501.     device.destroy_buffer(staging_buffer);
  502.     device.free_memory(staging_memory);
  503.  
  504.     (vertex_buffer, vertex_memory)
  505. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement