3#include "spark/render/Buffer.h"
4#include "spark/render/DescriptorBinding.h"
5#include "spark/render/Export.h"
6#include "spark/render/Sampler.h"
7#include "spark/render/ShaderStages.h"
12namespace spark::render
18 enum class DescriptorType
23 ConstantBuffer = 0x00000001,
28 StructuredBuffer = 0x00000002,
31 RWStructuredBuffer = 0x00000012,
39 RWTexture = 0x00000013,
45 InputAttachment = 0x00000005,
51 RWBuffer = 0x00000016,
54 ByteAddressBuffer = 0x00000007,
57 RWByteAddressBuffer = 0x00000017,
90 [[nodiscard]] virtual
unsigned int descriptors() const noexcept = 0;
96 [[nodiscard]] virtual const
ISampler* staticSampler() const noexcept = 0;
115 void update(
unsigned int binding,
const IBuffer& buffer,
unsigned int buffer_element = 0,
unsigned int elements = 0,
unsigned int first_descriptor = 0)
const
117 genericUpdate(binding, buffer, buffer_element, elements, first_descriptor);
132 unsigned int descriptor = 0,
133 unsigned int first_level = 0,
134 unsigned int levels = 0,
135 unsigned int first_layer = 0,
136 unsigned int layers = 0)
const { genericUpdate(binding, texture, descriptor, first_level, levels, first_layer, layers); }
144 void update(
unsigned int binding,
const ISampler& sampler,
unsigned int descriptor = 0)
const { genericUpdate(binding, sampler, descriptor); }
151 void attach(
unsigned int binding,
const IImage& image)
const { genericAttach(binding, image); }
156 virtual void genericUpdate(
unsigned int binding,
const IBuffer& buffer,
unsigned int buffer_element,
unsigned int elements,
unsigned int first_descriptor)
const = 0;
157 virtual void genericUpdate(
unsigned int binding,
159 unsigned int descriptor,
160 unsigned int first_level,
162 unsigned int first_layer,
163 unsigned int layers)
const = 0;
164 virtual void genericUpdate(
unsigned int binding,
const ISampler& sampler,
unsigned int descriptor)
const = 0;
165 virtual void genericAttach(
unsigned int binding,
const IImage& image)
const = 0;
209 template <
typename BufferType,
typename ImageType,
typename SamplerType>
213 using buffer_type = BufferType;
214 using image_type = ImageType;
215 using sampler_type = SamplerType;
219 virtual void update(
unsigned int binding,
220 const buffer_type& buffer,
221 unsigned int buffer_element = 0,
222 unsigned int elements = 0,
223 unsigned int first_descriptor = 0)
const = 0;
226 virtual void update(
unsigned int binding,
227 const image_type& texture,
228 unsigned int descriptor = 0,
229 unsigned int first_level = 0,
230 unsigned int levels = 0,
231 unsigned int first_layer = 0,
232 unsigned int layers = 0)
const = 0;
235 virtual void update(
unsigned int binding,
const sampler_type& sampler,
unsigned int descriptor = 0)
const = 0;
238 virtual void attach(
unsigned int binding,
const image_type& image)
const = 0;
241 void genericUpdate(
unsigned binding,
const IBuffer& buffer,
unsigned buffer_element,
unsigned elements,
unsigned first_descriptor)
const final
243 update(binding,
dynamic_cast<const buffer_type&
>(buffer), buffer_element, elements, first_descriptor);
246 void genericUpdate(
unsigned binding,
249 unsigned first_level,
251 unsigned first_layer,
252 unsigned layers)
const override { update(binding,
dynamic_cast<const image_type&
>(texture), descriptor, first_level, levels, first_layer, layers); }
254 void genericUpdate(
unsigned binding,
const ISampler& sampler,
unsigned descriptor)
const final { update(binding,
dynamic_cast<const sampler_type&
>(sampler), descriptor); }
255 void genericAttach(
unsigned binding,
const IImage& image)
const final { attach(binding,
dynamic_cast<const image_type&
>(image)); }
270 [[nodiscard]] std::vector<const IDescriptorLayout*>
descriptors() const noexcept {
return genericDescriptors(); }
285 [[nodiscard]]
virtual unsigned int space() const noexcept = 0;
291 [[nodiscard]] virtual ShaderStage shaderStage() const noexcept = 0;
297 [[nodiscard]] virtual
unsigned int uniforms() const noexcept = 0;
303 [[nodiscard]] virtual
unsigned int storages() const noexcept = 0;
309 [[nodiscard]] virtual
unsigned int images() const noexcept = 0;
315 [[nodiscard]] virtual
unsigned int buffers() const noexcept = 0;
321 [[nodiscard]] virtual
unsigned int samplers() const noexcept = 0;
327 [[nodiscard]] virtual
unsigned int staticSamplers() const noexcept = 0;
333 [[nodiscard]] virtual
unsigned int inputAttachments() const noexcept = 0;
367 [[nodiscard]] std::unique_ptr<IDescriptorSet>
allocate(
unsigned int descriptors,
const std::vector<DescriptorBinding>& bindings = {})
const
369 return genericAllocate(descriptors, bindings);
378 [[nodiscard]] std::vector<std::unique_ptr<IDescriptorSet>>
allocateMultiple(
unsigned int descriptors_sets,
379 const std::vector<std::vector<DescriptorBinding>>& bindings = {})
const noexcept
381 return allocateMultiple(descriptors_sets, 0, bindings);
390 [[nodiscard]] std::vector<std::unique_ptr<IDescriptorSet>>
allocateMultiple(
unsigned int descriptors_sets,
391 const std::function<std::vector<DescriptorBinding>(
unsigned)>& binding_factory)
const noexcept
393 return allocateMultiple(descriptors_sets, 0, binding_factory);
403 [[nodiscard]] std::vector<std::unique_ptr<IDescriptorSet>>
allocateMultiple(
unsigned int descriptors_sets,
404 unsigned int descriptors,
405 const std::vector<std::vector<DescriptorBinding>>& bindings = {})
const noexcept
407 return genericAllocate(descriptors_sets, descriptors, bindings);
417 [[nodiscard]] std::vector<std::unique_ptr<IDescriptorSet>>
allocateMultiple(
unsigned int descriptors_sets,
418 unsigned int descriptors,
419 const std::function<std::vector<DescriptorBinding>(
unsigned)>& binding_factory = {})
const
420 noexcept {
return genericAllocate(descriptors_sets, descriptors, binding_factory); }
431 [[nodiscard]]
virtual std::vector<const IDescriptorLayout*> genericDescriptors() const noexcept = 0;
432 [[nodiscard]] virtual std::unique_ptr<
IDescriptorSet> genericAllocate(
unsigned int descriptors, const std::vector<
DescriptorBinding>& bindings) const noexcept = 0;
433 [[nodiscard]] virtual std::vector<std::unique_ptr<
IDescriptorSet>> genericAllocate(
unsigned descriptor_sets,
434 unsigned descriptors,
436 [[nodiscard]] virtual std::vector<std::unique_ptr<
IDescriptorSet>> genericAllocate(
unsigned descriptor_sets,
437 unsigned descriptors,
438 const std::function<std::vector<
DescriptorBinding>(
unsigned)>& binding_factory) const =
440 virtual
void genericFree(const
IDescriptorSet& descriptor_set) const noexcept = 0;
449 template <typename DescriptorLayoutType, typename DescriptorSetType>
453 using descriptor_layout_type = DescriptorLayoutType;
454 using descriptor_set_type = DescriptorSetType;
458 [[nodiscard]]
virtual std::vector<const descriptor_layout_type*>
descriptors() const noexcept = 0;
461 [[nodiscard]] const descriptor_layout_type* descriptor(
unsigned binding) const override = 0;
464 [[nodiscard]] virtual std::unique_ptr<descriptor_set_type> allocate(const std::vector<
DescriptorBinding>& bindings = {})
const = 0;
467 [[nodiscard]]
virtual std::unique_ptr<descriptor_set_type>
allocate(
unsigned descriptors,
const std::vector<DescriptorBinding>& bindings = { })
const = 0;
470 [[nodiscard]]
virtual std::vector<std::unique_ptr<descriptor_set_type>>
allocateMultiple(
unsigned descriptor_sets,
const std::vector<std::vector<DescriptorBinding>>& bindings = { })
const = 0;
473 [[nodiscard]]
virtual std::vector<std::unique_ptr<descriptor_set_type>>
allocateMultiple(
unsigned descriptor_sets,
const std::function<std::vector<DescriptorBinding>(
unsigned)>& binding_factory)
const = 0;
476 [[nodiscard]]
virtual std::vector<std::unique_ptr<descriptor_set_type>>
allocateMultiple(
unsigned descriptor_sets,
unsigned descriptors,
const std::vector<std::vector<DescriptorBinding>>& bindings = { })
const = 0;
479 [[nodiscard]]
virtual std::vector<std::unique_ptr<descriptor_set_type>>
allocateMultiple(
unsigned descriptor_sets,
unsigned descriptors,
const std::function<std::vector<DescriptorBinding>(
unsigned)>& binding_factory)
const = 0;
482 virtual void free(
const descriptor_set_type& descriptor_set)
const noexcept = 0;
485 [[nodiscard]] std::vector<const IDescriptorLayout*> genericDescriptors() const noexcept final
487 auto tmp = descriptors();
488 std::vector<const IDescriptorLayout*> result;
489 result.reserve(tmp.size());
490 std::ranges::transform(tmp, std::back_inserter(result), [](
auto& ptr) {
return static_cast<const IDescriptorLayout*
>(ptr); });
494 [[nodiscard]] std::unique_ptr<IDescriptorSet> genericAllocate(
unsigned descriptors,
const std::vector<DescriptorBinding>& bindings)
const noexcept final
496 return allocate(descriptors, bindings);
499 [[nodiscard]] std::vector<std::unique_ptr<IDescriptorSet>> genericAllocate(
unsigned descriptor_sets,
500 unsigned descriptors,
501 const std::vector<std::vector<DescriptorBinding>>& bindings)
const final
503 auto tmp = allocateMultiple(descriptor_sets, descriptors, bindings);
504 std::vector<std::unique_ptr<IDescriptorSet>> result;
505 result.reserve(tmp.size());
506 std::ranges::transform(tmp, std::back_inserter(result), [](
auto& ptr) {
return std::unique_ptr<IDescriptorSet>(ptr.release()); });
510 [[nodiscard]] std::vector<std::unique_ptr<IDescriptorSet>> genericAllocate(
unsigned descriptor_sets,
511 unsigned descriptors,
512 const std::function<std::vector<DescriptorBinding>(
unsigned)>& binding_factory)
const final
514 auto tmp = allocateMultiple(descriptor_sets, descriptors, binding_factory);
515 std::vector<std::unique_ptr<IDescriptorSet>> result;
516 result.reserve(tmp.size());
517 std::ranges::transform(tmp, std::back_inserter(result), [](
auto& ptr) {
return std::unique_ptr<IDescriptorSet>(ptr.release()); });
521 void genericFree(
const IDescriptorSet& descriptor_set)
const noexcept final { free(
dynamic_cast<const descriptor_set_type&
>(descriptor_set)); }
526struct std::formatter<spark::render::DescriptorType> : std::formatter<std::string_view>
528 static constexpr auto parse(format_parse_context& ctx) {
return ctx.begin(); }
530 static constexpr auto format(
const spark::render::DescriptorType type,
auto& ctx)
534 case spark::render::DescriptorType::ConstantBuffer:
535 return std::format_to(ctx.out(),
"ConstantBuffer");
536 case spark::render::DescriptorType::StructuredBuffer:
537 return std::format_to(ctx.out(),
"StructuredBuffer");
538 case spark::render::DescriptorType::RWStructuredBuffer:
539 return std::format_to(ctx.out(),
"RWStructuredBuffer");
540 case spark::render::DescriptorType::Texture:
541 return std::format_to(ctx.out(),
"Texture");
542 case spark::render::DescriptorType::RWTexture:
543 return std::format_to(ctx.out(),
"RWTexture");
544 case spark::render::DescriptorType::Sampler:
545 return std::format_to(ctx.out(),
"Sampler");
546 case spark::render::DescriptorType::InputAttachment:
547 return std::format_to(ctx.out(),
"InputAttachment");
548 case spark::render::DescriptorType::Buffer:
549 return std::format_to(ctx.out(),
"Buffer");
550 case spark::render::DescriptorType::RWBuffer:
551 return std::format_to(ctx.out(),
"RWBuffer");
552 case spark::render::DescriptorType::ByteAddressBuffer:
553 return std::format_to(ctx.out(),
"ByteAddressBuffer");
554 case spark::render::DescriptorType::RWByteAddressBuffer:
555 return std::format_to(ctx.out(),
"RWByteAddressBuffer");
557 return std::format_to(ctx.out(),
"Unknown");
Describes the layout of a descriptor set.
Definition DescriptorSet.h:451
virtual std::vector< std::unique_ptr< descriptor_set_type > > allocateMultiple(unsigned descriptor_sets, unsigned descriptors, const std::function< std::vector< DescriptorBinding >(unsigned)> &binding_factory) const =0
Allocates an array of IDescriptorSet.
virtual std::unique_ptr< descriptor_set_type > allocate(unsigned descriptors, const std::vector< DescriptorBinding > &bindings={ }) const =0
Allocates a new IDescriptorSet or returns an unused descriptor set.
virtual void free(const descriptor_set_type &descriptor_set) const noexcept=0
Marks a IDescriptorSet as unused, so that it can be handed out again instead of allocating a new one.
virtual std::vector< std::unique_ptr< descriptor_set_type > > allocateMultiple(unsigned descriptor_sets, const std::function< std::vector< DescriptorBinding >(unsigned)> &binding_factory) const =0
Allocates an array of IDescriptorSet.
virtual std::vector< const descriptor_layout_type * > descriptors() const noexcept=0
Gets the layouts of all descriptors in the IDescriptorSet.
virtual std::vector< std::unique_ptr< descriptor_set_type > > allocateMultiple(unsigned descriptor_sets, const std::vector< std::vector< DescriptorBinding > > &bindings={ }) const =0
Allocates an array of IDescriptorSet.
virtual std::vector< std::unique_ptr< descriptor_set_type > > allocateMultiple(unsigned descriptor_sets, unsigned descriptors, const std::vector< std::vector< DescriptorBinding > > &bindings={ }) const =0
Allocates an array of IDescriptorSet.
Defines a set of descriptors.
Definition DescriptorSet.h:211
virtual void update(unsigned int binding, const buffer_type &buffer, unsigned int buffer_element=0, unsigned int elements=0, unsigned int first_descriptor=0) const =0
Updates a constant buffer within the IDescriptorSet.
virtual void update(unsigned int binding, const image_type &texture, unsigned int descriptor=0, unsigned int first_level=0, unsigned int levels=0, unsigned int first_layer=0, unsigned int layers=0) const =0
Updates a constant buffer within the IDescriptorSet.
virtual void attach(unsigned int binding, const image_type &image) const =0
Attaches an image as an input attachment to a descriptor bound at binding.
virtual void update(unsigned int binding, const sampler_type &sampler, unsigned int descriptor=0) const =0
Updates a constant buffer within the IDescriptorSet.
Describes the layout of a buffer.
Definition Buffer.h:166
Base interface for all buffers.
Definition Buffer.h:151
Describes a the layout of a single descriptor within a DescriptorSet.
Definition DescriptorSet.h:74
virtual DescriptorType descriptorType() const noexcept=0
Gets the type of the descriptor.
Interface for a descriptor set layout.
Definition DescriptorSet.h:262
std::vector< std::unique_ptr< IDescriptorSet > > allocateMultiple(unsigned int descriptors_sets, const std::function< std::vector< DescriptorBinding >(unsigned)> &binding_factory) const noexcept
Allocates an array of IDescriptorSet.
Definition DescriptorSet.h:390
void free(const IDescriptorSet &descriptor_set) const noexcept
Marks a IDescriptorSet as unused, so that it can be handed out again instead of allocating a new one.
Definition DescriptorSet.h:426
std::unique_ptr< IDescriptorSet > allocate(unsigned int descriptors, const std::vector< DescriptorBinding > &bindings={}) const
Allocates a new IDescriptorSet or returns an unused descriptor set.
Definition DescriptorSet.h:367
virtual unsigned int space() const noexcept=0
Gets the space index of the IDescriptorSet.
virtual const IDescriptorLayout * descriptor(unsigned int binding) const =0
Gets the layout of a descriptor in the IDescriptorSet bound to a specific binding point.
std::vector< std::unique_ptr< IDescriptorSet > > allocateMultiple(unsigned int descriptors_sets, const std::vector< std::vector< DescriptorBinding > > &bindings={}) const noexcept
Allocates an array of IDescriptorSet.
Definition DescriptorSet.h:378
std::vector< const IDescriptorLayout * > descriptors() const noexcept
Gets the layouts of all descriptors in the IDescriptorSet.
Definition DescriptorSet.h:270
std::vector< std::unique_ptr< IDescriptorSet > > allocateMultiple(unsigned int descriptors_sets, unsigned int descriptors, const std::function< std::vector< DescriptorBinding >(unsigned)> &binding_factory={}) const noexcept
Allocates an array of IDescriptorSet.
Definition DescriptorSet.h:417
std::vector< std::unique_ptr< IDescriptorSet > > allocateMultiple(unsigned int descriptors_sets, unsigned int descriptors, const std::vector< std::vector< DescriptorBinding > > &bindings={}) const noexcept
Allocates an array of IDescriptorSet.
Definition DescriptorSet.h:403
Interface for a descriptor set.
Definition DescriptorSet.h:103
void attach(unsigned int binding, const IImage &image) const
Attaches an image as an input attachment to a descriptor bound at binding.
Definition DescriptorSet.h:151
void update(unsigned int binding, const ISampler &sampler, unsigned int descriptor=0) const
Updates a sampler within the current descriptor set.
Definition DescriptorSet.h:144
void update(unsigned int binding, const IBuffer &buffer, unsigned int buffer_element=0, unsigned int elements=0, unsigned int first_descriptor=0) const
Updates a constant buffer within the IDescriptorSet.
Definition DescriptorSet.h:115
void update(unsigned int binding, const IImage &texture, unsigned int descriptor=0, unsigned int first_level=0, unsigned int levels=0, unsigned int first_layer=0, unsigned int layers=0) const
Updates a texture within the current descriptor set.
Definition DescriptorSet.h:130
Describes a texture sampler.
Definition Sampler.h:59
Describes a resource binding in a descriptor set.
Definition DescriptorBinding.h:18