Fixed the compound-assignment-type-combination.html test
The fix is in 2 parts:
1) Multiplying a matrix by a float was failing due to attempting
to use the matrix's index on the float, thus going out of bounds.
2) Multiplying a vector or matrix by vectors or matrices of a
different size was not causing a failure, but now it does.
BUG=18450319
Change-Id: Ie01a77eb32d7d52fcd0a803f3e5efc24c625dbfd
Reviewed-on: https://swiftshader-review.googlesource.com/1450
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/compiler/OutputASM.cpp b/src/OpenGL/compiler/OutputASM.cpp
index e8aa3f3..ff73893 100644
--- a/src/OpenGL/compiler/OutputASM.cpp
+++ b/src/OpenGL/compiler/OutputASM.cpp
@@ -1432,7 +1432,7 @@
TIntermTyped *arg = argument->getAsTyped();
const TType &type = arg->getType();
const TTypeList *structure = type.getStruct();
- ASSERT(index < arg->totalRegisterCount());
+ index = (index >= arg->totalRegisterCount()) ? arg->totalRegisterCount() - 1 : index;
int size = registerSize(type, index);
@@ -1522,8 +1522,15 @@
(swizzleElement(leftSwizzle, swizzleElement(rightSwizzle, 3)) << 6);
}
- void OutputASM::assignLvalue(TIntermTyped *dst, TIntermNode *src)
+ void OutputASM::assignLvalue(TIntermTyped *dst, TIntermTyped *src)
{
+ if(src &&
+ ((src->isVector() && (!dst->isVector() || (dst->getNominalSize() != dst->getNominalSize()))) ||
+ (src->isMatrix() && (!dst->isMatrix() || (src->getNominalSize() != dst->getNominalSize())))))
+ {
+ return mContext.error(src->getLine(), "Result type should match the l-value type in compound assignment", src->isVector() ? "vector" : "matrix");
+ }
+
TIntermBinary *binary = dst->getAsBinaryNode();
if(binary && binary->getOp() == EOpIndexIndirect && dst->isScalar())
diff --git a/src/OpenGL/compiler/OutputASM.h b/src/OpenGL/compiler/OutputASM.h
index ae6cfa7..4f0ae3d 100644
--- a/src/OpenGL/compiler/OutputASM.h
+++ b/src/OpenGL/compiler/OutputASM.h
@@ -113,7 +113,7 @@
void emitCmp(sw::Shader::Control cmpOp, TIntermTyped *dst, TIntermNode *left, TIntermNode *right, int index = 0);
void argument(sw::Shader::SourceParameter ¶meter, TIntermNode *argument, int index = 0);
void copy(TIntermTyped *dst, TIntermNode *src, int offset = 0);
- void assignLvalue(TIntermTyped *dst, TIntermNode *src);
+ void assignLvalue(TIntermTyped *dst, TIntermTyped *src);
int lvalue(sw::Shader::DestinationParameter &dst, Temporary &address, TIntermTyped *node);
sw::Shader::ParameterType registerType(TIntermTyped *operand);
int registerIndex(TIntermTyped *operand);
diff --git a/src/Radiance/compiler/OutputASM.cpp b/src/Radiance/compiler/OutputASM.cpp
index b85edf6..07b4bf0 100644
--- a/src/Radiance/compiler/OutputASM.cpp
+++ b/src/Radiance/compiler/OutputASM.cpp
@@ -1432,7 +1432,7 @@
TIntermTyped *arg = argument->getAsTyped();
const TType &type = arg->getType();
const TTypeList *structure = type.getStruct();
- ASSERT(index < arg->totalRegisterCount());
+ index = (index >= arg->totalRegisterCount()) ? arg->totalRegisterCount() - 1 : index;
int size = registerSize(type, index);
@@ -1522,8 +1522,15 @@
(swizzleElement(leftSwizzle, swizzleElement(rightSwizzle, 3)) << 6);
}
- void OutputASM::assignLvalue(TIntermTyped *dst, TIntermNode *src)
+ void OutputASM::assignLvalue(TIntermTyped *dst, TIntermTyped *src)
{
+ if(src &&
+ ((src->isVector() && (!dst->isVector() || (dst->getNominalSize() != dst->getNominalSize()))) ||
+ (src->isMatrix() && (!dst->isMatrix() || (src->getNominalSize() != dst->getNominalSize())))))
+ {
+ return mContext.error(src->getLine(), "Result type should match the l-value type in compound assignment", src->isVector() ? "vector" : "matrix");
+ }
+
TIntermBinary *binary = dst->getAsBinaryNode();
if(binary && binary->getOp() == EOpIndexIndirect && dst->isScalar())
diff --git a/src/Radiance/compiler/OutputASM.h b/src/Radiance/compiler/OutputASM.h
index a40fc36..fb58700 100644
--- a/src/Radiance/compiler/OutputASM.h
+++ b/src/Radiance/compiler/OutputASM.h
@@ -113,7 +113,7 @@
void emitCmp(sw::Shader::Control cmpOp, TIntermTyped *dst, TIntermNode *left, TIntermNode *right, int index = 0);
void argument(sw::Shader::SourceParameter ¶meter, TIntermNode *argument, int index = 0);
void copy(TIntermTyped *dst, TIntermNode *src, int offset = 0);
- void assignLvalue(TIntermTyped *dst, TIntermNode *src);
+ void assignLvalue(TIntermTyped *dst, TIntermTyped *src);
int lvalue(sw::Shader::DestinationParameter &dst, Temporary &address, TIntermTyped *node);
sw::Shader::ParameterType registerType(TIntermTyped *operand);
int registerIndex(TIntermTyped *operand);