GrVkRenderPass.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  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/GrVkRenderPass.h"
  8. #include "src/gpu/GrProcessor.h"
  9. #include "src/gpu/vk/GrVkFramebuffer.h"
  10. #include "src/gpu/vk/GrVkGpu.h"
  11. #include "src/gpu/vk/GrVkRenderTarget.h"
  12. #include "src/gpu/vk/GrVkUtil.h"
  13. typedef GrVkRenderPass::AttachmentsDescriptor::AttachmentDesc AttachmentDesc;
  14. void setup_vk_attachment_description(VkAttachmentDescription* attachment,
  15. const AttachmentDesc& desc,
  16. VkImageLayout layout) {
  17. attachment->flags = 0;
  18. attachment->format = desc.fFormat;
  19. SkAssertResult(GrSampleCountToVkSampleCount(desc.fSamples, &attachment->samples));
  20. switch (layout) {
  21. case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
  22. attachment->loadOp = desc.fLoadStoreOps.fLoadOp;
  23. attachment->storeOp = desc.fLoadStoreOps.fStoreOp;
  24. attachment->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  25. attachment->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
  26. break;
  27. case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
  28. attachment->loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  29. attachment->storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
  30. attachment->stencilLoadOp = desc.fLoadStoreOps.fLoadOp;
  31. attachment->stencilStoreOp = desc.fLoadStoreOps.fStoreOp;
  32. break;
  33. default:
  34. SK_ABORT("Unexpected attachment layout");
  35. }
  36. attachment->initialLayout = layout;
  37. attachment->finalLayout = layout;
  38. }
  39. void GrVkRenderPass::initSimple(const GrVkGpu* gpu, const GrVkRenderTarget& target) {
  40. static const GrVkRenderPass::LoadStoreOps kBasicLoadStoreOps(VK_ATTACHMENT_LOAD_OP_LOAD,
  41. VK_ATTACHMENT_STORE_OP_STORE);
  42. this->init(gpu, target, kBasicLoadStoreOps, kBasicLoadStoreOps);
  43. }
  44. void GrVkRenderPass::init(const GrVkGpu* gpu,
  45. const LoadStoreOps& colorOp,
  46. const LoadStoreOps& stencilOp) {
  47. uint32_t numAttachments = fAttachmentsDescriptor.fAttachmentCount;
  48. // Attachment descriptions to be set on the render pass
  49. SkTArray<VkAttachmentDescription> attachments(numAttachments);
  50. attachments.reset(numAttachments);
  51. memset(attachments.begin(), 0, numAttachments * sizeof(VkAttachmentDescription));
  52. // Refs to attachments on the render pass (as described by teh VkAttachmentDescription above),
  53. // that are used by the subpass.
  54. VkAttachmentReference colorRef;
  55. VkAttachmentReference stencilRef;
  56. uint32_t currentAttachment = 0;
  57. // Go through each of the attachment types (color, stencil) and set the necessary
  58. // on the various Vk structs.
  59. VkSubpassDescription subpassDesc;
  60. memset(&subpassDesc, 0, sizeof(VkSubpassDescription));
  61. subpassDesc.flags = 0;
  62. subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
  63. subpassDesc.inputAttachmentCount = 0;
  64. subpassDesc.pInputAttachments = nullptr;
  65. subpassDesc.pResolveAttachments = nullptr;
  66. if (fAttachmentFlags & kColor_AttachmentFlag) {
  67. // set up color attachment
  68. fAttachmentsDescriptor.fColor.fLoadStoreOps = colorOp;
  69. setup_vk_attachment_description(&attachments[currentAttachment],
  70. fAttachmentsDescriptor.fColor,
  71. VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
  72. // setup subpass use of attachment
  73. colorRef.attachment = currentAttachment++;
  74. colorRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  75. subpassDesc.colorAttachmentCount = 1;
  76. if (VK_ATTACHMENT_LOAD_OP_CLEAR == colorOp.fLoadOp) {
  77. fClearValueCount = colorRef.attachment + 1;
  78. }
  79. } else {
  80. // I don't think there should ever be a time where we don't have a color attachment
  81. SkASSERT(false);
  82. colorRef.attachment = VK_ATTACHMENT_UNUSED;
  83. colorRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
  84. subpassDesc.colorAttachmentCount = 0;
  85. }
  86. subpassDesc.pColorAttachments = &colorRef;
  87. if (fAttachmentFlags & kStencil_AttachmentFlag) {
  88. // set up stencil attachment
  89. fAttachmentsDescriptor.fStencil.fLoadStoreOps = stencilOp;
  90. setup_vk_attachment_description(&attachments[currentAttachment],
  91. fAttachmentsDescriptor.fStencil,
  92. VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
  93. // setup subpass use of attachment
  94. stencilRef.attachment = currentAttachment++;
  95. stencilRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  96. if (VK_ATTACHMENT_LOAD_OP_CLEAR == stencilOp.fLoadOp) {
  97. fClearValueCount = SkTMax(fClearValueCount, stencilRef.attachment + 1);
  98. }
  99. } else {
  100. stencilRef.attachment = VK_ATTACHMENT_UNUSED;
  101. stencilRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
  102. }
  103. subpassDesc.pDepthStencilAttachment = &stencilRef;
  104. subpassDesc.preserveAttachmentCount = 0;
  105. subpassDesc.pPreserveAttachments = nullptr;
  106. SkASSERT(numAttachments == currentAttachment);
  107. // Create the VkRenderPass compatible with the attachment descriptions above
  108. VkRenderPassCreateInfo createInfo;
  109. memset(&createInfo, 0, sizeof(VkRenderPassCreateInfo));
  110. createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
  111. createInfo.pNext = nullptr;
  112. createInfo.flags = 0;
  113. createInfo.attachmentCount = numAttachments;
  114. createInfo.pAttachments = attachments.begin();
  115. createInfo.subpassCount = 1;
  116. createInfo.pSubpasses = &subpassDesc;
  117. createInfo.dependencyCount = 0;
  118. createInfo.pDependencies = nullptr;
  119. GR_VK_CALL_ERRCHECK(gpu->vkInterface(), CreateRenderPass(gpu->device(),
  120. &createInfo,
  121. nullptr,
  122. &fRenderPass));
  123. // Get granularity for this render pass
  124. GR_VK_CALL(gpu->vkInterface(), GetRenderAreaGranularity(gpu->device(),
  125. fRenderPass,
  126. &fGranularity));
  127. }
  128. void GrVkRenderPass::init(const GrVkGpu* gpu,
  129. const GrVkRenderPass& compatibleRenderPass,
  130. const LoadStoreOps& colorOp,
  131. const LoadStoreOps& stencilOp) {
  132. fAttachmentFlags = compatibleRenderPass.fAttachmentFlags;
  133. fAttachmentsDescriptor = compatibleRenderPass.fAttachmentsDescriptor;
  134. this->init(gpu, colorOp, stencilOp);
  135. }
  136. void GrVkRenderPass::init(const GrVkGpu* gpu,
  137. const GrVkRenderTarget& target,
  138. const LoadStoreOps& colorOp,
  139. const LoadStoreOps& stencilOp) {
  140. // Get attachment information from render target. This includes which attachments the render
  141. // target has (color, stencil) and the attachments format and sample count.
  142. target.getAttachmentsDescriptor(&fAttachmentsDescriptor, &fAttachmentFlags);
  143. this->init(gpu, colorOp, stencilOp);
  144. }
  145. void GrVkRenderPass::freeGPUData(GrVkGpu* gpu) const {
  146. if (!(fAttachmentFlags & kExternal_AttachmentFlag)) {
  147. GR_VK_CALL(gpu->vkInterface(), DestroyRenderPass(gpu->device(), fRenderPass, nullptr));
  148. }
  149. }
  150. bool GrVkRenderPass::colorAttachmentIndex(uint32_t* index) const {
  151. *index = fColorAttachmentIndex;
  152. if ((fAttachmentFlags & kColor_AttachmentFlag) ||
  153. (fAttachmentFlags & kExternal_AttachmentFlag)) {
  154. return true;
  155. }
  156. return false;
  157. }
  158. // Works under the assumption that stencil attachment will always be after the color and resolve
  159. // attachment.
  160. bool GrVkRenderPass::stencilAttachmentIndex(uint32_t* index) const {
  161. *index = 0;
  162. if (fAttachmentFlags & kColor_AttachmentFlag) {
  163. ++(*index);
  164. }
  165. if (fAttachmentFlags & kStencil_AttachmentFlag) {
  166. return true;
  167. }
  168. return false;
  169. }
  170. bool GrVkRenderPass::isCompatible(const AttachmentsDescriptor& desc,
  171. const AttachmentFlags& flags) const {
  172. SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag));
  173. if (flags != fAttachmentFlags) {
  174. return false;
  175. }
  176. if (fAttachmentFlags & kColor_AttachmentFlag) {
  177. if (!fAttachmentsDescriptor.fColor.isCompatible(desc.fColor)) {
  178. return false;
  179. }
  180. }
  181. if (fAttachmentFlags & kStencil_AttachmentFlag) {
  182. if (!fAttachmentsDescriptor.fStencil.isCompatible(desc.fStencil)) {
  183. return false;
  184. }
  185. }
  186. return true;
  187. }
  188. bool GrVkRenderPass::isCompatible(const GrVkRenderTarget& target) const {
  189. SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag));
  190. AttachmentsDescriptor desc;
  191. AttachmentFlags flags;
  192. target.getAttachmentsDescriptor(&desc, &flags);
  193. return this->isCompatible(desc, flags);
  194. }
  195. bool GrVkRenderPass::isCompatible(const GrVkRenderPass& renderPass) const {
  196. SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag));
  197. return this->isCompatible(renderPass.fAttachmentsDescriptor, renderPass.fAttachmentFlags);
  198. }
  199. bool GrVkRenderPass::isCompatibleExternalRP(VkRenderPass renderPass) const {
  200. SkASSERT(fAttachmentFlags & kExternal_AttachmentFlag);
  201. return fRenderPass == renderPass;
  202. }
  203. bool GrVkRenderPass::equalLoadStoreOps(const LoadStoreOps& colorOps,
  204. const LoadStoreOps& stencilOps) const {
  205. SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag));
  206. if (fAttachmentFlags & kColor_AttachmentFlag) {
  207. if (fAttachmentsDescriptor.fColor.fLoadStoreOps != colorOps) {
  208. return false;
  209. }
  210. }
  211. if (fAttachmentFlags & kStencil_AttachmentFlag) {
  212. if (fAttachmentsDescriptor.fStencil.fLoadStoreOps != stencilOps) {
  213. return false;
  214. }
  215. }
  216. return true;
  217. }
  218. void GrVkRenderPass::genKey(GrProcessorKeyBuilder* b) const {
  219. b->add32(fAttachmentFlags);
  220. if (fAttachmentFlags & kColor_AttachmentFlag) {
  221. b->add32(fAttachmentsDescriptor.fColor.fFormat);
  222. b->add32(fAttachmentsDescriptor.fColor.fSamples);
  223. }
  224. if (fAttachmentFlags & kStencil_AttachmentFlag) {
  225. b->add32(fAttachmentsDescriptor.fStencil.fFormat);
  226. b->add32(fAttachmentsDescriptor.fStencil.fSamples);
  227. }
  228. if (fAttachmentFlags & kExternal_AttachmentFlag) {
  229. SkASSERT(!(fAttachmentFlags & ~kExternal_AttachmentFlag));
  230. uint64_t handle = (uint64_t)fRenderPass;
  231. b->add32((uint32_t)(handle & 0xFFFFFFFF));
  232. b->add32((uint32_t)(handle>>32));
  233. }
  234. }