Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
wgpu: use spirv passthrough and explicit pipeline layout creation
  • Loading branch information
Firestar99 committed Dec 7, 2025
commit a589f2f600ed4d1dc08a94f1eb77a12790c173d1
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ glam = { version = "0.30.9", default-features = false }
bytemuck = { version = "1.24.0", features = ["derive"] }
raw-window-handle = "0.6.2"
winit = "0.30.0"
cfg-if = "1.0.0"
env_logger = "0.11.8"
anyhow = "1.0.98"
2 changes: 1 addition & 1 deletion generated/graphics/ash/cargo-gpu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ glam = { version = "0.30.9", default-features = false }
bytemuck = { version = "1.24.0", features = ["derive"] }
raw-window-handle = "0.6.2"
winit = "0.30.0"
cfg-if = "1.0.0"
env_logger = "0.11.8"
anyhow = "1.0.98"

2 changes: 1 addition & 1 deletion generated/graphics/ash/spirv-builder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ glam = { version = "0.30.9", default-features = false }
bytemuck = { version = "1.24.0", features = ["derive"] }
raw-window-handle = "0.6.2"
winit = "0.30.0"
cfg-if = "1.0.0"
env_logger = "0.11.8"
anyhow = "1.0.98"

# Optimize build scripts, copied from rust-gpu's repo
Expand Down
2 changes: 1 addition & 1 deletion generated/graphics/wgpu/cargo-gpu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ glam = { version = "0.30.9", default-features = false }
bytemuck = { version = "1.24.0", features = ["derive"] }
raw-window-handle = "0.6.2"
winit = "0.30.0"
cfg-if = "1.0.0"
env_logger = "0.11.8"
anyhow = "1.0.98"

1 change: 1 addition & 0 deletions generated/graphics/wgpu/cargo-gpu/mygraphics/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ mygraphics-shaders = { path = "../mygraphics-shaders" }
# API
wgpu.workspace = true
pollster.workspace = true
env_logger.workspace = true

# other
raw-window-handle.workspace = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod renderer;
mod swapchain;

pub fn main() -> anyhow::Result<()> {
env_logger::init();
pollster::block_on(main_inner())
}

