Skip to content

Instantly share code, notes, and snippets.

@XavilPergis
Created April 3, 2019 08:35
Show Gist options
  • Save XavilPergis/1f6c2733eabe0ff4c0e4c9dc3cb1487b to your computer and use it in GitHub Desktop.
Save XavilPergis/1f6c2733eabe0ff4c0e4c9dc3cb1487b to your computer and use it in GitHub Desktop.
use rendy::command::QueueId;
use rendy::factory::Config;
use rendy::graph::{render::*, NodeBuffer, NodeImage};
use rendy::hal::buffer::Usage;
use rendy::memory::MemoryUsageValue;
use rendy::mesh::{AsVertex, PosColor};
use rendy::shader::{Shader, ShaderKind, SourceLanguage, StaticShaderInfo};
use winit::{ControlFlow, Event, WindowEvent};
use winit::{EventsLoop, WindowBuilder};
pub mod types {
#[cfg(feature = "dx12")]
pub type Backend = rendy::dx12::Backend;
#[cfg(feature = "metal")]
pub type Backend = rendy::metal::Backend;
#[cfg(feature = "vulkan")]
pub type Backend = rendy::vulkan::Backend;
pub type Factory = rendy::factory::Factory<Backend>;
pub type Buffer = rendy::resource::buffer::Buffer<Backend>;
// pub type DescriptorSetLayout = rendy::descriptor::DescriptorSetLayout<Backend>;
pub type DescriptorSetLayout = rendy::resource::set::DescriptorSetLayout<Backend>;
pub type GraphContext = rendy::graph::GraphContext<Backend>;
pub type GraphBuilder<T> = rendy::graph::GraphBuilder<Backend, T>;
pub type Graph<T> = rendy::graph::Graph<Backend, T>;
pub type PresentNode = rendy::graph::present::PresentNode<Backend>;
pub type PresentBuilder = rendy::graph::present::PresentBuilder<Backend>;
pub type RenderPassEncoder<'a> = rendy::command::RenderPassEncoder<'a, Backend>;
pub type HalPhysicalDevice = <Backend as rendy::hal::Backend>::PhysicalDevice;
pub type HalDevice = <Backend as rendy::hal::Backend>::Device;
pub type HalSurface = <Backend as rendy::hal::Backend>::Surface;
pub type HalSwapchain = <Backend as rendy::hal::Backend>::Swapchain;
pub type HalQueueFamily = <Backend as rendy::hal::Backend>::QueueFamily;
pub type HalCommandQueue = <Backend as rendy::hal::Backend>::CommandQueue;
pub type HalCommandBuffer = <Backend as rendy::hal::Backend>::CommandBuffer;
pub type HalShaderModule = <Backend as rendy::hal::Backend>::ShaderModule;
pub type HalRenderPass = <Backend as rendy::hal::Backend>::RenderPass;
pub type HalFramebuffer = <Backend as rendy::hal::Backend>::Framebuffer;
pub type HalMemory = <Backend as rendy::hal::Backend>::Memory;
pub type HalCommandPool = <Backend as rendy::hal::Backend>::CommandPool;
pub type HalBuffer = <Backend as rendy::hal::Backend>::Buffer;
pub type HalBufferView = <Backend as rendy::hal::Backend>::BufferView;
pub type HalImage = <Backend as rendy::hal::Backend>::Image;
pub type HalImageView = <Backend as rendy::hal::Backend>::ImageView;
pub type HalSampler = <Backend as rendy::hal::Backend>::Sampler;
pub type HalComputePipeline = <Backend as rendy::hal::Backend>::ComputePipeline;
pub type HalGraphicsPipeline = <Backend as rendy::hal::Backend>::GraphicsPipeline;
pub type HalPipelineCache = <Backend as rendy::hal::Backend>::PipelineCache;
pub type HalPipelineLayout = <Backend as rendy::hal::Backend>::PipelineLayout;
pub type HalDescriptorPool = <Backend as rendy::hal::Backend>::DescriptorPool;
pub type HalDescriptorSet = <Backend as rendy::hal::Backend>::DescriptorSet;
pub type HalDescriptorSetLayout = <Backend as rendy::hal::Backend>::DescriptorSetLayout;
pub type HalFence = <Backend as rendy::hal::Backend>::Fence;
pub type HalSemaphore = <Backend as rendy::hal::Backend>::Semaphore;
pub type HalQueryPool = <Backend as rendy::hal::Backend>::QueryPool;
}
use types::*;
#[cfg(any(feature = "dx12", feature = "metal", feature = "vulkan"))]
fn main() -> Result<(), Box<std::error::Error>> {
env_logger::Builder::from_default_env()
.filter_level(log::LevelFilter::Warn)
.filter_module("init", log::LevelFilter::Trace)
.init();
let mut event_loop = EventsLoop::new();
let window = WindowBuilder::new()
.with_title("Triangle!")
.build(&event_loop)?;
let config: Config = Default::default();
let (mut factory, mut families): (Factory, _) = rendy::factory::init(config).unwrap();
let surface = factory.create_surface(window.into());
let mut graph_builder = GraphBuilder::<()>::new();
let color_buffer = graph_builder.create_image(
surface.kind(),
1,
factory.get_surface_format(&surface),
MemoryUsageValue::Data,
Some(rendy::hal::command::ClearValue::Color(
[1.0, 1.0, 1.0, 1.0].into(),
)),
);
let pass = graph_builder.add_node(
TriangleRenderPipeline::builder()
.into_subpass()
.with_color(color_buffer)
.into_pass(),
);
graph_builder
.add_node(PresentNode::builder(&factory, surface, color_buffer).with_dependency(pass));
let mut graph = graph_builder
.build(&mut factory, &mut families, &())
.unwrap();
let mut do_close = false;
while !do_close {
factory.maintain(&mut families);
event_loop.poll_events(|event| match event {
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => {
do_close = true;
}
_ => (),
});
graph.run(&mut factory, &mut families, &());
}
Ok(())
}
#[cfg(not(any(feature = "dx12", feature = "metal", feature = "vulkan")))]
fn main() {
panic!("Specify a backend feature: [ vulkan, dx12, metal ]");
}
lazy_static::lazy_static! {
pub static ref VERTEX: StaticShaderInfo = StaticShaderInfo::new(
concat!(env!("CARGO_MANIFEST_DIR"), "/resources/triangle.vert"),
ShaderKind::Vertex,
SourceLanguage::GLSL,
"main",
);
pub static ref FRAGMENT: StaticShaderInfo = StaticShaderInfo::new(
concat!(env!("CARGO_MANIFEST_DIR"), "/resources/triangle.frag"),
ShaderKind::Fragment,
SourceLanguage::GLSL,
"main",
);
}
#[derive(Clone, Debug, Default)]
pub struct TriangleRenderPipelineDesc;
#[derive(Debug)]
pub struct TriangleRenderPipeline {
triangle: Buffer,
}
impl SimpleGraphicsPipelineDesc<Backend, ()> for TriangleRenderPipelineDesc {
type Pipeline = TriangleRenderPipeline;
fn vertices(
&self,
) -> Vec<(
Vec<rendy::hal::pso::Element<rendy::hal::format::Format>>,
rendy::hal::pso::ElemStride,
rendy::hal::pso::InstanceRate,
)> {
vec![PosColor::VERTEX.gfx_vertex_input_desc(0)]
}
fn depth_stencil(&self) -> Option<rendy::hal::pso::DepthStencilDesc> {
None
}
fn load_shader_set<'a>(
&self,
storage: &'a mut Vec<HalShaderModule>,
factory: &mut Factory,
_aux: &(),
) -> rendy::hal::pso::GraphicsShaderSet<'a, Backend> {
storage.clear();
log::trace!("Load shader module '{:#?}'", *VERTEX);
storage.push(VERTEX.module(factory).unwrap());
log::trace!("Load shader module '{:#?}'", *FRAGMENT);
storage.push(FRAGMENT.module(factory).unwrap());
rendy::hal::pso::GraphicsShaderSet {
vertex: rendy::hal::pso::EntryPoint {
entry: "main",
module: &storage[0],
specialization: rendy::hal::pso::Specialization::default(),
},
fragment: Some(rendy::hal::pso::EntryPoint {
entry: "main",
module: &storage[1],
specialization: rendy::hal::pso::Specialization::default(),
}),
hull: None,
domain: None,
geometry: None,
}
}
fn build<'a>(
self,
_ctx: &mut GraphContext,
factory: &mut Factory,
_queue: QueueId,
_aux: &(),
buffers: Vec<NodeBuffer>,
images: Vec<NodeImage>,
set_layouts: &[DescriptorSetLayout],
) -> Result<TriangleRenderPipeline, failure::Error> {
assert!(buffers.is_empty());
assert!(images.is_empty());
assert!(set_layouts.is_empty());
let mut triangle = factory.create_buffer(
512,
PosColor::VERTEX.stride as u64 * 3,
(Usage::VERTEX, MemoryUsageValue::Dynamic),
)?;
unsafe {
// Fresh buffer.
factory
.upload_visible_buffer(
&mut triangle,
0,
&[
PosColor {
position: [0.0, -0.5, 0.0].into(),
color: [1.0, 0.0, 0.0, 1.0].into(),
},
PosColor {
position: [0.5, 0.5, 0.0].into(),
color: [0.0, 1.0, 0.0, 1.0].into(),
},
PosColor {
position: [-0.5, 0.5, 0.0].into(),
color: [0.0, 0.0, 1.0, 1.0].into(),
},
],
)
.unwrap();
}
Ok(TriangleRenderPipeline { triangle })
}
}
impl SimpleGraphicsPipeline<Backend, ()> for TriangleRenderPipeline {
type Desc = TriangleRenderPipelineDesc;
fn prepare(
&mut self,
factory: &Factory,
_queue: QueueId,
_set_layouts: &[DescriptorSetLayout],
_index: usize,
_aux: &(),
) -> PrepareResult {
PrepareResult::DrawReuse
}
fn draw(
&mut self,
_layout: &HalPipelineLayout,
mut encoder: RenderPassEncoder<'_>,
_index: usize,
_aux: &(),
) {
encoder.bind_vertex_buffers(0, Some((self.triangle.raw(), 0)));
encoder.draw(0..3, 0..1);
}
fn dispose(self, _factory: &mut Factory, _aux: &()) {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment