[Vulkan] Sampler and texture support - something is rendering
[platform/core/uifw/dali-core.git] / dali / graphics / vulkan / vulkan-descriptor-set.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-descriptor-set.h>
19 #include <dali/graphics/vulkan/vulkan-graphics.h>
20 #include <dali/graphics/vulkan/vulkan-buffer.h>
21 #include <dali/graphics/vulkan/vulkan-image.h>
22 #include <dali/graphics/vulkan/vulkan-sampler.h>
23
24 namespace Dali
25 {
26 namespace Graphics
27 {
28 namespace Vulkan
29 {
30 struct DescriptorPool::Impl
31 {
32   Impl( DescriptorPool& owner, Graphics& graphics, vk::DescriptorPoolCreateInfo createInfo )
33   : mGraphics( graphics ),
34     mOwner( owner ),
35     mCreateInfo( createInfo )
36   {
37
38   }
39
40   ~Impl()
41   {
42
43   }
44
45   /**
46    * Allocates an array of descriptor sets
47    * @param allocateInfo
48    * @return
49    */
50   std::vector<Handle<DescriptorSet>> AllocateDescriptorSets( vk::DescriptorSetAllocateInfo allocateInfo )
51   {
52     // all other fields must be set correct
53     allocateInfo.setDescriptorPool( mVkDescriptorPool );
54     auto result = VkAssert( mGraphics.GetDevice().allocateDescriptorSets( allocateInfo ) );
55
56     std::vector<Handle<DescriptorSet>> retval;
57     retval.reserve( result.size() );
58     for( auto&& item : result )
59     {
60       Handle<DescriptorSet> handle( new DescriptorSet(mGraphics, mOwner, item, allocateInfo) );
61       retval.emplace_back( handle );
62       mDescriptorSetCache.emplace_back( handle );
63     }
64
65     return retval;
66   }
67
68   void Reset()
69   {
70     mGraphics.GetDevice().resetDescriptorPool( mVkDescriptorPool );
71     mDescriptorSetCache.clear();
72   }
73
74   bool Initialise()
75   {
76     mVkDescriptorPool = VkAssert( mGraphics.GetDevice().createDescriptorPool( mCreateInfo, mGraphics.GetAllocator() ) );
77     return true;
78   }
79
80   Graphics& mGraphics;
81   DescriptorPool& mOwner;
82   vk::DescriptorPoolCreateInfo mCreateInfo;
83
84   vk::DescriptorPool mVkDescriptorPool;
85
86   // cache
87   std::vector<Handle<DescriptorSet>> mDescriptorSetCache;
88 };
89
90 Handle<DescriptorPool> DescriptorPool::New( Graphics& graphics, const vk::DescriptorPoolCreateInfo& createInfo )
91 {
92   auto pool = Handle<DescriptorPool>( new DescriptorPool( graphics, createInfo ) );
93   if(pool->mImpl->Initialise())
94   {
95     graphics.AddDescriptorPool(pool);
96   }
97   return pool;
98 }
99
100 DescriptorPool::DescriptorPool( Graphics& graphics, const vk::DescriptorPoolCreateInfo& createInfo )
101 {
102   mImpl = MakeUnique<Impl>( *this, graphics, createInfo );
103 }
104
105 DescriptorPool::~DescriptorPool() = default;
106
107 vk::DescriptorPool DescriptorPool::GetVkDescriptorPool() const
108 {
109   return mImpl->mVkDescriptorPool;
110 }
111
112 std::vector<DescriptorSetHandle> DescriptorPool::AllocateDescriptorSets( vk::DescriptorSetAllocateInfo allocateInfo )
113 {
114   return mImpl->AllocateDescriptorSets( allocateInfo );
115 }
116
117 void DescriptorPool::Reset()
118 {
119   mImpl->Reset();
120 }
121
122 /****************************************************************************************
123  * Class DescriptorSet::Impl
124  */
125
126 struct DescriptorSet::Impl
127 {
128   Impl( Graphics& graphics, DescriptorPool& pool, vk::DescriptorSet set, vk::DescriptorSetAllocateInfo allocateInfo )
129   : mGraphics( graphics ),
130     mPool( pool ),
131     mAllocateInfo( allocateInfo ),
132     mVkDescriptorSet( set )
133   {
134
135   }
136
137   ~Impl()
138   {
139     if(mVkDescriptorSet)
140     {
141       // TODO: @todo non freeable!!!
142       //mGraphics.GetDevice().freeDescriptorSets( mPool.GetVkDescriptorPool(), 1, &mVkDescriptorSet );
143     }
144   }
145
146   void WriteUniformBuffer( uint32_t binding, Handle<Buffer> buffer, uint32_t offset, uint32_t size )
147   {
148     // add resource to the list
149     mResources.emplace_back( buffer.StaticCast<VkManaged>() );
150
151     auto bufferInfo = vk::DescriptorBufferInfo{}
152          .setOffset( U32(offset) )
153          .setRange( U32(size) )
154          .setBuffer( buffer->GetVkBuffer() );
155
156     auto write = vk::WriteDescriptorSet{}.setPBufferInfo( &bufferInfo )
157          .setDescriptorType( vk::DescriptorType::eUniformBuffer )
158          .setDescriptorCount( 1 )
159          .setDstSet( mVkDescriptorSet )
160          .setDstBinding( binding )
161          .setDstArrayElement( 0 );
162
163     // write descriptor set
164     mGraphics.GetDevice().updateDescriptorSets( 1, &write, 0, nullptr  );
165   }
166
167   void WriteCombinedImageSampler( uint32_t binding, SamplerRef sampler, ImageViewRef imageView )
168   {
169     // add resource to the list
170     mResources.emplace_back( sampler.StaticCast<VkManaged>() );
171     mResources.emplace_back( imageView.StaticCast<VkManaged>() );
172
173     auto imageViewInfo = vk::DescriptorImageInfo{}
174          .setImageLayout( vk::ImageLayout::eShaderReadOnlyOptimal )
175          .setImageView( imageView->GetVkImageView() )
176          .setSampler( sampler->GetVkSampler() );
177
178     auto write = vk::WriteDescriptorSet{}.setPImageInfo( &imageViewInfo )
179                                          .setDescriptorType( vk::DescriptorType::eCombinedImageSampler )
180                                          .setDescriptorCount( 1 )
181                                          .setDstSet( mVkDescriptorSet )
182                                          .setDstBinding( binding )
183                                          .setDstArrayElement( 0 );
184
185     // write descriptor set
186     mGraphics.GetDevice().updateDescriptorSets( 1, &write, 0, nullptr  );
187   }
188
189   void WriteStorageBuffer( Handle<Buffer> buffer, uint32_t offset, uint32_t size )
190   {
191     mResources.emplace_back( buffer.StaticCast<VkManaged>() );
192   }
193
194   Graphics& mGraphics;
195   DescriptorPool& mPool;
196   vk::DescriptorSetAllocateInfo mAllocateInfo;
197   vk::DescriptorSet             mVkDescriptorSet;
198
199   // attached resources
200   std::vector<Handle<VkManaged>> mResources;
201 };
202
203 /**
204  * Called by DescriptorPool only!
205  */
206 DescriptorSet::DescriptorSet( Graphics& graphics, DescriptorPool& pool, vk::DescriptorSet descriptorSet, vk::DescriptorSetAllocateInfo allocateInfo )
207 {
208   mImpl = MakeUnique<Impl>( graphics, pool, descriptorSet, allocateInfo );
209 }
210
211 DescriptorSet::~DescriptorSet() = default;
212
213 void DescriptorSet::WriteUniformBuffer( uint32_t binding, Handle<Buffer> buffer, uint32_t offset, uint32_t size )
214 {
215   mImpl->WriteUniformBuffer( binding, buffer, offset, size );
216 }
217
218 vk::DescriptorSet DescriptorSet::GetVkDescriptorSet() const
219 {
220   return mImpl->mVkDescriptorSet;
221 }
222
223 void DescriptorSet::WriteCombinedImageSampler( uint32_t binding, SamplerRef sampler, ImageViewRef imageView )
224 {
225   mImpl->WriteCombinedImageSampler( binding, sampler, imageView );
226 }
227
228 #if 0
229 struct DescriptorSetLayout::Impl
230 {
231   Impl( Graphics& graphics, const vk::DescriptorSetLayoutCreateInfo& createInfo ) :
232     mGraphics( graphics ),
233     mCreateInfo( createInfo )
234   {
235   }
236
237   ~Impl()
238   {
239     if(mLayout)
240     {
241       mGraphics.GetDevice().destroyDescriptorSetLayout( mLayout, mGraphics.GetAllocator() );
242     }
243   }
244
245   bool Initialise()
246   {
247     mLayout = VkAssert( mGraphics.GetDevice().createDescriptorSetLayout( mCreateInfo, mGraphics.GetAllocator() ));
248     if(mLayout)
249     {
250       return true;
251     }
252     return false;
253   }
254
255   Graphics&                         mGraphics;
256   vk::DescriptorSetLayout           mLayout;
257   vk::DescriptorSetLayoutCreateInfo mCreateInfo;
258 };
259
260 /**
261  * Class: DescriptorSetLayout
262  */
263
264 std::unique_ptr<DescriptorSetLayout> DescriptorSetLayout::New( Graphics& graphics, const vk::DescriptorSetLayoutCreateInfo& createInfo )
265 {
266   auto retval = std::unique_ptr<DescriptorSetLayout>( new DescriptorSetLayout(graphics, createInfo ) );
267   if( retval->mImpl->Initialise() )
268   {
269     return retval;
270   }
271   return nullptr;
272 }
273
274 DescriptorSetLayout::DescriptorSetLayout( Graphics& graphics, const vk::DescriptorSetLayoutCreateInfo& createInfo )
275 {
276   mImpl = MakeUnique<DescriptorSetLayout::Impl>( graphics, createInfo );
277 }
278 #endif
279 } // Namespace Vulkan
280
281 } // Namespace Graphics
282
283 } // Namespace Dali