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