123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381 |
- /*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #include "include/gpu/GrContext.h"
- #include "include/gpu/GrRenderTarget.h"
- #include "src/core/SkMipMap.h"
- #include "src/gpu/GrContextPriv.h"
- #include "src/gpu/GrPipeline.h"
- #include "src/gpu/GrTexturePriv.h"
- #include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
- #include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
- #include "src/gpu/glsl/GrGLSLXferProcessor.h"
- #include "src/gpu/vk/GrVkBufferView.h"
- #include "src/gpu/vk/GrVkCommandBuffer.h"
- #include "src/gpu/vk/GrVkDescriptorPool.h"
- #include "src/gpu/vk/GrVkDescriptorSet.h"
- #include "src/gpu/vk/GrVkGpu.h"
- #include "src/gpu/vk/GrVkImageView.h"
- #include "src/gpu/vk/GrVkMemory.h"
- #include "src/gpu/vk/GrVkPipeline.h"
- #include "src/gpu/vk/GrVkPipelineLayout.h"
- #include "src/gpu/vk/GrVkPipelineState.h"
- #include "src/gpu/vk/GrVkSampler.h"
- #include "src/gpu/vk/GrVkTexture.h"
- #include "src/gpu/vk/GrVkUniformBuffer.h"
- GrVkPipelineState::GrVkPipelineState(
- GrVkGpu* gpu,
- GrVkPipeline* pipeline,
- VkPipelineLayout layout,
- const GrVkDescriptorSetManager::Handle& samplerDSHandle,
- const GrGLSLBuiltinUniformHandles& builtinUniformHandles,
- const UniformInfoArray& uniforms,
- uint32_t geometryUniformSize,
- uint32_t fragmentUniformSize,
- const UniformInfoArray& samplers,
- std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
- std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
- std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors,
- int fragmentProcessorCnt)
- : fPipeline(pipeline)
- , fPipelineLayout(new GrVkPipelineLayout(layout))
- , fUniformDescriptorSet(nullptr)
- , fSamplerDescriptorSet(nullptr)
- , fSamplerDSHandle(samplerDSHandle)
- , fBuiltinUniformHandles(builtinUniformHandles)
- , fGeometryProcessor(std::move(geometryProcessor))
- , fXferProcessor(std::move(xferProcessor))
- , fFragmentProcessors(std::move(fragmentProcessors))
- , fFragmentProcessorCnt(fragmentProcessorCnt)
- , fDataManager(uniforms, geometryUniformSize, fragmentUniformSize) {
- fDescriptorSets[0] = VK_NULL_HANDLE;
- fDescriptorSets[1] = VK_NULL_HANDLE;
- fDescriptorSets[2] = VK_NULL_HANDLE;
- fGeometryUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, geometryUniformSize));
- fFragmentUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, fragmentUniformSize));
- fNumSamplers = samplers.count();
- for (int i = 0; i < fNumSamplers; ++i) {
- // We store the immutable samplers here and take ownership of the ref from the
- // GrVkUnformHandler.
- fImmutableSamplers.push_back(samplers[i].fImmutableSampler);
- }
- }
- GrVkPipelineState::~GrVkPipelineState() {
- // Must have freed all GPU resources before this is destroyed
- SkASSERT(!fPipeline);
- SkASSERT(!fPipelineLayout);
- }
- void GrVkPipelineState::freeGPUResources(GrVkGpu* gpu) {
- if (fPipeline) {
- fPipeline->unref(gpu);
- fPipeline = nullptr;
- }
- if (fPipelineLayout) {
- fPipelineLayout->unref(gpu);
- fPipelineLayout = nullptr;
- }
- if (fGeometryUniformBuffer) {
- fGeometryUniformBuffer->release(gpu);
- fGeometryUniformBuffer.reset();
- }
- if (fFragmentUniformBuffer) {
- fFragmentUniformBuffer->release(gpu);
- fFragmentUniformBuffer.reset();
- }
- if (fUniformDescriptorSet) {
- fUniformDescriptorSet->recycle(const_cast<GrVkGpu*>(gpu));
- fUniformDescriptorSet = nullptr;
- }
- if (fSamplerDescriptorSet) {
- fSamplerDescriptorSet->recycle(const_cast<GrVkGpu*>(gpu));
- fSamplerDescriptorSet = nullptr;
- }
- }
- void GrVkPipelineState::abandonGPUResources() {
- if (fPipeline) {
- fPipeline->unrefAndAbandon();
- fPipeline = nullptr;
- }
- if (fPipelineLayout) {
- fPipelineLayout->unrefAndAbandon();
- fPipelineLayout = nullptr;
- }
- if (fGeometryUniformBuffer) {
- fGeometryUniformBuffer->abandon();
- fGeometryUniformBuffer.reset();
- }
- if (fFragmentUniformBuffer) {
- fFragmentUniformBuffer->abandon();
- fFragmentUniformBuffer.reset();
- }
- if (fUniformDescriptorSet) {
- fUniformDescriptorSet->unrefAndAbandon();
- fUniformDescriptorSet = nullptr;
- }
- if (fSamplerDescriptorSet) {
- fSamplerDescriptorSet->unrefAndAbandon();
- fSamplerDescriptorSet = nullptr;
- }
- }
- void GrVkPipelineState::setAndBindUniforms(GrVkGpu* gpu,
- const GrRenderTarget* renderTarget,
- GrSurfaceOrigin origin,
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- GrVkCommandBuffer* commandBuffer) {
- this->setRenderTargetState(renderTarget, origin);
- fGeometryProcessor->setData(fDataManager, primProc,
- GrFragmentProcessor::CoordTransformIter(pipeline));
- GrFragmentProcessor::Iter iter(pipeline);
- GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
- const GrFragmentProcessor* fp = iter.next();
- GrGLSLFragmentProcessor* glslFP = glslIter.next();
- while (fp && glslFP) {
- glslFP->setData(fDataManager, *fp);
- fp = iter.next();
- glslFP = glslIter.next();
- }
- SkASSERT(!fp && !glslFP);
- {
- SkIPoint offset;
- GrTexture* dstTexture = pipeline.peekDstTexture(&offset);
- fXferProcessor->setData(fDataManager, pipeline.getXferProcessor(), dstTexture, offset);
- }
- // Get new descriptor set
- if (fGeometryUniformBuffer || fFragmentUniformBuffer) {
- int uniformDSIdx = GrVkUniformHandler::kUniformBufferDescSet;
- if (fDataManager.uploadUniformBuffers(
- gpu, fGeometryUniformBuffer.get(), fFragmentUniformBuffer.get()) ||
- !fUniformDescriptorSet) {
- if (fUniformDescriptorSet) {
- fUniformDescriptorSet->recycle(gpu);
- }
- fUniformDescriptorSet = gpu->resourceProvider().getUniformDescriptorSet();
- fDescriptorSets[uniformDSIdx] = fUniformDescriptorSet->descriptorSet();
- this->writeUniformBuffers(gpu);
- }
- commandBuffer->bindDescriptorSets(gpu, this, fPipelineLayout, uniformDSIdx, 1,
- &fDescriptorSets[uniformDSIdx], 0, nullptr);
- if (fUniformDescriptorSet) {
- commandBuffer->addRecycledResource(fUniformDescriptorSet);
- }
- if (fGeometryUniformBuffer) {
- commandBuffer->addRecycledResource(fGeometryUniformBuffer->resource());
- }
- if (fFragmentUniformBuffer) {
- commandBuffer->addRecycledResource(fFragmentUniformBuffer->resource());
- }
- }
- }
- void GrVkPipelineState::setAndBindTextures(GrVkGpu* gpu,
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- const GrTextureProxy* const primProcTextures[],
- GrVkCommandBuffer* commandBuffer) {
- SkASSERT(primProcTextures || !primProc.numTextureSamplers());
- struct SamplerBindings {
- GrSamplerState fState;
- GrVkTexture* fTexture;
- };
- SkAutoSTMalloc<8, SamplerBindings> samplerBindings(fNumSamplers);
- int currTextureBinding = 0;
- fGeometryProcessor->setData(fDataManager, primProc,
- GrFragmentProcessor::CoordTransformIter(pipeline));
- for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
- const auto& sampler = primProc.textureSampler(i);
- auto texture = static_cast<GrVkTexture*>(primProcTextures[i]->peekTexture());
- samplerBindings[currTextureBinding++] = {sampler.samplerState(), texture};
- }
- GrFragmentProcessor::Iter iter(pipeline);
- GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
- const GrFragmentProcessor* fp = iter.next();
- GrGLSLFragmentProcessor* glslFP = glslIter.next();
- while (fp && glslFP) {
- for (int i = 0; i < fp->numTextureSamplers(); ++i) {
- const auto& sampler = fp->textureSampler(i);
- samplerBindings[currTextureBinding++] =
- {sampler.samplerState(), static_cast<GrVkTexture*>(sampler.peekTexture())};
- }
- fp = iter.next();
- glslFP = glslIter.next();
- }
- SkASSERT(!fp && !glslFP);
- if (GrTextureProxy* dstTextureProxy = pipeline.dstTextureProxy()) {
- samplerBindings[currTextureBinding++] = {
- GrSamplerState::ClampNearest(),
- static_cast<GrVkTexture*>(dstTextureProxy->peekTexture())};
- }
- // Get new descriptor set
- SkASSERT(fNumSamplers == currTextureBinding);
- if (fNumSamplers) {
- if (fSamplerDescriptorSet) {
- fSamplerDescriptorSet->recycle(gpu);
- }
- fSamplerDescriptorSet = gpu->resourceProvider().getSamplerDescriptorSet(fSamplerDSHandle);
- int samplerDSIdx = GrVkUniformHandler::kSamplerDescSet;
- fDescriptorSets[samplerDSIdx] = fSamplerDescriptorSet->descriptorSet();
- for (int i = 0; i < fNumSamplers; ++i) {
- const GrSamplerState& state = samplerBindings[i].fState;
- GrVkTexture* texture = samplerBindings[i].fTexture;
- const GrVkImageView* textureView = texture->textureView();
- const GrVkSampler* sampler = nullptr;
- if (fImmutableSamplers[i]) {
- sampler = fImmutableSamplers[i];
- } else {
- sampler = gpu->resourceProvider().findOrCreateCompatibleSampler(
- state, texture->ycbcrConversionInfo());
- }
- SkASSERT(sampler);
- VkDescriptorImageInfo imageInfo;
- memset(&imageInfo, 0, sizeof(VkDescriptorImageInfo));
- imageInfo.sampler = sampler->sampler();
- imageInfo.imageView = textureView->imageView();
- imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
- VkWriteDescriptorSet writeInfo;
- memset(&writeInfo, 0, sizeof(VkWriteDescriptorSet));
- writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- writeInfo.pNext = nullptr;
- writeInfo.dstSet = fDescriptorSets[GrVkUniformHandler::kSamplerDescSet];
- writeInfo.dstBinding = i;
- writeInfo.dstArrayElement = 0;
- writeInfo.descriptorCount = 1;
- writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- writeInfo.pImageInfo = &imageInfo;
- writeInfo.pBufferInfo = nullptr;
- writeInfo.pTexelBufferView = nullptr;
- GR_VK_CALL(gpu->vkInterface(),
- UpdateDescriptorSets(gpu->device(), 1, &writeInfo, 0, nullptr));
- commandBuffer->addResource(sampler);
- if (!fImmutableSamplers[i]) {
- sampler->unref(gpu);
- }
- commandBuffer->addResource(samplerBindings[i].fTexture->textureView());
- commandBuffer->addResource(samplerBindings[i].fTexture->resource());
- }
- commandBuffer->bindDescriptorSets(gpu, this, fPipelineLayout, samplerDSIdx, 1,
- &fDescriptorSets[samplerDSIdx], 0, nullptr);
- commandBuffer->addRecycledResource(fSamplerDescriptorSet);
- }
- }
- void set_uniform_descriptor_writes(VkWriteDescriptorSet* descriptorWrite,
- VkDescriptorBufferInfo* bufferInfo,
- const GrVkUniformBuffer* buffer,
- VkDescriptorSet descriptorSet,
- uint32_t binding) {
- memset(bufferInfo, 0, sizeof(VkDescriptorBufferInfo));
- bufferInfo->buffer = buffer->buffer();
- bufferInfo->offset = buffer->offset();
- bufferInfo->range = buffer->size();
- memset(descriptorWrite, 0, sizeof(VkWriteDescriptorSet));
- descriptorWrite->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- descriptorWrite->pNext = nullptr;
- descriptorWrite->dstSet = descriptorSet;
- descriptorWrite->dstBinding = binding;
- descriptorWrite->dstArrayElement = 0;
- descriptorWrite->descriptorCount = 1;
- descriptorWrite->descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- descriptorWrite->pImageInfo = nullptr;
- descriptorWrite->pBufferInfo = bufferInfo;
- descriptorWrite->pTexelBufferView = nullptr;
- }
- void GrVkPipelineState::writeUniformBuffers(const GrVkGpu* gpu) {
- VkWriteDescriptorSet descriptorWrites[3];
- VkDescriptorBufferInfo bufferInfos[3];
- uint32_t writeCount = 0;
- // Geometry Uniform Buffer
- if (fGeometryUniformBuffer.get()) {
- set_uniform_descriptor_writes(&descriptorWrites[writeCount],
- &bufferInfos[writeCount],
- fGeometryUniformBuffer.get(),
- fDescriptorSets[GrVkUniformHandler::kUniformBufferDescSet],
- GrVkUniformHandler::kGeometryBinding);
- ++writeCount;
- }
- // Fragment Uniform Buffer
- if (fFragmentUniformBuffer.get()) {
- set_uniform_descriptor_writes(&descriptorWrites[writeCount],
- &bufferInfos[writeCount],
- fFragmentUniformBuffer.get(),
- fDescriptorSets[GrVkUniformHandler::kUniformBufferDescSet],
- GrVkUniformHandler::kFragBinding);
- ++writeCount;
- }
- if (writeCount) {
- GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(),
- writeCount,
- descriptorWrites,
- 0, nullptr));
- }
- }
- void GrVkPipelineState::setRenderTargetState(const GrRenderTarget* rt, GrSurfaceOrigin origin) {
- // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
- if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
- fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
- fDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height()));
- }
- // set RT adjustment
- SkISize size;
- size.set(rt->width(), rt->height());
- SkASSERT(fBuiltinUniformHandles.fRTAdjustmentUni.isValid());
- if (fRenderTargetState.fRenderTargetOrigin != origin ||
- fRenderTargetState.fRenderTargetSize != size) {
- fRenderTargetState.fRenderTargetSize = size;
- fRenderTargetState.fRenderTargetOrigin = origin;
- float rtAdjustmentVec[4];
- fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
- fDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
- }
- }
- void GrVkPipelineState::bindPipeline(const GrVkGpu* gpu, GrVkCommandBuffer* commandBuffer) {
- commandBuffer->bindPipeline(gpu, fPipeline);
- }
|