blob: 19ad35b4a4324d08dd3f9231674bd2b2d837b515 [file] [log] [blame]
Stephen White4da34bf2019-07-30 10:37:47 -04001/*
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
11GrDawnUniformHandler::GrDawnUniformHandler(GrGLSLProgramBuilder* program)
12 : INHERITED(program)
13 , fUniforms(kUniformsPerBlock)
14{
15}
16
17const GrShaderVar& GrDawnUniformHandler::getUniformVariable(UniformHandle u) const {
18 return fUniforms[u.toIndex()].fVar;
19}
20
21const char* GrDawnUniformHandler::getUniformCStr(UniformHandle u) const {
22 return fUniforms[u.toIndex()].fVar.getName().c_str();
23}
24
25// FIXME: this code was ripped from GrVkUniformHandler; should be refactored.
26namespace {
27
28uint32_t grsltype_to_alignment_mask(GrSLType type) {
29 switch(type) {
30 case kByte_GrSLType: // fall through
31 case kUByte_GrSLType:
32 return 0x0;
33 case kByte2_GrSLType: // fall through
34 case kUByte2_GrSLType:
35 return 0x1;
36 case kByte3_GrSLType: // fall through
37 case kByte4_GrSLType:
38 case kUByte3_GrSLType:
39 case kUByte4_GrSLType:
40 return 0x3;
41 case kShort_GrSLType: // fall through
42 case kUShort_GrSLType:
43 return 0x1;
44 case kShort2_GrSLType: // fall through
45 case kUShort2_GrSLType:
46 return 0x3;
47 case kShort3_GrSLType: // fall through
48 case kShort4_GrSLType:
49 case kUShort3_GrSLType:
50 case kUShort4_GrSLType:
51 return 0x7;
52 case kInt_GrSLType:
53 case kUint_GrSLType:
54 return 0x3;
55 case kHalf_GrSLType: // fall through
56 case kFloat_GrSLType:
57 return 0x3;
58 case kHalf2_GrSLType: // fall through
59 case kFloat2_GrSLType:
60 return 0x7;
61 case kHalf3_GrSLType: // fall through
62 case kFloat3_GrSLType:
63 return 0xF;
64 case kHalf4_GrSLType: // fall through
65 case kFloat4_GrSLType:
66 return 0xF;
67 case kUint2_GrSLType:
68 return 0x7;
69 case kInt2_GrSLType:
70 return 0x7;
71 case kInt3_GrSLType:
72 return 0xF;
73 case kInt4_GrSLType:
74 return 0xF;
75 case kHalf2x2_GrSLType: // fall through
76 case kFloat2x2_GrSLType:
77 return 0x7;
78 case kHalf3x3_GrSLType: // fall through
79 case kFloat3x3_GrSLType:
80 return 0xF;
81 case kHalf4x4_GrSLType: // fall through
82 case kFloat4x4_GrSLType:
83 return 0xF;
84
85 // This query is only valid for certain types.
86 case kVoid_GrSLType:
87 case kBool_GrSLType:
88 case kTexture2DSampler_GrSLType:
89 case kTextureExternalSampler_GrSLType:
90 case kTexture2DRectSampler_GrSLType:
91 case kTexture2D_GrSLType:
92 case kSampler_GrSLType:
93 break;
94 }
95 SK_ABORT("Unexpected type");
96 return 0;
97}
98
99static inline uint32_t grsltype_to_size(GrSLType type) {
100 switch(type) {
101 case kByte_GrSLType:
102 case kUByte_GrSLType:
103 return 1;
104 case kByte2_GrSLType:
105 case kUByte2_GrSLType:
106 return 2;
107 case kByte3_GrSLType:
108 case kUByte3_GrSLType:
109 return 3;
110 case kByte4_GrSLType:
111 case kUByte4_GrSLType:
112 return 4;
113 case kShort_GrSLType:
114 return sizeof(int16_t);
115 case kShort2_GrSLType:
116 return 2 * sizeof(int16_t);
117 case kShort3_GrSLType:
118 return 3 * sizeof(int16_t);
119 case kShort4_GrSLType:
120 return 4 * sizeof(int16_t);
121 case kUShort_GrSLType:
122 return sizeof(uint16_t);
123 case kUShort2_GrSLType:
124 return 2 * sizeof(uint16_t);
125 case kUShort3_GrSLType:
126 return 3 * sizeof(uint16_t);
127 case kUShort4_GrSLType:
128 return 4 * sizeof(uint16_t);
129 case kInt_GrSLType:
130 return sizeof(int32_t);
131 case kUint_GrSLType:
132 return sizeof(int32_t);
133 case kHalf_GrSLType: // fall through
134 case kFloat_GrSLType:
135 return sizeof(float);
136 case kHalf2_GrSLType: // fall through
137 case kFloat2_GrSLType:
138 return 2 * sizeof(float);
139 case kHalf3_GrSLType: // fall through
140 case kFloat3_GrSLType:
141 return 3 * sizeof(float);
142 case kHalf4_GrSLType: // fall through
143 case kFloat4_GrSLType:
144 return 4 * sizeof(float);
145 case kUint2_GrSLType:
146 return 2 * sizeof(uint32_t);
147 case kInt2_GrSLType:
148 return 2 * sizeof(int32_t);
149 case kInt3_GrSLType:
150 return 3 * sizeof(int32_t);
151 case kInt4_GrSLType:
152 return 4 * sizeof(int32_t);
153 case kHalf2x2_GrSLType: // fall through
154 case kFloat2x2_GrSLType:
155 //TODO: this will be 4 * szof(float) on std430.
156 return 8 * sizeof(float);
157 case kHalf3x3_GrSLType: // fall through
158 case kFloat3x3_GrSLType:
159 return 12 * sizeof(float);
160 case kHalf4x4_GrSLType: // fall through
161 case kFloat4x4_GrSLType:
162 return 16 * sizeof(float);
163
164 // This query is only valid for certain types.
165 case kVoid_GrSLType:
166 case kBool_GrSLType:
167 case kTexture2DSampler_GrSLType:
168 case kTextureExternalSampler_GrSLType:
169 case kTexture2DRectSampler_GrSLType:
170 case kTexture2D_GrSLType:
171 case kSampler_GrSLType:
172 break;
173 }
174 SK_ABORT("Unexpected type");
175 return 0;
176}
177
178uint32_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
204GrGLSLUniformHandler::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
236GrGLSLUniformHandler::SamplerHandle GrDawnUniformHandler::addSampler(const GrTexture* texture,
237 const GrSamplerState&,
238 const GrSwizzle& swizzle,
239 const char* name,
240 const GrShaderCaps* caps) {
241 SkASSERT(!"unimplemented");
242 SkASSERT(name && strlen(name));
243
244 return GrGLSLUniformHandler::SamplerHandle(0);
245}
246
247const char* GrDawnUniformHandler::samplerVariable(
248 GrGLSLUniformHandler::SamplerHandle handle) const {
249 SkASSERT(!"unimplemented");
250 return "";
251}
252
253GrSwizzle GrDawnUniformHandler::samplerSwizzle(GrGLSLUniformHandler::SamplerHandle handle) const {
254 SkASSERT(!"unimplemented");
255 return GrSwizzle();
256}
257
258void GrDawnUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString* out) const {
259 SkString uniformsString;
260 for (int i = 0; i < fUniforms.count(); ++i) {
261 if (fUniforms[i].fVisibility & visibility) {
262 fUniforms[i].fVar.appendDecl(fProgramBuilder->shaderCaps(), &uniformsString);
263 uniformsString.append(";\n");
264 }
265 }
266 if (!uniformsString.isEmpty()) {
267 uint32_t uniformBinding;
268 const char* stage;
269 if (kVertex_GrShaderFlag == visibility) {
270 uniformBinding = kGeometryBinding;
271 stage = "vertex";
272 } else if (kGeometry_GrShaderFlag == visibility) {
273 uniformBinding = kGeometryBinding;
274 stage = "geometry";
275 } else {
276 SkASSERT(kFragment_GrShaderFlag == visibility);
277 uniformBinding = kFragBinding;
278 stage = "fragment";
279 }
280 out->appendf("layout (set = %d, binding = %d) uniform %sUniformBuffer\n{\n",
281 kUniformBufferBindGroup, uniformBinding, stage);
282 out->appendf("%s\n};\n", uniformsString.c_str());
283 }
284}