Home | History | Annotate | Download | only in vk
      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 "GrVkPipelineStateDataManager.h"
      9 
     10 #include "GrVkGpu.h"
     11 #include "GrVkUniformBuffer.h"
     12 
     13 GrVkPipelineStateDataManager::GrVkPipelineStateDataManager(const UniformInfoArray& uniforms,
     14                                                            uint32_t geometryUniformSize,
     15                                                            uint32_t fragmentUniformSize)
     16     : fGeometryUniformSize(geometryUniformSize)
     17     , fFragmentUniformSize(fragmentUniformSize)
     18     , fGeometryUniformsDirty(false)
     19     , fFragmentUniformsDirty(false) {
     20     fGeometryUniformData.reset(geometryUniformSize);
     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 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];
     29         SkASSERT(GrShaderVar::kNonArray == uniformInfo.fVariable.getArrayCount() ||
     30                  uniformInfo.fVariable.getArrayCount() > 0);
     31         SkDEBUGCODE(
     32             uniform.fArrayCount = uniformInfo.fVariable.getArrayCount();
     33             uniform.fType = uniformInfo.fVariable.getType();
     34         );
     35 
     36         if (!(kFragment_GrShaderFlag & uniformInfo.fVisibility)) {
     37             uniform.fBinding = GrVkUniformHandler::kGeometryBinding;
     38         } else {
     39             SkASSERT(kFragment_GrShaderFlag == uniformInfo.fVisibility);
     40             uniform.fBinding = GrVkUniformHandler::kFragBinding;
     41         }
     42         uniform.fOffset = uniformInfo.fUBOffset;
     43     }
     44 }
     45 
     46 void* GrVkPipelineStateDataManager::getBufferPtrAndMarkDirty(const Uniform& uni) const {
     47     void* buffer;
     48     if (GrVkUniformHandler::kGeometryBinding == uni.fBinding) {
     49         buffer = fGeometryUniformData.get();
     50         fGeometryUniformsDirty = true;
     51     } else {
     52         SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
     53         buffer = fFragmentUniformData.get();
     54         fFragmentUniformsDirty = true;
     55     }
     56     buffer = static_cast<char*>(buffer)+uni.fOffset;
     57     return buffer;
     58 }
     59 
     60 void GrVkPipelineStateDataManager::set1i(UniformHandle u, int32_t i) const {
     61     const Uniform& uni = fUniforms[u.toIndex()];
     62     SkASSERT(uni.fType == kInt_GrSLType);
     63     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
     64     void* buffer = this->getBufferPtrAndMarkDirty(uni);
     65     memcpy(buffer, &i, sizeof(int32_t));
     66 }
     67 
     68 void GrVkPipelineStateDataManager::set1iv(UniformHandle u,
     69                                           int arrayCount,
     70                                           const int32_t v[]) const {
     71     const Uniform& uni = fUniforms[u.toIndex()];
     72     SkASSERT(uni.fType == kInt_GrSLType);
     73     SkASSERT(arrayCount > 0);
     74     SkASSERT(arrayCount <= uni.fArrayCount ||
     75              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
     76 
     77     void* buffer = this->getBufferPtrAndMarkDirty(uni);
     78     SkASSERT(sizeof(int32_t) == 4);
     79     for (int i = 0; i < arrayCount; ++i) {
     80         const int32_t* curVec = &v[i];
     81         memcpy(buffer, curVec, sizeof(int32_t));
     82         buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
     83     }
     84 }
     85 
     86 void GrVkPipelineStateDataManager::set1f(UniformHandle u, float v0) const {
     87     const Uniform& uni = fUniforms[u.toIndex()];
     88     SkASSERT(uni.fType == kFloat_GrSLType);
     89     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
     90     void* buffer = this->getBufferPtrAndMarkDirty(uni);
     91     SkASSERT(sizeof(float) == 4);
     92     memcpy(buffer, &v0, sizeof(float));
     93 }
     94 
     95 void GrVkPipelineStateDataManager::set1fv(UniformHandle u,
     96                                           int arrayCount,
     97                                           const float v[]) const {
     98     const Uniform& uni = fUniforms[u.toIndex()];
     99     SkASSERT(uni.fType == kFloat_GrSLType);
    100     SkASSERT(arrayCount > 0);
    101     SkASSERT(arrayCount <= uni.fArrayCount ||
    102              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
    103 
    104     void* buffer = this->getBufferPtrAndMarkDirty(uni);
    105     SkASSERT(sizeof(float) == 4);
    106     for (int i = 0; i < arrayCount; ++i) {
    107         const float* curVec = &v[i];
    108         memcpy(buffer, curVec, sizeof(float));
    109         buffer = static_cast<char*>(buffer) + 4*sizeof(float);
    110     }
    111 }
    112 
    113 void GrVkPipelineStateDataManager::set2f(UniformHandle u, float v0, float v1) const {
    114     const Uniform& uni = fUniforms[u.toIndex()];
    115     SkASSERT(uni.fType == kVec2f_GrSLType);
    116     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
    117     void* buffer = this->getBufferPtrAndMarkDirty(uni);
    118     SkASSERT(sizeof(float) == 4);
    119     float v[2] = { v0, v1 };
    120     memcpy(buffer, v, 2 * sizeof(float));
    121 }
    122 
    123 void GrVkPipelineStateDataManager::set2fv(UniformHandle u,
    124                                           int arrayCount,
    125                                           const float v[]) const {
    126     const Uniform& uni = fUniforms[u.toIndex()];
    127     SkASSERT(uni.fType == kVec2f_GrSLType);
    128     SkASSERT(arrayCount > 0);
    129     SkASSERT(arrayCount <= uni.fArrayCount ||
    130              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
    131 
    132     void* buffer = this->getBufferPtrAndMarkDirty(uni);
    133     SkASSERT(sizeof(float) == 4);
    134     for (int i = 0; i < arrayCount; ++i) {
    135         const float* curVec = &v[2 * i];
    136         memcpy(buffer, curVec, 2 * sizeof(float));
    137         buffer = static_cast<char*>(buffer) + 4*sizeof(float);
    138     }
    139 }
    140 
    141 void GrVkPipelineStateDataManager::set3f(UniformHandle u, float v0, float v1, float v2) const {
    142     const Uniform& uni = fUniforms[u.toIndex()];
    143     SkASSERT(uni.fType == kVec3f_GrSLType);
    144     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
    145     void* buffer = this->getBufferPtrAndMarkDirty(uni);
    146     SkASSERT(sizeof(float) == 4);
    147     float v[3] = { v0, v1, v2 };
    148     memcpy(buffer, v, 3 * sizeof(float));
    149 }
    150 
    151 void GrVkPipelineStateDataManager::set3fv(UniformHandle u,
    152                                           int arrayCount,
    153                                           const float v[]) const {
    154     const Uniform& uni = fUniforms[u.toIndex()];
    155     SkASSERT(uni.fType == kVec3f_GrSLType);
    156     SkASSERT(arrayCount > 0);
    157     SkASSERT(arrayCount <= uni.fArrayCount ||
    158              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
    159 
    160     void* buffer = this->getBufferPtrAndMarkDirty(uni);
    161     SkASSERT(sizeof(float) == 4);
    162     for (int i = 0; i < arrayCount; ++i) {
    163         const float* curVec = &v[3 * i];
    164         memcpy(buffer, curVec, 3 * sizeof(float));
    165         buffer = static_cast<char*>(buffer) + 4*sizeof(float);
    166     }
    167 }
    168 
    169 void GrVkPipelineStateDataManager::set4f(UniformHandle u,
    170                                          float v0,
    171                                          float v1,
    172                                          float v2,
    173                                          float v3) const {
    174     const Uniform& uni = fUniforms[u.toIndex()];
    175     SkASSERT(uni.fType == kVec4f_GrSLType);
    176     SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
    177     void* buffer = this->getBufferPtrAndMarkDirty(uni);
    178     SkASSERT(sizeof(float) == 4);
    179     float v[4] = { v0, v1, v2, v3 };
    180     memcpy(buffer, v, 4 * sizeof(float));
    181 }
    182 
    183 void GrVkPipelineStateDataManager::set4fv(UniformHandle u,
    184                                           int arrayCount,
    185                                           const float v[]) const {
    186     const Uniform& uni = fUniforms[u.toIndex()];
    187     SkASSERT(uni.fType == kVec4f_GrSLType);
    188     SkASSERT(arrayCount > 0);
    189     SkASSERT(arrayCount <= uni.fArrayCount ||
    190              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
    191 
    192     void* buffer = this->getBufferPtrAndMarkDirty(uni);
    193     SkASSERT(sizeof(float) == 4);
    194     memcpy(buffer, v, arrayCount * 4 * sizeof(float));
    195 }
    196 
    197 void GrVkPipelineStateDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const {
    198     this->setMatrices<2>(u, 1, matrix);
    199 }
    200 
    201 void GrVkPipelineStateDataManager::setMatrix2fv(UniformHandle u,
    202                                                 int arrayCount,
    203                                                 const float m[]) const {
    204     this->setMatrices<2>(u, arrayCount, m);
    205 }
    206 
    207 void GrVkPipelineStateDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const {
    208     this->setMatrices<3>(u, 1, matrix);
    209 }
    210 
    211 void GrVkPipelineStateDataManager::setMatrix3fv(UniformHandle u,
    212                                                 int arrayCount,
    213                                                 const float m[]) const {
    214     this->setMatrices<3>(u, arrayCount, m);
    215 }
    216 
    217 void GrVkPipelineStateDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const {
    218     this->setMatrices<4>(u, 1, matrix);
    219 }
    220 
    221 void GrVkPipelineStateDataManager::setMatrix4fv(UniformHandle u,
    222                                                 int arrayCount,
    223                                                 const float m[]) const {
    224     this->setMatrices<4>(u, arrayCount, m);
    225 }
    226 
    227 template<int N> struct set_uniform_matrix;
    228 
    229 template<int N> inline void GrVkPipelineStateDataManager::setMatrices(UniformHandle u,
    230                                                                       int arrayCount,
    231                                                                      const float matrices[]) const {
    232     const Uniform& uni = fUniforms[u.toIndex()];
    233     SkASSERT(uni.fType == kMat22f_GrSLType + (N - 2));
    234     SkASSERT(arrayCount > 0);
    235     SkASSERT(arrayCount <= uni.fArrayCount ||
    236              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
    237 
    238     void* buffer;
    239     if (GrVkUniformHandler::kGeometryBinding == uni.fBinding) {
    240         buffer = fGeometryUniformData.get();
    241         fGeometryUniformsDirty = true;
    242     } else {
    243         SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
    244         buffer = fFragmentUniformData.get();
    245         fFragmentUniformsDirty = true;
    246     }
    247 
    248     set_uniform_matrix<N>::set(buffer, uni.fOffset, arrayCount, matrices);
    249 }
    250 
    251 template<int N> struct set_uniform_matrix {
    252     inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
    253         GR_STATIC_ASSERT(sizeof(float) == 4);
    254         buffer = static_cast<char*>(buffer) + uniformOffset;
    255         for (int i = 0; i < count; ++i) {
    256             const float* matrix = &matrices[N * N * i];
    257             for (int j = 0; j < N; ++j) {
    258                 memcpy(buffer, &matrix[j * N], N * sizeof(float));
    259                 buffer = static_cast<char*>(buffer) + 4 * sizeof(float);
    260             }
    261         }
    262     }
    263 };
    264 
    265 template<> struct set_uniform_matrix<4> {
    266     inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
    267         GR_STATIC_ASSERT(sizeof(float) == 4);
    268         buffer = static_cast<char*>(buffer) + uniformOffset;
    269         memcpy(buffer, matrices, count * 16 * sizeof(float));
    270     }
    271 };
    272 
    273 bool GrVkPipelineStateDataManager::uploadUniformBuffers(GrVkGpu* gpu,
    274                                                         GrVkUniformBuffer* geometryBuffer,
    275                                                         GrVkUniformBuffer* fragmentBuffer) const {
    276     bool updatedBuffer = false;
    277     if (geometryBuffer && fGeometryUniformsDirty) {
    278         SkAssertResult(geometryBuffer->updateData(gpu, fGeometryUniformData.get(),
    279                                                   fGeometryUniformSize, &updatedBuffer));
    280         fGeometryUniformsDirty = false;
    281     }
    282     if (fragmentBuffer && fFragmentUniformsDirty) {
    283         SkAssertResult(fragmentBuffer->updateData(gpu, fFragmentUniformData.get(),
    284                                                   fFragmentUniformSize, &updatedBuffer));
    285         fFragmentUniformsDirty = false;
    286     }
    287 
    288     return updatedBuffer;
    289 }
    290