Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for using target-features for extensions and capabilities #610

Merged
merged 1 commit into from
May 3, 2021
Merged
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
10 changes: 9 additions & 1 deletion crates/rustc_codegen_spirv/src/builder_spirv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::builder;
use crate::codegen_cx::CodegenCx;
use crate::spirv_type::SpirvType;
use crate::target::SpirvTarget;
use crate::target_feature::TargetFeature;
use rspirv::dr::{Block, Builder, Module, Operand};
use rspirv::spirv::{AddressingModel, Capability, MemoryModel, Op, StorageClass, Word};
use rspirv::{binary::Assemble, binary::Disassemble};
Expand Down Expand Up @@ -303,13 +304,20 @@ pub struct BuilderSpirv {
}

impl BuilderSpirv {
pub fn new(target: &SpirvTarget) -> Self {
pub fn new(target: &SpirvTarget, features: &[TargetFeature]) -> Self {
let version = target.spirv_version();
let memory_model = target.memory_model();

let mut builder = Builder::new();
builder.set_version(version.0, version.1);

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

if target.is_kernel() {
builder.capability(Capability::Kernel);
} else {
Expand Down
16 changes: 12 additions & 4 deletions crates/rustc_codegen_spirv/src/codegen_cx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,24 @@ pub struct CodegenCx<'tcx> {
impl<'tcx> CodegenCx<'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, codegen_unit: &'tcx CodegenUnit<'tcx>) -> Self {
let sym = Symbols::get();
for &feature in &tcx.sess.target_features {
tcx.sess.err(&format!("Unknown feature {}", feature));
}
let features = tcx
.sess
.target_features
.iter()
.map(|s| s.as_str().parse())
.collect::<Result<_, String>>()
.unwrap_or_else(|error| {
tcx.sess.err(&error);
Vec::new()
});

let codegen_args = CodegenArgs::from_session(tcx.sess);
let target = tcx.sess.target.llvm_target.parse().unwrap();

Self {
tcx,
codegen_unit,
builder: BuilderSpirv::new(&target),
builder: BuilderSpirv::new(&target, &features),
instances: Default::default(),
function_parameter_values: Default::default(),
type_cache: Default::default(),
Expand Down
1 change: 1 addition & 0 deletions crates/rustc_codegen_spirv/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ mod spirv_type;
mod spirv_type_constraints;
mod symbols;
mod target;
mod target_feature;

use builder::Builder;
use codegen_cx::{CodegenArgs, CodegenCx, ModuleOutputType};
Expand Down
23 changes: 23 additions & 0 deletions crates/rustc_codegen_spirv/src/target_feature.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use rustc_span::symbol::Symbol;

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum TargetFeature {
Extension(Symbol),
Capability(rspirv::spirv::Capability),
}

impl std::str::FromStr for TargetFeature {
type Err = String;

fn from_str(input: &str) -> Result<Self, Self::Err> {
const EXT_PREFIX: &str = "ext:";

if let Some(input) = input.strip_prefix(EXT_PREFIX) {
Ok(Self::Extension(Symbol::intern(input)))
} else {
Ok(Self::Capability(input.parse().map_err(|_err| {
format!("Invalid Capability: `{}`", input)
})?))
}
}
}
4 changes: 1 addition & 3 deletions tests/ui/arch/convert_u_to_acceleration_structure_khr.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayTracingKHR,+ext:SPV_KHR_ray_tracing

#[spirv(ray_generation)]
pub fn main(#[spirv(ray_payload)] payload: &mut glam::Vec3) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_tracing""#);
asm!("OpCapability RayTracingKHR");

let handle = spirv_std::ray_tracing::AccelerationStructure::from_u64(0xffff_ffff);
let handle2 =
spirv_std::ray_tracing::AccelerationStructure::from_vec(glam::UVec2::new(0, 0));
Expand Down
3 changes: 1 addition & 2 deletions tests/ui/arch/ignore_intersection_khr.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayTracingKHR,+ext:SPV_KHR_ray_tracing

#[spirv(any_hit)]
pub fn main() {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_tracing""#);
asm!("OpCapability RayTracingKHR");
spirv_std::arch::ignore_intersection();
}
}
3 changes: 1 addition & 2 deletions tests/ui/arch/ray_query_get_intersection_barycentrics_khr.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};

#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
let barycentric_coords: glam::Vec2 = handle.get_intersection_barycentrics::<_, 5>();
Expand Down
3 changes: 1 addition & 2 deletions tests/ui/arch/ray_query_get_intersection_front_face_khr.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};

#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
assert!(handle.get_intersection_front_face::<5>());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};

#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
let t = handle.get_intersection_geometry_index::<5>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};

#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
let index = handle.get_intersection_instance_custom_index::<5>();
Expand Down
3 changes: 1 addition & 2 deletions tests/ui/arch/ray_query_get_intersection_instance_id_khr.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};

#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
let id = handle.get_intersection_instance_id::<5>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};

#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
let offset = handle.get_intersection_shader_binding_table_record_offset::<5>();
Expand Down
3 changes: 1 addition & 2 deletions tests/ui/arch/ray_query_get_intersection_t_khr.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};

