add pipeline constants plumbing

This commit is contained in:
teoxoy 2023-11-13 17:48:24 +01:00 committed by Teodor Tanasoaia
parent fb305b85f6
commit 3bda381812
67 changed files with 214 additions and 21 deletions

View File

@ -8,6 +8,7 @@ use deno_core::ResourceId;
use serde::Deserialize;
use serde::Serialize;
use std::borrow::Cow;
use std::collections::HashMap;
use std::rc::Rc;
use super::error::WebGpuError;
@ -75,7 +76,7 @@ pub enum GPUPipelineLayoutOrGPUAutoLayoutMode {
pub struct GpuProgrammableStage {
module: ResourceId,
entry_point: Option<String>,
// constants: HashMap<String, GPUPipelineConstantValue>
constants: HashMap<String, f64>,
}
#[op2]
@ -111,7 +112,7 @@ pub fn op_webgpu_create_compute_pipeline(
stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
module: compute_shader_module_resource.1,
entry_point: compute.entry_point.map(Cow::from),
// TODO(lucacasonato): support args.compute.constants
constants: Cow::Owned(compute.constants),
},
};
let implicit_pipelines = match layout {
@ -279,6 +280,7 @@ impl<'a> From<GpuVertexBufferLayout> for wgpu_core::pipeline::VertexBufferLayout
struct GpuVertexState {
module: ResourceId,
entry_point: String,
constants: HashMap<String, f64>,
buffers: Vec<Option<GpuVertexBufferLayout>>,
}
@ -306,7 +308,7 @@ struct GpuFragmentState {
targets: Vec<Option<wgpu_types::ColorTargetState>>,
module: u32,
entry_point: String,
// TODO(lucacasonato): constants
constants: HashMap<String, f64>,
}
#[derive(Deserialize)]
@ -356,8 +358,9 @@ pub fn op_webgpu_create_render_pipeline(
stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
module: fragment_shader_module_resource.1,
entry_point: Some(Cow::from(fragment.entry_point)),
constants: Cow::Owned(fragment.constants),
},
targets: Cow::from(fragment.targets),
targets: Cow::Owned(fragment.targets),
})
} else {
None
@ -378,6 +381,7 @@ pub fn op_webgpu_create_render_pipeline(
stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
module: vertex_shader_module_resource.1,
entry_point: Some(Cow::Owned(args.vertex.entry_point)),
constants: Cow::Owned(args.vertex.constants),
},
buffers: Cow::Owned(vertex_buffers),
},

View File

