You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Trac3r-rust/src/canvas/managed/shader/generic_shader.rs

145 lines
5.3 KiB

use vulkano::pipeline::GraphicsPipelineAbstract;
use std::sync::Arc;
use std::collections::{HashSet, HashMap};
use vulkano::device::Device;
use vulkano::framebuffer::{RenderPassAbstract, Subpass};
use vulkano::pipeline::GraphicsPipeline;
use vulkano::pipeline::shader::{GraphicsEntryPoint, ShaderModule, GraphicsShaderType, GeometryShaderExecutionMode, ShaderInterfaceDef};
use shade_runner::{Input, Output, Layout, Entry};
use std::ffi::CStr;
use std::marker::PhantomData;
use vulkano::pipeline::depth_stencil::{DepthStencil, Compare, DepthBounds, Stencil, StencilOp};
use vulkano::pipeline::vertex::{SingleBufferDefinition, VertexDefinition};
use crate::util::vertex_3d::Vertex3D;
use shade_runner as sr;
use vulkano::memory::pool::PotentialDedicatedAllocation::Generic;
use vulkano::SafeDeref;
use crate::canvas::managed::shader::shader_common::{ShaderType, CompiledGraphicsPipelineResources, CompiledGraphicsPipeline};
use crate::canvas::managed::handles::CompiledGraphicsPipelineHandle;
use crate::canvas::managed::shader::dynamic_vertex::RuntimeVertexDef;
use crate::canvas::managed::ShaderSpecializationConstants;
/// CanvasShader holds the pipeline and render pass for the input shader source
#[derive(Clone)]
pub struct GenericShader {
graphics_pipeline: Option<Arc<dyn GraphicsPipelineAbstract + Sync + Send>>,
handle: Arc<CompiledGraphicsPipelineHandle>,
name: String,
device: Arc<Device>,
renderpass: Arc<dyn RenderPassAbstract + Send + Sync>,
}
impl GenericShader {}
/// Gives CanvasShader the resource functions
impl CompiledGraphicsPipelineResources for GenericShader {}
/// Convenience interface so we don't have to juggle shader types
impl CompiledGraphicsPipeline for GenericShader {
/// This will explode when the shader does not want to compile
fn new(filename: String,
device: Arc<Device>,
handle: Arc<CompiledGraphicsPipelineHandle>,
render_pass: Arc<dyn RenderPassAbstract + Send + Sync>) -> GenericShader {
let compiled_vertex = GenericShader::compile(
GenericShader::get_path(filename.clone(), ShaderType::VERTEX),
device.clone(), ShaderType::VERTEX
);
let vertex_entry_point = unsafe {
Some(compiled_vertex.1.graphics_entry_point(
&CStr::from_bytes_with_nul_unchecked(b"main\0"),
compiled_vertex.0.input.unwrap(),
compiled_vertex.0.output.unwrap(),
compiled_vertex.0.layout,
GenericShader::convert_vk(ShaderType::VERTEX)
)).unwrap()
};
let compiled_fragment = GenericShader::compile(
GenericShader::get_path(filename.clone(), ShaderType::FRAGMENT).into(),
device.clone(), ShaderType::FRAGMENT
);
let fragment_entry_point = unsafe {
Some(compiled_fragment.1.graphics_entry_point(
&CStr::from_bytes_with_nul_unchecked(b"main\0"),
compiled_fragment.0.input.unwrap(),
compiled_fragment.0.output.unwrap(),
compiled_fragment.0.layout,
GenericShader::convert_vk(ShaderType::FRAGMENT)
)).unwrap()
};
let vertex_definition = RuntimeVertexDef::from_primitive(0);
GenericShader {
graphics_pipeline:
Some(Arc::new(GraphicsPipeline::start()
//SingleBufferDefinition::<Vertex3D>
.vertex_input(vertex_definition)
.vertex_shader(vertex_entry_point.clone(), ShaderSpecializationConstants {
first_constant: 0,
second_constant: 0,
third_constant: 0.0,
})
.triangle_list()
// Use a resizable viewport set to draw over the entire window
.viewports_dynamic_scissors_irrelevant(1)
.fragment_shader(fragment_entry_point.clone(), ShaderSpecializationConstants {
first_constant: 0,
second_constant: 0,
third_constant: 0.0,
})
.depth_stencil_simple_depth()
// We have to indicate which subpass of which render pass this pipeline is going to be used
// in. The pipeline will only be usable from this particular subpass.
.render_pass(Subpass::from(render_pass.clone(), 0).unwrap())
.build(device.clone())
.unwrap())),
device: device,
handle: handle.clone(),
name: filename.clone(),
renderpass: render_pass.clone(),
}
}
fn get_name(&self) -> String {
self.name.clone()
}
fn get_handle(&self) -> Arc<CompiledGraphicsPipelineHandle> {
self.handle.clone()
}
fn get_pipeline(&self) -> Arc<dyn GraphicsPipelineAbstract + Sync + Send> {
self.graphics_pipeline.clone().unwrap()
}
fn get_renderpass(&self) -> Arc<dyn RenderPassAbstract + Send + Sync> {
self.renderpass.clone()
}
fn recompile(self, render_pass: Arc<dyn RenderPassAbstract + Send + Sync>) -> GenericShader {
GenericShader::new(self.name,
self.device,
self.handle,
render_pass.clone())
}
}