simd interpreter

This commit is contained in:
2025-06-24 21:12:43 +01:00
parent 17cad7761a
commit 1ea3d73543
4 changed files with 46 additions and 56 deletions
+23 -39
View File
@@ -1,7 +1,7 @@
use std::simd::{
StdFloat,
cmp::{SimdPartialEq, SimdPartialOrd},
num::{SimdFloat, SimdInt},
num::SimdFloat,
};
use crate::{
@@ -9,8 +9,7 @@ use crate::{
ssa::{SSAInput, SSAInstruction, SSAOpcode},
};
type Value = core::simd::f32x8;
type IValue = core::simd::i32x8;
pub type Value = std::simd::f32x8;
#[derive(Clone, Debug)]
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 {
self.clear_stacks();
@@ -123,9 +124,14 @@ impl<'csg> Interpreter<'csg> {
SSAMod => {
self.param_two(instruction, |val_a, val_b| val_a % val_b);
},
SSAAtan2 => {
self.param_two(instruction, |val_a, val_b| val_a.atan2(val_b));
},
SSAAtan2 => self.param_two(instruction, |val_a, 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 => {
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[3] - val_b[3]) * (val_a[3] - val_b[3])))
.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[2] - val_b[2]) * (val_a[2] - val_b[2]))
+ ((val_a[3] - val_b[3]) * (val_a[3] - val_b[3]))
@@ -282,45 +288,23 @@ impl<'csg> Interpreter<'csg> {
},
SSATan => {
self.param_one(instruction, |val_a| {
let sign_bit = val_a.is_sign_positive();
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))
Value::from_array(val_a.to_array().map(|f| f.tan()))
});
},
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 => {
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 => {
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 => {
self.param_one(instruction, |val_a| val_a.exp());
+22 -13
View File
@@ -7,6 +7,7 @@ use std::{
fs::{File, remove_file, rename},
io::{Cursor, Read, Write},
path::{Path, PathBuf},
simd::StdFloat,
sync::Arc,
time::Instant,
};
@@ -306,7 +307,7 @@ impl App {
)
.unwrap();
let mut device_extensions = DeviceExtensions {
let device_extensions = DeviceExtensions {
khr_swapchain: true,
ext_mesh_shader: false,
khr_fragment_shading_rate: false,
@@ -625,7 +626,7 @@ impl ApplicationHandler for App {
.flatten()
.collect::<Vec<_>>();
File::create("out.spv").unwrap().write(&module_as_bytes);
File::create("out.spv").unwrap().write(&module_as_bytes).unwrap();
let smodule = unsafe {
::vulkano::shader::ShaderModule::new(
@@ -917,7 +918,7 @@ impl App {
.flatten()
.collect::<Vec<_>>();
File::create("out.spv").unwrap().write(&module_as_bytes);
File::create("out.spv").unwrap().write(&module_as_bytes).unwrap();
let smodule = unsafe {
::vulkano::shader::ShaderModule::new(
@@ -1149,17 +1150,25 @@ impl App {
* Mat4::from_scale(csg.scale * 2.0))
.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 highest_corner = Vec3::new(
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)),
);
let lowest_corner = Vec3::new(
-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)),
);
let interpreter_out = interpreter
.scene(INTERPRET_INPUT_X, INTERPRET_INPUT_Y, INTERPRET_INPUT_Z)
.mul_add(INTERPRET_MUL, INTERPRET_ADD).to_array();
let highest_corner = Vec3::new(interpreter_out[0], interpreter_out[1], interpreter_out[2]);
let lowest_corner = Vec3::new(interpreter_out[3], interpreter_out[4], interpreter_out[5]);
push_constants.dimensions = (highest_corner - lowest_corner).to_array().into();
push_constants.lowest_corner = lowest_corner.into();
+1 -3
View File
@@ -1,7 +1,7 @@
use std::{collections::HashMap, io::Read, sync::Arc};
use bytemuck::{Pod, Zeroable};
use glam::{self, Mat2, Mat3, Mat4, Vec2, Vec3, Vec4};
use glam::{self, Vec3};
use obj::{LoadConfig, ObjData, ObjError};
use vulkano::{
buffer::{Buffer, BufferCreateInfo, BufferUsage, Subbuffer},
@@ -43,8 +43,6 @@ pub(crate) struct CSG {
pub(crate) scale: Vec3,
}
pub(crate) type Float = f32;
pub(crate) fn load_obj(
memory_allocator: &Arc<StandardMemoryAllocator>,
input: &mut dyn Read,
-1
View File
@@ -1,6 +1,5 @@
use egui::ahash::HashMapExt;
use foldhash::HashMap;
use log::info;
use rspirv::{dr::Module, spirv};
use crate::instruction_set::InstructionSet;