OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrGLShaderBuilder.h" | 8 #include "GrGLShaderBuilder.h" |
9 #include "GrGLProgramBuilder.h" | 9 #include "gl/builders/GrGLProgramBuilder.h" |
10 #include "GrGLShaderStringBuilder.h" | |
11 #include "gl/GrGLCaps.h" | |
12 #include "gl/GrGLContext.h" | |
13 #include "gl/GrGLGpu.h" | |
14 #include "glsl/GrGLSLCaps.h" | 10 #include "glsl/GrGLSLCaps.h" |
15 #include "glsl/GrGLSLShaderVar.h" | 11 #include "glsl/GrGLSLShaderVar.h" |
16 #include "glsl/GrGLSLTextureSampler.h" | 12 #include "glsl/GrGLSLTextureSampler.h" |
17 | 13 |
18 namespace { | 14 namespace { |
19 void append_texture_lookup(SkString* out, | 15 void append_texture_lookup(SkString* out, |
20 GrGLGpu* gpu, | 16 const GrGLSLCaps* glslCaps, |
21 const char* samplerName, | 17 const char* samplerName, |
22 const char* coordName, | 18 const char* coordName, |
23 uint32_t configComponentMask, | 19 uint32_t configComponentMask, |
24 const char* swizzle, | 20 const char* swizzle, |
25 GrSLType varyingType = kVec2f_GrSLType) { | 21 GrSLType varyingType = kVec2f_GrSLType) { |
26 SkASSERT(coordName); | 22 SkASSERT(coordName); |
27 | 23 |
28 out->appendf("%s(%s, %s)", | 24 out->appendf("%s(%s, %s)", |
29 GrGLSLTexture2DFunctionName(varyingType, gpu->glslGeneration()) , | 25 GrGLSLTexture2DFunctionName(varyingType, glslCaps->generation() ), |
30 samplerName, | 26 samplerName, |
31 coordName); | 27 coordName); |
32 | 28 |
33 char mangledSwizzle[5]; | 29 char mangledSwizzle[5]; |
34 | 30 |
35 // The swizzling occurs using texture params instead of shader-mangling if A RB_texture_swizzle | 31 // The swizzling occurs using texture params instead of shader-mangling if A RB_texture_swizzle |
36 // is available. | 32 // is available. |
37 if (!gpu->glCaps().textureSwizzleSupport() && | 33 if (!glslCaps->textureSwizzleSupport() && |
38 (kA_GrColorComponentFlag == configComponentMask)) { | 34 (kA_GrColorComponentFlag == configComponentMask)) { |
39 char alphaChar = gpu->glCaps().textureRedSupport() ? 'r' : 'a'; | 35 char alphaChar = glslCaps->textureRedSupport() ? 'r' : 'a'; |
40 int i; | 36 int i; |
41 for (i = 0; '\0' != swizzle[i]; ++i) { | 37 for (i = 0; '\0' != swizzle[i]; ++i) { |
42 mangledSwizzle[i] = alphaChar; | 38 mangledSwizzle[i] = alphaChar; |
43 } | 39 } |
44 mangledSwizzle[i] ='\0'; | 40 mangledSwizzle[i] ='\0'; |
45 swizzle = mangledSwizzle; | 41 swizzle = mangledSwizzle; |
46 } | 42 } |
47 // For shader prettiness we omit the swizzle rather than appending ".rgba". | 43 // For shader prettiness we omit the swizzle rather than appending ".rgba". |
48 if (memcmp(swizzle, "rgba", 4)) { | 44 if (memcmp(swizzle, "rgba", 4)) { |
49 out->appendf(".%s", swizzle); | 45 out->appendf(".%s", swizzle); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
93 this->functions().append(") {\n"); | 89 this->functions().append(") {\n"); |
94 this->functions().append(body); | 90 this->functions().append(body); |
95 this->functions().append("}\n\n"); | 91 this->functions().append("}\n\n"); |
96 } | 92 } |
97 | 93 |
98 void GrGLShaderBuilder::appendTextureLookup(SkString* out, | 94 void GrGLShaderBuilder::appendTextureLookup(SkString* out, |
99 const GrGLSLTextureSampler& sampler, | 95 const GrGLSLTextureSampler& sampler, |
100 const char* coordName, | 96 const char* coordName, |
101 GrSLType varyingType) const { | 97 GrSLType varyingType) const { |
102 append_texture_lookup(out, | 98 append_texture_lookup(out, |
103 fProgramBuilder->gpu(), | 99 fProgramBuilder->glslCaps(), |
104 fProgramBuilder->getUniformCStr(sampler.fSamplerUnifor m), | 100 fProgramBuilder->getUniformCStr(sampler.fSamplerUnifor m), |
105 coordName, | 101 coordName, |
106 sampler.configComponentMask(), | 102 sampler.configComponentMask(), |
107 sampler.swizzle(), | 103 sampler.swizzle(), |
108 varyingType); | 104 varyingType); |
109 } | 105 } |
110 | 106 |
111 void GrGLShaderBuilder::appendTextureLookup(const GrGLSLTextureSampler& sampler, | 107 void GrGLShaderBuilder::appendTextureLookup(const GrGLSLTextureSampler& sampler, |
112 const char* coordName, | 108 const char* coordName, |
113 GrSLType varyingType) { | 109 GrSLType varyingType) { |
114 this->appendTextureLookup(&this->code(), sampler, coordName, varyingType); | 110 this->appendTextureLookup(&this->code(), sampler, coordName, varyingType); |
115 } | 111 } |
116 | 112 |
117 void GrGLShaderBuilder::appendTextureLookupAndModulate(const char* modulation, | 113 void GrGLShaderBuilder::appendTextureLookupAndModulate(const char* modulation, |
118 const GrGLSLTextureSample r& sampler, | 114 const GrGLSLTextureSample r& sampler, |
119 const char* coordName, | 115 const char* coordName, |
120 GrSLType varyingType) { | 116 GrSLType varyingType) { |
121 SkString lookup; | 117 SkString lookup; |
122 this->appendTextureLookup(&lookup, sampler, coordName, varyingType); | 118 this->appendTextureLookup(&lookup, sampler, coordName, varyingType); |
123 this->codeAppend((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str()); | 119 this->codeAppend((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str()); |
124 } | 120 } |
125 | 121 |
126 | |
127 const GrGLenum* GrGLShaderBuilder::GetTexParamSwizzle(GrPixelConfig config, cons t GrGLCaps& caps) { | |
128 if (caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(config)) { | |
129 if (caps.textureRedSupport()) { | |
130 static const GrGLenum gRedSmear[] = { GR_GL_RED, GR_GL_RED, GR_GL_RE D, GR_GL_RED }; | |
131 return gRedSmear; | |
132 } else { | |
133 static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA, | |
134 GR_GL_ALPHA, GR_GL_ALPHA }; | |
135 return gAlphaSmear; | |
136 } | |
137 } else { | |
138 static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE , GR_GL_ALPHA }; | |
139 return gStraight; | |
140 } | |
141 } | |
142 | |
143 void GrGLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionNam e) { | 122 void GrGLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionNam e) { |
144 if (!(featureBit & fFeaturesAddedMask)) { | 123 if (!(featureBit & fFeaturesAddedMask)) { |
145 this->extensions().appendf("#extension %s: require\n", extensionName); | 124 this->extensions().appendf("#extension %s: require\n", extensionName); |
146 fFeaturesAddedMask |= featureBit; | 125 fFeaturesAddedMask |= featureBit; |
147 } | 126 } |
148 } | 127 } |
149 | 128 |
150 void GrGLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const { | 129 void GrGLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const { |
151 for (int i = 0; i < vars.count(); ++i) { | 130 for (int i = 0; i < vars.count(); ++i) { |
152 vars[i].appendDecl(fProgramBuilder->glslCaps(), out); | 131 vars[i].appendDecl(fProgramBuilder->glslCaps(), out); |
153 out->append(";\n"); | 132 out->append(";\n"); |
154 } | 133 } |
155 } | 134 } |
156 | 135 |
157 void GrGLShaderBuilder::appendTextureLookup(const char* samplerName, | 136 void GrGLShaderBuilder::appendTextureLookup(const char* samplerName, |
158 const char* coordName, | 137 const char* coordName, |
159 uint32_t configComponentMask, | 138 uint32_t configComponentMask, |
160 const char* swizzle) { | 139 const char* swizzle) { |
161 append_texture_lookup(&this->code(), | 140 append_texture_lookup(&this->code(), |
162 fProgramBuilder->gpu(), | 141 fProgramBuilder->glslCaps(), |
163 samplerName, | 142 samplerName, |
164 coordName, | 143 coordName, |
165 configComponentMask, | 144 configComponentMask, |
166 swizzle, | 145 swizzle, |
167 kVec2f_GrSLType); | 146 kVec2f_GrSLType); |
168 } | 147 } |
169 | 148 |
170 void GrGLShaderBuilder::addLayoutQualifier(const char* param, InterfaceQualifier interface) { | 149 void GrGLShaderBuilder::addLayoutQualifier(const char* param, InterfaceQualifier interface) { |
171 SkASSERT(fProgramBuilder->gpu()->glslGeneration() >= k330_GrGLSLGeneration | | | 150 SkASSERT(fProgramBuilder->glslCaps()->generation() >= k330_GrGLSLGeneration || |
172 fProgramBuilder->gpu()->glCaps().glslCaps()->mustEnableAdvBlendEqs( )); | 151 fProgramBuilder->glslCaps()->mustEnableAdvBlendEqs()); |
173 fLayoutParams[interface].push_back() = param; | 152 fLayoutParams[interface].push_back() = param; |
174 } | 153 } |
175 | 154 |
176 void GrGLShaderBuilder::compileAndAppendLayoutQualifiers() { | 155 void GrGLShaderBuilder::compileAndAppendLayoutQualifiers() { |
177 static const char* interfaceQualifierNames[] = { | 156 static const char* interfaceQualifierNames[] = { |
178 "out" | 157 "out" |
179 }; | 158 }; |
180 | 159 |
181 for (int interface = 0; interface <= kLastInterfaceQualifier; ++interface) { | 160 for (int interface = 0; interface <= kLastInterfaceQualifier; ++interface) { |
182 const SkTArray<SkString>& params = fLayoutParams[interface]; | 161 const SkTArray<SkString>& params = fLayoutParams[interface]; |
183 if (params.empty()) { | 162 if (params.empty()) { |
184 continue; | 163 continue; |
185 } | 164 } |
186 this->layoutQualifiers().appendf("layout(%s", params[0].c_str()); | 165 this->layoutQualifiers().appendf("layout(%s", params[0].c_str()); |
187 for (int i = 1; i < params.count(); ++i) { | 166 for (int i = 1; i < params.count(); ++i) { |
188 this->layoutQualifiers().appendf(", %s", params[i].c_str()); | 167 this->layoutQualifiers().appendf(", %s", params[i].c_str()); |
189 } | 168 } |
190 this->layoutQualifiers().appendf(") %s;\n", interfaceQualifierNames[inte rface]); | 169 this->layoutQualifiers().appendf(") %s;\n", interfaceQualifierNames[inte rface]); |
191 } | 170 } |
192 | 171 |
193 GR_STATIC_ASSERT(0 == GrGLShaderBuilder::kOut_InterfaceQualifier); | 172 GR_STATIC_ASSERT(0 == GrGLShaderBuilder::kOut_InterfaceQualifier); |
194 GR_STATIC_ASSERT(SK_ARRAY_COUNT(interfaceQualifierNames) == kLastInterfaceQu alifier + 1); | 173 GR_STATIC_ASSERT(SK_ARRAY_COUNT(interfaceQualifierNames) == kLastInterfaceQu alifier + 1); |
195 } | 174 } |
196 | 175 |
197 bool | 176 void GrGLShaderBuilder::finalize(uint32_t visibility) { |
198 GrGLShaderBuilder::finalize(GrGLuint programId, GrGLenum type, SkTDArray<GrGLuin t>* shaderIds) { | |
199 SkASSERT(!fFinalized); | 177 SkASSERT(!fFinalized); |
178 this->versionDecl() = fProgramBuilder->glslCaps()->versionDeclString(); | |
179 this->compileAndAppendLayoutQualifiers(); | |
robertphillips
2015/10/30 16:39:46
\n somewhere ?
egdaniel
2015/10/30 18:24:20
Done.
| |
180 fProgramBuilder->appendUniformDecls((GrGLProgramBuilder::ShaderVisibility) v isibility, &this->uniforms()); | |
181 this->appendDecls(fInputs, &this->inputs()); | |
robertphillips
2015/10/30 16:39:46
can this be on one line ?
egdaniel
2015/10/30 18:24:20
sadly no, 101 chars
| |
182 SkASSERT(k110_GrGLSLGeneration != fProgramBuilder->glslCaps()->generation() || | |
183 fOutputs.empty()); | |
184 this->appendDecls(fOutputs, &this->outputs()); | |
185 this->onFinalize(); | |
200 // append the 'footer' to code | 186 // append the 'footer' to code |
201 this->code().append("}"); | 187 this->code().append("}"); |
202 | 188 |
203 for (int i = 0; i <= fCodeIndex; i++) { | 189 for (int i = 0; i <= fCodeIndex; i++) { |
204 fCompilerStrings[i] = fShaderStrings[i].c_str(); | 190 fCompilerStrings[i] = fShaderStrings[i].c_str(); |
205 fCompilerStringLengths[i] = (int)fShaderStrings[i].size(); | 191 fCompilerStringLengths[i] = (int)fShaderStrings[i].size(); |
206 } | 192 } |
207 | 193 |
208 GrGLGpu* gpu = fProgramBuilder->gpu(); | 194 fFinalized = true; |
209 GrGLuint shaderId = GrGLCompileAndAttachShader(gpu->glContext(), | 195 } |
210 programId, | |
211 type, | |
212 fCompilerStrings.begin(), | |
213 fCompilerStringLengths.begin( ), | |
214 fCompilerStrings.count(), | |
215 gpu->stats()); | |
216 | 196 |
217 fFinalized = true; | |
218 | |
219 if (!shaderId) { | |
220 return false; | |
221 } | |
222 | |
223 *shaderIds->append() = shaderId; | |
224 | |
225 return true; | |
226 } | |
OLD | NEW |