Started implementing triangle pipeline
+ Pipeline new() and drop() + Attachement new(() and drop() + draw_triangle_frame ! crashes at pipeline creation
This commit is contained in:
parent
64624dca20
commit
dd1d214a4a
30
Cargo.lock
generated
30
Cargo.lock
generated
@ -122,6 +122,15 @@ dependencies = [
|
|||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cmake"
|
||||||
|
version = "0.1.45"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eb6210b637171dfba4cda12e579ac6dc73f5165ad56133e5d72ef3131f320855"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cocoa"
|
name = "cocoa"
|
||||||
version = "0.20.2"
|
version = "0.20.2"
|
||||||
@ -362,6 +371,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
|
"shaderc",
|
||||||
"winit",
|
"winit",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -755,6 +765,26 @@ version = "1.0.115"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5"
|
checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shaderc"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "03f0cb8d1f8667fc9c50d5054be830a117af5f9a15f87c66b72bbca0c2fca484"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"shaderc-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shaderc-sys"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c89175f80244b82f882033a81bd188f87307c4c39b2fe8d0f194314f270bdea9"
|
||||||
|
dependencies = [
|
||||||
|
"cmake",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
|
|||||||
@ -14,6 +14,7 @@ gfx-hal = "^0.6.0"
|
|||||||
winit = "^0.22.0"
|
winit = "^0.22.0"
|
||||||
raw-window-handle = "^0.3.3"
|
raw-window-handle = "^0.3.3"
|
||||||
num-traits = "^0.2.12"
|
num-traits = "^0.2.12"
|
||||||
|
shaderc = "^0.7"
|
||||||
|
|
||||||
[dependencies.gfx-backend-vulkan]
|
[dependencies.gfx-backend-vulkan]
|
||||||
version = "^0.6.1"
|
version = "^0.6.1"
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -14,7 +14,7 @@ where
|
|||||||
O: Output<W>,
|
O: Output<W>,
|
||||||
{
|
{
|
||||||
pipelines: Vec<SubenginePipeline<'a, I, W, O>>,
|
pipelines: Vec<SubenginePipeline<'a, I, W, O>>,
|
||||||
color: [f32; 4],
|
mouse_pos: [f32; 2],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, W, O> Controller<'_, I, W, O>
|
impl<I, W, O> Controller<'_, I, W, O>
|
||||||
@ -38,7 +38,7 @@ where
|
|||||||
|
|
||||||
Controller {
|
Controller {
|
||||||
pipelines: pipelines_vec,
|
pipelines: pipelines_vec,
|
||||||
color: [0.0, 1.0, 1.0, 0.0],
|
mouse_pos: [0.5, 0.5],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +48,7 @@ where
|
|||||||
use crate::{
|
use crate::{
|
||||||
subengine::subengine_controller::SubengineCommand,
|
subengine::subengine_controller::SubengineCommand,
|
||||||
io::Key,
|
io::Key,
|
||||||
|
utils::Triangle,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut input_keys: Vec<Key> = Vec::new();
|
let mut input_keys: Vec<Key> = Vec::new();
|
||||||
@ -61,11 +62,10 @@ where
|
|||||||
}
|
}
|
||||||
for input_key in &input_keys {
|
for input_key in &input_keys {
|
||||||
match input_key {
|
match input_key {
|
||||||
Key::MouseMove{x,y} => self.color = [
|
Key::MouseMove{x,y} => self.mouse_pos = [
|
||||||
(x/1280.0) as f32,
|
(x/1280.0 * 2.0 - 1.0) as f32,
|
||||||
(y/720.0) as f32,
|
(y/720.0 * 2.0 - 1.0) as f32,
|
||||||
((x/1280.0 + y/720.0)/2.0) as f32,
|
],
|
||||||
1.0],
|
|
||||||
Key::Close => return,
|
Key::Close => return,
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
@ -78,13 +78,24 @@ where
|
|||||||
subengine.wait_for_exec(Duration::from_millis(1)).unwrap();
|
subengine.wait_for_exec(Duration::from_millis(1)).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let triangle = Triangle {
|
||||||
|
points: [self.mouse_pos, [-0.5, 0.5], [-0.5, -0.5]],
|
||||||
|
};
|
||||||
|
|
||||||
|
debug!("Triangle : {:#?}", triangle);
|
||||||
|
|
||||||
for (renderer, output) in &mut pipeline.renderers {
|
for (renderer, output) in &mut pipeline.renderers {
|
||||||
match renderer.draw_clear_frame(output, self.color) {
|
// match renderer.draw_clear_frame(output, self.color) {
|
||||||
|
// Err(err) => warn!("{}", err),
|
||||||
|
// _ => (),
|
||||||
|
// }
|
||||||
|
match renderer.draw_triangle_frame(output, triangle) {
|
||||||
Err(err) => warn!("{}", err),
|
Err(err) => warn!("{}", err),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//These tests are disabled because of some stange issue with cargo not waiting for the drop
|
//These tests are disabled because of some stange issue with cargo not waiting for the drop
|
||||||
|
|||||||
120
src/renderer.rs
120
src/renderer.rs
@ -9,13 +9,18 @@ use std::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
io::Output,
|
io::Output,
|
||||||
|
utils::Triangle,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mod gpu;
|
mod gpu;
|
||||||
use gpu::Gpu;
|
use self::gpu::Gpu;
|
||||||
|
|
||||||
mod swap_system;
|
mod swap_system;
|
||||||
use swap_system::SwapSystem;
|
use self::swap_system::SwapSystem;
|
||||||
|
|
||||||
|
mod pipeline;
|
||||||
|
use self::pipeline::Pipeline;
|
||||||
|
|
||||||
//--Renderer implementation-------------------------------------------------------------------------
|
//--Renderer implementation-------------------------------------------------------------------------
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -23,6 +28,7 @@ pub struct Renderer<B: gfx_hal::Backend> {
|
|||||||
instance: ManuallyDrop<B::Instance>,
|
instance: ManuallyDrop<B::Instance>,
|
||||||
gpu: ManuallyDrop<Gpu<B>>,
|
gpu: ManuallyDrop<Gpu<B>>,
|
||||||
swap_systems: Vec<SwapSystem<B>>,
|
swap_systems: Vec<SwapSystem<B>>,
|
||||||
|
pipelines: Vec<Pipeline<B>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> Drop for Renderer<B>
|
impl<B> Drop for Renderer<B>
|
||||||
@ -35,16 +41,17 @@ where
|
|||||||
device::Device,
|
device::Device,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
debug!("Dropping Pipelines...");
|
||||||
|
for pipeline in self.pipelines.drain(..) {
|
||||||
|
pipeline.drop(&mut self.gpu);
|
||||||
|
}
|
||||||
|
|
||||||
debug!("Waiting for device to idle...");
|
debug!("Waiting for device to idle...");
|
||||||
let _ = self.gpu
|
let _ = self.gpu
|
||||||
.device()
|
.device()
|
||||||
.wait_idle();
|
.wait_idle();
|
||||||
|
|
||||||
info!("Dropping Renderer...");
|
info!("Dropping Renderer...");
|
||||||
|
|
||||||
// for mut pipeline in self.pipelines.drain(..) {
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
unsafe {
|
unsafe {
|
||||||
for mut swap_system in self.swap_systems.drain(..) {
|
for mut swap_system in self.swap_systems.drain(..) {
|
||||||
self.instance.destroy_surface(swap_system.drop(&mut self.gpu));
|
self.instance.destroy_surface(swap_system.drop(&mut self.gpu));
|
||||||
@ -79,12 +86,15 @@ where
|
|||||||
.map(|surface| SwapSystem::new(&mut gpu, surface))
|
.map(|surface| SwapSystem::new(&mut gpu, surface))
|
||||||
.collect::<Result<Vec<_>, &str>>()?
|
.collect::<Result<Vec<_>, &str>>()?
|
||||||
};
|
};
|
||||||
|
let pipelines = vec!(Pipeline::new(&mut gpu, &swap_systems[0]) //TODO improve that
|
||||||
|
.map_err(|err| err)?);
|
||||||
|
|
||||||
debug!("Renderer created !");
|
debug!("Renderer created !");
|
||||||
Ok( Renderer {
|
Ok( Renderer {
|
||||||
instance: ManuallyDrop::new(instance),
|
instance: ManuallyDrop::new(instance),
|
||||||
gpu: ManuallyDrop::new(gpu),
|
gpu: ManuallyDrop::new(gpu),
|
||||||
swap_systems,
|
swap_systems,
|
||||||
|
pipelines,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,5 +181,103 @@ where
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn draw_triangle_frame<W, O>(&mut self, output: &RefCell<O>, triangle: Triangle)
|
||||||
|
-> Result<(), &'static str>
|
||||||
|
where
|
||||||
|
W: raw_window_handle::HasRawWindowHandle,
|
||||||
|
O: Output<W>,
|
||||||
|
{
|
||||||
|
use gfx_hal::{
|
||||||
|
window::AcquireError,
|
||||||
|
device::Device,
|
||||||
|
queue::Submission,
|
||||||
|
};
|
||||||
|
|
||||||
|
let swap_system = &mut self.swap_systems[output.borrow_mut().get_id()];
|
||||||
|
|
||||||
|
let mut frame = match swap_system.acquire_frame(&self.gpu) {
|
||||||
|
Ok(frame) => frame,
|
||||||
|
Err(err) => match err {
|
||||||
|
AcquireError::NotReady => {
|
||||||
|
return Err("Frame acquisition failed because all Frames are in use");
|
||||||
|
},
|
||||||
|
AcquireError::OutOfDate => {
|
||||||
|
swap_system.recreate(&mut self.gpu)?;
|
||||||
|
debug!("SwapSystem : {:#?}", swap_system);
|
||||||
|
return Ok(());
|
||||||
|
},
|
||||||
|
_ => Err("Could not acquire Frame from SwapSystem")?,
|
||||||
|
}};
|
||||||
|
|
||||||
|
trace!("Waiting for Frame...");
|
||||||
|
unsafe {
|
||||||
|
let _ = self.gpu.device()
|
||||||
|
.wait_for_fence(&frame.fences[0], !0)
|
||||||
|
.map_err(|_| "Failed to wait for Fence")?;
|
||||||
|
let _ = self.gpu.device()
|
||||||
|
.reset_fence(&frame.fences[0])
|
||||||
|
.map_err(|_| "Failed to reset fence")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace!("Uploading triangle data...");
|
||||||
|
let points = triangle.points_flat();
|
||||||
|
self.pipelines[0].write_vertex_buffer(&self.gpu, 0, (&points).to_vec())?; //TODO meh
|
||||||
|
|
||||||
|
trace!("Recording CommandBuffer...");
|
||||||
|
unsafe {
|
||||||
|
use gfx_hal::command::{
|
||||||
|
CommandBufferFlags,
|
||||||
|
SubpassContents,
|
||||||
|
ClearValue,
|
||||||
|
ClearColor,
|
||||||
|
CommandBuffer,
|
||||||
|
};
|
||||||
|
|
||||||
|
frame.command_buffer.begin_primary(CommandBufferFlags::ONE_TIME_SUBMIT);
|
||||||
|
|
||||||
|
const TRIANGLE_CLEAR: ClearValue =
|
||||||
|
ClearValue {color : ClearColor{float32 : [0.1, 0.2, 0.3, 1.0]}};
|
||||||
|
|
||||||
|
frame.command_buffer.begin_render_pass(
|
||||||
|
&swap_system.render_pass,
|
||||||
|
&frame.framebuffer.as_ref().unwrap(),
|
||||||
|
swap_system.render_area,
|
||||||
|
iter::once(TRIANGLE_CLEAR),
|
||||||
|
SubpassContents::Inline,
|
||||||
|
);
|
||||||
|
frame.command_buffer.bind_graphics_pipeline(self.pipelines[0].raw_pipeline());
|
||||||
|
|
||||||
|
// storing const data via the CommandBuffer
|
||||||
|
//let buffer_ref: &B::Buffer = &self.buffer;
|
||||||
|
//let buffers: Vec<[_; 1]> = vec![(buffer_ref, 0)].into();
|
||||||
|
frame.command_buffer.bind_vertex_buffers(0, self.pipelines[0].raw_vertex_buffers());
|
||||||
|
|
||||||
|
frame.command_buffer.draw(0..3, 0..1);
|
||||||
|
frame.command_buffer.end_render_pass();
|
||||||
|
frame.command_buffer.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
trace!("Submiting to queue...");
|
||||||
|
let submission = Submission {
|
||||||
|
command_buffers: iter::once(&*frame.command_buffer),
|
||||||
|
wait_semaphores: None,
|
||||||
|
signal_semaphores: iter::once(&frame.signal_semaphores[0]),
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
use gfx_hal::queue::CommandQueue;
|
||||||
|
|
||||||
|
self.gpu.queue_mut().submit(submission, Some(&frame.fences[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = swap_system.present_frame(frame, &mut self.gpu);
|
||||||
|
if result.is_err() {
|
||||||
|
swap_system.recreate(&mut self.gpu).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,20 +1,309 @@
|
|||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use log::{debug, error, info, trace, warn};
|
use log::{debug, error, info, trace, warn};
|
||||||
|
|
||||||
use std::{
|
use std::mem::{ManuallyDrop, size_of};
|
||||||
mem::ManuallyDrop,
|
|
||||||
|
use gfx_hal::{
|
||||||
|
buffer::SubRange,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
gpu::Gpu,
|
||||||
|
swap_system::SwapSystem,
|
||||||
|
};
|
||||||
|
|
||||||
|
mod attachement;
|
||||||
|
use self::attachement::Attachement;
|
||||||
|
|
||||||
|
const VERTEX_SOURCE: &str =
|
||||||
|
"#version 440 core
|
||||||
|
|
||||||
|
layout (location = 0) in vec2 position;
|
||||||
|
|
||||||
|
out gl_PerVertex {
|
||||||
|
vec4 gl_Position;
|
||||||
|
};
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vec4(position, 0.0, 1.0);
|
||||||
|
}";
|
||||||
|
|
||||||
|
const FRAGMENT_SOURCE: &str =
|
||||||
|
"#version 440 core
|
||||||
|
|
||||||
|
layout (location = 0) out vec4 frag_color;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
frag_color = vec4(0.5, 0.5, 0.5, 0.5);
|
||||||
|
}";
|
||||||
|
|
||||||
//--Pipeline implementation-------------------------------------------------------------------------
|
//--Pipeline implementation-------------------------------------------------------------------------
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Pipeline<B: gfx_hal::Backend> {
|
pub struct Pipeline<B: gfx_hal::Backend> {
|
||||||
render_pass: ManuallyDrop<B::RenderPass>,
|
set_layout: Vec<B::DescriptorSetLayout>,
|
||||||
|
layout: ManuallyDrop<B::PipelineLayout>,
|
||||||
|
gfx_pipeline: ManuallyDrop<B::GraphicsPipeline>,
|
||||||
|
vertex_buffers: Vec<Attachement<B>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> Pipeline<B>
|
impl<B> Pipeline<B>
|
||||||
where
|
where
|
||||||
B: gfx_hal::Backend,
|
B: gfx_hal::Backend,
|
||||||
{
|
{
|
||||||
|
pub fn drop(mut self, gpu: &mut Gpu<B>) {
|
||||||
|
use std::ptr::read;
|
||||||
|
|
||||||
|
use gfx_hal::device::Device;
|
||||||
|
|
||||||
|
debug!("Dropping Pipeline...");
|
||||||
|
for buffer in self.vertex_buffers.drain(..) {
|
||||||
|
buffer.drop(gpu);
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
gpu.device()
|
||||||
|
.destroy_graphics_pipeline(
|
||||||
|
ManuallyDrop::into_inner(read(&mut self.gfx_pipeline)));
|
||||||
|
gpu.device()
|
||||||
|
.destroy_pipeline_layout(
|
||||||
|
ManuallyDrop::into_inner(read(&mut self.layout)));
|
||||||
|
for layout in self.set_layout.drain(..) {
|
||||||
|
gpu.device().destroy_descriptor_set_layout(layout);
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(gpu: &mut Gpu<B>, swap_system: &SwapSystem<B>) -> Result<Pipeline<B>, &'static str> {
|
||||||
|
use gfx_hal::{
|
||||||
|
device::Device,
|
||||||
|
pso::{EntryPoint, Specialization, VertexBufferDesc, VertexInputRate, AttributeDesc,
|
||||||
|
Element, InputAssemblerDesc, Primitive, PrimitiveAssemblerDesc, Rasterizer,
|
||||||
|
PolygonMode, Face, FrontFace, State, DepthStencilDesc, BakedStates, Viewport,
|
||||||
|
DescriptorSetLayoutBinding, ShaderStageFlags
|
||||||
|
},
|
||||||
|
format::Format,
|
||||||
|
};
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
debug!("Compiling shaders...");
|
||||||
|
let mut compiler = shaderc::Compiler::new().ok_or("shaderc not found")?;
|
||||||
|
let vertex_compile_artifact = compiler
|
||||||
|
.compile_into_spirv(VERTEX_SOURCE, shaderc::ShaderKind::Vertex, "vertex.vert",
|
||||||
|
"main",
|
||||||
|
None)
|
||||||
|
.map_err(|err| {error!("{}", err);
|
||||||
|
"Could not compile vertex shader"})?;
|
||||||
|
let fragment_compile_artifact = compiler
|
||||||
|
.compile_into_spirv(FRAGMENT_SOURCE, shaderc::ShaderKind::Fragment, "fragement.frag",
|
||||||
|
"main",
|
||||||
|
None)
|
||||||
|
.map_err(|err| {error!("{}", err);
|
||||||
|
"Could not compile fragment shader"})?;
|
||||||
|
|
||||||
|
trace!("Creating ShaderModules...");
|
||||||
|
let vertex_shader_module = unsafe {
|
||||||
|
gpu.device()
|
||||||
|
.create_shader_module(vertex_compile_artifact.as_binary())
|
||||||
|
.map_err(|err| {error!("{}", err);
|
||||||
|
"Could not create vertex shader module"})?
|
||||||
|
};
|
||||||
|
let fragment_shader_module = unsafe {
|
||||||
|
gpu.device()
|
||||||
|
.create_shader_module(fragment_compile_artifact.as_binary())
|
||||||
|
.map_err(|err| {error!("{}", err);
|
||||||
|
"Could not create fragment shader module"})?
|
||||||
|
};
|
||||||
|
|
||||||
|
trace!("Creating shader set...");
|
||||||
|
let (vs_entry, fs_entry) = (
|
||||||
|
EntryPoint {
|
||||||
|
entry: "main",
|
||||||
|
module: &vertex_shader_module,
|
||||||
|
specialization: Specialization {
|
||||||
|
constants: Cow::Borrowed{0: &[]},
|
||||||
|
data: Cow::Borrowed{0: &[]},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
EntryPoint {
|
||||||
|
entry: "main",
|
||||||
|
module: &fragment_shader_module,
|
||||||
|
specialization: Specialization {
|
||||||
|
constants: Cow::Borrowed{0: &[]},
|
||||||
|
data: Cow::Borrowed{0: &[]},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
trace!("Creating PrimitiveAssembler...");
|
||||||
|
let buffers: Vec<VertexBufferDesc> =
|
||||||
|
vec![VertexBufferDesc {
|
||||||
|
binding: 0,
|
||||||
|
stride: (size_of::<f32>()*2) as u32,
|
||||||
|
rate: VertexInputRate::Vertex,
|
||||||
|
}];
|
||||||
|
let attributes: Vec<AttributeDesc> =
|
||||||
|
vec![AttributeDesc {
|
||||||
|
location: 0,
|
||||||
|
binding: 0,
|
||||||
|
element: Element {
|
||||||
|
format: Format::Rgb32Sfloat,
|
||||||
|
offset: 0,
|
||||||
|
},
|
||||||
|
}];
|
||||||
|
let input_assembler = InputAssemblerDesc {
|
||||||
|
primitive: Primitive::TriangleList, //TODO switch to strips
|
||||||
|
with_adjacency: false,
|
||||||
|
restart_index: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let primitive_assembler = PrimitiveAssemblerDesc::Vertex {
|
||||||
|
buffers: &buffers,
|
||||||
|
attributes: &attributes,
|
||||||
|
input_assembler,
|
||||||
|
vertex: vs_entry,
|
||||||
|
tessellation: None,
|
||||||
|
geometry: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
trace!("Creating Rasterizer...");
|
||||||
|
let rasterizer = Rasterizer {
|
||||||
|
polygon_mode: PolygonMode::Fill,
|
||||||
|
cull_face: Face::NONE, //TODO adjut that
|
||||||
|
front_face: FrontFace::CounterClockwise,
|
||||||
|
depth_clamping: false,
|
||||||
|
depth_bias: None,
|
||||||
|
conservative: false,
|
||||||
|
line_width: State::Static{0: 1.0}, //TODO may need to be changed
|
||||||
|
};
|
||||||
|
|
||||||
|
trace!("Configuring color blending...");
|
||||||
|
let blender = {
|
||||||
|
use gfx_hal::pso::{BlendState, BlendOp, Factor, BlendDesc, LogicOp, ColorBlendDesc,
|
||||||
|
ColorMask};
|
||||||
|
|
||||||
|
let blend_state = BlendState {
|
||||||
|
color: BlendOp::Add {
|
||||||
|
src: Factor::One,
|
||||||
|
dst: Factor::Zero,
|
||||||
|
},
|
||||||
|
alpha: BlendOp::Add {
|
||||||
|
src: Factor::One,
|
||||||
|
dst: Factor::Zero,
|
||||||
|
}};
|
||||||
|
BlendDesc {
|
||||||
|
logic_op: Some(LogicOp::Copy),
|
||||||
|
targets: vec![
|
||||||
|
ColorBlendDesc {
|
||||||
|
mask: ColorMask::ALL,
|
||||||
|
blend: Some(blend_state),
|
||||||
|
}]}
|
||||||
|
};
|
||||||
|
|
||||||
|
trace!("Configuring depth options...");
|
||||||
|
let depth_stencil = DepthStencilDesc {
|
||||||
|
depth: None,
|
||||||
|
depth_bounds: false,
|
||||||
|
stencil: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
trace!("Configuring baked-in pipeline states...");
|
||||||
|
let baked_states = BakedStates {
|
||||||
|
viewport: Some(Viewport {
|
||||||
|
rect: swap_system.render_area.clone(),
|
||||||
|
depth: (0.0..1.0),
|
||||||
|
}),
|
||||||
|
scissor: Some(swap_system.render_area.clone()),
|
||||||
|
blend_color: None,
|
||||||
|
depth_bounds: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
trace!("Creating PipelineLayout...");
|
||||||
|
let set_layout = {
|
||||||
|
let bindings = Vec::<DescriptorSetLayoutBinding>::new();
|
||||||
|
let immutable_samplers = Vec::<B::Sampler>::new();
|
||||||
|
unsafe {
|
||||||
|
vec![gpu.device()
|
||||||
|
.create_descriptor_set_layout(bindings, immutable_samplers)
|
||||||
|
.map_err(|_| "Could not create DescriptorSetLayout")?
|
||||||
|
]}};
|
||||||
|
let layout = {
|
||||||
|
let push_constants = Vec::<(ShaderStageFlags, std::ops::Range<u32>)>::new();
|
||||||
|
unsafe {
|
||||||
|
gpu.device()
|
||||||
|
.create_pipeline_layout(&set_layout, push_constants)
|
||||||
|
.map_err(|_| "Could not create PipelineLayout")?
|
||||||
|
}};
|
||||||
|
|
||||||
|
debug!("Creating GraphicsPipeline...");
|
||||||
|
let gfx_pipeline = {
|
||||||
|
use gfx_hal::{
|
||||||
|
pso::{GraphicsPipelineDesc, PipelineCreationFlags, BasePipeline},
|
||||||
|
pass::Subpass,
|
||||||
|
};
|
||||||
|
|
||||||
|
//manual deref for ManuallyDrop to not cause troubles
|
||||||
|
let render_pass_ref: &B::RenderPass = &swap_system.render_pass;
|
||||||
|
|
||||||
|
let pipeline_desc = GraphicsPipelineDesc {
|
||||||
|
primitive_assembler,
|
||||||
|
rasterizer,
|
||||||
|
fragment: Some(fs_entry),
|
||||||
|
blender,
|
||||||
|
depth_stencil,
|
||||||
|
multisampling: None,
|
||||||
|
baked_states,
|
||||||
|
layout: &layout,
|
||||||
|
subpass: Subpass {
|
||||||
|
index: 0,
|
||||||
|
main_pass: render_pass_ref,
|
||||||
|
},
|
||||||
|
flags: PipelineCreationFlags::empty(),
|
||||||
|
parent: BasePipeline::None,
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
gpu.device()
|
||||||
|
.create_graphics_pipeline(&pipeline_desc, None)
|
||||||
|
.map_err(|_| "Could not create GraphicsPipeline")?
|
||||||
|
}};
|
||||||
|
|
||||||
|
trace!("Destroying no-longer-needed shader modules...");
|
||||||
|
unsafe {
|
||||||
|
gpu.device()
|
||||||
|
.destroy_shader_module(vertex_shader_module);
|
||||||
|
gpu.device()
|
||||||
|
.destroy_shader_module(fragment_shader_module);
|
||||||
|
};
|
||||||
|
|
||||||
|
let vertex_buffers = vec![Attachement::new(gpu)?];
|
||||||
|
|
||||||
|
Ok( Pipeline {
|
||||||
|
set_layout,
|
||||||
|
layout: ManuallyDrop::new(layout),
|
||||||
|
gfx_pipeline: ManuallyDrop::new(gfx_pipeline),
|
||||||
|
vertex_buffers,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn raw_pipeline(&self) -> &B::GraphicsPipeline {
|
||||||
|
&self.gfx_pipeline
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn raw_vertex_buffers(&self) -> Vec<(&B::Buffer, SubRange)> {
|
||||||
|
|
||||||
|
self.vertex_buffers
|
||||||
|
.iter()
|
||||||
|
//TODO move SubRange to Attachement ?
|
||||||
|
.map(|buffer| (buffer.get_buffer(), SubRange {offset: 0, size: None}))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_vertex_buffer(&mut self, gpu: &Gpu<B>, index: usize, data: Vec<f32>)
|
||||||
|
-> Result<(), &'static str>
|
||||||
|
{
|
||||||
|
self.vertex_buffers[index].write_buffer(gpu, data)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
135
src/renderer/pipeline/attachement.rs
Normal file
135
src/renderer/pipeline/attachement.rs
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
#[allow(unused_imports)]
|
||||||
|
use log::{debug, error, info, trace, warn};
|
||||||
|
|
||||||
|
use std::mem::ManuallyDrop;
|
||||||
|
|
||||||
|
use crate::renderer::gpu::Gpu;
|
||||||
|
|
||||||
|
//--Attachement implementation----------------------------------------------------------------------
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Attachement<B: gfx_hal::Backend> {
|
||||||
|
buffer: ManuallyDrop<B::Buffer>,
|
||||||
|
memory: ManuallyDrop<B::Memory>,
|
||||||
|
size: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B> Attachement<B>
|
||||||
|
where
|
||||||
|
B: gfx_hal::Backend,
|
||||||
|
{
|
||||||
|
pub fn drop(mut self, gpu: &mut Gpu<B>) {
|
||||||
|
use std::ptr::read;
|
||||||
|
|
||||||
|
use gfx_hal::device::Device;
|
||||||
|
|
||||||
|
debug!("Dropping Attachement...");
|
||||||
|
unsafe {
|
||||||
|
gpu.device()
|
||||||
|
.free_memory(ManuallyDrop::into_inner(read(&mut self.memory)));
|
||||||
|
gpu.device()
|
||||||
|
.destroy_buffer(ManuallyDrop::into_inner(read(&mut self.buffer)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(gpu: &mut Gpu<B>) -> Result<Attachement<B>, &'static str> {
|
||||||
|
use std::mem::size_of;
|
||||||
|
|
||||||
|
use gfx_hal::{
|
||||||
|
device::Device,
|
||||||
|
adapter::PhysicalDevice,
|
||||||
|
buffer::Usage,
|
||||||
|
};
|
||||||
|
|
||||||
|
debug!("Creating attachement...");
|
||||||
|
let mut buffer = unsafe {
|
||||||
|
gpu.device()
|
||||||
|
.create_buffer((size_of::<f32>()*2*3) as u64, Usage::VERTEX)
|
||||||
|
.map_err(|_| "Could not create buffer")?
|
||||||
|
};
|
||||||
|
|
||||||
|
trace!("Creating underlying attachement memory...");
|
||||||
|
let (memory, size) = {
|
||||||
|
use gfx_hal::{
|
||||||
|
memory::Properties,
|
||||||
|
MemoryTypeId,
|
||||||
|
};
|
||||||
|
|
||||||
|
let requirements = unsafe {
|
||||||
|
gpu.device().get_buffer_requirements(&buffer)
|
||||||
|
};
|
||||||
|
let memory_type = gpu.adapter()
|
||||||
|
.physical_device
|
||||||
|
.memory_properties()
|
||||||
|
.memory_types
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.find(|&(id, memory_type)| {
|
||||||
|
requirements.type_mask & (1 << id) != 0 &&
|
||||||
|
memory_type.properties.contains(Properties::CPU_VISIBLE)})
|
||||||
|
.map(|(id, _)| MemoryTypeId(id))
|
||||||
|
.ok_or("Could not find a suitable memory type to allocate attachement memory")?;
|
||||||
|
|
||||||
|
(
|
||||||
|
unsafe {
|
||||||
|
gpu.device()
|
||||||
|
.allocate_memory(memory_type, requirements.size)
|
||||||
|
.map_err(|_| "Could not allocate buffer memory...")?
|
||||||
|
},
|
||||||
|
requirements.size,
|
||||||
|
)};
|
||||||
|
|
||||||
|
trace!("Binding memory to buffer...");
|
||||||
|
unsafe {
|
||||||
|
gpu.device()
|
||||||
|
.bind_buffer_memory(&memory, 0, &mut buffer)
|
||||||
|
.map_err(|__| "Could not bind memory to buffer")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Ok( Attachement {
|
||||||
|
buffer: ManuallyDrop::new(buffer),
|
||||||
|
memory: ManuallyDrop::new(memory),
|
||||||
|
size,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_buffer(&self) -> &B::Buffer {
|
||||||
|
//manual deref for ManuallyDrop to not cause troubles
|
||||||
|
&self.buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_buffer(&self, gpu: &Gpu<B>, data: Vec<f32>) -> Result<(), &'static str>
|
||||||
|
{
|
||||||
|
use gfx_hal::{
|
||||||
|
device::Device,
|
||||||
|
memory::Segment,
|
||||||
|
};
|
||||||
|
|
||||||
|
trace!("writing data to buffer...");
|
||||||
|
unsafe {
|
||||||
|
let mapped_memory = gpu.device()
|
||||||
|
.map_memory(&self.memory, Segment::ALL)
|
||||||
|
.map_err(|_| "Could not map buffer memory")?;
|
||||||
|
|
||||||
|
//debug!("before : {}", std::ptr::read(mapped_memory as *mut f32));
|
||||||
|
|
||||||
|
std::ptr::copy_nonoverlapping(data.as_ptr() as *const u8,
|
||||||
|
mapped_memory, self.size as usize);
|
||||||
|
|
||||||
|
//debug!("after : {}", std::ptr::read(mapped_memory as *mut f32));
|
||||||
|
|
||||||
|
//manual deref for ManuallyDrop to not cause troubles
|
||||||
|
let memory_ref: &B::Memory = &self.memory;
|
||||||
|
|
||||||
|
gpu.device()
|
||||||
|
.flush_mapped_memory_ranges(std::iter::once((memory_ref, Segment::ALL)))
|
||||||
|
.map_err(|_| "Could not flush mapped buffer memory")?;
|
||||||
|
|
||||||
|
gpu.device().unmap_memory(&self.memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ pub struct SwapSystem<B: gfx_hal::Backend> {
|
|||||||
format: Format,
|
format: Format,
|
||||||
extent: Extent2D,
|
extent: Extent2D,
|
||||||
pub render_area: GfxRect, //TODO may not be needed (duplicate of extent)
|
pub render_area: GfxRect, //TODO may not be needed (duplicate of extent)
|
||||||
pub render_pass: ManuallyDrop<B::RenderPass>,
|
pub render_pass: ManuallyDrop<B::RenderPass>, //TODO move to Pipeline ?
|
||||||
frames: VecDeque<Frame<B>>,
|
frames: VecDeque<Frame<B>>,
|
||||||
frame_nb: usize,
|
frame_nb: usize,
|
||||||
}
|
}
|
||||||
@ -51,7 +51,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(gpu: &mut Gpu<B>, mut surface: B::Surface)
|
pub fn new(gpu: &mut Gpu<B>, mut surface: B::Surface)
|
||||||
-> Result<SwapSystem<B>, &'static str>
|
-> Result<SwapSystem<B>, &'static str>
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@ where
|
|||||||
pub inputs: Vec<&'a RefCell<I>>,
|
pub inputs: Vec<&'a RefCell<I>>,
|
||||||
pub subengines: Vec<Vec<SubengineController>>,
|
pub subengines: Vec<Vec<SubengineController>>,
|
||||||
pub renderers: Vec<(Renderer<vk_back::Backend>, &'a RefCell<O>)>,
|
pub renderers: Vec<(Renderer<vk_back::Backend>, &'a RefCell<O>)>,
|
||||||
pub phantom: PhantomData<W>, //needed because of compiler limitations
|
phantom: PhantomData<W>, //needed because of compiler limitations
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, W, O> SubenginePipeline<'a, I, W, O>
|
impl<'a, I, W, O> SubenginePipeline<'a, I, W, O>
|
||||||
|
|||||||
13
src/utils.rs
13
src/utils.rs
@ -9,3 +9,16 @@ pub struct Rect<I: Num> {
|
|||||||
pub h: I,
|
pub h: I,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct Triangle {
|
||||||
|
pub points: [[f32; 2]; 3],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Triangle {
|
||||||
|
|
||||||
|
pub fn points_flat(&self) -> [f32; 6] {
|
||||||
|
let [[a, b], [c, d], [e, f]] = self.points;
|
||||||
|
[a, b, c, d, e, f]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user