simd interpreter
This commit is contained in:
+23
-39
@@ -1,7 +1,7 @@
|
|||||||
use std::simd::{
|
use std::simd::{
|
||||||
StdFloat,
|
StdFloat,
|
||||||
cmp::{SimdPartialEq, SimdPartialOrd},
|
cmp::{SimdPartialEq, SimdPartialOrd},
|
||||||
num::{SimdFloat, SimdInt},
|
num::SimdFloat,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -9,8 +9,7 @@ use crate::{
|
|||||||
ssa::{SSAInput, SSAInstruction, SSAOpcode},
|
ssa::{SSAInput, SSAInstruction, SSAOpcode},
|
||||||
};
|
};
|
||||||
|
|
||||||
type Value = core::simd::f32x8;
|
pub type Value = std::simd::f32x8;
|
||||||
type IValue = core::simd::i32x8;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) struct Interpreter<'csg> {
|
pub(crate) struct Interpreter<'csg> {
|
||||||
@@ -94,6 +93,8 @@ impl<'csg> Interpreter<'csg> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cargo asm "erroccfisuvsc::interpreter::Interpreter::scene" --no-color --rust > scene.asm
|
||||||
|
|
||||||
pub(crate) fn scene(&mut self, px: Value, py: Value, pz: Value) -> Value {
|
pub(crate) fn scene(&mut self, px: Value, py: Value, pz: Value) -> Value {
|
||||||
self.clear_stacks();
|
self.clear_stacks();
|
||||||
|
|
||||||
@@ -123,9 +124,14 @@ impl<'csg> Interpreter<'csg> {
|
|||||||
SSAMod => {
|
SSAMod => {
|
||||||
self.param_two(instruction, |val_a, val_b| val_a % val_b);
|
self.param_two(instruction, |val_a, val_b| val_a % val_b);
|
||||||
},
|
},
|
||||||
SSAAtan2 => {
|
SSAAtan2 => self.param_two(instruction, |val_a, val_b| {
|
||||||
self.param_two(instruction, |val_a, val_b| val_a.atan2(val_b));
|
let mut val_a = val_a.to_array();
|
||||||
},
|
let val_b = val_b.to_array();
|
||||||
|
for i in 0..Value::LEN {
|
||||||
|
val_a[i] = val_a[i].atan2(val_b[i]);
|
||||||
|
}
|
||||||
|
Value::from_array(val_a)
|
||||||
|
}),
|
||||||
SSAMin => {
|
SSAMin => {
|
||||||
self.param_two(instruction, |val_a, val_b| val_a.simd_min(val_b));
|
self.param_two(instruction, |val_a, val_b| val_a.simd_min(val_b));
|
||||||
},
|
},
|
||||||
@@ -213,7 +219,7 @@ impl<'csg> Interpreter<'csg> {
|
|||||||
+ ((val_a[2] - val_b[2]) * (val_a[2] - val_b[2]))
|
+ ((val_a[2] - val_b[2]) * (val_a[2] - val_b[2]))
|
||||||
+ ((val_a[3] - val_b[3]) * (val_a[3] - val_b[3])))
|
+ ((val_a[3] - val_b[3]) * (val_a[3] - val_b[3])))
|
||||||
.sqrt(),
|
.sqrt(),
|
||||||
3 => (((val_a[0] - val_b[0]) * (val_a[0] - val_b[0]))
|
4 => (((val_a[0] - val_b[0]) * (val_a[0] - val_b[0]))
|
||||||
+ ((val_a[1] - val_b[1]) * (val_a[1] - val_b[1]))
|
+ ((val_a[1] - val_b[1]) * (val_a[1] - val_b[1]))
|
||||||
+ ((val_a[2] - val_b[2]) * (val_a[2] - val_b[2]))
|
+ ((val_a[2] - val_b[2]) * (val_a[2] - val_b[2]))
|
||||||
+ ((val_a[3] - val_b[3]) * (val_a[3] - val_b[3]))
|
+ ((val_a[3] - val_b[3]) * (val_a[3] - val_b[3]))
|
||||||
@@ -282,45 +288,23 @@ impl<'csg> Interpreter<'csg> {
|
|||||||
},
|
},
|
||||||
SSATan => {
|
SSATan => {
|
||||||
self.param_one(instruction, |val_a| {
|
self.param_one(instruction, |val_a| {
|
||||||
let sign_bit = val_a.is_sign_positive();
|
Value::from_array(val_a.to_array().map(|f| f.tan()))
|
||||||
let x = val_a.abs();
|
|
||||||
let y = x * Value::splat(core::f32::consts::FRAC_2_PI * 2.);
|
|
||||||
let emm2 = (y.cast::<i32>() + IValue::splat(1)) & IValue::splat(!1);
|
|
||||||
let y = emm2.cast::<f32>();
|
|
||||||
let polymask = (emm2 & IValue::splat(2)).simd_eq(IValue::splat(0));
|
|
||||||
const MINUS_CEPHES_DP1: Value = Value::splat(-0.78515625);
|
|
||||||
const MINUS_CEPHES_DP2: Value = Value::splat(-2.4187564849853515625e-4);
|
|
||||||
const MINUS_CEPHES_DP3: Value = Value::splat(-3.77489497744594108e-8);
|
|
||||||
let z = ((x + (y * MINUS_CEPHES_DP1)) + (y * MINUS_CEPHES_DP2))
|
|
||||||
+ (y * MINUS_CEPHES_DP3);
|
|
||||||
let zz = z * z;
|
|
||||||
const TANCOF_P0: Value = Value::splat(9.38540185543E-3);
|
|
||||||
const TANCOF_P1: Value = Value::splat(3.11992232697E-3);
|
|
||||||
const TANCOF_P2: Value = Value::splat(2.44301354525E-2);
|
|
||||||
const TANCOF_P3: Value = Value::splat(5.34112807005E-2);
|
|
||||||
const TANCOF_P4: Value = Value::splat(1.33387994085E-1);
|
|
||||||
const TANCOF_P5: Value = Value::splat(3.33331568548E-1);
|
|
||||||
let y = ((((((((TANCOF_P0 * zz) + TANCOF_P1) * zz) + TANCOF_P2 * zz)
|
|
||||||
+ TANCOF_P3 * zz)
|
|
||||||
+ TANCOF_P4 * zz)
|
|
||||||
+ TANCOF_P5)
|
|
||||||
* zz
|
|
||||||
* z)
|
|
||||||
+ z;
|
|
||||||
let y2 = (Value::splat(1.0) / y)
|
|
||||||
* sign_bit.select(Value::splat(-1.0), Value::splat(0.0));
|
|
||||||
let y = polymask.select(y, y2);
|
|
||||||
y * sign_bit.select(Value::splat(-1.0), Value::splat(0.0))
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
SSAAsin => {
|
SSAAsin => {
|
||||||
self.param_one(instruction, |val_a| val_a.asin());
|
self.param_one(instruction, |val_a| {
|
||||||
|
Value::from_array(val_a.to_array().map(|f| f.asin()))
|
||||||
|
});
|
||||||
},
|
},
|
||||||
SSAAcos => {
|
SSAAcos => {
|
||||||
self.param_one(instruction, |val_a| val_a.acos());
|
self.param_one(instruction, |val_a| {
|
||||||
|
Value::from_array(val_a.to_array().map(|f| f.acos()))
|
||||||
|
});
|
||||||
},
|
},
|
||||||
SSAAtan => {
|
SSAAtan => {
|
||||||
self.param_one(instruction, |val_a| val_a.atan());
|
self.param_one(instruction, |val_a| {
|
||||||
|
Value::from_array(val_a.to_array().map(|f| f.atan()))
|
||||||
|
});
|
||||||
},
|
},
|
||||||
SSAExp => {
|
SSAExp => {
|
||||||
self.param_one(instruction, |val_a| val_a.exp());
|
self.param_one(instruction, |val_a| val_a.exp());
|
||||||
|
|||||||
+22
-13
@@ -7,6 +7,7 @@ use std::{
|
|||||||
fs::{File, remove_file, rename},
|
fs::{File, remove_file, rename},
|
||||||
io::{Cursor, Read, Write},
|
io::{Cursor, Read, Write},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
|
simd::StdFloat,
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
@@ -306,7 +307,7 @@ impl App {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut device_extensions = DeviceExtensions {
|
let device_extensions = DeviceExtensions {
|
||||||
khr_swapchain: true,
|
khr_swapchain: true,
|
||||||
ext_mesh_shader: false,
|
ext_mesh_shader: false,
|
||||||
khr_fragment_shading_rate: false,
|
khr_fragment_shading_rate: false,
|
||||||
@@ -625,7 +626,7 @@ impl ApplicationHandler for App {
|
|||||||
.flatten()
|
.flatten()
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
File::create("out.spv").unwrap().write(&module_as_bytes);
|
File::create("out.spv").unwrap().write(&module_as_bytes).unwrap();
|
||||||
|
|
||||||
let smodule = unsafe {
|
let smodule = unsafe {
|
||||||
::vulkano::shader::ShaderModule::new(
|
::vulkano::shader::ShaderModule::new(
|
||||||
@@ -917,7 +918,7 @@ impl App {
|
|||||||
.flatten()
|
.flatten()
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
File::create("out.spv").unwrap().write(&module_as_bytes);
|
File::create("out.spv").unwrap().write(&module_as_bytes).unwrap();
|
||||||
|
|
||||||
let smodule = unsafe {
|
let smodule = unsafe {
|
||||||
::vulkano::shader::ShaderModule::new(
|
::vulkano::shader::ShaderModule::new(
|
||||||
@@ -1149,17 +1150,25 @@ impl App {
|
|||||||
* Mat4::from_scale(csg.scale * 2.0))
|
* Mat4::from_scale(csg.scale * 2.0))
|
||||||
.to_cols_array_2d();
|
.to_cols_array_2d();
|
||||||
|
|
||||||
|
const INTERPRET_INPUT_X: interpreter::Value =
|
||||||
|
interpreter::Value::from_array([10000.0, 0.0, 0.0, -10000.0, 0.0, 0.0, 0.0, 0.0]);
|
||||||
|
const INTERPRET_INPUT_Y: interpreter::Value =
|
||||||
|
interpreter::Value::from_array([0.0, 10000.0, 0.0, 0.0, -10000.0, 0.0, 0.0, 0.0]);
|
||||||
|
const INTERPRET_INPUT_Z: interpreter::Value =
|
||||||
|
interpreter::Value::from_array([0.0, 0.0, 10000.0, 0.0, 0.0, -10000.0, 0.0, 0.0]);
|
||||||
|
const INTERPRET_MUL: interpreter::Value =
|
||||||
|
interpreter::Value::from_array([-1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 0.0, 0.0]);
|
||||||
|
const INTERPRET_ADD: interpreter::Value = interpreter::Value::from_array([
|
||||||
|
10000.0, 10000.0, 10000.0, -10000.0, -10000.0, -10000.0, 0.0, 0.0,
|
||||||
|
]);
|
||||||
|
|
||||||
let mut interpreter = Interpreter::new(csg);
|
let mut interpreter = Interpreter::new(csg);
|
||||||
let highest_corner = Vec3::new(
|
let interpreter_out = interpreter
|
||||||
10000.0 - interpreter.scene(Vec3::new(10000.0, 0.0, 0.0)),
|
.scene(INTERPRET_INPUT_X, INTERPRET_INPUT_Y, INTERPRET_INPUT_Z)
|
||||||
10000.0 - interpreter.scene(Vec3::new(0.0, 10000.0, 0.0)),
|
.mul_add(INTERPRET_MUL, INTERPRET_ADD).to_array();
|
||||||
10000.0 - interpreter.scene(Vec3::new(0.0, 0.0, 10000.0)),
|
|
||||||
);
|
let highest_corner = Vec3::new(interpreter_out[0], interpreter_out[1], interpreter_out[2]);
|
||||||
let lowest_corner = Vec3::new(
|
let lowest_corner = Vec3::new(interpreter_out[3], interpreter_out[4], interpreter_out[5]);
|
||||||
-10000.0 + interpreter.scene(Vec3::new(-10000.0, 0.0, 0.0)),
|
|
||||||
-10000.0 + interpreter.scene(Vec3::new(0.0, -10000.0, 0.0)),
|
|
||||||
-10000.0 + interpreter.scene(Vec3::new(0.0, 0.0, -10000.0)),
|
|
||||||
);
|
|
||||||
|
|
||||||
push_constants.dimensions = (highest_corner - lowest_corner).to_array().into();
|
push_constants.dimensions = (highest_corner - lowest_corner).to_array().into();
|
||||||
push_constants.lowest_corner = lowest_corner.into();
|
push_constants.lowest_corner = lowest_corner.into();
|
||||||
|
|||||||
+1
-3
@@ -1,7 +1,7 @@
|
|||||||
use std::{collections::HashMap, io::Read, sync::Arc};
|
use std::{collections::HashMap, io::Read, sync::Arc};
|
||||||
|
|
||||||
use bytemuck::{Pod, Zeroable};
|
use bytemuck::{Pod, Zeroable};
|
||||||
use glam::{self, Mat2, Mat3, Mat4, Vec2, Vec3, Vec4};
|
use glam::{self, Vec3};
|
||||||
use obj::{LoadConfig, ObjData, ObjError};
|
use obj::{LoadConfig, ObjData, ObjError};
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
buffer::{Buffer, BufferCreateInfo, BufferUsage, Subbuffer},
|
buffer::{Buffer, BufferCreateInfo, BufferUsage, Subbuffer},
|
||||||
@@ -43,8 +43,6 @@ pub(crate) struct CSG {
|
|||||||
pub(crate) scale: Vec3,
|
pub(crate) scale: Vec3,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) type Float = f32;
|
|
||||||
|
|
||||||
pub(crate) fn load_obj(
|
pub(crate) fn load_obj(
|
||||||
memory_allocator: &Arc<StandardMemoryAllocator>,
|
memory_allocator: &Arc<StandardMemoryAllocator>,
|
||||||
input: &mut dyn Read,
|
input: &mut dyn Read,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use egui::ahash::HashMapExt;
|
use egui::ahash::HashMapExt;
|
||||||
use foldhash::HashMap;
|
use foldhash::HashMap;
|
||||||
use log::info;
|
|
||||||
use rspirv::{dr::Module, spirv};
|
use rspirv::{dr::Module, spirv};
|
||||||
|
|
||||||
use crate::instruction_set::InstructionSet;
|
use crate::instruction_set::InstructionSet;
|
||||||
|
|||||||
Reference in New Issue
Block a user