Add SkSL DSLVar
Change-Id: I1093aa6bbdb481c98ea3dab10c06bfcf323b2a75 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/352058 Reviewed-by: John Stiles <johnstiles@google.com> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
parent
c0315a72d9
commit
bffe80a29d
@ -63,6 +63,7 @@ skia_sksl_sources = [
|
||||
"$_src/sksl/dsl/DSLCore.cpp",
|
||||
"$_src/sksl/dsl/DSLExpression.cpp",
|
||||
"$_src/sksl/dsl/DSLType.cpp",
|
||||
"$_src/sksl/dsl/DSLVar.cpp",
|
||||
"$_src/sksl/dsl/priv/DSLWriter.cpp",
|
||||
"$_src/sksl/ir/SkSLBinaryExpression.h",
|
||||
"$_src/sksl/ir/SkSLBlock.h",
|
||||
|
@ -8,12 +8,12 @@
|
||||
#ifndef SKSL_MODIFIERSPOOL
|
||||
#define SKSL_MODIFIERSPOOL
|
||||
|
||||
#include "src/sksl/ir/SkSLModifiers.h"
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
struct Modifiers;
|
||||
|
||||
/**
|
||||
* Deduplicates Modifiers objects and stores them in a shared pool. Modifiers are fairly heavy, and
|
||||
* tend to be reused a lot, so deduplication can be a significant win.
|
||||
|
@ -15,6 +15,7 @@ namespace SkSL {
|
||||
namespace dsl {
|
||||
|
||||
using Expression = DSLExpression;
|
||||
using Var = DSLVar;
|
||||
|
||||
} // namespace dsl
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "src/sksl/dsl/DSLExpression.h"
|
||||
#include "src/sksl/dsl/DSLType.h"
|
||||
#include "src/sksl/dsl/DSLVar.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "src/sksl/SkSLIRGenerator.h"
|
||||
#include "src/sksl/dsl/DSLVar.h"
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
#include "src/sksl/ir/SkSLBinaryExpression.h"
|
||||
#include "src/sksl/ir/SkSLBoolLiteral.h"
|
||||
@ -49,6 +50,12 @@ DSLExpression::DSLExpression(bool value)
|
||||
/*offset=*/-1,
|
||||
value)) {}
|
||||
|
||||
DSLExpression::DSLExpression(const DSLVar& var)
|
||||
: fExpression(std::make_unique<SkSL::VariableReference>(
|
||||
/*offset=*/-1,
|
||||
var.var(),
|
||||
SkSL::VariableReference::RefKind::kRead)) {}
|
||||
|
||||
DSLExpression::~DSLExpression() {
|
||||
SkASSERTF(fExpression == nullptr,
|
||||
"Expression destroyed without being incorporated into output tree");
|
||||
|
@ -21,6 +21,7 @@ class Expression;
|
||||
namespace dsl {
|
||||
|
||||
class DSLExpression;
|
||||
class DSLVar;
|
||||
|
||||
/**
|
||||
* Represents an expression such as 'cos(x)' or 'a + b'.
|
||||
@ -54,6 +55,11 @@ public:
|
||||
*/
|
||||
DSLExpression(bool value);
|
||||
|
||||
/**
|
||||
* Creates an expression representing a variable reference.
|
||||
*/
|
||||
DSLExpression(const DSLVar& var);
|
||||
|
||||
~DSLExpression();
|
||||
|
||||
/**
|
||||
|
47
src/sksl/dsl/DSLVar.cpp
Normal file
47
src/sksl/dsl/DSLVar.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2020 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/DSLVar.h"
|
||||
|
||||
#include "src/sksl/SkSLUtil.h"
|
||||
#include "src/sksl/dsl/DSLType.h"
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
#include "src/sksl/ir/SkSLBinaryExpression.h"
|
||||
#include "src/sksl/ir/SkSLSymbolTable.h"
|
||||
#include "src/sksl/ir/SkSLVariable.h"
|
||||
#include "src/sksl/ir/SkSLVariableReference.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
namespace dsl {
|
||||
|
||||
DSLVar::DSLVar(const char* name)
|
||||
: fName(name) {}
|
||||
|
||||
DSLVar::DSLVar(DSLType type, const char* name)
|
||||
: fName(DSLWriter::Name(name)) {
|
||||
fOwnedVar = std::make_unique<SkSL::Variable>(/*offset=*/-1,
|
||||
DSLWriter::Modifiers(Modifiers()),
|
||||
SkSL::StringFragment(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;
|
||||
}
|
||||
|
||||
} // namespace dsl
|
||||
|
||||
} // namespace SkSL
|
60
src/sksl/dsl/DSLVar.h
Normal file
60
src/sksl/dsl/DSLVar.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2020 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_VAR
|
||||
#define SKSL_DSL_VAR
|
||||
|
||||
#include "src/sksl/dsl/DSLExpression.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
class Variable;
|
||||
|
||||
namespace dsl {
|
||||
|
||||
class DSLType;
|
||||
|
||||
class DSLVar {
|
||||
public:
|
||||
/**
|
||||
* Constructs a new variable with the specified type and name. The name is used (in mangled
|
||||
* form) in the resulting shader code; it is not otherwise important. Since mangling prevents
|
||||
* name conflicts and the variable's name is only important when debugging shaders, the name
|
||||
* parameter is optional.
|
||||
*/
|
||||
DSLVar(DSLType type, const char* name = "var");
|
||||
|
||||
DSLVar(DSLVar&&) = delete;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Constructs a reference to a variable that already exists in the symbol table. This is used
|
||||
* internally to reference built-in vars.
|
||||
*/
|
||||
DSLVar(const char* name);
|
||||
|
||||
const SkSL::Variable* var() const;
|
||||
|
||||
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;
|
||||
const char* fName;
|
||||
|
||||
friend class DSLExpression;
|
||||
};
|
||||
|
||||
} // namespace dsl
|
||||
|
||||
} // namespace SkSL
|
||||
|
||||
|
||||
#endif
|
@ -43,6 +43,20 @@ const std::shared_ptr<SkSL::SymbolTable>& DSLWriter::SymbolTable() {
|
||||
return IRGenerator().fSymbolTable;
|
||||
}
|
||||
|
||||
const SkSL::Modifiers* DSLWriter::Modifiers(SkSL::Modifiers modifiers) {
|
||||
return IRGenerator().fModifiers->addToPool(modifiers);
|
||||
}
|
||||
|
||||
const char* DSLWriter::Name(const char* name) {
|
||||
if (ManglingEnabled()) {
|
||||
auto mangled =
|
||||
std::make_unique<String>(Instance().fMangler.uniqueName(name, SymbolTable().get()));
|
||||
const SkSL::String* s = SymbolTable()->takeOwnershipOfString(std::move(mangled));
|
||||
return s->c_str();
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
std::unique_ptr<SkSL::Expression> DSLWriter::Check(std::unique_ptr<SkSL::Expression> expr) {
|
||||
if (expr == nullptr) {
|
||||
if (DSLWriter::Compiler().errorCount()) {
|
||||
|
@ -8,6 +8,7 @@
|
||||
#ifndef SKSL_DSLWRITER
|
||||
#define SKSL_DSLWRITER
|
||||
|
||||
#include "src/sksl/SkSLMangler.h"
|
||||
#include "src/sksl/dsl/DSLExpression.h"
|
||||
#include "src/sksl/ir/SkSLExpressionStatement.h"
|
||||
#include "src/sksl/ir/SkSLProgram.h"
|
||||
@ -62,6 +63,18 @@ public:
|
||||
*/
|
||||
static const std::shared_ptr<SkSL::SymbolTable>& SymbolTable();
|
||||
|
||||
/**
|
||||
* Returns the final pointer to a pooled Modifiers object that should be used to represent the
|
||||
* given modifiers.
|
||||
*/
|
||||
static const SkSL::Modifiers* Modifiers(SkSL::Modifiers modifiers);
|
||||
|
||||
/**
|
||||
* Returns the (possibly mangled) final name that should be used for an entity with the given
|
||||
* raw name.
|
||||
*/
|
||||
static const char* Name(const char* name);
|
||||
|
||||
/**
|
||||
* Reports an error if the argument is null. Returns its argument unmodified.
|
||||
*/
|
||||
@ -84,6 +97,13 @@ public:
|
||||
*/
|
||||
static void ReportError(const char* msg);
|
||||
|
||||
/**
|
||||
* Returns whether name mangling is enabled. This should always be enabled outside of tests.
|
||||
*/
|
||||
static bool ManglingEnabled() {
|
||||
return Instance().fMangle;
|
||||
}
|
||||
|
||||
static DSLWriter& Instance();
|
||||
|
||||
static void SetInstance(std::unique_ptr<DSLWriter> instance);
|
||||
@ -92,6 +112,8 @@ private:
|
||||
SkSL::Program::Settings fSettings;
|
||||
SkSL::Compiler* fCompiler;
|
||||
ErrorHandler* fErrorHandler = nullptr;
|
||||
bool fMangle = true;
|
||||
Mangler fMangler;
|
||||
|
||||
friend class DSLCore;
|
||||
friend class ::AutoDSLContext;
|
||||
|
@ -21,6 +21,7 @@ class AutoDSLContext {
|
||||
public:
|
||||
AutoDSLContext(GrGpu* gpu) {
|
||||
Start(gpu->shaderCompiler());
|
||||
DSLWriter::Instance().fMangle = false;
|
||||
}
|
||||
|
||||
~AutoDSLContext() {
|
||||
@ -60,6 +61,9 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLStartup, r, ctxInfo) {
|
||||
REPORTER_ASSERT(r, e2.release()->description() == "1.0");
|
||||
Expression e3 = true;
|
||||
REPORTER_ASSERT(r, e3.release()->description() == "true");
|
||||
Var a(kInt, "a");
|
||||
Expression e4 = a;
|
||||
REPORTER_ASSERT(r, e4.release()->description() == "a");
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFloat, r, ctxInfo) {
|
||||
|
Loading…
Reference in New Issue
Block a user