mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-21 22:34:43 +00:00
Rework shader entry points (#708)
This commit is contained in:
parent
a4589e7a16
commit
bf82214ec1
@ -39,6 +39,7 @@ use vulkano::format;
|
||||
use vulkano::framebuffer::Framebuffer;
|
||||
use vulkano::framebuffer::Subpass;
|
||||
use vulkano::pipeline::GraphicsPipeline;
|
||||
use vulkano::pipeline::shader::GraphicsShaderType;
|
||||
use vulkano::pipeline::shader::ShaderInterfaceDef;
|
||||
use vulkano::pipeline::shader::ShaderInterfaceDefEntry;
|
||||
use vulkano::pipeline::shader::ShaderModule;
|
||||
@ -374,18 +375,20 @@ fn main() {
|
||||
// You must be extra careful to specify correct entry point, or program will
|
||||
// crash at runtime outside of rust and you will get NO meaningful error
|
||||
// information!
|
||||
let vert_main = unsafe { vs.vertex_shader_entry_point(
|
||||
let vert_main = unsafe { vs.graphics_entry_point(
|
||||
CStr::from_bytes_with_nul_unchecked(b"main\0"),
|
||||
VertInput,
|
||||
VertOutput,
|
||||
VertLayout(ShaderStages { vertex: true, ..ShaderStages::none() })
|
||||
VertLayout(ShaderStages { vertex: true, ..ShaderStages::none() }),
|
||||
GraphicsShaderType::Vertex
|
||||
) };
|
||||
|
||||
let frag_main = unsafe { fs.fragment_shader_entry_point(
|
||||
let frag_main = unsafe { fs.graphics_entry_point(
|
||||
CStr::from_bytes_with_nul_unchecked(b"main\0"),
|
||||
FragInput,
|
||||
FragOutput,
|
||||
FragLayout(ShaderStages { fragment: true, ..ShaderStages::none() })
|
||||
FragLayout(ShaderStages { fragment: true, ..ShaderStages::none() }),
|
||||
GraphicsShaderType::Fragment
|
||||
) };
|
||||
|
||||
let graphics_pipeline = Arc::new(
|
||||
|
@ -54,92 +54,73 @@ pub fn write_entry_point(doc: &parse::Spirv, instruction: &parse::Instruction) -
|
||||
_ => false,
|
||||
});
|
||||
|
||||
let (ty, f_call) = match *execution {
|
||||
enums::ExecutionModel::ExecutionModelVertex => {
|
||||
let t = format!("::vulkano::pipeline::shader::VertexShaderEntryPoint<(), {0}Input, \
|
||||
{0}Output, Layout>",
|
||||
capitalized_ep_name);
|
||||
let f = format!("vertex_shader_entry_point(::std::ffi::CStr::from_ptr(NAME.as_ptr() \
|
||||
as *const _), {0}Input, {0}Output, Layout(ShaderStages {{ vertex: \
|
||||
true, .. ShaderStages::none() }}))",
|
||||
capitalized_ep_name);
|
||||
(t, f)
|
||||
},
|
||||
let (ty, f_call) = {
|
||||
if let enums::ExecutionModel::ExecutionModelGLCompute = *execution {
|
||||
(format!("::vulkano::pipeline::shader::ComputeEntryPoint<(), Layout>"),
|
||||
format!("compute_entry_point(::std::ffi::CStr::from_ptr(NAME.as_ptr() as \
|
||||
*const _), Layout(ShaderStages {{ compute: true, .. ShaderStages::none() \
|
||||
}}))"))
|
||||
|
||||
enums::ExecutionModel::ExecutionModelTessellationControl => {
|
||||
let t = format!("::vulkano::pipeline::shader::TessControlShaderEntryPoint<(), \
|
||||
{0}Input, {0}Output, Layout>",
|
||||
capitalized_ep_name);
|
||||
let f = format!("tess_control_shader_entry_point(::std::ffi::CStr::from_ptr(NAME.\
|
||||
as_ptr() as *const _), {0}Input, {0}Output, Layout(ShaderStages {{ \
|
||||
tessellation_control: true, .. ShaderStages::none() }}))",
|
||||
capitalized_ep_name);
|
||||
(t, f)
|
||||
},
|
||||
} else {
|
||||
let ty = match *execution {
|
||||
enums::ExecutionModel::ExecutionModelVertex => {
|
||||
"::vulkano::pipeline::shader::GraphicsShaderType::Vertex".to_owned()
|
||||
},
|
||||
|
||||
enums::ExecutionModel::ExecutionModelTessellationEvaluation => {
|
||||
let t = format!("::vulkano::pipeline::shader::TessEvaluationShaderEntryPoint<(), \
|
||||
{0}Input, {0}Output, Layout>",
|
||||
capitalized_ep_name);
|
||||
let f = format!("tess_evaluation_shader_entry_point(::std::ffi::CStr::from_ptr(NAME.\
|
||||
as_ptr() as *const _), {0}Input, {0}Output, Layout(ShaderStages {{ \
|
||||
tessellation_evaluation: true, .. ShaderStages::none() }}))",
|
||||
capitalized_ep_name);
|
||||
(t, f)
|
||||
},
|
||||
enums::ExecutionModel::ExecutionModelTessellationControl => {
|
||||
"::vulkano::pipeline::shader::GraphicsShaderType::TessellationControl".to_owned()
|
||||
},
|
||||
|
||||
enums::ExecutionModel::ExecutionModelGeometry => {
|
||||
let mut execution_mode = None;
|
||||
|
||||
for instruction in doc.instructions.iter() {
|
||||
if let &parse::Instruction::ExecutionMode { target_id, ref mode, .. } = instruction {
|
||||
if target_id != id {
|
||||
continue;
|
||||
enums::ExecutionModel::ExecutionModelTessellationEvaluation => {
|
||||
"::vulkano::pipeline::shader::GraphicsShaderType::TessellationEvaluation".to_owned()
|
||||
},
|
||||
|
||||
enums::ExecutionModel::ExecutionModelGeometry => {
|
||||
let mut execution_mode = None;
|
||||
|
||||
for instruction in doc.instructions.iter() {
|
||||
if let &parse::Instruction::ExecutionMode { target_id, ref mode, .. } = instruction {
|
||||
if target_id != id {
|
||||
continue;
|
||||
}
|
||||
execution_mode = match mode {
|
||||
&enums::ExecutionMode::ExecutionModeInputPoints => Some("Points"),
|
||||
&enums::ExecutionMode::ExecutionModeInputLines => Some("Lines"),
|
||||
&enums::ExecutionMode::ExecutionModeInputLinesAdjacency => Some("LinesWithAdjacency"),
|
||||
&enums::ExecutionMode::ExecutionModeTriangles => Some("Triangles"),
|
||||
&enums::ExecutionMode::ExecutionModeInputTrianglesAdjacency => Some("TrianglesWithAdjacency"),
|
||||
_ => continue,
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
execution_mode = match mode {
|
||||
&enums::ExecutionMode::ExecutionModeInputPoints => Some("Points"),
|
||||
&enums::ExecutionMode::ExecutionModeInputLines => Some("Lines"),
|
||||
&enums::ExecutionMode::ExecutionModeInputLinesAdjacency => Some("LinesWithAdjacency"),
|
||||
&enums::ExecutionMode::ExecutionModeTriangles => Some("Triangles"),
|
||||
&enums::ExecutionMode::ExecutionModeInputTrianglesAdjacency => Some("TrianglesWithAdjacency"),
|
||||
_ => continue,
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let execution_mode = format!("::vulkano::pipeline::shader::GeometryShaderExecutionMode::{0}", execution_mode.unwrap());
|
||||
|
||||
let t = format!("::vulkano::pipeline::shader::GeometryShaderEntryPoint<(), {0}Input, \
|
||||
{0}Output, Layout>",
|
||||
format!("::vulkano::pipeline::shader::GraphicsShaderType::Geometry(
|
||||
::vulkano::pipeline::shader::GeometryShaderExecutionMode::{0}
|
||||
)", execution_mode.unwrap())
|
||||
},
|
||||
|
||||
enums::ExecutionModel::ExecutionModelFragment => {
|
||||
"::vulkano::pipeline::shader::GraphicsShaderType::Fragment".to_owned()
|
||||
},
|
||||
|
||||
enums::ExecutionModel::ExecutionModelGLCompute => {
|
||||
unreachable!()
|
||||
},
|
||||
|
||||
enums::ExecutionModel::ExecutionModelKernel => panic!("Kernels are not supported"),
|
||||
};
|
||||
|
||||
let t = format!("::vulkano::pipeline::shader::GraphicsEntryPoint<(), {0}Input, \
|
||||
{0}Output, Layout>",
|
||||
capitalized_ep_name);
|
||||
let f = format!("geometry_shader_entry_point(::std::ffi::CStr::from_ptr(NAME.\
|
||||
as_ptr() as *const _), {1}, {0}Input, {0}Output, Layout(ShaderStages {{ \
|
||||
geometry: true, .. ShaderStages::none() }}))",
|
||||
capitalized_ep_name,
|
||||
execution_mode);
|
||||
let f = format!("graphics_entry_point(::std::ffi::CStr::from_ptr(NAME.as_ptr() \
|
||||
as *const _), {0}Input, {0}Output, Layout(ShaderStages {{ vertex: \
|
||||
true, .. ShaderStages::none() }}), {1})",
|
||||
capitalized_ep_name, ty);
|
||||
|
||||
(t, f)
|
||||
},
|
||||
|
||||
enums::ExecutionModel::ExecutionModelFragment => {
|
||||
let t = format!("::vulkano::pipeline::shader::FragmentShaderEntryPoint<(), {0}Input, \
|
||||
{0}Output, Layout>",
|
||||
capitalized_ep_name);
|
||||
let f = format!("fragment_shader_entry_point(::std::ffi::CStr::from_ptr(NAME.\
|
||||
as_ptr() as *const _), {0}Input, {0}Output, Layout(ShaderStages {{ \
|
||||
fragment: true, .. ShaderStages::none() }}))",
|
||||
capitalized_ep_name);
|
||||
(t, f)
|
||||
},
|
||||
|
||||
enums::ExecutionModel::ExecutionModelGLCompute => {
|
||||
(format!("::vulkano::pipeline::shader::ComputeShaderEntryPoint<(), Layout>"),
|
||||
format!("compute_shader_entry_point(::std::ffi::CStr::from_ptr(NAME.as_ptr() as \
|
||||
*const _), Layout(ShaderStages {{ compute: true, .. ShaderStages::none() \
|
||||
}}))"))
|
||||
},
|
||||
|
||||
enums::ExecutionModel::ExecutionModelKernel => panic!("Kernels are not supported"),
|
||||
}
|
||||
};
|
||||
|
||||
let entry_point = format!(
|
||||
|
@ -25,7 +25,7 @@ use descriptor::pipeline_layout::PipelineLayoutDescPcRange;
|
||||
use descriptor::pipeline_layout::PipelineLayoutNotSupersetError;
|
||||
use descriptor::pipeline_layout::PipelineLayoutSuperset;
|
||||
use descriptor::pipeline_layout::PipelineLayoutSys;
|
||||
use pipeline::shader::ComputeShaderEntryPoint;
|
||||
use pipeline::shader::EntryPointAbstract;
|
||||
use pipeline::shader::SpecializationConstants;
|
||||
|
||||
use Error;
|
||||
@ -56,11 +56,11 @@ struct Inner {
|
||||
|
||||
impl ComputePipeline<()> {
|
||||
/// Builds a new `ComputePipeline`.
|
||||
pub fn new<Css, Csl>(
|
||||
device: Arc<Device>, shader: &ComputeShaderEntryPoint<Css, Csl>, specialization: &Css)
|
||||
-> Result<ComputePipeline<PipelineLayout<Csl>>, ComputePipelineCreationError>
|
||||
where Csl: PipelineLayoutDescNames + Clone,
|
||||
Css: SpecializationConstants
|
||||
pub fn new<Cs>(
|
||||
device: Arc<Device>, shader: &Cs, specialization: &Cs::SpecializationConstants)
|
||||
-> Result<ComputePipeline<PipelineLayout<Cs::PipelineLayout>>, ComputePipelineCreationError>
|
||||
where Cs::PipelineLayout: Clone,
|
||||
Cs: EntryPointAbstract
|
||||
{
|
||||
unsafe {
|
||||
let pipeline_layout = shader.layout().clone().build(device.clone())?;
|
||||
@ -77,12 +77,12 @@ impl<Pl> ComputePipeline<Pl> {
|
||||
///
|
||||
/// An error will be returned if the pipeline layout isn't a superset of what the shader
|
||||
/// uses.
|
||||
pub fn with_pipeline_layout<Css, Csl>(
|
||||
device: Arc<Device>, shader: &ComputeShaderEntryPoint<Css, Csl>, specialization: &Css,
|
||||
pub fn with_pipeline_layout<Cs>(
|
||||
device: Arc<Device>, shader: &Cs, specialization: &Cs::SpecializationConstants,
|
||||
pipeline_layout: Pl)
|
||||
-> Result<ComputePipeline<Pl>, ComputePipelineCreationError>
|
||||
where Csl: PipelineLayoutDescNames + Clone,
|
||||
Css: SpecializationConstants,
|
||||
where Cs::PipelineLayout: Clone,
|
||||
Cs: EntryPointAbstract,
|
||||
Pl: PipelineLayoutAbstract
|
||||
{
|
||||
unsafe {
|
||||
@ -96,23 +96,23 @@ impl<Pl> ComputePipeline<Pl> {
|
||||
|
||||
/// Same as `with_pipeline_layout`, but doesn't check whether the pipeline layout is a
|
||||
/// superset of what the shader expects.
|
||||
pub unsafe fn with_unchecked_pipeline_layout<Css, Csl>(
|
||||
device: Arc<Device>, shader: &ComputeShaderEntryPoint<Css, Csl>, specialization: &Css,
|
||||
pub unsafe fn with_unchecked_pipeline_layout<Cs>(
|
||||
device: Arc<Device>, shader: &Cs, specialization: &Cs::SpecializationConstants,
|
||||
pipeline_layout: Pl)
|
||||
-> Result<ComputePipeline<Pl>, ComputePipelineCreationError>
|
||||
where Csl: PipelineLayoutDescNames + Clone,
|
||||
Css: SpecializationConstants,
|
||||
where Cs::PipelineLayout: Clone,
|
||||
Cs: EntryPointAbstract,
|
||||
Pl: PipelineLayoutAbstract
|
||||
{
|
||||
let vk = device.pointers();
|
||||
|
||||
let pipeline = {
|
||||
let spec_descriptors = <Css as SpecializationConstants>::descriptors();
|
||||
let spec_descriptors = Cs::SpecializationConstants::descriptors();
|
||||
let specialization = vk::SpecializationInfo {
|
||||
mapEntryCount: spec_descriptors.len() as u32,
|
||||
pMapEntries: spec_descriptors.as_ptr() as *const _,
|
||||
dataSize: mem::size_of_val(specialization),
|
||||
pData: specialization as *const Css as *const _,
|
||||
pData: specialization as *const Cs::SpecializationConstants as *const _,
|
||||
};
|
||||
|
||||
let stage = vk::PipelineShaderStageCreateInfo {
|
||||
|
@ -11,9 +11,7 @@
|
||||
// to avoid duplicating code, so we hide the warnings for now
|
||||
#![allow(deprecated)]
|
||||
|
||||
use descriptor::pipeline_layout::EmptyPipelineDesc;
|
||||
use descriptor::pipeline_layout::PipelineLayoutAbstract;
|
||||
use descriptor::pipeline_layout::PipelineLayoutDescNames;
|
||||
use device::Device;
|
||||
use framebuffer::RenderPassAbstract;
|
||||
use framebuffer::RenderPassSubpassInterface;
|
||||
@ -34,14 +32,9 @@ use pipeline::raster::CullMode;
|
||||
use pipeline::raster::FrontFace;
|
||||
use pipeline::raster::PolygonMode;
|
||||
use pipeline::raster::Rasterization;
|
||||
use pipeline::shader::EmptyShaderInterfaceDef;
|
||||
use pipeline::shader::FragmentShaderEntryPoint;
|
||||
use pipeline::shader::GeometryShaderEntryPoint;
|
||||
use pipeline::shader::ShaderInterfaceDef;
|
||||
use pipeline::shader::EmptyEntryPointDummy;
|
||||
use pipeline::shader::GraphicsEntryPointAbstract;
|
||||
use pipeline::shader::ShaderInterfaceDefMatch;
|
||||
use pipeline::shader::TessControlShaderEntryPoint;
|
||||
use pipeline::shader::TessEvaluationShaderEntryPoint;
|
||||
use pipeline::shader::VertexShaderEntryPoint;
|
||||
use pipeline::vertex::SingleBufferDefinition;
|
||||
use pipeline::vertex::VertexDefinition;
|
||||
use pipeline::viewport::Scissor;
|
||||
@ -51,68 +44,36 @@ use std::sync::Arc;
|
||||
|
||||
/// Prototype for a `GraphicsPipeline`.
|
||||
// TODO: we can optimize this by filling directly the raw vk structs
|
||||
pub struct GraphicsPipelineBuilder<'a,
|
||||
pub struct GraphicsPipelineBuilder<
|
||||
Vdef,
|
||||
Vsp,
|
||||
Vi,
|
||||
Vo,
|
||||
Vl,
|
||||
Vs,
|
||||
Tcs,
|
||||
Tci,
|
||||
Tco,
|
||||
Tcl,
|
||||
Tes,
|
||||
Tei,
|
||||
Teo,
|
||||
Tel,
|
||||
Gs,
|
||||
Gi,
|
||||
Go,
|
||||
Gl,
|
||||
Fs,
|
||||
Fi,
|
||||
Fo,
|
||||
Fl,
|
||||
Rp>
|
||||
{
|
||||
vertex_input: Vdef,
|
||||
vertex_shader: Option<VertexShaderEntryPoint<'a, Vsp, Vi, Vo, Vl>>,
|
||||
vertex_shader: Option<Vs>,
|
||||
input_assembly: InputAssembly,
|
||||
tessellation: Option<GraphicsPipelineParamsTess<'a, Tcs, Tci, Tco, Tcl, Tes, Tei, Teo, Tel>>,
|
||||
geometry_shader: Option<GeometryShaderEntryPoint<'a, Gs, Gi, Go, Gl>>,
|
||||
tessellation: Option<GraphicsPipelineParamsTess<Tcs, Tes>>,
|
||||
geometry_shader: Option<Gs>,
|
||||
viewport: Option<ViewportsState>,
|
||||
raster: Rasterization,
|
||||
multisample: Multisample,
|
||||
fragment_shader: Option<FragmentShaderEntryPoint<'a, Fs, Fi, Fo, Fl>>,
|
||||
fragment_shader: Option<Fs>,
|
||||
depth_stencil: DepthStencil,
|
||||
blend: Blend,
|
||||
render_pass: Option<Subpass<Rp>>,
|
||||
}
|
||||
|
||||
impl<'a>
|
||||
GraphicsPipelineBuilder<'a,
|
||||
SingleBufferDefinition<()>,
|
||||
(),
|
||||
(),
|
||||
(),
|
||||
(),
|
||||
(),
|
||||
EmptyShaderInterfaceDef,
|
||||
EmptyShaderInterfaceDef,
|
||||
EmptyPipelineDesc,
|
||||
(),
|
||||
EmptyShaderInterfaceDef,
|
||||
EmptyShaderInterfaceDef,
|
||||
EmptyPipelineDesc,
|
||||
(),
|
||||
EmptyShaderInterfaceDef,
|
||||
EmptyShaderInterfaceDef,
|
||||
EmptyPipelineDesc,
|
||||
(),
|
||||
EmptyShaderInterfaceDef,
|
||||
EmptyShaderInterfaceDef,
|
||||
EmptyPipelineDesc,
|
||||
()> {
|
||||
impl GraphicsPipelineBuilder<SingleBufferDefinition<()>,
|
||||
EmptyEntryPointDummy,
|
||||
EmptyEntryPointDummy,
|
||||
EmptyEntryPointDummy,
|
||||
EmptyEntryPointDummy,
|
||||
EmptyEntryPointDummy,
|
||||
()> {
|
||||
/// Builds a new empty builder.
|
||||
pub(super) fn new() -> Self {
|
||||
GraphicsPipelineBuilder {
|
||||
@ -132,70 +93,38 @@ impl<'a>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a,
|
||||
Vdef,
|
||||
Vsp,
|
||||
Vi,
|
||||
Vo,
|
||||
Vl,
|
||||
impl<Vdef,
|
||||
Vs,
|
||||
Tcs,
|
||||
Tci,
|
||||
Tco,
|
||||
Tcl,
|
||||
Tes,
|
||||
Tei,
|
||||
Teo,
|
||||
Tel,
|
||||
Gs,
|
||||
Gi,
|
||||
Go,
|
||||
Gl,
|
||||
Fs,
|
||||
Fi,
|
||||
Fo,
|
||||
Fl,
|
||||
Rp>
|
||||
GraphicsPipelineBuilder<'a,
|
||||
Vdef,
|
||||
Vsp,
|
||||
Vi,
|
||||
Vo,
|
||||
Vl,
|
||||
GraphicsPipelineBuilder<Vdef,
|
||||
Vs,
|
||||
Tcs,
|
||||
Tci,
|
||||
Tco,
|
||||
Tcl,
|
||||
Tes,
|
||||
Tei,
|
||||
Teo,
|
||||
Tel,
|
||||
Gs,
|
||||
Gi,
|
||||
Go,
|
||||
Gl,
|
||||
Fs,
|
||||
Fi,
|
||||
Fo,
|
||||
Fl,
|
||||
Rp>
|
||||
where Vdef: VertexDefinition<Vi>,
|
||||
Vl: PipelineLayoutDescNames + Clone + 'static + Send + Sync, // TODO: Clone + 'static + Send + Sync shouldn't be required
|
||||
Fl: PipelineLayoutDescNames + Clone + 'static + Send + Sync, // TODO: Clone + 'static + Send + Sync shouldn't be required
|
||||
Tcl: PipelineLayoutDescNames + Clone + 'static + Send + Sync, // TODO: Clone + 'static + Send + Sync shouldn't be required
|
||||
Tel: PipelineLayoutDescNames + Clone + 'static + Send + Sync, // TODO: Clone + 'static + Send + Sync shouldn't be required
|
||||
Gl: PipelineLayoutDescNames + Clone + 'static + Send + Sync, // TODO: Clone + 'static + Send + Sync shouldn't be required
|
||||
Tci: ShaderInterfaceDefMatch<Vo>,
|
||||
Tei: ShaderInterfaceDefMatch<Tco>,
|
||||
Gi: ShaderInterfaceDefMatch<Teo> + ShaderInterfaceDefMatch<Vo>,
|
||||
Vo: ShaderInterfaceDef,
|
||||
Tco: ShaderInterfaceDef,
|
||||
Teo: ShaderInterfaceDef,
|
||||
Go: ShaderInterfaceDef,
|
||||
Fi: ShaderInterfaceDefMatch<Go>
|
||||
+ ShaderInterfaceDefMatch<Teo>
|
||||
+ ShaderInterfaceDefMatch<Vo>,
|
||||
Fo: ShaderInterfaceDef,
|
||||
Rp: RenderPassAbstract + RenderPassSubpassInterface<Fo>
|
||||
where Vdef: VertexDefinition<Vs::InputDefinition>,
|
||||
Vs: GraphicsEntryPointAbstract,
|
||||
Fs: GraphicsEntryPointAbstract,
|
||||
Gs: GraphicsEntryPointAbstract,
|
||||
Tcs: GraphicsEntryPointAbstract,
|
||||
Tes: GraphicsEntryPointAbstract,
|
||||
Vs::PipelineLayout: Clone + 'static + Send + Sync, // TODO: shouldn't be required
|
||||
Fs::PipelineLayout: Clone + 'static + Send + Sync, // TODO: shouldn't be required
|
||||
Tcs::PipelineLayout: Clone + 'static + Send + Sync, // TODO: shouldn't be required
|
||||
Tes::PipelineLayout: Clone + 'static + Send + Sync, // TODO: shouldn't be required
|
||||
Gs::PipelineLayout: Clone + 'static + Send + Sync, // TODO: shouldn't be required
|
||||
Tcs::InputDefinition: ShaderInterfaceDefMatch<Vs::OutputDefinition>,
|
||||
Tes::InputDefinition: ShaderInterfaceDefMatch<Tcs::OutputDefinition>,
|
||||
Gs::InputDefinition: ShaderInterfaceDefMatch<Tes::OutputDefinition> + ShaderInterfaceDefMatch<Vs::OutputDefinition>,
|
||||
Fs::InputDefinition: ShaderInterfaceDefMatch<Gs::OutputDefinition>
|
||||
+ ShaderInterfaceDefMatch<Tes::OutputDefinition>
|
||||
+ ShaderInterfaceDefMatch<Vs::OutputDefinition>,
|
||||
Rp: RenderPassAbstract + RenderPassSubpassInterface<Fs::OutputDefinition>
|
||||
{
|
||||
/// Builds the graphics pipeline.
|
||||
// TODO: replace Box<PipelineLayoutAbstract> with a PipelineUnion struct without template params
|
||||
@ -239,79 +168,31 @@ impl<'a,
|
||||
// TODO: add build_with_cache method
|
||||
}
|
||||
|
||||
impl<'a,
|
||||
Vdef,
|
||||
Vsp,
|
||||
Vi,
|
||||
Vo,
|
||||
Vl,
|
||||
impl<Vdef,
|
||||
Vs,
|
||||
Tcs,
|
||||
Tci,
|
||||
Tco,
|
||||
Tcl,
|
||||
Tes,
|
||||
Tei,
|
||||
Teo,
|
||||
Tel,
|
||||
Gs,
|
||||
Gi,
|
||||
Go,
|
||||
Gl,
|
||||
Fs,
|
||||
Fi,
|
||||
Fo,
|
||||
Fl,
|
||||
Rp>
|
||||
GraphicsPipelineBuilder<'a,
|
||||
Vdef,
|
||||
Vsp,
|
||||
Vi,
|
||||
Vo,
|
||||
Vl,
|
||||
GraphicsPipelineBuilder<Vdef,
|
||||
Vs,
|
||||
Tcs,
|
||||
Tci,
|
||||
Tco,
|
||||
Tcl,
|
||||
Tes,
|
||||
Tei,
|
||||
Teo,
|
||||
Tel,
|
||||
Gs,
|
||||
Gi,
|
||||
Go,
|
||||
Gl,
|
||||
Fs,
|
||||
Fi,
|
||||
Fo,
|
||||
Fl,
|
||||
Rp> {
|
||||
// TODO: add pipeline derivate system
|
||||
|
||||
/// Sets the vertex input.
|
||||
#[inline]
|
||||
pub fn vertex_input<T>(self, vertex_input: T)
|
||||
-> GraphicsPipelineBuilder<'a,
|
||||
T,
|
||||
Vsp,
|
||||
Vi,
|
||||
Vo,
|
||||
Vl,
|
||||
-> GraphicsPipelineBuilder<T,
|
||||
Vs,
|
||||
Tcs,
|
||||
Tci,
|
||||
Tco,
|
||||
Tcl,
|
||||
Tes,
|
||||
Tei,
|
||||
Teo,
|
||||
Tel,
|
||||
Gs,
|
||||
Gi,
|
||||
Go,
|
||||
Gl,
|
||||
Fs,
|
||||
Fi,
|
||||
Fo,
|
||||
Fl,
|
||||
Rp> {
|
||||
GraphicsPipelineBuilder {
|
||||
vertex_input: vertex_input,
|
||||
@ -335,28 +216,12 @@ impl<'a,
|
||||
/// vertex.
|
||||
#[inline]
|
||||
pub fn vertex_input_single_buffer<V>(self)
|
||||
-> GraphicsPipelineBuilder<'a,
|
||||
SingleBufferDefinition<V>,
|
||||
Vsp,
|
||||
Vi,
|
||||
Vo,
|
||||
Vl,
|
||||
-> GraphicsPipelineBuilder<SingleBufferDefinition<V>,
|
||||
Vs,
|
||||
Tcs,
|
||||
Tci,
|
||||
Tco,
|
||||
Tcl,
|
||||
Tes,
|
||||
Tei,
|
||||
Teo,
|
||||
Tel,
|
||||
Gs,
|
||||
Gi,
|
||||
Go,
|
||||
Gl,
|
||||
Fs,
|
||||
Fi,
|
||||
Fo,
|
||||
Fl,
|
||||
Rp> {
|
||||
self.vertex_input(SingleBufferDefinition::<V>::new())
|
||||
}
|
||||
@ -364,32 +229,18 @@ impl<'a,
|
||||
/// Sets the vertex shader to use.
|
||||
// TODO: correct specialization constants
|
||||
#[inline]
|
||||
pub fn vertex_shader<Vi2, Vo2, Vl2>(self,
|
||||
shader: VertexShaderEntryPoint<'a, (), Vi2, Vo2, Vl2>,
|
||||
specialization_constants: ())
|
||||
-> GraphicsPipelineBuilder<'a,
|
||||
Vdef,
|
||||
(),
|
||||
Vi2,
|
||||
Vo2,
|
||||
Vl2,
|
||||
Tcs,
|
||||
Tci,
|
||||
Tco,
|
||||
Tcl,
|
||||
Tes,
|
||||
Tei,
|
||||
Teo,
|
||||
Tel,
|
||||
Gs,
|
||||
Gi,
|
||||
Go,
|
||||
Gl,
|
||||
Fs,
|
||||
Fi,
|
||||
Fo,
|
||||
Fl,
|
||||
Rp> {
|
||||
pub fn vertex_shader<Vs2>(self,
|
||||
shader: Vs2,
|
||||
specialization_constants: ())
|
||||
-> GraphicsPipelineBuilder<Vdef,
|
||||
Vs2,
|
||||
Tcs,
|
||||
Tes,
|
||||
Gs,
|
||||
Fs,
|
||||
Rp>
|
||||
where Vs2: GraphicsEntryPointAbstract<SpecializationConstants = ()>,
|
||||
{
|
||||
GraphicsPipelineBuilder {
|
||||
vertex_input: self.vertex_input,
|
||||
vertex_shader: Some(shader),
|
||||
@ -523,13 +374,14 @@ impl<'a,
|
||||
/// Sets the tessellation shaders to use.
|
||||
// TODO: correct specialization constants
|
||||
#[inline]
|
||||
pub fn tessellation_shaders<Tci2, Tco2, Tcl2, Tei2, Teo2, Tel2>(self,
|
||||
tessellation_control_shader: TessControlShaderEntryPoint<'a, (), Tci2, Tco2, Tcl2>,
|
||||
pub fn tessellation_shaders<Tcs2, Tes2>(self,
|
||||
tessellation_control_shader: Tcs2,
|
||||
tessellation_control_shader_spec_constants: (),
|
||||
tessellation_evaluation_shader: TessEvaluationShaderEntryPoint<'a, (), Tei2, Teo2, Tel2>,
|
||||
tessellation_evaluation_shader: Tes2,
|
||||
tessellation_evaluation_shader_spec_constants: ())
|
||||
-> GraphicsPipelineBuilder<'a, Vdef, Vsp, Vi, Vo, Vl, (), Tci2, Tco2,
|
||||
Tcl2, (), Tei2, Teo2, Tel2, Gs, Gi, Go, Gl, Fs, Fi, Fo, Fl, Rp>
|
||||
-> GraphicsPipelineBuilder<Vdef, Vs, Tcs2, Tes2, Gs, Fs, Rp>
|
||||
where Tcs2: GraphicsEntryPointAbstract<SpecializationConstants = ()>,
|
||||
Tes2: GraphicsEntryPointAbstract<SpecializationConstants = ()>,
|
||||
{
|
||||
GraphicsPipelineBuilder {
|
||||
vertex_input: self.vertex_input,
|
||||
@ -560,32 +412,18 @@ impl<'a,
|
||||
/// Sets the geometry shader to use.
|
||||
// TODO: correct specialization constants
|
||||
#[inline]
|
||||
pub fn geometry_shader<Gi2, Go2, Gl2>(self,
|
||||
shader: GeometryShaderEntryPoint<'a, (), Gi2, Go2, Gl2>,
|
||||
specialization_constants: ())
|
||||
-> GraphicsPipelineBuilder<'a,
|
||||
Vdef,
|
||||
Vsp,
|
||||
Vi,
|
||||
Vo,
|
||||
Vl,
|
||||
Tcs,
|
||||
Tci,
|
||||
Tco,
|
||||
Tcl,
|
||||
Tes,
|
||||
Tei,
|
||||
Teo,
|
||||
Tel,
|
||||
(),
|
||||
Gi2,
|
||||
Go2,
|
||||
Gl2,
|
||||
Fs,
|
||||
Fi,
|
||||
Fo,
|
||||
Fl,
|
||||
Rp> {
|
||||
pub fn geometry_shader<Gs2>(self,
|
||||
shader: Gs2,
|
||||
specialization_constants: ())
|
||||
-> GraphicsPipelineBuilder<Vdef,
|
||||
Vs,
|
||||
Tcs,
|
||||
Tes,
|
||||
Gs2,
|
||||
Fs,
|
||||
Rp>
|
||||
where Gs2: GraphicsEntryPointAbstract<SpecializationConstants = ()>,
|
||||
{
|
||||
GraphicsPipelineBuilder {
|
||||
vertex_input: self.vertex_input,
|
||||
vertex_shader: self.vertex_shader,
|
||||
@ -782,32 +620,18 @@ impl<'a,
|
||||
/// The fragment shader is run once for each pixel that is covered by each primitive.
|
||||
// TODO: correct specialization constants
|
||||
#[inline]
|
||||
pub fn fragment_shader<Fi2, Fo2, Fl2>(self,
|
||||
shader: FragmentShaderEntryPoint<'a, (), Fi2, Fo2, Fl2>,
|
||||
specialization_constants: ())
|
||||
-> GraphicsPipelineBuilder<'a,
|
||||
Vdef,
|
||||
Vsp,
|
||||
Vi,
|
||||
Vo,
|
||||
Vl,
|
||||
Tcs,
|
||||
Tci,
|
||||
Tco,
|
||||
Tcl,
|
||||
Tes,
|
||||
Tei,
|
||||
Teo,
|
||||
Tel,
|
||||
Gs,
|
||||
Gi,
|
||||
Go,
|
||||
Gl,
|
||||
(),
|
||||
Fi2,
|
||||
Fo2,
|
||||
Fl2,
|
||||
Rp> {
|
||||
pub fn fragment_shader<Fs2>(self,
|
||||
shader: Fs2,
|
||||
specialization_constants: ())
|
||||
-> GraphicsPipelineBuilder<Vdef,
|
||||
Vs,
|
||||
Tcs,
|
||||
Tes,
|
||||
Gs,
|
||||
Fs2,
|
||||
Rp>
|
||||
where Fs2: GraphicsEntryPointAbstract<SpecializationConstants = ()>,
|
||||
{
|
||||
GraphicsPipelineBuilder {
|
||||
vertex_input: self.vertex_input,
|
||||
vertex_shader: self.vertex_shader,
|
||||
@ -921,28 +745,12 @@ impl<'a,
|
||||
/// Sets the render pass subpass to use.
|
||||
#[inline]
|
||||
pub fn render_pass<Rp2>(self, subpass: Subpass<Rp2>)
|
||||
-> GraphicsPipelineBuilder<'a,
|
||||
Vdef,
|
||||
Vsp,
|
||||
Vi,
|
||||
Vo,
|
||||
Vl,
|
||||
-> GraphicsPipelineBuilder<Vdef,
|
||||
Vs,
|
||||
Tcs,
|
||||
Tci,
|
||||
Tco,
|
||||
Tcl,
|
||||
Tes,
|
||||
Tei,
|
||||
Teo,
|
||||
Tel,
|
||||
Gs,
|
||||
Gi,
|
||||
Go,
|
||||
Gl,
|
||||
Fs,
|
||||
Fi,
|
||||
Fo,
|
||||
Fl,
|
||||
Rp2> {
|
||||
GraphicsPipelineBuilder {
|
||||
vertex_input: self.vertex_input,
|
||||
|
@ -29,7 +29,6 @@ use check_errors;
|
||||
use descriptor::PipelineLayoutAbstract;
|
||||
use descriptor::descriptor::DescriptorDesc;
|
||||
use descriptor::descriptor_set::UnsafeDescriptorSetLayout;
|
||||
use descriptor::pipeline_layout::EmptyPipelineDesc;
|
||||
use descriptor::pipeline_layout::PipelineLayout;
|
||||
use descriptor::pipeline_layout::PipelineLayoutDesc;
|
||||
use descriptor::pipeline_layout::PipelineLayoutDescNames;
|
||||
@ -63,15 +62,11 @@ use pipeline::multisample::Multisample;
|
||||
use pipeline::raster::DepthBiasControl;
|
||||
use pipeline::raster::PolygonMode;
|
||||
use pipeline::raster::Rasterization;
|
||||
use pipeline::shader::EmptyShaderInterfaceDef;
|
||||
use pipeline::shader::FragmentShaderEntryPoint;
|
||||
use pipeline::shader::GeometryShaderEntryPoint;
|
||||
use pipeline::shader::ShaderInterfaceDef;
|
||||
use pipeline::shader::EmptyEntryPointDummy;
|
||||
use pipeline::shader::GraphicsEntryPointAbstract;
|
||||
use pipeline::shader::GraphicsShaderType;
|
||||
use pipeline::shader::ShaderInterfaceDefMatch;
|
||||
use pipeline::shader::ShaderInterfaceMismatchError;
|
||||
use pipeline::shader::TessControlShaderEntryPoint;
|
||||
use pipeline::shader::TessEvaluationShaderEntryPoint;
|
||||
use pipeline::shader::VertexShaderEntryPoint;
|
||||
use pipeline::vertex::IncompatibleVertexDefinitionError;
|
||||
use pipeline::vertex::SingleBufferDefinition;
|
||||
use pipeline::vertex::VertexDefinition;
|
||||
@ -86,28 +81,13 @@ mod builder;
|
||||
|
||||
/// Description of a `GraphicsPipeline`.
|
||||
#[deprecated = "Use the GraphicsPipelineBuilder instead"]
|
||||
pub struct GraphicsPipelineParams<'a,
|
||||
pub struct GraphicsPipelineParams<
|
||||
Vdef,
|
||||
Vsp,
|
||||
Vi,
|
||||
Vo,
|
||||
Vl,
|
||||
Vs,
|
||||
Tcs,
|
||||
Tci,
|
||||
Tco,
|
||||
Tcl,
|
||||
Tes,
|
||||
Tei,
|
||||
Teo,
|
||||
Tel,
|
||||
Gs,
|
||||
Gi,
|
||||
Go,
|
||||
Gl,
|
||||
Fs,
|
||||
Fi,
|
||||
Fo,
|
||||
Fl,
|
||||
Rp>
|
||||
{
|
||||
/// Describes the layout of the vertex input.
|
||||
@ -119,7 +99,7 @@ pub struct GraphicsPipelineParams<'a,
|
||||
pub vertex_input: Vdef,
|
||||
|
||||
/// The entry point of the vertex shader that will be run on the vertex input.
|
||||
pub vertex_shader: VertexShaderEntryPoint<'a, Vsp, Vi, Vo, Vl>,
|
||||
pub vertex_shader: Vs,
|
||||
|
||||
/// Describes how vertices should be assembled into primitives. Essentially contains the type
|
||||
/// of primitives.
|
||||
@ -127,12 +107,11 @@ pub struct GraphicsPipelineParams<'a,
|
||||
|
||||
/// Parameters of the tessellation stage. `None` if you don't want to use tessellation.
|
||||
/// If you use tessellation, you must enable the `tessellation_shader` feature on the device.
|
||||
pub tessellation:
|
||||
Option<GraphicsPipelineParamsTess<'a, Tcs, Tci, Tco, Tcl, Tes, Tei, Teo, Tel>>,
|
||||
pub tessellation: Option<GraphicsPipelineParamsTess<Tcs, Tes>>,
|
||||
|
||||
/// The entry point of the geometry shader. `None` if you don't want a geometry shader.
|
||||
/// If you use a geometry shader, you must enable the `geometry_shader` feature on the device.
|
||||
pub geometry_shader: Option<GeometryShaderEntryPoint<'a, Gs, Gi, Go, Gl>>,
|
||||
pub geometry_shader: Option<Gs>,
|
||||
|
||||
/// Describes the subsection of the framebuffer attachments where the scene will be drawn.
|
||||
/// You can use one or multiple viewports, but using multiple viewports is only relevant with
|
||||
@ -146,7 +125,7 @@ pub struct GraphicsPipelineParams<'a,
|
||||
pub multisample: Multisample,
|
||||
|
||||
/// The entry point of the fragment shader that will be run on the pixels.
|
||||
pub fragment_shader: FragmentShaderEntryPoint<'a, Fs, Fi, Fo, Fl>,
|
||||
pub fragment_shader: Fs,
|
||||
|
||||
/// Describes how the implementation should perform the depth and stencil tests.
|
||||
pub depth_stencil: DepthStencil,
|
||||
@ -162,11 +141,11 @@ pub struct GraphicsPipelineParams<'a,
|
||||
|
||||
/// Additional parameters if you use tessellation.
|
||||
#[deprecated = "Use the GraphicsPipelineBuilder instead"]
|
||||
pub struct GraphicsPipelineParamsTess<'a, Tcs, Tci, Tco, Tcl, Tes, Tei, Teo, Tel> {
|
||||
pub struct GraphicsPipelineParamsTess<Tcs, Tes> {
|
||||
/// The entry point of the tessellation control shader.
|
||||
pub tessellation_control_shader: TessControlShaderEntryPoint<'a, Tcs, Tci, Tco, Tcl>,
|
||||
pub tessellation_control_shader: Tcs,
|
||||
/// The entry point of the tessellation evaluation shader.
|
||||
pub tessellation_evaluation_shader: TessEvaluationShaderEntryPoint<'a, Tes, Tei, Teo, Tel>,
|
||||
pub tessellation_evaluation_shader: Tes,
|
||||
}
|
||||
|
||||
/// Defines how the implementation should perform a draw operation.
|
||||
@ -204,28 +183,12 @@ impl GraphicsPipeline<(), (), ()> {
|
||||
/// Starts the building process of a graphics pipeline. Returns a builder object that you can
|
||||
/// fill with the various parameters.
|
||||
pub fn start<'a>()
|
||||
-> GraphicsPipelineBuilder<'a,
|
||||
SingleBufferDefinition<()>,
|
||||
(),
|
||||
(),
|
||||
(),
|
||||
(),
|
||||
(),
|
||||
EmptyShaderInterfaceDef,
|
||||
EmptyShaderInterfaceDef,
|
||||
EmptyPipelineDesc,
|
||||
(),
|
||||
EmptyShaderInterfaceDef,
|
||||
EmptyShaderInterfaceDef,
|
||||
EmptyPipelineDesc,
|
||||
(),
|
||||
EmptyShaderInterfaceDef,
|
||||
EmptyShaderInterfaceDef,
|
||||
EmptyPipelineDesc,
|
||||
(),
|
||||
EmptyShaderInterfaceDef,
|
||||
EmptyShaderInterfaceDef,
|
||||
EmptyPipelineDesc,
|
||||
-> GraphicsPipelineBuilder<SingleBufferDefinition<()>,
|
||||
EmptyEntryPointDummy,
|
||||
EmptyEntryPointDummy,
|
||||
EmptyEntryPointDummy,
|
||||
EmptyEntryPointDummy,
|
||||
EmptyEntryPointDummy,
|
||||
()>
|
||||
{
|
||||
GraphicsPipelineBuilder::new()
|
||||
@ -244,19 +207,17 @@ impl<Vdef, Rp> GraphicsPipeline<Vdef, (), Rp>
|
||||
/// the other constructors for other possibilities.
|
||||
#[inline]
|
||||
#[deprecated = "Use the GraphicsPipelineBuilder instead"]
|
||||
pub fn new<'a, Vsp, Vi, Vo, Vl, Fs, Fi, Fo, Fl>
|
||||
pub fn new<Vs, Fs>
|
||||
(device: Arc<Device>,
|
||||
params: GraphicsPipelineParams<'a, Vdef, Vsp, Vi, Vo, Vl, (), (), (), EmptyPipelineDesc,
|
||||
(), (), (), EmptyPipelineDesc, (), (), (), EmptyPipelineDesc,
|
||||
Fs, Fi, Fo, Fl, Rp>)
|
||||
-> Result<GraphicsPipeline<Vdef, PipelineLayout<PipelineLayoutDescUnion<Vl, Fl>>, Rp>, GraphicsPipelineCreationError>
|
||||
where Vdef: VertexDefinition<Vi>,
|
||||
Vl: PipelineLayoutDescNames + Clone,
|
||||
Fl: PipelineLayoutDescNames + Clone,
|
||||
Fi: ShaderInterfaceDefMatch<Vo>,
|
||||
Fo: ShaderInterfaceDef,
|
||||
Vo: ShaderInterfaceDef,
|
||||
Rp: RenderPassSubpassInterface<Fo>,
|
||||
params: GraphicsPipelineParams<Vdef, Vs, EmptyEntryPointDummy, EmptyEntryPointDummy, EmptyEntryPointDummy, Fs, Rp>)
|
||||
-> Result<GraphicsPipeline<Vdef, PipelineLayout<PipelineLayoutDescUnion<Vs::PipelineLayout, Fs::PipelineLayout>>, Rp>, GraphicsPipelineCreationError>
|
||||
where Vdef: VertexDefinition<Vs::InputDefinition>,
|
||||
Vs: GraphicsEntryPointAbstract,
|
||||
Fs: GraphicsEntryPointAbstract,
|
||||
Vs::PipelineLayout: Clone,
|
||||
Fs::PipelineLayout: Clone,
|
||||
Fs::InputDefinition: ShaderInterfaceDefMatch<Vs::OutputDefinition>,
|
||||
Rp: RenderPassSubpassInterface<Fs::OutputDefinition>,
|
||||
{
|
||||
if let Err(err) = params
|
||||
.fragment_shader
|
||||
@ -275,24 +236,9 @@ impl<Vdef, Rp> GraphicsPipeline<Vdef, (), Rp>
|
||||
.unwrap(); // TODO: error
|
||||
|
||||
GraphicsPipeline::new_inner::<_,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
(),
|
||||
(),
|
||||
(),
|
||||
EmptyPipelineDesc,
|
||||
(),
|
||||
(),
|
||||
(),
|
||||
EmptyPipelineDesc,
|
||||
(),
|
||||
(),
|
||||
(),
|
||||
EmptyPipelineDesc,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
EmptyEntryPointDummy,
|
||||
EmptyEntryPointDummy,
|
||||
EmptyEntryPointDummy,
|
||||
_>(device, params, pl)
|
||||
}
|
||||
|
||||
@ -305,22 +251,20 @@ impl<Vdef, Rp> GraphicsPipeline<Vdef, (), Rp>
|
||||
/// shader. See the other constructors for other possibilities.
|
||||
#[inline]
|
||||
#[deprecated = "Use the GraphicsPipelineBuilder instead"]
|
||||
pub fn with_geometry_shader<'a, Vsp, Vi, Vo, Vl, Gsp, Gi, Go, Gl, Fs, Fi, Fo, Fl>
|
||||
pub fn with_geometry_shader<Vs, Gs, Fs>
|
||||
(device: Arc<Device>,
|
||||
params: GraphicsPipelineParams<'a, Vdef, Vsp, Vi, Vo, Vl, (), (), (), EmptyPipelineDesc,
|
||||
(), (), (), EmptyPipelineDesc, Gsp, Gi, Go, Gl, Fs, Fi,
|
||||
Fo, Fl, Rp>)
|
||||
-> Result<GraphicsPipeline<Vdef, PipelineLayout<PipelineLayoutDescUnion<PipelineLayoutDescUnion<Vl, Fl>, Gl>>, Rp>, GraphicsPipelineCreationError>
|
||||
where Vdef: VertexDefinition<Vi>,
|
||||
Vl: PipelineLayoutDescNames + Clone,
|
||||
Fl: PipelineLayoutDescNames + Clone,
|
||||
Gl: PipelineLayoutDescNames + Clone,
|
||||
Gi: ShaderInterfaceDefMatch<Vo>,
|
||||
Vo: ShaderInterfaceDef,
|
||||
Fi: ShaderInterfaceDefMatch<Go> + ShaderInterfaceDefMatch<Vo>,
|
||||
Fo: ShaderInterfaceDef,
|
||||
Go: ShaderInterfaceDef,
|
||||
Rp: RenderPassSubpassInterface<Fo>,
|
||||
params: GraphicsPipelineParams<Vdef, Vs, EmptyEntryPointDummy, EmptyEntryPointDummy, Gs, Fs, Rp>)
|
||||
-> Result<GraphicsPipeline<Vdef, PipelineLayout<PipelineLayoutDescUnion<PipelineLayoutDescUnion<Vs::PipelineLayout, Fs::PipelineLayout>, Gs::PipelineLayout>>, Rp>, GraphicsPipelineCreationError>
|
||||
where Vdef: VertexDefinition<Vs::InputDefinition>,
|
||||
Vs: GraphicsEntryPointAbstract,
|
||||
Fs: GraphicsEntryPointAbstract,
|
||||
Gs: GraphicsEntryPointAbstract,
|
||||
Vs::PipelineLayout: Clone,
|
||||
Fs::PipelineLayout: Clone,
|
||||
Gs::PipelineLayout: Clone,
|
||||
Gs::InputDefinition: ShaderInterfaceDefMatch<Vs::OutputDefinition>,
|
||||
Fs::InputDefinition: ShaderInterfaceDefMatch<Gs::OutputDefinition> + ShaderInterfaceDefMatch<Vs::OutputDefinition>,
|
||||
Rp: RenderPassSubpassInterface<Fs::OutputDefinition>,
|
||||
{
|
||||
if let Some(ref geometry_shader) = params.geometry_shader {
|
||||
if let Err(err) = geometry_shader
|
||||
@ -365,26 +309,23 @@ impl<Vdef, Rp> GraphicsPipeline<Vdef, (), Rp>
|
||||
/// possibilities.
|
||||
#[inline]
|
||||
#[deprecated = "Use the GraphicsPipelineBuilder instead"]
|
||||
pub fn with_tessellation<'a, Vsp, Vi, Vo, Vl, Tcs, Tci, Tco, Tcl, Tes, Tei, Teo, Tel, Fs, Fi,
|
||||
Fo, Fl>
|
||||
pub fn with_tessellation<Vs, Tcs, Tes, Fs>
|
||||
(device: Arc<Device>,
|
||||
params: GraphicsPipelineParams<'a, Vdef, Vsp, Vi, Vo, Vl, Tcs, Tci, Tco, Tcl, Tes,
|
||||
Tei, Teo, Tel, (), (), (), EmptyPipelineDesc, Fs, Fi,
|
||||
Fo, Fl, Rp>)
|
||||
-> Result<GraphicsPipeline<Vdef, PipelineLayout<PipelineLayoutDescUnion<PipelineLayoutDescUnion<PipelineLayoutDescUnion<Vl, Fl>, Tcl>, Tel>>, Rp>, GraphicsPipelineCreationError>
|
||||
where Vdef: VertexDefinition<Vi>,
|
||||
Vl: PipelineLayoutDescNames + Clone,
|
||||
Fl: PipelineLayoutDescNames + Clone,
|
||||
Tcl: PipelineLayoutDescNames + Clone,
|
||||
Tel: PipelineLayoutDescNames + Clone,
|
||||
Tci: ShaderInterfaceDefMatch<Vo>,
|
||||
Tei: ShaderInterfaceDefMatch<Tco>,
|
||||
Vo: ShaderInterfaceDef,
|
||||
Tco: ShaderInterfaceDef,
|
||||
Teo: ShaderInterfaceDef,
|
||||
Fi: ShaderInterfaceDefMatch<Teo> + ShaderInterfaceDefMatch<Vo>,
|
||||
Fo: ShaderInterfaceDef,
|
||||
Rp: RenderPassAbstract + RenderPassSubpassInterface<Fo>,
|
||||
params: GraphicsPipelineParams<Vdef, Vs, Tcs, Tes, EmptyEntryPointDummy, Fs, Rp>)
|
||||
-> Result<GraphicsPipeline<Vdef, PipelineLayout<PipelineLayoutDescUnion<PipelineLayoutDescUnion<PipelineLayoutDescUnion<Vs::PipelineLayout, Fs::PipelineLayout>, Tcs::PipelineLayout>, Tes::PipelineLayout>>, Rp>, GraphicsPipelineCreationError>
|
||||
where Vdef: VertexDefinition<Vs::InputDefinition>,
|
||||
Vs: GraphicsEntryPointAbstract,
|
||||
Fs: GraphicsEntryPointAbstract,
|
||||
Tcs: GraphicsEntryPointAbstract,
|
||||
Tes: GraphicsEntryPointAbstract,
|
||||
Vs::PipelineLayout: Clone,
|
||||
Fs::PipelineLayout: Clone,
|
||||
Tcs::PipelineLayout: Clone,
|
||||
Tes::PipelineLayout: Clone,
|
||||
Tcs::InputDefinition: ShaderInterfaceDefMatch<Vs::OutputDefinition>,
|
||||
Tes::InputDefinition: ShaderInterfaceDefMatch<Tcs::OutputDefinition>,
|
||||
Fs::InputDefinition: ShaderInterfaceDefMatch<Tes::OutputDefinition> + ShaderInterfaceDefMatch<Vs::OutputDefinition>,
|
||||
Rp: RenderPassAbstract + RenderPassSubpassInterface<Fs::OutputDefinition>,
|
||||
{
|
||||
if let Some(ref tess) = params.tessellation {
|
||||
if let Err(err) = tess.tessellation_control_shader
|
||||
@ -437,71 +378,39 @@ impl<Vdef, Rp> GraphicsPipeline<Vdef, (), Rp>
|
||||
// TODO: replace Box<PipelineLayoutAbstract> with a PipelineUnion struct without template params
|
||||
#[inline]
|
||||
#[deprecated = "Use the GraphicsPipelineBuilder instead"]
|
||||
pub fn with_tessellation_and_geometry<'a,
|
||||
Vsp,
|
||||
Vi,
|
||||
Vo,
|
||||
Vl,
|
||||
pub fn with_tessellation_and_geometry<Vs,
|
||||
Tcs,
|
||||
Tci,
|
||||
Tco,
|
||||
Tcl,
|
||||
Tes,
|
||||
Tei,
|
||||
Teo,
|
||||
Tel,
|
||||
Gsp,
|
||||
Gi,
|
||||
Go,
|
||||
Gl,
|
||||
Fs,
|
||||
Fi,
|
||||
Fo,
|
||||
Fl>(
|
||||
Gs,
|
||||
Fs>(
|
||||
device: Arc<Device>,
|
||||
params: GraphicsPipelineParams<'a,
|
||||
Vdef,
|
||||
Vsp,
|
||||
Vi,
|
||||
Vo,
|
||||
Vl,
|
||||
params: GraphicsPipelineParams<Vdef,
|
||||
Vs,
|
||||
Tcs,
|
||||
Tci,
|
||||
Tco,
|
||||
Tcl,
|
||||
Tes,
|
||||
Tei,
|
||||
Teo,
|
||||
Tel,
|
||||
Gsp,
|
||||
Gi,
|
||||
Go,
|
||||
Gl,
|
||||
Gs,
|
||||
Fs,
|
||||
Fi,
|
||||
Fo,
|
||||
Fl,
|
||||
Rp>)
|
||||
-> Result<GraphicsPipeline<Vdef, Box<PipelineLayoutAbstract + Send + Sync>, Rp>,
|
||||
GraphicsPipelineCreationError>
|
||||
where Vdef: VertexDefinition<Vi>,
|
||||
Vl: PipelineLayoutDescNames + Clone + 'static + Send + Sync, // TODO: Clone + 'static + Send + Sync shouldn't be required
|
||||
Fl: PipelineLayoutDescNames + Clone + 'static + Send + Sync, // TODO: Clone + 'static + Send + Sync shouldn't be required
|
||||
Tcl: PipelineLayoutDescNames + Clone + 'static + Send + Sync, // TODO: Clone + 'static + Send + Sync shouldn't be required
|
||||
Tel: PipelineLayoutDescNames + Clone + 'static + Send + Sync, // TODO: Clone + 'static + Send + Sync shouldn't be required
|
||||
Gl: PipelineLayoutDescNames + Clone + 'static + Send + Sync, // TODO: Clone + 'static + Send + Sync shouldn't be required
|
||||
Tci: ShaderInterfaceDefMatch<Vo>,
|
||||
Tei: ShaderInterfaceDefMatch<Tco>,
|
||||
Gi: ShaderInterfaceDefMatch<Teo> + ShaderInterfaceDefMatch<Vo>,
|
||||
Vo: ShaderInterfaceDef,
|
||||
Tco: ShaderInterfaceDef,
|
||||
Teo: ShaderInterfaceDef,
|
||||
Go: ShaderInterfaceDef,
|
||||
Fi: ShaderInterfaceDefMatch<Go>
|
||||
+ ShaderInterfaceDefMatch<Teo>
|
||||
+ ShaderInterfaceDefMatch<Vo>,
|
||||
Fo: ShaderInterfaceDef,
|
||||
Rp: RenderPassAbstract + RenderPassSubpassInterface<Fo>
|
||||
where Vdef: VertexDefinition<Vs::InputDefinition>,
|
||||
Vs: GraphicsEntryPointAbstract,
|
||||
Fs: GraphicsEntryPointAbstract,
|
||||
Gs: GraphicsEntryPointAbstract,
|
||||
Tcs: GraphicsEntryPointAbstract,
|
||||
Tes: GraphicsEntryPointAbstract,
|
||||
Vs::PipelineLayout: Clone + 'static + Send + Sync, // TODO: shouldn't be required
|
||||
Fs::PipelineLayout: Clone + 'static + Send + Sync, // TODO: shouldn't be required
|
||||
Tcs::PipelineLayout: Clone + 'static + Send + Sync, // TODO: shouldn't be required
|
||||
Tes::PipelineLayout: Clone + 'static + Send + Sync, // TODO: shouldn't be required
|
||||
Gs::PipelineLayout: Clone + 'static + Send + Sync, // TODO: shouldn't be required
|
||||
Tcs::InputDefinition: ShaderInterfaceDefMatch<Vs::OutputDefinition>,
|
||||
Tes::InputDefinition: ShaderInterfaceDefMatch<Tcs::OutputDefinition>,
|
||||
Gs::InputDefinition: ShaderInterfaceDefMatch<Tes::OutputDefinition> + ShaderInterfaceDefMatch<Vs::OutputDefinition>,
|
||||
Fs::InputDefinition: ShaderInterfaceDefMatch<Gs::OutputDefinition>
|
||||
+ ShaderInterfaceDefMatch<Tes::OutputDefinition>
|
||||
+ ShaderInterfaceDefMatch<Vs::OutputDefinition>,
|
||||
Rp: RenderPassAbstract + RenderPassSubpassInterface<Fs::OutputDefinition>
|
||||
{
|
||||
let pl;
|
||||
|
||||
@ -610,61 +519,28 @@ impl<Vdef, Rp> GraphicsPipeline<Vdef, (), Rp>
|
||||
impl<Vdef, L, Rp> GraphicsPipeline<Vdef, L, Rp>
|
||||
where L: PipelineLayoutAbstract
|
||||
{
|
||||
fn new_inner<'a,
|
||||
Vsp,
|
||||
Vi,
|
||||
Vo,
|
||||
Vl,
|
||||
fn new_inner<Vs,
|
||||
Tcs,
|
||||
Tci,
|
||||
Tco,
|
||||
Tcl,
|
||||
Tes,
|
||||
Tei,
|
||||
Teo,
|
||||
Tel,
|
||||
Gsp,
|
||||
Gi,
|
||||
Go,
|
||||
Gl,
|
||||
Fs,
|
||||
Fi,
|
||||
Fo,
|
||||
Fl>(
|
||||
Gs,
|
||||
Fs>(
|
||||
device: Arc<Device>,
|
||||
params: GraphicsPipelineParams<'a,
|
||||
Vdef,
|
||||
Vsp,
|
||||
Vi,
|
||||
Vo,
|
||||
Vl,
|
||||
params: GraphicsPipelineParams<Vdef,
|
||||
Vs,
|
||||
Tcs,
|
||||
Tci,
|
||||
Tco,
|
||||
Tcl,
|
||||
Tes,
|
||||
Tei,
|
||||
Teo,
|
||||
Tel,
|
||||
Gsp,
|
||||
Gi,
|
||||
Go,
|
||||
Gl,
|
||||
Gs,
|
||||
Fs,
|
||||
Fi,
|
||||
Fo,
|
||||
Fl,
|
||||
Rp>,
|
||||
pipeline_layout: L)
|
||||
-> Result<GraphicsPipeline<Vdef, L, Rp>, GraphicsPipelineCreationError>
|
||||
where Vdef: VertexDefinition<Vi>,
|
||||
Fo: ShaderInterfaceDef,
|
||||
Vl: PipelineLayoutDescNames,
|
||||
Fl: PipelineLayoutDescNames,
|
||||
Gl: PipelineLayoutDescNames,
|
||||
Tcl: PipelineLayoutDescNames,
|
||||
Tel: PipelineLayoutDescNames,
|
||||
Rp: RenderPassAbstract + RenderPassDesc + RenderPassSubpassInterface<Fo>
|
||||
where Vdef: VertexDefinition<Vs::InputDefinition>,
|
||||
Vs: GraphicsEntryPointAbstract,
|
||||
Fs: GraphicsEntryPointAbstract,
|
||||
Gs: GraphicsEntryPointAbstract,
|
||||
Tcs: GraphicsEntryPointAbstract,
|
||||
Tes: GraphicsEntryPointAbstract,
|
||||
Rp: RenderPassAbstract + RenderPassDesc + RenderPassSubpassInterface<Fs::OutputDefinition>
|
||||
{
|
||||
let vk = device.pointers();
|
||||
|
||||
@ -700,6 +576,11 @@ impl<Vdef, L, Rp> GraphicsPipeline<Vdef, L, Rp>
|
||||
let stages = {
|
||||
let mut stages = SmallVec::<[_; 5]>::new();
|
||||
|
||||
match params.vertex_shader.ty() {
|
||||
GraphicsShaderType::Vertex => {},
|
||||
_ => return Err(GraphicsPipelineCreationError::WrongShaderType),
|
||||
};
|
||||
|
||||
stages.push(vk::PipelineShaderStageCreateInfo {
|
||||
sType: vk::STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
pNext: ptr::null(),
|
||||
@ -710,6 +591,11 @@ impl<Vdef, L, Rp> GraphicsPipeline<Vdef, L, Rp>
|
||||
pSpecializationInfo: ptr::null(), // TODO:
|
||||
});
|
||||
|
||||
match params.fragment_shader.ty() {
|
||||
GraphicsShaderType::Fragment => {},
|
||||
_ => return Err(GraphicsPipelineCreationError::WrongShaderType),
|
||||
};
|
||||
|
||||
stages.push(vk::PipelineShaderStageCreateInfo {
|
||||
sType: vk::STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
pNext: ptr::null(),
|
||||
@ -743,6 +629,16 @@ impl<Vdef, L, Rp> GraphicsPipeline<Vdef, L, Rp>
|
||||
return Err(GraphicsPipelineCreationError::TessellationShaderFeatureNotEnabled);
|
||||
}
|
||||
|
||||
match tess.tessellation_control_shader.ty() {
|
||||
GraphicsShaderType::TessellationControl => {},
|
||||
_ => return Err(GraphicsPipelineCreationError::WrongShaderType),
|
||||
};
|
||||
|
||||
match tess.tessellation_evaluation_shader.ty() {
|
||||
GraphicsShaderType::TessellationControl => {},
|
||||
_ => return Err(GraphicsPipelineCreationError::WrongShaderType),
|
||||
};
|
||||
|
||||
stages.push(vk::PipelineShaderStageCreateInfo {
|
||||
sType: vk::STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
pNext: ptr::null(),
|
||||
@ -774,7 +670,7 @@ impl<Vdef, L, Rp> GraphicsPipeline<Vdef, L, Rp>
|
||||
let (buffers_iter, attribs_iter) =
|
||||
params
|
||||
.vertex_input
|
||||
.definition(params.vertex_shader.input_definition())?;
|
||||
.definition(params.vertex_shader.input())?;
|
||||
|
||||
let mut binding_descriptions = SmallVec::<[_; 8]>::new();
|
||||
for (num, stride, rate) in buffers_iter {
|
||||
@ -882,8 +778,13 @@ impl<Vdef, L, Rp> GraphicsPipeline<Vdef, L, Rp>
|
||||
|
||||
// TODO: should check from the tess eval shader instead of the input assembly
|
||||
if let Some(ref gs) = params.geometry_shader {
|
||||
if !gs.primitives().matches(params.input_assembly.topology) {
|
||||
return Err(GraphicsPipelineCreationError::TopologyNotMatchingGeometryShader);
|
||||
match gs.ty() {
|
||||
GraphicsShaderType::Geometry(primitives) => {
|
||||
if !primitives.matches(params.input_assembly.topology) {
|
||||
return Err(GraphicsPipelineCreationError::TopologyNotMatchingGeometryShader);
|
||||
}
|
||||
},
|
||||
_ => return Err(GraphicsPipelineCreationError::WrongShaderType),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1922,6 +1823,11 @@ pub enum GraphicsPipelineCreationError {
|
||||
|
||||
/// The `maxTessellationPatchSize` limit was exceeded.
|
||||
MaxTessellationPatchSizeExceeded,
|
||||
|
||||
/// The wrong type of shader has been passed.
|
||||
///
|
||||
/// For example you passed a vertex shader as the fragment shader.
|
||||
WrongShaderType,
|
||||
}
|
||||
|
||||
impl error::Error for GraphicsPipelineCreationError {
|
||||
@ -2050,6 +1956,9 @@ impl error::Error for GraphicsPipelineCreationError {
|
||||
GraphicsPipelineCreationError::MaxTessellationPatchSizeExceeded => {
|
||||
"the maximum tessellation patch size was exceeded"
|
||||
},
|
||||
GraphicsPipelineCreationError::WrongShaderType => {
|
||||
"the wrong type of shader has been passed"
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,11 +29,12 @@ use std::ops::Range;
|
||||
use std::ptr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use descriptor::pipeline_layout::EmptyPipelineDesc;
|
||||
use descriptor::pipeline_layout::PipelineLayoutDescNames;
|
||||
use format::Format;
|
||||
use pipeline::input_assembly::PrimitiveTopology;
|
||||
|
||||
use OomError;
|
||||
use SafeDeref;
|
||||
use VulkanObject;
|
||||
use check_errors;
|
||||
use device::Device;
|
||||
@ -44,18 +45,14 @@ use vk;
|
||||
/// Note that it is advised to wrap around a `ShaderModule` with a struct that is different for
|
||||
/// each shader.
|
||||
#[derive(Debug)]
|
||||
pub struct ShaderModule<P = Arc<Device>>
|
||||
where P: SafeDeref<Target = Device>
|
||||
{
|
||||
pub struct ShaderModule {
|
||||
// The module.
|
||||
module: vk::ShaderModule,
|
||||
// Pointer to the device.
|
||||
device: P,
|
||||
device: Arc<Device>,
|
||||
}
|
||||
|
||||
impl<P> ShaderModule<P>
|
||||
where P: SafeDeref<Target = Device>
|
||||
{
|
||||
impl ShaderModule {
|
||||
/// Builds a new shader module from SPIR-V.
|
||||
///
|
||||
/// # Safety
|
||||
@ -64,7 +61,7 @@ impl<P> ShaderModule<P>
|
||||
/// - The SPIR-V code may require some features that are not enabled. This isn't checked by
|
||||
/// this function either.
|
||||
///
|
||||
pub unsafe fn new(device: P, spirv: &[u8]) -> Result<Arc<ShaderModule<P>>, OomError> {
|
||||
pub unsafe fn new(device: Arc<Device>, spirv: &[u8]) -> Result<Arc<ShaderModule>, OomError> {
|
||||
debug_assert!((spirv.len() % 4) == 0);
|
||||
|
||||
let module = {
|
||||
@ -103,117 +100,17 @@ impl<P> ShaderModule<P>
|
||||
/// - The input, output and layout must correctly describe the input, output and layout used
|
||||
/// by this stage.
|
||||
///
|
||||
pub unsafe fn vertex_shader_entry_point<'a, S, I, O, L>(
|
||||
&'a self, name: &'a CStr, input: I, output: O, layout: L)
|
||||
-> VertexShaderEntryPoint<'a, S, I, O, L, P> {
|
||||
VertexShaderEntryPoint {
|
||||
pub unsafe fn graphics_entry_point<'a, S, I, O, L>(&'a self, name: &'a CStr, input: I, output: O,
|
||||
layout: L, ty: GraphicsShaderType)
|
||||
-> GraphicsEntryPoint<'a, S, I, O, L>
|
||||
{
|
||||
GraphicsEntryPoint {
|
||||
module: self,
|
||||
name: name,
|
||||
input: input,
|
||||
output: output,
|
||||
layout: layout,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets access to an entry point contained in this module.
|
||||
///
|
||||
/// This is purely a *logical* operation. It returns a struct that *represents* the entry
|
||||
/// point but doesn't actually do anything.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// - The user must check that the entry point exists in the module, as this is not checked
|
||||
/// by Vulkan.
|
||||
/// - The input, output and layout must correctly describe the input, output and layout used
|
||||
/// by this stage.
|
||||
///
|
||||
pub unsafe fn tess_control_shader_entry_point<'a, S, I, O, L>(
|
||||
&'a self, name: &'a CStr, input: I, output: O, layout: L)
|
||||
-> TessControlShaderEntryPoint<'a, S, I, O, L, P> {
|
||||
TessControlShaderEntryPoint {
|
||||
module: self,
|
||||
name: name,
|
||||
layout: layout,
|
||||
input: input,
|
||||
output: output,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets access to an entry point contained in this module.
|
||||
///
|
||||
/// This is purely a *logical* operation. It returns a struct that *represents* the entry
|
||||
/// point but doesn't actually do anything.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// - The user must check that the entry point exists in the module, as this is not checked
|
||||
/// by Vulkan.
|
||||
/// - The input, output and layout must correctly describe the input, output and layout used
|
||||
/// by this stage.
|
||||
///
|
||||
pub unsafe fn tess_evaluation_shader_entry_point<'a, S, I, O, L>(
|
||||
&'a self, name: &'a CStr, input: I, output: O, layout: L)
|
||||
-> TessEvaluationShaderEntryPoint<'a, S, I, O, L, P> {
|
||||
TessEvaluationShaderEntryPoint {
|
||||
module: self,
|
||||
name: name,
|
||||
layout: layout,
|
||||
input: input,
|
||||
output: output,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets access to an entry point contained in this module.
|
||||
///
|
||||
/// This is purely a *logical* operation. It returns a struct that *represents* the entry
|
||||
/// point but doesn't actually do anything.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// - The user must check that the entry point exists in the module, as this is not checked
|
||||
/// by Vulkan.
|
||||
/// - The input, output and layout must correctly describe the input, output and layout used
|
||||
/// by this stage.
|
||||
///
|
||||
pub unsafe fn geometry_shader_entry_point<'a, S, I, O, L>(
|
||||
&'a self, name: &'a CStr, primitives: GeometryShaderExecutionMode, input: I, output: O,
|
||||
layout: L)
|
||||
-> GeometryShaderEntryPoint<'a, S, I, O, L, P> {
|
||||
GeometryShaderEntryPoint {
|
||||
module: self,
|
||||
name: name,
|
||||
layout: layout,
|
||||
primitives: primitives,
|
||||
input: input,
|
||||
output: output,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets access to an entry point contained in this module.
|
||||
///
|
||||
/// This is purely a *logical* operation. It returns a struct that *represents* the entry
|
||||
/// point but doesn't actually do anything.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// - The user must check that the entry point exists in the module, as this is not checked
|
||||
/// by Vulkan.
|
||||
/// - The input, output and layout must correctly describe the input, output and layout used
|
||||
/// by this stage.
|
||||
///
|
||||
pub unsafe fn fragment_shader_entry_point<'a, S, I, O, L>(
|
||||
&'a self, name: &'a CStr, input: I, output: O, layout: L)
|
||||
-> FragmentShaderEntryPoint<'a, S, I, O, L, P> {
|
||||
FragmentShaderEntryPoint {
|
||||
module: self,
|
||||
name: name,
|
||||
layout: layout,
|
||||
input: input,
|
||||
output: output,
|
||||
ty: ty,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
@ -230,9 +127,9 @@ impl<P> ShaderModule<P>
|
||||
/// - The layout must correctly describe the layout used by this stage.
|
||||
///
|
||||
#[inline]
|
||||
pub unsafe fn compute_shader_entry_point<'a, S, L>(&'a self, name: &'a CStr, layout: L)
|
||||
-> ComputeShaderEntryPoint<'a, S, L, P> {
|
||||
ComputeShaderEntryPoint {
|
||||
pub unsafe fn compute_entry_point<'a, S, L>(&'a self, name: &'a CStr, layout: L)
|
||||
-> ComputeEntryPoint<'a, S, L> {
|
||||
ComputeEntryPoint {
|
||||
module: self,
|
||||
name: name,
|
||||
layout: layout,
|
||||
@ -241,9 +138,7 @@ impl<P> ShaderModule<P>
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<P> VulkanObject for ShaderModule<P>
|
||||
where P: SafeDeref<Target = Device>
|
||||
{
|
||||
unsafe impl VulkanObject for ShaderModule {
|
||||
type Object = vk::ShaderModule;
|
||||
|
||||
#[inline]
|
||||
@ -252,9 +147,7 @@ unsafe impl<P> VulkanObject for ShaderModule<P>
|
||||
}
|
||||
}
|
||||
|
||||
impl<P> Drop for ShaderModule<P>
|
||||
where P: SafeDeref<Target = Device>
|
||||
{
|
||||
impl Drop for ShaderModule {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
@ -264,213 +157,95 @@ impl<P> Drop for ShaderModule<P>
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the entry point of a vertex shader in a shader module.
|
||||
pub unsafe trait GraphicsEntryPointAbstract: EntryPointAbstract {
|
||||
type InputDefinition: ShaderInterfaceDef;
|
||||
type OutputDefinition: ShaderInterfaceDef;
|
||||
|
||||
/// Returns the input attributes used by the shader stage.
|
||||
fn input(&self) -> &Self::InputDefinition;
|
||||
|
||||
/// Returns the output attributes used by the shader stage.
|
||||
fn output(&self) -> &Self::OutputDefinition;
|
||||
|
||||
/// Returns the type of shader.
|
||||
fn ty(&self) -> GraphicsShaderType;
|
||||
}
|
||||
|
||||
/// Represents a shader entry point in a shader module.
|
||||
///
|
||||
/// Can be obtained by calling `vertex_shader_entry_point()` on the shader module.
|
||||
/// Can be obtained by calling `entry_point()` on the shader module.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct VertexShaderEntryPoint<'a, S, I, O, L, P = Arc<Device>>
|
||||
where P: 'a + SafeDeref<Target = Device>
|
||||
{
|
||||
module: &'a ShaderModule<P>,
|
||||
pub struct GraphicsEntryPoint<'a, S, I, O, L> {
|
||||
module: &'a ShaderModule,
|
||||
name: &'a CStr,
|
||||
input: I,
|
||||
layout: L,
|
||||
output: O,
|
||||
ty: GraphicsShaderType,
|
||||
marker: PhantomData<S>,
|
||||
}
|
||||
|
||||
impl<'a, S, I, O, L, P> VertexShaderEntryPoint<'a, S, I, O, L, P>
|
||||
where P: 'a + SafeDeref<Target = Device>
|
||||
unsafe impl<'a, S, I, O, L> EntryPointAbstract for GraphicsEntryPoint<'a, S, I, O, L>
|
||||
where L: PipelineLayoutDescNames,
|
||||
I: ShaderInterfaceDef,
|
||||
O: ShaderInterfaceDef,
|
||||
S: SpecializationConstants,
|
||||
{
|
||||
/// Returns the module this entry point comes from.
|
||||
type PipelineLayout = L;
|
||||
type SpecializationConstants = S;
|
||||
|
||||
#[inline]
|
||||
pub fn module(&self) -> &'a ShaderModule<P> {
|
||||
fn module(&self) -> &ShaderModule {
|
||||
self.module
|
||||
}
|
||||
|
||||
/// Returns the name of the entry point.
|
||||
#[inline]
|
||||
pub fn name(&self) -> &'a CStr {
|
||||
fn name(&self) -> &CStr {
|
||||
self.name
|
||||
}
|
||||
|
||||
/// Returns the pipeline layout used by the shader stage.
|
||||
#[inline]
|
||||
pub fn layout(&self) -> &L {
|
||||
fn layout(&self) -> &L {
|
||||
&self.layout
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<'a, S, I, O, L> GraphicsEntryPointAbstract for GraphicsEntryPoint<'a, S, I, O, L>
|
||||
where L: PipelineLayoutDescNames,
|
||||
I: ShaderInterfaceDef,
|
||||
O: ShaderInterfaceDef,
|
||||
S: SpecializationConstants,
|
||||
{
|
||||
type InputDefinition = I;
|
||||
type OutputDefinition = O;
|
||||
|
||||
/// Returns the input attributes used by the shader stage.
|
||||
// TODO: rename "input" for consistency
|
||||
#[inline]
|
||||
pub fn input_definition(&self) -> &I {
|
||||
fn input(&self) -> &I {
|
||||
&self.input
|
||||
}
|
||||
|
||||
/// Returns the output attributes used by the shader stage.
|
||||
#[inline]
|
||||
pub fn output(&self) -> &O {
|
||||
fn output(&self) -> &O {
|
||||
&self.output
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the entry point of a tessellation control shader in a shader module.
|
||||
///
|
||||
/// Can be obtained by calling `tess_control_shader_entry_point()` on the shader module.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct TessControlShaderEntryPoint<'a, S, I, O, L, P = Arc<Device>>
|
||||
where P: 'a + SafeDeref<Target = Device>
|
||||
{
|
||||
module: &'a ShaderModule<P>,
|
||||
name: &'a CStr,
|
||||
layout: L,
|
||||
input: I,
|
||||
output: O,
|
||||
marker: PhantomData<S>,
|
||||
}
|
||||
|
||||
impl<'a, S, I, O, L, P> TessControlShaderEntryPoint<'a, S, I, O, L, P>
|
||||
where P: 'a + SafeDeref<Target = Device>
|
||||
{
|
||||
/// Returns the module this entry point comes from.
|
||||
#[inline]
|
||||
pub fn module(&self) -> &'a ShaderModule<P> {
|
||||
self.module
|
||||
}
|
||||
|
||||
/// Returns the name of the entry point.
|
||||
#[inline]
|
||||
pub fn name(&self) -> &'a CStr {
|
||||
self.name
|
||||
}
|
||||
|
||||
/// Returns the pipeline layout used by the shader stage.
|
||||
#[inline]
|
||||
pub fn layout(&self) -> &L {
|
||||
&self.layout
|
||||
}
|
||||
|
||||
/// Returns the input attributes used by the shader stage.
|
||||
#[inline]
|
||||
pub fn input(&self) -> &I {
|
||||
&self.input
|
||||
}
|
||||
|
||||
/// Returns the output attributes used by the shader stage.
|
||||
#[inline]
|
||||
pub fn output(&self) -> &O {
|
||||
&self.output
|
||||
fn ty(&self) -> GraphicsShaderType {
|
||||
self.ty
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the entry point of a tessellation evaluation shader in a shader module.
|
||||
///
|
||||
/// Can be obtained by calling `tess_evaluation_shader_entry_point()` on the shader module.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct TessEvaluationShaderEntryPoint<'a, S, I, O, L, P = Arc<Device>>
|
||||
where P: 'a + SafeDeref<Target = Device>
|
||||
{
|
||||
module: &'a ShaderModule<P>,
|
||||
name: &'a CStr,
|
||||
layout: L,
|
||||
input: I,
|
||||
output: O,
|
||||
marker: PhantomData<S>,
|
||||
}
|
||||
|
||||
impl<'a, S, I, O, L, P> TessEvaluationShaderEntryPoint<'a, S, I, O, L, P>
|
||||
where P: 'a + SafeDeref<Target = Device>
|
||||
{
|
||||
/// Returns the module this entry point comes from.
|
||||
#[inline]
|
||||
pub fn module(&self) -> &'a ShaderModule<P> {
|
||||
self.module
|
||||
}
|
||||
|
||||
/// Returns the name of the entry point.
|
||||
#[inline]
|
||||
pub fn name(&self) -> &'a CStr {
|
||||
self.name
|
||||
}
|
||||
|
||||
/// Returns the pipeline layout used by the shader stage.
|
||||
#[inline]
|
||||
pub fn layout(&self) -> &L {
|
||||
&self.layout
|
||||
}
|
||||
|
||||
/// Returns the input attributes used by the shader stage.
|
||||
#[inline]
|
||||
pub fn input(&self) -> &I {
|
||||
&self.input
|
||||
}
|
||||
|
||||
/// Returns the output attributes used by the shader stage.
|
||||
#[inline]
|
||||
pub fn output(&self) -> &O {
|
||||
&self.output
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the entry point of a geometry shader in a shader module.
|
||||
///
|
||||
/// Can be obtained by calling `geometry_shader_entry_point()` on the shader module.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct GeometryShaderEntryPoint<'a, S, I, O, L, P = Arc<Device>>
|
||||
where P: 'a + SafeDeref<Target = Device>
|
||||
{
|
||||
module: &'a ShaderModule<P>,
|
||||
name: &'a CStr,
|
||||
layout: L,
|
||||
primitives: GeometryShaderExecutionMode,
|
||||
input: I,
|
||||
output: O,
|
||||
marker: PhantomData<S>,
|
||||
}
|
||||
|
||||
impl<'a, S, I, O, L, P> GeometryShaderEntryPoint<'a, S, I, O, L, P>
|
||||
where P: 'a + SafeDeref<Target = Device>
|
||||
{
|
||||
/// Returns the module this entry point comes from.
|
||||
#[inline]
|
||||
pub fn module(&self) -> &'a ShaderModule<P> {
|
||||
self.module
|
||||
}
|
||||
|
||||
/// Returns the name of the entry point.
|
||||
#[inline]
|
||||
pub fn name(&self) -> &'a CStr {
|
||||
self.name
|
||||
}
|
||||
|
||||
/// Returns the kind of primitives expected by the geometry shader.
|
||||
#[inline]
|
||||
pub fn primitives(&self) -> GeometryShaderExecutionMode {
|
||||
self.primitives
|
||||
}
|
||||
|
||||
/// Returns the pipeline layout used by the shader stage.
|
||||
#[inline]
|
||||
pub fn layout(&self) -> &L {
|
||||
&self.layout
|
||||
}
|
||||
|
||||
/// Returns the input attributes used by the shader stage.
|
||||
#[inline]
|
||||
pub fn input(&self) -> &I {
|
||||
&self.input
|
||||
}
|
||||
|
||||
/// Returns the output attributes used by the shader stage.
|
||||
#[inline]
|
||||
pub fn output(&self) -> &O {
|
||||
&self.output
|
||||
}
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum GraphicsShaderType {
|
||||
Vertex,
|
||||
TessellationControl,
|
||||
TessellationEvaluation,
|
||||
Geometry(GeometryShaderExecutionMode),
|
||||
Fragment,
|
||||
}
|
||||
|
||||
/// Declares which type of primitives are expected by the geometry shader.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
#[doc(hidden)]
|
||||
pub enum GeometryShaderExecutionMode {
|
||||
Points,
|
||||
Lines,
|
||||
@ -503,90 +278,105 @@ impl GeometryShaderExecutionMode {
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the entry point of a fragment shader in a shader module.
|
||||
///
|
||||
/// Can be obtained by calling `fragment_shader_entry_point()` on the shader module.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct FragmentShaderEntryPoint<'a, S, I, O, L, P = Arc<Device>>
|
||||
where P: 'a + SafeDeref<Target = Device>
|
||||
{
|
||||
module: &'a ShaderModule<P>,
|
||||
name: &'a CStr,
|
||||
layout: L,
|
||||
input: I,
|
||||
output: O,
|
||||
marker: PhantomData<S>,
|
||||
}
|
||||
pub unsafe trait EntryPointAbstract {
|
||||
type PipelineLayout: PipelineLayoutDescNames;
|
||||
type SpecializationConstants: SpecializationConstants;
|
||||
|
||||
impl<'a, S, I, O, L, P> FragmentShaderEntryPoint<'a, S, I, O, L, P>
|
||||
where P: 'a + SafeDeref<Target = Device>
|
||||
{
|
||||
/// Returns the module this entry point comes from.
|
||||
#[inline]
|
||||
pub fn module(&self) -> &'a ShaderModule<P> {
|
||||
self.module
|
||||
}
|
||||
fn module(&self) -> &ShaderModule;
|
||||
|
||||
/// Returns the name of the entry point.
|
||||
#[inline]
|
||||
pub fn name(&self) -> &'a CStr {
|
||||
self.name
|
||||
}
|
||||
fn name(&self) -> &CStr;
|
||||
|
||||
/// Returns the pipeline layout used by the shader stage.
|
||||
#[inline]
|
||||
pub fn layout(&self) -> &L {
|
||||
&self.layout
|
||||
}
|
||||
|
||||
/// Returns the input attributes used by the shader stage.
|
||||
#[inline]
|
||||
pub fn input(&self) -> &I {
|
||||
&self.input
|
||||
}
|
||||
|
||||
/// Returns the output attributes used by the shader stage.
|
||||
#[inline]
|
||||
pub fn output(&self) -> &O {
|
||||
&self.output
|
||||
}
|
||||
fn layout(&self) -> &Self::PipelineLayout;
|
||||
}
|
||||
|
||||
/// Represents the entry point of a compute shader in a shader module.
|
||||
///
|
||||
/// Can be obtained by calling `compute_shader_entry_point()` on the shader module.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct ComputeShaderEntryPoint<'a, S, L, P = Arc<Device>>
|
||||
where P: 'a + SafeDeref<Target = Device>
|
||||
{
|
||||
module: &'a ShaderModule<P>,
|
||||
pub struct ComputeEntryPoint<'a, S, L> {
|
||||
module: &'a ShaderModule,
|
||||
name: &'a CStr,
|
||||
layout: L,
|
||||
marker: PhantomData<S>,
|
||||
}
|
||||
|
||||
impl<'a, S, L, P> ComputeShaderEntryPoint<'a, S, L, P>
|
||||
where P: 'a + SafeDeref<Target = Device>
|
||||
unsafe impl<'a, S, L> EntryPointAbstract for ComputeEntryPoint<'a, S, L>
|
||||
where L: PipelineLayoutDescNames,
|
||||
S: SpecializationConstants,
|
||||
{
|
||||
/// Returns the module this entry point comes from.
|
||||
type PipelineLayout = L;
|
||||
type SpecializationConstants = S;
|
||||
|
||||
#[inline]
|
||||
pub fn module(&self) -> &'a ShaderModule<P> {
|
||||
fn module(&self) -> &ShaderModule {
|
||||
self.module
|
||||
}
|
||||
|
||||
/// Returns the name of the entry point.
|
||||
#[inline]
|
||||
pub fn name(&self) -> &'a CStr {
|
||||
fn name(&self) -> &CStr {
|
||||
self.name
|
||||
}
|
||||
|
||||
/// Returns the pipeline layout used by the shader stage.
|
||||
#[inline]
|
||||
pub fn layout(&self) -> &L {
|
||||
fn layout(&self) -> &L {
|
||||
&self.layout
|
||||
}
|
||||
}
|
||||
|
||||
/// A dummy that implements `GraphicsEntryPointAbstract` and `EntryPointAbstract`.
|
||||
///
|
||||
/// When a function has a signature like: `fn foo<S: EntryPointAbstract>(shader: Option<S>)`, you
|
||||
/// can pass `None::<EmptyEntryPointDummy>`.
|
||||
///
|
||||
/// This object is meant to be a replacement to `!` before it is stabilized.
|
||||
// TODO: ^
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum EmptyEntryPointDummy {
|
||||
}
|
||||
|
||||
unsafe impl EntryPointAbstract for EmptyEntryPointDummy {
|
||||
type PipelineLayout = EmptyPipelineDesc;
|
||||
type SpecializationConstants = ();
|
||||
|
||||
#[inline]
|
||||
fn module(&self) -> &ShaderModule {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn name(&self) -> &CStr {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn layout(&self) -> &EmptyPipelineDesc {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl GraphicsEntryPointAbstract for EmptyEntryPointDummy {
|
||||
type InputDefinition = EmptyShaderInterfaceDef;
|
||||
type OutputDefinition = EmptyShaderInterfaceDef;
|
||||
|
||||
#[inline]
|
||||
fn input(&self) -> &EmptyShaderInterfaceDef {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn output(&self) -> &EmptyShaderInterfaceDef {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn ty(&self) -> GraphicsShaderType {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
/// Types that contain the definition of an interface between two shader stages, or between
|
||||
/// the outside and a shader stage.
|
||||
///
|
||||
|
Loading…
Reference in New Issue
Block a user