Blender V4.5
gpu_batch.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2016 by Mike Erwin. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11
12#include "BLI_math_base.h"
13#include "BLI_utildefines.h"
14
15#include "GPU_batch.hh"
16#include "GPU_batch_presets.hh"
17#include "GPU_shader.hh"
18
19#include "GPU_index_buffer.hh"
20#include "GPU_vertex_buffer.hh"
21#include "gpu_backend.hh"
23#include "gpu_shader_private.hh"
24
25#include <cstring>
26
27using namespace blender::gpu;
28
29/* -------------------------------------------------------------------- */
32
34{
35 std::fill_n(batch->verts, ARRAY_SIZE(batch->verts), nullptr);
36 std::fill_n(batch->inst, ARRAY_SIZE(batch->inst), nullptr);
37 batch->elem = nullptr;
38 batch->resource_id_buf = nullptr;
39 batch->flag = eGPUBatchFlag(0);
40 batch->prim_type = GPUPrimType(0);
41 batch->shader = nullptr;
42}
43
45{
46 Batch *batch = GPUBackend::get()->batch_alloc();
48 return batch;
49}
50
51Batch *GPU_batch_create_ex(GPUPrimType primitive_type,
52 VertBuf *vertex_buf,
53 IndexBuf *index_buf,
54 eGPUBatchFlag owns_flag)
55{
56 Batch *batch = GPU_batch_calloc();
57 GPU_batch_init_ex(batch, primitive_type, vertex_buf, index_buf, owns_flag);
58 return batch;
59}
60
62 GPUPrimType primitive_type,
63 VertBuf *vertex_buf,
64 IndexBuf *index_buf,
65 eGPUBatchFlag owns_flag)
66{
67 /* Do not pass any other flag */
68 BLI_assert((owns_flag & ~(GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX)) == 0);
69 /* Batch needs to be in cleared state. */
70 BLI_assert((batch->flag & GPU_BATCH_INIT) == 0);
71
72 batch->verts[0] = vertex_buf;
73 for (int v = 1; v < GPU_BATCH_VBO_MAX_LEN; v++) {
74 batch->verts[v] = nullptr;
75 }
76 for (auto &v : batch->inst) {
77 v = nullptr;
78 }
79 batch->elem = index_buf;
80 batch->prim_type = primitive_type;
81 batch->flag = owns_flag | GPU_BATCH_INIT | GPU_BATCH_DIRTY;
82 batch->shader = nullptr;
83}
84
85void GPU_batch_copy(Batch *batch_dst, Batch *batch_src)
86{
87 GPU_batch_clear(batch_dst);
89 batch_dst, GPU_PRIM_POINTS, batch_src->verts[0], batch_src->elem, GPU_BATCH_INVALID);
90
91 batch_dst->prim_type = batch_src->prim_type;
92 for (int v = 1; v < GPU_BATCH_VBO_MAX_LEN; v++) {
93 batch_dst->verts[v] = batch_src->verts[v];
94 }
95}
96
98{
99 if (batch->flag & GPU_BATCH_OWNS_INDEX) {
101 }
102 if (batch->flag & GPU_BATCH_OWNS_VBO_ANY) {
103 for (int v = 0; (v < GPU_BATCH_VBO_MAX_LEN) && batch->verts[v]; v++) {
104 if (batch->flag & (GPU_BATCH_OWNS_VBO << v)) {
106 }
107 }
108 }
110 for (int v = 0; (v < GPU_BATCH_INST_VBO_MAX_LEN) && batch->inst[v]; v++) {
111 if (batch->flag & (GPU_BATCH_OWNS_INST_VBO << v)) {
113 }
114 }
115 }
116 batch->flag = GPU_BATCH_INVALID;
117}
118
120{
122 delete batch;
123}
124
126
127/* -------------------------------------------------------------------- */
130
131void GPU_batch_instbuf_set(Batch *batch, VertBuf *vertex_buf, bool own_vbo)
132{
133 BLI_assert(vertex_buf);
134 batch->flag |= GPU_BATCH_DIRTY;
135
136 if (batch->inst[0] && (batch->flag & GPU_BATCH_OWNS_INST_VBO)) {
137 GPU_vertbuf_discard(batch->inst[0]);
138 }
139 batch->inst[0] = vertex_buf;
140
142}
143
144void GPU_batch_elembuf_set(Batch *batch, blender::gpu::IndexBuf *index_buf, bool own_ibo)
145{
146 BLI_assert(index_buf);
147 batch->flag |= GPU_BATCH_DIRTY;
148
149 if (batch->elem && (batch->flag & GPU_BATCH_OWNS_INDEX)) {
151 }
152 batch->elem = index_buf;
153
155}
156
157int GPU_batch_instbuf_add(Batch *batch, VertBuf *vertex_buf, bool own_vbo)
158{
159 BLI_assert(vertex_buf);
160 batch->flag |= GPU_BATCH_DIRTY;
161
162 for (uint v = 0; v < GPU_BATCH_INST_VBO_MAX_LEN; v++) {
163 if (batch->inst[v] == nullptr) {
164 /* for now all VertexBuffers must have same vertex_len */
165 if (batch->inst[0]) {
166 /* Allow for different size of vertex buffer (will choose the smallest number of verts). */
167 // BLI_assert(insts->vertex_len == batch->inst[0]->vertex_len);
168 }
169
170 batch->inst[v] = vertex_buf;
172 return v;
173 }
174 }
175 /* we only make it this far if there is no room for another VertBuf */
176 BLI_assert_msg(0, "Not enough Instance VBO slot in batch");
177 return -1;
178}
179
180int GPU_batch_vertbuf_add(Batch *batch, VertBuf *vertex_buf, bool own_vbo)
181{
182 BLI_assert(vertex_buf);
183 batch->flag |= GPU_BATCH_DIRTY;
184
185 for (uint v = 0; v < GPU_BATCH_VBO_MAX_LEN; v++) {
186 if (batch->verts[v] == nullptr) {
187 /* for now all VertexBuffers must have same vertex_len */
188 if (batch->verts[0] != nullptr) {
189 /* This is an issue for the HACK inside DRW_vbo_request(). */
190 // BLI_assert(verts->vertex_len == batch->verts[0]->vertex_len);
191 }
192 batch->verts[v] = vertex_buf;
194 return v;
195 }
196 }
197 /* we only make it this far if there is no room for another VertBuf */
198 BLI_assert_msg(0, "Not enough VBO slot in batch");
199 return -1;
200}
201
202bool GPU_batch_vertbuf_has(const Batch *batch, const VertBuf *vertex_buf)
203{
204 for (uint v = 0; v < GPU_BATCH_VBO_MAX_LEN; v++) {
205 if (batch->verts[v] == vertex_buf) {
206 return true;
207 }
208 }
209 return false;
210}
211
212void GPU_batch_resource_id_buf_set(Batch *batch, GPUStorageBuf *resource_id_buf)
213{
214 BLI_assert(resource_id_buf);
215 batch->flag |= GPU_BATCH_DIRTY;
216 batch->resource_id_buf = resource_id_buf;
217}
218
220
221/* -------------------------------------------------------------------- */
225
227 GPUShader *shader,
228 const shader::SpecializationConstants *constants_state)
229{
230 batch->shader = shader;
231 GPU_shader_bind(batch->shader, constants_state);
232}
233
235 GPUShader *shader,
236 VertBuf *vbo)
237{
238 const GPUVertFormat *format = &vbo->format;
239
240 /* We need to support GPU OpenSubdiv meshes. This assert can be enabled back after we refactor
241 * our OpenSubdiv implementation to output the same layout as the regular mesh extraction. */
242 // BLI_assert_msg(format->attr_len == 1, "Multi attribute buffers are not supported for now");
243
244 char uniform_name[] = "gpu_attr_0";
245 uint stride = format->stride;
246 uint offset = 0;
247 uint16_t bound_attr = 0u;
248 for (uint a_idx = 0; a_idx < format->attr_len; a_idx++) {
249 const GPUVertAttr *a = &format->attrs[a_idx];
250
251 if (format->deinterleaved) {
252 offset += ((a_idx == 0) ? 0 : format->attrs[a_idx - 1].size) * vbo->vertex_len;
253 stride = a->size;
254 }
255 else {
256 offset = a->offset;
257 }
258
259 for (uint n_idx = 0; n_idx < a->name_len; n_idx++) {
260 const char *name = GPU_vertformat_attr_name_get(format, a, n_idx);
261 const ShaderInput *input = interface->ssbo_get(name);
262 if (input == nullptr || input->location == -1) {
263 continue;
264 }
265 GPU_vertbuf_bind_as_ssbo(vbo, input->location);
266 bound_attr |= (1 << input->location);
267
268 /* WORKAROUND: This is to support complex format. But ideally this should not be supported.
269 */
270 uniform_name[9] = '0' + input->location;
271
272 /* Only support 4byte aligned attributes. */
273 BLI_assert((stride % 4) == 0);
274 BLI_assert((offset % 4) == 0);
275 int descriptor[2] = {int(stride) / 4, int(offset) / 4};
277 /* WORKAROUND: Fix for polyline workaround. Ideally should be fused with `gpu_attr_0`.
278 * But for now, changes are a bit too invasive. Will need to be revisited later on. */
279 char uniform_name_len[] = "gpu_attr_0_len";
280 uniform_name_len[9] = '0' + input->location;
281 GPU_shader_uniform_1i(shader, uniform_name_len, a->comp_len);
282 }
283 }
284 return bound_attr;
285}
286
288 GPUShader *shader,
289 const shader::SpecializationConstants *constants)
290{
291 const ShaderInterface *interface = unwrap(shader)->interface;
292 if (interface->ssbo_attr_mask_ == 0) {
293 return;
294 }
295
296 uint16_t ssbo_attributes = interface->ssbo_attr_mask_;
297
298 if (ssbo_attributes & (1 << GPU_SSBO_INDEX_BUF_SLOT)) {
299 /* Ensure binding for setting uniforms. This is required by the OpenGL backend. */
300 GPU_shader_bind(shader, constants);
301 if (batch->elem) {
303 GPU_shader_uniform_1b(shader, "gpu_index_no_buffer", false);
304 GPU_shader_uniform_1b(shader, "gpu_index_16bit", !batch->elem->is_32bit());
305 GPU_shader_uniform_1i(shader, "gpu_index_base_index", batch->elem->index_base_get());
306 }
307 else {
308 /* Still fulfill the binding requirements even if the buffer will not be read. */
310 GPU_shader_uniform_1b(shader, "gpu_index_no_buffer", true);
311 }
312 ssbo_attributes &= ~(1 << GPU_SSBO_INDEX_BUF_SLOT);
313 }
314
315 /* Reverse order so first VBO'S have more prevalence (in term of attribute override). */
316 for (int v = GPU_BATCH_VBO_MAX_LEN - 1; v > -1; v--) {
317 VertBuf *vbo = batch->verts_(v);
318 if (vbo) {
319 ssbo_attributes &= ~bind_attribute_as_ssbo(interface, shader, vbo);
320 }
321 }
322
323 BLI_assert_msg(ssbo_attributes == 0, "Not all attribute storage buffer fulfilled");
324 UNUSED_VARS_NDEBUG(ssbo_attributes);
325}
326
328
329/* -------------------------------------------------------------------- */
332
334 int *r_vertex_count,
335 int *r_vertex_first,
336 int *r_base_index,
337 int *r_instance_count)
338{
339 if (batch->elem) {
340 *r_vertex_count = batch->elem_()->index_len_get();
341 *r_vertex_first = batch->elem_()->index_start_get();
342 *r_base_index = batch->elem_()->index_base_get();
343 }
344 else {
345 *r_vertex_count = batch->verts_(0)->vertex_len;
346 *r_vertex_first = 0;
347 *r_base_index = -1;
348 }
349
350 int i_count = (batch->inst[0]) ? batch->inst_(0)->vertex_len : 1;
351 /* Meh. This is to be able to use different numbers of verts in instance VBO's. */
352 if (batch->inst[1] != nullptr) {
353 i_count = min_ii(i_count, batch->inst_(1)->vertex_len);
354 }
355 *r_instance_count = i_count;
356}
357
359 GPUPrimType output_prim_type,
360 int vertex_count,
361 int vertex_first,
362 int output_primitive_cout)
363{
364 int vert_per_original_primitive = indices_per_primitive(input_prim_type);
365 int vert_per_expanded_primitive = indices_per_primitive(output_prim_type);
366
367 int prim_first = vertex_first / vert_per_original_primitive;
368 int prim_len = vertex_count / vert_per_original_primitive;
369
370 BLI_assert_msg(vert_per_original_primitive != -1,
371 "Primitive expansion only works for primitives with known amount of vertices");
372
373 /* WORKAROUND: Needed for polyline_draw_workaround. */
374 if (input_prim_type == GPU_PRIM_LINE_STRIP) {
375 prim_len = vertex_count - 1;
376 }
377
378 int out_vertex_first = prim_first * vert_per_expanded_primitive * output_primitive_cout;
379 int out_vertex_count = prim_len * vert_per_expanded_primitive * output_primitive_cout;
380
381 return blender::IndexRange(out_vertex_first, out_vertex_count);
382}
383
385 Batch *batch, int vertex_first, int vertex_count, int instance_first, int instance_count)
386{
387 /* Early out as this can cause crashes on some backend (see #136831). */
388 if (vertex_count == 0) {
389 return;
390 }
391 /* Check compatible input primitive. */
393
396 batch->prim_type, GPU_PRIM_TRIS, vertex_count, vertex_first, 2);
397 Batch *tri_batch = Context::get()->procedural_triangles_batch_get();
398 GPU_batch_set_shader(tri_batch, batch->shader);
399
400 int vert_stride_count[3] = {(batch->prim_type == GPU_PRIM_LINES) ? 2 : 1, vertex_count, 0};
401 GPU_shader_uniform_3iv(batch->shader, "gpu_vert_stride_count_offset", vert_stride_count);
402 /* Assume GPU_FETCH_FLOAT for now. A bit cumbersome to assert for this or to find the correct
403 * attribute. */
404 GPU_shader_uniform_1b(batch->shader, "gpu_attr_0_fetch_int", false);
405
406 /* Allow byte color fetch. */
408 int id = GPU_vertformat_attr_id_get(format, "color");
409 if (id != -1) {
410 const GPUVertAttr &attr = format->attrs[id];
412 "color attribute for polylines can only use GPU_FETCH_INT_TO_FLOAT_UNIT or "
413 "GPU_FETCH_FLOAT");
415 "gpu_attr_1_fetch_unorm8",
417 }
418
419 GPU_batch_draw_advanced(tri_batch, range.start(), range.size(), instance_first, instance_count);
420}
421
423{
424 BLI_assert(batch != nullptr);
425 GPU_shader_bind(batch->shader);
426 if (unwrap(batch->shader)->is_polyline) {
427 polyline_draw_workaround(batch, 0, batch->vertex_count_get(), 0, 0);
428 }
429 else {
430 GPU_batch_draw_advanced(batch, 0, 0, 0, 0);
431 }
432}
433
434void GPU_batch_draw_range(Batch *batch, int vertex_first, int vertex_count)
435{
436 BLI_assert(batch != nullptr);
437 GPU_shader_bind(batch->shader);
438 if (unwrap(batch->shader)->is_polyline) {
439 polyline_draw_workaround(batch, vertex_first, vertex_count, 0, 0);
440 }
441 else {
442 GPU_batch_draw_advanced(batch, vertex_first, vertex_count, 0, 0);
443 }
444}
445
446void GPU_batch_draw_instance_range(Batch *batch, int instance_first, int instance_count)
447{
448 BLI_assert(batch != nullptr);
449 BLI_assert(batch->inst[0] == nullptr);
450 /* Not polyline shaders support instancing. */
451 BLI_assert(unwrap(batch->shader)->is_polyline == false);
452
453 GPU_shader_bind(batch->shader);
454 GPU_batch_draw_advanced(batch, 0, 0, instance_first, instance_count);
455}
456
458 Batch *batch, int vertex_first, int vertex_count, int instance_first, int instance_count)
459{
460 BLI_assert(batch != nullptr);
461 BLI_assert(Context::get()->shader != nullptr);
463
464 if (vertex_count == 0) {
465 if (batch->elem) {
466 vertex_count = batch->elem_()->index_len_get();
467 }
468 else {
469 vertex_count = batch->verts_(0)->vertex_len;
470 }
471 }
472 if (instance_count == 0) {
473 instance_count = (batch->inst[0]) ? batch->inst_(0)->vertex_len : 1;
474 /* Meh. This is to be able to use different numbers of verts in instance VBO's. */
475 if (batch->inst[1] != nullptr) {
476 instance_count = min_ii(instance_count, batch->inst_(1)->vertex_len);
477 }
478 }
479
480 if (vertex_count == 0 || instance_count == 0) {
481 /* Nothing to draw. */
482 return;
483 }
484
485 batch->draw(vertex_first, vertex_count, instance_first, instance_count);
486}
487
488void GPU_batch_draw_indirect(Batch *batch, GPUStorageBuf *indirect_buf, intptr_t offset)
489{
490 BLI_assert(batch != nullptr);
491 BLI_assert(indirect_buf != nullptr);
492 BLI_assert(Context::get()->shader != nullptr);
494
495 batch->draw_indirect(indirect_buf, offset);
496}
497
499 Batch *batch, GPUStorageBuf *indirect_buf, int count, intptr_t offset, intptr_t stride)
500{
501 BLI_assert(batch != nullptr);
502 BLI_assert(indirect_buf != nullptr);
503 BLI_assert(Context::get()->shader != nullptr);
505
506 batch->multi_draw_indirect(indirect_buf, count, offset, stride);
507}
508
510
511/* -------------------------------------------------------------------- */
514
522
527
532
537
542
547
552
554
555/* -------------------------------------------------------------------- */
558
563
568
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
MINLINE int min_ii(int a, int b)
unsigned int uint
#define ARRAY_SIZE(arr)
#define UNUSED_VARS_NDEBUG(...)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define ELEM(...)
static constexpr int GPU_BATCH_VBO_MAX_LEN
Definition GPU_batch.hh:31
static constexpr int GPU_BATCH_INST_VBO_MAX_LEN
Definition GPU_batch.hh:32
eGPUBatchFlag
Definition GPU_batch.hh:36
@ GPU_BATCH_INVALID
Definition GPU_batch.hh:38
@ GPU_BATCH_DIRTY
Definition GPU_batch.hh:57
@ GPU_BATCH_INIT
Definition GPU_batch.hh:53
@ GPU_BATCH_OWNS_INDEX
Definition GPU_batch.hh:50
@ GPU_BATCH_OWNS_INST_VBO
Definition GPU_batch.hh:45
@ GPU_BATCH_OWNS_VBO
Definition GPU_batch.hh:41
@ GPU_BATCH_OWNS_VBO_ANY
Definition GPU_batch.hh:43
@ GPU_BATCH_OWNS_INST_VBO_ANY
Definition GPU_batch.hh:47
void gpu_batch_presets_init()
void gpu_batch_presets_exit()
void GPU_indexbuf_discard(blender::gpu::IndexBuf *elem)
void GPU_indexbuf_bind_as_ssbo(blender::gpu::IndexBuf *elem, int binding)
GPUPrimType
@ GPU_PRIM_LINE_LOOP
@ GPU_PRIM_LINES
@ GPU_PRIM_POINTS
@ GPU_PRIM_LINE_STRIP
@ GPU_PRIM_TRIS
void GPU_shader_uniform_1i(GPUShader *sh, const char *name, int value)
void GPU_shader_uniform_3iv(GPUShader *sh, const char *name, const int data[3])
void GPU_shader_bind(GPUShader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
void GPU_shader_uniform_2iv(GPUShader *sh, const char *name, const int data[2])
void GPU_shader_uniform_1b(GPUShader *sh, const char *name, bool value)
@ GPU_SHADER_CFG_DEFAULT
GPUShader * GPU_shader_get_builtin_shader_with_config(eGPUBuiltinShader shader, eGPUShaderConfig sh_cfg)
eGPUBuiltinShader
#define GPU_VERTBUF_DISCARD_SAFE(verts)
const GPUVertFormat * GPU_vertbuf_get_format(const blender::gpu::VertBuf *verts)
void GPU_vertbuf_bind_as_ssbo(blender::gpu::VertBuf *verts, int binding)
void GPU_vertbuf_discard(blender::gpu::VertBuf *)
BLI_INLINE const char * GPU_vertformat_attr_name_get(const GPUVertFormat *format, const GPUVertAttr *attr, uint n_idx)
int GPU_vertformat_attr_id_get(const GPUVertFormat *, blender::StringRef name)
@ GPU_FETCH_FLOAT
@ GPU_FETCH_INT_TO_FLOAT_UNIT
ATTR_WARN_UNUSED_RESULT const BMVert * v
constexpr int64_t size() const
constexpr int64_t start() const
static Context * get()
Batch * procedural_triangles_batch_get()
void assert_framebuffer_shader_compatibility(Shader *sh)
Batch * procedural_triangle_strips_batch_get()
Batch * procedural_lines_batch_get()
Batch * procedural_points_batch_get()
static GPUBackend * get()
virtual Batch * batch_alloc()=0
void GPU_batch_resource_id_buf_set(Batch *batch, GPUStorageBuf *resource_id_buf)
Definition gpu_batch.cc:212
blender::gpu::Batch * GPU_batch_procedural_triangle_strips_get()
Definition gpu_batch.cc:548
void GPU_batch_multi_draw_indirect(Batch *batch, GPUStorageBuf *indirect_buf, int count, intptr_t offset, intptr_t stride)
Definition gpu_batch.cc:498
void GPU_batch_draw_parameter_get(Batch *batch, int *r_vertex_count, int *r_vertex_first, int *r_base_index, int *r_instance_count)
Definition gpu_batch.cc:333
void GPU_batch_discard(Batch *batch)
Definition gpu_batch.cc:119
int GPU_batch_instbuf_add(Batch *batch, VertBuf *vertex_buf, bool own_vbo)
Definition gpu_batch.cc:157
Batch * GPU_batch_create_ex(GPUPrimType primitive_type, VertBuf *vertex_buf, IndexBuf *index_buf, eGPUBatchFlag owns_flag)
Definition gpu_batch.cc:51
bool GPU_batch_vertbuf_has(const Batch *batch, const VertBuf *vertex_buf)
Definition gpu_batch.cc:202
static void polyline_draw_workaround(Batch *batch, int vertex_first, int vertex_count, int instance_first, int instance_count)
Definition gpu_batch.cc:384
blender::gpu::Batch * GPU_batch_procedural_lines_get()
Definition gpu_batch.cc:538
void GPU_batch_program_set_imm_shader(Batch *batch)
Definition gpu_batch.cc:528
void GPU_batch_draw(Batch *batch)
Definition gpu_batch.cc:422
void GPU_batch_draw_instance_range(Batch *batch, int instance_first, int instance_count)
Definition gpu_batch.cc:446
static uint16_t bind_attribute_as_ssbo(const ShaderInterface *interface, GPUShader *shader, VertBuf *vbo)
Definition gpu_batch.cc:234
blender::IndexRange GPU_batch_draw_expanded_parameter_get(GPUPrimType input_prim_type, GPUPrimType output_prim_type, int vertex_count, int vertex_first, int output_primitive_cout)
Definition gpu_batch.cc:358
Batch * GPU_batch_calloc()
Definition gpu_batch.cc:44
void GPU_batch_draw_range(Batch *batch, int vertex_first, int vertex_count)
Definition gpu_batch.cc:434
void GPU_batch_draw_indirect(Batch *batch, GPUStorageBuf *indirect_buf, intptr_t offset)
Definition gpu_batch.cc:488
int GPU_batch_vertbuf_add(Batch *batch, VertBuf *vertex_buf, bool own_vbo)
Definition gpu_batch.cc:180
void GPU_batch_set_shader(Batch *batch, GPUShader *shader, const shader::SpecializationConstants *constants_state)
Definition gpu_batch.cc:226
blender::gpu::Batch * GPU_batch_procedural_points_get()
Definition gpu_batch.cc:533
void GPU_batch_program_set_builtin(Batch *batch, eGPUBuiltinShader shader_id)
Definition gpu_batch.cc:523
void GPU_batch_init_ex(Batch *batch, GPUPrimType primitive_type, VertBuf *vertex_buf, IndexBuf *index_buf, eGPUBatchFlag owns_flag)
Definition gpu_batch.cc:61
void GPU_batch_instbuf_set(Batch *batch, VertBuf *vertex_buf, bool own_vbo)
Definition gpu_batch.cc:131
blender::gpu::Batch * GPU_batch_procedural_triangles_get()
Definition gpu_batch.cc:543
void GPU_batch_zero(Batch *batch)
Definition gpu_batch.cc:33
void GPU_batch_bind_as_resources(Batch *batch, GPUShader *shader, const shader::SpecializationConstants *constants)
Definition gpu_batch.cc:287
void gpu_batch_init()
Definition gpu_batch.cc:559
void GPU_batch_copy(Batch *batch_dst, Batch *batch_src)
Definition gpu_batch.cc:85
void GPU_batch_program_set_builtin_with_config(Batch *batch, eGPUBuiltinShader shader_id, eGPUShaderConfig sh_cfg)
Definition gpu_batch.cc:515
void GPU_batch_clear(Batch *batch)
Definition gpu_batch.cc:97
void GPU_batch_elembuf_set(Batch *batch, blender::gpu::IndexBuf *index_buf, bool own_ibo)
Definition gpu_batch.cc:144
void GPU_batch_draw_advanced(Batch *batch, int vertex_first, int vertex_count, int instance_first, int instance_count)
Definition gpu_batch.cc:457
void gpu_batch_exit()
Definition gpu_batch.cc:564
struct @242053044010324116347033273112253060004051364061::@051143074301336237271216303350234260141112266062 batch
#define input
#define interface
GPUShader * immGetShader()
#define GPU_SSBO_INDEX_BUF_SLOT
int count
format
descriptor
static Context * unwrap(GPUContext *ctx)
int indices_per_primitive(GPUPrimType prim_type)