Blender V5.0
mtl_shader_interface.mm
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2022-2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10
11#include "BLI_bitmap.h"
12
13#include "GPU_capabilities.hh"
14
15#include "mtl_common.hh"
16#include "mtl_debug.hh"
19
20#include "BLI_math_base.h"
21#include "BLI_string.h"
22#include "BLI_utildefines.h"
23#include "MEM_guardedalloc.h"
24
25namespace blender::gpu {
26
28{
29 /* Shared ShaderInputs array is populated later on in `prepare_common_shader_inputs`
30 * after Metal Shader Interface preparation. */
31 inputs_ = nullptr;
32
33 if (name != nullptr) {
34 STRNCPY(this->name, name);
35 }
36
37 /* Ensure #ShaderInterface parameters are cleared. */
38 this->init();
39}
40
42{
43 for (const int i : IndexRange(ARGUMENT_ENCODERS_CACHE_SIZE)) {
44 if (arg_encoders_[i].encoder != nil) {
45 id<MTLArgumentEncoder> enc = arg_encoders_[i].encoder;
46 [enc release];
47 }
48 }
49}
50
51const char *MTLShaderInterface::get_name_at_offset(uint32_t offset) const
52{
53 return name_buffer_ + offset;
54}
55
57{
58 total_attributes_ = 0;
59 total_constants_ = 0;
60 total_uniform_blocks_ = 0;
61 max_uniformbuf_index_ = 0;
62 total_storage_blocks_ = 0;
63 max_storagebuf_index_ = 0;
64 total_uniforms_ = 0;
65 total_textures_ = 0;
66 max_texture_index_ = -1;
67 enabled_attribute_mask_ = 0;
68 total_vert_stride_ = 0;
69 sampler_use_argument_buffer_ = false;
70 for (int i = 0; i < ARRAY_SIZE(sampler_argument_buffer_bind_index_); i++) {
71 sampler_argument_buffer_bind_index_[i] = -1;
72 }
73
74 /* NULL initialize uniform location markers for builtins. */
75 for (const int u : IndexRange(GPU_NUM_UNIFORMS)) {
76 builtins_[u] = -1;
77 }
78 for (const int ubo : IndexRange(GPU_NUM_UNIFORM_BLOCKS)) {
79 builtin_blocks_[ubo] = -1;
80 }
81 for (const int tex : IndexRange(MTL_MAX_TEXTURE_SLOTS)) {
82 textures_[tex].used = false;
83 textures_[tex].slot_index = -1;
84 }
85
86 /* Null initialization for argument encoders. */
87 for (const int i : IndexRange(ARGUMENT_ENCODERS_CACHE_SIZE)) {
88 arg_encoders_[i].encoder = nil;
89 arg_encoders_[i].buffer_index = -1;
90 }
91}
92
94 uint32_t attribute_location,
95 MTLVertexFormat format,
96 uint32_t buffer_index,
97 uint32_t size,
98 uint32_t offset,
99 int matrix_element_count)
100{
101 MTLShaderInputAttribute &input_attr = attributes_[total_attributes_];
102 input_attr.name_offset = name_offset;
103 input_attr.format = format;
104 input_attr.location = attribute_location;
105 input_attr.size = size;
106 input_attr.buffer_index = buffer_index;
107 input_attr.offset = offset;
108 input_attr.matrix_element_count = matrix_element_count;
109 input_attr.index = total_attributes_;
110 total_attributes_++;
111 total_vert_stride_ = max_ii(total_vert_stride_, offset + size);
112 enabled_attribute_mask_ |= (1 << attribute_location);
113}
114
115uint32_t MTLShaderInterface::add_uniform_block(uint32_t name_offset,
116 uint32_t buffer_index,
117 uint32_t location,
118 uint32_t size,
119 ShaderStage /*stage_mask*/)
120{
121 /* Ensure Size is 16 byte aligned to guarantees alignment rules are satisfied. */
122 if ((size % 16) != 0) {
123 size += 16 - (size % 16);
124 }
125
126 BLI_assert(buffer_index < MTL_MAX_BUFFER_BINDINGS);
127
128 MTLShaderBufferBlock &uni_block = ubos_[total_uniform_blocks_];
129 uni_block.name_offset = name_offset;
130 uni_block.buffer_index = buffer_index;
131 uni_block.location = location;
132 uni_block.size = size;
133 uni_block.current_offset = 0;
134 uni_block.stage_mask = ShaderStage::ANY;
135 max_uniformbuf_index_ = max_ii(max_uniformbuf_index_, buffer_index);
136 return (total_uniform_blocks_++);
137}
138
139uint32_t MTLShaderInterface::add_storage_block(uint32_t name_offset,
140 uint32_t buffer_index,
141 uint32_t location,
142 uint32_t size,
143 ShaderStage /*stage_mask*/)
144{
145 /* Ensure Size is 16 byte aligned to guarantees alignment rules are satisfied. */
146 if ((size % 16) != 0) {
147 size += 16 - (size % 16);
148 }
149
150 BLI_assert(buffer_index < MTL_MAX_BUFFER_BINDINGS);
151
152 MTLShaderBufferBlock &ssbo_block = ssbos_[total_storage_blocks_];
153 ssbo_block.name_offset = name_offset;
154 ssbo_block.buffer_index = buffer_index;
155 ssbo_block.location = location;
156 ssbo_block.size = size;
157 ssbo_block.current_offset = 0;
158 ssbo_block.stage_mask = ShaderStage::ANY;
159 max_storagebuf_index_ = max_ii(max_storagebuf_index_, buffer_index);
160 return (total_storage_blocks_++);
161}
162
164{
165 push_constant_block_.name_offset = name_offset;
166 /* Push constant data block is always uniform buffer index 0. */
167 push_constant_block_.buffer_index = 0;
168 /* Size starts at zero and grows as uniforms are added. */
169 push_constant_block_.size = 0;
170
171 push_constant_block_.current_offset = 0;
172 push_constant_block_.stage_mask = ShaderStage::ANY;
173}
174
175void MTLShaderInterface::add_uniform(uint32_t name_offset,
177 int array_len)
178{
179 BLI_assert(array_len > 0);
180 BLI_assert(total_uniforms_ < MTL_MAX_UNIFORMS_PER_BLOCK);
181 if (total_uniforms_ >= MTL_MAX_UNIFORMS_PER_BLOCK) {
183 "Cannot add uniform '%s' to shader interface '%s' as the uniform limit of %d has been "
184 "reached.",
185 name,
186 name,
188 return;
189 }
190 MTLShaderUniform &uniform = uniforms_[total_uniforms_];
191 uniform.name_offset = name_offset;
192
193 /* Determine size and offset alignment -- C++ struct alignment rules: Base address of value must
194 * match alignment of type. GLSL follows minimum type alignment of 4. */
195 int data_type_size = mtl_get_data_type_size(type) * array_len;
196 int data_type_alignment = mtl_get_data_type_alignment(type);
197 int current_offset = push_constant_block_.current_offset;
198 if ((current_offset % data_type_alignment) != 0) {
199 current_offset += data_type_alignment - (current_offset % data_type_alignment);
200 }
201
202 uniform.size_in_bytes = data_type_size;
203 uniform.byte_offset = current_offset;
204 uniform.type = type;
205 uniform.array_len = array_len;
206 total_uniforms_++;
207
208 /* Update Push constant block-- update offset, re-size and re-align total memory requirement to
209 * be 16-byte aligned. Following GLSL std140. */
210 push_constant_block_.current_offset = current_offset + data_type_size;
211 if (push_constant_block_.current_offset > push_constant_block_.size) {
212 push_constant_block_.size = push_constant_block_.current_offset;
213 if ((push_constant_block_.size % 16) != 0) {
214 push_constant_block_.size += 16 - (push_constant_block_.size % 16);
215 }
216 }
217
218 /* Validate properties. */
219 BLI_assert(uniform.size_in_bytes > 0);
221 current_offset + data_type_size <= push_constant_block_.size,
222 "Uniform size and offset sits outside the specified size range for the uniform block");
223}
224
225void MTLShaderInterface::add_texture(uint32_t name_offset,
226 uint32_t texture_slot,
227 uint32_t location,
228 GPUTextureType tex_binding_type,
229 GPUSamplerFormat sampler_format,
230 bool is_texture_sampler,
231 ShaderStage stage_mask,
232 int tex_buffer_ssbo_location)
233{
234 BLI_assert(texture_slot >= 0 && texture_slot < GPU_max_textures());
235 BLI_assert(sampler_format < GPU_SAMPLER_TYPE_MAX);
236 if (texture_slot >= 0 && texture_slot < GPU_max_textures()) {
237
238 MTLShaderTexture &tex = textures_[texture_slot];
239 BLI_assert_msg(tex.used == false, "Texture slot already in-use by another binding");
240 tex.name_offset = name_offset;
241 tex.slot_index = texture_slot;
242 tex.location = location;
243 tex.type = tex_binding_type;
244 tex.sampler_format = sampler_format;
245 tex.is_texture_sampler = is_texture_sampler;
246 tex.stage_mask = stage_mask;
247 tex.used = true;
248 tex.texture_buffer_ssbo_location = tex_buffer_ssbo_location;
249 total_textures_++;
250 max_texture_index_ = max_ii(max_texture_index_, texture_slot);
251 }
252 else {
253 BLI_assert_msg(false, "Exceeding maximum supported texture count.");
255 "Could not add additional texture with index %d to shader interface. Maximum "
256 "supported texture count is %d",
257 texture_slot,
259 }
260}
261
262void MTLShaderInterface::add_constant(uint32_t name_offset)
263{
264 MTLShaderConstant constant;
265 constant.name_offset = name_offset;
266 constants_.append(constant);
267 total_constants_++;
268}
269
271{
272 /* Clear builtin arrays to NULL locations. */
273 for (const int u : IndexRange(GPU_NUM_UNIFORMS)) {
274 builtins_[u] = -1;
275 }
276 for (const int ubo : IndexRange(GPU_NUM_UNIFORM_BLOCKS)) {
277 builtin_blocks_[ubo] = -1;
278 }
279
280 /* Resolve and cache uniform locations for builtin uniforms. */
281 for (const int u : IndexRange(GPU_NUM_UNIFORMS)) {
283 if (uni != nullptr) {
284 BLI_assert(uni->location >= 0);
285 if (uni->location >= 0) {
286 builtins_[u] = uni->location;
287 MTL_LOG_DEBUG("Mapped builtin uniform '%s' NB: '%s' to location: %d",
290 uni->location);
291 }
292 }
293 }
294
295 /* Resolve and cache uniform locations for builtin uniform blocks. */
296 for (const int u : IndexRange(GPU_NUM_UNIFORM_BLOCKS)) {
298
299 if (uni != nullptr) {
300 BLI_assert(uni->location >= 0);
301 if (uni->location >= 0) {
302 builtin_blocks_[u] = uni->binding;
303 MTL_LOG_DEBUG("Mapped builtin uniform block '%s' to location %d",
305 uni->location);
306 }
307 }
308 }
309}
310
311/* Populate #ShaderInput struct based on interface. */
313{
314 /* `ShaderInput inputs_` maps a uniform name to an external
315 * uniform location, which is used as an array index to look-up
316 * information in the local #MTLShaderInterface input structs.
317 *
318 * #ShaderInput population follows the ordering rules in #gpu_shader_interface. */
319
320 /* Populate #ShaderInterface counts. */
326
327 /* Calculate total inputs and allocate #ShaderInput array. */
328 /* NOTE: We use the existing `name_buffer_` allocated for internal input structs. */
329 int input_tot_len = attr_len_ + ubo_len_ + uniform_len_ + ssbo_len_ + constant_len_;
330 inputs_ = MEM_calloc_arrayN<ShaderInput>(input_tot_len, __func__);
331 ShaderInput *current_input = inputs_;
332
333 /* Attributes. */
334 for (const int attr_index : IndexRange(total_attributes_)) {
335 MTLShaderInputAttribute &shd_attr = attributes_[attr_index];
336 current_input->name_offset = shd_attr.name_offset;
337 current_input->name_hash = BLI_hash_string(this->get_name_at_offset(shd_attr.name_offset));
338 /* For Metal, we flatten the vertex attribute indices within the shader in order to minimize
339 * complexity. ShaderInput "Location" contains the original attribute location, as can be
340 * fetched using `GPU_shader_get_attribute_info`. ShaderInput binding contains the array index
341 * into the MTLShaderInterface `attributes_` array. */
342 current_input->location = shd_attr.location;
343 current_input->binding = attr_index;
344 current_input++;
345 }
346
347 /* UBOs. */
348 BLI_assert(&inputs_[attr_len_] >= current_input);
349 current_input = &inputs_[attr_len_];
350 for (const int ubo_index : IndexRange(total_uniform_blocks_)) {
351 MTLShaderBufferBlock &shd_ubo = ubos_[ubo_index];
352 current_input->name_offset = shd_ubo.name_offset;
353 current_input->name_hash = BLI_hash_string(this->get_name_at_offset(shd_ubo.name_offset));
354 /* Location refers to the index in the ubos_ array. */
355 current_input->location = shd_ubo.location;
356 /* Binding location refers to the UBO bind slot in
357 * #MTLContextGlobalShaderPipelineState::ubo_bindings. The buffer bind index [[buffer(N)]]
358 * within the shader will apply an offset for bound vertex buffers and the default uniform
359 * PushConstantBlock.
360 * see `mtl_shader_generator.hh` for buffer binding table breakdown. */
361 current_input->binding = shd_ubo.location;
362 current_input++;
363 }
364
365 /* Uniforms. */
366 BLI_assert(&inputs_[attr_len_ + ubo_len_] >= current_input);
367 current_input = &inputs_[attr_len_ + ubo_len_];
368 for (const int uniform_index : IndexRange(total_uniforms_)) {
369 MTLShaderUniform &shd_uni = uniforms_[uniform_index];
370 current_input->name_offset = shd_uni.name_offset;
371 current_input->name_hash = BLI_hash_string(this->get_name_at_offset(shd_uni.name_offset));
372 current_input->location = uniform_index;
373 current_input->binding = uniform_index;
374 current_input++;
375 }
376
377 /* Textures.
378 * NOTE(Metal): Textures are externally treated as uniforms in #gpu_shader_interface.
379 * Location for textures resolved as `binding` value. This
380 * is the index into the local `MTLShaderTexture textures[]` array.
381 *
382 * In MSL, we cannot trivially remap which texture slot a given texture
383 * handle points to, unlike in GLSL, where a uniform sampler/image can be updated
384 * and queried as both a texture and a uniform. */
385 for (int texture_index = 0; texture_index <= max_texture_index_; texture_index++) {
386 const MTLShaderTexture &shd_tex = textures_[texture_index];
387
388 /* Not all texture entries are used when explicit texture locations are specified. */
389 if (shd_tex.used) {
390 BLI_assert_msg(shd_tex.slot_index == texture_index,
391 "Texture binding slot should match array index for texture.");
392 current_input->name_offset = shd_tex.name_offset;
393 current_input->name_hash = BLI_hash_string(this->get_name_at_offset(shd_tex.name_offset));
394
395 /* Location represents look-up address.
396 * For Metal, this location is a unique value offset by
397 * total_uniforms such that it does not overlap.
398 *
399 * This range offset allows a check in the uniform look-up
400 * to ensure texture handles are not treated as standard uniforms in Metal. */
401 current_input->location = texture_index + total_uniforms_;
402
403 /* Binding represents texture slot `[[texture(n)]]`. */
404 current_input->binding = shd_tex.location;
405 current_input++;
406 }
407 }
408 if (info != nullptr) {
410 }
411
412 /* SSBO bindings. */
413 BLI_assert(&inputs_[attr_len_ + ubo_len_ + uniform_len_] >= current_input);
414 current_input = &inputs_[attr_len_ + ubo_len_ + uniform_len_];
415 BLI_assert(ssbo_len_ >= total_storage_blocks_);
416 for (const int ssbo_index : IndexRange(total_storage_blocks_)) {
417 MTLShaderBufferBlock &shd_ssbo = ssbos_[ssbo_index];
418 current_input->name_offset = shd_ssbo.name_offset;
419 current_input->name_hash = BLI_hash_string(this->get_name_at_offset(shd_ssbo.name_offset));
420 /* `Location` is used as the returned explicit bind index for SSBOs. */
421 current_input->location = shd_ssbo.location;
422 current_input->binding = shd_ssbo.location;
423 current_input++;
424 }
425
426 if (info != nullptr) {
429 ssbo_attr_mask_ |= (1 << res.slot);
430 }
431 else {
432 BLI_assert_msg(0, "Resource type is not supported for Geometry frequency");
433 }
434 }
435 }
436
437 /* Specialization Constants. */
438 BLI_assert(&inputs_[attr_len_ + ubo_len_ + uniform_len_ + ssbo_len_] >= current_input);
439 current_input = &inputs_[attr_len_ + ubo_len_ + uniform_len_ + ssbo_len_];
440 for (const int const_index : IndexRange(constant_len_)) {
441 MTLShaderConstant &shd_const = constants_[const_index];
442 current_input->name_offset = shd_const.name_offset;
443 current_input->name_hash = BLI_hash_string(this->get_name_at_offset(shd_const.name_offset));
444 current_input->location = const_index;
445 current_input++;
446 }
447
448 this->sort_inputs();
449
450 /* Map builtin uniform indices to uniform binding locations. */
451 this->map_builtins();
452
453 /* Pre-calculate texture metadata uniform locations for buffer-backed textures. */
454 for (int texture_index = 0; texture_index <= max_texture_index_; texture_index++) {
455 MTLShaderTexture &shd_tex = textures_[texture_index];
456 if (shd_tex.texture_buffer_ssbo_location != -1) {
457 char uniform_name[256];
458 const char *tex_name = get_name_at_offset(shd_tex.name_offset);
459 BLI_snprintf(uniform_name, 256, "%s_metadata", tex_name);
460 const ShaderInput *uni = this->uniform_get(uniform_name);
461 BLI_assert_msg(uni != nullptr,
462 "Could not find expected metadata uniform slot for buffer-backed texture.");
463 if (uni != nullptr) {
464 BLI_assert(uni->location >= 0);
465 if (uni->location >= 0) {
467 }
468 }
469 }
470 }
471}
472
473void MTLShaderInterface::set_sampler_properties(bool use_argument_buffer,
474 uint32_t argument_buffer_bind_index_vert,
475 uint32_t argument_buffer_bind_index_frag,
476 uint32_t argument_buffer_bind_index_compute)
477{
478 sampler_use_argument_buffer_ = use_argument_buffer;
479 sampler_argument_buffer_bind_index_[get_shader_stage_index(ShaderStage::VERTEX)] =
480 argument_buffer_bind_index_vert;
481 sampler_argument_buffer_bind_index_[get_shader_stage_index(ShaderStage::FRAGMENT)] =
482 argument_buffer_bind_index_frag;
483 sampler_argument_buffer_bind_index_[get_shader_stage_index(ShaderStage::COMPUTE)] =
484 argument_buffer_bind_index_compute;
485}
486
487/* Attributes. */
489{
492 return attributes_[index];
493}
494
496{
497 return total_attributes_;
498}
499
501{
502 return total_constants_;
503}
504
506{
507 return total_vert_stride_;
508}
509
511{
512 return enabled_attribute_mask_;
513}
514
515/* Uniforms. */
517{
520 return uniforms_[index];
521}
522
524{
525 return total_uniforms_;
526}
527
528/* Uniform Blocks. */
530{
533 return ubos_[index];
534}
535
537{
538 return push_constant_block_;
539}
540
542{
543 return total_uniform_blocks_;
544}
545
546bool MTLShaderInterface::has_uniform_block(uint32_t block_index) const
547{
548 return (block_index < total_uniform_blocks_);
549}
550
551uint32_t MTLShaderInterface::get_uniform_block_size(uint32_t block_index) const
552{
553 return (block_index < total_uniform_blocks_) ? ubos_[block_index].size : 0;
554}
555
556/* Storage Blocks. */
558{
561 return ssbos_[index];
562}
563
565{
566 return total_storage_blocks_;
567}
568
569bool MTLShaderInterface::has_storage_block(uint32_t block_index) const
570{
571 return (block_index < total_storage_blocks_);
572}
573
574uint32_t MTLShaderInterface::get_storage_block_size(uint32_t block_index) const
575{
576 return (block_index < total_storage_blocks_) ? ssbos_[block_index].size : 0;
577}
578
580{
581 /* PushConstantBlock + All uniform blocks + all storage blocks. */
583}
584
585/* Textures. */
587{
590 return textures_[index];
591}
592
594{
595 return total_textures_;
596}
597
599{
600 return max_texture_index_;
601}
602
604{
605 return sampler_use_argument_buffer_;
606}
607
609{
610 return sampler_argument_buffer_bind_index_[get_shader_stage_index(stage)];
611}
612
613id<MTLArgumentEncoder> MTLShaderInterface::find_argument_encoder(int buffer_index) const
614{
615 id encoder = nil;
616 for (const int i : IndexRange(ARGUMENT_ENCODERS_CACHE_SIZE)) {
617 encoder = arg_encoders_[i].buffer_index == buffer_index ? arg_encoders_[i].encoder : encoder;
618 }
619 return encoder;
620}
621
622void MTLShaderInterface::insert_argument_encoder(int buffer_index, id encoder)
623{
624 for (const int i : IndexRange(ARGUMENT_ENCODERS_CACHE_SIZE)) {
625 if (arg_encoders_[i].encoder == nil) {
626 arg_encoders_[i].encoder = encoder;
627 arg_encoders_[i].buffer_index = buffer_index;
628 return;
629 }
630 }
631 MTL_LOG_WARNING("could not insert encoder into cache!");
632}
633
635{
636 switch (type) {
638 return MTLVertexFormatChar;
640 return MTLVertexFormatUChar;
642 return MTLVertexFormatUChar;
644 return MTLVertexFormatChar2;
646 return MTLVertexFormatUChar2;
648 return MTLVertexFormatUChar2;
650 return MTLVertexFormatShort;
652 return MTLVertexFormatUShort;
654 return MTLVertexFormatChar3;
656 return MTLVertexFormatUChar3;
658 return MTLVertexFormatUChar3;
660 return MTLVertexFormatChar4;
662 return MTLVertexFormatUChar4;
663 case MTL_DATATYPE_INT:
664 return MTLVertexFormatInt;
666 return MTLVertexFormatUInt;
668 return MTLVertexFormatUChar4;
670 return MTLVertexFormatShort2;
672 return MTLVertexFormatUShort2;
674 return MTLVertexFormatFloat;
678 BLI_assert_msg(false, "Unsupported raw vertex attribute types in Blender.");
679 return MTLVertexFormatInvalid;
680
682 return MTLVertexFormatShort3;
684 return MTLVertexFormatUShort3;
686 return MTLVertexFormatShort4;
688 return MTLVertexFormatUShort4;
690 return MTLVertexFormatInt2;
692 return MTLVertexFormatUInt2;
694 return MTLVertexFormatFloat2;
696 return MTLVertexFormatInt;
698 return MTLVertexFormatUInt;
708 BLI_assert_msg(false, "Unsupported raw vertex attribute types in Blender.");
709 return MTLVertexFormatInvalid;
710
712 return MTLVertexFormatInt3;
714 return MTLVertexFormatInt4;
716 return MTLVertexFormatUInt3;
718 return MTLVertexFormatUInt4;
720 return MTLVertexFormatFloat3;
722 return MTLVertexFormatFloat4;
724 return MTLVertexFormatInt2;
726 return MTLVertexFormatUInt2;
733 BLI_assert_msg(false, "Unsupported raw vertex attribute types in Blender.");
734 return MTLVertexFormatInvalid;
735
737 return MTLVertexFormatInt3;
739 return MTLVertexFormatInt4;
741 return MTLVertexFormatUInt3;
743 return MTLVertexFormatUInt4;
744
745 /* Special Types */
747 return MTLVertexFormatUInt1010102Normalized;
749 return MTLVertexFormatInt1010102Normalized;
750
751 default:
752 BLI_assert(false);
753 return MTLVertexFormatInvalid;
754 };
755}
756
757} // namespace blender::gpu
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
BLI_INLINE unsigned int BLI_hash_string(const char *str)
Definition BLI_hash.h:67
MINLINE int max_ii(int a, int b)
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:693
size_t BLI_snprintf(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
unsigned int uint
#define ARRAY_SIZE(arr)
int GPU_max_textures()
#define GPU_NUM_UNIFORMS
GPUUniformBuiltin
GPUUniformBlockBuiltin
@ GPU_NUM_UNIFORM_BLOCKS
Read Guarded memory(de)allocation.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
bool has_storage_block(uint32_t block_index) const
uint32_t add_storage_block(uint32_t name_offset, uint32_t buffer_index, uint32_t location, uint32_t size, ShaderStage stage_mask=ShaderStage::ANY)
uint32_t add_uniform_block(uint32_t name_offset, uint32_t buffer_index, uint32_t location, uint32_t size, ShaderStage stage_mask=ShaderStage::ANY)
void add_texture(uint32_t name_offset, uint32_t texture_slot, uint32_t location, GPUTextureType tex_binding_type, GPUSamplerFormat sampler_format, bool is_texture_sampler, ShaderStage stage_mask=ShaderStage::FRAGMENT, int tex_buffer_ssbo_location=-1)
const MTLShaderBufferBlock & get_push_constant_block() const
const MTLShaderTexture & get_texture(uint index) const
void insert_argument_encoder(int buffer_index, id encoder)
const MTLShaderBufferBlock & get_uniform_block(uint index) const
uint32_t get_storage_block_size(uint32_t block_index) const
const char * get_name_at_offset(uint32_t offset) const
bool has_uniform_block(uint32_t block_index) const
int get_argument_buffer_bind_index(ShaderStage stage) const
const MTLShaderInputAttribute & get_attribute(uint index) const
const MTLShaderBufferBlock & get_storage_block(uint index) const
const MTLShaderUniform & get_uniform(uint index) const
void add_input_attribute(uint32_t name_offset, uint32_t attribute_location, MTLVertexFormat format, uint32_t buffer_index, uint32_t size, uint32_t offset, int matrix_element_count=1)
id< MTLArgumentEncoder > find_argument_encoder(int buffer_index) const
uint32_t get_uniform_block_size(uint32_t block_index) const
void add_constant(uint32_t name_offset)
void add_push_constant_block(uint32_t name_offset)
void set_sampler_properties(bool use_argument_buffer, uint32_t argument_buffer_bind_index_vert, uint32_t argument_buffer_bind_index_frag, uint32_t argument_buffer_bind_index_compute)
void add_uniform(uint32_t name_offset, MTLInterfaceDataType type, int array_len=1)
void prepare_common_shader_inputs(const shader::ShaderCreateInfo *info=nullptr)
void set_image_formats_from_info(const shader::ShaderCreateInfo &info)
const ShaderInput * uniform_get(const StringRefNull name) const
static const char * builtin_uniform_block_name(GPUUniformBlockBuiltin u)
const ShaderInput * ubo_get(const StringRefNull name) const
int32_t builtin_blocks_[GPU_NUM_UNIFORM_BLOCKS]
int32_t builtins_[GPU_NUM_UNIFORMS]
static const char * builtin_uniform_name(GPUUniformBuiltin u)
format
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
#define MTL_MAX_BUFFER_BINDINGS
#define MTL_MAX_TEXTURE_SLOTS
#define MTL_MAX_VERTEX_INPUT_ATTRIBUTES
#define MTL_MAX_UNIFORMS_PER_BLOCK
#define MTL_LOG_WARNING(info,...)
Definition mtl_debug.hh:42
#define MTL_LOG_DEBUG(info,...)
Definition mtl_debug.hh:49
uint mtl_get_data_type_alignment(MTLInterfaceDataType type)
@ MTL_DATATYPE_INT1010102_NORM
@ MTL_DATATYPE_UINT1010102_NORM
uint mtl_get_data_type_size(MTLInterfaceDataType type)
uint get_shader_stage_index(ShaderStage stage)
MTLVertexFormat mtl_datatype_to_vertex_type(MTLInterfaceDataType type)
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...
i
Definition text_draw.cc:230