glsl-in: fix pre/postfix ops on swizzles

This commit is contained in:
João Capucho 2021-12-04 21:54:55 +00:00 committed by Dzmitry Malyshau
parent c69f676609
commit 14719553a6
3 changed files with 77 additions and 62 deletions

View File

@ -418,6 +418,69 @@ impl Context {
Ok((expr, meta))
}
fn lower_store(
&mut self,
pointer: Handle<Expression>,
value: Handle<Expression>,
meta: Span,
body: &mut Block,
) {
if let Expression::Swizzle {
size,
mut vector,
pattern,
} = self.expressions[pointer]
{
// Stores to swizzled values are not directly supported,
// lower them as series of per-component stores.
let size = match size {
VectorSize::Bi => 2,
VectorSize::Tri => 3,
VectorSize::Quad => 4,
};
if let Expression::Load { pointer } = self.expressions[vector] {
vector = pointer;
}
#[allow(clippy::needless_range_loop)]
for index in 0..size {
let dst = self.add_expression(
Expression::AccessIndex {
base: vector,
index: pattern[index].index(),
},
meta,
body,
);
let src = self.add_expression(
Expression::AccessIndex {
base: value,
index: index as u32,
},
meta,
body,
);
self.emit_flush(body);
self.emit_start();
body.push(
Statement::Store {
pointer: dst,
value: src,
},
meta,
);
}
} else {
self.emit_flush(body);
self.emit_start();
body.push(Statement::Store { pointer, value }, meta);
}
}
/// Internal implementation of [`lower`](Self::lower)
fn lower_inner(
&mut self,
@ -694,68 +757,18 @@ impl Context {
self.implicit_conversion(parser, &mut value, value_meta, kind, width)?;
}
if let Expression::Swizzle {
size,
mut vector,
pattern,
} = self.expressions[pointer]
{
// Stores to swizzled values are not directly supported,
// lower them as series of per-component stores.
let size = match size {
VectorSize::Bi => 2,
VectorSize::Tri => 3,
VectorSize::Quad => 4,
};
if let Expression::Load { pointer } = self.expressions[vector] {
vector = pointer;
}
#[allow(clippy::needless_range_loop)]
for index in 0..size {
let dst = self.add_expression(
Expression::AccessIndex {
base: vector,
index: pattern[index].index(),
},
meta,
body,
);
let src = self.add_expression(
Expression::AccessIndex {
base: value,
index: index as u32,
},
meta,
body,
);
self.emit_flush(body);
self.emit_start();
body.push(
Statement::Store {
pointer: dst,
value: src,
},
meta,
);
}
} else {
self.emit_flush(body);
self.emit_start();
body.push(Statement::Store { pointer, value }, meta);
}
self.lower_store(pointer, value, meta, body);
value
}
HirExprKind::PrePostfix { op, postfix, expr } if ExprPos::Lhs != pos => {
let pointer = self
.lower_expect_inner(stmt, parser, expr, ExprPos::Lhs, body)?
.0;
let left = self.add_expression(Expression::Load { pointer }, meta, body);
let (pointer, _) =
self.lower_expect_inner(stmt, parser, expr, ExprPos::Lhs, body)?;
let left = if let Expression::Swizzle { .. } = self.expressions[pointer] {
pointer
} else {
self.add_expression(Expression::Load { pointer }, meta, body)
};
let make_constant_inner = |kind, width| {
let value = match kind {
@ -844,10 +857,7 @@ impl Context {
let value = self.add_expression(Expression::Binary { op, left, right }, meta, body);
self.emit_flush(body);
self.emit_start();
body.push(Statement::Store { pointer, value }, meta);
self.lower_store(pointer, value, meta, body);
if postfix {
left

View File

@ -5,4 +5,5 @@ void main() {
vec3 x = vec3(2.0);
x.zxy.xy = vec2(3.0, 4.0);
x.rg *= 5.0;
x.zy++;
}

View File

@ -10,6 +10,10 @@ fn main_1() {
let _e18 = (_e15.xy * 5.0);
x.x = _e18.x;
x.y = _e18.y;
let _e23 = x;
let _e27 = (_e23.zy + vec2<f32>(1.0));
x.z = _e27.x;
x.y = _e27.y;
return;
}