Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
GrVkPipelineState.cpp
Go to the documentation of this file.
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
9
10#include "src/core/SkMipmap.h"
28
29using namespace skia_private;
30
32 GrVkGpu* gpu,
34 const GrVkDescriptorSetManager::Handle& samplerDSHandle,
35 const GrGLSLBuiltinUniformHandles& builtinUniformHandles,
36 const UniformInfoArray& uniforms,
37 uint32_t uniformSize,
38 bool usePushConstants,
39 const UniformInfoArray& samplers,
40 std::unique_ptr<GrGeometryProcessor::ProgramImpl> gpImpl,
41 std::unique_ptr<GrXferProcessor::ProgramImpl> xpImpl,
42 std::vector<std::unique_ptr<GrFragmentProcessor::ProgramImpl>> fpImpls)
43 : fPipeline(std::move(pipeline))
44 , fSamplerDSHandle(samplerDSHandle)
45 , fBuiltinUniformHandles(builtinUniformHandles)
46 , fGPImpl(std::move(gpImpl))
47 , fXPImpl(std::move(xpImpl))
48 , fFPImpls(std::move(fpImpls))
49 , fDataManager(uniforms, uniformSize, usePushConstants) {
50 fNumSamplers = samplers.count();
51 for (const auto& sampler : samplers.items()) {
52 // We store the immutable samplers here and take a ref on the sampler. Once we switch to
53 // using sk_sps here we should just move the immutable samplers to save the extra ref/unref.
54 if (sampler.fImmutableSampler) {
55 sampler.fImmutableSampler->ref();
56 }
57 fImmutableSamplers.push_back(sampler.fImmutableSampler);
58 }
59}
60
62 // Must have freed all GPU resources before this is destroyed
63 SkASSERT(!fPipeline);
64}
65
67 fPipeline.reset();
68 fDataManager.releaseData();
69 for (int i = 0; i < fImmutableSamplers.size(); ++i) {
70 if (fImmutableSamplers[i]) {
71 fImmutableSamplers[i]->unref();
72 fImmutableSamplers[i] = nullptr;
73 }
74 }
75}
76
78 SkISize colorAttachmentDimensions,
79 const GrProgramInfo& programInfo,
80 GrVkCommandBuffer* commandBuffer) {
81 this->setRenderTargetState(colorAttachmentDimensions, programInfo.origin());
82
83 fGPImpl->setData(fDataManager, *gpu->caps()->shaderCaps(), programInfo.geomProc());
84
85 for (int i = 0; i < programInfo.pipeline().numFragmentProcessors(); ++i) {
86 const auto& fp = programInfo.pipeline().getFragmentProcessor(i);
87 fp.visitWithImpls([&](const GrFragmentProcessor& fp,
89 impl.setData(fDataManager, fp);
90 }, *fFPImpls[i]);
91 }
92
93 programInfo.pipeline().setDstTextureUniforms(fDataManager, &fBuiltinUniformHandles);
94 fXPImpl->setData(fDataManager, programInfo.pipeline().getXferProcessor());
95
96 // Upload uniform data and bind descriptor set.
97 auto [uniformBuffer, success] = fDataManager.uploadUniforms(gpu, fPipeline->layout(),
98 commandBuffer);
99 if (!success) {
100 return false;
101 }
102 if (uniformBuffer) {
103 const GrVkBuffer* vkBuffer = static_cast<GrVkBuffer*>(uniformBuffer.get());
104 static const int kUniformDSIdx = GrVkUniformHandler::kUniformBufferDescSet;
105 commandBuffer->bindDescriptorSets(gpu, fPipeline->layout(), kUniformDSIdx, /*setCount=*/1,
106 vkBuffer->uniformDescriptorSet(),
107 /*dynamicOffsetCount=*/0, /*dynamicOffsets=*/nullptr);
108 commandBuffer->addGrBuffer(std::move(uniformBuffer));
109 }
110 return true;
111}
112
114 const GrGeometryProcessor& geomProc,
115 const GrPipeline& pipeline,
116 const GrSurfaceProxy* const geomProcTextures[],
117 GrVkCommandBuffer* commandBuffer) {
118 SkASSERT(geomProcTextures || !geomProc.numTextureSamplers());
119 if (!fNumSamplers) {
120 return true;
121 }
122 struct SamplerBindings {
123 GrSamplerState fState;
124 GrVkTexture* fTexture;
125 };
126 AutoSTArray<8, SamplerBindings> samplerBindings(fNumSamplers);
127 int currTextureBinding = 0;
128
129 for (int i = 0; i < geomProc.numTextureSamplers(); ++i) {
130 SkASSERT(geomProcTextures[i]->asTextureProxy());
131 const auto& sampler = geomProc.textureSampler(i);
132 auto texture = static_cast<GrVkTexture*>(geomProcTextures[i]->peekTexture());
133 samplerBindings[currTextureBinding++] = {sampler.samplerState(), texture};
134 }
135
136
137 if (GrTexture* dstTexture = pipeline.peekDstTexture()) {
138 samplerBindings[currTextureBinding++] = {GrSamplerState::Filter::kNearest,
139 static_cast<GrVkTexture*>(dstTexture)};
140 }
141
142 pipeline.visitTextureEffects([&](const GrTextureEffect& te) {
143 GrSamplerState samplerState = te.samplerState();
144 auto* texture = static_cast<GrVkTexture*>(te.texture());
145 samplerBindings[currTextureBinding++] = {samplerState, texture};
146 });
147
148 // Get new descriptor set
149 SkASSERT(fNumSamplers == currTextureBinding);
150 static const int kSamplerDSIdx = GrVkUniformHandler::kSamplerDescSet;
151
152 if (fNumSamplers == 1) {
153 auto texture = samplerBindings[0].fTexture;
154 auto texAttachment = texture->textureImage();
155 const auto& samplerState = samplerBindings[0].fState;
156 const GrVkDescriptorSet* descriptorSet = texture->cachedSingleDescSet(samplerState);
157 if (descriptorSet) {
158 commandBuffer->addGrSurface(sk_ref_sp<const GrSurface>(texture));
159 commandBuffer->addResource(texAttachment->textureView());
160 commandBuffer->addResource(texAttachment->resource());
161 commandBuffer->addRecycledResource(descriptorSet);
162 commandBuffer->bindDescriptorSets(gpu, fPipeline->layout(), kSamplerDSIdx,
163 /*setCount=*/1, descriptorSet->descriptorSet(),
164 /*dynamicOffsetCount=*/0,
165 /*dynamicOffsets=*/nullptr);
166 return true;
167 }
168 }
169
170 const GrVkDescriptorSet* descriptorSet =
171 gpu->resourceProvider().getSamplerDescriptorSet(fSamplerDSHandle);
172 if (!descriptorSet) {
173 return false;
174 }
175
176 for (int i = 0; i < fNumSamplers; ++i) {
177 GrSamplerState state = samplerBindings[i].fState;
178 GrVkTexture* texture = samplerBindings[i].fTexture;
179 auto texAttachment = texture->textureImage();
180
181 const GrVkImageView* textureView = texAttachment->textureView();
182 const GrVkSampler* sampler = nullptr;
183 if (fImmutableSamplers[i]) {
184 sampler = fImmutableSamplers[i];
185 } else {
187 state, texAttachment->ycbcrConversionInfo());
188 if (!sampler) {
189 descriptorSet->recycle();
190 return false;
191 }
192 }
193 SkASSERT(sampler);
194
195 VkDescriptorImageInfo imageInfo;
196 memset(&imageInfo, 0, sizeof(VkDescriptorImageInfo));
197 imageInfo.sampler = fImmutableSamplers[i] ? VK_NULL_HANDLE : sampler->sampler();
198 imageInfo.imageView = textureView->imageView();
200
201 VkWriteDescriptorSet writeInfo;
202 memset(&writeInfo, 0, sizeof(VkWriteDescriptorSet));
204 writeInfo.pNext = nullptr;
205 writeInfo.dstSet = *descriptorSet->descriptorSet();
206 writeInfo.dstBinding = i;
207 writeInfo.dstArrayElement = 0;
208 writeInfo.descriptorCount = 1;
210 writeInfo.pImageInfo = &imageInfo;
211 writeInfo.pBufferInfo = nullptr;
212 writeInfo.pTexelBufferView = nullptr;
213
214 GR_VK_CALL(gpu->vkInterface(),
215 UpdateDescriptorSets(gpu->device(), 1, &writeInfo, 0, nullptr));
216 commandBuffer->addResource(sampler);
217 if (!fImmutableSamplers[i]) {
218 sampler->unref();
219 }
220 commandBuffer->addResource(textureView);
221 commandBuffer->addResource(texAttachment->resource());
222 }
223 if (fNumSamplers == 1) {
224 GrSamplerState state = samplerBindings[0].fState;
225 GrVkTexture* texture = samplerBindings[0].fTexture;
226 texture->addDescriptorSetToCache(descriptorSet, state);
227 }
228
229 commandBuffer->bindDescriptorSets(gpu, fPipeline->layout(), kSamplerDSIdx, /*setCount=*/1,
230 descriptorSet->descriptorSet(),
231 /*dynamicOffsetCount=*/0, /*dynamicOffsets=*/nullptr);
232 commandBuffer->addRecycledResource(descriptorSet);
233 descriptorSet->recycle();
234 return true;
235}
236
239 GrVkCommandBuffer* commandBuffer) {
240 SkASSERT(inputDescSet);
241 commandBuffer->bindDescriptorSets(gpu, fPipeline->layout(), GrVkUniformHandler::kInputDescSet,
242 /*setCount=*/1, inputDescSet->descriptorSet(),
243 /*dynamicOffsetCount=*/0, /*dynamicOffsets=*/nullptr);
244 // We don't add the input resource to the command buffer to track since the input will be
245 // the same as the color attachment which is already tracked on the command buffer.
246 commandBuffer->addRecycledResource(std::move(inputDescSet));
247 return true;
248}
249
250void GrVkPipelineState::setRenderTargetState(SkISize colorAttachmentDimensions,
251 GrSurfaceOrigin origin) {
252 // Set RT adjustment and RT flip
253 SkASSERT(fBuiltinUniformHandles.fRTAdjustmentUni.isValid());
254 if (fRenderTargetState.fRenderTargetOrigin != origin ||
255 fRenderTargetState.fRenderTargetSize != colorAttachmentDimensions) {
256 fRenderTargetState.fRenderTargetSize = colorAttachmentDimensions;
257 fRenderTargetState.fRenderTargetOrigin = origin;
258
259 // The client will mark a swap buffer as kTopLeft when making a SkSurface because
260 // Vulkan's framebuffer space has (0, 0) at the top left. This agrees with Skia's device
261 // coords and with Vulkan's NDC that has (-1, -1) in the top left. So a flip is needed when
262 // surface origin is kBottomLeft rather than kTopLeft.
263 bool flip = (origin == kBottomLeft_GrSurfaceOrigin);
264 std::array<float, 4> v = SkSL::Compiler::GetRTAdjustVector(colorAttachmentDimensions, flip);
265 fDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, v.data());
266 if (fBuiltinUniformHandles.fRTFlipUni.isValid()) {
267 std::array<float, 2> d =
268 SkSL::Compiler::GetRTFlipVector(colorAttachmentDimensions.height(), flip);
269 fDataManager.set2fv(fBuiltinUniformHandles.fRTFlipUni, 1, d.data());
270 }
271 }
272}
273
275 commandBuffer->bindPipeline(gpu, fPipeline);
276}
GrSurfaceOrigin
Definition GrTypes.h:147
@ kBottomLeft_GrSurfaceOrigin
Definition GrTypes.h:149
#define GR_VK_CALL(IFACE, X)
Definition GrVkUtil.h:24
#define SkASSERT(cond)
Definition SkAssert.h:116
const GrShaderCaps * shaderCaps() const
Definition GrCaps.h:63
void setData(const GrGLSLProgramDataManager &pdman, const GrFragmentProcessor &processor)
const TextureSampler & textureSampler(int index) const
const GrCaps * caps() const
Definition GrGpu.h:73
void setDstTextureUniforms(const GrGLSLProgramDataManager &pdm, GrGLSLBuiltinUniformHandles *fBuiltinUniformHandles) const
const GrFragmentProcessor & getFragmentProcessor(int idx) const
Definition GrPipeline.h:157
void visitTextureEffects(const std::function< void(const GrTextureEffect &)> &) const
GrTexture * peekDstTexture() const
Definition GrPipeline.h:145
const GrXferProcessor & getXferProcessor() const
Definition GrPipeline.h:116
GrSurfaceOrigin origin() const
const GrPipeline & pipeline() const
const GrGeometryProcessor & geomProc() const
GrTexture * peekTexture() const
GrTexture * texture() const
GrSamplerState samplerState() const
void set4fv(UniformHandle, int arrayCount, const float v[]) const override
const VkDescriptorSet * uniformDescriptorSet() const
void bindPipeline(const GrVkGpu *gpu, sk_sp< const GrVkPipeline > pipeline)
void addResource(sk_sp< const GrManagedResource > resource)
void addRecycledResource(gr_rp< const GrRecycledResource > resource)
void addGrSurface(sk_sp< const GrSurface > surface)
void addGrBuffer(sk_sp< const GrBuffer > buffer)
void bindDescriptorSets(const GrVkGpu *gpu, VkPipelineLayout layout, uint32_t firstSet, uint32_t setCount, const VkDescriptorSet *descriptorSets, uint32_t dynamicOffsetCount, const uint32_t *dynamicOffsets)
const VkDescriptorSet * descriptorSet() const
const skgpu::VulkanInterface * vkInterface() const
Definition GrVkGpu.h:60
VkDevice device() const
Definition GrVkGpu.h:71
GrVkResourceProvider & resourceProvider()
Definition GrVkGpu.h:83
VkImageView imageView() const
std::pair< sk_sp< GrGpuBuffer >, bool > uploadUniforms(GrVkGpu *gpu, VkPipelineLayout, GrVkCommandBuffer *commandBuffer)
void set2fv(UniformHandle, int arrayCount, const float v[]) const override
bool setAndBindTextures(GrVkGpu *, const GrGeometryProcessor &, const GrPipeline &, const GrSurfaceProxy *const geomProcTextures[], GrVkCommandBuffer *)
bool setAndBindUniforms(GrVkGpu *, SkISize colorAttachmentDimensions, const GrProgramInfo &, GrVkCommandBuffer *)
void bindPipeline(const GrVkGpu *gpu, GrVkCommandBuffer *commandBuffer)
bool setAndBindInputAttachment(GrVkGpu *, gr_rp< const GrVkDescriptorSet > inputDescSet, GrVkCommandBuffer *)
void freeGPUResources(GrVkGpu *gpu)
GrVkPipelineState(GrVkGpu *, sk_sp< const GrVkPipeline >, const GrVkDescriptorSetManager::Handle &samplerDSHandle, const GrGLSLBuiltinUniformHandles &builtinUniformHandles, const UniformInfoArray &uniforms, uint32_t uniformSize, bool usePushConstants, const UniformInfoArray &samplers, std::unique_ptr< GrGeometryProcessor::ProgramImpl >, std::unique_ptr< GrXferProcessor::ProgramImpl >, std::vector< std::unique_ptr< GrFragmentProcessor::ProgramImpl > > fpImpls)
VkPipelineLayout layout() const
const GrVkDescriptorSet * getSamplerDescriptorSet(const GrVkDescriptorSetManager::Handle &)
GrVkSampler * findOrCreateCompatibleSampler(GrSamplerState, const GrVkYcbcrConversionInfo &ycbcrInfo)
VkSampler sampler() const
Definition GrVkSampler.h:26
static std::array< float, 2 > GetRTFlipVector(int rtHeight, bool flipY)
static std::array< float, 4 > GetRTAdjustVector(SkISize rtDims, bool flipY)
int count() const
void reset(T *ptr=nullptr)
Definition SkRefCnt.h:310
int size() const
Definition SkTArray.h:416
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition main.cc:19
AtkStateType state
FlTexture * texture
Definition ref_ptr.h:256
GrGLSLProgramDataManager::UniformHandle fRTFlipUni
GrGLSLProgramDataManager::UniformHandle fRTAdjustmentUni
constexpr int32_t height() const
Definition SkSize.h:37
VkImageLayout imageLayout
const VkBufferView * pTexelBufferView
VkStructureType sType
const VkDescriptorImageInfo * pImageInfo
const VkDescriptorBufferInfo * pBufferInfo
VkDescriptorSet dstSet
VkDescriptorType descriptorType
@ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
@ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
#define VK_NULL_HANDLE
Definition vulkan_core.h:46
@ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET