8f8f4e7ae99ec42b4e12a20f33d89fa238d12f0a
[platform/core/uifw/dali-core.git] / dali / graphics / vulkan / vulkan-framebuffer.cpp
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 #include <dali/graphics/vulkan/vulkan-framebuffer.h>
19 #include <dali/graphics/vulkan/vulkan-graphics.h>
20 #include <dali/graphics/vulkan/vulkan-image.h>
21
22
23 namespace Dali
24 {
25 namespace Graphics
26 {
27 namespace Vulkan
28 {
29 struct Framebuffer::Impl
30 {
31   Impl( Framebuffer& owner, Graphics& graphics, uint32_t width, uint32_t height )
32   : mInterface( owner ), mGraphics( graphics ), mColorImageViewAttachments{}, mDepthStencilImageViewAttachment()
33   {
34     mWidth = width;
35     mHeight = height;
36   }
37
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="
42   bool Initialise()
43   {
44     mAttachmentReference.clear();
45     mAttachmentDescription.clear();
46     mDefaultClearValues.clear();
47     /*
48      * COLOR ATTACHMENTS
49      */
50     auto attachments         = std::vector<vk::ImageView>{};
51     auto colorAttachmentSize = 0u;
52     for( auto&& colorAttachment : mColorImageViewAttachments )
53     {
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() );
59
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 );
69
70       mAttachmentDescription.emplace_back( attDesc );
71
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 );
76     }
77
78     /*
79      * DEPTH-STENCIL ATTACHMENT
80      */
81     if( mDepthStencilImageViewAttachment )
82     {
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() );
88
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 );
99
100       // update clear depth/stencil values
101       vk::ClearDepthStencilValue clear;
102       clear.setDepth( 0.0f ).setStencil( 1.0f );
103       mDefaultClearValues.emplace_back( clear );
104     }
105
106     /*
107      * SUBPASS
108      */
109     // creating single subpass per framebuffer
110     auto subpassDesc = vk::SubpassDescription{};
111     subpassDesc.setPipelineBindPoint( vk::PipelineBindPoint::eGraphics );
112     subpassDesc.setColorAttachmentCount( colorAttachmentSize );
113     if( mDepthStencilImageViewAttachment )
114     {
115       subpassDesc.setPDepthStencilAttachment( &mAttachmentReference[colorAttachmentSize] );
116     }
117     subpassDesc.setPColorAttachments( &mAttachmentReference[0] );
118
119     /*
120      * RENDERPASS
121      */
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() ));
129
130     /*
131      * FRAMEBUFFER
132      */
133     vk::FramebufferCreateInfo info;
134     info.setRenderPass( mVkRenderPass )
135         .setPAttachments( attachments.data() )
136         .setLayers( 1 )
137         .setWidth( mWidth )
138         .setHeight( mHeight )
139         .setAttachmentCount( U32(attachments.size()) );
140
141     mVkFramebuffer = VkAssert( mGraphics.GetDevice().createFramebuffer( info, mGraphics.GetAllocator() ) );
142
143     return true;
144   }
145 #pragma GCC diagnostic pop
146
147   /**
148    * Creates immutable framebuffer object
149    */
150   bool Commit()
151   {
152     if(!mInitialised)
153     {
154       mInitialised = Initialise();
155       return mInitialised;
156     }
157     return false;
158   }
159
160   void SetAttachment( ImageViewRef imageViewRef, Framebuffer::AttachmentType type, uint32_t index )
161   {
162     // TODO: all array-type atyachments
163     if( type == AttachmentType::COLOR )
164     {
165       auto& attachments = mColorImageViewAttachments;
166       if( attachments.size() <= index )
167       {
168         attachments.resize( index + 1 );
169       }
170       attachments[index] = imageViewRef;
171     }
172     else if( type == AttachmentType::DEPTH_STENCIL )
173     {
174       mDepthStencilImageViewAttachment = imageViewRef;
175     }
176   }
177
178   ImageViewRef GetAttachment( AttachmentType type, uint32_t index ) const
179   {
180     switch( type )
181     {
182       case AttachmentType::COLOR:
183       {
184         return mColorImageViewAttachments[index];
185       }
186       case AttachmentType::DEPTH_STENCIL:
187       {
188         return mDepthStencilImageViewAttachment;
189       }
190       case AttachmentType::DEPTH:
191       case AttachmentType::INPUT:
192       case AttachmentType::RESOLVE:
193       case AttachmentType::PRESERVE:
194       {
195         return ImageViewRef();
196       }
197     }
198     return ImageViewRef();
199   }
200
201   std::vector<ImageViewRef> GetAttachments( AttachmentType type ) const
202   {
203     std::vector<ImageViewRef> retval{};
204     switch( type )
205     {
206       case AttachmentType::COLOR:
207       {
208         retval.insert( retval.end(), mColorImageViewAttachments.begin(), mColorImageViewAttachments.end() );
209         return retval;
210       }
211       case AttachmentType::DEPTH_STENCIL:
212       {
213         retval.push_back( mDepthStencilImageViewAttachment );
214         return retval;
215       }
216       case AttachmentType::DEPTH:
217       case AttachmentType::INPUT:
218       case AttachmentType::RESOLVE:
219       case AttachmentType::PRESERVE:
220       {
221         return retval;
222       }
223     }
224     return retval;
225   }
226
227   uint32_t GetAttachmentCount( AttachmentType type ) const
228   {
229     std::vector<ImageViewRef> retval{};
230     switch( type )
231     {
232       case AttachmentType::COLOR:
233       {
234         return U32(mColorImageViewAttachments.size());
235       }
236       case AttachmentType::DEPTH_STENCIL:
237       {
238         return mDepthStencilImageViewAttachment ? 1u : 0u;
239       }
240       case AttachmentType::DEPTH:
241       case AttachmentType::INPUT:
242       case AttachmentType::RESOLVE:
243       case AttachmentType::PRESERVE:
244       {
245         return 0u;
246       }
247     }
248     return 0u;
249   }
250
251   const std::vector<vk::ClearValue>& GetDefaultClearValues() const
252   {
253     return mDefaultClearValues;
254   }
255
256   ~Impl() = default;
257
258   vk::RenderPass GetVkRenderPass() const
259   {
260     return mVkRenderPass;
261   }
262
263   vk::Framebuffer GetVkFramebuffer() const
264   {
265     return mVkFramebuffer;
266   }
267
268   Framebuffer& mInterface;
269   Graphics&    mGraphics;
270
271   uint32_t mWidth;
272   uint32_t mHeight;
273
274   std::vector<ImageViewRef> mColorImageViewAttachments;
275   ImageViewRef              mDepthStencilImageViewAttachment;
276   vk::Framebuffer           mVkFramebuffer;
277   vk::RenderPass            mVkRenderPass;
278
279   // attachment references for the main subpass
280   std::vector<vk::AttachmentReference>   mAttachmentReference;
281   std::vector<vk::AttachmentDescription> mAttachmentDescription;
282
283   std::vector<vk::ClearValue> mDefaultClearValues;
284   bool mInitialised{false};
285 };
286
287 FramebufferRef Framebuffer::New( Graphics& graphics, uint32_t width, uint32_t height )
288 {
289   FramebufferRef ref( new Framebuffer( graphics, width, height ) );
290   return ref;
291 }
292
293 Framebuffer::Framebuffer( Graphics& graphics, uint32_t width, uint32_t height )
294 {
295   mImpl = std::make_unique<Impl>( *this, graphics, width, height );
296 }
297
298 void Framebuffer::SetAttachment( ImageViewRef imageViewRef, Framebuffer::AttachmentType type, uint32_t index )
299 {
300   mImpl->SetAttachment( imageViewRef, type, index );
301 }
302
303 uint32_t Framebuffer::GetWidth() const
304 {
305   return mImpl->mWidth;
306 }
307
308 uint32_t Framebuffer::GetHeight() const
309 {
310   return mImpl->mHeight;
311 }
312
313 ImageViewRef Framebuffer::GetAttachment( AttachmentType type, uint32_t index ) const
314 {
315   return mImpl->GetAttachment( type, index );
316 }
317
318 std::vector<ImageViewRef> Framebuffer::GetAttachments( AttachmentType type ) const
319 {
320   return mImpl->GetAttachments( type );
321 }
322
323 uint32_t Framebuffer::GetAttachmentCount( AttachmentType type ) const
324 {
325   return mImpl->GetAttachmentCount( type );
326 }
327
328 void Framebuffer::Commit()
329 {
330   mImpl->Commit();
331 }
332
333 vk::RenderPass Framebuffer::GetVkRenderPass() const
334 {
335   return mImpl->mVkRenderPass;
336 }
337
338 vk::Framebuffer Framebuffer::GetVkFramebuffer() const
339 {
340   return mImpl->mVkFramebuffer;
341 }
342
343 const std::vector<vk::ClearValue>& Framebuffer::GetDefaultClearValues() const
344 {
345   return mImpl->GetDefaultClearValues();
346 }
347
348 } // Namespace Vulkan
349
350 } // Namespace Graphics
351
352 } // Namespace Dali