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

This commit is contained in:
XAMPPRocky 2021-05-03 13:19:10 +02:00 committed by GitHub
parent 1431c18b9d
commit 2f451ee993
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 87 additions and 45 deletions

View File

@ -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};
@ -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 {

View File

@ -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(),

View File

@ -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};

View File

@ -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)
})?))
}
}
}

View File

@ -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));

View File

@ -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();
}
}

View File

@ -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};
@ -6,8 +7,6 @@ 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>();

View File

@ -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};
@ -6,8 +7,6 @@ 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>());

View File

@ -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};
@ -6,8 +7,6 @@ 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>();

View File

@ -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};
@ -6,8 +7,6 @@ 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>();

View File

@ -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};
@ -6,8 +7,6 @@ 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>();

View File

@ -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};
@ -6,8 +7,6 @@ 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>();

View File

@ -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};
@ -6,8 +7,6 @@ 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>();

View File

@ -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};
@ -6,8 +7,6 @@ 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>();

View File

@ -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};
@ -6,8 +7,6 @@ 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();

View File

@ -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};
@ -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(

View File

@ -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};
@ -6,8 +7,6 @@ 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());

View File

@ -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};
@ -6,8 +7,6 @@ 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();

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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)
@ -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,

View File

@ -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" -> ""
@ -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",

View File

@ -1,5 +1,5 @@
OpCapability Shader
OpCapability RuntimeDescriptorArray
OpCapability Shader
OpExtension "SPV_EXT_descriptor_indexing"
OpMemoryModel Logical Simple
OpEntryPoint Fragment %1 "main"

View File

@ -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 _;
@ -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",

View File

@ -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

View File

@ -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() }
}

View File

@ -0,0 +1,4 @@
error: Invalid Capability: `rayTracingKHR`
error: aborting due to previous error