blob: 5b5a48d4badaac77fa16ae96dd4706a7d86e4283 [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
Greg Danield59a91d2020-04-23 13:22:47 -04008#include "src/gpu/GrSPIRVUniformHandler.h"
Greg Daniel690a4502020-04-21 09:19:51 -04009
Stephen White4da34bf2019-07-30 10:37:47 -040010#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
11
Greg Danield59a91d2020-04-23 13:22:47 -040012GrSPIRVUniformHandler::GrSPIRVUniformHandler(GrGLSLProgramBuilder* program)
Stephen White4da34bf2019-07-30 10:37:47 -040013 : INHERITED(program)
14 , fUniforms(kUniformsPerBlock)
Stephen White170d9902019-08-15 16:48:24 -040015 , fSamplers(kUniformsPerBlock)
16 , fTextures(kUniformsPerBlock)
Stephen White4da34bf2019-07-30 10:37:47 -040017{
18}
19
Greg Danield59a91d2020-04-23 13:22:47 -040020const GrShaderVar& GrSPIRVUniformHandler::getUniformVariable(UniformHandle u) const {
Ethan Nicholas16464c32020-04-06 13:53:05 -040021 return fUniforms.item(u.toIndex()).fVariable;
Stephen White4da34bf2019-07-30 10:37:47 -040022}
23
Greg Danield59a91d2020-04-23 13:22:47 -040024const char* GrSPIRVUniformHandler::getUniformCStr(UniformHandle u) const {
Ethan Nicholas16464c32020-04-06 13:53:05 -040025 return fUniforms.item(u.toIndex()).fVariable.getName().c_str();
Stephen White4da34bf2019-07-30 10:37:47 -040026}
27
28// FIXME: this code was ripped from GrVkUniformHandler; should be refactored.
29namespace {
30
31uint32_t grsltype_to_alignment_mask(GrSLType type) {
32 switch(type) {
33 case kByte_GrSLType: // fall through
34 case kUByte_GrSLType:
35 return 0x0;
36 case kByte2_GrSLType: // fall through
37 case kUByte2_GrSLType:
38 return 0x1;
39 case kByte3_GrSLType: // fall through
40 case kByte4_GrSLType:
41 case kUByte3_GrSLType:
42 case kUByte4_GrSLType:
43 return 0x3;
44 case kShort_GrSLType: // fall through
45 case kUShort_GrSLType:
46 return 0x1;
47 case kShort2_GrSLType: // fall through
48 case kUShort2_GrSLType:
49 return 0x3;
50 case kShort3_GrSLType: // fall through
51 case kShort4_GrSLType:
52 case kUShort3_GrSLType:
53 case kUShort4_GrSLType:
54 return 0x7;
55 case kInt_GrSLType:
56 case kUint_GrSLType:
57 return 0x3;
58 case kHalf_GrSLType: // fall through
59 case kFloat_GrSLType:
60 return 0x3;
61 case kHalf2_GrSLType: // fall through
62 case kFloat2_GrSLType:
63 return 0x7;
64 case kHalf3_GrSLType: // fall through
65 case kFloat3_GrSLType:
66 return 0xF;
67 case kHalf4_GrSLType: // fall through
68 case kFloat4_GrSLType:
69 return 0xF;
70 case kUint2_GrSLType:
71 return 0x7;
72 case kInt2_GrSLType:
73 return 0x7;
74 case kInt3_GrSLType:
75 return 0xF;
76 case kInt4_GrSLType:
77 return 0xF;
78 case kHalf2x2_GrSLType: // fall through
79 case kFloat2x2_GrSLType:
80 return 0x7;
81 case kHalf3x3_GrSLType: // fall through
82 case kFloat3x3_GrSLType:
83 return 0xF;
84 case kHalf4x4_GrSLType: // fall through
85 case kFloat4x4_GrSLType:
86 return 0xF;
87
88 // This query is only valid for certain types.
89 case kVoid_GrSLType:
90 case kBool_GrSLType:
91 case kTexture2DSampler_GrSLType:
92 case kTextureExternalSampler_GrSLType:
93 case kTexture2DRectSampler_GrSLType:
94 case kTexture2D_GrSLType:
95 case kSampler_GrSLType:
Greg Daniel37fd6582020-09-14 12:36:09 -040096 case kInput_GrSLType:
Stephen White4da34bf2019-07-30 10:37:47 -040097 break;
98 }
99 SK_ABORT("Unexpected type");
Stephen White4da34bf2019-07-30 10:37:47 -0400100}
101
102static inline uint32_t grsltype_to_size(GrSLType type) {
103 switch(type) {
104 case kByte_GrSLType:
105 case kUByte_GrSLType:
106 return 1;
107 case kByte2_GrSLType:
108 case kUByte2_GrSLType:
109 return 2;
110 case kByte3_GrSLType:
111 case kUByte3_GrSLType:
112 return 3;
113 case kByte4_GrSLType:
114 case kUByte4_GrSLType:
115 return 4;
116 case kShort_GrSLType:
117 return sizeof(int16_t);
118 case kShort2_GrSLType:
119 return 2 * sizeof(int16_t);
120 case kShort3_GrSLType:
121 return 3 * sizeof(int16_t);
122 case kShort4_GrSLType:
123 return 4 * sizeof(int16_t);
124 case kUShort_GrSLType:
125 return sizeof(uint16_t);
126 case kUShort2_GrSLType:
127 return 2 * sizeof(uint16_t);
128 case kUShort3_GrSLType:
129 return 3 * sizeof(uint16_t);
130 case kUShort4_GrSLType:
131 return 4 * sizeof(uint16_t);
132 case kInt_GrSLType:
133 return sizeof(int32_t);
134 case kUint_GrSLType:
135 return sizeof(int32_t);
136 case kHalf_GrSLType: // fall through
137 case kFloat_GrSLType:
138 return sizeof(float);
139 case kHalf2_GrSLType: // fall through
140 case kFloat2_GrSLType:
141 return 2 * sizeof(float);
142 case kHalf3_GrSLType: // fall through
143 case kFloat3_GrSLType:
144 return 3 * sizeof(float);
145 case kHalf4_GrSLType: // fall through
146 case kFloat4_GrSLType:
147 return 4 * sizeof(float);
148 case kUint2_GrSLType:
149 return 2 * sizeof(uint32_t);
150 case kInt2_GrSLType:
151 return 2 * sizeof(int32_t);
152 case kInt3_GrSLType:
153 return 3 * sizeof(int32_t);
154 case kInt4_GrSLType:
155 return 4 * sizeof(int32_t);
156 case kHalf2x2_GrSLType: // fall through
157 case kFloat2x2_GrSLType:
158 //TODO: this will be 4 * szof(float) on std430.
159 return 8 * sizeof(float);
160 case kHalf3x3_GrSLType: // fall through
161 case kFloat3x3_GrSLType:
162 return 12 * sizeof(float);
163 case kHalf4x4_GrSLType: // fall through
164 case kFloat4x4_GrSLType:
165 return 16 * sizeof(float);
166
167 // This query is only valid for certain types.
168 case kVoid_GrSLType:
169 case kBool_GrSLType:
170 case kTexture2DSampler_GrSLType:
171 case kTextureExternalSampler_GrSLType:
172 case kTexture2DRectSampler_GrSLType:
173 case kTexture2D_GrSLType:
174 case kSampler_GrSLType:
Greg Daniel37fd6582020-09-14 12:36:09 -0400175 case kInput_GrSLType:
Stephen White4da34bf2019-07-30 10:37:47 -0400176 break;
177 }
178 SK_ABORT("Unexpected type");
Stephen White4da34bf2019-07-30 10:37:47 -0400179}
180
Stephen White40c47e12019-11-01 13:13:03 -0400181uint32_t get_ubo_offset(uint32_t* currentOffset, GrSLType type, int arrayCount) {
Stephen White4da34bf2019-07-30 10:37:47 -0400182 uint32_t alignmentMask = grsltype_to_alignment_mask(type);
183 // We want to use the std140 layout here, so we must make arrays align to 16 bytes.
184 if (arrayCount || type == kFloat2x2_GrSLType) {
185 alignmentMask = 0xF;
186 }
187 uint32_t offsetDiff = *currentOffset & alignmentMask;
188 if (offsetDiff != 0) {
189 offsetDiff = alignmentMask - offsetDiff + 1;
190 }
191 uint32_t uniformOffset = *currentOffset + offsetDiff;
192 SkASSERT(sizeof(float) == 4);
193 if (arrayCount) {
Brian Osman788b9162020-02-07 10:36:46 -0500194 uint32_t elementSize = std::max<uint32_t>(16, grsltype_to_size(type));
Stephen White4da34bf2019-07-30 10:37:47 -0400195 SkASSERT(0 == (elementSize & 0xF));
196 *currentOffset = uniformOffset + elementSize * arrayCount;
197 } else {
198 *currentOffset = uniformOffset + grsltype_to_size(type);
199 }
200 return uniformOffset;
201}
202
John Stilesa6841be2020-08-06 14:11:56 -0400203} // namespace
Stephen White4da34bf2019-07-30 10:37:47 -0400204
Greg Danield59a91d2020-04-23 13:22:47 -0400205GrGLSLUniformHandler::UniformHandle GrSPIRVUniformHandler::internalAddUniformArray(
Ethan Nicholas16464c32020-04-06 13:53:05 -0400206 const GrFragmentProcessor* owner,
Stephen White4da34bf2019-07-30 10:37:47 -0400207 uint32_t visibility,
208 GrSLType type,
209 const char* name,
210 bool mangleName,
211 int arrayCount,
212 const char** outName) {
Ben Wagnerdabd98c2020-03-25 15:17:18 -0400213 SkString resolvedName;
Stephen White4da34bf2019-07-30 10:37:47 -0400214 char prefix = 'u';
215 if ('u' == name[0] || !strncmp(name, GR_NO_MANGLE_PREFIX, strlen(GR_NO_MANGLE_PREFIX))) {
216 prefix = '\0';
217 }
Ben Wagnerdabd98c2020-03-25 15:17:18 -0400218 fProgramBuilder->nameVariable(&resolvedName, prefix, name, mangleName);
219
220 int offset = get_ubo_offset(&fCurrentUBOOffset, type, arrayCount);
Stephen White4da34bf2019-07-30 10:37:47 -0400221 SkString layoutQualifier;
Ben Wagnerdabd98c2020-03-25 15:17:18 -0400222 layoutQualifier.appendf("offset = %d", offset);
223
Greg Danield59a91d2020-04-23 13:22:47 -0400224 UniformInfo& info = fUniforms.push_back(SPIRVUniformInfo{
Ethan Nicholas16464c32020-04-06 13:53:05 -0400225 {
226 GrShaderVar{std::move(resolvedName), type, GrShaderVar::TypeModifier::None, arrayCount,
227 std::move(layoutQualifier), SkString()},
228 visibility, owner, SkString(name)
229 },
230 offset
Ben Wagnerdabd98c2020-03-25 15:17:18 -0400231 });
232
Stephen White4da34bf2019-07-30 10:37:47 -0400233 if (outName) {
Ethan Nicholas16464c32020-04-06 13:53:05 -0400234 *outName = info.fVariable.c_str();
Stephen White4da34bf2019-07-30 10:37:47 -0400235 }
236 return GrGLSLUniformHandler::UniformHandle(fUniforms.count() - 1);
237}
238
Greg Danield59a91d2020-04-23 13:22:47 -0400239GrGLSLUniformHandler::SamplerHandle GrSPIRVUniformHandler::addSampler(const GrBackendFormat&,
Brian Salomonccb61422020-01-09 10:46:36 -0500240 GrSamplerState,
Stephen White4da34bf2019-07-30 10:37:47 -0400241 const GrSwizzle& swizzle,
242 const char* name,
243 const GrShaderCaps* caps) {
Stephen White7cb52cb2019-11-12 10:40:27 -0500244 int binding = fSamplers.count() * 2;
Ben Wagnerdabd98c2020-03-25 15:17:18 -0400245
246 SkString mangleName;
247 fProgramBuilder->nameVariable(&mangleName, 's', name, true);
Stephen White170d9902019-08-15 16:48:24 -0400248 SkString layoutQualifier;
Greg Daniel690a4502020-04-21 09:19:51 -0400249 layoutQualifier.appendf("set = %d, binding = %d", kSamplerTextureDescriptorSet, binding);
Greg Danield59a91d2020-04-23 13:22:47 -0400250 SPIRVUniformInfo& info = fSamplers.push_back(SPIRVUniformInfo{
Ethan Nicholas16464c32020-04-06 13:53:05 -0400251 {
252 GrShaderVar{std::move(mangleName), kSampler_GrSLType,
253 GrShaderVar::TypeModifier::Uniform, GrShaderVar::kNonArray,
254 std::move(layoutQualifier), SkString()},
255 kFragment_GrShaderFlag, nullptr, SkString(name)
256 },
257 0
Ben Wagnerdabd98c2020-03-25 15:17:18 -0400258 });
259
Stephen White170d9902019-08-15 16:48:24 -0400260 fSamplerSwizzles.push_back(swizzle);
261 SkASSERT(fSamplerSwizzles.count() == fSamplers.count());
262
263 SkString mangleTexName;
Ben Wagnerdabd98c2020-03-25 15:17:18 -0400264 fProgramBuilder->nameVariable(&mangleTexName, 't', name, true);
Stephen White170d9902019-08-15 16:48:24 -0400265 SkString texLayoutQualifier;
Greg Daniel690a4502020-04-21 09:19:51 -0400266 texLayoutQualifier.appendf("set = %d, binding = %d", kSamplerTextureDescriptorSet, binding + 1);
Greg Danield59a91d2020-04-23 13:22:47 -0400267 UniformInfo& texInfo = fTextures.push_back(SPIRVUniformInfo{
Ethan Nicholas16464c32020-04-06 13:53:05 -0400268 {
269 GrShaderVar{std::move(mangleTexName), kTexture2D_GrSLType,
270 GrShaderVar::TypeModifier::Uniform, GrShaderVar::kNonArray,
271 std::move(texLayoutQualifier), SkString()},
272 kFragment_GrShaderFlag, nullptr, SkString(name)
273 },
274 0
Ben Wagnerdabd98c2020-03-25 15:17:18 -0400275 });
Stephen White170d9902019-08-15 16:48:24 -0400276
277 SkString reference;
Ethan Nicholas16464c32020-04-06 13:53:05 -0400278 reference.printf("makeSampler2D(%s, %s)", texInfo.fVariable.getName().c_str(),
279 info.fVariable.getName().c_str());
Ben Wagnerdabd98c2020-03-25 15:17:18 -0400280 fSamplerReferences.emplace_back(std::move(reference));
Stephen White170d9902019-08-15 16:48:24 -0400281 return GrGLSLUniformHandler::SamplerHandle(fSamplers.count() - 1);
Stephen White4da34bf2019-07-30 10:37:47 -0400282}
283
Greg Danield59a91d2020-04-23 13:22:47 -0400284const char* GrSPIRVUniformHandler::samplerVariable(
Stephen White4da34bf2019-07-30 10:37:47 -0400285 GrGLSLUniformHandler::SamplerHandle handle) const {
Stephen White170d9902019-08-15 16:48:24 -0400286 return fSamplerReferences[handle.toIndex()].c_str();
Stephen White4da34bf2019-07-30 10:37:47 -0400287}
288
Greg Danield59a91d2020-04-23 13:22:47 -0400289GrSwizzle GrSPIRVUniformHandler::samplerSwizzle(GrGLSLUniformHandler::SamplerHandle handle) const {
Stephen White170d9902019-08-15 16:48:24 -0400290 return fSamplerSwizzles[handle.toIndex()];
Stephen White4da34bf2019-07-30 10:37:47 -0400291}
292
Greg Danield59a91d2020-04-23 13:22:47 -0400293void GrSPIRVUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString* out) const {
Michael Ludwig45191342020-03-24 12:29:39 -0400294 auto textures = fTextures.items().begin();
Greg Danield59a91d2020-04-23 13:22:47 -0400295 for (const SPIRVUniformInfo& sampler : fSamplers.items()) {
Michael Ludwig45191342020-03-24 12:29:39 -0400296 if (sampler.fVisibility & visibility) {
Ethan Nicholas16464c32020-04-06 13:53:05 -0400297 sampler.fVariable.appendDecl(fProgramBuilder->shaderCaps(), out);
Stephen White170d9902019-08-15 16:48:24 -0400298 out->append(";\n");
Ethan Nicholas16464c32020-04-06 13:53:05 -0400299 (*textures).fVariable.appendDecl(fProgramBuilder->shaderCaps(), out);
Stephen White170d9902019-08-15 16:48:24 -0400300 out->append(";\n");
301 }
Michael Ludwig45191342020-03-24 12:29:39 -0400302 ++textures;
Stephen White170d9902019-08-15 16:48:24 -0400303 }
Stephen White4da34bf2019-07-30 10:37:47 -0400304 SkString uniformsString;
Michael Ludwig45191342020-03-24 12:29:39 -0400305 for (const UniformInfo& uniform : fUniforms.items()) {
306 if (uniform.fVisibility & visibility) {
Ethan Nicholas16464c32020-04-06 13:53:05 -0400307 uniform.fVariable.appendDecl(fProgramBuilder->shaderCaps(), &uniformsString);
Stephen White4da34bf2019-07-30 10:37:47 -0400308 uniformsString.append(";\n");
309 }
310 }
311 if (!uniformsString.isEmpty()) {
Greg Daniel690a4502020-04-21 09:19:51 -0400312 out->appendf("layout (set = %d, binding = %d) uniform UniformBuffer\n{\n",
313 kUniformDescriptorSet, kUniformBinding);
Stephen White4da34bf2019-07-30 10:37:47 -0400314 out->appendf("%s\n};\n", uniformsString.c_str());
315 }
316}
Stephen White40c47e12019-11-01 13:13:03 -0400317
Greg Danield59a91d2020-04-23 13:22:47 -0400318uint32_t GrSPIRVUniformHandler::getRTHeightOffset() const {
Stephen White40c47e12019-11-01 13:13:03 -0400319 uint32_t dummy = fCurrentUBOOffset;
320 return get_ubo_offset(&dummy, kFloat_GrSLType, 0);
321}