Add support for spirv v1.3

This commit is contained in:
khyperia 2020-09-24 18:20:46 +02:00
parent 3e569e3a32
commit 3821aa2060
5 changed files with 52 additions and 36 deletions

View File

@ -1131,10 +1131,12 @@ impl std::fmt::Display for AggregateType {
pub fn link(inputs: &mut [&mut rspirv::dr::Module], opts: &Options) -> Result<rspirv::dr::Module> {
// shift all the ids
let mut bound = inputs[0].header.as_ref().unwrap().bound - 1;
let version = inputs[0].header.as_ref().unwrap().version();
for mut module in inputs.iter_mut().skip(1) {
shift_ids(&mut module, bound);
bound += module.header.as_ref().unwrap().bound - 1;
assert_eq!(version, module.header.as_ref().unwrap().version());
}
// merge the binaries
@ -1184,7 +1186,9 @@ pub fn link(inputs: &mut [&mut rspirv::dr::Module], opts: &Options) -> Result<rs
// compact the ids https://github.com/KhronosGroup/SPIRV-Tools/blob/e02f178a716b0c3c803ce31b9df4088596537872/source/opt/compact_ids_pass.cpp#L43
compact_ids(&mut output)
};
output.header = Some(rspirv::dr::ModuleHeader::new(bound));
let mut header = rspirv::dr::ModuleHeader::new(bound);
header.set_version(version.0, version.1);
output.header = Some(header);
output.debugs.push(rspirv::dr::Instruction::new(
spirv::Op::ModuleProcessed,

View File

@ -5,6 +5,6 @@ authors = ["Ashley Hauck <ashley.hauck@embark-studios.com>"]
edition = "2018"
[dependencies]
ocl = ""
ocl = { version = "", features = ["opencl_version_2_1"] }
[workspace]

View File

@ -976,47 +976,49 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
IntSLE => self.emit().s_less_than_equal(b, None, lhs.def, rhs.def),
},
SpirvType::Pointer { .. } => match op {
IntEQ => self.emit().ptr_equal(b, None, lhs.def, rhs.def),
IntNE => self.emit().ptr_not_equal(b, None, lhs.def, rhs.def),
IntEQ => {
if self.emit().version().unwrap() > (1, 3) {
self.emit().ptr_equal(b, None, lhs.def, rhs.def)
} else {
let int_ty = self.type_usize();
let lhs = self.emit().convert_ptr_to_u(int_ty, None, lhs.def).unwrap();
let rhs = self.emit().convert_ptr_to_u(int_ty, None, rhs.def).unwrap();
self.emit().i_not_equal(b, None, lhs, rhs)
}
}
IntNE => {
if self.emit().version().unwrap() > (1, 3) {
self.emit().ptr_not_equal(b, None, lhs.def, rhs.def)
} else {
let int_ty = self.type_usize();
let lhs = self.emit().convert_ptr_to_u(int_ty, None, lhs.def).unwrap();
let rhs = self.emit().convert_ptr_to_u(int_ty, None, rhs.def).unwrap();
self.emit().i_not_equal(b, None, lhs, rhs)
}
}
IntUGT => {
let ptr_size = self.tcx.data_layout.pointer_size.bits() as u32;
let ptr_diff = SpirvType::Integer(ptr_size, false).def(self);
let diff = self
.emit()
.ptr_diff(ptr_diff, None, lhs.def, rhs.def)
.unwrap();
let zero = self.constant_int(ptr_diff, 0);
self.emit().u_greater_than(b, None, diff, zero.def)
let int_ty = self.type_usize();
let lhs = self.emit().convert_ptr_to_u(int_ty, None, lhs.def).unwrap();
let rhs = self.emit().convert_ptr_to_u(int_ty, None, rhs.def).unwrap();
self.emit().u_greater_than(b, None, lhs, rhs)
}
IntUGE => {
let ptr_size = self.tcx.data_layout.pointer_size.bits() as u32;
let ptr_diff = SpirvType::Integer(ptr_size, false).def(self);
let diff = self
.emit()
.ptr_diff(ptr_diff, None, lhs.def, rhs.def)
.unwrap();
let zero = self.constant_int(ptr_diff, 0);
self.emit().u_greater_than_equal(b, None, diff, zero.def)
let int_ty = self.type_usize();
let lhs = self.emit().convert_ptr_to_u(int_ty, None, lhs.def).unwrap();
let rhs = self.emit().convert_ptr_to_u(int_ty, None, rhs.def).unwrap();
self.emit().u_greater_than_equal(b, None, lhs, rhs)
}
IntULT => {
let ptr_size = self.tcx.data_layout.pointer_size.bits() as u32;
let ptr_diff = SpirvType::Integer(ptr_size, false).def(self);
let diff = self
.emit()
.ptr_diff(ptr_diff, None, lhs.def, rhs.def)
.unwrap();
let zero = self.constant_int(ptr_diff, 0);
self.emit().u_less_than(b, None, diff, zero.def)
let int_ty = self.type_usize();
let lhs = self.emit().convert_ptr_to_u(int_ty, None, lhs.def).unwrap();
let rhs = self.emit().convert_ptr_to_u(int_ty, None, rhs.def).unwrap();
self.emit().u_less_than(b, None, lhs, rhs)
}
IntULE => {
let ptr_size = self.tcx.data_layout.pointer_size.bits() as u32;
let ptr_diff = SpirvType::Integer(ptr_size, false).def(self);
let diff = self
.emit()
.ptr_diff(ptr_diff, None, lhs.def, rhs.def)
.unwrap();
let zero = self.constant_int(ptr_diff, 0);
self.emit().u_less_than_equal(b, None, diff, zero.def)
let int_ty = self.type_usize();
let lhs = self.emit().convert_ptr_to_u(int_ty, None, lhs.def).unwrap();
let rhs = self.emit().convert_ptr_to_u(int_ty, None, rhs.def).unwrap();
self.emit().u_less_than_equal(b, None, lhs, rhs)
}
IntSGT => panic!("TODO: pointer operator IntSGT not implemented yet"),
IntSGE => panic!("TODO: pointer operator IntSGE not implemented yet"),

View File

@ -66,6 +66,8 @@ pub struct BuilderSpirv {
impl BuilderSpirv {
pub fn new() -> Self {
let mut builder = Builder::new();
// intel-compute-runtime only supports v1.3
builder.set_version(1, 3);
// TODO: Flip this back to Shader once the structurizer is working.
builder.capability(Capability::Kernel);
// Temp hack: Linkage allows us to get away with no OpEntryPoint

View File

@ -2,6 +2,7 @@ use super::CodegenCx;
use crate::abi::ConvSpirvType;
use crate::spirv_type::SpirvType;
use rspirv::spirv::StorageClass;
use rspirv::spirv::Word;
use rustc_codegen_ssa::common::TypeKind;
use rustc_codegen_ssa::traits::{BaseTypeMethods, LayoutTypeMethods};
use rustc_middle::ty::layout::{LayoutError, TyAndLayout};
@ -94,6 +95,13 @@ impl<'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'tcx> {
}
}
impl<'tcx> CodegenCx<'tcx> {
pub fn type_usize(&self) -> Word {
let ptr_size = self.tcx.data_layout.pointer_size.bits() as u32;
SpirvType::Integer(ptr_size, false).def(self)
}
}
impl<'tcx> BaseTypeMethods<'tcx> for CodegenCx<'tcx> {
fn type_i1(&self) -> Self::Type {
SpirvType::Bool.def(self)