Skip to content

Commit

Permalink
Add support for using target-features for extensions and capabilities (
Browse files Browse the repository at this point in the history
  • Loading branch information
XAMPPRocky committed May 3, 2021
1 parent 12e737f commit 590d97d
Show file tree
Hide file tree
Showing 27 changed files with 87 additions and 45 deletions.
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

0 comments on commit 590d97d

Please sign in to comment.