1 /*
2 * Copyright 2019 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 "src/gpu/dawn/GrDawnProgramDataManager.h"
9
10 #include "src/gpu/dawn/GrDawnGpu.h"
11
GrDawnProgramDataManager(const UniformInfoArray & uniforms,uint32_t uniformBufferSize)12 GrDawnProgramDataManager::GrDawnProgramDataManager(const UniformInfoArray& uniforms,
13 uint32_t uniformBufferSize)
14 : fUniformBufferSize(uniformBufferSize)
15 , fUniformsDirty(false) {
16 fUniformData.reset(uniformBufferSize);
17 memset(fUniformData.get(), 0, fUniformBufferSize);
18 fUniforms.push_back_n(uniforms.count());
19 // We must add uniforms in same order is the UniformInfoArray so that UniformHandles already
20 // owned by other objects will still match up here.
21 int i = 0;
22 for (const auto& uniformInfo : uniforms.items()) {
23 Uniform& uniform = fUniforms[i];
24 SkDEBUGCODE(
25 uniform.fArrayCount = uniformInfo.fVar.getArrayCount();
26 uniform.fType = uniformInfo.fVar.getType();
27 )
28 uniform.fOffset = uniformInfo.fUBOOffset;
29 ++i;
30 }
31 }
32
getBufferPtrAndMarkDirty(const Uniform & uni) const33 void* GrDawnProgramDataManager::getBufferPtrAndMarkDirty(const Uniform& uni) const {
34 fUniformsDirty = true;
35 return static_cast<char*>(fUniformData.get()) + uni.fOffset;
36 }
37
set1i(UniformHandle u,int32_t i) const38 void GrDawnProgramDataManager::set1i(UniformHandle u, int32_t i) const {
39 const Uniform& uni = fUniforms[u.toIndex()];
40 void* buffer = this->getBufferPtrAndMarkDirty(uni);
41 memcpy(buffer, &i, sizeof(int32_t));
42 }
43
set1iv(UniformHandle u,int arrayCount,const int32_t v[]) const44 void GrDawnProgramDataManager::set1iv(UniformHandle u, int arrayCount, const int32_t v[]) const {
45 const Uniform& uni = fUniforms[u.toIndex()];
46 uint32_t* buffer = static_cast<uint32_t*>(this->getBufferPtrAndMarkDirty(uni));
47 for (int i = 0; i < arrayCount; ++i) {
48 const int32_t* curVec = &v[i];
49 memcpy(buffer, curVec, sizeof(int32_t));
50 buffer += 4;
51 }
52 }
53
set2i(UniformHandle u,int32_t i0,int32_t i1) const54 void GrDawnProgramDataManager::set2i(UniformHandle u, int32_t i0, int32_t i1) const {
55 const Uniform& uni = fUniforms[u.toIndex()];
56 void* buffer = this->getBufferPtrAndMarkDirty(uni);
57 int32_t v[2] = { i0, i1 };
58 memcpy(buffer, v, 2 * sizeof(int32_t));
59 }
60
set2iv(UniformHandle u,int arrayCount,const int32_t v[]) const61 void GrDawnProgramDataManager::set2iv(UniformHandle u, int arrayCount, const int32_t v[]) const {
62 const Uniform& uni = fUniforms[u.toIndex()];
63 uint32_t* buffer = static_cast<uint32_t*>(this->getBufferPtrAndMarkDirty(uni));
64 for (int i = 0; i < arrayCount; ++i) {
65 const int32_t* curVec = &v[2 * i];
66 memcpy(buffer, curVec, 2 * sizeof(int32_t));
67 buffer += 4;
68 }
69 }
70
set3i(UniformHandle u,int32_t i0,int32_t i1,int32_t i2) const71 void GrDawnProgramDataManager::set3i(UniformHandle u, int32_t i0, int32_t i1, int32_t i2) const {
72 const Uniform& uni = fUniforms[u.toIndex()];
73 void* buffer = this->getBufferPtrAndMarkDirty(uni);
74 int32_t v[3] = { i0, i1, i2 };
75 memcpy(buffer, v, 3 * sizeof(int32_t));
76 }
77
set3iv(UniformHandle u,int arrayCount,const int32_t v[]) const78 void GrDawnProgramDataManager::set3iv(UniformHandle u, int arrayCount, const int32_t v[]) const {
79 const Uniform& uni = fUniforms[u.toIndex()];
80 uint32_t* buffer = static_cast<uint32_t*>(this->getBufferPtrAndMarkDirty(uni));
81 for (int i = 0; i < arrayCount; ++i) {
82 const int32_t* curVec = &v[3 * i];
83 memcpy(buffer, curVec, 3 * sizeof(int32_t));
84 buffer += 4;
85 }
86 }
87
set4i(UniformHandle u,int32_t i0,int32_t i1,int32_t i2,int32_t i3) const88 void GrDawnProgramDataManager::set4i(UniformHandle u,
89 int32_t i0,
90 int32_t i1,
91 int32_t i2,
92 int32_t i3) const {
93 const Uniform& uni = fUniforms[u.toIndex()];
94 void* buffer = this->getBufferPtrAndMarkDirty(uni);
95 int32_t v[4] = { i0, i1, i2, i3 };
96 memcpy(buffer, v, sizeof(v));
97 }
98
set4iv(UniformHandle u,int arrayCount,const int32_t v[]) const99 void GrDawnProgramDataManager::set4iv(UniformHandle u, int arrayCount, const int32_t v[]) const {
100 const Uniform& uni = fUniforms[u.toIndex()];
101 uint32_t* buffer = static_cast<uint32_t*>(this->getBufferPtrAndMarkDirty(uni));
102 for (int i = 0; i < arrayCount; ++i) {
103 const int32_t* curVec = &v[4 * i];
104 memcpy(buffer, curVec, 4 * sizeof(int32_t));
105 buffer += 4;
106 }
107 }
108
set1f(UniformHandle u,float v0) const109 void GrDawnProgramDataManager::set1f(UniformHandle u, float v0) const {
110 const Uniform& uni = fUniforms[u.toIndex()];
111 void* buffer = this->getBufferPtrAndMarkDirty(uni);
112 memcpy(buffer, &v0, sizeof(float));
113 }
114
set1fv(UniformHandle u,int arrayCount,const float v[]) const115 void GrDawnProgramDataManager::set1fv(UniformHandle u, int arrayCount, const float v[]) const {
116 const Uniform& uni = fUniforms[u.toIndex()];
117 void* buffer = this->getBufferPtrAndMarkDirty(uni);
118 for (int i = 0; i < arrayCount; ++i) {
119 const float* curVec = &v[i];
120 memcpy(buffer, curVec, sizeof(float));
121 buffer = static_cast<char*>(buffer) + 4*sizeof(float);
122 }
123 }
124
set2f(UniformHandle u,float v0,float v1) const125 void GrDawnProgramDataManager::set2f(UniformHandle u, float v0, float v1) const {
126 const Uniform& uni = fUniforms[u.toIndex()];
127 void* buffer = this->getBufferPtrAndMarkDirty(uni);
128 float v[2] = { v0, v1 };
129 memcpy(buffer, v, 2 * sizeof(float));
130 }
131
set2fv(UniformHandle u,int arrayCount,const float v[]) const132 void GrDawnProgramDataManager::set2fv(UniformHandle u, int arrayCount, const float v[]) const {
133 const Uniform& uni = fUniforms[u.toIndex()];
134 void* buffer = this->getBufferPtrAndMarkDirty(uni);
135 for (int i = 0; i < arrayCount; ++i) {
136 const float* curVec = &v[2 * i];
137 memcpy(buffer, curVec, 2 * sizeof(float));
138 buffer = static_cast<char*>(buffer) + 4*sizeof(float);
139 }
140 }
141
set3f(UniformHandle u,float v0,float v1,float v2) const142 void GrDawnProgramDataManager::set3f(UniformHandle u, float v0, float v1, float v2) const {
143 const Uniform& uni = fUniforms[u.toIndex()];
144 void* buffer = this->getBufferPtrAndMarkDirty(uni);
145 float v[3] = { v0, v1, v2 };
146 memcpy(buffer, v, 3 * sizeof(float));
147 }
148
set3fv(UniformHandle u,int arrayCount,const float v[]) const149 void GrDawnProgramDataManager::set3fv(UniformHandle u, int arrayCount, const float v[]) const {
150 const Uniform& uni = fUniforms[u.toIndex()];
151 void* buffer = this->getBufferPtrAndMarkDirty(uni);
152 for (int i = 0; i < arrayCount; ++i) {
153 const float* curVec = &v[3 * i];
154 memcpy(buffer, curVec, 3 * sizeof(float));
155 buffer = static_cast<char*>(buffer) + 4*sizeof(float);
156 }
157 }
158
set4f(UniformHandle u,float v0,float v1,float v2,float v3) const159 void GrDawnProgramDataManager::set4f(UniformHandle u,
160 float v0,
161 float v1,
162 float v2,
163 float v3) const {
164 const Uniform& uni = fUniforms[u.toIndex()];
165 void* buffer = this->getBufferPtrAndMarkDirty(uni);
166 float v[4] = { v0, v1, v2, v3 };
167 memcpy(buffer, v, 4 * sizeof(float));
168 }
169
set4fv(UniformHandle u,int arrayCount,const float v[]) const170 void GrDawnProgramDataManager::set4fv(UniformHandle u, int arrayCount, const float v[]) const {
171 const Uniform& uni = fUniforms[u.toIndex()];
172 void* buffer = this->getBufferPtrAndMarkDirty(uni);
173 memcpy(buffer, v, arrayCount * 4 * sizeof(float));
174 }
175
setMatrix2f(UniformHandle u,const float matrix[]) const176 void GrDawnProgramDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const {
177 this->setMatrices<2>(u, 1, matrix);
178 }
179
setMatrix2fv(UniformHandle u,int arrayCount,const float m[]) const180 void GrDawnProgramDataManager::setMatrix2fv(UniformHandle u,
181 int arrayCount,
182 const float m[]) const {
183 this->setMatrices<2>(u, arrayCount, m);
184 }
185
setMatrix3f(UniformHandle u,const float matrix[]) const186 void GrDawnProgramDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const {
187 this->setMatrices<3>(u, 1, matrix);
188 }
189
setMatrix3fv(UniformHandle u,int arrayCount,const float m[]) const190 void GrDawnProgramDataManager::setMatrix3fv(UniformHandle u,
191 int arrayCount,
192 const float m[]) const {
193 this->setMatrices<3>(u, arrayCount, m);
194 }
195
setMatrix4f(UniformHandle u,const float matrix[]) const196 void GrDawnProgramDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const {
197 this->setMatrices<4>(u, 1, matrix);
198 }
199
setMatrix4fv(UniformHandle u,int arrayCount,const float m[]) const200 void GrDawnProgramDataManager::setMatrix4fv(UniformHandle u,
201 int arrayCount,
202 const float m[]) const {
203 this->setMatrices<4>(u, arrayCount, m);
204 }
205
206 template<int N> struct set_uniform_matrix;
207
setMatrices(UniformHandle u,int arrayCount,const float matrices[]) const208 template<int N> inline void GrDawnProgramDataManager::setMatrices(UniformHandle u,
209 int arrayCount,
210 const float matrices[]) const {
211 const Uniform& uni = fUniforms[u.toIndex()];
212 fUniformsDirty = true;
213 set_uniform_matrix<N>::set(fUniformData.get(), uni.fOffset, arrayCount, matrices);
214 }
215
216 template<int N> struct set_uniform_matrix {
setset_uniform_matrix217 inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
218 static_assert(sizeof(float) == 4);
219 buffer = static_cast<char*>(buffer) + uniformOffset;
220 for (int i = 0; i < count; ++i) {
221 const float* matrix = &matrices[N * N * i];
222 for (int j = 0; j < N; ++j) {
223 memcpy(buffer, &matrix[j * N], N * sizeof(float));
224 buffer = static_cast<char*>(buffer) + 4 * sizeof(float);
225 }
226 }
227 }
228 };
229
230 template<> struct set_uniform_matrix<4> {
setset_uniform_matrix231 inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
232 static_assert(sizeof(float) == 4);
233 buffer = static_cast<char*>(buffer) + uniformOffset;
234 memcpy(buffer, matrices, count * 16 * sizeof(float));
235 }
236 };
237
uploadUniformBuffers(void * dest) const238 void GrDawnProgramDataManager::uploadUniformBuffers(void* dest) const {
239 if (fUniformsDirty) {
240 memcpy(dest, fUniformData.get(), fUniformBufferSize);
241 }
242 }
243