blob: 50fdeeb89c93f03373c12d20b9c784ab3d690347 [file] [log] [blame]
joshualitt30ba4362014-08-21 20:18:45 -07001/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
egdaniel2d721d32015-11-11 13:06:05 -08008#ifndef GrGLSLFragmentShaderBuilder_DEFINED
9#define GrGLSLFragmentShaderBuilder_DEFINED
joshualitt47bb3822014-10-07 16:43:25 -070010
Brian Salomon096b0912019-08-14 16:56:13 -040011#include "src/gpu/GrBlend.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "src/gpu/GrProcessor.h"
Ethan Nicholasc6dce5a2019-07-24 16:51:36 -040013#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "src/gpu/glsl/GrGLSLShaderBuilder.h"
egdaniel7dc4bd02015-10-29 07:57:01 -070015
egdaniel574a4c12015-11-02 06:22:44 -080016class GrRenderTarget;
egdaniel8dcdedc2015-11-11 06:27:20 -080017class GrGLSLVarying;
joshualitt74077b92014-10-24 11:26:03 -070018
joshualittb0a8a372014-09-23 09:50:21 -070019/*
cdalton85285412016-02-18 12:37:07 -080020 * This class is used by fragment processors to build their fragment code.
joshualittb0a8a372014-09-23 09:50:21 -070021 */
Brian Salomonffd15ea2020-07-01 16:48:20 -040022class GrGLSLFPFragmentBuilder : virtual public GrGLSLShaderBuilder {
joshualittb0a8a372014-09-23 09:50:21 -070023public:
Brian Salomonffd15ea2020-07-01 16:48:20 -040024 /** Appease the compiler; the derived class initializes GrGLSLShaderBuilder. */
25 GrGLSLFPFragmentBuilder() : GrGLSLShaderBuilder(nullptr) {
Michael Ludwig45191342020-03-24 12:29:39 -040026 // Suppress unused warning error
Kevin Lubickbe03ef12021-06-16 15:28:00 -040027 (void) fPadding;
Michael Ludwig45191342020-03-24 12:29:39 -040028 }
joshualitt47bb3822014-10-07 16:43:25 -070029
Chris Dalton0dffbab2019-03-27 13:08:50 -060030 enum class ScopeFlags {
31 // Every fragment will always execute this code, and will do it exactly once.
32 kTopLevel = 0,
33 // Either all fragments in a given primitive, or none, will execute this code.
34 kInsidePerPrimitiveBranch = (1 << 0),
35 // Any given fragment may or may not execute this code.
36 kInsidePerPixelBranch = (1 << 1),
37 // This code will be executed more than once.
38 kInsideLoop = (1 << 2)
Robert Phillips7f861922018-01-30 13:13:42 +000039 };
40
Brian Salomonf3178a52020-04-16 10:37:55 -040041 SkString writeProcessorFunction(GrGLSLFragmentProcessor*, GrGLSLFragmentProcessor::EmitArgs&);
Ethan Nicholasf7b88202017-09-18 14:10:39 -040042
43 virtual void forceHighPrecision() = 0;
Michael Ludwig45191342020-03-24 12:29:39 -040044
John Stilesbb04e3d2021-06-04 12:09:11 -040045 /** Returns the variable name that holds the color of the destination pixel. This may be nullptr
46 * if no effect advertised that it will read the destination. */
47 virtual const char* dstColor() = 0;
48
Michael Ludwig45191342020-03-24 12:29:39 -040049private:
Brian Salomonf3178a52020-04-16 10:37:55 -040050 /**
51 * These are called before/after calling emitCode on a child proc to update mangling.
52 */
53 virtual void onBeforeChildProcEmitCode() = 0;
54 virtual void onAfterChildProcEmitCode() = 0;
55
56 virtual const SkString& getMangleString() const = 0;
57
Michael Ludwig45191342020-03-24 12:29:39 -040058 // WARNING: LIke GrRenderTargetProxy, changes to this can cause issues in ASAN. This is caused
Michael Ludwigcc848b52020-07-22 16:36:49 -040059 // by GrGLSLProgramBuilder's GrTBlockLists requiring 16 byte alignment, but since
Michael Ludwig45191342020-03-24 12:29:39 -040060 // GrGLSLFragmentShaderBuilder has a virtual diamond hierarchy, ASAN requires all this pointers
61 // to start aligned, even though clang is already correctly offsetting the individual fields
62 // that require the larger alignment. In the current world, this extra padding is sufficient to
63 // correctly initialize GrGLSLXPFragmentBuilder second.
Kevin Lubickbe03ef12021-06-16 15:28:00 -040064 char fPadding[4] = {};
cdalton85285412016-02-18 12:37:07 -080065};
66
Brian Osman2421b992021-06-19 10:44:54 -040067GR_MAKE_BITFIELD_CLASS_OPS(GrGLSLFPFragmentBuilder::ScopeFlags)
Chris Dalton0dffbab2019-03-27 13:08:50 -060068
cdalton85285412016-02-18 12:37:07 -080069/*
cdalton85285412016-02-18 12:37:07 -080070 * This class is used by Xfer processors to build their fragment code.
71 */
Brian Salomonffd15ea2020-07-01 16:48:20 -040072class GrGLSLXPFragmentBuilder : virtual public GrGLSLShaderBuilder {
cdalton85285412016-02-18 12:37:07 -080073public:
Brian Salomonffd15ea2020-07-01 16:48:20 -040074 /** Appease the compiler; the derived class initializes GrGLSLShaderBuilder. */
75 GrGLSLXPFragmentBuilder() : GrGLSLShaderBuilder(nullptr) {}
cdalton85285412016-02-18 12:37:07 -080076
77 virtual bool hasCustomColorOutput() const = 0;
78 virtual bool hasSecondaryOutput() const = 0;
79
80 /** Returns the variable name that holds the color of the destination pixel. This may be nullptr
81 * if no effect advertised that it will read the destination. */
joshualittb0a8a372014-09-23 09:50:21 -070082 virtual const char* dstColor() = 0;
83
cdalton8917d622015-05-06 13:40:21 -070084 /** Adds any necessary layout qualifiers in order to legalize the supplied blend equation with
85 this shader. It is only legal to call this method with an advanced blend equation, and only
86 if these equations are supported. */
87 virtual void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) = 0;
joshualittb0a8a372014-09-23 09:50:21 -070088};
89
cdalton85285412016-02-18 12:37:07 -080090/*
91 * This class implements the various fragment builder interfaces.
92 */
Chris Dalton60283612018-02-14 13:38:14 -070093class GrGLSLFragmentShaderBuilder : public GrGLSLFPFragmentBuilder, public GrGLSLXPFragmentBuilder {
joshualitt30ba4362014-08-21 20:18:45 -070094public:
Robert Phillips7f861922018-01-30 13:13:42 +000095 /** Returns a nonzero key for a surface's origin. This should only be called if a processor will
96 use the fragment position and/or sample locations. */
97 static uint8_t KeyForSurfaceOrigin(GrSurfaceOrigin);
98
cdalton28f45b92016-03-07 13:58:26 -080099 GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* program);
joshualitt30ba4362014-08-21 20:18:45 -0700100
John Stilesbb04e3d2021-06-04 12:09:11 -0400101 // Shared FP/XP interface.
102 const char* dstColor() override;
103
cdalton85285412016-02-18 12:37:07 -0800104 // GrGLSLFPFragmentBuilder interface.
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400105 void forceHighPrecision() override { fForceHighPrecision = true; }
cdalton85285412016-02-18 12:37:07 -0800106
107 // GrGLSLXPFragmentBuilder interface.
Michael Ludwig45191342020-03-24 12:29:39 -0400108 bool hasCustomColorOutput() const override { return SkToBool(fCustomColorOutput); }
cdalton85285412016-02-18 12:37:07 -0800109 bool hasSecondaryOutput() const override { return fHasSecondaryOutput; }
cdalton8917d622015-05-06 13:40:21 -0700110 void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) override;
111
joshualitt74077b92014-10-24 11:26:03 -0700112private:
Chris Daltond7291ba2019-03-07 14:17:03 -0700113 using CustomFeatures = GrProcessor::CustomFeatures;
114
Brian Salomonf3178a52020-04-16 10:37:55 -0400115 // GrGLSLFPFragmentBuilder private interface.
116 void onBeforeChildProcEmitCode() override;
117 void onAfterChildProcEmitCode() override;
118 const SkString& getMangleString() const override { return fMangleString; }
119
joshualitt47bb3822014-10-07 16:43:25 -0700120 // Private public interface, used by GrGLProgramBuilder to build a fragment shader
joshualitt47bb3822014-10-07 16:43:25 -0700121 void enableCustomOutput();
122 void enableSecondaryOutput();
123 const char* getPrimaryColorOutputName() const;
124 const char* getSecondaryColorOutputName() const;
Brian Salomondc092132018-04-04 10:14:16 -0400125 bool primaryColorOutputIsInOut() const;
joshualitt47bb3822014-10-07 16:43:25 -0700126
cdalton87332102016-02-26 12:22:02 -0800127#ifdef SK_DEBUG
egdaniel57d3b032015-11-13 11:57:27 -0800128 // As GLSLProcessors emit code, there are some conditions we need to verify. We use the below
joshualitt47bb3822014-10-07 16:43:25 -0700129 // state to track this. The reset call is called per processor emitted.
Chris Daltond7291ba2019-03-07 14:17:03 -0700130 bool fHasReadDstColorThisStage_DebugOnly = false;
131 CustomFeatures fUsedProcessorFeaturesThisStage_DebugOnly = CustomFeatures::kNone;
132 CustomFeatures fUsedProcessorFeaturesAllStages_DebugOnly = CustomFeatures::kNone;
133
134 void debugOnly_resetPerStageVerification() {
135 fHasReadDstColorThisStage_DebugOnly = false;
136 fUsedProcessorFeaturesThisStage_DebugOnly = CustomFeatures::kNone;
joshualitt47bb3822014-10-07 16:43:25 -0700137 }
cdalton87332102016-02-26 12:22:02 -0800138#endif
joshualitt30ba4362014-08-21 20:18:45 -0700139
ethannicholas5961bc92016-10-12 06:39:56 -0700140 static const char* DeclaredColorOutputName() { return "sk_FragColor"; }
egdaniel8dcdedc2015-11-11 06:27:20 -0800141 static const char* DeclaredSecondaryColorOutputName() { return "fsSecondaryColorOut"; }
142
cdalton28f45b92016-03-07 13:58:26 -0800143 GrSurfaceOrigin getSurfaceOrigin() const;
joshualitt74077b92014-10-24 11:26:03 -0700144
egdaniel574a4c12015-11-02 06:22:44 -0800145 void onFinalize() override;
joshualitt30ba4362014-08-21 20:18:45 -0700146
John Stilesbb04e3d2021-06-04 12:09:11 -0400147 static constexpr const char kDstColorName[] = "_dstColor";
joshualitt47bb3822014-10-07 16:43:25 -0700148
cdalton85285412016-02-18 12:37:07 -0800149 /*
150 * State that tracks which child proc in the proc tree is currently emitting code. This is
151 * used to update the fMangleString, which is used to mangle the names of uniforms and functions
152 * emitted by the proc. fSubstageIndices is a stack: its count indicates how many levels deep
153 * we are in the tree, and its second-to-last value is the index of the child proc at that
154 * level which is currently emitting code. For example, if fSubstageIndices = [3, 1, 2, 0], that
155 * means we're currently emitting code for the base proc's 3rd child's 1st child's 2nd child.
156 */
157 SkTArray<int> fSubstageIndices;
158
159 /*
160 * The mangle string is used to mangle the names of uniforms/functions emitted by the child
161 * procs so no duplicate uniforms/functions appear in the generated shader program. The mangle
162 * string is simply based on fSubstageIndices. For example, if fSubstageIndices = [3, 1, 2, 0],
163 * then the manglestring will be "_c3_c1_c2", and any uniform/function emitted by that proc will
164 * have "_c3_c1_c2" appended to its name, which can be interpreted as "base proc's 3rd child's
165 * 1st child's 2nd child".
166 */
167 SkString fMangleString;
168
Michael Ludwig45191342020-03-24 12:29:39 -0400169 GrShaderVar* fCustomColorOutput = nullptr;
170
Chris Daltond7291ba2019-03-07 14:17:03 -0700171 bool fSetupFragPosition = false;
Chris Daltond7291ba2019-03-07 14:17:03 -0700172 bool fHasSecondaryOutput = false;
Chris Dalton0dffbab2019-03-27 13:08:50 -0600173 bool fHasModifiedSampleMask = false;
Chris Daltond7291ba2019-03-07 14:17:03 -0700174 bool fForceHighPrecision = false;
joshualittfe1233c2014-10-07 12:16:35 -0700175
egdanielfa896322016-01-13 12:19:30 -0800176 friend class GrGLSLProgramBuilder;
joshualitt47bb3822014-10-07 16:43:25 -0700177 friend class GrGLProgramBuilder;
Ethan Nicholas8f352ce2021-03-17 14:12:20 -0400178 friend class GrVkPipelineStateBuilder;
joshualitt30ba4362014-08-21 20:18:45 -0700179};
180
181#endif