101 if (blocks_.
is_empty() || blocks_.
last()->size() == block_size) {
104 return blocks_.
last()->append_and_get_index(std::move(elem)) +
105 (blocks_.
size() - 1) * block_size;
110 return (*blocks_[index / block_size])[index % block_size];
115 return (*blocks_[index / block_size])[index % block_size];
124 typename DrawCommandBufType>
155 DrawCommandBufType &draw_command_buf,
157 GPUShader *shader =
nullptr)
248 bool deferred_texture_loading =
false);
256 uint instance_len = -1,
257 uint vertex_len = -1,
258 uint vertex_first = -1,
275 uint vertex_first = -1,
296 uint vertex_len = -1,
297 uint vertex_first = -1,
442 resources.bind_resources(*
this);
448 std::string
serialize(std::string line_prefix =
"")
const;
496 DrawCommandBufType draw_commands_buf_main_;
500 : detail::
PassBase<DrawCommandBufType>(
name, draw_commands_buf_main_, sub_passes_main_){};
504 this->manager_fingerprint_ = 0;
505 this->view_fingerprint_ = 0;
506 this->headers_.
clear();
507 this->commands_.
clear();
508 this->sub_passes_.
clear();
509 this->draw_commands_buf_.clear();
510 this->is_empty_ =
true;
547 bool sorted_ =
false;
554 sorting_values_.
clear();
572 }
while (sorting_index != index);
576 std::string
serialize(std::string line_prefix =
"")
const
578 if (sorted_ ==
false) {
587 if (sorted_ ==
false) {
589 BLI_assert(a.type == Type::SubPass && b.type == Type::SubPass);
590 float a_val = sorting_values_[a.index];
591 float b_val = sorting_values_[b.index];
592 return a_val < b_val || (a_val == b_val && a.index < b.index);
614 if (header.type != Type::SubPass) {
617 if (!sub_passes_[header.index].is_empty()) {
629 BLI_assert_msg(this->has_generated_commands() ==
false,
"Command added after submission");
638 Type::DispatchIndirect,
645 return commands_[index];
654 create_command(command::Type::Clear).
clear = {
uint8_t(planes), stencil, depth, color};
659 create_command(command::Type::ClearMulti).
clear_multi = {colors.
data(),
660 static_cast<int>(colors.
size())};
684 PassBase(
name, draw_commands_buf_, sub_passes_, shader_));
685 headers_.
append({command::Type::SubPass,
uint(index)});
686 return sub_passes_[index];
696 switch (header.type) {
701 sub_passes_[header.index].warm_shader_specialization(
state);
703 case command::Type::FramebufferBind:
705 case command::Type::SubPassTransition:
707 case command::Type::ShaderBind:
708 commands_[header.index].shader_bind.execute(
state);
710 case command::Type::ResourceBind:
712 case command::Type::PushConstant:
714 case command::Type::SpecializeConstant:
715 commands_[header.index].specialize_constant.execute(
state);
717 case command::Type::Draw:
719 case command::Type::DrawMulti:
721 case command::Type::DrawIndirect:
723 case command::Type::Dispatch:
725 case command::Type::DispatchIndirect:
727 case command::Type::Barrier:
729 case command::Type::Clear:
731 case command::Type::ClearMulti:
733 case command::Type::StateSet:
735 case command::Type::StencilSet:
753 switch (header.type) {
758 sub_passes_[header.index].submit(
state);
760 case command::Type::FramebufferBind:
761 commands_[header.index].framebuffer_bind.execute();
763 case command::Type::SubPassTransition:
764 commands_[header.index].subpass_transition.execute();
766 case command::Type::ShaderBind:
767 commands_[header.index].shader_bind.execute(
state);
769 case command::Type::ResourceBind:
770 commands_[header.index].resource_bind.execute();
772 case command::Type::PushConstant:
773 commands_[header.index].push_constant.execute(
state);
775 case command::Type::SpecializeConstant:
776 commands_[header.index].specialize_constant.execute(
state);
778 case command::Type::Draw:
779 commands_[header.index].draw.execute(
state);
781 case command::Type::DrawMulti:
782 commands_[header.index].draw_multi.execute(
state);
784 case command::Type::DrawIndirect:
785 commands_[header.index].draw_indirect.execute(
state);
787 case command::Type::Dispatch:
788 commands_[header.index].dispatch.execute(
state);
790 case command::Type::DispatchIndirect:
791 commands_[header.index].dispatch_indirect.execute(
state);
793 case command::Type::Barrier:
794 commands_[header.index].barrier.execute();
796 case command::Type::Clear:
797 commands_[header.index].
clear.execute();
799 case command::Type::ClearMulti:
800 commands_[header.index].clear_multi.execute();
802 case command::Type::StateSet:
803 commands_[header.index].state_set.execute(
state);
805 case command::Type::StencilSet:
806 commands_[header.index].stencil_set.execute();
816 std::stringstream ss;
817 ss << line_prefix <<
"." << debug_name << std::endl;
820 switch (header.type) {
825 ss << sub_passes_[header.index].serialize(line_prefix);
827 case Type::FramebufferBind:
828 ss << line_prefix << commands_[header.index].framebuffer_bind.serialize() << std::endl;
830 case Type::SubPassTransition:
831 ss << line_prefix << commands_[header.index].subpass_transition.serialize() << std::endl;
833 case Type::ShaderBind:
834 ss << line_prefix << commands_[header.index].shader_bind.serialize() << std::endl;
836 case Type::ResourceBind:
837 ss << line_prefix << commands_[header.index].resource_bind.serialize() << std::endl;
839 case Type::PushConstant:
840 ss << line_prefix << commands_[header.index].push_constant.serialize() << std::endl;
843 ss << line_prefix << commands_[header.index].draw.serialize() << std::endl;
845 case Type::DrawMulti:
846 ss << commands_[header.index].draw_multi.serialize(line_prefix);
848 case Type::DrawIndirect:
849 ss << line_prefix << commands_[header.index].draw_indirect.serialize() << std::endl;
852 ss << line_prefix << commands_[header.index].dispatch.serialize() << std::endl;
854 case Type::DispatchIndirect:
855 ss << line_prefix << commands_[header.index].dispatch_indirect.serialize() << std::endl;
858 ss << line_prefix << commands_[header.index].barrier.serialize() << std::endl;
861 ss << line_prefix << commands_[header.index].
clear.serialize() << std::endl;
863 case Type::ClearMulti:
864 ss << line_prefix << commands_[header.index].clear_multi.serialize() << std::endl;
867 ss << line_prefix << commands_[header.index].state_set.serialize() << std::endl;
869 case Type::StencilSet:
870 ss << line_prefix << commands_[header.index].stencil_set.serialize() << std::endl;
891 if (instance_len == 0 || vertex_len == 0) {
895 draw_commands_buf_.append_draw(headers_,
911 this->draw(
batch, -1, -1, -1, handle, custom_id);
924 if (instance_len == 0 || vertex_len == 0 || primitive_len == 0) {
928 draw_commands_buf_.append_draw(headers_,
949 this->draw_expand(
batch, primitive_type, primitive_len, instance_len, -1, -1, handle, custom_id);
961 procedural_batch_get(primitive), instance_len, vertex_len, vertex_first, handle, custom_id);
976 create_command(Type::DrawIndirect).draw_indirect = {
batch, &indirect_buffer, handle};
985 this->draw_indirect(procedural_batch_get(primitive), indirect_buffer, handle);
997 create_command(Type::Dispatch).dispatch = {
int3(group_len, 1, 1)};
1003 create_command(Type::Dispatch).dispatch = {
int3(group_len.x, group_len.y, 1)};
1009 create_command(Type::Dispatch).dispatch = {group_len};
1015 create_command(Type::Dispatch).dispatch = {group_len};
1022 create_command(Type::DispatchIndirect).dispatch_indirect = {&indirect_buffer};
1065 create_command(Type::Barrier).
barrier = {type};
1077 if (clip_plane_count > 0) {
1082 create_command(Type::StateSet).
state_set = {
state, clip_plane_count};
1088 create_command(Type::StencilSet).stencil_set = {write_mask, compare_mask, reference};
1094 create_command(Type::ShaderBind).shader_bind = {shader};
1099 create_command(Type::FramebufferBind).framebuffer_bind = {framebuffer};
1108 color_states[i] =
uint8_t(color_attachments[i]);
1110 create_command(Type::SubPassTransition).subpass_transition = {
uint8_t(depth_attachment),
1124 bool deferred_texture_loading)
1134 const bool use_tile_mapping =
tex->tiled_mapping_name[0];
1138 if (deferred_texture_loading) {
1145 if (*gputex.
texture ==
nullptr) {
1148 bind_texture(
tex->sampler_name, gputex.
texture,
tex->sampler_state);
1156 bind_texture(
tex->sampler_name, *gputex.
texture,
tex->sampler_state);
1163 else if (
tex->colorband) {
1165 bind_texture(
tex->sampler_name, *
tex->colorband);
1167 else if (
tex->sky) {
1169 bind_texture(
tex->sampler_name, *
tex->sky,
tex->sampler_state);
1174 if (ubo !=
nullptr) {
1266 create_command(Type::ResourceBind).resource_bind = {slot, buffer};
1272 create_command(Type::ResourceBind).resource_bind = {
1273 slot, buffer, ResourceBind::Type::UniformAsStorageBuf};
1279 create_command(Type::ResourceBind).resource_bind = {
1280 slot, buffer, ResourceBind::Type::UniformAsStorageBuf};
1286 create_command(Type::ResourceBind).resource_bind = {
1287 slot, buffer, ResourceBind::Type::VertexAsStorageBuf};
1293 create_command(Type::ResourceBind).resource_bind = {
1294 slot, buffer, ResourceBind::Type::VertexAsStorageBuf};
1300 create_command(Type::ResourceBind).resource_bind = {
1301 slot, buffer, ResourceBind::Type::IndexAsStorageBuf};
1307 create_command(Type::ResourceBind).resource_bind = {
1308 slot, buffer, ResourceBind::Type::IndexAsStorageBuf};
1314 create_command(Type::ResourceBind).resource_bind = {slot, buffer};
1321 create_command(Type::ResourceBind).resource_bind = {slot,
texture,
state};
1327 create_command(Type::ResourceBind).resource_bind = {slot, buffer};
1333 create_command(Type::ResourceBind).resource_bind = {slot, buffer};
1339 create_command(Type::ResourceBind).resource_bind = {slot, as_image(image)};
1373 create_command(Type::ResourceBind).resource_bind = {slot, buffer};
1379 create_command(Type::ResourceBind).resource_bind = {slot, buffer};
1386 create_command(Type::ResourceBind).resource_bind = {slot,
texture,
state};
1392 create_command(Type::ResourceBind).resource_bind = {slot, as_image(image)};
1509 cmd.
type = PushConstant::Type::FloatValue;
1513 create_command(Type::PushConstant) = commands[0];
1514 create_command(Type::None) = commands[1];
1515 create_command(Type::None) = commands[2];
1526 const char *constant_name,
1527 const int &constant_value)
1535 const char *constant_name,
1536 const uint &constant_value)
1544 const char *constant_name,
1545 const float &constant_value)
1553 const char *constant_name,
1554 const bool &constant_value)
1562 const char *constant_name,
1563 const int *constant_value)
1571 const char *constant_name,
1572 const uint *constant_value)
1580 const char *constant_name,
1581 const float *constant_value)
1589 const char *constant_name,
1590 const bool *constant_value)
ImageGPUTextures BKE_image_get_gpu_material_texture_try(Image *image, ImageUser *iuser, const bool use_tile_mapping)
ImageGPUTextures BKE_image_get_gpu_material_texture(Image *image, ImageUser *iuser, const bool use_tile_mapping)
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
blender::gpu::Batch * GPU_batch_procedural_triangle_strips_get()
blender::gpu::Batch * GPU_batch_procedural_lines_get()
blender::gpu::Batch * GPU_batch_procedural_points_get()
blender::gpu::Batch * GPU_batch_procedural_triangles_get()
void GPU_debug_group_end()
void GPU_debug_group_begin(const char *name)
GPUPass * GPU_material_get_pass(GPUMaterial *material)
ListBase GPU_material_textures(GPUMaterial *material)
GPUUniformBuf * GPU_material_uniform_buffer_get(GPUMaterial *material)
GPUShader * GPU_pass_shader_get(GPUPass *pass)
int GPU_shader_get_sampler_binding(GPUShader *shader, const char *name)
int GPU_shader_get_uniform(GPUShader *shader, const char *name)
int GPU_shader_get_ubo_binding(GPUShader *shader, const char *name)
int GPU_shader_get_ssbo_binding(GPUShader *shader, const char *name)
int GPU_shader_get_constant(GPUShader *shader, const char *name)
constexpr const T * data() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
int64_t append_and_get_index(const T &value)
void append(const T &value)
const T & last(const int64_t n=0) const
void acquire_texture(GPUTexture *texture)
std::string serialize(std::string line_prefix="") const
PassSortable(const char *name_)
PassMain::Sub & sub(const char *name, float sorting_value)
void bind_ssbo(int slot, gpu::IndexBuf *buffer)
void clear_multi(Span< float4 > colors)
void bind_texture(const char *name, GPUTexture *texture, GPUSamplerState state=sampler_auto)
void specialize_constant(GPUShader *shader, const char *name, const uint &data)
void bind_texture(const char *name, GPUTexture **texture, GPUSamplerState state=sampler_auto)
void push_constant(const char *name, const float3 *data, int array_len=1)
void dispatch(StorageBuffer< DispatchCommand > &indirect_buffer)
void push_constant(const char *name, const int *data, int array_len=1)
void bind_texture(int slot, gpu::VertBuf *buffer)
void push_constant(const char *name, const int &data)
void bind_resources(U &resources)
void draw_procedural_indirect(GPUPrimType primitive, StorageBuffer< DrawCommand, true > &indirect_buffer, ResourceHandle handle={0})
void bind_ssbo(int slot, GPUStorageBuf **buffer)
void push_constant(const char *name, const int2 &data)
void bind_image(const char *name, GPUTexture *image)
void push_constant(const char *name, const bool &data)
friend std::ostream & operator<<(std::ostream &stream, const PassBase &pass)
void push_constant(const char *name, const int3 &data)
void bind_ssbo(const char *name, gpu::IndexBuf *buffer)
void bind_ssbo(int slot, gpu::VertBuf **buffer)
void draw_expand(gpu::Batch *batch, GPUPrimType primitive_type, uint primitive_len, uint instance_len, ResourceHandleRange handle={0}, uint custom_id=0)
void push_constant(const char *name, const float *data, int array_len=1)
void clear_depth(float depth)
void bind_texture(int slot, GPUTexture **texture, GPUSamplerState state=sampler_auto)
Vector< command::Header, 0 > headers_
uint64_t view_fingerprint_
uint64_t manager_fingerprint_
void specialize_constant(GPUShader *shader, const char *name, const bool *data)
bool has_generated_commands() const
void specialize_constant(GPUShader *shader, const char *name, const float &data)
void clear_stencil(uint8_t stencil)
void clear_color(float4 color)
void push_constant(const char *name, const float4 *data, int array_len=1)
void warm_shader_specialization(command::RecordingState &state) const
void draw(gpu::Batch *batch, uint instance_len=-1, uint vertex_len=-1, uint vertex_first=-1, ResourceHandleRange handle={0}, uint custom_id=0)
void subpass_transition(GPUAttachmentState depth_attachment, Span< GPUAttachmentState > color_attachments)
void bind_texture(const char *name, gpu::VertBuf *buffer)
void draw(gpu::Batch *batch, ResourceHandleRange handle, uint custom_id=0)
void push_constant(const char *name, const float4x4 *data)
void bind_ssbo(int slot, gpu::VertBuf *buffer)
void clear_depth_stencil(float depth, uint8_t stencil)
void bind_ssbo(int slot, GPUUniformBuf **buffer)
void specialize_constant(GPUShader *shader, const char *name, const int *data)
void push_constant(const char *name, const float2 &data)
void dispatch(int3 *group_len)
SubPassVector< PassBase< DrawCommandBufType > > & sub_passes_
void bind_ubo(int slot, GPUUniformBuf **buffer)
PassBase(const char *name, DrawCommandBufType &draw_command_buf, SubPassVector< PassBase< DrawCommandBufType > > &sub_passes, GPUShader *shader=nullptr)
void bind_image(const char *name, GPUTexture **image)
command::Undetermined & create_command(command::Type type)
void bind_ssbo(const char *name, gpu::VertBuf *buffer)
void bind_ssbo(const char *name, gpu::IndexBuf **buffer)
void specialize_constant(GPUShader *shader, const char *name, const uint *data)
PassBase< DrawCommandBufType > & sub(const char *name)
void dispatch(int group_len)
int push_constant_offset(const char *name)
void bind_image(int slot, GPUTexture *image)
void submit(command::RecordingState &state) const
void push_constant(const char *name, const float4x4 &data)
void bind_ssbo(int slot, gpu::IndexBuf **buffer)
void push_constant(const char *name, const float2 *data, int array_len=1)
void push_constant(const char *name, const float4 &data)
void barrier(eGPUBarrier type)
void state_set(DRWState state, int clip_plane_count=0)
void bind_ssbo(int slot, GPUUniformBuf *buffer)
void bind_ubo(const char *name, GPUUniformBuf **buffer)
void specialize_constant(GPUShader *shader, const char *name, const float *data)
void specialize_constant(GPUShader *shader, const char *name, const bool &data)
void draw_indirect(gpu::Batch *batch, StorageBuffer< DrawCommand, true > &indirect_buffer, ResourceHandle handle={0})
void draw_expand(gpu::Batch *batch, GPUPrimType primitive_type, uint primitive_len, uint instance_len, uint vertex_len=-1, uint vertex_first=-1, ResourceHandleRange handle={0}, uint custom_id=0)
void bind_ubo(const char *name, GPUUniformBuf *buffer)
void push_constant(const char *name, const int2 *data, int array_len=1)
void dispatch(int3 group_len)
void clear(eGPUFrameBufferBits planes, float4 color, float depth, uint8_t stencil)
void dispatch(int2 group_len)
void push_constant(const char *name, const float3 &data)
void framebuffer_set(GPUFrameBuffer **framebuffer)
Vector< command::Undetermined, 0 > commands_
void state_stencil(uint8_t write_mask, uint8_t reference, uint8_t compare_mask)
void clear_color_depth_stencil(float4 color, float depth, uint8_t stencil)
void material_set(Manager &manager, GPUMaterial *material, bool deferred_texture_loading=false)
std::string serialize(std::string line_prefix="") const
void push_constant(const char *name, const float &data)
void bind_ssbo(const char *name, gpu::VertBuf **buffer)
void push_constant(const char *name, const int4 *data, int array_len=1)
void bind_texture(int slot, GPUTexture *texture, GPUSamplerState state=sampler_auto)
void bind_ssbo(const char *name, GPUUniformBuf **buffer)
void bind_ssbo(int slot, GPUStorageBuf *buffer)
void bind_ssbo(const char *name, GPUUniformBuf *buffer)
void bind_texture(const char *name, gpu::VertBuf **buffer)
void specialize_constant(GPUShader *shader, const char *name, const int &data)
void bind_ubo(int slot, GPUUniformBuf *buffer)
void push_constant(const char *name, const int4 &data)
void bind_texture(int slot, gpu::VertBuf **buffer)
void bind_ssbo(const char *name, GPUStorageBuf **buffer)
void draw_procedural(GPUPrimType primitive, uint instance_len, uint vertex_len, uint vertex_first=-1, ResourceHandleRange handle={0}, uint custom_id=0)
gpu::Batch * procedural_batch_get(GPUPrimType primitive)
DrawCommandBufType & draw_commands_buf_
void bind_ssbo(const char *name, GPUStorageBuf *buffer)
void push_constant(const char *name, const int3 *data, int array_len=1)
void shader_set(GPUShader *shader)
void bind_image(int slot, GPUTexture **image)
T & operator[](int64_t index)
const T & operator[](int64_t index) const
int64_t append_and_get_index(T &&elem)
@ DRW_STATE_PROGRAM_POINT_SIZE
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
static void clear(Message &msg)
VecBase< float, 4 > float4
VecBase< int32_t, 3 > int3
ListBaseWrapperTemplate< ListBase, T > ListBaseWrapper
unsigned __int64 uint64_t
static constexpr GPUSamplerState internal_sampler()
GPUTexture ** tile_mapping
enum blender::draw::command::PushConstant::Type type
PushConstant push_constant