Advertisement
Guest User

Untitled

a guest
Aug 17th, 2019
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 33.56 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement