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;
43 for (
int i = 0; i < MTL_FB_CONFIG_MAX; i++) {
44 framebuffer_descriptor_[i] = [[MTLRenderPassDescriptor alloc]
init];
45 descriptor_dirty_[i] =
true;
49 colour_attachment_descriptors_[i] = [[MTLRenderPassColorAttachmentDescriptor alloc]
init];
74 for (
int config = 0; config < MTL_FB_CONFIG_MAX; config++) {
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;
487 for (
int i : color_attachment_states.
index_range()) {
510 if (area[2] <= 0 || area[3] <= 0) {
520 size_t sample_len = area[2] * area[3];
522 size_t debug_data_size = sample_len * sample_size;
523 tex->read_internal(0,
538 "Attempting to read depth from a framebuffer which does not have a depth "
549 size_t sample_len = area[2] * area[3];
551 size_t debug_data_size = sample_len * sample_size * channel_len;
552 tex->read_internal(0,
569 MTL_LOG_ERROR(
"Framebuffer: Trying to read stencil bit. Unsupported.");
605 else if (do_stencil) {
632 is_loadstore_dirty_ =
true;
637 is_loadstore_dirty_ =
true;
642 has_pending_clear_ =
false;
647 has_pending_clear_ =
true;
659 use_multilayered_rendering_ =
false;
666 bool depth_added =
false;
722 first_attachment = type;
765 first_attachment = type;
797 if (
dirty_state_ ==
false && dirty_state_ctx_ == mtl_ctx) {
805 if (viewport_w == 0 || viewport_h == 0) {
806 MTL_LOG_WARNING(
"Viewport had width and height of (0,0) -- Updating -- DEBUG Safety check");
807 viewport_w = default_width_;
808 viewport_h = default_height_;
822 dirty_state_ctx_ = mtl_ctx;
826 "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;
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;
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;
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).");
1209 colour_attachment_count_ -= (mtl_color_attachments_[slot].
used) ? 1 : 0;
1210 mtl_color_attachments_[slot].
used =
false;
1223 mtl_depth_attachment_.
used =
false;
1224 mtl_depth_attachment_.
texture =
nullptr;
1235 mtl_stencil_attachment_.
used =
false;
1236 mtl_stencil_attachment_.
texture =
nullptr;
1252 colour_attachment_count_ = 0;
1310 float *attachment_clear_color = mtl_color_attachments_[slot].
clear_value.
color;
1311 changed = changed || (attachment_clear_color[0] != clear_color[0] ||
1312 attachment_clear_color[1] != clear_color[1] ||
1313 attachment_clear_color[2] != clear_color[2] ||
1314 attachment_clear_color[3] != clear_color[3]);
1316 attachment_clear_color[0] = clear_color[0];
1317 attachment_clear_color[1] = clear_color[1];
1318 attachment_clear_color[2] = clear_color[2];
1319 attachment_clear_color[3] = clear_color[3];
1364 mtl_color_attachments_[slot].
load_action = load_action;
1365 mtl_color_attachments_[slot].
store_action = store_action;
1367 bool changed = (mtl_color_attachments_[slot].
load_action != prev_load_action ||
1368 mtl_color_attachments_[slot].
store_action != prev_store_action);
1384 bool changed = (mtl_depth_attachment_.
load_action != prev_load_action ||
1385 mtl_depth_attachment_.
store_action != prev_store_action);
1398 mtl_stencil_attachment_.
load_action = load_action;
1401 bool changed = (mtl_stencil_attachment_.
load_action != prev_load_action ||
1402 mtl_stencil_attachment_.
store_action != prev_store_action);
1412 for (
int slot = 0; slot < colour_attachment_count_; slot++) {
1431 return mtl_color_attachments_[slot].
used;
1441 if (mtl_color_attachments_[attachment].used &&
1453 return mtl_depth_attachment_.
used;
1459 return mtl_stencil_attachment_.
used;
1468 if (mtl_color_attachments_[attachment].used &&
1480 return colour_attachment_count_;
1487 return mtl_color_attachments_[slot];
1490 null_attachment.
used =
false;
1491 return null_attachment;
1497 return mtl_depth_attachment_;
1503 return mtl_stencil_attachment_;
1540 if (load_contents) {
1553 for (
int config = 0; config < 3; config++) {
1554 descriptor_dirty_[config] =
true;
1557 else if (is_loadstore_dirty_) {
1559 descriptor_dirty_[MTL_FB_CONFIG_CLEAR] =
true;
1560 descriptor_dirty_[MTL_FB_CONFIG_CUSTOM] =
true;
1572 uint descriptor_config = (load_contents) ? MTL_FB_CONFIG_LOAD :
1574 MTL_FB_CONFIG_CUSTOM);
1580 descriptor_config = MTL_FB_CONFIG_CUSTOM;
1581 descriptor_dirty_[descriptor_config] =
true;
1584 if (descriptor_dirty_[descriptor_config] || framebuffer_descriptor_[descriptor_config] == nil) {
1587 if (framebuffer_descriptor_[descriptor_config] == nil) {
1588 framebuffer_descriptor_[descriptor_config] = [[MTLRenderPassDescriptor alloc]
init];
1592 if (use_multilayered_rendering_) {
1599 if (mtl_color_attachments_[attachment_ind].used) {
1610 if (mtl_depth_attachment_.
used) {
1619 if (mtl_stencil_attachment_.
used) {
1630 framebuffer_descriptor_[descriptor_config].renderTargetArrayLength =
len;
1633 framebuffer_descriptor_[descriptor_config].renderTargetArrayLength = 0;
1637 int colour_attachments = 0;
1639 MTLAttachment &attachment_config = mtl_color_attachments_[attachment_ind];
1641 if (attachment_config.
used) {
1642 id<MTLTexture>
texture = attachment_config.
texture->get_metal_handle_base();
1644 MTL_LOG_ERROR(
"Attempting to assign invalid texture as attachment");
1651 id<MTLTexture> source_color_texture =
texture;
1655 source_color_texture = attachment_config.
texture->get_non_srgb_handle();
1662 if (descriptor_config == MTL_FB_CONFIG_LOAD) {
1687 MTLRenderPassColorAttachmentDescriptor *attachment =
1688 colour_attachment_descriptors_[attachment_ind];
1691 attachment.texture = source_color_texture;
1696 MTLClearColorMake(0.0, 0.0, 0.0, 0.0);
1698 attachment.level = attachment_config.
mip;
1699 attachment.slice = attachment_config.
slice;
1700 attachment.depthPlane = attachment_config.
depth_plane;
1701 colour_attachments++;
1704 [framebuffer_descriptor_[descriptor_config].colorAttachments setObject:attachment
1705 atIndexedSubscript:attachment_ind];
1709 [framebuffer_descriptor_[descriptor_config].colorAttachments setObject:nil
1710 atIndexedSubscript:attachment_ind];
1713 BLI_assert(colour_attachments == colour_attachment_count_);
1717 if (mtl_depth_attachment_.
used) {
1718 framebuffer_descriptor_[descriptor_config].depthAttachment.texture =
1719 (id<MTLTexture>)mtl_depth_attachment_.
texture->get_metal_handle_base();
1727 if (descriptor_config == MTL_FB_CONFIG_LOAD) {
1749 framebuffer_descriptor_[descriptor_config].depthAttachment.loadAction =
1751 framebuffer_descriptor_[descriptor_config].depthAttachment.clearDepth =
1753 framebuffer_descriptor_[descriptor_config].depthAttachment.storeAction =
1755 framebuffer_descriptor_[descriptor_config].depthAttachment.level = mtl_depth_attachment_.
mip;
1756 framebuffer_descriptor_[descriptor_config].depthAttachment.slice =
1757 mtl_depth_attachment_.
slice;
1758 framebuffer_descriptor_[descriptor_config].depthAttachment.depthPlane =
1762 framebuffer_descriptor_[descriptor_config].depthAttachment.texture = nil;
1766 if (mtl_stencil_attachment_.
used) {
1767 framebuffer_descriptor_[descriptor_config].stencilAttachment.texture =
1768 (id<MTLTexture>)mtl_stencil_attachment_.
texture->get_metal_handle_base();
1770 bool texture_is_memoryless = (mtl_stencil_attachment_.
texture->
usage_get() &
1776 if (descriptor_config == MTL_FB_CONFIG_LOAD) {
1798 framebuffer_descriptor_[descriptor_config].stencilAttachment.loadAction =
1800 framebuffer_descriptor_[descriptor_config].stencilAttachment.clearStencil =
1802 framebuffer_descriptor_[descriptor_config].stencilAttachment.storeAction =
1804 framebuffer_descriptor_[descriptor_config].stencilAttachment.level =
1805 mtl_stencil_attachment_.
mip;
1806 framebuffer_descriptor_[descriptor_config].stencilAttachment.slice =
1807 mtl_stencil_attachment_.
slice;
1808 framebuffer_descriptor_[descriptor_config].stencilAttachment.depthPlane =
1812 framebuffer_descriptor_[descriptor_config].stencilAttachment.texture = nil;
1816 int total_num_attachments = colour_attachment_count_ + (mtl_depth_attachment_.
used ? 1 : 0) +
1817 (mtl_stencil_attachment_.
used ? 1 : 0);
1818 if (total_num_attachments == 0) {
1820 framebuffer_descriptor_[descriptor_config].renderTargetWidth =
width_;
1821 framebuffer_descriptor_[descriptor_config].renderTargetHeight =
height_;
1822 framebuffer_descriptor_[descriptor_config].defaultRasterSampleCount = 1;
1825 descriptor_dirty_[descriptor_config] =
false;
1829 is_loadstore_dirty_ =
false;
1834 return framebuffer_descriptor_[descriptor_config];
1855 if (!metal_fb_write) {
1865 if (!(do_color || do_depth || do_stencil)) {
1866 MTL_LOG_WARNING(
"FrameBuffer: requested blit but no color, depth or stencil flag was set");
1870 id<MTLBlitCommandEncoder> blit_encoder = nil;
1881 "currently only supporting slice 0 for graphics framebuffer blit");
1890 dst_attachment.
slice,
1903 if (src_attachment.
used && dst_attachment.
used) {
1906 src_attachment.
texture->blit(blit_encoder,
1910 src_attachment.
slice,
1916 dst_attachment.
slice,
1927 if ((do_depth || do_stencil) && blit_encoder == nil) {
1935 if (src_attachment.
used && dst_attachment.
used) {
1938 src_attachment.
texture->blit(blit_encoder,
1942 src_attachment.
slice,
1948 dst_attachment.
slice,
1964 if (src_attachment.
used && dst_attachment.
used) {
1967 src_attachment.
texture->blit(blit_encoder,
1971 src_attachment.
slice,
1977 dst_attachment.
slice,
2000 return default_width_;
2004 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()
static constexpr int 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)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
constexpr IndexRange index_range() const
void size_set(int width, int height)
bool use_explicit_load_store_
void set_color_attachment_bit(GPUAttachmentType type, bool value)
char name_[DEBUG_NAME_LEN]
GPUAttachment attachments_[GPU_FB_MAX_ATTACHMENT]
int viewport_[GPU_MAX_VIEWPORTS][4]
static MTLCapabilities capabilities
MTLFrameBuffer * get_active_framebuffer()
bool end_active_command_encoder(bool retain_framebuffers=false)
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)
~MTLFrameBuffer() override
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
@ 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
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
#define assert(assertion)
#define MTL_LOG_WARNING(info,...)
#define MTL_LOG_ERROR(info,...)
static Context * unwrap(GPUContext *ctx)
MTLLoadAction mtl_load_action_from_gpu(eGPULoadOp action)
int to_bytesize(const DataFormat format)
static const int MTL_MAX_MIPMAP_COUNT
MTLStoreAction mtl_store_action_from_gpu(eGPUStoreOp action)
gpu::MTLTexture * texture
union blender::gpu::MTLAttachment::@576 clear_value
uint render_target_array_length