diff options
Diffstat (limited to 'source/blender/gpu/metal/mtl_index_buffer.hh')
-rw-r--r-- | source/blender/gpu/metal/mtl_index_buffer.hh | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/source/blender/gpu/metal/mtl_index_buffer.hh b/source/blender/gpu/metal/mtl_index_buffer.hh new file mode 100644 index 00000000000..702aa7f27d6 --- /dev/null +++ b/source/blender/gpu/metal/mtl_index_buffer.hh @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup gpu + */ + +#pragma once + +#include "MEM_guardedalloc.h" +#include "gpu_index_buffer_private.hh" +#include "mtl_context.hh" +#include <Cocoa/Cocoa.h> +#include <Metal/Metal.h> +#include <QuartzCore/QuartzCore.h> + +namespace blender::gpu { + +class MTLIndexBuf : public IndexBuf { + friend class MTLBatch; + friend class MTLDrawList; + + private: + /* Metal buffer resource. */ + gpu::MTLBuffer *ibo_ = nullptr; + uint64_t alloc_size_ = 0; + +#ifndef NDEBUG + /* Flags whether point index buffer has been compacted + * to remove false restart indices. */ + bool point_restarts_stripped_ = false; +#endif + + /* Optimized index buffers. + * NOTE(Metal): This optimization encodes a new index buffer following + * #TriangleList topology. Parsing of Index buffers is more optimal + * when not using restart-compatible primitive topology types. */ + GPUPrimType optimized_primitive_type_; + gpu::MTLBuffer *optimized_ibo_ = nullptr; + uint32_t emulated_v_count = 0; + void free_optimized_buffer(); + + /* Flags whether an index buffer can be optimized. + * For index buffers which are partially modified + * on the host, or by the GPU, optimization cannot be performed. */ + bool can_optimize_ = true; + + public: + ~MTLIndexBuf(); + + void bind_as_ssbo(uint32_t binding) override; + const uint32_t *read() const override; + + void upload_data() override; + void update_sub(uint32_t start, uint32_t len, const void *data) override; + + /* #get_index_buffer can conditionally return an optimized index buffer of a + * differing format, if it is concluded that optimization is preferred + * for the given inputs. + * Index buffer optimization is used to replace restart-compatible + * primitive types with non-restart-compatible ones such as #TriangleList and + * #LineList. This improves GPU execution for these types significantly, while + * only incurring a small performance penalty. + * + * This is also used to emulate unsupported topology types + * such as triangle fan. */ + id<MTLBuffer> get_index_buffer(GPUPrimType &in_out_primitive_type, uint &in_out_v_count); + void flag_can_optimize(bool can_optimize); + + static MTLIndexType gpu_index_type_to_metal(GPUIndexBufType type) + { + return (type == GPU_INDEX_U16) ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32; + } + + private: + void strip_restart_indices() override; + + MEM_CXX_CLASS_ALLOC_FUNCS("MTLIndexBuf") +}; + +} // namespace blender::gpu |