2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <dali/graphics/vulkan/vulkan-framebuffer.h>
19 #include <dali/graphics/vulkan/vulkan-graphics.h>
20 #include <dali/graphics/vulkan/vulkan-image.h>
28 struct Framebuffer::Impl
30 Impl( Framebuffer& owner, Graphics& graphics, uint32_t width, uint32_t height )
31 : mInterface( owner ), mGraphics( graphics ), mColorImageViewAttachments{}, mDepthStencilImageViewAttachment()
37 // creating render pass may happen either as deferred or
38 // when framebuffer is initialised into immutable state
41 mAttachmentReference.clear();
42 mAttachmentDescription.clear();
43 mDefaultClearValues.clear();
47 auto attachments = std::vector<vk::ImageView>{};
48 auto colorAttachmentSize = 0u;
49 for( auto&& colorAttachment : mColorImageViewAttachments )
51 auto attRef = vk::AttachmentReference{};
52 attRef.setLayout( vk::ImageLayout::eColorAttachmentOptimal );
53 attRef.setAttachment( colorAttachmentSize++ );
54 mAttachmentReference.emplace_back( attRef );
55 attachments.emplace_back( colorAttachment->GetVkImageView() );
57 vk::AttachmentDescription attDesc{};
58 attDesc.setSamples( vk::SampleCountFlagBits::e1 )
59 .setInitialLayout( vk::ImageLayout::eUndefined )
60 .setFormat( colorAttachment->GetImage()->GetVkFormat() )
61 .setStencilStoreOp( vk::AttachmentStoreOp::eDontCare )
62 .setStencilLoadOp( vk::AttachmentLoadOp::eDontCare )
63 .setLoadOp( vk::AttachmentLoadOp::eClear )
64 .setStoreOp( vk::AttachmentStoreOp::eStore )
65 .setFinalLayout( vk::ImageLayout::ePresentSrcKHR );
67 mAttachmentDescription.emplace_back( attDesc );
69 // update clear color values
70 vk::ClearColorValue clear;
71 clear.setFloat32( {0.0f, 0.0f, 0.0f, 1.0f} );
72 mDefaultClearValues.emplace_back( clear );
76 * DEPTH-STENCIL ATTACHMENT
78 if( mDepthStencilImageViewAttachment )
80 auto attRef = vk::AttachmentReference{};
81 attRef.setLayout( vk::ImageLayout::eDepthStencilAttachmentOptimal );
82 attRef.setAttachment( colorAttachmentSize );
83 mAttachmentReference.emplace_back( attRef );
84 attachments.emplace_back( mDepthStencilImageViewAttachment->GetVkImageView() );
86 vk::AttachmentDescription attDesc{};
87 attDesc.setSamples( vk::SampleCountFlagBits::e1 )
88 .setInitialLayout( vk::ImageLayout::eUndefined )
89 .setFormat( mDepthStencilImageViewAttachment->GetImage()->GetVkFormat() )
90 .setStencilStoreOp( vk::AttachmentStoreOp::eDontCare )
91 .setStencilLoadOp( vk::AttachmentLoadOp::eDontCare )
92 .setLoadOp( vk::AttachmentLoadOp::eClear )
93 .setStoreOp( vk::AttachmentStoreOp::eDontCare )
94 .setFinalLayout( vk::ImageLayout::eDepthStencilAttachmentOptimal );
95 mAttachmentDescription.emplace_back( attDesc );
97 // update clear depth/stencil values
98 vk::ClearDepthStencilValue clear;
99 clear.setDepth( 0.0f ).setStencil( 1.0f );
100 mDefaultClearValues.emplace_back( clear );
106 // creating single subpass per framebuffer
107 auto subpassDesc = vk::SubpassDescription{};
108 subpassDesc.setPipelineBindPoint( vk::PipelineBindPoint::eGraphics );
109 subpassDesc.setColorAttachmentCount( colorAttachmentSize );
110 if( mDepthStencilImageViewAttachment )
112 subpassDesc.setPDepthStencilAttachment( &mAttachmentReference[colorAttachmentSize] );
114 subpassDesc.setPColorAttachments( &mAttachmentReference[0] );
119 // create compatible render pass
120 auto rpInfo = vk::RenderPassCreateInfo{};
121 rpInfo.setAttachmentCount( U32(mAttachmentDescription.size()) );
122 rpInfo.setPAttachments( mAttachmentDescription.data() );
123 rpInfo.setPSubpasses( &subpassDesc );
124 rpInfo.setSubpassCount( 1 );
125 mVkRenderPass = VkAssert( mGraphics.GetDevice().createRenderPass( rpInfo, mGraphics.GetAllocator() ));
130 vk::FramebufferCreateInfo info;
131 info.setRenderPass( mVkRenderPass )
132 .setPAttachments( attachments.data() )
135 .setHeight( mHeight )
136 .setAttachmentCount( U32(attachments.size()) );
138 mVkFramebuffer = VkAssert( mGraphics.GetDevice().createFramebuffer( info, mGraphics.GetAllocator() ) );
144 * Creates immutable framebuffer object
150 mInitialised = Initialise();
156 void SetAttachment( ImageViewRef imageViewRef, Framebuffer::AttachmentType type, uint32_t index )
158 // TODO: all array-type atyachments
159 if( type == AttachmentType::COLOR )
161 auto& attachments = mColorImageViewAttachments;
162 if( attachments.size() <= index )
164 attachments.resize( index + 1 );
166 attachments[index] = imageViewRef;
168 else if( type == AttachmentType::DEPTH_STENCIL )
170 mDepthStencilImageViewAttachment = imageViewRef;
174 ImageViewRef GetAttachment( AttachmentType type, uint32_t index ) const
178 case AttachmentType::COLOR:
180 return mColorImageViewAttachments[index];
182 case AttachmentType::DEPTH_STENCIL:
184 return mDepthStencilImageViewAttachment;
186 case AttachmentType::DEPTH:
187 case AttachmentType::INPUT:
188 case AttachmentType::RESOLVE:
189 case AttachmentType::PRESERVE:
191 return ImageViewRef();
194 return ImageViewRef();
197 std::vector<ImageViewRef> GetAttachments( AttachmentType type ) const
199 std::vector<ImageViewRef> retval{};
202 case AttachmentType::COLOR:
204 retval.insert( retval.end(), mColorImageViewAttachments.begin(), mColorImageViewAttachments.end() );
207 case AttachmentType::DEPTH_STENCIL:
209 retval.push_back( mDepthStencilImageViewAttachment );
212 case AttachmentType::DEPTH:
213 case AttachmentType::INPUT:
214 case AttachmentType::RESOLVE:
215 case AttachmentType::PRESERVE:
223 uint32_t GetAttachmentCount( AttachmentType type ) const
225 std::vector<ImageViewRef> retval{};
228 case AttachmentType::COLOR:
230 return U32(mColorImageViewAttachments.size());
232 case AttachmentType::DEPTH_STENCIL:
234 return mDepthStencilImageViewAttachment ? 1u : 0u;
236 case AttachmentType::DEPTH:
237 case AttachmentType::INPUT:
238 case AttachmentType::RESOLVE:
239 case AttachmentType::PRESERVE:
247 const std::vector<vk::ClearValue>& GetDefaultClearValues() const
249 return mDefaultClearValues;
254 vk::RenderPass GetVkRenderPass() const
256 return mVkRenderPass;
259 vk::Framebuffer GetVkFramebuffer() const
261 return mVkFramebuffer;
264 Framebuffer& mInterface;
270 std::vector<ImageViewRef> mColorImageViewAttachments;
271 ImageViewRef mDepthStencilImageViewAttachment;
272 vk::Framebuffer mVkFramebuffer;
273 vk::RenderPass mVkRenderPass;
275 // attachment references for the main subpass
276 std::vector<vk::AttachmentReference> mAttachmentReference;
277 std::vector<vk::AttachmentDescription> mAttachmentDescription;
279 std::vector<vk::ClearValue> mDefaultClearValues;
280 bool mInitialised{false};
283 FramebufferRef Framebuffer::New( Graphics& graphics, uint32_t width, uint32_t height )
285 FramebufferRef ref( new Framebuffer( graphics, width, height ) );
289 Framebuffer::Framebuffer( Graphics& graphics, uint32_t width, uint32_t height )
291 mImpl = std::make_unique<Impl>( *this, graphics, width, height );
294 void Framebuffer::SetAttachment( ImageViewRef imageViewRef, Framebuffer::AttachmentType type, uint32_t index )
296 mImpl->SetAttachment( imageViewRef, type, index );
299 uint32_t Framebuffer::GetWidth() const
301 return mImpl->mWidth;
304 uint32_t Framebuffer::GetHeight() const
306 return mImpl->mHeight;
309 ImageViewRef Framebuffer::GetAttachment( AttachmentType type, uint32_t index ) const
311 return mImpl->GetAttachment( type, index );
314 std::vector<ImageViewRef> Framebuffer::GetAttachments( AttachmentType type ) const
316 return mImpl->GetAttachments( type );
319 uint32_t Framebuffer::GetAttachmentCount( AttachmentType type ) const
321 return mImpl->GetAttachmentCount( type );
324 void Framebuffer::Commit()
329 vk::RenderPass Framebuffer::GetVkRenderPass() const
331 return mImpl->mVkRenderPass;
334 vk::Framebuffer Framebuffer::GetVkFramebuffer() const
336 return mImpl->mVkFramebuffer;
339 const std::vector<vk::ClearValue>& Framebuffer::GetDefaultClearValues() const
341 return mImpl->GetDefaultClearValues();
344 } // Namespace Vulkan
346 } // Namespace Graphics