mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-25 00:04:11 +00:00
builder_spirv: split out the type field from SpirvConst
.
This commit is contained in:
parent
aa444f007e
commit
84350e31d3
@ -38,8 +38,8 @@ macro_rules! simple_op {
|
||||
let size = Size::from_bits(bits);
|
||||
let as_u128 = |const_val| {
|
||||
let x = match const_val {
|
||||
SpirvConst::U32(_, x) => x as u128,
|
||||
SpirvConst::U64(_, x) => x as u128,
|
||||
SpirvConst::U32(x) => x as u128,
|
||||
SpirvConst::U64(x) => x as u128,
|
||||
_ => return None,
|
||||
};
|
||||
Some(if signed {
|
||||
|
@ -171,16 +171,22 @@ impl SpirvValueExt for Word {
|
||||
|
||||
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
||||
pub enum SpirvConst {
|
||||
U32(Word, u32),
|
||||
U64(Word, u64),
|
||||
U32(u32),
|
||||
U64(u64),
|
||||
/// f32 isn't hash, so store bits
|
||||
F32(Word, u32),
|
||||
F32(u32),
|
||||
/// f64 isn't hash, so store bits
|
||||
F64(Word, u64),
|
||||
Bool(Word, bool),
|
||||
Composite(Word, Vec<Word>),
|
||||
Null(Word),
|
||||
Undef(Word),
|
||||
F64(u64),
|
||||
Bool(bool),
|
||||
Composite(Vec<Word>),
|
||||
Null,
|
||||
Undef,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
||||
struct WithType<V> {
|
||||
ty: Word,
|
||||
val: V,
|
||||
}
|
||||
|
||||
/// Cursor system:
|
||||
@ -214,7 +220,7 @@ pub struct BuilderCursor {
|
||||
|
||||
pub struct BuilderSpirv {
|
||||
builder: RefCell<Builder>,
|
||||
constants: RefCell<BiHashMap<SpirvConst, SpirvValue>>,
|
||||
constants: RefCell<BiHashMap<WithType<SpirvConst>, SpirvValue>>,
|
||||
}
|
||||
|
||||
impl BuilderSpirv {
|
||||
@ -329,44 +335,44 @@ impl BuilderSpirv {
|
||||
bug!("Function not found: {}", id);
|
||||
}
|
||||
|
||||
pub fn def_constant(&self, val: SpirvConst) -> SpirvValue {
|
||||
pub fn def_constant(&self, ty: Word, val: SpirvConst) -> SpirvValue {
|
||||
let val_with_type = WithType { ty, val };
|
||||
let mut builder = self.builder(BuilderCursor::default());
|
||||
if let Some(value) = self.constants.borrow_mut().get_by_left(&val) {
|
||||
if let Some(value) = self.constants.borrow_mut().get_by_left(&val_with_type) {
|
||||
return *value;
|
||||
}
|
||||
let id = match val {
|
||||
SpirvConst::U32(ty, v) => builder.constant_u32(ty, v).with_type(ty),
|
||||
SpirvConst::U64(ty, v) => builder.constant_u64(ty, v).with_type(ty),
|
||||
SpirvConst::F32(ty, v) => builder.constant_f32(ty, f32::from_bits(v)).with_type(ty),
|
||||
SpirvConst::F64(ty, v) => builder.constant_f64(ty, f64::from_bits(v)).with_type(ty),
|
||||
SpirvConst::Bool(ty, v) => {
|
||||
let id = match val_with_type.val {
|
||||
SpirvConst::U32(v) => builder.constant_u32(ty, v),
|
||||
SpirvConst::U64(v) => builder.constant_u64(ty, v),
|
||||
SpirvConst::F32(v) => builder.constant_f32(ty, f32::from_bits(v)),
|
||||
SpirvConst::F64(v) => builder.constant_f64(ty, f64::from_bits(v)),
|
||||
SpirvConst::Bool(v) => {
|
||||
if v {
|
||||
builder.constant_true(ty).with_type(ty)
|
||||
builder.constant_true(ty)
|
||||
} else {
|
||||
builder.constant_false(ty).with_type(ty)
|
||||
builder.constant_false(ty)
|
||||
}
|
||||
}
|
||||
SpirvConst::Composite(ty, ref v) => builder
|
||||
.constant_composite(ty, v.iter().copied())
|
||||
.with_type(ty),
|
||||
SpirvConst::Null(ty) => builder.constant_null(ty).with_type(ty),
|
||||
SpirvConst::Undef(ty) => builder.undef(ty, None).with_type(ty),
|
||||
SpirvConst::Composite(ref v) => builder.constant_composite(ty, v.iter().copied()),
|
||||
SpirvConst::Null => builder.constant_null(ty),
|
||||
SpirvConst::Undef => builder.undef(ty, None),
|
||||
};
|
||||
let spirv_value = id.with_type(ty);
|
||||
self.constants
|
||||
.borrow_mut()
|
||||
.insert_no_overwrite(val, id)
|
||||
.insert_no_overwrite(val_with_type, spirv_value)
|
||||
.unwrap();
|
||||
id
|
||||
spirv_value
|
||||
}
|
||||
|
||||
pub fn lookup_const(&self, def: SpirvValue) -> Option<SpirvConst> {
|
||||
self.constants.borrow().get_by_right(&def).cloned()
|
||||
Some(self.constants.borrow().get_by_right(&def)?.val.clone())
|
||||
}
|
||||
|
||||
pub fn lookup_const_u64(&self, def: SpirvValue) -> Option<u64> {
|
||||
match self.lookup_const(def)? {
|
||||
SpirvConst::U32(_, v) => Some(v as u64),
|
||||
SpirvConst::U64(_, v) => Some(v),
|
||||
SpirvConst::U32(v) => Some(v as u64),
|
||||
SpirvConst::U64(v) => Some(v),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -16,27 +16,27 @@ use rustc_target::abi::{self, AddressSpace, HasDataLayout, Integer, LayoutOf, Pr
|
||||
impl<'tcx> CodegenCx<'tcx> {
|
||||
pub fn constant_u8(&self, span: Span, val: u8) -> SpirvValue {
|
||||
let ty = SpirvType::Integer(8, false).def(span, self);
|
||||
self.builder.def_constant(SpirvConst::U32(ty, val as u32))
|
||||
self.builder.def_constant(ty, SpirvConst::U32(val as u32))
|
||||
}
|
||||
|
||||
pub fn constant_u16(&self, span: Span, val: u16) -> SpirvValue {
|
||||
let ty = SpirvType::Integer(16, false).def(span, self);
|
||||
self.builder.def_constant(SpirvConst::U32(ty, val as u32))
|
||||
self.builder.def_constant(ty, SpirvConst::U32(val as u32))
|
||||
}
|
||||
|
||||
pub fn constant_i32(&self, span: Span, val: i32) -> SpirvValue {
|
||||
let ty = SpirvType::Integer(32, !self.kernel_mode).def(span, self);
|
||||
self.builder.def_constant(SpirvConst::U32(ty, val as u32))
|
||||
self.builder.def_constant(ty, SpirvConst::U32(val as u32))
|
||||
}
|
||||
|
||||
pub fn constant_u32(&self, span: Span, val: u32) -> SpirvValue {
|
||||
let ty = SpirvType::Integer(32, false).def(span, self);
|
||||
self.builder.def_constant(SpirvConst::U32(ty, val))
|
||||
self.builder.def_constant(ty, SpirvConst::U32(val))
|
||||
}
|
||||
|
||||
pub fn constant_u64(&self, span: Span, val: u64) -> SpirvValue {
|
||||
let ty = SpirvType::Integer(64, false).def(span, self);
|
||||
self.builder.def_constant(SpirvConst::U64(ty, val))
|
||||
self.builder.def_constant(ty, SpirvConst::U64(val))
|
||||
}
|
||||
|
||||
pub fn constant_int(&self, ty: Word, val: u64) -> SpirvValue {
|
||||
@ -44,18 +44,18 @@ impl<'tcx> CodegenCx<'tcx> {
|
||||
SpirvType::Integer(bits @ 8..=32, signed) => {
|
||||
let size = Size::from_bits(bits);
|
||||
let val = val as u128;
|
||||
self.builder.def_constant(SpirvConst::U32(
|
||||
self.builder.def_constant(
|
||||
ty,
|
||||
if signed {
|
||||
SpirvConst::U32(if signed {
|
||||
size.sign_extend(val)
|
||||
} else {
|
||||
size.truncate(val)
|
||||
} as u32,
|
||||
))
|
||||
} as u32),
|
||||
)
|
||||
}
|
||||
SpirvType::Integer(64, _) => self.builder.def_constant(SpirvConst::U64(ty, val)),
|
||||
SpirvType::Integer(64, _) => self.builder.def_constant(ty, SpirvConst::U64(val)),
|
||||
SpirvType::Bool => match val {
|
||||
0 | 1 => self.builder.def_constant(SpirvConst::Bool(ty, val != 0)),
|
||||
0 | 1 => self.builder.def_constant(ty, SpirvConst::Bool(val != 0)),
|
||||
_ => self
|
||||
.tcx
|
||||
.sess
|
||||
@ -76,23 +76,23 @@ impl<'tcx> CodegenCx<'tcx> {
|
||||
pub fn constant_f32(&self, span: Span, val: f32) -> SpirvValue {
|
||||
let ty = SpirvType::Float(32).def(span, self);
|
||||
self.builder
|
||||
.def_constant(SpirvConst::F32(ty, val.to_bits()))
|
||||
.def_constant(ty, SpirvConst::F32(val.to_bits()))
|
||||
}
|
||||
|
||||
pub fn constant_f64(&self, span: Span, val: f64) -> SpirvValue {
|
||||
let ty = SpirvType::Float(64).def(span, self);
|
||||
self.builder
|
||||
.def_constant(SpirvConst::F64(ty, val.to_bits()))
|
||||
.def_constant(ty, SpirvConst::F64(val.to_bits()))
|
||||
}
|
||||
|
||||
pub fn constant_float(&self, ty: Word, val: f64) -> SpirvValue {
|
||||
match self.lookup_type(ty) {
|
||||
SpirvType::Float(32) => self
|
||||
.builder
|
||||
.def_constant(SpirvConst::F32(ty, (val as f32).to_bits())),
|
||||
.def_constant(ty, SpirvConst::F32((val as f32).to_bits())),
|
||||
SpirvType::Float(64) => self
|
||||
.builder
|
||||
.def_constant(SpirvConst::F64(ty, val.to_bits())),
|
||||
.def_constant(ty, SpirvConst::F64(val.to_bits())),
|
||||
other => self.tcx.sess.fatal(&format!(
|
||||
"constant_float invalid on type {}",
|
||||
other.debug(ty, self)
|
||||
@ -102,19 +102,19 @@ impl<'tcx> CodegenCx<'tcx> {
|
||||
|
||||
pub fn constant_bool(&self, span: Span, val: bool) -> SpirvValue {
|
||||
let ty = SpirvType::Bool.def(span, self);
|
||||
self.builder.def_constant(SpirvConst::Bool(ty, val))
|
||||
self.builder.def_constant(ty, SpirvConst::Bool(val))
|
||||
}
|
||||
|
||||
pub fn constant_composite(&self, ty: Word, val: Vec<Word>) -> SpirvValue {
|
||||
self.builder.def_constant(SpirvConst::Composite(ty, val))
|
||||
self.builder.def_constant(ty, SpirvConst::Composite(val))
|
||||
}
|
||||
|
||||
pub fn constant_null(&self, ty: Word) -> SpirvValue {
|
||||
self.builder.def_constant(SpirvConst::Null(ty))
|
||||
self.builder.def_constant(ty, SpirvConst::Null)
|
||||
}
|
||||
|
||||
pub fn undef(&self, ty: Word) -> SpirvValue {
|
||||
self.builder.def_constant(SpirvConst::Undef(ty))
|
||||
self.builder.def_constant(ty, SpirvConst::Undef)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -264,9 +264,8 @@ impl<'tcx> StaticMethods for CodegenCx<'tcx> {
|
||||
let mut v = self.create_const_alloc(alloc, value_ty);
|
||||
|
||||
if self.lookup_type(v.ty) == SpirvType::Bool {
|
||||
let val = self.builder.lookup_const(v).unwrap();
|
||||
let val_int = match val {
|
||||
SpirvConst::Bool(_, val) => val as u8,
|
||||
let val_int = match self.builder.lookup_const(v).unwrap() {
|
||||
SpirvConst::Bool(val) => val as u8,
|
||||
_ => bug!(),
|
||||
};
|
||||
v = self.constant_u8(span, val_int);
|
||||
|
Loading…
Reference in New Issue
Block a user