SHARE
TWEET

Untitled

a guest Aug 17th, 2019 124 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. use arrayvec::ArrayVec;
  2. use core::mem::ManuallyDrop;
  3. use gfx_hal::{
  4.     adapter::{Adapter, PhysicalDevice},
  5.     buffer::{self, IndexBufferView},
  6.     command::{ClearColor, ClearValue, CommandBuffer, MultiShot, Primary},
  7.     device::Device,
  8.     format::{Aspects, ChannelType, Format, Swizzle},
  9.     image::{Extent, Layout, SubresourceRange, Usage, ViewKind},
  10.     pass::{Attachment, AttachmentLoadOp, AttachmentOps, AttachmentStoreOp, Subpass, SubpassDesc},
  11.     pool::{CommandPool, CommandPoolCreateFlags},
  12.     pso::{
  13.         AttributeDesc, BakedStates, BasePipeline, BlendDesc, BlendOp, BlendState, ColorBlendDesc,
  14.         ColorMask, DepthStencilDesc, DescriptorRangeDesc, DescriptorSetLayoutBinding,
  15.         DescriptorType, ElemOffset, ElemStride, Element, EntryPoint, Face, Factor, FrontFace,
  16.         GraphicsPipelineDesc, GraphicsShaderSet, InputAssemblerDesc, LogicOp,
  17.         PipelineCreationFlags, PipelineStage, PolygonMode, PrimitiveRestart, Rasterizer, Rect,
  18.         ShaderStageFlags, Specialization, VertexBufferDesc, VertexInputRate, Viewport,
  19.     },
  20.     queue::{family::QueueGroup, Submission},
  21.     window::{Extent2D, PresentMode, Suboptimal, Surface, Swapchain, SwapchainConfig},
  22.     Backend, DescriptorPool, Features, Gpu, Graphics, IndexType, Instance, Primitive, QueueFamily,
  23. };
  24. use std::{borrow::Cow, mem::size_of, ops::Deref, time::Instant};
  25. use winit::Window;
  26.  
  27. #[cfg(feature = "dx12")]
  28. use gfx_backend_dx12 as back;
  29. #[cfg(feature = "metal")]
  30. use gfx_backend_metal as back;
  31. #[cfg(feature = "vulkan")]
  32. use gfx_backend_vulkan as back;
  33.  
  34. use super::{BufferBundle, LoadedImage, Quad, Sprite, SpriteName};
  35.  
  36. pub const VERTEX_SOURCE: &str = include_str!("shaders/vert_default.vert");
  37. pub const FRAGMENT_SOURCE: &str = include_str!("shaders/frag_default.frag");
  38.  
  39. pub struct Renderer<I: Instance> {
  40.     // Top
  41.     _instance: ManuallyDrop<I>,
  42.     _surface: <I::Backend as Backend>::Surface,
  43.     _adapter: Adapter<I::Backend>,
  44.     queue_group: ManuallyDrop<QueueGroup<I::Backend, Graphics>>,
  45.     device: ManuallyDrop<<I::Backend as Backend>::Device>,
  46.  
  47.     // Pipeline nonsense
  48.     vertices: BufferBundle<I::Backend>,
  49.     indexes: BufferBundle<I::Backend>,
  50.     descriptor_set_layouts: Vec<<I::Backend as Backend>::DescriptorSetLayout>,
  51.     descriptor_pool: ManuallyDrop<<I::Backend as Backend>::DescriptorPool>,
  52.     pipeline_layout: ManuallyDrop<<I::Backend as Backend>::PipelineLayout>,
  53.     graphics_pipeline: ManuallyDrop<<I::Backend as Backend>::GraphicsPipeline>,
  54.  
  55.     // GPU Swapchain
  56.     textures: Vec<LoadedImage<I::Backend>>,
  57.     swapchain: ManuallyDrop<<I::Backend as Backend>::Swapchain>,
  58.     render_area: Rect,
  59.     in_flight_fences: Vec<<I::Backend as Backend>::Fence>,
  60.     frames_in_flight: usize,
  61.     image_available_semaphores: Vec<<I::Backend as Backend>::Semaphore>,
  62.     render_finished_semaphores: Vec<<I::Backend as Backend>::Semaphore>,
  63.  
  64.     // Render Pass
  65.     render_pass: ManuallyDrop<<I::Backend as Backend>::RenderPass>,
  66.  
  67.     // Render Targets
  68.     image_views: Vec<(<I::Backend as Backend>::ImageView)>,
  69.     framebuffers: Vec<<I::Backend as Backend>::Framebuffer>,
  70.  
  71.     // Command Issues
  72.     command_pool: ManuallyDrop<CommandPool<I::Backend, Graphics>>,
  73.     command_buffers: Vec<CommandBuffer<I::Backend, Graphics, MultiShot, Primary>>,
  74.  
  75.     // Mis
  76.     current_frame: usize,
  77.     creation_time: Instant,
  78. }
  79.  
  80. pub type TypedRenderer = Renderer<back::Instance>;
  81. impl<I: Instance> Renderer<I> {
  82.     pub fn typed_new(
  83.         window: &Window,
  84.         window_name: &str,
  85.         sprite_info: &'static [(SpriteName, &[u8])],
  86.     ) -> Result<(TypedRenderer, Vec<Sprite>), &'static str> {
  87.         // Create An Instance
  88.         let instance = back::Instance::create(window_name, 1);
  89.         // Create A Surface
  90.         let surface = instance.create_surface(window);
  91.         // Create A HalState
  92.         let mut tr = TypedRenderer::new(window, instance, surface)?;
  93.         let sprites = tr.record_textures(sprite_info)?;
  94.  
  95.         Ok((tr, sprites))
  96.     }
  97.  
  98.     pub fn new(
  99.         window: &Window,
  100.         instance: I,
  101.         mut surface: <I::Backend as Backend>::Surface,
  102.     ) -> Result<Self, &'static str> {
  103.         let creation_time = Instant::now();
  104.  
  105.         let adapter = instance
  106.             .enumerate_adapters()
  107.             .into_iter()
  108.             .find(|a| {
  109.                 a.queue_families
  110.                     .iter()
  111.                     .any(|qf| qf.supports_graphics() && surface.supports_queue_family(qf))
  112.             })
  113.             .ok_or("Couldn't find a graphical adapter!")?;
  114.  
  115.         // open it up!
  116.         let (mut device, queue_group) = {
  117.             let queue_family = adapter
  118.                 .queue_families
  119.                 .iter()
  120.                 .find(|qf| qf.supports_graphics() && surface.supports_queue_family(qf))
  121.                 .ok_or("Couldn't find a QueueFamily with graphics!")?;
  122.  
  123.             let Gpu { device, mut queues } = unsafe {
  124.                 adapter
  125.                     .physical_device
  126.                     .open(&[(queue_family, &[1.0; 1])], Features::empty())
  127.                     .map_err(|_| "Couldn't open the PhysicalDevice!")?
  128.             };
  129.  
  130.             let queue_group = queues
  131.                 .take::<Graphics>(queue_family.id())
  132.                 .expect("Couldn't take ownership of the QueueGroup!");
  133.  
  134.             if queue_group.queues.len() == 0 {
  135.                 return Err("The QueueGroup did not have any CommandQueues available");
  136.             }
  137.             (device, queue_group)
  138.         };
  139.  
  140.         let (swapchain, extent, backbuffer, format, frames_in_flight) = {
  141.             // no composite alpha here
  142.             let (caps, preferred_formats, present_modes) =
  143.                 surface.compatibility(&adapter.physical_device);
  144.             trace!("{:?}", caps);
  145.             trace!("Preferred Formats: {:?}", preferred_formats);
  146.             trace!("Present Modes: {:?}", present_modes);
  147.  
  148.             let present_mode = {
  149.                 use gfx_hal::window::PresentMode::*;
  150.                 [Mailbox, Fifo, Relaxed, Immediate]
  151.                     .iter()
  152.                     .cloned()
  153.                     .find(|pm| present_modes.contains(pm))
  154.                     .ok_or("No PresentMode values specified!")?
  155.             };
  156.  
  157.             use gfx_hal::window::CompositeAlpha;
  158.             trace!("We're setting composite alpha to opaque...Need to figure out where to find the user's intent.");
  159.             let composite_alpha = CompositeAlpha::OPAQUE;
  160.  
  161.             let format = match preferred_formats {
  162.                 None => Format::Rgba8Srgb,
  163.                 Some(formats) => match formats
  164.                     .iter()
  165.                     .find(|format| format.base_format().1 == ChannelType::Srgb)
  166.                     .cloned()
  167.                 {
  168.                     Some(srgb_format) => srgb_format,
  169.                     None => formats
  170.                         .get(0)
  171.                         .cloned()
  172.                         .ok_or("Preferred format list was empty!")?,
  173.                 },
  174.             };
  175.  
  176.             let extent = {
  177.                 let window_client_area = window
  178.                     .get_inner_size()
  179.                     .ok_or("Window doesn't exist!")?
  180.                     .to_physical(window.get_hidpi_factor());
  181.  
  182.                 Extent2D {
  183.                     width: caps
  184.                         .extents
  185.                         .end()
  186.                         .width
  187.                         .min(window_client_area.width as u32),
  188.                     height: caps
  189.                         .extents
  190.                         .end()
  191.                         .height
  192.                         .min(window_client_area.height as u32),
  193.                 }
  194.             };
  195.  
  196.             let image_count = if present_mode == PresentMode::Mailbox {
  197.                 (caps.image_count.end() - 1).min(*caps.image_count.start().max(&3))
  198.             } else {
  199.                 (caps.image_count.end() - 1).min(*caps.image_count.start().max(&2))
  200.             };
  201.  
  202.             let image_layers = 1;
  203.             if caps.usage.contains(Usage::COLOR_ATTACHMENT) == false {
  204.                 return Err("The Surface isn't capable of supporting color!");
  205.             }
  206.  
  207.             let image_usage = Usage::COLOR_ATTACHMENT;
  208.  
  209.             let swapchain_config = SwapchainConfig {
  210.                 present_mode,
  211.                 composite_alpha,
  212.                 format,
  213.                 extent,
  214.                 image_count,
  215.                 image_layers,
  216.                 image_usage,
  217.             };
  218.  
  219.             trace!("{:?}", swapchain_config);
  220.  
  221.             // Final pop out. PHEW!
  222.             let (swapchain, backbuffer) = unsafe {
  223.                 device
  224.                     .create_swapchain(&mut surface, swapchain_config, None)
  225.                     .map_err(|_| "Failed to create the swapchain on the last step!")?
  226.             };
  227.  
  228.             (swapchain, extent, backbuffer, format, image_count as usize)
  229.         };
  230.  
  231.         let (image_available_semaphores, render_finished_semaphores, in_flight_fences) = {
  232.             let mut image_available_semaphores = vec![];
  233.             let mut render_finished_semaphores = vec![];
  234.             let mut in_flight_fences = vec![];
  235.             for _ in 0..frames_in_flight {
  236.                 in_flight_fences.push(
  237.                     device
  238.                         .create_fence(true)
  239.                         .map_err(|_| "Could not create a fence!")?,
  240.                 );
  241.                 image_available_semaphores.push(
  242.                     device
  243.                         .create_semaphore()
  244.                         .map_err(|_| "Could not create a semaphore!")?,
  245.                 );
  246.                 render_finished_semaphores.push(
  247.                     device
  248.                         .create_semaphore()
  249.                         .map_err(|_| "Could not create a semaphore!")?,
  250.                 );
  251.             }
  252.             (
  253.                 image_available_semaphores,
  254.                 render_finished_semaphores,
  255.                 in_flight_fences,
  256.             )
  257.         };
  258.  
  259.         let render_pass = {
  260.             let color_attachment = Attachment {
  261.                 format: Some(format),
  262.                 samples: 1,
  263.                 ops: AttachmentOps {
  264.                     load: AttachmentLoadOp::Clear,
  265.                     store: AttachmentStoreOp::Store,
  266.                 },
  267.                 stencil_ops: AttachmentOps::DONT_CARE,
  268.                 layouts: Layout::Undefined..Layout::Present,
  269.             };
  270.  
  271.             let subpass = SubpassDesc {
  272.                 colors: &[(0, Layout::ColorAttachmentOptimal)],
  273.                 depth_stencil: None,
  274.                 inputs: &[],
  275.                 resolves: &[],
  276.                 preserves: &[],
  277.             };
  278.  
  279.             unsafe {
  280.                 device
  281.                     .create_render_pass(&[color_attachment], &[subpass], &[])
  282.                     .map_err(|_| "Couldn't create a render pass!")?
  283.             }
  284.         };
  285.  
  286.         let image_views = {
  287.             backbuffer
  288.                 .into_iter()
  289.                 .map(|image| unsafe {
  290.                     device
  291.                         .create_image_view(
  292.                             &image,
  293.                             ViewKind::D2,
  294.                             format,
  295.                             Swizzle::NO,
  296.                             SubresourceRange {
  297.                                 aspects: Aspects::COLOR,
  298.                                 levels: 0..1,
  299.                                 layers: 0..1,
  300.                             },
  301.                         )
  302.                         .map_err(|_| "Couldn't create the image_view for the image!")
  303.                 })
  304.                 .collect::<Result<Vec<_>, &str>>()?
  305.         };
  306.  
  307.         let framebuffers = {
  308.             image_views
  309.                 .iter()
  310.                 .map(|image_view| unsafe {
  311.                     device
  312.                         .create_framebuffer(
  313.                             &render_pass,
  314.                             vec![image_view],
  315.                             Extent {
  316.                                 width: extent.width as u32,
  317.                                 height: extent.height as u32,
  318.                                 depth: 1,
  319.                             },
  320.                         )
  321.                         .map_err(|_| "Failed to create a framebuffer!")
  322.                 })
  323.                 .collect::<Result<Vec<_>, &str>>()?
  324.         };
  325.  
  326.         let mut command_pool = unsafe {
  327.             device
  328.                 .create_command_pool_typed(&queue_group, CommandPoolCreateFlags::RESET_INDIVIDUAL)
  329.                 .map_err(|_| "Could not create the raw command pool!")?
  330.         };
  331.  
  332.         let command_buffers: Vec<_> = framebuffers
  333.             .iter()
  334.             .map(|_| command_pool.acquire_command_buffer())
  335.             .collect();
  336.  
  337.         let (descriptor_set_layouts, descriptor_pool, pipeline_layout, graphics_pipeline) =
  338.             Self::create_pipeline(&mut device, extent, &render_pass)?;
  339.  
  340.         const F32_XY_RGB_UV_QUAD: u64 = (size_of::<f32>() * 2 * 3) as u64;
  341.         let vertices =
  342.             BufferBundle::new(&adapter, &device, F32_XY_RGB_UV_QUAD, buffer::Usage::VERTEX)?;
  343.         Renderer::<I>::bind_to_memory(&mut device, &vertices)?;
  344.  
  345.         const U16_QUAD_INDICES: u64 = (size_of::<u16>() * 2 * 3) as u64;
  346.         let indexes = BufferBundle::new(&adapter, &device, U16_QUAD_INDICES, buffer::Usage::INDEX)?;
  347.         Renderer::<I>::bind_to_memory(&mut device, &indexes)?;
  348.  
  349.         // WRITE INDEX DATA JUST ONCE
  350.         unsafe {
  351.             let mut data_target = device
  352.                 .acquire_mapping_writer(&indexes.memory, 0..indexes.requirements.size)
  353.                 .map_err(|_| "Failed to acquire an index buffer mapping writer!")?;
  354.  
  355.             const INDEX_DATA: &[u16] = &[0, 1, 2, 2, 3, 0];
  356.             data_target[..INDEX_DATA.len()].copy_from_slice(&INDEX_DATA);
  357.  
  358.             device
  359.                 .release_mapping_writer(data_target)
  360.                 .map_err(|_| "Couldn't release the index buffer mapping writer!")?;
  361.         }
  362.  
  363.         Ok(Self {
  364.             _instance: manual_new!(instance),
  365.             _surface: surface,
  366.             _adapter: adapter,
  367.             device: manual_new!(device),
  368.             queue_group: manual_new!(queue_group),
  369.             swapchain: manual_new!(swapchain),
  370.             render_area: extent.to_extent().rect(),
  371.             render_pass: manual_new!(render_pass),
  372.             image_views,
  373.             framebuffers,
  374.             command_pool: manual_new!(command_pool),
  375.             command_buffers,
  376.             image_available_semaphores,
  377.             render_finished_semaphores,
  378.             in_flight_fences,
  379.             frames_in_flight,
  380.             current_frame: 0,
  381.  
  382.             vertices,
  383.             indexes,
  384.             textures: vec![],
  385.             descriptor_set_layouts,
  386.             descriptor_pool: manual_new!(descriptor_pool),
  387.             pipeline_layout: manual_new!(pipeline_layout),
  388.             graphics_pipeline: manual_new!(graphics_pipeline),
  389.             creation_time,
  390.         })
  391.     }
  392.  
  393.     fn create_pipeline(
  394.         device: &mut <I::Backend as Backend>::Device,
  395.         extent: Extent2D,
  396.         render_pass: &<I::Backend as Backend>::RenderPass,
  397.     ) -> Result<
  398.         (
  399.             Vec<<I::Backend as Backend>::DescriptorSetLayout>,
  400.             <I::Backend as Backend>::DescriptorPool,
  401.             <I::Backend as Backend>::PipelineLayout,
  402.             <I::Backend as Backend>::GraphicsPipeline,
  403.         ),
  404.         &'static str,
  405.     > {
  406.         let mut compiler = shaderc::Compiler::new().ok_or("shaderc not found!")?;
  407.         let vertex_compile_artifact = compiler
  408.             .compile_into_spirv(
  409.                 VERTEX_SOURCE,
  410.                 shaderc::ShaderKind::Vertex,
  411.                 "vertex.vert",
  412.                 "main",
  413.                 None,
  414.             )
  415.             .map_err(|_| "Couldn't compile vertex shader!")?;
  416.  
  417.         let fragment_compile_artifact = compiler
  418.             .compile_into_spirv(
  419.                 FRAGMENT_SOURCE,
  420.                 shaderc::ShaderKind::Fragment,
  421.                 "fragment.frag",
  422.                 "main",
  423.                 None,
  424.             )
  425.             .map_err(|e| {
  426.                 error!("{}", e);
  427.                 "Couldn't compile fragment shader!"
  428.             })?;
  429.  
  430.         let vertex_shader_module = unsafe {
  431.             device
  432.                 .create_shader_module(vertex_compile_artifact.as_binary())
  433.                 .map_err(|_| "Couldn't make the vertex module!")?
  434.         };
  435.  
  436.         let fragment_shader_module = unsafe {
  437.             device
  438.                 .create_shader_module(fragment_compile_artifact.as_binary())
  439.                 .map_err(|_| "Couldn't make the fragment module!")?
  440.         };
  441.  
  442.         let (vs_entry, fs_entry) = (
  443.             EntryPoint {
  444.                 entry: "main",
  445.                 module: &vertex_shader_module,
  446.                 specialization: Specialization {
  447.                     constants: Cow::Borrowed(&[]),
  448.                     data: Cow::Borrowed(&[]),
  449.                 },
  450.             },
  451.             EntryPoint {
  452.                 entry: "main",
  453.                 module: &fragment_shader_module,
  454.                 specialization: Specialization {
  455.                     constants: Cow::Borrowed(&[]),
  456.                     data: Cow::Borrowed(&[]),
  457.                 },
  458.             },
  459.         );
  460.  
  461.         let input_assembler = InputAssemblerDesc {
  462.             primitive: Primitive::TriangleList,
  463.             primitive_restart: PrimitiveRestart::Disabled,
  464.         };
  465.  
  466.         let shaders = GraphicsShaderSet {
  467.             vertex: vs_entry,
  468.             fragment: Some(fs_entry),
  469.             domain: None,
  470.             geometry: None,
  471.             hull: None,
  472.         };
  473.  
  474.         const VERTEX_STRIDE: ElemStride = (size_of::<f32>() * (2 + 3 + 2)) as ElemStride;
  475.         let vertex_buffers = vec![VertexBufferDesc {
  476.             binding: 0,
  477.             stride: VERTEX_STRIDE,
  478.             rate: VertexInputRate::Vertex,
  479.         }];
  480.  
  481.         let position_attribute = AttributeDesc {
  482.             location: 0,
  483.             binding: 0,
  484.             element: Element {
  485.                 format: Format::Rg32Sfloat,
  486.                 offset: 0,
  487.             },
  488.         };
  489.  
  490.         let color_attribute = AttributeDesc {
  491.             location: 1,
  492.             binding: 0,
  493.             element: Element {
  494.                 format: Format::Rgb32Sfloat,
  495.                 offset: (size_of::<f32>() * 2) as ElemOffset,
  496.             },
  497.         };
  498.  
  499.         const UV_STRIDE: ElemStride = (size_of::<f32>() * 5) as ElemStride;
  500.         let uv_attribute = AttributeDesc {
  501.             location: 2,
  502.             binding: 0,
  503.             element: Element {
  504.                 format: Format::Rg32Sfloat,
  505.                 offset: UV_STRIDE,
  506.             },
  507.         };
  508.  
  509.         let attributes = vec![position_attribute, color_attribute, uv_attribute];
  510.  
  511.         let rasterizer = Rasterizer {
  512.             depth_clamping: false,
  513.             polygon_mode: PolygonMode::Fill,
  514.             cull_face: Face::NONE,
  515.             front_face: FrontFace::Clockwise,
  516.             depth_bias: None,
  517.             conservative: false,
  518.         };
  519.  
  520.         let depth_stencil = DepthStencilDesc {
  521.             depth: None,
  522.             depth_bounds: false,
  523.             stencil: None,
  524.         };
  525.  
  526.         let blender = {
  527.             let blend_state = BlendState {
  528.                 color: BlendOp::Add {
  529.                     src: Factor::One,
  530.                     dst: Factor::Zero,
  531.                 },
  532.                 alpha: BlendOp::Add {
  533.                     src: Factor::One,
  534.                     dst: Factor::Zero,
  535.                 },
  536.             };
  537.             BlendDesc {
  538.                 logic_op: Some(LogicOp::Copy),
  539.                 targets: vec![ColorBlendDesc {
  540.                     mask: ColorMask::ALL,
  541.                     blend: Some(blend_state),
  542.                 }],
  543.             }
  544.         };
  545.  
  546.         let baked_states = BakedStates {
  547.             viewport: Some(Viewport {
  548.                 rect: extent.to_extent().rect(),
  549.                 depth: (0.0..1.0),
  550.             }),
  551.             scissor: Some(extent.to_extent().rect()),
  552.             blend_color: None,
  553.             depth_bounds: None,
  554.         };
  555.  
  556.         let descriptor_set_layouts = vec![unsafe {
  557.             device
  558.                 .create_descriptor_set_layout(
  559.                     &[
  560.                         DescriptorSetLayoutBinding {
  561.                             binding: 0,
  562.                             ty: DescriptorType::SampledImage,
  563.                             count: 1,
  564.                             stage_flags: ShaderStageFlags::FRAGMENT,
  565.                             immutable_samplers: false,
  566.                         },
  567.                         DescriptorSetLayoutBinding {
  568.                             binding: 1,
  569.                             ty: DescriptorType::Sampler,
  570.                             count: 1,
  571.                             stage_flags: ShaderStageFlags::FRAGMENT,
  572.                             immutable_samplers: false,
  573.                         },
  574.                     ],
  575.                     &[],
  576.                 )
  577.                 .map_err(|_| "Couldn't make a DescriptorSetLayout!")?
  578.         }];
  579.  
  580.         let descriptor_pool = unsafe {
  581.             device
  582.                 .create_descriptor_pool(
  583.                     1,
  584.                     &[
  585.                         DescriptorRangeDesc {
  586.                             ty: DescriptorType::SampledImage,
  587.                             count: 2,
  588.                         },
  589.                         DescriptorRangeDesc {
  590.                             ty: DescriptorType::Sampler,
  591.                             count: 2,
  592.                         },
  593.                     ],
  594.                     gfx_hal::pso::DescriptorPoolCreateFlags::empty(),
  595.                 )
  596.                 .map_err(|_| "Couldn't create a descriptor pool!")?
  597.         };
  598.  
  599.         let push_constants = vec![(ShaderStageFlags::FRAGMENT, 0..1)];
  600.         let layout = unsafe {
  601.             device
  602.                 .create_pipeline_layout(&descriptor_set_layouts, push_constants)
  603.                 .map_err(|_| "Couldn't create a pipeline layout")?
  604.         };
  605.  
  606.         let gfx_pipeline = {
  607.             let desc = GraphicsPipelineDesc {
  608.                 shaders,
  609.                 rasterizer,
  610.                 vertex_buffers,
  611.                 attributes,
  612.                 input_assembler,
  613.                 blender,
  614.                 depth_stencil,
  615.                 multisampling: None,
  616.                 baked_states,
  617.                 layout: &layout,
  618.                 subpass: Subpass {
  619.                     index: 0,
  620.                     main_pass: render_pass,
  621.                 },
  622.                 flags: PipelineCreationFlags::empty(),
  623.                 parent: BasePipeline::None,
  624.             };
  625.  
  626.             unsafe {
  627.                 device
  628.                     .create_graphics_pipeline(&desc, None)
  629.                     .map_err(|_| "Couldn't create a graphics pipeline!")?
  630.             }
  631.         };
  632.  
  633.         Ok((
  634.             descriptor_set_layouts,
  635.             descriptor_pool,
  636.             layout,
  637.             gfx_pipeline,
  638.         ))
  639.     }
  640.  
  641.     fn bind_to_memory(device: &mut <I::Backend as Backend>::Device, buffer_bundle: &BufferBundle<I::Backend>, data: ) -> Result<(), &'static str> {
  642.         unsafe {
  643.             let mut data_target = device
  644.                 .acquire_mapping_writer(&buffer_bundle.memory, 0..buffer_bundle.requirements.size)
  645.                 .map_err(|_| "Failed to acquire an buffer mapping writer!")?;
  646.  
  647.             const INDEX_DATA: &[u16] = &[0, 1, 2, 2, 3, 0];
  648.             data_target[..INDEX_DATA.len()].copy_from_slice(&INDEX_DATA);
  649.  
  650.             device
  651.                 .release_mapping_writer(data_target)
  652.                 .map_err(|_| "Couldn't release the buffer mapping writer!")?;
  653.         };
  654.  
  655.         Ok(())
  656.     }
  657.  
  658.     fn record_textures<'a>(
  659.         &mut self,
  660.         sprite_info: &'static [(SpriteName, &'static [u8])],
  661.     ) -> Result<Vec<Sprite>, &'static str> {
  662.         let mut ret = vec![];
  663.         for (name, file) in sprite_info {
  664.             let texture = unsafe {
  665.                 let descriptor_set = self
  666.                     .descriptor_pool
  667.                     .allocate_set(&self.descriptor_set_layouts[0])
  668.                     .map_err(|_| "Couldn't make a Descriptor Set!")?;
  669.  
  670.                 println!("Made one descriptor set!");
  671.  
  672.                 LoadedImage::new(
  673.                     &self._adapter,
  674.                     &*self.device,
  675.                     &mut self.command_pool,
  676.                     &mut self.queue_group.queues[0],
  677.                     image::load_from_memory(file)
  678.                         .expect("Binary Corrupted!")
  679.                         .to_rgba(),
  680.                     descriptor_set,
  681.                 )?
  682.             };
  683.             let len = self.textures.len();
  684.             self.textures.push(texture);
  685.             ret.push(Sprite {
  686.                 name,
  687.                 file,
  688.                 texture: len,
  689.             });
  690.         }
  691.  
  692.         Ok(ret)
  693.     }
  694.  
  695.     pub fn draw_clear_frame(
  696.         &mut self,
  697.         color: [f32; 4],
  698.     ) -> Result<Option<Suboptimal>, &'static str> {
  699.         // SETUP FOR THIS FRAME
  700.         let image_available = &self.image_available_semaphores[self.current_frame];
  701.         let render_finished = &self.render_finished_semaphores[self.current_frame];
  702.         // Advance the frame _before_ we start using the `?` operator
  703.         self.current_frame = (self.current_frame + 1) % self.frames_in_flight;
  704.  
  705.         let (i_u32, i_usize) = unsafe {
  706.             let image_index = self
  707.                 .swapchain
  708.                 .acquire_image(core::u64::MAX, Some(image_available), None)
  709.                 .map_err(|_| "Couldn't acquire an image from the swapchain!")?;
  710.             (image_index.0, image_index.0 as usize)
  711.         };
  712.         let flight_fence = &self.in_flight_fences[i_usize];
  713.  
  714.         unsafe {
  715.             self.device
  716.                 .wait_for_fence(flight_fence, core::u64::MAX)
  717.                 .map_err(|_| "Failed to wait on the fence!")?;
  718.             self.device
  719.                 .reset_fence(flight_fence)
  720.                 .map_err(|_| "Couldn't reset the fence!")?;
  721.         }
  722.  
  723.         // RECORD COMMANDS
  724.         unsafe {
  725.             let buffer = &mut self.command_buffers[i_usize];
  726.             let clear_values = [ClearValue::Color(ClearColor::Sfloat(color))];
  727.             buffer.begin(false);
  728.             buffer.begin_render_pass_inline(
  729.                 &self.render_pass,
  730.                 &self.framebuffers[i_usize],
  731.                 self.render_area,
  732.                 clear_values.iter(),
  733.             );
  734.             buffer.finish();
  735.         }
  736.  
  737.         // SUBMISSION AND PRESENT
  738.         let command_buffers = &self.command_buffers[i_usize..=i_usize];
  739.         let wait_semaphores: ArrayVec<[_; 1]> =
  740.             [(image_available, PipelineStage::COLOR_ATTACHMENT_OUTPUT)].into();
  741.         let signal_semaphores: ArrayVec<[_; 1]> = [render_finished].into();
  742.         // yes, you have to write it twice like this. yes, it's silly.
  743.         let present_wait_semaphores: ArrayVec<[_; 1]> = [render_finished].into();
  744.         let submission = Submission {
  745.             command_buffers,
  746.             wait_semaphores,
  747.             signal_semaphores,
  748.         };
  749.         let the_command_queue = &mut self.queue_group.queues[0];
  750.         unsafe {
  751.             the_command_queue.submit(submission, Some(flight_fence));
  752.             self.swapchain
  753.                 .present(the_command_queue, i_u32, present_wait_semaphores)
  754.                 .map_err(|_| "Failed to present into the swapchain!")
  755.         }
  756.     }
  757.  
  758.     pub fn draw_quad_frame(
  759.         &mut self,
  760.         quad1: Quad,
  761.         quad2: Quad,
  762.         sprite: &Sprite,
  763.     ) -> Result<Option<Suboptimal>, &'static str> {
  764.         // SETUP FOR THIS FRAME
  765.         let image_available = &self.image_available_semaphores[self.current_frame];
  766.         let render_finished = &self.render_finished_semaphores[self.current_frame];
  767.         // Advance the frame _before_ we start using the `?` operator
  768.         self.current_frame = (self.current_frame + 1) % self.frames_in_flight;
  769.  
  770.         let (i_u32, i_usize) = unsafe {
  771.             let image_index = self
  772.                 .swapchain
  773.                 .acquire_image(core::u64::MAX, Some(image_available), None)
  774.                 .map_err(|_| "Couldn't acquire an image from the swapchain!")?;
  775.             (image_index.0, image_index.0 as usize)
  776.         };
  777.  
  778.         // Get the fence, and wait for the fence
  779.         let flight_fence = &self.in_flight_fences[i_usize];
  780.         unsafe {
  781.             self.device
  782.                 .wait_for_fence(flight_fence, core::u64::MAX)
  783.                 .map_err(|_| "Failed to wait on the fence!")?;
  784.             self.device
  785.                 .reset_fence(flight_fence)
  786.                 .map_err(|_| "Couldn't reset the fence!")?;
  787.         }
  788.  
  789.         // RECORD COMMANDS
  790.         unsafe {
  791.             let buffer = &mut self.command_buffers[i_usize];
  792.             const TRIANGLE_CLEAR: [ClearValue; 1] =
  793.                 [ClearValue::Color(ClearColor::Sfloat([0.1, 0.2, 0.3, 1.0]))];
  794.             buffer.begin(false);
  795.             {
  796.                 let mut encoder = buffer.begin_render_pass_inline(
  797.                     &self.render_pass,
  798.                     &self.framebuffers[i_usize],
  799.                     self.render_area,
  800.                     TRIANGLE_CLEAR.iter(),
  801.                 );
  802.                 encoder.bind_graphics_pipeline(&self.graphics_pipeline);
  803.  
  804.                 let vertex_buffers: ArrayVec<[_; 1]> = [(self.vertices.buffer.deref(), 0)].into();
  805.                 encoder.bind_vertex_buffers(0, vertex_buffers);
  806.                 encoder.bind_index_buffer(IndexBufferView {
  807.                     buffer: &self.indexes.buffer,
  808.                     offset: 0,
  809.                     index_type: IndexType::U16,
  810.                 });
  811.  
  812.                 // We'll move this into the loop eventually...
  813.                 encoder.bind_graphics_descriptor_sets(
  814.                     &self.pipeline_layout,
  815.                     0,
  816.                     Some(self.textures[sprite.texture].descriptor_set.deref()),
  817.                     &[],
  818.                 );
  819.  
  820.                 // we actually push our models here! the vertex shader will "move" it
  821.                 {
  822.                     // encoder.push_graphics_constants(
  823.                     //     &self.pipeline_layout,
  824.                     //     ShaderStageFlags::FRAGMENT,
  825.                     //     0,
  826.                     //     &[time_f32.to_bits()],
  827.                     // );
  828.                     encoder.draw_indexed(0..6, 0, 0..1);
  829.                 }
  830.             }
  831.             buffer.finish();
  832.         }
  833.  
  834.         // SUBMISSION AND PRESENT
  835.         let command_buffers = &self.command_buffers[i_usize..=i_usize];
  836.         let wait_semaphores: ArrayVec<[_; 1]> =
  837.             [(image_available, PipelineStage::COLOR_ATTACHMENT_OUTPUT)].into();
  838.         let signal_semaphores: ArrayVec<[_; 1]> = [render_finished].into();
  839.         // yes, you have to write it twice like this. yes, it's silly.
  840.         let present_wait_semaphores: ArrayVec<[_; 1]> = [render_finished].into();
  841.         let submission = Submission {
  842.             command_buffers,
  843.             wait_semaphores,
  844.             signal_semaphores,
  845.         };
  846.         let the_command_queue = &mut self.queue_group.queues[0];
  847.         unsafe {
  848.             the_command_queue.submit(submission, Some(flight_fence));
  849.             self.swapchain
  850.                 .present(the_command_queue, i_u32, present_wait_semaphores)
  851.                 .map_err(|_| "Failed to present into the swapchain!")
  852.         }
  853.     }
  854. }
  855.  
  856. impl<I: Instance> core::ops::Drop for Renderer<I> {
  857.     fn drop(&mut self) {
  858.         error!("Dropping HALState.");
  859.         self.device.wait_idle().unwrap();
  860.  
  861.         unsafe {
  862.             for fence in self.in_flight_fences.drain(..) {
  863.                 self.device.destroy_fence(fence);
  864.             }
  865.  
  866.             for semaphore in self.render_finished_semaphores.drain(..) {
  867.                 self.device.destroy_semaphore(semaphore)
  868.             }
  869.             for semaphore in self.image_available_semaphores.drain(..) {
  870.                 self.device.destroy_semaphore(semaphore)
  871.             }
  872.             for framebuffer in self.framebuffers.drain(..) {
  873.                 self.device.destroy_framebuffer(framebuffer);
  874.             }
  875.             for image_view in self.image_views.drain(..) {
  876.                 self.device.destroy_image_view(image_view);
  877.             }
  878.  
  879.             for this_layout in self.descriptor_set_layouts.drain(..) {
  880.                 self.device.destroy_descriptor_set_layout(this_layout);
  881.             }
  882.             for texture in self.textures.drain(..) {
  883.                 texture.manually_drop(&self.device);
  884.             }
  885.  
  886.             // LAST RESORT STYLE CODE, NOT TO BE IMITATED LIGHTLY
  887.             use core::ptr::read;
  888.             self.vertices.manually_drop(&self.device);
  889.             self.indexes.manually_drop(&self.device);
  890.  
  891.             self.device
  892.                 .destroy_pipeline_layout(manual_drop!(self.pipeline_layout));
  893.             self.device
  894.                 .destroy_graphics_pipeline(manual_drop!(self.graphics_pipeline));
  895.             self.device
  896.                 .destroy_command_pool(manual_drop!(self.command_pool).into_raw());
  897.             self.device
  898.                 .destroy_render_pass(manual_drop!(self.render_pass));
  899.             self.device.destroy_swapchain(manual_drop!(self.swapchain));
  900.             self.device
  901.                 .destroy_descriptor_pool(manual_drop!(self.descriptor_pool));
  902.  
  903.             ManuallyDrop::drop(&mut self.device);
  904.             ManuallyDrop::drop(&mut self._instance);
  905.         }
  906.     }
  907. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top