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
use std::ffi::CStr;
use vulkano::buffer::{CpuAccessibleBuffer, BufferUsage};
use std::sync::Arc;
use crate::canvas::{Drawable, CanvasState, CanvasImageHandle, CanvasTextureHandle};
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::compu_kernel::{CompuKernel, CompuKernelHandle};
use crate::compu_buffer::{CompuBuffers, CompuBufferHandle};
use crate::compu_frame::CompuFrame;


// Canvas analog
pub struct CompuState {
    compute_buffers: Vec<CompuBuffers>,
    kernels: Vec<CompuKernel>,
}

impl CompuState {

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

    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
    }

    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()
        Vec::new()
    }
    pub fn write_compute_buffer(&self, handle: Arc<CompuBufferHandle>, data: Vec<u8>) {}

    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().handle as usize;
            let kernel_id = (*i.1).clone().handle as usize;

            let buffer = self.compute_buffers.get(buffer_id).unwrap();
            let kernel = self.kernels.get(buffer_id).unwrap();

            let p = kernel.clone().get_pipeline();
            let d = 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], p, d, ()).unwrap()
        }

        // i = (Buffer, Image, Kernel)
        for i in compute_frame.swapped_to_image {
            let buffer_id = (*i.0).clone().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(buffer_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,size.1,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().handle as usize;
            let output_buffer_id = (*i.1).clone().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());

            command_buffer = command_buffer
                .dispatch([100,100,1], pipeline, descriptor_set, ()).unwrap()
                .copy_buffer(
                    input_buffer.get_output_buffer(),
                    output_buffer.get_input_buffer()).unwrap();
        }

        command_buffer
    }
}