60382d499712f6dc2097ff83ffdb242e59845b62
[platform/core/uifw/dali-core.git] / dali / graphics-api / graphics-api-render-command.h
1 #ifndef DALI_GRAPHICS_API_RENDER_COMMAND_H
2 #define DALI_GRAPHICS_API_RENDER_COMMAND_H
3
4 /*
5  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <tuple>
23 #include <utility>
24 #include <vector>
25
26 // INTERNAL INCLUDES
27 #include <dali/graphics-api/graphics-api-shader-details.h>
28 #include <dali/graphics-api/graphics-api-accessor.h>
29 #include <dali/graphics-api/graphics-api-framebuffer.h>
30 #include <dali/graphics-api/graphics-api-buffer.h>
31
32 namespace Dali
33 {
34 namespace Graphics
35 {
36 namespace API
37 {
38 class Shader;
39 class Texture;
40 class Buffer;
41 class Sampler;
42 class Pipeline;
43
44
45 /**
46  * @brief Interface class for RenderCommand types in the graphics API.
47  */
48 class RenderCommand
49 {
50 public:
51
52   static constexpr uint32_t BINDING_INDEX_DONT_CARE { 0xffffffff };
53
54   enum class InputAttributeRate
55   {
56     PER_VERTEX,
57     PER_INSTANCE
58   };
59
60   enum class IndexType
61   {
62     INDEX_TYPE_UINT16,
63     INDEX_TYPE_UINT32,
64   };
65
66   enum class DrawType
67   {
68     UNDEFINED_DRAW,
69     VERTEX_DRAW,
70     INDEXED_DRAW,
71   };
72
73   /**
74    * Describes buffer attribute binding
75    */
76   struct VertexAttributeBufferBinding
77   {
78     VertexAttributeBufferBinding() = default;
79
80     Accessor<Buffer> buffer{ nullptr };
81     uint32_t location { 0u };
82     uint32_t offset { 0u };
83     uint32_t stride { 0u };
84     InputAttributeRate rate { InputAttributeRate::PER_VERTEX };
85
86     uint32_t binding { 0u };
87     void*    pNext{ nullptr };
88
89     VertexAttributeBufferBinding& SetBuffer( Accessor<Buffer> value )
90     {
91       buffer = value;
92       return *this;
93     }
94     VertexAttributeBufferBinding& SetLocation( uint32_t value )
95     {
96       location = value;
97       return *this;
98     }
99     VertexAttributeBufferBinding& SetOffset( uint32_t value )
100     {
101       offset = value;
102       return *this;
103     }
104     VertexAttributeBufferBinding& SetStride( uint32_t value )
105     {
106       stride = value;
107       return *this;
108     }
109     VertexAttributeBufferBinding& SetBinding( uint32_t value )
110     {
111       binding = value;
112       return *this;
113     }
114     VertexAttributeBufferBinding& SetInputAttributeRate( InputAttributeRate value)
115     {
116       rate = value;
117       return *this;
118     }
119   };
120
121   /**
122    * Structure describes uniform buffer binding
123    */
124   struct UniformBufferBinding
125   {
126     UniformBufferBinding() :
127     buffer( nullptr ), offset( 0u ), dataSize( 0u ), binding( 0u ) {}
128     Accessor<Buffer> buffer;
129     uint32_t offset;
130     uint32_t dataSize;
131     uint32_t binding;
132     void*    pNext{ nullptr };
133
134     UniformBufferBinding& SetBuffer( Accessor<Buffer> value )
135     {
136       buffer = value;
137       return *this;
138     }
139     UniformBufferBinding& SetOffset( uint32_t value )
140     {
141       offset = value;
142       return *this;
143     }
144     UniformBufferBinding& SetDataSize( uint32_t value )
145     {
146       dataSize = value;
147       return *this;
148     }
149     UniformBufferBinding& SetBinding( uint32_t value )
150     {
151       binding = value;
152       return *this;
153     }
154   };
155
156   /**
157    *
158    */
159   struct TextureBinding
160   {
161     Accessor<Texture> texture;
162     Accessor<Sampler> sampler;
163     uint32_t binding;
164     void*    pNext{ nullptr };
165     TextureBinding() : texture(nullptr), sampler( nullptr ), binding( 0u ) {}
166
167     TextureBinding& SetTexture( Accessor<Texture> value )
168     {
169       texture = value;
170       return *this;
171     }
172     TextureBinding& SetSampler( Accessor<Sampler> value )
173     {
174       sampler = value;
175       return *this;
176     }
177     TextureBinding& SetBinding( uint32_t value )
178     {
179       binding = value;
180       return *this;
181     }
182   };
183
184   /**
185    *
186    */
187   struct SamplerBinding
188   {
189     Accessor<Sampler> sampler;
190     uint32_t binding;
191     void*    pNext{ nullptr };
192     SamplerBinding& SetSampler( Accessor<Sampler> value )
193     {
194       sampler = value;
195       return *this;
196     }
197     SamplerBinding& SetBinding( uint32_t value )
198     {
199       binding = value;
200       return *this;
201     }
202   };
203
204   /**
205    *
206    */
207   struct IndexBufferBinding
208   {
209     Accessor<Buffer> buffer { nullptr };
210     uint32_t offset { 0u };
211     IndexType type { IndexType::INDEX_TYPE_UINT16 };
212     void*    pNext{ nullptr };
213     IndexBufferBinding() = default;
214
215     IndexBufferBinding& SetBuffer( Accessor<Buffer> value )
216     {
217       buffer = value;
218       return *this;
219     }
220
221     IndexBufferBinding& SetOffset( uint32_t value )
222     {
223       offset = value;
224       return *this;
225     }
226
227     IndexBufferBinding& SetType( IndexType value )
228     {
229       type = value;
230       return *this;
231     }
232   };
233
234   struct RenderTargetBinding
235   {
236     Accessor<Framebuffer>                 framebuffer { nullptr };
237     std::vector<Framebuffer::ClearColor>  clearColors {};
238     Framebuffer::DepthStencilClearColor   dsClearColor {};
239     void*    pNext{ nullptr };
240     RenderTargetBinding() = default;
241
242     RenderTargetBinding& SetFramebuffer( Accessor<Framebuffer> value )
243     {
244       framebuffer = value;
245       return *this;
246     }
247
248     RenderTargetBinding& SetClearColors( std::vector<Framebuffer::ClearColor>&& value )
249     {
250       clearColors = value;
251       return *this;
252     }
253
254     RenderTargetBinding& SetFramebuffer( Framebuffer::DepthStencilClearColor value )
255     {
256       dsClearColor = value;
257       return *this;
258     }
259   };
260
261   struct DrawCommand
262   {
263     DrawCommand() :
264      drawType( DrawType::UNDEFINED_DRAW ){}
265     DrawType drawType;
266     union
267     {
268       uint32_t firstVertex;
269       uint32_t firstIndex;
270     };
271     union
272     {
273       uint32_t vertexCount;
274       uint32_t indicesCount;
275     };
276     uint32_t firstInstance;
277     uint32_t instanceCount;
278     void*    pNext{ nullptr };
279     DrawCommand& SetDrawType( DrawType value )
280     {
281       drawType = value;
282       return *this;
283     }
284     DrawCommand& SetFirstVertex( uint32_t value )
285     {
286       firstVertex = value;
287       return *this;
288     }
289     DrawCommand& SetFirstIndex( uint32_t value )
290     {
291       firstIndex = value;
292       return *this;
293     }
294     DrawCommand& SetVertexCount( uint32_t value )
295     {
296       vertexCount = value;
297       return *this;
298     }
299     DrawCommand& SetIndicesCount( uint32_t value )
300     {
301       indicesCount = value;
302       return *this;
303     }
304     DrawCommand& SetFirstInstance( uint32_t value )
305     {
306       firstInstance = value;
307       return *this;
308     }
309     DrawCommand& SetInstanceCount( uint32_t value )
310     {
311       instanceCount = value;
312       return *this;
313     }
314   };
315
316   /**
317    *
318    */
319   struct PushConstantsBinding
320   {
321     void*     data;
322     uint32_t  size;
323     uint32_t  binding;
324     void*    pNext{ nullptr };
325     PushConstantsBinding() = default;
326
327     PushConstantsBinding& SetData( void* value )
328     {
329       data = value;
330       return *this;
331     }
332     PushConstantsBinding& SetSize( uint32_t value )
333     {
334       size = value;
335       return *this;
336     }
337     PushConstantsBinding& SetBinding( uint32_t value )
338     {
339       binding = value;
340       return *this;
341     }
342   };
343
344   /**
345    *
346    */
347   struct RenderState
348   {
349     struct BlendState
350     {
351       bool blendingEnabled { false };
352     };
353
354     RenderState() = default;
355
356     Accessor<Shader> shader { nullptr };
357     BlendState blendState {};
358
359     RenderState& SetShader( Accessor<Shader> value )
360     {
361       shader = value;
362       return *this;
363     }
364
365     RenderState& SetBlendState( BlendState value )
366     {
367       blendState = value;
368       return *this;
369     }
370
371     void*    pNext{ nullptr };
372   };
373
374   RenderCommand()
375   : mVertexBufferBindings(),
376     mUniformBufferBindings(),
377     mTextureBindings(),
378     mIndexBufferBinding(),
379     mRenderTargetBinding(),
380     mDrawCommand(),
381     mPushConstantsBindings(),
382     mRenderState(),
383     mPipeline( nullptr )
384   {
385   }
386
387   // derived types should not be moved direcly to prevent slicing
388   RenderCommand( RenderCommand&& ) = default;
389   RenderCommand& operator=( RenderCommand&& ) = default;
390
391   // not copyable
392   RenderCommand( const RenderCommand& ) = delete;
393   RenderCommand& operator=( const RenderCommand& ) = delete;
394
395   virtual ~RenderCommand() = default;
396
397   /**
398    * Resource binding API
399    */
400   RenderCommand& BindVertexBuffers( std::vector<VertexAttributeBufferBinding>&& bindings )
401   {
402     mVertexBufferBindings = std::move( bindings );
403     return *this;
404   }
405
406   RenderCommand& BindUniformBuffers( std::vector<UniformBufferBinding>&& bindings )
407   {
408     mUniformBufferBindings = std::move( bindings );
409     return *this;
410   }
411
412   RenderCommand& BindTextures( std::vector<TextureBinding>&& bindings )
413   {
414     mTextureBindings = std::move( bindings );
415     return *this;
416   }
417
418   RenderCommand& BindSamplers( std::vector<SamplerBinding>&& bindings )
419   {
420     mSamplerBindings = std::move( bindings );
421     return *this;
422   }
423
424   RenderCommand& PushConstants( std::vector<PushConstantsBinding>&& bindings )
425   {
426     mPushConstantsBindings = bindings;
427     return *this;
428   }
429
430   RenderCommand& BindRenderState( RenderState& renderState )
431   {
432     mRenderState = renderState;
433     return *this;
434   }
435
436   RenderCommand& BindRenderTarget( const RenderTargetBinding& binding )
437   {
438     mRenderTargetBinding = binding;
439     return *this;
440   }
441
442   RenderCommand& BindRenderTarget( RenderTargetBinding&& binding )
443   {
444     mRenderTargetBinding = std::move(binding);
445     return *this;
446   }
447
448   RenderCommand& Draw( DrawCommand&& drawCommand )
449   {
450     mDrawCommand = drawCommand;
451     return *this;
452   }
453
454   RenderCommand& BindPipeline( const Accessor<Pipeline>& pipeline )
455   {
456     mPipeline = pipeline;
457     return *this;
458   }
459
460   static std::vector<VertexAttributeBufferBinding> NewVertexAttributeBufferBindings()
461   {
462     return std::vector<VertexAttributeBufferBinding>{};
463   }
464
465   /**
466    * Makes a copy ( or moves ) all bindings from the source array
467    * @param bindings
468    * @return
469    */
470   static std::vector<VertexAttributeBufferBinding> NewVertexAttributeBufferBindings( std::vector<VertexAttributeBufferBinding>&& bindings )
471   {
472     return std::vector<VertexAttributeBufferBinding>{ std::move(bindings) };
473   }
474
475   static std::vector<VertexAttributeBufferBinding> NewVertexAttributeBufferBindings( const std::vector<VertexAttributeBufferBinding>& bindings )
476   {
477     return std::vector<VertexAttributeBufferBinding>{ bindings };
478   }
479
480   static std::vector<TextureBinding> NewTextureBindings()
481   {
482     return std::vector<TextureBinding>{};
483   }
484
485   static std::vector<PushConstantsBinding> NewPushConstantsBindings( uint32_t count )
486   {
487     auto retval = std::vector<PushConstantsBinding>{};
488     retval.resize( count );
489     return retval;
490   }
491
492   // Getters
493   const std::vector<VertexAttributeBufferBinding>& GetVertexBufferBindings() const
494   {
495     return mVertexBufferBindings;
496   }
497
498   const auto& GetUniformBufferBindings() const
499   {
500     return mUniformBufferBindings;
501   }
502
503   const std::vector<TextureBinding>& GetTextureBindings() const
504   {
505     return mTextureBindings;
506   }
507
508   const auto& GetIndexBufferBinding() const
509   {
510     return mIndexBufferBinding;
511   }
512
513   const auto& GetRenderTargetBinding() const
514   {
515     return mRenderTargetBinding;
516   }
517
518   const DrawCommand& GetDrawCommand() const
519   {
520     return mDrawCommand;
521   }
522
523   const std::vector<PushConstantsBinding>& GetPushConstantsBindings() const
524   {
525     return mPushConstantsBindings;
526   }
527
528   const RenderState& GetRenderState() const
529   {
530     return mRenderState;
531   }
532
533   Accessor<Pipeline> GetPipeline() const
534   {
535     return mPipeline;
536   }
537
538 protected:
539
540   std::vector<VertexAttributeBufferBinding> mVertexBufferBindings;
541   std::vector<UniformBufferBinding>         mUniformBufferBindings;
542   std::vector<TextureBinding>               mTextureBindings;
543   std::vector<SamplerBinding>               mSamplerBindings;
544   IndexBufferBinding                        mIndexBufferBinding;
545   RenderTargetBinding                       mRenderTargetBinding;
546   DrawCommand                               mDrawCommand;
547   std::vector<PushConstantsBinding>         mPushConstantsBindings;
548   RenderState                               mRenderState;
549   Accessor<Pipeline>                        mPipeline;
550
551 };
552
553 } // namespace API
554 } // namespace Graphics
555 } // namespace Dali
556
557 #endif // DALI_GRAPHICS_API_RENDER_COMMAND_H
558
559
560 /**
561  * @brief Interface class for RenderCommand types in the graphics API.
562  *
563  * @startuml
564  *
565  * skinparam defaultFontName Ubuntu Mono
566  * class RenderCommand {
567  *  -- protected --
568  *  #VertexAttributeBufferBinding[]  mVertexBufferBindings
569  *  #UniformBufferBinding[]          mUniformBufferBindings
570  *  #TextureBinding[]                mTextureBindings
571  *  #SamplerBinding[]                mSamplerBindings
572  *  #IndexBufferBinding              mIndexBufferBinding
573  *  #RenderTargetBinding             mRenderTargetBinding
574  *  #DrawCommand                     mDrawCommand
575  *  #PushConstantsBinding[]          mPushConstantsBindings
576  *  #RenderState                     mRenderState
577  *
578  * -- public API --
579  *  +RenderCommand& BindVertextBuffers()
580  *  +RenderCommand& BindUniformBuffers()
581  *  +RenderCommand& BindTextures()
582  *  +RenderCommand& BindSamplers()
583  *  +RenderCommand& PushConstants()
584  *  +RenderCommand& BindRenderState()
585  *  +RenderCommand& Draw()
586  *  -- static API ( helper functions )--
587  *  {static} NewVertexAttributeBufferBindings()
588  *  {static} NewVertexAttributeBufferBindings()
589  *  {static} NewVertexAttributeBufferBindings()
590  *  {static} NewTextureBindings()
591  *  {static} NewPushConstantsBindings()
592  * }
593  *
594  * class VertexAttributeBufferBinding {
595  * Accessor<Buffer>   buffer
596  * uint32_t           location
597  * uint32_t           offset
598  * uint32_t           stride
599  * InputAttributeRate rate
600  * void*              pNext
601  * }
602  *
603  * class UniformBufferBinding {
604  *   #Accessor<Buffer> buffer
605  *   #uint32_t         offset
606  *   #uint32_t         dataSize
607  *   #uint32_t         binding
608  *   #void*            pNext
609  * }
610  *
611   class IndexBufferBinding {
612     #Accessor<Buffer> buffer
613     #uint32_t         offset
614     #IndexType        type
615     #void*            pNext
616   }
617
618   class RenderTargetBinding {
619     #Accessor<Framebuffer>                 framebuffer
620     #std::vector<Framebuffer::ClearColor>  clearColors
621     #Framebuffer::DepthStencilClearColor   dsClearColor
622     #void*                                 pNext
623   }
624
625   class DrawCommand {
626       #DrawType drawType;
627       #uint32_t firstVertex
628       #uint32_t firstIndex
629       #uint32_t vertexCount
630       #uint32_t indicesCount
631       #uint32_t firstInstance
632       #uint32_t instanceCount
633       #void*    pNext
634   }
635
636   class PushConstantsBinding {
637     #void*     data
638     #uint32_t  size
639     #uint32_t  binding
640     #void*    pNext
641   }
642
643   class RenderState {
644     #Accessor<Shader> shader
645     #void*    pNext
646   }
647
648   class TextureBinding {
649     #Accessor<Texture> texture
650     #Accessor<Sampler> sampler
651     #uint32_t          binding
652     #void*             pNext
653   }
654
655   class SamplerBinding {
656     #Accessor<Sampler> sampler
657     #uint32_t binding
658     #void*    pNext
659   }
660
661  note as RenderStateWIP
662  Other render states like
663  blending etc. should be added
664  as public fields of this structure.
665  end note
666
667  RenderStateWIP .. RenderState
668
669  * note as N1
670  * Each state is described as POD
671  * structure which is a Vulkan
672  * approach.
673  * end note
674  *
675  * note as N2
676  * Field pNext may be used by the
677  * implementation to pass additional
678  * data.
679  * end note
680  *
681  * N2 .. VertexAttributeBufferBinding::pNext
682  * N1 .. VertexAttributeBufferBinding
683  * N1 .. UniformBufferBinding
684  * N1 .. IndexBufferBinding
685  * N1 .. RenderTargetBinding
686  *
687
688  *
689  * RenderCommand *-right- VertexAttributeBufferBinding
690  * RenderCommand *-right- UniformBufferBinding
691  * RenderCommand *-left- IndexBufferBinding
692  * RenderCommand *-left- RenderTargetBinding
693  * RenderCommand *-up- RenderState
694  * RenderCommand *-up- DrawCommand
695  * RenderCommand *-down- PushConstantsBinding
696  * RenderCommand *-down- SamplerBinding
697  * RenderCommand *-down- TextureBinding
698  * @enduml
699  */