mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-29 02:04:32 +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
|
# 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.
|
# 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)
|
# (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
|
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::builder_spirv::SpirvValueExt;
|
||||||
use crate::codegen_cx::CodegenCx;
|
use crate::codegen_cx::CodegenCx;
|
||||||
use crate::spirv_type::SpirvType;
|
use crate::spirv_type::SpirvType;
|
||||||
|
use rspirv::spirv::GLOp;
|
||||||
use rustc_codegen_ssa::common::span_invalid_monomorphization_error;
|
use rustc_codegen_ssa::common::span_invalid_monomorphization_error;
|
||||||
use rustc_codegen_ssa::common::IntPredicate;
|
use rustc_codegen_ssa::common::IntPredicate;
|
||||||
use rustc_codegen_ssa::glue;
|
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 => {
|
sym::float_to_int_unchecked => {
|
||||||
if float_type_width(arg_tys[0]).is_none() {
|
if float_type_width(arg_tys[0]).is_none() {
|
||||||
span_invalid_monomorphization_error(
|
span_invalid_monomorphization_error(
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
mod builder_methods;
|
mod builder_methods;
|
||||||
|
mod ext_inst;
|
||||||
mod intrinsics;
|
mod intrinsics;
|
||||||
|
|
||||||
|
pub use ext_inst::ExtInst;
|
||||||
|
|
||||||
use crate::abi::ConvSpirvType;
|
use crate::abi::ConvSpirvType;
|
||||||
use crate::builder_spirv::{BuilderCursor, SpirvValue, SpirvValueExt};
|
use crate::builder_spirv::{BuilderCursor, SpirvValue, SpirvValueExt};
|
||||||
use crate::codegen_cx::CodegenCx;
|
use crate::codegen_cx::CodegenCx;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::abi::ConvSpirvType;
|
use crate::abi::ConvSpirvType;
|
||||||
|
use crate::builder::ExtInst;
|
||||||
use crate::builder_spirv::{BuilderCursor, BuilderSpirv, SpirvValue, SpirvValueExt};
|
use crate::builder_spirv::{BuilderCursor, BuilderSpirv, SpirvValue, SpirvValueExt};
|
||||||
use crate::spirv_type::{SpirvType, SpirvTypePrinter, TypeCache};
|
use crate::spirv_type::{SpirvType, SpirvTypePrinter, TypeCache};
|
||||||
use rspirv::dr::{Module, Operand};
|
use rspirv::dr::{Module, Operand};
|
||||||
@ -63,6 +64,7 @@ pub struct CodegenCx<'tcx> {
|
|||||||
pub type_cache: TypeCache<'tcx>,
|
pub type_cache: TypeCache<'tcx>,
|
||||||
/// Cache generated vtables
|
/// Cache generated vtables
|
||||||
pub vtables: RefCell<FxHashMap<(Ty<'tcx>, Option<PolyExistentialTraitRef<'tcx>>), SpirvValue>>,
|
pub vtables: RefCell<FxHashMap<(Ty<'tcx>, Option<PolyExistentialTraitRef<'tcx>>), SpirvValue>>,
|
||||||
|
pub ext_inst: RefCell<ExtInst>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> CodegenCx<'tcx> {
|
impl<'tcx> CodegenCx<'tcx> {
|
||||||
@ -76,6 +78,7 @@ impl<'tcx> CodegenCx<'tcx> {
|
|||||||
function_parameter_values: RefCell::new(HashMap::new()),
|
function_parameter_values: RefCell::new(HashMap::new()),
|
||||||
type_cache: Default::default(),
|
type_cache: Default::default(),
|
||||||
vtables: RefCell::new(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)
|
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)]
|
#[allow(dead_code)]
|
||||||
pub fn set_linkage_export(&self, target: Word, name: String) {
|
pub fn set_linkage_export(&self, target: Word, name: String) {
|
||||||
self.emit_global().decorate(
|
self.emit_global().decorate(
|
||||||
|
Loading…
Reference in New Issue
Block a user