Blender V4.3
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
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_blenlib.h"
21#include "BLI_math_base.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
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
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
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, eMTLDataType type, int array_len)
176{
177 BLI_assert(array_len > 0);
178 BLI_assert(total_uniforms_ < MTL_MAX_UNIFORMS_PER_BLOCK);
179 if (total_uniforms_ >= MTL_MAX_UNIFORMS_PER_BLOCK) {
181 "Cannot add uniform '%s' to shader interface '%s' as the uniform limit of %d has been "
182 "reached.",
183 name,
184 name,
186 return;
187 }
188 MTLShaderUniform &uniform = uniforms_[total_uniforms_];
189 uniform.name_offset = name_offset;
190
191 /* Determine size and offset alignment -- C++ struct alignment rules: Base address of value must
192 * match alignment of type. GLSL follows minimum type alignment of 4. */
193 int data_type_size = mtl_get_data_type_size(type) * array_len;
194 int data_type_alignment = mtl_get_data_type_alignment(type);
195 int current_offset = push_constant_block_.current_offset;
196 if ((current_offset % data_type_alignment) != 0) {
197 current_offset += data_type_alignment - (current_offset % data_type_alignment);
198 }
199
200 uniform.size_in_bytes = data_type_size;
201 uniform.byte_offset = current_offset;
202 uniform.type = type;
203 uniform.array_len = array_len;
204 total_uniforms_++;
205
206 /* Update Push constant block-- update offset, re-size and re-align total memory requirement to
207 * be 16-byte aligned. Following GLSL std140. */
208 push_constant_block_.current_offset = current_offset + data_type_size;
209 if (push_constant_block_.current_offset > push_constant_block_.size) {
210 push_constant_block_.size = push_constant_block_.current_offset;
211 if ((push_constant_block_.size % 16) != 0) {
212 push_constant_block_.size += 16 - (push_constant_block_.size % 16);
213 }
214 }
215
216 /* Validate properties. */
217 BLI_assert(uniform.size_in_bytes > 0);
219 current_offset + data_type_size <= push_constant_block_.size,
220 "Uniform size and offset sits outside the specified size range for the uniform block");
221}
222
224 uint32_t texture_slot,
225 uint32_t location,
226 eGPUTextureType tex_binding_type,
227 eGPUSamplerFormat sampler_format,
228 bool is_texture_sampler,
229 ShaderStage stage_mask,
230 int tex_buffer_ssbo_location)
231{
232 BLI_assert(texture_slot >= 0 && texture_slot < GPU_max_textures());
233 BLI_assert(sampler_format < GPU_SAMPLER_TYPE_MAX);
234 if (texture_slot >= 0 && texture_slot < GPU_max_textures()) {
235
236 MTLShaderTexture &tex = textures_[texture_slot];
237 BLI_assert_msg(tex.used == false, "Texture slot already in-use by another binding");
238 tex.name_offset = name_offset;
239 tex.slot_index = texture_slot;
240 tex.location = location;
241 tex.type = tex_binding_type;
242 tex.sampler_format = sampler_format;
243 tex.is_texture_sampler = is_texture_sampler;
244 tex.stage_mask = stage_mask;
245 tex.used = true;
246 tex.texture_buffer_ssbo_location = tex_buffer_ssbo_location;
247 total_textures_++;
248 max_texture_index_ = max_ii(max_texture_index_, texture_slot);
249 }
250 else {
251 BLI_assert_msg(false, "Exceeding maximum supported texture count.");
253 "Could not add additional texture with index %d to shader interface. Maximum "
254 "supported texture count is %d",
255 texture_slot,
257 }
258}
259
261{
262 MTLShaderConstant constant;
263 constant.name_offset = name_offset;
264 constants_.append(constant);
265 total_constants_++;
266}
267
269{
270 /* Clear builtin arrays to NULL locations. */
271 for (const int u : IndexRange(GPU_NUM_UNIFORMS)) {
272 builtins_[u] = -1;
273 }
274 for (const int ubo : IndexRange(GPU_NUM_UNIFORM_BLOCKS)) {
275 builtin_blocks_[ubo] = -1;
276 }
277
278 /* Resolve and cache uniform locations for builtin uniforms. */
279 for (const int u : IndexRange(GPU_NUM_UNIFORMS)) {
281 if (uni != nullptr) {
282 BLI_assert(uni->location >= 0);
283 if (uni->location >= 0) {
284 builtins_[u] = uni->location;
285 MTL_LOG_INFO("Mapped builtin uniform '%s' NB: '%s' to location: %d",
288 uni->location);
289 }
290 }
291 }
292
293 /* Resolve and cache uniform locations for builtin uniform blocks. */
294 for (const int u : IndexRange(GPU_NUM_UNIFORM_BLOCKS)) {
296
297 if (uni != nullptr) {
298 BLI_assert(uni->location >= 0);
299 if (uni->location >= 0) {
300 builtin_blocks_[u] = uni->binding;
301 MTL_LOG_INFO("Mapped builtin uniform block '%s' to location %d",
303 uni->location);
304 }
305 }
306 }
307}
308
309/* Populate #ShaderInput struct based on interface. */
311{
312 /* `ShaderInput inputs_` maps a uniform name to an external
313 * uniform location, which is used as an array index to look-up
314 * information in the local #MTLShaderInterface input structs.
315 *
316 * #ShaderInput population follows the ordering rules in #gpu_shader_interface. */
317
318 /* Populate #ShaderInterface counts. */
324
325 /* Calculate total inputs and allocate #ShaderInput array. */
326 /* NOTE: We use the existing `name_buffer_` allocated for internal input structs. */
327 int input_tot_len = attr_len_ + ubo_len_ + uniform_len_ + ssbo_len_ + constant_len_;
328 inputs_ = (ShaderInput *)MEM_callocN(sizeof(ShaderInput) * input_tot_len, __func__);
329 ShaderInput *current_input = inputs_;
330
331 /* Attributes. */
332 for (const int attr_index : IndexRange(total_attributes_)) {
333 MTLShaderInputAttribute &shd_attr = attributes_[attr_index];
334 current_input->name_offset = shd_attr.name_offset;
335 current_input->name_hash = BLI_hash_string(this->get_name_at_offset(shd_attr.name_offset));
336 /* For Metal, we flatten the vertex attribute indices within the shader in order to minimize
337 * complexity. ShaderInput "Location" contains the original attribute location, as can be
338 * fetched using `GPU_shader_get_attribute_info`. ShaderInput binding contains the array index
339 * into the MTLShaderInterface `attributes_` array. */
340 current_input->location = shd_attr.location;
341 current_input->binding = attr_index;
342 current_input++;
343 }
344
345 /* UBOs. */
346 BLI_assert(&inputs_[attr_len_] >= current_input);
347 current_input = &inputs_[attr_len_];
348 for (const int ubo_index : IndexRange(total_uniform_blocks_)) {
349 MTLShaderBufferBlock &shd_ubo = ubos_[ubo_index];
350 current_input->name_offset = shd_ubo.name_offset;
351 current_input->name_hash = BLI_hash_string(this->get_name_at_offset(shd_ubo.name_offset));
352 /* Location refers to the index in the ubos_ array. */
353 current_input->location = shd_ubo.location;
354 /* Binding location refers to the UBO bind slot in
355 * #MTLContextGlobalShaderPipelineState::ubo_bindings. The buffer bind index [[buffer(N)]]
356 * within the shader will apply an offset for bound vertex buffers and the default uniform
357 * PushConstantBlock.
358 * see `mtl_shader_generator.hh` for buffer binding table breakdown. */
359 current_input->binding = shd_ubo.location;
360 current_input++;
361 }
362
363 /* Uniforms. */
364 BLI_assert(&inputs_[attr_len_ + ubo_len_] >= current_input);
365 current_input = &inputs_[attr_len_ + ubo_len_];
366 for (const int uniform_index : IndexRange(total_uniforms_)) {
367 MTLShaderUniform &shd_uni = uniforms_[uniform_index];
368 current_input->name_offset = shd_uni.name_offset;
369 current_input->name_hash = BLI_hash_string(this->get_name_at_offset(shd_uni.name_offset));
370 current_input->location = uniform_index;
371 current_input->binding = uniform_index;
372 current_input++;
373 }
374
375 /* Textures.
376 * NOTE(Metal): Textures are externally treated as uniforms in #gpu_shader_interface.
377 * Location for textures resolved as `binding` value. This
378 * is the index into the local `MTLShaderTexture textures[]` array.
379 *
380 * In MSL, we cannot trivially remap which texture slot a given texture
381 * handle points to, unlike in GLSL, where a uniform sampler/image can be updated
382 * and queried as both a texture and a uniform. */
383 for (int texture_index = 0; texture_index <= max_texture_index_; texture_index++) {
384 const MTLShaderTexture &shd_tex = textures_[texture_index];
385
386 /* Not all texture entries are used when explicit texture locations are specified. */
387 if (shd_tex.used) {
388 BLI_assert_msg(shd_tex.slot_index == texture_index,
389 "Texture binding slot should match array index for texture.");
390 current_input->name_offset = shd_tex.name_offset;
391 current_input->name_hash = BLI_hash_string(this->get_name_at_offset(shd_tex.name_offset));
392
393 /* Location represents look-up address.
394 * For Metal, this location is a unique value offset by
395 * total_uniforms such that it does not overlap.
396 *
397 * This range offset allows a check in the uniform look-up
398 * to ensure texture handles are not treated as standard uniforms in Metal. */
399 current_input->location = texture_index + total_uniforms_;
400
401 /* Binding represents texture slot `[[texture(n)]]`. */
402 current_input->binding = shd_tex.location;
403 current_input++;
404 }
405 }
406
407 /* SSBO bindings. */
408 BLI_assert(&inputs_[attr_len_ + ubo_len_ + uniform_len_] >= current_input);
409 current_input = &inputs_[attr_len_ + ubo_len_ + uniform_len_];
410 BLI_assert(ssbo_len_ >= total_storage_blocks_);
411 for (const int ssbo_index : IndexRange(total_storage_blocks_)) {
412 MTLShaderBufferBlock &shd_ssbo = ssbos_[ssbo_index];
413 current_input->name_offset = shd_ssbo.name_offset;
414 current_input->name_hash = BLI_hash_string(this->get_name_at_offset(shd_ssbo.name_offset));
415 /* `Location` is used as the returned explicit bind index for SSBOs. */
416 current_input->location = shd_ssbo.location;
417 current_input->binding = shd_ssbo.location;
418 current_input++;
419 }
420
421 if (info != nullptr) {
424 ssbo_attr_mask_ |= (1 << res.slot);
425 }
426 else {
427 BLI_assert_msg(0, "Resource type is not supported for Geometry frequency");
428 }
429 }
430 }
431
432 /* Specialization Constants. */
433 BLI_assert(&inputs_[attr_len_ + ubo_len_ + uniform_len_ + ssbo_len_] >= current_input);
434 current_input = &inputs_[attr_len_ + ubo_len_ + uniform_len_ + ssbo_len_];
435 for (const int const_index : IndexRange(constant_len_)) {
436 MTLShaderConstant &shd_const = constants_[const_index];
437 current_input->name_offset = shd_const.name_offset;
438 current_input->name_hash = BLI_hash_string(this->get_name_at_offset(shd_const.name_offset));
439 current_input->location = const_index;
440 current_input++;
441 }
442
443 this->sort_inputs();
444
445 /* Map builtin uniform indices to uniform binding locations. */
446 this->map_builtins();
447
448 /* Pre-calculate texture metadata uniform locations for buffer-backed textures. */
449 for (int texture_index = 0; texture_index <= max_texture_index_; texture_index++) {
450 MTLShaderTexture &shd_tex = textures_[texture_index];
451 if (shd_tex.texture_buffer_ssbo_location != -1) {
452 char uniform_name[256];
453 const char *tex_name = get_name_at_offset(shd_tex.name_offset);
454 BLI_snprintf(uniform_name, 256, "%s_metadata", tex_name);
455 const ShaderInput *uni = this->uniform_get(uniform_name);
456 BLI_assert_msg(uni != nullptr,
457 "Could not find expected metadata uniform slot for buffer-backed texture.");
458 if (uni != nullptr) {
459 BLI_assert(uni->location >= 0);
460 if (uni->location >= 0) {
462 }
463 }
464 }
465 }
466}
467
468void MTLShaderInterface::set_sampler_properties(bool use_argument_buffer,
469 uint32_t argument_buffer_bind_index_vert,
470 uint32_t argument_buffer_bind_index_frag,
471 uint32_t argument_buffer_bind_index_compute)
472{
473 sampler_use_argument_buffer_ = use_argument_buffer;
474 sampler_argument_buffer_bind_index_[get_shader_stage_index(ShaderStage::VERTEX)] =
475 argument_buffer_bind_index_vert;
476 sampler_argument_buffer_bind_index_[get_shader_stage_index(ShaderStage::FRAGMENT)] =
477 argument_buffer_bind_index_frag;
478 sampler_argument_buffer_bind_index_[get_shader_stage_index(ShaderStage::COMPUTE)] =
479 argument_buffer_bind_index_compute;
480}
481
482/* Attributes. */
484{
487 return attributes_[index];
488}
489
491{
492 return total_attributes_;
493}
494
496{
497 return total_constants_;
498}
499
501{
502 return total_vert_stride_;
503}
504
506{
507 return enabled_attribute_mask_;
508}
509
510/* Uniforms. */
512{
515 return uniforms_[index];
516}
517
519{
520 return total_uniforms_;
521}
522
523/* Uniform Blocks. */
525{
528 return ubos_[index];
529}
530
532{
533 return push_constant_block_;
534}
535
537{
538 return total_uniform_blocks_;
539}
540
542{
543 return (block_index < total_uniform_blocks_);
544}
545
547{
548 return (block_index < total_uniform_blocks_) ? ubos_[block_index].size : 0;
549}
550
551/* Storage Blocks. */
553{
556 return ssbos_[index];
557}
558
560{
561 return total_storage_blocks_;
562}
563
565{
566 return (block_index < total_storage_blocks_);
567}
568
570{
571 return (block_index < total_storage_blocks_) ? ssbos_[block_index].size : 0;
572}
573
575{
576 /* PushConstantBlock + All uniform blocks + all storage blocks. */
578}
579
580/* Textures. */
582{
585 return textures_[index];
586}
587
589{
590 return total_textures_;
591}
592
594{
595 return max_texture_index_;
596}
597
599{
600 return sampler_use_argument_buffer_;
601}
602
604{
605 return sampler_argument_buffer_bind_index_[get_shader_stage_index(stage)];
606}
607
608id<MTLArgumentEncoder> MTLShaderInterface::find_argument_encoder(int buffer_index) const
609{
610 id encoder = nil;
611 for (const int i : IndexRange(ARGUMENT_ENCODERS_CACHE_SIZE)) {
612 encoder = arg_encoders_[i].buffer_index == buffer_index ? arg_encoders_[i].encoder : encoder;
613 }
614 return encoder;
615}
616
617void MTLShaderInterface::insert_argument_encoder(int buffer_index, id encoder)
618{
619 for (const int i : IndexRange(ARGUMENT_ENCODERS_CACHE_SIZE)) {
620 if (arg_encoders_[i].encoder == nil) {
621 arg_encoders_[i].encoder = encoder;
622 arg_encoders_[i].buffer_index = buffer_index;
623 return;
624 }
625 }
626 MTL_LOG_WARNING("could not insert encoder into cache!");
627}
628
630{
631 switch (type) {
633 return MTLVertexFormatChar;
635 return MTLVertexFormatUChar;
637 return MTLVertexFormatUChar;
639 return MTLVertexFormatChar2;
641 return MTLVertexFormatUChar2;
643 return MTLVertexFormatUChar2;
645 return MTLVertexFormatShort;
647 return MTLVertexFormatUShort;
649 return MTLVertexFormatChar3;
651 return MTLVertexFormatUChar3;
653 return MTLVertexFormatUChar3;
655 return MTLVertexFormatChar4;
657 return MTLVertexFormatUChar4;
658 case MTL_DATATYPE_INT:
659 return MTLVertexFormatInt;
661 return MTLVertexFormatUInt;
663 return MTLVertexFormatUChar4;
665 return MTLVertexFormatShort2;
667 return MTLVertexFormatUShort2;
669 return MTLVertexFormatFloat;
673 BLI_assert_msg(false, "Unsupported raw vertex attribute types in Blender.");
674 return MTLVertexFormatInvalid;
675
677 return MTLVertexFormatShort3;
679 return MTLVertexFormatUShort3;
681 return MTLVertexFormatShort4;
683 return MTLVertexFormatUShort4;
685 return MTLVertexFormatInt2;
687 return MTLVertexFormatUInt2;
689 return MTLVertexFormatFloat2;
691 return MTLVertexFormatInt;
693 return MTLVertexFormatUInt;
703 BLI_assert_msg(false, "Unsupported raw vertex attribute types in Blender.");
704 return MTLVertexFormatInvalid;
705
707 return MTLVertexFormatInt3;
709 return MTLVertexFormatInt4;
711 return MTLVertexFormatUInt3;
713 return MTLVertexFormatUInt4;
715 return MTLVertexFormatFloat3;
717 return MTLVertexFormatFloat4;
719 return MTLVertexFormatInt2;
721 return MTLVertexFormatUInt2;
728 BLI_assert_msg(false, "Unsupported raw vertex attribute types in Blender.");
729 return MTLVertexFormatInvalid;
730
732 return MTLVertexFormatInt3;
734 return MTLVertexFormatInt4;
736 return MTLVertexFormatUInt3;
738 return MTLVertexFormatUInt4;
739
740 /* Special Types */
742 return MTLVertexFormatUInt1010102Normalized;
744 return MTLVertexFormatInt1010102Normalized;
745
746 default:
747 BLI_assert(false);
748 return MTLVertexFormatInvalid;
749 };
750}
751
752} // namespace blender::gpu
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
BLI_INLINE unsigned int BLI_hash_string(const char *str)
Definition BLI_hash.h:71
MINLINE int max_ii(int a, int b)
#define STRNCPY(dst, src)
Definition BLI_string.h:593
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_uniform(uint32_t name_offset, eMTLDataType type, int array_len=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_texture(uint32_t name_offset, uint32_t texture_slot, uint32_t location, eGPUTextureType tex_binding_type, eGPUSamplerFormat sampler_format, bool is_texture_sampler, ShaderStage stage_mask=ShaderStage::FRAGMENT, int tex_buffer_ssbo_location=-1)
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 prepare_common_shader_inputs(const shader::ShaderCreateInfo *info=nullptr)
const ShaderInput * ubo_get(const char *name) const
static const char * builtin_uniform_block_name(GPUUniformBlockBuiltin u)
int32_t builtin_blocks_[GPU_NUM_UNIFORM_BLOCKS]
int32_t builtins_[GPU_NUM_UNIFORMS]
const ShaderInput * uniform_get(const char *name) const
static const char * builtin_uniform_name(GPUUniformBuiltin u)
EvaluationStage stage
Definition deg_eval.cc:83
format
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
#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_INFO(info,...)
Definition mtl_debug.hh:51
#define MTL_LOG_WARNING(info,...)
Definition mtl_debug.hh:44
uint mtl_get_data_type_alignment(eMTLDataType type)
@ MTL_DATATYPE_INT1010102_NORM
@ MTL_DATATYPE_UINT1010102_NORM
uint mtl_get_data_type_size(eMTLDataType type)
uint get_shader_stage_index(ShaderStage stage)
MTLVertexFormat mtl_datatype_to_vertex_type(eMTLDataType type)
unsigned int uint32_t
Definition stdint.h:80
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...