GrVkPipelineState.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  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. #include "include/gpu/GrContext.h"
  8. #include "include/gpu/GrRenderTarget.h"
  9. #include "src/core/SkMipMap.h"
  10. #include "src/gpu/GrContextPriv.h"
  11. #include "src/gpu/GrPipeline.h"
  12. #include "src/gpu/GrTexturePriv.h"
  13. #include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
  14. #include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
  15. #include "src/gpu/glsl/GrGLSLXferProcessor.h"
  16. #include "src/gpu/vk/GrVkBufferView.h"
  17. #include "src/gpu/vk/GrVkCommandBuffer.h"
  18. #include "src/gpu/vk/GrVkDescriptorPool.h"
  19. #include "src/gpu/vk/GrVkDescriptorSet.h"
  20. #include "src/gpu/vk/GrVkGpu.h"
  21. #include "src/gpu/vk/GrVkImageView.h"
  22. #include "src/gpu/vk/GrVkMemory.h"
  23. #include "src/gpu/vk/GrVkPipeline.h"
  24. #include "src/gpu/vk/GrVkPipelineLayout.h"
  25. #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"
  29. GrVkPipelineState::GrVkPipelineState(
  30. GrVkGpu* gpu,
  31. GrVkPipeline* pipeline,
  32. VkPipelineLayout layout,
  33. const GrVkDescriptorSetManager::Handle& samplerDSHandle,
  34. const GrGLSLBuiltinUniformHandles& builtinUniformHandles,
  35. const UniformInfoArray& uniforms,
  36. uint32_t geometryUniformSize,
  37. uint32_t fragmentUniformSize,
  38. const UniformInfoArray& samplers,
  39. std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
  40. std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
  41. std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors,
  42. int fragmentProcessorCnt)
  43. : fPipeline(pipeline)
  44. , fPipelineLayout(new GrVkPipelineLayout(layout))
  45. , fUniformDescriptorSet(nullptr)
  46. , fSamplerDescriptorSet(nullptr)
  47. , fSamplerDSHandle(samplerDSHandle)
  48. , fBuiltinUniformHandles(builtinUniformHandles)
  49. , fGeometryProcessor(std::move(geometryProcessor))
  50. , fXferProcessor(std::move(xferProcessor))
  51. , fFragmentProcessors(std::move(fragmentProcessors))
  52. , fFragmentProcessorCnt(fragmentProcessorCnt)
  53. , fDataManager(uniforms, geometryUniformSize, fragmentUniformSize) {
  54. fDescriptorSets[0] = VK_NULL_HANDLE;
  55. fDescriptorSets[1] = VK_NULL_HANDLE;
  56. fDescriptorSets[2] = VK_NULL_HANDLE;
  57. fGeometryUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, geometryUniformSize));
  58. fFragmentUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, fragmentUniformSize));
  59. fNumSamplers = samplers.count();
  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. }
  65. }
  66. GrVkPipelineState::~GrVkPipelineState() {
  67. // Must have freed all GPU resources before this is destroyed
  68. SkASSERT(!fPipeline);
  69. SkASSERT(!fPipelineLayout);
  70. }
  71. void GrVkPipelineState::freeGPUResources(GrVkGpu* gpu) {
  72. if (fPipeline) {
  73. fPipeline->unref(gpu);
  74. fPipeline = nullptr;
  75. }
  76. if (fPipelineLayout) {
  77. fPipelineLayout->unref(gpu);
  78. fPipelineLayout = nullptr;
  79. }
  80. if (fGeometryUniformBuffer) {
  81. fGeometryUniformBuffer->release(gpu);
  82. fGeometryUniformBuffer.reset();
  83. }
  84. if (fFragmentUniformBuffer) {
  85. fFragmentUniformBuffer->release(gpu);
  86. fFragmentUniformBuffer.reset();
  87. }
  88. if (fUniformDescriptorSet) {
  89. fUniformDescriptorSet->recycle(const_cast<GrVkGpu*>(gpu));
  90. fUniformDescriptorSet = nullptr;
  91. }
  92. if (fSamplerDescriptorSet) {
  93. fSamplerDescriptorSet->recycle(const_cast<GrVkGpu*>(gpu));
  94. fSamplerDescriptorSet = nullptr;
  95. }
  96. }
  97. void GrVkPipelineState::abandonGPUResources() {
  98. if (fPipeline) {
  99. fPipeline->unrefAndAbandon();
  100. fPipeline = nullptr;
  101. }
  102. if (fPipelineLayout) {
  103. fPipelineLayout->unrefAndAbandon();
  104. fPipelineLayout = nullptr;
  105. }
  106. if (fGeometryUniformBuffer) {
  107. fGeometryUniformBuffer->abandon();
  108. fGeometryUniformBuffer.reset();
  109. }
  110. if (fFragmentUniformBuffer) {
  111. fFragmentUniformBuffer->abandon();
  112. fFragmentUniformBuffer.reset();
  113. }
  114. if (fUniformDescriptorSet) {
  115. fUniformDescriptorSet->unrefAndAbandon();
  116. fUniformDescriptorSet = nullptr;
  117. }
  118. if (fSamplerDescriptorSet) {
  119. fSamplerDescriptorSet->unrefAndAbandon();
  120. fSamplerDescriptorSet = nullptr;
  121. }
  122. }
  123. void GrVkPipelineState::setAndBindUniforms(GrVkGpu* gpu,
  124. const GrRenderTarget* renderTarget,
  125. GrSurfaceOrigin origin,
  126. const GrPrimitiveProcessor& primProc,
  127. const GrPipeline& pipeline,
  128. GrVkCommandBuffer* commandBuffer) {
  129. this->setRenderTargetState(renderTarget, origin);
  130. fGeometryProcessor->setData(fDataManager, primProc,
  131. GrFragmentProcessor::CoordTransformIter(pipeline));
  132. GrFragmentProcessor::Iter iter(pipeline);
  133. GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
  134. const GrFragmentProcessor* fp = iter.next();
  135. GrGLSLFragmentProcessor* glslFP = glslIter.next();
  136. while (fp && glslFP) {
  137. glslFP->setData(fDataManager, *fp);
  138. fp = iter.next();
  139. glslFP = glslIter.next();
  140. }
  141. SkASSERT(!fp && !glslFP);
  142. {
  143. SkIPoint offset;
  144. GrTexture* dstTexture = pipeline.peekDstTexture(&offset);
  145. fXferProcessor->setData(fDataManager, pipeline.getXferProcessor(), dstTexture, offset);
  146. }
  147. // Get new descriptor set
  148. if (fGeometryUniformBuffer || fFragmentUniformBuffer) {
  149. int uniformDSIdx = GrVkUniformHandler::kUniformBufferDescSet;
  150. if (fDataManager.uploadUniformBuffers(
  151. gpu, fGeometryUniformBuffer.get(), fFragmentUniformBuffer.get()) ||
  152. !fUniformDescriptorSet) {
  153. if (fUniformDescriptorSet) {
  154. fUniformDescriptorSet->recycle(gpu);
  155. }
  156. fUniformDescriptorSet = gpu->resourceProvider().getUniformDescriptorSet();
  157. fDescriptorSets[uniformDSIdx] = fUniformDescriptorSet->descriptorSet();
  158. this->writeUniformBuffers(gpu);
  159. }
  160. commandBuffer->bindDescriptorSets(gpu, this, fPipelineLayout, uniformDSIdx, 1,
  161. &fDescriptorSets[uniformDSIdx], 0, nullptr);
  162. if (fUniformDescriptorSet) {
  163. commandBuffer->addRecycledResource(fUniformDescriptorSet);
  164. }
  165. if (fGeometryUniformBuffer) {
  166. commandBuffer->addRecycledResource(fGeometryUniformBuffer->resource());
  167. }
  168. if (fFragmentUniformBuffer) {
  169. commandBuffer->addRecycledResource(fFragmentUniformBuffer->resource());
  170. }
  171. }
  172. }
  173. void GrVkPipelineState::setAndBindTextures(GrVkGpu* gpu,
  174. const GrPrimitiveProcessor& primProc,
  175. const GrPipeline& pipeline,
  176. const GrTextureProxy* const primProcTextures[],
  177. GrVkCommandBuffer* commandBuffer) {
  178. SkASSERT(primProcTextures || !primProc.numTextureSamplers());
  179. struct SamplerBindings {
  180. GrSamplerState fState;
  181. GrVkTexture* fTexture;
  182. };
  183. SkAutoSTMalloc<8, SamplerBindings> samplerBindings(fNumSamplers);
  184. int currTextureBinding = 0;
  185. fGeometryProcessor->setData(fDataManager, primProc,
  186. GrFragmentProcessor::CoordTransformIter(pipeline));
  187. for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
  188. const auto& sampler = primProc.textureSampler(i);
  189. auto texture = static_cast<GrVkTexture*>(primProcTextures[i]->peekTexture());
  190. samplerBindings[currTextureBinding++] = {sampler.samplerState(), texture};
  191. }
  192. GrFragmentProcessor::Iter iter(pipeline);
  193. GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
  194. const GrFragmentProcessor* fp = iter.next();
  195. GrGLSLFragmentProcessor* glslFP = glslIter.next();
  196. while (fp && glslFP) {
  197. for (int i = 0; i < fp->numTextureSamplers(); ++i) {
  198. const auto& sampler = fp->textureSampler(i);
  199. samplerBindings[currTextureBinding++] =
  200. {sampler.samplerState(), static_cast<GrVkTexture*>(sampler.peekTexture())};
  201. }
  202. fp = iter.next();
  203. glslFP = glslIter.next();
  204. }
  205. SkASSERT(!fp && !glslFP);
  206. if (GrTextureProxy* dstTextureProxy = pipeline.dstTextureProxy()) {
  207. samplerBindings[currTextureBinding++] = {
  208. GrSamplerState::ClampNearest(),
  209. static_cast<GrVkTexture*>(dstTextureProxy->peekTexture())};
  210. }
  211. // Get new descriptor set
  212. SkASSERT(fNumSamplers == currTextureBinding);
  213. if (fNumSamplers) {
  214. if (fSamplerDescriptorSet) {
  215. fSamplerDescriptorSet->recycle(gpu);
  216. }
  217. fSamplerDescriptorSet = gpu->resourceProvider().getSamplerDescriptorSet(fSamplerDSHandle);
  218. int samplerDSIdx = GrVkUniformHandler::kSamplerDescSet;
  219. fDescriptorSets[samplerDSIdx] = fSamplerDescriptorSet->descriptorSet();
  220. for (int i = 0; i < fNumSamplers; ++i) {
  221. const GrSamplerState& state = samplerBindings[i].fState;
  222. GrVkTexture* texture = samplerBindings[i].fTexture;
  223. const GrVkImageView* textureView = texture->textureView();
  224. const GrVkSampler* sampler = nullptr;
  225. if (fImmutableSamplers[i]) {
  226. sampler = fImmutableSamplers[i];
  227. } else {
  228. sampler = gpu->resourceProvider().findOrCreateCompatibleSampler(
  229. state, texture->ycbcrConversionInfo());
  230. }
  231. SkASSERT(sampler);
  232. VkDescriptorImageInfo imageInfo;
  233. memset(&imageInfo, 0, sizeof(VkDescriptorImageInfo));
  234. imageInfo.sampler = sampler->sampler();
  235. imageInfo.imageView = textureView->imageView();
  236. imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
  237. VkWriteDescriptorSet writeInfo;
  238. memset(&writeInfo, 0, sizeof(VkWriteDescriptorSet));
  239. writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  240. writeInfo.pNext = nullptr;
  241. writeInfo.dstSet = fDescriptorSets[GrVkUniformHandler::kSamplerDescSet];
  242. writeInfo.dstBinding = i;
  243. writeInfo.dstArrayElement = 0;
  244. writeInfo.descriptorCount = 1;
  245. writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
  246. writeInfo.pImageInfo = &imageInfo;
  247. writeInfo.pBufferInfo = nullptr;
  248. writeInfo.pTexelBufferView = nullptr;
  249. GR_VK_CALL(gpu->vkInterface(),
  250. UpdateDescriptorSets(gpu->device(), 1, &writeInfo, 0, nullptr));
  251. commandBuffer->addResource(sampler);
  252. if (!fImmutableSamplers[i]) {
  253. sampler->unref(gpu);
  254. }
  255. commandBuffer->addResource(samplerBindings[i].fTexture->textureView());
  256. commandBuffer->addResource(samplerBindings[i].fTexture->resource());
  257. }
  258. commandBuffer->bindDescriptorSets(gpu, this, fPipelineLayout, samplerDSIdx, 1,
  259. &fDescriptorSets[samplerDSIdx], 0, nullptr);
  260. commandBuffer->addRecycledResource(fSamplerDescriptorSet);
  261. }
  262. }
  263. void set_uniform_descriptor_writes(VkWriteDescriptorSet* descriptorWrite,
  264. VkDescriptorBufferInfo* bufferInfo,
  265. const GrVkUniformBuffer* buffer,
  266. VkDescriptorSet descriptorSet,
  267. uint32_t binding) {
  268. memset(bufferInfo, 0, sizeof(VkDescriptorBufferInfo));
  269. bufferInfo->buffer = buffer->buffer();
  270. bufferInfo->offset = buffer->offset();
  271. bufferInfo->range = buffer->size();
  272. memset(descriptorWrite, 0, sizeof(VkWriteDescriptorSet));
  273. descriptorWrite->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  274. descriptorWrite->pNext = nullptr;
  275. descriptorWrite->dstSet = descriptorSet;
  276. descriptorWrite->dstBinding = binding;
  277. descriptorWrite->dstArrayElement = 0;
  278. descriptorWrite->descriptorCount = 1;
  279. descriptorWrite->descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
  280. descriptorWrite->pImageInfo = nullptr;
  281. descriptorWrite->pBufferInfo = bufferInfo;
  282. descriptorWrite->pTexelBufferView = nullptr;
  283. }
  284. void GrVkPipelineState::writeUniformBuffers(const GrVkGpu* gpu) {
  285. VkWriteDescriptorSet descriptorWrites[3];
  286. VkDescriptorBufferInfo bufferInfos[3];
  287. uint32_t writeCount = 0;
  288. // Geometry Uniform Buffer
  289. if (fGeometryUniformBuffer.get()) {
  290. set_uniform_descriptor_writes(&descriptorWrites[writeCount],
  291. &bufferInfos[writeCount],
  292. fGeometryUniformBuffer.get(),
  293. fDescriptorSets[GrVkUniformHandler::kUniformBufferDescSet],
  294. GrVkUniformHandler::kGeometryBinding);
  295. ++writeCount;
  296. }
  297. // Fragment Uniform Buffer
  298. if (fFragmentUniformBuffer.get()) {
  299. set_uniform_descriptor_writes(&descriptorWrites[writeCount],
  300. &bufferInfos[writeCount],
  301. fFragmentUniformBuffer.get(),
  302. fDescriptorSets[GrVkUniformHandler::kUniformBufferDescSet],
  303. GrVkUniformHandler::kFragBinding);
  304. ++writeCount;
  305. }
  306. if (writeCount) {
  307. GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(),
  308. writeCount,
  309. descriptorWrites,
  310. 0, nullptr));
  311. }
  312. }
  313. void GrVkPipelineState::setRenderTargetState(const GrRenderTarget* rt, GrSurfaceOrigin origin) {
  314. // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
  315. if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
  316. fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
  317. fDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height()));
  318. }
  319. // set RT adjustment
  320. SkISize size;
  321. size.set(rt->width(), rt->height());
  322. SkASSERT(fBuiltinUniformHandles.fRTAdjustmentUni.isValid());
  323. if (fRenderTargetState.fRenderTargetOrigin != origin ||
  324. fRenderTargetState.fRenderTargetSize != size) {
  325. fRenderTargetState.fRenderTargetSize = size;
  326. fRenderTargetState.fRenderTargetOrigin = origin;
  327. float rtAdjustmentVec[4];
  328. fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
  329. fDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
  330. }
  331. }
  332. void GrVkPipelineState::bindPipeline(const GrVkGpu* gpu, GrVkCommandBuffer* commandBuffer) {
  333. commandBuffer->bindPipeline(gpu, fPipeline);
  334. }