Blender V5.0
mtl_texture.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#pragma once
10
11#include "BLI_assert.h"
12#include "BLI_map.hh"
13#include "GPU_texture.hh"
14#include "MEM_guardedalloc.h"
15
17
18#include <mutex>
19#include <string>
20#include <thread>
21
22#include <Cocoa/Cocoa.h>
23#include <Metal/Metal.h>
24#include <QuartzCore/QuartzCore.h>
25
26@class CAMetalLayer;
27@class MTLCommandQueue;
28@class MTLRenderPipelineState;
29
30namespace blender::gpu {
31class FrameBuffer;
32} // namespace blender::gpu
33
34/* Texture Update system structs. */
36
37 /* The METAL type of data in input array, e.g. half, float, short, int */
38 std::string input_data_type;
39
40 /* The type of the texture data texture2d<T,..>, e.g. T=float, half, int etc. */
41 std::string output_data_type;
42
43 /* Number of image channels provided in input texture data array (min=1, max=4). */
45
46 /* Number of channels the destination texture has (min=1, max=4). */
48
49 /* Whether the update routine is a clear, and only the first texel of the input data buffer will
50 * be read. */
52
61
62 uint64_t hash() const
63 {
65 return (uint64_t)string_hasher(this->input_data_type + this->output_data_type +
66 std::to_string((this->component_count_input << 9) |
67 (this->component_count_output << 5) |
68 (this->is_clear ? 1 : 0)));
69 }
70};
71
72/* Type of data is being written to the depth target:
73 * 0 = floating point (0.0 - 1.0)
74 * 1 = 24 bit integer (0 - 2^24)
75 * 2 = 32 bit integer (0 - 2^32) */
76
82
85
87 {
88 return ((data_mode == other.data_mode));
89 }
90
91 uint64_t hash() const
92 {
93 return (uint64_t)(this->data_mode);
94 }
95};
96
97/* Texture Read system structs. */
99 std::string input_data_type;
100 std::string output_data_type;
103
104 /* Format for depth data.
105 * 0 = Not a Depth format,
106 * 1 = FLOAT DEPTH,
107 * 2 = 24Bit Integer Depth,
108 * 4 = 32bit Unsigned-Integer Depth. */
110
119
121 {
123 return uint64_t(string_hasher(this->input_data_type + this->output_data_type +
124 std::to_string((this->component_count_input << 8) +
125 this->component_count_output +
126 (this->depth_format_mode << 28))));
127 }
128};
129
130namespace blender::gpu {
131
132class MTLContext;
133class MTLVertBuf;
134class MTLStorageBuf;
135class MTLBuffer;
136
137/* Metal Texture internal implementation. */
138static const int MTL_MAX_MIPMAP_COUNT = 15; /* Max: 16384x16384 */
139static const int MTL_MAX_FBO_ATTACHED = 16;
140
141/* Samplers */
144
145 /* Mip min and mip max on sampler state always the same.
146 * Level range now controlled with textureView to be consistent with GL baseLevel. */
147 bool operator==(const MTLSamplerState &other) const
148 {
149 /* Add other parameters as needed. */
150 return (this->state == other.state);
151 }
152
153 operator uint() const
154 {
155 uint integer_representation = 0;
156 integer_representation |= this->state.filtering;
157 integer_representation |= this->state.extend_x << 8;
158 integer_representation |= this->state.extend_yz << 12;
159 integer_representation |= this->state.custom_type << 16;
160 integer_representation |= this->state.type << 24;
161 return integer_representation;
162 }
163
164 operator uint64_t() const
165 {
166 uint64_t integer_representation = 0;
167 integer_representation |= this->state.filtering;
168 integer_representation |= this->state.extend_x << 8;
169 integer_representation |= this->state.extend_yz << 12;
170 integer_representation |= this->state.custom_type << 16;
171 integer_representation |= this->state.type << 24;
172 return integer_representation;
173 }
174};
175
177
178class MTLTexture : public Texture {
179 friend class MTLContext;
180 friend class MTLStateManager;
181 friend class MTLFrameBuffer;
182 friend class MTLStorageBuf;
183
184 private:
185 /* Where the textures data comes from. */
186 enum {
187 MTL_TEXTURE_MODE_DEFAULT, /* Texture is self-initialized (Standard). */
188 MTL_TEXTURE_MODE_EXTERNAL, /* Texture source from external id<MTLTexture> handle */
189 MTL_TEXTURE_MODE_VBO, /* Texture source initialized from VBO */
190 MTL_TEXTURE_MODE_TEXTURE_VIEW /* Texture is a view into an existing texture. */
191 } resource_mode_;
192
193 /* 'baking' refers to the generation of GPU-backed resources. This flag ensures GPU resources are
194 * ready. Baking is generally deferred until as late as possible, to ensure all associated
195 * resource state has been specified up-front. */
196 bool is_baked_ = false;
197 MTLTextureDescriptor *texture_descriptor_ = nullptr;
198 id<MTLTexture> texture_ = nil;
199
200 /* Texture Storage. */
201 size_t aligned_w_ = 0;
202
203 /* Storage buffer view.
204 * Buffer backed textures can be wrapped with a storage buffer instance for direct data
205 * reading/writing. Required for atomic operations on texture data when texture atomics are
206 * unsupported.
207 *
208 * tex_buffer_metadata_ packs 4 parameters required by the shader to perform texture space
209 * remapping: (x, y, z) = (width, height, depth/layers) (w) = aligned width. */
210 MTLBuffer *backing_buffer_ = nullptr;
211 MTLStorageBuf *storage_buffer_ = nullptr;
212 int tex_buffer_metadata_[4];
213
214 /* Blit Frame-buffer. */
215 gpu::FrameBuffer *blit_fb_ = nullptr;
216 uint blit_fb_slice_ = 0;
217 uint blit_fb_mip_ = 0;
218
219 /* Non-SRGB texture view, used for when a framebuffer is bound with SRGB disabled. */
220 id<MTLTexture> texture_no_srgb_ = nil;
221
222 /* Texture view properties */
223 /* In Metal, we use texture views to either limit mipmap ranges,
224 * , apply a swizzle mask, or both.
225 *
226 * We apply the mip limit in the view rather than in the sampler, as
227 * certain effects and functionality such as textureSize rely on the base level
228 * being modified.
229 *
230 * Texture views can also point to external textures, rather than the owned
231 * texture if MTL_TEXTURE_MODE_TEXTURE_VIEW is used.
232 * If this mode is used, source_texture points to a gpu::Texture from which
233 * we pull their texture handle as a root.
234 */
235 const gpu::Texture *source_texture_ = nullptr;
236
237 enum TextureViewDirtyState {
238 TEXTURE_VIEW_NOT_DIRTY = 0,
239 TEXTURE_VIEW_SWIZZLE_DIRTY = (1 << 0),
240 TEXTURE_VIEW_MIP_DIRTY = (1 << 1)
241 };
242 id<MTLTexture> mip_swizzle_view_ = nil;
243 char tex_swizzle_mask_[4];
244 MTLTextureSwizzleChannels mtl_swizzle_mask_;
245 bool mip_range_dirty_ = false;
246
247 bool texture_view_stencil_ = false;
248 int mip_texture_base_level_ = 0;
249 int mip_texture_max_level_ = 1000;
250 int mip_texture_base_layer_ = 0;
251 int texture_view_dirty_flags_ = TEXTURE_VIEW_NOT_DIRTY;
252
253 /* Max mip-maps for currently allocated texture resource. */
254 int mtl_max_mips_ = 1;
255 bool has_generated_mips_ = false;
256
257 /* We may modify the requested usage flags so store them separately. */
258 eGPUTextureUsage internal_gpu_image_usage_flags_;
259
260 /* VBO. */
261 MTLVertBuf *vert_buffer_;
262 id<MTLBuffer> vert_buffer_mtl_;
263
264 /* Whether the texture's properties or state has changed (e.g. mipmap range), and re-baking of
265 * GPU resource is required. */
266 bool is_dirty_;
267 bool is_bound_;
268
269 public:
270 MTLTexture(const char *name);
271 MTLTexture(const char *name,
273 GPUTextureType type,
274 id<MTLTexture> metal_texture);
275 ~MTLTexture() override;
276
277 void update_sub(
278 int mip, int offset[3], int extent[3], eGPUDataFormat type, const void *data) override;
279 void update_sub(int offset[3],
280 int extent[3],
282 GPUPixelBuffer *pixbuf) override;
283
284 void generate_mipmap() override;
285 void copy_to(Texture *dst) override;
286 void clear(eGPUDataFormat format, const void *data) override;
287 void swizzle_set(const char swizzle_mask[4]) override;
288 void mip_range_set(int min, int max) override;
289 void *read(int mip, eGPUDataFormat type) override;
290
291 bool is_format_srgb();
292 bool texture_is_baked();
293 const char *get_name()
294 {
295 return name_;
296 }
297
299 {
300 return (mtl_swizzle_mask_.red != MTLTextureSwizzleRed ||
301 mtl_swizzle_mask_.green != MTLTextureSwizzleGreen ||
302 mtl_swizzle_mask_.blue != MTLTextureSwizzleBlue ||
303 mtl_swizzle_mask_.alpha != MTLTextureSwizzleAlpha);
304 }
305
306 id<MTLBuffer> get_vertex_buffer() const
307 {
308 if (resource_mode_ == MTL_TEXTURE_MODE_VBO) {
309 return vert_buffer_mtl_;
310 }
311 return nil;
312 }
313
315
316 const int *get_texture_metadata_ptr() const
317 {
318 return tex_buffer_metadata_;
319 }
320
321 protected:
322 bool init_internal() override;
323 bool init_internal(VertBuf *vbo) override;
324 bool init_internal(gpu::Texture *src,
325 int mip_offset,
326 int layer_offset,
327 bool use_stencil) override; /* Texture View */
328
329 private:
330 /* Common Constructor, default initialization. */
331 void mtl_texture_init();
332
333 /* Post-construction and member initialization, prior to baking.
334 * Called during init_internal */
335 void prepare_internal();
336
337 /* Generate Metal GPU resources and upload data if needed */
338 void ensure_baked();
339
340 /* Delete associated Metal GPU resources. */
341 void reset();
342 void ensure_mipmaps(int miplvl);
343
344 /* Flags a given mip level as being used. */
345 void add_subresource(uint level);
346
347 void read_internal(int mip,
348 int x_off,
349 int y_off,
350 int z_off,
351 int width,
352 int height,
353 int depth,
354 eGPUDataFormat desired_output_format,
355 int num_output_components,
356 size_t debug_data_size,
357 void *r_data);
358 void bake_mip_swizzle_view();
359
360 id<MTLTexture> get_metal_handle();
361 id<MTLTexture> get_metal_handle_base();
362 id<MTLTexture> get_non_srgb_handle();
363 MTLSamplerState get_sampler_state();
364 void blit(id<MTLBlitCommandEncoder> blit_encoder,
365 uint src_x_offset,
366 uint src_y_offset,
367 uint src_z_offset,
368 uint src_slice,
369 uint src_mip,
370 gpu::MTLTexture *dst,
371 uint dst_x_offset,
372 uint dst_y_offset,
373 uint dst_z_offset,
374 uint dst_slice,
375 uint dst_mip,
376 uint width,
377 uint height,
378 uint depth);
379 void blit(gpu::MTLTexture *dst,
380 uint src_x_offset,
381 uint src_y_offset,
382 uint dst_x_offset,
383 uint dst_y_offset,
384 uint src_mip,
385 uint dst_mip,
386 uint dst_slice,
387 int width,
388 int height);
389 gpu::FrameBuffer *get_blit_framebuffer(int dst_slice, uint dst_mip);
390 /* Texture Update function Utilities. */
391 /* Metal texture updating does not provide the same range of functionality for type conversion
392 * and format compatibility as are available in OpenGL. To achieve the same level of
393 * functionality, we need to instead use compute kernels to perform texture data conversions
394 * where appropriate.
395 * There are a number of different inputs which affect permutations and thus require different
396 * shaders and PSOs, such as:
397 * - Texture format
398 * - Texture type (e.g. 2D, 3D, 2D Array, Depth etc;)
399 * - Source data format and component count (e.g. floating point)
400 *
401 * MECHANISM:
402 *
403 * blender::map<INPUT DEFINES STRUCT, compute PSO> update_2d_array_kernel_psos;
404 * - Generate compute shader with configured kernel below with variable parameters depending
405 * on input/output format configurations. Do not need to keep source or descriptors around,
406 * just PSO, as same input defines will always generate the same code.
407 *
408 * - IF datatype IS an exact match e.g. :
409 * - Per-component size matches (e.g. GPU_DATA_UBYTE)
410 * OR GPU_DATA_10_11_11_REV && GPU_R11G11B10 (equiv)
411 * OR D24S8 and GPU_DATA_UINT_24_8_DEPRECATED
412 * We can use BLIT ENCODER.
413 *
414 * OTHERWISE TRIGGER COMPUTE:
415 * - Compute sizes will vary. Threads per grid WILL match 'extent'.
416 * Dimensions will vary depending on texture type.
417 * - Will use setBytes with 'TextureUpdateParams' struct to pass in useful member params.
418 */
419 struct TextureUpdateParams {
420 int mip_index;
421 int extent[3]; /* Width, Height, Slice on 2D Array tex. */
422 int offset[3]; /* Width, Height, Slice on 2D Array tex. */
423 uint unpack_row_length; /* Number of pixels between bytes in input data. */
424 };
425
426 id<MTLComputePipelineState> texture_update_1d_get_kernel(
428 id<MTLComputePipelineState> texture_update_1d_array_get_kernel(
430 id<MTLComputePipelineState> texture_update_2d_get_kernel(
432 id<MTLComputePipelineState> texture_update_2d_array_get_kernel(
434 id<MTLComputePipelineState> texture_update_3d_get_kernel(
436
437 id<MTLComputePipelineState> mtl_texture_update_impl(
438 TextureUpdateRoutineSpecialisation specialization_params,
439 blender::Map<TextureUpdateRoutineSpecialisation, id<MTLComputePipelineState>>
440 &specialization_cache,
441 GPUTextureType texture_type);
442
443 /* Depth Update Utilities */
444 /* Depth texture updates are not directly supported with Blit operations, similarly, we cannot
445 * use a compute shader to write to depth, so we must instead render to a depth target.
446 * These processes use vertex/fragment shaders to render texture data from an intermediate
447 * source, in order to prime the depth buffer. */
448 gpu::Shader *depth_2d_update_sh_get(DepthTextureUpdateRoutineSpecialisation specialization);
449
450 void update_sub_depth_2d(
451 int mip, int offset[3], int extent[3], eGPUDataFormat type, const void *data);
452
453 /* Texture Read function utilities -- Follows a similar mechanism to the updating routines */
454 struct TextureReadParams {
455 int mip_index;
456 int extent[3]; /* Width, Height, Slice on 2D Array tex. */
457 int offset[3]; /* Width, Height, Slice on 2D Array tex. */
458 };
459
460 id<MTLComputePipelineState> texture_read_1d_get_kernel(
461 TextureReadRoutineSpecialisation specialization);
462 id<MTLComputePipelineState> texture_read_1d_array_get_kernel(
463 TextureReadRoutineSpecialisation specialization);
464 id<MTLComputePipelineState> texture_read_2d_get_kernel(
465 TextureReadRoutineSpecialisation specialization);
466 id<MTLComputePipelineState> texture_read_2d_array_get_kernel(
467 TextureReadRoutineSpecialisation specialization);
468 id<MTLComputePipelineState> texture_read_3d_get_kernel(
469 TextureReadRoutineSpecialisation specialization);
470
471 id<MTLComputePipelineState> mtl_texture_read_impl(
472 TextureReadRoutineSpecialisation specialization_params,
473 blender::Map<TextureReadRoutineSpecialisation, id<MTLComputePipelineState>>
474 &specialization_cache,
475 GPUTextureType texture_type);
476
477 /* fullscreen blit utilities. */
478 gpu::Shader *fullscreen_blit_sh_get();
479
480 MEM_CXX_CLASS_ALLOC_FUNCS("MTLTexture")
481};
482
484 private:
485 id<MTLBuffer> buffer_ = nil;
486
487 public:
488 MTLPixelBuffer(size_t size);
490
491 void *map() override;
492 void unmap() override;
494 size_t get_size() override;
495
496 id<MTLBuffer> get_metal_buffer();
497
498 MEM_CXX_CLASS_ALLOC_FUNCS("MTLPixelBuffer")
499};
500
501/* Utility */
502MTLPixelFormat gpu_texture_format_to_metal(TextureFormat tex_format);
503size_t get_mtl_format_bytesize(MTLPixelFormat tex_format);
504int get_mtl_format_num_components(MTLPixelFormat tex_format);
505bool mtl_format_supports_blending(MTLPixelFormat format);
506
507/* The type used to define the per-component data in the input buffer. */
509{
510 switch (type) {
511 case GPU_DATA_FLOAT:
512 return "float";
514 return "half";
515 case GPU_DATA_INT:
516 return "int";
517 case GPU_DATA_UINT:
518 return "uint";
519 case GPU_DATA_UBYTE:
520 return "uchar";
522 return "uint"; /* Problematic type - but will match alignment. */
525 return "float"; /* Problematic type - each component will be read as a float. */
526 default:
527 BLI_assert(false);
528 break;
529 }
530 return "";
531}
532
533/* The type T which goes into texture2d<T, access>. */
535{
536 switch (type) {
537 case GPU_DATA_FLOAT:
538 return "float";
540 return "half";
541 case GPU_DATA_INT:
542 return "int";
543 case GPU_DATA_UINT:
544 return "uint";
545 case GPU_DATA_UBYTE:
546 return "ushort";
548 return "uint"; /* Problematic type. */
551 return "float"; /* Problematic type. */
552 default:
553 BLI_assert(false);
554 break;
555 }
556 return "";
557}
558
559/* Fetch Metal texture type from GPU texture type. */
560inline MTLTextureType to_metal_type(GPUTextureType type)
561{
562 switch (type) {
563 case GPU_TEXTURE_1D:
564 return MTLTextureType1D;
565 case GPU_TEXTURE_2D:
566 return MTLTextureType2D;
567 case GPU_TEXTURE_3D:
568 return MTLTextureType3D;
569 case GPU_TEXTURE_CUBE:
570 return MTLTextureTypeCube;
572 return MTLTextureTypeTextureBuffer;
574 return MTLTextureType1DArray;
576 return MTLTextureType2DArray;
578 return MTLTextureTypeCubeArray;
579 default:
581 }
582 return MTLTextureType2D;
583}
584
585/* Determine whether format is writable or not. Use mtl_format_get_writeable_view_format(..) for
586 * these. */
587inline bool mtl_format_is_writable(MTLPixelFormat format)
588{
589 switch (format) {
590 case MTLPixelFormatRGBA8Unorm_sRGB:
591 case MTLPixelFormatBGRA8Unorm_sRGB:
592 case MTLPixelFormatDepth16Unorm:
593 case MTLPixelFormatDepth32Float:
594 case MTLPixelFormatDepth32Float_Stencil8:
595 case MTLPixelFormatBGR10A2Unorm:
596 case MTLPixelFormatDepth24Unorm_Stencil8:
597 return false;
598 default:
599 return true;
600 }
601 return true;
602}
603
604/* For the cases where a texture format is unwritable, we can create a texture view of a similar
605 * format */
606inline MTLPixelFormat mtl_format_get_writeable_view_format(MTLPixelFormat format)
607{
608 switch (format) {
609 case MTLPixelFormatRGBA8Unorm_sRGB:
610 return MTLPixelFormatRGBA8Unorm;
611 case MTLPixelFormatBGRA8Unorm_sRGB:
612 return MTLPixelFormatBGRA8Unorm;
613 case MTLPixelFormatDepth16Unorm:
614 return MTLPixelFormatR16Unorm;
615 case MTLPixelFormatDepth32Float:
616 return MTLPixelFormatR32Float;
617 case MTLPixelFormatDepth32Float_Stencil8:
618 // return MTLPixelFormatRG32Float;
619 /* No alternative mirror format. This should not be used for
620 * manual data upload */
621 return MTLPixelFormatInvalid;
622 case MTLPixelFormatBGR10A2Unorm:
623 // return MTLPixelFormatBGRA8Unorm;
624 /* No alternative mirror format. This should not be used for
625 * manual data upload */
626 return MTLPixelFormatInvalid;
627 case MTLPixelFormatDepth24Unorm_Stencil8:
628 /* No direct format, but we'll just mirror the bytes -- `Uint`
629 * should ensure bytes are not re-normalized or manipulated */
630 // return MTLPixelFormatR32Uint;
631 return MTLPixelFormatInvalid;
632 default:
633 return format;
634 }
635 return format;
636}
637
638inline MTLTextureUsage mtl_usage_from_gpu(eGPUTextureUsage usage)
639{
640 MTLTextureUsage mtl_usage = MTLTextureUsageUnknown;
641 if (usage == GPU_TEXTURE_USAGE_GENERAL) {
642 return MTLTextureUsageUnknown;
643 }
644 /* Host read implies general read support, as the compute-based host read routine requires
645 * reading of texture data. */
647 mtl_usage = mtl_usage | MTLTextureUsageShaderRead;
648 }
649 if (usage & GPU_TEXTURE_USAGE_SHADER_WRITE) {
650 mtl_usage = mtl_usage | MTLTextureUsageShaderWrite;
651 }
652 if (usage & GPU_TEXTURE_USAGE_ATTACHMENT) {
653 mtl_usage = mtl_usage | MTLTextureUsageRenderTarget;
654 }
655 if (usage & GPU_TEXTURE_USAGE_FORMAT_VIEW) {
656 mtl_usage = mtl_usage | MTLTextureUsagePixelFormatView;
657 }
658#if defined(MAC_OS_VERSION_14_0)
659 if (@available(macOS 14.0, *)) {
660 if (usage & GPU_TEXTURE_USAGE_ATOMIC) {
661 mtl_usage = mtl_usage | MTLTextureUsageShaderAtomic;
662 }
663 }
664#endif
665 return mtl_usage;
666}
667
668inline eGPUTextureUsage gpu_usage_from_mtl(MTLTextureUsage mtl_usage)
669{
671 if (mtl_usage == MTLTextureUsageUnknown) {
673 }
674 if (mtl_usage & MTLTextureUsageShaderRead) {
675 usage = usage | GPU_TEXTURE_USAGE_SHADER_READ;
676 }
677 if (mtl_usage & MTLTextureUsageShaderWrite) {
678 usage = usage | GPU_TEXTURE_USAGE_SHADER_WRITE;
679 }
680 if (mtl_usage & MTLTextureUsageRenderTarget) {
681 usage = usage | GPU_TEXTURE_USAGE_ATTACHMENT;
682 }
683 if (mtl_usage & MTLTextureUsagePixelFormatView) {
684 usage = usage | GPU_TEXTURE_USAGE_FORMAT_VIEW;
685 }
686 return usage;
687}
688
689} // namespace blender::gpu
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
unsigned int uint
eGPUDataFormat
@ GPU_DATA_HALF_FLOAT
@ GPU_DATA_INT
@ GPU_DATA_10_11_11_REV
@ GPU_DATA_UBYTE
@ GPU_DATA_UINT
@ GPU_DATA_UINT_24_8_DEPRECATED
@ GPU_DATA_2_10_10_10_REV
@ GPU_DATA_FLOAT
eGPUTextureUsage
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_TEXTURE_USAGE_SHADER_WRITE
@ GPU_TEXTURE_USAGE_HOST_READ
@ GPU_TEXTURE_USAGE_ATTACHMENT
@ GPU_TEXTURE_USAGE_GENERAL
@ GPU_TEXTURE_USAGE_ATOMIC
@ GPU_TEXTURE_USAGE_FORMAT_VIEW
Read Guarded memory(de)allocation.
BMesh const char void * data
unsigned long long int uint64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
void reset()
clear internal cached data and reset random seed
GPUPixelBufferNativeHandle get_native_handle() override
id< MTLBuffer > get_metal_buffer()
void copy_to(Texture *dst) override
void update_sub(int mip, int offset[3], int extent[3], eGPUDataFormat type, const void *data) override
MTLTexture(const char *name)
void clear(eGPUDataFormat format, const void *data) override
MTLStorageBuf * get_storagebuf()
void mip_range_set(int min, int max) override
const int * get_texture_metadata_ptr() const
void generate_mipmap() override
bool init_internal() override
void swizzle_set(const char swizzle_mask[4]) override
id< MTLBuffer > get_vertex_buffer() const
char name_[DEBUG_NAME_LEN]
Texture(const char *name)
format
DepthTextureUpdateMode
@ MTL_DEPTH_UPDATE_MODE_INT32
@ MTL_DEPTH_UPDATE_MODE_INT24
@ MTL_DEPTH_UPDATE_MODE_FLOAT
size_t get_mtl_format_bytesize(MTLPixelFormat tex_format)
MTLPixelFormat gpu_texture_format_to_metal(TextureFormat tex_format)
static const int MTL_MAX_FBO_ATTACHED
std::string tex_data_format_to_msl_type_str(eGPUDataFormat type)
bool mtl_format_is_writable(MTLPixelFormat format)
std::string tex_data_format_to_msl_texture_template_type(eGPUDataFormat type)
MTLPixelFormat mtl_format_get_writeable_view_format(MTLPixelFormat format)
int get_mtl_format_num_components(MTLPixelFormat tex_format)
static const int MTL_MAX_MIPMAP_COUNT
const MTLSamplerState DEFAULT_SAMPLER_STATE
MTLTextureUsage mtl_usage_from_gpu(eGPUTextureUsage usage)
MTLTextureType to_metal_type(GPUTextureType type)
bool mtl_format_supports_blending(MTLPixelFormat format)
eGPUTextureUsage gpu_usage_from_mtl(MTLTextureUsage mtl_usage)
const char * name
#define min(a, b)
Definition sort.cc:36
bool operator==(const DepthTextureUpdateRoutineSpecialisation &other) const
GPUSamplerCustomType custom_type
GPUSamplerExtendMode extend_yz
static constexpr GPUSamplerState default_sampler()
GPUSamplerFiltering filtering
GPUSamplerExtendMode extend_x
GPUSamplerStateType type
bool operator==(const TextureReadRoutineSpecialisation &other) const
bool operator==(const TextureUpdateRoutineSpecialisation &other) const
bool operator==(const MTLSamplerState &other) const
max
Definition text_draw.cc:251