Skip to content

Commit

Permalink
feat(spv): shader debug option
Browse files Browse the repository at this point in the history
  • Loading branch information
wicast committed Aug 10, 2023
1 parent e36c560 commit 88e83c5
Show file tree
Hide file tree
Showing 31 changed files with 94 additions and 10 deletions.
1 change: 1 addition & 0 deletions deno_webgpu/shader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub fn op_webgpu_create_shader_module(
let descriptor = wgpu_core::pipeline::ShaderModuleDescriptor {
label: label.map(Cow::from),
shader_bound_checks: wgpu_types::ShaderBoundChecks::default(),
debug: false,
};

gfx_put!(device => instance.device_create_shader_module(
Expand Down
2 changes: 2 additions & 0 deletions examples/boids/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ impl wgpu_example::framework::Example for Example {
let compute_shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: None,
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("compute.wgsl"))),
debug: false,
});
let draw_shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: None,
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("draw.wgsl"))),
debug: false,
});

// buffer for simulation parameters uniform
Expand Down
1 change: 1 addition & 0 deletions examples/bunnymark/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ impl wgpu_example::framework::Example for Example {
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!(
"../../../wgpu-hal/examples/halmark/shader.wgsl"
))),
debug: false,
});

let global_bind_group_layout =
Expand Down
2 changes: 2 additions & 0 deletions examples/conservative-raster/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ impl wgpu_example::framework::Example for Example {
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!(
"triangle_and_lines.wgsl"
))),
debug: false,
});

let pipeline_triangle_conservative =
Expand Down Expand Up @@ -197,6 +198,7 @@ impl wgpu_example::framework::Example for Example {
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: None,
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("upscale.wgsl"))),
debug: false,
});
(
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
Expand Down
1 change: 1 addition & 0 deletions examples/cube/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ impl wgpu_example::framework::Example for Example {
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: None,
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
debug: false,
});

let vertex_buffers = [wgpu::VertexBufferLayout {
Expand Down
1 change: 1 addition & 0 deletions examples/hello-compute/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ async fn execute_gpu_inner(
let cs_module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: None,
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
debug: false,
});

// Gets the size in bytes of the buffer.
Expand Down
1 change: 1 addition & 0 deletions examples/hello-triangle/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: None,
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
debug: false,
});

let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
Expand Down
2 changes: 2 additions & 0 deletions examples/mipmap/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ impl Example {
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: None,
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("blit.wgsl"))),
debug: false,
});

let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
Expand Down Expand Up @@ -282,6 +283,7 @@ impl wgpu_example::framework::Example for Example {
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: None,
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("draw.wgsl"))),
debug: false,
});

let draw_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
Expand Down
1 change: 1 addition & 0 deletions examples/msaa-line/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ impl wgpu_example::framework::Example for Example {
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: None,
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
debug: false,
});

let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
Expand Down
1 change: 1 addition & 0 deletions examples/shadow/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ impl wgpu_example::framework::Example for Example {
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: None,
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
debug: false,
});

let shadow_pass = {
Expand Down
1 change: 1 addition & 0 deletions examples/skybox/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ impl wgpu_example::framework::Example for Skybox {
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: None,
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
debug: false,
});

let camera = Camera {
Expand Down
1 change: 1 addition & 0 deletions examples/stencil-triangles/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ impl wgpu_example::framework::Example for Triangles {
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: None,
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
debug: false,
});

let vertex_buffers = [wgpu::VertexBufferLayout {
Expand Down
1 change: 1 addition & 0 deletions examples/timestamp-queries/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ fn submit_render_and_compute_pass_with_queries(
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: None,
source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed(include_str!("shader.wgsl"))),
debug: false,
});

encoder.write_timestamp(&queries.set, queries.next_unused_query);
Expand Down
2 changes: 2 additions & 0 deletions examples/water/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,10 +496,12 @@ impl wgpu_example::framework::Example for Example {
let terrain_module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some("terrain"),
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("terrain.wgsl"))),
debug: false,
});
let water_module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some("water"),
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("water.wgsl"))),
debug: false,
});

