Blender
V3.3
source
blender
gpu
metal
mtl_uniform_buffer.mm
Go to the documentation of this file.
1
/* SPDX-License-Identifier: GPL-2.0-or-later */
2
7
#include "
BKE_global.h
"
8
9
#include "
BLI_string.h
"
10
11
#include "
gpu_backend.hh
"
12
#include "
gpu_context_private.hh
"
13
14
#include "
mtl_backend.hh
"
15
#include "
mtl_context.hh
"
16
#include "
mtl_debug.hh
"
17
#include "
mtl_uniform_buffer.hh
"
18
19
namespace
blender::gpu
{
20
21
MTLUniformBuf::MTLUniformBuf
(
size_t
size
,
const
char
*name) :
UniformBuf
(
size
, name)
22
{
23
}
24
25
MTLUniformBuf::~MTLUniformBuf
()
26
{
27
if
(metal_buffer_ !=
nullptr
) {
28
metal_buffer_->
free
();
29
metal_buffer_ =
nullptr
;
30
}
31
has_data_ =
false
;
32
33
/* Ensure UBO is not bound to active CTX.
34
* UBO bindings are reset upon Context-switch so we do not need
35
* to check deactivated context's. */
36
MTLContext
*ctx =
MTLContext::get
();
37
if
(ctx) {
38
for
(
int
i = 0; i <
MTL_MAX_UNIFORM_BUFFER_BINDINGS
; i++) {
39
MTLUniformBufferBinding
&slot = ctx->
pipeline_state
.
ubo_bindings
[i];
40
if
(slot.
bound
&& slot.
ubo
==
this
) {
41
slot.
bound
=
false
;
42
slot.
ubo
=
nullptr
;
43
}
44
}
45
}
46
}
47
48
void
MTLUniformBuf::update
(
const
void
*
data
)
49
{
50
BLI_assert
(
this
);
51
BLI_assert
(
size_in_bytes_
> 0);
52
53
/* Free existing allocation.
54
* The previous UBO resource will be tracked by the memory manager,
55
* in case dependent GPU work is still executing. */
56
if
(metal_buffer_ !=
nullptr
) {
57
metal_buffer_->
free
();
58
metal_buffer_ =
nullptr
;
59
}
60
61
/* Allocate MTL buffer */
62
MTLContext
*ctx =
static_cast<
MTLContext
*
>
(
unwrap
(
GPU_context_active_get
()));
63
BLI_assert
(ctx);
64
BLI_assert
(ctx->
device
);
65
UNUSED_VARS_NDEBUG
(ctx);
66
67
if
(
data
!=
nullptr
) {
68
metal_buffer_ =
MTLContext::get_global_memory_manager
().
allocate_with_data
(
69
size_in_bytes_
,
true
,
data
);
70
has_data_ =
true
;
71
72
metal_buffer_->
set_label
(
@"Uniform Buffer"
);
73
BLI_assert
(metal_buffer_ !=
nullptr
);
74
BLI_assert
(metal_buffer_->
get_metal_buffer
() != nil);
75
}
76
else
{
77
/* If data is not yet present, no buffer will be allocated and MTLContext will use an empty
78
* null buffer, containing zeroes, if the UBO is bound. */
79
metal_buffer_ =
nullptr
;
80
has_data_ =
false
;
81
}
82
}
83
84
void
MTLUniformBuf::bind
(
int
slot)
85
{
86
if
(slot < 0) {
87
MTL_LOG_WARNING
(
"Failed to bind UBO %p. uniform location %d invalid.\n"
,
this
, slot);
88
return
;
89
}
90
91
BLI_assert
(slot <
MTL_MAX_UNIFORM_BUFFER_BINDINGS
);
92
93
/* Bind current UBO to active context. */
94
MTLContext
*ctx =
MTLContext::get
();
95
BLI_assert
(ctx);
96
97
MTLUniformBufferBinding
&ctx_ubo_bind_slot = ctx->
pipeline_state
.
ubo_bindings
[slot];
98
ctx_ubo_bind_slot.
ubo
=
this
;
99
ctx_ubo_bind_slot.
bound
=
true
;
100
101
bind_slot_ = slot;
102
bound_ctx_ = ctx;
103
104
/* Check if we have any deferred data to upload. */
105
if
(
data_
!=
nullptr
) {
106
this->
update
(
data_
);
107
MEM_SAFE_FREE
(
data_
);
108
}
109
110
/* Ensure there is at least an empty dummy buffer. */
111
if
(metal_buffer_ ==
nullptr
) {
112
this->
update
(
nullptr
);
113
}
114
}
115
116
void
MTLUniformBuf::unbind
()
117
{
118
/* Unbind in debug mode to validate missing binds.
119
* Otherwise, only perform a full unbind upon destruction
120
* to ensure no lingering references. */
121
#ifndef NDEBUG
122
if
(
true
) {
123
#else
124
if
(
G
.debug &
G_DEBUG_GPU
) {
125
#endif
126
if
(bound_ctx_ !=
nullptr
&& bind_slot_ > -1) {
127
MTLUniformBufferBinding
&ctx_ubo_bind_slot =
128
bound_ctx_->
pipeline_state
.
ubo_bindings
[bind_slot_];
129
if
(ctx_ubo_bind_slot.
bound
&& ctx_ubo_bind_slot.
ubo
==
this
) {
130
ctx_ubo_bind_slot.
bound
=
false
;
131
ctx_ubo_bind_slot.
ubo
=
nullptr
;
132
}
133
}
134
}
135
136
/* Reset bind index. */
137
bind_slot_ = -1;
138
bound_ctx_ =
nullptr
;
139
}
140
141
id<MTLBuffer>
MTLUniformBuf::get_metal_buffer
(
int
*r_offset)
142
{
143
BLI_assert
(
this
);
144
*r_offset = 0;
145
if
(metal_buffer_ !=
nullptr
&& has_data_) {
146
*r_offset = 0;
147
metal_buffer_->
debug_ensure_used
();
148
return
metal_buffer_->
get_metal_buffer
();
149
}
150
else
{
151
*r_offset = 0;
152
return
nil;
153
}
154
}
155
156
int
MTLUniformBuf::get_size
()
157
{
158
BLI_assert
(
this
);
159
return
size_in_bytes_
;
160
}
161
162
}
// blender::gpu
BKE_global.h
G_DEBUG_GPU
@ G_DEBUG_GPU
Definition:
BKE_global.h:193
BLI_assert
#define BLI_assert(a)
Definition:
BLI_assert.h:46
BLI_string.h
UNUSED_VARS_NDEBUG
#define UNUSED_VARS_NDEBUG(...)
Definition:
BLI_utildefines.h:736
GPU_context_active_get
GPUContext * GPU_context_active_get(void)
Definition:
gpu_context.cc:142
MEM_SAFE_FREE
#define MEM_SAFE_FREE(v)
Definition:
MEM_guardedalloc.h:186
data
data
Definition:
bmesh_operator_api_inline.h:157
size
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition:
btDbvt.cpp:52
blender::gpu::MTLBufferPool::allocate_with_data
gpu::MTLBuffer * allocate_with_data(uint64_t size, bool cpu_visible, const void *data=nullptr)
Definition:
mtl_memory.mm:67
blender::gpu::MTLBuffer::get_metal_buffer
id< MTLBuffer > get_metal_buffer() const
Definition:
mtl_memory.mm:515
blender::gpu::MTLBuffer::debug_ensure_used
void debug_ensure_used()
Definition:
mtl_memory.mm:548
blender::gpu::MTLBuffer::free
void free()
Definition:
mtl_memory.mm:502
blender::gpu::MTLBuffer::set_label
void set_label(NSString *str)
Definition:
mtl_memory.mm:543
blender::gpu::MTLContext
Definition:
mtl_context.hh:570
blender::gpu::MTLContext::pipeline_state
MTLContextGlobalShaderPipelineState pipeline_state
Definition:
mtl_context.hh:600
blender::gpu::MTLContext::device
id< MTLDevice > device
Definition:
mtl_context.hh:604
blender::gpu::MTLContext::get
static MTLContext * get()
Definition:
mtl_context.hh:629
blender::gpu::MTLContext::get_global_memory_manager
static MTLBufferPool & get_global_memory_manager()
Definition:
mtl_context.hh:713
blender::gpu::MTLUniformBuf::unbind
void unbind() override
Definition:
mtl_uniform_buffer.mm:116
blender::gpu::MTLUniformBuf::~MTLUniformBuf
~MTLUniformBuf()
Definition:
mtl_uniform_buffer.mm:25
blender::gpu::MTLUniformBuf::MTLUniformBuf
MTLUniformBuf(size_t size, const char *name)
Definition:
mtl_uniform_buffer.mm:21
blender::gpu::MTLUniformBuf::bind
void bind(int slot) override
Definition:
mtl_uniform_buffer.mm:84
blender::gpu::MTLUniformBuf::update
void update(const void *data) override
Definition:
mtl_uniform_buffer.mm:48
blender::gpu::MTLUniformBuf::get_size
int get_size()
Definition:
mtl_uniform_buffer.mm:156
blender::gpu::MTLUniformBuf::get_metal_buffer
id< MTLBuffer > get_metal_buffer(int *r_offset)
Definition:
mtl_uniform_buffer.mm:141
blender::gpu::UniformBuf
Definition:
gpu_uniform_buffer_private.hh:27
blender::gpu::UniformBuf::data_
void * data_
Definition:
gpu_uniform_buffer_private.hh:32
blender::gpu::UniformBuf::size_in_bytes_
size_t size_in_bytes_
Definition:
gpu_uniform_buffer_private.hh:30
gpu_backend.hh
gpu_context_private.hh
G
#define G(x, y, z)
mtl_backend.hh
MTL_MAX_UNIFORM_BUFFER_BINDINGS
#define MTL_MAX_UNIFORM_BUFFER_BINDINGS
Definition:
mtl_capabilities.hh:17
mtl_context.hh
mtl_debug.hh
MTL_LOG_WARNING
#define MTL_LOG_WARNING(info,...)
Definition:
mtl_debug.hh:36
mtl_uniform_buffer.hh
blender::gpu
Definition:
gpu_backend.hh:15
blender::gpu::unwrap
static Context * unwrap(GPUContext *ctx)
Definition:
gpu_context_private.hh:87
blender::gpu::MTLContextGlobalShaderPipelineState::ubo_bindings
MTLUniformBufferBinding ubo_bindings[MTL_MAX_UNIFORM_BUFFER_BINDINGS]
Definition:
mtl_context.hh:404
blender::gpu::MTLUniformBufferBinding
Definition:
mtl_context.hh:380
blender::gpu::MTLUniformBufferBinding::ubo
MTLUniformBuf * ubo
Definition:
mtl_context.hh:382
blender::gpu::MTLUniformBufferBinding::bound
bool bound
Definition:
mtl_context.hh:381
Generated on Tue Oct 22 2024 13:18:25 for Blender by
doxygen
1.9.1