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