// Create the render pipelines. These describe how the data will flow through the GPU, and what
Expand Down
1 change: 1 addition & 0 deletions player/tests/data/bind-group.ron
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
desc: (
label: None,
flags: (bits: 3),
debug: false,
),
data: "empty.wgsl",
),
Expand Down
1 change: 1 addition & 0 deletions player/tests/data/pipeline-statistics-query.ron
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
desc: (
label: None,
flags: (bits: 3),
debug: false,
),
data: "empty.wgsl",
),
Expand Down
1 change: 1 addition & 0 deletions player/tests/data/quad.ron
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
desc: (
label: None,
flags: (bits: 3),
debug: false,
),
data: "quad.wgsl",
),
Expand Down
1 change: 1 addition & 0 deletions player/tests/data/zero-init-buffer.ron
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
desc: (
label: None,
flags: (bits: 3),
debug: false,
),
data: "zero-init-buffer-for-binding.wgsl",
),
Expand Down
1 change: 1 addition & 0 deletions player/tests/data/zero-init-texture-binding.ron
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
desc: (
label: None,
flags: (bits: 3),
debug: false,
),
data: "zero-init-texture-binding.wgsl",
),
Expand Down
1 change: 1 addition & 0 deletions tests/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ fn copy_via_compute(
let sm = device.create_shader_module(ShaderModuleDescriptor {
label: Some("shader copy_texture_to_buffer.wgsl"),
source: ShaderSource::Wgsl(Cow::Borrowed(&processed_source)),
debug: false,
});

let pipeline_copy = device.create_compute_pipeline(&ComputePipelineDescriptor {
Expand Down
1 change: 1 addition & 0 deletions tests/tests/occlusion_query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ fn occlusion_query() {
.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some("Shader module"),
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
debug: false,
});
let pipeline = ctx
.device
Expand Down
1 change: 1 addition & 0 deletions tests/tests/partially_bounded_arrays/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ fn partially_bounded_array() {
let cs_module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: None,
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
debug: false,
});

let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
Expand Down
1 change: 1 addition & 0 deletions tests/tests/shader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ fn shader_input_output_test(
let sm = ctx.device.create_shader_module(ShaderModuleDescriptor {
label: Some(&format!("shader {test_name}")),
source: ShaderSource::Wgsl(Cow::Borrowed(&processed)),
debug: false,
});

let pipeline = ctx
Expand Down
20 changes: 19 additions & 1 deletion wgpu-core/src/device/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1276,6 +1276,19 @@ impl<A: HalApi> Device<A> {
.contains(wgt::DownlevelFlags::MULTISAMPLED_SHADING),
);

let debug_source = if desc.debug {
Some(hal::DebugSource {
file_name: Cow::Owned(
desc.label
.as_ref()
.map_or("shader".to_string(), |l| l.to_string()),
),
source_code: Cow::Owned(source.clone()),
})
} else {
None
};

let info = naga::valid::Validator::new(naga::valid::ValidationFlags::all(), caps)
.validate(&module)
.map_err(|inner| {
Expand All @@ -1286,7 +1299,12 @@ impl<A: HalApi> Device<A> {
})
})?;
let interface = validation::Interface::new(&module, &info, self.limits.clone());
let hal_shader = hal::ShaderInput::Naga(hal::NagaShader { module, info });

let hal_shader = hal::ShaderInput::Naga(hal::NagaShader {
module,
info,
debug_source,
});

let hal_desc = hal::ShaderModuleDescriptor {
label: desc.label.borrow_option(),
Expand Down
1 change: 1 addition & 0 deletions wgpu-core/src/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub struct ShaderModuleDescriptor<'a> {
pub label: Label<'a>,
#[cfg_attr(feature = "serde", serde(default))]
pub shader_bound_checks: wgt::ShaderBoundChecks,
pub debug: bool,
}

#[derive(Debug)]
Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/examples/halmark/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ impl<A: hal::Api> Example<A> {
hal::NagaShader {
module: Cow::Owned(module),
info,
debug_source: None,
}
};
let shader_desc = hal::ShaderModuleDescriptor {
Expand Down
8 changes: 8 additions & 0 deletions wgpu-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1058,6 +1058,8 @@ pub struct NagaShader {
pub module: Cow<'static, naga::Module>,
/// Analysis information of the module.
pub info: naga::valid::ModuleInfo,
/// Source codes for debug
pub debug_source: Option<DebugSource>,
}

// Custom implementation avoids the need to generate Debug impl code
Expand All @@ -1080,6 +1082,12 @@ pub struct ShaderModuleDescriptor<'a> {
pub runtime_checks: bool,
}

#[derive(Debug, Clone)]
pub struct DebugSource {
pub file_name: Cow<'static, str>,
pub source_code: Cow<'static, str>,
}

/// Describes a programmable pipeline stage.
#[derive(Debug)]
pub struct ProgrammableStage<'a, A: Api> {
Expand Down
20 changes: 19 additions & 1 deletion wgpu-hal/src/vulkan/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,9 @@ impl super::Device {
entry_point: stage.entry_point.to_string(),
shader_stage: naga_stage,
};
let needs_temp_options = !runtime_checks || !binding_map.is_empty();
let needs_temp_options = !runtime_checks
|| !binding_map.is_empty()
|| naga_shader.debug_source.is_some();
let mut temp_options;
let options = if needs_temp_options {
temp_options = self.naga_options.clone();
Expand All @@ -739,6 +741,14 @@ impl super::Device {
if !binding_map.is_empty() {
temp_options.binding_map = binding_map.clone();
}

if let Some(ref debug) = naga_shader.debug_source {
temp_options.debug_info = Some(naga::back::spv::DebugInfo {
source_code: &debug.source_code,
file_name: &debug.file_name,
})
}

&temp_options
} else {
&self.naga_options
Expand Down Expand Up @@ -1523,6 +1533,14 @@ impl crate::Device<super::Api> for super::Device {
});
}
let mut naga_options = self.naga_options.clone();
naga_options.debug_info =
naga_shader
.debug_source
.as_ref()
.map(|d| naga::back::spv::DebugInfo {
source_code: d.source_code.as_ref(),
file_name: d.file_name.as_ref(),
});
if !desc.runtime_checks {
naga_options.bounds_check_policies = naga::proc::BoundsCheckPolicies {
index: naga::proc::BoundsCheckPolicy::Unchecked,
Expand Down
2 changes: 2 additions & 0 deletions wgpu/src/backend/direct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,7 @@ impl crate::Context for Context {
let descriptor = wgc::pipeline::ShaderModuleDescriptor {
label: desc.label.map(Borrowed),
shader_bound_checks,
debug: desc.debug,
};
let source = match desc.source {
#[cfg(feature = "spirv")]
Expand Down Expand Up @@ -951,6 +952,7 @@ impl crate::Context for Context {
// Doesn't matter the value since spirv shaders aren't mutated to include
// runtime checks
shader_bound_checks: unsafe { wgt::ShaderBoundChecks::unchecked() },
debug: false,
};
let (id, error) = wgc::gfx_select!(
device => global.device_create_shader_module_spirv(*device, &descriptor, Borrowed(&desc.source), ())
Expand Down
2 changes: 2 additions & 0 deletions wgpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,8 @@ pub struct ShaderModuleDescriptor<'a> {
pub label: Label<'a>,
/// Source code for the shader.
pub source: ShaderSource<'a>,
/// Generate debug symbols, only available in spv-out
pub debug: bool,
}
static_assertions::assert_impl_all!(ShaderModuleDescriptor: Send, Sync);

Expand Down
23 changes: 15 additions & 8 deletions wgpu/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,20 @@ macro_rules! include_spirv_raw {
/// Macro to load a WGSL module statically.
#[macro_export]
macro_rules! include_wgsl {
($($token:tt)*) => {
{
//log::info!("including '{}'", $($token)*);
$crate::ShaderModuleDescriptor {
label: Some($($token)*),
source: $crate::ShaderSource::Wgsl(include_str!($($token)*).into()),
}
($name:tt) => {{
// log::info!("including '{}'", $name);
$crate::ShaderModuleDescriptor {
label: Some($name),
source: $crate::ShaderSource::Wgsl(include_str!($name).into()),
debug: false,
}
};
}};
($name:tt, $debug:tt) => {{
// log::info!("including '{}', '{}'", $name, $debug);
$crate::ShaderModuleDescriptor {
label: Some($name),
source: $crate::ShaderSource::Wgsl(include_str!($name).into()),
debug: $debug,
}
}};
}

0 comments on commit 88e83c5

Please sign in to comment.