From b6e4a9470ebf9aec2850f24d703f2d0d4907f50f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Sun, 2 Jan 2022 22:02:46 +0100 Subject: [PATCH] Shader/Ast: Treat repeated swizzle as rvalue (cannot be assigned) --- src/Nazara/Shader/Ast/AstUtils.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Shader/Ast/AstUtils.cpp b/src/Nazara/Shader/Ast/AstUtils.cpp index 695be1291..eedfedd6a 100644 --- a/src/Nazara/Shader/Ast/AstUtils.cpp +++ b/src/Nazara/Shader/Ast/AstUtils.cpp @@ -84,11 +84,33 @@ namespace Nz::ShaderAst void ShaderAstValueCategory::Visit(SwizzleExpression& node) { - // Swizzling more than a component on a primitive produces a rvalue (a.xxxx cannot be assigned) if (IsPrimitiveType(GetExpressionType(node)) && node.componentCount > 1) + // Swizzling more than a component on a primitive produces a rvalue (a.xxxx cannot be assigned) m_expressionCategory = ExpressionCategory::RValue; else - node.expression->Visit(*this); + { + bool isRVaLue = false; + + std::array used; + used.fill(false); + + for (std::size_t i = 0; i < node.componentCount; ++i) + { + if (used[node.components[i]]) + { + // Swizzling the same component multiple times produces a rvalue (a.xx cannot be assigned) + isRVaLue = true; + break; + } + + used[node.components[i]] = true; + } + + if (isRVaLue) + m_expressionCategory = ExpressionCategory::RValue; + else + node.expression->Visit(*this); + } } void ShaderAstValueCategory::Visit(VariableExpression& /*node*/)