LiteFX 0.4.1.2025
Computer Graphics Engine
Loading...
Searching...
No Matches
rendering_builders.hpp
1#pragma once
2
3#include "rendering_api.hpp"
4#include "rendering.hpp"
5
6#if defined(LITEFX_BUILD_DEFINE_BUILDERS)
7namespace LiteFX::Rendering {
8
15 template <typename TBarrier> requires
16 meta::implements<TBarrier, Barrier<typename TBarrier::buffer_type, typename TBarrier::image_type>>
17 class BarrierBuilder : public Builder<TBarrier> {
18 public:
19 template <typename TParent> requires
20 meta::implements<TParent, BarrierBuilder<TBarrier>>
21 struct [[nodiscard]] ImageBarrierBuilder;
22
27 template <typename TParent> requires
28 meta::implements<TParent, BarrierBuilder<TBarrier>>
29 struct [[nodiscard]] SecondStageBuilder {
30 private:
31 TParent m_parent;
32 PipelineStage m_from;
33
39 constexpr SecondStageBuilder(TParent&& parent, PipelineStage waitFor) noexcept :
40 m_parent(std::move(parent)), m_from(waitFor) { }
41
42 public:
43 friend class BarrierBuilder;
44
50 constexpr auto toContinueWith(PipelineStage stage) -> TParent {
51 this->m_parent.stagesCallback(this->m_from, stage);
52 return std::move(this->m_parent);
53 }
54 };
55
60 template <typename TParent> requires
61 meta::implements<TParent, BarrierBuilder<TBarrier>>
62 struct [[nodiscard]] GlobalBarrierBuilder {
63 private:
64 ResourceAccess m_access;
65 TParent m_parent;
66
72 constexpr GlobalBarrierBuilder(TParent&& parent, ResourceAccess access) noexcept :
73 m_parent(std::move(parent)), m_access(access) { }
74
75 public:
76 friend class BarrierBuilder;
77
82 constexpr auto untilFinishedWith(ResourceAccess access) -> TParent {
83 this->m_parent.globalBarrierCallback(access, m_access);
84 return std::move(this->m_parent);
85 }
86 };
87
92 template <typename TParent> requires
93 meta::implements<TParent, BarrierBuilder<TBarrier>>
94 struct [[nodiscard]] BufferBarrierBuilder {
95 private:
96 ResourceAccess m_access;
97 SharedPtr<IBuffer> m_buffer;
98 TParent m_parent;
99
106 constexpr BufferBarrierBuilder(TParent&& parent, IBuffer& buffer, ResourceAccess access) noexcept :
107 m_parent(std::move(parent)), m_buffer(buffer.shared_from_this()), m_access(access) { }
108
109 public:
110 friend class BarrierBuilder;
111
116 constexpr auto untilFinishedWith(ResourceAccess access) -> TParent {
117 this->m_parent.bufferBarrierCallback(*m_buffer, access, m_access);
118 return std::move(this->m_parent);
119 }
120 };
121
126 template <typename TParent> requires
127 meta::implements<TParent, BarrierBuilder<TBarrier>>
128 struct [[nodiscard]] ImageLayoutBarrierBuilder {
129 private:
130 TParent m_parent;
131 ResourceAccess m_access;
132 SharedPtr<IImage> m_image;
133 ImageLayout m_layout;
134 UInt32 m_level{ 0 }, m_levels{ 1 }, m_layer{ 0 }, m_layers{ 1 }, m_plane{ 0 };
135
148 constexpr ImageLayoutBarrierBuilder(TParent&& parent, IImage& image, ResourceAccess access, ImageLayout layout, UInt32 level, UInt32 levels, UInt32 layer, UInt32 layers, UInt32 plane) noexcept :
149 m_parent(std::move(parent)), m_access(access), m_image(image.shared_from_this()), m_layout(layout), m_level(level), m_levels(levels), m_layer(layer), m_layers(layers), m_plane(plane) { }
150
151 public:
152 friend class BarrierBuilder;
153 friend struct ImageBarrierBuilder<TParent>;
154
159 constexpr auto whenFinishedWith(ResourceAccess access) -> TParent {
160 this->m_parent.imageBarrierCallback(*m_image, access, m_access, m_layout, m_level, m_levels, m_layer, m_layers, m_plane);
161 return std::move(this->m_parent);
162 }
163 };
164
169 template <typename TParent> requires
170 meta::implements<TParent, BarrierBuilder<TBarrier>>
171 struct [[nodiscard]] ImageBarrierBuilder {
172 private:
173 TParent m_parent;
174 ResourceAccess m_access;
175 SharedPtr<IImage> m_image;
176 UInt32 m_level{ 0 }, m_levels{ 0 }, m_layer{ 0 }, m_layers{ 0 }, m_plane{ 0 };
177
184 constexpr ImageBarrierBuilder(TParent&& parent, IImage& image, ResourceAccess access) noexcept :
185 m_parent(std::move(parent)), m_access(access), m_image(image.shared_from_this()) { }
186
187 public:
188 friend class BarrierBuilder;
189
194 constexpr auto transitionLayout(ImageLayout layout) -> ImageLayoutBarrierBuilder<TParent> {
195 return ImageLayoutBarrierBuilder<TParent>{ std::move(m_parent), *m_image, m_access, layout, m_level, m_levels, m_layer, m_layers, m_plane };
196 }
197
206 constexpr auto subresource(UInt32 level, UInt32 levels, UInt32 layer = 0, UInt32 layers = 1, UInt32 plane = 0) -> ImageBarrierBuilder<TParent>& {
207 m_level = level;
208 m_levels = levels;
209 m_layer = layer;
210 m_layers = layers;
211 m_plane = plane;
212
213 return *this;
214 };
215 };
216
217 private:
223 constexpr void stagesCallback(PipelineStage waitFor, PipelineStage continueWith) {
224 this->setupStages(waitFor, continueWith);
225 }
226
232 constexpr void globalBarrierCallback(ResourceAccess before, ResourceAccess after) {
233 this->setupGlobalBarrier(before, after);
234 }
235
242 constexpr void bufferBarrierCallback(IBuffer& buffer, ResourceAccess before, ResourceAccess after) {
243 this->setupBufferBarrier(buffer, before, after);
244 }
245
258 constexpr void imageBarrierCallback(IImage& image, ResourceAccess before, ResourceAccess after, ImageLayout layout, UInt32 level, UInt32 levels, UInt32 layer, UInt32 layers, UInt32 plane) {
259 this->setupImageBarrier(image, before, after, layout, level, levels, layer, layers, plane);
260 }
261
262 protected:
268 constexpr virtual void setupStages(PipelineStage waitFor, PipelineStage continueWith) = 0;
269
275 constexpr virtual void setupGlobalBarrier(ResourceAccess before, ResourceAccess after) = 0;
276
283 constexpr virtual void setupBufferBarrier(IBuffer& buffer, ResourceAccess before, ResourceAccess after) = 0;
284
297 constexpr virtual void setupImageBarrier(IImage& image, ResourceAccess before, ResourceAccess after, ImageLayout layout, UInt32 level, UInt32 levels, UInt32 layer, UInt32 layers, UInt32 plane) = 0;
298
299 public:
300 using Builder<TBarrier>::Builder;
301 using barrier_type = TBarrier;
302
303 public:
308 template <typename TSelf>
309 [[nodiscard]] constexpr auto waitFor(this TSelf&& self, PipelineStage stage) -> SecondStageBuilder<TSelf> {
310 return SecondStageBuilder<TSelf>{ std::forward<TSelf>(self), stage };
311 }
312
317 template <typename TSelf>
318 [[nodiscard]] constexpr auto blockAccessTo(this TSelf&& self, ResourceAccess access) -> GlobalBarrierBuilder<TSelf> {
319 return GlobalBarrierBuilder<TSelf>{ std::forward<TSelf>(self), access };
320 }
321
327 template <typename TSelf>
328 [[nodiscard]] constexpr auto blockAccessTo(this TSelf&& self, IBuffer& buffer, ResourceAccess access) -> BufferBarrierBuilder<TSelf> {
329 return BufferBarrierBuilder<TSelf>{ std::forward<TSelf>(self), buffer, access };
330 }
331
338 template <typename TSelf>
339 [[nodiscard]] constexpr auto blockAccessTo(this TSelf&& self, IBuffer& buffer, UInt32 subresource, ResourceAccess access) -> BufferBarrierBuilder<TSelf> {
340 return BufferBarrierBuilder<TSelf>{ std::forward<TSelf>(self), buffer, subresource, access };
341 }
342
348 template <typename TSelf>
349 [[nodiscard]] constexpr auto blockAccessTo(this TSelf&& self, IImage& image, ResourceAccess access) -> ImageBarrierBuilder<TSelf> {
350 return ImageBarrierBuilder<TSelf>{ std::forward<TSelf>(self), image, access };
351 }
352 };
353
359 template <typename TShaderProgram> requires
360 meta::implements<TShaderProgram, ShaderProgram<typename TShaderProgram::shader_module_type>>
361 class ShaderProgramBuilder : public Builder<TShaderProgram, std::nullptr_t, SharedPtr<TShaderProgram>> {
362 public:
363 using Builder<TShaderProgram, std::nullptr_t, SharedPtr<TShaderProgram>>::Builder;
364 using shader_program_type = TShaderProgram;
365 using shader_module_type = shader_program_type::shader_module_type;
366
367 private:
371 struct ShaderProgramState {
376 } m_state;
377
378 protected:
383 inline ShaderProgramState& state() noexcept {
384 return m_state;
385 }
386
395 constexpr virtual UniquePtr<shader_module_type> makeShaderModule(ShaderStage type, const String& fileName, const String& entryPoint, const Optional<DescriptorBindingPoint>& shaderLocalDescriptor) = 0;
396
406 constexpr virtual UniquePtr<shader_module_type> makeShaderModule(ShaderStage type, std::istream& stream, const String& name, const String& entryPoint, const Optional<DescriptorBindingPoint>& shaderLocalDescriptor) = 0;
407
408 public:
416 template<typename TSelf>
417 [[nodiscard]] constexpr auto withShaderModule(this TSelf&& self, ShaderStage type, const String& fileName, const String& entryPoint = "main", const Optional<DescriptorBindingPoint>& shaderLocalDescriptor = std::nullopt) -> TSelf&& {
418 self.m_state.modules.push_back(std::move(static_cast<ShaderProgramBuilder&>(self).makeShaderModule(type, fileName, entryPoint, shaderLocalDescriptor)));
419 return std::forward<TSelf>(self);
420 }
421
430 template<typename TSelf>
431 [[nodiscard]] constexpr auto withShaderModule(this TSelf&& self, ShaderStage type, std::istream& stream, const String& name, const String& entryPoint = "main", const Optional<DescriptorBindingPoint>& shaderLocalDescriptor = std::nullopt) -> TSelf&& {
432 self.m_state.modules.push_back(std::move(static_cast<ShaderProgramBuilder&>(self).makeShaderModule(type, stream, name, entryPoint, shaderLocalDescriptor)));
433 return std::forward<TSelf>(self);
434 }
435
441 template<typename TSelf>
442 [[nodiscard]] constexpr auto withVertexShaderModule(this TSelf&& self, const String& fileName, const String& entryPoint = "main") -> TSelf&& {
443 return std::forward<TSelf>(self).withShaderModule(ShaderStage::Vertex, fileName, entryPoint);
444 }
445
452 template<typename TSelf>
453 [[nodiscard]] constexpr auto withVertexShaderModule(this TSelf&& self, std::istream& stream, const String& name, const String& entryPoint = "main") -> TSelf&& {
454 return std::forward<TSelf>(self).withShaderModule(ShaderStage::Vertex, stream, name, entryPoint);
455 }
456
465 template<typename TSelf>
466 [[nodiscard]] constexpr auto withTaskShaderModule(this TSelf&& self, const String& fileName, const String& entryPoint = "main") -> TSelf&& {
467 return std::forward<TSelf>(self).withShaderModule(ShaderStage::Task, fileName, entryPoint);
468 }
478 template<typename TSelf>
479 [[nodiscard]] constexpr auto withTaskShaderModule(this TSelf&& self, std::istream& stream, const String& name, const String& entryPoint = "main") -> TSelf&& {
480 return std::forward<TSelf>(self).withShaderModule(ShaderStage::Task, stream, name, entryPoint);
481 }
482
491 template<typename TSelf>
492 [[nodiscard]] constexpr auto withMeshShaderModule(this TSelf&& self, const String& fileName, const String& entryPoint = "main") -> TSelf&& {
493 return std::forward<TSelf>(self).withShaderModule(ShaderStage::Mesh, fileName, entryPoint);
494 }
495
505 template<typename TSelf>
506 [[nodiscard]] constexpr auto withMeshShaderModule(this TSelf&& self, std::istream& stream, const String& name, const String& entryPoint = "main") -> TSelf&& {
507 return std::forward<TSelf>(self).withShaderModule(ShaderStage::Mesh, stream, name, entryPoint);
508 }
509
515 template<typename TSelf>
516 [[nodiscard]] constexpr auto withTessellationControlShaderModule(this TSelf&& self, const String& fileName, const String& entryPoint = "main") -> TSelf&& {
517 return std::forward<TSelf>(self).withShaderModule(ShaderStage::TessellationControl, fileName, entryPoint);
518 }
519
526 template<typename TSelf>
527 [[nodiscard]] constexpr auto withTessellationControlShaderModule(this TSelf&& self, std::istream& stream, const String& name, const String& entryPoint = "main") -> TSelf&& {
528 return std::forward<TSelf>(self).withShaderModule(ShaderStage::TessellationControl, stream, name, entryPoint);
529 }
530
536 template<typename TSelf>
537 [[nodiscard]] constexpr auto withTessellationEvaluationShaderModule(this TSelf&& self, const String& fileName, const String& entryPoint = "main") -> TSelf&& {
538 return std::forward<TSelf>(self).withShaderModule(ShaderStage::TessellationEvaluation, fileName, entryPoint);
539 }
540
547 template<typename TSelf>
548 [[nodiscard]] constexpr auto withTessellationEvaluationShaderModule(this TSelf&& self, std::istream& stream, const String& name, const String& entryPoint = "main") -> TSelf&& {
549 return std::forward<TSelf>(self).withShaderModule(ShaderStage::TessellationEvaluation, stream, name, entryPoint);
550 }
551
557 template<typename TSelf>
558 [[nodiscard]] constexpr auto withGeometryShaderModule(this TSelf&& self, const String& fileName, const String& entryPoint = "main") -> TSelf&& {
559 return std::forward<TSelf>(self).withShaderModule(ShaderStage::Geometry, fileName, entryPoint);
560 }
561
568 template<typename TSelf>
569 [[nodiscard]] constexpr auto withGeometryShaderModule(this TSelf&& self, std::istream& stream, const String& name, const String& entryPoint = "main") -> TSelf&& {
570 return std::forward<TSelf>(self).withShaderModule(ShaderStage::Geometry, stream, name, entryPoint);
571 }
572
578 template<typename TSelf>
579 [[nodiscard]] constexpr auto withFragmentShaderModule(this TSelf&& self, const String& fileName, const String& entryPoint = "main") -> TSelf&& {
580 return std::forward<TSelf>(self).withShaderModule(ShaderStage::Fragment, fileName, entryPoint);
581 }
582
589 template<typename TSelf>
590 [[nodiscard]] constexpr auto withFragmentShaderModule(this TSelf&& self, std::istream& stream, const String& name, const String& entryPoint = "main") -> TSelf&& {
591 return std::forward<TSelf>(self).withShaderModule(ShaderStage::Fragment, stream, name, entryPoint);
592 }
593
599 template<typename TSelf>
600 [[nodiscard]] constexpr auto withComputeShaderModule(this TSelf&& self, const String& fileName, const String& entryPoint = "main") -> TSelf&& {
601 return std::forward<TSelf>(self).withShaderModule(ShaderStage::Compute, fileName, entryPoint);
602 }
603
610 template<typename TSelf>
611 [[nodiscard]] constexpr auto withComputeShaderModule(this TSelf&& self, std::istream& stream, const String& name, const String& entryPoint = "main") -> TSelf&& {
612 return std::forward<TSelf>(self).withShaderModule(ShaderStage::Compute, stream, name, entryPoint);
613 }
614
624 template<typename TSelf>
625 [[nodiscard]] constexpr auto withRayGenerationShaderModule(this TSelf&& self, const String& fileName, const Optional<DescriptorBindingPoint>& shaderLocalDescriptor = std::nullopt, const String& entryPoint = "main") -> TSelf&& {
626 return std::forward<TSelf>(self).withShaderModule(ShaderStage::RayGeneration, fileName, entryPoint, shaderLocalDescriptor);
627 }
628
639 template<typename TSelf>
640 [[nodiscard]] constexpr auto withRayGenerationShaderModule(this TSelf&& self, std::istream& stream, const String& name, const Optional<DescriptorBindingPoint>& shaderLocalDescriptor = std::nullopt, const String& entryPoint = "main") -> TSelf&& {
641 return std::forward<TSelf>(self).withShaderModule(ShaderStage::RayGeneration, stream, name, entryPoint, shaderLocalDescriptor);
642 }
643
653 template<typename TSelf>
654 [[nodiscard]] constexpr auto withMissShaderModule(this TSelf&& self, const String& fileName, const Optional<DescriptorBindingPoint>& shaderLocalDescriptor = std::nullopt, const String& entryPoint = "main") -> TSelf&& {
655 return std::forward<TSelf>(self).withShaderModule(ShaderStage::Miss, fileName, entryPoint, shaderLocalDescriptor);
656 }
657
668 template<typename TSelf>
669 [[nodiscard]] constexpr auto withMissShaderModule(this TSelf&& self, std::istream& stream, const String& name, const Optional<DescriptorBindingPoint>& shaderLocalDescriptor = std::nullopt, const String& entryPoint = "main") -> TSelf&& {
670 return std::forward<TSelf>(self).withShaderModule(ShaderStage::Miss, stream, name, entryPoint, shaderLocalDescriptor);
671 }
672
682 template<typename TSelf>
683 [[nodiscard]] constexpr auto withCallableShaderModule(this TSelf&& self, const String& fileName, const Optional<DescriptorBindingPoint>& shaderLocalDescriptor = std::nullopt, const String& entryPoint = "main") -> TSelf&& {
684 return std::forward<TSelf>(self).withShaderModule(ShaderStage::Callable, fileName, entryPoint, shaderLocalDescriptor);
685 }
686
697 template<typename TSelf>
698 [[nodiscard]] constexpr auto withCallableShaderModule(this TSelf&& self, std::istream& stream, const String& name, const Optional<DescriptorBindingPoint>& shaderLocalDescriptor = std::nullopt, const String& entryPoint = "main") -> TSelf&& {
699 return std::forward<TSelf>(self).withShaderModule(ShaderStage::Callable, stream, name, entryPoint, shaderLocalDescriptor);
700 }
701
710 template<typename TSelf>
711 [[nodiscard]] constexpr auto withIntersectionShaderModule(this TSelf&& self, const String& fileName, const Optional<DescriptorBindingPoint>& shaderLocalDescriptor = std::nullopt, const String& entryPoint = "main") -> TSelf&& {
712 return std::forward<TSelf>(self).withShaderModule(ShaderStage::Intersection, fileName, entryPoint, shaderLocalDescriptor);
713 }
714
725 template<typename TSelf>
726 [[nodiscard]] constexpr auto withIntersectionShaderModule(this TSelf&& self, std::istream& stream, const String& name, const Optional<DescriptorBindingPoint>& shaderLocalDescriptor = std::nullopt, const String& entryPoint = "main") -> TSelf&& {
727 return std::forward<TSelf>(self).withShaderModule(ShaderStage::Intersection, stream, name, entryPoint, shaderLocalDescriptor);
728 }
729
739 template<typename TSelf>
740 [[nodiscard]] constexpr auto withAnyHitShaderModule(this TSelf&& self, const String& fileName, const Optional<DescriptorBindingPoint>& shaderLocalDescriptor = std::nullopt, const String& entryPoint = "main") -> TSelf&& {
741 return std::forward<TSelf>(self).withShaderModule(ShaderStage::AnyHit, fileName, entryPoint, shaderLocalDescriptor);
742 }
743
754 template<typename TSelf>
755 [[nodiscard]] constexpr auto withAnyHitShaderModule(this TSelf&& self, std::istream& stream, const String& name, const Optional<DescriptorBindingPoint>& shaderLocalDescriptor = std::nullopt, const String& entryPoint = "main") -> TSelf&& {
756 return std::forward<TSelf>(self).withShaderModule(ShaderStage::AnyHit, stream, name, entryPoint, shaderLocalDescriptor);
757 }
758
768 template<typename TSelf>
769 [[nodiscard]] constexpr auto withClosestHitShaderModule(this TSelf&& self, const String& fileName, const Optional<DescriptorBindingPoint>& shaderLocalDescriptor = std::nullopt, const String& entryPoint = "main") -> TSelf&& {
770 return std::forward<TSelf>(self).withShaderModule(ShaderStage::ClosestHit, fileName, entryPoint, shaderLocalDescriptor);
771 }
772
783 template<typename TSelf>
784 [[nodiscard]] constexpr auto withClosestHitShaderModule(this TSelf&& self, std::istream& stream, const String& name, const Optional<DescriptorBindingPoint>& shaderLocalDescriptor = std::nullopt, const String& entryPoint = "main") -> TSelf&& {
785 return std::forward<TSelf>(self).withShaderModule(ShaderStage::ClosestHit, stream, name, entryPoint, shaderLocalDescriptor);
786 }
787 };
788
794 template <typename TRasterizer> requires
795 meta::implements<TRasterizer, IRasterizer>
796 class RasterizerBuilder : public Builder<TRasterizer, std::nullptr_t, SharedPtr<TRasterizer>> {
797 public:
798 using Builder<TRasterizer, std::nullptr_t, SharedPtr<TRasterizer>>::Builder;
799 using rasterizer_type = TRasterizer;
800
801 private:
805 struct RasterizerState {
809 PolygonMode polygonMode{ PolygonMode::Solid };
810
814 CullMode cullMode{ CullMode::BackFaces };
815
819 CullOrder cullOrder{ CullOrder::ClockWise };
820
824 Float lineWidth{ 1.0f };
825
829 DepthStencilState::DepthBias depthBias{ };
830
834 DepthStencilState::DepthState depthState{ };
835
839 DepthStencilState::StencilState stencilState{ };
840 } m_state;
841
842 protected:
847 inline RasterizerState& state() noexcept {
848 return m_state;
849 }
850
851 public:
856 template<typename TSelf>
857 [[nodiscard]] constexpr auto polygonMode(this TSelf&& self, PolygonMode mode) noexcept -> TSelf&& {
858 self.m_state.polygonMode = mode;
859 return std::forward<TSelf>(self);
860 }
861
866 template<typename TSelf>
867 [[nodiscard]] constexpr auto cullMode(this TSelf&& self, CullMode mode) noexcept -> TSelf&& {
868 self.m_state.cullMode = mode;
869 return std::forward<TSelf>(self);
870 }
871
876 template<typename TSelf>
877 [[nodiscard]] constexpr auto cullOrder(this TSelf&& self, CullOrder order) noexcept -> TSelf&& {
878 self.m_state.cullOrder = order;
879 return std::forward<TSelf>(self);
880 }
881
886 template<typename TSelf>
887 [[nodiscard]] constexpr auto lineWidth(this TSelf&& self, Float width) noexcept -> TSelf&& {
888 self.m_state.lineWidth = width;
889 return std::forward<TSelf>(self);
890 }
891
896 template<typename TSelf>
897 [[nodiscard]] constexpr auto depthBias(this TSelf&& self, const DepthStencilState::DepthBias& depthBias) noexcept -> TSelf&& {
898 self.m_state.depthBias = depthBias;
899 return std::forward<TSelf>(self);
900 }
901
906 template<typename TSelf>
907 [[nodiscard]] constexpr auto depthState(this TSelf&& self, const DepthStencilState::DepthState& depthState) noexcept -> TSelf&& {
908 self.m_state.depthState = depthState;
909 return std::forward<TSelf>(self);
910 }
911
916 template<typename TSelf>
917 [[nodiscard]] constexpr auto stencilState(this TSelf&& self, const DepthStencilState::StencilState& stencilState) noexcept -> TSelf&& {
918 self.m_state.stencilState = stencilState;
919 return std::forward<TSelf>(self);
920 }
921 };
922
928 template <typename TVertexBufferLayout, typename TParent> requires
929 meta::implements<TVertexBufferLayout, IVertexBufferLayout>
930 class VertexBufferLayoutBuilder : public Builder<TVertexBufferLayout, TParent, SharedPtr<TVertexBufferLayout>> {
931 public:
932 using Builder<TVertexBufferLayout, TParent, SharedPtr<TVertexBufferLayout>>::Builder;
933 using vertex_buffer_layout_type = TVertexBufferLayout;
934
935 private:
939 struct VertexBufferLayoutState {
943 Array<BufferAttribute> attributes{ };
944 } m_state;
945
946 protected:
951 inline VertexBufferLayoutState& state() noexcept {
952 return m_state;
953 }
954
955 public:
960 template <typename TSelf>
961 [[nodiscard]] constexpr auto withAttribute(this TSelf&& self, BufferAttribute&& attribute) -> TSelf&& {
962 self.m_state.attributes.push_back(std::move(attribute));
963 return std::forward<TSelf>(self);
964 }
965
976 template <typename TSelf>
977 [[nodiscard]] constexpr auto withAttribute(this TSelf&& self, BufferFormat format, UInt32 offset, AttributeSemantic semantic = AttributeSemantic::Unknown, UInt32 semanticIndex = 0) -> TSelf&& {
978 return std::forward<TSelf>(self).withAttribute({ static_cast<UInt32>(self.m_state.attributes.size()), offset, format, semantic, semanticIndex });
979 }
980
989 template <typename TSelf>
990 [[nodiscard]] constexpr auto withAttribute(this TSelf&& self, UInt32 location, BufferFormat format, UInt32 offset, AttributeSemantic semantic = AttributeSemantic::Unknown, UInt32 semanticIndex = 0) -> TSelf&& {
991 return std::forward<TSelf>(self).withAttribute({ location, offset, format, semantic, semanticIndex });
992 }
993 };
994
1001 template <typename TDescriptorSetLayout, typename TParent> requires
1002 meta::implements<TDescriptorSetLayout, DescriptorSetLayout<typename TDescriptorSetLayout::descriptor_layout_type, typename TDescriptorSetLayout::descriptor_set_type>>
1003 class DescriptorSetLayoutBuilder : public Builder<TDescriptorSetLayout, TParent, SharedPtr<TDescriptorSetLayout>> {
1004 public:
1005 using Builder<TDescriptorSetLayout, TParent, SharedPtr<TDescriptorSetLayout>>::Builder;
1006 using descriptor_set_layout_type = TDescriptorSetLayout;
1007 using descriptor_layout_type = descriptor_set_layout_type::descriptor_layout_type;
1008 using descriptor_set_type = descriptor_set_layout_type::descriptor_set_type;
1009
1010 private:
1014 struct DescriptorSetLayoutState {
1018 UInt32 space{};
1019
1023 ShaderStage stages{};
1024
1028 Array<descriptor_layout_type> descriptorLayouts{};
1029 } m_state;
1030
1031 protected:
1036 inline DescriptorSetLayoutState& state() noexcept {
1037 return m_state;
1038 }
1039
1048 constexpr virtual descriptor_layout_type makeDescriptor(DescriptorType type, UInt32 binding, UInt32 descriptorSize, UInt32 descriptors) = 0;
1049
1065 constexpr virtual descriptor_layout_type makeDescriptor(UInt32 binding, FilterMode magFilter, FilterMode minFilter, BorderMode borderU, BorderMode borderV, BorderMode borderW, MipMapMode mipMapMode, Float mipMapBias, Float minLod, Float maxLod, Float anisotropy) = 0;
1066
1067 public:
1072 template <typename TSelf>
1073 [[nodiscard]] constexpr auto withDescriptor(this TSelf&& self, descriptor_layout_type&& layout) -> TSelf&& {
1074 self.m_state.descriptorLayouts.push_back(std::move(layout));
1075 return std::forward<TSelf>(self);
1076 }
1077
1085 template <typename TSelf>
1086 [[nodiscard]] constexpr auto withDescriptor(this TSelf&& self, DescriptorType type, UInt32 binding, UInt32 descriptorSize, UInt32 descriptors = 1) -> TSelf&& {
1087 self.m_state.descriptorLayouts.push_back(std::move(static_cast<DescriptorSetLayoutBuilder&>(self).makeDescriptor(type, binding, descriptorSize, descriptors)));
1088 return std::forward<TSelf>(self);
1089 }
1090
1105 template <typename TSelf>
1106 [[nodiscard]] constexpr auto withStaticSampler(this TSelf&& self, UInt32 binding, FilterMode magFilter = FilterMode::Nearest, FilterMode minFilter = FilterMode::Nearest, BorderMode borderU = BorderMode::Repeat, BorderMode borderV = BorderMode::Repeat, BorderMode borderW = BorderMode::Repeat, MipMapMode mipMapMode = MipMapMode::Nearest, Float mipMapBias = 0.f, Float minLod = 0.f, Float maxLod = std::numeric_limits<Float>::max(), Float anisotropy = 0.f) -> TSelf&& {
1107 self.m_state.descriptorLayouts.push_back(std::move(static_cast<DescriptorSetLayoutBuilder&>(self).makeDescriptor(binding, magFilter, minFilter, borderU, borderV, borderW, mipMapMode, mipMapBias, minLod, maxLod, anisotropy)));
1108 return std::forward<TSelf>(self);
1109 }
1110
1117 template <typename TSelf>
1118 [[nodiscard]] constexpr auto withConstantBuffer(this TSelf&& self, UInt32 binding, UInt32 descriptorSize, UInt32 descriptors = 1) -> TSelf&& {
1119 self.m_state.descriptorLayouts.push_back(std::move(static_cast<DescriptorSetLayoutBuilder&>(self).makeDescriptor(DescriptorType::ConstantBuffer, binding, descriptorSize, descriptors)));
1120 return std::forward<TSelf>(self);
1121 }
1122
1129 template <typename TSelf>
1130 [[nodiscard]] constexpr auto withBuffer(this TSelf&& self, UInt32 binding, UInt32 descriptors = 1, bool writable = false) -> TSelf&& {
1131 self.m_state.descriptorLayouts.push_back(std::move(static_cast<DescriptorSetLayoutBuilder&>(self).makeDescriptor(writable ? DescriptorType::RWBuffer : DescriptorType::Buffer, binding, 0, descriptors)));
1132 return std::forward<TSelf>(self);
1133 }
1134
1141 template <typename TSelf>
1142 [[nodiscard]] constexpr auto withStructuredBuffer(this TSelf&& self, UInt32 binding, UInt32 descriptors = 1, bool writable = false) -> TSelf&& {
1143 self.m_state.descriptorLayouts.push_back(std::move(static_cast<DescriptorSetLayoutBuilder&>(self).makeDescriptor(writable ? DescriptorType::RWStructuredBuffer : DescriptorType::StructuredBuffer, binding, 0, descriptors)));
1144 return std::forward<TSelf>(self);
1145 }
1146
1153 template <typename TSelf>
1154 [[nodiscard]] constexpr auto withByteAddressBuffer(this TSelf&& self, UInt32 binding, UInt32 descriptors = 1, bool writable = false) -> TSelf&& {
1155 self.m_state.descriptorLayouts.push_back(std::move(static_cast<DescriptorSetLayoutBuilder&>(self).makeDescriptor(writable ? DescriptorType::RWByteAddressBuffer : DescriptorType::ByteAddressBuffer, binding, 0, descriptors)));
1156 return std::forward<TSelf>(self);
1157 }
1158
1165 template <typename TSelf>
1166 [[nodiscard]] constexpr auto withTexture(this TSelf&& self, UInt32 binding, UInt32 descriptors = 1, bool writable = false) -> TSelf&& {
1167 self.m_state.descriptorLayouts.push_back(std::move(static_cast<DescriptorSetLayoutBuilder&>(self).makeDescriptor(writable ? DescriptorType::RWTexture : DescriptorType::Texture, binding, 0, descriptors)));
1168 return std::forward<TSelf>(self);
1169 }
1170
1175 template <typename TSelf>
1176 [[nodiscard]] constexpr auto withInputAttachment(this TSelf&& self, UInt32 binding) -> TSelf&& {
1177 self.m_state.descriptorLayouts.push_back(std::move(static_cast<DescriptorSetLayoutBuilder&>(self).makeDescriptor(DescriptorType::InputAttachment, binding, 0)));
1178 return std::forward<TSelf>(self);
1179 }
1180
1188 template <typename TSelf>
1189 [[nodiscard]] constexpr auto withAccelerationStructure(this TSelf&& self, UInt32 binding) -> TSelf&& {
1190 self.m_state.descriptorLayouts.push_back(std::move(static_cast<DescriptorSetLayoutBuilder&>(self).makeDescriptor(DescriptorType::AccelerationStructure, binding, 0)));
1191 return std::forward<TSelf>(self);
1192 }
1193
1199 template <typename TSelf>
1200 [[nodiscard]] constexpr auto withSampler(this TSelf&& self, UInt32 binding, UInt32 descriptors = 1) -> TSelf&& {
1201 self.m_state.descriptorLayouts.push_back(std::move(static_cast<DescriptorSetLayoutBuilder&>(self).makeDescriptor(DescriptorType::Sampler, binding, 0, descriptors)));
1202 return std::forward<TSelf>(self);
1203 }
1204
1209 template <typename TSelf>
1210 constexpr auto space(this TSelf&& self, UInt32 space) noexcept -> TSelf&& {
1211 self.m_state.space = space;
1212 return std::forward<TSelf>(self);
1213 }
1214
1219 template <typename TSelf>
1220 constexpr auto shaderStages(this TSelf&& self, ShaderStage stages) noexcept -> TSelf&& {
1221 self.m_state.stages = stages;
1222 return std::forward<TSelf>(self);
1223 }
1224
1225 public:
1231 template <typename TSelf>
1232 [[nodiscard]] constexpr auto use(this TSelf&& self, UniquePtr<descriptor_layout_type>&& layout) -> TSelf&& {
1233 self.m_state.descriptorLayouts.push_back(std::move(layout));
1234 return std::forward<TSelf>(self);
1235 }
1236 };
1237
1243 template <typename TPushConstantsLayout, typename TParent> requires
1244 meta::implements<TPushConstantsLayout, PushConstantsLayout<typename TPushConstantsLayout::push_constants_range_type>>
1245 class PushConstantsLayoutBuilder : public Builder<TPushConstantsLayout, TParent> {
1246 public:
1247 using Builder<TPushConstantsLayout, TParent>::Builder;
1248 using push_constants_layout_type = TPushConstantsLayout;
1249 using push_constants_range_type = push_constants_layout_type::push_constants_range_type;
1250
1251 private:
1255 struct PushConstantsLayoutState {
1260 } m_state;
1261
1262 protected:
1267 inline PushConstantsLayoutState& state() noexcept {
1268 return m_state;
1269 }
1270
1280 virtual UniquePtr<push_constants_range_type> makeRange(ShaderStage shaderStages, UInt32 offset, UInt32 size, UInt32 space, UInt32 binding) = 0;
1281
1282 public:
1291 template <typename TSelf>
1292 constexpr auto withRange(this TSelf&& self, ShaderStage shaderStages, UInt32 offset, UInt32 size, UInt32 space, UInt32 binding) -> TSelf&& {
1293 self.m_state.ranges.push_back(std::move(static_cast<PushConstantsLayoutBuilder&>(self).makeRange(shaderStages, offset, size, space, binding)));
1294 return std::forward<TSelf>(self);
1295 }
1296 };
1297
1303 template <typename TPipelineLayout> requires
1304 meta::implements<TPipelineLayout, PipelineLayout<typename TPipelineLayout::descriptor_set_layout_type, typename TPipelineLayout::push_constants_layout_type>>
1305 class PipelineLayoutBuilder : public Builder<TPipelineLayout, std::nullptr_t, SharedPtr<TPipelineLayout>> {
1306 public:
1307 using Builder<TPipelineLayout, std::nullptr_t, SharedPtr<TPipelineLayout>>::Builder;
1308 using pipeline_layout_type = TPipelineLayout;
1309 using descriptor_set_layout_type = pipeline_layout_type::descriptor_set_layout_type;
1310 using push_constants_layout_type = pipeline_layout_type::push_constants_layout_type;
1311
1312 private:
1316 struct PipelineLayoutState {
1320 Array<SharedPtr<descriptor_set_layout_type>> descriptorSetLayouts{ };
1321
1325 UniquePtr<push_constants_layout_type> pushConstantsLayout{ };
1326 } m_state;
1327
1328 protected:
1333 inline PipelineLayoutState& state() noexcept {
1334 return m_state;
1335 }
1336
1337 public:
1343 template <typename TSelf>
1344 constexpr auto use(this TSelf&& self, SharedPtr<descriptor_set_layout_type>&& layout) -> TSelf&& {
1345 self.m_state.descriptorSetLayouts.push_back(std::move(layout));
1346 return std::forward<TSelf>(self);
1347 }
1348
1354 template <typename TSelf>
1355 constexpr auto use(this TSelf&& self, UniquePtr<push_constants_layout_type>&& layout) -> TSelf&& {
1356 self.m_state.pushConstantsLayout = std::move(layout);
1357 return std::forward<TSelf>(self);
1358 }
1359 };
1360
1366 template <typename TInputAssembler> requires
1367 meta::implements<TInputAssembler, InputAssembler<typename TInputAssembler::vertex_buffer_layout_type, typename TInputAssembler::index_buffer_layout_type>>
1368 class InputAssemblerBuilder : public Builder<TInputAssembler, std::nullptr_t, SharedPtr<TInputAssembler>> {
1369 public:
1370 using Builder<TInputAssembler, std::nullptr_t, SharedPtr<TInputAssembler>>::Builder;
1371 using input_assembler_type = TInputAssembler;
1372 using vertex_buffer_layout_type = input_assembler_type::vertex_buffer_layout_type;
1373 using index_buffer_layout_type = input_assembler_type::index_buffer_layout_type;
1374
1375 private:
1379 struct InputAssemblerState {
1383 PrimitiveTopology topology{};
1384
1388 Array<SharedPtr<vertex_buffer_layout_type>> vertexBufferLayouts{};
1389
1393 SharedPtr<index_buffer_layout_type> indexBufferLayout{};
1394 } m_state;
1395
1396 protected:
1401 inline InputAssemblerState& state() noexcept {
1402 return m_state;
1403 }
1404
1405 public:
1410 template <typename TSelf>
1411 constexpr auto topology(this TSelf&& self, PrimitiveTopology topology) -> TSelf&& {
1412 self.m_state.topology = topology;
1413 return std::forward<TSelf>(self);
1414 }
1415
1420 template <typename TSelf>
1421 constexpr auto use(this TSelf&& self, SharedPtr<vertex_buffer_layout_type>&& layout) -> TSelf&& {
1422 self.m_state.vertexBufferLayouts.push_back(std::move(layout));
1423 return std::forward<TSelf>(self);
1424 }
1425
1431 template <typename TSelf>
1432 constexpr auto use(this TSelf&& self, SharedPtr<index_buffer_layout_type>&& layout) -> TSelf&& {
1433 self.m_state.indexBufferLayout = std::move(layout);
1434 return std::forward<TSelf>(self);
1435 }
1436 };
1437
1443 template <typename TRenderPipeline> requires
1444 meta::implements<TRenderPipeline, RenderPipeline<typename TRenderPipeline::pipeline_layout_type, typename TRenderPipeline::shader_program_type, typename TRenderPipeline::input_assembler_type, typename TRenderPipeline::rasterizer_type>>
1445 class RenderPipelineBuilder : public Builder<TRenderPipeline> {
1446 public:
1447 using Builder<TRenderPipeline>::Builder;
1448 using render_pipeline_type = TRenderPipeline;
1449 using pipeline_layout_type = render_pipeline_type::pipeline_layout_type;
1450 using shader_program_type = render_pipeline_type::shader_program_type;
1451 using input_assembler_type = render_pipeline_type::input_assembler_type;
1452 using rasterizer_type = render_pipeline_type::rasterizer_type;
1453
1454 private:
1458 struct RenderPipelineState {
1462 SharedPtr<shader_program_type> shaderProgram{ };
1463
1467 SharedPtr<pipeline_layout_type> pipelineLayout{ };
1468
1472 SharedPtr<rasterizer_type> rasterizer{ };
1473
1477 SharedPtr<input_assembler_type> inputAssembler{ };
1478
1482 bool enableAlphaToCoverage{ false };
1483
1487 MultiSamplingLevel samples { MultiSamplingLevel::x1 };
1488 } m_state;
1489
1490 protected:
1495 inline RenderPipelineState& state() noexcept {
1496 return m_state;
1497 }
1498
1499 public:
1508 template <typename TSelf>
1509 constexpr auto shaderProgram(this TSelf&& self, SharedPtr<shader_program_type> program) -> TSelf&& {
1510 self.m_state.shaderProgram = std::move(program);
1511 return std::forward<TSelf>(self);
1512 }
1513
1518 template <typename TSelf>
1519 constexpr auto layout(this TSelf&& self, SharedPtr<pipeline_layout_type> layout) -> TSelf&& {
1520 self.m_state.pipelineLayout = std::move(layout);
1521 return std::forward<TSelf>(self);
1522 }
1523
1528 template <typename TSelf>
1529 constexpr auto rasterizer(this TSelf&& self, SharedPtr<rasterizer_type> rasterizer) -> TSelf&& {
1530 self.m_state.rasterizer = std::move(rasterizer);
1531 return std::forward<TSelf>(self);
1532 }
1533
1538 template <typename TSelf>
1539 constexpr auto inputAssembler(this TSelf&& self, SharedPtr<input_assembler_type> inputAssembler) -> TSelf&& {
1540 self.m_state.inputAssembler = std::move(inputAssembler);
1541 return std::forward<TSelf>(self);
1542 }
1543
1551 template <typename TSelf>
1552 constexpr auto enableAlphaToCoverage(this TSelf&& self, bool enable = true) -> TSelf&& {
1553 self.m_state.enableAlphaToCoverage = enable;
1554 return std::forward<TSelf>(self);
1555 }
1556
1561 template <typename TSelf>
1562 constexpr auto samples(this TSelf&& self, MultiSamplingLevel samples) -> TSelf&& {
1563 self.m_state.samples = samples;
1564 return std::forward<TSelf>(self);
1565 }
1566 };
1567
1573 template <typename TComputePipeline> requires
1574 meta::implements<TComputePipeline, ComputePipeline<typename TComputePipeline::pipeline_layout_type, typename TComputePipeline::shader_program_type>>
1575 class ComputePipelineBuilder : public Builder<TComputePipeline> {
1576 public:
1577 using Builder<TComputePipeline>::Builder;
1578 using compute_pipeline_type = TComputePipeline;
1579 using pipeline_layout_type = compute_pipeline_type::pipeline_layout_type;
1580 using shader_program_type = compute_pipeline_type::shader_program_type;
1581
1582 private:
1586 struct ComputePipelineState {
1590 SharedPtr<shader_program_type> shaderProgram{ };
1591
1595 SharedPtr<pipeline_layout_type> pipelineLayout{ };
1596 } m_state;
1597
1598 protected:
1603 inline ComputePipelineState& state() noexcept {
1604 return m_state;
1605 }
1606
1607 public:
1616 template <typename TSelf>
1617 constexpr auto shaderProgram(this TSelf&& self, SharedPtr<shader_program_type> program) -> TSelf&& {
1618 self.m_state.shaderProgram = std::move(program);
1619 return std::forward<TSelf>(self);
1620 }
1621
1626 template <typename TSelf>
1627 constexpr auto layout(this TSelf&& self, SharedPtr<pipeline_layout_type> layout) -> TSelf&& {
1628 self.m_state.pipelineLayout = std::move(layout);
1629 return std::forward<TSelf>(self);
1630 }
1631 };
1632
1638 template <typename TRayTracingPipeline> requires
1639 meta::implements<TRayTracingPipeline, RayTracingPipeline<typename TRayTracingPipeline::pipeline_layout_type, typename TRayTracingPipeline::shader_program_type>>
1640 class RayTracingPipelineBuilder : public Builder<TRayTracingPipeline> {
1641 public:
1642 using Builder<TRayTracingPipeline>::Builder;
1643 using raytracing_pipeline_type = TRayTracingPipeline;
1644 using pipeline_layout_type = raytracing_pipeline_type::pipeline_layout_type;
1645 using shader_program_type = raytracing_pipeline_type::shader_program_type;
1646
1647 private:
1651 struct RayTracingPipelineState {
1655 SharedPtr<pipeline_layout_type> pipelineLayout { };
1656
1660 UInt32 maxRecursionDepth { 10 }; // NOLINT(cppcoreguidelines-avoid-magic-numbers)
1661
1665 UInt32 maxPayloadSize { 0 }; // NOLINT(cppcoreguidelines-avoid-magic-numbers)
1666
1670 UInt32 maxAttributeSize { 32 }; // NOLINT(cppcoreguidelines-avoid-magic-numbers)
1671 } m_state;
1672
1673 protected:
1678 inline RayTracingPipelineState& state() noexcept {
1679 return m_state;
1680 }
1681
1682 public:
1687 template <typename TSelf>
1688 constexpr auto layout(this TSelf&& self, SharedPtr<pipeline_layout_type> layout) -> TSelf&& {
1689 self.m_state.pipelineLayout = std::move(layout);
1690 return std::forward<TSelf>(self);
1691 }
1692
1697 template <typename TSelf>
1698 constexpr auto maxBounces(this TSelf&& self, UInt32 maxRecursionDepth) -> TSelf&& {
1699 self.m_state.maxRecursionDepth = maxRecursionDepth;
1700 return std::forward<TSelf>(self);
1701 }
1702
1707 template <typename TSelf>
1708 constexpr auto maxPayloadSize(this TSelf&& self, UInt32 maxPayloadSize) -> TSelf&& {
1709 self.m_state.maxPayloadSize = maxPayloadSize;
1710 return std::forward<TSelf>(self);
1711 }
1712
1717 template <typename TSelf>
1718 constexpr auto maxAttributeSize(this TSelf&& self, UInt32 maxAttributeSize) -> TSelf&& {
1719 self.m_state.maxAttributeSize = maxAttributeSize;
1720 return std::forward<TSelf>(self);
1721 }
1722 };
1723
1730 template <typename TRenderPass> requires
1731 meta::implements<TRenderPass, RenderPass<typename TRenderPass::command_queue_type, typename TRenderPass::frame_buffer_type>>
1732 class RenderPassBuilder : public Builder<TRenderPass, std::nullptr_t, SharedPtr<TRenderPass>> {
1733 public:
1734 using Builder<TRenderPass, std::nullptr_t, SharedPtr<TRenderPass>>::Builder;
1735 using render_pass_type = TRenderPass;
1736 using command_queue_type = render_pass_type::command_queue_type;
1737
1738 private:
1742 struct RenderPassState {
1746 UInt32 commandBufferCount{ 0 };
1747
1751 Array<RenderTarget> renderTargets{ };
1752
1756 Array<RenderPassDependency> inputAttachments{ };
1757
1761 SharedPtr<const command_queue_type> commandQueue{ nullptr };
1762
1766 Optional<DescriptorBindingPoint> inputAttachmentSamplerBinding{ std::nullopt };
1767 } m_state;
1768
1769 protected:
1774 inline RenderPassState& state() noexcept {
1775 return m_state;
1776 }
1777
1784 virtual RenderPassDependency makeInputAttachment(DescriptorBindingPoint binding, const RenderTarget& renderTarget) = 0;
1785
1786 public:
1795 template <typename TSelf>
1796 constexpr auto executeOn(this TSelf&& self, const command_queue_type& queue) -> TSelf&& {
1797 self.m_state.commandQueue = queue.shared_from_this();
1798 return std::forward<TSelf>(self);
1799 }
1800
1805 template <typename TSelf>
1806 constexpr auto commandBuffers(this TSelf&& self, UInt32 count) -> TSelf&& {
1807 self.m_state.commandBufferCount = count;
1808 return std::forward<TSelf>(self);
1809 }
1810
1818 template <typename TSelf>
1819 constexpr auto renderTarget(this TSelf&& self, RenderTargetType type, Format format, RenderTargetFlags flags = RenderTargetFlags::None, const Vector4f& clearValues = { 0.0f, 0.0f, 0.0f, 0.0f }) -> TSelf&& {
1820 self.renderTarget("", static_cast<UInt32>(self.m_state.renderTargets.size()), type, format, flags, clearValues);
1821 return std::forward<TSelf>(self);
1822 }
1823
1832 template <typename TSelf>
1833 constexpr auto renderTarget(this TSelf&& self, const String& name, RenderTargetType type, Format format, RenderTargetFlags flags = RenderTargetFlags::None, const Vector4f& clearValues = { 0.0f, 0.0f, 0.0f, 0.0f }) -> TSelf&& {
1834 self.renderTarget(name, static_cast<UInt32>(self.m_state.renderTargets.size()), type, format, flags, clearValues);
1835 return std::forward<TSelf>(self);
1836 }
1837
1846 template <typename TSelf>
1847 constexpr auto renderTarget(this TSelf&& self, UInt32 location, RenderTargetType type, Format format, RenderTargetFlags flags = RenderTargetFlags::None, const Vector4f& clearValues = { 0.0f, 0.0f, 0.0f, 0.0f }) -> TSelf&& {
1848 self.renderTarget("", location, type, format, flags, clearValues);
1849 return std::forward<TSelf>(self);
1850 }
1851
1861 template <typename TSelf>
1862 constexpr auto renderTarget(this TSelf&& self, const String& name, UInt32 location, RenderTargetType type, Format format, RenderTargetFlags flags = RenderTargetFlags::None, const Vector4f& clearValues = { 0.0f, 0.0f, 0.0f, 0.0f }) -> TSelf&& {
1863 self.m_state.renderTargets.push_back(RenderTarget(name, location, type, format, flags, clearValues));
1864 return std::forward<TSelf>(self);
1865 }
1866
1873 template <typename TSelf>
1874 constexpr auto inputAttachment(this TSelf&& self, DescriptorBindingPoint binding, const render_pass_type& renderPass, UInt32 outputLocation) -> TSelf&& {
1875 self.m_state.inputAttachments.push_back(static_cast<RenderPassBuilder&>(self).makeInputAttachment(binding, renderPass.renderTarget(outputLocation)));
1876 return std::forward<TSelf>(self);
1877 }
1878
1884 template <typename TSelf>
1885 auto inputAttachment(this TSelf&& self, DescriptorBindingPoint binding, RenderTarget renderTarget) -> TSelf&& {
1886 self.m_state.inputAttachments.push_back(static_cast<RenderPassBuilder&>(self).makeInputAttachment(binding, renderTarget));
1887 return std::forward<TSelf>(self);
1888 }
1889
1894 template <typename TSelf>
1895 constexpr auto inputAttachmentSamplerBinding(this TSelf&& self, const DescriptorBindingPoint& bindingPoint) -> TSelf&& {
1896 self.m_state.inputAttachmentSamplerBinding = bindingPoint;
1897 return std::forward<TSelf>(self);
1898 }
1899 };
1900
1901}
1902#endif // defined(LITEFX_BUILD_DEFINE_BUILDERS)
Describes an generic builder type.
Definition containers.hpp:960
Definition math.hpp:534
Stores meta data about a buffer attribute, i.e. a member or field of a descriptor or buffer.
Definition rendering_api.hpp:3792
Base interface for buffer objects.
Definition rendering_api.hpp:4186
Describes a generic image.
Definition rendering_api.hpp:4208
Represents a mapping between a set of RenderTarget instances and the input attachments of a IRenderPa...
Definition rendering_api.hpp:3076
Implements a render target.
Definition rendering_api.hpp:2976
float_t Float
A type for a floating point value with single precision.
Definition math.hpp:71
uint32_t UInt32
A type for an unsigned 32 bit integer.
Definition math.hpp:56
Definition dx12.hpp:11
BorderMode
Describes how to treat texture coordinates that are outside the domain [0..1].
Definition rendering_api.hpp:1184
CullOrder
Describes the order or vertex winding, that is used to determine, whether a polygon is facing towards...
Definition rendering_api.hpp:1018
RenderTargetFlags
Describes the behavior of render targets.
Definition rendering_api.hpp:1056
ImageLayout
Specifies the layout of an IImage resource.
Definition rendering_api.hpp:1686
MipMapMode
Describes the filter operation between two mip-map levels.
Definition rendering_api.hpp:1169
CullMode
Describes which faces are culled by the Rasterizer stage.
Definition rendering_api.hpp:991
ShaderStage
Describes the valid shader stages of a graphics pipeline.
Definition rendering_api.hpp:799
RenderTargetType
Describes the type of a render target.
Definition rendering_api.hpp:1033
PrimitiveTopology
Describes the topology of a mesh primitive.
Definition rendering_api.hpp:765
PolygonMode
Describes the draw mode for polygons.
Definition rendering_api.hpp:970
AttributeSemantic
Describes the semantic of a buffer attribute.
Definition rendering_api.hpp:371
@ RenderTarget
Allows the resource to be used as a render target.
DescriptorType
Describes the type of a IDescriptor.
Definition rendering_api.hpp:436
FilterMode
Describes the filter operation when accessing a pixel from a texture coordinate.
Definition rendering_api.hpp:1152
PipelineStage
Defines pipeline stages as points where synchronization may occur.
Definition rendering_api.hpp:1373
BufferFormat
Describes a buffer attribute format.
Definition rendering_api.hpp:339
ResourceAccess
Defines how a IBuffer or IImage resource is accessed.
Definition rendering_api.hpp:1537
Format
Describes a texel format.
Definition rendering_api.hpp:182
MultiSamplingLevel
Describes the number of samples with which a IImage is sampled.
Definition rendering_api.hpp:1111
std::vector< T > Array
Represents a dynamic array.
Definition containers.hpp:73
std::optional< T > Optional
Represents an optional value.
Definition containers.hpp:94
std::shared_ptr< T > SharedPtr
Represents a shared pointer, that expresses non-exclusive ownership.
Definition containers.hpp:109
std::unique_ptr< T, TDeleter > UniquePtr
Represents a unique pointer, that expresses exclusive ownership.
Definition containers.hpp:102
std::string String
Definition string.hpp:24
Describes the rasterizer depth bias.
Definition rendering_api.hpp:3177
Describes the rasterizer depth state.
Definition rendering_api.hpp:3150
Describes the rasterizer stencil state.
Definition rendering_api.hpp:3229
Describes a single descriptor binding point within a IShaderModule.
Definition rendering_api.hpp:2735