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;
856 mtl_color_attachments_[slot].texture =
texture;
857 mtl_color_attachments_[slot].mip = miplevel;
860 mtl_color_attachments_[slot].render_target_array_length = 0;
867 mtl_color_attachments_[slot].slice = 0;
868 mtl_color_attachments_[slot].depth_plane = 0;
873 MTL_LOG_WARNING(
"TODO: Support layered rendering for 1D array textures, if needed.");
876 mtl_color_attachments_[slot].slice = layer;
877 mtl_color_attachments_[slot].depth_plane = 0;
881 mtl_color_attachments_[slot].slice = layer;
882 mtl_color_attachments_[slot].depth_plane = 0;
884 mtl_color_attachments_[slot].slice = 0;
885 mtl_color_attachments_[slot].render_target_array_length =
texture->d_;
886 use_multilayered_rendering_ =
true;
891 mtl_color_attachments_[slot].slice = 0;
892 mtl_color_attachments_[slot].depth_plane = layer;
894 mtl_color_attachments_[slot].depth_plane = 0;
895 mtl_color_attachments_[slot].render_target_array_length =
texture->d_;
896 use_multilayered_rendering_ =
true;
901 mtl_color_attachments_[slot].slice = layer;
902 mtl_color_attachments_[slot].depth_plane = 0;
904 mtl_color_attachments_[slot].slice = 0;
905 mtl_color_attachments_[slot].depth_plane = 0;
906 mtl_color_attachments_[slot].render_target_array_length = 6;
907 use_multilayered_rendering_ =
true;
913 mtl_color_attachments_[slot].slice = layer;
914 mtl_color_attachments_[slot].depth_plane = 0;
916 mtl_color_attachments_[slot].slice = 0;
917 mtl_color_attachments_[slot].depth_plane = 0;
918 mtl_color_attachments_[slot].render_target_array_length =
texture->d_;
919 use_multilayered_rendering_ =
true;
923 mtl_color_attachments_[slot].slice = 0;
924 mtl_color_attachments_[slot].depth_plane = 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;
976 mtl_depth_attachment_.texture =
texture;
977 mtl_depth_attachment_.mip = miplevel;
980 mtl_depth_attachment_.render_target_array_length = 0;
987 mtl_depth_attachment_.slice = 0;
988 mtl_depth_attachment_.depth_plane = 0;
993 MTL_LOG_WARNING(
"TODO: Support layered rendering for 1D array textures, if needed");
996 mtl_depth_attachment_.slice = layer;
997 mtl_depth_attachment_.depth_plane = 0;
1001 mtl_depth_attachment_.slice = layer;
1002 mtl_depth_attachment_.depth_plane = 0;
1004 mtl_depth_attachment_.slice = 0;
1005 mtl_depth_attachment_.render_target_array_length =
texture->d_;
1006 use_multilayered_rendering_ =
true;
1011 mtl_depth_attachment_.slice = 0;
1012 mtl_depth_attachment_.depth_plane = layer;
1014 mtl_depth_attachment_.depth_plane = 0;
1015 mtl_depth_attachment_.render_target_array_length =
texture->d_;
1016 use_multilayered_rendering_ =
true;
1021 mtl_depth_attachment_.slice = layer;
1022 mtl_depth_attachment_.depth_plane = 0;
1024 mtl_depth_attachment_.slice = 0;
1025 mtl_depth_attachment_.depth_plane = 0;
1026 mtl_depth_attachment_.render_target_array_length = 6;
1027 use_multilayered_rendering_ =
true;
1033 mtl_depth_attachment_.slice = layer;
1034 mtl_depth_attachment_.depth_plane = 0;
1036 mtl_depth_attachment_.slice = 0;
1037 mtl_depth_attachment_.depth_plane = 0;
1038 mtl_depth_attachment_.render_target_array_length =
texture->d_;
1039 use_multilayered_rendering_ =
true;
1043 mtl_depth_attachment_.slice = 0;
1044 mtl_depth_attachment_.depth_plane = 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;
1095 mtl_stencil_attachment_.texture =
texture;
1096 mtl_stencil_attachment_.mip = miplevel;
1099 mtl_stencil_attachment_.render_target_array_length = 0;
1106 mtl_stencil_attachment_.slice = 0;
1107 mtl_stencil_attachment_.depth_plane = 0;
1112 MTL_LOG_WARNING(
"TODO: Support layered rendering for 1D array textures, if needed");
1115 mtl_stencil_attachment_.slice = layer;
1116 mtl_stencil_attachment_.depth_plane = 0;
1120 mtl_stencil_attachment_.slice = layer;
1121 mtl_stencil_attachment_.depth_plane = 0;
1123 mtl_stencil_attachment_.slice = 0;
1124 mtl_stencil_attachment_.render_target_array_length =
texture->d_;
1125 use_multilayered_rendering_ =
true;
1130 mtl_stencil_attachment_.slice = 0;
1131 mtl_stencil_attachment_.depth_plane = layer;
1133 mtl_stencil_attachment_.depth_plane = 0;
1134 mtl_stencil_attachment_.render_target_array_length =
texture->d_;
1135 use_multilayered_rendering_ =
true;
1140 mtl_stencil_attachment_.slice = layer;
1141 mtl_stencil_attachment_.depth_plane = 0;
1143 mtl_stencil_attachment_.slice = 0;
1144 mtl_stencil_attachment_.depth_plane = 0;
1145 mtl_stencil_attachment_.render_target_array_length = 6;
1146 use_multilayered_rendering_ =
true;
1152 mtl_stencil_attachment_.slice = layer;
1153 mtl_stencil_attachment_.depth_plane = 0;
1155 mtl_stencil_attachment_.slice = 0;
1156 mtl_stencil_attachment_.depth_plane = 0;
1157 mtl_stencil_attachment_.render_target_array_length =
texture->d_;
1158 use_multilayered_rendering_ =
true;
1162 mtl_stencil_attachment_.slice = 0;
1163 mtl_stencil_attachment_.depth_plane = 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).");
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) {
1595 len = mtl_color_attachments_[attachment_ind].render_target_array_length;
1599 (
len == mtl_color_attachments_[attachment_ind].render_target_array_length);
1604 if (mtl_depth_attachment_.used) {
1606 len = mtl_depth_attachment_.render_target_array_length;
1609 valid = valid && (
len == mtl_depth_attachment_.render_target_array_length);
1613 if (mtl_stencil_attachment_.used) {
1615 len = mtl_stencil_attachment_.render_target_array_length;
1618 valid = valid && (
len == mtl_stencil_attachment_.render_target_array_length);
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();
1638 MTL_LOG_ERROR(
"Attempting to assign invalid texture as attachment");
1645 id<MTLTexture> source_color_texture =
texture;
1647 !this->get_srgb_enabled())
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();
1715 bool texture_is_memoryless = (mtl_depth_attachment_.texture->usage_get() &
1720 eGPULoadOp load_action = mtl_depth_attachment_.load_action;
1721 if (descriptor_config == MTL_FB_CONFIG_LOAD) {
1735 eGPUStoreOp store_action = mtl_depth_attachment_.store_action;
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 =
1753 mtl_depth_attachment_.depth_plane;
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() &
1769 eGPULoadOp load_action = mtl_stencil_attachment_.load_action;
1770 if (descriptor_config == MTL_FB_CONFIG_LOAD) {
1784 eGPUStoreOp store_action = mtl_stencil_attachment_.store_action;
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 =
1803 mtl_stencil_attachment_.depth_plane;
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];