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>
29 struct Framebuffer::Impl
31 Impl( Framebuffer& owner, Graphics& graphics, uint32_t width, uint32_t height )
32 : mInterface( owner ), mGraphics( graphics ), mColorImageViewAttachments{}, mDepthStencilImageViewAttachment()
38 // creating render pass may happen either as deferred or
39 // when framebuffer is initialised into immutable state
40 #pragma GCC diagnostic push
41 #pragma GCC diagnostic ignored "-Wframe-larger-than="
44 mAttachmentReference.clear();
45 mAttachmentDescription.clear();
46 mDefaultClearValues.clear();
50 auto attachments = std::vector<vk::ImageView>{};
51 auto colorAttachmentSize = 0u;
52 for( auto&& colorAttachment : mColorImageViewAttachments )
54 auto attRef = vk::AttachmentReference{};
55 attRef.setLayout( vk::ImageLayout::eColorAttachmentOptimal );
56 attRef.setAttachment( colorAttachmentSize++ );
57 mAttachmentReference.emplace_back( attRef );
58 attachments.emplace_back( colorAttachment->GetVkImageView() );
60 vk::AttachmentDescription attDesc{};
61 attDesc.setSamples( vk::SampleCountFlagBits::e1 )
62 .setInitialLayout( vk::ImageLayout::eUndefined )
63 .setFormat( colorAttachment->GetImage()->GetVkFormat() )
64 .setStencilStoreOp( vk::AttachmentStoreOp::eDontCare )
65 .setStencilLoadOp( vk::AttachmentLoadOp::eDontCare )
66 .setLoadOp( vk::AttachmentLoadOp::eClear )
67 .setStoreOp( vk::AttachmentStoreOp::eStore )
68 .setFinalLayout( vk::ImageLayout::ePresentSrcKHR );
70 mAttachmentDescription.emplace_back( attDesc );
72 // update clear color values
73 vk::ClearColorValue clear;
74 clear.setFloat32( {0.0f, 0.0f, 0.0f, 1.0f} );
75 mDefaultClearValues.emplace_back( clear );
79 * DEPTH-STENCIL ATTACHMENT
81 if( mDepthStencilImageViewAttachment )
83 auto attRef = vk::AttachmentReference{};
84 attRef.setLayout( vk::ImageLayout::eDepthStencilAttachmentOptimal );
85 attRef.setAttachment( colorAttachmentSize );
86 mAttachmentReference.emplace_back( attRef );
87 attachments.emplace_back( mDepthStencilImageViewAttachment->GetVkImageView() );
89 vk::AttachmentDescription attDesc{};
90 attDesc.setSamples( vk::SampleCountFlagBits::e1 )
91 .setInitialLayout( vk::ImageLayout::eUndefined )
92 .setFormat( mDepthStencilImageViewAttachment->GetImage()->GetVkFormat() )
93 .setStencilStoreOp( vk::AttachmentStoreOp::eDontCare )
94 .setStencilLoadOp( vk::AttachmentLoadOp::eDontCare )
95 .setLoadOp( vk::AttachmentLoadOp::eClear )
96 .setStoreOp( vk::AttachmentStoreOp::eDontCare )
97 .setFinalLayout( vk::ImageLayout::eDepthStencilAttachmentOptimal );
98 mAttachmentDescription.emplace_back( attDesc );
100 // update clear depth/stencil values
101 vk::ClearDepthStencilValue clear;
102 clear.setDepth( 0.0f ).setStencil( 1.0f );
103 mDefaultClearValues.emplace_back( clear );
109 // creating single subpass per framebuffer
110 auto subpassDesc = vk::SubpassDescription{};
111 subpassDesc.setPipelineBindPoint( vk::PipelineBindPoint::eGraphics );
112 subpassDesc.setColorAttachmentCount( colorAttachmentSize );
113 if( mDepthStencilImageViewAttachment )
115 subpassDesc.setPDepthStencilAttachment( &mAttachmentReference[colorAttachmentSize] );
117 subpassDesc.setPColorAttachments( &mAttachmentReference[0] );
122 // create compatible render pass
123 auto rpInfo = vk::RenderPassCreateInfo{};
124 rpInfo.setAttachmentCount( U32(mAttachmentDescription.size()) );
125 rpInfo.setPAttachments( mAttachmentDescription.data() );
126 rpInfo.setPSubpasses( &subpassDesc );
127 rpInfo.setSubpassCount( 1 );
128 mVkRenderPass = VkAssert( mGraphics.GetDevice().createRenderPass( rpInfo, mGraphics.GetAllocator() ));
133 vk::FramebufferCreateInfo info;
134 info.setRenderPass( mVkRenderPass )
135 .setPAttachments( attachments.data() )
138 .setHeight( mHeight )
139 .setAttachmentCount( U32(attachments.size()) );
141 mVkFramebuffer = VkAssert( mGraphics.GetDevice().createFramebuffer( info, mGraphics.GetAllocator() ) );
145 #pragma GCC diagnostic pop
148 * Creates immutable framebuffer object
154 mInitialised = Initialise();
160 void SetAttachment( ImageViewRef imageViewRef, Framebuffer::AttachmentType type, uint32_t index )
162 // TODO: all array-type atyachments
163 if( type == AttachmentType::COLOR )
165 auto& attachments = mColorImageViewAttachments;
166 if( attachments.size() <= index )
168 attachments.resize( index + 1 );
170 attachments[index] = imageViewRef;
172 else if( type == AttachmentType::DEPTH_STENCIL )
174 mDepthStencilImageViewAttachment = imageViewRef;
178 ImageViewRef GetAttachment( AttachmentType type, uint32_t index ) const
182 case AttachmentType::COLOR:
184 return mColorImageViewAttachments[index];
186 case AttachmentType::DEPTH_STENCIL:
188 return mDepthStencilImageViewAttachment;
190 case AttachmentType::DEPTH:
191 case AttachmentType::INPUT:
192 case AttachmentType::RESOLVE:
193 case AttachmentType::PRESERVE:
195 return ImageViewRef();
198 return ImageViewRef();
201 std::vector<ImageViewRef> GetAttachments( AttachmentType type ) const
203 std::vector<ImageViewRef> retval{};
206 case AttachmentType::COLOR:
208 retval.insert( retval.end(), mColorImageViewAttachments.begin(), mColorImageViewAttachments.end() );
211 case AttachmentType::DEPTH_STENCIL:
213 retval.push_back( mDepthStencilImageViewAttachment );
216 case AttachmentType::DEPTH:
217 case AttachmentType::INPUT:
218 case AttachmentType::RESOLVE:
219 case AttachmentType::PRESERVE:
227 uint32_t GetAttachmentCount( AttachmentType type ) const
229 std::vector<ImageViewRef> retval{};
232 case AttachmentType::COLOR:
234 return U32(mColorImageViewAttachments.size());
236 case AttachmentType::DEPTH_STENCIL:
238 return mDepthStencilImageViewAttachment ? 1u : 0u;
240 case AttachmentType::DEPTH:
241 case AttachmentType::INPUT:
242 case AttachmentType::RESOLVE:
243 case AttachmentType::PRESERVE:
251 const std::vector<vk::ClearValue>& GetDefaultClearValues() const
253 return mDefaultClearValues;
258 vk::RenderPass GetVkRenderPass() const
260 return mVkRenderPass;
263 vk::Framebuffer GetVkFramebuffer() const
265 return mVkFramebuffer;
268 Framebuffer& mInterface;
274 std::vector<ImageViewRef> mColorImageViewAttachments;
275 ImageViewRef mDepthStencilImageViewAttachment;
276 vk::Framebuffer mVkFramebuffer;
277 vk::RenderPass mVkRenderPass;
279 // attachment references for the main subpass
280 std::vector<vk::AttachmentReference> mAttachmentReference;
281 std::vector<vk::AttachmentDescription> mAttachmentDescription;
283 std::vector<vk::ClearValue> mDefaultClearValues;
284 bool mInitialised{false};
287 FramebufferRef Framebuffer::New( Graphics& graphics, uint32_t width, uint32_t height )
289 FramebufferRef ref( new Framebuffer( graphics, width, height ) );
293 Framebuffer::Framebuffer( Graphics& graphics, uint32_t width, uint32_t height )
295 mImpl = std::make_unique<Impl>( *this, graphics, width, height );
298 void Framebuffer::SetAttachment( ImageViewRef imageViewRef, Framebuffer::AttachmentType type, uint32_t index )
300 mImpl->SetAttachment( imageViewRef, type, index );
303 uint32_t Framebuffer::GetWidth() const
305 return mImpl->mWidth;
308 uint32_t Framebuffer::GetHeight() const
310 return mImpl->mHeight;
313 ImageViewRef Framebuffer::GetAttachment( AttachmentType type, uint32_t index ) const
315 return mImpl->GetAttachment( type, index );
318 std::vector<ImageViewRef> Framebuffer::GetAttachments( AttachmentType type ) const
320 return mImpl->GetAttachments( type );
323 uint32_t Framebuffer::GetAttachmentCount( AttachmentType type ) const
325 return mImpl->GetAttachmentCount( type );
328 void Framebuffer::Commit()
333 vk::RenderPass Framebuffer::GetVkRenderPass() const
335 return mImpl->mVkRenderPass;
338 vk::Framebuffer Framebuffer::GetVkFramebuffer() const
340 return mImpl->mVkFramebuffer;
343 const std::vector<vk::ClearValue>& Framebuffer::GetDefaultClearValues() const
345 return mImpl->GetDefaultClearValues();
348 } // Namespace Vulkan
350 } // Namespace Graphics