spirv 常量的管理
作者:Miracle
- 2025-09-24 四川
本文字数:1897 字
阅读完需:约 6 分钟

下面我们开始编译 Assign 指令了
处理 Assign 之前 必须首先处理 Const(0) 我们注意到 SpirvBuilder 是没有常量的 所以我们需要 增加一种类型 常量的类型 然后将 Zeta 中间代码 的常量表导入进来
我们的 Module 是这样的
pub struct Module { pub consts: Vec<Dynamic>, pub fns: Vec<(bool, FnDef, Vec<Statement>)>,}
复制代码
中间代码,使用 Symbol::Const(usize) 来访问具体的 常量值
我们使用下面的代码 导入常量 完成类型 ID 的获取 值的存储
for val in module.consts { let ty = self.get_type(val.get_type()); if val.is_f64() { self.consts.push(Const{id: self.builder.constant_bit64(ty, val.as_f64().unwrap().to_bits()), val}); } else if val.is_f32() { self.consts.push(Const{id: self.builder.constant_bit32(ty, val.as_f32().unwrap().to_bits()), val}); } else if val.is_int() { if let Dynamic::I64(val) = val { self.consts.push(Const{id: self.builder.constant_bit64(ty, val as u64), val: Dynamic::from(val)}); } else { self.consts.push(Const{id: self.builder.constant_bit32(ty, val.as_i32().unwrap() as u32), val}); } } else if val.is_uint() { if let Dynamic::U64(val) = val { self.consts.push(Const{id: self.builder.constant_bit64(ty, val as u64), val: Dynamic::U64(val)}); } else { self.consts.push(Const{id: self.builder.constant_bit32(ty, val.as_u32().unwrap()), val}); } } else { self.consts.push(Const{ id: 0, val}); } }复制代码
然后 我们开始处理索引了 刚才 Assign 时候 左边是 Idx(Var(1), Const(0))
所以我们首先要取出 这个 Var(1) 索引 常量变量为 0 的值
代码是这样的
Symbol::Idx(obj, idx)=> { let obj = self.get(obj); if let Type::Vec(ty, num) = obj.ty { if let Some(val) = self.get_const(idx) { let ty_id = self.get_type((*ty).clone()); let id = self.builder.composite_extract(ty_id, None, obj.id, vec![val.val.as_u32().unwrap()]).unwrap(); Var{id, ty: (*ty).clone(), cls: StorageClass::Function} } else { panic!("") } } else { panic!("")}复制代码
当我获取左边的时候 得到这样的结果
这个时候可以简单的把 id 16 赋值给 Var(2) 就行了
我们的代码是这样的
Statement::Assign(left, right) => { if let Symbol::Idx(obj, idx) = right { } else { let left = self.get(left); *self.get_mut(right) = left; } }
复制代码
执行的结果是这样
完美,现在就是另外半边的赋值了
我们看看右半边是什么
实现写入的代码是这样的
if let Symbol::Idx(obj, idx) = right { let obj = self.get(obj); if let Type::Array(ty, num) = obj.ty { let idx = self.get(idx); let ty_id = self.get_type((*ty).clone()); let ty_pt = self.builder.type_pointer(None, obj.cls, ty_id); let pt = self.builder.access_chain(ty_pt, None, obj.id, vec![idx.id])?;//然后向 ID装入值 let src = self.get(left); self.builder.store(pt, src.id, None, None)?; } else if let Type::Vec(ty, num) = obj.ty { if let Some(val) = self.get_const(idx) { let ty_id = self.get_type((*ty).clone()); } }复制代码
我们生成 spirv 汇编代码是这样的
完美,那么是时候让这个 shader 在我的显卡上运行起来了
划线
评论
复制
发布于: 刚刚阅读数: 2
Miracle
关注
三十年资深码农 2019-10-25 加入
还未添加个人简介







评论