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