blob: 90a27e35a76a4b3e1f28310f7ec72da90ceb0955 [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"
jvanverth992ad362016-02-26 09:21:02 -08009
10#include "GrPipeline.h"
11#include "GrVkCommandBuffer.h"
12#include "GrVkDescriptorPool.h"
13#include "GrVkGpu.h"
14#include "GrVkImageView.h"
15#include "GrVkMemory.h"
16#include "GrVkPipeline.h"
egdaniel22281c12016-03-23 13:49:40 -070017#include "GrVkRenderTarget.h"
jvanverth992ad362016-02-26 09:21:02 -080018#include "GrVkSampler.h"
19#include "GrVkTexture.h"
20#include "GrVkUniformBuffer.h"
21#include "glsl/GrGLSLFragmentProcessor.h"
22#include "glsl/GrGLSLGeometryProcessor.h"
23#include "glsl/GrGLSLXferProcessor.h"
24
egdaniel22281c12016-03-23 13:49:40 -070025GrVkPipelineState::GrVkPipelineState(GrVkGpu* gpu,
26 const GrVkPipelineState::Desc& desc,
27 GrVkPipeline* pipeline,
28 VkPipelineLayout layout,
29 VkDescriptorSetLayout dsLayout[2],
30 const BuiltinUniformHandles& builtinUniformHandles,
31 const UniformInfoArray& uniforms,
32 uint32_t vertexUniformSize,
33 uint32_t fragmentUniformSize,
34 uint32_t numSamplers,
35 GrGLSLPrimitiveProcessor* geometryProcessor,
36 GrGLSLXferProcessor* xferProcessor,
37 const GrGLSLFragProcs& fragmentProcessors)
egdanielc2dc1b22016-03-18 13:18:23 -070038 : fPipeline(pipeline)
jvanverth992ad362016-02-26 09:21:02 -080039 , fPipelineLayout(layout)
egdanielb4aa3622016-04-06 13:47:08 -070040 , fStartDS(SK_MaxS32)
41 , fDSCount(0)
jvanverth992ad362016-02-26 09:21:02 -080042 , fBuiltinUniformHandles(builtinUniformHandles)
43 , fGeometryProcessor(geometryProcessor)
44 , fXferProcessor(xferProcessor)
45 , fFragmentProcessors(fragmentProcessors)
egdaniel22281c12016-03-23 13:49:40 -070046 , fDesc(desc)
47 , fDataManager(uniforms, vertexUniformSize, fragmentUniformSize)
egdanielc2dc1b22016-03-18 13:18:23 -070048 , fSamplerPoolManager(dsLayout[GrVkUniformHandler::kSamplerDescSet],
49 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, numSamplers, gpu)
50 , fUniformPoolManager(dsLayout[GrVkUniformHandler::kUniformBufferDescSet],
egdanielb4aa3622016-04-06 13:47:08 -070051 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
52 (vertexUniformSize || fragmentUniformSize) ? 2 : 0, gpu) {
jvanverth992ad362016-02-26 09:21:02 -080053 fSamplers.setReserve(numSamplers);
54 fTextureViews.setReserve(numSamplers);
55 fTextures.setReserve(numSamplers);
56
egdanielc2dc1b22016-03-18 13:18:23 -070057 fDescriptorSets[0] = VK_NULL_HANDLE;
58 fDescriptorSets[1] = VK_NULL_HANDLE;
59
60 // Currently we are always binding a descriptor set for uniform buffers.
egdanielb4aa3622016-04-06 13:47:08 -070061 if (vertexUniformSize || fragmentUniformSize) {
62 fDSCount++;
63 fStartDS = GrVkUniformHandler::kUniformBufferDescSet;
64 }
egdanielc2dc1b22016-03-18 13:18:23 -070065 if (numSamplers) {
66 fDSCount++;
67 fStartDS = SkTMin(fStartDS, (int)GrVkUniformHandler::kSamplerDescSet);
68 }
jvanverth992ad362016-02-26 09:21:02 -080069
70 fVertexUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, vertexUniformSize, true));
71 fFragmentUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, fragmentUniformSize, true));
72
jvanverth992ad362016-02-26 09:21:02 -080073 fNumSamplers = numSamplers;
jvanverth992ad362016-02-26 09:21:02 -080074}
75
egdaniel22281c12016-03-23 13:49:40 -070076GrVkPipelineState::~GrVkPipelineState() {
jvanverth992ad362016-02-26 09:21:02 -080077 // Must of freed all GPU resources before this is destroyed
78 SkASSERT(!fPipeline);
jvanverth992ad362016-02-26 09:21:02 -080079 SkASSERT(!fPipelineLayout);
jvanverth992ad362016-02-26 09:21:02 -080080 SkASSERT(!fSamplers.count());
81 SkASSERT(!fTextureViews.count());
82 SkASSERT(!fTextures.count());
83}
84
egdaniel22281c12016-03-23 13:49:40 -070085void GrVkPipelineState::freeTempResources(const GrVkGpu* gpu) {
jvanverth992ad362016-02-26 09:21:02 -080086 for (int i = 0; i < fSamplers.count(); ++i) {
87 fSamplers[i]->unref(gpu);
88 }
89 fSamplers.rewind();
90
91 for (int i = 0; i < fTextureViews.count(); ++i) {
92 fTextureViews[i]->unref(gpu);
93 }
94 fTextureViews.rewind();
95
96 for (int i = 0; i < fTextures.count(); ++i) {
97 fTextures[i]->unref(gpu);
98 }
99 fTextures.rewind();
100}
101
egdaniel22281c12016-03-23 13:49:40 -0700102void GrVkPipelineState::freeGPUResources(const GrVkGpu* gpu) {
jvanverth992ad362016-02-26 09:21:02 -0800103 if (fPipeline) {
104 fPipeline->unref(gpu);
105 fPipeline = nullptr;
106 }
egdanielc2dc1b22016-03-18 13:18:23 -0700107
jvanverth992ad362016-02-26 09:21:02 -0800108 if (fPipelineLayout) {
109 GR_VK_CALL(gpu->vkInterface(), DestroyPipelineLayout(gpu->device(),
110 fPipelineLayout,
111 nullptr));
jvanverth9846ef22016-03-02 12:08:22 -0800112 fPipelineLayout = VK_NULL_HANDLE;
jvanverth992ad362016-02-26 09:21:02 -0800113 }
114
jvanverth992ad362016-02-26 09:21:02 -0800115 if (fVertexUniformBuffer) {
116 fVertexUniformBuffer->release(gpu);
117 }
118
119 if (fFragmentUniformBuffer) {
120 fFragmentUniformBuffer->release(gpu);
121 }
egdanielc2dc1b22016-03-18 13:18:23 -0700122
123 fSamplerPoolManager.freeGPUResources(gpu);
124 fUniformPoolManager.freeGPUResources(gpu);
125
jvanverth992ad362016-02-26 09:21:02 -0800126 this->freeTempResources(gpu);
127}
128
egdaniel22281c12016-03-23 13:49:40 -0700129void GrVkPipelineState::abandonGPUResources() {
jvanverth992ad362016-02-26 09:21:02 -0800130 fPipeline->unrefAndAbandon();
131 fPipeline = nullptr;
egdanielc2dc1b22016-03-18 13:18:23 -0700132
jvanverth9846ef22016-03-02 12:08:22 -0800133 fPipelineLayout = VK_NULL_HANDLE;
jvanverth992ad362016-02-26 09:21:02 -0800134
135 fVertexUniformBuffer->abandon();
136 fFragmentUniformBuffer->abandon();
137
138 for (int i = 0; i < fSamplers.count(); ++i) {
139 fSamplers[i]->unrefAndAbandon();
140 }
141 fSamplers.rewind();
142
143 for (int i = 0; i < fTextureViews.count(); ++i) {
144 fTextureViews[i]->unrefAndAbandon();
145 }
146 fTextureViews.rewind();
147
148 for (int i = 0; i < fTextures.count(); ++i) {
149 fTextures[i]->unrefAndAbandon();
150 }
151 fTextures.rewind();
egdanielc2dc1b22016-03-18 13:18:23 -0700152
153 fSamplerPoolManager.abandonGPUResources();
154 fUniformPoolManager.abandonGPUResources();
jvanverth992ad362016-02-26 09:21:02 -0800155}
156
157static void append_texture_bindings(const GrProcessor& processor,
158 SkTArray<const GrTextureAccess*>* textureBindings) {
159 if (int numTextures = processor.numTextures()) {
160 const GrTextureAccess** bindings = textureBindings->push_back_n(numTextures);
161 int i = 0;
162 do {
163 bindings[i] = &processor.textureAccess(i);
164 } while (++i < numTextures);
165 }
166}
167
egdaniel22281c12016-03-23 13:49:40 -0700168void GrVkPipelineState::setData(GrVkGpu* gpu,
169 const GrPrimitiveProcessor& primProc,
170 const GrPipeline& pipeline) {
jvanverth992ad362016-02-26 09:21:02 -0800171 // This is here to protect against someone calling setData multiple times in a row without
172 // freeing the tempData between calls.
173 this->freeTempResources(gpu);
174
175 this->setRenderTargetState(pipeline);
176
177 SkSTArray<8, const GrTextureAccess*> textureBindings;
178
egdaniel22281c12016-03-23 13:49:40 -0700179 fGeometryProcessor->setData(fDataManager, primProc);
jvanverth992ad362016-02-26 09:21:02 -0800180 append_texture_bindings(primProc, &textureBindings);
181
182 for (int i = 0; i < fFragmentProcessors.count(); ++i) {
183 const GrFragmentProcessor& processor = pipeline.getFragmentProcessor(i);
egdaniel22281c12016-03-23 13:49:40 -0700184 fFragmentProcessors[i]->setData(fDataManager, processor);
185 fGeometryProcessor->setTransformData(primProc, fDataManager, i,
jvanverth992ad362016-02-26 09:21:02 -0800186 processor.coordTransforms());
187 append_texture_bindings(processor, &textureBindings);
188 }
189
egdaniel22281c12016-03-23 13:49:40 -0700190 fXferProcessor->setData(fDataManager, pipeline.getXferProcessor());
jvanverth992ad362016-02-26 09:21:02 -0800191 append_texture_bindings(pipeline.getXferProcessor(), &textureBindings);
192
egdanielc2dc1b22016-03-18 13:18:23 -0700193 // Get new descriptor sets
194 if (fNumSamplers) {
195 fSamplerPoolManager.getNewDescriptorSet(gpu,
196 &fDescriptorSets[GrVkUniformHandler::kSamplerDescSet]);
egdanielb4aa3622016-04-06 13:47:08 -0700197 this->writeSamplers(gpu, textureBindings);
egdanielc2dc1b22016-03-18 13:18:23 -0700198 }
egdanielb4aa3622016-04-06 13:47:08 -0700199
200
201 if (fVertexUniformBuffer.get() || fFragmentUniformBuffer.get()) {
202 fUniformPoolManager.getNewDescriptorSet(gpu,
egdanielc2dc1b22016-03-18 13:18:23 -0700203 &fDescriptorSets[GrVkUniformHandler::kUniformBufferDescSet]);
egdanielb4aa3622016-04-06 13:47:08 -0700204 this->writeUniformBuffers(gpu);
205 }
jvanverth992ad362016-02-26 09:21:02 -0800206}
207
egdaniel22281c12016-03-23 13:49:40 -0700208void GrVkPipelineState::writeUniformBuffers(const GrVkGpu* gpu) {
209 fDataManager.uploadUniformBuffers(gpu, fVertexUniformBuffer, fFragmentUniformBuffer);
jvanverth992ad362016-02-26 09:21:02 -0800210
211 VkWriteDescriptorSet descriptorWrites[2];
212 memset(descriptorWrites, 0, 2 * sizeof(VkWriteDescriptorSet));
213
214 uint32_t firstUniformWrite = 0;
215 uint32_t uniformBindingUpdateCount = 0;
216
egdanield524f162016-02-26 13:06:55 -0800217 VkDescriptorBufferInfo vertBufferInfo;
jvanverth992ad362016-02-26 09:21:02 -0800218 // Vertex Uniform Buffer
219 if (fVertexUniformBuffer.get()) {
220 ++uniformBindingUpdateCount;
jvanverth992ad362016-02-26 09:21:02 -0800221 memset(&vertBufferInfo, 0, sizeof(VkDescriptorBufferInfo));
222 vertBufferInfo.buffer = fVertexUniformBuffer->buffer();
223 vertBufferInfo.offset = 0;
224 vertBufferInfo.range = fVertexUniformBuffer->size();
225
226 descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
227 descriptorWrites[0].pNext = nullptr;
egdanielb4aa3622016-04-06 13:47:08 -0700228 descriptorWrites[0].dstSet = fDescriptorSets[GrVkUniformHandler::kUniformBufferDescSet];
jvanverth992ad362016-02-26 09:21:02 -0800229 descriptorWrites[0].dstBinding = GrVkUniformHandler::kVertexBinding;
230 descriptorWrites[0].dstArrayElement = 0;
231 descriptorWrites[0].descriptorCount = 1;
232 descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
233 descriptorWrites[0].pImageInfo = nullptr;
234 descriptorWrites[0].pBufferInfo = &vertBufferInfo;
235 descriptorWrites[0].pTexelBufferView = nullptr;
egdaniel22281c12016-03-23 13:49:40 -0700236
237 fVertexUniformBuffer->addMemoryBarrier(gpu,
238 VK_ACCESS_HOST_WRITE_BIT,
239 VK_ACCESS_UNIFORM_READ_BIT,
240 VK_PIPELINE_STAGE_HOST_BIT,
241 VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
242 false);
jvanverth992ad362016-02-26 09:21:02 -0800243 }
244
egdanield524f162016-02-26 13:06:55 -0800245 VkDescriptorBufferInfo fragBufferInfo;
jvanverth992ad362016-02-26 09:21:02 -0800246 // Fragment Uniform Buffer
247 if (fFragmentUniformBuffer.get()) {
248 if (0 == uniformBindingUpdateCount) {
249 firstUniformWrite = 1;
250 }
251 ++uniformBindingUpdateCount;
jvanverth992ad362016-02-26 09:21:02 -0800252 memset(&fragBufferInfo, 0, sizeof(VkDescriptorBufferInfo));
253 fragBufferInfo.buffer = fFragmentUniformBuffer->buffer();
254 fragBufferInfo.offset = 0;
255 fragBufferInfo.range = fFragmentUniformBuffer->size();
256
257 descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
258 descriptorWrites[1].pNext = nullptr;
egdanielb4aa3622016-04-06 13:47:08 -0700259 descriptorWrites[1].dstSet = fDescriptorSets[GrVkUniformHandler::kUniformBufferDescSet];
jvanverth992ad362016-02-26 09:21:02 -0800260 descriptorWrites[1].dstBinding = GrVkUniformHandler::kFragBinding;;
261 descriptorWrites[1].dstArrayElement = 0;
262 descriptorWrites[1].descriptorCount = 1;
263 descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
264 descriptorWrites[1].pImageInfo = nullptr;
265 descriptorWrites[1].pBufferInfo = &fragBufferInfo;
266 descriptorWrites[1].pTexelBufferView = nullptr;
egdaniel22281c12016-03-23 13:49:40 -0700267
268 fFragmentUniformBuffer->addMemoryBarrier(gpu,
269 VK_ACCESS_HOST_WRITE_BIT,
270 VK_ACCESS_UNIFORM_READ_BIT,
271 VK_PIPELINE_STAGE_HOST_BIT,
272 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
273 false);
jvanverth992ad362016-02-26 09:21:02 -0800274 }
275
276 if (uniformBindingUpdateCount) {
277 GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(),
278 uniformBindingUpdateCount,
279 &descriptorWrites[firstUniformWrite],
280 0, nullptr));
281 }
282}
283
egdaniel22281c12016-03-23 13:49:40 -0700284void GrVkPipelineState::writeSamplers(GrVkGpu* gpu,
285 const SkTArray<const GrTextureAccess*>& textureBindings) {
jvanverth992ad362016-02-26 09:21:02 -0800286 SkASSERT(fNumSamplers == textureBindings.count());
287
288 for (int i = 0; i < textureBindings.count(); ++i) {
egdaniel8b6394c2016-03-04 07:35:10 -0800289 const GrTextureParams& params = textureBindings[i]->getParams();
290 fSamplers.push(gpu->resourceProvider().findOrCreateCompatibleSampler(params));
jvanverth992ad362016-02-26 09:21:02 -0800291
292 GrVkTexture* texture = static_cast<GrVkTexture*>(textureBindings[i]->getTexture());
293
294 const GrVkImage::Resource* textureResource = texture->resource();
295 textureResource->ref();
296 fTextures.push(textureResource);
297
298 const GrVkImageView* textureView = texture->textureView();
299 textureView->ref();
300 fTextureViews.push(textureView);
301
302 // Change texture layout so it can be read in shader
303 VkImageLayout layout = texture->currentLayout();
304 VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(layout);
305 VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
306 VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(layout);
307 VkAccessFlags dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
308 texture->setImageLayout(gpu,
309 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
310 srcAccessMask,
311 dstAccessMask,
312 srcStageMask,
313 dstStageMask,
314 false);
315
316 VkDescriptorImageInfo imageInfo;
317 memset(&imageInfo, 0, sizeof(VkDescriptorImageInfo));
318 imageInfo.sampler = fSamplers[i]->sampler();
319 imageInfo.imageView = texture->textureView()->imageView();
320 imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
321
322 VkWriteDescriptorSet writeInfo;
323 memset(&writeInfo, 0, sizeof(VkWriteDescriptorSet));
324 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
325 writeInfo.pNext = nullptr;
326 writeInfo.dstSet = fDescriptorSets[GrVkUniformHandler::kSamplerDescSet];
327 writeInfo.dstBinding = i;
328 writeInfo.dstArrayElement = 0;
329 writeInfo.descriptorCount = 1;
330 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
331 writeInfo.pImageInfo = &imageInfo;
332 writeInfo.pBufferInfo = nullptr;
333 writeInfo.pTexelBufferView = nullptr;
334
335 GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(),
336 1,
337 &writeInfo,
338 0,
339 nullptr));
340 }
341}
342
egdaniel22281c12016-03-23 13:49:40 -0700343void GrVkPipelineState::setRenderTargetState(const GrPipeline& pipeline) {
jvanverth992ad362016-02-26 09:21:02 -0800344 // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
345 if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
346 fRenderTargetState.fRenderTargetSize.fHeight != pipeline.getRenderTarget()->height()) {
egdaniel22281c12016-03-23 13:49:40 -0700347 fDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni,
jvanverth992ad362016-02-26 09:21:02 -0800348 SkIntToScalar(pipeline.getRenderTarget()->height()));
349 }
350
351 // set RT adjustment
352 const GrRenderTarget* rt = pipeline.getRenderTarget();
353 SkISize size;
354 size.set(rt->width(), rt->height());
355 SkASSERT(fBuiltinUniformHandles.fRTAdjustmentUni.isValid());
356 if (fRenderTargetState.fRenderTargetOrigin != rt->origin() ||
357 fRenderTargetState.fRenderTargetSize != size) {
358 fRenderTargetState.fRenderTargetSize = size;
359 fRenderTargetState.fRenderTargetOrigin = rt->origin();
360
361 float rtAdjustmentVec[4];
362 fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
egdaniel22281c12016-03-23 13:49:40 -0700363 fDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
jvanverth992ad362016-02-26 09:21:02 -0800364 }
365}
366
egdaniel22281c12016-03-23 13:49:40 -0700367void GrVkPipelineState::bind(const GrVkGpu* gpu, GrVkCommandBuffer* commandBuffer) {
jvanverth992ad362016-02-26 09:21:02 -0800368 commandBuffer->bindPipeline(gpu, fPipeline);
egdanielc2dc1b22016-03-18 13:18:23 -0700369
370 if (fDSCount) {
371 commandBuffer->bindDescriptorSets(gpu, this, fPipelineLayout, fStartDS, fDSCount,
372 &fDescriptorSets[fStartDS], 0, nullptr);
373 }
jvanverth992ad362016-02-26 09:21:02 -0800374}
375
egdaniel22281c12016-03-23 13:49:40 -0700376void GrVkPipelineState::addUniformResources(GrVkCommandBuffer& commandBuffer) {
egdanielc2dc1b22016-03-18 13:18:23 -0700377 if (fSamplerPoolManager.fPool) {
378 commandBuffer.addResource(fSamplerPoolManager.fPool);
379 }
380 if (fUniformPoolManager.fPool) {
381 commandBuffer.addResource(fUniformPoolManager.fPool);
382 }
383
jvanverth992ad362016-02-26 09:21:02 -0800384 if (fVertexUniformBuffer.get()) {
385 commandBuffer.addResource(fVertexUniformBuffer->resource());
386 }
387 if (fFragmentUniformBuffer.get()) {
388 commandBuffer.addResource(fFragmentUniformBuffer->resource());
389 }
390 for (int i = 0; i < fSamplers.count(); ++i) {
391 commandBuffer.addResource(fSamplers[i]);
392 }
393
394 for (int i = 0; i < fTextureViews.count(); ++i) {
395 commandBuffer.addResource(fTextureViews[i]);
396 }
397
398 for (int i = 0; i < fTextures.count(); ++i) {
399 commandBuffer.addResource(fTextures[i]);
400 }
egdanielc2dc1b22016-03-18 13:18:23 -0700401}
402
403////////////////////////////////////////////////////////////////////////////////
404
egdaniel22281c12016-03-23 13:49:40 -0700405void GrVkPipelineState::DescriptorPoolManager::getNewPool(GrVkGpu* gpu) {
egdanielc2dc1b22016-03-18 13:18:23 -0700406 if (fPool) {
407 fPool->unref(gpu);
408 SkASSERT(fMaxDescriptorSets < (SK_MaxU32 >> 1));
409 fMaxDescriptorSets = fMaxDescriptorSets << 1;
410
411 }
412 if (fMaxDescriptorSets) {
413 fPool = gpu->resourceProvider().findOrCreateCompatibleDescriptorPool(fDescType,
414 fMaxDescriptorSets);
415 }
416 SkASSERT(fPool || !fMaxDescriptorSets);
417}
418
egdaniel22281c12016-03-23 13:49:40 -0700419void GrVkPipelineState::DescriptorPoolManager::getNewDescriptorSet(GrVkGpu* gpu, VkDescriptorSet* ds) {
egdanielc2dc1b22016-03-18 13:18:23 -0700420 if (!fMaxDescriptorSets) {
421 return;
422 }
423 if (fCurrentDescriptorSet == fMaxDescriptorSets) {
424 this->getNewPool(gpu);
425 fCurrentDescriptorSet = 0;
426 }
427 fCurrentDescriptorSet++;
428
429 VkDescriptorSetAllocateInfo dsAllocateInfo;
430 memset(&dsAllocateInfo, 0, sizeof(VkDescriptorSetAllocateInfo));
431 dsAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
432 dsAllocateInfo.pNext = nullptr;
433 dsAllocateInfo.descriptorPool = fPool->descPool();
434 dsAllocateInfo.descriptorSetCount = 1;
435 dsAllocateInfo.pSetLayouts = &fDescLayout;
egdanielc2dc1b22016-03-18 13:18:23 -0700436 GR_VK_CALL_ERRCHECK(gpu->vkInterface(), AllocateDescriptorSets(gpu->device(),
437 &dsAllocateInfo,
438 ds));
439}
440
egdaniel22281c12016-03-23 13:49:40 -0700441void GrVkPipelineState::DescriptorPoolManager::freeGPUResources(const GrVkGpu* gpu) {
egdanielc2dc1b22016-03-18 13:18:23 -0700442 if (fDescLayout) {
443 GR_VK_CALL(gpu->vkInterface(), DestroyDescriptorSetLayout(gpu->device(), fDescLayout,
444 nullptr));
445 fDescLayout = VK_NULL_HANDLE;
446 }
447
448 if (fPool) {
449 fPool->unref(gpu);
450 fPool = nullptr;
451 }
452}
453
egdaniel22281c12016-03-23 13:49:40 -0700454void GrVkPipelineState::DescriptorPoolManager::abandonGPUResources() {
egdanielc2dc1b22016-03-18 13:18:23 -0700455 fDescLayout = VK_NULL_HANDLE;
456 if (fPool) {
457 fPool->unrefAndAbandon();
458 fPool = nullptr;
459 }
jvanverth992ad362016-02-26 09:21:02 -0800460}
egdaniel22281c12016-03-23 13:49:40 -0700461
462uint32_t get_blend_info_key(const GrPipeline& pipeline) {
463 GrXferProcessor::BlendInfo blendInfo;
464 pipeline.getXferProcessor().getBlendInfo(&blendInfo);
465
466 static const uint32_t kBlendWriteShift = 1;
467 static const uint32_t kBlendCoeffShift = 5;
468 GR_STATIC_ASSERT(kLast_GrBlendCoeff < (1 << kBlendCoeffShift));
469 GR_STATIC_ASSERT(kFirstAdvancedGrBlendEquation - 1 < 4);
470
471 uint32_t key = blendInfo.fWriteColor;
472 key |= (blendInfo.fSrcBlend << kBlendWriteShift);
473 key |= (blendInfo.fDstBlend << (kBlendWriteShift + kBlendCoeffShift));
474 key |= (blendInfo.fEquation << (kBlendWriteShift + 2 * kBlendCoeffShift));
475
476 return key;
477}
478
479void GrVkPipelineState::BuildStateKey(const GrPipeline& pipeline, GrPrimitiveType primitiveType,
480 SkTArray<uint8_t, true>* key) {
481 // Save room for the key length and key header
482 key->reset();
483 key->push_back_n(kData_StateKeyOffset);
484
485 GrProcessorKeyBuilder b(key);
486
487 GrVkRenderTarget* vkRT = (GrVkRenderTarget*)pipeline.getRenderTarget();
488 vkRT->simpleRenderPass()->genKey(&b);
489
490 pipeline.getStencil().genKey(&b);
491
492 SkASSERT(sizeof(GrPipelineBuilder::DrawFace) <= sizeof(uint32_t));
493 b.add32(pipeline.getDrawFace());
494
495 b.add32(get_blend_info_key(pipeline));
496
497 b.add32(primitiveType);
498
halcanary9d524f22016-03-29 09:03:52 -0700499 // Set key length
egdaniel22281c12016-03-23 13:49:40 -0700500 int keyLength = key->count();
501 SkASSERT(0 == (keyLength % 4));
502 *reinterpret_cast<uint32_t*>(key->begin()) = SkToU32(keyLength);
503}