]> git.tdb.fi Git - libs/gl.git/commitdiff
Refactor matrix constructor resolving with some early checks
authorMikko Rasa <tdb@tdb.fi>
Sat, 16 Dec 2023 08:29:16 +0000 (10:29 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sat, 16 Dec 2023 23:08:17 +0000 (01:08 +0200)
source/glsl/resolve.cpp

index e1d2065b7ffaa74f09512d57fe36d76231cd8330..7c6d2bad80cac32ae2640a49200f64d227f9b78b 100644 (file)
@@ -919,6 +919,7 @@ void ExpressionResolver::visit_constructor(FunctionCall &call)
                vector<ArgumentInfo> args;
                args.reserve(call.arguments.size());
                unsigned arg_component_total = 0;
+               bool homogeneous_args = true;
                bool has_matrices = false;
                for(const RefPtr<Expression> &a: call.arguments)
                {
@@ -937,6 +938,8 @@ void ExpressionResolver::visit_constructor(FunctionCall &call)
                        else
                                return;
                        arg_component_total += info.component_count;
+                       if(!args.empty() && info.component_count!=args.back().component_count)
+                               homogeneous_args = false;
                        args.push_back(info);
                }
 
@@ -1026,18 +1029,34 @@ void ExpressionResolver::visit_constructor(FunctionCall &call)
                                else
                                        return;
                        }
+                       else if(homogeneous_args && args.front().component_count==row_count)
+                       {
+                               /* A matrix can be constructed from column vectors of appropriate
+                               size. */
+                               if(args.size()!=column_count)
+                                       return;
+                       }
                        else if(arg_component_total==column_count*row_count && !has_matrices)
                        {
                                /* Construct a matrix from individual components in column-major
                                order.  Arguments must align at column boundaries. */
+                               unsigned column_component_count = 0;
+                               for(unsigned j=0; j<call.arguments.size(); ++j)
+                               {
+                                       column_component_count += args[j].component_count;
+                                       if(column_component_count>=row_count && (column_component_count -= row_count))
+                                               // Argument alignment mismatch
+                                               return;
+                               }
+
                                vector<RefPtr<Expression> > column_args;
                                column_args.reserve(row_count);
-                               unsigned column_component_count = 0;
 
+                               column_component_count = 0;
                                for(unsigned j=0; j<call.arguments.size(); ++j)
                                {
                                        const ArgumentInfo &info = args[j];
-                                       if(!column_component_count && info.type->kind==BasicTypeDeclaration::VECTOR && info.component_count==row_count)
+                                       if(!column_component_count && info.component_count==row_count)
                                                // A vector filling the entire column can be used as is.
                                                columns.push_back(call.arguments[j]);
                                        else
@@ -1060,13 +1079,10 @@ void ExpressionResolver::visit_constructor(FunctionCall &call)
                                                        column_args.clear();
                                                        column_component_count = 0;
                                                }
-                                               else if(column_component_count>row_count)
-                                                       // Argument alignment mismatch.
-                                                       return;
-
-                                               changed_columns = true;
                                        }
                                }
+
+                               changed_columns = true;
                        }
                        else
                                return;