mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-25 16:25:25 +00:00
Extension instructions
This commit is contained in:
parent
3a9d6f87ca
commit
913e19f696
@ -12,5 +12,5 @@ pushd build_libcore_test
|
||||
# Use wasm32 because it's a relatively simple platform - if the x86 libcore is used, there's all sorts of "feature sse2
|
||||
# not found" and the like, and our spirv backend is never reached. With wasm32, it at least gets reached.
|
||||
# (We probably want to add our own target eventually)
|
||||
xargo build --target wasm32-unknown-unknown -Ccodegen-units=1
|
||||
xargo build --target wasm32-unknown-unknown
|
||||
popd
|
||||
|
1
rustc_codegen_spirv/build_libcore_test/.gitignore
vendored
Normal file
1
rustc_codegen_spirv/build_libcore_test/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target/
|
10
rustc_codegen_spirv/build_libcore_test/src/lib.rs
Normal file
10
rustc_codegen_spirv/build_libcore_test/src/lib.rs
Normal file
@ -0,0 +1,10 @@
|
||||
#![no_std]
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
|
||||
pub fn screaming_bananans() {}
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(_: &PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
@ -1 +0,0 @@
|
||||
fn main() {}
|
42
rustc_codegen_spirv/src/builder/ext_inst.rs
Normal file
42
rustc_codegen_spirv/src/builder/ext_inst.rs
Normal file
@ -0,0 +1,42 @@
|
||||
use super::Builder;
|
||||
use crate::builder_spirv::{SpirvValue, SpirvValueExt};
|
||||
use rspirv::dr::Operand;
|
||||
use rspirv::spirv::{GLOp, Word};
|
||||
|
||||
const GLSL_STD_450: &str = "GLSL.std.450";
|
||||
|
||||
/// Manager for OpExtInst/OpExtImport instructions
|
||||
#[derive(Default)]
|
||||
pub struct ExtInst {
|
||||
glsl: Option<Word>,
|
||||
}
|
||||
|
||||
impl ExtInst {
|
||||
pub fn import_glsl<'a, 'tcx>(&mut self, bx: &Builder<'a, 'tcx>) -> Word {
|
||||
match self.glsl {
|
||||
Some(id) => id,
|
||||
None => {
|
||||
let id = bx.emit_global().ext_inst_import(GLSL_STD_450);
|
||||
self.glsl = Some(id);
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
pub fn gl_op(&mut self, op: GLOp, args: impl AsRef<[SpirvValue]>) -> SpirvValue {
|
||||
let args = args.as_ref();
|
||||
let glsl = self.ext_inst.borrow_mut().import_glsl(self);
|
||||
self.emit()
|
||||
.ext_inst(
|
||||
args[0].ty,
|
||||
None,
|
||||
glsl,
|
||||
op as u32,
|
||||
args.iter().map(|a| Operand::IdRef(a.def)),
|
||||
)
|
||||
.unwrap()
|
||||
.with_type(args[0].ty)
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ use crate::abi::ConvSpirvType;
|
||||
use crate::builder_spirv::SpirvValueExt;
|
||||
use crate::codegen_cx::CodegenCx;
|
||||
use crate::spirv_type::SpirvType;
|
||||
use rspirv::spirv::GLOp;
|
||||
use rustc_codegen_ssa::common::span_invalid_monomorphization_error;
|
||||
use rustc_codegen_ssa::common::IntPredicate;
|
||||
use rustc_codegen_ssa::glue;
|
||||
@ -455,6 +456,45 @@ impl<'a, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Configure these to be ocl vs. gl ext instructions, etc.
|
||||
sym::sqrtf32 | sym::sqrtf64 => self.gl_op(GLOp::Sqrt, [args[0].immediate()]),
|
||||
sym::powif32 | sym::powif64 => {
|
||||
let float = self.sitofp(args[1].immediate(), args[0].immediate().ty);
|
||||
self.gl_op(GLOp::Pow, [args[0].immediate(), float])
|
||||
}
|
||||
sym::sinf32 | sym::sinf64 => self.gl_op(GLOp::Sin, [args[0].immediate()]),
|
||||
sym::cosf32 | sym::cosf64 => self.gl_op(GLOp::Cos, [args[0].immediate()]),
|
||||
sym::powf32 | sym::powf64 => {
|
||||
self.gl_op(GLOp::Pow, [args[0].immediate(), args[1].immediate()])
|
||||
}
|
||||
sym::expf32 | sym::expf64 => self.gl_op(GLOp::Exp, [args[0].immediate()]),
|
||||
sym::exp2f32 | sym::exp2f64 => self.gl_op(GLOp::Exp2, [args[0].immediate()]),
|
||||
sym::logf32 | sym::logf64 => self.gl_op(GLOp::Log, [args[0].immediate()]),
|
||||
sym::log2f32 | sym::log2f64 => self.gl_op(GLOp::Log2, [args[0].immediate()]),
|
||||
sym::log10f32 | sym::log10f64 => {
|
||||
// spir-v doesn't have log10, so,
|
||||
// log10(x) == (1 / ln(10)) * ln(x)
|
||||
let mul = self.constant_float(args[0].immediate().ty, 1.0 / 10.0f64.ln());
|
||||
let ln = self.gl_op(GLOp::Log, [args[0].immediate()]);
|
||||
self.mul(mul, ln)
|
||||
}
|
||||
sym::fmaf32 | sym::fmaf64 => self.gl_op(GLOp::Fma, [args[0].immediate()]),
|
||||
sym::fabsf32 | sym::fabsf64 => self.gl_op(GLOp::FAbs, [args[0].immediate()]),
|
||||
sym::minnumf32 | sym::minnumf64 => self.gl_op(GLOp::FMin, [args[0].immediate()]),
|
||||
sym::maxnumf32 | sym::maxnumf64 => self.gl_op(GLOp::FMax, [args[0].immediate()]),
|
||||
// sym::copysignf32 => "llvm.copysign.f32",
|
||||
// sym::copysignf64 => "llvm.copysign.f64",
|
||||
sym::floorf32 | sym::floorf64 => self.gl_op(GLOp::Floor, [args[0].immediate()]),
|
||||
sym::ceilf32 | sym::ceilf64 => self.gl_op(GLOp::Ceil, [args[0].immediate()]),
|
||||
sym::truncf32 | sym::truncf64 => self.gl_op(GLOp::Trunc, [args[0].immediate()]),
|
||||
// TODO: Correctness of round
|
||||
sym::rintf32
|
||||
| sym::rintf64
|
||||
| sym::nearbyintf32
|
||||
| sym::nearbyintf64
|
||||
| sym::roundf32
|
||||
| sym::roundf64 => self.gl_op(GLOp::Round, [args[1].immediate()]),
|
||||
|
||||
sym::float_to_int_unchecked => {
|
||||
if float_type_width(arg_tys[0]).is_none() {
|
||||
span_invalid_monomorphization_error(
|
||||
|
@ -1,6 +1,9 @@
|
||||
mod builder_methods;
|
||||
mod ext_inst;
|
||||
mod intrinsics;
|
||||
|
||||
pub use ext_inst::ExtInst;
|
||||
|
||||
use crate::abi::ConvSpirvType;
|
||||
use crate::builder_spirv::{BuilderCursor, SpirvValue, SpirvValueExt};
|
||||
use crate::codegen_cx::CodegenCx;
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::abi::ConvSpirvType;
|
||||
use crate::builder::ExtInst;
|
||||
use crate::builder_spirv::{BuilderCursor, BuilderSpirv, SpirvValue, SpirvValueExt};
|
||||
use crate::spirv_type::{SpirvType, SpirvTypePrinter, TypeCache};
|
||||
use rspirv::dr::{Module, Operand};
|
||||
@ -63,6 +64,7 @@ pub struct CodegenCx<'tcx> {
|
||||
pub type_cache: TypeCache<'tcx>,
|
||||
/// Cache generated vtables
|
||||
pub vtables: RefCell<FxHashMap<(Ty<'tcx>, Option<PolyExistentialTraitRef<'tcx>>), SpirvValue>>,
|
||||
pub ext_inst: RefCell<ExtInst>,
|
||||
}
|
||||
|
||||
impl<'tcx> CodegenCx<'tcx> {
|
||||
@ -76,6 +78,7 @@ impl<'tcx> CodegenCx<'tcx> {
|
||||
function_parameter_values: RefCell::new(HashMap::new()),
|
||||
type_cache: Default::default(),
|
||||
vtables: RefCell::new(Default::default()),
|
||||
ext_inst: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,6 +187,14 @@ impl<'tcx> CodegenCx<'tcx> {
|
||||
self.builder.constant_f64(ty, val).with_type(ty)
|
||||
}
|
||||
|
||||
pub fn constant_float(&self, ty: Word, val: f64) -> SpirvValue {
|
||||
match self.lookup_type(ty) {
|
||||
SpirvType::Float(32) => self.builder.constant_f32(ty, val as f32).with_type(ty),
|
||||
SpirvType::Float(64) => self.builder.constant_f64(ty, val).with_type(ty),
|
||||
other => panic!("constant_float invalid on type {}", other.debug(ty, self)),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn set_linkage_export(&self, target: Word, name: String) {
|
||||
self.emit_global().decorate(
|
||||
|
Loading…
Reference in New Issue
Block a user