• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 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 
8 #include "src/gpu/dawn/GrDawnUniformHandler.h"
9 #include "src/gpu/glsl/GrGLSLProgramBuilder.h"
10 
GrDawnUniformHandler(GrGLSLProgramBuilder * program)11 GrDawnUniformHandler::GrDawnUniformHandler(GrGLSLProgramBuilder* program)
12     : INHERITED(program)
13     , fUniforms(kUniformsPerBlock)
14     , fSamplers(kUniformsPerBlock)
15     , fTextures(kUniformsPerBlock)
16 {
17 }
18 
getUniformVariable(UniformHandle u) const19 const GrShaderVar& GrDawnUniformHandler::getUniformVariable(UniformHandle u) const {
20     return fUniforms[u.toIndex()].fVar;
21 }
22 
getUniformCStr(UniformHandle u) const23 const char* GrDawnUniformHandler::getUniformCStr(UniformHandle u) const {
24     return fUniforms[u.toIndex()].fVar.getName().c_str();
25 }
26 
27 // FIXME: this code was ripped from GrVkUniformHandler; should be refactored.
28 namespace {
29 
grsltype_to_alignment_mask(GrSLType type)30 uint32_t grsltype_to_alignment_mask(GrSLType type) {
31     switch(type) {
32         case kByte_GrSLType: // fall through
33         case kUByte_GrSLType:
34             return 0x0;
35         case kByte2_GrSLType: // fall through
36         case kUByte2_GrSLType:
37             return 0x1;
38         case kByte3_GrSLType: // fall through
39         case kByte4_GrSLType:
40         case kUByte3_GrSLType:
41         case kUByte4_GrSLType:
42             return 0x3;
43         case kShort_GrSLType: // fall through
44         case kUShort_GrSLType:
45             return 0x1;
46         case kShort2_GrSLType: // fall through
47         case kUShort2_GrSLType:
48             return 0x3;
49         case kShort3_GrSLType: // fall through
50         case kShort4_GrSLType:
51         case kUShort3_GrSLType:
52         case kUShort4_GrSLType:
53             return 0x7;
54         case kInt_GrSLType:
55         case kUint_GrSLType:
56             return 0x3;
57         case kHalf_GrSLType: // fall through
58         case kFloat_GrSLType:
59             return 0x3;
60         case kHalf2_GrSLType: // fall through
61         case kFloat2_GrSLType:
62             return 0x7;
63         case kHalf3_GrSLType: // fall through
64         case kFloat3_GrSLType:
65             return 0xF;
66         case kHalf4_GrSLType: // fall through
67         case kFloat4_GrSLType:
68             return 0xF;
69         case kUint2_GrSLType:
70             return 0x7;
71         case kInt2_GrSLType:
72             return 0x7;
73         case kInt3_GrSLType:
74             return 0xF;
75         case kInt4_GrSLType:
76             return 0xF;
77         case kHalf2x2_GrSLType: // fall through
78         case kFloat2x2_GrSLType:
79             return 0x7;
80         case kHalf3x3_GrSLType: // fall through
81         case kFloat3x3_GrSLType:
82             return 0xF;
83         case kHalf4x4_GrSLType: // fall through
84         case kFloat4x4_GrSLType:
85             return 0xF;
86 
87         // This query is only valid for certain types.
88         case kVoid_GrSLType:
89         case kBool_GrSLType:
90         case kTexture2DSampler_GrSLType:
91         case kTextureExternalSampler_GrSLType:
92         case kTexture2DRectSampler_GrSLType:
93         case kTexture2D_GrSLType:
94         case kSampler_GrSLType:
95             break;
96     }
97     SK_ABORT("Unexpected type");
98 }
99 
grsltype_to_size(GrSLType type)100 static inline uint32_t grsltype_to_size(GrSLType type) {
101     switch(type) {
102         case kByte_GrSLType:
103         case kUByte_GrSLType:
104             return 1;
105         case kByte2_GrSLType:
106         case kUByte2_GrSLType:
107             return 2;
108         case kByte3_GrSLType:
109         case kUByte3_GrSLType:
110             return 3;
111         case kByte4_GrSLType:
112         case kUByte4_GrSLType:
113             return 4;
114         case kShort_GrSLType:
115             return sizeof(int16_t);
116         case kShort2_GrSLType:
117             return 2 * sizeof(int16_t);
118         case kShort3_GrSLType:
119             return 3 * sizeof(int16_t);
120         case kShort4_GrSLType:
121             return 4 * sizeof(int16_t);
122         case kUShort_GrSLType:
123             return sizeof(uint16_t);
124         case kUShort2_GrSLType:
125             return 2 * sizeof(uint16_t);
126         case kUShort3_GrSLType:
127             return 3 * sizeof(uint16_t);
128         case kUShort4_GrSLType:
129             return 4 * sizeof(uint16_t);
130         case kInt_GrSLType:
131             return sizeof(int32_t);
132         case kUint_GrSLType:
133             return sizeof(int32_t);
134         case kHalf_GrSLType: // fall through
135         case kFloat_GrSLType:
136             return sizeof(float);
137         case kHalf2_GrSLType: // fall through
138         case kFloat2_GrSLType:
139             return 2 * sizeof(float);
140         case kHalf3_GrSLType: // fall through
141         case kFloat3_GrSLType:
142             return 3 * sizeof(float);
143         case kHalf4_GrSLType: // fall through
144         case kFloat4_GrSLType:
145             return 4 * sizeof(float);
146         case kUint2_GrSLType:
147             return 2 * sizeof(uint32_t);
148         case kInt2_GrSLType:
149             return 2 * sizeof(int32_t);
150         case kInt3_GrSLType:
151             return 3 * sizeof(int32_t);
152         case kInt4_GrSLType:
153             return 4 * sizeof(int32_t);
154         case kHalf2x2_GrSLType: // fall through
155         case kFloat2x2_GrSLType:
156             //TODO: this will be 4 * szof(float) on std430.
157             return 8 * sizeof(float);
158         case kHalf3x3_GrSLType: // fall through
159         case kFloat3x3_GrSLType:
160             return 12 * sizeof(float);
161         case kHalf4x4_GrSLType: // fall through
162         case kFloat4x4_GrSLType:
163             return 16 * sizeof(float);
164 
165         // This query is only valid for certain types.
166         case kVoid_GrSLType:
167         case kBool_GrSLType:
168         case kTexture2DSampler_GrSLType:
169         case kTextureExternalSampler_GrSLType:
170         case kTexture2DRectSampler_GrSLType:
171         case kTexture2D_GrSLType:
172         case kSampler_GrSLType:
173             break;
174     }
175     SK_ABORT("Unexpected type");
176 }
177 
get_ubo_offset(uint32_t * currentOffset,GrSLType type,int arrayCount)178 uint32_t get_ubo_offset(uint32_t* currentOffset,
179                         GrSLType type,
180                         int arrayCount) {
181     uint32_t alignmentMask = grsltype_to_alignment_mask(type);
182     // We want to use the std140 layout here, so we must make arrays align to 16 bytes.
183     if (arrayCount || type == kFloat2x2_GrSLType) {
184         alignmentMask = 0xF;
185     }
186     uint32_t offsetDiff = *currentOffset & alignmentMask;
187     if (offsetDiff != 0) {
188         offsetDiff = alignmentMask - offsetDiff + 1;
189     }
190     uint32_t uniformOffset = *currentOffset + offsetDiff;
191     SkASSERT(sizeof(float) == 4);
192     if (arrayCount) {
193         uint32_t elementSize = SkTMax<uint32_t>(16, grsltype_to_size(type));
194         SkASSERT(0 == (elementSize & 0xF));
195         *currentOffset = uniformOffset + elementSize * arrayCount;
196     } else {
197         *currentOffset = uniformOffset + grsltype_to_size(type);
198     }
199     return uniformOffset;
200 }
201 
202 }
203 
internalAddUniformArray(uint32_t visibility,GrSLType type,const char * name,bool mangleName,int arrayCount,const char ** outName)204 GrGLSLUniformHandler::UniformHandle GrDawnUniformHandler::internalAddUniformArray(
205         uint32_t visibility,
206         GrSLType type,
207         const char* name,
208         bool mangleName,
209         int arrayCount,
210         const char** outName) {
211     UniformInfo& info = fUniforms.push_back();
212     info.fVisibility = visibility;
213     if (visibility == kFragment_GrShaderFlag) {
214         info.fUBOOffset = get_ubo_offset(&fCurrentFragmentUBOOffset, type, arrayCount);
215     } else {
216         info.fUBOOffset = get_ubo_offset(&fCurrentGeometryUBOOffset, type, arrayCount);
217     }
218     GrShaderVar& var = info.fVar;
219     char prefix = 'u';
220     if ('u' == name[0] || !strncmp(name, GR_NO_MANGLE_PREFIX, strlen(GR_NO_MANGLE_PREFIX))) {
221         prefix = '\0';
222     }
223     fProgramBuilder->nameVariable(var.accessName(), prefix, name, mangleName);
224     var.setType(type);
225     var.setTypeModifier(GrShaderVar::kNone_TypeModifier);
226     var.setArrayCount(arrayCount);
227     SkString layoutQualifier;
228     layoutQualifier.appendf("offset = %d", info.fUBOOffset);
229     var.addLayoutQualifier(layoutQualifier.c_str());
230     if (outName) {
231         *outName = var.c_str();
232     }
233     return GrGLSLUniformHandler::UniformHandle(fUniforms.count() - 1);
234 }
235 
addSampler(const GrTexture * texture,const GrSamplerState &,const GrSwizzle & swizzle,const char * name,const GrShaderCaps * caps)236 GrGLSLUniformHandler::SamplerHandle GrDawnUniformHandler::addSampler(const GrTexture* texture,
237                                                                      const GrSamplerState&,
238                                                                      const GrSwizzle& swizzle,
239                                                                      const char* name,
240                                                                      const GrShaderCaps* caps) {
241     SkString mangleName;
242     char prefix = 's';
243     fProgramBuilder->nameVariable(&mangleName, prefix, name, true);
244 
245     GrSLType samplerType = kSampler_GrSLType, textureType = kTexture2D_GrSLType;
246     int binding = kSamplerBindingBase + fSamplers.count() * 2;
247     UniformInfo& info = fSamplers.push_back();
248     info.fVar.setType(samplerType);
249     info.fVar.setTypeModifier(GrShaderVar::kUniform_TypeModifier);
250     info.fVar.setName(mangleName);
251     SkString layoutQualifier;
252     layoutQualifier.appendf("set = 0, binding = %d", binding);
253     info.fVar.addLayoutQualifier(layoutQualifier.c_str());
254     info.fVisibility = kFragment_GrShaderFlag;
255     info.fUBOOffset = 0;
256     fSamplerSwizzles.push_back(swizzle);
257     SkASSERT(fSamplerSwizzles.count() == fSamplers.count());
258 
259     SkString mangleTexName;
260     char texPrefix = 't';
261     fProgramBuilder->nameVariable(&mangleTexName, texPrefix, name, true);
262     UniformInfo& texInfo = fTextures.push_back();
263     texInfo.fVar.setType(textureType);
264     texInfo.fVar.setTypeModifier(GrShaderVar::kUniform_TypeModifier);
265     texInfo.fVar.setName(mangleTexName);
266     SkString texLayoutQualifier;
267     texLayoutQualifier.appendf("set = 0, binding = %d", binding + 1);
268     texInfo.fVar.addLayoutQualifier(texLayoutQualifier.c_str());
269     texInfo.fVisibility = kFragment_GrShaderFlag;
270     texInfo.fUBOOffset = 0;
271 
272     SkString reference;
273     reference.printf("makeSampler2D(%s, %s)", texInfo.fVar.getName().c_str(),
274                                               info.fVar.getName().c_str());
275     fSamplerReferences.push_back() = reference;
276     return GrGLSLUniformHandler::SamplerHandle(fSamplers.count() - 1);
277 }
278 
samplerVariable(GrGLSLUniformHandler::SamplerHandle handle) const279 const char* GrDawnUniformHandler::samplerVariable(
280         GrGLSLUniformHandler::SamplerHandle handle) const {
281     return fSamplerReferences[handle.toIndex()].c_str();
282 }
283 
samplerSwizzle(GrGLSLUniformHandler::SamplerHandle handle) const284 GrSwizzle GrDawnUniformHandler::samplerSwizzle(GrGLSLUniformHandler::SamplerHandle handle) const {
285     return fSamplerSwizzles[handle.toIndex()];
286 }
287 
appendUniformDecls(GrShaderFlags visibility,SkString * out) const288 void GrDawnUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString* out) const {
289     for (int i = 0; i < fSamplers.count(); ++i) {
290         if (fSamplers[i].fVisibility & visibility) {
291             fSamplers[i].fVar.appendDecl(fProgramBuilder->shaderCaps(), out);
292             out->append(";\n");
293             fTextures[i].fVar.appendDecl(fProgramBuilder->shaderCaps(), out);
294             out->append(";\n");
295         }
296     }
297     SkString uniformsString;
298     for (int i = 0; i < fUniforms.count(); ++i) {
299         if (fUniforms[i].fVisibility & visibility) {
300             fUniforms[i].fVar.appendDecl(fProgramBuilder->shaderCaps(), &uniformsString);
301             uniformsString.append(";\n");
302         }
303     }
304     if (!uniformsString.isEmpty()) {
305         uint32_t uniformBinding;
306         const char* stage;
307         if (kVertex_GrShaderFlag == visibility) {
308             uniformBinding = kGeometryBinding;
309             stage = "vertex";
310         } else if (kGeometry_GrShaderFlag == visibility) {
311             uniformBinding = kGeometryBinding;
312             stage = "geometry";
313         } else {
314             SkASSERT(kFragment_GrShaderFlag == visibility);
315             uniformBinding = kFragBinding;
316             stage = "fragment";
317         }
318         out->appendf("layout (set = 0, binding = %d) uniform %sUniformBuffer\n{\n",
319                      uniformBinding, stage);
320         out->appendf("%s\n};\n", uniformsString.c_str());
321     }
322 }
323