blob: 694c84649ce837681cefc2ca4e1df26c8f0f0d89 [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
egdaniel22281c12016-03-23 13:49:40 -07008#include "GrVkPipelineState.h"
Robert Phillips9bee2e52017-05-29 12:37:20 -04009#include "GrContext.h"
Robert Phillips6be756b2018-01-16 15:07:54 -050010#include "GrContextPriv.h"
jvanverth992ad362016-02-26 09:21:02 -080011#include "GrPipeline.h"
Brian Salomon1471df92018-06-08 10:49:00 -040012#include "GrRenderTarget.h"
jvanverth62340062016-04-26 08:01:44 -070013#include "GrTexturePriv.h"
Greg Daniel31ec1442017-05-08 10:30:59 -040014#include "GrVkBufferView.h"
jvanverth992ad362016-02-26 09:21:02 -080015#include "GrVkCommandBuffer.h"
16#include "GrVkDescriptorPool.h"
egdaniela95220d2016-07-21 11:50:37 -070017#include "GrVkDescriptorSet.h"
jvanverth992ad362016-02-26 09:21:02 -080018#include "GrVkGpu.h"
19#include "GrVkImageView.h"
20#include "GrVkMemory.h"
21#include "GrVkPipeline.h"
Greg Daniel7d918fd2018-06-19 15:22:01 -040022#include "GrVkPipelineLayout.h"
jvanverth992ad362016-02-26 09:21:02 -080023#include "GrVkSampler.h"
24#include "GrVkTexture.h"
25#include "GrVkUniformBuffer.h"
Brian Salomon1471df92018-06-08 10:49:00 -040026#include "SkMipMap.h"
jvanverth992ad362016-02-26 09:21:02 -080027#include "glsl/GrGLSLFragmentProcessor.h"
28#include "glsl/GrGLSLGeometryProcessor.h"
29#include "glsl/GrGLSLXferProcessor.h"
30
Brian Salomon1471df92018-06-08 10:49:00 -040031GrVkPipelineState::GrVkPipelineState(
32 GrVkGpu* gpu,
Brian Salomon4d3f5172018-06-07 14:42:52 -040033 GrVkPipeline* pipeline,
34 VkPipelineLayout layout,
35 const GrVkDescriptorSetManager::Handle& samplerDSHandle,
Brian Salomon1471df92018-06-08 10:49:00 -040036 const GrGLSLBuiltinUniformHandles& builtinUniformHandles,
Brian Salomon4d3f5172018-06-07 14:42:52 -040037 const UniformInfoArray& uniforms,
38 uint32_t geometryUniformSize,
39 uint32_t fragmentUniformSize,
40 uint32_t numSamplers,
Brian Salomon4d3f5172018-06-07 14:42:52 -040041 std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
42 std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
43 std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors,
44 int fragmentProcessorCnt)
45 : fPipeline(pipeline)
Greg Daniel7d918fd2018-06-19 15:22:01 -040046 , fPipelineLayout(new GrVkPipelineLayout(layout))
Brian Salomon4d3f5172018-06-07 14:42:52 -040047 , fUniformDescriptorSet(nullptr)
48 , fSamplerDescriptorSet(nullptr)
Brian Salomon4d3f5172018-06-07 14:42:52 -040049 , fSamplerDSHandle(samplerDSHandle)
Brian Salomon4d3f5172018-06-07 14:42:52 -040050 , fBuiltinUniformHandles(builtinUniformHandles)
51 , fGeometryProcessor(std::move(geometryProcessor))
52 , fXferProcessor(std::move(xferProcessor))
53 , fFragmentProcessors(std::move(fragmentProcessors))
54 , fFragmentProcessorCnt(fragmentProcessorCnt)
Brian Salomon4d3f5172018-06-07 14:42:52 -040055 , fDataManager(uniforms, geometryUniformSize, fragmentUniformSize) {
egdanielc2dc1b22016-03-18 13:18:23 -070056 fDescriptorSets[0] = VK_NULL_HANDLE;
57 fDescriptorSets[1] = VK_NULL_HANDLE;
Greg Daniel31ec1442017-05-08 10:30:59 -040058 fDescriptorSets[2] = VK_NULL_HANDLE;
jvanverth992ad362016-02-26 09:21:02 -080059
Greg Daniel18f96022017-05-04 15:09:03 -040060 fGeometryUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, geometryUniformSize));
jvanverth4c6e47a2016-07-22 10:34:52 -070061 fFragmentUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, fragmentUniformSize));
jvanverth992ad362016-02-26 09:21:02 -080062
jvanverth992ad362016-02-26 09:21:02 -080063 fNumSamplers = numSamplers;
jvanverth992ad362016-02-26 09:21:02 -080064}
65
egdaniel22281c12016-03-23 13:49:40 -070066GrVkPipelineState::~GrVkPipelineState() {
Ethan Nicholas87f340e2017-01-03 14:32:01 -050067 // Must have freed all GPU resources before this is destroyed
jvanverth992ad362016-02-26 09:21:02 -080068 SkASSERT(!fPipeline);
jvanverth992ad362016-02-26 09:21:02 -080069 SkASSERT(!fPipelineLayout);
jvanverth992ad362016-02-26 09:21:02 -080070}
71
egdaniel22281c12016-03-23 13:49:40 -070072void GrVkPipelineState::freeGPUResources(const 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
jvanverth992ad362016-02-26 09:21:02 -080078 if (fPipelineLayout) {
Greg Daniel7d918fd2018-06-19 15:22:01 -040079 fPipelineLayout->unref(gpu);
80 fPipelineLayout = nullptr;
jvanverth992ad362016-02-26 09:21:02 -080081 }
82
Greg Daniel18f96022017-05-04 15:09:03 -040083 if (fGeometryUniformBuffer) {
84 fGeometryUniformBuffer->release(gpu);
Greg Danieladb4bfe2018-08-23 16:15:05 -040085 fGeometryUniformBuffer.reset();
jvanverth992ad362016-02-26 09:21:02 -080086 }
87
88 if (fFragmentUniformBuffer) {
89 fFragmentUniformBuffer->release(gpu);
Greg Danieladb4bfe2018-08-23 16:15:05 -040090 fFragmentUniformBuffer.reset();
jvanverth992ad362016-02-26 09:21:02 -080091 }
egdanielc2dc1b22016-03-18 13:18:23 -070092
egdaniela95220d2016-07-21 11:50:37 -070093 if (fUniformDescriptorSet) {
94 fUniformDescriptorSet->recycle(const_cast<GrVkGpu*>(gpu));
95 fUniformDescriptorSet = nullptr;
egdaniel778555c2016-05-02 06:50:36 -070096 }
egdanielc2dc1b22016-03-18 13:18:23 -070097
egdaniel707bbd62016-07-26 07:19:47 -070098 if (fSamplerDescriptorSet) {
99 fSamplerDescriptorSet->recycle(const_cast<GrVkGpu*>(gpu));
100 fSamplerDescriptorSet = nullptr;
101 }
jvanverth992ad362016-02-26 09:21:02 -0800102}
103
egdaniel22281c12016-03-23 13:49:40 -0700104void GrVkPipelineState::abandonGPUResources() {
Greg Daniel7d918fd2018-06-19 15:22:01 -0400105 if (fPipeline) {
106 fPipeline->unrefAndAbandon();
107 fPipeline = nullptr;
108 }
egdanielc2dc1b22016-03-18 13:18:23 -0700109
Greg Daniel7d918fd2018-06-19 15:22:01 -0400110 if (fPipelineLayout) {
111 fPipelineLayout->unrefAndAbandon();
112 fPipelineLayout = nullptr;
113 }
jvanverth992ad362016-02-26 09:21:02 -0800114
Greg Danieladb4bfe2018-08-23 16:15:05 -0400115 if (fGeometryUniformBuffer) {
116 fGeometryUniformBuffer->abandon();
117 fGeometryUniformBuffer.reset();
118 }
119
120 if (fFragmentUniformBuffer) {
121 fFragmentUniformBuffer->abandon();
122 fFragmentUniformBuffer.reset();
123 }
jvanverth992ad362016-02-26 09:21:02 -0800124
egdaniela95220d2016-07-21 11:50:37 -0700125 if (fUniformDescriptorSet) {
126 fUniformDescriptorSet->unrefAndAbandon();
127 fUniformDescriptorSet = nullptr;
egdaniel778555c2016-05-02 06:50:36 -0700128 }
egdaniel707bbd62016-07-26 07:19:47 -0700129
130 if (fSamplerDescriptorSet) {
131 fSamplerDescriptorSet->unrefAndAbandon();
132 fSamplerDescriptorSet = nullptr;
133 }
jvanverth992ad362016-02-26 09:21:02 -0800134}
135
Brian Salomon5e81a122018-08-23 16:46:07 -0400136void GrVkPipelineState::setAndBindUniforms(GrVkGpu* gpu,
137 const GrPrimitiveProcessor& primProc,
138 const GrPipeline& pipeline,
139 GrVkCommandBuffer* commandBuffer) {
Robert Phillips2890fbf2017-07-26 15:48:41 -0400140 this->setRenderTargetState(pipeline.proxy());
jvanverth992ad362016-02-26 09:21:02 -0800141
bsalomona624bf32016-09-20 09:12:47 -0700142 fGeometryProcessor->setData(fDataManager, primProc,
143 GrFragmentProcessor::CoordTransformIter(pipeline));
bsalomonb58a2b42016-09-26 06:55:02 -0700144 GrFragmentProcessor::Iter iter(pipeline);
Brian Salomon4d3f5172018-06-07 14:42:52 -0400145 GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
bsalomonb58a2b42016-09-26 06:55:02 -0700146 const GrFragmentProcessor* fp = iter.next();
147 GrGLSLFragmentProcessor* glslFP = glslIter.next();
148 while (fp && glslFP) {
149 glslFP->setData(fDataManager, *fp);
mtklein85552e42016-09-26 08:39:43 -0700150 fp = iter.next();
151 glslFP = glslIter.next();
jvanverth992ad362016-02-26 09:21:02 -0800152 }
bsalomonb58a2b42016-09-26 06:55:02 -0700153 SkASSERT(!fp && !glslFP);
jvanverth992ad362016-02-26 09:21:02 -0800154
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400155 {
156 SkIPoint offset;
157 GrTexture* dstTexture = pipeline.peekDstTexture(&offset);
158
159 fXferProcessor->setData(fDataManager, pipeline.getXferProcessor(), dstTexture, offset);
160 }
161
Brian Salomon5e81a122018-08-23 16:46:07 -0400162 // Get new descriptor set
163 if (fGeometryUniformBuffer || fFragmentUniformBuffer) {
164 int uniformDSIdx = GrVkUniformHandler::kUniformBufferDescSet;
165 if (fDataManager.uploadUniformBuffers(
166 gpu, fGeometryUniformBuffer.get(), fFragmentUniformBuffer.get()) ||
167 !fUniformDescriptorSet) {
168 if (fUniformDescriptorSet) {
169 fUniformDescriptorSet->recycle(gpu);
170 }
171 fUniformDescriptorSet = gpu->resourceProvider().getUniformDescriptorSet();
172 fDescriptorSets[uniformDSIdx] = fUniformDescriptorSet->descriptorSet();
173 this->writeUniformBuffers(gpu);
174 }
175 commandBuffer->bindDescriptorSets(gpu, this, fPipelineLayout, uniformDSIdx, 1,
176 &fDescriptorSets[uniformDSIdx], 0, nullptr);
177 if (fUniformDescriptorSet) {
178 commandBuffer->addRecycledResource(fUniformDescriptorSet);
179 }
180 if (fGeometryUniformBuffer) {
181 commandBuffer->addRecycledResource(fGeometryUniformBuffer->resource());
182 }
183 if (fFragmentUniformBuffer) {
184 commandBuffer->addRecycledResource(fFragmentUniformBuffer->resource());
185 }
186 }
187}
188
189void GrVkPipelineState::setAndBindTextures(GrVkGpu* gpu,
190 const GrPrimitiveProcessor& primProc,
191 const GrPipeline& pipeline,
192 const GrTextureProxy* const primProcTextures[],
193 GrVkCommandBuffer* commandBuffer) {
194 SkASSERT(primProcTextures || !primProc.numTextureSamplers());
195
196 struct SamplerBindings {
197 GrSamplerState fState;
198 GrVkTexture* fTexture;
199 };
200 SkAutoSTMalloc<8, SamplerBindings> samplerBindings(fNumSamplers);
201 int currTextureBinding = 0;
202
203 fGeometryProcessor->setData(fDataManager, primProc,
204 GrFragmentProcessor::CoordTransformIter(pipeline));
205 for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
206 const auto& sampler = primProc.textureSampler(i);
207 auto texture = static_cast<GrVkTexture*>(primProcTextures[i]->peekTexture());
208 samplerBindings[currTextureBinding++] = {sampler.samplerState(), texture};
209 }
210
211 GrFragmentProcessor::Iter iter(pipeline);
212 GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
213 const GrFragmentProcessor* fp = iter.next();
214 GrGLSLFragmentProcessor* glslFP = glslIter.next();
215 while (fp && glslFP) {
216 for (int i = 0; i < fp->numTextureSamplers(); ++i) {
217 const auto& sampler = fp->textureSampler(i);
218 samplerBindings[currTextureBinding++] =
219 {sampler.samplerState(), static_cast<GrVkTexture*>(sampler.peekTexture())};
220 }
221 fp = iter.next();
222 glslFP = glslIter.next();
223 }
224 SkASSERT(!fp && !glslFP);
225
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400226 if (GrTextureProxy* dstTextureProxy = pipeline.dstTextureProxy()) {
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400227 samplerBindings[currTextureBinding++] = {
228 GrSamplerState::ClampNearest(),
229 static_cast<GrVkTexture*>(dstTextureProxy->peekTexture())};
Brian Salomon18dfa982017-04-03 16:57:43 -0400230 }
jvanverth992ad362016-02-26 09:21:02 -0800231
Brian Salomon5e81a122018-08-23 16:46:07 -0400232 // Get new descriptor set
Brian Salomone782f842018-07-31 13:53:11 -0400233 SkASSERT(fNumSamplers == currTextureBinding);
egdanielc2dc1b22016-03-18 13:18:23 -0700234 if (fNumSamplers) {
egdaniel707bbd62016-07-26 07:19:47 -0700235 if (fSamplerDescriptorSet) {
236 fSamplerDescriptorSet->recycle(gpu);
237 }
238 fSamplerDescriptorSet = gpu->resourceProvider().getSamplerDescriptorSet(fSamplerDSHandle);
239 int samplerDSIdx = GrVkUniformHandler::kSamplerDescSet;
240 fDescriptorSets[samplerDSIdx] = fSamplerDescriptorSet->descriptorSet();
Brian Salomon5e81a122018-08-23 16:46:07 -0400241 for (int i = 0; i < fNumSamplers; ++i) {
242 const GrSamplerState& state = samplerBindings[i].fState;
243 GrVkTexture* texture = samplerBindings[i].fTexture;
egdanielb4aa3622016-04-06 13:47:08 -0700244
Brian Salomon5e81a122018-08-23 16:46:07 -0400245 const GrVkImageView* textureView = texture->textureView();
246 GrVkSampler* sampler = gpu->resourceProvider().findOrCreateCompatibleSampler(
247 state, texture->texturePriv().maxMipMapLevel());
248
249 VkDescriptorImageInfo imageInfo;
250 memset(&imageInfo, 0, sizeof(VkDescriptorImageInfo));
251 imageInfo.sampler = sampler->sampler();
252 imageInfo.imageView = textureView->imageView();
253 imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
254
255 VkWriteDescriptorSet writeInfo;
256 memset(&writeInfo, 0, sizeof(VkWriteDescriptorSet));
257 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
258 writeInfo.pNext = nullptr;
259 writeInfo.dstSet = fDescriptorSets[GrVkUniformHandler::kSamplerDescSet];
260 writeInfo.dstBinding = i;
261 writeInfo.dstArrayElement = 0;
262 writeInfo.descriptorCount = 1;
263 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
264 writeInfo.pImageInfo = &imageInfo;
265 writeInfo.pBufferInfo = nullptr;
266 writeInfo.pTexelBufferView = nullptr;
267
268 GR_VK_CALL(gpu->vkInterface(),
269 UpdateDescriptorSets(gpu->device(), 1, &writeInfo, 0, nullptr));
270 commandBuffer->addResource(sampler);
271 sampler->unref(gpu);
272 commandBuffer->addResource(samplerBindings[i].fTexture->textureView());
273 commandBuffer->addResource(samplerBindings[i].fTexture->resource());
egdaniel7cbffda2016-04-08 13:27:53 -0700274 }
Brian Salomon5e81a122018-08-23 16:46:07 -0400275
276 commandBuffer->bindDescriptorSets(gpu, this, fPipelineLayout, samplerDSIdx, 1,
277 &fDescriptorSets[samplerDSIdx], 0, nullptr);
278 commandBuffer->addRecycledResource(fSamplerDescriptorSet);
egdanielb4aa3622016-04-06 13:47:08 -0700279 }
jvanverth992ad362016-02-26 09:21:02 -0800280}
281
Greg Daniel18f96022017-05-04 15:09:03 -0400282void set_uniform_descriptor_writes(VkWriteDescriptorSet* descriptorWrite,
283 VkDescriptorBufferInfo* bufferInfo,
284 const GrVkUniformBuffer* buffer,
285 VkDescriptorSet descriptorSet,
286 uint32_t binding) {
287
288 memset(bufferInfo, 0, sizeof(VkDescriptorBufferInfo));
289 bufferInfo->buffer = buffer->buffer();
290 bufferInfo->offset = buffer->offset();
291 bufferInfo->range = buffer->size();
292
293 memset(descriptorWrite, 0, sizeof(VkWriteDescriptorSet));
294 descriptorWrite->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
295 descriptorWrite->pNext = nullptr;
Greg Daniel783c4362017-05-04 17:29:09 -0400296 descriptorWrite->dstSet = descriptorSet;
Greg Daniel18f96022017-05-04 15:09:03 -0400297 descriptorWrite->dstBinding = binding;
298 descriptorWrite->dstArrayElement = 0;
299 descriptorWrite->descriptorCount = 1;
300 descriptorWrite->descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
301 descriptorWrite->pImageInfo = nullptr;
302 descriptorWrite->pBufferInfo = bufferInfo;
303 descriptorWrite->pTexelBufferView = nullptr;
304}
305
egdaniel22281c12016-03-23 13:49:40 -0700306void GrVkPipelineState::writeUniformBuffers(const GrVkGpu* gpu) {
Greg Daniel18f96022017-05-04 15:09:03 -0400307 VkWriteDescriptorSet descriptorWrites[3];
308 VkDescriptorBufferInfo bufferInfos[3];
jvanverth992ad362016-02-26 09:21:02 -0800309
Greg Daniel18f96022017-05-04 15:09:03 -0400310 uint32_t writeCount = 0;
jvanverth992ad362016-02-26 09:21:02 -0800311
Greg Daniel18f96022017-05-04 15:09:03 -0400312 // Geometry Uniform Buffer
313 if (fGeometryUniformBuffer.get()) {
314 set_uniform_descriptor_writes(&descriptorWrites[writeCount],
315 &bufferInfos[writeCount],
316 fGeometryUniformBuffer.get(),
317 fDescriptorSets[GrVkUniformHandler::kUniformBufferDescSet],
318 GrVkUniformHandler::kGeometryBinding);
319 ++writeCount;
jvanverth992ad362016-02-26 09:21:02 -0800320 }
321
322 // Fragment Uniform Buffer
323 if (fFragmentUniformBuffer.get()) {
Greg Daniel18f96022017-05-04 15:09:03 -0400324 set_uniform_descriptor_writes(&descriptorWrites[writeCount],
325 &bufferInfos[writeCount],
326 fFragmentUniformBuffer.get(),
327 fDescriptorSets[GrVkUniformHandler::kUniformBufferDescSet],
328 GrVkUniformHandler::kFragBinding);
329 ++writeCount;
jvanverth992ad362016-02-26 09:21:02 -0800330 }
331
Greg Daniel18f96022017-05-04 15:09:03 -0400332 if (writeCount) {
jvanverth992ad362016-02-26 09:21:02 -0800333 GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(),
Greg Daniel18f96022017-05-04 15:09:03 -0400334 writeCount,
335 descriptorWrites,
jvanverth992ad362016-02-26 09:21:02 -0800336 0, nullptr));
337 }
338}
339
Robert Phillips2890fbf2017-07-26 15:48:41 -0400340void GrVkPipelineState::setRenderTargetState(const GrRenderTargetProxy* proxy) {
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400341 GrRenderTarget* rt = proxy->peekRenderTarget();
Robert Phillips2890fbf2017-07-26 15:48:41 -0400342
jvanverth992ad362016-02-26 09:21:02 -0800343 // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
Greg Daniele6ab9982018-08-22 13:56:32 +0000344 if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
345 fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
346 fDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height()));
jvanverth992ad362016-02-26 09:21:02 -0800347 }
348
349 // set RT adjustment
jvanverth992ad362016-02-26 09:21:02 -0800350 SkISize size;
351 size.set(rt->width(), rt->height());
352 SkASSERT(fBuiltinUniformHandles.fRTAdjustmentUni.isValid());
Robert Phillips2890fbf2017-07-26 15:48:41 -0400353 if (fRenderTargetState.fRenderTargetOrigin != proxy->origin() ||
jvanverth992ad362016-02-26 09:21:02 -0800354 fRenderTargetState.fRenderTargetSize != size) {
355 fRenderTargetState.fRenderTargetSize = size;
Robert Phillips2890fbf2017-07-26 15:48:41 -0400356 fRenderTargetState.fRenderTargetOrigin = proxy->origin();
jvanverth992ad362016-02-26 09:21:02 -0800357
358 float rtAdjustmentVec[4];
359 fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
egdaniel22281c12016-03-23 13:49:40 -0700360 fDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
jvanverth992ad362016-02-26 09:21:02 -0800361 }
362}
363
Brian Salomon5e81a122018-08-23 16:46:07 -0400364void GrVkPipelineState::bindPipeline(const GrVkGpu* gpu, GrVkCommandBuffer* commandBuffer) {
jvanverth992ad362016-02-26 09:21:02 -0800365 commandBuffer->bindPipeline(gpu, fPipeline);
egdanielc2dc1b22016-03-18 13:18:23 -0700366}