1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
use std::ffi::CStr;
use vulkano::buffer::{CpuAccessibleBuffer, BufferUsage};
use std::sync::Arc;
use vulkano::framebuffer::RenderPassAbstract;
use vulkano::pipeline::{GraphicsPipelineAbstract, ComputePipeline};
use vulkano::device::Device;
use image::ImageBuffer;
use image::GenericImageView;
use vulkano::image::{ImageUsage, AttachmentImage};
use vulkano::descriptor::descriptor_set::{PersistentDescriptorSetBuf, PersistentDescriptorSet};
use vulkano::format::Format;
use vulkano::descriptor::pipeline_layout::PipelineLayout;
use std::borrow::Borrow;
use image::Rgba;
use vulkano::command_buffer::AutoCommandBufferBuilder;
use std::path::PathBuf;
use shade_runner::{CompiledShaders, Entry, CompileError};
use vulkano::pipeline::shader::ShaderModule;
use shaderc::CompileOptions;
use crate::compute::compu_frame::CompuFrame;
use crate::canvas::managed::handles::Handle;
use crate::compute::managed::compu_buffer::CompuBuffers;
use crate::compute::managed::handles::{CompuKernelHandle, CompuBufferHandle};
use crate::compute::managed::compu_kernel::CompuKernel;
use crate::canvas::canvas_state::CanvasState;


/// State holding the compute buffers for computation and the kernels which will compute them
pub struct CompuState {
    compute_buffers: Vec<CompuBuffers>,
    kernels: Vec<CompuKernel>,
}

impl CompuState {

    pub fn new() -> CompuState {
        CompuState {
            compute_buffers: vec![],
            kernels: vec![],
        }
    }

    /// 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
    }

    /// Read the compute buffer back into a Vec (TODO BROKEN)
    pub fn read_compute_buffer(&mut self, handle: Arc<CompuBufferHandle>) -> Vec<u8> {
        // This is way more difficult than it should be
        //let compute_buffer : CompuBuffers = self.compute_buffers.get(handle.into()).unwrap();
        //compute_buffer.read_output_buffer().to_vec()
        unimplemented!("read_compute_buffer is not implemented")
    }

    /// 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: AutoCommandBufferBuilder,
                            canvas: &CanvasState)
                            -> 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 = canvas.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[0], dimensions[1]);
            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_input_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();
        }

        command_buffer
    }
}