aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/glsl
diff options
context:
space:
mode:
authorGravatar egdaniel <egdaniel@google.com>2015-11-11 06:27:20 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-11-11 06:27:20 -0800
commit8dcdedc4a087ea46ce1e2458d335d60918e56310 (patch)
tree40ef4cd4b187fceb923c4de5d7311b7684d7d6e8 /src/gpu/glsl
parent49115b57cb9d260ddd49a6905ee87af63b3ab066 (diff)
Make GrGLSLProgramBuilder base class for GrGLProgramBuilder.
This CL still keeps the weird diamond shape we have for all our ProgramBuilders. However, the GrGLSL base class will allow us to pull multiple other parts of our program setup away from GL which will eventually allow us to break up the diamond. As part of this all ShaderBuilder subclass have been made gl independent, however I will move them to GLSL files/class names in a follow on CL. BUG=skia: Review URL: https://codereview.chromium.org/1416423003
Diffstat (limited to 'src/gpu/glsl')
-rwxr-xr-xsrc/gpu/glsl/GrGLSLCaps.cpp9
-rwxr-xr-xsrc/gpu/glsl/GrGLSLCaps.h26
-rw-r--r--src/gpu/glsl/GrGLSLProgramBuilder.cpp39
-rw-r--r--src/gpu/glsl/GrGLSLProgramBuilder.h261
4 files changed, 334 insertions, 1 deletions
diff --git a/src/gpu/glsl/GrGLSLCaps.cpp b/src/gpu/glsl/GrGLSLCaps.cpp
index 140cb11494..aed98880f5 100755
--- a/src/gpu/glsl/GrGLSLCaps.cpp
+++ b/src/gpu/glsl/GrGLSLCaps.cpp
@@ -22,8 +22,12 @@ GrGLSLCaps::GrGLSLCaps(const GrContextOptions& options) {
fUsesPrecisionModifiers = false;
fCanUseAnyFunctionInShader = true;
fForceHighPrecisionNDSTransform = false;
+ fCanUseMinAndAbsTogether = true;
+ fMustForceNegatedAtanParamToFloat = false;
fVersionDeclString = nullptr;
fShaderDerivativeExtensionString = nullptr;
+ fFragCoordConventionsExtensionString = nullptr;
+ fSecondaryOutputExtensionString = nullptr;
fFBFetchColorName = nullptr;
fFBFetchExtensionString = nullptr;
fAdvBlendEqInteraction = kNotSupported_AdvBlendEqInteraction;
@@ -53,9 +57,12 @@ SkString GrGLSLCaps::dump() const {
r.appendf("Drops tile on zero divide: %s\n", (fDropsTileOnZeroDivide ? "YES" : "NO"));
r.appendf("Bindless texture support: %s\n", (fBindlessTextureSupport ? "YES" : "NO"));
r.appendf("Uses precision modifiers: %s\n", (fUsesPrecisionModifiers ? "YES" : "NO"));
- r.appendf("Can Use any() function: %s\n", (fCanUseAnyFunctionInShader ? "YES" : "NO"));
+ r.appendf("Can use any() function: %s\n", (fCanUseAnyFunctionInShader ? "YES" : "NO"));
r.appendf("Force high precision on NDS transform: %s\n", (fForceHighPrecisionNDSTransform ?
"YES" : "NO"));
+ r.appendf("Can use min() and abs() together: %s\n", (fCanUseMinAndAbsTogether ? "YES" : "NO"));
+ r.appendf("Must force negated atan param to float: %s\n", (fMustForceNegatedAtanParamToFloat ?
+ "YES" : "NO"));
r.appendf("Advanced blend equation interaction: %s\n",
kAdvBlendEqInteractionStr[fAdvBlendEqInteraction]);
return r;
diff --git a/src/gpu/glsl/GrGLSLCaps.h b/src/gpu/glsl/GrGLSLCaps.h
index e703fb8523..68e91b6666 100755
--- a/src/gpu/glsl/GrGLSLCaps.h
+++ b/src/gpu/glsl/GrGLSLCaps.h
@@ -74,6 +74,10 @@ public:
bool forceHighPrecisionNDSTransform() const { return fForceHighPrecisionNDSTransform; }
+ bool canUseMinAndAbsTogether() const { return fCanUseMinAndAbsTogether; }
+
+ bool mustForceNegatedAtanParamToFloat() const { return fMustForceNegatedAtanParamToFloat; }
+
// Returns the string of an extension that must be enabled in the shader to support
// derivatives. If nullptr is returned then no extension needs to be enabled. Before calling
// this function, the caller should check that shaderDerivativeSupport exists.
@@ -81,6 +85,22 @@ public:
SkASSERT(this->shaderDerivativeSupport());
return fShaderDerivativeExtensionString;
}
+
+ // Returns the string of an extension that will do all necessary coord transfomations needed
+ // when reading the fragment position. If such an extension does not exisits, this function
+ // returns a nullptr, and all transforms of the frag position must be done manually in the
+ // shader.
+ const char* fragCoordConventionsExtensionString() const {
+ return fFragCoordConventionsExtensionString;
+ }
+
+ // This returns the name of an extension that must be enabled in the shader, if such a thing is
+ // required in order to use a secondary output in the shader. This returns a nullptr if no such
+ // extension is required. However, the return value of this function does not say whether dual
+ // source blending is supported.
+ const char* secondaryOutputExtensionString() const {
+ return fSecondaryOutputExtensionString;
+ }
bool mustSwizzleInShader() const { return fMustSwizzleInShader; }
@@ -111,9 +131,15 @@ private:
bool fCanUseAnyFunctionInShader : 1;
bool fForceHighPrecisionNDSTransform : 1;
+ // Used for specific driver bug work arounds
+ bool fCanUseMinAndAbsTogether : 1;
+ bool fMustForceNegatedAtanParamToFloat : 1;
+
const char* fVersionDeclString;
const char* fShaderDerivativeExtensionString;
+ const char* fFragCoordConventionsExtensionString;
+ const char* fSecondaryOutputExtensionString;
const char* fFBFetchColorName;
const char* fFBFetchExtensionString;
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
new file mode 100644
index 0000000000..54e82b30c0
--- /dev/null
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "glsl/GrGLSLProgramBuilder.h"
+
+const int GrGLSLProgramBuilder::kVarsPerBlock = 8;
+
+GrGLSLProgramBuilder::GrGLSLProgramBuilder(const DrawArgs& args)
+ : fVS(this)
+ , fGS(this)
+ , fFS(this, args.fDesc->header().fFragPosKey)
+ , fStageIndex(-1)
+ , fArgs(args) {
+}
+
+void GrGLSLProgramBuilder::nameVariable(SkString* out, char prefix, const char* name, bool mangle) {
+ if ('\0' == prefix) {
+ *out = name;
+ } else {
+ out->printf("%c%s", prefix, name);
+ }
+ if (mangle) {
+ if (out->endsWith('_')) {
+ // Names containing "__" are reserved.
+ out->append("x");
+ }
+ out->appendf("_Stage%d%s", fStageIndex, fFS.getMangleString().c_str());
+ }
+}
+
+void GrGLSLProgramBuilder::appendUniformDecls(ShaderVisibility visibility,
+ SkString* out) const {
+ this->onAppendUniformDecls(visibility, out);
+}
+
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.h b/src/gpu/glsl/GrGLSLProgramBuilder.h
new file mode 100644
index 0000000000..f783a40db4
--- /dev/null
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.h
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLSLProgramBuilder_DEFINED
+#define GrGLSLProgramBuilder_DEFINED
+
+#include "GrGeometryProcessor.h"
+#include "GrGpu.h"
+#include "gl/builders/GrGLFragmentShaderBuilder.h"
+#include "gl/builders/GrGLGeometryShaderBuilder.h"
+#include "gl/builders/GrGLVertexShaderBuilder.h"
+#include "glsl/GrGLSLProgramDataManager.h"
+
+class GrGLSLCaps;
+class GrGLSLShaderVar;
+
+class GrGLSLUniformBuilder {
+public:
+ enum ShaderVisibility {
+ kVertex_Visibility = 1 << kVertex_GrShaderType,
+ kGeometry_Visibility = 1 << kGeometry_GrShaderType,
+ kFragment_Visibility = 1 << kFragment_GrShaderType,
+ };
+
+ virtual ~GrGLSLUniformBuilder() {}
+
+ typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
+ typedef GrGLSLProgramDataManager::SeparableVaryingHandle SeparableVaryingHandle;
+
+ /** Add a uniform variable to the current program, that has visibility in one or more shaders.
+ visibility is a bitfield of ShaderVisibility values indicating from which shaders the
+ uniform should be accessible. At least one bit must be set. Geometry shader uniforms are not
+ supported at this time. The actual uniform name will be mangled. If outName is not nullptr
+ then it will refer to the final uniform name after return. Use the addUniformArray variant
+ to add an array of uniforms. */
+ UniformHandle addUniform(uint32_t visibility,
+ GrSLType type,
+ GrSLPrecision precision,
+ const char* name,
+ const char** outName = nullptr) {
+ return this->addUniformArray(visibility, type, precision, name, 0, outName);
+ }
+
+ UniformHandle addUniformArray(uint32_t visibility,
+ GrSLType type,
+ GrSLPrecision precision,
+ const char* name,
+ int arrayCount,
+ const char** outName = nullptr) {
+ return this->internalAddUniformArray(visibility, type, precision, name, true, arrayCount,
+ outName);
+ }
+
+ virtual const GrGLSLShaderVar& getUniformVariable(UniformHandle u) const = 0;
+
+ /**
+ * Shortcut for getUniformVariable(u).c_str()
+ */
+ virtual const char* getUniformCStr(UniformHandle u) const = 0;
+
+ virtual const GrGLSLCaps* glslCaps() const = 0;
+
+ /*
+ * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
+ */
+protected:
+ virtual UniformHandle internalAddUniformArray(
+ uint32_t visibility,
+ GrSLType type,
+ GrSLPrecision precision,
+ const char* name,
+ bool mangleName,
+ int arrayCount,
+ const char** outName) = 0;
+};
+
+// TODO move this into GrGLSLGPBuilder and move them both out of this file
+class GrGLSLVarying {
+public:
+ bool vsVarying() const { return kVertToFrag_Varying == fVarying ||
+ kVertToGeo_Varying == fVarying; }
+ bool fsVarying() const { return kVertToFrag_Varying == fVarying ||
+ kGeoToFrag_Varying == fVarying; }
+ const char* vsOut() const { return fVsOut; }
+ const char* gsIn() const { return fGsIn; }
+ const char* gsOut() const { return fGsOut; }
+ const char* fsIn() const { return fFsIn; }
+ GrSLType type() const { return fType; }
+
+protected:
+ enum Varying {
+ kVertToFrag_Varying,
+ kVertToGeo_Varying,
+ kGeoToFrag_Varying,
+ };
+
+ GrGLSLVarying(GrSLType type, Varying varying)
+ : fVarying(varying), fType(type), fVsOut(nullptr), fGsIn(nullptr), fGsOut(nullptr),
+ fFsIn(nullptr) {}
+
+ Varying fVarying;
+
+private:
+ GrSLType fType;
+ const char* fVsOut;
+ const char* fGsIn;
+ const char* fGsOut;
+ const char* fFsIn;
+
+ friend class GrGLVertexBuilder;
+ friend class GrGLGeometryBuilder;
+ friend class GrGLXferBuilder;
+ friend class GrGLFragmentShaderBuilder;
+};
+
+struct GrGLSLVertToFrag : public GrGLSLVarying {
+ GrGLSLVertToFrag(GrSLType type)
+ : GrGLSLVarying(type, kVertToFrag_Varying) {}
+};
+
+struct GrGLSLVertToGeo : public GrGLSLVarying {
+ GrGLSLVertToGeo(GrSLType type)
+ : GrGLSLVarying(type, kVertToGeo_Varying) {}
+};
+
+struct GrGLSLGeoToFrag : public GrGLSLVarying {
+ GrGLSLGeoToFrag(GrSLType type)
+ : GrGLSLVarying(type, kGeoToFrag_Varying) {}
+};
+
+/* a specialization of the above for GPs. Lets the user add uniforms, varyings, and VS / FS code */
+class GrGLSLGPBuilder : public virtual GrGLSLUniformBuilder {
+public:
+ /*
+ * addVarying allows fine grained control for setting up varyings between stages. If you just
+ * need to take an attribute and pass it through to an output value in a fragment shader, use
+ * addPassThroughAttribute.
+ * TODO convert most uses of addVarying to addPassThroughAttribute
+ */
+ virtual void addVarying(const char* name,
+ GrGLSLVarying*,
+ GrSLPrecision precision = kDefault_GrSLPrecision) = 0;
+
+ /*
+ * This call can be used by GP to pass an attribute through all shaders directly to 'output' in
+ * the fragment shader. Though this call effects both the vertex shader and fragment shader,
+ * it expects 'output' to be defined in the fragment shader before this call is made.
+ * TODO it might be nicer behavior to have a flag to declare output inside this call
+ */
+ virtual void addPassThroughAttribute(const GrGeometryProcessor::Attribute*,
+ const char* output) = 0;
+
+ /*
+ * Creates a fragment shader varying that can be referred to.
+ * Comparable to GrGLSLUniformBuilder::addUniform().
+ */
+ virtual SeparableVaryingHandle addSeparableVarying(
+ const char* name, GrGLSLVertToFrag*,
+ GrSLPrecision fsPrecision = kDefault_GrSLPrecision) = 0;
+
+ // TODO rename getFragmentBuilder
+ virtual GrGLFragmentBuilder* getFragmentShaderBuilder() = 0;
+ virtual GrGLVertexBuilder* getVertexShaderBuilder() = 0;
+
+ /*
+ * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
+ */
+};
+
+
+/* a specializations for FPs. Lets the user add uniforms and FS code */
+class GrGLSLFPBuilder : public virtual GrGLSLUniformBuilder {
+public:
+ virtual GrGLFragmentBuilder* getFragmentShaderBuilder() = 0;
+
+ /*
+ * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
+ */
+};
+
+/* a specializations for XPs. Lets the user add uniforms and FS code */
+class GrGLSLXPBuilder : public virtual GrGLSLUniformBuilder {
+public:
+ virtual GrGLXPFragmentBuilder* getFragmentShaderBuilder() = 0;
+
+ /*
+ * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
+ */
+};
+
+class GrGLSLProgramBuilder : public GrGLSLGPBuilder,
+ public GrGLSLFPBuilder,
+ public GrGLSLXPBuilder {
+public:
+ typedef GrGpu::DrawArgs DrawArgs;
+
+ GrGLXPFragmentBuilder* getFragmentShaderBuilder() override { return &fFS; }
+ GrGLVertexBuilder* getVertexShaderBuilder() override { return &fVS; }
+
+ // Handles for program uniforms (other than per-effect uniforms)
+ struct BuiltinUniformHandles {
+ UniformHandle fRTAdjustmentUni;
+
+ // We use the render target height to provide a y-down frag coord when specifying
+ // origin_upper_left is not supported.
+ UniformHandle fRTHeightUni;
+ };
+
+protected:
+ explicit GrGLSLProgramBuilder(const DrawArgs& args);
+
+ const GrPrimitiveProcessor& primitiveProcessor() const { return *fArgs.fPrimitiveProcessor; }
+ const GrPipeline& pipeline() const { return *fArgs.fPipeline; }
+ const GrProgramDesc& desc() const { return *fArgs.fDesc; }
+ const GrProgramDesc::KeyHeader& header() const { return fArgs.fDesc->header(); }
+
+ void appendUniformDecls(ShaderVisibility, SkString*) const;
+
+ // Used to add a uniform for frag position without mangling the name of the uniform inside of a
+ // stage.
+ UniformHandle addFragPosUniform(uint32_t visibility,
+ GrSLType type,
+ GrSLPrecision precision,
+ const char* name,
+ const char** outName) {
+ return this->internalAddUniformArray(visibility, type, precision, name, false, 0, outName);
+ }
+
+ const char* rtAdjustment() const { return "rtAdjustment"; }
+
+ // Generates a name for a variable. The generated string will be name prefixed by the prefix
+ // char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless
+ // explicitly asked not to.
+ void nameVariable(SkString* out, char prefix, const char* name, bool mangle = true);
+
+ // number of each input/output type in a single allocation block, used by many builders
+ static const int kVarsPerBlock;
+
+ GrGLVertexBuilder fVS;
+ GrGLGeometryBuilder fGS;
+ GrGLFragmentShaderBuilder fFS;
+ int fStageIndex;
+
+ BuiltinUniformHandles fUniformHandles;
+
+ const DrawArgs& fArgs;
+
+private:
+ virtual void onAppendUniformDecls(ShaderVisibility visibility, SkString* out) const = 0;
+
+ friend class GrGLShaderBuilder;
+ friend class GrGLVertexBuilder;
+ friend class GrGLFragmentShaderBuilder;
+ friend class GrGLGeometryBuilder;
+};
+
+#endif