#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
let t = handle.get_intersection_t::<5>();
Expand Down
3 changes: 1 addition & 2 deletions tests/ui/arch/ray_query_get_intersection_type_khr.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};

#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
handle.get_intersection_type::<5>();
Expand Down
3 changes: 1 addition & 2 deletions tests/ui/arch/ray_query_get_ray_t_min_khr.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};

#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
let tmin = handle.get_ray_t_min();
Expand Down
3 changes: 1 addition & 2 deletions tests/ui/arch/ray_query_initialize_khr.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
Expand All @@ -11,8 +12,6 @@ pub fn main(
#[spirv(ray_payload)] payload: &mut Vec3,
) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut ray_query);

ray_query.initialize(
Expand Down
3 changes: 1 addition & 2 deletions tests/ui/arch/ray_query_proceed_khr.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};

#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
assert!(handle.proceed());
Expand Down
3 changes: 1 addition & 2 deletions tests/ui/arch/ray_query_terminate_khr.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};

#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
handle.terminate();
Expand Down
3 changes: 1 addition & 2 deletions tests/ui/arch/report_intersection_khr.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayTracingKHR,+ext:SPV_KHR_ray_tracing

#[spirv(intersection)]
pub fn main() {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_tracing""#);
asm!("OpCapability RayTracingKHR");
spirv_std::arch::report_intersection(2.0, 4);
}
}
3 changes: 1 addition & 2 deletions tests/ui/arch/terminate_ray_khr.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayTracingKHR,+ext:SPV_KHR_ray_tracing

#[spirv(any_hit)]
pub fn main() {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_tracing""#);
asm!("OpCapability RayTracingKHR");
spirv_std::arch::terminate_ray();
}
}
3 changes: 1 addition & 2 deletions tests/ui/arch/trace_ray_khr.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayTracingKHR,+ext:SPV_KHR_ray_tracing

#[spirv(ray_generation)]
// Rustfmt will eat long attributes (https://github.com/rust-lang/rustfmt/issues/4579)
Expand All @@ -9,8 +10,6 @@ pub fn main(
#[spirv(ray_payload)] payload: &mut glam::Vec3,
) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_tracing""#);
asm!("OpCapability RayTracingKHR");
acceleration_structure.trace_ray(
spirv_std::ray_tracing::RayFlags::NONE,
0,
Expand Down
3 changes: 1 addition & 2 deletions tests/ui/dis/asm_op_decorate.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// build-pass
// compile-flags: -C target-feature=+RuntimeDescriptorArray,+ext:SPV_EXT_descriptor_indexing
// compile-flags: -C llvm-args=--disassemble-globals
// normalize-stderr-test "OpCapability VulkanMemoryModel\n" -> ""
// normalize-stderr-test "OpExtension .SPV_KHR_vulkan_memory_model.\n" -> ""
Expand All @@ -10,8 +11,6 @@ fn add_decorate() {
unsafe {
let offset = 1u32;
asm!(
"OpExtension \"SPV_EXT_descriptor_indexing\"",
"OpCapability RuntimeDescriptorArray",
"OpDecorate %image_2d_var DescriptorSet 0",
"OpDecorate %image_2d_var Binding 0",
"%uint = OpTypeInt 32 0",
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/dis/asm_op_decorate.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
OpCapability Shader
OpCapability RuntimeDescriptorArray
OpCapability Shader
OpExtension "SPV_EXT_descriptor_indexing"
OpMemoryModel Logical Simple
OpEntryPoint Fragment %1 "main"
Expand Down
3 changes: 1 addition & 2 deletions tests/ui/dis/complex_image_sample_inst.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// build-pass
// compile-flags: -Ctarget-feature=+RuntimeDescriptorArray,+ext:SPV_EXT_descriptor_indexing
// compile-flags: -C llvm-args=--disassemble-fn=complex_image_sample_inst::sample_proj_lod

use spirv_std as _;
Expand All @@ -14,8 +15,6 @@ fn sample_proj_lod(
let mut result = glam::Vec4::default();
let index = 0u32;
asm!(
"OpExtension \"SPV_EXT_descriptor_indexing\"",
"OpCapability RuntimeDescriptorArray",
"OpDecorate %image_2d_var DescriptorSet 0",
"OpDecorate %image_2d_var Binding 0",
"%uint = OpTypeInt 32 0",
Expand Down
8 changes: 8 additions & 0 deletions tests/ui/dis/target_features.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
OpCapability RayTracingKHR
OpCapability Shader
OpExtension "SPV_KHR_ray_tracing"
OpMemoryModel Logical Simple
OpEntryPoint AnyHitNV %1 "main"
OpName %2 "target_features::main"
%3 = OpTypeVoid
%4 = OpTypeFunction %3
10 changes: 10 additions & 0 deletions tests/ui/target_features_err.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// build-fail
// compile-flags: -Ctarget-feature=+rayTracingKHR,+ext:SPV_KHR_ray_tracing

use spirv_std as _;

#[spirv(any_hit)]
pub fn main() {
unsafe { spirv_std::arch::terminate_ray() }
}

4 changes: 4 additions & 0 deletions tests/ui/target_features_err.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
error: Invalid Capability: `rayTracingKHR`

error: aborting due to previous error