GrVkProgramDataManager.cpp revision 48cf268defad66f58f1aa03b4835e5583be96b2f
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 "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);
77    memcpy(buffer, v, arrayCount * sizeof(float));
78}
79
80void GrVkProgramDataManager::set2f(UniformHandle u, float v0, float v1) const {
81    const Uniform& uni = fUniforms[u.toIndex()];
82    SkASSERT(uni.fType == kVec2f_GrSLType);
83    SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount);
84    SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
85    void* buffer;
86    if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {
87        buffer = fVertexUniformData.get();
88    } else {
89        SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
90        buffer = fFragmentUniformData.get();
91    }
92    buffer = static_cast<char*>(buffer) + uni.fOffset;
93    SkASSERT(sizeof(float) == 4);
94    float v[2] = { v0, v1 };
95    memcpy(buffer, v, 2 * sizeof(float));
96}
97
98void GrVkProgramDataManager::set2fv(UniformHandle u,
99                                    int arrayCount,
100                                    const float v[]) const {
101    const Uniform& uni = fUniforms[u.toIndex()];
102    SkASSERT(uni.fType == kVec2f_GrSLType);
103    SkASSERT(arrayCount > 0);
104    SkASSERT(arrayCount <= uni.fArrayCount ||
105             (1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount));
106    SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
107
108    void* buffer;
109    if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {
110        buffer = fVertexUniformData.get();
111    } else {
112        SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
113        buffer = fFragmentUniformData.get();
114    }
115    buffer = static_cast<char*>(buffer) + uni.fOffset;
116    SkASSERT(sizeof(float) == 4);
117    memcpy(buffer, v, arrayCount * 2* sizeof(float));
118}
119
120void GrVkProgramDataManager::set3f(UniformHandle u, float v0, float v1, float v2) const {
121    const Uniform& uni = fUniforms[u.toIndex()];
122    SkASSERT(uni.fType == kVec3f_GrSLType);
123    SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount);
124    SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
125    void* buffer;
126    if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {
127        buffer = fVertexUniformData.get();
128    } else {
129        SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
130        buffer = fFragmentUniformData.get();
131    }
132    buffer = static_cast<char*>(buffer) + uni.fOffset;
133    SkASSERT(sizeof(float) == 4);
134    float v[3] = { v0, v1, v2 };
135    memcpy(buffer, v, 3 * sizeof(float));
136}
137
138void GrVkProgramDataManager::set3fv(UniformHandle u,
139                                    int arrayCount,
140                                    const float v[]) const {
141    const Uniform& uni = fUniforms[u.toIndex()];
142    SkASSERT(uni.fType == kVec3f_GrSLType);
143    SkASSERT(arrayCount > 0);
144    SkASSERT(arrayCount <= uni.fArrayCount ||
145             (1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount));
146    SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
147
148    void* buffer;
149    if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {
150        buffer = fVertexUniformData.get();
151    } else {
152        SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
153        buffer = fFragmentUniformData.get();
154    }
155    buffer = static_cast<char*>(buffer) + uni.fOffset;
156    SkASSERT(sizeof(float) == 4);
157    memcpy(buffer, v, arrayCount * 3 * sizeof(float));
158}
159
160void GrVkProgramDataManager::set4f(UniformHandle u, float v0, float v1, float v2, float v3) const {
161    const Uniform& uni = fUniforms[u.toIndex()];
162    SkASSERT(uni.fType == kVec4f_GrSLType);
163    SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount);
164    SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
165    void* buffer;
166    if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {
167        buffer = fVertexUniformData.get();
168    } else {
169        SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
170        buffer = fFragmentUniformData.get();
171    }
172    buffer = static_cast<char*>(buffer) + uni.fOffset;
173    SkASSERT(sizeof(float) == 4);
174    float v[4] = { v0, v1, v2, v3 };
175    memcpy(buffer, v, 4 * sizeof(float));
176}
177
178void GrVkProgramDataManager::set4fv(UniformHandle u,
179                                    int arrayCount,
180                                    const float v[]) const {
181    const Uniform& uni = fUniforms[u.toIndex()];
182    SkASSERT(uni.fType == kVec4f_GrSLType);
183    SkASSERT(arrayCount > 0);
184    SkASSERT(arrayCount <= uni.fArrayCount ||
185             (1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount));
186    SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
187
188    void* buffer;
189    if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {
190        buffer = fVertexUniformData.get();
191    } else {
192        SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
193        buffer = fFragmentUniformData.get();
194    }
195    buffer = static_cast<char*>(buffer) + uni.fOffset;
196    SkASSERT(sizeof(float) == 4);
197    memcpy(buffer, v, arrayCount * 4 * sizeof(float));
198}
199
200void GrVkProgramDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const {
201    const Uniform& uni = fUniforms[u.toIndex()];
202    SkASSERT(uni.fType == kMat33f_GrSLType);
203    SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount);
204    SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
205    void* buffer;
206    if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {
207        buffer = fVertexUniformData.get();
208    } else {
209        SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
210        buffer = fFragmentUniformData.get();
211    }
212
213    SkASSERT(sizeof(float) == 4);
214    buffer = static_cast<char*>(buffer) + uni.fOffset;
215    memcpy(buffer, &matrix[0], 3 * sizeof(float));
216    buffer = static_cast<char*>(buffer) + 4*sizeof(float);
217    memcpy(buffer, &matrix[3], 3 * sizeof(float));
218    buffer = static_cast<char*>(buffer) + 4 * sizeof(float);
219    memcpy(buffer, &matrix[6], 3 * sizeof(float));
220}
221
222void GrVkProgramDataManager::setMatrix3fv(UniformHandle u,
223                                          int arrayCount,
224                                          const float matrices[]) const {
225    const Uniform& uni = fUniforms[u.toIndex()];
226    SkASSERT(uni.fType == kMat33f_GrSLType);
227    SkASSERT(arrayCount > 0);
228    SkASSERT(arrayCount <= uni.fArrayCount ||
229             (1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount));
230    SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
231
232    void* buffer;
233    if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {
234        buffer = fVertexUniformData.get();
235    } else {
236        SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
237        buffer = fFragmentUniformData.get();
238    }
239    SkASSERT(sizeof(float) == 4);
240    buffer = static_cast<char*>(buffer)+uni.fOffset;
241    for (int i = 0; i < arrayCount; ++i) {
242        const float* matrix = &matrices[9 * i];
243        memcpy(buffer, &matrix[0], 3 * sizeof(float));
244        buffer = static_cast<char*>(buffer)+4 * sizeof(float);
245        memcpy(buffer, &matrix[3], 3 * sizeof(float));
246        buffer = static_cast<char*>(buffer)+4 * sizeof(float);
247        memcpy(buffer, &matrix[6], 3 * sizeof(float));
248        buffer = static_cast<char*>(buffer)+4 * sizeof(float);
249    }
250}
251
252
253void GrVkProgramDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const {
254    const Uniform& uni = fUniforms[u.toIndex()];
255    SkASSERT(uni.fType == kMat44f_GrSLType);
256    SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount);
257    SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
258    void* buffer;
259    if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {
260        buffer = fVertexUniformData.get();
261    } else {
262        SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
263        buffer = fFragmentUniformData.get();
264    }
265    buffer = static_cast<char*>(buffer) + uni.fOffset;
266    SkASSERT(sizeof(float) == 4);
267    memcpy(buffer, matrix, 16 * sizeof(float));
268}
269
270void GrVkProgramDataManager::setMatrix4fv(UniformHandle u,
271                                          int arrayCount,
272                                          const float matrices[]) const {
273    const Uniform& uni = fUniforms[u.toIndex()];
274    SkASSERT(uni.fType == kMat44f_GrSLType);
275    SkASSERT(arrayCount > 0);
276    SkASSERT(arrayCount <= uni.fArrayCount ||
277             (1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount));
278    SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber);
279
280    void* buffer;
281    if (GrVkUniformHandler::kVertexBinding == uni.fBinding) {
282        buffer = fVertexUniformData.get();
283    } else {
284        SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
285        buffer = fFragmentUniformData.get();
286    }
287    buffer = static_cast<char*>(buffer) + uni.fOffset;
288    SkASSERT(sizeof(float) == 4);
289    memcpy(buffer, matrices, arrayCount * 16 * sizeof(float));
290}
291
292void GrVkProgramDataManager::uploadUniformBuffers(const GrVkGpu* gpu,
293                                                  GrVkUniformBuffer* vertexBuffer,
294                                                  GrVkUniformBuffer* fragmentBuffer) const {
295    if (vertexBuffer) {
296        vertexBuffer->addMemoryBarrier(gpu,
297                                       VK_ACCESS_UNIFORM_READ_BIT,
298                                       VK_ACCESS_HOST_WRITE_BIT,
299                                       VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
300                                       VK_PIPELINE_STAGE_HOST_BIT,
301                                       false);
302        SkAssertResult(vertexBuffer->updateData(gpu, fVertexUniformData.get(), fVertexUniformSize));
303    }
304
305    if (fragmentBuffer) {
306        fragmentBuffer->addMemoryBarrier(gpu,
307                                         VK_ACCESS_UNIFORM_READ_BIT,
308                                         VK_ACCESS_HOST_WRITE_BIT,
309                                         VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
310                                         VK_PIPELINE_STAGE_HOST_BIT,
311                                         false);
312        SkAssertResult(fragmentBuffer->updateData(gpu, fFragmentUniformData.get(),
313                                                  fFragmentUniformSize));
314    }
315}
316