Represent matrix casts with CompositeCast type.
Vector and matrix typecasting is mechanically very similar, so it makes sense to represent these with a single constructor type and paper over the tiny differences in each backend. (SPIR-V in particular needs a separate path for matrix casting versus vector casting.) Change-Id: Id9ea7ca6297e69b3e813c69bfdc56073b50d8d89 Bug: skia:11032 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/393216 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: John Stiles <johnstiles@google.com> Auto-Submit: John Stiles <johnstiles@google.com>
This commit is contained in:
parent
75ee737770
commit
268a73f9e8
@ -98,6 +98,8 @@ skia_sksl_sources = [
|
||||
"$_src/sksl/ir/SkSLConstructorArray.h",
|
||||
"$_src/sksl/ir/SkSLConstructorComposite.cpp",
|
||||
"$_src/sksl/ir/SkSLConstructorComposite.h",
|
||||
"$_src/sksl/ir/SkSLConstructorCompositeCast.cpp",
|
||||
"$_src/sksl/ir/SkSLConstructorCompositeCast.h",
|
||||
"$_src/sksl/ir/SkSLConstructorDiagonalMatrix.cpp",
|
||||
"$_src/sksl/ir/SkSLConstructorDiagonalMatrix.h",
|
||||
"$_src/sksl/ir/SkSLConstructorMatrixResize.cpp",
|
||||
@ -106,8 +108,6 @@ skia_sksl_sources = [
|
||||
"$_src/sksl/ir/SkSLConstructorScalarCast.h",
|
||||
"$_src/sksl/ir/SkSLConstructorSplat.cpp",
|
||||
"$_src/sksl/ir/SkSLConstructorSplat.h",
|
||||
"$_src/sksl/ir/SkSLConstructorVectorCast.cpp",
|
||||
"$_src/sksl/ir/SkSLConstructorVectorCast.h",
|
||||
"$_src/sksl/ir/SkSLContinueStatement.h",
|
||||
"$_src/sksl/ir/SkSLDiscardStatement.h",
|
||||
"$_src/sksl/ir/SkSLDoStatement.cpp",
|
||||
|
@ -749,11 +749,11 @@ bool Analysis::IsSameExpressionTree(const Expression& left, const Expression& ri
|
||||
case Expression::Kind::kConstructor:
|
||||
case Expression::Kind::kConstructorArray:
|
||||
case Expression::Kind::kConstructorComposite:
|
||||
case Expression::Kind::kConstructorCompositeCast:
|
||||
case Expression::Kind::kConstructorDiagonalMatrix:
|
||||
case Expression::Kind::kConstructorMatrixResize:
|
||||
case Expression::Kind::kConstructorScalarCast:
|
||||
case Expression::Kind::kConstructorSplat:
|
||||
case Expression::Kind::kConstructorVectorCast: {
|
||||
case Expression::Kind::kConstructorSplat: {
|
||||
if (left.kind() != right.kind()) {
|
||||
return false;
|
||||
}
|
||||
@ -1029,11 +1029,11 @@ public:
|
||||
case Expression::Kind::kConstructor:
|
||||
case Expression::Kind::kConstructorArray:
|
||||
case Expression::Kind::kConstructorComposite:
|
||||
case Expression::Kind::kConstructorCompositeCast:
|
||||
case Expression::Kind::kConstructorDiagonalMatrix:
|
||||
case Expression::Kind::kConstructorMatrixResize:
|
||||
case Expression::Kind::kConstructorScalarCast:
|
||||
case Expression::Kind::kConstructorSplat:
|
||||
case Expression::Kind::kConstructorVectorCast:
|
||||
case Expression::Kind::kFieldAccess:
|
||||
case Expression::Kind::kIndex:
|
||||
case Expression::Kind::kPrefix:
|
||||
@ -1158,11 +1158,11 @@ template <typename T> bool TProgramVisitor<T>::visitExpression(typename T::Expre
|
||||
case Expression::Kind::kConstructor:
|
||||
case Expression::Kind::kConstructorArray:
|
||||
case Expression::Kind::kConstructorComposite:
|
||||
case Expression::Kind::kConstructorCompositeCast:
|
||||
case Expression::Kind::kConstructorDiagonalMatrix:
|
||||
case Expression::Kind::kConstructorMatrixResize:
|
||||
case Expression::Kind::kConstructorScalarCast:
|
||||
case Expression::Kind::kConstructorSplat:
|
||||
case Expression::Kind::kConstructorVectorCast: {
|
||||
case Expression::Kind::kConstructorSplat: {
|
||||
auto& c = e.asAnyConstructor();
|
||||
for (auto& arg : c.argumentSpan()) {
|
||||
if (this->visitExpressionPtr(arg)) { return true; }
|
||||
|
@ -18,11 +18,11 @@
|
||||
#include "src/sksl/ir/SkSLConstructor.h"
|
||||
#include "src/sksl/ir/SkSLConstructorArray.h"
|
||||
#include "src/sksl/ir/SkSLConstructorComposite.h"
|
||||
#include "src/sksl/ir/SkSLConstructorCompositeCast.h"
|
||||
#include "src/sksl/ir/SkSLConstructorDiagonalMatrix.h"
|
||||
#include "src/sksl/ir/SkSLConstructorMatrixResize.h"
|
||||
#include "src/sksl/ir/SkSLConstructorScalarCast.h"
|
||||
#include "src/sksl/ir/SkSLConstructorSplat.h"
|
||||
#include "src/sksl/ir/SkSLConstructorVectorCast.h"
|
||||
#include "src/sksl/ir/SkSLContinueStatement.h"
|
||||
#include "src/sksl/ir/SkSLDiscardStatement.h"
|
||||
#include "src/sksl/ir/SkSLDoStatement.h"
|
||||
@ -306,6 +306,12 @@ void Dehydrator::write(const Expression* e) {
|
||||
this->writeExpressionSpan(e->as<ConstructorComposite>().argumentSpan());
|
||||
break;
|
||||
|
||||
case Expression::Kind::kConstructorCompositeCast:
|
||||
this->writeCommand(Rehydrator::kConstructorCompositeCast_Command);
|
||||
this->write(e->type());
|
||||
this->writeExpressionSpan(e->as<ConstructorCompositeCast>().argumentSpan());
|
||||
break;
|
||||
|
||||
case Expression::Kind::kConstructorDiagonalMatrix:
|
||||
this->writeCommand(Rehydrator::kConstructorDiagonalMatrix_Command);
|
||||
this->write(e->type());
|
||||
@ -330,12 +336,6 @@ void Dehydrator::write(const Expression* e) {
|
||||
this->writeExpressionSpan(e->as<ConstructorSplat>().argumentSpan());
|
||||
break;
|
||||
|
||||
case Expression::Kind::kConstructorVectorCast:
|
||||
this->writeCommand(Rehydrator::kConstructorVectorCast_Command);
|
||||
this->write(e->type());
|
||||
this->writeExpressionSpan(e->as<ConstructorVectorCast>().argumentSpan());
|
||||
break;
|
||||
|
||||
case Expression::Kind::kExternalFunctionCall:
|
||||
case Expression::Kind::kExternalFunctionReference:
|
||||
SkDEBUGFAIL("unimplemented--not expected to be used from within an include file");
|
||||
|
@ -205,7 +205,7 @@ void GLSLCodeGenerator::writeExpression(const Expression& expr, Precedence paren
|
||||
this->writeAnyConstructor(expr.asAnyConstructor(), parentPrecedence);
|
||||
break;
|
||||
case Expression::Kind::kConstructorScalarCast:
|
||||
case Expression::Kind::kConstructorVectorCast:
|
||||
case Expression::Kind::kConstructorCompositeCast:
|
||||
this->writeCastConstructor(expr.asAnyConstructor(), parentPrecedence);
|
||||
break;
|
||||
case Expression::Kind::kIntLiteral:
|
||||
|
@ -19,11 +19,11 @@
|
||||
#include "src/sksl/ir/SkSLConstructor.h"
|
||||
#include "src/sksl/ir/SkSLConstructorArray.h"
|
||||
#include "src/sksl/ir/SkSLConstructorComposite.h"
|
||||
#include "src/sksl/ir/SkSLConstructorCompositeCast.h"
|
||||
#include "src/sksl/ir/SkSLConstructorDiagonalMatrix.h"
|
||||
#include "src/sksl/ir/SkSLConstructorMatrixResize.h"
|
||||
#include "src/sksl/ir/SkSLConstructorScalarCast.h"
|
||||
#include "src/sksl/ir/SkSLConstructorSplat.h"
|
||||
#include "src/sksl/ir/SkSLConstructorVectorCast.h"
|
||||
#include "src/sksl/ir/SkSLContinueStatement.h"
|
||||
#include "src/sksl/ir/SkSLDiscardStatement.h"
|
||||
#include "src/sksl/ir/SkSLDoStatement.h"
|
||||
@ -331,6 +331,12 @@ std::unique_ptr<Expression> Inliner::inlineExpression(int offset,
|
||||
*ctor.type().clone(symbolTableForExpression),
|
||||
argList(ctor.arguments()));
|
||||
}
|
||||
case Expression::Kind::kConstructorCompositeCast: {
|
||||
const ConstructorCompositeCast& ctor = expression.as<ConstructorCompositeCast>();
|
||||
return ConstructorCompositeCast::Make(*fContext, offset,
|
||||
*ctor.type().clone(symbolTableForExpression),
|
||||
expr(ctor.argument()));
|
||||
}
|
||||
case Expression::Kind::kConstructorDiagonalMatrix: {
|
||||
const ConstructorDiagonalMatrix& ctor = expression.as<ConstructorDiagonalMatrix>();
|
||||
return ConstructorDiagonalMatrix::Make(*fContext, offset,
|
||||
@ -355,12 +361,6 @@ std::unique_ptr<Expression> Inliner::inlineExpression(int offset,
|
||||
*ctor.type().clone(symbolTableForExpression),
|
||||
expr(ctor.argument()));
|
||||
}
|
||||
case Expression::Kind::kConstructorVectorCast: {
|
||||
const ConstructorVectorCast& ctor = expression.as<ConstructorVectorCast>();
|
||||
return ConstructorVectorCast::Make(*fContext, offset,
|
||||
*ctor.type().clone(symbolTableForExpression),
|
||||
expr(ctor.argument()));
|
||||
}
|
||||
case Expression::Kind::kExternalFunctionCall: {
|
||||
const ExternalFunctionCall& externalCall = expression.as<ExternalFunctionCall>();
|
||||
return std::make_unique<ExternalFunctionCall>(offset, &externalCall.function(),
|
||||
@ -958,11 +958,11 @@ public:
|
||||
case Expression::Kind::kConstructor:
|
||||
case Expression::Kind::kConstructorArray:
|
||||
case Expression::Kind::kConstructorComposite:
|
||||
case Expression::Kind::kConstructorCompositeCast:
|
||||
case Expression::Kind::kConstructorDiagonalMatrix:
|
||||
case Expression::Kind::kConstructorMatrixResize:
|
||||
case Expression::Kind::kConstructorScalarCast:
|
||||
case Expression::Kind::kConstructorSplat:
|
||||
case Expression::Kind::kConstructorVectorCast: {
|
||||
case Expression::Kind::kConstructorSplat: {
|
||||
AnyConstructor& constructorExpr = (*expr)->asAnyConstructor();
|
||||
for (std::unique_ptr<Expression>& arg : constructorExpr.argumentSpan()) {
|
||||
this->visitExpression(&arg);
|
||||
|
@ -11,10 +11,10 @@
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "src/sksl/SkSLMemoryLayout.h"
|
||||
#include "src/sksl/ir/SkSLConstructorArray.h"
|
||||
#include "src/sksl/ir/SkSLConstructorCompositeCast.h"
|
||||
#include "src/sksl/ir/SkSLConstructorDiagonalMatrix.h"
|
||||
#include "src/sksl/ir/SkSLConstructorMatrixResize.h"
|
||||
#include "src/sksl/ir/SkSLConstructorSplat.h"
|
||||
#include "src/sksl/ir/SkSLConstructorVectorCast.h"
|
||||
#include "src/sksl/ir/SkSLExpressionStatement.h"
|
||||
#include "src/sksl/ir/SkSLExtension.h"
|
||||
#include "src/sksl/ir/SkSLIndexExpression.h"
|
||||
@ -189,7 +189,7 @@ void MetalCodeGenerator::writeExpression(const Expression& expr, Precedence pare
|
||||
break;
|
||||
case Expression::Kind::kConstructor:
|
||||
case Expression::Kind::kConstructorScalarCast:
|
||||
case Expression::Kind::kConstructorVectorCast:
|
||||
case Expression::Kind::kConstructorCompositeCast:
|
||||
this->writeCastConstructor(expr.asAnyConstructor(), "(", ")", parentPrecedence);
|
||||
break;
|
||||
case Expression::Kind::kIntLiteral:
|
||||
@ -2277,11 +2277,11 @@ MetalCodeGenerator::Requirements MetalCodeGenerator::requirements(const Expressi
|
||||
}
|
||||
case Expression::Kind::kConstructor:
|
||||
case Expression::Kind::kConstructorComposite:
|
||||
case Expression::Kind::kConstructorCompositeCast:
|
||||
case Expression::Kind::kConstructorArray:
|
||||
case Expression::Kind::kConstructorDiagonalMatrix:
|
||||
case Expression::Kind::kConstructorScalarCast:
|
||||
case Expression::Kind::kConstructorSplat:
|
||||
case Expression::Kind::kConstructorVectorCast: {
|
||||
case Expression::Kind::kConstructorSplat: {
|
||||
const AnyConstructor& c = e->asAnyConstructor();
|
||||
Requirements result = kNo_Requirements;
|
||||
for (const auto& arg : c.argumentSpan()) {
|
||||
|
@ -411,11 +411,11 @@ void PipelineStageCodeGenerator::writeExpression(const Expression& expr,
|
||||
case Expression::Kind::kConstructor:
|
||||
case Expression::Kind::kConstructorArray:
|
||||
case Expression::Kind::kConstructorComposite:
|
||||
case Expression::Kind::kConstructorCompositeCast:
|
||||
case Expression::Kind::kConstructorDiagonalMatrix:
|
||||
case Expression::Kind::kConstructorMatrixResize:
|
||||
case Expression::Kind::kConstructorScalarCast:
|
||||
case Expression::Kind::kConstructorSplat:
|
||||
case Expression::Kind::kConstructorVectorCast:
|
||||
this->writeAnyConstructor(expr.asAnyConstructor(), parentPrecedence);
|
||||
break;
|
||||
case Expression::Kind::kFieldAccess:
|
||||
|
@ -18,11 +18,11 @@
|
||||
#include "src/sksl/ir/SkSLConstructor.h"
|
||||
#include "src/sksl/ir/SkSLConstructorArray.h"
|
||||
#include "src/sksl/ir/SkSLConstructorComposite.h"
|
||||
#include "src/sksl/ir/SkSLConstructorCompositeCast.h"
|
||||
#include "src/sksl/ir/SkSLConstructorDiagonalMatrix.h"
|
||||
#include "src/sksl/ir/SkSLConstructorMatrixResize.h"
|
||||
#include "src/sksl/ir/SkSLConstructorScalarCast.h"
|
||||
#include "src/sksl/ir/SkSLConstructorSplat.h"
|
||||
#include "src/sksl/ir/SkSLConstructorVectorCast.h"
|
||||
#include "src/sksl/ir/SkSLContinueStatement.h"
|
||||
#include "src/sksl/ir/SkSLDiscardStatement.h"
|
||||
#include "src/sksl/ir/SkSLDoStatement.h"
|
||||
@ -499,11 +499,12 @@ std::unique_ptr<Expression> Rehydrator::expression() {
|
||||
SkASSERT(args.size() == 1);
|
||||
return ConstructorSplat::Make(fContext, /*offset=*/-1, *type, std::move(args[0]));
|
||||
}
|
||||
case Rehydrator::kConstructorVectorCast_Command: {
|
||||
case Rehydrator::kConstructorCompositeCast_Command: {
|
||||
const Type* type = this->type();
|
||||
ExpressionArray args = this->expressionArray();
|
||||
SkASSERT(args.size() == 1);
|
||||
return ConstructorVectorCast::Make(fContext, /*offset=*/-1, *type, std::move(args[0]));
|
||||
return ConstructorCompositeCast::Make(fContext, /*offset=*/-1, *type,
|
||||
std::move(args[0]));
|
||||
}
|
||||
case Rehydrator::kFieldAccess_Command: {
|
||||
std::unique_ptr<Expression> base = this->expression();
|
||||
|
@ -53,11 +53,11 @@ public:
|
||||
kConstructor_Command,
|
||||
kConstructorArray_Command,
|
||||
kConstructorComposite_Command,
|
||||
kConstructorCompositeCast_Command,
|
||||
kConstructorDiagonalMatrix_Command,
|
||||
kConstructorMatrixResize_Command,
|
||||
kConstructorScalarCast_Command,
|
||||
kConstructorSplat_Command,
|
||||
kConstructorVectorCast_Command,
|
||||
kConstructorReserved4_Command,
|
||||
kConstructorReserved5_Command,
|
||||
kContinue_Command,
|
||||
|
@ -723,8 +723,8 @@ SpvId SPIRVCodeGenerator::writeExpression(const Expression& expr, OutputStream&
|
||||
return this->writeConstructorSplat(expr.as<ConstructorSplat>(), out);
|
||||
case Expression::Kind::kConstructorComposite:
|
||||
return this->writeConstructorComposite(expr.as<ConstructorComposite>(), out);
|
||||
case Expression::Kind::kConstructorVectorCast:
|
||||
return this->writeConstructorVectorCast(expr.as<ConstructorVectorCast>(), out);
|
||||
case Expression::Kind::kConstructorCompositeCast:
|
||||
return this->writeConstructorCompositeCast(expr.as<ConstructorCompositeCast>(), out);
|
||||
case Expression::Kind::kIntLiteral:
|
||||
return this->writeIntLiteral(expr.as<IntLiteral>());
|
||||
case Expression::Kind::kFieldAccess:
|
||||
@ -1415,11 +1415,12 @@ void SPIRVCodeGenerator::writeUniformScaleMatrix(SpvId id, SpvId diagonal, const
|
||||
}
|
||||
}
|
||||
|
||||
void SPIRVCodeGenerator::writeMatrixCopy(SpvId id, SpvId src, const Type& srcType,
|
||||
const Type& dstType, OutputStream& out) {
|
||||
SpvId SPIRVCodeGenerator::writeMatrixCopy(SpvId src, const Type& srcType, const Type& dstType,
|
||||
OutputStream& out) {
|
||||
SkASSERT(srcType.isMatrix());
|
||||
SkASSERT(dstType.isMatrix());
|
||||
SkASSERT(srcType.componentType() == dstType.componentType());
|
||||
SpvId id = this->nextId(&dstType);
|
||||
SpvId srcColumnType = this->getType(srcType.componentType().toCompound(fContext,
|
||||
srcType.rows(),
|
||||
1));
|
||||
@ -1486,6 +1487,7 @@ void SPIRVCodeGenerator::writeMatrixCopy(SpvId id, SpvId src, const Type& srcTyp
|
||||
for (int i = 0; i < dstType.columns(); i++) {
|
||||
this->writeWord(columns[i], out);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
void SPIRVCodeGenerator::addColumnEntry(SpvId columnType, Precision precision,
|
||||
@ -1525,9 +1527,8 @@ SpvId SPIRVCodeGenerator::writeMatrixConstructor(const ConstructorComposite& c,
|
||||
SpvId result = this->nextId(&type);
|
||||
int rows = type.rows();
|
||||
int columns = type.columns();
|
||||
if (arguments.size() == 1 && arg0Type.isMatrix()) {
|
||||
this->writeMatrixCopy(result, arguments[0], arg0Type, type, out);
|
||||
} else if (arguments.size() == 1 && arg0Type.isVector()) {
|
||||
if (arguments.size() == 1 && arg0Type.isVector()) {
|
||||
// Special-case handling of float4 -> mat2x2.
|
||||
SkASSERT(type.rows() == 2 && type.columns() == 2);
|
||||
SkASSERT(arg0Type.columns() == 4);
|
||||
SpvId componentType = this->getType(type.componentType());
|
||||
@ -1666,11 +1667,6 @@ SpvId SPIRVCodeGenerator::writeArrayConstructor(const ConstructorArray& c, Outpu
|
||||
}
|
||||
|
||||
SpvId SPIRVCodeGenerator::writeConstructor(const Constructor& c, OutputStream& out) {
|
||||
const Type& type = c.type();
|
||||
if (c.arguments().size() == 1 &&
|
||||
this->getActualType(type) == this->getActualType(c.arguments()[0]->type())) {
|
||||
return this->writeExpression(*c.arguments()[0], out);
|
||||
}
|
||||
fErrors.error(c.fOffset, "unsupported constructor: " + c.description());
|
||||
return -1;
|
||||
}
|
||||
@ -1687,16 +1683,21 @@ SpvId SPIRVCodeGenerator::writeConstructorScalarCast(const ConstructorScalarCast
|
||||
return this->castScalarToType(expressionId, ctorExpr.type(), type, out);
|
||||
}
|
||||
|
||||
SpvId SPIRVCodeGenerator::writeConstructorVectorCast(const ConstructorVectorCast& c,
|
||||
OutputStream& out) {
|
||||
SpvId SPIRVCodeGenerator::writeConstructorCompositeCast(const ConstructorCompositeCast& c,
|
||||
OutputStream& out) {
|
||||
const Type& ctorType = c.type();
|
||||
const Type& argType = c.argument()->type();
|
||||
SkASSERT(ctorType.isVector());
|
||||
SkASSERT(ctorType.isVector() || ctorType.isMatrix());
|
||||
|
||||
// Write the vector that we are casting. If the actual type matches, we are done.
|
||||
SpvId vectorId = this->writeExpression(*c.argument(), out);
|
||||
// Write the composite that we are casting. If the actual type matches, we are done.
|
||||
SpvId compositeId = this->writeExpression(*c.argument(), out);
|
||||
if (this->getActualType(ctorType) == this->getActualType(argType)) {
|
||||
return vectorId;
|
||||
return compositeId;
|
||||
}
|
||||
|
||||
// writeMatrixCopy can cast matrices to a different type.
|
||||
if (ctorType.isMatrix()) {
|
||||
return this->writeMatrixCopy(compositeId, argType, ctorType, out);
|
||||
}
|
||||
|
||||
// SPIR-V doesn't support vector(vector-of-different-type) directly, so we need to extract the
|
||||
@ -1705,10 +1706,11 @@ SpvId SPIRVCodeGenerator::writeConstructorVectorCast(const ConstructorVectorCast
|
||||
const Type& dstType = ctorType.componentType();
|
||||
|
||||
std::vector<SpvId> arguments;
|
||||
arguments.reserve(argType.columns());
|
||||
for (int index = 0; index < argType.columns(); ++index) {
|
||||
SpvId componentId = this->nextId(&srcType);
|
||||
this->writeInstruction(SpvOpCompositeExtract, this->getType(srcType), componentId,
|
||||
vectorId, index, out);
|
||||
compositeId, index, out);
|
||||
arguments.push_back(this->castScalarToType(componentId, srcType, dstType, out));
|
||||
}
|
||||
|
||||
@ -1736,10 +1738,7 @@ SpvId SPIRVCodeGenerator::writeConstructorMatrixResize(const ConstructorMatrixRe
|
||||
SpvId argument = this->writeExpression(*c.argument(), out);
|
||||
|
||||
// Use matrix-copy to resize the input matrix to its new size.
|
||||
const Type& type = c.type();
|
||||
SpvId result = this->nextId(&type);
|
||||
this->writeMatrixCopy(result, argument, c.argument()->type(), type, out);
|
||||
return result;
|
||||
return this->writeMatrixCopy(argument, c.argument()->type(), c.type(), out);
|
||||
}
|
||||
|
||||
static SpvStorageClass_ get_storage_class(const Variable& var,
|
||||
|
@ -24,11 +24,11 @@
|
||||
#include "src/sksl/ir/SkSLConstructor.h"
|
||||
#include "src/sksl/ir/SkSLConstructorArray.h"
|
||||
#include "src/sksl/ir/SkSLConstructorComposite.h"
|
||||
#include "src/sksl/ir/SkSLConstructorCompositeCast.h"
|
||||
#include "src/sksl/ir/SkSLConstructorDiagonalMatrix.h"
|
||||
#include "src/sksl/ir/SkSLConstructorMatrixResize.h"
|
||||
#include "src/sksl/ir/SkSLConstructorScalarCast.h"
|
||||
#include "src/sksl/ir/SkSLConstructorSplat.h"
|
||||
#include "src/sksl/ir/SkSLConstructorVectorCast.h"
|
||||
#include "src/sksl/ir/SkSLDoStatement.h"
|
||||
#include "src/sksl/ir/SkSLFieldAccess.h"
|
||||
#include "src/sksl/ir/SkSLFloatLiteral.h"
|
||||
@ -282,8 +282,7 @@ private:
|
||||
* source matrix are filled with zero; entries which do not exist in the destination matrix are
|
||||
* ignored.
|
||||
*/
|
||||
void writeMatrixCopy(SpvId id, SpvId src, const Type& srcType, const Type& dstType,
|
||||
OutputStream& out);
|
||||
SpvId writeMatrixCopy(SpvId src, const Type& srcType, const Type& dstType, OutputStream& out);
|
||||
|
||||
void addColumnEntry(SpvId columnType, Precision precision, std::vector<SpvId>* currentColumn,
|
||||
std::vector<SpvId>* columnIds, int* currentCount, int rows, SpvId entry,
|
||||
@ -307,7 +306,7 @@ private:
|
||||
|
||||
SpvId writeConstructorSplat(const ConstructorSplat& c, OutputStream& out);
|
||||
|
||||
SpvId writeConstructorVectorCast(const ConstructorVectorCast& c, OutputStream& out);
|
||||
SpvId writeConstructorCompositeCast(const ConstructorCompositeCast& c, OutputStream& out);
|
||||
|
||||
SpvId writeComposite(const std::vector<SpvId>& arguments, const Type& type, OutputStream& out);
|
||||
|
||||
|
@ -646,29 +646,6 @@ Value SkVMGenerator::writeAggregationConstructor(const AnyConstructor& c) {
|
||||
}
|
||||
|
||||
Value SkVMGenerator::writeConstructor(const Constructor& c) {
|
||||
if (c.arguments().size() > 1) {
|
||||
// Multi-argument constructors just aggregate their arguments, with no conversion
|
||||
// NOTE: This (SkSL rule) is actually more restrictive than GLSL.
|
||||
return this->writeAggregationConstructor(c);
|
||||
}
|
||||
|
||||
const Type& srcType = c.arguments()[0]->type();
|
||||
const Type& dstType = c.type();
|
||||
Type::NumberKind srcKind = base_number_kind(srcType),
|
||||
dstKind = base_number_kind(dstType);
|
||||
Value src = this->writeExpression(*c.arguments()[0]);
|
||||
size_t dstSlots = dstType.slotCount();
|
||||
|
||||
// Conversion among "similar" types (floatN <-> halfN), (shortN <-> intN), etc. is a no-op
|
||||
if (srcKind == dstKind && src.slots() == dstSlots) {
|
||||
return src;
|
||||
}
|
||||
|
||||
if (srcKind != dstKind) {
|
||||
// One argument constructors can do type conversion
|
||||
return this->writeTypeConversion(src, srcKind, dstKind);
|
||||
}
|
||||
|
||||
SkDEBUGFAIL("Invalid constructor");
|
||||
return {};
|
||||
}
|
||||
@ -1472,7 +1449,7 @@ Value SkVMGenerator::writeExpression(const Expression& e) {
|
||||
case Expression::Kind::kConstructorMatrixResize:
|
||||
return this->writeConstructorMatrixResize(e.as<ConstructorMatrixResize>());
|
||||
case Expression::Kind::kConstructorScalarCast:
|
||||
case Expression::Kind::kConstructorVectorCast:
|
||||
case Expression::Kind::kConstructorCompositeCast:
|
||||
return this->writeConstructorCast(e.asAnyConstructor());
|
||||
case Expression::Kind::kConstructorSplat:
|
||||
return this->writeConstructorSplat(e.as<ConstructorSplat>());
|
||||
|
@ -3899,7 +3899,7 @@ static uint8_t SKSL_INCLUDE_sksl_gpu[] = {8,10,
|
||||
2,
|
||||
51,0,0,0,0,1,
|
||||
43,
|
||||
12,
|
||||
13,
|
||||
49,15,2,1,
|
||||
28,
|
||||
49,176,0,0,0,0,0,1,0,
|
||||
@ -3948,11 +3948,11 @@ static uint8_t SKSL_INCLUDE_sksl_gpu[] = {8,10,
|
||||
53,
|
||||
1,
|
||||
58,167,3,0,66,
|
||||
12,
|
||||
13,
|
||||
49,15,2,1,
|
||||
28,
|
||||
49,176,0,0,0,0,0,
|
||||
12,
|
||||
13,
|
||||
49,15,2,1,
|
||||
28,
|
||||
49,176,0,0,0,0,0,
|
||||
@ -5115,7 +5115,7 @@ static uint8_t SKSL_INCLUDE_sksl_gpu[] = {8,10,
|
||||
2,
|
||||
51,0,0,0,0,1,
|
||||
43,
|
||||
12,
|
||||
13,
|
||||
49,172,1,1,
|
||||
28,
|
||||
49,176,0,0,0,0,0,1,1,1,211,3,
|
||||
@ -5823,7 +5823,7 @@ static uint8_t SKSL_INCLUDE_sksl_gpu[] = {8,10,
|
||||
58,18,4,0,
|
||||
59,
|
||||
43,
|
||||
12,
|
||||
13,
|
||||
49,15,2,1,
|
||||
28,
|
||||
49,176,0,0,0,0,0,1,29,154,3,157,3,160,3,163,3,166,3,169,3,172,3,175,3,178,3,181,3,184,3,187,3,190,3,193,3,196,3,202,3,205,3,208,3,221,3,227,3,230,3,236,3,239,3,242,3,245,3,6,4,9,4,12,4,15,4,
|
||||
|
@ -10,11 +10,11 @@
|
||||
#include "src/sksl/ir/SkSLBoolLiteral.h"
|
||||
#include "src/sksl/ir/SkSLConstructorArray.h"
|
||||
#include "src/sksl/ir/SkSLConstructorComposite.h"
|
||||
#include "src/sksl/ir/SkSLConstructorCompositeCast.h"
|
||||
#include "src/sksl/ir/SkSLConstructorDiagonalMatrix.h"
|
||||
#include "src/sksl/ir/SkSLConstructorMatrixResize.h"
|
||||
#include "src/sksl/ir/SkSLConstructorScalarCast.h"
|
||||
#include "src/sksl/ir/SkSLConstructorSplat.h"
|
||||
#include "src/sksl/ir/SkSLConstructorVectorCast.h"
|
||||
#include "src/sksl/ir/SkSLFloatLiteral.h"
|
||||
#include "src/sksl/ir/SkSLIntLiteral.h"
|
||||
#include "src/sksl/ir/SkSLPrefixExpression.h"
|
||||
@ -71,28 +71,24 @@ std::unique_ptr<Expression> Constructor::MakeCompoundConstructor(const Context&
|
||||
// A vector constructor containing a single vector with the same number of columns is a
|
||||
// cast (e.g. float3 -> int3).
|
||||
if (type.isVector() && argument->type().columns() == type.columns()) {
|
||||
return ConstructorVectorCast::Make(context, offset, type, std::move(argument));
|
||||
return ConstructorCompositeCast::Make(context, offset, type, std::move(argument));
|
||||
}
|
||||
} else if (argument->type().isMatrix()) {
|
||||
// A matrix constructor containing a single matrix can be a resize, typecast, or both.
|
||||
// GLSL lumps these into one category, but internally SkSL keeps them distinct.
|
||||
if (type.isMatrix()) {
|
||||
// First, handle type conversion. If the component types differ, synthesize the
|
||||
// destination type with the argument's rows/columns. If not, leave it as-is.
|
||||
std::unique_ptr<Expression> typecast;
|
||||
if (type.componentType() != argument->type().componentType()) {
|
||||
const Type& typecastType = type.componentType().toCompound(
|
||||
context,
|
||||
argument->type().columns(),
|
||||
argument->type().rows());
|
||||
typecast = std::make_unique<Constructor>(offset, typecastType, std::move(args));
|
||||
SkASSERT(typecast);
|
||||
} else {
|
||||
typecast = std::move(argument);
|
||||
}
|
||||
// destination type with the argument's rows/columns. (This will be a no-op if it's
|
||||
// already the right type.)
|
||||
const Type& typecastType = type.componentType().toCompound(
|
||||
context,
|
||||
argument->type().columns(),
|
||||
argument->type().rows());
|
||||
std::unique_ptr<Expression> typecast = ConstructorCompositeCast::Make(
|
||||
context, offset, typecastType, std::move(argument));
|
||||
|
||||
// Next, wrap the typecasted expression in a matrix-resize constructor if the sizes
|
||||
// differ. If not, return the typecasted expression as-is.
|
||||
// Next, wrap the typecasted expression in a matrix-resize constructor if the
|
||||
// sizes differ. (This will be a no-op if it's already the right size.)
|
||||
return ConstructorMatrixResize::Make(context, offset, type, std::move(typecast));
|
||||
}
|
||||
}
|
||||
|
@ -188,6 +188,11 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static std::unique_ptr<Expression> MakeScalarConstructor(const Context& context,
|
||||
int offset,
|
||||
const Type& type,
|
||||
ExpressionArray args);
|
||||
|
||||
static std::unique_ptr<Expression> MakeCompoundConstructor(const Context& context,
|
||||
int offset,
|
||||
const Type& type,
|
||||
|
@ -5,21 +5,22 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "src/sksl/ir/SkSLConstructorVectorCast.h"
|
||||
#include "src/sksl/ir/SkSLConstructorCompositeCast.h"
|
||||
|
||||
#include "src/sksl/ir/SkSLConstructor.h"
|
||||
#include "src/sksl/ir/SkSLConstructorComposite.h"
|
||||
#include "src/sksl/ir/SkSLConstructorDiagonalMatrix.h"
|
||||
#include "src/sksl/ir/SkSLConstructorScalarCast.h"
|
||||
#include "src/sksl/ir/SkSLConstructorSplat.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
static std::unique_ptr<Expression> cast_constant_vector(const Context& context,
|
||||
const Type& destType,
|
||||
std::unique_ptr<Expression> constCtor) {
|
||||
static std::unique_ptr<Expression> cast_constant_composite(const Context& context,
|
||||
const Type& destType,
|
||||
std::unique_ptr<Expression> constCtor) {
|
||||
const Type& scalarType = destType.componentType();
|
||||
if (constCtor->is<ConstructorSplat>()) {
|
||||
// This is a vector-cast of a splat containing a constant value, e.g. `half4(7)`. We can
|
||||
// This is a composite-cast of a splat containing a constant value, e.g. `half4(7)`. We can
|
||||
// replace it with a splat of a different type, e.g. `int4(7)`.
|
||||
ConstructorSplat& splat = constCtor->as<ConstructorSplat>();
|
||||
return ConstructorSplat::Make(
|
||||
@ -28,6 +29,16 @@ static std::unique_ptr<Expression> cast_constant_vector(const Context& context,
|
||||
std::move(splat.argument())));
|
||||
}
|
||||
|
||||
if (constCtor->is<ConstructorDiagonalMatrix>()) {
|
||||
// This is a composite-cast of a diagonal matrix, e.g. `float3x3(2)`. We can
|
||||
// replace it with a splat of a different type, e.g. `half3x3(2)`.
|
||||
ConstructorDiagonalMatrix& splat = constCtor->as<ConstructorDiagonalMatrix>();
|
||||
return ConstructorDiagonalMatrix::Make(
|
||||
context, constCtor->fOffset, destType,
|
||||
ConstructorScalarCast::Make(context, constCtor->fOffset, scalarType,
|
||||
std::move(splat.argument())));
|
||||
}
|
||||
|
||||
// Create a composite Constructor(literal, ...) which typecasts each argument inside.
|
||||
auto inputArgs = constCtor->asAnyConstructor().argumentSpan();
|
||||
ExpressionArray typecastArgs;
|
||||
@ -39,9 +50,9 @@ static std::unique_ptr<Expression> cast_constant_vector(const Context& context,
|
||||
typecastArgs.push_back(ConstructorScalarCast::Make(context, offset, scalarType,
|
||||
std::move(arg)));
|
||||
} else {
|
||||
// Convert inner constant-vectors recursively.
|
||||
// Convert inner constant-composites recursively.
|
||||
SkASSERT(argType.isVector());
|
||||
typecastArgs.push_back(cast_constant_vector(
|
||||
typecastArgs.push_back(cast_constant_composite(
|
||||
context,
|
||||
scalarType.toCompound(context, /*columns=*/argType.columns(), /*rows=*/1),
|
||||
std::move(arg)));
|
||||
@ -52,14 +63,16 @@ static std::unique_ptr<Expression> cast_constant_vector(const Context& context,
|
||||
std::move(typecastArgs));
|
||||
}
|
||||
|
||||
std::unique_ptr<Expression> ConstructorVectorCast::Make(const Context& context,
|
||||
std::unique_ptr<Expression> ConstructorCompositeCast::Make(const Context& context,
|
||||
int offset,
|
||||
const Type& type,
|
||||
std::unique_ptr<Expression> arg) {
|
||||
// The types must both be vectors of the same size.
|
||||
SkASSERT(type.isVector());
|
||||
SkASSERT(arg->type().isVector());
|
||||
// Only vectors or matrices of the same dimensions are allowed.
|
||||
SkASSERT(type.isVector() || type.isMatrix());
|
||||
SkASSERT(arg->type().isVector() == type.isVector());
|
||||
SkASSERT(arg->type().isMatrix() == type.isMatrix());
|
||||
SkASSERT(type.columns() == arg->type().columns());
|
||||
SkASSERT(type.rows() == arg->type().rows());
|
||||
|
||||
// If this is a no-op cast, return the expression as-is.
|
||||
if (type == arg->type()) {
|
||||
@ -67,9 +80,9 @@ std::unique_ptr<Expression> ConstructorVectorCast::Make(const Context& context,
|
||||
}
|
||||
// We can cast a vector of compile-time constants at compile-time.
|
||||
if (arg->isCompileTimeConstant()) {
|
||||
return cast_constant_vector(context, type, std::move(arg));
|
||||
return cast_constant_composite(context, type, std::move(arg));
|
||||
}
|
||||
return std::make_unique<ConstructorVectorCast>(offset, type, std::move(arg));
|
||||
return std::make_unique<ConstructorCompositeCast>(offset, type, std::move(arg));
|
||||
}
|
||||
|
||||
} // namespace SkSL
|
@ -17,15 +17,16 @@
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Represents the construction of a vector cast, such as `half3(myInt3)`.
|
||||
* Represents the construction of a vector/matrix typecast, such as `half3(myInt3)` or
|
||||
* `float4x4(myHalf4x4)`. Matrix resizes are done in ConstructorMatrixResize, not here.
|
||||
*
|
||||
* These always contain exactly 1 vector of matching size, and are never constant.
|
||||
* These always contain exactly 1 vector or matrix of matching size, and are never constant.
|
||||
*/
|
||||
class ConstructorVectorCast final : public SingleArgumentConstructor {
|
||||
class ConstructorCompositeCast final : public SingleArgumentConstructor {
|
||||
public:
|
||||
static constexpr Kind kExpressionKind = Kind::kConstructorVectorCast;
|
||||
static constexpr Kind kExpressionKind = Kind::kConstructorCompositeCast;
|
||||
|
||||
ConstructorVectorCast(int offset, const Type& type, std::unique_ptr<Expression> arg)
|
||||
ConstructorCompositeCast(int offset, const Type& type, std::unique_ptr<Expression> arg)
|
||||
: INHERITED(offset, kExpressionKind, &type, std::move(arg)) {}
|
||||
|
||||
static std::unique_ptr<Expression> Make(const Context& context,
|
||||
@ -39,7 +40,8 @@ public:
|
||||
}
|
||||
|
||||
std::unique_ptr<Expression> clone() const override {
|
||||
return std::make_unique<ConstructorVectorCast>(fOffset, this->type(), argument()->clone());
|
||||
return std::make_unique<ConstructorCompositeCast>(fOffset, this->type(),
|
||||
argument()->clone());
|
||||
}
|
||||
|
||||
private:
|
@ -33,11 +33,11 @@ public:
|
||||
kConstructor,
|
||||
kConstructorArray,
|
||||
kConstructorComposite,
|
||||
kConstructorCompositeCast,
|
||||
kConstructorDiagonalMatrix,
|
||||
kConstructorMatrixResize,
|
||||
kConstructorScalarCast,
|
||||
kConstructorSplat,
|
||||
kConstructorVectorCast,
|
||||
kDefined,
|
||||
kExternalFunctionCall,
|
||||
kExternalFunctionReference,
|
||||
@ -88,8 +88,9 @@ public:
|
||||
}
|
||||
|
||||
bool isAnyConstructor() const {
|
||||
static_assert((int)Kind::kConstructorVectorCast + 1 == (int)Kind::kDefined);
|
||||
return this->kind() >= Kind::kConstructor && this->kind() <= Kind::kConstructorVectorCast;
|
||||
static_assert((int)Kind::kConstructor - 1 == (int)Kind::kCodeString);
|
||||
static_assert((int)Kind::kConstructorSplat + 1 == (int)Kind::kDefined);
|
||||
return this->kind() >= Kind::kConstructor && this->kind() <= Kind::kConstructorSplat;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user