Line data Source code
1 : /* Copyright (C) 2023 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #include "precompiled.h"
19 :
20 : #include "Framebuffer.h"
21 :
22 : #include "renderer/backend/vulkan/Device.h"
23 : #include "renderer/backend/vulkan/Mapping.h"
24 : #include "renderer/backend/vulkan/RenderPassManager.h"
25 : #include "renderer/backend/vulkan/Texture.h"
26 : #include "renderer/backend/vulkan/Utilities.h"
27 :
28 : namespace Renderer
29 : {
30 :
31 : namespace Backend
32 : {
33 :
34 : namespace Vulkan
35 : {
36 :
37 : // static
38 0 : std::unique_ptr<CFramebuffer> CFramebuffer::Create(
39 : CDevice* device, const char* name,
40 : SColorAttachment* colorAttachment, SDepthStencilAttachment* depthStencilAttachment)
41 : {
42 0 : ENSURE(colorAttachment || depthStencilAttachment);
43 :
44 0 : if (colorAttachment && depthStencilAttachment)
45 : {
46 0 : CTexture* colorAttachmentTexture = colorAttachment->texture->As<CTexture>();
47 0 : CTexture* depthStencilAttachmentTexture = depthStencilAttachment->texture->As<CTexture>();
48 0 : ENSURE(
49 : colorAttachmentTexture->GetWidth() == depthStencilAttachmentTexture->GetWidth() &&
50 : colorAttachmentTexture->GetHeight() == depthStencilAttachmentTexture->GetHeight() &&
51 : colorAttachmentTexture->GetSampleCount() == depthStencilAttachmentTexture->GetSampleCount());
52 : }
53 :
54 0 : std::unique_ptr<CFramebuffer> framebuffer(new CFramebuffer());
55 0 : framebuffer->m_Device = device;
56 0 : if (colorAttachment)
57 0 : framebuffer->m_ClearColor = colorAttachment->clearColor;
58 :
59 0 : PS::StaticVector<VkImageView, 4> attachments;
60 :
61 0 : if (colorAttachment)
62 : {
63 0 : CTexture* colorAttachmentTexture = colorAttachment->texture->As<CTexture>();
64 :
65 0 : framebuffer->m_Width = colorAttachmentTexture->GetWidth();
66 0 : framebuffer->m_Height = colorAttachmentTexture->GetHeight();
67 0 : framebuffer->m_SampleCount = colorAttachmentTexture->GetSampleCount();
68 0 : framebuffer->m_ColorAttachmentLoadOp = colorAttachment->loadOp;
69 0 : framebuffer->m_ColorAttachmentStoreOp = colorAttachment->storeOp;
70 :
71 0 : attachments.emplace_back(colorAttachmentTexture->GetAttachmentImageView());
72 0 : framebuffer->m_ColorAttachments.emplace_back(colorAttachmentTexture);
73 : }
74 :
75 0 : if (depthStencilAttachment)
76 : {
77 0 : CTexture* depthStencilAttachmentTexture = depthStencilAttachment->texture->As<CTexture>();
78 :
79 0 : framebuffer->m_Width = depthStencilAttachmentTexture->GetWidth();
80 0 : framebuffer->m_Height = depthStencilAttachmentTexture->GetHeight();
81 0 : framebuffer->m_SampleCount = depthStencilAttachmentTexture->GetSampleCount();
82 :
83 0 : framebuffer->m_DepthStencilAttachmentLoadOp = depthStencilAttachment->loadOp;
84 0 : framebuffer->m_DepthStencilAttachmentStoreOp = depthStencilAttachment->storeOp;
85 :
86 0 : attachments.emplace_back(depthStencilAttachmentTexture->GetAttachmentImageView());
87 0 : framebuffer->m_DepthStencilAttachment = depthStencilAttachmentTexture;
88 : }
89 :
90 0 : ENSURE(framebuffer->m_Width > 0 && framebuffer->m_Height > 0);
91 0 : ENSURE(framebuffer->m_SampleCount > 0);
92 :
93 0 : framebuffer->m_RenderPass = device->GetRenderPassManager().GetOrCreateRenderPass(
94 : colorAttachment, depthStencilAttachment);
95 :
96 0 : VkFramebufferCreateInfo framebufferInfo{};
97 0 : framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
98 0 : framebufferInfo.renderPass = framebuffer->m_RenderPass;
99 0 : framebufferInfo.attachmentCount = attachments.size();
100 0 : framebufferInfo.pAttachments = attachments.data();
101 0 : framebufferInfo.width = framebuffer->m_Width;
102 0 : framebufferInfo.height = framebuffer->m_Height;
103 0 : framebufferInfo.layers = 1;
104 :
105 0 : ENSURE_VK_SUCCESS(vkCreateFramebuffer(
106 : device->GetVkDevice(), &framebufferInfo, nullptr, &framebuffer->m_Framebuffer));
107 :
108 0 : device->SetObjectName(VK_OBJECT_TYPE_FRAMEBUFFER, framebuffer->m_Framebuffer, name);
109 :
110 0 : return framebuffer;
111 : }
112 :
113 0 : CFramebuffer::~CFramebuffer()
114 : {
115 0 : if (m_Framebuffer != VK_NULL_HANDLE)
116 0 : m_Device->ScheduleObjectToDestroy(
117 0 : VK_OBJECT_TYPE_FRAMEBUFFER, m_Framebuffer, VK_NULL_HANDLE);
118 0 : }
119 :
120 0 : IDevice* CFramebuffer::GetDevice()
121 : {
122 0 : return m_Device;
123 : }
124 :
125 : } // namespace Vulkan
126 :
127 : } // namespace Backend
128 :
129 3 : } // namespace Renderer
|