663: Shader module descriptor r=cwfitzgerald,grovesNL a=kvark

Depends on https://github.com/gfx-rs/wgpu/pull/1071
Fixes #665
Based on #662

Co-authored-by: Dzmitry Malyshau <kvarkus@gmail.com>
This commit is contained in:
bors[bot]
2020-12-06 02:13:54 +00:00
committed by GitHub
17 changed files with 80 additions and 56 deletions

View File

@@ -1,4 +1,7 @@
# Change Log
### unreleased
- introduce `ShaderModuleDescriptor`
### v0.6.2 (2020-11-24)
- don't panic in the staging belt if the channel is dropped

View File

@@ -26,14 +26,14 @@ vulkan-portability = ["wgc/gfx-backend-vulkan"]
package = "wgpu-core"
#version = "0.6"
git = "https://github.com/gfx-rs/wgpu"
rev = "4513fb2b83fe2cd19682ccca9c55a6995f061699"
rev = "9960ded7ae83762e7e84f7f2e8d974b9a38580a1"
features = ["raw-window-handle"]
[dependencies.wgt]
package = "wgpu-types"
#version = "0.6"
git = "https://github.com/gfx-rs/wgpu"
rev = "4513fb2b83fe2cd19682ccca9c55a6995f061699"
rev = "9960ded7ae83762e7e84f7f2e8d974b9a38580a1"
[dependencies]
arrayvec = "0.5"
@@ -48,8 +48,10 @@ serde = { version = "1", features = ["derive"], optional = true }
# Enable X11 support for GL
# Note: we may consider switching this to "dev-dependencies" if users
# want to opt into X11 explicitly.
[target.'cfg(all(unix, not(target_os = "ios"), not(target_os = "macos")))'.dependencies]
gfx-backend-gl = { git = "https://github.com/gfx-rs/gfx", features = ["x11"] }
[target.'cfg(all(unix, not(target_os = "ios"), not(target_os = "macos")))'.dependencies.gfx-backend-gl]
git = "https://github.com/gfx-rs/gfx"
rev = "654ad48ee39ce2a341407ae2857ddf4db639ea54"
features = ["x11"]
[dev-dependencies]
cgmath = "0.17"

View File

