| 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 |