mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
[msl] fix vertex pulling with a stride of 0 (#8265)
This commit is contained in:
parent
3375284f16
commit
ce96254f4f
@ -18,7 +18,7 @@ webgpu:api,operation,compute,basic:memcpy:*
|
|||||||
webgpu:api,operation,compute_pipeline,overrides:*
|
webgpu:api,operation,compute_pipeline,overrides:*
|
||||||
webgpu:api,operation,device,lost:*
|
webgpu:api,operation,device,lost:*
|
||||||
webgpu:api,operation,render_pass,storeOp:*
|
webgpu:api,operation,render_pass,storeOp:*
|
||||||
fails-if(metal,vulkan) webgpu:api,operation,vertex_state,correctness:array_stride_zero:*
|
fails-if(vulkan) webgpu:api,operation,vertex_state,correctness:array_stride_zero:*
|
||||||
// Presumably vertex pulling, revisit after https://github.com/gfx-rs/wgpu/issues/7981 is fixed.
|
// Presumably vertex pulling, revisit after https://github.com/gfx-rs/wgpu/issues/7981 is fixed.
|
||||||
fails-if(metal) webgpu:api,operation,vertex_state,correctness:setVertexBuffer_offset_and_attribute_offset:*
|
fails-if(metal) webgpu:api,operation,vertex_state,correctness:setVertexBuffer_offset_and_attribute_offset:*
|
||||||
fails-if(dx12) webgpu:api,validation,capability_checks,limits,maxBindGroups:setBindGroup,*
|
fails-if(dx12) webgpu:api,validation,capability_checks,limits,maxBindGroups:setBindGroup,*
|
||||||
|
|||||||
@ -418,6 +418,17 @@ pub enum VertexFormat {
|
|||||||
Unorm8x4Bgra = 44,
|
Unorm8x4Bgra = 44,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Defines how to advance the data in vertex buffers.
|
||||||
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
|
||||||
|
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
|
||||||
|
pub enum VertexBufferStepMode {
|
||||||
|
Constant,
|
||||||
|
#[default]
|
||||||
|
ByVertex,
|
||||||
|
ByInstance,
|
||||||
|
}
|
||||||
|
|
||||||
/// A mapping of vertex buffers and their attributes to shader
|
/// A mapping of vertex buffers and their attributes to shader
|
||||||
/// locations.
|
/// locations.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
@ -446,9 +457,8 @@ pub struct VertexBufferMapping {
|
|||||||
pub id: u32,
|
pub id: u32,
|
||||||
/// Size of the structure in bytes
|
/// Size of the structure in bytes
|
||||||
pub stride: u32,
|
pub stride: u32,
|
||||||
/// True if the buffer is indexed by vertex, false if indexed
|
/// Vertex buffer step mode
|
||||||
/// by instance.
|
pub step_mode: VertexBufferStepMode,
|
||||||
pub indexed_by_vertex: bool,
|
|
||||||
/// Vec of the attributes within the structure
|
/// Vec of the attributes within the structure
|
||||||
pub attributes: Vec<AttributeMapping>,
|
pub attributes: Vec<AttributeMapping>,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6359,7 +6359,7 @@ template <typename A>
|
|||||||
struct VertexBufferMappingResolved<'a> {
|
struct VertexBufferMappingResolved<'a> {
|
||||||
id: u32,
|
id: u32,
|
||||||
stride: u32,
|
stride: u32,
|
||||||
indexed_by_vertex: bool,
|
step_mode: back::msl::VertexBufferStepMode,
|
||||||
ty_name: String,
|
ty_name: String,
|
||||||
param_name: String,
|
param_name: String,
|
||||||
elem_name: String,
|
elem_name: String,
|
||||||
@ -6395,10 +6395,14 @@ template <typename A>
|
|||||||
"Vertex pulling requires a non-zero buffer stride."
|
"Vertex pulling requires a non-zero buffer stride."
|
||||||
);
|
);
|
||||||
|
|
||||||
if vbm.indexed_by_vertex {
|
match vbm.step_mode {
|
||||||
needs_vertex_id = true;
|
back::msl::VertexBufferStepMode::Constant => {}
|
||||||
} else {
|
back::msl::VertexBufferStepMode::ByVertex => {
|
||||||
needs_instance_id = true;
|
needs_vertex_id = true;
|
||||||
|
}
|
||||||
|
back::msl::VertexBufferStepMode::ByInstance => {
|
||||||
|
needs_instance_id = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let buffer_ty = self.namer.call(format!("vb_{buffer_id}_type").as_str());
|
let buffer_ty = self.namer.call(format!("vb_{buffer_id}_type").as_str());
|
||||||
@ -6408,7 +6412,7 @@ template <typename A>
|
|||||||
vbm_resolved.push(VertexBufferMappingResolved {
|
vbm_resolved.push(VertexBufferMappingResolved {
|
||||||
id: buffer_id,
|
id: buffer_id,
|
||||||
stride: buffer_stride,
|
stride: buffer_stride,
|
||||||
indexed_by_vertex: vbm.indexed_by_vertex,
|
step_mode: vbm.step_mode,
|
||||||
ty_name: buffer_ty,
|
ty_name: buffer_ty,
|
||||||
param_name: buffer_param,
|
param_name: buffer_param,
|
||||||
elem_name: buffer_elem,
|
elem_name: buffer_elem,
|
||||||
@ -7199,8 +7203,6 @@ template <typename A>
|
|||||||
}
|
}
|
||||||
|
|
||||||
if do_vertex_pulling {
|
if do_vertex_pulling {
|
||||||
assert!(needs_vertex_id || needs_instance_id);
|
|
||||||
|
|
||||||
let mut separator = if is_first_argument {
|
let mut separator = if is_first_argument {
|
||||||
is_first_argument = false;
|
is_first_argument = false;
|
||||||
' '
|
' '
|
||||||
@ -7278,16 +7280,22 @@ template <typename A>
|
|||||||
|
|
||||||
let idx = &vbm.id;
|
let idx = &vbm.id;
|
||||||
let stride = &vbm.stride;
|
let stride = &vbm.stride;
|
||||||
let index_name = if vbm.indexed_by_vertex {
|
let index_name = match vbm.step_mode {
|
||||||
if let Some(ref name) = v_existing_id {
|
back::msl::VertexBufferStepMode::Constant => "0",
|
||||||
name
|
back::msl::VertexBufferStepMode::ByVertex => {
|
||||||
} else {
|
if let Some(ref name) = v_existing_id {
|
||||||
&v_id
|
name
|
||||||
|
} else {
|
||||||
|
&v_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
back::msl::VertexBufferStepMode::ByInstance => {
|
||||||
|
if let Some(ref name) = i_existing_id {
|
||||||
|
name
|
||||||
|
} else {
|
||||||
|
&i_id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if let Some(ref name) = i_existing_id {
|
|
||||||
name
|
|
||||||
} else {
|
|
||||||
&i_id
|
|
||||||
};
|
};
|
||||||
write!(
|
write!(
|
||||||
self.out,
|
self.out,
|
||||||
|
|||||||
@ -49,5 +49,5 @@ attributes = [
|
|||||||
{ offset = 640, shader_location = 40, format = "unorm8x4-bgra" },
|
{ offset = 640, shader_location = 40, format = "unorm8x4-bgra" },
|
||||||
]
|
]
|
||||||
id = 1
|
id = 1
|
||||||
indexed_by_vertex = true
|
step_mode = "ByVertex"
|
||||||
stride = 644
|
stride = 644
|
||||||
|
|||||||
@ -49,5 +49,5 @@ attributes = [
|
|||||||
{ offset = 640, shader_location = 40, format = "unorm8x4-bgra" },
|
{ offset = 640, shader_location = 40, format = "unorm8x4-bgra" },
|
||||||
]
|
]
|
||||||
id = 1
|
id = 1
|
||||||
indexed_by_vertex = true
|
step_mode = "ByVertex"
|
||||||
stride = 644
|
stride = 644
|
||||||
|
|||||||
@ -49,5 +49,5 @@ attributes = [
|
|||||||
{ offset = 640, shader_location = 40, format = "unorm8x4-bgra" },
|
{ offset = 640, shader_location = 40, format = "unorm8x4-bgra" },
|
||||||
]
|
]
|
||||||
id = 1
|
id = 1
|
||||||
indexed_by_vertex = true
|
step_mode = "ByVertex"
|
||||||
stride = 644
|
stride = 644
|
||||||
|
|||||||
@ -49,5 +49,5 @@ attributes = [
|
|||||||
{ offset = 640, shader_location = 40, format = "unorm8x4-bgra" },
|
{ offset = 640, shader_location = 40, format = "unorm8x4-bgra" },
|
||||||
]
|
]
|
||||||
id = 1
|
id = 1
|
||||||
indexed_by_vertex = true
|
step_mode = "ByVertex"
|
||||||
stride = 644
|
stride = 644
|
||||||
|
|||||||
@ -10,11 +10,11 @@ attributes = [
|
|||||||
{ offset = 4, shader_location = 1, format = "Float32x4" },
|
{ offset = 4, shader_location = 1, format = "Float32x4" },
|
||||||
]
|
]
|
||||||
id = 1
|
id = 1
|
||||||
indexed_by_vertex = true
|
step_mode = "ByVertex"
|
||||||
stride = 20
|
stride = 20
|
||||||
|
|
||||||
[[msl_pipeline.vertex_buffer_mappings]]
|
[[msl_pipeline.vertex_buffer_mappings]]
|
||||||
attributes = [{ offset = 0, shader_location = 2, format = "Float32x2" }]
|
attributes = [{ offset = 0, shader_location = 2, format = "Float32x2" }]
|
||||||
id = 2
|
id = 2
|
||||||
indexed_by_vertex = false
|
step_mode = "ByInstance"
|
||||||
stride = 16
|
stride = 16
|
||||||
|
|||||||
@ -3,7 +3,7 @@ use wgpu::{
|
|||||||
vertex_attr_array,
|
vertex_attr_array,
|
||||||
};
|
};
|
||||||
use wgpu_test::{
|
use wgpu_test::{
|
||||||
gpu_test, FailureCase, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext,
|
gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn all_tests(vec: &mut Vec<GpuTestInitializer>) {
|
pub fn all_tests(vec: &mut Vec<GpuTestInitializer>) {
|
||||||
@ -12,11 +12,7 @@ pub fn all_tests(vec: &mut Vec<GpuTestInitializer>) {
|
|||||||
|
|
||||||
#[gpu_test]
|
#[gpu_test]
|
||||||
static SET_ARRAY_STRIDE_TO_0: GpuTestConfiguration = GpuTestConfiguration::new()
|
static SET_ARRAY_STRIDE_TO_0: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||||
.parameters(
|
.parameters(TestParameters::default().limits(wgpu::Limits::downlevel_defaults()))
|
||||||
TestParameters::default()
|
|
||||||
.limits(wgpu::Limits::downlevel_defaults())
|
|
||||||
.expect_fail(FailureCase::backend(wgpu::Backends::METAL)),
|
|
||||||
)
|
|
||||||
.run_async(set_array_stride_to_0);
|
.run_async(set_array_stride_to_0);
|
||||||
|
|
||||||
/// Tests that draws using a vertex buffer with stride of 0 works correctly (especially on the
|
/// Tests that draws using a vertex buffer with stride of 0 works correctly (especially on the
|
||||||
|
|||||||
@ -1154,7 +1154,15 @@ impl crate::Device for super::Device {
|
|||||||
.try_into()
|
.try_into()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
},
|
},
|
||||||
indexed_by_vertex: (vbl.step_mode == wgt::VertexStepMode::Vertex {}),
|
step_mode: match (vbl.array_stride == 0, vbl.step_mode) {
|
||||||
|
(true, _) => naga::back::msl::VertexBufferStepMode::Constant,
|
||||||
|
(false, wgt::VertexStepMode::Vertex) => {
|
||||||
|
naga::back::msl::VertexBufferStepMode::ByVertex
|
||||||
|
}
|
||||||
|
(false, wgt::VertexStepMode::Instance) => {
|
||||||
|
naga::back::msl::VertexBufferStepMode::ByInstance
|
||||||
|
}
|
||||||
|
},
|
||||||
attributes,
|
attributes,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user