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.
123 lines
4.4 KiB
123 lines
4.4 KiB
6 years ago
|
|
||
|
use std::collections::HashSet;
|
||
|
use std::path::PathBuf;
|
||
|
use vulkano::pipeline::GraphicsPipelineAbstract;
|
||
|
use vulkano::framebuffer::RenderPassAbstract;
|
||
|
use std::sync::Arc;
|
||
6 years ago
|
use vulkano::pipeline::shader::{ShaderModule, GraphicsShaderType, GeometryShaderExecutionMode};
|
||
|
use vulkano::device::Device;
|
||
|
use shade_runner::Entry;
|
||
|
use shaderc::ShaderKind;
|
||
5 years ago
|
use crate::canvas::managed::handles::CompiledGraphicsPipelineHandle;
|
||
6 years ago
|
|
||
|
/*
|
||
|
|
||
|
Realistically, what should the API for this thing look like...
|
||
|
|
||
|
It's going to just generate a pipeline. But that consists of loading and compiling various shaders,
|
||
|
and generating a pipeline for those shaders and other customer behaviour.
|
||
|
|
||
|
This best works I think if I allow users to
|
||
|
A.) impl from a base trait which allows resource lookup
|
||
|
B.) Generate 1 of each of the types of shaders
|
||
|
C.) Modify specilization constants, whatever that might mean
|
||
|
D.) impl from a base trait which defines it's interface
|
||
|
|
||
|
*/
|
||
|
|
||
|
|
||
|
|
||
|
/// Inheriting this gives private functions to grab resources
|
||
5 years ago
|
pub trait CompiledGraphicsPipelineResources {
|
||
6 years ago
|
|
||
|
fn get_path(filename: String, shader_type: ShaderType) -> PathBuf {
|
||
6 years ago
|
let project_root =
|
||
|
std::env::current_dir()
|
||
|
.expect("failed to get root directory");
|
||
|
|
||
|
let mut shader_path = project_root.clone();
|
||
|
shader_path.push(PathBuf::from("resources/shaders/"));
|
||
|
|
||
6 years ago
|
|
||
|
let mut shader_path = shader_path.clone();
|
||
|
|
||
|
match shader_type {
|
||
|
ShaderType::VERTEX => {
|
||
|
shader_path.push(PathBuf::from(filename.clone() + ".vert"));
|
||
|
}
|
||
|
ShaderType::FRAGMENT => {
|
||
|
shader_path.push(PathBuf::from(filename.clone() + ".frag"));
|
||
|
}
|
||
|
ShaderType::GEOMETRY => {
|
||
|
shader_path.push(PathBuf::from(filename.clone() + ".geom"));
|
||
6 years ago
|
}
|
||
6 years ago
|
ShaderType::TESSELLATION_CONTROL => {
|
||
|
shader_path.push(PathBuf::from(filename.clone() + ".tesscont"));
|
||
|
}
|
||
|
ShaderType::TESSELLATION_EVALUATION => {
|
||
|
shader_path.push(PathBuf::from(filename.clone() + ".tesseval"));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
shader_path
|
||
|
}
|
||
|
|
||
|
|
||
|
fn compile(filepath: PathBuf, device: Arc<Device>, shader_type: ShaderType) -> (Entry, Arc<ShaderModule>) {
|
||
|
let compiled_shader = shade_runner::load(filepath, Self::convert_sr(shader_type))
|
||
|
.expect("Shader didn't compile");
|
||
|
|
||
|
let vulkano_entry =
|
||
|
shade_runner::parse(&compiled_shader)
|
||
|
.expect("failed to parse");
|
||
|
|
||
|
(vulkano_entry, unsafe {
|
||
|
ShaderModule::from_words(device.clone(), &compiled_shader.spriv.clone())
|
||
|
}.unwrap())
|
||
|
}
|
||
|
|
||
|
fn convert_vk(shader_type: ShaderType) -> GraphicsShaderType {
|
||
|
match shader_type {
|
||
|
ShaderType::VERTEX => { GraphicsShaderType::Vertex }
|
||
|
ShaderType::FRAGMENT => { GraphicsShaderType::Fragment }
|
||
|
ShaderType::GEOMETRY => { GraphicsShaderType::Geometry(GeometryShaderExecutionMode::Triangles) }
|
||
|
ShaderType::TESSELLATION_CONTROL => { GraphicsShaderType::TessellationControl }
|
||
|
ShaderType::TESSELLATION_EVALUATION => { GraphicsShaderType::TessellationEvaluation }
|
||
6 years ago
|
}
|
||
6 years ago
|
}
|
||
6 years ago
|
|
||
6 years ago
|
fn convert_sr(shader_type: ShaderType) -> ShaderKind {
|
||
|
match shader_type {
|
||
|
ShaderType::VERTEX => { ShaderKind::Vertex }
|
||
|
ShaderType::FRAGMENT => { ShaderKind::Fragment }
|
||
|
ShaderType::GEOMETRY => { ShaderKind::Geometry }
|
||
|
ShaderType::TESSELLATION_CONTROL => { ShaderKind::TessControl }
|
||
|
ShaderType::TESSELLATION_EVALUATION => { ShaderKind::TessEvaluation }
|
||
|
}
|
||
6 years ago
|
}
|
||
|
}
|
||
|
|
||
5 years ago
|
|
||
6 years ago
|
|
||
|
pub trait CompiledGraphicsPipeline {
|
||
6 years ago
|
fn new(filename: String,
|
||
6 years ago
|
device: Arc<Device>,
|
||
|
handle: Arc<CompiledGraphicsPipelineHandle>,
|
||
|
render_pass: Arc<dyn RenderPassAbstract + Send + Sync>) -> Self where Self: Sized;
|
||
6 years ago
|
fn get_name(&self) -> String;
|
||
|
fn get_handle(&self) -> Arc<CompiledGraphicsPipelineHandle>;
|
||
|
fn get_pipeline(&self) -> Arc<dyn GraphicsPipelineAbstract + Sync + Send>;
|
||
5 years ago
|
fn get_renderpass(&self) -> Arc<dyn RenderPassAbstract + Send + Sync>;
|
||
6 years ago
|
fn recompile(self, render_pass: Arc<dyn RenderPassAbstract + Send + Sync>)
|
||
|
-> Self where Self: Sized;
|
||
|
}
|
||
|
|
||
|
/// Legacy ShaderType enum for single type shaders.
|
||
|
#[derive(PartialEq, Eq, Hash, Clone)]
|
||
|
pub enum ShaderType {
|
||
|
VERTEX = 0,
|
||
|
FRAGMENT = 1,
|
||
|
GEOMETRY = 2,
|
||
|
TESSELLATION_CONTROL = 3,
|
||
|
TESSELLATION_EVALUATION = 4,
|
||
|
}
|