mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-21 22:34:34 +00:00
Add support for using target-features for extensions and capabilities (#610)
This commit is contained in:
parent
1431c18b9d
commit
2f451ee993
@ -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 {
|
||||
|
@ -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(),
|
||||
|
@ -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};
|
||||
|
23
crates/rustc_codegen_spirv/src/target_feature.rs
Normal file
23
crates/rustc_codegen_spirv/src/target_feature.rs
Normal 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)
|
||||
})?))
|
||||
}
|
||||
}
|
||||
}
|
@ -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));
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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>();
|
||||
|
@ -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>());
|
||||
|
@ -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>();
|
||||
|
@ -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>();
|
||||
|
@ -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>();
|
||||
|
@ -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>();
|
||||
|
@ -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>();
|
||||
|
@ -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>();
|
||||
|
@ -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();
|
||||
|
@ -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(
|
||||
|
@ -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());
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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",
|
||||
|
@ -1,5 +1,5 @@
|
||||
OpCapability Shader
|
||||
OpCapability RuntimeDescriptorArray
|
||||
OpCapability Shader
|
||||
OpExtension "SPV_EXT_descriptor_indexing"
|
||||
OpMemoryModel Logical Simple
|
||||
OpEntryPoint Fragment %1 "main"
|
||||
|
@ -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",
|
||||
|
8
tests/ui/dis/target_features.stderr
Normal file
8
tests/ui/dis/target_features.stderr
Normal 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
|
10
tests/ui/target_features_err.rs
Normal file
10
tests/ui/target_features_err.rs
Normal 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() }
|
||||
}
|
||||
|
4
tests/ui/target_features_err.stderr
Normal file
4
tests/ui/target_features_err.stderr
Normal file
@ -0,0 +1,4 @@
|
||||
error: Invalid Capability: `rayTracingKHR`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Reference in New Issue
Block a user