fixed SkSL handling of negated literal vectors
Bug: oss-fuzz:14409 Change-Id: I837083139489d46f7db2f697ce85a0cabf85fb94 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/219997 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
parent
6488077ea3
commit
d188c18835
@ -535,9 +535,15 @@ bool is_constant(const Expression& expr, double value) {
|
||||
return ((FloatLiteral&) expr).fValue == value;
|
||||
case Expression::kConstructor_Kind: {
|
||||
Constructor& c = (Constructor&) expr;
|
||||
bool isFloat = c.fType.columns() > 1 ? c.fType.componentType().isFloat()
|
||||
: c.fType.isFloat();
|
||||
if (c.fType.kind() == Type::kVector_Kind && c.isConstant()) {
|
||||
for (int i = 0; i < c.fType.columns(); ++i) {
|
||||
if (!is_constant(*c.getVecComponent(i), value)) {
|
||||
if (isFloat) {
|
||||
if (c.getFVecComponent(i) != value) {
|
||||
return false;
|
||||
}
|
||||
} else if (c.getIVecComponent(i) != value) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
#endif // SK_SUPPORT_GPU
|
||||
#endif // SKSL_STANDALONE
|
||||
|
||||
using SKSL_INT = uint32_t;
|
||||
using SKSL_INT = int32_t;
|
||||
using SKSL_FLOAT = float;
|
||||
|
||||
class GrShaderCaps;
|
||||
|
@ -92,8 +92,14 @@ struct Constructor : public Expression {
|
||||
SkASSERT(other.fKind == Expression::kConstructor_Kind && other.fType == fType);
|
||||
Constructor& c = (Constructor&) other;
|
||||
if (c.fType.kind() == Type::kVector_Kind) {
|
||||
bool isFloat = c.fType.columns() > 1 ? c.fType.componentType().isFloat()
|
||||
: c.fType.isFloat();
|
||||
for (int i = 0; i < fType.columns(); i++) {
|
||||
if (!this->getVecComponent(i)->compareConstant(context, *c.getVecComponent(i))) {
|
||||
if (isFloat) {
|
||||
if (this->getFVecComponent(i) != c.getFVecComponent(i)) {
|
||||
return false;
|
||||
}
|
||||
} else if (this->getIVecComponent(i) != c.getIVecComponent(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -113,22 +119,39 @@ struct Constructor : public Expression {
|
||||
return true;
|
||||
}
|
||||
|
||||
const Expression* getVecComponent(int index) const {
|
||||
template<typename type>
|
||||
type getVecComponent(int index) const {
|
||||
SkASSERT(fType.kind() == Type::kVector_Kind);
|
||||
if (fArguments.size() == 1 && fArguments[0]->fType.kind() == Type::kScalar_Kind) {
|
||||
return fArguments[0].get();
|
||||
if (std::is_floating_point<type>::value) {
|
||||
return fArguments[0]->getConstantFloat();
|
||||
} else {
|
||||
return fArguments[0]->getConstantInt();
|
||||
}
|
||||
}
|
||||
int current = 0;
|
||||
for (const auto& arg : fArguments) {
|
||||
SkASSERT(current <= index);
|
||||
if (arg->fType.kind() == Type::kScalar_Kind) {
|
||||
if (index == current) {
|
||||
return arg.get();
|
||||
if (std::is_floating_point<type>::value) {
|
||||
return arg.get()->getConstantFloat();
|
||||
} else {
|
||||
return arg.get()->getConstantInt();
|
||||
}
|
||||
}
|
||||
current++;
|
||||
} else if (arg->fKind == kConstructor_Kind) {
|
||||
if (current + arg->fType.columns() > index) {
|
||||
return ((const Constructor&) *arg).getVecComponent<type>(index - current);
|
||||
}
|
||||
current += arg->fType.columns();
|
||||
} else {
|
||||
if (current + arg->fType.columns() > index) {
|
||||
return ((const Constructor&) *arg).getVecComponent(index - current);
|
||||
SkASSERT(arg->fKind == kPrefix_Kind);
|
||||
const PrefixExpression& p = (PrefixExpression&) *arg;
|
||||
const Constructor& c = (const Constructor&) *p.fOperand;
|
||||
return -c.getVecComponent<type>(index - current);
|
||||
}
|
||||
current += arg->fType.columns();
|
||||
}
|
||||
@ -136,15 +159,19 @@ struct Constructor : public Expression {
|
||||
ABORT("failed to find vector component %d in %s\n", index, description().c_str());
|
||||
}
|
||||
|
||||
double getFVecComponent(int index) const override {
|
||||
return this->getVecComponent(index)->getConstantFloat();
|
||||
SKSL_FLOAT getFVecComponent(int n) const override {
|
||||
return this->getVecComponent<SKSL_FLOAT>(n);
|
||||
}
|
||||
|
||||
int64_t getIVecComponent(int index) const override {
|
||||
return this->getVecComponent(index)->getConstantInt();
|
||||
/**
|
||||
* For a literal vector expression, return the integer value of the n'th vector component. It is
|
||||
* an error to call this method on an expression which is not a literal vector.
|
||||
*/
|
||||
SKSL_INT getIVecComponent(int n) const override {
|
||||
return this->getVecComponent<SKSL_INT>(n);
|
||||
}
|
||||
|
||||
double getMatComponent(int col, int row) const override {
|
||||
SKSL_FLOAT getMatComponent(int col, int row) const override {
|
||||
SkASSERT(this->isConstant());
|
||||
SkASSERT(fType.kind() == Type::kMatrix_Kind);
|
||||
SkASSERT(col < fType.columns() && row < fType.rows());
|
||||
|
@ -113,7 +113,7 @@ struct Expression : public IRNode {
|
||||
* For a literal vector expression, return the floating point value of the n'th vector
|
||||
* component. It is an error to call this method on an expression which is not a literal vector.
|
||||
*/
|
||||
virtual double getFVecComponent(int n) const {
|
||||
virtual SKSL_FLOAT getFVecComponent(int n) const {
|
||||
SkASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
@ -122,7 +122,7 @@ struct Expression : public IRNode {
|
||||
* For a literal vector expression, return the integer value of the n'th vector component. It is
|
||||
* an error to call this method on an expression which is not a literal vector.
|
||||
*/
|
||||
virtual int64_t getIVecComponent(int n) const {
|
||||
virtual SKSL_INT getIVecComponent(int n) const {
|
||||
SkASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
@ -132,7 +132,7 @@ struct Expression : public IRNode {
|
||||
* [col][row]. It is an error to call this method on an expression which is not a literal
|
||||
* matrix.
|
||||
*/
|
||||
virtual double getMatComponent(int col, int row) const {
|
||||
virtual SKSL_FLOAT getMatComponent(int col, int row) const {
|
||||
SkASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
|
@ -46,17 +46,17 @@ struct PrefixExpression : public Expression {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
double getFVecComponent(int index) const override {
|
||||
SKSL_FLOAT getFVecComponent(int index) const override {
|
||||
SkASSERT(fOperator == Token::Kind::MINUS);
|
||||
return -fOperand->getFVecComponent(index);
|
||||
}
|
||||
|
||||
int64_t getIVecComponent(int index) const override {
|
||||
SKSL_INT getIVecComponent(int index) const override {
|
||||
SkASSERT(fOperator == Token::Kind::MINUS);
|
||||
return -fOperand->getIVecComponent(index);
|
||||
}
|
||||
|
||||
double getMatComponent(int col, int row) const override {
|
||||
SKSL_FLOAT getMatComponent(int col, int row) const override {
|
||||
SkASSERT(fOperator == Token::Kind::MINUS);
|
||||
return -fOperand->getMatComponent(col, row);
|
||||
}
|
||||
|
@ -2296,3 +2296,19 @@ DEF_TEST(SkSLSwizzleConstants, r) {
|
||||
SkSL::Program::kFragment_Kind
|
||||
);
|
||||
}
|
||||
|
||||
DEF_TEST(SkSLNegatedVectorLiteral, r) {
|
||||
test(r,
|
||||
"void main() {"
|
||||
" if (half4(1) == half4(-half2(-1), half2(1)))"
|
||||
" sk_FragColor = half4(0, 1, 0, 1);"
|
||||
" else"
|
||||
" sk_FragColor = half4(1, 0, 0, 1);"
|
||||
"}",
|
||||
*SkSL::ShaderCapsFactory::Default(),
|
||||
"#version 400\n"
|
||||
"out vec4 sk_FragColor;\n"
|
||||
"void main() {\n"
|
||||
" sk_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
|
||||
"}\n");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user