// Vector by matrix multiplication has a pattern of: // float2(dot(m_row1, v), dot(m_row2, v)) // float3(dot(m_row1, v), dot(m_row2, v), dot(m_row3, v)) // float4(dot(m_row1, v), dot(m_row2, v), dot(m_row3, v), dot(m_row4, v)) public MatrixMultiplicationContext TryGetMultiplicationGroup(IList <HlslTreeNode> components) { const bool allowMatrix = true; if (!(components[0] is DotProductOperation firstDot)) { return(null); } int dimension = firstDot.X.Length; if (components.Count < dimension) { return(null); } GroupNode firstMatrixRow = TryGetMatrixRow(firstDot, firstDot, 0); if (firstMatrixRow == null) { return(null); } GroupNode vector = firstDot.X == firstMatrixRow ? firstDot.Y : firstDot.X; var matrixRows = new List <GroupNode>(); matrixRows.Add(firstMatrixRow); for (int i = 1; i < components.Count; i++) { if (!(components[i] is DotProductOperation nextDot)) { break; } GroupNode matrixRow = TryGetMatrixRow(nextDot, firstDot, i); if (matrixRow == null) { break; } GroupNode nextVector = nextDot.X == matrixRow ? nextDot.Y : nextDot.X; if (!NodeGrouper.AreNodesEquivalent(vector, nextVector)) { break; } matrixRows.Add(matrixRow); } if (matrixRows.Count < 2) { return(null); } ConstantDeclaration matrix = TryGetMatrixDeclaration(matrixRows); if (matrix == null) { return(null); } bool matrixByVector = firstMatrixRow.Inputs .Cast <RegisterInputNode>() .All(row => row.ComponentIndex == 0); vector = SwizzleVector(vector, firstMatrixRow, matrixByVector); return(new MatrixMultiplicationContext(vector, matrix, matrixByVector, matrixRows.Count)); }