still working on getiting these shaders to a usable API

master
mitchellhansen 5 years ago
parent 1a247e482a
commit 77d30591e6

@ -0,0 +1,21 @@
#version 450
// SIMPLE TEXTURE : FRAGMENT SHADER
// These come in from the previous shader (vertex)
layout(location = 0) in vec2 texture_position;
// This goes out to the bound image in window_size_dependent setup
layout(location = 0) out vec4 f_color;
// This is bound by the descriptor set
// Currently handled by the individual buffer and are 1:1
layout(set = 0, binding = 0) uniform sampler2D tex;
void main() {
ivec2 pixel_pos = ivec2(gl_FragCoord.x, gl_FragCoord.y);
f_color = texture(tex, texture_position);
float gamma = 0.5;
f_color.rgb = pow(f_color.rgb, vec3(1.0/gamma));
}

@ -0,0 +1,21 @@
#version 450
// SIMPLE TEXTURE : VERTEX SHADER
// These come in from the vertex definition
// TODO : Need to add texture coordinate attribute so I can single VBO all these sumbitches
layout(location = 0) in vec3 v_position;
layout(location = 1) in vec4 color;
layout(location = 2) in vec2 ti_position;
// These are made up in the shader themselves
layout(location = 0) out vec2 tex_coords;
void main() {
gl_Position = vec4(v_position, 1.0);
tex_coords = ti_position;
}

