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