3#include "rendering_api.hpp"
4#include "rendering.hpp"
6#if defined(LITEFX_BUILD_DEFINE_BUILDERS)
15 template <
typename TBarrier>
requires
16 meta::implements<TBarrier, Barrier<typename TBarrier::buffer_type, typename TBarrier::image_type>>
17 class BarrierBuilder :
public Builder<TBarrier> {
19 template <
typename TParent>
requires
20 meta::implements<TParent, BarrierBuilder<TBarrier>>
21 struct [[nodiscard]] ImageBarrierBuilder;
27 template <
typename TParent>
requires
28 meta::implements<TParent, BarrierBuilder<TBarrier>>
29 struct [[nodiscard]] SecondStageBuilder {
39 constexpr SecondStageBuilder(TParent&& parent,
PipelineStage waitFor) noexcept :
40 m_parent(std::move(parent)), m_from(waitFor) { }
43 friend class BarrierBuilder;
50 constexpr auto toContinueWith(
PipelineStage stage) -> TParent {
51 this->m_parent.stagesCallback(this->m_from, stage);
52 return std::move(this->m_parent);
60 template <
typename TParent>
requires
61 meta::implements<TParent, BarrierBuilder<TBarrier>>
62 struct [[nodiscard]] GlobalBarrierBuilder {
72 constexpr GlobalBarrierBuilder(TParent&& parent,
ResourceAccess access) noexcept :
73 m_parent(std::move(parent)), m_access(access) { }
76 friend class BarrierBuilder;
82 constexpr auto untilFinishedWith(
ResourceAccess access) -> TParent {
83 this->m_parent.globalBarrierCallback(access, m_access);
84 return std::move(this->m_parent);
92 template <
typename TParent>
requires
93 meta::implements<TParent, BarrierBuilder<TBarrier>>
94 struct [[nodiscard]] BufferBarrierBuilder {
107 m_parent(std::move(parent)), m_buffer(buffer.shared_from_this()), m_access(access) { }
110 friend class BarrierBuilder;
116 constexpr auto untilFinishedWith(
ResourceAccess access) -> TParent {
117 this->m_parent.bufferBarrierCallback(*m_buffer, access, m_access);
118 return std::move(this->m_parent);
126 template <
typename TParent>
requires
127 meta::implements<TParent, BarrierBuilder<TBarrier>>
128 struct [[nodiscard]] ImageLayoutBarrierBuilder {
134 UInt32 m_level{ 0 }, m_levels{ 1 }, m_layer{ 0 }, m_layers{ 1 }, m_plane{ 0 };
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) { }
152 friend class BarrierBuilder;
153 friend struct ImageBarrierBuilder<TParent>;
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);
169 template <
typename TParent>
requires
170 meta::implements<TParent, BarrierBuilder<TBarrier>>
171 struct [[nodiscard]] ImageBarrierBuilder {
176 UInt32 m_level{ 0 }, m_levels{ 0 }, m_layer{ 0 }, m_layers{ 0 }, m_plane{ 0 };
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()) { }
188 friend class BarrierBuilder;
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 };
224 this->setupStages(waitFor, continueWith);
233 this->setupGlobalBarrier(before, after);
243 this->setupBufferBarrier(buffer, before, after);
259 this->setupImageBarrier(image, before, after, layout, level, levels, layer, layers, plane);
301 using barrier_type = TBarrier;
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 };
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 };
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 };
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 };
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 };
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>> {
364 using shader_program_type = TShaderProgram;
365 using shader_module_type = shader_program_type::shader_module_type;
371 struct ShaderProgramState {
383 inline ShaderProgramState& state() noexcept {
416 template<
typename 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);
430 template<
typename 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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
794 template <
typename TRasterizer>
requires
795 meta::implements<TRasterizer, IRasterizer>
796 class RasterizerBuilder :
public Builder<TRasterizer, std::nullptr_t, SharedPtr<TRasterizer>> {
799 using rasterizer_type = TRasterizer;
805 struct RasterizerState {
814 CullMode cullMode{ CullMode::BackFaces };
819 CullOrder cullOrder{ CullOrder::ClockWise };
824 Float lineWidth{ 1.0f };
847 inline RasterizerState& state() noexcept {
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);
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);
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);
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);
896 template<
typename TSelf>
898 self.m_state.depthBias = depthBias;
899 return std::forward<TSelf>(self);
906 template<
typename TSelf>
908 self.m_state.depthState = depthState;
909 return std::forward<TSelf>(self);
916 template<
typename TSelf>
918 self.m_state.stencilState = stencilState;
919 return std::forward<TSelf>(self);
928 template <
typename TVertexBufferLayout,
typename TParent>
requires
929 meta::implements<TVertexBufferLayout, IVertexBufferLayout>
930 class VertexBufferLayoutBuilder :
public Builder<TVertexBufferLayout, TParent, SharedPtr<TVertexBufferLayout>> {
933 using vertex_buffer_layout_type = TVertexBufferLayout;
939 struct VertexBufferLayoutState {
951 inline VertexBufferLayoutState& state() noexcept {
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);
976 template <
typename TSelf>
978 return std::forward<TSelf>(self).withAttribute({
static_cast<UInt32>(self.m_state.attributes.size()), offset, format, semantic, semanticIndex });
989 template <
typename TSelf>
991 return std::forward<TSelf>(self).withAttribute({ location, offset, format, semantic, semanticIndex });
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>> {
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;
1014 struct DescriptorSetLayoutState {
1036 inline DescriptorSetLayoutState& state() noexcept {
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;
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
1231 template <
typename TSelf>
1233 self.m_state.descriptorLayouts.push_back(std::move(layout));
1234 return std::forward<TSelf>(self);
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> {
1248 using push_constants_layout_type = TPushConstantsLayout;
1249 using push_constants_range_type = push_constants_layout_type::push_constants_range_type;
1255 struct PushConstantsLayoutState {
1267 inline PushConstantsLayoutState& state() noexcept {
1291 template <
typename 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);
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>> {
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;
1316 struct PipelineLayoutState {
1333 inline PipelineLayoutState& state() noexcept {
1343 template <
typename TSelf>
1345 self.m_state.descriptorSetLayouts.push_back(std::move(layout));
1346 return std::forward<TSelf>(self);
1354 template <
typename TSelf>
1356 self.m_state.pushConstantsLayout = std::move(layout);
1357 return std::forward<TSelf>(self);
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>> {
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;
1379 struct InputAssemblerState {
1401 inline InputAssemblerState& state() noexcept {
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);
1420 template <
typename TSelf>
1422 self.m_state.vertexBufferLayouts.push_back(std::move(layout));
1423 return std::forward<TSelf>(self);
1431 template <
typename TSelf>
1433 self.m_state.indexBufferLayout = std::move(layout);
1434 return std::forward<TSelf>(self);
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> {
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;
1458 struct RenderPipelineState {
1482 bool enableAlphaToCoverage{
false };
1495 inline RenderPipelineState& state() noexcept {
1508 template <
typename TSelf>
1510 self.m_state.shaderProgram = std::move(program);
1511 return std::forward<TSelf>(self);
1518 template <
typename TSelf>
1520 self.m_state.pipelineLayout = std::move(layout);
1521 return std::forward<TSelf>(self);
1528 template <
typename TSelf>
1530 self.m_state.rasterizer = std::move(rasterizer);
1531 return std::forward<TSelf>(self);
1538 template <
typename TSelf>
1540 self.m_state.inputAssembler = std::move(inputAssembler);
1541 return std::forward<TSelf>(self);
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);
1561 template <
typename TSelf>
1563 self.m_state.samples = samples;
1564 return std::forward<TSelf>(self);
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> {
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;
1586 struct ComputePipelineState {
1603 inline ComputePipelineState& state() noexcept {
1616 template <
typename TSelf>
1618 self.m_state.shaderProgram = std::move(program);
1619 return std::forward<TSelf>(self);
1626 template <
typename TSelf>
1628 self.m_state.pipelineLayout = std::move(layout);
1629 return std::forward<TSelf>(self);
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> {
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;
1651 struct RayTracingPipelineState {
1660 UInt32 maxRecursionDepth { 10 };
1665 UInt32 maxPayloadSize { 0 };
1670 UInt32 maxAttributeSize { 32 };
1678 inline RayTracingPipelineState& state() noexcept {
1687 template <
typename TSelf>
1689 self.m_state.pipelineLayout = std::move(layout);
1690 return std::forward<TSelf>(self);
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);
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);
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);
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>> {
1735 using render_pass_type = TRenderPass;
1736 using command_queue_type = render_pass_type::command_queue_type;
1742 struct RenderPassState {
1746 UInt32 commandBufferCount{ 0 };
1774 inline RenderPassState& state() noexcept {
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);
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);
1818 template <
typename TSelf>
1820 self.renderTarget(
"",
static_cast<UInt32>(self.m_state.renderTargets.size()), type, format, flags, clearValues);
1821 return std::forward<TSelf>(self);
1832 template <
typename TSelf>
1834 self.renderTarget(name,
static_cast<UInt32>(self.m_state.renderTargets.size()), type, format, flags, clearValues);
1835 return std::forward<TSelf>(self);
1846 template <
typename TSelf>
1848 self.renderTarget(
"", location, type, format, flags, clearValues);
1849 return std::forward<TSelf>(self);
1861 template <
typename TSelf>
1863 self.m_state.renderTargets.push_back(
RenderTarget(name, location, type, format, flags, clearValues));
1864 return std::forward<TSelf>(self);
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);
1884 template <
typename TSelf>
1886 self.m_state.inputAttachments.push_back(
static_cast<RenderPassBuilder&
>(self).makeInputAttachment(binding, renderTarget));
1887 return std::forward<TSelf>(self);
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);
Describes an generic builder type.
Definition containers.hpp:960
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
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