@ -27,24 +27,27 @@ use std::io::Read;
use rusttype ::{ Font , PositionedGlyph , Scale , Rect , point , GlyphId , Line , Curve , Segment } ;
use vulkano ::pipeline ::vertex ::{ VertexDefinition , Vertex } ;
use crate ::canvas ::managed ::shader ::dynamic_vertex ::RuntimeVertexDef ;
use crate ::canvas ::managed ::handles ::{ CanvasTextureHandle , CanvasImageHandle , CanvasFontHandle , CompiledShaderHandle , Handle , DrawableHandle };
use crate ::canvas ::managed ::handles ::{ CanvasTextureHandle , CanvasImageHandle , CanvasFontHandle , CompiledShaderHandle , Handle , DrawableHandle , CompuBufferHandle , CompuKernelHandle };
use crate ::canvas ::managed ::gpu_buffers ::{ CanvasImage , CanvasTexture , CanvasFont } ;
use crate ::canvas ::managed ::shader ::shader_common ::CompiledShader ;
use crate ::canvas ::managed ::shader ::generic_shader ::GenericShader ;
use crate ::VertexType ;
use crate ::VertexType Container ;
use crate ::util ::vertex ::{ TextVertex3D , TextureVertex3D , ImageVertex3D , ColorVertex3D , CanvasFrameAllocation } ;
use shade_runner ::Input ;
use winit ::window ::Window ;
use crate ::canvas ::managed ::compu_buffer ::CompuBuffers ;
use crate ::canvas ::managed ::compu_kernel ::CompuKernel ;
use crate ::canvas ::compu_frame ::CompuFrame ;
/// Canvas state is used for storage of texture and image buffers in addition to vertex buffers
/// Canvas state also contains logic for writing the stored buffers to the command_buffer
#[ derive(Clone )]
#[ derive(Clone , Default )]
pub struct CanvasState {
/// Generated during new()
dynamic_state : DynamicState ,
/// Generated during new()
sampler : Arc < Sampler > ,
sampler : Option < Arc < Sampler > > ,
/// hold the image, texture, and Fonts the same was as we do CompuState
image_buffers : Vec < Arc < CanvasImage > > ,
@ -52,12 +55,15 @@ pub struct CanvasState {
font_buffers : Vec < Arc < CanvasFont > > ,
/// Compiled Graphics pipelines have a handle which self describe their position in this vector
shader_buffers : Vec < Arc < Box < dyn CompiledShader > > > ,
shader_buffers : Vec < Arc < Box < dyn CompiledShader + Send + Sync > > > ,
/// Looks like we gotta hold onto the queue for managing textures
queue : Arc < Queue > ,
device : Arc < Device > ,
render_pass : Arc < dyn RenderPassAbstract + Send + Sync > ,
queue : Option < Arc < Queue > > ,
device : Option < Arc < Device > > ,
render_pass : Option < Arc < dyn RenderPassAbstract + Send + Sync > > ,
compute_buffers : Vec < CompuBuffers > ,
kernels : Vec < CompuKernel > ,
}
@ -75,11 +81,11 @@ impl CanvasState {
} ] ) ;
let dimensions = [ dimensions . width ( ) , dimensions . height ( ) ] ;
let depth_buffer = AttachmentImage ::transient ( self . device . clone ( ) , dimensions , Format ::D32Sfloat_S8Uint ) . unwrap ( ) ;
let depth_buffer = AttachmentImage ::transient ( self . device . clone ( ) .unwrap ( ) , dimensions , Format ::D32Sfloat_S8Uint ) . unwrap ( ) ;
images . iter ( ) . map ( | image | {
Arc ::new (
Framebuffer ::start ( self . render_pass . clone ( ) )
Framebuffer ::start ( self . render_pass . clone ( ) .unwrap ( ) )
. add ( image . clone ( ) ) . unwrap ( )
. add ( depth_buffer . clone ( ) ) . unwrap ( )
. build ( ) . unwrap ( )
@ -133,6 +139,9 @@ impl CanvasState {
CanvasState {
compute_buffers : vec ! [ ] ,
kernels : vec ! [ ] ,
// TODO: Might need to move this
dynamic_state : DynamicState {
line_width : None ,
@ -151,20 +160,147 @@ impl CanvasState {
value : 0xFF ,
} ) ,
} ,
sampler : Sampler::new ( device . clone ( ) ,
sampler : Some ( Sampler::new ( device . clone ( ) ,
Filter ::Linear , Filter ::Linear ,
MipmapMode ::Nearest ,
SamplerAddressMode ::Repeat , SamplerAddressMode ::Repeat ,
SamplerAddressMode ::Repeat , 0.0 , 1.0 , 0.0 , 0.0 ) . unwrap ( ) ,
SamplerAddressMode ::Repeat , 0.0 , 1.0 , 0.0 , 0.0 ) . unwrap ( ) ) ,
image_buffers : vec ! [ ] ,
texture_buffers : vec ! [ ] ,
shader_buffers : vec ! [ ] ,
font_buffers : vec ! [ ] ,
queue : queue . clone ( ) ,
device : device . clone ( ) ,
render_pass : render_pass . clone ( ) ,
queue : Some ( queue . clone ( ) ) ,
device : Some ( device . clone ( ) ) ,
render_pass : Some ( render_pass . clone ( ) ) ,
}
}
pub fn read_compute_buffer ( & mut self , handle : Arc < CompuBufferHandle > ) -> Vec < u8 > {
let mut buffer : & CompuBuffers = self . compute_buffers . get ( handle . handle as usize ) . unwrap ( ) ;
let v = buffer . read_output_buffer ( ) ;
v . into_vec ( )
}
/// Write to the compute buffer, ostensibly overwriting what's already there
pub fn write_compute_buffer ( & self , handle : Arc < CompuBufferHandle > , data : Vec < u8 > ) {
unimplemented! ( "read_compute_buffer is not implemented" )
}
pub fn new_kernel ( & mut self ,
filename : String ,
device : Arc < Device > ) -> Arc < CompuKernelHandle > {
let handle = Arc ::new ( CompuKernelHandle {
handle : self . kernels . len ( ) as u32
} ) ;
self . kernels . push ( ( CompuKernel ::new ( filename , device . clone ( ) , handle . clone ( ) ) ) ) ;
handle
}
pub fn get_kernel_handle ( & self , kernel_name : String ) -> Option < Arc < CompuKernelHandle > > {
for i in self . kernels . clone ( ) {
if i . get_name ( ) = = kernel_name {
return Some ( i . get_handle ( ) ) ;
}
}
None
}
pub fn compute_commands ( & mut self ,
compute_frame : & CompuFrame ,
mut command_buffer : & mut AutoCommandBufferBuilder ) {
// i = (Buffer, Kernel)
for i in & compute_frame . pure_compute {
let buffer_id = ( * i . 0 ) . clone ( ) . get_handle ( ) as usize ;
let kernel_id = ( * i . 1 ) . clone ( ) . get_handle ( ) as usize ;
let buffer = self . compute_buffers . get ( buffer_id ) . unwrap ( ) ;
let kernel = self . kernels . get ( kernel_id ) . unwrap ( ) ;
let pipeline = kernel . clone ( ) . get_pipeline ( ) ;
let descriptorset = buffer . get_descriptor_set ( kernel . clone ( ) . get_pipeline ( ) ) ;
let size = buffer . get_size ( ) ;
command_buffer = command_buffer
. dispatch ( [ size . 0 / 8 , size . 1 / 8 , 1 ] , pipeline , descriptorset , ( ) ) . unwrap ( )
}
// i = (Buffer, Image, Kernel)
for i in & compute_frame . swapped_to_image {
let buffer_id = ( * i . 0 ) . clone ( ) . get_handle ( ) as usize ;
let image_id = i . 1. clone ( ) ;
let kernel_id = ( * i . 2 ) . clone ( ) . handle as usize ;
let buffer = self . compute_buffers . get ( buffer_id ) . unwrap ( ) ;
let image = self . get_image ( image_id ) ;
let kernel = self . kernels . get ( kernel_id ) . unwrap ( ) ;
let p = kernel . clone ( ) . get_pipeline ( ) ;
let d = buffer . get_descriptor_set ( kernel . clone ( ) . get_pipeline ( ) ) ;
let dimensions = image . dimensions ( ) ;
let dimensions = ( dimensions . width ( ) , dimensions . height ( ) ) ;
if dimensions ! = buffer . get_size ( ) {
panic! ( "Buffer sizes not the same" ) ;
}
let size = buffer . get_size ( ) ;
command_buffer = command_buffer
. dispatch ( [ size . 0 / 8 , size . 1 / 8 , 1 ] , p , d , ( ) ) . unwrap ( )
. copy_buffer_to_image ( buffer . get_output_buffer ( ) , image ) . unwrap ( ) ;
}
// i = (Input Buffer, Output Buffer, Kernel)
// Input buffer -> Kernel -> Output buffer
for i in & compute_frame . swapped_to_buffer {
let input_buffer_id = ( * i . 0 ) . clone ( ) . get_handle ( ) as usize ;
let output_buffer_id = ( * i . 1 ) . clone ( ) . get_handle ( ) as usize ;
let kernel_id = ( * i . 2 ) . clone ( ) . handle as usize ;
let input_buffer = self . compute_buffers . get ( input_buffer_id ) . unwrap ( ) ;
let output_buffer = self . compute_buffers . get ( output_buffer_id ) . unwrap ( ) ;
let kernel = self . kernels . get ( kernel_id ) . unwrap ( ) ;
let pipeline = kernel . clone ( ) . get_pipeline ( ) ;
let descriptor_set = input_buffer . get_descriptor_set ( kernel . clone ( ) . get_pipeline ( ) ) ;
if input_buffer . get_size ( ) ! = output_buffer . get_size ( ) {
panic! ( "Buffer sizes not the same" ) ;
}
let size = input_buffer . get_size ( ) ;
command_buffer = command_buffer
// .dispatch([size.0/8, size.1/8,1], pipeline, descriptor_set, ()).unwrap()
. copy_buffer (
input_buffer . get_output_buffer ( ) ,
output_buffer . get_input_buffer ( ) ) . unwrap ( ) ;
}
}
/// Creates a 2d compute buffer from incoming data
pub fn new_compute_buffer ( & mut self ,
data : Vec < u8 > ,
dimensions : ( u32 , u32 ) ,
stride : u32 ,
device : Arc < Device > ) -> Arc < CompuBufferHandle > {
let handle = Arc ::new ( CompuBufferHandle {
handle : self . compute_buffers . len ( ) as u32
} ) ;
self . compute_buffers . push (
( CompuBuffers ::new ( device . clone ( ) , data , dimensions , stride , handle . clone ( ) ) ) ) ;
handle
}
/// Using the dimensions and suggested usage, load a CanvasImage and return it's handle
@ -174,7 +310,7 @@ impl CanvasState {
let image = CanvasImage {
handle : handle . clone ( ) ,
buffer : AttachmentImage ::with_usage (
self . device . clone ( ) ,
self . device . clone ( ) .unwrap ( ) ,
[ dimensions . 0 , dimensions . 1 ] ,
Format ::R8G8B8A8Uint ,
usage ) . unwrap ( ) ,
@ -228,7 +364,7 @@ impl CanvasState {
image_buffer . iter ( ) . cloned ( ) ,
Dimensions ::Dim2d { width : xy . 0 , height : xy . 1 } ,
Format ::R8G8B8A8Srgb ,
self . queue . clone ( ) ,
self . queue . clone ( ) .unwrap ( ) ,
) . unwrap ( ) ;
texture
@ -254,19 +390,19 @@ impl CanvasState {
/// Load and Compile a shader with the filename at resources/shaders
/// Takes physical and capabilities as we don't store that in Canvas
pub fn load_shader < T : ' static , V > ( & mut self ,
filename : String ,
capabilities : Capabilities ) -> Option < Arc < CompiledShaderHandle > >
where T : CompiledShader , V : Vertex {
pub fn load_shader < T , V > ( & mut self ,
filename : String ) -> Option < Arc < CompiledShaderHandle > >
where T : CompiledShader + Send + Sync + ' static , V : Vertex {
let handle = Arc ::new ( CompiledShaderHandle {
handle : self . shader_buffers . len ( ) as u32
} ) ;
let shader : Box < dyn CompiledShader > = Box ::new ( T ::new ::< V > (
let shader : Box < dyn CompiledShader + Send + Sync > = Box ::new ( T ::new ::< V > (
filename . clone ( ) ,
self . device . clone ( ) ,
self . device . clone ( ) .unwrap ( ) ,
handle . clone ( ) ,
self . render_pass . clone ( ) ,
self . render_pass . clone ( ) .unwrap ( ) ,
) ) ;
self . shader_buffers . push ( Arc ::new ( shader ) ) ;
@ -324,7 +460,7 @@ impl CanvasState {
name : name ,
buffer : ImmutableBuffer ::from_iter (
accumulator . iter ( ) . cloned ( ) ,
BufferUsage ::vertex_buffer ( ) , self . queue . clone ( ) ). unwrap ( ) . 0 ,
BufferUsage ::vertex_buffer ( ) , self . queue . clone ( ) .unwrap ( ) ). unwrap ( ) . 0 ,
}
} ) ) ;
@ -396,19 +532,19 @@ impl CanvasState {
// separate the mux of vertex containers back out
for value in & canvas_frame . map {
match value {
VertexType ::TextureType ( vertices , handle ) = > {
VertexType Container ::TextureType ( vertices , handle ) = > {
textured_vertex_buffer . entry ( handle . clone ( ) ) . or_insert ( vertices . clone ( ) ) . extend ( vertices ) ;
}
VertexType ::ImageType ( vertices , handle ) = > {
VertexType Container ::ImageType ( vertices , handle ) = > {
image_vertex_buffer . entry ( handle . clone ( ) ) . or_insert ( vertices . clone ( ) ) . extend ( vertices ) ;
}
VertexType ::ColorType ( vertices ) = > {
VertexType Container ::ColorType ( vertices ) = > {
colored_vertex_buffer . extend ( vertices ) ;
}
VertexType ::ThreeDType ( vertices ) = > {
VertexType Container ::ThreeDType ( vertices ) = > {
}
VertexType ::TextType ( vertices ) = > {
VertexType Container ::TextType ( vertices ) = > {
text_vertex_buffer . extend ( vertices ) ;
}
} ;
@ -419,7 +555,7 @@ impl CanvasState {
allocated_colored_buffer . push ( ImmutableBuffer ::from_iter (
colored_vertex_buffer . iter ( ) . cloned ( ) ,
BufferUsage ::vertex_buffer ( ) ,
self . queue . clone ( ) ,
self . queue . clone ( ) .unwrap ( ) ,
) . unwrap ( ) . 0 ) ;
}
@ -428,7 +564,7 @@ impl CanvasState {
allocated_text_buffer . push ( ImmutableBuffer ::from_iter (
text_vertex_buffer . iter ( ) . cloned ( ) ,
BufferUsage ::vertex_buffer ( ) ,
self . queue . clone ( ) ,
self . queue . clone ( ) .unwrap ( ) ,
) . unwrap ( ) . 0 ) ;
}
@ -439,7 +575,7 @@ impl CanvasState {
ImmutableBuffer ::from_iter (
v . iter ( ) . cloned ( ) ,
BufferUsage ::vertex_buffer ( ) ,
self . queue . clone ( ) ,
self . queue . clone ( ) .unwrap ( ) ,
) . unwrap ( ) . 0 as Arc < ( dyn BufferAccess + Send + Sync ) > )
} ) . collect ( ) ,
image_vertex_buffer : image_vertex_buffer . into_iter ( ) . map ( | ( k , v ) | {
@ -447,7 +583,7 @@ impl CanvasState {
ImmutableBuffer ::from_iter (
v . iter ( ) . cloned ( ) ,
BufferUsage ::vertex_buffer ( ) ,
self . queue . clone ( ) ,
self . queue . clone ( ) .unwrap ( ) ,
) . unwrap ( ) . 0 as Arc < ( dyn BufferAccess + Send + Sync ) > )
} ) . collect ( ) ,
text_instances : Default ::default ( ) ,
@ -532,7 +668,7 @@ impl CanvasState {
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 ( ) );
. get_descriptor_set ( shader . get_pipeline ( ) , self . sampler . clone ( ) .unwrap ( ) );
command_buffer = command_buffer . draw (
shader . get_pipeline ( ) . clone ( ) ,