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
8
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
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
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.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Texture
struct GPUShader GPUShader
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
void reset()
clear internal cached data and reset random seed
id< MTLBuffer > get_metal_buffer()
int64_t get_native_handle() 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
uint gl_bindcode_get() const override
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(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
float max