Blender V5.0
mtl_index_buffer.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#pragma once
10
11#include "GPU_index_buffer.hh"
12#include "MEM_guardedalloc.h"
13
14#include "mtl_context.hh"
15
16#include <Cocoa/Cocoa.h>
17#include <Metal/Metal.h>
18#include <QuartzCore/QuartzCore.h>
19
20namespace blender::gpu {
21
22class MTLIndexBuf : public IndexBuf {
23 friend class MTLBatch;
24 friend class MTLDrawList;
25 friend class MTLStorageBuf; /* For bind as SSBO resource access. */
26
27 private:
28 /* Metal buffer resource. */
29 gpu::MTLBuffer *ibo_ = nullptr;
30 uint64_t alloc_size_ = 0;
31
32 /* SSBO wrapper for bind_as_ssbo support. */
33 MTLStorageBuf *ssbo_wrapper_ = nullptr;
34
35#ifndef NDEBUG
36 /* Flags whether point index buffer has been compacted
37 * to remove false restart indices. */
38 bool point_restarts_stripped_ = false;
39#endif
40
41 /* Optimized index buffers.
42 * NOTE(Metal): This optimization encodes a new index buffer following
43 * #TriangleList topology. Parsing of Index buffers is more optimal
44 * when not using restart-compatible primitive topology types. */
45 GPUPrimType optimized_primitive_type_;
46 gpu::MTLBuffer *optimized_ibo_ = nullptr;
47 uint32_t emulated_v_count = 0;
48 void free_optimized_buffer();
49
50 /* Flags whether an index buffer can be optimized.
51 * For index buffers which are partially modified
52 * on the host, or by the GPU, optimization cannot be performed. */
53 bool can_optimize_ = true;
54
55 public:
56 ~MTLIndexBuf() override;
57
58 void bind_as_ssbo(uint32_t binding) override;
59 void read(uint32_t *data) const override;
60
61 void upload_data() override;
62 void update_sub(uint32_t start, uint32_t len, const void *data) override;
63
64 /* #get_index_buffer can conditionally return an optimized index buffer of a
65 * differing format, if it is concluded that optimization is preferred
66 * for the given inputs.
67 * Index buffer optimization is used to replace restart-compatible
68 * primitive types with non-restart-compatible ones such as #TriangleList and
69 * #LineList. This improves GPU execution for these types significantly, while
70 * only incurring a small performance penalty.
71 *
72 * This is also used to emulate unsupported topology types
73 * such as triangle fan. */
74 id<MTLBuffer> get_index_buffer(GPUPrimType &in_out_primitive_type, uint &in_out_v_count);
75 void flag_can_optimize(bool can_optimize);
76
77 static MTLIndexType gpu_index_type_to_metal(GPUIndexBufType type)
78 {
79 return (type == GPU_INDEX_U16) ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32;
80 }
81
82 private:
83 void strip_restart_indices() override;
84
85 MEM_CXX_CLASS_ALLOC_FUNCS("MTLIndexBuf")
86};
87
88} // namespace blender::gpu
unsigned int uint
GPUPrimType
Read Guarded memory(de)allocation.
BMesh const char void * data
unsigned long long int uint64_t
static MTLIndexType gpu_index_type_to_metal(GPUIndexBufType type)
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)
uint len