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 
GrVkProgramDataManager(const UniformInfoArray & uniforms,uint32_t vertexUniformSize,uint32_t fragmentUniformSize)13 GrVkProgramDataManager::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 
set1f(UniformHandle u,float v0) const41 void 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 
set1fv(UniformHandle u,int arrayCount,const float v[]) const58 void 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 
set2f(UniformHandle u,float v0,float v1) const80 void 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 
set2fv(UniformHandle u,int arrayCount,const float v[]) const98 void 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 
set3f(UniformHandle u,float v0,float v1,float v2) const120 void 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 
set3fv(UniformHandle u,int arrayCount,const float v[]) const138 void 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 
set4f(UniformHandle u,float v0,float v1,float v2,float v3) const160 void 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 
set4fv(UniformHandle u,int arrayCount,const float v[]) const178 void 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 
setMatrix3f(UniformHandle u,const float matrix[]) const200 void 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 
setMatrix3fv(UniformHandle u,int arrayCount,const float matrices[]) const222 void 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 
setMatrix4f(UniformHandle u,const float matrix[]) const253 void 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 
setMatrix4fv(UniformHandle u,int arrayCount,const float matrices[]) const270 void 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 
uploadUniformBuffers(const GrVkGpu * gpu,GrVkUniformBuffer * vertexBuffer,GrVkUniformBuffer * fragmentBuffer) const292 void 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