This port is not so straightforward. This shader is used in different configurations and is available to python bindings. So we need to keep compatibility with different attributes configurations. This is why attributes are loaded per component and a uniform sets the length of the component. Since this shader can be used from both the imm and batch API, we need to inject some workarounds to bind the buffers correctly. The end result is still less versatile than the previous metal workaround (i.e.: more attribute fetch mode supported), but it is also way less code. ### Limitations: The new shader has some limitation: - Both `color` and `pos` attributes need to be `F32`. - Each attribute needs to be 4byte aligned. - Fetch type needs to be `GPU_FETCH_FLOAT`. - Primitive type needs to be `GPU_PRIM_LINES`, `GPU_PRIM_LINE_STRIP` or `GPU_PRIM_LINE_LOOP`. - If drawing using an index buffer, it must contain no primitive restart. Rel #127493 Co-authored-by: Jeroen Bakker <jeroen@blender.org> Pull Request: https://projects.blender.org/blender/blender/pulls/129315
100 lines
2.5 KiB
C++
100 lines
2.5 KiB
C++
/* SPDX-FileCopyrightText: 2022 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup gpu
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
#include "gpu_storage_buffer_private.hh"
|
|
|
|
#include "mtl_context.hh"
|
|
|
|
namespace blender::gpu {
|
|
|
|
class MTLUniformBuf;
|
|
class MTLVertBuf;
|
|
class MTLIndexBuf;
|
|
class MTLCircularBuffer;
|
|
|
|
/**
|
|
* Implementation of Storage Buffers using Metal.
|
|
*/
|
|
class MTLStorageBuf : public StorageBuf {
|
|
friend MTLCircularBuffer;
|
|
|
|
private:
|
|
/** Allocation Handle or indirect wrapped instance.
|
|
* MTLStorageBuf can wrap a MTLVertBuf, MTLIndexBuf or MTLUniformBuf for binding as a writeable
|
|
* resource. */
|
|
enum {
|
|
MTL_STORAGE_BUF_TYPE_DEFAULT = 0,
|
|
MTL_STORAGE_BUF_TYPE_UNIFORMBUF = 1,
|
|
MTL_STORAGE_BUF_TYPE_VERTBUF = 2,
|
|
MTL_STORAGE_BUF_TYPE_INDEXBUF = 3,
|
|
MTL_STORAGE_BUF_TYPE_TEXTURE = 4,
|
|
} storage_source_ = MTL_STORAGE_BUF_TYPE_DEFAULT;
|
|
|
|
union {
|
|
/** Own allocation. */
|
|
gpu::MTLBuffer *metal_buffer_;
|
|
/* Wrapped type. */
|
|
MTLUniformBuf *uniform_buffer_;
|
|
MTLVertBuf *vertex_buffer_;
|
|
MTLIndexBuf *index_buffer_;
|
|
gpu::MTLTexture *texture_;
|
|
};
|
|
|
|
/* Whether buffer has contents, if false, no GPU buffer will
|
|
* have yet been allocated. */
|
|
bool has_data_ = false;
|
|
/** Bind-state tracking. */
|
|
int bind_slot_ = -1;
|
|
MTLContext *bound_ctx_ = nullptr;
|
|
|
|
/** Usage type. */
|
|
GPUUsageType usage_;
|
|
|
|
/* Synchronization event for host reads. */
|
|
id<MTLSharedEvent> gpu_write_fence_ = nil;
|
|
uint64_t host_read_signal_value_ = 0;
|
|
|
|
public:
|
|
MTLStorageBuf(size_t size, GPUUsageType usage, const char *name);
|
|
~MTLStorageBuf() override;
|
|
|
|
MTLStorageBuf(MTLUniformBuf *uniform_buf, size_t size);
|
|
MTLStorageBuf(MTLVertBuf *vert_buf, size_t size);
|
|
MTLStorageBuf(MTLIndexBuf *index_buf, size_t size);
|
|
MTLStorageBuf(MTLTexture *texture, size_t size);
|
|
|
|
/* Only used internally to create a bindable buffer for #Immediate. */
|
|
MTLStorageBuf(size_t size);
|
|
|
|
void update(const void *data) override;
|
|
void bind(int slot) override;
|
|
void unbind() override;
|
|
void clear(uint32_t clear_value) override;
|
|
void copy_sub(VertBuf *src, uint dst_offset, uint src_offset, uint copy_size) override;
|
|
void read(void *data) override;
|
|
void async_flush_to_host() override;
|
|
void sync_as_indirect_buffer() override{/* No-Op. */};
|
|
|
|
void init();
|
|
|
|
id<MTLBuffer> get_metal_buffer();
|
|
size_t get_size();
|
|
const char *get_name()
|
|
{
|
|
return name_;
|
|
}
|
|
|
|
private:
|
|
MEM_CXX_CLASS_ALLOC_FUNCS("MTLStorageBuf");
|
|
};
|
|
|
|
} // namespace blender::gpu
|