17#import <Availability.h>
30 is_loadstore_dirty_ =
true;
31 dirty_state_ctx_ =
nullptr;
32 has_pending_clear_ =
false;
33 colour_attachment_count_ = 0;
34 enabled_srgb_ =
false;
38 mtl_color_attachments_[i].
used =
false;
40 mtl_depth_attachment_.
used =
false;
41 mtl_stencil_attachment_.
used =
false;
44 framebuffer_descriptor_[i] = [[MTLRenderPassDescriptor alloc]
init];
45 descriptor_dirty_[i] =
true;
49 colour_attachment_descriptors_[i] = [[MTLRenderPassColorAttachmentDescriptor alloc]
init];
75 if (framebuffer_descriptor_[config] != nil) {
76 [framebuffer_descriptor_[config] release];
77 framebuffer_descriptor_[config] = nil;
83 if (colour_attachment_descriptors_[i] != nil) {
84 [colour_attachment_descriptors_[i] release];
85 colour_attachment_descriptors_[i] = nil;
92 if (context_ ==
nullptr) {
114 BLI_assert_msg(
false,
"Trying to use the same frame-buffer in multiple context's.");
124 bool srgb_state_changed = enabled_srgb_ != enabled_srgb;
125 if (context_->
active_fb !=
this || srgb_state_changed) {
126 if (srgb_state_changed) {
129 enabled_srgb_ = enabled_srgb;
143 MTL_LOG_WARNING(
"Attempting to bind FrameBuffer, but no context is active");
158 const char *
format =
"Framebuffer %s does not have any attachments.\n";
185 "Framebuffer %s: Color attachment dimensions do not match those of previous "
200 "Framebuffer %s: Color attachment texture does not have usage flag "
201 "'GPU_TEXTURE_USAGE_ATTACHMENT'\n";
215 if (depth_att.
used) {
224 "Framebuffer %n: Depth attachment does not have usage "
225 "'GPU_TEXTURE_USAGE_ATTACHMENT'\n";
239 "Framebuffer %n: Depth attachment dimensions do not match that of previous "
252 if (stencil_att.
used) {
257 valid = (stencil_att.
texture->internal_gpu_image_usage_flags_ &
261 "Framebuffer %s: Stencil attachment does not have usage "
262 "'GPU_TEXTURE_USAGE_ATTACHMENT'\n";
277 "Framebuffer %s: Stencil attachment dimensions do not match that of previous "
295void MTLFrameBuffer::force_clear()
300 if (current_framebuffer) {
312 const float clear_col[4],
324 if (!has_pending_clear_) {
329 bool do_clear =
false;
331 for (
int i = 0; i < colour_attachment_count_; i++) {
347 has_pending_clear_ =
true;
364 if (!has_pending_clear_) {
368 bool do_clear =
false;
377 has_pending_clear_ =
true;
393 const void *clear_value)
399 if (!has_pending_clear_) {
403 bool do_clear =
false;
408 float depth = ((*(
uint32_t *)clear_value) & 0x00FFFFFFu) / (
float)0x00FFFFFFu;
409 int stencil = ((*(
uint32_t *)clear_value) >> 24);
421 float depth = *(
uint32_t *)clear_value / (
float)0xFFFFFFFFu;
430 float col_clear_val[4] = {0.0};
431 switch (data_format) {
433 const float *vals = (
float *)clear_value;
434 col_clear_val[0] = vals[0];
435 col_clear_val[1] = vals[1];
436 col_clear_val[2] = vals[2];
437 col_clear_val[3] = vals[3];
440 const uint *vals = (
uint *)clear_value;
441 col_clear_val[0] = (
float)(vals[0]);
442 col_clear_val[1] = (
float)(vals[1]);
443 col_clear_val[2] = (
float)(vals[2]);
444 col_clear_val[3] = (
float)(vals[3]);
447 const int *vals = (
int *)clear_value;
448 col_clear_val[0] = (
float)(vals[0]);
449 col_clear_val[1] = (
float)(vals[1]);
450 col_clear_val[2] = (
float)(vals[2]);
451 col_clear_val[3] = (
float)(vals[3]);
463 has_pending_clear_ =
true;
480 if (!is_tile_based_arch) {
488 for (
int i : color_attachment_states.
index_range()) {
511 if (area[2] <= 0 || area[3] <= 0) {
521 size_t sample_len = area[2] * area[3];
523 size_t debug_data_size = sample_len * sample_size;
524 tex->read_internal(0,
539 "Attempting to read depth from a framebuffer which does not have a depth "
550 size_t sample_len = area[2] * area[3];
552 size_t debug_data_size = sample_len * sample_size * channel_len;
553 tex->read_internal(0,
570 MTL_LOG_ERROR(
"Framebuffer: Trying to read stencil bit. Unsupported.");
606 else if (do_stencil) {
633 is_loadstore_dirty_ =
true;
638 is_loadstore_dirty_ =
true;
643 has_pending_clear_ =
false;
648 has_pending_clear_ =
true;
660 use_multilayered_rendering_ =
false;
667 bool depth_added =
false;
723 first_attachment = type;
766 first_attachment = type;
798 if (
dirty_state_ ==
false && dirty_state_ctx_ == mtl_ctx) {
806 if (viewport_w == 0 || viewport_h == 0) {
807 MTL_LOG_WARNING(
"Viewport had width and height of (0,0) -- Updating -- DEBUG Safety check");
808 viewport_w = default_width_;
809 viewport_h = default_height_;
823 dirty_state_ctx_ = mtl_ctx;
827 "Attempting to set FrameBuffer State (VIEWPORT, SCISSOR), But FrameBuffer is not bound to "
848 MTL_LOG_WARNING(
"Attachment specified with invalid mip level %u", miplevel);
854 colour_attachment_count_ += (!mtl_color_attachments_[slot].
used) ? 1 : 0;
855 mtl_color_attachments_[slot].
used =
true;
857 mtl_color_attachments_[slot].
mip = miplevel;
863 switch (texture->type_) {
867 mtl_color_attachments_[slot].
slice = 0;
873 MTL_LOG_WARNING(
"TODO: Support layered rendering for 1D array textures, if needed.");
876 mtl_color_attachments_[slot].
slice = layer;
881 mtl_color_attachments_[slot].
slice = layer;
884 mtl_color_attachments_[slot].
slice = 0;
886 use_multilayered_rendering_ =
true;
891 mtl_color_attachments_[slot].
slice = 0;
896 use_multilayered_rendering_ =
true;
901 mtl_color_attachments_[slot].
slice = layer;
904 mtl_color_attachments_[slot].
slice = 0;
907 use_multilayered_rendering_ =
true;
913 mtl_color_attachments_[slot].
slice = layer;
916 mtl_color_attachments_[slot].
slice = 0;
919 use_multilayered_rendering_ =
true;
923 mtl_color_attachments_[slot].
slice = 0;
927 MTL_LOG_ERROR(
"MTLFrameBuffer::add_color_attachment Unrecognized texture type %u",
933 int width_of_miplayer, height_of_miplayer;
935 width_of_miplayer = texture->width_get();
936 height_of_miplayer = texture->height_get();
939 width_of_miplayer =
max_ii(texture->width_get() >> miplevel, 1);
940 height_of_miplayer =
max_ii(texture->height_get() >> miplevel, 1);
943 if (default_width_ == 0 || default_height_ == 0) {
949 BLI_assert(default_width_ == width_of_miplayer);
950 BLI_assert(default_height_ == height_of_miplayer);
958 "Passing in null texture to MTLFrameBuffer::add_color_attachment (This could be due to "
959 "not all texture types being supported).");
970 MTL_LOG_WARNING(
"Attachment specified with invalid mip level %u", miplevel);
975 mtl_depth_attachment_.
used =
true;
977 mtl_depth_attachment_.
mip = miplevel;
983 switch (texture->type_) {
987 mtl_depth_attachment_.
slice = 0;
993 MTL_LOG_WARNING(
"TODO: Support layered rendering for 1D array textures, if needed");
996 mtl_depth_attachment_.
slice = layer;
1001 mtl_depth_attachment_.
slice = layer;
1004 mtl_depth_attachment_.
slice = 0;
1006 use_multilayered_rendering_ =
true;
1011 mtl_depth_attachment_.
slice = 0;
1016 use_multilayered_rendering_ =
true;
1021 mtl_depth_attachment_.
slice = layer;
1024 mtl_depth_attachment_.
slice = 0;
1027 use_multilayered_rendering_ =
true;
1033 mtl_depth_attachment_.
slice = layer;
1036 mtl_depth_attachment_.
slice = 0;
1039 use_multilayered_rendering_ =
true;
1043 mtl_depth_attachment_.
slice = 0;
1052 int width_of_miplayer, height_of_miplayer;
1053 if (miplevel <= 0) {
1054 width_of_miplayer = texture->width_get();
1055 height_of_miplayer = texture->height_get();
1058 width_of_miplayer =
max_ii(texture->width_get() >> miplevel, 1);
1059 height_of_miplayer =
max_ii(texture->height_get() >> miplevel, 1);
1062 if (default_width_ == 0 || default_height_ == 0) {
1068 BLI_assert(default_width_ == width_of_miplayer);
1069 BLI_assert(default_height_ == height_of_miplayer);
1077 "Passing in null texture to MTLFrameBuffer::addDepthAttachment (This could be due to not "
1078 "all texture types being supported).");
1089 MTL_LOG_WARNING(
"Attachment specified with invalid mip level %u", miplevel);
1094 mtl_stencil_attachment_.
used =
true;
1096 mtl_stencil_attachment_.
mip = miplevel;
1102 switch (texture->type_) {
1106 mtl_stencil_attachment_.
slice = 0;
1112 MTL_LOG_WARNING(
"TODO: Support layered rendering for 1D array textures, if needed");
1115 mtl_stencil_attachment_.
slice = layer;
1120 mtl_stencil_attachment_.
slice = layer;
1123 mtl_stencil_attachment_.
slice = 0;
1125 use_multilayered_rendering_ =
true;
1130 mtl_stencil_attachment_.
slice = 0;
1135 use_multilayered_rendering_ =
true;
1140 mtl_stencil_attachment_.
slice = layer;
1143 mtl_stencil_attachment_.
slice = 0;
1146 use_multilayered_rendering_ =
true;
1152 mtl_stencil_attachment_.
slice = layer;
1155 mtl_stencil_attachment_.
slice = 0;
1158 use_multilayered_rendering_ =
true;
1162 mtl_stencil_attachment_.
slice = 0;
1171 int width_of_miplayer, height_of_miplayer;
1172 if (miplevel <= 0) {
1173 width_of_miplayer = texture->width_get();
1174 height_of_miplayer = texture->height_get();
1177 width_of_miplayer =
max_ii(texture->width_get() >> miplevel, 1);
1178 height_of_miplayer =
max_ii(texture->height_get() >> miplevel, 1);
1181 if (default_width_ == 0 || default_height_ == 0) {
1187 BLI_assert(default_width_ == width_of_miplayer);
1188 BLI_assert(default_height_ == height_of_miplayer);
1196 "Passing in null texture to MTLFrameBuffer::addStencilAttachment (This could be due to "
1197 "not all texture types being supported).");
1208 colour_attachment_count_ -= (mtl_color_attachments_[slot].
used) ? 1 : 0;
1209 mtl_color_attachments_[slot].
used =
false;
1222 mtl_depth_attachment_.
used =
false;
1223 mtl_depth_attachment_.
texture =
nullptr;
1234 mtl_stencil_attachment_.
used =
false;
1235 mtl_stencil_attachment_.
texture =
nullptr;
1251 colour_attachment_count_ = 0;
1309 changed = changed || (memcmp(mtl_color_attachments_[slot].clear_value.
color,
1311 sizeof(
float) * 4) != 0);
1313 memcpy(mtl_color_attachments_[slot].clear_value.
color, clear_color,
sizeof(
float) * 4);
1358 mtl_color_attachments_[slot].
load_action = load_action;
1359 mtl_color_attachments_[slot].
store_action = store_action;
1361 bool changed = (mtl_color_attachments_[slot].
load_action != prev_load_action ||
1362 mtl_color_attachments_[slot].
store_action != prev_store_action);
1378 bool changed = (mtl_depth_attachment_.
load_action != prev_load_action ||
1379 mtl_depth_attachment_.
store_action != prev_store_action);
1392 mtl_stencil_attachment_.
load_action = load_action;
1395 bool changed = (mtl_stencil_attachment_.
load_action != prev_load_action ||
1396 mtl_stencil_attachment_.
store_action != prev_store_action);
1406 for (
int slot = 0; slot < colour_attachment_count_; slot++) {
1425 return mtl_color_attachments_[slot].
used;
1435 if (mtl_color_attachments_[attachment].used &&
1436 mtl_color_attachments_[attachment].texture == texture)
1447 return mtl_depth_attachment_.
used;
1453 return mtl_stencil_attachment_.
used;
1462 if (mtl_color_attachments_[attachment].used &&
1463 (mtl_color_attachments_[attachment].texture == texture))
1474 return colour_attachment_count_;
1481 return mtl_color_attachments_[slot];
1484 null_attachment.
used =
false;
1485 return null_attachment;
1491 return mtl_depth_attachment_;
1497 return mtl_stencil_attachment_;
1534 if (load_contents) {
1547 for (
int config = 0; config < 3; config++) {
1548 descriptor_dirty_[config] =
true;
1551 else if (is_loadstore_dirty_) {
1553 descriptor_dirty_[MTL_FB_CONFIG_CLEAR] =
true;
1554 descriptor_dirty_[MTL_FB_CONFIG_CUSTOM] =
true;
1566 uint descriptor_config = (load_contents) ? MTL_FB_CONFIG_LOAD :
1568 MTL_FB_CONFIG_CUSTOM);
1574 descriptor_config = MTL_FB_CONFIG_CUSTOM;
1575 descriptor_dirty_[descriptor_config] =
true;
1578 if (descriptor_dirty_[descriptor_config] || framebuffer_descriptor_[descriptor_config] == nil) {
1581 if (framebuffer_descriptor_[descriptor_config] == nil) {
1582 framebuffer_descriptor_[descriptor_config] = [[MTLRenderPassDescriptor alloc]
init];
1586 if (use_multilayered_rendering_) {
1593 if (mtl_color_attachments_[attachment_ind].used) {
1604 if (mtl_depth_attachment_.
used) {
1613 if (mtl_stencil_attachment_.
used) {
1624 framebuffer_descriptor_[descriptor_config].renderTargetArrayLength =
len;
1627 framebuffer_descriptor_[descriptor_config].renderTargetArrayLength = 0;
1631 int colour_attachments = 0;
1633 MTLAttachment &attachment_config = mtl_color_attachments_[attachment_ind];
1635 if (attachment_config.
used) {
1636 id<MTLTexture> texture = attachment_config.
texture->get_metal_handle_base();
1637 if (texture == nil) {
1638 MTL_LOG_ERROR(
"Attempting to assign invalid texture as attachment");
1645 id<MTLTexture> source_color_texture =
texture;
1649 source_color_texture = attachment_config.
texture->get_non_srgb_handle();
1656 if (descriptor_config == MTL_FB_CONFIG_LOAD) {
1681 MTLRenderPassColorAttachmentDescriptor *attachment =
1682 colour_attachment_descriptors_[attachment_ind];
1685 attachment.texture = source_color_texture;
1690 MTLClearColorMake(0.0, 0.0, 0.0, 0.0);
1692 attachment.level = attachment_config.
mip;
1693 attachment.slice = attachment_config.
slice;
1694 attachment.depthPlane = attachment_config.
depth_plane;
1695 colour_attachments++;
1698 [framebuffer_descriptor_[descriptor_config].colorAttachments setObject:attachment
1699 atIndexedSubscript:attachment_ind];
1703 [framebuffer_descriptor_[descriptor_config].colorAttachments setObject:nil
1704 atIndexedSubscript:attachment_ind];
1707 BLI_assert(colour_attachments == colour_attachment_count_);
1711 if (mtl_depth_attachment_.
used) {
1712 framebuffer_descriptor_[descriptor_config].depthAttachment.texture =
1713 (id<MTLTexture>)mtl_depth_attachment_.
texture->get_metal_handle_base();
1721 if (descriptor_config == MTL_FB_CONFIG_LOAD) {
1743 framebuffer_descriptor_[descriptor_config].depthAttachment.loadAction =
1745 framebuffer_descriptor_[descriptor_config].depthAttachment.clearDepth =
1747 framebuffer_descriptor_[descriptor_config].depthAttachment.storeAction =
1749 framebuffer_descriptor_[descriptor_config].depthAttachment.level = mtl_depth_attachment_.
mip;
1750 framebuffer_descriptor_[descriptor_config].depthAttachment.slice =
1751 mtl_depth_attachment_.
slice;
1752 framebuffer_descriptor_[descriptor_config].depthAttachment.depthPlane =
1756 framebuffer_descriptor_[descriptor_config].depthAttachment.texture = nil;
1760 if (mtl_stencil_attachment_.
used) {
1761 framebuffer_descriptor_[descriptor_config].stencilAttachment.texture =
1762 (id<MTLTexture>)mtl_stencil_attachment_.
texture->get_metal_handle_base();
1764 bool texture_is_memoryless = (mtl_stencil_attachment_.
texture->
usage_get() &
1770 if (descriptor_config == MTL_FB_CONFIG_LOAD) {
1792 framebuffer_descriptor_[descriptor_config].stencilAttachment.loadAction =
1794 framebuffer_descriptor_[descriptor_config].stencilAttachment.clearStencil =
1796 framebuffer_descriptor_[descriptor_config].stencilAttachment.storeAction =
1798 framebuffer_descriptor_[descriptor_config].stencilAttachment.level =
1799 mtl_stencil_attachment_.
mip;
1800 framebuffer_descriptor_[descriptor_config].stencilAttachment.slice =
1801 mtl_stencil_attachment_.
slice;
1802 framebuffer_descriptor_[descriptor_config].stencilAttachment.depthPlane =
1806 framebuffer_descriptor_[descriptor_config].stencilAttachment.texture = nil;
1810 int total_num_attachments = colour_attachment_count_ + (mtl_depth_attachment_.
used ? 1 : 0) +
1811 (mtl_stencil_attachment_.
used ? 1 : 0);
1812 if (total_num_attachments == 0) {
1814 framebuffer_descriptor_[descriptor_config].renderTargetWidth =
width_;
1815 framebuffer_descriptor_[descriptor_config].renderTargetHeight =
height_;
1816 framebuffer_descriptor_[descriptor_config].defaultRasterSampleCount = 1;
1819 descriptor_dirty_[descriptor_config] =
false;
1823 is_loadstore_dirty_ =
false;
1828 return framebuffer_descriptor_[descriptor_config];
1849 if (!metal_fb_write) {
1859 if (!(do_color || do_depth || do_stencil)) {
1860 MTL_LOG_WARNING(
"FrameBuffer: requested blit but no color, depth or stencil flag was set");
1864 id<MTLBlitCommandEncoder> blit_encoder = nil;
1874 assert(src_attachment.
slice == 0 &&
1875 "currently only supporting slice 0 for graphics framebuffer blit");
1884 dst_attachment.
slice,
1897 if (src_attachment.
used && dst_attachment.
used) {
1900 src_attachment.
texture->blit(blit_encoder,
1904 src_attachment.
slice,
1910 dst_attachment.
slice,
1921 if ((do_depth || do_stencil) && blit_encoder == nil) {
1929 if (src_attachment.
used && dst_attachment.
used) {
1932 src_attachment.
texture->blit(blit_encoder,
1936 src_attachment.
slice,
1942 dst_attachment.
slice,
1958 if (src_attachment.
used && dst_attachment.
used) {
1961 src_attachment.
texture->blit(blit_encoder,
1965 src_attachment.
slice,
1971 dst_attachment.
slice,
1994 return default_width_;
1998 return default_height_;
#define BLI_assert_msg(a, msg)
MINLINE int max_ii(int a, int b)
size_t BLI_snprintf(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define UNUSED_VARS_NDEBUG(...)
@ GPU_LOADACTION_DONT_CARE
@ GPU_STOREACTION_DONT_CARE
void GPU_framebuffer_restore()
#define GPU_MAX_VIEWPORTS
@ GPU_TEXTURE_USAGE_MEMORYLESS
@ GPU_TEXTURE_USAGE_ATTACHMENT
void GPU_texture_image_bind(GPUTexture *texture, int unit)
void GPU_texture_get_mipmap_size(GPUTexture *texture, int mip_level, int *r_size)
eGPUTextureFormat GPU_texture_format(const GPUTexture *texture)
constexpr IndexRange index_range() const
void size_set(int width, int height)
bool use_explicit_load_store_
char name_[DEBUG_NAME_LEN]
GPUAttachment attachments_[GPU_FB_MAX_ATTACHMENT]
int viewport_[GPU_MAX_VIEWPORTS][4]
MTLFrameBuffer * get_active_framebuffer()
bool end_active_command_encoder()
bool is_inside_render_pass()
id< MTLBlitCommandEncoder > ensure_begin_blit_encoder()
MTLFrameBuffer * get_current_framebuffer()
void set_scissor_enabled(bool scissor_enabled)
void framebuffer_bind(MTLFrameBuffer *framebuffer)
id< MTLRenderCommandEncoder > ensure_begin_render_pass()
static MTLContext * get()
void set_viewport(int origin_x, int origin_y, int width, int height)
void set_viewports(int count, const int(&viewports)[GPU_MAX_VIEWPORTS][4])
void set_scissor(int scissor_x, int scissor_y, int scissor_width, int scissor_height)
MTLCommandBufferManager main_command_buffer
bool remove_stencil_attachment()
bool set_depth_loadstore_op(eGPULoadOp load_action, eGPUStoreOp store_action)
MTLAttachment get_color_attachment(uint slot)
bool remove_color_attachment(uint slot)
void blit(uint read_slot, uint src_x_offset, uint src_y_offset, MTLFrameBuffer *metal_fb_write, uint write_slot, uint dst_x_offset, uint dst_y_offset, uint width, uint height, eGPUFrameBufferBits blit_buffers)
void read(eGPUFrameBufferBits planes, eGPUDataFormat format, const int area[4], int channel_len, int slot, void *r_data) override
void remove_all_attachments()
int get_color_attachment_slot_from_texture(gpu::MTLTexture *texture)
void blit_to(eGPUFrameBufferBits planes, int src_slot, FrameBuffer *dst, int dst_slot, int dst_offset_x, int dst_offset_y) override
void default_size_set(int w, int h)
bool remove_depth_attachment()
bool check(char err_out[256]) override
bool add_color_attachment(gpu::MTLTexture *texture, uint slot, int miplevel, int layer)
bool set_color_attachment_clear_color(uint slot, const float clear_color[4])
MTLFrameBuffer(MTLContext *ctx, const char *name)
bool set_depth_attachment_clear_value(float depth_clear)
void update_attachments(bool update_viewport)
void ensure_render_target_size()
MTLAttachment get_stencil_attachment()
void ensure_attachments_and_viewport()
MTLRenderPassDescriptor * bake_render_pass_descriptor(bool load_contents)
bool has_color_attachment_with_texture(gpu::MTLTexture *texture)
MTLAttachment get_depth_attachment()
void clear_multi(const float(*clear_cols)[4]) override
bool set_stencil_loadstore_op(eGPULoadOp load_action, eGPUStoreOp store_action)
bool set_color_loadstore_op(uint slot, eGPULoadOp load_action, eGPUStoreOp store_action)
uint get_attachment_limit()
bool add_depth_attachment(gpu::MTLTexture *texture, int miplevel, int layer)
void attachment_set_loadstore_op(GPUAttachmentType type, GPULoadStore ls) override
bool validate_render_pass()
bool set_stencil_attachment_clear_value(uint stencil_clear)
bool add_stencil_attachment(gpu::MTLTexture *texture, int miplevel, int layer)
bool has_stencil_attachment()
bool has_attachment_at_slot(uint slot)
void clear_attachment(GPUAttachmentType type, eGPUDataFormat data_format, const void *clear_value) override
void mark_loadstore_dirty()
void clear(eGPUFrameBufferBits buffers, const float clear_col[4], float clear_depth, uint clear_stencil) override
void bind(bool enabled_srgb) override
void subpass_transition_impl(const GPUAttachmentState, Span< GPUAttachmentState > color_attachment_states) override
uint get_attachment_count()
bool has_depth_attachment()
static void set_framebuffer_srgb_target(int use_srgb_to_linear)
eGPUTextureFormat format_get() const
eGPUTextureUsage usage_get() const
local_group_size(16, 16) .push_constant(Type texture
draw_view in_light_buf[] float
@ GPU_FB_DEPTH_STENCIL_ATTACHMENT
@ GPU_FB_COLOR_ATTACHMENT5
@ GPU_FB_COLOR_ATTACHMENT2
@ GPU_FB_COLOR_ATTACHMENT3
@ GPU_FB_COLOR_ATTACHMENT6
@ GPU_FB_COLOR_ATTACHMENT7
@ GPU_FB_COLOR_ATTACHMENT4
@ GPU_FB_COLOR_ATTACHMENT1
@ GPU_FB_COLOR_ATTACHMENT0
@ GPU_FB_DEPTH_ATTACHMENT
#define GPU_FB_MAX_COLOR_ATTACHMENT
#define MTL_LOG_WARNING(info,...)
#define MTL_LOG_ERROR(info,...)
#define MTL_FB_CONFIG_MAX
static Context * unwrap(GPUContext *ctx)
MTLLoadAction mtl_load_action_from_gpu(eGPULoadOp action)
size_t to_bytesize(GPUIndexBufType type)
static const int MTL_MAX_MIPMAP_COUNT
MTLStoreAction mtl_store_action_from_gpu(eGPUStoreOp action)
gpu::MTLTexture * texture
uint render_target_array_length
union blender::gpu::MTLAttachment::@650 clear_value