blob: 5d96bd70191ee379e1a511f157cd4ff86db1be1a [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
egdaniel22281c12016-03-23 13:49:40 -07008#include "GrVkPipelineStateDataManager.h"
egdaniel42701e92016-02-26 08:02:55 -08009
10#include "GrVkGpu.h"
11#include "GrVkUniformBuffer.h"
12
egdaniel22281c12016-03-23 13:49:40 -070013GrVkPipelineStateDataManager::GrVkPipelineStateDataManager(const UniformInfoArray& uniforms,
Greg Daniel18f96022017-05-04 15:09:03 -040014 uint32_t geometryUniformSize,
egdaniel22281c12016-03-23 13:49:40 -070015 uint32_t fragmentUniformSize)
Greg Daniel18f96022017-05-04 15:09:03 -040016 : fGeometryUniformSize(geometryUniformSize)
jvanverth910114a2016-03-08 12:09:27 -080017 , fFragmentUniformSize(fragmentUniformSize)
Greg Daniel18f96022017-05-04 15:09:03 -040018 , fGeometryUniformsDirty(false)
jvanverth910114a2016-03-08 12:09:27 -080019 , fFragmentUniformsDirty(false) {
Greg Daniel18f96022017-05-04 15:09:03 -040020 fGeometryUniformData.reset(geometryUniformSize);
egdaniel42701e92016-02-26 08:02:55 -080021 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 UniformHandles 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];
Brian Salomon99938a82016-11-21 13:41:08 -050029 SkASSERT(GrShaderVar::kNonArray == uniformInfo.fVariable.getArrayCount() ||
egdaniel42701e92016-02-26 08:02:55 -080030 uniformInfo.fVariable.getArrayCount() > 0);
31 SkDEBUGCODE(
32 uniform.fArrayCount = uniformInfo.fVariable.getArrayCount();
33 uniform.fType = uniformInfo.fVariable.getType();
34 );
Greg Daniel18f96022017-05-04 15:09:03 -040035
36 if (kVertex_GrShaderFlag == uniformInfo.fVisibility ||
37 kGeometry_GrShaderFlag == uniformInfo.fVisibility) {
38 uniform.fBinding = GrVkUniformHandler::kGeometryBinding;
39 } else {
40 SkASSERT(kFragment_GrShaderFlag == uniformInfo.fVisibility);
41 uniform.fBinding = GrVkUniformHandler::kFragBinding;
42 }
egdaniel42701e92016-02-26 08:02:55 -080043 uniform.fOffset = uniformInfo.fUBOffset;
egdaniel42701e92016-02-26 08:02:55 -080044 }
45}
46
egdaniel22281c12016-03-23 13:49:40 -070047void* GrVkPipelineStateDataManager::getBufferPtrAndMarkDirty(const Uniform& uni) const {
jvanverth910114a2016-03-08 12:09:27 -080048 void* buffer;
Greg Daniel18f96022017-05-04 15:09:03 -040049 if (GrVkUniformHandler::kGeometryBinding == uni.fBinding) {
50 buffer = fGeometryUniformData.get();
51 fGeometryUniformsDirty = true;
52 } else {
jvanverth910114a2016-03-08 12:09:27 -080053 SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
54 buffer = fFragmentUniformData.get();
55 fFragmentUniformsDirty = true;
56 }
57 buffer = static_cast<char*>(buffer)+uni.fOffset;
58 return buffer;
59}
60
fmenozzi497e9e22016-06-21 09:42:12 -070061void GrVkPipelineStateDataManager::set1i(UniformHandle u, int32_t i) const {
62 const Uniform& uni = fUniforms[u.toIndex()];
63 SkASSERT(uni.fType == kInt_GrSLType);
Brian Salomon99938a82016-11-21 13:41:08 -050064 SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
fmenozzi497e9e22016-06-21 09:42:12 -070065 void* buffer = this->getBufferPtrAndMarkDirty(uni);
66 memcpy(buffer, &i, sizeof(int32_t));
67}
68
fmenozzi35a98c72016-07-20 08:26:12 -070069void GrVkPipelineStateDataManager::set1iv(UniformHandle u,
70 int arrayCount,
71 const int32_t v[]) const {
72 const Uniform& uni = fUniforms[u.toIndex()];
73 SkASSERT(uni.fType == kInt_GrSLType);
74 SkASSERT(arrayCount > 0);
75 SkASSERT(arrayCount <= uni.fArrayCount ||
Brian Salomon99938a82016-11-21 13:41:08 -050076 (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
fmenozzi35a98c72016-07-20 08:26:12 -070077
78 void* buffer = this->getBufferPtrAndMarkDirty(uni);
79 SkASSERT(sizeof(int32_t) == 4);
80 for (int i = 0; i < arrayCount; ++i) {
81 const int32_t* curVec = &v[i];
82 memcpy(buffer, curVec, sizeof(int32_t));
83 buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
84 }
85}
86
egdaniel22281c12016-03-23 13:49:40 -070087void GrVkPipelineStateDataManager::set1f(UniformHandle u, float v0) const {
egdaniel42701e92016-02-26 08:02:55 -080088 const Uniform& uni = fUniforms[u.toIndex()];
89 SkASSERT(uni.fType == kFloat_GrSLType);
Brian Salomon99938a82016-11-21 13:41:08 -050090 SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
jvanverth910114a2016-03-08 12:09:27 -080091 void* buffer = this->getBufferPtrAndMarkDirty(uni);
egdaniel42701e92016-02-26 08:02:55 -080092 SkASSERT(sizeof(float) == 4);
93 memcpy(buffer, &v0, sizeof(float));
94}
95
egdaniel22281c12016-03-23 13:49:40 -070096void GrVkPipelineStateDataManager::set1fv(UniformHandle u,
97 int arrayCount,
98 const float v[]) const {
egdaniel42701e92016-02-26 08:02:55 -080099 const Uniform& uni = fUniforms[u.toIndex()];
100 SkASSERT(uni.fType == kFloat_GrSLType);
101 SkASSERT(arrayCount > 0);
102 SkASSERT(arrayCount <= uni.fArrayCount ||
Brian Salomon99938a82016-11-21 13:41:08 -0500103 (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
egdaniel42701e92016-02-26 08:02:55 -0800104
jvanverth910114a2016-03-08 12:09:27 -0800105 void* buffer = this->getBufferPtrAndMarkDirty(uni);
egdaniel42701e92016-02-26 08:02:55 -0800106 SkASSERT(sizeof(float) == 4);
egdaniel4ee1cda2016-02-26 08:18:49 -0800107 for (int i = 0; i < arrayCount; ++i) {
108 const float* curVec = &v[i];
109 memcpy(buffer, curVec, sizeof(float));
110 buffer = static_cast<char*>(buffer) + 4*sizeof(float);
111 }
egdaniel42701e92016-02-26 08:02:55 -0800112}
113
egdaniel22281c12016-03-23 13:49:40 -0700114void GrVkPipelineStateDataManager::set2f(UniformHandle u, float v0, float v1) const {
egdaniel42701e92016-02-26 08:02:55 -0800115 const Uniform& uni = fUniforms[u.toIndex()];
116 SkASSERT(uni.fType == kVec2f_GrSLType);
Brian Salomon99938a82016-11-21 13:41:08 -0500117 SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
jvanverth910114a2016-03-08 12:09:27 -0800118 void* buffer = this->getBufferPtrAndMarkDirty(uni);
egdaniel42701e92016-02-26 08:02:55 -0800119 SkASSERT(sizeof(float) == 4);
120 float v[2] = { v0, v1 };
121 memcpy(buffer, v, 2 * sizeof(float));
122}
123
egdaniel22281c12016-03-23 13:49:40 -0700124void GrVkPipelineStateDataManager::set2fv(UniformHandle u,
125 int arrayCount,
126 const float v[]) const {
egdaniel42701e92016-02-26 08:02:55 -0800127 const Uniform& uni = fUniforms[u.toIndex()];
128 SkASSERT(uni.fType == kVec2f_GrSLType);
129 SkASSERT(arrayCount > 0);
130 SkASSERT(arrayCount <= uni.fArrayCount ||
Brian Salomon99938a82016-11-21 13:41:08 -0500131 (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
egdaniel42701e92016-02-26 08:02:55 -0800132
jvanverth910114a2016-03-08 12:09:27 -0800133 void* buffer = this->getBufferPtrAndMarkDirty(uni);
egdaniel42701e92016-02-26 08:02:55 -0800134 SkASSERT(sizeof(float) == 4);
egdaniel4ee1cda2016-02-26 08:18:49 -0800135 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 }
egdaniel42701e92016-02-26 08:02:55 -0800140}
141
egdaniel22281c12016-03-23 13:49:40 -0700142void GrVkPipelineStateDataManager::set3f(UniformHandle u, float v0, float v1, float v2) const {
egdaniel42701e92016-02-26 08:02:55 -0800143 const Uniform& uni = fUniforms[u.toIndex()];
144 SkASSERT(uni.fType == kVec3f_GrSLType);
Brian Salomon99938a82016-11-21 13:41:08 -0500145 SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
jvanverth910114a2016-03-08 12:09:27 -0800146 void* buffer = this->getBufferPtrAndMarkDirty(uni);
egdaniel42701e92016-02-26 08:02:55 -0800147 SkASSERT(sizeof(float) == 4);
148 float v[3] = { v0, v1, v2 };
149 memcpy(buffer, v, 3 * sizeof(float));
150}
151
egdaniel22281c12016-03-23 13:49:40 -0700152void GrVkPipelineStateDataManager::set3fv(UniformHandle u,
153 int arrayCount,
154 const float v[]) const {
egdaniel42701e92016-02-26 08:02:55 -0800155 const Uniform& uni = fUniforms[u.toIndex()];
156 SkASSERT(uni.fType == kVec3f_GrSLType);
157 SkASSERT(arrayCount > 0);
158 SkASSERT(arrayCount <= uni.fArrayCount ||
Brian Salomon99938a82016-11-21 13:41:08 -0500159 (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
egdaniel42701e92016-02-26 08:02:55 -0800160
jvanverth910114a2016-03-08 12:09:27 -0800161 void* buffer = this->getBufferPtrAndMarkDirty(uni);
egdaniel42701e92016-02-26 08:02:55 -0800162 SkASSERT(sizeof(float) == 4);
egdaniel4ee1cda2016-02-26 08:18:49 -0800163 for (int i = 0; i < arrayCount; ++i) {
164 const float* curVec = &v[3 * i];
165 memcpy(buffer, curVec, 3 * sizeof(float));
166 buffer = static_cast<char*>(buffer) + 4*sizeof(float);
167 }
egdaniel42701e92016-02-26 08:02:55 -0800168}
169
egdaniel22281c12016-03-23 13:49:40 -0700170void GrVkPipelineStateDataManager::set4f(UniformHandle u,
171 float v0,
172 float v1,
173 float v2,
174 float v3) const {
egdaniel42701e92016-02-26 08:02:55 -0800175 const Uniform& uni = fUniforms[u.toIndex()];
176 SkASSERT(uni.fType == kVec4f_GrSLType);
Brian Salomon99938a82016-11-21 13:41:08 -0500177 SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
jvanverth910114a2016-03-08 12:09:27 -0800178 void* buffer = this->getBufferPtrAndMarkDirty(uni);
egdaniel42701e92016-02-26 08:02:55 -0800179 SkASSERT(sizeof(float) == 4);
180 float v[4] = { v0, v1, v2, v3 };
181 memcpy(buffer, v, 4 * sizeof(float));
182}
183
egdaniel22281c12016-03-23 13:49:40 -0700184void GrVkPipelineStateDataManager::set4fv(UniformHandle u,
185 int arrayCount,
186 const float v[]) const {
egdaniel42701e92016-02-26 08:02:55 -0800187 const Uniform& uni = fUniforms[u.toIndex()];
188 SkASSERT(uni.fType == kVec4f_GrSLType);
189 SkASSERT(arrayCount > 0);
190 SkASSERT(arrayCount <= uni.fArrayCount ||
Brian Salomon99938a82016-11-21 13:41:08 -0500191 (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
egdaniel42701e92016-02-26 08:02:55 -0800192
jvanverth910114a2016-03-08 12:09:27 -0800193 void* buffer = this->getBufferPtrAndMarkDirty(uni);
egdaniel42701e92016-02-26 08:02:55 -0800194 SkASSERT(sizeof(float) == 4);
195 memcpy(buffer, v, arrayCount * 4 * sizeof(float));
196}
197
egdaniel22281c12016-03-23 13:49:40 -0700198void GrVkPipelineStateDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const {
cdalton8d988b32016-03-07 15:39:09 -0800199 this->setMatrices<2>(u, 1, matrix);
200}
201
egdaniel22281c12016-03-23 13:49:40 -0700202void GrVkPipelineStateDataManager::setMatrix2fv(UniformHandle u,
203 int arrayCount,
204 const float m[]) const {
cdalton8d988b32016-03-07 15:39:09 -0800205 this->setMatrices<2>(u, arrayCount, m);
206}
207
egdaniel22281c12016-03-23 13:49:40 -0700208void GrVkPipelineStateDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const {
cdalton8d988b32016-03-07 15:39:09 -0800209 this->setMatrices<3>(u, 1, matrix);
egdaniel42701e92016-02-26 08:02:55 -0800210}
211
egdaniel22281c12016-03-23 13:49:40 -0700212void GrVkPipelineStateDataManager::setMatrix3fv(UniformHandle u,
213 int arrayCount,
214 const float m[]) const {
cdalton8d988b32016-03-07 15:39:09 -0800215 this->setMatrices<3>(u, arrayCount, m);
egdaniel42701e92016-02-26 08:02:55 -0800216}
217
egdaniel22281c12016-03-23 13:49:40 -0700218void GrVkPipelineStateDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const {
cdalton8d988b32016-03-07 15:39:09 -0800219 this->setMatrices<4>(u, 1, matrix);
egdaniel42701e92016-02-26 08:02:55 -0800220}
221
egdaniel22281c12016-03-23 13:49:40 -0700222void GrVkPipelineStateDataManager::setMatrix4fv(UniformHandle u,
223 int arrayCount,
224 const float m[]) const {
cdalton8d988b32016-03-07 15:39:09 -0800225 this->setMatrices<4>(u, arrayCount, m);
226}
227
228template<int N> struct set_uniform_matrix;
229
egdaniel22281c12016-03-23 13:49:40 -0700230template<int N> inline void GrVkPipelineStateDataManager::setMatrices(UniformHandle u,
231 int arrayCount,
232 const float matrices[]) const {
egdaniel42701e92016-02-26 08:02:55 -0800233 const Uniform& uni = fUniforms[u.toIndex()];
cdalton8d988b32016-03-07 15:39:09 -0800234 SkASSERT(uni.fType == kMat22f_GrSLType + (N - 2));
egdaniel42701e92016-02-26 08:02:55 -0800235 SkASSERT(arrayCount > 0);
236 SkASSERT(arrayCount <= uni.fArrayCount ||
Brian Salomon99938a82016-11-21 13:41:08 -0500237 (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
egdaniel42701e92016-02-26 08:02:55 -0800238
239 void* buffer;
Greg Daniel18f96022017-05-04 15:09:03 -0400240 if (GrVkUniformHandler::kGeometryBinding == uni.fBinding) {
241 buffer = fGeometryUniformData.get();
242 fGeometryUniformsDirty = true;
egdaniel42701e92016-02-26 08:02:55 -0800243 } else {
244 SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
245 buffer = fFragmentUniformData.get();
jvanverth910114a2016-03-08 12:09:27 -0800246 fFragmentUniformsDirty = true;
egdaniel42701e92016-02-26 08:02:55 -0800247 }
cdalton8d988b32016-03-07 15:39:09 -0800248
249 set_uniform_matrix<N>::set(buffer, uni.fOffset, arrayCount, matrices);
egdaniel42701e92016-02-26 08:02:55 -0800250}
251
cdalton8d988b32016-03-07 15:39:09 -0800252template<int N> struct set_uniform_matrix {
253 inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
254 GR_STATIC_ASSERT(sizeof(float) == 4);
255 buffer = static_cast<char*>(buffer) + uniformOffset;
256 for (int i = 0; i < count; ++i) {
257 const float* matrix = &matrices[N * N * i];
egdaniel75d2bfc2016-07-07 08:04:08 -0700258 for (int j = 0; j < N; ++j) {
259 memcpy(buffer, &matrix[j * N], N * sizeof(float));
260 buffer = static_cast<char*>(buffer) + 4 * sizeof(float);
261 }
cdalton8d988b32016-03-07 15:39:09 -0800262 }
263 }
264};
265
266template<> struct set_uniform_matrix<4> {
267 inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
268 GR_STATIC_ASSERT(sizeof(float) == 4);
269 buffer = static_cast<char*>(buffer) + uniformOffset;
270 memcpy(buffer, matrices, count * 16 * sizeof(float));
271 }
272};
273
jvanvertha584de92016-06-30 09:10:52 -0700274bool GrVkPipelineStateDataManager::uploadUniformBuffers(GrVkGpu* gpu,
Greg Daniel18f96022017-05-04 15:09:03 -0400275 GrVkUniformBuffer* geometryBuffer,
egdaniel22281c12016-03-23 13:49:40 -0700276 GrVkUniformBuffer* fragmentBuffer) const {
egdaniel7cbffda2016-04-08 13:27:53 -0700277 bool updatedBuffer = false;
Greg Daniel18f96022017-05-04 15:09:03 -0400278 if (geometryBuffer && fGeometryUniformsDirty) {
279 SkAssertResult(geometryBuffer->updateData(gpu, fGeometryUniformData.get(),
280 fGeometryUniformSize, &updatedBuffer));
281 fGeometryUniformsDirty = false;
egdaniel42701e92016-02-26 08:02:55 -0800282 }
jvanverth910114a2016-03-08 12:09:27 -0800283 if (fragmentBuffer && fFragmentUniformsDirty) {
egdaniel42701e92016-02-26 08:02:55 -0800284 SkAssertResult(fragmentBuffer->updateData(gpu, fFragmentUniformData.get(),
egdaniel7cbffda2016-04-08 13:27:53 -0700285 fFragmentUniformSize, &updatedBuffer));
jvanverth910114a2016-03-08 12:09:27 -0800286 fFragmentUniformsDirty = false;
egdaniel42701e92016-02-26 08:02:55 -0800287 }
Greg Daniel18f96022017-05-04 15:09:03 -0400288
egdaniel7cbffda2016-04-08 13:27:53 -0700289 return updatedBuffer;
egdaniel42701e92016-02-26 08:02:55 -0800290}