Expand All @@ -35,7 +36,8 @@ pub async fn main_inner() -> anyhow::Result<()> {
let adapter =
wgpu::util::initialize_adapter_from_env_or_default(&instance, Some(&surface)).await?;

let required_features = wgpu::Features::PUSH_CONSTANTS;
let required_features =
wgpu::Features::PUSH_CONSTANTS | wgpu::Features::EXPERIMENTAL_PASSTHROUGH_SHADERS;
let required_limits = wgpu::Limits {
max_push_constant_size: 128,
..Default::default()
Expand All @@ -45,7 +47,7 @@ pub async fn main_inner() -> anyhow::Result<()> {
label: None,
required_features,
required_limits,
experimental_features: wgpu::ExperimentalFeatures::disabled(),
experimental_features: unsafe { wgpu::ExperimentalFeatures::enabled() },
memory_hints: wgpu::MemoryHints::Performance,
trace: Default::default(),
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use mygraphics_shaders::ShaderConstants;
use wgpu::{
include_spirv, ColorTargetState, ColorWrites, Device, FragmentState, FrontFace,
MultisampleState, PolygonMode, PrimitiveState, PrimitiveTopology, RenderPass, RenderPipeline,
RenderPipelineDescriptor, ShaderStages, TextureFormat, VertexState,
ColorTargetState, ColorWrites, Device, FragmentState, FrontFace, MultisampleState,
PipelineLayoutDescriptor, PolygonMode, PrimitiveState, PrimitiveTopology, PushConstantRange,
RenderPass, RenderPipeline, RenderPipelineDescriptor, ShaderModuleDescriptorPassthrough,
ShaderRuntimeChecks, ShaderStages, TextureFormat, VertexState,
};

pub struct MyRenderPipeline {
Expand All @@ -11,14 +12,44 @@ pub struct MyRenderPipeline {

impl MyRenderPipeline {
pub fn new(device: &Device, out_format: TextureFormat) -> anyhow::Result<Self> {
let module = device.create_shader_module(include_spirv!(env!("SHADER_SPV_PATH")));
// Workaround in wgpu 27.0.1 where the macro expansion of `include_spirv_raw!` doesn't compile
// see https://github.com/gfx-rs/wgpu/pull/8250
// let module = unsafe {
// device.create_shader_module_passthrough(include_spirv_raw!(env!("SHADER_SPV_PATH")))
// };
let module = unsafe {
device.create_shader_module_passthrough(ShaderModuleDescriptorPassthrough {
label: Some(env!("SHADER_SPV_PATH")),
entry_point: "".to_owned(),
num_workgroups: (0, 0, 0),
runtime_checks: ShaderRuntimeChecks::unchecked(),
spirv: Some(wgpu::util::make_spirv_raw(include_bytes!(env!(
"SHADER_SPV_PATH"
)))),
dxil: None,
msl: None,
hlsl: None,
glsl: None,
wgsl: None,
})
};

let layout = device.create_pipeline_layout(&PipelineLayoutDescriptor {
label: Some("MyRenderPipeline layout"),
bind_group_layouts: &[],
push_constant_ranges: &[PushConstantRange {
stages: ShaderStages::VERTEX_FRAGMENT,
range: 0..size_of::<ShaderConstants>() as u32,
}],
});

Ok(Self {
pipeline: device.create_render_pipeline(&RenderPipelineDescriptor {
label: Some("MyRenderPipeline"),
layout: None,
layout: Some(&layout),
vertex: VertexState {
module: &module,
entry_point: None,
entry_point: Some("main_vs"),
compilation_options: Default::default(),
buffers: &[],
},
Expand All @@ -35,7 +66,7 @@ impl MyRenderPipeline {
multisample: MultisampleState::default(),
fragment: Some(FragmentState {
module: &module,
entry_point: None,
entry_point: Some("main_fs"),
compilation_options: Default::default(),
targets: &[Some(ColorTargetState {
format: out_format,
Expand Down
2 changes: 1 addition & 1 deletion generated/graphics/wgpu/spirv-builder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ glam = { version = "0.30.9", default-features = false }
bytemuck = { version = "1.24.0", features = ["derive"] }
raw-window-handle = "0.6.2"
winit = "0.30.0"
cfg-if = "1.0.0"
env_logger = "0.11.8"
anyhow = "1.0.98"

# Optimize build scripts, copied from rust-gpu's repo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ mygraphics-shaders = { path = "../mygraphics-shaders" }
# API
wgpu.workspace = true
pollster.workspace = true
env_logger.workspace = true

# other
raw-window-handle.workspace = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod renderer;
mod swapchain;

pub fn main() -> anyhow::Result<()> {
env_logger::init();
pollster::block_on(main_inner())
}

Expand All @@ -35,7 +36,8 @@ pub async fn main_inner() -> anyhow::Result<()> {
let adapter =
wgpu::util::initialize_adapter_from_env_or_default(&instance, Some(&surface)).await?;

let required_features = wgpu::Features::PUSH_CONSTANTS;
let required_features =
wgpu::Features::PUSH_CONSTANTS | wgpu::Features::EXPERIMENTAL_PASSTHROUGH_SHADERS;
let required_limits = wgpu::Limits {
max_push_constant_size: 128,
..Default::default()
Expand All @@ -45,7 +47,7 @@ pub async fn main_inner() -> anyhow::Result<()> {
label: None,
required_features,
required_limits,
experimental_features: wgpu::ExperimentalFeatures::disabled(),
experimental_features: unsafe { wgpu::ExperimentalFeatures::enabled() },
memory_hints: wgpu::MemoryHints::Performance,
trace: Default::default(),
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use mygraphics_shaders::ShaderConstants;
use wgpu::{
include_spirv, ColorTargetState, ColorWrites, Device, FragmentState, FrontFace,
MultisampleState, PolygonMode, PrimitiveState, PrimitiveTopology, RenderPass, RenderPipeline,
RenderPipelineDescriptor, ShaderStages, TextureFormat, VertexState,
ColorTargetState, ColorWrites, Device, FragmentState, FrontFace, MultisampleState,
PipelineLayoutDescriptor, PolygonMode, PrimitiveState, PrimitiveTopology, PushConstantRange,
RenderPass, RenderPipeline, RenderPipelineDescriptor, ShaderModuleDescriptorPassthrough,
ShaderRuntimeChecks, ShaderStages, TextureFormat, VertexState,
};

pub struct MyRenderPipeline {
Expand All @@ -11,14 +12,44 @@ pub struct MyRenderPipeline {

impl MyRenderPipeline {
pub fn new(device: &Device, out_format: TextureFormat) -> anyhow::Result<Self> {
let module = device.create_shader_module(include_spirv!(env!("SHADER_SPV_PATH")));
// Workaround in wgpu 27.0.1 where the macro expansion of `include_spirv_raw!` doesn't compile
// see https://github.com/gfx-rs/wgpu/pull/8250
// let module = unsafe {
// device.create_shader_module_passthrough(include_spirv_raw!(env!("SHADER_SPV_PATH")))
// };
let module = unsafe {
device.create_shader_module_passthrough(ShaderModuleDescriptorPassthrough {
label: Some(env!("SHADER_SPV_PATH")),
entry_point: "".to_owned(),
num_workgroups: (0, 0, 0),
runtime_checks: ShaderRuntimeChecks::unchecked(),
spirv: Some(wgpu::util::make_spirv_raw(include_bytes!(env!(
"SHADER_SPV_PATH"
)))),
dxil: None,
msl: None,
hlsl: None,
glsl: None,
wgsl: None,
})
};

let layout = device.create_pipeline_layout(&PipelineLayoutDescriptor {
label: Some("MyRenderPipeline layout"),
bind_group_layouts: &[],
push_constant_ranges: &[PushConstantRange {
stages: ShaderStages::VERTEX_FRAGMENT,
range: 0..size_of::<ShaderConstants>() as u32,
}],
});

Ok(Self {
pipeline: device.create_render_pipeline(&RenderPipelineDescriptor {
label: Some("MyRenderPipeline"),
layout: None,
layout: Some(&layout),
vertex: VertexState {
module: &module,
entry_point: None,
entry_point: Some("main_vs"),
compilation_options: Default::default(),
buffers: &[],
},
Expand All @@ -35,7 +66,7 @@ impl MyRenderPipeline {
multisample: MultisampleState::default(),
fragment: Some(FragmentState {
module: &module,
entry_point: None,
entry_point: Some("main_fs"),
compilation_options: Default::default(),
targets: &[Some(ColorTargetState {
format: out_format,
Expand Down
2 changes: 1 addition & 1 deletion graphics/Cargo.toml.liquid
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ glam = { version = "0.30.9", default-features = false }
bytemuck = { version = "1.24.0", features = ["derive"] }
raw-window-handle = "0.6.2"
winit = "0.30.0"
cfg-if = "1.0.0"
env_logger = "0.11.8"
anyhow = "1.0.98"

{% if integration == "spirv-builder" -%}
Expand Down
1 change: 1 addition & 0 deletions graphics/mygraphics/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ ash.workspace = true
ash-window.workspace = true
wgpu.workspace = true
pollster.workspace = true
env_logger.workspace = true

# other
raw-window-handle.workspace = true
Expand Down
1 change: 1 addition & 0 deletions graphics/mygraphics/Cargo.toml.liquid
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ ash-window.workspace = true
{%- if api == "wgpu" -%}
wgpu.workspace = true
pollster.workspace = true
env_logger.workspace = true
{%- endif %}

# other
Expand Down
6 changes: 4 additions & 2 deletions graphics/mygraphics/src/wgpu_renderer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod renderer;
mod swapchain;

pub fn main() -> anyhow::Result<()> {
env_logger::init();
pollster::block_on(main_inner())
}

Expand All @@ -35,7 +36,8 @@ pub async fn main_inner() -> anyhow::Result<()> {
let adapter =
wgpu::util::initialize_adapter_from_env_or_default(&instance, Some(&surface)).await?;

let required_features = wgpu::Features::PUSH_CONSTANTS;
let required_features =
wgpu::Features::PUSH_CONSTANTS | wgpu::Features::EXPERIMENTAL_PASSTHROUGH_SHADERS;
let required_limits = wgpu::Limits {
max_push_constant_size: 128,
..Default::default()
Expand All @@ -45,7 +47,7 @@ pub async fn main_inner() -> anyhow::Result<()> {
label: None,
required_features,
required_limits,
experimental_features: wgpu::ExperimentalFeatures::disabled(),
experimental_features: unsafe { wgpu::ExperimentalFeatures::enabled() },
memory_hints: wgpu::MemoryHints::Performance,
trace: Default::default(),
})
Expand Down
45 changes: 38 additions & 7 deletions graphics/mygraphics/src/wgpu_renderer/render_pipeline.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use mygraphics_shaders::ShaderConstants;
use wgpu::{
ColorTargetState, ColorWrites, Device, FragmentState, FrontFace, MultisampleState, PolygonMode,
PrimitiveState, PrimitiveTopology, RenderPass, RenderPipeline, RenderPipelineDescriptor,
ShaderStages, TextureFormat, VertexState, include_spirv,
ColorTargetState, ColorWrites, Device, FragmentState, FrontFace, MultisampleState,
PipelineLayoutDescriptor, PolygonMode, PrimitiveState, PrimitiveTopology, PushConstantRange,
RenderPass, RenderPipeline, RenderPipelineDescriptor, ShaderModuleDescriptorPassthrough,
ShaderRuntimeChecks, ShaderStages, TextureFormat, VertexState,
};

pub struct MyRenderPipeline {
Expand All @@ -11,14 +12,44 @@ pub struct MyRenderPipeline {

impl MyRenderPipeline {
pub fn new(device: &Device, out_format: TextureFormat) -> anyhow::Result<Self> {
let module = device.create_shader_module(include_spirv!(env!("SHADER_SPV_PATH")));
// Workaround in wgpu 27.0.1 where the macro expansion of `include_spirv_raw!` doesn't compile
// see https://github.com/gfx-rs/wgpu/pull/8250
// let module = unsafe {
// device.create_shader_module_passthrough(include_spirv_raw!(env!("SHADER_SPV_PATH")))
// };
let module = unsafe {
device.create_shader_module_passthrough(ShaderModuleDescriptorPassthrough {
label: Some(env!("SHADER_SPV_PATH")),
entry_point: "".to_owned(),
num_workgroups: (0, 0, 0),
runtime_checks: ShaderRuntimeChecks::unchecked(),
spirv: Some(wgpu::util::make_spirv_raw(include_bytes!(env!(
"SHADER_SPV_PATH"
)))),
dxil: None,
msl: None,
hlsl: None,
glsl: None,
wgsl: None,
})
};

let layout = device.create_pipeline_layout(&PipelineLayoutDescriptor {
label: Some("MyRenderPipeline layout"),
bind_group_layouts: &[],
push_constant_ranges: &[PushConstantRange {
stages: ShaderStages::VERTEX_FRAGMENT,
range: 0..size_of::<ShaderConstants>() as u32,
}],
});

Ok(Self {
pipeline: device.create_render_pipeline(&RenderPipelineDescriptor {
label: Some("MyRenderPipeline"),
layout: None,
layout: Some(&layout),
vertex: VertexState {
module: &module,
entry_point: None,
entry_point: Some("main_vs"),
compilation_options: Default::default(),
buffers: &[],
},
Expand All @@ -35,7 +66,7 @@ impl MyRenderPipeline {
multisample: MultisampleState::default(),
fragment: Some(FragmentState {
module: &module,
entry_point: None,
entry_point: Some("main_fs"),
compilation_options: Default::default(),
targets: &[Some(ColorTargetState {
format: out_format,
Expand Down
Loading