Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
12 changes: 5 additions & 7 deletions crates/rustc_codegen_spirv/src/builder/builder_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::custom_insts::CustomInst;
use crate::spirv_type::SpirvType;
use itertools::Itertools;
use rspirv::dr::{InsertPoint, Instruction, Operand};
use rspirv::spirv::{Capability, MemoryModel, MemorySemantics, Op, Scope, StorageClass, Word};
use rspirv::spirv::{MemoryModel, MemorySemantics, Op, Scope, StorageClass, Word};
use rustc_abi::{Align, BackendRepr, Scalar, Size, WrappingRange};
use rustc_apfloat::{Float, Round, Status, ieee};
use rustc_codegen_ssa::MemFlags;
Expand Down Expand Up @@ -569,12 +569,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {

#[instrument(level = "trace", skip(self))]
fn zombie_ptr_equal(&self, def: Word, inst: &str) {
if !self.builder.has_capability(Capability::VariablePointers) {
self.zombie(
def,
&format!("{inst} without OpCapability VariablePointers"),
);
}
self.zombie(
def,
&format!("{inst} without OpCapability VariablePointers"),
);
}

/// Convenience wrapper for `adjust_pointer_for_sized_access`, falling back
Expand Down
25 changes: 10 additions & 15 deletions crates/rustc_codegen_spirv/src/builder/byte_addressable_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use crate::builder_spirv::{SpirvValue, SpirvValueExt, SpirvValueKind};
use crate::spirv_type::SpirvType;
use rspirv::spirv::{Decoration, Word};
use rustc_abi::{Align, Size};
use rustc_codegen_spirv_types::Capability;
use rustc_codegen_ssa::traits::BuilderMethods;
use rustc_errors::ErrorGuaranteed;
use rustc_middle::ty::Ty;
Expand Down Expand Up @@ -50,13 +49,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
.in_bounds_access_chain(u32_ptr, None, array, [actual_index])
.unwrap()
.with_type(u32_ptr);
if self.builder.has_capability(Capability::ShaderNonUniform) {
// apply NonUniform to the operation and the index
self.emit()
.decorate(ptr.def(self), Decoration::NonUniform, []);
self.emit()
.decorate(actual_index, Decoration::NonUniform, []);
}
// apply NonUniform to the operation and the index
self.emit()
.decorate(ptr.def(self), Decoration::NonUniform, []);
self.emit()
.decorate(actual_index, Decoration::NonUniform, []);
self.load(u32_ty, ptr, Align::ONE)
}

Expand Down Expand Up @@ -252,13 +249,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
.in_bounds_access_chain(u32_ptr, None, array, [actual_index])
.unwrap()
.with_type(u32_ptr);
if self.builder.has_capability(Capability::ShaderNonUniform) {
// apply NonUniform to the operation and the index
self.emit()
.decorate(ptr.def(self), Decoration::NonUniform, []);
self.emit()
.decorate(actual_index, Decoration::NonUniform, []);
}
// apply NonUniform to the operation and the index
self.emit()
.decorate(ptr.def(self), Decoration::NonUniform, []);
self.emit()
.decorate(actual_index, Decoration::NonUniform, []);
self.store(value, ptr, Align::ONE);
Ok(())
}
Expand Down
46 changes: 7 additions & 39 deletions crates/rustc_codegen_spirv/src/builder_spirv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@ use rspirv::{binary::Assemble, binary::Disassemble};
use rustc_abi::Size;
use rustc_arena::DroplessArena;
use rustc_codegen_ssa::traits::ConstCodegenMethods as _;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::fx::FxHashMap;
use rustc_middle::bug;
use rustc_middle::mir::interpret::ConstAllocation;
use rustc_middle::ty::TyCtxt;
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::Symbol;
use rustc_span::{DUMMY_SP, FileName, FileNameDisplayPreference, SourceFile, Span};
use std::assert_matches::assert_matches;
use std::cell::{RefCell, RefMut};
Expand Down Expand Up @@ -443,8 +442,6 @@ pub struct BuilderSpirv<'tcx> {
id_to_const: RefCell<FxHashMap<Word, WithConstLegality<SpirvConst<'tcx, 'tcx>>>>,