@ -27,6 +27,7 @@ use crate::util::vertex_3d::Vertex3D;
use vulkano::pipeline::depth_stencil::{StencilFaceFlags, DynamicStencilValue}; use vulkano::pipeline::depth_stencil::{StencilFaceFlags, DynamicStencilValue};
use crate::canvas::shader::common::{CompiledGraphicsPipeline, CompiledGraphicsPipelineHandle}; use crate::canvas::shader::common::{CompiledGraphicsPipeline, CompiledGraphicsPipelineHandle};
use crate::canvas::shader::generic_shader::GenericShader; use crate::canvas::shader::generic_shader::GenericShader;
use vulkano::memory::pool::PotentialDedicatedAllocation::Generic;
/// A drawable object can be passed into a CanvasFrame to be rendered /// A drawable object can be passed into a CanvasFrame to be rendered
/// Very generic implementation. (N % 2 == 0) vertices, ditto for texture coords, and rgba color /// Very generic implementation. (N % 2 == 0) vertices, ditto for texture coords, and rgba color
@ -336,17 +337,17 @@ impl CanvasState {
/// Load and Compile a shader with the filename at resources/shaders /// Load and Compile a shader with the filename at resources/shaders
/// Takes physical and capabilities as we don't store that in Canvas /// Takes physical and capabilities as we don't store that in Canvas
pub fn load_shader(&mut self, pub fn load_shader<T: 'static>(&mut self,
filename: String, filename: String,
physical: PhysicalDevice, physical: PhysicalDevice,
capabilities: Capabilities) -> Option<Arc<CompiledGraphicsPipelineHandle>> { capabilities: Capabilities) -> Option<Arc<CompiledGraphicsPipelineHandle>>
where T: CompiledGraphicsPipeline {
let handle = Arc::new(CompiledGraphicsPipelineHandle { let handle = Arc::new(CompiledGraphicsPipelineHandle {
handle: self.shader_buffers.len() as u32 handle: self.shader_buffers.len() as u32
}); });
let shader : Box<dyn CompiledGraphicsPipeline> = Box::new(T::new(
let shader : Box<dyn CompiledGraphicsPipeline> = Box::new(GenericShader::new(
filename.clone(), filename.clone(),
self.device.clone(), self.device.clone(),
handle.clone(), handle.clone(),

@ -1,22 +0,0 @@
use vulkano::device::{Device, Queue};
use vulkano::instance::{PhysicalDevice, QueueFamily, LayerProperties};
use vulkano::pipeline::{GraphicsPipeline, GraphicsPipelineAbstract, GraphicsPipelineBuilder};
use std::sync::Arc;
use std::ffi::CStr;
use std::path::PathBuf;
use shade_runner as sr;
use vulkano::framebuffer::{Subpass, RenderPassAbstract, Framebuffer, FramebufferAbstract};
use vulkano::pipeline::shader::{GraphicsShaderType, ShaderModule, SpecializationConstants, SpecializationMapEntry, GeometryShaderExecutionMode, GraphicsEntryPointAbstract, GraphicsEntryPoint, EmptyEntryPointDummy};
use vulkano::swapchain::Capabilities;
use vulkano::pipeline::vertex::SingleBufferDefinition;
use crate::util::vertex_3d::Vertex3D;
use vulkano::pipeline::depth_stencil::{DepthStencil, Stencil, StencilOp, Compare, DepthBounds};
use std::collections::{HashSet, HashMap};
use shade_runner::{Layout, Output, Input, Entry};
use vulkano::descriptor::pipeline_layout::PipelineLayout;
use std::marker::PhantomData;
use vulkano::pipeline::input_assembly::PrimitiveTopology;
use vulkano::pipeline::blend::{Blend, AttachmentsBlend};
use vulkano::pipeline::vertex::BufferlessDefinition;

@ -4,6 +4,10 @@ use std::path::PathBuf;
use vulkano::pipeline::GraphicsPipelineAbstract; use vulkano::pipeline::GraphicsPipelineAbstract;
use vulkano::framebuffer::RenderPassAbstract; use vulkano::framebuffer::RenderPassAbstract;
use std::sync::Arc; use std::sync::Arc;
use vulkano::pipeline::shader::{ShaderModule, GraphicsShaderType, GeometryShaderExecutionMode};
use vulkano::device::Device;
use shade_runner::Entry;
use shaderc::ShaderKind;
/* /*
@ -24,7 +28,8 @@ This best works I think if I allow users to
/// Inheriting this gives private functions to grab resources /// Inheriting this gives private functions to grab resources
pub(super) trait CompiledGraphicsPipelineResources { pub(super) trait CompiledGraphicsPipelineResources {
fn get_paths(filename: String, types: HashSet<ShaderType>) -> Vec<(ShaderType, PathBuf)> {
fn get_path(filename: String, shader_type: ShaderType) -> PathBuf {
let project_root = let project_root =
std::env::current_dir() std::env::current_dir()
.expect("failed to get root directory"); .expect("failed to get root directory");
@ -32,39 +37,62 @@ pub(super) trait CompiledGraphicsPipelineResources {
let mut shader_path = project_root.clone(); let mut shader_path = project_root.clone();
shader_path.push(PathBuf::from("resources/shaders/")); shader_path.push(PathBuf::from("resources/shaders/"));
let mut paths = Vec::new();
for shader_type in types { let mut shader_path = shader_path.clone();
match shader_type { match shader_type {
ShaderType::VERTEX => { ShaderType::VERTEX => {
let mut shader_path = shader_path.clone();
shader_path.push(PathBuf::from(filename.clone() + ".vert")); shader_path.push(PathBuf::from(filename.clone() + ".vert"));
paths.push((shader_type, shader_path));
} }
ShaderType::FRAGMENT => { ShaderType::FRAGMENT => {
let mut shader_path = shader_path.clone();
shader_path.push(PathBuf::from(filename.clone() + ".frag")); shader_path.push(PathBuf::from(filename.clone() + ".frag"));
paths.push((shader_type, shader_path));
} }
ShaderType::GEOMETRY => { ShaderType::GEOMETRY => {
let mut shader_path = shader_path.clone();
shader_path.push(PathBuf::from(filename.clone() + ".geom")); shader_path.push(PathBuf::from(filename.clone() + ".geom"));
paths.push((shader_type, shader_path));
} }
ShaderType::TESSELLATION_CONTROL => { ShaderType::TESSELLATION_CONTROL => {
let mut shader_path = shader_path.clone();
shader_path.push(PathBuf::from(filename.clone() + ".tesscont")); shader_path.push(PathBuf::from(filename.clone() + ".tesscont"));
paths.push((shader_type, shader_path));
} }
ShaderType::TESSELLATION_EVALUATION => { ShaderType::TESSELLATION_EVALUATION => {
let mut shader_path = shader_path.clone();
shader_path.push(PathBuf::from(filename.clone() + ".tesseval")); shader_path.push(PathBuf::from(filename.clone() + ".tesseval"));
paths.push((shader_type, shader_path));
} }
} }
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 }
}
} }
paths 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 }
}
} }
} }
@ -75,6 +103,10 @@ pub struct CompiledGraphicsPipelineHandle {
} }
pub trait CompiledGraphicsPipeline { pub trait CompiledGraphicsPipeline {
fn new(filename: String,
device: Arc<Device>,
handle: Arc<CompiledGraphicsPipelineHandle>,
render_pass: Arc<dyn RenderPassAbstract + Send + Sync>) -> Self where Self: Sized;
fn get_name(&self) -> String; fn get_name(&self) -> String;
fn get_handle(&self) -> Arc<CompiledGraphicsPipelineHandle>; fn get_handle(&self) -> Arc<CompiledGraphicsPipelineHandle>;
fn get_pipeline(&self) -> Arc<dyn GraphicsPipelineAbstract + Sync + Send>; fn get_pipeline(&self) -> Arc<dyn GraphicsPipelineAbstract + Sync + Send>;

@ -16,6 +16,7 @@ use vulkano::pipeline::vertex::SingleBufferDefinition;
use crate::util::vertex_3d::Vertex3D; use crate::util::vertex_3d::Vertex3D;
use shade_runner as sr; use shade_runner as sr;
use crate::canvas::shader::common::CompiledGraphicsPipelineResources; use crate::canvas::shader::common::CompiledGraphicsPipelineResources;
use vulkano::memory::pool::PotentialDedicatedAllocation::Generic;
/// CanvasShader holds the pipeline and render pass for the input shader source /// CanvasShader holds the pipeline and render pass for the input shader source
#[derive(Clone)] #[derive(Clone)]
@ -24,122 +25,53 @@ pub struct GenericShader {
handle: Arc<CompiledGraphicsPipelineHandle>, handle: Arc<CompiledGraphicsPipelineHandle>,
name: String, name: String,
shader_types: HashSet<ShaderType>,
device: Arc<Device>, device: Arc<Device>,
} }
impl GenericShader {}
/// Gives CanvasShader the resource functions /// Gives CanvasShader the resource functions
impl CompiledGraphicsPipelineResources for GenericShader {} impl CompiledGraphicsPipelineResources for GenericShader {}
/// Convenience interface so we don't have to juggle shader types /// Convenience interface so we don't have to juggle shader types
impl CompiledGraphicsPipeline for GenericShader { impl CompiledGraphicsPipeline for GenericShader {
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 recompile(self, render_pass: Arc<dyn RenderPassAbstract + Send + Sync>) -> GenericShader {
GenericShader::new(self.name,
self.device,
self.handle,
render_pass.clone())
}
}
impl GenericShader {
/// This will explode when the shader does not want to compile /// This will explode when the shader does not want to compile
pub fn new(filename: String, fn new(filename: String,
device: Arc<Device>, device: Arc<Device>,
handle: Arc<CompiledGraphicsPipelineHandle>, handle: Arc<CompiledGraphicsPipelineHandle>,
render_pass: Arc<dyn RenderPassAbstract + Send + Sync>) -> GenericShader { render_pass: Arc<dyn RenderPassAbstract + Send + Sync>) -> GenericShader {
let mut shader_types : HashSet<ShaderType> = vec![ let compiled_vertex = GenericShader::compile(
ShaderType::VERTEX, GenericShader::get_path(filename.clone(), ShaderType::VERTEX),
ShaderType::FRAGMENT, device.clone(), ShaderType::VERTEX
].iter().cloned().collect(); );
let filenames = GenericShader::get_paths(filename.clone(), shader_types.clone()); let vertex_entry_point = unsafe {
Some(compiled_vertex.1.graphics_entry_point(
// I guess this really herky intermediate store is going to be the most flexible way to &CStr::from_bytes_with_nul_unchecked(b"main\0"),
// create these pipelines? compiled_vertex.0.input.unwrap(),
compiled_vertex.0.output.unwrap(),
let mut modules: HashMap<ShaderType, (Entry, Arc<ShaderModule>)> = HashMap::default(); compiled_vertex.0.layout,
GenericShader::convert_vk(ShaderType::VERTEX)
let mut entry_points: HashMap<ShaderType, GraphicsEntryPoint<ShaderSpecializationConstants,Input,Output,Layout>> = HashMap::default(); )).unwrap()
for shader in filenames {
let compiled_shader = sr::load_vertex(shader.1)
.expect("Shader didn't compile");
let vulkano_entry =
sr::parse(&compiled_shader)
.expect("failed to parse");
modules.insert(shader.0, (vulkano_entry, unsafe {
ShaderModule::from_words(device.clone(), &compiled_shader.spriv.clone())
}.unwrap()));
}
for (shader_type, (entry, module)) in modules {
let graphics_shader_type = 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 }
};
let entry_point: Option<GraphicsEntryPoint<
ShaderSpecializationConstants,
Input,
Output,
Layout>> = unsafe {
Some(GraphicsEntryPoint {
module: &module,
name: &CStr::from_bytes_with_nul_unchecked(b"main\0"),
input: entry.input.unwrap(),
layout: entry.layout,
output: entry.output.unwrap(),
ty: graphics_shader_type,
marker: PhantomData::default(),
})
}; };
entry_points.insert(shader_type, entry_point.unwrap().to_owned()); let compiled_fragment = GenericShader::compile(
} GenericShader::get_path(filename.clone(), ShaderType::FRAGMENT).into(),
device.clone(), ShaderType::FRAGMENT
let stencil = DepthStencil { );
depth_compare: Compare::Less,
depth_write: true, let fragment_entry_point = unsafe {
depth_bounds_test: DepthBounds::Disabled, Some(compiled_fragment.1.graphics_entry_point(
stencil_front: Stencil { &CStr::from_bytes_with_nul_unchecked(b"main\0"),
compare: Compare::Equal, compiled_fragment.0.input.unwrap(),
pass_op: StencilOp::IncrementAndWrap, compiled_fragment.0.output.unwrap(),
fail_op: StencilOp::DecrementAndClamp, compiled_fragment.0.layout,
depth_fail_op: StencilOp::Keep, GenericShader::convert_vk(ShaderType::FRAGMENT)
compare_mask: None, )).unwrap()
write_mask: None,
reference: None,
},
stencil_back: Stencil {
compare: Compare::Equal,
pass_op: StencilOp::Invert,
fail_op: StencilOp::Zero,
depth_fail_op: StencilOp::Zero,
compare_mask: None,
write_mask: None,
reference: None,
},
}; };
GenericShader { GenericShader {
@ -148,7 +80,7 @@ impl GenericShader {
.vertex_input(SingleBufferDefinition::<Vertex3D>::new()) .vertex_input(SingleBufferDefinition::<Vertex3D>::new())
.vertex_shader(entry_points.get(&ShaderType::VERTEX).unwrap().clone(), ShaderSpecializationConstants { .vertex_shader(vertex_entry_point.clone(), ShaderSpecializationConstants {
first_constant: 0, first_constant: 0,
second_constant: 0, second_constant: 0,
third_constant: 0.0, third_constant: 0.0,
@ -158,14 +90,13 @@ impl GenericShader {
// Use a resizable viewport set to draw over the entire window // Use a resizable viewport set to draw over the entire window
.viewports_dynamic_scissors_irrelevant(1) .viewports_dynamic_scissors_irrelevant(1)
.fragment_shader(entry_points.get(&ShaderType::VERTEX).unwrap().clone(), ShaderSpecializationConstants { .fragment_shader(fragment_entry_point.clone(), ShaderSpecializationConstants {
first_constant: 0, first_constant: 0,
second_constant: 0, second_constant: 0,
third_constant: 0.0, third_constant: 0.0,
}) })
.depth_stencil(stencil) .depth_stencil(DepthStencil::default())
// We have to indicate which subpass of which render pass this pipeline is going to be used // 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. // in. The pipeline will only be usable from this particular subpass.
@ -177,7 +108,26 @@ impl GenericShader {
device: device, device: device,
handle: handle.clone(), handle: handle.clone(),
name: filename.clone(), name: filename.clone(),
shader_types: shader_types.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 recompile(self, render_pass: Arc<dyn RenderPassAbstract + Send + Sync>) -> GenericShader {
GenericShader::new(self.name,
self.device,
self.handle,
render_pass.clone())
}
}

@ -23,98 +23,54 @@ pub struct TextShader {
handle: Arc<CompiledGraphicsPipelineHandle>, handle: Arc<CompiledGraphicsPipelineHandle>,
name: String, name: String,
shader_types: HashSet<ShaderType>,
device: Arc<Device>, device: Arc<Device>,
} }
impl TextShader {}
/// Gives CanvasShader the resource functions /// Gives CanvasShader the resource functions
impl CompiledGraphicsPipelineResources for TextShader {} impl CompiledGraphicsPipelineResources for TextShader {}
/// Convenience interface so we don't have to juggle shader types /// Convenience interface so we don't have to juggle shader types
impl CompiledGraphicsPipeline for TextShader { impl CompiledGraphicsPipeline for TextShader {
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 recompile(self, render_pass: Arc<dyn RenderPassAbstract + Send + Sync>) -> TextShader {
TextShader::new(self.name,
self.device,
self.handle,
render_pass.clone())
}
}
impl TextShader {
/// This will explode when the shader does not want to compile /// This will explode when the shader does not want to compile
pub fn new(filename: String, fn new(filename: String,
device: Arc<Device>, device: Arc<Device>,
handle: Arc<CompiledGraphicsPipelineHandle>, handle: Arc<CompiledGraphicsPipelineHandle>,
render_pass: Arc<dyn RenderPassAbstract + Send + Sync>) -> TextShader { render_pass: Arc<dyn RenderPassAbstract + Send + Sync>) -> TextShader {
let mut shader_types: HashSet<ShaderType> = vec![
ShaderType::VERTEX,
ShaderType::FRAGMENT,
].iter().cloned().collect();
let filenames = GenericShader::get_paths(filename.clone(), shader_types.clone());
// I guess this really herky intermediate store is going to be the most flexible way to
// create these pipelines?
let mut modules: HashMap<ShaderType, (Entry, Arc<ShaderModule>)> = HashMap::default();
let mut entry_points: HashMap<ShaderType, GraphicsEntryPoint<ShaderSpecializationConstants, Input, Output, Layout>> = HashMap::default(); let compiled_vertex = GenericShader::compile(
GenericShader::get_path(filename.clone(), ShaderType::VERTEX).into(),
for shader in filenames { device.clone(), ShaderType::VERTEX
let compiled_shader = sr::load_vertex(shader.1) );
.expect("Shader didn't compile");
let vertex_entry_point = unsafe {
let vulkano_entry = Some(compiled_vertex.1.graphics_entry_point(
sr::parse(&compiled_shader) &CStr::from_bytes_with_nul_unchecked(b"main\0"),
.expect("failed to parse"); compiled_vertex.0.input.unwrap(),
compiled_vertex.0.output.unwrap(),
modules.insert(shader.0, (vulkano_entry, unsafe { compiled_vertex.0.layout,
ShaderModule::from_words(device.clone(), &compiled_shader.spriv.clone()) GenericShader::convert_vk(ShaderType::VERTEX),
}.unwrap())); )).unwrap()
}
for (shader_type, (entry, module)) in modules {
let graphics_shader_type = 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 }
}; };
let entry_point: Option<GraphicsEntryPoint< let compiled_fragment = GenericShader::compile(
ShaderSpecializationConstants, GenericShader::get_path(filename.clone(), ShaderType::FRAGMENT).into(),
Input, device.clone(), ShaderType::FRAGMENT
Output, );
Layout>> = unsafe {
Some(GraphicsEntryPoint { let fragment_entry_point = unsafe {
module: &module, Some(compiled_fragment.1.graphics_entry_point(
name: &CStr::from_bytes_with_nul_unchecked(b"main\0"), &CStr::from_bytes_with_nul_unchecked(b"main\0"),
input: entry.input.unwrap(), compiled_fragment.0.input.unwrap(),
layout: entry.layout, compiled_fragment.0.output.unwrap(),
output: entry.output.unwrap(), compiled_fragment.0.layout,
ty: graphics_shader_type, GenericShader::convert_vk(ShaderType::FRAGMENT),
marker: PhantomData::default(), )).unwrap()
})
}; };
entry_points.insert(shader_type, entry_point.unwrap().clone());
}
let stencil = DepthStencil { let stencil = DepthStencil {
depth_compare: Compare::Less, depth_compare: Compare::Less,
depth_write: true, depth_write: true,
@ -145,7 +101,7 @@ impl TextShader {
.vertex_input(SingleBufferDefinition::<Vertex3D>::new()) .vertex_input(SingleBufferDefinition::<Vertex3D>::new())
.vertex_shader(entry_points.get(&ShaderType::VERTEX).unwrap().clone(), ShaderSpecializationConstants { .vertex_shader(vertex_entry_point.clone(), ShaderSpecializationConstants {
first_constant: 0, first_constant: 0,
second_constant: 0, second_constant: 0,
third_constant: 0.0, third_constant: 0.0,
@ -155,7 +111,7 @@ impl TextShader {
// Use a resizable viewport set to draw over the entire window // Use a resizable viewport set to draw over the entire window
.viewports_dynamic_scissors_irrelevant(1) .viewports_dynamic_scissors_irrelevant(1)
.fragment_shader(entry_points.get(&ShaderType::VERTEX).unwrap().clone(), ShaderSpecializationConstants { .fragment_shader(fragment_entry_point.clone(), ShaderSpecializationConstants {
first_constant: 0, first_constant: 0,
second_constant: 0, second_constant: 0,
third_constant: 0.0, third_constant: 0.0,
@ -163,7 +119,6 @@ impl TextShader {
.depth_stencil(stencil) .depth_stencil(stencil)
// We have to indicate which subpass of which render pass this pipeline is going to be used // 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. // in. The pipeline will only be usable from this particular subpass.
.render_pass(Subpass::from(render_pass.clone(), 0).unwrap()) .render_pass(Subpass::from(render_pass.clone(), 0).unwrap())
@ -174,7 +129,37 @@ impl TextShader {
device: device, device: device,
handle: handle.clone(), handle: handle.clone(),
name: filename.clone(), name: filename.clone(),
shader_types: shader_types.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 recompile(self, render_pass: Arc<dyn RenderPassAbstract + Send + Sync>) -> TextShader {
TextShader::new(self.name,
self.device,
self.handle,
render_pass.clone())
}
} }

@ -79,7 +79,6 @@ pub fn main() {
let mut accumulator_time: f32 = 0.0; let mut accumulator_time: f32 = 0.0;
let mut current_time: f32 = timer.elap_time(); let mut current_time: f32 = timer.elap_time();
let image_data = load_raw(String::from("funky-bird.jpg")); let image_data = load_raw(String::from("funky-bird.jpg"));
let image_dimensions_f = ((image_data.1).0 as f32, (image_data.1).1 as f32); let image_dimensions_f = ((image_data.1).0 as f32, (image_data.1).1 as f32);
let image_dimensions_u = image_data.1; let image_dimensions_u = image_data.1;
@ -163,9 +162,11 @@ pub fn main() {
} }
let mut canvas = CanvasFrame::new(); let mut canvas = CanvasFrame::new();
canvas.draw(&funky_sprite); canvas.draw(&funky_sprite);
canvas.draw(&sfml_sprite);
canvas.draw(&compu_sprite1); // canvas.draw(&sfml_sprite);
// canvas.draw(&compu_sprite1);
canvas.draw(&test_polygon); canvas.draw(&test_polygon);

@ -18,6 +18,8 @@ use crate::compute::compu_buffer::{CompuBuffers, CompuBufferHandle};
use std::time::Duration; use std::time::Duration;
use vulkano::pipeline::depth_stencil::{DynamicStencilValue, StencilFaceFlags}; use vulkano::pipeline::depth_stencil::{DynamicStencilValue, StencilFaceFlags};
use crate::canvas::shader::common::CompiledGraphicsPipelineHandle; use crate::canvas::shader::common::CompiledGraphicsPipelineHandle;
use crate::canvas::shader::generic_shader::GenericShader;
use crate::canvas::shader::text_shader::TextShader;
/// VKProcessor holds the vulkan instance information, the swapchain, and the compute and canvas states /// VKProcessor holds the vulkan instance information, the swapchain, and the compute and canvas states
/// ///
@ -155,9 +157,10 @@ impl<'a> VkProcessor<'a> {
/// A hardcoded list of shaders which can be proloaded from this function /// A hardcoded list of shaders which can be proloaded from this function
pub fn preload_shaders(&mut self) { pub fn preload_shaders(&mut self) {
self.canvas.load_shader(String::from("color-passthrough"), self.physical.clone(), self.capabilities.clone()); self.canvas.load_shader::<GenericShader>(String::from("color-passthrough"), self.physical.clone(), self.capabilities.clone());
self.canvas.load_shader(String::from("simple_texture"), self.physical.clone(), self.capabilities.clone()); self.canvas.load_shader::<GenericShader>(String::from("simple_texture"), self.physical.clone(), self.capabilities.clone());
self.canvas.load_shader(String::from("simple_image"), self.physical.clone(), self.capabilities.clone()); self.canvas.load_shader::<GenericShader>(String::from("simple_image"), self.physical.clone(), self.capabilities.clone());
self.canvas.load_shader::<TextShader>(String::from("simple_text"), self.physical.clone(), self.capabilities.clone());
} }
/// O(n) Lookup for the matching texture string /// O(n) Lookup for the matching texture string
@ -256,6 +259,7 @@ impl<'a> VkProcessor<'a> {
drop(g); drop(g);
let g = hprof::enter("Push draw commands to command buffer"); let g = hprof::enter("Push draw commands to command buffer");
// Add the draw commands // Add the draw commands
let mut command_buffer = self.canvas.draw_commands(command_buffer, framebuffers, image_num); let mut command_buffer = self.canvas.draw_commands(command_buffer, framebuffers, image_num);

Loading…
Cancel
Save