@ -132,6 +132,7 @@ impl crate::framework::Example for Example {
vertex: wgpu::VertexState {
module: &draw_shader,
entry_point: "main_vs",
constants: &Default::default(),
buffers: &[
wgpu::VertexBufferLayout {
array_stride: 4 * 4,
@ -148,6 +149,7 @@ impl crate::framework::Example for Example {
fragment: Some(wgpu::FragmentState {
module: &draw_shader,
entry_point: "main_fs",
constants: &Default::default(),
targets: &[Some(config.view_formats[0].into())],
}),
primitive: wgpu::PrimitiveState::default(),
@ -163,6 +165,7 @@ impl crate::framework::Example for Example {
layout: Some(&compute_pipeline_layout),
module: &compute_shader,
entry_point: "main",
constants: &Default::default(),
});
// buffer for the three 2d triangle vertices of each instance

View File

@ -203,11 +203,13 @@ impl crate::framework::Example for Example {
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &[],
},
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(wgpu::ColorTargetState {
format: config.view_formats[0],
blend: Some(wgpu::BlendState::ALPHA_BLENDING),

View File

@ -97,11 +97,13 @@ impl crate::framework::Example for Example {
vertex: wgpu::VertexState {
module: &shader_triangle_and_lines,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &[],
},
fragment: Some(wgpu::FragmentState {
module: &shader_triangle_and_lines,
entry_point: "fs_main_red",
constants: &Default::default(),
targets: &[Some(RENDER_TARGET_FORMAT.into())],
}),
primitive: wgpu::PrimitiveState {
@ -120,11 +122,13 @@ impl crate::framework::Example for Example {
vertex: wgpu::VertexState {
module: &shader_triangle_and_lines,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &[],
},
fragment: Some(wgpu::FragmentState {
module: &shader_triangle_and_lines,
entry_point: "fs_main_blue",
constants: &Default::default(),
targets: &[Some(RENDER_TARGET_FORMAT.into())],
}),
primitive: wgpu::PrimitiveState::default(),
@ -144,11 +148,13 @@ impl crate::framework::Example for Example {
vertex: wgpu::VertexState {
module: &shader_triangle_and_lines,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &[],
},
fragment: Some(wgpu::FragmentState {
module: &shader_triangle_and_lines,
entry_point: "fs_main_white",
constants: &Default::default(),
targets: &[Some(config.view_formats[0].into())],
}),
primitive: wgpu::PrimitiveState {
@ -205,11 +211,13 @@ impl crate::framework::Example for Example {
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &[],
},
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(config.view_formats[0].into())],
}),
primitive: wgpu::PrimitiveState::default(),

View File

@ -244,11 +244,13 @@ impl crate::framework::Example for Example {
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &vertex_buffers,
},
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(config.view_formats[0].into())],
}),
primitive: wgpu::PrimitiveState {
@ -270,11 +272,13 @@ impl crate::framework::Example for Example {
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &vertex_buffers,
},
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: "fs_wire",
constants: &Default::default(),
targets: &[Some(wgpu::ColorTargetState {
format: config.view_formats[0],
blend: Some(wgpu::BlendState {

View File

@ -109,6 +109,7 @@ async fn execute_gpu_inner(
layout: None,
module: &cs_module,
entry_point: "main",
constants: &Default::default(),
});
// Instantiates the bind group, once again specifying the binding of buffers.

View File

@ -103,12 +103,14 @@ async fn execute(
layout: Some(&pipeline_layout),
module: &shaders_module,
entry_point: "patient_main",
constants: &Default::default(),
});
let hasty_pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor {
label: None,
layout: Some(&pipeline_layout),
module: &shaders_module,
entry_point: "hasty_main",
constants: &Default::default(),
});
//----------------------------------------------------------

View File

@ -60,10 +60,12 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
module: &shader,
entry_point: "vs_main",
buffers: &[],
constants: &Default::default(),
},
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(swapchain_format.into())],
}),
primitive: wgpu::PrimitiveState::default(),

View File

@ -110,6 +110,7 @@ async fn run() {
layout: Some(&pipeline_layout),
module: &shader,
entry_point: "main",
constants: &Default::default(),
});
//----------------------------------------------------------

View File

@ -93,11 +93,13 @@ impl Example {
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &[],
},
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(TEXTURE_FORMAT.into())],
}),
primitive: wgpu::PrimitiveState {
@ -290,11 +292,13 @@ impl crate::framework::Example for Example {
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &[],
},
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(config.view_formats[0].into())],
}),
primitive: wgpu::PrimitiveState {

View File

@ -54,6 +54,7 @@ impl Example {
vertex: wgpu::VertexState {
module: shader,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &[wgpu::VertexBufferLayout {
array_stride: std::mem::size_of::<Vertex>() as wgpu::BufferAddress,
step_mode: wgpu::VertexStepMode::Vertex,
@ -63,6 +64,7 @@ impl Example {
fragment: Some(wgpu::FragmentState {
module: shader,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(config.view_formats[0].into())],
}),
primitive: wgpu::PrimitiveState {

View File

@ -59,11 +59,13 @@ async fn run(_path: Option<String>) {
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &[],
},
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(wgpu::TextureFormat::Rgba8UnormSrgb.into())],
}),
primitive: wgpu::PrimitiveState::default(),

View File

@ -245,6 +245,7 @@ impl WgpuContext {
layout: Some(&pipeline_layout),
module: &shader,
entry_point: "main",
constants: &Default::default(),
});
WgpuContext {

View File

@ -500,6 +500,7 @@ impl crate::framework::Example for Example {
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_bake",
constants: &Default::default(),
buffers: &[vb_desc.clone()],
},
fragment: None,
@ -632,6 +633,7 @@ impl crate::framework::Example for Example {
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &[vb_desc],
},
fragment: Some(wgpu::FragmentState {
@ -641,6 +643,7 @@ impl crate::framework::Example for Example {
} else {
"fs_main_without_storage"
},
constants: &Default::default(),
targets: &[Some(config.view_formats[0].into())],
}),
primitive: wgpu::PrimitiveState {

View File

@ -199,11 +199,13 @@ impl crate::framework::Example for Example {
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_sky",
constants: &Default::default(),
buffers: &[],
},
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: "fs_sky",
constants: &Default::default(),
targets: &[Some(config.view_formats[0].into())],
}),
primitive: wgpu::PrimitiveState {
@ -226,6 +228,7 @@ impl crate::framework::Example for Example {
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_entity",
constants: &Default::default(),
buffers: &[wgpu::VertexBufferLayout {
array_stride: std::mem::size_of::<Vertex>() as wgpu::BufferAddress,
step_mode: wgpu::VertexStepMode::Vertex,
@ -235,6 +238,7 @@ impl crate::framework::Example for Example {
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: "fs_entity",
constants: &Default::default(),
targets: &[Some(config.view_formats[0].into())],
}),
primitive: wgpu::PrimitiveState {

View File

@ -131,11 +131,13 @@ impl<const SRGB: bool> crate::framework::Example for Example<SRGB> {
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &vertex_buffers,
},
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(wgpu::ColorTargetState {
format: config.view_formats[0],
blend: Some(wgpu::BlendState::ALPHA_BLENDING),

View File

@ -74,11 +74,13 @@ impl crate::framework::Example for Example {
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &vertex_buffers,
},
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(wgpu::ColorTargetState {
format: config.view_formats[0],
blend: None,
@ -112,11 +114,13 @@ impl crate::framework::Example for Example {
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &vertex_buffers,
},
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(config.view_formats[0].into())],
}),
primitive: Default::default(),

View File

@ -100,6 +100,7 @@ async fn run(_path: Option<String>) {
layout: Some(&pipeline_layout),
module: &shader,
entry_point: "main",
constants: &Default::default(),
});
log::info!("Wgpu context set up.");

View File

@ -321,6 +321,7 @@ impl crate::framework::Example for Example {
vertex: wgpu::VertexState {
module: &base_shader_module,
entry_point: "vert_main",
constants: &Default::default(),
buffers: &[wgpu::VertexBufferLayout {
array_stride: vertex_size as wgpu::BufferAddress,
step_mode: wgpu::VertexStepMode::Vertex,
@ -330,6 +331,7 @@ impl crate::framework::Example for Example {
fragment: Some(wgpu::FragmentState {
module: fragment_shader_module,
entry_point: fragment_entry_point,
constants: &Default::default(),
targets: &[Some(config.view_formats[0].into())],
}),
primitive: wgpu::PrimitiveState {

View File

@ -298,6 +298,7 @@ fn compute_pass(
layout: None,
module,
entry_point: "main_cs",
constants: &Default::default(),
});
let bind_group_layout = compute_pipeline.get_bind_group_layout(0);
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
@ -352,11 +353,13 @@ fn render_pass(
vertex: wgpu::VertexState {
module,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &[],
},
fragment: Some(wgpu::FragmentState {
module,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(format.into())],
}),
primitive: wgpu::PrimitiveState::default(),

View File

@ -179,11 +179,13 @@ impl WgpuContext {
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &[],
},
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(swapchain_format.into())],
}),
primitive: wgpu::PrimitiveState::default(),

View File

@ -512,6 +512,7 @@ impl crate::framework::Example for Example {
vertex: wgpu::VertexState {
module: &water_module,
entry_point: "vs_main",
constants: &Default::default(),
// Layout of our vertices. This should match the structs
// which are uploaded to the GPU. This should also be
// ensured by tagging on either a `#[repr(C)]` onto a
@ -527,6 +528,7 @@ impl crate::framework::Example for Example {
fragment: Some(wgpu::FragmentState {
module: &water_module,
entry_point: "fs_main",
constants: &Default::default(),
// Describes how the colour will be interpolated
// and assigned to the output attachment.
targets: &[Some(wgpu::ColorTargetState {
@ -581,6 +583,7 @@ impl crate::framework::Example for Example {
vertex: wgpu::VertexState {
module: &terrain_module,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &[wgpu::VertexBufferLayout {
array_stride: terrain_vertex_size as wgpu::BufferAddress,
step_mode: wgpu::VertexStepMode::Vertex,
@ -590,6 +593,7 @@ impl crate::framework::Example for Example {
fragment: Some(wgpu::FragmentState {
module: &terrain_module,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(config.view_formats[0].into())],
}),
primitive: wgpu::PrimitiveState {

View File

@ -593,6 +593,7 @@ fn write_output(
pipeline_options_owned = spv::PipelineOptions {
entry_point: name.clone(),
shader_stage: module.entry_points[ep_index].stage,
constants: naga::back::PipelineConstants::default(),
};
Some(&pipeline_options_owned)
}
@ -633,6 +634,7 @@ fn write_output(
_ => unreachable!(),
},
multiview: None,
constants: naga::back::PipelineConstants::default(),
};
let mut buffer = String::new();
@ -668,6 +670,7 @@ fn write_output(
"Generating hlsl output requires validation to \
succeed, and it failed in a previous step",
))?,
&hlsl::PipelineOptions::default(),
)
.unwrap_pretty();
fs::write(output_path, buffer)?;

View File

@ -193,6 +193,7 @@ fn backends(c: &mut Criterion) {
let pipeline_options = naga::back::spv::PipelineOptions {
shader_stage: ep.stage,
entry_point: ep.name.clone(),
constants: naga::back::PipelineConstants::default(),
};
writer
.write(module, info, Some(&pipeline_options), &None, &mut data)
@ -223,10 +224,11 @@ fn backends(c: &mut Criterion) {
group.bench_function("hlsl", |b| {
b.iter(|| {
let options = naga::back::hlsl::Options::default();
let pipeline_options = naga::back::hlsl::PipelineOptions::default();
let mut string = String::new();
for &(ref module, ref info) in inputs.iter() {
let mut writer = naga::back::hlsl::Writer::new(&mut string, &options);
let _ = writer.write(module, info); // may fail on unimplemented things
let _ = writer.write(module, info, &pipeline_options); // may fail on unimplemented things
string.clear();
}
});
@ -248,6 +250,7 @@ fn backends(c: &mut Criterion) {
shader_stage: ep.stage,
entry_point: ep.name.clone(),
multiview: None,
constants: naga::back::PipelineConstants::default(),
};
// might be `Err` if missing features

View File

@ -282,7 +282,7 @@ impl Default for Options {
}
/// A subset of options meant to be changed per pipeline.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
pub struct PipelineOptions {
@ -294,6 +294,8 @@ pub struct PipelineOptions {
pub entry_point: String,
/// How many views to render to, if doing multiview rendering.
pub multiview: Option<std::num::NonZeroU32>,
/// Pipeline constants.
pub constants: back::PipelineConstants,
}
#[derive(Debug)]

View File

@ -195,6 +195,14 @@ pub struct Options {
pub zero_initialize_workgroup_memory: bool,
}
#[derive(Clone, Debug, Default)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
pub struct PipelineOptions {
/// Pipeline constants.
pub constants: back::PipelineConstants,
}
impl Default for Options {
fn default() -> Self {
Options {

View File

@ -1,7 +1,7 @@
use super::{
help::{WrappedArrayLength, WrappedConstructor, WrappedImageQuery, WrappedStructMatrixAccess},
storage::StoreValue,
BackendResult, Error, Options,
BackendResult, Error, Options, PipelineOptions,
};
use crate::{
back,
@ -167,6 +167,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
&mut self,
module: &Module,
module_info: &valid::ModuleInfo,
_pipeline_options: &PipelineOptions,
) -> Result<super::ReflectionInfo, Error> {
self.reset(module);

View File

@ -26,6 +26,15 @@ pub const BAKE_PREFIX: &str = "_e";
/// Expressions that need baking.
pub type NeedBakeExpressions = crate::FastHashSet<crate::Handle<crate::Expression>>;
/// Specifies the values of pipeline-overridable constants in the shader module.
///
/// If an `@id` attribute was specified on the declaration,
/// the key must be the pipeline constant ID as a decimal ASCII number; if not,
/// the key must be the constant's identifier name.
///
/// The value may represent any of WGSL's concrete scalar types.
pub type PipelineConstants = std::collections::HashMap<String, f64>;
/// Indentation level.
#[derive(Clone, Copy)]
pub struct Level(pub usize);

View File

@ -221,7 +221,7 @@ impl Default for Options {
}
/// A subset of options that are meant to be changed per pipeline.
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Default, Clone)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
pub struct PipelineOptions {
@ -232,6 +232,8 @@ pub struct PipelineOptions {
///
/// Enable this for vertex shaders with point primitive topologies.
pub allow_and_force_point_size: bool,
/// Pipeline constants.
pub constants: crate::back::PipelineConstants,
}
impl Options {

View File

@ -725,7 +725,7 @@ impl<'a> Default for Options<'a> {
}
// A subset of options meant to be changed per pipeline.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
pub struct PipelineOptions {
@ -735,6 +735,8 @@ pub struct PipelineOptions {
///
/// If no entry point that matches is found while creating a [`Writer`], a error will be thrown.
pub entry_point: String,
/// Pipeline constants.
pub constants: crate::back::PipelineConstants,
}
pub fn write_vec(

View File

@ -27,5 +27,6 @@
),
msl_pipeline: (
allow_and_force_point_size: true,
constants: {},
),
)

View File

@ -428,6 +428,7 @@ fn write_output_spv(
let pipeline_options = spv::PipelineOptions {
entry_point: ep.name.clone(),
shader_stage: ep.stage,
constants: naga::back::PipelineConstants::default(),
};
write_output_spv_inner(
input,
@ -516,6 +517,7 @@ fn write_output_glsl(
shader_stage: stage,
entry_point: ep_name.to_string(),
multiview,
constants: naga::back::PipelineConstants::default(),
};
let mut buffer = String::new();
@ -548,7 +550,9 @@ fn write_output_hlsl(
let mut buffer = String::new();
let mut writer = hlsl::Writer::new(&mut buffer, options);
let reflection_info = writer.write(module, info).expect("HLSL write failed");
let reflection_info = writer
.write(module, info, &hlsl::PipelineOptions::default())
.expect("HLSL write failed");
input.write_output_file("hlsl", "hlsl", buffer);

View File

@ -57,6 +57,7 @@
stage: (
module: Id(0, 1, Empty),
entry_point: None,
constants: {},
),
),
),

View File

@ -30,6 +30,7 @@
stage: (
module: Id(0, 1, Empty),
entry_point: None,
constants: {},
),
),
),

View File

@ -58,6 +58,7 @@
stage: (
module: Id(0, 1, Empty),
entry_point: None,
constants: {},
),
buffers: [],
),
@ -65,6 +66,7 @@
stage: (
module: Id(0, 1, Empty),
entry_point: None,
constants: {},
),
targets: [
Some((

View File

@ -134,6 +134,7 @@
stage: (
module: Id(0, 1, Empty),
entry_point: None,
constants: {},
),
),
),

View File

@ -135,6 +135,7 @@
stage: (
module: Id(0, 1, Empty),
entry_point: None,
constants: {},
),
),
),

View File

@ -369,6 +369,7 @@ fn copy_via_compute(
layout: Some(&pll),
module: &sm,
entry_point: "copy_texture_to_buffer",
constants: &Default::default(),
});
{

View File

@ -96,6 +96,7 @@ static BGRA8_UNORM_STORAGE: GpuTestConfiguration = GpuTestConfiguration::new()
label: None,
layout: Some(&pl),
entry_point: "main",
constants: &Default::default(),
module: &module,
});

View File

@ -90,6 +90,7 @@ async fn bgl_dedupe(ctx: TestingContext) {
layout: Some(&pipeline_layout),
module: &module,
entry_point: "no_resources",
constants: &Default::default(),
};
let pipeline = ctx.device.create_compute_pipeline(&desc);
@ -218,6 +219,7 @@ fn bgl_dedupe_with_dropped_user_handle(ctx: TestingContext) {
layout: Some(&pipeline_layout),
module: &module,
entry_point: "no_resources",
constants: &Default::default(),
});
let mut encoder = ctx.device.create_command_encoder(&Default::default());
@ -263,6 +265,7 @@ fn bgl_dedupe_derived(ctx: TestingContext) {
layout: None,
module: &module,
entry_point: "resources",
constants: &Default::default(),
});
// We create two bind groups, pulling the bind_group_layout from the pipeline each time.
@ -333,6 +336,7 @@ fn separate_programs_have_incompatible_derived_bgls(ctx: TestingContext) {
layout: None,
module: &module,
entry_point: "resources",
constants: &Default::default(),
};
// Create two pipelines, creating a BG from the second.
let pipeline1 = ctx.device.create_compute_pipeline(&desc);
@ -394,6 +398,7 @@ fn derived_bgls_incompatible_with_regular_bgls(ctx: TestingContext) {
layout: None,
module: &module,
entry_point: "resources",
constants: &Default::default(),
});
// Create a matching BGL

View File

@ -224,6 +224,7 @@ static MINIMUM_BUFFER_BINDING_SIZE_LAYOUT: GpuTestConfiguration = GpuTestConfigu
layout: Some(&pipeline_layout),
module: &shader_module,
entry_point: "main",
constants: &Default::default(),
});
});
});
@ -292,6 +293,7 @@ static MINIMUM_BUFFER_BINDING_SIZE_DISPATCH: GpuTestConfiguration = GpuTestConfi
layout: Some(&pipeline_layout),
module: &shader_module,
entry_point: "main",
constants: &Default::default(),
});
let buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor {

View File

@ -480,6 +480,7 @@ static DEVICE_DESTROY_THEN_MORE: GpuTestConfiguration = GpuTestConfiguration::ne
vertex: wgpu::VertexState {
module: &shader_module,
entry_point: "",
constants: &Default::default(),
buffers: &[],
},
primitive: wgpu::PrimitiveState::default(),
@ -498,6 +499,7 @@ static DEVICE_DESTROY_THEN_MORE: GpuTestConfiguration = GpuTestConfiguration::ne
layout: None,
module: &shader_module,
entry_point: "",
constants: &Default::default(),
});
});
@ -734,6 +736,7 @@ fn vs_main() -> @builtin(position) vec4<f32> {
fragment: Some(wgpu::FragmentState {
module: &trivial_shaders_with_some_reversed_bindings,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(wgt::ColorTargetState {
format: wgt::TextureFormat::Bgra8Unorm,
blend: None,
@ -747,6 +750,7 @@ fn vs_main() -> @builtin(position) vec4<f32> {
vertex: wgpu::VertexState {
module: &trivial_shaders_with_some_reversed_bindings,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &[],
},
primitive: wgt::PrimitiveState::default(),

View File

@ -95,15 +95,17 @@ async fn draw_test_with_reports(
layout: Some(&ppl),
vertex: wgpu::VertexState {
buffers: &[],
entry_point: "vs_main_builtin",
module: &shader,
entry_point: "vs_main_builtin",
constants: &Default::default(),
},
primitive: wgpu::PrimitiveState::default(),
depth_stencil: None,
multisample: wgpu::MultisampleState::default(),
fragment: Some(wgpu::FragmentState {
entry_point: "fs_main",
module: &shader,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba8Unorm,
blend: None,

View File

@ -24,11 +24,13 @@ static NV12_TEXTURE_CREATION_SAMPLING: GpuTestConfiguration = GpuTestConfigurati
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &[],
},
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(target_format.into())],
}),
primitive: wgpu::PrimitiveState {

View File

@ -37,6 +37,7 @@ static OCCLUSION_QUERY: GpuTestConfiguration = GpuTestConfiguration::new()
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &[],
},
fragment: None,

View File

@ -69,6 +69,7 @@ static PARTIALLY_BOUNDED_ARRAY: GpuTestConfiguration = GpuTestConfiguration::new
layout: Some(&pipeline_layout),
module: &cs_module,
entry_point: "main",
constants: &Default::default(),
});
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {

View File

@ -28,6 +28,7 @@ static PIPELINE_DEFAULT_LAYOUT_BAD_MODULE: GpuTestConfiguration = GpuTestConfigu
layout: None,
module: &module,
entry_point: "doesn't exist",
constants: &Default::default(),
});
pipeline.get_bind_group_layout(0);

View File

@ -103,6 +103,7 @@ async fn partial_update_test(ctx: TestingContext) {
layout: Some(&pipeline_layout),
module: &sm,
entry_point: "main",
constants: &Default::default(),
});
let mut encoder = ctx

View File

@ -102,11 +102,13 @@ async fn multi_stage_data_binding_test(ctx: TestingContext) {
vertex: wgpu::VertexState {
module: &vs_sm,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &[],
},
fragment: Some(wgpu::FragmentState {
module: &fs_sm,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba8Unorm,
blend: None,

View File

@ -52,6 +52,7 @@ static PASS_RESET_VERTEX_BUFFER: GpuTestConfiguration =
vertex: VertexState {
module: &module,
entry_point: "double_buffer_vert",
constants: &Default::default(),
buffers: &[
VertexBufferLayout {
array_stride: 16,
@ -71,6 +72,7 @@ static PASS_RESET_VERTEX_BUFFER: GpuTestConfiguration =
fragment: Some(FragmentState {
module: &module,
entry_point: "double_buffer_frag",
constants: &Default::default(),
targets: &[Some(ColorTargetState {
format: TextureFormat::Rgba8Unorm,
blend: None,
@ -88,6 +90,7 @@ static PASS_RESET_VERTEX_BUFFER: GpuTestConfiguration =
vertex: VertexState {
module: &module,
entry_point: "single_buffer_vert",
constants: &Default::default(),
buffers: &[VertexBufferLayout {
array_stride: 16,
step_mode: VertexStepMode::Vertex,
@ -100,6 +103,7 @@ static PASS_RESET_VERTEX_BUFFER: GpuTestConfiguration =
fragment: Some(FragmentState {
module: &module,
entry_point: "single_buffer_frag",
constants: &Default::default(),
targets: &[Some(ColorTargetState {
format: TextureFormat::Rgba8Unorm,
blend: None,

View File

@ -42,16 +42,18 @@ async fn scissor_test_impl(
label: Some("Pipeline"),
layout: None,
vertex: wgpu::VertexState {
entry_point: "vs_main",
module: &shader,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &[],
},
primitive: wgpu::PrimitiveState::default(),
depth_stencil: None,
multisample: wgpu::MultisampleState::default(),
fragment: Some(wgpu::FragmentState {
entry_point: "fs_main",
module: &shader,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba8Unorm,
blend: None,

View File

@ -307,6 +307,7 @@ async fn shader_input_output_test(
layout: Some(&pll),
module: &sm,
entry_point: "cs_main",
constants: &Default::default(),
});
// -- Initializing data --

View File

@ -87,6 +87,7 @@ static ZERO_INIT_WORKGROUP_MEMORY: GpuTestConfiguration = GpuTestConfiguration::
layout: Some(&pll),
module: &sm,
entry_point: "read",
constants: &Default::default(),
});
let pipeline_write = ctx
@ -96,6 +97,7 @@ static ZERO_INIT_WORKGROUP_MEMORY: GpuTestConfiguration = GpuTestConfiguration::
layout: None,
module: &sm,
entry_point: "write",
constants: &Default::default(),
});
// -- Initializing data --

View File

@ -120,6 +120,9 @@ async fn pulling_common(
label: None,
layout: None,
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &[wgpu::VertexBufferLayout {
array_stride: 8,
step_mode: wgpu::VertexStepMode::Vertex,
@ -129,15 +132,14 @@ async fn pulling_common(
shader_location: 0,
}],
}],
entry_point: "vs_main",
module: &shader,
},
primitive: wgpu::PrimitiveState::default(),
depth_stencil: None,
multisample: wgpu::MultisampleState::default(),
fragment: Some(wgpu::FragmentState {
entry_point: "fs_main",
module: &shader,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba8Unorm,
blend: None,

View File

@ -93,11 +93,13 @@ async fn reinterpret(
vertex: wgpu::VertexState {
module: shader,
entry_point: "vs_main",
constants: &Default::default(),
buffers: &[],
},
fragment: Some(wgpu::FragmentState {
module: shader,
entry_point: "fs_main",
constants: &Default::default(),
targets: &[Some(src_format.into())],
}),
primitive: wgpu::PrimitiveState {

View File

@ -272,20 +272,23 @@ async fn vertex_index_common(ctx: TestingContext) {
push_constant_ranges: &[],
});
let constants = &Default::default();
let mut pipeline_desc = wgpu::RenderPipelineDescriptor {
label: None,
layout: Some(&ppl),
vertex: wgpu::VertexState {
buffers: &[],
entry_point: "vs_main_builtin",
module: &shader,
entry_point: "vs_main_builtin",
constants,
},
primitive: wgpu::PrimitiveState::default(),
depth_stencil: None,
multisample: wgpu::MultisampleState::default(),
fragment: Some(wgpu::FragmentState {
entry_point: "fs_main",
module: &shader,
entry_point: "fs_main",
constants,
targets: &[Some(wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba8Unorm,
blend: None,

View File

@ -2762,8 +2762,9 @@ impl<A: HalApi> Device<A> {
label: desc.label.to_hal(self.instance_flags),
layout: pipeline_layout.raw(),
stage: hal::ProgrammableStage {
entry_point: final_entry_point_name.as_ref(),
module: shader_module.raw(),
entry_point: final_entry_point_name.as_ref(),
constants: desc.stage.constants.as_ref(),
},
};
@ -3178,6 +3179,7 @@ impl<A: HalApi> Device<A> {
hal::ProgrammableStage {
module: vertex_shader_module.raw(),
entry_point: &vertex_entry_point_name,
constants: stage_desc.constants.as_ref(),
}
};
@ -3237,6 +3239,7 @@ impl<A: HalApi> Device<A> {
Some(hal::ProgrammableStage {
module: shader_module.raw(),
entry_point: &fragment_entry_point_name,
constants: fragment_state.stage.constants.as_ref(),
})
}
None => None,

View File

@ -233,6 +233,14 @@ pub struct ProgrammableStageDescriptor<'a> {
/// * If a single entry point associated with this stage must be in the shader, then proceed as
/// if `Some(…)` was specified with that entry point's name.
pub entry_point: Option<Cow<'a, str>>,
/// Specifies the values of pipeline-overridable constants in the shader module.
///
/// If an `@id` attribute was specified on the declaration,
/// the key must be the pipeline constant ID as a decimal ASCII number; if not,
/// the key must be the constant's identifier name.
///
/// The value may represent any of WGSL's concrete scalar types.
pub constants: Cow<'a, naga::back::PipelineConstants>,
}
/// Number of implicit bind groups derived at pipeline creation.

View File

@ -245,17 +245,20 @@ impl<A: hal::Api> Example<A> {
.unwrap()
};
let constants = naga::back::PipelineConstants::default();
let pipeline_desc = hal::RenderPipelineDescriptor {
label: None,
layout: &pipeline_layout,
vertex_stage: hal::ProgrammableStage {
module: &shader,
entry_point: "vs_main",
constants: &constants,
},
vertex_buffers: &[],
fragment_stage: Some(hal::ProgrammableStage {
module: &shader,
entry_point: "fs_main",
constants: &constants,
}),
primitive: wgt::PrimitiveState {
topology: wgt::PrimitiveTopology::TriangleStrip,

View File

@ -371,6 +371,7 @@ impl<A: hal::Api> Example<A> {
stage: hal::ProgrammableStage {
module: &shader_module,
entry_point: "main",
constants: &Default::default(),
},
})
}

View File

@ -222,10 +222,13 @@ impl super::Device {
//TODO: reuse the writer
let mut source = String::new();
let mut writer = hlsl::Writer::new(&mut source, &layout.naga_options);
let pipeline_options = hlsl::PipelineOptions {
constants: stage.constants.to_owned(),
};
let reflection_info = {
profiling::scope!("naga::back::hlsl::write");
writer
.write(module, &stage.module.naga.info)
.write(module, &stage.module.naga.info, &pipeline_options)
.map_err(|e| crate::PipelineError::Linkage(stage_bit, format!("HLSL: {e:?}")))?
};

View File

@ -218,6 +218,7 @@ impl super::Device {
shader_stage: naga_stage,
entry_point: stage.entry_point.to_string(),
multiview: context.multiview,
constants: stage.constants.to_owned(),
};
let shader = &stage.module.naga;

View File

@ -1318,6 +1318,8 @@ pub struct ProgrammableStage<'a, A: Api> {
/// The name of the entry point in the compiled shader. There must be a function with this name
/// in the shader.
pub entry_point: &'a str,
/// Pipeline constants
pub constants: &'a naga::back::PipelineConstants,
}
// Rust gets confused about the impl requirements for `A`
@ -1326,6 +1328,7 @@ impl<A: Api> Clone for ProgrammableStage<'_, A> {
Self {
module: self.module,
entry_point: self.entry_point,
constants: self.constants,
}
}
}

View File

@ -112,6 +112,7 @@ impl super::Device {
metal::MTLPrimitiveTopologyClass::Point => true,
_ => false,
},
constants: stage.constants.to_owned(),
};
let (source, info) = naga::back::msl::write_string(

View File

@ -734,6 +734,7 @@ impl super::Device {
let pipeline_options = naga::back::spv::PipelineOptions {
entry_point: stage.entry_point.to_string(),
shader_stage: naga_stage,
constants: stage.constants.to_owned(),
};
let needs_temp_options = !runtime_checks
|| !binding_map.is_empty()

View File

@ -1143,6 +1143,7 @@ impl crate::Context for ContextWgpuCore {
stage: pipe::ProgrammableStageDescriptor {
module: desc.vertex.module.id.into(),
entry_point: Some(Borrowed(desc.vertex.entry_point)),
constants: Borrowed(desc.vertex.constants),
},
buffers: Borrowed(&vertex_buffers),
},
@ -1153,6 +1154,7 @@ impl crate::Context for ContextWgpuCore {
stage: pipe::ProgrammableStageDescriptor {
module: frag.module.id.into(),
entry_point: Some(Borrowed(frag.entry_point)),
constants: Borrowed(frag.constants),
},
targets: Borrowed(frag.targets),
}),
@ -1201,6 +1203,7 @@ impl crate::Context for ContextWgpuCore {
stage: pipe::ProgrammableStageDescriptor {
module: desc.module.id.into(),
entry_point: Some(Borrowed(desc.entry_point)),
constants: Borrowed(desc.constants),
},
};

View File

@ -28,6 +28,7 @@ use std::{
any::Any,
borrow::Cow,
cmp::Ordering,
collections::HashMap,
error, fmt,
future::Future,
marker::PhantomData,
@ -1467,6 +1468,14 @@ pub struct VertexState<'a> {
/// The name of the entry point in the compiled shader. There must be a function with this name
/// in the shader.
pub entry_point: &'a str,
/// Specifies the values of pipeline-overridable constants in the shader module.
///
/// If an `@id` attribute was specified on the declaration,
/// the key must be the pipeline constant ID as a decimal ASCII number; if not,
/// the key must be the constant's identifier name.
///
/// The value may represent any of WGSL's concrete scalar types.
pub constants: &'a HashMap<String, f64>,
/// The format of any vertex buffers used with this pipeline.
pub buffers: &'a [VertexBufferLayout<'a>],
}
@ -1486,6 +1495,14 @@ pub struct FragmentState<'a> {
/// The name of the entry point in the compiled shader. There must be a function with this name
/// in the shader.
pub entry_point: &'a str,
/// Specifies the values of pipeline-overridable constants in the shader module.
///
/// If an `@id` attribute was specified on the declaration,
/// the key must be the pipeline constant ID as a decimal ASCII number; if not,
/// the key must be the constant's identifier name.
///
/// The value may represent any of WGSL's concrete scalar types.
pub constants: &'a HashMap<String, f64>,
/// The color state of the render targets.
pub targets: &'a [Option<ColorTargetState>],
}
@ -1575,6 +1592,14 @@ pub struct ComputePipelineDescriptor<'a> {
/// The name of the entry point in the compiled shader. There must be a function with this name
/// and no return value in the shader.
pub entry_point: &'a str,
/// Specifies the values of pipeline-overridable constants in the shader module.
///
/// If an `@id` attribute was specified on the declaration,
/// the key must be the pipeline constant ID as a decimal ASCII number; if not,
/// the key must be the constant's identifier name.
///
/// The value may represent any of WGSL's concrete scalar types.
pub constants: &'a HashMap<String, f64>,
}
#[cfg(send_sync)]
static_assertions::assert_impl_all!(ComputePipelineDescriptor<'_>: Send, Sync);