Blender V4.3
GPU_index_buffer.hh
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#pragma once
12
13#include "BLI_span.hh"
14
15#include "GPU_primitive.hh"
16
17#define GPU_TRACK_INDEX_RANGE 1
18
19namespace blender::gpu {
20
22constexpr uint32_t RESTART_INDEX = 0xFFFFFFFF;
23
28
29inline size_t to_bytesize(GPUIndexBufType type)
30{
31 return (type == GPU_INDEX_U32) ? sizeof(uint32_t) : sizeof(uint16_t);
32}
33
40class IndexBuf {
41 protected:
51 bool is_init_ = false;
53 bool is_subrange_ = false;
55 bool is_empty_ = false;
56
57 union {
59 void *data_ = nullptr;
62 };
63
64 public:
66 virtual ~IndexBuf();
67
68 void init(uint indices_len,
69 uint32_t *indices,
70 uint min_index,
71 uint max_index,
72 GPUPrimType prim_type,
73 bool uses_restart_indices);
74 void init_subrange(IndexBuf *elem_src, uint start, uint length);
75 void init_build_on_device(uint index_len);
76
77 /* Returns render index count (not precise). */
79 {
80 /* Return 0 to bypass drawing for index buffers full of restart indices.
81 * They can lead to graphical glitches on some systems. (See #96892) */
82 return is_empty_ ? 0 : index_len_;
83 }
85 {
86 return index_start_;
87 }
89 {
90 return index_base_;
91 }
92 bool is_32bit() const
93 {
94 return index_type_ == GPU_INDEX_U32;
95 }
96 /* Return size in byte of the drawable data buffer range. Actual buffer size might be bigger. */
97 size_t size_get() const
98 {
100 };
101
102 bool is_init() const
103 {
104 return is_init_;
105 };
106
107 virtual void upload_data() = 0;
108
109 virtual void bind_as_ssbo(uint binding) = 0;
110
111 virtual void read(uint32_t *data) const = 0;
112
113 virtual void update_sub(uint start, uint len, const void *data) = 0;
114
115 private:
116 inline void squeeze_indices_short(uint min_idx,
117 uint max_idx,
118 GPUPrimType prim_type,
119 bool clamp_indices_in_range);
120 inline uint index_range(uint *r_min, uint *r_max);
121 virtual void strip_restart_indices() = 0;
122};
123
125{
126 switch (prim_type) {
127 case GPU_PRIM_POINTS:
128 return 1;
129 case GPU_PRIM_LINES:
130 return 2;
131 case GPU_PRIM_TRIS:
132 return 3;
134 return 4;
136 return 6;
137 default:
138 return -1;
139 }
140}
141
142} // namespace blender::gpu
143
145
158
160void GPU_indexbuf_init_ex(GPUIndexBufBuilder *, GPUPrimType, uint index_len, uint vertex_len);
161
163void GPU_indexbuf_init(GPUIndexBufBuilder *, GPUPrimType, uint prim_len, uint vertex_len);
165
167
169
170/*
171 * Thread safe.
172 *
173 * Function inspired by the reduction directives of multi-thread work API's.
174 */
175void GPU_indexbuf_join(GPUIndexBufBuilder *builder, const GPUIndexBufBuilder *builder_from);
176
179
184
188
189/* Skip primitive rendering at the given index. */
193
197 uint index_min,
198 uint index_max,
199 bool uses_restart_indices,
201
210 GPUPrimType prim_type,
211 const uint32_t *data,
212 int32_t data_len,
213 int32_t index_min,
214 int32_t index_max,
215 bool uses_restart_indices);
216
218
220 uint curves_num,
221 uint verts_per_curve);
222
223/* Upload data to the GPU (if not built on the device) and bind the buffer to its default target.
224 */
226
227/* Partially update the blender::gpu::IndexBuf which was already sent to the device, or built
228 * directly on the device. The data needs to be compatible with potential compression applied to
229 * the original indices when the index buffer was built, i.e., if the data was compressed to use
230 * shorts instead of ints, shorts should passed here. */
231void GPU_indexbuf_update_sub(blender::gpu::IndexBuf *elem, uint start, uint len, const void *data);
232
233/* Create a sub-range of an existing index-buffer. */
235 uint start,
236 uint length);
238 blender::gpu::IndexBuf *elem_src,
239 uint start,
240 uint length);
241
248
250
252
254
255/* Macros */
256
257#define GPU_INDEXBUF_DISCARD_SAFE(elem) \
258 do { \
259 if (elem != nullptr) { \
260 GPU_indexbuf_discard(elem); \
261 elem = nullptr; \
262 } \
263 } while (0)
unsigned int uint
void GPU_indexbuf_discard(blender::gpu::IndexBuf *elem)
void GPU_indexbuf_set_point_vert(GPUIndexBufBuilder *builder, uint elem, uint v1)
void GPU_indexbuf_build_in_place_ex(GPUIndexBufBuilder *builder, uint index_min, uint index_max, bool uses_restart_indices, blender::gpu::IndexBuf *elem)
int GPU_indexbuf_primitive_len(GPUPrimType prim_type)
blender::MutableSpan< uint32_t > GPU_indexbuf_get_data(GPUIndexBufBuilder *)
blender::gpu::IndexBuf * GPU_indexbuf_build_on_device(uint index_len)
void GPU_indexbuf_set_point_restart(GPUIndexBufBuilder *builder, uint elem)
void GPU_indexbuf_create_subrange_in_place(blender::gpu::IndexBuf *elem, blender::gpu::IndexBuf *elem_src, uint start, uint length)
void GPU_indexbuf_init(GPUIndexBufBuilder *, GPUPrimType, uint prim_len, uint vertex_len)
void GPU_indexbuf_bind_as_ssbo(blender::gpu::IndexBuf *elem, int binding)
void GPU_indexbuf_add_primitive_restart(GPUIndexBufBuilder *)
blender::gpu::IndexBuf * GPU_indexbuf_calloc()
void GPU_indexbuf_add_point_vert(GPUIndexBufBuilder *, uint v)
blender::gpu::IndexBuf * GPU_indexbuf_build(GPUIndexBufBuilder *)
void GPU_indexbuf_add_line_verts(GPUIndexBufBuilder *, uint v1, uint v2)
void GPU_indexbuf_join(GPUIndexBufBuilder *builder, const GPUIndexBufBuilder *builder_from)
blender::gpu::IndexBuf * GPU_indexbuf_build_curves_on_device(GPUPrimType prim_type, uint curves_num, uint verts_per_curve)
void GPU_indexbuf_set_line_verts(GPUIndexBufBuilder *builder, uint elem, uint v1, uint v2)
void GPU_indexbuf_read(blender::gpu::IndexBuf *elem, uint32_t *data)
void GPU_indexbuf_set_tri_verts(GPUIndexBufBuilder *builder, uint elem, uint v1, uint v2, uint v3)
void GPU_indexbuf_set_line_restart(GPUIndexBufBuilder *builder, uint elem)
void GPU_indexbuf_add_generic_vert(GPUIndexBufBuilder *, uint v)
void GPU_indexbuf_build_in_place(GPUIndexBufBuilder *, blender::gpu::IndexBuf *)
void GPU_indexbuf_set_tri_restart(GPUIndexBufBuilder *builder, uint elem)
void GPU_indexbuf_add_line_adj_verts(GPUIndexBufBuilder *, uint v1, uint v2, uint v3, uint v4)
void GPU_indexbuf_use(blender::gpu::IndexBuf *elem)
void GPU_indexbuf_build_in_place_from_memory(blender::gpu::IndexBuf *ibo, GPUPrimType prim_type, const uint32_t *data, int32_t data_len, int32_t index_min, int32_t index_max, bool uses_restart_indices)
blender::gpu::IndexBuf * GPU_indexbuf_create_subrange(blender::gpu::IndexBuf *elem_src, uint start, uint length)
void GPU_indexbuf_init_ex(GPUIndexBufBuilder *, GPUPrimType, uint index_len, uint vertex_len)
void GPU_indexbuf_update_sub(blender::gpu::IndexBuf *elem, uint start, uint len, const void *data)
void GPU_indexbuf_init_build_on_device(blender::gpu::IndexBuf *elem, uint index_len)
bool GPU_indexbuf_is_init(blender::gpu::IndexBuf *elem)
void GPU_indexbuf_add_tri_verts(GPUIndexBufBuilder *, uint v1, uint v2, uint v3)
GPUPrimType
@ GPU_PRIM_TRIS_ADJ
@ GPU_PRIM_LINES
@ GPU_PRIM_POINTS
@ GPU_PRIM_LINES_ADJ
@ GPU_PRIM_TRIS
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
void init()
uint32_t index_start_get() const
uint32_t index_base_get() const
virtual void upload_data()=0
virtual void read(uint32_t *data) const =0
GPUIndexBufType index_type_
virtual void update_sub(uint start, uint len, const void *data)=0
void init_build_on_device(uint index_len)
void init_subrange(IndexBuf *elem_src, uint start, uint length)
uint32_t index_len_get() const
virtual void bind_as_ssbo(uint binding)=0
int len
size_t to_bytesize(GPUIndexBufType type)
constexpr uint32_t RESTART_INDEX
int indices_per_primitive(GPUPrimType prim_type)
unsigned short uint16_t
Definition stdint.h:79
unsigned int uint32_t
Definition stdint.h:80
signed int int32_t
Definition stdint.h:77