blob: 14fe5ed15b5870667b0ef8e85df98538b4cf2ac5 [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)
Stephen White170d9902019-08-15 16:48:24 -040014 , fSamplers(kUniformsPerBlock)
15 , fTextures(kUniformsPerBlock)
Stephen White4da34bf2019-07-30 10:37:47 -040016{
17}
18
19const GrShaderVar& GrDawnUniformHandler::getUniformVariable(UniformHandle u) const {
Michael Ludwig45191342020-03-24 12:29:39 -040020 return fUniforms.item(u.toIndex()).fVar;
Stephen White4da34bf2019-07-30 10:37:47 -040021}
22
23const char* GrDawnUniformHandler::getUniformCStr(UniformHandle u) const {
Michael Ludwig45191342020-03-24 12:29:39 -040024 return fUniforms.item(u.toIndex()).fVar.getName().c_str();
Stephen White4da34bf2019-07-30 10:37:47 -040025}
26
27// FIXME: this code was ripped from GrVkUniformHandler; should be refactored.
28namespace {
29
30uint32_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");
Stephen White4da34bf2019-07-30 10:37:47 -040098}
99
100static 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");
Stephen White4da34bf2019-07-30 10:37:47 -0400176}
177
Stephen White40c47e12019-11-01 13:13:03 -0400178uint32_t get_ubo_offset(uint32_t* currentOffset, GrSLType type, int arrayCount) {
Stephen White4da34bf2019-07-30 10:37:47 -0400179 uint32_t alignmentMask = grsltype_to_alignment_mask(type);
180 // We want to use the std140 layout here, so we must make arrays align to 16 bytes.
181 if (arrayCount || type == kFloat2x2_GrSLType) {
182 alignmentMask = 0xF;
183 }
184 uint32_t offsetDiff = *currentOffset & alignmentMask;
185 if (offsetDiff != 0) {
186 offsetDiff = alignmentMask - offsetDiff + 1;
187 }
188 uint32_t uniformOffset = *currentOffset + offsetDiff;
189 SkASSERT(sizeof(float) == 4);
190 if (arrayCount) {
Brian Osman788b9162020-02-07 10:36:46 -0500191 uint32_t elementSize = std::max<uint32_t>(16, grsltype_to_size(type));
Stephen White4da34bf2019-07-30 10:37:47 -0400192 SkASSERT(0 == (elementSize & 0xF));
193 *currentOffset = uniformOffset + elementSize * arrayCount;
194 } else {
195 *currentOffset = uniformOffset + grsltype_to_size(type);
196 }
197 return uniformOffset;
198}
199
200}
201
202GrGLSLUniformHandler::UniformHandle GrDawnUniformHandler::internalAddUniformArray(
203 uint32_t visibility,
204 GrSLType type,
205 const char* name,
206 bool mangleName,
207 int arrayCount,
208 const char** outName) {
Ben Wagnerdabd98c2020-03-25 15:17:18 -0400209 SkString resolvedName;
Stephen White4da34bf2019-07-30 10:37:47 -0400210 char prefix = 'u';
211 if ('u' == name[0] || !strncmp(name, GR_NO_MANGLE_PREFIX, strlen(GR_NO_MANGLE_PREFIX))) {
212 prefix = '\0';
213 }
Ben Wagnerdabd98c2020-03-25 15:17:18 -0400214 fProgramBuilder->nameVariable(&resolvedName, prefix, name, mangleName);
215
216 int offset = get_ubo_offset(&fCurrentUBOOffset, type, arrayCount);
Stephen White4da34bf2019-07-30 10:37:47 -0400217 SkString layoutQualifier;
Ben Wagnerdabd98c2020-03-25 15:17:18 -0400218 layoutQualifier.appendf("offset = %d", offset);
219
220 UniformInfo& info = fUniforms.push_back(GrDawnUniformHandler::UniformInfo{
221 GrShaderVar{std::move(resolvedName), type, GrShaderVar::TypeModifier::None, arrayCount,
222 std::move(layoutQualifier), SkString()},
223 offset, static_cast<int>(visibility)
224 });
225
Stephen White4da34bf2019-07-30 10:37:47 -0400226 if (outName) {
Ben Wagnerdabd98c2020-03-25 15:17:18 -0400227 *outName = info.fVar.c_str();
Stephen White4da34bf2019-07-30 10:37:47 -0400228 }
229 return GrGLSLUniformHandler::UniformHandle(fUniforms.count() - 1);
230}
231
Chris Dalton1b1b0d52020-03-03 12:00:59 -0700232GrGLSLUniformHandler::SamplerHandle GrDawnUniformHandler::addSampler(const GrBackendFormat&,
Brian Salomonccb61422020-01-09 10:46:36 -0500233 GrSamplerState,
Stephen White4da34bf2019-07-30 10:37:47 -0400234 const GrSwizzle& swizzle,
235 const char* name,
236 const GrShaderCaps* caps) {
Stephen White7cb52cb2019-11-12 10:40:27 -0500237 int binding = fSamplers.count() * 2;
Ben Wagnerdabd98c2020-03-25 15:17:18 -0400238
239 SkString mangleName;
240 fProgramBuilder->nameVariable(&mangleName, 's', name, true);
Stephen White170d9902019-08-15 16:48:24 -0400241 SkString layoutQualifier;
Stephen White7cb52cb2019-11-12 10:40:27 -0500242 layoutQualifier.appendf("set = 1, binding = %d", binding);
Ben Wagnerdabd98c2020-03-25 15:17:18 -0400243 UniformInfo& info = fSamplers.push_back(GrDawnUniformHandler::UniformInfo{
244 GrShaderVar{std::move(mangleName), kSampler_GrSLType,
245 GrShaderVar::TypeModifier::Uniform, GrShaderVar::kNonArray,
246 std::move(layoutQualifier), SkString()},
247 0, kFragment_GrShaderFlag
248 });
249
Stephen White170d9902019-08-15 16:48:24 -0400250 fSamplerSwizzles.push_back(swizzle);
251 SkASSERT(fSamplerSwizzles.count() == fSamplers.count());
252
253 SkString mangleTexName;
Ben Wagnerdabd98c2020-03-25 15:17:18 -0400254 fProgramBuilder->nameVariable(&mangleTexName, 't', name, true);
Stephen White170d9902019-08-15 16:48:24 -0400255 SkString texLayoutQualifier;
Stephen White7cb52cb2019-11-12 10:40:27 -0500256 texLayoutQualifier.appendf("set = 1, binding = %d", binding + 1);
Ben Wagnerdabd98c2020-03-25 15:17:18 -0400257 UniformInfo& texInfo = fTextures.push_back(GrDawnUniformHandler::UniformInfo{
258 GrShaderVar{std::move(mangleTexName), kTexture2D_GrSLType,
259 GrShaderVar::TypeModifier::Uniform, GrShaderVar::kNonArray,
260 std::move(texLayoutQualifier), SkString()},
261 0, kFragment_GrShaderFlag
262 });
Stephen White170d9902019-08-15 16:48:24 -0400263
264 SkString reference;
265 reference.printf("makeSampler2D(%s, %s)", texInfo.fVar.getName().c_str(),
266 info.fVar.getName().c_str());
Ben Wagnerdabd98c2020-03-25 15:17:18 -0400267 fSamplerReferences.emplace_back(std::move(reference));
Stephen White170d9902019-08-15 16:48:24 -0400268 return GrGLSLUniformHandler::SamplerHandle(fSamplers.count() - 1);
Stephen White4da34bf2019-07-30 10:37:47 -0400269}
270
271const char* GrDawnUniformHandler::samplerVariable(
272 GrGLSLUniformHandler::SamplerHandle handle) const {
Stephen White170d9902019-08-15 16:48:24 -0400273 return fSamplerReferences[handle.toIndex()].c_str();
Stephen White4da34bf2019-07-30 10:37:47 -0400274}
275
276GrSwizzle GrDawnUniformHandler::samplerSwizzle(GrGLSLUniformHandler::SamplerHandle handle) const {
Stephen White170d9902019-08-15 16:48:24 -0400277 return fSamplerSwizzles[handle.toIndex()];
Stephen White4da34bf2019-07-30 10:37:47 -0400278}
279
280void GrDawnUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString* out) const {
Michael Ludwig45191342020-03-24 12:29:39 -0400281 auto textures = fTextures.items().begin();
282 for (const UniformInfo& sampler : fSamplers.items()) {
283 if (sampler.fVisibility & visibility) {
284 sampler.fVar.appendDecl(fProgramBuilder->shaderCaps(), out);
Stephen White170d9902019-08-15 16:48:24 -0400285 out->append(";\n");
Michael Ludwig45191342020-03-24 12:29:39 -0400286 (*textures).fVar.appendDecl(fProgramBuilder->shaderCaps(), out);
Stephen White170d9902019-08-15 16:48:24 -0400287 out->append(";\n");
288 }
Michael Ludwig45191342020-03-24 12:29:39 -0400289 ++textures;
Stephen White170d9902019-08-15 16:48:24 -0400290 }
Stephen White4da34bf2019-07-30 10:37:47 -0400291 SkString uniformsString;
Michael Ludwig45191342020-03-24 12:29:39 -0400292 for (const UniformInfo& uniform : fUniforms.items()) {
293 if (uniform.fVisibility & visibility) {
294 uniform.fVar.appendDecl(fProgramBuilder->shaderCaps(), &uniformsString);
Stephen White4da34bf2019-07-30 10:37:47 -0400295 uniformsString.append(";\n");
296 }
297 }
298 if (!uniformsString.isEmpty()) {
Stephen Whitedd78efd2019-10-23 15:00:20 -0400299 out->appendf("layout (set = 0, binding = %d) uniform UniformBuffer\n{\n", kUniformBinding);
Stephen White4da34bf2019-07-30 10:37:47 -0400300 out->appendf("%s\n};\n", uniformsString.c_str());
301 }
302}
Stephen White40c47e12019-11-01 13:13:03 -0400303
304uint32_t GrDawnUniformHandler::getRTHeightOffset() const {
305 uint32_t dummy = fCurrentUBOOffset;
306 return get_ubo_offset(&dummy, kFloat_GrSLType, 0);
307}