• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "src/gpu/ganesh/vk/GrVkPipelineStateDataManager.h"
9 
10 #include "include/gpu/GrDirectContext.h"
11 #include "src/gpu/ganesh/GrDirectContextPriv.h"
12 #include "src/gpu/ganesh/GrGpuBuffer.h"
13 #include "src/gpu/ganesh/GrResourceProvider.h"
14 #include "src/gpu/ganesh/vk/GrVkCommandBuffer.h"
15 #include "src/gpu/ganesh/vk/GrVkGpu.h"
16 
GrVkPipelineStateDataManager(const UniformInfoArray & uniforms,uint32_t uniformSize,bool usePushConstants)17 GrVkPipelineStateDataManager::GrVkPipelineStateDataManager(const UniformInfoArray& uniforms,
18                                                            uint32_t uniformSize,
19                                                            bool usePushConstants)
20     : INHERITED(uniforms.count(), uniformSize)
21     , fUsePushConstants(usePushConstants) {
22     // We must add uniforms in same order as the UniformInfoArray so that UniformHandles already
23     // owned by other objects will still match up here.
24     int i = 0;
25     GrVkUniformHandler::Layout memLayout = usePushConstants ? GrVkUniformHandler::kStd430Layout
26                                                             : GrVkUniformHandler::kStd140Layout;
27     for (const auto& uniformInfo : uniforms.items()) {
28         Uniform& uniform = fUniforms[i];
29         SkASSERT(GrShaderVar::kNonArray == uniformInfo.fVariable.getArrayCount() ||
30                  uniformInfo.fVariable.getArrayCount() > 0);
31         SkDEBUGCODE(
32             uniform.fArrayCount = uniformInfo.fVariable.getArrayCount();
33         )
34 
35         uniform.fOffset = uniformInfo.fOffsets[memLayout];
36         uniform.fType = uniformInfo.fVariable.getType();
37         ++i;
38     }
39 }
40 
uploadUniforms(GrVkGpu * gpu,VkPipelineLayout layout,GrVkCommandBuffer * commandBuffer)41 std::pair<sk_sp<GrGpuBuffer>, bool> GrVkPipelineStateDataManager::uploadUniforms(
42         GrVkGpu* gpu, VkPipelineLayout layout, GrVkCommandBuffer* commandBuffer) {
43     if (fUniformSize == 0) {
44         return std::make_pair(nullptr, true);
45     }
46     if (fUsePushConstants) {
47         commandBuffer->pushConstants(gpu, layout, gpu->vkCaps().getPushConstantStageFlags(),
48                                      0, fUniformSize, fUniformData.get());
49         fUniformBuffer = nullptr;
50     } else {
51         if (fUniformsDirty) {
52             GrResourceProvider* resourceProvider = gpu->getContext()->priv().resourceProvider();
53             fUniformBuffer = resourceProvider->createBuffer(fUniformData.get(),
54                                                             fUniformSize,
55                                                             GrGpuBufferType::kUniform,
56                                                             kDynamic_GrAccessPattern);
57             if (!fUniformBuffer) {
58                 return std::make_pair(nullptr, false);
59             }
60             fUniformsDirty = false;
61         }
62     }
63 
64     return std::make_pair(fUniformBuffer, true);
65 }
66 
set1iv(UniformHandle u,int arrayCount,const int32_t v[]) const67 void GrVkPipelineStateDataManager::set1iv(UniformHandle u,
68                                           int arrayCount,
69                                           const int32_t v[]) const {
70     if (fUsePushConstants) {
71         const Uniform& uni = fUniforms[u.toIndex()];
72         SkASSERT(uni.fType == SkSLType::kInt || uni.fType == SkSLType::kShort);
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         memcpy(buffer, v, arrayCount * sizeof(int32_t));
80     } else {
81         return this->INHERITED::set1iv(u, arrayCount, v);
82     }
83 }
84 
set1fv(UniformHandle u,int arrayCount,const float v[]) const85 void GrVkPipelineStateDataManager::set1fv(UniformHandle u,
86                                           int arrayCount,
87                                           const float v[]) const {
88     if (fUsePushConstants) {
89         const Uniform& uni = fUniforms[u.toIndex()];
90         SkASSERT(uni.fType == SkSLType::kFloat || uni.fType == SkSLType::kHalf);
91         SkASSERT(arrayCount > 0);
92         SkASSERT(arrayCount <= uni.fArrayCount ||
93                  (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
94 
95         void* buffer = this->getBufferPtrAndMarkDirty(uni);
96         SkASSERT(sizeof(float) == 4);
97         memcpy(buffer, v, arrayCount * sizeof(float));
98     } else {
99         return this->INHERITED::set1fv(u, arrayCount, v);
100     }
101 }
102 
set2iv(UniformHandle u,int arrayCount,const int32_t v[]) const103 void GrVkPipelineStateDataManager::set2iv(UniformHandle u,
104                                           int arrayCount,
105                                           const int32_t v[]) const {
106     if (fUsePushConstants) {
107         const Uniform& uni = fUniforms[u.toIndex()];
108         SkASSERT(uni.fType == SkSLType::kInt2 || uni.fType == SkSLType::kShort2);
109         SkASSERT(arrayCount > 0);
110         SkASSERT(arrayCount <= uni.fArrayCount ||
111                  (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
112 
113         void* buffer = this->getBufferPtrAndMarkDirty(uni);
114         SkASSERT(sizeof(int32_t) == 4);
115         memcpy(buffer, v, arrayCount * 2 * sizeof(int32_t));
116     } else {
117         return this->INHERITED::set2iv(u, arrayCount, v);
118     }
119 }
120 
set2fv(UniformHandle u,int arrayCount,const float v[]) const121 void GrVkPipelineStateDataManager::set2fv(UniformHandle u,
122                                           int arrayCount,
123                                           const float v[]) const {
124     if (fUsePushConstants) {
125         const Uniform& uni = fUniforms[u.toIndex()];
126         SkASSERT(uni.fType == SkSLType::kFloat2 || uni.fType == SkSLType::kHalf2);
127         SkASSERT(arrayCount > 0);
128         SkASSERT(arrayCount <= uni.fArrayCount ||
129                  (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
130 
131         void* buffer = this->getBufferPtrAndMarkDirty(uni);
132         SkASSERT(sizeof(float) == 4);
133         memcpy(buffer, v, arrayCount * 2 * sizeof(float));
134     } else {
135         return this->INHERITED::set2fv(u, arrayCount, v);
136     }
137 }
138 
setMatrix2fv(UniformHandle u,int arrayCount,const float m[]) const139 void GrVkPipelineStateDataManager::setMatrix2fv(UniformHandle u,
140                                                 int arrayCount,
141                                                 const float m[]) const {
142     if (fUsePushConstants) {
143         // upload as std430
144         const Uniform& uni = fUniforms[u.toIndex()];
145         SkASSERT(uni.fType == SkSLType::kFloat2x2 || uni.fType == SkSLType::kHalf2x2);
146         SkASSERT(arrayCount > 0);
147         SkASSERT(arrayCount <= uni.fArrayCount ||
148                  (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
149 
150         void* buffer = fUniformData.get();
151         fUniformsDirty = true;
152 
153         static_assert(sizeof(float) == 4);
154         buffer = static_cast<char*>(buffer) + uni.fOffset;
155         memcpy(buffer, m, arrayCount * 2 * 2 * sizeof(float));
156     } else {
157         this->INHERITED::setMatrix2fv(u, arrayCount, m);
158     }
159 }
160 
releaseData()161 void GrVkPipelineStateDataManager::releaseData() { fUniformBuffer.reset(); }
162