OLD | NEW |
| (Empty) |
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 | |
13 GrVkProgramDataManager::GrVkProgramDataManager(const UniformInfoArray& uniforms, | |
14 uint32_t vertexUniformSize, | |
15 uint32_t fragmentUniformSize) | |
16 : fVertexUniformSize(vertexUniformSize) | |
17 , fFragmentUniformSize(fragmentUniformSize) | |
18 , fVertexUniformsDirty(false) | |
19 , fFragmentUniformsDirty(false) { | |
20 fVertexUniformData.reset(vertexUniformSize); | |
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 Unifor
mHandles 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(GrGLSLShaderVar::kNonArray == uniformInfo.fVariable.getArrayCou
nt() || | |
30 uniformInfo.fVariable.getArrayCount() > 0); | |
31 SkDEBUGCODE( | |
32 uniform.fArrayCount = uniformInfo.fVariable.getArrayCount(); | |
33 uniform.fType = uniformInfo.fVariable.getType(); | |
34 ); | |
35 uniform.fBinding = uniformInfo.fBinding; | |
36 uniform.fOffset = uniformInfo.fUBOffset; | |
37 SkDEBUGCODE( | |
38 uniform.fSetNumber = uniformInfo.fSetNumber; | |
39 ); | |
40 } | |
41 } | |
42 | |
43 void* GrVkProgramDataManager::getBufferPtrAndMarkDirty(const Uniform& uni) const
{ | |
44 void* buffer; | |
45 if (GrVkUniformHandler::kVertexBinding == uni.fBinding) { | |
46 buffer = fVertexUniformData.get(); | |
47 fVertexUniformsDirty = true; | |
48 } | |
49 else { | |
50 SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding); | |
51 buffer = fFragmentUniformData.get(); | |
52 fFragmentUniformsDirty = true; | |
53 } | |
54 buffer = static_cast<char*>(buffer)+uni.fOffset; | |
55 return buffer; | |
56 } | |
57 | |
58 void GrVkProgramDataManager::set1f(UniformHandle u, float v0) const { | |
59 const Uniform& uni = fUniforms[u.toIndex()]; | |
60 SkASSERT(uni.fType == kFloat_GrSLType); | |
61 SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount); | |
62 SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber); | |
63 void* buffer = this->getBufferPtrAndMarkDirty(uni); | |
64 SkASSERT(sizeof(float) == 4); | |
65 memcpy(buffer, &v0, sizeof(float)); | |
66 } | |
67 | |
68 void GrVkProgramDataManager::set1fv(UniformHandle u, | |
69 int arrayCount, | |
70 const float v[]) const { | |
71 const Uniform& uni = fUniforms[u.toIndex()]; | |
72 SkASSERT(uni.fType == kFloat_GrSLType); | |
73 SkASSERT(arrayCount > 0); | |
74 SkASSERT(arrayCount <= uni.fArrayCount || | |
75 (1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount))
; | |
76 SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber); | |
77 | |
78 void* buffer = this->getBufferPtrAndMarkDirty(uni); | |
79 SkASSERT(sizeof(float) == 4); | |
80 for (int i = 0; i < arrayCount; ++i) { | |
81 const float* curVec = &v[i]; | |
82 memcpy(buffer, curVec, sizeof(float)); | |
83 buffer = static_cast<char*>(buffer) + 4*sizeof(float); | |
84 } | |
85 } | |
86 | |
87 void GrVkProgramDataManager::set2f(UniformHandle u, float v0, float v1) const { | |
88 const Uniform& uni = fUniforms[u.toIndex()]; | |
89 SkASSERT(uni.fType == kVec2f_GrSLType); | |
90 SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount); | |
91 SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber); | |
92 void* buffer = this->getBufferPtrAndMarkDirty(uni); | |
93 SkASSERT(sizeof(float) == 4); | |
94 float v[2] = { v0, v1 }; | |
95 memcpy(buffer, v, 2 * sizeof(float)); | |
96 } | |
97 | |
98 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 = this->getBufferPtrAndMarkDirty(uni); | |
109 SkASSERT(sizeof(float) == 4); | |
110 for (int i = 0; i < arrayCount; ++i) { | |
111 const float* curVec = &v[2 * i]; | |
112 memcpy(buffer, curVec, 2 * sizeof(float)); | |
113 buffer = static_cast<char*>(buffer) + 4*sizeof(float); | |
114 } | |
115 } | |
116 | |
117 void GrVkProgramDataManager::set3f(UniformHandle u, float v0, float v1, float v2
) const { | |
118 const Uniform& uni = fUniforms[u.toIndex()]; | |
119 SkASSERT(uni.fType == kVec3f_GrSLType); | |
120 SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount); | |
121 SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber); | |
122 void* buffer = this->getBufferPtrAndMarkDirty(uni); | |
123 SkASSERT(sizeof(float) == 4); | |
124 float v[3] = { v0, v1, v2 }; | |
125 memcpy(buffer, v, 3 * sizeof(float)); | |
126 } | |
127 | |
128 void GrVkProgramDataManager::set3fv(UniformHandle u, | |
129 int arrayCount, | |
130 const float v[]) const { | |
131 const Uniform& uni = fUniforms[u.toIndex()]; | |
132 SkASSERT(uni.fType == kVec3f_GrSLType); | |
133 SkASSERT(arrayCount > 0); | |
134 SkASSERT(arrayCount <= uni.fArrayCount || | |
135 (1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount))
; | |
136 SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber); | |
137 | |
138 void* buffer = this->getBufferPtrAndMarkDirty(uni); | |
139 SkASSERT(sizeof(float) == 4); | |
140 for (int i = 0; i < arrayCount; ++i) { | |
141 const float* curVec = &v[3 * i]; | |
142 memcpy(buffer, curVec, 3 * sizeof(float)); | |
143 buffer = static_cast<char*>(buffer) + 4*sizeof(float); | |
144 } | |
145 } | |
146 | |
147 void GrVkProgramDataManager::set4f(UniformHandle u, float v0, float v1, float v2
, float v3) const { | |
148 const Uniform& uni = fUniforms[u.toIndex()]; | |
149 SkASSERT(uni.fType == kVec4f_GrSLType); | |
150 SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount); | |
151 SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber); | |
152 void* buffer = this->getBufferPtrAndMarkDirty(uni); | |
153 SkASSERT(sizeof(float) == 4); | |
154 float v[4] = { v0, v1, v2, v3 }; | |
155 memcpy(buffer, v, 4 * sizeof(float)); | |
156 } | |
157 | |
158 void GrVkProgramDataManager::set4fv(UniformHandle u, | |
159 int arrayCount, | |
160 const float v[]) const { | |
161 const Uniform& uni = fUniforms[u.toIndex()]; | |
162 SkASSERT(uni.fType == kVec4f_GrSLType); | |
163 SkASSERT(arrayCount > 0); | |
164 SkASSERT(arrayCount <= uni.fArrayCount || | |
165 (1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount))
; | |
166 SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber); | |
167 | |
168 void* buffer = this->getBufferPtrAndMarkDirty(uni); | |
169 SkASSERT(sizeof(float) == 4); | |
170 memcpy(buffer, v, arrayCount * 4 * sizeof(float)); | |
171 } | |
172 | |
173 void GrVkProgramDataManager::setMatrix2f(UniformHandle u, const float matrix[])
const { | |
174 this->setMatrices<2>(u, 1, matrix); | |
175 } | |
176 | |
177 void GrVkProgramDataManager::setMatrix2fv(UniformHandle u, int arrayCount, const
float m[]) const { | |
178 this->setMatrices<2>(u, arrayCount, m); | |
179 } | |
180 | |
181 void GrVkProgramDataManager::setMatrix3f(UniformHandle u, const float matrix[])
const { | |
182 this->setMatrices<3>(u, 1, matrix); | |
183 } | |
184 | |
185 void GrVkProgramDataManager::setMatrix3fv(UniformHandle u, int arrayCount, const
float m[]) const { | |
186 this->setMatrices<3>(u, arrayCount, m); | |
187 } | |
188 | |
189 void GrVkProgramDataManager::setMatrix4f(UniformHandle u, const float matrix[])
const { | |
190 this->setMatrices<4>(u, 1, matrix); | |
191 } | |
192 | |
193 void GrVkProgramDataManager::setMatrix4fv(UniformHandle u, int arrayCount, const
float m[]) const { | |
194 this->setMatrices<4>(u, arrayCount, m); | |
195 } | |
196 | |
197 template<int N> struct set_uniform_matrix; | |
198 | |
199 template<int N> inline void GrVkProgramDataManager::setMatrices(UniformHandle u, | |
200 int arrayCount, | |
201 const float matr
ices[]) const { | |
202 const Uniform& uni = fUniforms[u.toIndex()]; | |
203 SkASSERT(uni.fType == kMat22f_GrSLType + (N - 2)); | |
204 SkASSERT(arrayCount > 0); | |
205 SkASSERT(arrayCount <= uni.fArrayCount || | |
206 (1 == arrayCount && GrGLSLShaderVar::kNonArray == uni.fArrayCount))
; | |
207 SkASSERT(GrVkUniformHandler::kUniformBufferDescSet == uni.fSetNumber); | |
208 | |
209 void* buffer; | |
210 if (GrVkUniformHandler::kVertexBinding == uni.fBinding) { | |
211 buffer = fVertexUniformData.get(); | |
212 fVertexUniformsDirty = true; | |
213 } else { | |
214 SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding); | |
215 buffer = fFragmentUniformData.get(); | |
216 fFragmentUniformsDirty = true; | |
217 } | |
218 | |
219 set_uniform_matrix<N>::set(buffer, uni.fOffset, arrayCount, matrices); | |
220 } | |
221 | |
222 template<int N> struct set_uniform_matrix { | |
223 inline static void set(void* buffer, int uniformOffset, int count, const flo
at matrices[]) { | |
224 GR_STATIC_ASSERT(sizeof(float) == 4); | |
225 buffer = static_cast<char*>(buffer) + uniformOffset; | |
226 for (int i = 0; i < count; ++i) { | |
227 const float* matrix = &matrices[N * N * i]; | |
228 memcpy(buffer, &matrix[0], N * sizeof(float)); | |
229 buffer = static_cast<char*>(buffer) + 4*sizeof(float); | |
230 memcpy(buffer, &matrix[3], N * sizeof(float)); | |
231 buffer = static_cast<char*>(buffer) + 4*sizeof(float); | |
232 memcpy(buffer, &matrix[6], N * sizeof(float)); | |
233 buffer = static_cast<char*>(buffer) + 4*sizeof(float); | |
234 } | |
235 } | |
236 }; | |
237 | |
238 template<> struct set_uniform_matrix<4> { | |
239 inline static void set(void* buffer, int uniformOffset, int count, const flo
at matrices[]) { | |
240 GR_STATIC_ASSERT(sizeof(float) == 4); | |
241 buffer = static_cast<char*>(buffer) + uniformOffset; | |
242 memcpy(buffer, matrices, count * 16 * sizeof(float)); | |
243 } | |
244 }; | |
245 | |
246 void GrVkProgramDataManager::uploadUniformBuffers(const GrVkGpu* gpu, | |
247 GrVkUniformBuffer* vertexBuffe
r, | |
248 GrVkUniformBuffer* fragmentBuf
fer) const { | |
249 if (vertexBuffer && fVertexUniformsDirty) { | |
250 vertexBuffer->addMemoryBarrier(gpu, | |
251 VK_ACCESS_UNIFORM_READ_BIT, | |
252 VK_ACCESS_HOST_WRITE_BIT, | |
253 VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, | |
254 VK_PIPELINE_STAGE_HOST_BIT, | |
255 false); | |
256 SkAssertResult(vertexBuffer->updateData(gpu, fVertexUniformData.get(), f
VertexUniformSize)); | |
257 fVertexUniformsDirty = false; | |
258 } | |
259 | |
260 if (fragmentBuffer && fFragmentUniformsDirty) { | |
261 fragmentBuffer->addMemoryBarrier(gpu, | |
262 VK_ACCESS_UNIFORM_READ_BIT, | |
263 VK_ACCESS_HOST_WRITE_BIT, | |
264 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, | |
265 VK_PIPELINE_STAGE_HOST_BIT, | |
266 false); | |
267 SkAssertResult(fragmentBuffer->updateData(gpu, fFragmentUniformData.get(
), | |
268 fFragmentUniformSize)); | |
269 fFragmentUniformsDirty = false; | |
270 } | |
271 } | |
272 | |
OLD | NEW |