Skip to content

Commit 0068c23

Browse files
committed
mesh shaders: added per_primitive_ext output attribute
1 parent 583f886 commit 0068c23

File tree

4 files changed

+65
-0
lines changed

4 files changed

+65
-0
lines changed

crates/rustc_codegen_spirv/src/attr.rs

+9
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ pub enum SpirvAttribute {
9191
DescriptorSet(u32),
9292
Binding(u32),
9393
Flat,
94+
PerPrimitiveExt,
9495
Invariant,
9596
InputAttachmentIndex(u32),
9697
SpecConstant(SpecConstant),
@@ -127,6 +128,7 @@ pub struct AggregatedSpirvAttributes {
127128
pub binding: Option<Spanned<u32>>,
128129
pub flat: Option<Spanned<()>>,
129130
pub invariant: Option<Spanned<()>>,
131+
pub per_primitive_ext: Option<Spanned<()>>,
130132
pub input_attachment_index: Option<Spanned<u32>>,
131133
pub spec_constant: Option<Spanned<SpecConstant>>,
132134

@@ -213,6 +215,12 @@ impl AggregatedSpirvAttributes {
213215
Binding(value) => try_insert(&mut self.binding, value, span, "#[spirv(binding)]"),
214216
Flat => try_insert(&mut self.flat, (), span, "#[spirv(flat)]"),
215217
Invariant => try_insert(&mut self.invariant, (), span, "#[spirv(invariant)]"),
218+
PerPrimitiveExt => try_insert(
219+
&mut self.per_primitive_ext,
220+
(),
221+
span,
222+
"#[spirv(per_primitive_ext)]",
223+
),
216224
InputAttachmentIndex(value) => try_insert(
217225
&mut self.input_attachment_index,
218226
value,
@@ -314,6 +322,7 @@ impl CheckSpirvAttrVisitor<'_> {
314322
| SpirvAttribute::Binding(_)
315323
| SpirvAttribute::Flat
316324
| SpirvAttribute::Invariant
325+
| SpirvAttribute::PerPrimitiveExt
317326
| SpirvAttribute::InputAttachmentIndex(_)
318327
| SpirvAttribute::SpecConstant(_) => match target {
319328
Target::Param => {

crates/rustc_codegen_spirv/src/codegen_cx/entry.rs

+21
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,27 @@ impl<'tcx> CodegenCx<'tcx> {
708708
self.emit_global()
709709
.decorate(var_id.unwrap(), Decoration::Invariant, std::iter::empty());
710710
}
711+
if let Some(per_primitive_ext) = attrs.per_primitive_ext {
712+
if storage_class != Ok(StorageClass::Output) {
713+
self.tcx.sess.span_fatal(
714+
per_primitive_ext.span,
715+
"`#[spirv(per_primitive_ext)]` is only valid on Output variables",
716+
);
717+
}
718+
if !(execution_model == ExecutionModel::MeshEXT
719+
|| execution_model == ExecutionModel::MeshNV)
720+
{
721+
self.tcx.sess.span_fatal(
722+
per_primitive_ext.span,
723+
"`#[spirv(per_primitive_ext)]` is only valid in mesh shaders",
724+
);
725+
}
726+
self.emit_global().decorate(
727+
var_id.unwrap(),
728+
Decoration::PerPrimitiveEXT,
729+
std::iter::empty(),
730+
);
731+
}
711732

712733
let is_subpass_input = match self.lookup_type(value_spirv_type) {
713734
SpirvType::Image {

crates/rustc_codegen_spirv/src/symbols.rs

+1
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ impl Symbols {
357357
("block", SpirvAttribute::Block),
358358
("flat", SpirvAttribute::Flat),
359359
("invariant", SpirvAttribute::Invariant),
360+
("per_primitive_ext", SpirvAttribute::PerPrimitiveExt),
360361
(
361362
"sampled_image",
362363
SpirvAttribute::IntrinsicType(IntrinsicType::SampledImage),
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// build-pass
2+
// only-vulkan1.2
3+
// compile-flags: -Ctarget-feature=+MeshShadingEXT,+ext:SPV_EXT_mesh_shader
4+
5+
use spirv_std::arch::set_mesh_outputs_ext;
6+
use spirv_std::glam::{UVec3, Vec4};
7+
use spirv_std::spirv;
8+
9+
#[spirv(mesh_ext(
10+
threads(1),
11+
output_vertices = 3,
12+
output_primitives_ext = 1,
13+
output_triangles_ext
14+
))]
15+
pub fn main(
16+
#[spirv(position)] positions: &mut [Vec4; 3],
17+
out_per_vertex: &mut [u32; 3],
18+
#[spirv(per_primitive_ext)] out_per_primitive: &mut [u32; 1],
19+
#[spirv(primitive_triangle_indices_ext)] indices: &mut [UVec3; 1],
20+
) {
21+
unsafe {
22+
set_mesh_outputs_ext(3, 1);
23+
}
24+
25+
positions[0] = Vec4::new(-0.5, 0.5, 0.0, 1.0);
26+
positions[1] = Vec4::new(0.5, 0.5, 0.0, 1.0);
27+
positions[2] = Vec4::new(0.0, -0.5, 0.0, 1.0);
28+
out_per_vertex[0] = 0;
29+
out_per_vertex[1] = 1;
30+
out_per_vertex[2] = 2;
31+
32+
indices[0] = UVec3::new(0, 1, 2);
33+
out_per_primitive[0] = 42;
34+
}

0 commit comments

Comments
 (0)