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