I wanted to write a simple renderer using WGPU-rs and I stumbled upon this.
BTW, The laptops we have both utilize PRIME, in other words they both have an Intel and a NVidia GPU.
This is all the code imo relevant to the issue.
pub fn new(window: &Window) -> Self {
let size = window.inner_size();
let surface = wgpu::Surface::create(window);
let adapter = wgpu::Adapter::request(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default
}, wgpu::BackendBit::PRIMARY).unwrap(); // @TODO handle error
let (device, queue) = adapter.request_device(&wgpu::DeviceDescriptor{
extensions: wgpu::Extensions {
anisotropic_filtering: false
},
limits: Default::default()
});
let sc_desc = wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
format: wgpu::TextureFormat::Bgra8UnormSrgb, // @TODO handle better when the formats can be queried
width: size.width,
height: size.height,
present_mode: wgpu::PresentMode::Vsync
};
let swap_chain = device.create_swap_chain(&surface, &sc_desc);
let (vertex_shader, fragment_shader) = {
let mut compiler = shaderc::Compiler::new().unwrap(); // @TODO handle
let vertex_shader = include_str!("../glsl/vertex.glsl");
let fragment_shader = include_str!("../glsl/fragment.glsl");
let vertex_shader = compiler.compile_into_spirv(vertex_shader, shaderc::ShaderKind::Vertex, "vertex.glsl", "main", None).unwrap();
let fragment_shader = compiler.compile_into_spirv(fragment_shader, shaderc::ShaderKind::Vertex, "fragment.glsl", "main", None).unwrap();
(device.create_shader_module(vertex_shader.as_binary()), device.create_shader_module(fragment_shader.as_binary()))
};
let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
bind_group_layouts: &[]
});
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
layout: &render_pipeline_layout,
vertex_stage: wgpu::ProgrammableStageDescriptor {
module: &vertex_shader,
entry_point: "main"
},
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
module: &fragment_shader,
entry_point: "main"
}),
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
front_face: wgpu::FrontFace::Ccw,
cull_mode: wgpu::CullMode::Back,
depth_bias: 0,
depth_bias_slope_scale: 0.0,
depth_bias_clamp: 0.0
}),
color_states: &[
wgpu::ColorStateDescriptor {
format: sc_desc.format,
color_blend: wgpu::BlendDescriptor::REPLACE,
alpha_blend: wgpu::BlendDescriptor::REPLACE,
write_mask: wgpu::ColorWrite::ALL
}
],
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
depth_stencil_state: None,
index_format: wgpu::IndexFormat::Uint16,
vertex_buffers: &[
Vertex::desc()
],
sample_count: 1,
sample_mask: !0,
alpha_to_coverage_enabled: false
});
Self {
vertex_shader,
fragment_shader,
surface,
adapter,
device,
queue,
sc_desc,
swap_chain,
render_pipeline,
size
}
}
// Open Window
let event_loop = EventLoop::new();
// winit & wgpu setup
let (window, size, surface) = {
let window = WindowBuilder::new()
.with_title("ra-engine-rs")
.build(&event_loop)
.unwrap();
let size = window.inner_size();
let surface = wgpu::Surface::create(&window);
(window, size, surface)
};
let mut renderer = system::renderer::Renderer::new(&window);
I sadly don't how to use gdb, so I'll provide screenshots from CLion>

That is the stacktrace CLion spits out after it segfaults, before that is some assembly code, which I don't understand, if you want to see the addresses tell me and I'll provide.
pub unsafe fn create_graphics_pipelines(
&self,
device: Device,
pipeline_cache: PipelineCache,
create_info_count: u32,
p_create_infos: *const GraphicsPipelineCreateInfo,
p_allocator: *const AllocationCallbacks,
p_pipelines: *mut Pipeline,
) -> Result {
(self.create_graphics_pipelines)(
device,
pipeline_cache,
create_info_count,
p_create_infos,
p_allocator,
p_pipelines,
)
}
pub create_graphics_pipelines: extern "system" fn(
device: Device,
pipeline_cache: PipelineCache,
create_info_count: u32,
p_create_infos: *const GraphicsPipelineCreateInfo,
p_allocator: *const AllocationCallbacks,
p_pipelines: *mut Pipeline,
) -> Result,
These are the last two readable functions, kind of.
Thanks for your help, if some other piece of information could be relevant I'll gladly provide said information.
EDIT: The segfault happens inside ash, if this issue is more relevant to ash, I'll close this and post there
Thanks for reporting the issue! One issue seems to be in the line
let fragment_shader = compiler.compile_into_spirv(fragment_shader, shaderc::ShaderKind::Vertex, "fragment.glsl", "main", None).unwrap();
which compiles fragment.glsl as a vertex shader (shaderc::ShaderKind::Vertex). wgpu doesn't validate shaders yet, so we probably aren't able to fail gracefully in this case.
Oh right, I'll fix that and test again.
I fixed it and it still segfaults. BTW here is the full source code, I don't think there is anything relevant, but if we can't figure it out, it still might help.
I can continue looking later but FWIW that branch seems to run fine using cargo run on macOS/Metal and Windows 10/Vulkan (I did have to remove the line log4rs::init_file("data/log4rs.yaml", Default::default()).unwrap(); because I'm missing that file)
Hmm, it works on my desktop, but not on my laptop, neither it does on my friends laptop, it must be something PRIME related, did I mention I'm testing everything on Linux?
EDIT: I copied the .elf from my desktop onto my laptop just to be it's the same code running
@MagicRB is the segfault in the same place? If not, could you provide the stack trace?
Are you running with validation layers installed? If not, please install them and run again to see if there are any validation errors.
I appear to have found the issue, if I pass the VertexBufferDescriptor into the RenderPipelineDescriptor, but I do not set any buffers and attempt to render, it segfaults, I'm pretty sure it doesn't do that on my desktop, I'll check once I get home.
Alright, moving to https://github.com/gfx-rs/wgpu/issues/487
Most helpful comment
Oh right, I'll fix that and test again.