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 "src/gpu/vk/GrVkPipelineStateDataManager.h"
9 
10 #include "src/gpu/vk/GrVkGpu.h"
11 #include "src/gpu/vk/GrVkUniformBuffer.h"
12 
GrVkPipelineStateDataManager(const UniformInfoArray & uniforms,uint32_t uniformSize)13 GrVkPipelineStateDataManager::GrVkPipelineStateDataManager(const UniformInfoArray& uniforms,
14                                                            uint32_t uniformSize)
15     : fUniformSize(uniformSize)
16     , fUniformsDirty(false) {
17     fUniformData.reset(uniformSize);
18     int count = uniforms.count();
19     fUniforms.push_back_n(count);
20     // We must add uniforms in same order is the UniformInfoArray so that UniformHandles already
21     // owned by other objects will still match up here.
22     for (int i = 0; i < count; i++) {
23         Uniform& uniform = fUniforms[i];
24         const GrVkUniformHandler::UniformInfo uniformInfo = uniforms[i];
25         SkASSERT(GrShaderVar::kNonArray == uniformInfo.fVariable.getArrayCount() ||
26                  uniformInfo.fVariable.getArrayCount() > 0);
27         SkDEBUGCODE(
28             uniform.fArrayCount = uniformInfo.fVariable.getArrayCount();
29             uniform.fType = uniformInfo.fVariable.getType();
30         )
31 
32         uniform.fOffset = uniformInfo.fUBOffset;
33     }
34 }
35 
getBufferPtrAndMarkDirty(const Uniform & uni) const36 void* GrVkPipelineStateDataManager::getBufferPtrAndMarkDirty(const Uniform& uni) const {
37     fUniformsDirty = true;
38     return static_cast<char*>(fUniformData.get())+uni.fOffset;
39 }
40 
set1i(UniformHandle u,int32_t i) const41 void GrVkPipelineStateDataManager::set1i(UniformHandle u, int32_t i) const {
42     const Uniform& uni = fUniforms[u.toIndex()];
43     SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType);
44     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
45     void* buffer = this->getBufferPtrAndMarkDirty(uni);
46     memcpy(buffer, &i, sizeof(int32_t));
47 }
48 
set1iv(UniformHandle u,int arrayCount,const int32_t v[]) const49 void GrVkPipelineStateDataManager::set1iv(UniformHandle u,
50                                           int arrayCount,
51                                           const int32_t v[]) const {
52     const Uniform& uni = fUniforms[u.toIndex()];
53     SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType);
54     SkASSERT(arrayCount > 0);
55     SkASSERT(arrayCount <= uni.fArrayCount ||
56              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
57 
58     void* buffer = this->getBufferPtrAndMarkDirty(uni);
59     SkASSERT(sizeof(int32_t) == 4);
60     for (int i = 0; i < arrayCount; ++i) {
61         const int32_t* curVec = &v[i];
62         memcpy(buffer, curVec, sizeof(int32_t));
63         buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
64     }
65 }
66 
set1f(UniformHandle u,float v0) const67 void GrVkPipelineStateDataManager::set1f(UniformHandle u, float v0) const {
68     const Uniform& uni = fUniforms[u.toIndex()];
69     SkASSERT(uni.fType == kFloat_GrSLType || uni.fType == kHalf_GrSLType);
70     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
71     void* buffer = this->getBufferPtrAndMarkDirty(uni);
72     SkASSERT(sizeof(float) == 4);
73     memcpy(buffer, &v0, sizeof(float));
74 }
75 
set1fv(UniformHandle u,int arrayCount,const float v[]) const76 void GrVkPipelineStateDataManager::set1fv(UniformHandle u,
77                                           int arrayCount,
78                                           const float v[]) const {
79     const Uniform& uni = fUniforms[u.toIndex()];
80     SkASSERT(uni.fType == kFloat_GrSLType || uni.fType == kHalf_GrSLType);
81     SkASSERT(arrayCount > 0);
82     SkASSERT(arrayCount <= uni.fArrayCount ||
83              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
84 
85     void* buffer = this->getBufferPtrAndMarkDirty(uni);
86     SkASSERT(sizeof(float) == 4);
87     for (int i = 0; i < arrayCount; ++i) {
88         const float* curVec = &v[i];
89         memcpy(buffer, curVec, sizeof(float));
90         buffer = static_cast<char*>(buffer) + 4*sizeof(float);
91     }
92 }
93 
set2i(UniformHandle u,int32_t i0,int32_t i1) const94 void GrVkPipelineStateDataManager::set2i(UniformHandle u, int32_t i0, int32_t i1) const {
95     const Uniform& uni = fUniforms[u.toIndex()];
96     SkASSERT(uni.fType == kInt2_GrSLType || uni.fType == kShort2_GrSLType);
97     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
98     void* buffer = this->getBufferPtrAndMarkDirty(uni);
99     int32_t v[2] = { i0, i1 };
100     memcpy(buffer, v, 2 * sizeof(int32_t));
101 }
102 
set2iv(UniformHandle u,int arrayCount,const int32_t v[]) const103 void GrVkPipelineStateDataManager::set2iv(UniformHandle u,
104                                           int arrayCount,
105                                           const int32_t v[]) const {
106     const Uniform& uni = fUniforms[u.toIndex()];
107     SkASSERT(uni.fType == kInt2_GrSLType || uni.fType == kShort2_GrSLType);
108     SkASSERT(arrayCount > 0);
109     SkASSERT(arrayCount <= uni.fArrayCount ||
110              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
111 
112     void* buffer = this->getBufferPtrAndMarkDirty(uni);
113     SkASSERT(sizeof(int32_t) == 4);
114     for (int i = 0; i < arrayCount; ++i) {
115         const int32_t* curVec = &v[2 * i];
116         memcpy(buffer, curVec, 2 * sizeof(int32_t));
117         buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
118     }
119 }
120 
set2f(UniformHandle u,float v0,float v1) const121 void GrVkPipelineStateDataManager::set2f(UniformHandle u, float v0, float v1) const {
122     const Uniform& uni = fUniforms[u.toIndex()];
123     SkASSERT(uni.fType == kFloat2_GrSLType || uni.fType == kHalf2_GrSLType);
124     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
125     void* buffer = this->getBufferPtrAndMarkDirty(uni);
126     SkASSERT(sizeof(float) == 4);
127     float v[2] = { v0, v1 };
128     memcpy(buffer, v, 2 * sizeof(float));
129 }
130 
set2fv(UniformHandle u,int arrayCount,const float v[]) const131 void GrVkPipelineStateDataManager::set2fv(UniformHandle u,
132                                           int arrayCount,
133                                           const float v[]) const {
134     const Uniform& uni = fUniforms[u.toIndex()];
135     SkASSERT(uni.fType == kFloat2_GrSLType || uni.fType == kHalf2_GrSLType);
136     SkASSERT(arrayCount > 0);
137     SkASSERT(arrayCount <= uni.fArrayCount ||
138              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
139 
140     void* buffer = this->getBufferPtrAndMarkDirty(uni);
141     SkASSERT(sizeof(float) == 4);
142     for (int i = 0; i < arrayCount; ++i) {
143         const float* curVec = &v[2 * i];
144         memcpy(buffer, curVec, 2 * sizeof(float));
145         buffer = static_cast<char*>(buffer) + 4*sizeof(float);
146     }
147 }
148 
set3i(UniformHandle u,int32_t i0,int32_t i1,int32_t i2) const149 void GrVkPipelineStateDataManager::set3i(UniformHandle u,
150                                          int32_t i0,
151                                          int32_t i1,
152                                          int32_t i2) const {
153     const Uniform& uni = fUniforms[u.toIndex()];
154     SkASSERT(uni.fType == kInt3_GrSLType || uni.fType == kShort3_GrSLType);
155     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
156     void* buffer = this->getBufferPtrAndMarkDirty(uni);
157     int32_t v[3] = { i0, i1, i2 };
158     memcpy(buffer, v, 3 * sizeof(int32_t));
159 }
160 
set3iv(UniformHandle u,int arrayCount,const int32_t v[]) const161 void GrVkPipelineStateDataManager::set3iv(UniformHandle u,
162                                           int arrayCount,
163                                           const int32_t v[]) const {
164     const Uniform& uni = fUniforms[u.toIndex()];
165     SkASSERT(uni.fType == kInt3_GrSLType || uni.fType == kShort3_GrSLType);
166     SkASSERT(arrayCount > 0);
167     SkASSERT(arrayCount <= uni.fArrayCount ||
168              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
169 
170     void* buffer = this->getBufferPtrAndMarkDirty(uni);
171     SkASSERT(sizeof(int32_t) == 4);
172     for (int i = 0; i < arrayCount; ++i) {
173         const int32_t* curVec = &v[3 * i];
174         memcpy(buffer, curVec, 3 * sizeof(int32_t));
175         buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
176     }
177 }
178 
set3f(UniformHandle u,float v0,float v1,float v2) const179 void GrVkPipelineStateDataManager::set3f(UniformHandle u, float v0, float v1, float v2) const {
180     const Uniform& uni = fUniforms[u.toIndex()];
181     SkASSERT(uni.fType == kFloat3_GrSLType || uni.fType == kHalf3_GrSLType);
182     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
183     void* buffer = this->getBufferPtrAndMarkDirty(uni);
184     SkASSERT(sizeof(float) == 4);
185     float v[3] = { v0, v1, v2 };
186     memcpy(buffer, v, 3 * sizeof(float));
187 }
188 
set3fv(UniformHandle u,int arrayCount,const float v[]) const189 void GrVkPipelineStateDataManager::set3fv(UniformHandle u,
190                                           int arrayCount,
191                                           const float v[]) const {
192     const Uniform& uni = fUniforms[u.toIndex()];
193     SkASSERT(uni.fType == kFloat3_GrSLType || uni.fType == kHalf3_GrSLType);
194     SkASSERT(arrayCount > 0);
195     SkASSERT(arrayCount <= uni.fArrayCount ||
196              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
197 
198     void* buffer = this->getBufferPtrAndMarkDirty(uni);
199     SkASSERT(sizeof(float) == 4);
200     for (int i = 0; i < arrayCount; ++i) {
201         const float* curVec = &v[3 * i];
202         memcpy(buffer, curVec, 3 * sizeof(float));
203         buffer = static_cast<char*>(buffer) + 4*sizeof(float);
204     }
205 }
206 
set4i(UniformHandle u,int32_t i0,int32_t i1,int32_t i2,int32_t i3) const207 void GrVkPipelineStateDataManager::set4i(UniformHandle u,
208                                          int32_t i0,
209                                          int32_t i1,
210                                          int32_t i2,
211                                          int32_t i3) const {
212     const Uniform& uni = fUniforms[u.toIndex()];
213     SkASSERT(uni.fType == kInt4_GrSLType || uni.fType == kShort4_GrSLType);
214     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
215     void* buffer = this->getBufferPtrAndMarkDirty(uni);
216     int32_t v[4] = { i0, i1, i2, i3 };
217     memcpy(buffer, v, 4 * sizeof(int32_t));
218 }
219 
set4iv(UniformHandle u,int arrayCount,const int32_t v[]) const220 void GrVkPipelineStateDataManager::set4iv(UniformHandle u,
221                                           int arrayCount,
222                                           const int32_t v[]) const {
223     const Uniform& uni = fUniforms[u.toIndex()];
224     SkASSERT(uni.fType == kInt4_GrSLType || uni.fType == kShort4_GrSLType);
225     SkASSERT(arrayCount > 0);
226     SkASSERT(arrayCount <= uni.fArrayCount ||
227              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
228 
229     void* buffer = this->getBufferPtrAndMarkDirty(uni);
230     SkASSERT(sizeof(int32_t) == 4);
231     for (int i = 0; i < arrayCount; ++i) {
232         const int32_t* curVec = &v[4 * i];
233         memcpy(buffer, curVec, 4 * sizeof(int32_t));
234         buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
235     }
236 }
237 
set4f(UniformHandle u,float v0,float v1,float v2,float v3) const238 void GrVkPipelineStateDataManager::set4f(UniformHandle u,
239                                          float v0,
240                                          float v1,
241                                          float v2,
242                                          float v3) const {
243     const Uniform& uni = fUniforms[u.toIndex()];
244     SkASSERT(uni.fType == kFloat4_GrSLType || uni.fType == kHalf4_GrSLType);
245     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
246     void* buffer = this->getBufferPtrAndMarkDirty(uni);
247     SkASSERT(sizeof(float) == 4);
248     float v[4] = { v0, v1, v2, v3 };
249     memcpy(buffer, v, 4 * sizeof(float));
250 }
251 
set4fv(UniformHandle u,int arrayCount,const float v[]) const252 void GrVkPipelineStateDataManager::set4fv(UniformHandle u,
253                                           int arrayCount,
254                                           const float v[]) const {
255     const Uniform& uni = fUniforms[u.toIndex()];
256     SkASSERT(uni.fType == kFloat4_GrSLType || uni.fType == kHalf4_GrSLType);
257     SkASSERT(arrayCount > 0);
258     SkASSERT(arrayCount <= uni.fArrayCount ||
259              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
260 
261     void* buffer = this->getBufferPtrAndMarkDirty(uni);
262     SkASSERT(sizeof(float) == 4);
263     memcpy(buffer, v, arrayCount * 4 * sizeof(float));
264 }
265 
setMatrix2f(UniformHandle u,const float matrix[]) const266 void GrVkPipelineStateDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const {
267     this->setMatrices<2>(u, 1, matrix);
268 }
269 
setMatrix2fv(UniformHandle u,int arrayCount,const float m[]) const270 void GrVkPipelineStateDataManager::setMatrix2fv(UniformHandle u,
271                                                 int arrayCount,
272                                                 const float m[]) const {
273     this->setMatrices<2>(u, arrayCount, m);
274 }
275 
setMatrix3f(UniformHandle u,const float matrix[]) const276 void GrVkPipelineStateDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const {
277     this->setMatrices<3>(u, 1, matrix);
278 }
279 
setMatrix3fv(UniformHandle u,int arrayCount,const float m[]) const280 void GrVkPipelineStateDataManager::setMatrix3fv(UniformHandle u,
281                                                 int arrayCount,
282                                                 const float m[]) const {
283     this->setMatrices<3>(u, arrayCount, m);
284 }
285 
setMatrix4f(UniformHandle u,const float matrix[]) const286 void GrVkPipelineStateDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const {
287     this->setMatrices<4>(u, 1, matrix);
288 }
289 
setMatrix4fv(UniformHandle u,int arrayCount,const float m[]) const290 void GrVkPipelineStateDataManager::setMatrix4fv(UniformHandle u,
291                                                 int arrayCount,
292                                                 const float m[]) const {
293     this->setMatrices<4>(u, arrayCount, m);
294 }
295 
296 template<int N> struct set_uniform_matrix;
297 
setMatrices(UniformHandle u,int arrayCount,const float matrices[]) const298 template<int N> inline void GrVkPipelineStateDataManager::setMatrices(UniformHandle u,
299                                                                       int arrayCount,
300                                                                      const float matrices[]) const {
301     const Uniform& uni = fUniforms[u.toIndex()];
302     SkASSERT(uni.fType == kFloat2x2_GrSLType + (N - 2) ||
303              uni.fType == kHalf2x2_GrSLType + (N - 2));
304     SkASSERT(arrayCount > 0);
305     SkASSERT(arrayCount <= uni.fArrayCount ||
306              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
307 
308     void* buffer = fUniformData.get();
309     fUniformsDirty = true;
310 
311     set_uniform_matrix<N>::set(buffer, uni.fOffset, arrayCount, matrices);
312 }
313 
314 template<int N> struct set_uniform_matrix {
setset_uniform_matrix315     inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
316         GR_STATIC_ASSERT(sizeof(float) == 4);
317         buffer = static_cast<char*>(buffer) + uniformOffset;
318         for (int i = 0; i < count; ++i) {
319             const float* matrix = &matrices[N * N * i];
320             for (int j = 0; j < N; ++j) {
321                 memcpy(buffer, &matrix[j * N], N * sizeof(float));
322                 buffer = static_cast<char*>(buffer) + 4 * sizeof(float);
323             }
324         }
325     }
326 };
327 
328 template<> struct set_uniform_matrix<4> {
setset_uniform_matrix329     inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
330         GR_STATIC_ASSERT(sizeof(float) == 4);
331         buffer = static_cast<char*>(buffer) + uniformOffset;
332         memcpy(buffer, matrices, count * 16 * sizeof(float));
333     }
334 };
335 
uploadUniformBuffers(GrVkGpu * gpu,GrVkUniformBuffer * buffer) const336 bool GrVkPipelineStateDataManager::uploadUniformBuffers(GrVkGpu* gpu,
337                                                         GrVkUniformBuffer* buffer) const {
338     bool updatedBuffer = false;
339     if (buffer && fUniformsDirty) {
340         SkAssertResult(buffer->updateData(gpu, fUniformData.get(),
341                                           fUniformSize, &updatedBuffer));
342         fUniformsDirty = false;
343     }
344 
345     return updatedBuffer;
346 }
347