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