Home | History | Annotate | Download | only in vk
      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 
      8 #include "GrVkRenderPass.h"
      9 
     10 #include "GrVkFramebuffer.h"
     11 #include "GrVkGpu.h"
     12 #include "GrVkRenderTarget.h"
     13 #include "GrVkUtil.h"
     14 
     15 void setup_simple_vk_attachment_description(VkAttachmentDescription* attachment,
     16                                             VkFormat format,
     17                                             uint32_t samples,
     18                                             VkImageLayout layout) {
     19     attachment->flags = 0;
     20     attachment->format = format;
     21     SkAssertResult(GrSampleCountToVkSampleCount(samples, &attachment->samples));
     22     attachment->loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
     23     attachment->storeOp = VK_ATTACHMENT_STORE_OP_STORE;
     24     attachment->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
     25     attachment->storeOp = VK_ATTACHMENT_STORE_OP_STORE;
     26     attachment->initialLayout = layout;
     27     attachment->finalLayout = layout;
     28 }
     29 
     30 void GrVkRenderPass::initSimple(const GrVkGpu* gpu, const GrVkRenderTarget& target) {
     31     // Get attachment information from render target. This includes which attachments the render
     32     // target has (color, resolve, stencil) and the attachments format and sample count.
     33     target.getAttachmentsDescriptor(&fAttachmentsDescriptor, &fAttachmentFlags);
     34 
     35     uint32_t numAttachments = fAttachmentsDescriptor.fAttachmentCount;
     36     // Attachment descriptions to be set on the render pass
     37     SkTArray<VkAttachmentDescription> attachments(numAttachments);
     38     attachments.reset(numAttachments);
     39     memset(attachments.begin(), 0, numAttachments*sizeof(VkAttachmentDescription));
     40 
     41     // Refs to attachments on the render pass (as described by teh VkAttachmentDescription above),
     42     // that are used by the subpass.
     43     VkAttachmentReference colorRef;
     44     VkAttachmentReference resolveRef;
     45     VkAttachmentReference stencilRef;
     46     uint32_t currentAttachment = 0;
     47 
     48     // Go through each of the attachment types (color, resolve, stencil) and set the necessary
     49     // on the various Vk structs.
     50     VkSubpassDescription subpassDesc;
     51     memset(&subpassDesc, 0, sizeof(VkSubpassDescription));
     52     subpassDesc.flags = 0;
     53     subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
     54     subpassDesc.inputAttachmentCount = 0;
     55     subpassDesc.pInputAttachments = nullptr;
     56     if (fAttachmentFlags & kColor_AttachmentFlag) {
     57         // set up color attachment
     58         setup_simple_vk_attachment_description(&attachments[currentAttachment],
     59                                                fAttachmentsDescriptor.fColor.fFormat,
     60                                                fAttachmentsDescriptor.fColor.fSamples,
     61                                                VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
     62         // setup subpass use of attachment
     63         colorRef.attachment = currentAttachment++;
     64         colorRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
     65         subpassDesc.colorAttachmentCount = 1;
     66     } else {
     67         // I don't think there should ever be a time where we don't have a color attachment
     68         SkASSERT(false);
     69         colorRef.attachment = VK_ATTACHMENT_UNUSED;
     70         colorRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
     71         subpassDesc.colorAttachmentCount = 0;
     72     }
     73     subpassDesc.pColorAttachments = &colorRef;
     74 
     75     if (fAttachmentFlags & kResolve_AttachmentFlag) {
     76         // set up resolve attachment
     77         setup_simple_vk_attachment_description(&attachments[currentAttachment],
     78                                                fAttachmentsDescriptor.fResolve.fFormat,
     79                                                fAttachmentsDescriptor.fResolve.fSamples,
     80                                                VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
     81         // setup subpass use of attachment
     82         resolveRef.attachment = currentAttachment++;
     83         // I'm really not sure what the layout should be for the resolve textures.
     84         resolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
     85         subpassDesc.pResolveAttachments = &resolveRef;
     86     } else {
     87         subpassDesc.pResolveAttachments = nullptr;
     88     }
     89 
     90     if (fAttachmentFlags & kStencil_AttachmentFlag) {
     91         // set up stencil attachment
     92         setup_simple_vk_attachment_description(&attachments[currentAttachment],
     93                                                fAttachmentsDescriptor.fStencil.fFormat,
     94                                                fAttachmentsDescriptor.fStencil.fSamples,
     95                                                VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
     96         // setup subpass use of attachment
     97         stencilRef.attachment = currentAttachment++;
     98         stencilRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
     99     } else {
    100         stencilRef.attachment = VK_ATTACHMENT_UNUSED;
    101         stencilRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
    102     }
    103     subpassDesc.pDepthStencilAttachment = &stencilRef;
    104 
    105     subpassDesc.preserveAttachmentCount = 0;
    106     subpassDesc.pPreserveAttachments = nullptr;
    107 
    108     SkASSERT(numAttachments == currentAttachment);
    109 
    110     // Create the VkRenderPass compatible with the attachment descriptions above
    111     VkRenderPassCreateInfo createInfo;
    112     memset(&createInfo, 0, sizeof(VkRenderPassCreateInfo));
    113     createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
    114     createInfo.pNext = nullptr;
    115     createInfo.flags = 0;
    116     createInfo.attachmentCount = numAttachments;
    117     createInfo.pAttachments = attachments.begin();
    118     createInfo.subpassCount = 1;
    119     createInfo.pSubpasses = &subpassDesc;
    120     createInfo.dependencyCount = 0;
    121     createInfo.pDependencies = nullptr;
    122 
    123     GR_VK_CALL_ERRCHECK(gpu->vkInterface(), CreateRenderPass(gpu->device(),
    124                                                              &createInfo,
    125                                                              nullptr,
    126                                                              &fRenderPass));
    127 }
    128 
    129 void GrVkRenderPass::freeGPUData(const GrVkGpu* gpu) const {
    130     GR_VK_CALL(gpu->vkInterface(), DestroyRenderPass(gpu->device(), fRenderPass, nullptr));
    131 }
    132 
    133 // Works under the assumption that color attachment will always be the first attachment in our
    134 // attachment array if it exists.
    135 bool GrVkRenderPass::colorAttachmentIndex(uint32_t* index) const {
    136     *index = 0;
    137     if (fAttachmentFlags & kColor_AttachmentFlag) {
    138         return true;
    139     }
    140     return false;
    141 }
    142 
    143 // Works under the assumption that resolve attachment will always be after the color attachment.
    144 bool GrVkRenderPass::resolveAttachmentIndex(uint32_t* index) const {
    145     *index = 0;
    146     if (fAttachmentFlags & kColor_AttachmentFlag) {
    147         ++(*index);
    148     }
    149     if (fAttachmentFlags & kResolve_AttachmentFlag) {
    150         return true;
    151     }
    152     return false;
    153 }
    154 
    155 // Works under the assumption that stencil attachment will always be after the color and resolve
    156 // attachment.
    157 bool GrVkRenderPass::stencilAttachmentIndex(uint32_t* index) const {
    158     *index = 0;
    159     if (fAttachmentFlags & kColor_AttachmentFlag) {
    160         ++(*index);
    161     }
    162     if (fAttachmentFlags & kResolve_AttachmentFlag) {
    163         ++(*index);
    164     }
    165     if (fAttachmentFlags & kStencil_AttachmentFlag) {
    166         return true;
    167     }
    168     return false;
    169 }
    170 
    171 void GrVkRenderPass::getBeginInfo(const GrVkRenderTarget& target,
    172                                   VkRenderPassBeginInfo* beginInfo,
    173                                   VkSubpassContents* contents) const {
    174     SkASSERT(this->isCompatible(target));
    175 
    176     VkRect2D renderArea;
    177     renderArea.offset = { 0, 0 };
    178     renderArea.extent = { (uint32_t)target.width(), (uint32_t)target.height() };
    179 
    180     memset(beginInfo, 0, sizeof(VkRenderPassBeginInfo));
    181     beginInfo->sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
    182     beginInfo->pNext = nullptr;
    183     beginInfo->renderPass = fRenderPass;
    184     beginInfo->framebuffer = target.framebuffer()->framebuffer();
    185     beginInfo->renderArea = renderArea;
    186     beginInfo->clearValueCount = 0;
    187     beginInfo->pClearValues = nullptr;
    188 
    189     // Currently just assuming no secondary cmd buffers. This value will need to be update if we
    190     // have them.
    191     *contents = VK_SUBPASS_CONTENTS_INLINE;
    192 }
    193 
    194 bool GrVkRenderPass::isCompatible(const GrVkRenderTarget& target) const {
    195     AttachmentsDescriptor desc;
    196     AttachmentFlags flags;
    197     target.getAttachmentsDescriptor(&desc, &flags);
    198 
    199     if (flags != fAttachmentFlags) {
    200         return false;
    201     }
    202 
    203     if (fAttachmentFlags & kColor_AttachmentFlag) {
    204         if (fAttachmentsDescriptor.fColor != desc.fColor) {
    205             return false;
    206         }
    207     }
    208     if (fAttachmentFlags & kResolve_AttachmentFlag) {
    209         if (fAttachmentsDescriptor.fResolve != desc.fResolve) {
    210             return false;
    211         }
    212     }
    213     if (fAttachmentFlags & kStencil_AttachmentFlag) {
    214         if (fAttachmentsDescriptor.fStencil != desc.fStencil) {
    215             return false;
    216         }
    217     }
    218 
    219     return true;
    220 }
    221