27 this->free_optimized_buffer();
31 ssbo_wrapper_ =
nullptr;
35void MTLIndexBuf::free_optimized_buffer()
38 optimized_ibo_->
free();
39 optimized_ibo_ =
nullptr;
48 this->free_optimized_buffer();
57 if (ssbo_wrapper_ ==
nullptr) {
62 ssbo_wrapper_->
bind(binding);
67 if (ibo_ !=
nullptr) {
74 if (source_buffer.storageMode == MTLStorageModeManaged) {
76 [enc synchronizeResource:source_buffer];
87 BLI_assert(
false &&
"Index buffer not ready to be read.");
99 "Cannot use sub-range on stripped point buffer.");
104 if (alloc_size_ != mtlsrc->alloc_size_ || ibo_ != mtlsrc->ibo_) {
107 alloc_size_ = mtlsrc->alloc_size_;
111 this->free_optimized_buffer();
117 if ((ibo_ !=
nullptr) && (this->
data_ !=
nullptr)) {
118 MTL_LOG_INFO(
"Re-creating index buffer with new data. IndexBuf %p",
this);
124 if (ibo_ ==
nullptr) {
126 if (alloc_size_ == 0) {
127 MTL_LOG_WARNING(
"Warning! Trying to allocate index buffer with size=0 bytes");
132 alloc_size_,
true,
data_);
153 if (
data_ !=
nullptr) {
164 void *modified_base_ptr =
data_;
167 modified_base_ptr =
static_cast<void *
>(
ptr);
170 memcpy(modified_base_ptr, data,
len);
182 memcpy(range.data, data,
len);
190 [enc copyFromBuffer:range.metal_buffer
191 sourceOffset:(
uint32_t)range.buffer_offset
193 destinationOffset:start
198 if (dest_buffer.storageMode == MTLStorageModeManaged) {
199 [enc synchronizeResource:dest_buffer];
203 this->free_optimized_buffer();
214 can_optimize_ = can_optimize;
222 "Index buffer optimization disabled, but optimal buffer already generated.");
245 for (
int c_index = 0; c_index < input_index_len; c_index++) {
246 T current_index = original_data[c_index];
247 if (current_index ==
T(-1)) {
249 current_vert_len = 0;
252 if (current_vert_len < 3) {
255 indices[current_vert_len] = current_index;
259 if (current_vert_len == 3) {
261 output_data[current_output_ind++] = indices[0];
262 output_data[current_output_ind++] = indices[1];
263 output_data[current_output_ind++] = indices[2];
265 else if (current_vert_len > 3) {
269 uint32_t tri_id = current_vert_len - 3;
270 uint32_t base_output_ind = current_output_ind;
271 if ((tri_id % 2) == 0) {
272 output_data[base_output_ind + 0] = output_data[base_output_ind - 2];
273 output_data[base_output_ind + 1] = current_index;
274 output_data[base_output_ind + 2] = output_data[base_output_ind - 1];
277 output_data[base_output_ind + 0] = output_data[base_output_ind - 1];
278 output_data[base_output_ind + 1] = output_data[base_output_ind - 2];
279 output_data[base_output_ind + 2] = current_index;
281 current_output_ind += 3;
288 return current_output_ind;
298 T base_prim_ind_val = 0;
303 for (
int c_index = 0; c_index < input_index_len; c_index++) {
304 T current_index = original_data[c_index];
305 if (current_index ==
T(-1)) {
307 current_vert_len = 0;
310 if (current_vert_len < 3) {
313 indices[current_vert_len] = current_index;
317 if (current_vert_len == 3) {
319 output_data[current_output_ind++] = indices[0];
320 output_data[current_output_ind++] = indices[1];
321 output_data[current_output_ind++] = indices[2];
322 base_prim_ind_val = indices[0];
324 else if (current_vert_len > 3) {
328 uint32_t base_output_ind = current_output_ind;
330 output_data[base_output_ind + 0] = base_prim_ind_val;
331 output_data[base_output_ind + 1] = output_data[base_output_ind - 1];
332 output_data[base_output_ind + 2] = current_index;
333 current_output_ind += 3;
340 return current_output_ind;
349 bool should_optimize_or_emulate = (in_out_primitive_type ==
GPU_PRIM_TRI_FAN) ||
351 if (!should_optimize_or_emulate ||
is_subrange_ || !can_optimize_) {
361 GPUPrimType input_prim_type = in_out_primitive_type;
363 if (!ibo_ && optimized_ibo_ ==
nullptr) {
369 if (optimized_ibo_ !=
nullptr && optimized_primitive_type_ != input_prim_type) {
371 "Cannot change the optimized primitive format after generation, as source "
372 "index buffer data is discarded.");
377 if (optimized_ibo_ ==
nullptr) {
380 switch (input_prim_type) {
411 BLI_assert(emulated_v_count <= max_possible_verts);
414 optimized_ibo_->
flush();
415 optimized_primitive_type_ = input_prim_type;
416 in_out_v_count = emulated_v_count;
450 BLI_assert(emulated_v_count <= max_possible_verts);
453 optimized_ibo_->
flush();
454 optimized_primitive_type_ = input_prim_type;
455 in_out_v_count = emulated_v_count;
463 MTL_LOG_INFO(
"TODO: Primitive topology: Optimize line strip topology types");
471 "TODO: Primitive topology: Line Loop Index buffer optimization required for "
491 if (optimized_ibo_ !=
nullptr) {
494 if (ibo_ !=
nullptr) {
500 in_out_v_count = emulated_v_count;
507void MTLIndexBuf::strip_restart_indices()
519 if (uint_idx[i] == 0xFFFFFFFFu) {
525 if (uint_idx[j] == 0xFFFFFFFFu) {
541 if (swap_index == -1) {
548 uint32_t swap_index_value = uint_idx[swap_index];
549 uint_idx[i] = swap_index_value;
550 uint_idx[swap_index] = 0xFFFFFFFFu;
560 point_restarts_stripped_ =
true;
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
MINLINE uint ceil_to_multiple_u(uint a, uint b)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
GPUIndexBufType index_type_
gpu::MTLBuffer * allocate_with_data(uint64_t size, bool cpu_visible, const void *data=nullptr)
gpu::MTLBuffer * allocate(uint64_t size, bool cpu_visible)
void * get_host_ptr() const
void set_label(NSString *str)
id< MTLBuffer > get_metal_buffer() const
id< MTLBlitCommandEncoder > ensure_begin_blit_encoder()
static MTLContext * get()
MTLCommandBufferManager main_command_buffer
MTLScratchBufferManager & get_scratchbuffer_manager()
static MTLBufferPool * get_global_memory_manager()
void upload_data() override
void read(uint32_t *data) const override
friend class MTLStorageBuf
id< MTLBuffer > get_index_buffer(GPUPrimType &in_out_primitive_type, uint &in_out_v_count)
void bind_as_ssbo(uint32_t binding) override
void update_sub(uint32_t start, uint32_t len, const void *data) override
void flag_can_optimize(bool can_optimize)
MTLTemporaryBuffer scratch_buffer_allocate_range(uint64_t alloc_size)
void bind(int slot) override
#define MTL_LOG_INFO(info,...)
#define MTL_LOG_WARNING(info,...)
static uint32_t populate_emulated_tri_fan_buf(Span< T > original_data, MutableSpan< T > output_data, uint32_t input_index_len)
static uint32_t populate_optimized_tri_strip_buf(Span< T > original_data, MutableSpan< T > output_data, uint32_t input_index_len)