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 };
829 bool depthClip{
true };
849 bool conservativeRasterization{
false };
857 inline RasterizerState& state() noexcept {
866 template<
typename TSelf>
867 [[nodiscard]]
constexpr auto polygonMode(
this TSelf&& self,
PolygonMode mode)
noexcept -> TSelf&& {
868 self.m_state.polygonMode = mode;
869 return std::forward<TSelf>(self);
876 template<
typename TSelf>
877 [[nodiscard]]
constexpr auto cullMode(
this TSelf&& self,
CullMode mode)
noexcept -> TSelf&& {
878 self.m_state.cullMode = mode;
879 return std::forward<TSelf>(self);
886 template<
typename TSelf>
887 [[nodiscard]]
constexpr auto cullOrder(
this TSelf&& self,
CullOrder order)
noexcept -> TSelf&& {
888 self.m_state.cullOrder = order;
889 return std::forward<TSelf>(self);
896 template<
typename TSelf>
897 [[nodiscard]]
constexpr auto lineWidth(
this TSelf&& self,
Float width)
noexcept -> TSelf&& {
898 self.m_state.lineWidth = width;
899 return std::forward<TSelf>(self);
906 template<
typename TSelf>
907 [[nodiscard]]
constexpr auto depthClip(
this TSelf&& self,
bool depthClip)
noexcept -> TSelf&& {
908 self.m_state.depthClip = depthClip;
909 return std::forward<TSelf>(self);
916 template<
typename TSelf>
917 [[nodiscard]]
constexpr auto conservativeRasterization(
this TSelf&& self,
bool enable)
noexcept -> TSelf&& {
918 self.m_state.conservativeRasterization = enable;
919 return std::forward<TSelf>(self);
926 template<
typename TSelf>
928 self.m_state.depthBias = depthBias;
929 return std::forward<TSelf>(self);
936 template<
typename TSelf>
938 self.m_state.depthState = depthState;
939 return std::forward<TSelf>(self);
946 template<
typename TSelf>
948 self.m_state.stencilState = stencilState;
949 return std::forward<TSelf>(self);
958 template <
typename TVertexBufferLayout,
typename TParent>
requires
959 meta::implements<TVertexBufferLayout, IVertexBufferLayout>
960 class VertexBufferLayoutBuilder :
public Builder<TVertexBufferLayout, TParent, SharedPtr<TVertexBufferLayout>> {
963 using vertex_buffer_layout_type = TVertexBufferLayout;
969 struct VertexBufferLayoutState {
986 inline VertexBufferLayoutState& state() noexcept {
995 template <
typename TSelf>
996 [[nodiscard]]
constexpr auto withAttribute(
this TSelf&& self,
BufferAttribute&& attribute) -> TSelf&& {
997 self.m_state.attributes.push_back(std::move(attribute));
998 return std::forward<TSelf>(self);
1011 template <
typename TSelf>
1013 return std::forward<TSelf>(self).withAttribute({
static_cast<UInt32>(self.m_state.attributes.size()), offset, format, semantic, semanticIndex });
1024 template <
typename TSelf>
1026 return std::forward<TSelf>(self).withAttribute({ location, offset, format, semantic, semanticIndex });
1033 template <
typename TSelf>
1034 [[nodiscard]]
constexpr auto atRate(
this TSelf&& self,
VertexBufferInputRate inputRate) -> TSelf&& {
1035 self.m_state.inputRate = inputRate;
1036 return std::forward<TSelf>(self);
1046 template <
typename TDescriptorSetLayout,
typename TParent>
requires
1047 meta::implements<TDescriptorSetLayout, DescriptorSetLayout<typename TDescriptorSetLayout::descriptor_layout_type, typename TDescriptorSetLayout::descriptor_set_type>>
1048 class DescriptorSetLayoutBuilder :
public Builder<TDescriptorSetLayout, TParent, SharedPtr<TDescriptorSetLayout>> {
1051 using descriptor_set_layout_type = TDescriptorSetLayout;
1052 using descriptor_layout_type = descriptor_set_layout_type::descriptor_layout_type;
1053 using descriptor_set_type = descriptor_set_layout_type::descriptor_set_type;
1059 struct DescriptorSetLayoutState {
1081 inline DescriptorSetLayoutState& state() noexcept {
1094 constexpr virtual descriptor_layout_type makeDescriptor(
DescriptorType type,
UInt32 binding,
UInt32 descriptorSize,
UInt32 descriptors,
bool unbounded) = 0;
1111 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;
1118 template <
typename TSelf>
1119 [[nodiscard]]
constexpr auto withDescriptor(
this TSelf&& self, descriptor_layout_type&& layout) -> TSelf&& {
1120 self.m_state.descriptorLayouts.push_back(std::move(layout));
1121 return std::forward<TSelf>(self);
1132 template <
typename TSelf>
1133 [[nodiscard]]
constexpr auto withDescriptor(
this TSelf&& self,
DescriptorType type,
UInt32 binding,
UInt32 descriptorSize,
UInt32 descriptors = 1,
bool unbounded =
false) -> TSelf&& {
1134 self.m_state.descriptorLayouts.push_back(std::move(
static_cast<DescriptorSetLayoutBuilder&
>(self).makeDescriptor(type, binding, descriptorSize, descriptors, unbounded)));
1135 return std::forward<TSelf>(self);
1152 template <
typename TSelf>
1153 [[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&& {
1154 self.m_state.descriptorLayouts.push_back(std::move(
static_cast<DescriptorSetLayoutBuilder&
>(self).makeDescriptor(binding, magFilter, minFilter, borderU, borderV, borderW, mipMapMode, mipMapBias, minLod, maxLod, anisotropy)));
1155 return std::forward<TSelf>(self);
1163 template <
typename TSelf>
1164 [[nodiscard]]
constexpr auto withConstantBuffer(
this TSelf&& self,
UInt32 binding,
UInt32 descriptorSize) -> TSelf&& {
1165 self.m_state.descriptorLayouts.push_back(std::move(
static_cast<DescriptorSetLayoutBuilder&
>(self).makeDescriptor(DescriptorType::ConstantBuffer, binding, descriptorSize, 1u,
false)));
1166 return std::forward<TSelf>(self);
1180 template <
typename TSelf>
1181 [[nodiscard]]
constexpr auto withConstantBufferArray(
this TSelf&& self,
UInt32 binding,
UInt32 descriptorSize,
UInt32 descriptors,
bool unbounded =
false) -> TSelf&& {
1182 self.m_state.descriptorLayouts.push_back(std::move(
static_cast<DescriptorSetLayoutBuilder&
>(self).makeDescriptor(DescriptorType::ConstantBuffer, binding, descriptorSize, descriptors, unbounded)));
1183 return std::forward<TSelf>(self);
1191 template <
typename TSelf>
1192 [[nodiscard]]
constexpr auto withBuffer(
this TSelf&& self,
UInt32 binding,
bool writable =
false) -> TSelf&& {
1193 self.m_state.descriptorLayouts.push_back(std::move(
static_cast<DescriptorSetLayoutBuilder&
>(self).makeDescriptor(writable ? DescriptorType::RWBuffer : DescriptorType::Buffer, binding, 0u, 1u,
false)));
1194 return std::forward<TSelf>(self);
1207 template <
typename TSelf>
1208 [[nodiscard]]
constexpr auto withBufferArray(
this TSelf&& self,
UInt32 binding,
UInt32 descriptors = 1,
bool writable =
false,
bool unbounded =
false) -> TSelf&& {
1209 self.m_state.descriptorLayouts.push_back(std::move(
static_cast<DescriptorSetLayoutBuilder&
>(self).makeDescriptor(writable ? DescriptorType::RWBuffer : DescriptorType::Buffer, binding, 0, descriptors, unbounded)));
1210 return std::forward<TSelf>(self);
1218 template <
typename TSelf>
1219 [[nodiscard]]
constexpr auto withStructuredBuffer(
this TSelf&& self,
UInt32 binding,
bool writable =
false) -> TSelf&& {
1220 self.m_state.descriptorLayouts.push_back(std::move(
static_cast<DescriptorSetLayoutBuilder&
>(self).makeDescriptor(writable ? DescriptorType::RWStructuredBuffer : DescriptorType::StructuredBuffer, binding, 0u, 1u,
false)));
1221 return std::forward<TSelf>(self);
1234 template <
typename TSelf>
1235 [[nodiscard]]
constexpr auto withStructuredBufferArray(
this TSelf&& self,
UInt32 binding,
UInt32 descriptors = 1,
bool writable =
false,
bool unbounded =
false) -> TSelf&& {
1236 self.m_state.descriptorLayouts.push_back(std::move(
static_cast<DescriptorSetLayoutBuilder&
>(self).makeDescriptor(writable ? DescriptorType::RWStructuredBuffer : DescriptorType::StructuredBuffer, binding, 0, descriptors, unbounded)));
1237 return std::forward<TSelf>(self);
1245 template <
typename TSelf>
1246 [[nodiscard]]
constexpr auto withByteAddressBuffer(
this TSelf&& self,
UInt32 binding,
bool writable =
false) -> TSelf&& {
1247 self.m_state.descriptorLayouts.push_back(std::move(
static_cast<DescriptorSetLayoutBuilder&
>(self).makeDescriptor(writable ? DescriptorType::RWByteAddressBuffer : DescriptorType::ByteAddressBuffer, binding, 0u, 1u,
false)));
1248 return std::forward<TSelf>(self);
1261 template <
typename TSelf>
1262 [[nodiscard]]
constexpr auto withByteAddressBufferArray(
this TSelf&& self,
UInt32 binding,
UInt32 descriptors = 1,
bool writable =
false,
bool unbounded =
false) -> TSelf&& {
1263 self.m_state.descriptorLayouts.push_back(std::move(
static_cast<DescriptorSetLayoutBuilder&
>(self).makeDescriptor(writable ? DescriptorType::RWByteAddressBuffer : DescriptorType::ByteAddressBuffer, binding, 0, descriptors, unbounded)));
1264 return std::forward<TSelf>(self);
1272 template <
typename TSelf>
1273 [[nodiscard]]
constexpr auto withTexture(
this TSelf&& self,
UInt32 binding,
bool writable =
false) -> TSelf&& {
1274 self.m_state.descriptorLayouts.push_back(std::move(
static_cast<DescriptorSetLayoutBuilder&
>(self).makeDescriptor(writable ? DescriptorType::RWTexture : DescriptorType::Texture, binding, 0u, 1u,
false)));
1275 return std::forward<TSelf>(self);
1288 template <
typename TSelf>
1289 [[nodiscard]]
constexpr auto withTextureArray(
this TSelf&& self,
UInt32 binding,
UInt32 descriptors = 1,
bool writable =
false,
bool unbounded =
false) -> TSelf&& {
1290 self.m_state.descriptorLayouts.push_back(std::move(
static_cast<DescriptorSetLayoutBuilder&
>(self).makeDescriptor(writable ? DescriptorType::RWTexture : DescriptorType::Texture, binding, 0, descriptors, unbounded)));
1291 return std::forward<TSelf>(self);
1298 template <
typename TSelf>
1299 [[nodiscard]]
constexpr auto withInputAttachment(
this TSelf&& self,
UInt32 binding) -> TSelf&& {
1300 self.m_state.descriptorLayouts.push_back(std::move(
static_cast<DescriptorSetLayoutBuilder&
>(self).makeDescriptor(DescriptorType::InputAttachment, binding, 0,
false)));
1301 return std::forward<TSelf>(self);
1311 template <
typename TSelf>
1312 [[nodiscard]]
constexpr auto withAccelerationStructure(
this TSelf&& self,
UInt32 binding) -> TSelf&& {
1313 self.m_state.descriptorLayouts.push_back(std::move(
static_cast<DescriptorSetLayoutBuilder&
>(self).makeDescriptor(DescriptorType::AccelerationStructure, binding, 0,
false)));
1314 return std::forward<TSelf>(self);
1321 template <
typename TSelf>
1322 [[nodiscard]]
constexpr auto withSampler(
this TSelf&& self,
UInt32 binding) -> TSelf&& {
1323 self.m_state.descriptorLayouts.push_back(std::move(
static_cast<DescriptorSetLayoutBuilder&
>(self).makeDescriptor(DescriptorType::Sampler, binding, 0u, 1u,
false)));
1324 return std::forward<TSelf>(self);
1336 template <
typename TSelf>
1337 [[nodiscard]]
constexpr auto withSamplerArray(
this TSelf&& self,
UInt32 binding,
UInt32 descriptors = 1,
bool unbounded =
false) -> TSelf&& {
1338 self.m_state.descriptorLayouts.push_back(std::move(
static_cast<DescriptorSetLayoutBuilder&
>(self).makeDescriptor(DescriptorType::Sampler, binding, 0, descriptors, unbounded)));
1339 return std::forward<TSelf>(self);
1348 template <
typename TSelf>
1349 [[nodiscard]]
constexpr auto withResourceHeapAccess(
this TSelf&& self,
UInt32 binding,
UInt32 heapSize) -> TSelf&& {
1350 self.m_state.descriptorLayouts.push_back(std::move(
static_cast<DescriptorSetLayoutBuilder&
>(self).makeDescriptor(DescriptorType::ResourceDescriptorHeap, binding, 0u, heapSize,
false)));
1351 return std::forward<TSelf>(self);
1360 template <
typename TSelf>
1361 [[nodiscard]]
constexpr auto withSamplerHeapAccess(
this TSelf&& self,
UInt32 binding,
UInt32 heapSize) -> TSelf&& {
1362 self.m_state.descriptorLayouts.push_back(std::move(
static_cast<DescriptorSetLayoutBuilder&
>(self).makeDescriptor(DescriptorType::SamplerDescriptorHeap, binding, 0u, heapSize,
false)));
1363 return std::forward<TSelf>(self);
1370 template <
typename TSelf>
1371 constexpr auto space(
this TSelf&& self,
UInt32 space)
noexcept -> TSelf&& {
1372 self.m_state.space = space;
1373 return std::forward<TSelf>(self);
1380 template <
typename TSelf>
1381 constexpr auto shaderStages(
this TSelf&& self,
ShaderStage stages)
noexcept -> TSelf&& {
1382 self.m_state.stages = stages;
1383 return std::forward<TSelf>(self);
1392 template <
typename TSelf>
1394 self.m_state.descriptorLayouts.push_back(std::move(layout));
1395 return std::forward<TSelf>(self);
1404 template <
typename TPushConstantsLayout,
typename TParent>
requires
1405 meta::implements<TPushConstantsLayout, PushConstantsLayout<typename TPushConstantsLayout::push_constants_range_type>>
1406 class PushConstantsLayoutBuilder :
public Builder<TPushConstantsLayout, TParent> {
1409 using push_constants_layout_type = TPushConstantsLayout;
1410 using push_constants_range_type = push_constants_layout_type::push_constants_range_type;
1416 struct PushConstantsLayoutState {
1428 inline PushConstantsLayoutState& state() noexcept {
1452 template <
typename TSelf>
1454 self.m_state.ranges.push_back(std::move(
static_cast<PushConstantsLayoutBuilder&
>(self).makeRange(shaderStages, offset, size, space, binding)));
1455 return std::forward<TSelf>(self);
1464 template <
typename TPipelineLayout>
requires
1465 meta::implements<TPipelineLayout, PipelineLayout<typename TPipelineLayout::descriptor_set_layout_type, typename TPipelineLayout::push_constants_layout_type>>
1466 class PipelineLayoutBuilder :
public Builder<TPipelineLayout, std::nullptr_t, SharedPtr<TPipelineLayout>> {
1469 using pipeline_layout_type = TPipelineLayout;
1470 using descriptor_set_layout_type = pipeline_layout_type::descriptor_set_layout_type;
1471 using push_constants_layout_type = pipeline_layout_type::push_constants_layout_type;
1477 struct PipelineLayoutState {
1494 inline PipelineLayoutState& state() noexcept {
1504 template <
typename TSelf>
1506 self.m_state.descriptorSetLayouts.push_back(std::move(layout));
1507 return std::forward<TSelf>(self);
1515 template <
typename TSelf>
1517 self.m_state.pushConstantsLayout = std::move(layout);
1518 return std::forward<TSelf>(self);
1527 template <
typename TInputAssembler>
requires
1528 meta::implements<TInputAssembler, InputAssembler<typename TInputAssembler::vertex_buffer_layout_type, typename TInputAssembler::index_buffer_layout_type>>
1529 class InputAssemblerBuilder :
public Builder<TInputAssembler, std::nullptr_t, SharedPtr<TInputAssembler>> {
1532 using input_assembler_type = TInputAssembler;
1533 using vertex_buffer_layout_type = input_assembler_type::vertex_buffer_layout_type;
1534 using index_buffer_layout_type = input_assembler_type::index_buffer_layout_type;
1540 struct InputAssemblerState {
1562 inline InputAssemblerState& state() noexcept {
1571 template <
typename TSelf>
1572 constexpr auto topology(
this TSelf&& self,
PrimitiveTopology topology) -> TSelf&& {
1573 self.m_state.topology = topology;
1574 return std::forward<TSelf>(self);
1581 template <
typename TSelf>
1583 self.m_state.vertexBufferLayouts.push_back(std::move(layout));
1584 return std::forward<TSelf>(self);
1592 template <
typename TSelf>
1594 self.m_state.indexBufferLayout = std::move(layout);
1595 return std::forward<TSelf>(self);
1604 template <
typename TRenderPipeline>
requires
1605 meta::implements<TRenderPipeline, RenderPipeline<typename TRenderPipeline::pipeline_layout_type, typename TRenderPipeline::shader_program_type, typename TRenderPipeline::input_assembler_type, typename TRenderPipeline::rasterizer_type>>
1606 class RenderPipelineBuilder :
public Builder<TRenderPipeline> {
1609 using render_pipeline_type = TRenderPipeline;
1610 using pipeline_layout_type = render_pipeline_type::pipeline_layout_type;
1611 using shader_program_type = render_pipeline_type::shader_program_type;
1612 using input_assembler_type = render_pipeline_type::input_assembler_type;
1613 using rasterizer_type = render_pipeline_type::rasterizer_type;
1619 struct RenderPipelineState {
1643 bool enableAlphaToCoverage{
false };
1656 inline RenderPipelineState& state() noexcept {
1669 template <
typename TSelf>
1671 self.m_state.shaderProgram = std::move(program);
1672 return std::forward<TSelf>(self);
1679 template <
typename TSelf>
1681 self.m_state.pipelineLayout = std::move(layout);
1682 return std::forward<TSelf>(self);
1689 template <
typename TSelf>
1691 self.m_state.rasterizer = std::move(rasterizer);
1692 return std::forward<TSelf>(self);
1699 template <
typename TSelf>
1701 self.m_state.inputAssembler = std::move(inputAssembler);
1702 return std::forward<TSelf>(self);
1712 template <
typename TSelf>
1713 constexpr auto enableAlphaToCoverage(
this TSelf&& self,
bool enable =
true) -> TSelf&& {
1714 self.m_state.enableAlphaToCoverage = enable;
1715 return std::forward<TSelf>(self);
1722 template <
typename TSelf>
1724 self.m_state.samples = samples;
1725 return std::forward<TSelf>(self);
1734 template <
typename TComputePipeline>
requires
1735 meta::implements<TComputePipeline, ComputePipeline<typename TComputePipeline::pipeline_layout_type, typename TComputePipeline::shader_program_type>>
1736 class ComputePipelineBuilder :
public Builder<TComputePipeline> {
1739 using compute_pipeline_type = TComputePipeline;
1740 using pipeline_layout_type = compute_pipeline_type::pipeline_layout_type;
1741 using shader_program_type = compute_pipeline_type::shader_program_type;
1747 struct ComputePipelineState {
1764 inline ComputePipelineState& state() noexcept {
1777 template <
typename TSelf>
1779 self.m_state.shaderProgram = std::move(program);
1780 return std::forward<TSelf>(self);
1787 template <
typename TSelf>
1789 self.m_state.pipelineLayout = std::move(layout);
1790 return std::forward<TSelf>(self);
1799 template <
typename TRayTracingPipeline>
requires
1800 meta::implements<TRayTracingPipeline, RayTracingPipeline<typename TRayTracingPipeline::pipeline_layout_type, typename TRayTracingPipeline::shader_program_type>>
1801 class RayTracingPipelineBuilder :
public Builder<TRayTracingPipeline> {
1804 using raytracing_pipeline_type = TRayTracingPipeline;
1805 using pipeline_layout_type = raytracing_pipeline_type::pipeline_layout_type;
1806 using shader_program_type = raytracing_pipeline_type::shader_program_type;
1812 struct RayTracingPipelineState {
1821 UInt32 maxRecursionDepth { 10 };
1826 UInt32 maxPayloadSize { 0 };
1831 UInt32 maxAttributeSize { 32 };
1839 inline RayTracingPipelineState& state() noexcept {
1848 template <
typename TSelf>
1850 self.m_state.pipelineLayout = std::move(layout);
1851 return std::forward<TSelf>(self);
1858 template <
typename TSelf>
1859 constexpr auto maxBounces(
this TSelf&& self,
UInt32 maxRecursionDepth) -> TSelf&& {
1860 self.m_state.maxRecursionDepth = maxRecursionDepth;
1861 return std::forward<TSelf>(self);
1868 template <
typename TSelf>
1869 constexpr auto maxPayloadSize(
this TSelf&& self,
UInt32 maxPayloadSize) -> TSelf&& {
1870 self.m_state.maxPayloadSize = maxPayloadSize;
1871 return std::forward<TSelf>(self);
1878 template <
typename TSelf>
1879 constexpr auto maxAttributeSize(
this TSelf&& self,
UInt32 maxAttributeSize) -> TSelf&& {
1880 self.m_state.maxAttributeSize = maxAttributeSize;
1881 return std::forward<TSelf>(self);
1891 template <
typename TRenderPass>
requires
1892 meta::implements<TRenderPass, RenderPass<typename TRenderPass::command_queue_type, typename TRenderPass::frame_buffer_type>>
1893 class RenderPassBuilder :
public Builder<TRenderPass, std::nullptr_t, SharedPtr<TRenderPass>> {
1896 using render_pass_type = TRenderPass;
1897 using command_queue_type = render_pass_type::command_queue_type;
1903 struct RenderPassState {
1907 UInt32 commandBufferCount{ 0 };
1933 UInt32 viewMask{ 0b0000 };
1941 inline RenderPassState& state() noexcept {
1962 template <
typename TSelf>
1963 constexpr auto executeOn(
this TSelf&& self,
const command_queue_type& queue) -> TSelf&& {
1964 self.m_state.commandQueue = queue.shared_from_this();
1965 return std::forward<TSelf>(self);
1972 template <
typename TSelf>
1973 constexpr auto commandBuffers(
this TSelf&& self,
UInt32 count) -> TSelf&& {
1974 self.m_state.commandBufferCount = count;
1975 return std::forward<TSelf>(self);
1985 template <
typename TSelf>
1987 self.renderTarget(
"",
static_cast<UInt32>(self.m_state.renderTargets.size()), type, format, flags, clearValues);
1988 return std::forward<TSelf>(self);
1999 template <
typename TSelf>
2001 self.renderTarget(name,
static_cast<UInt32>(self.m_state.renderTargets.size()), type, format, flags, clearValues);
2002 return std::forward<TSelf>(self);
2013 template <
typename TSelf>
2015 self.renderTarget(
"", location, type, format, flags, clearValues);
2016 return std::forward<TSelf>(self);
2028 template <
typename TSelf>
2030 self.m_state.renderTargets.push_back(
RenderTarget(name, location, type, format, flags, clearValues));
2031 return std::forward<TSelf>(self);
2040 template <
typename TSelf>
2041 constexpr auto inputAttachment(
this TSelf&& self,
DescriptorBindingPoint binding,
const render_pass_type& renderPass,
UInt32 outputLocation) -> TSelf&& {
2042 self.m_state.inputAttachments.push_back(
static_cast<RenderPassBuilder&
>(self).makeInputAttachment(binding, renderPass.renderTarget(outputLocation)));
2043 return std::forward<TSelf>(self);
2051 template <
typename TSelf>
2053 self.m_state.inputAttachments.push_back(
static_cast<RenderPassBuilder&
>(self).makeInputAttachment(binding, renderTarget));
2054 return std::forward<TSelf>(self);
2061 template <
typename TSelf>
2062 constexpr auto inputAttachmentSamplerBinding(
this TSelf&& self,
const DescriptorBindingPoint& bindingPoint) -> TSelf&& {
2063 self.m_state.inputAttachmentSamplerBinding = bindingPoint;
2064 return std::forward<TSelf>(self);
2071 template <
typename TSelf>
2072 constexpr auto inputAttachmentSamplerBinding(
this TSelf&& self,
UInt32 viewMask) -> TSelf&& {
2073 self.m_state.viewMask = viewMask;
2074 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:4437
Base interface for buffer objects.
Definition rendering_api.hpp:4997
Describes a generic image.
Definition rendering_api.hpp:5019
Represents a mapping between a set of RenderTarget instances and the input attachments of a IRenderPa...
Definition rendering_api.hpp:3684
Implements a render target.
Definition rendering_api.hpp:3584
float_t Float
A type for a floating point value with single precision.
Definition math.hpp:76
uint32_t UInt32
A type for an unsigned 32 bit integer.
Definition math.hpp:61
BorderMode
Describes how to treat texture coordinates that are outside the domain [0..1].
Definition rendering_api.hpp:1356
CullOrder
Describes the order or vertex winding, that is used to determine, whether a polygon is facing towards...
Definition rendering_api.hpp:1190
RenderTargetFlags
Describes the behavior of render targets.
Definition rendering_api.hpp:1228
ImageLayout
Specifies the layout of an IImage resource.
Definition rendering_api.hpp:1858
MipMapMode
Describes the filter operation between two mip-map levels.
Definition rendering_api.hpp:1341
CullMode
Describes which faces are culled by the Rasterizer stage.
Definition rendering_api.hpp:1163
ShaderStage
Describes the valid shader stages of a graphics pipeline.
Definition rendering_api.hpp:971
RenderTargetType
Describes the type of a render target.
Definition rendering_api.hpp:1205
PrimitiveTopology
Describes the topology of a mesh primitive.
Definition rendering_api.hpp:937
PolygonMode
Describes the draw mode for polygons.
Definition rendering_api.hpp:1142
AttributeSemantic
Describes the semantic of a buffer attribute.
Definition rendering_api.hpp:372
@ RenderTarget
Allows the resource to be used as a render target.
DescriptorType
Describes the type of a IDescriptor.
Definition rendering_api.hpp:442
FilterMode
Describes the filter operation when accessing a pixel from a texture coordinate.
Definition rendering_api.hpp:1324
VertexBufferInputRate
The rate at which a vertex buffer of a certain IVertexBufferLayout is made available for vertex shade...
Definition rendering_api.hpp:922
PipelineStage
Defines pipeline stages as points where synchronization may occur.
Definition rendering_api.hpp:1545
BufferFormat
Describes a buffer attribute format.
Definition rendering_api.hpp:340
ResourceAccess
Defines how a IBuffer or IImage resource is accessed.
Definition rendering_api.hpp:1709
Format
Describes a texel format.
Definition rendering_api.hpp:183
MultiSamplingLevel
Describes the number of samples with which a IImage is sampled.
Definition rendering_api.hpp:1283
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:3797
Describes the rasterizer depth state.
Definition rendering_api.hpp:3758
Describes the rasterizer stencil state.
Definition rendering_api.hpp:3849
Describes a single descriptor binding point within a IShaderModule.
Definition rendering_api.hpp:3309