99 if (blocks_.
is_empty() || blocks_.
last()->size() == block_size) {
102 return blocks_.
last()->append_and_get_index(std::move(elem)) +
103 (blocks_.
size() - 1) * block_size;
108 return (*blocks_[index / block_size])[index % block_size];
113 return (*blocks_[index / block_size])[index % block_size];
122 typename DrawCommandBufType>
148 DrawCommandBufType &draw_command_buf,
242 uint instance_len = -1,
243 uint vertex_len = -1,
244 uint vertex_first = -1,
261 uint vertex_first = -1,
282 uint vertex_len = -1,
283 uint vertex_first = -1,
347 void bind_ssbo(
const char *name, GPUStorageBuf *buffer);
348 void bind_ssbo(
const char *name, GPUStorageBuf **buffer);
351 void bind_ssbo(
const char *name, GPUUniformBuf *buffer);
352 void bind_ssbo(
const char *name, GPUUniformBuf **buffer);
363 void bind_ubo(
const char *name, GPUUniformBuf *buffer);
364 void bind_ubo(
const char *name, GPUUniformBuf **buffer);
428 resources.bind_resources(*
this);
434 std::string
serialize(std::string line_prefix =
"")
const;
438 return stream << pass.serialize();
468 DrawCommandBufType draw_commands_buf_main_;
472 : detail::
PassBase<DrawCommandBufType>(name, draw_commands_buf_main_, sub_passes_main_){};
476 this->headers_.
clear();
477 this->commands_.
clear();
478 this->sub_passes_.
clear();
479 this->draw_commands_buf_.clear();
516 bool sorted_ =
false;
523 sorting_values_.
clear();
541 }
while (sorting_index != index);
545 std::string
serialize(std::string line_prefix =
"")
const
547 if (sorted_ ==
false) {
556 if (sorted_ ==
false) {
558 BLI_assert(a.type == Type::SubPass && b.type == Type::SubPass);
559 float a_val = sorting_values_[a.index];
560 float b_val = sorting_values_[b.index];
561 return a_val < b_val || (a_val == b_val && a.index < b.index);
580 return commands_[index];
589 create_command(command::Type::Clear).
clear = {
uint8_t(planes), stencil, depth, color};
594 create_command(command::Type::ClearMulti).
clear_multi = {colors.data(),
595 static_cast<int>(colors.size())};
619 PassBase(name, draw_commands_buf_, sub_passes_, shader_));
620 headers_.
append({command::Type::SubPass,
uint(index)});
621 return sub_passes_[index];
629 switch (header.type) {
634 sub_passes_[header.index].submit(
state);
636 case command::Type::FramebufferBind:
637 commands_[header.index].framebuffer_bind.execute();
639 case command::Type::SubPassTransition:
640 commands_[header.index].subpass_transition.execute();
642 case command::Type::ShaderBind:
643 commands_[header.index].shader_bind.execute(
state);
645 case command::Type::ResourceBind:
646 commands_[header.index].resource_bind.execute();
648 case command::Type::PushConstant:
649 commands_[header.index].push_constant.execute(
state);
651 case command::Type::SpecializeConstant:
652 commands_[header.index].specialize_constant.execute();
654 case command::Type::Draw:
655 commands_[header.index].draw.execute(
state);
657 case command::Type::DrawMulti:
658 commands_[header.index].draw_multi.execute(
state);
660 case command::Type::DrawIndirect:
661 commands_[header.index].draw_indirect.execute(
state);
663 case command::Type::Dispatch:
664 commands_[header.index].dispatch.execute(
state);
666 case command::Type::DispatchIndirect:
667 commands_[header.index].dispatch_indirect.execute(
state);
669 case command::Type::Barrier:
670 commands_[header.index].barrier.execute();
672 case command::Type::Clear:
673 commands_[header.index].
clear.execute();
675 case command::Type::ClearMulti:
676 commands_[header.index].clear_multi.execute();
678 case command::Type::StateSet:
679 commands_[header.index].state_set.execute(
state);
681 case command::Type::StencilSet:
682 commands_[header.index].stencil_set.execute();
692 std::stringstream ss;
693 ss << line_prefix <<
"." << debug_name << std::endl;
696 switch (header.type) {
701 ss << sub_passes_[header.index].serialize(line_prefix);
703 case Type::FramebufferBind:
704 ss << line_prefix << commands_[header.index].framebuffer_bind.serialize() << std::endl;
706 case Type::SubPassTransition:
707 ss << line_prefix << commands_[header.index].subpass_transition.serialize() << std::endl;
709 case Type::ShaderBind:
710 ss << line_prefix << commands_[header.index].shader_bind.serialize() << std::endl;
712 case Type::ResourceBind:
713 ss << line_prefix << commands_[header.index].resource_bind.serialize() << std::endl;
715 case Type::PushConstant:
716 ss << line_prefix << commands_[header.index].push_constant.serialize() << std::endl;
719 ss << line_prefix << commands_[header.index].draw.serialize() << std::endl;
721 case Type::DrawMulti:
722 ss << commands_[header.index].draw_multi.serialize(line_prefix);
724 case Type::DrawIndirect:
725 ss << line_prefix << commands_[header.index].draw_indirect.serialize() << std::endl;
728 ss << line_prefix << commands_[header.index].dispatch.serialize() << std::endl;
730 case Type::DispatchIndirect:
731 ss << line_prefix << commands_[header.index].dispatch_indirect.serialize() << std::endl;
734 ss << line_prefix << commands_[header.index].barrier.serialize() << std::endl;
737 ss << line_prefix << commands_[header.index].
clear.serialize() << std::endl;
739 case Type::ClearMulti:
740 ss << line_prefix << commands_[header.index].clear_multi.serialize() << std::endl;
743 ss << line_prefix << commands_[header.index].state_set.serialize() << std::endl;
745 case Type::StencilSet:
746 ss << line_prefix << commands_[header.index].stencil_set.serialize() << std::endl;
767 if (instance_len == 0 || vertex_len == 0) {
771 draw_commands_buf_.append_draw(headers_,
779#ifdef WITH_METAL_BACKEND
789 this->draw(
batch, -1, -1, -1, handle, custom_id);
802 if (instance_len == 0 || vertex_len == 0 || primitive_len == 0) {
806 draw_commands_buf_.append_draw(headers_,
814#ifdef WITH_METAL_BACKEND
829 this->draw_expand(
batch, primitive_type, primitive_len, instance_len, -1, -1, handle, custom_id);
841 procedural_batch_get(primitive), instance_len, vertex_len, vertex_first, handle, custom_id);
856 create_command(Type::DrawIndirect).draw_indirect = {
batch, &indirect_buffer, handle};
865 this->draw_indirect(procedural_batch_get(primitive), indirect_buffer, handle);
877 create_command(Type::Dispatch).dispatch = {
int3(group_len, 1, 1)};
883 create_command(Type::Dispatch).dispatch = {
int3(group_len.x, group_len.y, 1)};
889 create_command(Type::Dispatch).dispatch = {group_len};
895 create_command(Type::Dispatch).dispatch = {group_len};
902 create_command(Type::DispatchIndirect).dispatch_indirect = {&indirect_buffer};
945 create_command(Type::Barrier).
barrier = {type};
957 if (clip_plane_count > 0) {
962 create_command(Type::StateSet).
state_set = {
state, clip_plane_count};
968 create_command(Type::StencilSet).stencil_set = {write_mask, compare_mask, reference};
974 create_command(Type::ShaderBind).shader_bind = {shader};
979 create_command(Type::FramebufferBind).framebuffer_bind = {framebuffer};
988 color_states[i] =
uint8_t(color_attachments[i]);
990 create_command(Type::SubPassTransition).subpass_transition = {
uint8_t(depth_attachment),
1011 const bool use_tile_mapping =
tex->tiled_mapping_name[0];
1014 tex->
ima, iuser, use_tile_mapping);
1017 bind_texture(
tex->sampler_name, gputex.
texture,
tex->sampler_state);
1024 else if (
tex->colorband) {
1026 bind_texture(
tex->sampler_name, *
tex->colorband);
1028 else if (
tex->sky) {
1030 bind_texture(
tex->sampler_name, *
tex->sky,
tex->sampler_state);
1035 if (ubo !=
nullptr) {
1127 create_command(Type::ResourceBind).resource_bind = {slot, buffer};
1133 create_command(Type::ResourceBind).resource_bind = {
1134 slot, buffer, ResourceBind::Type::UniformAsStorageBuf};
1140 create_command(Type::ResourceBind).resource_bind = {
1141 slot, buffer, ResourceBind::Type::UniformAsStorageBuf};
1147 create_command(Type::ResourceBind).resource_bind = {
1148 slot, buffer, ResourceBind::Type::VertexAsStorageBuf};
1154 create_command(Type::ResourceBind).resource_bind = {
1155 slot, buffer, ResourceBind::Type::VertexAsStorageBuf};
1161 create_command(Type::ResourceBind).resource_bind = {
1162 slot, buffer, ResourceBind::Type::IndexAsStorageBuf};
1168 create_command(Type::ResourceBind).resource_bind = {
1169 slot, buffer, ResourceBind::Type::IndexAsStorageBuf};
1175 create_command(Type::ResourceBind).resource_bind = {slot, buffer};
1182 create_command(Type::ResourceBind).resource_bind = {slot,
texture,
state};
1188 create_command(Type::ResourceBind).resource_bind = {slot, buffer};
1194 create_command(Type::ResourceBind).resource_bind = {slot, buffer};
1200 create_command(Type::ResourceBind).resource_bind = {slot, as_image(image)};
1217 GPUTexture **texture,
1234 create_command(Type::ResourceBind).resource_bind = {slot, buffer};
1240 create_command(Type::ResourceBind).resource_bind = {slot, buffer};
1247 create_command(Type::ResourceBind).resource_bind = {slot,
texture,
state};
1253 create_command(Type::ResourceBind).resource_bind = {slot, as_image(image)};
1264 create_command(Type::PushConstant).
push_constant = {push_constant_offset(name), data};
1269 create_command(Type::PushConstant).
push_constant = {push_constant_offset(name), data};
1274 create_command(Type::PushConstant).
push_constant = {push_constant_offset(name), data};
1279 create_command(Type::PushConstant).
push_constant = {push_constant_offset(name), data};
1284 create_command(Type::PushConstant).
push_constant = {push_constant_offset(name), data};
1289 create_command(Type::PushConstant).
push_constant = {push_constant_offset(name), data};
1294 create_command(Type::PushConstant).
push_constant = {push_constant_offset(name), data};
1299 create_command(Type::PushConstant).
push_constant = {push_constant_offset(name), data};
1304 create_command(Type::PushConstant).
push_constant = {push_constant_offset(name), data};
1310 create_command(Type::PushConstant).
push_constant = {push_constant_offset(name),
data, array_len};
1316 create_command(Type::PushConstant).
push_constant = {push_constant_offset(name),
data, array_len};
1322 create_command(Type::PushConstant).
push_constant = {push_constant_offset(name),
data, array_len};
1328 create_command(Type::PushConstant).
push_constant = {push_constant_offset(name),
data, array_len};
1334 create_command(Type::PushConstant).
push_constant = {push_constant_offset(name),
data, array_len};
1340 create_command(Type::PushConstant).
push_constant = {push_constant_offset(name),
data, array_len};
1346 create_command(Type::PushConstant).
push_constant = {push_constant_offset(name),
data, array_len};
1352 create_command(Type::PushConstant).
push_constant = {push_constant_offset(name),
data, array_len};
1357 create_command(Type::PushConstant).
push_constant = {push_constant_offset(name), data};
1367 cmd.
location = push_constant_offset(name);
1370 cmd.
type = PushConstant::Type::FloatValue;
1374 create_command(Type::PushConstant) = commands[0];
1375 create_command(Type::None) = commands[1];
1376 create_command(Type::None) = commands[2];
1387 const char *constant_name,
1388 const int &constant_value)
1396 const char *constant_name,
1397 const uint &constant_value)
1405 const char *constant_name,
1406 const float &constant_value)
1414 const char *constant_name,
1415 const bool &constant_value)
1423 const char *constant_name,
1424 const int *constant_value)
1432 const char *constant_name,
1433 const uint *constant_value)
1441 const char *constant_name,
1442 const float *constant_value)
1450 const char *constant_name,
1451 const bool *constant_value)
ImageGPUTextures BKE_image_get_gpu_material_texture(Image *image, ImageUser *iuser, const bool use_tile_mapping)
#define BLI_assert_unreachable()
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)
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)
bool GPU_shader_uses_ssbo_vertex_fetch(GPUShader *shader)
int GPU_shader_get_ssbo_binding(GPUShader *shader, const char *name)
int GPU_shader_get_constant(GPUShader *shader, const char *name)
struct GPUShader GPUShader
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 draw_expand(gpu::Batch *batch, GPUPrimType primitive_type, uint primitive_len, uint instance_len, ResourceHandle handle={0}, uint custom_id=0)
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 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_
void specialize_constant(GPUShader *shader, const char *name, const bool *data)
void specialize_constant(GPUShader *shader, const char *name, const float &data)
void draw(gpu::Batch *batch, uint instance_len=-1, uint vertex_len=-1, uint vertex_first=-1, ResourceHandle handle={0}, uint custom_id=0)
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 subpass_transition(GPUAttachmentState depth_attachment, Span< GPUAttachmentState > color_attachments)
void bind_texture(const char *name, gpu::VertBuf *buffer)
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 draw_procedural(GPUPrimType primitive, uint instance_len, uint vertex_len, uint vertex_first=-1, ResourceHandle handle={0}, uint custom_id=0)
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 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)
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 draw_expand(gpu::Batch *batch, GPUPrimType primitive_type, uint primitive_len, uint instance_len, uint vertex_len=-1, uint vertex_first=-1, ResourceHandle handle={0}, uint custom_id=0)
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 material_set(Manager &manager, GPUMaterial *material)
void draw(gpu::Batch *batch, ResourceHandle handle, uint custom_id=0)
void bind_texture(int slot, gpu::VertBuf **buffer)
void bind_ssbo(const char *name, GPUStorageBuf **buffer)
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)
local_group_size(16, 16) .push_constant(Type b
local_group_size(16, 16) .push_constant(Type texture
blender::gpu::Batch * drw_cache_procedural_lines_get()
blender::gpu::Batch * drw_cache_procedural_triangles_get()
blender::gpu::Batch * drw_cache_procedural_triangle_strips_get()
blender::gpu::Batch * drw_cache_procedural_points_get()
@ DRW_STATE_PROGRAM_POINT_SIZE
GPUShader * GPU_pass_shader_get(GPUPass *pass)
static void clear(Message &msg)
VecBase< float, 4 > float4
VecBase< int32_t, 3 > int3
ListBaseWrapperTemplate< ListBase, T > ListBaseWrapper
static constexpr GPUSamplerState internal_sampler()
GPUTexture * tile_mapping
enum blender::draw::command::PushConstant::Type type
PushConstant push_constant