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",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb6210b637171dfba4cda12e579ac6dc73f5165ad56133e5d72ef3131f320855"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cocoa"
|
||||
version = "0.20.2"
|
||||
@ -362,6 +371,7 @@ dependencies = [
|
||||
"log",
|
||||
"num-traits",
|
||||
"raw-window-handle",
|
||||
"shaderc",
|
||||
"winit",
|
||||
]
|
||||
|
||||
@ -755,6 +765,26 @@ version = "1.0.115"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "slab"
|
||||
version = "0.4.2"
|
||||
|
||||
@ -14,6 +14,7 @@ gfx-hal = "^0.6.0"
|
||||
winit = "^0.22.0"
|
||||
raw-window-handle = "^0.3.3"
|
||||
num-traits = "^0.2.12"
|
||||
shaderc = "^0.7"
|
||||
|
||||
[dependencies.gfx-backend-vulkan]
|
||||
version = "^0.6.1"
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -14,7 +14,7 @@ where
|
||||
O: Output<W>,
|
||||
{
|
||||
pipelines: Vec<SubenginePipeline<'a, I, W, O>>,
|
||||
color: [f32; 4],
|
||||
mouse_pos: [f32; 2],
|
||||
}
|
||||
|
||||
impl<I, W, O> Controller<'_, I, W, O>
|
||||
@ -38,7 +38,7 @@ where
|
||||
|
||||
Controller {
|
||||
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::{
|
||||
subengine::subengine_controller::SubengineCommand,
|
||||
io::Key,
|
||||
utils::Triangle,
|
||||
};
|
||||
|
||||
let mut input_keys: Vec<Key> = Vec::new();
|
||||
@ -61,11 +62,10 @@ where
|
||||
}
|
||||
for input_key in &input_keys {
|
||||
match input_key {
|
||||
Key::MouseMove{x,y} => self.color = [
|
||||
(x/1280.0) as f32,
|
||||
(y/720.0) as f32,
|
||||
((x/1280.0 + y/720.0)/2.0) as f32,
|
||||
1.0],
|
||||
Key::MouseMove{x,y} => self.mouse_pos = [
|
||||
(x/1280.0 * 2.0 - 1.0) as f32,
|
||||
(y/720.0 * 2.0 - 1.0) as f32,
|
||||
],
|
||||
Key::Close => return,
|
||||
_ => (),
|
||||
};
|
||||
@ -78,13 +78,24 @@ where
|
||||
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 {
|
||||
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),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
//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::{
|
||||
io::Output,
|
||||
utils::Triangle,
|
||||
|
||||
};
|
||||
|
||||
mod gpu;
|
||||
use gpu::Gpu;
|
||||
use self::gpu::Gpu;
|
||||
|
||||
mod swap_system;
|
||||
use swap_system::SwapSystem;
|
||||
use self::swap_system::SwapSystem;
|
||||
|
||||
mod pipeline;
|
||||
use self::pipeline::Pipeline;
|
||||
|
||||
//--Renderer implementation-------------------------------------------------------------------------
|
||||
#[derive(Debug)]
|
||||
@ -23,6 +28,7 @@ pub struct Renderer<B: gfx_hal::Backend> {
|
||||
instance: ManuallyDrop<B::Instance>,
|
||||
gpu: ManuallyDrop<Gpu<B>>,
|
||||
swap_systems: Vec<SwapSystem<B>>,
|
||||
pipelines: Vec<Pipeline<B>>,
|
||||
}
|
||||
|
||||
impl<B> Drop for Renderer<B>
|
||||
@ -35,16 +41,17 @@ where
|
||||
device::Device,
|
||||
};
|
||||
|
||||
debug!("Dropping Pipelines...");
|
||||
for pipeline in self.pipelines.drain(..) {
|
||||
pipeline.drop(&mut self.gpu);
|
||||
}
|
||||
|
||||
debug!("Waiting for device to idle...");
|
||||
let _ = self.gpu
|
||||
.device()
|
||||
.wait_idle();
|
||||
|
||||
info!("Dropping Renderer...");
|
||||
|
||||
// for mut pipeline in self.pipelines.drain(..) {
|
||||
// }
|
||||
//
|
||||
unsafe {
|
||||
for mut swap_system in self.swap_systems.drain(..) {
|
||||
self.instance.destroy_surface(swap_system.drop(&mut self.gpu));
|
||||
@ -79,12 +86,15 @@ where
|
||||
.map(|surface| SwapSystem::new(&mut gpu, surface))
|
||||
.collect::<Result<Vec<_>, &str>>()?
|
||||
};
|
||||
let pipelines = vec!(Pipeline::new(&mut gpu, &swap_systems[0]) //TODO improve that
|
||||
.map_err(|err| err)?);
|
||||
|
||||
debug!("Renderer created !");
|
||||
Ok( Renderer {
|
||||
instance: ManuallyDrop::new(instance),
|
||||
gpu: ManuallyDrop::new(gpu),
|
||||
swap_systems,
|
||||
pipelines,
|
||||
})
|
||||
}
|
||||
|
||||
@ -171,5 +181,103 @@ where
|
||||
|
||||
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)]
|
||||
use log::{debug, error, info, trace, warn};
|
||||
|
||||
use std::{
|
||||
mem::ManuallyDrop,
|
||||
use std::mem::{ManuallyDrop, size_of};
|
||||
|
||||
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-------------------------------------------------------------------------
|
||||
#[derive(Debug)]
|
||||
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>
|
||||
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 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,
|
||||
extent: Extent2D,
|
||||
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>>,
|
||||
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>
|
||||
{
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@ where
|
||||
pub inputs: Vec<&'a RefCell<I>>,
|
||||
pub subengines: Vec<Vec<SubengineController>>,
|
||||
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>
|
||||
|
||||
13
src/utils.rs
13
src/utils.rs
@ -9,3 +9,16 @@ pub struct Rect<I: Num> {
|
||||
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