@@ -34,9 +34,9 @@ impl framework::Example for Example {
) -> Self {
// load (and compile) shaders and create shader modules
let boids_module = device.create_shader_module(wgpu::include_spirv!("boids.comp.spv"));
let vs_module = device.create_shader_module(wgpu::include_spirv!("shader.vert.spv"));
let fs_module = device.create_shader_module(wgpu::include_spirv!("shader.frag.spv"));
let boids_module = device.create_shader_module(&wgpu::include_spirv!("boids.comp.spv"));
let vs_module = device.create_shader_module(&wgpu::include_spirv!("shader.vert.spv"));
let fs_module = device.create_shader_module(&wgpu::include_spirv!("shader.frag.spv"));
// buffer for simulation parameters uniform

View File

@@ -273,8 +273,8 @@ impl framework::Example for Example {
}],
};
let vs_module = device.create_shader_module(wgpu::include_spirv!("shader.vert.spv"));
let fs_module = device.create_shader_module(wgpu::include_spirv!("shader.frag.spv"));
let vs_module = device.create_shader_module(&wgpu::include_spirv!("shader.vert.spv"));
let fs_module = device.create_shader_module(&wgpu::include_spirv!("shader.frag.spv"));
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: None,
@@ -310,7 +310,8 @@ impl framework::Example for Example {
.features()
.contains(wgt::Features::NON_FILL_POLYGON_MODE)
{
let fs_wire_module = device.create_shader_module(wgpu::include_spirv!("wire.frag.spv"));
let fs_wire_module =
device.create_shader_module(&wgpu::include_spirv!("wire.frag.spv"));
let pipeline_wire = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: None,
layout: Some(&pipeline_layout),

View File

@@ -45,7 +45,7 @@ async fn execute_gpu(numbers: Vec<u32>) -> Vec<u32> {
.unwrap();
// Loads the shader from the SPIR-V file.arrayvec
let cs_module = device.create_shader_module(wgpu::include_spirv!("shader.comp.spv"));
let cs_module = device.create_shader_module(&wgpu::include_spirv!("shader.comp.spv"));
// Gets the size in bytes of the buffer.
let slice_size = numbers.len() * std::mem::size_of::<u32>();

View File

@@ -32,8 +32,8 @@ async fn run(event_loop: EventLoop<()>, window: Window, swapchain_format: wgpu::
.expect("Failed to create device");
// Load the shaders from disk
let vs_module = device.create_shader_module(wgpu::include_spirv!("shader.vert.spv"));
let fs_module = device.create_shader_module(wgpu::include_spirv!("shader.frag.spv"));
let vs_module = device.create_shader_module(&wgpu::include_spirv!("shader.vert.spv"));
let fs_module = device.create_shader_module(&wgpu::include_spirv!("shader.frag.spv"));
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: None,

View File

@@ -79,8 +79,8 @@ impl Example {
texture: &wgpu::Texture,
mip_count: u32,
) {
let vs_module = device.create_shader_module(wgpu::include_spirv!("blit.vert.spv"));
let fs_module = device.create_shader_module(wgpu::include_spirv!("blit.frag.spv"));
let vs_module = device.create_shader_module(&wgpu::include_spirv!("blit.vert.spv"));
let fs_module = device.create_shader_module(&wgpu::include_spirv!("blit.frag.spv"));
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("blit"),
@@ -257,8 +257,8 @@ impl framework::Example for Example {
});
// Create the render pipeline
let vs_module = device.create_shader_module(wgpu::include_spirv!("draw.vert.spv"));
let fs_module = device.create_shader_module(wgpu::include_spirv!("draw.frag.spv"));
let vs_module = device.create_shader_module(&wgpu::include_spirv!("draw.vert.spv"));
let fs_module = device.create_shader_module(&wgpu::include_spirv!("draw.frag.spv"));
let draw_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("draw"),

View File

@@ -128,8 +128,8 @@ impl framework::Example for Example {
log::info!("Press left/right arrow keys to change sample_count.");
let sample_count = 4;
let vs_module = device.create_shader_module(wgpu::include_spirv!("shader.vert.spv"));
let fs_module = device.create_shader_module(wgpu::include_spirv!("shader.frag.spv"));
let vs_module = device.create_shader_module(&wgpu::include_spirv!("shader.vert.spv"));
let fs_module = device.create_shader_module(&wgpu::include_spirv!("shader.frag.spv"));
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: None,

View File

@@ -464,7 +464,7 @@ impl framework::Example for Example {
});
// Create the render pipeline
let vs_module = device.create_shader_module(wgpu::include_spirv!("bake.vert.spv"));
let vs_module = device.create_shader_module(&wgpu::include_spirv!("bake.vert.spv"));
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("shadow"),
@@ -600,8 +600,8 @@ impl framework::Example for Example {
});
// Create the render pipeline
let vs_module = device.create_shader_module(wgpu::include_spirv!("forward.vert.spv"));
let fs_module = device.create_shader_module(wgpu::include_spirv!("forward.frag.spv"));
let vs_module = device.create_shader_module(&wgpu::include_spirv!("forward.vert.spv"));
let fs_module = device.create_shader_module(&wgpu::include_spirv!("forward.frag.spv"));
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("main"),

View File

@@ -84,8 +84,8 @@ impl framework::Example for Skybox {
});
// Create the render pipeline
let vs_module = device.create_shader_module(wgpu::include_spirv!("shader.vert.spv"));
let fs_module = device.create_shader_module(wgpu::include_spirv!("shader.frag.spv"));
let vs_module = device.create_shader_module(&wgpu::include_spirv!("shader.vert.spv"));
let fs_module = device.create_shader_module(&wgpu::include_spirv!("shader.frag.spv"));
let aspect = sc_desc.width as f32 / sc_desc.height as f32;
let uniforms = Self::generate_uniforms(aspect);

View File

@@ -91,7 +91,7 @@ impl framework::Example for Example {
queue: &wgpu::Queue,
) -> Self {
let mut uniform_workaround = false;
let vs_module = device.create_shader_module(wgpu::include_spirv!("shader.vert.spv"));
let vs_module = device.create_shader_module(&wgpu::include_spirv!("shader.vert.spv"));
let fs_source = match device.features() {
f if f.contains(wgpu::Features::UNSIZED_BINDING_ARRAY) => {
wgpu::include_spirv!("unsized-non-uniform.frag.spv")
@@ -108,7 +108,7 @@ impl framework::Example for Example {
}
_ => unreachable!(),
};
let fs_module = device.create_shader_module(fs_source);
let fs_module = device.create_shader_module(&fs_source);
let vertex_size = std::mem::size_of::<Vertex>();
let vertex_data = create_vertices();

View File

@@ -486,13 +486,13 @@ impl framework::Example for Example {
// Upload/compile them to GPU code.
let water_vs_module =
device.create_shader_module(wgpu::include_spirv!("water_shader.vert.spv"));
device.create_shader_module(&wgpu::include_spirv!("water_shader.vert.spv"));
let water_fs_module =
device.create_shader_module(wgpu::include_spirv!("water_shader.frag.spv"));
device.create_shader_module(&wgpu::include_spirv!("water_shader.frag.spv"));
let terrain_vs_module =
device.create_shader_module(wgpu::include_spirv!("terrain_shader.vert.spv"));
device.create_shader_module(&wgpu::include_spirv!("terrain_shader.vert.spv"));
let terrain_fs_module =
device.create_shader_module(wgpu::include_spirv!("terrain_shader.frag.spv"));
device.create_shader_module(&wgpu::include_spirv!("terrain_shader.frag.spv"));
// Create the render pipelines. These describe how the data will flow through the GPU, and what
// constraints and modifiers it will have.

View File

@@ -3,7 +3,7 @@ use crate::{
BindGroupDescriptor, BindGroupLayoutDescriptor, BindingResource, CommandEncoderDescriptor,
ComputePipelineDescriptor, Features, Label, Limits, LoadOp, MapMode, Operations,
PipelineLayoutDescriptor, RenderBundleEncoderDescriptor, RenderPipelineDescriptor,
SamplerDescriptor, ShaderModuleSource, SwapChainStatus, TextureDescriptor,
SamplerDescriptor, ShaderModuleDescriptor, ShaderSource, SwapChainStatus, TextureDescriptor,
TextureViewDescriptor,
};
@@ -725,18 +725,19 @@ impl crate::Context for Context {
fn device_create_shader_module(
&self,
device: &Self::DeviceId,
source: ShaderModuleSource,
desc: &ShaderModuleDescriptor,
) -> Self::ShaderModuleId {
let descriptor = wgc::pipeline::ShaderModuleDescriptor {
label: None,
source: match source {
ShaderModuleSource::SpirV(spv) => wgc::pipeline::ShaderModuleSource::SpirV(spv),
ShaderModuleSource::Wgsl(code) => wgc::pipeline::ShaderModuleSource::Wgsl(code),
},
};
let global = &self.0;
let descriptor = wgc::pipeline::ShaderModuleDescriptor {
label: desc.label.map(Borrowed),
experimental_translation: desc.experimental_translation,
};
let source = match desc.source {
ShaderSource::SpirV(ref spv) => wgc::pipeline::ShaderModuleSource::SpirV(Borrowed(spv)),
ShaderSource::Wgsl(ref code) => wgc::pipeline::ShaderModuleSource::Wgsl(Borrowed(code)),
};
let (id, error) = wgc::gfx_select!(
device.id => global.device_create_shader_module(device.id, &descriptor, PhantomData)
device.id => global.device_create_shader_module(device.id, &descriptor, source, PhantomData)
);
if let Some(cause) = error {
self.handle_error(

View File

@@ -2,8 +2,9 @@ use crate::{
BindGroupDescriptor, BindGroupLayoutDescriptor, BindingResource, BindingType,
BufferBindingType, BufferDescriptor, CommandEncoderDescriptor, ComputePipelineDescriptor,
LoadOp, PipelineLayoutDescriptor, ProgrammableStageDescriptor, RenderBundleEncoderDescriptor,
RenderPipelineDescriptor, SamplerDescriptor, ShaderModuleSource, StorageTextureAccess,
SwapChainStatus, TextureDescriptor, TextureViewDescriptor, TextureViewDimension,
RenderPipelineDescriptor, SamplerDescriptor, ShaderModuleDescriptor, ShaderSource,
StorageTextureAccess, SwapChainStatus, TextureDescriptor, TextureViewDescriptor,
TextureViewDimension,
};
use futures::FutureExt;
@@ -965,18 +966,20 @@ impl crate::Context for Context {
fn device_create_shader_module(
&self,
device: &Self::DeviceId,
source: ShaderModuleSource,
desc: &ShaderModuleDescriptor,
) -> Self::ShaderModuleId {
let desc = match source {
ShaderModuleSource::SpirV(spv) => {
web_sys::GpuShaderModuleDescriptor::new(&js_sys::Uint32Array::from(&*spv))
let mut descriptor = match desc.source {
ShaderSource::SpirV(ref spv) => {
web_sys::GpuShaderModuleDescriptor::new(&js_sys::Uint32Array::from(&**spv))
}
ShaderModuleSource::Wgsl(_code) => {
ShaderSource::Wgsl(_) => {
panic!("WGSL is not yet supported by the Web backend")
}
};
// TODO: label
Sendable(device.0.create_shader_module(&desc))
if let Some(ref label) = desc.label {
descriptor.label(label);
}
Sendable(device.0.create_shader_module(&descriptor))
}
fn device_create_bind_group_layout(

View File

@@ -210,7 +210,7 @@ trait Context: Debug + Send + Sized + Sync {
fn device_create_shader_module(
&self,
device: &Self::DeviceId,
source: ShaderModuleSource,
desc: &ShaderModuleDescriptor,
) -> Self::ShaderModuleId;
fn device_create_bind_group_layout(
&self,
@@ -672,7 +672,7 @@ impl Drop for ShaderModule {
}
/// Source of a shader module.
pub enum ShaderModuleSource<'a> {
pub enum ShaderSource<'a> {
/// SPIR-V module represented as a slice of words.
///
/// wgpu will attempt to parse and validate it, but the original binary
@@ -687,6 +687,16 @@ pub enum ShaderModuleSource<'a> {
Wgsl(Cow<'a, str>),
}
/// Descriptor for a shader module.
pub struct ShaderModuleDescriptor<'a> {
/// Debug label of the shader module. This will show up in graphics debuggers for easy identification.
pub label: Label<'a>,
/// Source code for the shader.
pub source: ShaderSource<'a>,
/// Experimental translation path attempts to avoid SPIR-V and work with Naga IR directly.
pub experimental_translation: bool,
}
/// Handle to a pipeline layout.
///
/// A `PipelineLayout` object describes the available binding groups of a pipeline.
@@ -1415,10 +1425,10 @@ impl Device {
}
/// Creates a shader module from either SPIR-V or WGSL source code.
pub fn create_shader_module(&self, source: ShaderModuleSource) -> ShaderModule {
pub fn create_shader_module(&self, desc: &ShaderModuleDescriptor) -> ShaderModule {
ShaderModule {
context: Arc::clone(&self.context),
id: Context::device_create_shader_module(&*self.context, &self.id, source),
id: Context::device_create_shader_module(&*self.context, &self.id, desc),
}
}

View File

@@ -49,7 +49,11 @@ macro_rules! include_spirv {
($($token:tt)*) => {
{
//log::info!("including '{}'", $($token)*);
$crate::util::make_spirv(include_bytes!($($token)*))
$crate::ShaderModuleDescriptor {
label: Some($($token)*),
source: $crate::util::make_spirv(include_bytes!($($token)*)),
experimental_translation: false,
}
}
};
}

View File

@@ -19,7 +19,7 @@ pub use belt::StagingBelt;
/// - Input length isn't multiple of 4
/// - Input is longer than [`usize::max_value`]
/// - SPIR-V magic number is missing from beginning of stream
pub fn make_spirv<'a>(data: &'a [u8]) -> super::ShaderModuleSource<'a> {
pub fn make_spirv<'a>(data: &'a [u8]) -> super::ShaderSource<'a> {
const MAGIC_NUMBER: u32 = 0x0723_0203;
assert_eq!(
@@ -48,7 +48,7 @@ pub fn make_spirv<'a>(data: &'a [u8]) -> super::ShaderModuleSource<'a> {
"wrong magic word {:x}. Make sure you are using a binary SPIRV file.",
words[0]
);
super::ShaderModuleSource::SpirV(words)
super::ShaderSource::SpirV(words)
}
/// Utility methods not meant to be in the main API.