blob: 6e7de88d43cc00935c78033cf442d3abda22c98f [file] [log] [blame]
jvanverth992ad362016-02-26 09:21:02 -08001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/gpu/GrContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -05009#include "src/core/SkMipMap.h"
10#include "src/gpu/GrContextPriv.h"
11#include "src/gpu/GrPipeline.h"
Brian Salomon201cdbb2019-08-14 17:00:30 -040012#include "src/gpu/GrRenderTarget.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "src/gpu/GrTexturePriv.h"
14#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
15#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
16#include "src/gpu/glsl/GrGLSLXferProcessor.h"
17#include "src/gpu/vk/GrVkBufferView.h"
18#include "src/gpu/vk/GrVkCommandBuffer.h"
19#include "src/gpu/vk/GrVkDescriptorPool.h"
20#include "src/gpu/vk/GrVkDescriptorSet.h"
21#include "src/gpu/vk/GrVkGpu.h"
22#include "src/gpu/vk/GrVkImageView.h"
23#include "src/gpu/vk/GrVkMemory.h"
24#include "src/gpu/vk/GrVkPipeline.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050025#include "src/gpu/vk/GrVkPipelineState.h"
26#include "src/gpu/vk/GrVkSampler.h"
27#include "src/gpu/vk/GrVkTexture.h"
28#include "src/gpu/vk/GrVkUniformBuffer.h"
jvanverth992ad362016-02-26 09:21:02 -080029
Brian Salomon1471df92018-06-08 10:49:00 -040030GrVkPipelineState::GrVkPipelineState(
31 GrVkGpu* gpu,
Brian Salomon4d3f5172018-06-07 14:42:52 -040032 GrVkPipeline* pipeline,
Brian Salomon4d3f5172018-06-07 14:42:52 -040033 const GrVkDescriptorSetManager::Handle& samplerDSHandle,
Brian Salomon1471df92018-06-08 10:49:00 -040034 const GrGLSLBuiltinUniformHandles& builtinUniformHandles,
Brian Salomon4d3f5172018-06-07 14:42:52 -040035 const UniformInfoArray& uniforms,
Ethan Nicholas0be34802019-08-15 12:36:58 -040036 uint32_t uniformSize,
Greg Daniel7a82edf2018-12-04 10:54:34 -050037 const UniformInfoArray& samplers,
Brian Salomon4d3f5172018-06-07 14:42:52 -040038 std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
39 std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
40 std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors,
41 int fragmentProcessorCnt)
42 : fPipeline(pipeline)
Brian Salomon4d3f5172018-06-07 14:42:52 -040043 , fUniformDescriptorSet(nullptr)
44 , fSamplerDescriptorSet(nullptr)
Brian Salomon4d3f5172018-06-07 14:42:52 -040045 , fSamplerDSHandle(samplerDSHandle)
Brian Salomon4d3f5172018-06-07 14:42:52 -040046 , fBuiltinUniformHandles(builtinUniformHandles)
47 , fGeometryProcessor(std::move(geometryProcessor))
48 , fXferProcessor(std::move(xferProcessor))
49 , fFragmentProcessors(std::move(fragmentProcessors))
50 , fFragmentProcessorCnt(fragmentProcessorCnt)
Ethan Nicholas0be34802019-08-15 12:36:58 -040051 , fDataManager(uniforms, uniformSize) {
egdanielc2dc1b22016-03-18 13:18:23 -070052 fDescriptorSets[0] = VK_NULL_HANDLE;
53 fDescriptorSets[1] = VK_NULL_HANDLE;
Greg Daniel31ec1442017-05-08 10:30:59 -040054 fDescriptorSets[2] = VK_NULL_HANDLE;
jvanverth992ad362016-02-26 09:21:02 -080055
Ethan Nicholas0be34802019-08-15 12:36:58 -040056 fUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, uniformSize));
jvanverth992ad362016-02-26 09:21:02 -080057
Greg Daniel7a82edf2018-12-04 10:54:34 -050058 fNumSamplers = samplers.count();
59
60 for (int i = 0; i < fNumSamplers; ++i) {
61 // We store the immutable samplers here and take ownership of the ref from the
62 // GrVkUnformHandler.
63 fImmutableSamplers.push_back(samplers[i].fImmutableSampler);
64 }
jvanverth992ad362016-02-26 09:21:02 -080065}
66
egdaniel22281c12016-03-23 13:49:40 -070067GrVkPipelineState::~GrVkPipelineState() {
Ethan Nicholas87f340e2017-01-03 14:32:01 -050068 // Must have freed all GPU resources before this is destroyed
jvanverth992ad362016-02-26 09:21:02 -080069 SkASSERT(!fPipeline);
jvanverth992ad362016-02-26 09:21:02 -080070}
71
Ethan Nicholas8e265a72018-12-12 16:22:40 -050072void GrVkPipelineState::freeGPUResources(GrVkGpu* gpu) {
jvanverth992ad362016-02-26 09:21:02 -080073 if (fPipeline) {
74 fPipeline->unref(gpu);
75 fPipeline = nullptr;
76 }
egdanielc2dc1b22016-03-18 13:18:23 -070077
Ethan Nicholas0be34802019-08-15 12:36:58 -040078 if (fUniformBuffer) {
79 fUniformBuffer->release(gpu);
80 fUniformBuffer.reset();
jvanverth992ad362016-02-26 09:21:02 -080081 }
egdanielc2dc1b22016-03-18 13:18:23 -070082
egdaniela95220d2016-07-21 11:50:37 -070083 if (fUniformDescriptorSet) {
84 fUniformDescriptorSet->recycle(const_cast<GrVkGpu*>(gpu));
85 fUniformDescriptorSet = nullptr;
egdaniel778555c2016-05-02 06:50:36 -070086 }
egdanielc2dc1b22016-03-18 13:18:23 -070087
egdaniel707bbd62016-07-26 07:19:47 -070088 if (fSamplerDescriptorSet) {
89 fSamplerDescriptorSet->recycle(const_cast<GrVkGpu*>(gpu));
90 fSamplerDescriptorSet = nullptr;
91 }
jvanverth992ad362016-02-26 09:21:02 -080092}
93
egdaniel22281c12016-03-23 13:49:40 -070094void GrVkPipelineState::abandonGPUResources() {
Greg Daniel7d918fd2018-06-19 15:22:01 -040095 if (fPipeline) {
96 fPipeline->unrefAndAbandon();
97 fPipeline = nullptr;
98 }
egdanielc2dc1b22016-03-18 13:18:23 -070099
Ethan Nicholas0be34802019-08-15 12:36:58 -0400100 if (fUniformBuffer) {
101 fUniformBuffer->abandon();
102 fUniformBuffer.reset();
Greg Danieladb4bfe2018-08-23 16:15:05 -0400103 }
jvanverth992ad362016-02-26 09:21:02 -0800104
egdaniela95220d2016-07-21 11:50:37 -0700105 if (fUniformDescriptorSet) {
106 fUniformDescriptorSet->unrefAndAbandon();
107 fUniformDescriptorSet = nullptr;
egdaniel778555c2016-05-02 06:50:36 -0700108 }
egdaniel707bbd62016-07-26 07:19:47 -0700109
110 if (fSamplerDescriptorSet) {
111 fSamplerDescriptorSet->unrefAndAbandon();
112 fSamplerDescriptorSet = nullptr;
113 }
jvanverth992ad362016-02-26 09:21:02 -0800114}
115
Brian Salomonf7232642018-09-19 08:58:08 -0400116void GrVkPipelineState::setAndBindUniforms(GrVkGpu* gpu,
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500117 const GrRenderTarget* renderTarget,
118 GrSurfaceOrigin origin,
Brian Salomonf7232642018-09-19 08:58:08 -0400119 const GrPrimitiveProcessor& primProc,
120 const GrPipeline& pipeline,
121 GrVkCommandBuffer* commandBuffer) {
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500122 this->setRenderTargetState(renderTarget, origin);
jvanverth992ad362016-02-26 09:21:02 -0800123
Brian Salomonf7232642018-09-19 08:58:08 -0400124 fGeometryProcessor->setData(fDataManager, primProc,
125 GrFragmentProcessor::CoordTransformIter(pipeline));
126 GrFragmentProcessor::Iter iter(pipeline);
127 GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
128 const GrFragmentProcessor* fp = iter.next();
129 GrGLSLFragmentProcessor* glslFP = glslIter.next();
130 while (fp && glslFP) {
131 glslFP->setData(fDataManager, *fp);
132 fp = iter.next();
133 glslFP = glslIter.next();
134 }
135 SkASSERT(!fp && !glslFP);
136
137 {
138 SkIPoint offset;
139 GrTexture* dstTexture = pipeline.peekDstTexture(&offset);
140
141 fXferProcessor->setData(fDataManager, pipeline.getXferProcessor(), dstTexture, offset);
142 }
143
144 // Get new descriptor set
Ethan Nicholas0be34802019-08-15 12:36:58 -0400145 if (fUniformBuffer) {
Brian Salomonf7232642018-09-19 08:58:08 -0400146 int uniformDSIdx = GrVkUniformHandler::kUniformBufferDescSet;
Ethan Nicholas0be34802019-08-15 12:36:58 -0400147 if (fDataManager.uploadUniformBuffers(gpu, fUniformBuffer.get()) ||
Brian Salomonf7232642018-09-19 08:58:08 -0400148 !fUniformDescriptorSet) {
149 if (fUniformDescriptorSet) {
150 fUniformDescriptorSet->recycle(gpu);
151 }
152 fUniformDescriptorSet = gpu->resourceProvider().getUniformDescriptorSet();
153 fDescriptorSets[uniformDSIdx] = fUniformDescriptorSet->descriptorSet();
154 this->writeUniformBuffers(gpu);
155 }
Greg Danieleecc6872019-07-29 13:21:37 -0400156 commandBuffer->bindDescriptorSets(gpu, this, fPipeline->layout(), uniformDSIdx, 1,
Brian Salomonf7232642018-09-19 08:58:08 -0400157 &fDescriptorSets[uniformDSIdx], 0, nullptr);
158 if (fUniformDescriptorSet) {
159 commandBuffer->addRecycledResource(fUniformDescriptorSet);
160 }
Ethan Nicholas0be34802019-08-15 12:36:58 -0400161 if (fUniformBuffer) {
162 commandBuffer->addRecycledResource(fUniformBuffer->resource());
Brian Salomonf7232642018-09-19 08:58:08 -0400163 }
164 }
165}
166
167void GrVkPipelineState::setAndBindTextures(GrVkGpu* gpu,
168 const GrPrimitiveProcessor& primProc,
169 const GrPipeline& pipeline,
170 const GrTextureProxy* const primProcTextures[],
171 GrVkCommandBuffer* commandBuffer) {
172 SkASSERT(primProcTextures || !primProc.numTextureSamplers());
173
174 struct SamplerBindings {
175 GrSamplerState fState;
176 GrVkTexture* fTexture;
177 };
Brian Salomon5e81a122018-08-23 16:46:07 -0400178 SkAutoSTMalloc<8, SamplerBindings> samplerBindings(fNumSamplers);
179 int currTextureBinding = 0;
180
181 fGeometryProcessor->setData(fDataManager, primProc,
182 GrFragmentProcessor::CoordTransformIter(pipeline));
183 for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
184 const auto& sampler = primProc.textureSampler(i);
185 auto texture = static_cast<GrVkTexture*>(primProcTextures[i]->peekTexture());
186 samplerBindings[currTextureBinding++] = {sampler.samplerState(), texture};
187 }
188
189 GrFragmentProcessor::Iter iter(pipeline);
190 GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
191 const GrFragmentProcessor* fp = iter.next();
192 GrGLSLFragmentProcessor* glslFP = glslIter.next();
193 while (fp && glslFP) {
194 for (int i = 0; i < fp->numTextureSamplers(); ++i) {
195 const auto& sampler = fp->textureSampler(i);
196 samplerBindings[currTextureBinding++] =
197 {sampler.samplerState(), static_cast<GrVkTexture*>(sampler.peekTexture())};
198 }
199 fp = iter.next();
200 glslFP = glslIter.next();
201 }
202 SkASSERT(!fp && !glslFP);
203
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400204 if (GrTextureProxy* dstTextureProxy = pipeline.dstTextureProxy()) {
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400205 samplerBindings[currTextureBinding++] = {
206 GrSamplerState::ClampNearest(),
207 static_cast<GrVkTexture*>(dstTextureProxy->peekTexture())};
Brian Salomon18dfa982017-04-03 16:57:43 -0400208 }
jvanverth992ad362016-02-26 09:21:02 -0800209
Brian Salomonf7232642018-09-19 08:58:08 -0400210 // Get new descriptor set
Brian Salomone782f842018-07-31 13:53:11 -0400211 SkASSERT(fNumSamplers == currTextureBinding);
egdanielc2dc1b22016-03-18 13:18:23 -0700212 if (fNumSamplers) {
egdaniel707bbd62016-07-26 07:19:47 -0700213 if (fSamplerDescriptorSet) {
214 fSamplerDescriptorSet->recycle(gpu);
215 }
216 fSamplerDescriptorSet = gpu->resourceProvider().getSamplerDescriptorSet(fSamplerDSHandle);
217 int samplerDSIdx = GrVkUniformHandler::kSamplerDescSet;
218 fDescriptorSets[samplerDSIdx] = fSamplerDescriptorSet->descriptorSet();
Brian Salomonf7232642018-09-19 08:58:08 -0400219 for (int i = 0; i < fNumSamplers; ++i) {
220 const GrSamplerState& state = samplerBindings[i].fState;
221 GrVkTexture* texture = samplerBindings[i].fTexture;
egdanielb4aa3622016-04-06 13:47:08 -0700222
Brian Salomonf7232642018-09-19 08:58:08 -0400223 const GrVkImageView* textureView = texture->textureView();
Greg Daniel7a82edf2018-12-04 10:54:34 -0500224 const GrVkSampler* sampler = nullptr;
225 if (fImmutableSamplers[i]) {
226 sampler = fImmutableSamplers[i];
227 } else {
228 sampler = gpu->resourceProvider().findOrCreateCompatibleSampler(
Greg Daniel7e000222018-12-03 10:08:21 -0500229 state, texture->ycbcrConversionInfo());
Greg Daniel7a82edf2018-12-04 10:54:34 -0500230 }
231 SkASSERT(sampler);
Brian Salomonf7232642018-09-19 08:58:08 -0400232
233 VkDescriptorImageInfo imageInfo;
234 memset(&imageInfo, 0, sizeof(VkDescriptorImageInfo));
235 imageInfo.sampler = sampler->sampler();
236 imageInfo.imageView = textureView->imageView();
237 imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
238
239 VkWriteDescriptorSet writeInfo;
240 memset(&writeInfo, 0, sizeof(VkWriteDescriptorSet));
241 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
242 writeInfo.pNext = nullptr;
243 writeInfo.dstSet = fDescriptorSets[GrVkUniformHandler::kSamplerDescSet];
244 writeInfo.dstBinding = i;
245 writeInfo.dstArrayElement = 0;
246 writeInfo.descriptorCount = 1;
247 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
248 writeInfo.pImageInfo = &imageInfo;
249 writeInfo.pBufferInfo = nullptr;
250 writeInfo.pTexelBufferView = nullptr;
251
252 GR_VK_CALL(gpu->vkInterface(),
253 UpdateDescriptorSets(gpu->device(), 1, &writeInfo, 0, nullptr));
254 commandBuffer->addResource(sampler);
Greg Daniel7a82edf2018-12-04 10:54:34 -0500255 if (!fImmutableSamplers[i]) {
256 sampler->unref(gpu);
257 }
Brian Salomonf7232642018-09-19 08:58:08 -0400258 commandBuffer->addResource(samplerBindings[i].fTexture->textureView());
259 commandBuffer->addResource(samplerBindings[i].fTexture->resource());
egdaniel7cbffda2016-04-08 13:27:53 -0700260 }
Brian Salomonf7232642018-09-19 08:58:08 -0400261
Greg Danieleecc6872019-07-29 13:21:37 -0400262 commandBuffer->bindDescriptorSets(gpu, this, fPipeline->layout(), samplerDSIdx, 1,
Brian Salomonf7232642018-09-19 08:58:08 -0400263 &fDescriptorSets[samplerDSIdx], 0, nullptr);
264 commandBuffer->addRecycledResource(fSamplerDescriptorSet);
egdanielb4aa3622016-04-06 13:47:08 -0700265 }
jvanverth992ad362016-02-26 09:21:02 -0800266}
267
Greg Daniel18f96022017-05-04 15:09:03 -0400268void set_uniform_descriptor_writes(VkWriteDescriptorSet* descriptorWrite,
269 VkDescriptorBufferInfo* bufferInfo,
270 const GrVkUniformBuffer* buffer,
Ethan Nicholas0be34802019-08-15 12:36:58 -0400271 VkDescriptorSet descriptorSet) {
Greg Daniel18f96022017-05-04 15:09:03 -0400272
273 memset(bufferInfo, 0, sizeof(VkDescriptorBufferInfo));
274 bufferInfo->buffer = buffer->buffer();
275 bufferInfo->offset = buffer->offset();
276 bufferInfo->range = buffer->size();
277
278 memset(descriptorWrite, 0, sizeof(VkWriteDescriptorSet));
279 descriptorWrite->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
280 descriptorWrite->pNext = nullptr;
Greg Daniel783c4362017-05-04 17:29:09 -0400281 descriptorWrite->dstSet = descriptorSet;
Ethan Nicholas0be34802019-08-15 12:36:58 -0400282 descriptorWrite->dstBinding = GrVkUniformHandler::kUniformBinding;
Greg Daniel18f96022017-05-04 15:09:03 -0400283 descriptorWrite->dstArrayElement = 0;
284 descriptorWrite->descriptorCount = 1;
285 descriptorWrite->descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
286 descriptorWrite->pImageInfo = nullptr;
287 descriptorWrite->pBufferInfo = bufferInfo;
288 descriptorWrite->pTexelBufferView = nullptr;
289}
290
egdaniel22281c12016-03-23 13:49:40 -0700291void GrVkPipelineState::writeUniformBuffers(const GrVkGpu* gpu) {
Greg Daniel18f96022017-05-04 15:09:03 -0400292 VkWriteDescriptorSet descriptorWrites[3];
293 VkDescriptorBufferInfo bufferInfos[3];
jvanverth992ad362016-02-26 09:21:02 -0800294
Greg Daniel18f96022017-05-04 15:09:03 -0400295 uint32_t writeCount = 0;
jvanverth992ad362016-02-26 09:21:02 -0800296
Ethan Nicholas0be34802019-08-15 12:36:58 -0400297 if (fUniformBuffer.get()) {
Greg Daniel18f96022017-05-04 15:09:03 -0400298 set_uniform_descriptor_writes(&descriptorWrites[writeCount],
299 &bufferInfos[writeCount],
Ethan Nicholas0be34802019-08-15 12:36:58 -0400300 fUniformBuffer.get(),
301 fDescriptorSets[GrVkUniformHandler::kUniformBufferDescSet]);
Greg Daniel18f96022017-05-04 15:09:03 -0400302 ++writeCount;
jvanverth992ad362016-02-26 09:21:02 -0800303 }
304
Greg Daniel18f96022017-05-04 15:09:03 -0400305 if (writeCount) {
jvanverth992ad362016-02-26 09:21:02 -0800306 GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(),
Greg Daniel18f96022017-05-04 15:09:03 -0400307 writeCount,
308 descriptorWrites,
jvanverth992ad362016-02-26 09:21:02 -0800309 0, nullptr));
310 }
311}
312
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500313void GrVkPipelineState::setRenderTargetState(const GrRenderTarget* rt, GrSurfaceOrigin origin) {
Robert Phillips2890fbf2017-07-26 15:48:41 -0400314
jvanverth992ad362016-02-26 09:21:02 -0800315 // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
Greg Daniele6ab9982018-08-22 13:56:32 +0000316 if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
317 fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
318 fDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height()));
jvanverth992ad362016-02-26 09:21:02 -0800319 }
320
321 // set RT adjustment
jvanverth992ad362016-02-26 09:21:02 -0800322 SkISize size;
323 size.set(rt->width(), rt->height());
324 SkASSERT(fBuiltinUniformHandles.fRTAdjustmentUni.isValid());
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500325 if (fRenderTargetState.fRenderTargetOrigin != origin ||
jvanverth992ad362016-02-26 09:21:02 -0800326 fRenderTargetState.fRenderTargetSize != size) {
327 fRenderTargetState.fRenderTargetSize = size;
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500328 fRenderTargetState.fRenderTargetOrigin = origin;
jvanverth992ad362016-02-26 09:21:02 -0800329
330 float rtAdjustmentVec[4];
331 fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
egdaniel22281c12016-03-23 13:49:40 -0700332 fDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
jvanverth992ad362016-02-26 09:21:02 -0800333 }
334}
335
Brian Salomonf7232642018-09-19 08:58:08 -0400336void GrVkPipelineState::bindPipeline(const GrVkGpu* gpu, GrVkCommandBuffer* commandBuffer) {
jvanverth992ad362016-02-26 09:21:02 -0800337 commandBuffer->bindPipeline(gpu, fPipeline);
egdanielc2dc1b22016-03-18 13:18:23 -0700338}