mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
[rs] Merge #663
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:
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user