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