GrVkTextureRenderTarget.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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/GrVkTextureRenderTarget.h"
  8. #include "src/gpu/GrTexturePriv.h"
  9. #include "src/gpu/vk/GrVkGpu.h"
  10. #include "src/gpu/vk/GrVkImageView.h"
  11. #include "src/gpu/vk/GrVkUtil.h"
  12. #include "src/core/SkMipMap.h"
  13. #include "include/gpu/vk/GrVkTypes.h"
  14. #define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
  15. GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu,
  16. SkBudgeted budgeted,
  17. const GrSurfaceDesc& desc,
  18. int sampleCnt,
  19. const GrVkImageInfo& info,
  20. sk_sp<GrVkImageLayout> layout,
  21. const GrVkImageView* texView,
  22. const GrVkImageInfo& msaaInfo,
  23. sk_sp<GrVkImageLayout> msaaLayout,
  24. const GrVkImageView* colorAttachmentView,
  25. const GrVkImageView* resolveAttachmentView,
  26. GrMipMapsStatus mipMapsStatus)
  27. : GrSurface(gpu, desc, info.fProtected)
  28. , GrVkImage(info, layout, GrBackendObjectOwnership::kOwned)
  29. , GrVkTexture(gpu, desc, info, layout, texView, mipMapsStatus,
  30. GrBackendObjectOwnership::kOwned)
  31. , GrVkRenderTarget(gpu, desc, sampleCnt, info, layout, msaaInfo, std::move(msaaLayout),
  32. colorAttachmentView, resolveAttachmentView,
  33. GrBackendObjectOwnership::kOwned) {
  34. SkASSERT(info.fProtected == msaaInfo.fProtected);
  35. this->registerWithCache(budgeted);
  36. }
  37. GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu,
  38. SkBudgeted budgeted,
  39. const GrSurfaceDesc& desc,
  40. const GrVkImageInfo& info,
  41. sk_sp<GrVkImageLayout> layout,
  42. const GrVkImageView* texView,
  43. const GrVkImageView* colorAttachmentView,
  44. GrMipMapsStatus mipMapsStatus)
  45. : GrSurface(gpu, desc, info.fProtected)
  46. , GrVkImage(info, layout, GrBackendObjectOwnership::kOwned)
  47. , GrVkTexture(gpu, desc, info, layout, texView, mipMapsStatus,
  48. GrBackendObjectOwnership::kOwned)
  49. , GrVkRenderTarget(gpu, desc, info, layout, colorAttachmentView,
  50. GrBackendObjectOwnership::kOwned) {
  51. this->registerWithCache(budgeted);
  52. }
  53. GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu,
  54. const GrSurfaceDesc& desc,
  55. int sampleCnt,
  56. const GrVkImageInfo& info,
  57. sk_sp<GrVkImageLayout> layout,
  58. const GrVkImageView* texView,
  59. const GrVkImageInfo& msaaInfo,
  60. sk_sp<GrVkImageLayout> msaaLayout,
  61. const GrVkImageView* colorAttachmentView,
  62. const GrVkImageView* resolveAttachmentView,
  63. GrMipMapsStatus mipMapsStatus,
  64. GrBackendObjectOwnership ownership,
  65. GrWrapCacheable cacheable)
  66. : GrSurface(gpu, desc, info.fProtected)
  67. , GrVkImage(info, layout, ownership)
  68. , GrVkTexture(gpu, desc, info, layout, texView, mipMapsStatus, ownership)
  69. , GrVkRenderTarget(gpu, desc, sampleCnt, info, layout, msaaInfo, std::move(msaaLayout),
  70. colorAttachmentView, resolveAttachmentView, ownership) {
  71. SkASSERT(info.fProtected == msaaInfo.fProtected);
  72. this->registerWithCacheWrapped(cacheable);
  73. }
  74. GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu,
  75. const GrSurfaceDesc& desc,
  76. const GrVkImageInfo& info,
  77. sk_sp<GrVkImageLayout> layout,
  78. const GrVkImageView* texView,
  79. const GrVkImageView* colorAttachmentView,
  80. GrMipMapsStatus mipMapsStatus,
  81. GrBackendObjectOwnership ownership,
  82. GrWrapCacheable cacheable)
  83. : GrSurface(gpu, desc, info.fProtected)
  84. , GrVkImage(info, layout, ownership)
  85. , GrVkTexture(gpu, desc, info, layout, texView, mipMapsStatus, ownership)
  86. , GrVkRenderTarget(gpu, desc, info, layout, colorAttachmentView, ownership) {
  87. this->registerWithCacheWrapped(cacheable);
  88. }
  89. namespace {
  90. struct Views {
  91. const GrVkImageView* imageView = nullptr;
  92. const GrVkImageView* colorAttachmentView = nullptr;
  93. const GrVkImageView* resolveAttachmentView = nullptr;
  94. GrVkImageInfo msInfo;
  95. sk_sp<GrVkImageLayout> msLayout;
  96. };
  97. } // anonymous namespace
  98. static Views create_views(GrVkGpu* gpu, const GrSurfaceDesc& desc, int sampleCnt,
  99. const GrVkImageInfo& info) {
  100. VkImage image = info.fImage;
  101. // Create the texture ImageView
  102. Views views;
  103. views.imageView = GrVkImageView::Create(gpu, image, info.fFormat, GrVkImageView::kColor_Type,
  104. info.fLevelCount, info.fYcbcrConversionInfo);
  105. if (!views.imageView) {
  106. return {};
  107. }
  108. VkFormat pixelFormat;
  109. GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat);
  110. VkImage colorImage;
  111. // create msaa surface if necessary
  112. if (sampleCnt > 1) {
  113. GrVkImage::ImageDesc msImageDesc;
  114. msImageDesc.fImageType = VK_IMAGE_TYPE_2D;
  115. msImageDesc.fFormat = pixelFormat;
  116. msImageDesc.fWidth = desc.fWidth;
  117. msImageDesc.fHeight = desc.fHeight;
  118. msImageDesc.fLevels = 1;
  119. msImageDesc.fSamples = sampleCnt;
  120. msImageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
  121. msImageDesc.fUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
  122. VK_IMAGE_USAGE_TRANSFER_DST_BIT |
  123. VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
  124. msImageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
  125. if (!GrVkImage::InitImageInfo(gpu, msImageDesc, &views.msInfo)) {
  126. views.imageView->unref(gpu);
  127. return {};
  128. }
  129. // Set color attachment image
  130. colorImage = views.msInfo.fImage;
  131. // Create resolve attachment view.
  132. views.resolveAttachmentView =
  133. GrVkImageView::Create(gpu, image, pixelFormat, GrVkImageView::kColor_Type,
  134. info.fLevelCount, GrVkYcbcrConversionInfo());
  135. if (!views.resolveAttachmentView) {
  136. GrVkImage::DestroyImageInfo(gpu, &views.msInfo);
  137. views.imageView->unref(gpu);
  138. return {};
  139. }
  140. views.msLayout.reset(new GrVkImageLayout(views.msInfo.fImageLayout));
  141. } else {
  142. // Set color attachment image
  143. colorImage = info.fImage;
  144. }
  145. views.colorAttachmentView = GrVkImageView::Create(
  146. gpu, colorImage, pixelFormat, GrVkImageView::kColor_Type, 1, GrVkYcbcrConversionInfo());
  147. if (!views.colorAttachmentView) {
  148. if (sampleCnt > 1) {
  149. views.resolveAttachmentView->unref(gpu);
  150. GrVkImage::DestroyImageInfo(gpu, &views.msInfo);
  151. }
  152. views.imageView->unref(gpu);
  153. return {};
  154. }
  155. return views;
  156. }
  157. sk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::MakeNewTextureRenderTarget(
  158. GrVkGpu* gpu,
  159. SkBudgeted budgeted,
  160. const GrSurfaceDesc& desc,
  161. int sampleCnt,
  162. const GrVkImage::ImageDesc& imageDesc,
  163. GrMipMapsStatus mipMapsStatus) {
  164. SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
  165. SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT);
  166. GrVkImageInfo info;
  167. if (!GrVkImage::InitImageInfo(gpu, imageDesc, &info)) {
  168. return nullptr;
  169. }
  170. sk_sp<GrVkImageLayout> layout(new GrVkImageLayout(info.fImageLayout));
  171. Views views = create_views(gpu, desc, sampleCnt, info);
  172. if (!views.colorAttachmentView) {
  173. GrVkImage::DestroyImageInfo(gpu, &info);
  174. return nullptr;
  175. }
  176. if (sampleCnt > 1) {
  177. return sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
  178. gpu, budgeted, desc, sampleCnt, info, std::move(layout), views.imageView,
  179. views.msInfo, std::move(views.msLayout), views.colorAttachmentView,
  180. views.resolveAttachmentView, mipMapsStatus));
  181. } else {
  182. return sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
  183. gpu, budgeted, desc, info, std::move(layout), views.imageView,
  184. views.colorAttachmentView, mipMapsStatus));
  185. }
  186. }
  187. sk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget(
  188. GrVkGpu* gpu,
  189. const GrSurfaceDesc& desc,
  190. int sampleCnt,
  191. GrWrapOwnership wrapOwnership,
  192. GrWrapCacheable cacheable,
  193. const GrVkImageInfo& info,
  194. sk_sp<GrVkImageLayout> layout) {
  195. // Adopted textures require both image and allocation because we're responsible for freeing
  196. SkASSERT(VK_NULL_HANDLE != info.fImage &&
  197. (kBorrow_GrWrapOwnership == wrapOwnership || VK_NULL_HANDLE != info.fAlloc.fMemory));
  198. GrMipMapsStatus mipMapsStatus = info.fLevelCount > 1 ? GrMipMapsStatus::kDirty
  199. : GrMipMapsStatus::kNotAllocated;
  200. GrBackendObjectOwnership ownership = kBorrow_GrWrapOwnership == wrapOwnership
  201. ? GrBackendObjectOwnership::kBorrowed : GrBackendObjectOwnership::kOwned;
  202. Views views = create_views(gpu, desc, sampleCnt, info);
  203. if (!views.colorAttachmentView) {
  204. return nullptr;
  205. }
  206. if (sampleCnt > 1) {
  207. return sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
  208. gpu, desc, sampleCnt, info, std::move(layout), views.imageView, views.msInfo,
  209. std::move(views.msLayout), views.colorAttachmentView, views.resolveAttachmentView,
  210. mipMapsStatus, ownership, cacheable));
  211. } else {
  212. return sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
  213. gpu, desc, info, std::move(layout), views.imageView, views.colorAttachmentView,
  214. mipMapsStatus, ownership, cacheable));
  215. }
  216. }
  217. size_t GrVkTextureRenderTarget::onGpuMemorySize() const {
  218. int numColorSamples = this->numSamples();
  219. if (numColorSamples > 1) {
  220. // Add one to account for the resolve VkImage.
  221. ++numColorSamples;
  222. }
  223. return GrSurface::ComputeSize(this->config(), this->width(), this->height(),
  224. numColorSamples, // TODO: this still correct?
  225. this->texturePriv().mipMapped());
  226. }