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