Added basic SkSL DSL statements
(and Ternary for good measure) Change-Id: I4afa121d54ab9ba8d0814693ce53da7cb73ef340 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/353626 Commit-Queue: Ethan Nicholas <ethannicholas@google.com> Reviewed-by: John Stiles <johnstiles@google.com>
This commit is contained in:
parent
2a4c0fbdca
commit
d6b6f3ec84
@ -58,8 +58,10 @@ skia_sksl_sources = [
|
||||
"$_src/sksl/SkSLUtil.h",
|
||||
"$_src/sksl/SkSLVMGenerator.cpp",
|
||||
"$_src/sksl/SkSLVMGenerator.h",
|
||||
"$_src/sksl/dsl/DSLBlock.cpp",
|
||||
"$_src/sksl/dsl/DSLCore.cpp",
|
||||
"$_src/sksl/dsl/DSLExpression.cpp",
|
||||
"$_src/sksl/dsl/DSLStatement.cpp",
|
||||
"$_src/sksl/dsl/DSLType.cpp",
|
||||
"$_src/sksl/dsl/DSLVar.cpp",
|
||||
"$_src/sksl/dsl/priv/DSLWriter.cpp",
|
||||
|
@ -539,8 +539,7 @@ std::unique_ptr<ModifiersDeclaration> IRGenerator::convertModifiersDeclaration(c
|
||||
std::unique_ptr<Statement> IRGenerator::convertIf(const ASTNode& n) {
|
||||
SkASSERT(n.fKind == ASTNode::Kind::kIf);
|
||||
auto iter = n.begin();
|
||||
std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*(iter++)),
|
||||
*fContext.fTypes.fBool);
|
||||
std::unique_ptr<Expression> test = this->convertExpression(*(iter++));
|
||||
if (!test) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -564,7 +563,10 @@ std::unique_ptr<Statement> IRGenerator::convertIf(int offset, bool isStatic,
|
||||
std::unique_ptr<Expression> test,
|
||||
std::unique_ptr<Statement> ifTrue,
|
||||
std::unique_ptr<Statement> ifFalse) {
|
||||
SkASSERT(test->type().isBoolean());
|
||||
test = this->coerce(std::move(test), *fContext.fTypes.fBool);
|
||||
if (!test) {
|
||||
return nullptr;
|
||||
}
|
||||
if (test->is<BoolLiteral>()) {
|
||||
// Static Boolean values can fold down to a single branch.
|
||||
if (test->as<BoolLiteral>().value()) {
|
||||
|
@ -33,6 +33,8 @@
|
||||
namespace SkSL {
|
||||
|
||||
namespace dsl {
|
||||
class DSLCore;
|
||||
class DSLVar;
|
||||
class DSLWriter;
|
||||
}
|
||||
|
||||
@ -153,7 +155,7 @@ private:
|
||||
std::unique_ptr<ModifiersPool> releaseModifiers();
|
||||
|
||||
void checkModifiers(int offset, const Modifiers& modifiers, int permitted);
|
||||
void checkVarDeclaration(int offset, const Modifiers& modifiers,const Type* baseType,
|
||||
void checkVarDeclaration(int offset, const Modifiers& modifiers, const Type* baseType,
|
||||
Variable::Storage storage);
|
||||
std::unique_ptr<Statement> convertVarDeclaration(int offset, const Modifiers& modifiers,
|
||||
const Type* baseType, StringFragment name,
|
||||
@ -299,6 +301,8 @@ private:
|
||||
friend class AutoSwitchLevel;
|
||||
friend class AutoDisableInline;
|
||||
friend class Compiler;
|
||||
friend class dsl::DSLCore;
|
||||
friend class dsl::DSLVar;
|
||||
friend class dsl::DSLWriter;
|
||||
};
|
||||
|
||||
|
@ -14,7 +14,9 @@ namespace SkSL {
|
||||
|
||||
namespace dsl {
|
||||
|
||||
using Block = DSLBlock;
|
||||
using Expression = DSLExpression;
|
||||
using Statement = DSLStatement;
|
||||
using Var = DSLVar;
|
||||
|
||||
} // namespace dsl
|
||||
|
27
src/sksl/dsl/DSLBlock.cpp
Normal file
27
src/sksl/dsl/DSLBlock.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2021 Google LLC.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "src/sksl/dsl/DSLBlock.h"
|
||||
|
||||
#include "src/sksl/dsl/DSLStatement.h"
|
||||
#include "src/sksl/ir/SkSLBlock.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
namespace dsl {
|
||||
|
||||
std::unique_ptr<SkSL::Statement> DSLBlock::release() {
|
||||
return std::make_unique<SkSL::Block>(/*offset=*/-1, std::move(fStatements));
|
||||
}
|
||||
|
||||
void DSLBlock::append(DSLStatement stmt) {
|
||||
fStatements.push_back(stmt.release());
|
||||
}
|
||||
|
||||
} // namespace dsl
|
||||
|
||||
} // namespace SkSL
|
50
src/sksl/dsl/DSLBlock.h
Normal file
50
src/sksl/dsl/DSLBlock.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2021 Google LLC.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_DSL_BLOCK
|
||||
#define SKSL_DSL_BLOCK
|
||||
|
||||
#include "include/private/SkTArray.h"
|
||||
#include "src/sksl/dsl/DSLExpression.h"
|
||||
#include "src/sksl/dsl/DSLStatement.h"
|
||||
#include "src/sksl/ir/SkSLIRNode.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
class Statement;
|
||||
|
||||
namespace dsl {
|
||||
|
||||
class DSLBlock {
|
||||
public:
|
||||
template<class... Statements>
|
||||
DSLBlock(Statements... statements) {
|
||||
fStatements.reserve_back(sizeof...(statements));
|
||||
(fStatements.push_back(DSLStatement(std::move(statements)).release()), ...);
|
||||
}
|
||||
|
||||
DSLBlock(SkSL::StatementArray statements)
|
||||
: fStatements(std::move(statements)) {}
|
||||
|
||||
void append(DSLStatement stmt);
|
||||
|
||||
private:
|
||||
std::unique_ptr<SkSL::Statement> release();
|
||||
|
||||
SkSL::StatementArray fStatements;
|
||||
|
||||
friend class DSLStatement;
|
||||
friend class DSLFunction;
|
||||
};
|
||||
|
||||
} // namespace dsl
|
||||
|
||||
} // namespace SkSL
|
||||
|
||||
#endif
|
@ -7,7 +7,12 @@
|
||||
|
||||
#include "src/sksl/dsl/DSLCore.h"
|
||||
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "src/sksl/SkSLIRGenerator.h"
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
#include "src/sksl/ir/SkSLDoStatement.h"
|
||||
#include "src/sksl/ir/SkSLForStatement.h"
|
||||
#include "src/sksl/ir/SkSLIfStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
@ -26,6 +31,70 @@ void End() {
|
||||
void SetErrorHandler(ErrorHandler* errorHandler) {
|
||||
DSLWriter::SetErrorHandler(errorHandler);
|
||||
}
|
||||
class DSLCore {
|
||||
public:
|
||||
static DSLStatement Declare(DSLVar& var, DSLExpression initialValue) {
|
||||
if (!var.fDeclaration) {
|
||||
DSLWriter::ReportError("Declare failed (was the variable already declared?)");
|
||||
return DSLStatement();
|
||||
}
|
||||
VarDeclaration& decl = var.fDeclaration->as<SkSL::VarDeclaration>();
|
||||
std::unique_ptr<Expression> expr = initialValue.coerceAndRelease(decl.var().type());
|
||||
if (expr) {
|
||||
decl.fValue = std::move(expr);
|
||||
}
|
||||
return DSLStatement(std::move(var.fDeclaration));
|
||||
}
|
||||
|
||||
static DSLStatement Do(DSLStatement stmt, DSLExpression test) {
|
||||
return DSLWriter::IRGenerator().convertDo(stmt.release(), test.release());
|
||||
}
|
||||
|
||||
static DSLStatement For(DSLStatement initializer, DSLExpression test, DSLExpression next,
|
||||
DSLStatement stmt) {
|
||||
return DSLWriter::IRGenerator().convertFor(/*offset=*/-1, initializer.release(),
|
||||
test.release(), next.release(), stmt.release());
|
||||
}
|
||||
|
||||
static DSLStatement If(DSLExpression test, DSLStatement ifTrue, DSLStatement ifFalse) {
|
||||
return DSLWriter::IRGenerator().convertIf(/*offset=*/-1, /*isStatic=*/false, test.release(),
|
||||
ifTrue.release(), ifFalse.release());
|
||||
}
|
||||
|
||||
static DSLExpression Ternary(DSLExpression test, DSLExpression ifTrue, DSLExpression ifFalse) {
|
||||
return DSLWriter::IRGenerator().convertTernaryExpression(test.release(), ifTrue.release(),
|
||||
ifFalse.release());
|
||||
}
|
||||
|
||||
static DSLStatement While(DSLExpression test, DSLStatement stmt) {
|
||||
return DSLWriter::IRGenerator().convertWhile(/*offset=*/-1, test.release(), stmt.release());
|
||||
}
|
||||
};
|
||||
|
||||
DSLStatement Declare(DSLVar& var, DSLExpression initialValue) {
|
||||
return DSLCore::Declare(var, std::move(initialValue));
|
||||
}
|
||||
|
||||
DSLStatement Do(DSLStatement stmt, DSLExpression test) {
|
||||
return DSLCore::Do(std::move(stmt), std::move(test));
|
||||
}
|
||||
|
||||
DSLStatement For(DSLStatement initializer, DSLExpression test, DSLExpression next,
|
||||
DSLStatement stmt) {
|
||||
return DSLCore::For(std::move(initializer), std::move(test), std::move(next), std::move(stmt));
|
||||
}
|
||||
|
||||
DSLStatement If(DSLExpression test, DSLStatement ifTrue, DSLStatement ifFalse) {
|
||||
return DSLCore::If(std::move(test), std::move(ifTrue), std::move(ifFalse));
|
||||
}
|
||||
|
||||
DSLExpression Ternary(DSLExpression test, DSLExpression ifTrue, DSLExpression ifFalse) {
|
||||
return DSLCore::Ternary(std::move(test), std::move(ifTrue), std::move(ifFalse));
|
||||
}
|
||||
|
||||
DSLStatement While(DSLExpression test, DSLStatement stmt) {
|
||||
return DSLCore::While(std::move(test), std::move(stmt));
|
||||
}
|
||||
|
||||
} // namespace dsl
|
||||
|
||||
|
@ -8,7 +8,9 @@
|
||||
#ifndef SKSL_DSL_CORE
|
||||
#define SKSL_DSL_CORE
|
||||
|
||||
#include "src/sksl/dsl/DSLBlock.h"
|
||||
#include "src/sksl/dsl/DSLExpression.h"
|
||||
#include "src/sksl/dsl/DSLStatement.h"
|
||||
#include "src/sksl/dsl/DSLType.h"
|
||||
#include "src/sksl/dsl/DSLVar.h"
|
||||
|
||||
@ -28,7 +30,6 @@ public:
|
||||
virtual void handleError(const char* msg) = 0;
|
||||
};
|
||||
|
||||
#if SK_SUPPORT_GPU && !defined(SKSL_STANDALONE)
|
||||
/**
|
||||
* Starts DSL output on the current thread using the specified compiler. This must be called
|
||||
* prior to any other DSL functions.
|
||||
@ -41,7 +42,36 @@ void Start(SkSL::Compiler* compiler);
|
||||
*/
|
||||
void End();
|
||||
|
||||
#endif // SK_SUPPORT_GPU && !defined(SKSL_STANDALONE)
|
||||
/**
|
||||
* Creates a variable declaration statement with an initial value.
|
||||
*/
|
||||
DSLStatement Declare(DSLVar& var, DSLExpression initialValue = DSLExpression());
|
||||
|
||||
/**
|
||||
* do stmt; while (test);
|
||||
*/
|
||||
DSLStatement Do(DSLStatement stmt, DSLExpression test);
|
||||
|
||||
/**
|
||||
* for (initializer; test; next) stmt;
|
||||
*/
|
||||
DSLStatement For(DSLStatement initializer, DSLExpression test, DSLExpression next,
|
||||
DSLStatement stmt);
|
||||
|
||||
/**
|
||||
* if (test) ifTrue; [else ifFalse;]
|
||||
*/
|
||||
DSLStatement If(DSLExpression test, DSLStatement ifTrue, DSLStatement ifFalse = DSLStatement());
|
||||
|
||||
/**
|
||||
* test ? ifTrue : ifFalse
|
||||
*/
|
||||
DSLExpression Ternary(DSLExpression test, DSLExpression ifTrue, DSLExpression ifFalse);
|
||||
|
||||
/**
|
||||
* while (test) stmt;
|
||||
*/
|
||||
DSLStatement While(DSLExpression test, DSLStatement stmt);
|
||||
|
||||
/**
|
||||
* Installs an ErrorHandler which will be notified of any errors that occur during DSL calls. If
|
||||
|
@ -58,7 +58,7 @@ DSLExpression::DSLExpression(const DSLVar& var)
|
||||
|
||||
DSLExpression::~DSLExpression() {
|
||||
SkASSERTF(fExpression == nullptr,
|
||||
"Expression destroyed without being incorporated into output tree");
|
||||
"Expression destroyed without being incorporated into program");
|
||||
}
|
||||
|
||||
std::unique_ptr<SkSL::Expression> DSLExpression::release() {
|
||||
|
@ -83,6 +83,7 @@ private:
|
||||
|
||||
std::unique_ptr<SkSL::Expression> fExpression;
|
||||
|
||||
friend class DSLCore;
|
||||
friend class DSLVar;
|
||||
friend class DSLWriter;
|
||||
};
|
||||
|
44
src/sksl/dsl/DSLStatement.cpp
Normal file
44
src/sksl/dsl/DSLStatement.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2021 Google LLC.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "src/sksl/dsl/DSLStatement.h"
|
||||
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "src/sksl/dsl/DSLBlock.h"
|
||||
#include "src/sksl/dsl/DSLExpression.h"
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
#include "src/sksl/ir/SkSLExpressionStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
namespace dsl {
|
||||
|
||||
DSLStatement::DSLStatement(DSLBlock block)
|
||||
: fStatement(block.release()) {}
|
||||
|
||||
DSLStatement::DSLStatement(DSLExpression expr) {
|
||||
std::unique_ptr<SkSL::Expression> skslExpr = expr.release();
|
||||
if (skslExpr) {
|
||||
fStatement = std::make_unique<SkSL::ExpressionStatement>(std::move(skslExpr));
|
||||
}
|
||||
}
|
||||
|
||||
DSLStatement::DSLStatement(std::unique_ptr<SkSL::Expression> expr)
|
||||
: fStatement(std::make_unique<SkSL::ExpressionStatement>(std::move(expr))) {}
|
||||
|
||||
DSLStatement::DSLStatement(std::unique_ptr<SkSL::Statement> stmt)
|
||||
: fStatement(std::move(stmt)) {
|
||||
if (!fStatement) {
|
||||
SkASSERTF(DSLWriter::Compiler().errorCount(),
|
||||
"statement is null, but no errors were reported");
|
||||
DSLWriter::ReportError(DSLWriter::Compiler().errorText(/*showCount=*/false).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dsl
|
||||
|
||||
} // namespace SkSL
|
62
src/sksl/dsl/DSLStatement.h
Normal file
62
src/sksl/dsl/DSLStatement.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2021 Google LLC.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_DSL_STATEMENT
|
||||
#define SKSL_DSL_STATEMENT
|
||||
|
||||
#include "include/core/SkString.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
#include "src/sksl/ir/SkSLIRNode.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
class GrGLSLShaderBuilder;
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
class Statement;
|
||||
|
||||
namespace dsl {
|
||||
|
||||
class DSLBlock;
|
||||
class DSLExpression;
|
||||
class DSLVar;
|
||||
|
||||
class DSLStatement {
|
||||
public:
|
||||
DSLStatement() {}
|
||||
|
||||
DSLStatement(DSLExpression expr);
|
||||
|
||||
DSLStatement(DSLBlock block);
|
||||
|
||||
DSLStatement(DSLStatement&&) = default;
|
||||
|
||||
~DSLStatement() {
|
||||
SkASSERTF(!fStatement, "Statement destroyed without being incorporated into program");
|
||||
}
|
||||
|
||||
std::unique_ptr<SkSL::Statement> release() {
|
||||
return std::move(fStatement);
|
||||
}
|
||||
|
||||
private:
|
||||
DSLStatement(std::unique_ptr<SkSL::Statement> stmt);
|
||||
|
||||
DSLStatement(std::unique_ptr<SkSL::Expression> expr);
|
||||
|
||||
std::unique_ptr<SkSL::Statement> fStatement;
|
||||
|
||||
friend class DSLBlock;
|
||||
friend class DSLCore;
|
||||
};
|
||||
|
||||
} // namespace dsl
|
||||
|
||||
} // namespace SkSL
|
||||
|
||||
#endif
|
@ -20,38 +20,31 @@ namespace SkSL {
|
||||
namespace dsl {
|
||||
|
||||
DSLVar::DSLVar(const char* name)
|
||||
: fName(name) {}
|
||||
: fName(name) {
|
||||
const SkSL::Symbol* result = (*DSLWriter::SymbolTable())[fName];
|
||||
SkASSERTF(result, "could not find '%s' in symbol table", fName);
|
||||
fVar = &result->as<SkSL::Variable>();
|
||||
}
|
||||
|
||||
DSLVar::DSLVar(DSLType type, const char* name)
|
||||
: fName(DSLWriter::Name(name)) {
|
||||
fOwnedVar = std::make_unique<SkSL::Variable>(/*offset=*/-1,
|
||||
DSLWriter::Modifiers(Modifiers()),
|
||||
fName,
|
||||
&type.skslType(),
|
||||
/*builtin=*/false,
|
||||
SkSL::Variable::Storage::kLocal);
|
||||
fVar = fOwnedVar.get();
|
||||
}
|
||||
|
||||
const SkSL::Variable* DSLVar::var() const {
|
||||
if (!fVar) {
|
||||
const SkSL::Symbol* result = (*DSLWriter::SymbolTable())[fName];
|
||||
SkASSERTF(result, "could not find '%s' in symbol table", fName);
|
||||
fVar = &result->as<SkSL::Variable>();
|
||||
}
|
||||
return fVar;
|
||||
Modifiers modifiers;
|
||||
DSLWriter::IRGenerator().checkVarDeclaration(/*offset=*/-1, modifiers, &type.skslType(),
|
||||
Variable::Storage::kLocal);
|
||||
fDeclaration = DSLWriter::IRGenerator().convertVarDeclaration(/*offset=*/-1,
|
||||
modifiers,
|
||||
&type.skslType(),
|
||||
fName,
|
||||
/*isArray=*/false,
|
||||
/*arraySize=*/nullptr,
|
||||
/*value=*/nullptr,
|
||||
Variable::Storage::kLocal);
|
||||
fVar = &fDeclaration->as<SkSL::VarDeclaration>().var();
|
||||
}
|
||||
|
||||
DSLExpression DSLVar::operator=(DSLExpression expr) {
|
||||
const SkSL::Variable* var = this->var();
|
||||
return DSLExpression(std::make_unique<SkSL::BinaryExpression>(
|
||||
/*offset=*/-1,
|
||||
std::make_unique<SkSL::VariableReference>(/*offset=*/-1,
|
||||
var,
|
||||
SkSL::VariableReference::RefKind::kWrite),
|
||||
SkSL::Token::Kind::TK_EQ,
|
||||
expr.coerceAndRelease(var->type()),
|
||||
&var->type()));
|
||||
return DSLWriter::ConvertBinary(DSLExpression(*this).release(), SkSL::Token::Kind::TK_EQ,
|
||||
expr.release());
|
||||
}
|
||||
|
||||
} // namespace dsl
|
||||
|
@ -59,18 +59,19 @@ private:
|
||||
*/
|
||||
DSLVar(const char* name);
|
||||
|
||||
const SkSL::Variable* var() const;
|
||||
const SkSL::Variable* var() const {
|
||||
return fVar;
|
||||
}
|
||||
|
||||
const char* name() const {
|
||||
return fName;
|
||||
}
|
||||
|
||||
// this object owns the var until it is added to a symboltable
|
||||
std::unique_ptr<SkSL::Variable> fOwnedVar;
|
||||
// mutable to allow us to cache lookups of system vars
|
||||
mutable const SkSL::Variable* fVar = nullptr;
|
||||
std::unique_ptr<SkSL::Statement> fDeclaration;
|
||||
const SkSL::Variable* fVar = nullptr;
|
||||
const char* fName;
|
||||
|
||||
friend class DSLCore;
|
||||
friend class DSLExpression;
|
||||
friend class DSLWriter;
|
||||
};
|
||||
|
@ -15,6 +15,11 @@
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
|
||||
namespace dsl {
|
||||
class DSLCore;
|
||||
}
|
||||
|
||||
/**
|
||||
* A single variable declaration statement. Multiple variables declared together are expanded to
|
||||
* separate (sequential) statements. For instance, the SkSL 'int x = 2, y[3];' produces two
|
||||
@ -86,6 +91,8 @@ private:
|
||||
int fArraySize; // zero means "not an array", Type::kUnsizedArray means var[]
|
||||
std::unique_ptr<Expression> fValue;
|
||||
|
||||
friend class dsl::DSLCore;
|
||||
|
||||
using INHERITED = Statement;
|
||||
};
|
||||
|
||||
|
@ -53,6 +53,29 @@ private:
|
||||
skiatest::Reporter* fReporter;
|
||||
};
|
||||
|
||||
static bool whitespace_insensitive_compare(const char* a, const char* b) {
|
||||
for (;;) {
|
||||
while (isspace(*a)) {
|
||||
++a;
|
||||
}
|
||||
while (isspace(*b)) {
|
||||
++b;
|
||||
}
|
||||
if (*a != *b) {
|
||||
return false;
|
||||
}
|
||||
if (*a == 0) {
|
||||
return true;
|
||||
}
|
||||
++a;
|
||||
++b;
|
||||
}
|
||||
}
|
||||
|
||||
static bool whitespace_insensitive_compare(DSLStatement& stmt, const char* description) {
|
||||
return whitespace_insensitive_compare(stmt.release()->description().c_str(), description);
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLStartup, r, ctxInfo) {
|
||||
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
|
||||
Expression e1 = 1;
|
||||
@ -64,6 +87,15 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLStartup, r, ctxInfo) {
|
||||
Var a(kInt, "a");
|
||||
Expression e4 = a;
|
||||
REPORTER_ASSERT(r, e4.release()->description() == "a");
|
||||
|
||||
REPORTER_ASSERT(r, whitespace_insensitive_compare("", ""));
|
||||
REPORTER_ASSERT(r, !whitespace_insensitive_compare("", "a"));
|
||||
REPORTER_ASSERT(r, !whitespace_insensitive_compare("a", ""));
|
||||
REPORTER_ASSERT(r, whitespace_insensitive_compare("a", "a"));
|
||||
REPORTER_ASSERT(r, whitespace_insensitive_compare("abc", "abc"));
|
||||
REPORTER_ASSERT(r, whitespace_insensitive_compare("abc", " abc "));
|
||||
REPORTER_ASSERT(r, whitespace_insensitive_compare("a b c ", "\n\n\nabc"));
|
||||
REPORTER_ASSERT(r, !whitespace_insensitive_compare("a b c d", "\n\n\nabc"));
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFloat, r, ctxInfo) {
|
||||
@ -851,3 +883,105 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDecrement, r, ctxInfo) {
|
||||
((a + 1)--).release();
|
||||
}
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBlock, r, ctxInfo) {
|
||||
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
|
||||
Statement x = Block();
|
||||
REPORTER_ASSERT(r, whitespace_insensitive_compare(x, "{ }"));
|
||||
Var a(kInt, "a"), b(kInt, "b");
|
||||
Statement y = Block(Declare(a, 1), Declare(b, 2), a = b);
|
||||
REPORTER_ASSERT(r, whitespace_insensitive_compare(y, "{ int a = 1; int b = 2; (a = b); }"));
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDeclare, r, ctxInfo) {
|
||||
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
|
||||
Var a(kHalf4, "a"), b(kHalf4, "b");
|
||||
Statement x = Declare(a);
|
||||
REPORTER_ASSERT(r, x.release()->description() == "half4 a;");
|
||||
Statement y = Declare(b, Half4(1));
|
||||
REPORTER_ASSERT(r, y.release()->description() == "half4 b = half4(1.0);");
|
||||
|
||||
{
|
||||
Var c(kHalf4, "c");
|
||||
ExpectError error(r, "error: expected 'half4', but found 'int'\n");
|
||||
Declare(c, 1).release();
|
||||
}
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDo, r, ctxInfo) {
|
||||
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
|
||||
Statement x = Do(Block(), true);
|
||||
REPORTER_ASSERT(r, whitespace_insensitive_compare(x, "do {} while (true);"));
|
||||
|
||||
Var a(kFloat, "a"), b(kFloat, "b");
|
||||
Statement y = Do(Block(a++, --b), a != b);
|
||||
REPORTER_ASSERT(r, whitespace_insensitive_compare(y, "do { a++; --b; } while ((a != b));"));
|
||||
|
||||
{
|
||||
ExpectError error(r, "error: expected 'bool', but found 'int'\n");
|
||||
Do(Block(), 7).release();
|
||||
}
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFor, r, ctxInfo) {
|
||||
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
|
||||
Statement x = For(Statement(), Expression(), Expression(), Block());
|
||||
REPORTER_ASSERT(r, whitespace_insensitive_compare(x, "for (;;) {}"));
|
||||
|
||||
Var i(kInt, "i");
|
||||
Statement y = For(Declare(i, 0), i < 10, ++i, i += 5);
|
||||
REPORTER_ASSERT(r, whitespace_insensitive_compare(y,
|
||||
"for (int i = 0; (i < 10); ++i) (i += 5);"));
|
||||
|
||||
{
|
||||
ExpectError error(r, "error: expected 'bool', but found 'int'\n");
|
||||
For(i = 0, i + 10, ++i, i += 5).release();
|
||||
}
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLIf, r, ctxInfo) {
|
||||
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
|
||||
Var a(kFloat, "a"), b(kFloat, "b");
|
||||
Statement x = If(a > b, a -= b);
|
||||
REPORTER_ASSERT(r, x.release()->description() == "if ((a > b)) (a -= b);");
|
||||
|
||||
Statement y = If(a > b, a -= b, b -= a);
|
||||
REPORTER_ASSERT(r, y.release()->description() == "if ((a > b)) (a -= b); else (b -= a);");
|
||||
|
||||
{
|
||||
ExpectError error(r, "error: expected 'bool', but found 'float'\n");
|
||||
If(a + b, a -= b).release();
|
||||
}
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLTernary, r, ctxInfo) {
|
||||
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
|
||||
Var a(kInt, "a");
|
||||
Expression x = Ternary(a > 0, 1, -1);
|
||||
REPORTER_ASSERT(r, x.release()->description() == "((a > 0) ? 1 : -1)");
|
||||
|
||||
{
|
||||
ExpectError error(r, "error: expected 'bool', but found 'int'\n");
|
||||
Ternary(a, 1, -1).release();
|
||||
}
|
||||
|
||||
{
|
||||
ExpectError error(r, "error: ternary operator result mismatch: 'float2', 'float3'\n");
|
||||
Ternary(a > 0, Float2(1), Float3(1)).release();
|
||||
}
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLWhile, r, ctxInfo) {
|
||||
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
|
||||
Statement x = While(true, Block());
|
||||
REPORTER_ASSERT(r, whitespace_insensitive_compare(x, "for (; true;) {}"));
|
||||
|
||||
Var a(kFloat, "a"), b(kFloat, "b");
|
||||
Statement y = While(a != b, Block(a++, --b));
|
||||
REPORTER_ASSERT(r, whitespace_insensitive_compare(y, "for (; (a != b);) { a++; --b; }"));
|
||||
|
||||
{
|
||||
ExpectError error(r, "error: expected 'bool', but found 'int'\n");
|
||||
While(7, Block()).release();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user