1 /*
2 * Copyright 2016 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 "GrVkPipelineStateDataManager.h"
9
10 #include "GrVkGpu.h"
11 #include "GrVkUniformBuffer.h"
12
GrVkPipelineStateDataManager(const UniformInfoArray & uniforms,uint32_t geometryUniformSize,uint32_t fragmentUniformSize)13 GrVkPipelineStateDataManager::GrVkPipelineStateDataManager(const UniformInfoArray& uniforms,
14 uint32_t geometryUniformSize,
15 uint32_t fragmentUniformSize)
16 : fGeometryUniformSize(geometryUniformSize)
17 , fFragmentUniformSize(fragmentUniformSize)
18 , fGeometryUniformsDirty(false)
19 , fFragmentUniformsDirty(false) {
20 fGeometryUniformData.reset(geometryUniformSize);
21 fFragmentUniformData.reset(fragmentUniformSize);
22 int count = uniforms.count();
23 fUniforms.push_back_n(count);
24 // We must add uniforms in same order is the UniformInfoArray so that UniformHandles already
25 // owned by other objects will still match up here.
26 for (int i = 0; i < count; i++) {
27 Uniform& uniform = fUniforms[i];
28 const GrVkUniformHandler::UniformInfo uniformInfo = uniforms[i];
29 SkASSERT(GrShaderVar::kNonArray == uniformInfo.fVariable.getArrayCount() ||
30 uniformInfo.fVariable.getArrayCount() > 0);
31 SkDEBUGCODE(
32 uniform.fArrayCount = uniformInfo.fVariable.getArrayCount();
33 uniform.fType = uniformInfo.fVariable.getType();
34 )
35
36 if (!(kFragment_GrShaderFlag & uniformInfo.fVisibility)) {
37 uniform.fBinding = GrVkUniformHandler::kGeometryBinding;
38 } else {
39 SkASSERT(kFragment_GrShaderFlag == uniformInfo.fVisibility);
40 uniform.fBinding = GrVkUniformHandler::kFragBinding;
41 }
42 uniform.fOffset = uniformInfo.fUBOffset;
43 }
44 }
45
getBufferPtrAndMarkDirty(const Uniform & uni) const46 void* GrVkPipelineStateDataManager::getBufferPtrAndMarkDirty(const Uniform& uni) const {
47 void* buffer;
48 if (GrVkUniformHandler::kGeometryBinding == uni.fBinding) {
49 buffer = fGeometryUniformData.get();
50 fGeometryUniformsDirty = true;
51 } else {
52 SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
53 buffer = fFragmentUniformData.get();
54 fFragmentUniformsDirty = true;
55 }
56 buffer = static_cast<char*>(buffer)+uni.fOffset;
57 return buffer;
58 }
59
set1i(UniformHandle u,int32_t i) const60 void GrVkPipelineStateDataManager::set1i(UniformHandle u, int32_t i) const {
61 const Uniform& uni = fUniforms[u.toIndex()];
62 SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType);
63 SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
64 void* buffer = this->getBufferPtrAndMarkDirty(uni);
65 memcpy(buffer, &i, sizeof(int32_t));
66 }
67
set1iv(UniformHandle u,int arrayCount,const int32_t v[]) const68 void GrVkPipelineStateDataManager::set1iv(UniformHandle u,
69 int arrayCount,
70 const int32_t v[]) const {
71 const Uniform& uni = fUniforms[u.toIndex()];
72 SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType);
73 SkASSERT(arrayCount > 0);
74 SkASSERT(arrayCount <= uni.fArrayCount ||
75 (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
76
77 void* buffer = this->getBufferPtrAndMarkDirty(uni);
78 SkASSERT(sizeof(int32_t) == 4);
79 for (int i = 0; i < arrayCount; ++i) {
80 const int32_t* curVec = &v[i];
81 memcpy(buffer, curVec, sizeof(int32_t));
82 buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
83 }
84 }
85
set1f(UniformHandle u,float v0) const86 void GrVkPipelineStateDataManager::set1f(UniformHandle u, float v0) const {
87 const Uniform& uni = fUniforms[u.toIndex()];
88 SkASSERT(uni.fType == kFloat_GrSLType || uni.fType == kHalf_GrSLType);
89 SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
90 void* buffer = this->getBufferPtrAndMarkDirty(uni);
91 SkASSERT(sizeof(float) == 4);
92 memcpy(buffer, &v0, sizeof(float));
93 }
94
set1fv(UniformHandle u,int arrayCount,const float v[]) const95 void GrVkPipelineStateDataManager::set1fv(UniformHandle u,
96 int arrayCount,
97 const float v[]) const {
98 const Uniform& uni = fUniforms[u.toIndex()];
99 SkASSERT(uni.fType == kFloat_GrSLType || uni.fType == kHalf_GrSLType);
100 SkASSERT(arrayCount > 0);
101 SkASSERT(arrayCount <= uni.fArrayCount ||
102 (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
103
104 void* buffer = this->getBufferPtrAndMarkDirty(uni);
105 SkASSERT(sizeof(float) == 4);
106 for (int i = 0; i < arrayCount; ++i) {
107 const float* curVec = &v[i];
108 memcpy(buffer, curVec, sizeof(float));
109 buffer = static_cast<char*>(buffer) + 4*sizeof(float);
110 }
111 }
112
set2i(UniformHandle u,int32_t i0,int32_t i1) const113 void GrVkPipelineStateDataManager::set2i(UniformHandle u, int32_t i0, int32_t i1) const {
114 const Uniform& uni = fUniforms[u.toIndex()];
115 SkASSERT(uni.fType == kInt2_GrSLType || uni.fType == kShort2_GrSLType);
116 SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
117 void* buffer = this->getBufferPtrAndMarkDirty(uni);
118 int32_t v[2] = { i0, i1 };
119 memcpy(buffer, v, 2 * sizeof(int32_t));
120 }
121
set2iv(UniformHandle u,int arrayCount,const int32_t v[]) const122 void GrVkPipelineStateDataManager::set2iv(UniformHandle u,
123 int arrayCount,
124 const int32_t v[]) const {
125 const Uniform& uni = fUniforms[u.toIndex()];
126 SkASSERT(uni.fType == kInt2_GrSLType || uni.fType == kShort2_GrSLType);
127 SkASSERT(arrayCount > 0);
128 SkASSERT(arrayCount <= uni.fArrayCount ||
129 (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
130
131 void* buffer = this->getBufferPtrAndMarkDirty(uni);
132 SkASSERT(sizeof(int32_t) == 4);
133 for (int i = 0; i < arrayCount; ++i) {
134 const int32_t* curVec = &v[2 * i];
135 memcpy(buffer, curVec, 2 * sizeof(int32_t));
136 buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
137 }
138 }
139
set2f(UniformHandle u,float v0,float v1) const140 void GrVkPipelineStateDataManager::set2f(UniformHandle u, float v0, float v1) const {
141 const Uniform& uni = fUniforms[u.toIndex()];
142 SkASSERT(uni.fType == kFloat2_GrSLType || uni.fType == kHalf2_GrSLType);
143 SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
144 void* buffer = this->getBufferPtrAndMarkDirty(uni);
145 SkASSERT(sizeof(float) == 4);
146 float v[2] = { v0, v1 };
147 memcpy(buffer, v, 2 * sizeof(float));
148 }
149
set2fv(UniformHandle u,int arrayCount,const float v[]) const150 void GrVkPipelineStateDataManager::set2fv(UniformHandle u,
151 int arrayCount,
152 const float v[]) const {
153 const Uniform& uni = fUniforms[u.toIndex()];
154 SkASSERT(uni.fType == kFloat2_GrSLType || uni.fType == kHalf2_GrSLType);
155 SkASSERT(arrayCount > 0);
156 SkASSERT(arrayCount <= uni.fArrayCount ||
157 (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
158
159 void* buffer = this->getBufferPtrAndMarkDirty(uni);
160 SkASSERT(sizeof(float) == 4);
161 for (int i = 0; i < arrayCount; ++i) {
162 const float* curVec = &v[2 * i];
163 memcpy(buffer, curVec, 2 * sizeof(float));
164 buffer = static_cast<char*>(buffer) + 4*sizeof(float);
165 }
166 }
167
set3i(UniformHandle u,int32_t i0,int32_t i1,int32_t i2) const168 void GrVkPipelineStateDataManager::set3i(UniformHandle u,
169 int32_t i0,
170 int32_t i1,
171 int32_t i2) const {
172 const Uniform& uni = fUniforms[u.toIndex()];
173 SkASSERT(uni.fType == kInt3_GrSLType || uni.fType == kShort3_GrSLType);
174 SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
175 void* buffer = this->getBufferPtrAndMarkDirty(uni);
176 int32_t v[3] = { i0, i1, i2 };
177 memcpy(buffer, v, 3 * sizeof(int32_t));
178 }
179
set3iv(UniformHandle u,int arrayCount,const int32_t v[]) const180 void GrVkPipelineStateDataManager::set3iv(UniformHandle u,
181 int arrayCount,
182 const int32_t v[]) const {
183 const Uniform& uni = fUniforms[u.toIndex()];
184 SkASSERT(uni.fType == kInt3_GrSLType || uni.fType == kShort3_GrSLType);
185 SkASSERT(arrayCount > 0);
186 SkASSERT(arrayCount <= uni.fArrayCount ||
187 (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
188
189 void* buffer = this->getBufferPtrAndMarkDirty(uni);
190 SkASSERT(sizeof(int32_t) == 4);
191 for (int i = 0; i < arrayCount; ++i) {
192 const int32_t* curVec = &v[3 * i];
193 memcpy(buffer, curVec, 3 * sizeof(int32_t));
194 buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
195 }
196 }
197
set3f(UniformHandle u,float v0,float v1,float v2) const198 void GrVkPipelineStateDataManager::set3f(UniformHandle u, float v0, float v1, float v2) const {
199 const Uniform& uni = fUniforms[u.toIndex()];
200 SkASSERT(uni.fType == kFloat3_GrSLType || uni.fType == kHalf3_GrSLType);
201 SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
202 void* buffer = this->getBufferPtrAndMarkDirty(uni);
203 SkASSERT(sizeof(float) == 4);
204 float v[3] = { v0, v1, v2 };
205 memcpy(buffer, v, 3 * sizeof(float));
206 }
207
set3fv(UniformHandle u,int arrayCount,const float v[]) const208 void GrVkPipelineStateDataManager::set3fv(UniformHandle u,
209 int arrayCount,
210 const float v[]) const {
211 const Uniform& uni = fUniforms[u.toIndex()];
212 SkASSERT(uni.fType == kFloat3_GrSLType || uni.fType == kHalf3_GrSLType);
213 SkASSERT(arrayCount > 0);
214 SkASSERT(arrayCount <= uni.fArrayCount ||
215 (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
216
217 void* buffer = this->getBufferPtrAndMarkDirty(uni);
218 SkASSERT(sizeof(float) == 4);
219 for (int i = 0; i < arrayCount; ++i) {
220 const float* curVec = &v[3 * i];
221 memcpy(buffer, curVec, 3 * sizeof(float));
222 buffer = static_cast<char*>(buffer) + 4*sizeof(float);
223 }
224 }
225
set4i(UniformHandle u,int32_t i0,int32_t i1,int32_t i2,int32_t i3) const226 void GrVkPipelineStateDataManager::set4i(UniformHandle u,
227 int32_t i0,
228 int32_t i1,
229 int32_t i2,
230 int32_t i3) const {
231 const Uniform& uni = fUniforms[u.toIndex()];
232 SkASSERT(uni.fType == kInt4_GrSLType || uni.fType == kShort4_GrSLType);
233 SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
234 void* buffer = this->getBufferPtrAndMarkDirty(uni);
235 int32_t v[4] = { i0, i1, i2, i3 };
236 memcpy(buffer, v, 4 * sizeof(int32_t));
237 }
238
set4iv(UniformHandle u,int arrayCount,const int32_t v[]) const239 void GrVkPipelineStateDataManager::set4iv(UniformHandle u,
240 int arrayCount,
241 const int32_t v[]) const {
242 const Uniform& uni = fUniforms[u.toIndex()];
243 SkASSERT(uni.fType == kInt4_GrSLType || uni.fType == kShort4_GrSLType);
244 SkASSERT(arrayCount > 0);
245 SkASSERT(arrayCount <= uni.fArrayCount ||
246 (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
247
248 void* buffer = this->getBufferPtrAndMarkDirty(uni);
249 SkASSERT(sizeof(int32_t) == 4);
250 for (int i = 0; i < arrayCount; ++i) {
251 const int32_t* curVec = &v[4 * i];
252 memcpy(buffer, curVec, 4 * sizeof(int32_t));
253 buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
254 }
255 }
256
set4f(UniformHandle u,float v0,float v1,float v2,float v3) const257 void GrVkPipelineStateDataManager::set4f(UniformHandle u,
258 float v0,
259 float v1,
260 float v2,
261 float v3) const {
262 const Uniform& uni = fUniforms[u.toIndex()];
263 SkASSERT(uni.fType == kFloat4_GrSLType || uni.fType == kHalf4_GrSLType);
264 SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
265 void* buffer = this->getBufferPtrAndMarkDirty(uni);
266 SkASSERT(sizeof(float) == 4);
267 float v[4] = { v0, v1, v2, v3 };
268 memcpy(buffer, v, 4 * sizeof(float));
269 }
270
set4fv(UniformHandle u,int arrayCount,const float v[]) const271 void GrVkPipelineStateDataManager::set4fv(UniformHandle u,
272 int arrayCount,
273 const float v[]) const {
274 const Uniform& uni = fUniforms[u.toIndex()];
275 SkASSERT(uni.fType == kFloat4_GrSLType || uni.fType == kHalf4_GrSLType);
276 SkASSERT(arrayCount > 0);
277 SkASSERT(arrayCount <= uni.fArrayCount ||
278 (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
279
280 void* buffer = this->getBufferPtrAndMarkDirty(uni);
281 SkASSERT(sizeof(float) == 4);
282 memcpy(buffer, v, arrayCount * 4 * sizeof(float));
283 }
284
setMatrix2f(UniformHandle u,const float matrix[]) const285 void GrVkPipelineStateDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const {
286 this->setMatrices<2>(u, 1, matrix);
287 }
288
setMatrix2fv(UniformHandle u,int arrayCount,const float m[]) const289 void GrVkPipelineStateDataManager::setMatrix2fv(UniformHandle u,
290 int arrayCount,
291 const float m[]) const {
292 this->setMatrices<2>(u, arrayCount, m);
293 }
294
setMatrix3f(UniformHandle u,const float matrix[]) const295 void GrVkPipelineStateDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const {
296 this->setMatrices<3>(u, 1, matrix);
297 }
298
setMatrix3fv(UniformHandle u,int arrayCount,const float m[]) const299 void GrVkPipelineStateDataManager::setMatrix3fv(UniformHandle u,
300 int arrayCount,
301 const float m[]) const {
302 this->setMatrices<3>(u, arrayCount, m);
303 }
304
setMatrix4f(UniformHandle u,const float matrix[]) const305 void GrVkPipelineStateDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const {
306 this->setMatrices<4>(u, 1, matrix);
307 }
308
setMatrix4fv(UniformHandle u,int arrayCount,const float m[]) const309 void GrVkPipelineStateDataManager::setMatrix4fv(UniformHandle u,
310 int arrayCount,
311 const float m[]) const {
312 this->setMatrices<4>(u, arrayCount, m);
313 }
314
315 template<int N> struct set_uniform_matrix;
316
setMatrices(UniformHandle u,int arrayCount,const float matrices[]) const317 template<int N> inline void GrVkPipelineStateDataManager::setMatrices(UniformHandle u,
318 int arrayCount,
319 const float matrices[]) const {
320 const Uniform& uni = fUniforms[u.toIndex()];
321 SkASSERT(uni.fType == kFloat2x2_GrSLType + (N - 2) ||
322 uni.fType == kHalf2x2_GrSLType + (N - 2));
323 SkASSERT(arrayCount > 0);
324 SkASSERT(arrayCount <= uni.fArrayCount ||
325 (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
326
327 void* buffer;
328 if (GrVkUniformHandler::kGeometryBinding == uni.fBinding) {
329 buffer = fGeometryUniformData.get();
330 fGeometryUniformsDirty = true;
331 } else {
332 SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
333 buffer = fFragmentUniformData.get();
334 fFragmentUniformsDirty = true;
335 }
336
337 set_uniform_matrix<N>::set(buffer, uni.fOffset, arrayCount, matrices);
338 }
339
340 template<int N> struct set_uniform_matrix {
setset_uniform_matrix341 inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
342 GR_STATIC_ASSERT(sizeof(float) == 4);
343 buffer = static_cast<char*>(buffer) + uniformOffset;
344 for (int i = 0; i < count; ++i) {
345 const float* matrix = &matrices[N * N * i];
346 for (int j = 0; j < N; ++j) {
347 memcpy(buffer, &matrix[j * N], N * sizeof(float));
348 buffer = static_cast<char*>(buffer) + 4 * sizeof(float);
349 }
350 }
351 }
352 };
353
354 template<> struct set_uniform_matrix<4> {
setset_uniform_matrix355 inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
356 GR_STATIC_ASSERT(sizeof(float) == 4);
357 buffer = static_cast<char*>(buffer) + uniformOffset;
358 memcpy(buffer, matrices, count * 16 * sizeof(float));
359 }
360 };
361
uploadUniformBuffers(GrVkGpu * gpu,GrVkUniformBuffer * geometryBuffer,GrVkUniformBuffer * fragmentBuffer) const362 bool GrVkPipelineStateDataManager::uploadUniformBuffers(GrVkGpu* gpu,
363 GrVkUniformBuffer* geometryBuffer,
364 GrVkUniformBuffer* fragmentBuffer) const {
365 bool updatedBuffer = false;
366 if (geometryBuffer && fGeometryUniformsDirty) {
367 SkAssertResult(geometryBuffer->updateData(gpu, fGeometryUniformData.get(),
368 fGeometryUniformSize, &updatedBuffer));
369 fGeometryUniformsDirty = false;
370 }
371 if (fragmentBuffer && fFragmentUniformsDirty) {
372 SkAssertResult(fragmentBuffer->updateData(gpu, fFragmentUniformData.get(),
373 fFragmentUniformSize, &updatedBuffer));
374 fFragmentUniformsDirty = false;
375 }
376
377 return updatedBuffer;
378 }
379