blob: f189097b973be0dd21ea45836a457cf1461bc2b3 [file] [log] [blame]
egdaniel42701e92016-02-26 08:02:55 -08001/*
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 "GrVkProgramDataManager.h"
9
10#include "GrVkGpu.h"
11#include "GrVkUniformBuffer.h"
12
13GrVkProgramDataManager::GrVkProgramDataManager(const UniformInfoArray& uniforms,
14 uint32_t vertexUniformSize,
15 uint32_t fragmentUniformSize)
16 : fVertexUniformSize(vertexUniformSize)
17 , fFragmentUniformSize(fragmentUniformSize) {
18 fVertexUniformData.reset(vertexUniformSize);
19 fFragmentUniformData.reset(fragmentUniformSize);
20 int count = uniforms.count();
21 fUniforms.push_back_n(count);
22 // We must add uniforms in same order is the UniformInfoArray so that UniformHandles already
23 // owned by other objects will still match up here.
24 for (int i = 0; i < count; i++) {
25 Uniform& uniform = fUniforms[i];
26 const GrVkUniformHandler::UniformInfo uniformInfo = uniforms[i];
27 SkASSERT(GrGLSLShaderVar::kNonArray == uniformInfo.fVariable.getArrayCount() ||
28 uniformInfo.fVariable.getArrayCount() > 0);
29 SkDEBUGCODE(
30 uniform.fArrayCount = uniformInfo.fVariable.getArrayCount();
31 uniform.fType = uniformInfo.fVariable.getType();
32 );
33 uniform.fBinding = uniformInfo.fBinding;
34 uniform.fOffset = uniformInfo.fUBOffset;
35 SkDEBUGCODE(
36 uniform.fSetNumber = uniformInfo.fSetNumber;
37 );
38 }
39}
40
41void GrVkProgramDataManager::set1f(UniformHandle u, float v0) const {
42 const Uniform& uni = fUniforms[u.toIndex()];
43 SkASSERT(uni.fType == kFloat_GrSLType);
44 SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount);
45 SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
46 void* buffer;
47 if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {
48 buffer = fVertexUniformData.get();
49 } else {
50 SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
51 buffer = fFragmentUniformData.get();
52 }
53 buffer = static_cast<char*>(buffer) + uni.fOffset;
54 SkASSERT(sizeof(float) == 4);
55 memcpy(buffer, &v0, sizeof(float));
56}
57
58void GrVkProgramDataManager::set1fv(UniformHandle u,
59 int arrayCount,
60 const float v[]) const {
61 const Uniform& uni = fUniforms[u.toIndex()];
62 SkASSERT(uni.fType == kFloat_GrSLType);
63 SkASSERT(arrayCount > 0);
64 SkASSERT(arrayCount <= uni.fArrayCount ||
65 (1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount));
66 SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
67
68 void* buffer;
69 if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {
70 buffer = fVertexUniformData.get();
71 } else {
72 SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
73 buffer = fFragmentUniformData.get();
74 }
75 buffer = static_cast<char*>(buffer) + uni.fOffset;
76 SkASSERT(sizeof(float) == 4);
egdaniel4ee1cda2016-02-26 08:18:49 -080077 for (int i = 0; i < arrayCount; ++i) {
78 const float* curVec = &v[i];
79 memcpy(buffer, curVec, sizeof(float));
80 buffer = static_cast<char*>(buffer) + 4*sizeof(float);
81 }
egdaniel42701e92016-02-26 08:02:55 -080082}
83
84void GrVkProgramDataManager::set2f(UniformHandle u, float v0, float v1) const {
85 const Uniform& uni = fUniforms[u.toIndex()];
86 SkASSERT(uni.fType == kVec2f_GrSLType);
87 SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount);
88 SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
89 void* buffer;
90 if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {
91 buffer = fVertexUniformData.get();
92 } else {
93 SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
94 buffer = fFragmentUniformData.get();
95 }
96 buffer = static_cast<char*>(buffer) + uni.fOffset;
97 SkASSERT(sizeof(float) == 4);
98 float v[2] = { v0, v1 };
99 memcpy(buffer, v, 2 * sizeof(float));
100}
101
102void GrVkProgramDataManager::set2fv(UniformHandle u,
103 int arrayCount,
104 const float v[]) const {
105 const Uniform& uni = fUniforms[u.toIndex()];
106 SkASSERT(uni.fType == kVec2f_GrSLType);
107 SkASSERT(arrayCount > 0);
108 SkASSERT(arrayCount <= uni.fArrayCount ||
109 (1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount));
110 SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
111
112 void* buffer;
113 if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {
114 buffer = fVertexUniformData.get();
115 } else {
116 SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
117 buffer = fFragmentUniformData.get();
118 }
119 buffer = static_cast<char*>(buffer) + uni.fOffset;
120 SkASSERT(sizeof(float) == 4);
egdaniel4ee1cda2016-02-26 08:18:49 -0800121 for (int i = 0; i < arrayCount; ++i) {
122 const float* curVec = &v[2 * i];
123 memcpy(buffer, curVec, 2 * sizeof(float));
124 buffer = static_cast<char*>(buffer) + 4*sizeof(float);
125 }
egdaniel42701e92016-02-26 08:02:55 -0800126}
127
128void GrVkProgramDataManager::set3f(UniformHandle u, float v0, float v1, float v2) const {
129 const Uniform& uni = fUniforms[u.toIndex()];
130 SkASSERT(uni.fType == kVec3f_GrSLType);
131 SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount);
132 SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
133 void* buffer;
134 if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {
135 buffer = fVertexUniformData.get();
136 } else {
137 SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
138 buffer = fFragmentUniformData.get();
139 }
140 buffer = static_cast<char*>(buffer) + uni.fOffset;
141 SkASSERT(sizeof(float) == 4);
142 float v[3] = { v0, v1, v2 };
143 memcpy(buffer, v, 3 * sizeof(float));
144}
145
146void GrVkProgramDataManager::set3fv(UniformHandle u,
147 int arrayCount,
148 const float v[]) const {
149 const Uniform& uni = fUniforms[u.toIndex()];
150 SkASSERT(uni.fType == kVec3f_GrSLType);
151 SkASSERT(arrayCount > 0);
152 SkASSERT(arrayCount <= uni.fArrayCount ||
153 (1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount));
154 SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
155
156 void* buffer;
157 if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {
158 buffer = fVertexUniformData.get();
159 } else {
160 SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
161 buffer = fFragmentUniformData.get();
162 }
163 buffer = static_cast<char*>(buffer) + uni.fOffset;
164 SkASSERT(sizeof(float) == 4);
egdaniel4ee1cda2016-02-26 08:18:49 -0800165 for (int i = 0; i < arrayCount; ++i) {
166 const float* curVec = &v[3 * i];
167 memcpy(buffer, curVec, 3 * sizeof(float));
168 buffer = static_cast<char*>(buffer) + 4*sizeof(float);
169 }
egdaniel42701e92016-02-26 08:02:55 -0800170}
171
172void GrVkProgramDataManager::set4f(UniformHandle u, float v0, float v1, float v2, float v3) const {
173 const Uniform& uni = fUniforms[u.toIndex()];
174 SkASSERT(uni.fType == kVec4f_GrSLType);
175 SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount);
176 SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
177 void* buffer;
178 if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {
179 buffer = fVertexUniformData.get();
180 } else {
181 SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
182 buffer = fFragmentUniformData.get();
183 }
184 buffer = static_cast<char*>(buffer) + uni.fOffset;
185 SkASSERT(sizeof(float) == 4);
186 float v[4] = { v0, v1, v2, v3 };
187 memcpy(buffer, v, 4 * sizeof(float));
188}
189
190void GrVkProgramDataManager::set4fv(UniformHandle u,
191 int arrayCount,
192 const float v[]) const {
193 const Uniform& uni = fUniforms[u.toIndex()];
194 SkASSERT(uni.fType == kVec4f_GrSLType);
195 SkASSERT(arrayCount > 0);
196 SkASSERT(arrayCount <= uni.fArrayCount ||
197 (1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount));
198 SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
199
200 void* buffer;
201 if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {
202 buffer = fVertexUniformData.get();
203 } else {
204 SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
205 buffer = fFragmentUniformData.get();
206 }
207 buffer = static_cast<char*>(buffer) + uni.fOffset;
208 SkASSERT(sizeof(float) == 4);
209 memcpy(buffer, v, arrayCount * 4 * sizeof(float));
210}
211
cdalton8d988b32016-03-07 15:39:09 -0800212void GrVkProgramDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const {
213 this->setMatrices<2>(u, 1, matrix);
214}
215
216void GrVkProgramDataManager::setMatrix2fv(UniformHandle u, int arrayCount, const float m[]) const {
217 this->setMatrices<2>(u, arrayCount, m);
218}
219
egdaniel42701e92016-02-26 08:02:55 -0800220void GrVkProgramDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const {
cdalton8d988b32016-03-07 15:39:09 -0800221 this->setMatrices<3>(u, 1, matrix);
egdaniel42701e92016-02-26 08:02:55 -0800222}
223
cdalton8d988b32016-03-07 15:39:09 -0800224void GrVkProgramDataManager::setMatrix3fv(UniformHandle u, int arrayCount, const float m[]) const {
225 this->setMatrices<3>(u, arrayCount, m);
egdaniel42701e92016-02-26 08:02:55 -0800226}
227
egdaniel42701e92016-02-26 08:02:55 -0800228void GrVkProgramDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const {
cdalton8d988b32016-03-07 15:39:09 -0800229 this->setMatrices<4>(u, 1, matrix);
egdaniel42701e92016-02-26 08:02:55 -0800230}
231
cdalton8d988b32016-03-07 15:39:09 -0800232void GrVkProgramDataManager::setMatrix4fv(UniformHandle u, int arrayCount, const float m[]) const {
233 this->setMatrices<4>(u, arrayCount, m);
234}
235
236template<int N> struct set_uniform_matrix;
237
238template<int N> inline void GrVkProgramDataManager::setMatrices(UniformHandle u,
239 int arrayCount,
240 const float matrices[]) const {
egdaniel42701e92016-02-26 08:02:55 -0800241 const Uniform& uni = fUniforms[u.toIndex()];
cdalton8d988b32016-03-07 15:39:09 -0800242 SkASSERT(uni.fType == kMat22f_GrSLType + (N - 2));
egdaniel42701e92016-02-26 08:02:55 -0800243 SkASSERT(arrayCount > 0);
244 SkASSERT(arrayCount <= uni.fArrayCount ||
245 (1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount));
246 SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
247
248 void* buffer;
249 if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {
250 buffer = fVertexUniformData.get();
251 } else {
252 SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
253 buffer = fFragmentUniformData.get();
254 }
cdalton8d988b32016-03-07 15:39:09 -0800255
256 set_uniform_matrix<N>::set(buffer, uni.fOffset, arrayCount, matrices);
egdaniel42701e92016-02-26 08:02:55 -0800257}
258
cdalton8d988b32016-03-07 15:39:09 -0800259template<int N> struct set_uniform_matrix {
260 inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
261 GR_STATIC_ASSERT(sizeof(float) == 4);
262 buffer = static_cast<char*>(buffer) + uniformOffset;
263 for (int i = 0; i < count; ++i) {
264 const float* matrix = &matrices[N * N * i];
265 memcpy(buffer, &matrix[0], N * sizeof(float));
266 buffer = static_cast<char*>(buffer) + 4*sizeof(float);
267 memcpy(buffer, &matrix[3], N * sizeof(float));
268 buffer = static_cast<char*>(buffer) + 4*sizeof(float);
269 memcpy(buffer, &matrix[6], N * sizeof(float));
270 buffer = static_cast<char*>(buffer) + 4*sizeof(float);
271 }
272 }
273};
274
275template<> struct set_uniform_matrix<4> {
276 inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
277 GR_STATIC_ASSERT(sizeof(float) == 4);
278 buffer = static_cast<char*>(buffer) + uniformOffset;
279 memcpy(buffer, matrices, count * 16 * sizeof(float));
280 }
281};
282
egdaniel42701e92016-02-26 08:02:55 -0800283void GrVkProgramDataManager::uploadUniformBuffers(const GrVkGpu* gpu,
284 GrVkUniformBuffer* vertexBuffer,
285 GrVkUniformBuffer* fragmentBuffer) const {
286 if (vertexBuffer) {
287 vertexBuffer->addMemoryBarrier(gpu,
288 VK_ACCESS_UNIFORM_READ_BIT,
289 VK_ACCESS_HOST_WRITE_BIT,
290 VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
291 VK_PIPELINE_STAGE_HOST_BIT,
292 false);
293 SkAssertResult(vertexBuffer->updateData(gpu, fVertexUniformData.get(), fVertexUniformSize));
294 }
295
296 if (fragmentBuffer) {
297 fragmentBuffer->addMemoryBarrier(gpu,
298 VK_ACCESS_UNIFORM_READ_BIT,
299 VK_ACCESS_HOST_WRITE_BIT,
300 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
301 VK_PIPELINE_STAGE_HOST_BIT,
302 false);
303 SkAssertResult(fragmentBuffer->updateData(gpu, fFragmentUniformData.get(),
304 fFragmentUniformSize));
305 }
306}
307