|
|
|
@ -20,7 +20,6 @@ use vulkano::pipeline::viewport::Viewport;
|
|
|
|
|
use vulkano::descriptor::descriptor::DescriptorDescTy::TexelBuffer;
|
|
|
|
|
use crate::canvas::canvas_frame::{CanvasFrame, CanvasFrameTest};
|
|
|
|
|
use std::hash::Hash;
|
|
|
|
|
use crate::util::vertex_3d::{Vertex3D, TextVertex3D};
|
|
|
|
|
use vulkano::pipeline::depth_stencil::{StencilFaceFlags, DynamicStencilValue};
|
|
|
|
|
use vulkano::memory::pool::PotentialDedicatedAllocation::Generic;
|
|
|
|
|
use std::borrow::Borrow;
|
|
|
|
@ -29,11 +28,12 @@ use std::io::Read;
|
|
|
|
|
use rusttype::{Font, PositionedGlyph, Scale, Rect, point, GlyphId, Line, Curve, Segment};
|
|
|
|
|
use vulkano::pipeline::vertex::VertexDefinition;
|
|
|
|
|
use crate::canvas::managed::shader::dynamic_vertex::RuntimeVertexDef;
|
|
|
|
|
use crate::canvas::managed::handles::{CanvasTextureHandle, CanvasImageHandle, CanvasFontHandle, CompiledShaderHandle, Handle};
|
|
|
|
|
use crate::canvas::managed::handles::{CanvasTextureHandle, CanvasImageHandle, CanvasFontHandle, CompiledShaderHandle, Handle, DrawableHandle};
|
|
|
|
|
use crate::canvas::managed::gpu_buffers::{CanvasImage, CanvasTexture, CanvasFont};
|
|
|
|
|
use crate::canvas::managed::shader::shader_common::CompiledGraphicsPipeline;
|
|
|
|
|
use crate::canvas::managed::shader::generic_shader::GenericShader;
|
|
|
|
|
use crate::VertexTypes;
|
|
|
|
|
use crate::util::vertex::{TextVertex3D, TextureVertex2D, ImageVertex2D, ColorVertex2D, CanvasFrameAllocation};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Canvas state is used for storage of texture and image buffers in addition to vertex buffers
|
|
|
|
@ -53,16 +53,6 @@ pub struct CanvasState {
|
|
|
|
|
// Compiled Graphics pipelines have a handle which self describe their position in this vector
|
|
|
|
|
shader_buffers: Vec<Arc<Box<dyn CompiledGraphicsPipeline>>>,
|
|
|
|
|
|
|
|
|
|
// Hold onto the vertices we get from the Compu and Canvas Frames
|
|
|
|
|
// When the run comes around, push the vertices to the GPU
|
|
|
|
|
colored_vertex_buffer: Vec<Arc<(dyn BufferAccess + Send + Sync)>>,
|
|
|
|
|
|
|
|
|
|
textured_vertex_buffer: HashMap<Arc<CanvasTextureHandle>, Arc<(dyn BufferAccess + Send + Sync)>>,
|
|
|
|
|
|
|
|
|
|
image_vertex_buffer: HashMap<Arc<CanvasImageHandle>, Arc<(dyn BufferAccess + Send + Sync)>>,
|
|
|
|
|
|
|
|
|
|
text_instances: HashMap<Arc<CanvasFontHandle>, Arc<(dyn BufferAccess + Send + Sync)>>,
|
|
|
|
|
|
|
|
|
|
// Looks like we gotta hold onto the queue for managing textures
|
|
|
|
|
queue: Arc<Queue>,
|
|
|
|
|
device: Arc<Device>,
|
|
|
|
@ -70,7 +60,6 @@ pub struct CanvasState {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl CanvasState {
|
|
|
|
|
/// This method is called once during initialization, then again whenever the window is resized
|
|
|
|
|
pub fn window_size_dependent_setup(&mut self, images: &[Arc<SwapchainImage<Window>>])
|
|
|
|
@ -102,7 +91,6 @@ impl CanvasState {
|
|
|
|
|
device: Arc<Device>,
|
|
|
|
|
physical: PhysicalDevice,
|
|
|
|
|
capabilities: Capabilities) -> CanvasState {
|
|
|
|
|
|
|
|
|
|
let format = capabilities.supported_formats[0].0;
|
|
|
|
|
|
|
|
|
|
let render_pass = Arc::new(vulkano::single_pass_renderpass!(
|
|
|
|
@ -172,11 +160,6 @@ impl CanvasState {
|
|
|
|
|
shader_buffers: vec![],
|
|
|
|
|
font_buffers: vec![],
|
|
|
|
|
|
|
|
|
|
colored_vertex_buffer: vec![],
|
|
|
|
|
textured_vertex_buffer: Default::default(),
|
|
|
|
|
image_vertex_buffer: Default::default(),
|
|
|
|
|
text_instances: HashMap::default(),
|
|
|
|
|
|
|
|
|
|
queue: queue.clone(),
|
|
|
|
|
device: device.clone(),
|
|
|
|
|
render_pass: render_pass.clone(),
|
|
|
|
@ -393,91 +376,6 @@ impl CanvasState {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Scrape all the values from the CanvasFrame and then allocate the vertex buffers
|
|
|
|
|
pub fn draw(&mut self, canvas_frame: CanvasFrame) {
|
|
|
|
|
|
|
|
|
|
// Consume the canvas frame
|
|
|
|
|
let mut textured_drawables = canvas_frame.textured_drawables;
|
|
|
|
|
let mut colored_drawables = canvas_frame.colored_drawables;
|
|
|
|
|
let mut image_drawables = canvas_frame.image_drawables;
|
|
|
|
|
let mut text_drawables = canvas_frame.text_drawables;
|
|
|
|
|
|
|
|
|
|
// Walk through the consumed items and allocate them to GPU buffers
|
|
|
|
|
|
|
|
|
|
self.colored_vertex_buffer.clear();
|
|
|
|
|
{
|
|
|
|
|
let g = hprof::enter("Colored Vertex Buffer");
|
|
|
|
|
self.colored_vertex_buffer.push(
|
|
|
|
|
ImmutableBuffer::from_iter(
|
|
|
|
|
colored_drawables.iter().cloned(),
|
|
|
|
|
BufferUsage::vertex_buffer(),
|
|
|
|
|
self.queue.clone(),
|
|
|
|
|
).unwrap().0
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self.textured_vertex_buffer.clear();
|
|
|
|
|
{
|
|
|
|
|
let g = hprof::enter("Textured Vertex Buffer");
|
|
|
|
|
for (k, v) in textured_drawables.drain() {
|
|
|
|
|
let vertex_buffer = v.clone().get(0).unwrap().clone();
|
|
|
|
|
// TODO
|
|
|
|
|
// v.clone().iter()
|
|
|
|
|
// .fold(Vec::new(), |mut a: Vec<RuntimeVertexDef>, b| {
|
|
|
|
|
// a.extend(b);
|
|
|
|
|
// a
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
self.textured_vertex_buffer.insert(
|
|
|
|
|
k.clone(),
|
|
|
|
|
ImmutableBuffer::from_iter(
|
|
|
|
|
vertex_buffer.iter().cloned(),
|
|
|
|
|
BufferUsage::vertex_buffer(),
|
|
|
|
|
self.queue.clone(),
|
|
|
|
|
).unwrap().0,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self.image_vertex_buffer.clear();
|
|
|
|
|
{
|
|
|
|
|
let g = hprof::enter("Image Vertex Buffer");
|
|
|
|
|
for (k, v) in image_drawables.drain() {
|
|
|
|
|
let vertex_buffer = v.clone().get(0).unwrap().clone();
|
|
|
|
|
// TODO
|
|
|
|
|
// v.clone().iter()
|
|
|
|
|
// .fold(Vec::new(), |mut a: Vec<&RuntimeVertexDef>, b| {
|
|
|
|
|
// a.extend(b);
|
|
|
|
|
// a
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
self.image_vertex_buffer.insert(
|
|
|
|
|
k.clone(),
|
|
|
|
|
ImmutableBuffer::from_iter(
|
|
|
|
|
vertex_buffer.iter().cloned(),
|
|
|
|
|
BufferUsage::vertex_buffer(),
|
|
|
|
|
self.queue.clone(),
|
|
|
|
|
).unwrap().0,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self.text_instances.clear();
|
|
|
|
|
{
|
|
|
|
|
let g = hprof::enter("Text Instance Vertex Buffer");
|
|
|
|
|
for (k, v) in text_drawables.drain() {
|
|
|
|
|
self.text_instances.insert(
|
|
|
|
|
k.clone(),
|
|
|
|
|
ImmutableBuffer::from_iter(
|
|
|
|
|
v.iter().cloned(),
|
|
|
|
|
BufferUsage::all(),
|
|
|
|
|
self.queue.clone(),
|
|
|
|
|
).unwrap().0,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Builds the descriptor set for solid colors using the input kernel (needs to support solid colors)
|
|
|
|
|
fn get_solid_color_descriptor_set(&self, kernel: Arc<GenericShader>) -> Box<dyn DescriptorSet + Send + Sync> {
|
|
|
|
|
let o: Box<dyn DescriptorSet + Send + Sync> = Box::new(
|
|
|
|
@ -487,79 +385,58 @@ impl CanvasState {
|
|
|
|
|
o
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Consume and allocated the canvas frame data to the GPU
|
|
|
|
|
pub fn allocate(&mut self, canvas_frame: CanvasFrameTest) -> CanvasFrameAllocation {
|
|
|
|
|
|
|
|
|
|
// This is taking in a canvas frame, which should be some sort of matrix of vertices of generic
|
|
|
|
|
// types and handles
|
|
|
|
|
pub fn draw_commands_test<VTypes: Into<VertexTypes>>(&mut self,
|
|
|
|
|
mut command_buffer: AutoCommandBufferBuilder,
|
|
|
|
|
framebuffers: Vec<Arc<dyn FramebufferAbstract + Send + Sync>>,
|
|
|
|
|
image_num: usize,
|
|
|
|
|
canvas_frame: CanvasFrameTest<VTypes>) -> AutoCommandBufferBuilder {
|
|
|
|
|
let mut colored_vertex_buffer: Vec<ColorVertex2D> = Vec::default();
|
|
|
|
|
let mut textured_vertex_buffer: HashMap<Arc<CanvasTextureHandle>, Vec<TextureVertex2D>> = HashMap::new();
|
|
|
|
|
let mut image_vertex_buffer: HashMap<Arc<CanvasImageHandle>, Vec<ImageVertex2D>> = HashMap::new();
|
|
|
|
|
let mut text_instances: HashMap<Arc<CanvasFontHandle>, Vec<TextVertex3D>> = HashMap::new();
|
|
|
|
|
|
|
|
|
|
// Specify the color to clear the framebuffer with i.e. blue
|
|
|
|
|
let clear_values = vec!(
|
|
|
|
|
ClearValue::Float([0.0, 0.0, 1.0, 1.0]),
|
|
|
|
|
ClearValue::DepthStencil((1.0, 0x00)),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
self.dynamic_state = DynamicState {
|
|
|
|
|
line_width: None,
|
|
|
|
|
viewports: self.dynamic_state.viewports.clone(),
|
|
|
|
|
scissors: None,
|
|
|
|
|
compare_mask: None,
|
|
|
|
|
write_mask: None,
|
|
|
|
|
reference: None,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let mut command_buffer = command_buffer.begin_render_pass(
|
|
|
|
|
framebuffers[image_num].clone(), false, clear_values.clone(),
|
|
|
|
|
).unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (k,v) in canvas_frame.map {
|
|
|
|
|
|
|
|
|
|
let buffer: Arc<(dyn BufferAccess + Send + Sync)> = match v.into() {
|
|
|
|
|
|
|
|
|
|
VertexTypes::TexturedType(vertices) => {
|
|
|
|
|
|
|
|
|
|
// Solid colors
|
|
|
|
|
let mut shader = self.shader_buffers.get(
|
|
|
|
|
self.get_shader_handle(String::from("color-passthrough"))
|
|
|
|
|
.unwrap().clone().get_handle() as usize
|
|
|
|
|
).unwrap();
|
|
|
|
|
|
|
|
|
|
let buffer = ImmutableBuffer::from_iter(
|
|
|
|
|
vertices.iter().cloned(),
|
|
|
|
|
BufferUsage::vertex_buffer(),
|
|
|
|
|
self.queue.clone(),
|
|
|
|
|
).unwrap().0;
|
|
|
|
|
|
|
|
|
|
if !self.colored_vertex_buffer.is_empty() {
|
|
|
|
|
command_buffer = command_buffer.draw(
|
|
|
|
|
shader.get_pipeline().clone(),
|
|
|
|
|
&self.dynamic_state.clone(),
|
|
|
|
|
vec![buffer.clone()],
|
|
|
|
|
(), (),
|
|
|
|
|
).unwrap();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buffer
|
|
|
|
|
},
|
|
|
|
|
VertexTypes::VType2(vertices) => {
|
|
|
|
|
ImmutableBuffer::from_iter(
|
|
|
|
|
vertices.iter().cloned(),
|
|
|
|
|
BufferUsage::vertex_buffer(),
|
|
|
|
|
self.queue.clone(),
|
|
|
|
|
).unwrap().0
|
|
|
|
|
for value in canvas_frame.map {
|
|
|
|
|
match value {
|
|
|
|
|
VertexTypes::TextureType(vertices, handle) => {
|
|
|
|
|
textured_vertex_buffer.entry(handle).or_insert(vertices.clone()).extend(vertices);
|
|
|
|
|
}
|
|
|
|
|
VertexTypes::ImageType(vertices, handle) => {
|
|
|
|
|
image_vertex_buffer.entry(handle).or_insert(vertices.clone()).extend(vertices);
|
|
|
|
|
}
|
|
|
|
|
VertexTypes::ColorType(vertices) => {
|
|
|
|
|
colored_vertex_buffer.extend(vertices);
|
|
|
|
|
}
|
|
|
|
|
VertexTypes::ThreeDType(vertices) => {}
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut allocated_colored_buffer: Vec<Arc<(dyn BufferAccess + Send + Sync)>> = Vec::new();
|
|
|
|
|
if !colored_vertex_buffer.is_empty() {
|
|
|
|
|
allocated_colored_buffer.push(ImmutableBuffer::from_iter(
|
|
|
|
|
colored_vertex_buffer.iter().cloned(),
|
|
|
|
|
BufferUsage::vertex_buffer(),
|
|
|
|
|
self.queue.clone(),
|
|
|
|
|
).unwrap().0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
command_buffer
|
|
|
|
|
|
|
|
|
|
CanvasFrameAllocation {
|
|
|
|
|
colored_vertex_buffer: allocated_colored_buffer,
|
|
|
|
|
textured_vertex_buffer: textured_vertex_buffer.into_iter().map(|(k, v)| {
|
|
|
|
|
(k,
|
|
|
|
|
ImmutableBuffer::from_iter(
|
|
|
|
|
v.iter().cloned(),
|
|
|
|
|
BufferUsage::vertex_buffer(),
|
|
|
|
|
self.queue.clone(),
|
|
|
|
|
).unwrap().0 as Arc<(dyn BufferAccess + Send + Sync)>)
|
|
|
|
|
}).collect(),
|
|
|
|
|
image_vertex_buffer: image_vertex_buffer.into_iter().map(|(k, v)| {
|
|
|
|
|
(k,
|
|
|
|
|
ImmutableBuffer::from_iter(
|
|
|
|
|
v.iter().cloned(),
|
|
|
|
|
BufferUsage::vertex_buffer(),
|
|
|
|
|
self.queue.clone(),
|
|
|
|
|
).unwrap().0 as Arc<(dyn BufferAccess + Send + Sync)>)
|
|
|
|
|
}).collect(),
|
|
|
|
|
text_instances: Default::default(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Pushes the draw commands to the command buffer. Requires the framebuffers and
|
|
|
|
@ -567,7 +444,8 @@ impl CanvasState {
|
|
|
|
|
pub fn draw_commands(&mut self,
|
|
|
|
|
mut command_buffer: AutoCommandBufferBuilder,
|
|
|
|
|
framebuffers: Vec<Arc<dyn FramebufferAbstract + Send + Sync>>,
|
|
|
|
|
image_num: usize) -> AutoCommandBufferBuilder {
|
|
|
|
|
image_num: usize,
|
|
|
|
|
allocated_buffers: CanvasFrameAllocation) -> AutoCommandBufferBuilder {
|
|
|
|
|
|
|
|
|
|
// Specify the color to clear the framebuffer with i.e. blue
|
|
|
|
|
let clear_values = vec!(
|
|
|
|
@ -597,11 +475,11 @@ impl CanvasState {
|
|
|
|
|
// This looks a little weird as colored_vertex_buffer is a vec of GPU allocated vecs.
|
|
|
|
|
// But we can pass in multiple vertex buffers
|
|
|
|
|
|
|
|
|
|
if !self.colored_vertex_buffer.is_empty() {
|
|
|
|
|
if allocated_buffers.colored_vertex_buffer.is_empty() {
|
|
|
|
|
command_buffer = command_buffer.draw(
|
|
|
|
|
shader.get_pipeline().clone(),
|
|
|
|
|
&self.dynamic_state.clone(),
|
|
|
|
|
self.colored_vertex_buffer.clone(),
|
|
|
|
|
allocated_buffers.colored_vertex_buffer.clone(),
|
|
|
|
|
(), (),
|
|
|
|
|
).unwrap();
|
|
|
|
|
}
|
|
|
|
@ -612,8 +490,8 @@ impl CanvasState {
|
|
|
|
|
.unwrap().clone().get_handle() as usize
|
|
|
|
|
).unwrap();
|
|
|
|
|
|
|
|
|
|
if !self.image_vertex_buffer.is_empty() {
|
|
|
|
|
for (image_handle, vertex_buffer) in self.image_vertex_buffer.clone() {
|
|
|
|
|
if !allocated_buffers.image_vertex_buffer.is_empty() {
|
|
|
|
|
for (image_handle, vertex_buffer) in allocated_buffers.image_vertex_buffer.clone() {
|
|
|
|
|
let handle = image_handle.clone().get_handle() as usize;
|
|
|
|
|
let descriptor_set = self.image_buffers.get(handle).clone().unwrap().clone()
|
|
|
|
|
.get_descriptor_set(shader.get_pipeline().clone());
|
|
|
|
@ -633,8 +511,8 @@ impl CanvasState {
|
|
|
|
|
.unwrap().clone().get_handle() as usize
|
|
|
|
|
).unwrap();
|
|
|
|
|
|
|
|
|
|
if !self.textured_vertex_buffer.is_empty() {
|
|
|
|
|
for (texture_handle, vertex_buffer) in self.textured_vertex_buffer.clone() {
|
|
|
|
|
if !allocated_buffers.textured_vertex_buffer.is_empty() {
|
|
|
|
|
for (texture_handle, vertex_buffer) in allocated_buffers.textured_vertex_buffer.clone() {
|
|
|
|
|
let handle = texture_handle.clone().get_handle() as usize;
|
|
|
|
|
let descriptor_set = self.texture_buffers.get(handle).clone().unwrap().clone()
|
|
|
|
|
.get_descriptor_set(shader.get_pipeline(), self.sampler.clone());
|
|
|
|
|