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/vk/GrVkPipelineStateDataManager.h"
9
10 #include "include/gpu/GrDirectContext.h"
11 #include "src/gpu/GrDirectContextPriv.h"
12 #include "src/gpu/GrGpuBuffer.h"
13 #include "src/gpu/GrResourceProvider.h"
14 #include "src/gpu/vk/GrVkCommandBuffer.h"
15 #include "src/gpu/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(
54 fUniformSize, GrGpuBufferType::kUniform, kDynamic_GrAccessPattern,
55 fUniformData.get());
56 if (!fUniformBuffer) {
57 return std::make_pair(nullptr, false);
58 }
59 fUniformsDirty = false;
60 }
61 }
62
63 return std::make_pair(fUniformBuffer, true);
64 }
65
set1iv(UniformHandle u,int arrayCount,const int32_t v[]) const66 void GrVkPipelineStateDataManager::set1iv(UniformHandle u,
67 int arrayCount,
68 const int32_t v[]) const {
69 if (fUsePushConstants) {
70 const Uniform& uni = fUniforms[u.toIndex()];
71 SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType);
72 SkASSERT(arrayCount > 0);
73 SkASSERT(arrayCount <= uni.fArrayCount ||
74 (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
75
76 void* buffer = this->getBufferPtrAndMarkDirty(uni);
77 SkASSERT(sizeof(int32_t) == 4);
78 memcpy(buffer, v, arrayCount * sizeof(int32_t));
79 } else {
80 return this->INHERITED::set1iv(u, arrayCount, v);
81 }
82 }
83
set1fv(UniformHandle u,int arrayCount,const float v[]) const84 void GrVkPipelineStateDataManager::set1fv(UniformHandle u,
85 int arrayCount,
86 const float v[]) const {
87 if (fUsePushConstants) {
88 const Uniform& uni = fUniforms[u.toIndex()];
89 SkASSERT(uni.fType == kFloat_GrSLType || uni.fType == kHalf_GrSLType);
90 SkASSERT(arrayCount > 0);
91 SkASSERT(arrayCount <= uni.fArrayCount ||
92 (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
93
94 void* buffer = this->getBufferPtrAndMarkDirty(uni);
95 SkASSERT(sizeof(float) == 4);
96 memcpy(buffer, v, arrayCount * sizeof(float));
97 } else {
98 return this->INHERITED::set1fv(u, arrayCount, v);
99 }
100 }
101
set2iv(UniformHandle u,int arrayCount,const int32_t v[]) const102 void GrVkPipelineStateDataManager::set2iv(UniformHandle u,
103 int arrayCount,
104 const int32_t v[]) const {
105 if (fUsePushConstants) {
106 const Uniform& uni = fUniforms[u.toIndex()];
107 SkASSERT(uni.fType == kInt2_GrSLType || uni.fType == kShort2_GrSLType);
108 SkASSERT(arrayCount > 0);
109 SkASSERT(arrayCount <= uni.fArrayCount ||
110 (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
111
112 void* buffer = this->getBufferPtrAndMarkDirty(uni);
113 SkASSERT(sizeof(int32_t) == 4);
114 memcpy(buffer, v, arrayCount * 2 * sizeof(int32_t));
115 } else {
116 return this->INHERITED::set2iv(u, arrayCount, v);
117 }
118 }
119
set2fv(UniformHandle u,int arrayCount,const float v[]) const120 void GrVkPipelineStateDataManager::set2fv(UniformHandle u,
121 int arrayCount,
122 const float v[]) const {
123 if (fUsePushConstants) {
124 const Uniform& uni = fUniforms[u.toIndex()];
125 SkASSERT(uni.fType == kFloat2_GrSLType || uni.fType == kHalf2_GrSLType);
126 SkASSERT(arrayCount > 0);
127 SkASSERT(arrayCount <= uni.fArrayCount ||
128 (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
129
130 void* buffer = this->getBufferPtrAndMarkDirty(uni);
131 SkASSERT(sizeof(float) == 4);
132 memcpy(buffer, v, arrayCount * 2 * sizeof(float));
133 } else {
134 return this->INHERITED::set2fv(u, arrayCount, v);
135 }
136 }
137
setMatrix2fv(UniformHandle u,int arrayCount,const float m[]) const138 void GrVkPipelineStateDataManager::setMatrix2fv(UniformHandle u,
139 int arrayCount,
140 const float m[]) const {
141 if (fUsePushConstants) {
142 // upload as std430
143 const Uniform& uni = fUniforms[u.toIndex()];
144 SkASSERT(uni.fType == kFloat2x2_GrSLType || uni.fType == kHalf2x2_GrSLType);
145 SkASSERT(arrayCount > 0);
146 SkASSERT(arrayCount <= uni.fArrayCount ||
147 (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
148
149 void* buffer = fUniformData.get();
150 fUniformsDirty = true;
151
152 static_assert(sizeof(float) == 4);
153 buffer = static_cast<char*>(buffer) + uni.fOffset;
154 memcpy(buffer, m, arrayCount * 2 * 2 * sizeof(float));
155 } else {
156 this->INHERITED::setMatrix2fv(u, arrayCount, m);
157 }
158 }
159
releaseData()160 void GrVkPipelineStateDataManager::releaseData() { fUniformBuffer.reset(); }
161