• 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);
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);
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);
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);
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 
set2f(UniformHandle u,float v0,float v1) const113 void GrVkPipelineStateDataManager::set2f(UniformHandle u, float v0, float v1) const {
114     const Uniform& uni = fUniforms[u.toIndex()];
115     SkASSERT(uni.fType == kVec2f_GrSLType);
116     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
117     void* buffer = this->getBufferPtrAndMarkDirty(uni);
118     SkASSERT(sizeof(float) == 4);
119     float v[2] = { v0, v1 };
120     memcpy(buffer, v, 2 * sizeof(float));
121 }
122 
set2fv(UniformHandle u,int arrayCount,const float v[]) const123 void GrVkPipelineStateDataManager::set2fv(UniformHandle u,
124                                           int arrayCount,
125                                           const float v[]) const {
126     const Uniform& uni = fUniforms[u.toIndex()];
127     SkASSERT(uni.fType == kVec2f_GrSLType);
128     SkASSERT(arrayCount > 0);
129     SkASSERT(arrayCount <= uni.fArrayCount ||
130              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
131 
132     void* buffer = this->getBufferPtrAndMarkDirty(uni);
133     SkASSERT(sizeof(float) == 4);
134     for (int i = 0; i < arrayCount; ++i) {
135         const float* curVec = &v[2 * i];
136         memcpy(buffer, curVec, 2 * sizeof(float));
137         buffer = static_cast<char*>(buffer) + 4*sizeof(float);
138     }
139 }
140 
set3f(UniformHandle u,float v0,float v1,float v2) const141 void GrVkPipelineStateDataManager::set3f(UniformHandle u, float v0, float v1, float v2) const {
142     const Uniform& uni = fUniforms[u.toIndex()];
143     SkASSERT(uni.fType == kVec3f_GrSLType);
144     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
145     void* buffer = this->getBufferPtrAndMarkDirty(uni);
146     SkASSERT(sizeof(float) == 4);
147     float v[3] = { v0, v1, v2 };
148     memcpy(buffer, v, 3 * sizeof(float));
149 }
150 
set3fv(UniformHandle u,int arrayCount,const float v[]) const151 void GrVkPipelineStateDataManager::set3fv(UniformHandle u,
152                                           int arrayCount,
153                                           const float v[]) const {
154     const Uniform& uni = fUniforms[u.toIndex()];
155     SkASSERT(uni.fType == kVec3f_GrSLType);
156     SkASSERT(arrayCount > 0);
157     SkASSERT(arrayCount <= uni.fArrayCount ||
158              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
159 
160     void* buffer = this->getBufferPtrAndMarkDirty(uni);
161     SkASSERT(sizeof(float) == 4);
162     for (int i = 0; i < arrayCount; ++i) {
163         const float* curVec = &v[3 * i];
164         memcpy(buffer, curVec, 3 * sizeof(float));
165         buffer = static_cast<char*>(buffer) + 4*sizeof(float);
166     }
167 }
168 
set4f(UniformHandle u,float v0,float v1,float v2,float v3) const169 void GrVkPipelineStateDataManager::set4f(UniformHandle u,
170                                          float v0,
171                                          float v1,
172                                          float v2,
173                                          float v3) const {
174     const Uniform& uni = fUniforms[u.toIndex()];
175     SkASSERT(uni.fType == kVec4f_GrSLType);
176     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
177     void* buffer = this->getBufferPtrAndMarkDirty(uni);
178     SkASSERT(sizeof(float) == 4);
179     float v[4] = { v0, v1, v2, v3 };
180     memcpy(buffer, v, 4 * sizeof(float));
181 }
182 
set4fv(UniformHandle u,int arrayCount,const float v[]) const183 void GrVkPipelineStateDataManager::set4fv(UniformHandle u,
184                                           int arrayCount,
185                                           const float v[]) const {
186     const Uniform& uni = fUniforms[u.toIndex()];
187     SkASSERT(uni.fType == kVec4f_GrSLType);
188     SkASSERT(arrayCount > 0);
189     SkASSERT(arrayCount <= uni.fArrayCount ||
190              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
191 
192     void* buffer = this->getBufferPtrAndMarkDirty(uni);
193     SkASSERT(sizeof(float) == 4);
194     memcpy(buffer, v, arrayCount * 4 * sizeof(float));
195 }
196 
setMatrix2f(UniformHandle u,const float matrix[]) const197 void GrVkPipelineStateDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const {
198     this->setMatrices<2>(u, 1, matrix);
199 }
200 
setMatrix2fv(UniformHandle u,int arrayCount,const float m[]) const201 void GrVkPipelineStateDataManager::setMatrix2fv(UniformHandle u,
202                                                 int arrayCount,
203                                                 const float m[]) const {
204     this->setMatrices<2>(u, arrayCount, m);
205 }
206 
setMatrix3f(UniformHandle u,const float matrix[]) const207 void GrVkPipelineStateDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const {
208     this->setMatrices<3>(u, 1, matrix);
209 }
210 
setMatrix3fv(UniformHandle u,int arrayCount,const float m[]) const211 void GrVkPipelineStateDataManager::setMatrix3fv(UniformHandle u,
212                                                 int arrayCount,
213                                                 const float m[]) const {
214     this->setMatrices<3>(u, arrayCount, m);
215 }
216 
setMatrix4f(UniformHandle u,const float matrix[]) const217 void GrVkPipelineStateDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const {
218     this->setMatrices<4>(u, 1, matrix);
219 }
220 
setMatrix4fv(UniformHandle u,int arrayCount,const float m[]) const221 void GrVkPipelineStateDataManager::setMatrix4fv(UniformHandle u,
222                                                 int arrayCount,
223                                                 const float m[]) const {
224     this->setMatrices<4>(u, arrayCount, m);
225 }
226 
227 template<int N> struct set_uniform_matrix;
228 
setMatrices(UniformHandle u,int arrayCount,const float matrices[]) const229 template<int N> inline void GrVkPipelineStateDataManager::setMatrices(UniformHandle u,
230                                                                       int arrayCount,
231                                                                      const float matrices[]) const {
232     const Uniform& uni = fUniforms[u.toIndex()];
233     SkASSERT(uni.fType == kMat22f_GrSLType + (N - 2));
234     SkASSERT(arrayCount > 0);
235     SkASSERT(arrayCount <= uni.fArrayCount ||
236              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
237 
238     void* buffer;
239     if (GrVkUniformHandler::kGeometryBinding == uni.fBinding) {
240         buffer = fGeometryUniformData.get();
241         fGeometryUniformsDirty = true;
242     } else {
243         SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
244         buffer = fFragmentUniformData.get();
245         fFragmentUniformsDirty = true;
246     }
247 
248     set_uniform_matrix<N>::set(buffer, uni.fOffset, arrayCount, matrices);
249 }
250 
251 template<int N> struct set_uniform_matrix {
setset_uniform_matrix252     inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
253         GR_STATIC_ASSERT(sizeof(float) == 4);
254         buffer = static_cast<char*>(buffer) + uniformOffset;
255         for (int i = 0; i < count; ++i) {
256             const float* matrix = &matrices[N * N * i];
257             for (int j = 0; j < N; ++j) {
258                 memcpy(buffer, &matrix[j * N], N * sizeof(float));
259                 buffer = static_cast<char*>(buffer) + 4 * sizeof(float);
260             }
261         }
262     }
263 };
264 
265 template<> struct set_uniform_matrix<4> {
setset_uniform_matrix266     inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
267         GR_STATIC_ASSERT(sizeof(float) == 4);
268         buffer = static_cast<char*>(buffer) + uniformOffset;
269         memcpy(buffer, matrices, count * 16 * sizeof(float));
270     }
271 };
272 
uploadUniformBuffers(GrVkGpu * gpu,GrVkUniformBuffer * geometryBuffer,GrVkUniformBuffer * fragmentBuffer) const273 bool GrVkPipelineStateDataManager::uploadUniformBuffers(GrVkGpu* gpu,
274                                                         GrVkUniformBuffer* geometryBuffer,
275                                                         GrVkUniformBuffer* fragmentBuffer) const {
276     bool updatedBuffer = false;
277     if (geometryBuffer && fGeometryUniformsDirty) {
278         SkAssertResult(geometryBuffer->updateData(gpu, fGeometryUniformData.get(),
279                                                   fGeometryUniformSize, &updatedBuffer));
280         fGeometryUniformsDirty = false;
281     }
282     if (fragmentBuffer && fFragmentUniformsDirty) {
283         SkAssertResult(fragmentBuffer->updateData(gpu, fFragmentUniformData.get(),
284                                                   fFragmentUniformSize, &updatedBuffer));
285         fFragmentUniformsDirty = false;
286     }
287 
288     return updatedBuffer;
289 }
290