• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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