aboutsummaryrefslogtreecommitdiff
path: root/stockton-render/src/draw/ui
diff options
context:
space:
mode:
Diffstat (limited to 'stockton-render/src/draw/ui')
-rw-r--r--stockton-render/src/draw/ui/data/stockton.frag8
-rw-r--r--stockton-render/src/draw/ui/data/stockton.vert11
-rw-r--r--stockton-render/src/draw/ui/mod.rs22
-rw-r--r--stockton-render/src/draw/ui/pipeline.rs295
-rw-r--r--stockton-render/src/draw/ui/render.rs28
5 files changed, 364 insertions, 0 deletions
diff --git a/stockton-render/src/draw/ui/data/stockton.frag b/stockton-render/src/draw/ui/data/stockton.frag
new file mode 100644
index 0000000..1a85ab6
--- /dev/null
+++ b/stockton-render/src/draw/ui/data/stockton.frag
@@ -0,0 +1,8 @@
+#version 450
+#extension GL_ARB_separate_shader_objects : enable
+
+layout(location = 0) out vec4 outColor;
+
+void main() {
+ outColor = vec4(1.0, 0.0, 0.0, 1.0);
+} \ No newline at end of file
diff --git a/stockton-render/src/draw/ui/data/stockton.vert b/stockton-render/src/draw/ui/data/stockton.vert
new file mode 100644
index 0000000..1dd9477
--- /dev/null
+++ b/stockton-render/src/draw/ui/data/stockton.vert
@@ -0,0 +1,11 @@
+#version 450
+
+vec2 positions[3] = vec2[](
+ vec2(0.0, -0.5),
+ vec2(0.5, 0.5),
+ vec2(-0.5, 0.5)
+);
+
+void main() {
+ gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
+}
diff --git a/stockton-render/src/draw/ui/mod.rs b/stockton-render/src/draw/ui/mod.rs
new file mode 100644
index 0000000..cd19362
--- /dev/null
+++ b/stockton-render/src/draw/ui/mod.rs
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) Oscar Shrimpton 2020
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+pub mod pipeline;
+pub mod render;
+
+pub use pipeline::UIPipeline;
+pub use render::do_render;
diff --git a/stockton-render/src/draw/ui/pipeline.rs b/stockton-render/src/draw/ui/pipeline.rs
new file mode 100644
index 0000000..378c558
--- /dev/null
+++ b/stockton-render/src/draw/ui/pipeline.rs
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) Oscar Shrimpton 2020
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+//! A complete graphics pipeline
+
+/// Entry point name for shaders
+const ENTRY_NAME: &str = "main";
+
+/// Source for vertex shader. TODO
+const VERTEX_SOURCE: &str = include_str!("./data/stockton.vert");
+
+/// Source for fragment shader. TODO
+const FRAGMENT_SOURCE: &str = include_str!("./data/stockton.frag");
+
+use std::{
+ borrow::Borrow,
+ mem::{size_of, ManuallyDrop},
+};
+
+use hal::prelude::*;
+
+use crate::draw::target::SwapchainProperties;
+use crate::error;
+use crate::types::*;
+
+/// A complete 2D graphics pipeline and associated resources
+pub struct UIPipeline {
+ /// Our main render pass
+ pub(crate) renderpass: ManuallyDrop<RenderPass>,
+
+ /// The layout of our main graphics pipeline
+ pub(crate) pipeline_layout: ManuallyDrop<PipelineLayout>,
+
+ /// Our main graphics pipeline
+ pub(crate) pipeline: ManuallyDrop<GraphicsPipeline>,
+
+ /// The vertex shader module
+ pub(crate) vs_module: ManuallyDrop<ShaderModule>,
+
+ /// The fragment shader module
+ pub(crate) fs_module: ManuallyDrop<ShaderModule>,
+}
+
+impl UIPipeline {
+ pub fn new<T>(
+ device: &mut Device,
+ extent: hal::image::Extent,
+ swapchain_properties: &SwapchainProperties,
+ set_layouts: T,
+ ) -> Result<Self, error::CreationError>
+ where
+ T: IntoIterator,
+ T::Item: Borrow<DescriptorSetLayout>,
+ {
+ use hal::format::Format;
+ use hal::pso::*;
+
+ // Renderpass
+ let renderpass = {
+ use hal::{
+ image::{Access, Layout},
+ memory::Dependencies,
+ pass::*,
+ };
+
+ let img_attachment = Attachment {
+ format: Some(swapchain_properties.format),
+ samples: 1,
+ ops: AttachmentOps::new(AttachmentLoadOp::Load, AttachmentStoreOp::Store),
+ stencil_ops: AttachmentOps::new(
+ AttachmentLoadOp::DontCare,
+ AttachmentStoreOp::DontCare,
+ ),
+ layouts: Layout::ColorAttachmentOptimal..Layout::Present,
+ };
+
+ let subpass = SubpassDesc {
+ colors: &[(0, Layout::ColorAttachmentOptimal)],
+ depth_stencil: None,
+ inputs: &[],
+ resolves: &[],
+ preserves: &[],
+ };
+
+ let external_dependency = SubpassDependency {
+ flags: Dependencies::empty(),
+ passes: None..Some(0),
+ stages: PipelineStage::COLOR_ATTACHMENT_OUTPUT
+ ..(PipelineStage::COLOR_ATTACHMENT_OUTPUT
+ | PipelineStage::EARLY_FRAGMENT_TESTS),
+ accesses: Access::empty()
+ ..(Access::COLOR_ATTACHMENT_READ | Access::COLOR_ATTACHMENT_WRITE),
+ };
+
+ unsafe {
+ device.create_render_pass(&[img_attachment], &[subpass], &[external_dependency])
+ }
+ .map_err(|_| error::CreationError::OutOfMemoryError)?
+ };
+
+ // Subpass
+ let subpass = hal::pass::Subpass {
+ index: 0,
+ main_pass: &renderpass,
+ };
+
+ // Shader modules
+ let (vs_module, fs_module) = {
+ let mut compiler = shaderc::Compiler::new().ok_or(error::CreationError::NoShaderC)?;
+
+ let vertex_compile_artifact = compiler
+ .compile_into_spirv(
+ VERTEX_SOURCE,
+ shaderc::ShaderKind::Vertex,
+ "vertex.vert",
+ ENTRY_NAME,
+ None,
+ )
+ .map_err(error::CreationError::ShaderCError)?;
+
+ let fragment_compile_artifact = compiler
+ .compile_into_spirv(
+ FRAGMENT_SOURCE,
+ shaderc::ShaderKind::Fragment,
+ "fragment.frag",
+ ENTRY_NAME,
+ None,
+ )
+ .map_err(error::CreationError::ShaderCError)?;
+
+ // Make into shader module
+ unsafe {
+ (
+ device
+ .create_shader_module(vertex_compile_artifact.as_binary())
+ .map_err(error::CreationError::ShaderModuleFailed)?,
+ device
+ .create_shader_module(fragment_compile_artifact.as_binary())
+ .map_err(error::CreationError::ShaderModuleFailed)?,
+ )
+ }
+ };
+
+ // Shader entry points (ShaderStage)
+ let (vs_entry, fs_entry) = (
+ EntryPoint::<back::Backend> {
+ entry: ENTRY_NAME,
+ module: &vs_module,
+ specialization: Specialization::default(),
+ },
+ EntryPoint::<back::Backend> {
+ entry: ENTRY_NAME,
+ module: &fs_module,
+ specialization: Specialization::default(),
+ },
+ );
+
+ // Shader set
+ let shaders = GraphicsShaderSet {
+ vertex: vs_entry,
+ fragment: Some(fs_entry),
+ hull: None,
+ domain: None,
+ geometry: None,
+ };
+
+ // Vertex buffers
+ let vertex_buffers: Vec<VertexBufferDesc> = vec![VertexBufferDesc {
+ binding: 0,
+ stride: (size_of::<f32>() * 5) as u32,
+ rate: VertexInputRate::Vertex,
+ }];
+
+ let attributes: Vec<AttributeDesc> = pipeline_vb_attributes!(0,
+ size_of::<f32>() * 2; Rg32Sfloat,
+ size_of::<f32>() * 3; Rgb32Sfloat
+ );
+
+ // Rasterizer
+ let rasterizer = Rasterizer {
+ polygon_mode: PolygonMode::Fill,
+ cull_face: Face::NONE,
+ front_face: FrontFace::CounterClockwise,
+ depth_clamping: false,
+ depth_bias: None,
+ conservative: true,
+ line_width: hal::pso::State::Static(1.0),
+ };
+
+ // Depth stencil
+ let depth_stencil = DepthStencilDesc {
+ depth: None,
+ depth_bounds: false,
+ stencil: None,
+ };
+
+ // Pipeline layout
+ let layout = unsafe { device.create_pipeline_layout(set_layouts, &[]) }
+ .map_err(|_| error::CreationError::OutOfMemoryError)?;
+
+ // Colour blending
+ let blender = {
+ let blend_state = BlendState {
+ color: BlendOp::Add {
+ src: Factor::SrcAlpha,
+ dst: Factor::OneMinusSrcAlpha,
+ },
+ alpha: BlendOp::Add {
+ src: Factor::OneMinusSrcAlpha,
+ dst: Factor::Zero,
+ },
+ };
+
+ BlendDesc {
+ logic_op: None,
+ targets: vec![ColorBlendDesc {
+ mask: ColorMask::ALL,
+ blend: Some(blend_state),
+ }],
+ }
+ };
+
+ // Baked states
+ let baked_states = BakedStates {
+ viewport: Some(Viewport {
+ rect: extent.rect(),
+ depth: (0.0..1.0),
+ }),
+ scissor: Some(extent.rect()),
+ blend_color: None,
+ depth_bounds: None,
+ };
+
+ // Input assembler
+ let input_assembler = InputAssemblerDesc::new(Primitive::TriangleList);
+
+ // Pipeline description
+ let pipeline_desc = GraphicsPipelineDesc {
+ shaders,
+ rasterizer,
+ vertex_buffers,
+ blender,
+ depth_stencil,
+ multisampling: None,
+ baked_states,
+ layout: &layout,
+ subpass,
+ flags: PipelineCreationFlags::empty(),
+ parent: BasePipeline::None,
+ input_assembler,
+ attributes,
+ };
+
+ // Pipeline
+ let pipeline = unsafe { device.create_graphics_pipeline(&pipeline_desc, None) }
+ .map_err(error::CreationError::PipelineError)?;
+
+ Ok(UIPipeline {
+ renderpass: ManuallyDrop::new(renderpass),
+ pipeline_layout: ManuallyDrop::new(layout),
+ pipeline: ManuallyDrop::new(pipeline),
+ vs_module: ManuallyDrop::new(vs_module),
+ fs_module: ManuallyDrop::new(fs_module),
+ })
+ }
+
+ /// Deactivate vulkan resources. Use before dropping
+ pub fn deactivate(self, device: &mut Device) {
+ unsafe {
+ use core::ptr::read;
+
+ device.destroy_render_pass(ManuallyDrop::into_inner(read(&self.renderpass)));
+
+ device.destroy_shader_module(ManuallyDrop::into_inner(read(&self.vs_module)));
+ device.destroy_shader_module(ManuallyDrop::into_inner(read(&self.fs_module)));
+
+ device.destroy_graphics_pipeline(ManuallyDrop::into_inner(read(&self.pipeline)));
+
+ device.destroy_pipeline_layout(ManuallyDrop::into_inner(read(&self.pipeline_layout)));
+ }
+ }
+}
diff --git a/stockton-render/src/draw/ui/render.rs b/stockton-render/src/draw/ui/render.rs
new file mode 100644
index 0000000..b965a80
--- /dev/null
+++ b/stockton-render/src/draw/ui/render.rs
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) Oscar Shrimpton 2020
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+use hal::prelude::*;
+
+use crate::draw::draw_buffers::DrawBuffers;
+use crate::types::*;
+
+pub fn do_render(cmd_buffer: &mut CommandBuffer, _draw_buffers: &mut DrawBuffers) {
+ // TODO: Actual UI Rendering
+ unsafe {
+ cmd_buffer.draw(0..3, 0..1);
+ }
+}