blob: 02d433792ae33118da37f2bfb5e5e4dfbfd16811 [file] [log] [blame]
Corentin Wallez6f7749c2018-05-02 18:10:13 -04001// Copyright 2018 The NXT Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Corentin Wallez8d6b5d22018-05-11 13:04:44 -040015#include "backend/vulkan/RenderPassDescriptorVk.h"
Corentin Wallez6f7749c2018-05-02 18:10:13 -040016
17#include "backend/vulkan/FencedDeleter.h"
18#include "backend/vulkan/RenderPassCache.h"
19#include "backend/vulkan/TextureVk.h"
20#include "backend/vulkan/VulkanBackend.h"
21#include "common/BitSetIterator.h"
22
23namespace backend { namespace vulkan {
24
Corentin Wallez8d6b5d22018-05-11 13:04:44 -040025 RenderPassDescriptor::RenderPassDescriptor(RenderPassDescriptorBuilder* builder)
26 : RenderPassDescriptorBase(builder), mDevice(ToBackend(builder->GetDevice())) {
Corentin Wallez6f7749c2018-05-02 18:10:13 -040027 }
28
Corentin Wallez8d6b5d22018-05-11 13:04:44 -040029 void RenderPassDescriptor::RecordBeginRenderPass(VkCommandBuffer commands) {
Corentin Wallez6f7749c2018-05-02 18:10:13 -040030 // Query a VkRenderPass from the cache
31 VkRenderPass renderPass = VK_NULL_HANDLE;
32 {
33 RenderPassCacheQuery query;
34
35 for (uint32_t i : IterateBitSet(GetColorAttachmentMask())) {
36 const auto& attachmentInfo = GetColorAttachment(i);
37 query.SetColor(i, attachmentInfo.view->GetTexture()->GetFormat(),
38 attachmentInfo.loadOp);
39 }
40
41 if (HasDepthStencilAttachment()) {
42 const auto& attachmentInfo = GetDepthStencilAttachment();
43 query.SetDepthStencil(attachmentInfo.view->GetTexture()->GetFormat(),
44 attachmentInfo.depthLoadOp, attachmentInfo.stencilLoadOp);
45 }
46
47 renderPass = mDevice->GetRenderPassCache()->GetRenderPass(query);
48 }
49
50 // Create a framebuffer that will be used once for the render pass and gather the clear
51 // values for the attachments at the same time.
52 std::array<VkClearValue, kMaxColorAttachments + 1> clearValues;
53 VkFramebuffer framebuffer = VK_NULL_HANDLE;
54 uint32_t attachmentCount = 0;
55 {
56 // Fill in the attachment info that will be chained in the framebuffer create info.
57 std::array<VkImageView, kMaxColorAttachments + 1> attachments;
58
59 for (uint32_t i : IterateBitSet(GetColorAttachmentMask())) {
60 auto& attachmentInfo = GetColorAttachment(i);
61 TextureView* view = ToBackend(attachmentInfo.view.Get());
62
63 attachments[attachmentCount] = view->GetHandle();
64
65 clearValues[attachmentCount].color.float32[0] = attachmentInfo.clearColor[0];
66 clearValues[attachmentCount].color.float32[1] = attachmentInfo.clearColor[1];
67 clearValues[attachmentCount].color.float32[2] = attachmentInfo.clearColor[2];
68 clearValues[attachmentCount].color.float32[3] = attachmentInfo.clearColor[3];
69
70 attachmentCount++;
71 }
72
73 if (HasDepthStencilAttachment()) {
74 auto& attachmentInfo = GetDepthStencilAttachment();
75 TextureView* view = ToBackend(attachmentInfo.view.Get());
76
77 attachments[attachmentCount] = view->GetHandle();
78
79 clearValues[attachmentCount].depthStencil.depth = attachmentInfo.clearDepth;
80 clearValues[attachmentCount].depthStencil.stencil = attachmentInfo.clearStencil;
81
82 attachmentCount++;
83 }
84
85 // Chain attachments and create the framebuffer
86 VkFramebufferCreateInfo createInfo;
87 createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
88 createInfo.pNext = nullptr;
89 createInfo.flags = 0;
90 createInfo.renderPass = renderPass;
91 createInfo.attachmentCount = attachmentCount;
92 createInfo.pAttachments = attachments.data();
93 createInfo.width = GetWidth();
94 createInfo.height = GetHeight();
95 createInfo.layers = 1;
96
97 if (mDevice->fn.CreateFramebuffer(mDevice->GetVkDevice(), &createInfo, nullptr,
98 &framebuffer) != VK_SUCCESS) {
99 ASSERT(false);
100 }
101
102 // We don't reuse VkFramebuffers so mark the framebuffer for deletion as soon as the
103 // commands currently being recorded are finished.
104 mDevice->GetFencedDeleter()->DeleteWhenUnused(framebuffer);
105 }
106
107 VkRenderPassBeginInfo beginInfo;
108 beginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
109 beginInfo.pNext = nullptr;
110 beginInfo.renderPass = renderPass;
111 beginInfo.framebuffer = framebuffer;
112 beginInfo.renderArea.offset.x = 0;
113 beginInfo.renderArea.offset.y = 0;
114 beginInfo.renderArea.extent.width = GetWidth();
115 beginInfo.renderArea.extent.height = GetHeight();
116 beginInfo.clearValueCount = attachmentCount;
117 beginInfo.pClearValues = clearValues.data();
118
119 mDevice->fn.CmdBeginRenderPass(commands, &beginInfo, VK_SUBPASS_CONTENTS_INLINE);
120 }
121
122}} // namespace backend::vulkan