GrVkRenderTarget.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. /*
  2. * Copyright 2015 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 "src/gpu/vk/GrVkRenderTarget.h"
  8. #include "include/gpu/GrBackendSurface.h"
  9. #include "src/gpu/GrRenderTargetPriv.h"
  10. #include "src/gpu/vk/GrVkCommandBuffer.h"
  11. #include "src/gpu/vk/GrVkFramebuffer.h"
  12. #include "src/gpu/vk/GrVkGpu.h"
  13. #include "src/gpu/vk/GrVkImageView.h"
  14. #include "src/gpu/vk/GrVkResourceProvider.h"
  15. #include "src/gpu/vk/GrVkUtil.h"
  16. #include "include/gpu/vk/GrVkTypes.h"
  17. #define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
  18. // We're virtually derived from GrSurface (via GrRenderTarget) so its
  19. // constructor must be explicitly called.
  20. GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
  21. const GrSurfaceDesc& desc,
  22. int sampleCnt,
  23. const GrVkImageInfo& info,
  24. sk_sp<GrVkImageLayout> layout,
  25. const GrVkImageInfo& msaaInfo,
  26. sk_sp<GrVkImageLayout> msaaLayout,
  27. const GrVkImageView* colorAttachmentView,
  28. const GrVkImageView* resolveAttachmentView)
  29. : GrSurface(gpu, desc, info.fProtected)
  30. , GrVkImage(info, std::move(layout), GrBackendObjectOwnership::kBorrowed)
  31. // for the moment we only support 1:1 color to stencil
  32. , GrRenderTarget(gpu, desc, sampleCnt, info.fProtected)
  33. , fColorAttachmentView(colorAttachmentView)
  34. , fMSAAImage(new GrVkImage(msaaInfo, std::move(msaaLayout),
  35. GrBackendObjectOwnership::kOwned))
  36. , fResolveAttachmentView(resolveAttachmentView)
  37. , fFramebuffer(nullptr)
  38. , fCachedSimpleRenderPass(nullptr) {
  39. SkASSERT(info.fProtected == msaaInfo.fProtected);
  40. SkASSERT(sampleCnt > 1);
  41. this->createFramebuffer(gpu);
  42. this->registerWithCacheWrapped(GrWrapCacheable::kNo);
  43. }
  44. // We're virtually derived from GrSurface (via GrRenderTarget) so its
  45. // constructor must be explicitly called.
  46. GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
  47. const GrSurfaceDesc& desc,
  48. int sampleCnt,
  49. const GrVkImageInfo& info,
  50. sk_sp<GrVkImageLayout> layout,
  51. const GrVkImageInfo& msaaInfo,
  52. sk_sp<GrVkImageLayout> msaaLayout,
  53. const GrVkImageView* colorAttachmentView,
  54. const GrVkImageView* resolveAttachmentView,
  55. GrBackendObjectOwnership ownership)
  56. : GrSurface(gpu, desc, info.fProtected)
  57. , GrVkImage(info, std::move(layout), ownership)
  58. // for the moment we only support 1:1 color to stencil
  59. , GrRenderTarget(gpu, desc, sampleCnt, info.fProtected)
  60. , fColorAttachmentView(colorAttachmentView)
  61. , fMSAAImage(new GrVkImage(msaaInfo, std::move(msaaLayout),
  62. GrBackendObjectOwnership::kOwned))
  63. , fResolveAttachmentView(resolveAttachmentView)
  64. , fFramebuffer(nullptr)
  65. , fCachedSimpleRenderPass(nullptr) {
  66. SkASSERT(info.fProtected == msaaInfo.fProtected);
  67. SkASSERT(sampleCnt > 1);
  68. this->createFramebuffer(gpu);
  69. }
  70. // We're virtually derived from GrSurface (via GrRenderTarget) so its
  71. // constructor must be explicitly called.
  72. GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
  73. const GrSurfaceDesc& desc,
  74. const GrVkImageInfo& info,
  75. sk_sp<GrVkImageLayout> layout,
  76. const GrVkImageView* colorAttachmentView)
  77. : GrSurface(gpu, desc, info.fProtected)
  78. , GrVkImage(info, std::move(layout), GrBackendObjectOwnership::kBorrowed)
  79. , GrRenderTarget(gpu, desc, 1, info.fProtected)
  80. , fColorAttachmentView(colorAttachmentView)
  81. , fMSAAImage(nullptr)
  82. , fResolveAttachmentView(nullptr)
  83. , fFramebuffer(nullptr)
  84. , fCachedSimpleRenderPass(nullptr) {
  85. this->createFramebuffer(gpu);
  86. this->registerWithCacheWrapped(GrWrapCacheable::kNo);
  87. }
  88. // We're virtually derived from GrSurface (via GrRenderTarget) so its
  89. // constructor must be explicitly called.
  90. GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
  91. const GrSurfaceDesc& desc,
  92. const GrVkImageInfo& info,
  93. sk_sp<GrVkImageLayout> layout,
  94. const GrVkImageView* colorAttachmentView,
  95. GrBackendObjectOwnership ownership)
  96. : GrSurface(gpu, desc, info.fProtected)
  97. , GrVkImage(info, std::move(layout), ownership)
  98. , GrRenderTarget(gpu, desc, 1, info.fProtected)
  99. , fColorAttachmentView(colorAttachmentView)
  100. , fMSAAImage(nullptr)
  101. , fResolveAttachmentView(nullptr)
  102. , fFramebuffer(nullptr)
  103. , fCachedSimpleRenderPass(nullptr) {
  104. this->createFramebuffer(gpu);
  105. }
  106. GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
  107. const GrSurfaceDesc& desc,
  108. const GrVkImageInfo& info,
  109. sk_sp<GrVkImageLayout> layout,
  110. const GrVkRenderPass* renderPass,
  111. GrVkSecondaryCommandBuffer* secondaryCommandBuffer)
  112. : GrSurface(gpu, desc, info.fProtected)
  113. , GrVkImage(info, std::move(layout), GrBackendObjectOwnership::kBorrowed, true)
  114. , GrRenderTarget(gpu, desc, 1, info.fProtected)
  115. , fColorAttachmentView(nullptr)
  116. , fMSAAImage(nullptr)
  117. , fResolveAttachmentView(nullptr)
  118. , fFramebuffer(nullptr)
  119. , fCachedSimpleRenderPass(renderPass)
  120. , fSecondaryCommandBuffer(secondaryCommandBuffer) {
  121. this->registerWithCacheWrapped(GrWrapCacheable::kNo);
  122. }
  123. sk_sp<GrVkRenderTarget> GrVkRenderTarget::MakeWrappedRenderTarget(GrVkGpu* gpu,
  124. const GrSurfaceDesc& desc,
  125. int sampleCnt,
  126. const GrVkImageInfo& info,
  127. sk_sp<GrVkImageLayout> layout) {
  128. SkASSERT(VK_NULL_HANDLE != info.fImage);
  129. SkASSERT(1 == info.fLevelCount);
  130. VkFormat pixelFormat;
  131. GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat);
  132. VkImage colorImage;
  133. // create msaa surface if necessary
  134. GrVkImageInfo msInfo;
  135. sk_sp<GrVkImageLayout> msLayout;
  136. const GrVkImageView* resolveAttachmentView = nullptr;
  137. if (sampleCnt > 1) {
  138. GrVkImage::ImageDesc msImageDesc;
  139. msImageDesc.fImageType = VK_IMAGE_TYPE_2D;
  140. msImageDesc.fFormat = pixelFormat;
  141. msImageDesc.fWidth = desc.fWidth;
  142. msImageDesc.fHeight = desc.fHeight;
  143. msImageDesc.fLevels = 1;
  144. msImageDesc.fSamples = sampleCnt;
  145. msImageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
  146. msImageDesc.fUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
  147. VK_IMAGE_USAGE_TRANSFER_DST_BIT |
  148. VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
  149. msImageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
  150. msImageDesc.fIsProtected = info.fProtected;
  151. if (!GrVkImage::InitImageInfo(gpu, msImageDesc, &msInfo)) {
  152. return nullptr;
  153. }
  154. // Set color attachment image
  155. colorImage = msInfo.fImage;
  156. // Create Resolve attachment view
  157. resolveAttachmentView = GrVkImageView::Create(gpu, info.fImage, pixelFormat,
  158. GrVkImageView::kColor_Type, 1,
  159. GrVkYcbcrConversionInfo());
  160. if (!resolveAttachmentView) {
  161. GrVkImage::DestroyImageInfo(gpu, &msInfo);
  162. return nullptr;
  163. }
  164. msLayout.reset(new GrVkImageLayout(msInfo.fImageLayout));
  165. } else {
  166. // Set color attachment image
  167. colorImage = info.fImage;
  168. }
  169. // Get color attachment view
  170. const GrVkImageView* colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat,
  171. GrVkImageView::kColor_Type, 1,
  172. GrVkYcbcrConversionInfo());
  173. if (!colorAttachmentView) {
  174. if (sampleCnt > 1) {
  175. resolveAttachmentView->unref(gpu);
  176. GrVkImage::DestroyImageInfo(gpu, &msInfo);
  177. }
  178. return nullptr;
  179. }
  180. GrVkRenderTarget* vkRT;
  181. if (sampleCnt > 1) {
  182. vkRT = new GrVkRenderTarget(gpu, desc, sampleCnt, info, std::move(layout), msInfo,
  183. std::move(msLayout), colorAttachmentView,
  184. resolveAttachmentView);
  185. } else {
  186. vkRT = new GrVkRenderTarget(gpu, desc, info, std::move(layout), colorAttachmentView);
  187. }
  188. return sk_sp<GrVkRenderTarget>(vkRT);
  189. }
  190. sk_sp<GrVkRenderTarget> GrVkRenderTarget::MakeSecondaryCBRenderTarget(
  191. GrVkGpu* gpu, const GrSurfaceDesc& desc, const GrVkDrawableInfo& vkInfo) {
  192. // We only set the few properties of the GrVkImageInfo that we know like layout and format. The
  193. // others we keep at the default "null" values.
  194. GrVkImageInfo info;
  195. info.fImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  196. info.fFormat = vkInfo.fFormat;
  197. sk_sp<GrVkImageLayout> layout(new GrVkImageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
  198. const GrVkRenderPass* rp =
  199. gpu->resourceProvider().findCompatibleExternalRenderPass(vkInfo.fCompatibleRenderPass,
  200. vkInfo.fColorAttachmentIndex);
  201. if (!rp) {
  202. return nullptr;
  203. }
  204. GrVkSecondaryCommandBuffer* scb =
  205. GrVkSecondaryCommandBuffer::Create(vkInfo.fSecondaryCommandBuffer);
  206. if (!scb) {
  207. return nullptr;
  208. }
  209. GrVkRenderTarget* vkRT = new GrVkRenderTarget(gpu, desc, info, std::move(layout), rp, scb);
  210. return sk_sp<GrVkRenderTarget>(vkRT);
  211. }
  212. bool GrVkRenderTarget::completeStencilAttachment() {
  213. SkASSERT(!this->wrapsSecondaryCommandBuffer());
  214. this->createFramebuffer(this->getVkGpu());
  215. return true;
  216. }
  217. void GrVkRenderTarget::createFramebuffer(GrVkGpu* gpu) {
  218. SkASSERT(!this->wrapsSecondaryCommandBuffer());
  219. if (fFramebuffer) {
  220. fFramebuffer->unref(gpu);
  221. }
  222. if (fCachedSimpleRenderPass) {
  223. fCachedSimpleRenderPass->unref(gpu);
  224. }
  225. // Vulkan requires us to create a compatible renderpass before we can create our framebuffer,
  226. // so we use this to get a (cached) basic renderpass, only for creation.
  227. fCachedSimpleRenderPass =
  228. gpu->resourceProvider().findCompatibleRenderPass(*this, &fCompatibleRPHandle);
  229. // Stencil attachment view is stored in the base RT stencil attachment
  230. const GrVkImageView* stencilView = this->stencilAttachmentView();
  231. fFramebuffer = GrVkFramebuffer::Create(gpu, this->width(), this->height(),
  232. fCachedSimpleRenderPass, fColorAttachmentView,
  233. stencilView);
  234. SkASSERT(fFramebuffer);
  235. }
  236. void GrVkRenderTarget::getAttachmentsDescriptor(
  237. GrVkRenderPass::AttachmentsDescriptor* desc,
  238. GrVkRenderPass::AttachmentFlags* attachmentFlags) const {
  239. SkASSERT(!this->wrapsSecondaryCommandBuffer());
  240. VkFormat colorFormat;
  241. GrPixelConfigToVkFormat(this->config(), &colorFormat);
  242. desc->fColor.fFormat = colorFormat;
  243. desc->fColor.fSamples = this->numSamples();
  244. *attachmentFlags = GrVkRenderPass::kColor_AttachmentFlag;
  245. uint32_t attachmentCount = 1;
  246. const GrStencilAttachment* stencil = this->renderTargetPriv().getStencilAttachment();
  247. if (stencil) {
  248. const GrVkStencilAttachment* vkStencil = static_cast<const GrVkStencilAttachment*>(stencil);
  249. desc->fStencil.fFormat = vkStencil->vkFormat();
  250. desc->fStencil.fSamples = vkStencil->numSamples();
  251. // Currently in vulkan stencil and color attachments must all have same number of samples
  252. SkASSERT(desc->fColor.fSamples == desc->fStencil.fSamples);
  253. *attachmentFlags |= GrVkRenderPass::kStencil_AttachmentFlag;
  254. ++attachmentCount;
  255. }
  256. desc->fAttachmentCount = attachmentCount;
  257. }
  258. GrVkRenderTarget::~GrVkRenderTarget() {
  259. // either release or abandon should have been called by the owner of this object.
  260. SkASSERT(!fMSAAImage);
  261. SkASSERT(!fResolveAttachmentView);
  262. SkASSERT(!fColorAttachmentView);
  263. SkASSERT(!fFramebuffer);
  264. SkASSERT(!fCachedSimpleRenderPass);
  265. SkASSERT(!fSecondaryCommandBuffer);
  266. }
  267. void GrVkRenderTarget::addResources(GrVkCommandBuffer& commandBuffer) const {
  268. commandBuffer.addResource(this->framebuffer());
  269. commandBuffer.addResource(this->colorAttachmentView());
  270. commandBuffer.addResource(this->msaaImageResource() ? this->msaaImageResource()
  271. : this->resource());
  272. if (this->stencilImageResource()) {
  273. commandBuffer.addResource(this->stencilImageResource());
  274. commandBuffer.addResource(this->stencilAttachmentView());
  275. }
  276. }
  277. void GrVkRenderTarget::releaseInternalObjects() {
  278. GrVkGpu* gpu = this->getVkGpu();
  279. if (fMSAAImage) {
  280. fMSAAImage->releaseImage(gpu);
  281. fMSAAImage.reset();
  282. }
  283. if (fResolveAttachmentView) {
  284. fResolveAttachmentView->unref(gpu);
  285. fResolveAttachmentView = nullptr;
  286. }
  287. if (fColorAttachmentView) {
  288. fColorAttachmentView->unref(gpu);
  289. fColorAttachmentView = nullptr;
  290. }
  291. if (fFramebuffer) {
  292. fFramebuffer->unref(gpu);
  293. fFramebuffer = nullptr;
  294. }
  295. if (fCachedSimpleRenderPass) {
  296. fCachedSimpleRenderPass->unref(gpu);
  297. fCachedSimpleRenderPass = nullptr;
  298. }
  299. if (fSecondaryCommandBuffer) {
  300. fSecondaryCommandBuffer->unref(gpu);
  301. fSecondaryCommandBuffer = nullptr;
  302. }
  303. }
  304. void GrVkRenderTarget::abandonInternalObjects() {
  305. if (fMSAAImage) {
  306. fMSAAImage->abandonImage();
  307. fMSAAImage.reset();
  308. }
  309. if (fResolveAttachmentView) {
  310. fResolveAttachmentView->unrefAndAbandon();
  311. fResolveAttachmentView = nullptr;
  312. }
  313. if (fColorAttachmentView) {
  314. fColorAttachmentView->unrefAndAbandon();
  315. fColorAttachmentView = nullptr;
  316. }
  317. if (fFramebuffer) {
  318. fFramebuffer->unrefAndAbandon();
  319. fFramebuffer = nullptr;
  320. }
  321. if (fCachedSimpleRenderPass) {
  322. fCachedSimpleRenderPass->unrefAndAbandon();
  323. fCachedSimpleRenderPass = nullptr;
  324. }
  325. if (fSecondaryCommandBuffer) {
  326. fSecondaryCommandBuffer->unrefAndAbandon();
  327. fSecondaryCommandBuffer = nullptr;
  328. }
  329. }
  330. void GrVkRenderTarget::onRelease() {
  331. this->releaseInternalObjects();
  332. this->releaseImage(this->getVkGpu());
  333. GrRenderTarget::onRelease();
  334. }
  335. void GrVkRenderTarget::onAbandon() {
  336. this->abandonInternalObjects();
  337. this->abandonImage();
  338. GrRenderTarget::onAbandon();
  339. }
  340. GrBackendRenderTarget GrVkRenderTarget::getBackendRenderTarget() const {
  341. SkASSERT(!this->wrapsSecondaryCommandBuffer());
  342. return GrBackendRenderTarget(this->width(), this->height(), this->numSamples(), fInfo,
  343. this->grVkImageLayout());
  344. }
  345. const GrVkResource* GrVkRenderTarget::stencilImageResource() const {
  346. SkASSERT(!this->wrapsSecondaryCommandBuffer());
  347. const GrStencilAttachment* stencil = this->renderTargetPriv().getStencilAttachment();
  348. if (stencil) {
  349. const GrVkStencilAttachment* vkStencil = static_cast<const GrVkStencilAttachment*>(stencil);
  350. return vkStencil->imageResource();
  351. }
  352. return nullptr;
  353. }
  354. const GrVkImageView* GrVkRenderTarget::stencilAttachmentView() const {
  355. SkASSERT(!this->wrapsSecondaryCommandBuffer());
  356. const GrStencilAttachment* stencil = this->renderTargetPriv().getStencilAttachment();
  357. if (stencil) {
  358. const GrVkStencilAttachment* vkStencil = static_cast<const GrVkStencilAttachment*>(stencil);
  359. return vkStencil->stencilView();
  360. }
  361. return nullptr;
  362. }
  363. GrVkGpu* GrVkRenderTarget::getVkGpu() const {
  364. SkASSERT(!this->wasDestroyed());
  365. return static_cast<GrVkGpu*>(this->getGpu());
  366. }