From 38f3c4eb192350fa2aa3dba9fec62ae2b4046cda Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Wed, 10 Feb 2021 16:54:48 -0500 Subject: [PATCH] [spv-in] support dynamic vector insert/extract --- src/front/spv/error.rs | 1 + src/front/spv/mod.rs | 112 +++++++++++++++++++++++++++++ src/proc/validator.rs | 2 +- tests/out/shadow.ron.snap | 146 +++++++++++++++++++++++--------------- 4 files changed, 203 insertions(+), 58 deletions(-) diff --git a/src/front/spv/error.rs b/src/front/spv/error.rs index d05213643c..194c279b8d 100644 --- a/src/front/spv/error.rs +++ b/src/front/spv/error.rs @@ -43,6 +43,7 @@ pub enum Error { InvalidSampleImage(Handle), InvalidDepthReference(Handle), InvalidAsType(Handle), + InvalidVectorType(Handle), InconsistentComparisonSampling(Handle), WrongFunctionResultType(spirv::Word), WrongFunctionArgumentType(spirv::Word), diff --git a/src/front/spv/mod.rs b/src/front/spv/mod.rs index 1a78c80574..f8945c6ea4 100644 --- a/src/front/spv/mod.rs +++ b/src/front/spv/mod.rs @@ -321,6 +321,7 @@ pub struct Parser { deferred_function_calls: FastHashMap, spirv::Word>, dummy_functions: Arena, options: Options, + index_constants: Vec>, } impl> Parser { @@ -347,6 +348,7 @@ impl> Parser { deferred_function_calls: FastHashMap::default(), dummy_functions: Arena::new(), options: options.clone(), + index_constants: Vec::new(), } } @@ -760,6 +762,103 @@ impl> Parser { }; self.lookup_expression.insert(result_id, lookup_expression); } + Op::VectorExtractDynamic => { + inst.expect(5)?; + let result_type_id = self.next()?; + let id = self.next()?; + let composite_id = self.next()?; + let index_id = self.next()?; + + let root_lexp = self.lookup_expression.lookup(composite_id)?; + let root_type_lookup = self.lookup_type.lookup(root_lexp.type_id)?; + let index_lexp = self.lookup_expression.lookup(index_id)?; + + let num_components = match type_arena[root_type_lookup.handle].inner { + crate::TypeInner::Vector { size, .. } => size as usize, + _ => return Err(Error::InvalidVectorType(root_type_lookup.handle)), + }; + + let mut index_expr = + expressions.append(crate::Expression::Constant(self.index_constants[0])); + let mut handle = expressions.append(crate::Expression::Access { + base: root_lexp.handle, + index: index_expr, + }); + for &index in self.index_constants[1..num_components].iter() { + index_expr = expressions.append(crate::Expression::Constant(index)); + let access_expr = expressions.append(crate::Expression::Access { + base: root_lexp.handle, + index: index_expr, + }); + let cond = expressions.append(crate::Expression::Binary { + op: crate::BinaryOperator::Equal, + left: index_expr, + right: index_lexp.handle, + }); + handle = expressions.append(crate::Expression::Select { + condition: cond, + accept: access_expr, + reject: handle, + }); + } + + self.lookup_expression.insert( + id, + LookupExpression { + handle, + type_id: result_type_id, + }, + ); + } + Op::VectorInsertDynamic => { + inst.expect(6)?; + let result_type_id = self.next()?; + let id = self.next()?; + let composite_id = self.next()?; + let object_id = self.next()?; + let index_id = self.next()?; + + let object_lexp = self.lookup_expression.lookup(object_id)?; + let root_lexp = self.lookup_expression.lookup(composite_id)?; + let root_type_lookup = self.lookup_type.lookup(root_lexp.type_id)?; + let index_lexp = self.lookup_expression.lookup(index_id)?; + + let num_components = match type_arena[root_type_lookup.handle].inner { + crate::TypeInner::Vector { size, .. } => size as usize, + _ => return Err(Error::InvalidVectorType(root_type_lookup.handle)), + }; + let mut components = Vec::with_capacity(num_components); + for &index in self.index_constants[..num_components].iter() { + let index_expr = expressions.append(crate::Expression::Constant(index)); + let access_expr = expressions.append(crate::Expression::Access { + base: root_lexp.handle, + index: index_expr, + }); + let cond = expressions.append(crate::Expression::Binary { + op: crate::BinaryOperator::Equal, + left: index_expr, + right: index_lexp.handle, + }); + let handle = expressions.append(crate::Expression::Select { + condition: cond, + accept: object_lexp.handle, + reject: access_expr, + }); + components.push(handle); + } + let handle = expressions.append(crate::Expression::Compose { + ty: root_type_lookup.handle, + components, + }); + + self.lookup_expression.insert( + id, + LookupExpression { + handle, + type_id: result_type_id, + }, + ); + } Op::CompositeExtract => { inst.expect_at_least(4)?; let result_type_id = self.next()?; @@ -1521,6 +1620,19 @@ impl> Parser { crate::Module::generate_empty() }; + self.index_constants.clear(); + for i in 0..4 { + let handle = module.constants.append(crate::Constant { + name: None, + specialization: None, + inner: crate::ConstantInner::Scalar { + width: 4, + value: crate::ScalarValue::Uint(i), + }, + }); + self.index_constants.push(handle); + } + while let Ok(inst) = self.next_inst() { use spirv::Op; log::debug!("\t{:?} [{}]", inst.op, inst.wc); diff --git a/src/proc/validator.rs b/src/proc/validator.rs index b41972955a..628a5c48cf 100644 --- a/src/proc/validator.rs +++ b/src/proc/validator.rs @@ -194,7 +194,7 @@ impl crate::GlobalVariable { }, Bi::FrontFacing => Ti::Scalar { kind: Sk::Bool, - width, + width: 1, }, Bi::GlobalInvocationId | Bi::LocalInvocationId diff --git a/tests/out/shadow.ron.snap b/tests/out/shadow.ron.snap index 7a7e6c2333..dd89e48740 100644 --- a/tests/out/shadow.ron.snap +++ b/tests/out/shadow.ron.snap @@ -174,6 +174,38 @@ expression: output ), ], constants: [ + ( + name: None, + specialization: None, + inner: Scalar( + width: 4, + value: Uint(0), + ), + ), + ( + name: None, + specialization: None, + inner: Scalar( + width: 4, + value: Uint(1), + ), + ), + ( + name: None, + specialization: None, + inner: Scalar( + width: 4, + value: Uint(2), + ), + ), + ( + name: None, + specialization: None, + inner: Scalar( + width: 4, + value: Uint(3), + ), + ), ( name: None, specialization: None, @@ -220,9 +252,9 @@ expression: output inner: Composite( ty: 2, components: [ - 5, - 5, - 5, + 9, + 9, + 9, ], ), ), @@ -596,41 +628,41 @@ expression: output GlobalVariable(2), GlobalVariable(4), GlobalVariable(7), - Constant(16), - Constant(3), + Constant(20), + Constant(7), + Constant(33), + Constant(31), Constant(29), Constant(27), Constant(25), + Constant(15), + Constant(12), Constant(23), - Constant(21), - Constant(11), Constant(8), - Constant(19), - Constant(4), + Constant(36), + Constant(34), + Constant(14), Constant(32), Constant(30), - Constant(10), - Constant(28), - Constant(26), - Constant(13), - Constant(22), - Constant(35), - Constant(9), - Constant(7), - Constant(5), - Constant(2), Constant(17), - Constant(31), - Constant(15), - Constant(33), - Constant(14), - Constant(24), - Constant(12), - Constant(20), - Constant(34), - Constant(18), + Constant(26), + Constant(39), + Constant(13), + Constant(11), + Constant(9), Constant(6), - Constant(1), + Constant(21), + Constant(35), + Constant(19), + Constant(37), + Constant(18), + Constant(28), + Constant(16), + Constant(24), + Constant(38), + Constant(22), + Constant(10), + Constant(5), FunctionArgument(0), FunctionArgument(1), AccessIndex( @@ -824,12 +856,12 @@ expression: output ( name: Some("color"), ty: 2, - init: Some(6), + init: Some(10), ), ( name: Some("i"), ty: 3, - init: Some(8), + init: Some(12), ), ], expressions: [ @@ -840,41 +872,41 @@ expression: output GlobalVariable(2), GlobalVariable(4), GlobalVariable(7), - Constant(16), - Constant(3), + Constant(20), + Constant(7), + Constant(33), + Constant(31), Constant(29), Constant(27), Constant(25), + Constant(15), + Constant(12), Constant(23), - Constant(21), - Constant(11), Constant(8), - Constant(19), - Constant(4), + Constant(36), + Constant(34), + Constant(14), Constant(32), Constant(30), - Constant(10), - Constant(28), - Constant(26), - Constant(13), - Constant(22), - Constant(35), - Constant(9), - Constant(7), - Constant(5), - Constant(2), Constant(17), - Constant(31), - Constant(15), - Constant(33), - Constant(14), - Constant(24), - Constant(12), - Constant(20), - Constant(34), - Constant(18), + Constant(26), + Constant(39), + Constant(13), + Constant(11), + Constant(9), Constant(6), - Constant(1), + Constant(21), + Constant(35), + Constant(19), + Constant(37), + Constant(18), + Constant(28), + Constant(16), + Constant(24), + Constant(38), + Constant(22), + Constant(10), + Constant(5), LocalVariable(1), LocalVariable(2), AccessIndex(