debug_file_cache: RefCell<FxHashMap<DebugFileKey, DebugFileSpirv<'tcx>>>,

enabled_capabilities: FxHashSet<Capability>,
}

impl<'tcx> BuilderSpirv<'tcx> {
Expand All @@ -461,50 +458,26 @@ impl<'tcx> BuilderSpirv<'tcx> {
builder.set_version(version.0, version.1);
builder.module_mut().header.as_mut().unwrap().generator = 0x001B_0000;

let mut enabled_capabilities = FxHashSet::default();

fn add_cap(
builder: &mut Builder,
enabled_capabilities: &mut FxHashSet<Capability>,
cap: Capability,
) {
// This should be the only callsite of Builder::capability (aside from tests), to make
// sure the hashset stays in sync.
builder.capability(cap);
enabled_capabilities.insert(cap);
}
fn add_ext(builder: &mut Builder, ext: Symbol) {
// This should be the only callsite of Builder::extension (aside from tests), to make
// sure the hashset stays in sync.
builder.extension(ext.as_str());
}

for feature in features {
match *feature {
TargetFeature::Capability(cap) => {
add_cap(&mut builder, &mut enabled_capabilities, cap);
builder.capability(cap);
}
TargetFeature::Extension(ext) => {
add_ext(&mut builder, ext);
builder.extension(ext.as_str());
}
}
}

add_cap(&mut builder, &mut enabled_capabilities, Capability::Shader);
builder.capability(Capability::Shader);
if memory_model == MemoryModel::Vulkan {
if version < (1, 5) {
add_ext(&mut builder, sym.spv_khr_vulkan_memory_model);
builder.extension(sym.spv_khr_vulkan_memory_model.as_str());
}
add_cap(
&mut builder,
&mut enabled_capabilities,
Capability::VulkanMemoryModel,
);
builder.capability(Capability::VulkanMemoryModel);
}

// The linker will always be ran on this module
add_cap(&mut builder, &mut enabled_capabilities, Capability::Linkage);

builder.capability(Capability::Linkage);
builder.memory_model(AddressingModel::Logical, memory_model);

Self {
Expand All @@ -514,7 +487,6 @@ impl<'tcx> BuilderSpirv<'tcx> {
const_to_id: Default::default(),
id_to_const: Default::default(),
debug_file_cache: Default::default(),
enabled_capabilities,
}
}

Expand All @@ -535,10 +507,6 @@ impl<'tcx> BuilderSpirv<'tcx> {
.unwrap();
}

pub fn has_capability(&self, capability: Capability) -> bool {
self.enabled_capabilities.contains(&capability)
}

/// See comment on `BuilderCursor`
fn builder(&self, cursor: BuilderCursor) -> RefMut<'_, Builder> {
let mut builder = self.builder.borrow_mut();
Expand Down
8 changes: 2 additions & 6 deletions crates/rustc_codegen_spirv/src/codegen_cx/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::builder_spirv::{SpirvFunctionCursor, SpirvValue, SpirvValueExt};
use crate::spirv_type::SpirvType;
use rspirv::dr::Operand;
use rspirv::spirv::{
BuiltIn, Capability, Decoration, Dim, ExecutionModel, FunctionControl, StorageClass, Word,
BuiltIn, Decoration, Dim, ExecutionModel, FunctionControl, StorageClass, Word,
};
use rustc_abi::FieldsShape;
use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, BuilderMethods, MiscCodegenMethods as _};
Expand Down Expand Up @@ -931,16 +931,12 @@ impl<'tcx> CodegenCx<'tcx> {
_ => false,
};
if let Some(attachment_index) = attrs.input_attachment_index {
if is_subpass_input && self.builder.has_capability(Capability::InputAttachment) {
if is_subpass_input {
self.emit_global().decorate(
var_id.unwrap(),
Decoration::InputAttachmentIndex,
std::iter::once(Operand::LiteralBit32(attachment_index.value)),
);
} else if is_subpass_input {
self.tcx
.dcx()
.span_err(hir_param.ty_span, "Missing capability InputAttachment");
} else {
self.tcx.dcx().span_err(
attachment_index.span,
Expand Down
34 changes: 34 additions & 0 deletions tests/compiletests/ui/arch/non_uniform/buffer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// build-pass
// compile-flags: -C llvm-args=--disassemble
// compile-flags: -C target-feature=+RuntimeDescriptorArray,+StorageBufferArrayDynamicIndexing
// compile-flags: -C target-feature=+ShaderNonUniform,+StorageBufferArrayNonUniformIndexing
// normalize-stderr-test "OpSource .*\n" -> ""
// normalize-stderr-test "OpLine .*\n" -> ""
// normalize-stderr-test "%\d+ = OpString .*\n" -> ""
// normalize-stderr-test "; .*\n" -> ""
// normalize-stderr-test "OpCapability VulkanMemoryModel\n" -> ""
// normalize-stderr-test "OpMemoryModel Logical Vulkan" -> "OpMemoryModel Logical Simple"
// ignore-spv1.0
// ignore-spv1.1
// ignore-spv1.2
// ignore-spv1.3
// ignore-spv1.4
// ignore-vulkan1.0
// ignore-vulkan1.1

use spirv_std::glam::*;
use spirv_std::image::*;
use spirv_std::*;

#[spirv(vertex)]
pub fn main(
index: u32,
#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buffers: &RuntimeArray<
TypedBuffer<Vec4>,
>,
out: &mut Vec4,
) {
unsafe {
*out = **buffers.index(index as usize);
}
}
44 changes: 44 additions & 0 deletions tests/compiletests/ui/arch/non_uniform/buffer.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
OpCapability Shader
OpCapability StorageBufferArrayDynamicIndexing
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability StorageBufferArrayNonUniformIndexing
OpMemoryModel Logical Simple
OpEntryPoint Vertex %1 "main" %2 %3 %4
OpName %2 "index"
OpName %3 "buffers"
OpName %4 "out"
OpDecorate %8 Block
OpMemberDecorate %8 0 Offset 0
OpDecorate %2 Location 0
OpDecorate %3 NonWritable
OpDecorate %3 Binding 0
OpDecorate %3 DescriptorSet 0
OpDecorate %4 Location 0
OpDecorate %9 NonUniform
%10 = OpTypeInt 32 0
%11 = OpTypePointer Input %10
%12 = OpTypeFloat 32
%13 = OpTypeVector %12 4
%8 = OpTypeStruct %13
%14 = OpTypeRuntimeArray %8
%15 = OpTypePointer StorageBuffer %14
%16 = OpTypePointer Output %13
%17 = OpTypeVoid
%18 = OpTypeFunction %17
%2 = OpVariable %11 Input
%19 = OpTypePointer StorageBuffer %8
%3 = OpVariable %15 StorageBuffer
%20 = OpTypePointer StorageBuffer %13
%21 = OpConstant %10 0
%4 = OpVariable %16 Output
%1 = OpFunction %17 None %18
%22 = OpLabel
%23 = OpLoad %10 %2
%9 = OpAccessChain %19 %3 %23
%24 = OpAccessChain %20 %9 %21
%25 = OpLoad %13 %24
OpStore %4 %25
OpNoLine
OpReturn
OpFunctionEnd
33 changes: 33 additions & 0 deletions tests/compiletests/ui/arch/non_uniform/buffer_uniform.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// build-pass
// compile-flags: -C llvm-args=--disassemble
// compile-flags: -C target-feature=+RuntimeDescriptorArray,+StorageBufferArrayDynamicIndexing
// normalize-stderr-test "OpSource .*\n" -> ""
// normalize-stderr-test "OpLine .*\n" -> ""
// normalize-stderr-test "%\d+ = OpString .*\n" -> ""
// normalize-stderr-test "; .*\n" -> ""
// normalize-stderr-test "OpCapability VulkanMemoryModel\n" -> ""
// normalize-stderr-test "OpMemoryModel Logical Vulkan" -> "OpMemoryModel Logical Simple"
// ignore-spv1.0
// ignore-spv1.1
// ignore-spv1.2
// ignore-spv1.3
// ignore-spv1.4
// ignore-vulkan1.0
// ignore-vulkan1.1

use spirv_std::glam::*;
use spirv_std::image::*;
use spirv_std::*;

#[spirv(vertex)]
pub fn main(
index: u32,
#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buffers: &RuntimeArray<
TypedBuffer<Vec4>,
>,
out: &mut Vec4,
) {
unsafe {
*out = **buffers.index(index as usize);
}
}
41 changes: 41 additions & 0 deletions tests/compiletests/ui/arch/non_uniform/buffer_uniform.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
OpCapability Shader
OpCapability StorageBufferArrayDynamicIndexing
OpCapability RuntimeDescriptorArray
OpMemoryModel Logical Simple
OpEntryPoint Vertex %1 "main" %2 %3 %4
OpName %2 "index"
OpName %3 "buffers"
OpName %4 "out"
OpDecorate %8 Block
OpMemberDecorate %8 0 Offset 0
OpDecorate %2 Location 0
OpDecorate %3 NonWritable
OpDecorate %3 Binding 0
OpDecorate %3 DescriptorSet 0
OpDecorate %4 Location 0
%9 = OpTypeInt 32 0
%10 = OpTypePointer Input %9
%11 = OpTypeFloat 32
%12 = OpTypeVector %11 4
%8 = OpTypeStruct %12
%13 = OpTypeRuntimeArray %8
%14 = OpTypePointer StorageBuffer %13
%15 = OpTypePointer Output %12
%16 = OpTypeVoid
%17 = OpTypeFunction %16
%2 = OpVariable %10 Input
%18 = OpTypePointer StorageBuffer %8
%3 = OpVariable %14 StorageBuffer
%19 = OpTypePointer StorageBuffer %12
%20 = OpConstant %9 0
%4 = OpVariable %15 Output
%1 = OpFunction %16 None %17
%21 = OpLabel
%22 = OpLoad %9 %2
%23 = OpAccessChain %18 %3 %22
%24 = OpAccessChain %19 %23 %20
%25 = OpLoad %12 %24
OpStore %4 %25
OpNoLine
OpReturn
OpFunctionEnd
32 changes: 32 additions & 0 deletions tests/compiletests/ui/arch/non_uniform/image.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// build-pass
// compile-flags: -C llvm-args=--disassemble
// compile-flags: -C target-feature=+RuntimeDescriptorArray,+SampledImageArrayDynamicIndexing
// compile-flags: -C target-feature=+ShaderNonUniform,+SampledImageArrayNonUniformIndexing
// normalize-stderr-test "OpSource .*\n" -> ""
// normalize-stderr-test "OpLine .*\n" -> ""
// normalize-stderr-test "%\d+ = OpString .*\n" -> ""
// normalize-stderr-test "; .*\n" -> ""
// normalize-stderr-test "OpCapability VulkanMemoryModel\n" -> ""
// normalize-stderr-test "OpMemoryModel Logical Vulkan" -> "OpMemoryModel Logical Simple"
// ignore-spv1.0
// ignore-spv1.1
// ignore-spv1.2
// ignore-spv1.3
// ignore-spv1.4
// ignore-vulkan1.0
// ignore-vulkan1.1

use spirv_std::glam::*;
use spirv_std::image::*;
use spirv_std::*;

#[spirv(vertex)]
pub fn main(
index: u32,
#[spirv(descriptor_set = 0, binding = 0)] images: &RuntimeArray<Image2d>,
out: &mut Vec4,
) {
unsafe {
*out = images.index(index as usize).fetch(UVec2::new(1, 2));
}
}
Loading
Loading