37void gpu::MTLTexture::mtl_texture_init()
44 resource_mode_ = MTL_TEXTURE_MODE_DEFAULT;
49 mip_swizzle_view_ = nil;
55 vert_buffer_ =
nullptr;
56 vert_buffer_mtl_ = nil;
59 tex_swizzle_mask_[0] =
'r';
60 tex_swizzle_mask_[1] =
'g';
61 tex_swizzle_mask_[2] =
'b';
62 tex_swizzle_mask_[3] =
'a';
63 mtl_swizzle_mask_ = MTLTextureSwizzleChannelsMake(
64 MTLTextureSwizzleRed, MTLTextureSwizzleGreen, MTLTextureSwizzleBlue, MTLTextureSwizzleAlpha);
76 id<MTLTexture> metal_texture)
86 init_2D((
int)metal_texture.width, (
int)metal_texture.height, 0, 1,
format);
89 texture_ = metal_texture;
97 resource_mode_ = MTL_TEXTURE_MODE_EXTERNAL;
105 if (ctx !=
nullptr) {
117void gpu::MTLTexture::bake_mip_swizzle_view()
119 if (texture_view_dirty_flags_) {
125 if (resource_mode_ != MTL_TEXTURE_MODE_TEXTURE_VIEW &&
126 texture_view_dirty_flags_ == TEXTURE_VIEW_MIP_DIRTY && mip_swizzle_view_ == nil)
129 if (mip_texture_base_level_ == 0 && mip_texture_max_level_ == mtl_max_mips_) {
130 texture_view_dirty_flags_ = TEXTURE_VIEW_NOT_DIRTY;
136 if (mip_swizzle_view_ != nil) {
137 [mip_swizzle_view_ release];
138 mip_swizzle_view_ = nil;
143 const gpu::Texture *tex_view_src =
this;
144 if (resource_mode_ == MTL_TEXTURE_MODE_TEXTURE_VIEW) {
145 tex_view_src =
unwrap(source_texture_);
153 max_slices = tex_view_src->height_get();
157 max_slices = tex_view_src->depth_get();
166 max_slices = tex_view_src->depth_get();
177 if (texture_view_stencil_) {
178 switch (texture_view_pixel_format) {
179 case MTLPixelFormatDepth24Unorm_Stencil8:
180 texture_view_pixel_format = MTLPixelFormatX24_Stencil8;
182 case MTLPixelFormatDepth32Float_Stencil8:
183 texture_view_pixel_format = MTLPixelFormatX32_Stencil8;
186 BLI_assert_msg(
false,
"Texture format does not support stencil views.");
193 MTLTextureType texture_view_texture_type =
to_metal_type(type_);
200 (texture_view_pixel_format == texture_.pixelFormat) ||
202 "Usage Flag GPU_TEXTURE_USAGE_FORMAT_VIEW must be specified if a texture view is "
203 "created with a different format to its source texture.");
205 int range_len =
min_ii((mip_texture_max_level_ - mip_texture_base_level_) + 1,
206 (
int)texture_.mipmapLevelCount - mip_texture_base_level_);
208 BLI_assert(mip_texture_base_level_ < texture_.mipmapLevelCount);
209 BLI_assert(mip_texture_base_layer_ < max_slices);
211 mip_swizzle_view_ = [texture_
212 newTextureViewWithPixelFormat:texture_view_pixel_format
213 textureType:texture_view_texture_type
214 levels:NSMakeRange(mip_texture_base_level_, range_len)
215 slices:NSMakeRange(mip_texture_base_layer_, num_slices)
216 swizzle:mtl_swizzle_mask_];
218 "Updating texture view - MIP TEXTURE BASE LEVEL: %d, MAX LEVEL: %d (Range len: %d)",
219 mip_texture_base_level_,
220 min_ii(mip_texture_max_level_, (
int)texture_.mipmapLevelCount),
223 mip_swizzle_view_.label = [NSString
225 @"MipSwizzleView_%s__format=%u_type=%u_baselevel=%u_numlevels=%u_swizzle='%c%c%c%c'",
226 [[texture_
label] UTF8String],
227 (
uint)texture_view_pixel_format,
228 (
uint)texture_view_texture_type,
229 (
uint)mip_texture_base_level_,
231 tex_swizzle_mask_[0],
232 tex_swizzle_mask_[1],
233 tex_swizzle_mask_[2],
234 tex_swizzle_mask_[3]];
236 mip_swizzle_view_.label = [texture_
label];
238 texture_view_dirty_flags_ = TEXTURE_VIEW_NOT_DIRTY;
245id<MTLTexture> gpu::MTLTexture::get_metal_handle()
249 if (resource_mode_ == MTL_TEXTURE_MODE_VBO) {
250 id<MTLBuffer> buf = vert_buffer_->get_metal_buffer();
253 if (buf != vert_buffer_mtl_) {
255 "MTLTexture '%p' using MTL_TEXTURE_MODE_VBO requires re-generation due to updated "
262 this->init_internal(vert_buffer_);
265 buf = vert_buffer_->get_metal_buffer();
271 BLI_assert(vert_buffer_->get_metal_buffer() == vert_buffer_mtl_);
275 this->ensure_baked();
279 if (resource_mode_ == MTL_TEXTURE_MODE_TEXTURE_VIEW) {
280 BLI_assert_msg(mip_swizzle_view_,
"Texture view should always have a valid handle.");
283 if (mip_swizzle_view_ != nil || texture_view_dirty_flags_) {
284 bake_mip_swizzle_view();
289 if (mip_swizzle_view_ != nil) {
290 return mip_swizzle_view_;
298id<MTLTexture> gpu::MTLTexture::get_metal_handle_base()
302 this->ensure_baked();
305 if (resource_mode_ == MTL_TEXTURE_MODE_TEXTURE_VIEW) {
306 BLI_assert_msg(mip_swizzle_view_,
"Texture view should always have a valid handle.");
307 if (mip_swizzle_view_ != nil || texture_view_dirty_flags_) {
308 bake_mip_swizzle_view();
311 return mip_swizzle_view_;
321void gpu::MTLTexture::blit(id<MTLBlitCommandEncoder> blit_encoder,
327 gpu::MTLTexture *dest,
339 BLI_assert(width > 0 && height > 0 && depth > 0);
340 MTLSize src_size = MTLSizeMake(width, height, depth);
341 MTLOrigin src_origin = MTLOriginMake(src_x_offset, src_y_offset, src_z_offset);
342 MTLOrigin dst_origin = MTLOriginMake(dst_x_offset, dst_y_offset, dst_z_offset);
344 if (this->format_get() != dest->format_get()) {
346 "gpu::MTLTexture: Cannot copy between two textures of different types using a "
347 "blit encoder. TODO: Support this operation");
353 [blit_encoder copyFromTexture:this->get_metal_handle_base()
354 sourceSlice:src_slice
356 sourceOrigin:src_origin
358 toTexture:dest->get_metal_handle_base()
359 destinationSlice:dst_slice
360 destinationLevel:dst_mip
361 destinationOrigin:dst_origin];
364void gpu::MTLTexture::blit(gpu::MTLTexture *dst,
375 BLI_assert(this->type_get() == dst->type_get());
377 GPUShader *shader = fullscreen_blit_sh_get();
383 GPUFrameBuffer *blit_target_fb = dst->get_blit_framebuffer(dst_slice, dst_mip);
391 float w = dst->width_get();
392 float h = dst->height_get();
431 if (restore_fb !=
nullptr) {
439GPUFrameBuffer *gpu::MTLTexture::get_blit_framebuffer(
int dst_slice,
uint dst_mip)
443 bool update_attachments =
false;
446 update_attachments =
true;
451 if (blit_fb_slice_ != dst_slice || blit_fb_mip_ != dst_mip) {
452 update_attachments =
true;
456 if (update_attachments) {
462 static_cast<int>(dst_slice),
463 static_cast<int>(dst_mip)),
472 static_cast<int>(dst_slice),
473 static_cast<int>(dst_mip))});
475 blit_fb_slice_ = dst_slice;
476 blit_fb_mip_ = dst_mip;
483MTLSamplerState gpu::MTLTexture::get_sampler_state()
485 MTLSamplerState sampler_state;
486 sampler_state.state = this->sampler_state;
488 return sampler_state;
492 int mip,
int offset[3],
int extent[3],
eGPUDataFormat type,
const void *data)
499 BLI_assert(resource_mode_ != MTL_TEXTURE_MODE_TEXTURE_VIEW);
502 this->ensure_mipmaps(mip);
505 this->ensure_baked();
509 BLI_assert(mip >= mip_min_ && mip <= mip_max_);
511 BLI_assert(texture_.mipmapLevelCount >= mip_max_);
517 if (is_depth_format) {
521 update_sub_depth_2d(mip, offset, extent, type, data);
525 "gpu::MTLTexture::update_sub not yet supported for other depth "
536 size_t input_bytes_per_pixel =
to_bytesize(format_, type);
537 size_t totalsize = 0;
548 totalsize = ((expected_update_w + 3) / 4) * ((extent[1] + 3) / 4) *
to_block_size(format_);
551 switch (this->dimensions_count()) {
553 totalsize = input_bytes_per_pixel *
max_ulul(expected_update_w, 1);
556 totalsize = input_bytes_per_pixel *
max_ulul(expected_update_w, 1) * (size_t)extent[1];
559 totalsize = input_bytes_per_pixel *
max_ulul(expected_update_w, 1) * (size_t)extent[1] *
570 if (totalsize <= 0 || extent[0] <= 0) {
572 "MTLTexture::update_sub called with extent size of zero for one or more dimensions. "
573 "(%d, %d, %d) - DimCount: %u",
577 this->dimensions_count());
601 destination_num_channels,
608 bool can_use_direct_blit =
true;
609 if (!is_compressed && (expected_dst_bytes_per_pixel != input_bytes_per_pixel ||
610 num_channels != destination_num_channels))
612 can_use_direct_blit =
false;
615 if (is_depth_format) {
619 if (extent[0] == 1 && extent[1] == 1 && extent[2] == 1 && totalsize == 4) {
620 can_use_direct_blit =
false;
627 "SRGB data upload does not work correctly using compute upload. "
637 "Special input data type must be a 1-1 mapping with destination texture as it "
638 "cannot easily be split");
642 if (!can_use_direct_blit) {
644 "gpu::MTLTexture::update_sub supplied bpp is %lu bytes (%d components per "
645 "pixel), but backing texture bpp is %lu bytes (%d components per pixel) "
646 "(TODO(Metal): Channel Conversion needed) (w: %d, h: %d, d: %d)",
647 input_bytes_per_pixel,
649 expected_dst_bytes_per_pixel,
650 destination_num_channels,
658 "Updating texture layers other than mip=0 when data is mismatched is not "
659 "possible in METAL on macOS using texture->write\n");
666 "Updating texture -- destination MTLPixelFormat '%d' does not support write "
667 "operations, and no suitable TextureView format exists.\n",
668 *(
int *)(&destination_format));
678 if (compatible_write_format == MTLPixelFormatInvalid) {
679 MTL_LOG_ERROR(
"Cannot use compute update blit with texture-view format: %d\n",
680 *((
int *)&compatible_write_format));
686 totalsize,
true, data);
691 id<MTLBlitCommandEncoder> blit_encoder = nil;
692 id<MTLComputeCommandEncoder> compute_encoder = nil;
693 id<MTLTexture> staging_texture = nil;
694 id<MTLTexture> texture_handle = nil;
697 bool use_staging_texture =
false;
699 if (can_use_direct_blit) {
706 if ((compatible_write_format != destination_format) &&
709 use_staging_texture =
true;
720 use_staging_texture =
true;
722 if (compatible_write_format != destination_format) {
724 use_staging_texture =
true;
730 if (use_staging_texture) {
733 MTLTextureUsage original_usage = texture_descriptor_.usage;
734 texture_descriptor_.usage = original_usage | MTLTextureUsageShaderWrite |
735 MTLTextureUsagePixelFormatView;
736 staging_texture = [ctx->
device newTextureWithDescriptor:texture_descriptor_];
737 staging_texture.label =
@"Staging texture";
738 texture_descriptor_.usage = original_usage;
741 texture_handle = ((compatible_write_format == destination_format)) ?
742 [staging_texture retain] :
743 [staging_texture newTextureViewWithPixelFormat:compatible_write_format];
747 if (compatible_write_format != destination_format) {
749 texture_handle = [texture_ newTextureViewWithPixelFormat:compatible_write_format];
752 texture_handle = texture_;
753 [texture_handle retain];
762 if (can_use_direct_blit) {
764 size_t bytes_per_row = expected_dst_bytes_per_pixel *
768 size_t bytes_per_image = bytes_per_row;
772 bytes_per_row = blocks_x * block_size;
773 bytes_per_image = bytes_per_row;
776 for (
int array_index = 0; array_index < max_array_index; array_index++) {
778 size_t buffer_array_offset = (bytes_per_image * (size_t)array_index);
780 copyFromBuffer:staging_buffer
781 sourceOffset:buffer_array_offset
782 sourceBytesPerRow:bytes_per_row
783 sourceBytesPerImage:bytes_per_image
784 sourceSize:MTLSizeMake(extent[0], 1, 1)
785 toTexture:texture_handle
789 destinationOrigin:MTLOriginMake(offset[0], 0, 0)];
795 id<MTLComputePipelineState> pso = texture_update_1d_get_kernel(
796 compute_specialization_kernel);
797 TextureUpdateParams
params = {mip,
811 dispatchThreads:MTLSizeMake(extent[0], 1, 1)
812 threadsPerThreadgroup:MTLSizeMake(64, 1, 1)];
815 id<MTLComputePipelineState> pso = texture_update_1d_array_get_kernel(
816 compute_specialization_kernel);
817 TextureUpdateParams
params = {mip,
818 {extent[0], extent[1], 1},
819 {offset[0], offset[1], 0},
831 dispatchThreads:MTLSizeMake(extent[0], extent[1], 1)
832 threadsPerThreadgroup:MTLSizeMake(8, 8, 1)];
840 if (can_use_direct_blit) {
842 size_t bytes_per_row = expected_dst_bytes_per_pixel *
846 size_t bytes_per_image = bytes_per_row * extent[1];
851 bytes_per_row = blocks_x * block_size;
852 bytes_per_image = bytes_per_row * blocks_y;
855 size_t texture_array_relative_offset = 0;
859 for (
int array_slice = base_slice; array_slice < final_slice; array_slice++) {
861 if (array_slice > 0) {
866 [blit_encoder copyFromBuffer:staging_buffer
867 sourceOffset:texture_array_relative_offset
868 sourceBytesPerRow:bytes_per_row
869 sourceBytesPerImage:bytes_per_image
870 sourceSize:MTLSizeMake(extent[0], extent[1], 1)
871 toTexture:texture_handle
872 destinationSlice:array_slice
874 destinationOrigin:MTLOriginMake(offset[0], offset[1], 0)];
876 texture_array_relative_offset += bytes_per_image;
882 id<MTLComputePipelineState> pso = texture_update_2d_get_kernel(
883 compute_specialization_kernel);
884 TextureUpdateParams
params = {mip,
885 {extent[0], extent[1], 1},
886 {offset[0], offset[1], 0},
898 dispatchThreads:MTLSizeMake(
899 extent[0], extent[1], 1)
900 threadsPerThreadgroup:MTLSizeMake(8, 8, 1)];
903 id<MTLComputePipelineState> pso = texture_update_2d_array_get_kernel(
904 compute_specialization_kernel);
905 TextureUpdateParams
params = {mip,
906 {extent[0], extent[1], extent[2]},
907 {offset[0], offset[1], offset[2]},
918 [compute_encoder dispatchThreads:MTLSizeMake(extent[0],
921 threadsPerThreadgroup:MTLSizeMake(4, 4, 4)];
929 if (can_use_direct_blit) {
930 size_t bytes_per_row = expected_dst_bytes_per_pixel *
934 size_t bytes_per_image = bytes_per_row * extent[1];
935 [blit_encoder copyFromBuffer:staging_buffer
937 sourceBytesPerRow:bytes_per_row
938 sourceBytesPerImage:bytes_per_image
939 sourceSize:MTLSizeMake(extent[0], extent[1], extent[2])
940 toTexture:texture_handle
943 destinationOrigin:MTLOriginMake(offset[0], offset[1], offset[2])];
946 id<MTLComputePipelineState> pso = texture_update_3d_get_kernel(
947 compute_specialization_kernel);
948 TextureUpdateParams
params = {mip,
949 {extent[0], extent[1], extent[2]},
950 {offset[0], offset[1], offset[2]},
962 dispatchThreads:MTLSizeMake(
963 extent[0], extent[1], extent[2])
964 threadsPerThreadgroup:MTLSizeMake(4, 4, 4)];
970 if (can_use_direct_blit) {
971 size_t bytes_per_row = expected_dst_bytes_per_pixel *
975 size_t bytes_per_image = bytes_per_row * extent[1];
976 size_t texture_array_relative_offset = 0;
979 for (
int i = 0; i < extent[2]; i++) {
980 int face_index = offset[2] + i;
982 [blit_encoder copyFromBuffer:staging_buffer
983 sourceOffset:texture_array_relative_offset
984 sourceBytesPerRow:bytes_per_row
985 sourceBytesPerImage:bytes_per_image
986 sourceSize:MTLSizeMake(extent[0], extent[1], 1)
987 toTexture:texture_handle
988 destinationSlice:face_index
990 destinationOrigin:MTLOriginMake(offset[0], offset[1], 0)];
991 texture_array_relative_offset += bytes_per_image;
996 "TODO(Metal): Support compute texture update for GPU_TEXTURE_CUBE %d, %d, %d\n",
1004 if (can_use_direct_blit) {
1006 size_t bytes_per_row = expected_dst_bytes_per_pixel *
1010 size_t bytes_per_image = bytes_per_row * extent[1];
1013 size_t texture_array_relative_offset = 0;
1014 for (
int i = 0; i < extent[2]; i++) {
1015 int face_index = offset[2] + i;
1016 [blit_encoder copyFromBuffer:staging_buffer
1017 sourceOffset:texture_array_relative_offset
1018 sourceBytesPerRow:bytes_per_row
1019 sourceBytesPerImage:bytes_per_image
1020 sourceSize:MTLSizeMake(extent[0], extent[1], 1)
1021 toTexture:texture_handle
1022 destinationSlice:face_index
1023 destinationLevel:mip
1024 destinationOrigin:MTLOriginMake(offset[0], offset[1], 0)];
1025 texture_array_relative_offset += bytes_per_image;
1030 "TODO(Metal): Support compute texture update for GPU_TEXTURE_CUBE_ARRAY %d, %d, "
1050 if (use_staging_texture) {
1062 for (
int array_index = base_slice; array_index < final_slice; array_index++) {
1063 [blit_encoder copyFromTexture:staging_texture
1064 sourceSlice:array_index
1066 sourceOrigin:MTLOriginMake(offset[0], 0, 0)
1067 sourceSize:MTLSizeMake(extent[0], 1, 1)
1069 destinationSlice:array_index
1070 destinationLevel:mip
1071 destinationOrigin:MTLOriginMake(offset[0], 0, 0)];
1078 for (
int array_index = base_slice; array_index < final_slice; array_index++) {
1079 [blit_encoder copyFromTexture:staging_texture
1080 sourceSlice:array_index
1082 sourceOrigin:MTLOriginMake(offset[0], offset[1], 0)
1083 sourceSize:MTLSizeMake(extent[0], extent[1], 1)
1085 destinationSlice:array_index
1086 destinationLevel:mip
1087 destinationOrigin:MTLOriginMake(offset[0], offset[1], 0)];
1091 [blit_encoder copyFromTexture:staging_texture
1094 sourceOrigin:MTLOriginMake(offset[0], offset[1], offset[2])
1095 sourceSize:MTLSizeMake(extent[0], extent[1], extent[2])
1098 destinationLevel:mip
1099 destinationOrigin:MTLOriginMake(offset[0], offset[1], offset[2])];
1104 for (
int i = 0; i < extent[2]; i++) {
1105 int face_index = offset[2] + i;
1106 [blit_encoder copyFromTexture:staging_texture
1107 sourceSlice:face_index
1109 sourceOrigin:MTLOriginMake(offset[0], offset[1], 0)
1110 sourceSize:MTLSizeMake(extent[0], extent[1], 1)
1112 destinationSlice:face_index
1113 destinationLevel:mip
1114 destinationOrigin:MTLOriginMake(offset[0], offset[1], 0)];
1123 [staging_texture release];
1127 if (can_use_direct_blit) {
1130 if (texture_.storageMode == MTLStorageModeManaged) {
1131 [blit_encoder synchronizeResource:texture_];
1133 [blit_encoder optimizeContentsForGPUAccess:texture_];
1139 if (texture_.storageMode == MTLStorageModeManaged) {
1141 [blit_encoder synchronizeResource:texture_];
1143 [blit_encoder optimizeContentsForGPUAccess:texture_];
1147 [texture_handle release];
1154 temp_allocation->
free();
1161 GPUPixelBuffer *pixbuf)
1171 if (buffer == nil) {
1176 this->ensure_baked();
1183 size_t bytes_per_row = bits_per_pixel * extent[0];
1184 size_t bytes_per_image = bytes_per_row * extent[1];
1194 [blit_encoder copyFromBuffer:buffer
1196 sourceBytesPerRow:bytes_per_row
1197 sourceBytesPerImage:bytes_per_image
1198 sourceSize:MTLSizeMake(extent[0], extent[1], 1)
1202 destinationOrigin:MTLOriginMake(offset[0], offset[1], 0)];
1204 if (texture_.storageMode == MTLStorageModeManaged) {
1205 [blit_encoder synchronizeResource:texture_];
1207 [blit_encoder optimizeContentsForGPUAccess:texture_];
1214void gpu::MTLTexture::ensure_mipmaps(
int miplvl)
1218 BLI_assert(resource_mode_ != MTL_TEXTURE_MODE_TEXTURE_VIEW);
1223 int max_dimension =
max_iii(w_, effective_h, effective_d);
1224 int max_miplvl =
floor(log2(max_dimension));
1225 miplvl =
min_ii(max_miplvl, miplvl);
1228 if (mipmaps_ < miplvl) {
1232 if (is_baked_ && mipmaps_ > mtl_max_mips_) {
1234 "Texture requires a higher mipmap level count. Please specify the required "
1237 MTL_LOG_WARNING(
"Texture requires regenerating due to increase in mip-count");
1240 this->mip_range_set(0, mipmaps_);
1256 MTL_LOG_ERROR(
"Cannot Generate mip-maps -- metal device invalid\n");
1262 this->ensure_mipmaps(mtl_max_mips_);
1265 this->ensure_baked();
1266 BLI_assert_msg(is_baked_ && texture_,
"MTLTexture is not valid");
1268 if (mipmaps_ == 1 || mtl_max_mips_ == 1) {
1269 MTL_LOG_WARNING(
"Call to generate mipmaps on texture with 'mipmaps_=1'");
1278 MTL_LOG_WARNING(
"Cannot generate mipmaps for textures using DEPTH formats");
1287 [enc insertDebugSignpost:
@"Generate MipMaps"];
1289 [enc generateMipmapsForTexture:texture_];
1290 has_generated_mips_ =
true;
1301 (mt_dst->
d_ == mt_src->
d_));
1312 this->ensure_baked();
1324 int extent[3] = {1, 1, 1};
1325 this->mip_size_get(mip, extent);
1327 switch (mt_dst->
type_) {
1333 [blit_encoder copyFromTexture:this->get_metal_handle_base()
1334 toTexture:mt_dst->get_metal_handle_base()];
1335 [blit_encoder optimizeContentsForGPUAccess:mt_dst->get_metal_handle_base()];
1339 this->blit(blit_encoder,
1362 this->ensure_baked();
1365 bool do_render_pass_clear =
true;
1367 do_render_pass_clear =
false;
1371 if (backing_buffer_ !=
nullptr) {
1373 bool fast_buf_clear_to_zero =
true;
1374 const uint *val =
reinterpret_cast<const uint *
>(
data);
1375 for (
int i = 0; i < num_channels; i++) {
1376 fast_buf_clear_to_zero = fast_buf_clear_to_zero && (val[i] == 0);
1378 if (fast_buf_clear_to_zero) {
1384 id<MTLBlitCommandEncoder> blit_encoder =
1386 [blit_encoder fillBuffer:backing_buffer_->get_metal_buffer()
1387 range:NSMakeRange(0, backing_buffer_->get_size())
1391 BLI_assert_msg(
false,
"Non-zero buffer-backed texture clear not supported!");
1396 if (do_render_pass_clear) {
1401 fb->clear_attachment(this->attachment_type(0), data_format, data);
1424 id<MTLTexture> texture_handle = texture_;
1427 id<MTLComputeCommandEncoder> compute_encoder =
1433 id<MTLComputePipelineState> pso = texture_update_1d_get_kernel(
1434 compute_specialization_kernel);
1435 TextureUpdateParams
params = {0,
1448 [compute_encoder dispatchThreads:MTLSizeMake(w_, 1, 1)
1449 threadsPerThreadgroup:MTLSizeMake(64, 1, 1)];
1452 id<MTLComputePipelineState> pso = texture_update_1d_array_get_kernel(
1453 compute_specialization_kernel);
1454 TextureUpdateParams
params = {0,
1467 [compute_encoder dispatchThreads:MTLSizeMake(w_, h_, 1)
1468 threadsPerThreadgroup:MTLSizeMake(8, 8, 1)];
1472 "gpu::MTLTexture::clear requires compute pass for texture"
1473 "type: %d, but this is not yet supported",
1481 if (texture_.storageMode == MTLStorageModeManaged) {
1482 [blit_encoder synchronizeResource:texture_];
1484 [blit_encoder optimizeContentsForGPUAccess:texture_];
1493 return MTLTextureSwizzleRed;
1496 return MTLTextureSwizzleGreen;
1499 return MTLTextureSwizzleBlue;
1502 return MTLTextureSwizzleAlpha;
1504 return MTLTextureSwizzleZero;
1506 return MTLTextureSwizzleOne;
1512 if (memcmp(tex_swizzle_mask_, swizzle_mask, 4) != 0) {
1513 memcpy(tex_swizzle_mask_, swizzle_mask, 4);
1516 MTLTextureSwizzleChannels new_swizzle_mask = MTLTextureSwizzleChannelsMake(
1522 mtl_swizzle_mask_ = new_swizzle_mask;
1523 texture_view_dirty_flags_ |= TEXTURE_VIEW_SWIZZLE_DIRTY;
1548 " MTLTexture of type TEXTURE_1D_ARRAY or TEXTURE_BUFFER cannot have a mipcount "
1549 "greater than 1\n");
1557 mip_texture_base_level_ = mip_min_;
1558 mip_texture_max_level_ = mip_max_;
1559 texture_view_dirty_flags_ |= TEXTURE_VIEW_MIP_DIRTY;
1570 int extent[3] = {1, 1, 1};
1571 this->mip_size_get(mip, extent);
1573 size_t sample_len = extent[0] *
max_ii(extent[1], 1) *
max_ii(extent[2], 1);
1575 size_t texture_size = sample_len * sample_size;
1578 void *data =
MEM_mallocN(texture_size + 8,
"GPU_texture_read");
1582 this->read_internal(
1583 mip, 0, 0, 0, extent[0], extent[1], extent[2], type, num_channels, texture_size + 8, data);
1587 MTL_LOG_WARNING(
"MTLTexture::read - reading from texture with no image data");
1594void gpu::MTLTexture::read_internal(
int mip,
1602 int num_output_components,
1603 size_t debug_data_size,
1608 MTL_LOG_WARNING(
"gpu::MTLTexture::read_internal - Trying to read from a non-baked texture!");
1617 BLI_assert(num_output_components <= num_channels);
1618 size_t desired_output_bpp = num_output_components *
to_bytesize(desired_output_format);
1627 bool format_conversion_needed = (data_format != desired_output_format);
1628 bool can_use_simple_read = (desired_output_bpp == image_bpp) && (!format_conversion_needed) &&
1629 (num_output_components == image_components);
1633 if (is_depth_format) {
1634 can_use_simple_read =
false;
1636 image_components = 1;
1652 image_bpp =
sizeof(
int);
1653 image_components = 1;
1654 desired_output_bpp =
sizeof(
int);
1655 num_output_components = 1;
1658 format_conversion_needed =
false;
1659 can_use_simple_read =
true;
1663 size_t bytes_per_row = desired_output_bpp * width;
1664 size_t bytes_per_image = bytes_per_row * height;
1665 size_t total_bytes = bytes_per_image *
max_ii(depth, 1);
1667 if (can_use_simple_read) {
1671 ((num_output_components *
to_bytesize(desired_output_format)) == desired_output_bpp) &&
1672 (desired_output_bpp == image_bpp));
1680 total_bytes, 256,
true);
1683 id<MTLBuffer> destination_buffer = dest_buf->get_metal_buffer();
1685 void *destination_buffer_host_ptr = dest_buf->get_host_ptr();
1686 BLI_assert(destination_buffer_host_ptr !=
nullptr);
1689 int depth_format_mode = 0;
1690 if (is_depth_format) {
1691 depth_format_mode = 1;
1692 switch (desired_output_format) {
1694 depth_format_mode = 1;
1697 depth_format_mode = 2;
1700 depth_format_mode = 4;
1712 num_output_components,
1715 bool copy_successful =
false;
1723 id<MTLTexture> read_texture = texture_;
1725 if (resource_mode_ == MTL_TEXTURE_MODE_TEXTURE_VIEW) {
1726 read_texture = this->get_metal_handle();
1731 read_texture = [read_texture newTextureViewWithPixelFormat:MTLPixelFormatRGBA8Unorm];
1737 if (can_use_simple_read) {
1739 id<MTLBlitCommandEncoder> enc = ctx->main_command_buffer.ensure_begin_blit_encoder();
1741 [enc insertDebugSignpost:
@"GPUTextureRead1D"];
1743 [enc copyFromTexture:read_texture
1746 sourceOrigin:MTLOriginMake(x_off, 0, 0)
1747 sourceSize:MTLSizeMake(width, 1, 1)
1748 toBuffer:destination_buffer
1750 destinationBytesPerRow:bytes_per_row
1751 destinationBytesPerImage:bytes_per_image];
1752 copy_successful =
true;
1757 id<MTLComputeCommandEncoder> compute_encoder =
1758 ctx->main_command_buffer.ensure_begin_compute_encoder();
1759 id<MTLComputePipelineState> pso = texture_read_1d_get_kernel(
1760 compute_specialization_kernel);
1761 TextureReadParams
params = {
1768 MTLComputeState &cs = ctx->main_command_buffer.get_compute_state();
1771 cs.bind_compute_buffer(destination_buffer, 0, 1);
1772 cs.bind_compute_texture(read_texture, 0);
1773 [compute_encoder dispatchThreads:MTLSizeMake(width, 1, 1)
1774 threadsPerThreadgroup:MTLSizeMake(8, 8, 1)];
1775 copy_successful =
true;
1780 if (can_use_simple_read) {
1782 id<MTLBlitCommandEncoder> enc = ctx->main_command_buffer.ensure_begin_blit_encoder();
1784 [enc insertDebugSignpost:
@"GPUTextureRead1DArray"];
1787 int base_slice = y_off;
1788 int final_slice = base_slice + height;
1789 size_t texture_array_relative_offset = 0;
1791 for (
int array_slice = base_slice; array_slice < final_slice; array_slice++) {
1792 [enc copyFromTexture:read_texture
1793 sourceSlice:base_slice
1795 sourceOrigin:MTLOriginMake(x_off, 0, 0)
1796 sourceSize:MTLSizeMake(width, 1, 1)
1797 toBuffer:destination_buffer
1798 destinationOffset:texture_array_relative_offset
1799 destinationBytesPerRow:bytes_per_row
1800 destinationBytesPerImage:bytes_per_row];
1801 texture_array_relative_offset += bytes_per_row;
1803 copy_successful =
true;
1807 id<MTLComputeCommandEncoder> compute_encoder =
1808 ctx->main_command_buffer.ensure_begin_compute_encoder();
1809 id<MTLComputePipelineState> pso = texture_read_1d_array_get_kernel(
1810 compute_specialization_kernel);
1811 TextureReadParams
params = {
1818 MTLComputeState &cs = ctx->main_command_buffer.get_compute_state();
1821 cs.bind_compute_buffer(destination_buffer, 0, 1);
1822 cs.bind_compute_texture(read_texture, 0);
1823 [compute_encoder dispatchThreads:MTLSizeMake(width, height, 1)
1824 threadsPerThreadgroup:MTLSizeMake(8, 8, 1)];
1825 copy_successful =
true;
1830 if (can_use_simple_read) {
1832 id<MTLBlitCommandEncoder> enc = ctx->main_command_buffer.ensure_begin_blit_encoder();
1834 [enc insertDebugSignpost:
@"GPUTextureRead2D"];
1836 [enc copyFromTexture:read_texture
1839 sourceOrigin:MTLOriginMake(x_off, y_off, 0)
1840 sourceSize:MTLSizeMake(width, height, 1)
1841 toBuffer:destination_buffer
1843 destinationBytesPerRow:bytes_per_row
1844 destinationBytesPerImage:bytes_per_image];
1845 copy_successful =
true;
1850 id<MTLComputeCommandEncoder> compute_encoder =
1851 ctx->main_command_buffer.ensure_begin_compute_encoder();
1852 id<MTLComputePipelineState> pso = texture_read_2d_get_kernel(
1853 compute_specialization_kernel);
1854 TextureReadParams
params = {
1861 MTLComputeState &cs = ctx->main_command_buffer.get_compute_state();
1864 cs.bind_compute_buffer(destination_buffer, 0, 1);
1865 cs.bind_compute_texture(read_texture, 0);
1866 [compute_encoder dispatchThreads:MTLSizeMake(width, height, 1)
1867 threadsPerThreadgroup:MTLSizeMake(8, 8, 1)];
1868 copy_successful =
true;
1873 if (can_use_simple_read) {
1875 id<MTLBlitCommandEncoder> enc = ctx->main_command_buffer.ensure_begin_blit_encoder();
1877 [enc insertDebugSignpost:
@"GPUTextureRead2DArray"];
1879 int base_slice = z_off;
1880 int final_slice = base_slice + depth;
1881 size_t texture_array_relative_offset = 0;
1883 for (
int array_slice = base_slice; array_slice < final_slice; array_slice++) {
1884 [enc copyFromTexture:read_texture
1885 sourceSlice:array_slice
1887 sourceOrigin:MTLOriginMake(x_off, y_off, 0)
1888 sourceSize:MTLSizeMake(width, height, 1)
1889 toBuffer:destination_buffer
1890 destinationOffset:texture_array_relative_offset
1891 destinationBytesPerRow:bytes_per_row
1892 destinationBytesPerImage:bytes_per_image];
1893 texture_array_relative_offset += bytes_per_image;
1895 copy_successful =
true;
1900 id<MTLComputeCommandEncoder> compute_encoder =
1901 ctx->main_command_buffer.ensure_begin_compute_encoder();
1902 id<MTLComputePipelineState> pso = texture_read_2d_array_get_kernel(
1903 compute_specialization_kernel);
1904 TextureReadParams
params = {
1906 {width, height, depth},
1907 {x_off, y_off, z_off},
1911 MTLComputeState &cs = ctx->main_command_buffer.get_compute_state();
1914 cs.bind_compute_buffer(destination_buffer, 0, 1);
1915 cs.bind_compute_texture(read_texture, 0);
1917 dispatchThreads:MTLSizeMake(width, height, depth)
1918 threadsPerThreadgroup:MTLSizeMake(8, 8, 1)];
1919 copy_successful =
true;
1924 if (can_use_simple_read) {
1926 id<MTLBlitCommandEncoder> enc = ctx->main_command_buffer.ensure_begin_blit_encoder();
1928 [enc insertDebugSignpost:
@"GPUTextureRead3D"];
1930 [enc copyFromTexture:read_texture
1933 sourceOrigin:MTLOriginMake(x_off, y_off, z_off)
1934 sourceSize:MTLSizeMake(width, height, depth)
1935 toBuffer:destination_buffer
1937 destinationBytesPerRow:bytes_per_row
1938 destinationBytesPerImage:bytes_per_image];
1939 copy_successful =
true;
1944 id<MTLComputeCommandEncoder> compute_encoder =
1945 ctx->main_command_buffer.ensure_begin_compute_encoder();
1946 id<MTLComputePipelineState> pso = texture_read_3d_get_kernel(
1947 compute_specialization_kernel);
1948 TextureReadParams
params = {
1950 {width, height, depth},
1951 {x_off, y_off, z_off},
1955 MTLComputeState &cs = ctx->main_command_buffer.get_compute_state();
1958 cs.bind_compute_buffer(destination_buffer, 0, 1);
1959 cs.bind_compute_texture(read_texture, 0);
1961 dispatchThreads:MTLSizeMake(width, height, depth)
1962 threadsPerThreadgroup:MTLSizeMake(4, 4, 4)];
1963 copy_successful =
true;
1970 "z_off > 0 is only supported by TEXTURE CUBE ARRAY reads.");
1972 "depth > 6 is only supported by TEXTURE CUBE ARRAY reads. ");
1973 if (can_use_simple_read) {
1974 id<MTLBlitCommandEncoder> enc = ctx->main_command_buffer.ensure_begin_blit_encoder();
1976 [enc insertDebugSignpost:
@"GPUTextureReadCubeArray"];
1980 int base_slice = z_off;
1981 int final_slice = base_slice + depth;
1982 size_t texture_array_relative_offset = 0;
1984 for (
int array_slice = base_slice; array_slice < final_slice; array_slice++) {
1985 [enc copyFromTexture:read_texture
1986 sourceSlice:array_slice
1988 sourceOrigin:MTLOriginMake(x_off, y_off, 0)
1989 sourceSize:MTLSizeMake(width, height, 1)
1990 toBuffer:destination_buffer
1991 destinationOffset:texture_array_relative_offset
1992 destinationBytesPerRow:bytes_per_row
1993 destinationBytesPerImage:bytes_per_image];
1995 texture_array_relative_offset += bytes_per_image;
1998 copy_successful =
true;
2001 MTL_LOG_ERROR(
"TODO(Metal): unsupported compute copy of texture cube array");
2007 "gpu::MTLTexture::read_internal simple-copy not yet supported for texture "
2013 if (copy_successful) {
2016 if (dest_buf->get_resource_options() == MTLResourceStorageModeManaged) {
2017 id<MTLBlitCommandEncoder> enc = ctx->main_command_buffer.ensure_begin_blit_encoder();
2019 [enc insertDebugSignpost:
@"GPUTextureRead-syncResource"];
2021 [enc synchronizeResource:destination_buffer];
2028 memcpy(r_data, destination_buffer_host_ptr, total_bytes);
2029 MTL_LOG_INFO(
"gpu::MTLTexture::read_internal success! %lu bytes read", total_bytes);
2033 "gpu::MTLTexture::read_internal not yet supported for this config -- data "
2034 "format different (src %lu bytes, dst %lu bytes) (src format: %d, dst format: %d), or "
2035 "varying component counts (src %d, dst %d)",
2039 (
int)desired_output_format,
2041 num_output_components);
2057 this->prepare_internal();
2061 if ((type_ ==
GPU_TEXTURE_3D) && (w_ > limit || h_ > limit || d_ > limit)) {
2072 this->mip_range_set(0, 0);
2080 id<MTLBuffer> source_buffer = mtl_vbo->get_metal_buffer();
2092 size_t bytes_per_row = bytes_per_pixel * w_;
2096 [mtl_ctx->
device minimumLinearTextureAlignmentForPixelFormat:mtl_format]);
2100 if (
format->stride > bytes_per_pixel &&
format->attr_len > 1) {
2106 if (bytes_per_pixel *
format->attr_len !=
format->stride) {
2108 "Cannot split attributes across multiple pixels as attribute format sizes do "
2115 bytes_per_row *=
format->attr_len;
2120 BLI_assert(bytes_per_row == bytes_per_pixel * w_);
2122 "Image should contain one pixel for each attribute in every vertex.");
2127 "Pixel format stride MUST match the texture format stride -- These being different "
2128 "is likely caused by Metal's VBO padding to a minimum of 4-bytes per-vertex."
2129 " If multiple attributes are used. Each attribute is to be packed into its own "
2130 "individual pixel when stride length is exceeded. ");
2135 texture_descriptor_ = [[MTLTextureDescriptor alloc]
init];
2136 texture_descriptor_.pixelFormat = mtl_format;
2137 texture_descriptor_.textureType = MTLTextureTypeTextureBuffer;
2138 texture_descriptor_.width = w_;
2139 texture_descriptor_.height = 1;
2140 texture_descriptor_.depth = 1;
2141 texture_descriptor_.arrayLength = 1;
2142 texture_descriptor_.mipmapLevelCount = mtl_max_mips_;
2143 texture_descriptor_.usage =
2144 MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite |
2145 MTLTextureUsagePixelFormatView;
2146 texture_descriptor_.storageMode = [source_buffer storageMode];
2147 texture_descriptor_.sampleCount = 1;
2148 texture_descriptor_.cpuCacheMode = [source_buffer cpuCacheMode];
2149 texture_descriptor_.hazardTrackingMode = [source_buffer hazardTrackingMode];
2151 texture_ = [source_buffer
2152 newTextureWithDescriptor:texture_descriptor_
2155 aligned_w_ = bytes_per_row / bytes_per_pixel;
2158 texture_.label = [NSString stringWithUTF8String:this->get_name()];
2161 resource_mode_ = MTL_TEXTURE_MODE_VBO;
2164 vert_buffer_ = mtl_vbo;
2165 vert_buffer_mtl_ = source_buffer;
2178 this->prepare_internal();
2181 resource_mode_ = MTL_TEXTURE_MODE_TEXTURE_VIEW;
2182 source_texture_ = src;
2183 mip_texture_base_level_ = mip_offset;
2184 mip_texture_base_layer_ = layer_offset;
2185 texture_view_dirty_flags_ |= TEXTURE_VIEW_MIP_DIRTY;
2192 mtltex->ensure_baked();
2193 texture_ = mtltex->texture_;
2202 texture_view_stencil_ =
false;
2205 texture_view_stencil_ =
true;
2209 bake_mip_swizzle_view();
2225void gpu::MTLTexture::prepare_internal()
2229 internal_gpu_image_usage_flags_ = gpu_image_usage_flags_;
2252 mtl_max_mips_ = mipmaps_;
2256void gpu::MTLTexture::ensure_baked()
2260 id<MTLTexture> previous_texture = nil;
2261 bool copy_previous_contents =
false;
2263 if (is_baked_ && is_dirty_) {
2264 copy_previous_contents =
true;
2265 previous_texture = texture_;
2266 [previous_texture retain];
2275 BLI_assert(resource_mode_ != MTL_TEXTURE_MODE_EXTERNAL);
2276 BLI_assert(resource_mode_ != MTL_TEXTURE_MODE_TEXTURE_VIEW);
2277 BLI_assert(resource_mode_ != MTL_TEXTURE_MODE_VBO);
2296 texture_descriptor_ = [[MTLTextureDescriptor alloc]
init];
2297 texture_descriptor_.pixelFormat = mtl_format;
2300 texture_descriptor_.width = w_;
2301 texture_descriptor_.height = 1;
2302 texture_descriptor_.depth = 1;
2304 texture_descriptor_.mipmapLevelCount = (mtl_max_mips_ > 0) ? mtl_max_mips_ : 1;
2306 texture_descriptor_.storageMode = MTLStorageModePrivate;
2307 texture_descriptor_.sampleCount = 1;
2308 texture_descriptor_.cpuCacheMode = MTLCPUCacheModeDefaultCache;
2309 texture_descriptor_.hazardTrackingMode = MTLHazardTrackingModeDefault;
2316 texture_descriptor_ = [[MTLTextureDescriptor alloc]
init];
2317 texture_descriptor_.pixelFormat = mtl_format;
2320 texture_descriptor_.width = w_;
2321 texture_descriptor_.height = h_;
2322 texture_descriptor_.depth = 1;
2324 texture_descriptor_.mipmapLevelCount = (mtl_max_mips_ > 0) ? mtl_max_mips_ : 1;
2326 texture_descriptor_.storageMode = MTLStorageModePrivate;
2327 texture_descriptor_.sampleCount = 1;
2328 texture_descriptor_.cpuCacheMode = MTLCPUCacheModeDefaultCache;
2329 texture_descriptor_.hazardTrackingMode = MTLHazardTrackingModeDefault;
2335 texture_descriptor_ = [[MTLTextureDescriptor alloc]
init];
2336 texture_descriptor_.pixelFormat = mtl_format;
2337 texture_descriptor_.textureType = MTLTextureType3D;
2338 texture_descriptor_.width = w_;
2339 texture_descriptor_.height = h_;
2340 texture_descriptor_.depth = d_;
2341 texture_descriptor_.arrayLength = 1;
2342 texture_descriptor_.mipmapLevelCount = (mtl_max_mips_ > 0) ? mtl_max_mips_ : 1;
2344 texture_descriptor_.storageMode = MTLStorageModePrivate;
2345 texture_descriptor_.sampleCount = 1;
2346 texture_descriptor_.cpuCacheMode = MTLCPUCacheModeDefaultCache;
2347 texture_descriptor_.hazardTrackingMode = MTLHazardTrackingModeDefault;
2356 texture_descriptor_ = [[MTLTextureDescriptor alloc]
init];
2357 texture_descriptor_.pixelFormat = mtl_format;
2359 MTLTextureTypeCubeArray :
2361 texture_descriptor_.width = w_;
2362 texture_descriptor_.height = h_;
2363 texture_descriptor_.depth = 1;
2365 texture_descriptor_.mipmapLevelCount = (mtl_max_mips_ > 0) ? mtl_max_mips_ : 1;
2367 texture_descriptor_.storageMode = MTLStorageModePrivate;
2368 texture_descriptor_.sampleCount = 1;
2369 texture_descriptor_.cpuCacheMode = MTLCPUCacheModeDefaultCache;
2370 texture_descriptor_.hazardTrackingMode = MTLHazardTrackingModeDefault;
2375 texture_descriptor_ = [[MTLTextureDescriptor alloc]
init];
2376 texture_descriptor_.pixelFormat = mtl_format;
2377 texture_descriptor_.textureType = MTLTextureTypeTextureBuffer;
2378 texture_descriptor_.width = w_;
2379 texture_descriptor_.height = 1;
2380 texture_descriptor_.depth = 1;
2381 texture_descriptor_.arrayLength = 1;
2382 texture_descriptor_.mipmapLevelCount = (mtl_max_mips_ > 0) ? mtl_max_mips_ : 1;
2384 texture_descriptor_.storageMode = MTLStorageModePrivate;
2385 texture_descriptor_.sampleCount = 1;
2386 texture_descriptor_.cpuCacheMode = MTLCPUCacheModeDefaultCache;
2387 texture_descriptor_.hazardTrackingMode = MTLHazardTrackingModeDefault;
2391 MTL_LOG_ERROR(
"[METAL] Error: Cannot create texture with unknown type: %d\n", type_);
2397 resource_mode_ = MTL_TEXTURE_MODE_DEFAULT;
2403 if (is_tile_based_arch) {
2404 texture_descriptor_.storageMode = MTLStorageModeMemoryless;
2417 "Texture atomic fallback support is only available for GPU_TEXTURE_2D, "
2418 "GPU_TEXTURE_2D_ARRAY and GPU_TEXTURE_3D.");
2427 const uint max_width = 16384;
2428 const uint max_height = 16384;
2429 const uint pixels_res = w_ * h_ * d_;
2431 uint new_w = 0, new_h = 0;
2432 if (pixels_res <= max_width) {
2438 new_h = ((pixels_res % new_w) == 0) ? (pixels_res / new_w) : ((pixels_res / new_w) + 1);
2441 texture_descriptor_.width = new_w;
2442 texture_descriptor_.height = new_h;
2446 texture_descriptor_.height <= max_height,
2447 "Atomic fallback support texture is too large.");
2452 size_t bytes_per_row = bytes_per_pixel * texture_descriptor_.width;
2453 size_t total_bytes = bytes_per_row * texture_descriptor_.height;
2460 texture_descriptor_.textureType = MTLTextureType2D;
2461 texture_descriptor_.depth = 1;
2462 texture_descriptor_.arrayLength = 1;
2466 tex_buffer_metadata_[0] = w_;
2467 tex_buffer_metadata_[1] = h_;
2468 tex_buffer_metadata_[2] = d_;
2473 [ctx->device minimumLinearTextureAlignmentForPixelFormat:mtl_format]);
2475 texture_ = [backing_buffer_->get_metal_buffer()
2476 newTextureWithDescriptor:texture_descriptor_
2478 bytesPerRow:aligned_bytes_per_row];
2480 tex_buffer_metadata_[3] = bytes_per_row / bytes_per_pixel;
2483 texture_.label = [NSString
2484 stringWithFormat:
@"AtomicBufferBackedTexture_%s", this->
get_name()];
2490 texture_ = [ctx->device newTextureWithDescriptor:texture_descriptor_];
2494 texture_.label = [NSString stringWithFormat:
@"MemorylessTexture_%s", this->
get_name()];
2497 texture_.label = [NSString stringWithFormat:
@"Texture_%s", this->
get_name()];
2508 if (copy_previous_contents) {
2510 [previous_texture release];
2514void gpu::MTLTexture::reset()
2518 if (texture_ != nil) {
2526 if (backing_buffer_ !=
nullptr) {
2527 backing_buffer_->free();
2528 backing_buffer_ =
nullptr;
2532 if (storage_buffer_ !=
nullptr) {
2533 delete storage_buffer_;
2534 storage_buffer_ =
nullptr;
2537 if (texture_no_srgb_ != nil) {
2538 [texture_no_srgb_ release];
2539 texture_no_srgb_ = nil;
2542 if (mip_swizzle_view_ != nil) {
2543 [mip_swizzle_view_ release];
2544 mip_swizzle_view_ = nil;
2554 if (texture_descriptor_ !=
nullptr) {
2555 [texture_descriptor_ release];
2556 texture_descriptor_ =
nullptr;
2560 has_generated_mips_ =
false;
2574 backing_buffer_ !=
nullptr,
2575 "Resource must have been created as a buffer backed resource to support SSBO wrapping.");
2577 this->ensure_baked();
2578 if (storage_buffer_ == nil) {
2580 id<MTLBuffer> backing_buffer = [texture_ buffer];
2582 storage_buffer_ =
new MTLStorageBuf(
this, [backing_buffer length]);
2584 return storage_buffer_;
2596id<MTLTexture> MTLTexture::get_non_srgb_handle()
2598 id<MTLTexture> base_tex = get_metal_handle_base();
2600 if (texture_no_srgb_ == nil) {
2601 texture_no_srgb_ = [base_tex newTextureViewWithPixelFormat:MTLPixelFormatRGBA8Unorm];
2603 return texture_no_srgb_;
2634 MTLResourceOptions resource_options = ([ctx->
device hasUnifiedMemory]) ?
2635 MTLResourceStorageModeShared :
2636 MTLResourceStorageModeManaged;
2638 if (buffer_ != nil) {
2639 id<MTLBuffer> new_buffer = [ctx->
device newBufferWithBytes:[buffer_ contents]
2643 buffer_ = new_buffer;
2649 return [buffer_ contents];
2654 if (buffer_ == nil) {
2659 if (buffer_.resourceOptions & MTLResourceStorageModeManaged) {
2660 [buffer_ didModifyRange:NSMakeRange(0,
size_)];
2666 if (buffer_ == nil) {
2670 return reinterpret_cast<int64_t>(buffer_);
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
MINLINE int min_ii(int a, int b)
MINLINE uint divide_ceil_u(uint a, uint b)
MINLINE int max_ii(int a, int b)
MINLINE int max_iii(int a, int b, int c)
MINLINE uint64_t ceil_to_multiple_ul(uint64_t a, uint64_t b)
#define UNUSED_VARS_NDEBUG(...)
GHOST C-API function and type declarations.
#define GPU_batch_texture_bind(batch, name, tex)
void GPU_batch_set_shader(blender::gpu::Batch *batch, GPUShader *shader)
void GPU_batch_draw(blender::gpu::Batch *batch)
blender::gpu::Batch * GPU_batch_preset_quad()
int GPU_max_texture_3d_size()
GPUFrameBuffer * GPU_framebuffer_create(const char *name)
GPUFrameBuffer * GPU_framebuffer_active_get()
void GPU_framebuffer_restore()
#define GPU_ATTACHMENT_NONE
void GPU_framebuffer_bind(GPUFrameBuffer *framebuffer)
#define GPU_framebuffer_ensure_config(_fb,...)
#define GPU_ATTACHMENT_TEXTURE_LAYER_MIP(_texture, _layer, _mip)
void GPU_framebuffer_free(GPUFrameBuffer *framebuffer)
void GPU_shader_uniform_1i(GPUShader *sh, const char *name, int value)
void GPU_shader_uniform_2f(GPUShader *sh, const char *name, float x, float y)
void GPU_face_culling(eGPUFaceCullTest culling)
eGPUFaceCullTest GPU_face_culling_get()
void GPU_blend(eGPUBlend blend)
void GPU_scissor_test(bool enable)
eGPUBlend GPU_blend_get()
void GPU_depth_mask(bool depth)
eGPUDepthTest GPU_depth_test_get()
void GPU_stencil_test(eGPUStencilTest test)
void GPU_stencil_write_mask_set(uint write_mask)
void GPU_stencil_reference_set(uint reference)
eGPUStencilTest GPU_stencil_test_get()
uint GPU_stencil_mask_get()
void GPU_depth_test(eGPUDepthTest test)
bool GPU_depth_mask_get()
@ GPU_DATA_2_10_10_10_REV
@ GPU_TEXTURE_USAGE_SHADER_WRITE
@ GPU_TEXTURE_USAGE_HOST_READ
@ GPU_TEXTURE_USAGE_MEMORYLESS
@ GPU_TEXTURE_USAGE_ATTACHMENT
@ GPU_TEXTURE_USAGE_ATOMIC
@ GPU_TEXTURE_USAGE_FORMAT_VIEW
eGPUTextureUsage GPU_texture_usage(const GPUTexture *texture)
const GPUVertFormat * GPU_vertbuf_get_format(const blender::gpu::VertBuf *verts)
struct GPUShader GPUShader
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
void reset()
clear internal cached data and reset random seed
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
StateManager * state_manager
static MTLCapabilities & get_capabilities()
gpu::MTLBuffer * allocate_with_data(uint64_t size, bool cpu_visible, const void *data=nullptr)
gpu::MTLBuffer * allocate(uint64_t size, bool cpu_visible)
gpu::MTLBuffer * allocate_aligned(uint64_t size, uint alignment, bool cpu_visible)
id< MTLBuffer > get_metal_buffer() const
id< MTLComputeCommandEncoder > ensure_begin_compute_encoder()
MTLComputeState & get_compute_state()
id< MTLBlitCommandEncoder > ensure_begin_blit_encoder()
void bind_compute_bytes(const void *bytes, uint64_t length, uint index)
void bind_compute_texture(id< MTLTexture > tex, uint slot)
void bind_compute_buffer(id< MTLBuffer > buffer, uint64_t buffer_offset, uint index)
void bind_pso(id< MTLComputePipelineState > pso)
static MTLContext * get()
MTLContextGlobalShaderPipelineState pipeline_state
MTLCommandBufferManager main_command_buffer
static MTLBufferPool * get_global_memory_manager()
id< MTLBuffer > get_metal_buffer()
size_t get_size() override
MTLPixelBuffer(size_t size)
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
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
virtual void texture_unbind(Texture *tex)=0
eGPUTextureFormat format_
eGPUTextureUsage gpu_image_usage_flags_
bool init_2D(int w, int h, int layers, int mip_len, eGPUTextureFormat format)
CCL_NAMESPACE_BEGIN struct Options options
DOF_TILES_FLATTEN_GROUP_SIZE coc_tx GPU_R11F_G11F_B10F
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
blender::gpu::Batch * quad
BLI_INLINE float fb(float length, float L)
void *(* MEM_mallocN)(size_t len, const char *str)
MINLINE unsigned long long max_ulul(unsigned long long a, unsigned long long b)
ccl_device_inline float2 floor(const float2 a)
#define MTL_LOG_INFO(info,...)
#define MTL_LOG_WARNING(info,...)
#define MTL_LOG_ERROR(info,...)
std::string get_name(const VolumeGridData &grid)
size_t get_mtl_format_bytesize(MTLPixelFormat tex_format)
static Context * unwrap(GPUContext *ctx)
MTLPixelFormat gpu_texture_format_to_metal(eGPUTextureFormat tex_format)
std::string tex_data_format_to_msl_type_str(eGPUDataFormat type)
size_t to_block_size(eGPUTextureFormat data_type)
static GPUContext * wrap(Context *ctx)
constexpr bool validate_data_format(eGPUTextureFormat tex_format, eGPUDataFormat data_format)
std::string tex_data_format_to_msl_texture_template_type(eGPUDataFormat type)
MTLPixelFormat mtl_format_get_writeable_view_format(MTLPixelFormat format)
static MTLTextureSwizzle swizzle_to_mtl(const char swizzle)
size_t to_bytesize(GPUIndexBufType type)
int get_mtl_format_num_components(MTLPixelFormat tex_format)
eGPUDataFormat to_data_format(eGPUTextureFormat tex_format)
MTLTextureUsage mtl_usage_from_gpu(eGPUTextureUsage usage)
MTLTextureType to_metal_type(eGPUTextureType type)
int to_component_len(eGPUTextureFormat format)
eGPUTextureUsage gpu_usage_from_mtl(MTLTextureUsage mtl_usage)
bool supports_texture_atomics