Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/gpu/metal/mtl_texture.mm')
-rw-r--r--source/blender/gpu/metal/mtl_texture.mm876
1 files changed, 355 insertions, 521 deletions
diff --git a/source/blender/gpu/metal/mtl_texture.mm b/source/blender/gpu/metal/mtl_texture.mm
index ca19d1f9e4b..2b7c2333bff 100644
--- a/source/blender/gpu/metal/mtl_texture.mm
+++ b/source/blender/gpu/metal/mtl_texture.mm
@@ -23,13 +23,6 @@
#include "GHOST_C-api.h"
-/* Debug assistance. */
-/* Capture texture update routine for analysis in XCode GPU Frame Debugger. */
-#define DEBUG_TEXTURE_UPDATE_CAPTURE false
-
-/* Capture texture read routine for analysis in XCode GPU Frame Debugger. */
-#define DEBUG_TEXTURE_READ_CAPTURE false
-
namespace blender::gpu {
/* -------------------------------------------------------------------- */
@@ -41,34 +34,34 @@ void gpu::MTLTexture::mtl_texture_init()
BLI_assert(MTLContext::get() != nullptr);
/* Status. */
- this->is_baked_ = false;
- this->is_dirty_ = false;
- this->resource_mode_ = MTL_TEXTURE_MODE_DEFAULT;
- this->mtl_max_mips_ = 1;
+ is_baked_ = false;
+ is_dirty_ = false;
+ resource_mode_ = MTL_TEXTURE_MODE_DEFAULT;
+ mtl_max_mips_ = 1;
/* Metal properties. */
- this->texture_ = nil;
- this->texture_buffer_ = nil;
- this->mip_swizzle_view_ = nil;
+ texture_ = nil;
+ texture_buffer_ = nil;
+ mip_swizzle_view_ = nil;
/* Binding information. */
- this->is_bound_ = false;
+ is_bound_ = false;
/* VBO. */
- this->vert_buffer_ = nullptr;
- this->vert_buffer_mtl_ = nil;
- this->vert_buffer_offset_ = -1;
+ vert_buffer_ = nullptr;
+ vert_buffer_mtl_ = nil;
+ vert_buffer_offset_ = -1;
/* Default Swizzle. */
- this->tex_swizzle_mask_[0] = 'r';
- this->tex_swizzle_mask_[1] = 'g';
- this->tex_swizzle_mask_[2] = 'b';
- this->tex_swizzle_mask_[3] = 'a';
- this->mtl_swizzle_mask_ = MTLTextureSwizzleChannelsMake(
+ tex_swizzle_mask_[0] = 'r';
+ tex_swizzle_mask_[1] = 'g';
+ tex_swizzle_mask_[2] = 'b';
+ tex_swizzle_mask_[3] = 'a';
+ mtl_swizzle_mask_ = MTLTextureSwizzleChannelsMake(
MTLTextureSwizzleRed, MTLTextureSwizzleGreen, MTLTextureSwizzleBlue, MTLTextureSwizzleAlpha);
/* TODO(Metal): Find a way of specifying texture usage externally. */
- this->gpu_image_usage_flags_ = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
+ gpu_image_usage_flags_ = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
}
gpu::MTLTexture::MTLTexture(const char *name) : Texture(name)
@@ -89,23 +82,23 @@ gpu::MTLTexture::MTLTexture(const char *name,
/* Prep texture from METAL handle. */
BLI_assert(metal_texture != nil);
BLI_assert(type == GPU_TEXTURE_2D);
- this->type_ = type;
+ type_ = type;
init_2D(metal_texture.width, metal_texture.height, 0, 1, format);
/* Assign MTLTexture. */
- this->texture_ = metal_texture;
- [this->texture_ retain];
+ texture_ = metal_texture;
+ [texture_ retain];
/* Flag as Baked. */
- this->is_baked_ = true;
- this->is_dirty_ = false;
- this->resource_mode_ = MTL_TEXTURE_MODE_EXTERNAL;
+ is_baked_ = true;
+ is_dirty_ = false;
+ resource_mode_ = MTL_TEXTURE_MODE_EXTERNAL;
}
gpu::MTLTexture::~MTLTexture()
{
/* Unbind if bound. */
- if (this->is_bound_) {
+ if (is_bound_) {
MTLContext *ctx = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
if (ctx != nullptr) {
ctx->state_manager->texture_unbind(this);
@@ -123,49 +116,49 @@ void gpu::MTLTexture::bake_mip_swizzle_view()
{
if (texture_view_dirty_flags_) {
/* if a texture view was previously created we release it. */
- if (this->mip_swizzle_view_ != nil) {
- [this->mip_swizzle_view_ release];
+ if (mip_swizzle_view_ != nil) {
+ [mip_swizzle_view_ release];
+ mip_swizzle_view_ = nil;
}
/* Determine num slices */
int num_slices = 1;
- switch (this->type_) {
+ switch (type_) {
case GPU_TEXTURE_1D_ARRAY:
- num_slices = this->h_;
+ num_slices = h_;
break;
case GPU_TEXTURE_2D_ARRAY:
- num_slices = this->d_;
+ num_slices = d_;
break;
case GPU_TEXTURE_CUBE:
num_slices = 6;
break;
case GPU_TEXTURE_CUBE_ARRAY:
/* d_ is equal to array levels * 6, including face count. */
- num_slices = this->d_;
+ num_slices = d_;
break;
default:
num_slices = 1;
break;
}
- int range_len = min_ii((this->mip_texture_max_level_ - this->mip_texture_base_level_) + 1,
- this->texture_.mipmapLevelCount);
+ int range_len = min_ii((mip_texture_max_level_ - mip_texture_base_level_) + 1,
+ texture_.mipmapLevelCount);
BLI_assert(range_len > 0);
- BLI_assert(mip_texture_base_level_ < this->texture_.mipmapLevelCount);
- BLI_assert(this->mip_texture_base_layer_ < num_slices);
- this->mip_swizzle_view_ = [this->texture_
- newTextureViewWithPixelFormat:this->texture_.pixelFormat
- textureType:this->texture_.textureType
- levels:NSMakeRange(this->mip_texture_base_level_, range_len)
- slices:NSMakeRange(this->mip_texture_base_layer_, num_slices)
- swizzle:this->mtl_swizzle_mask_];
+ BLI_assert(mip_texture_base_level_ < texture_.mipmapLevelCount);
+ BLI_assert(mip_texture_base_layer_ < num_slices);
+ mip_swizzle_view_ = [texture_
+ newTextureViewWithPixelFormat:texture_.pixelFormat
+ textureType:texture_.textureType
+ levels:NSMakeRange(mip_texture_base_level_, range_len)
+ slices:NSMakeRange(mip_texture_base_layer_, num_slices)
+ swizzle:mtl_swizzle_mask_];
MTL_LOG_INFO(
"Updating texture view - MIP TEXTURE BASE LEVEL: %d, MAX LEVEL: %d (Range len: %d)\n",
- this->mip_texture_base_level_,
- min_ii(this->mip_texture_max_level_, this->texture_.mipmapLevelCount),
+ mip_texture_base_level_,
+ min_ii(mip_texture_max_level_, texture_.mipmapLevelCount),
range_len);
- [this->mip_swizzle_view_ retain];
- this->mip_swizzle_view_.label = [this->texture_ label];
+ mip_swizzle_view_.label = [texture_ label];
texture_view_dirty_flags_ = TEXTURE_VIEW_NOT_DIRTY;
}
}
@@ -180,29 +173,29 @@ id<MTLTexture> gpu::MTLTexture::get_metal_handle()
this->ensure_baked();
/* Verify VBO texture shares same buffer. */
- if (this->resource_mode_ == MTL_TEXTURE_MODE_VBO) {
+ if (resource_mode_ == MTL_TEXTURE_MODE_VBO) {
int r_offset = -1;
/* TODO(Metal): Fetch buffer from MTLVertBuf when implemented. */
id<MTLBuffer> buf = nil; /*vert_buffer_->get_metal_buffer(&r_offset);*/
- BLI_assert(this->vert_buffer_mtl_ != nil);
- BLI_assert(buf == this->vert_buffer_mtl_ && r_offset == this->vert_buffer_offset_);
+ BLI_assert(vert_buffer_mtl_ != nil);
+ BLI_assert(buf == vert_buffer_mtl_ && r_offset == vert_buffer_offset_);
UNUSED_VARS(buf);
UNUSED_VARS_NDEBUG(r_offset);
}
- if (this->is_baked_) {
+ if (is_baked_) {
/* For explicit texture views, ensure we always return the texture view. */
- if (this->resource_mode_ == MTL_TEXTURE_MODE_TEXTURE_VIEW) {
- BLI_assert(this->mip_swizzle_view_ && "Texture view should always have a valid handle.");
+ if (resource_mode_ == MTL_TEXTURE_MODE_TEXTURE_VIEW) {
+ BLI_assert(mip_swizzle_view_ && "Texture view should always have a valid handle.");
}
- if (this->mip_swizzle_view_ != nil || texture_view_dirty_flags_) {
+ if (mip_swizzle_view_ != nil || texture_view_dirty_flags_) {
bake_mip_swizzle_view();
- return this->mip_swizzle_view_;
+ return mip_swizzle_view_;
}
- return this->texture_;
+ return texture_;
}
return nil;
}
@@ -214,36 +207,36 @@ id<MTLTexture> gpu::MTLTexture::get_metal_handle_base()
this->ensure_baked();
/* For explicit texture views, always return the texture view. */
- if (this->resource_mode_ == MTL_TEXTURE_MODE_TEXTURE_VIEW) {
- BLI_assert(this->mip_swizzle_view_ && "Texture view should always have a valid handle.");
- if (this->mip_swizzle_view_ != nil || texture_view_dirty_flags_) {
+ if (resource_mode_ == MTL_TEXTURE_MODE_TEXTURE_VIEW) {
+ BLI_assert(mip_swizzle_view_ && "Texture view should always have a valid handle.");
+ if (mip_swizzle_view_ != nil || texture_view_dirty_flags_) {
bake_mip_swizzle_view();
}
- return this->mip_swizzle_view_;
+ return mip_swizzle_view_;
}
/* Return base handle. */
- if (this->is_baked_) {
- return this->texture_;
+ if (is_baked_) {
+ return texture_;
}
return nil;
}
void gpu::MTLTexture::blit(id<MTLBlitCommandEncoder> blit_encoder,
- unsigned int src_x_offset,
- unsigned int src_y_offset,
- unsigned int src_z_offset,
- unsigned int src_slice,
- unsigned int src_mip,
+ uint src_x_offset,
+ uint src_y_offset,
+ uint src_z_offset,
+ uint src_slice,
+ uint src_mip,
gpu::MTLTexture *dest,
- unsigned int dst_x_offset,
- unsigned int dst_y_offset,
- unsigned int dst_z_offset,
- unsigned int dst_slice,
- unsigned int dst_mip,
- unsigned int width,
- unsigned int height,
- unsigned int depth)
+ uint dst_x_offset,
+ uint dst_y_offset,
+ uint dst_z_offset,
+ uint dst_slice,
+ uint dst_mip,
+ uint width,
+ uint height,
+ uint depth)
{
BLI_assert(this && dest);
@@ -273,13 +266,13 @@ void gpu::MTLTexture::blit(id<MTLBlitCommandEncoder> blit_encoder,
}
void gpu::MTLTexture::blit(gpu::MTLTexture *dst,
- unsigned int src_x_offset,
- unsigned int src_y_offset,
- unsigned int dst_x_offset,
- unsigned int dst_y_offset,
- unsigned int src_mip,
- unsigned int dst_mip,
- unsigned int dst_slice,
+ uint src_x_offset,
+ uint src_y_offset,
+ uint dst_x_offset,
+ uint dst_y_offset,
+ uint src_mip,
+ uint dst_mip,
+ uint dst_slice,
int width,
int height)
{
@@ -348,19 +341,19 @@ void gpu::MTLTexture::blit(gpu::MTLTexture *dst,
}
}
-GPUFrameBuffer *gpu::MTLTexture::get_blit_framebuffer(unsigned int dst_slice, unsigned int dst_mip)
+GPUFrameBuffer *gpu::MTLTexture::get_blit_framebuffer(uint dst_slice, uint dst_mip)
{
/* Check if layer has changed. */
bool update_attachments = false;
- if (!this->blit_fb_) {
- this->blit_fb_ = GPU_framebuffer_create("gpu_blit");
+ if (!blit_fb_) {
+ blit_fb_ = GPU_framebuffer_create("gpu_blit");
update_attachments = true;
}
/* Check if current blit FB has the correct attachment properties. */
- if (this->blit_fb_) {
- if (this->blit_fb_slice_ != dst_slice || this->blit_fb_mip_ != dst_mip) {
+ if (blit_fb_) {
+ if (blit_fb_slice_ != dst_slice || blit_fb_mip_ != dst_mip) {
update_attachments = true;
}
}
@@ -369,7 +362,7 @@ GPUFrameBuffer *gpu::MTLTexture::get_blit_framebuffer(unsigned int dst_slice, un
if (format_flag_ & GPU_FORMAT_DEPTH || format_flag_ & GPU_FORMAT_STENCIL) {
/* DEPTH TEX */
GPU_framebuffer_ensure_config(
- &this->blit_fb_,
+ &blit_fb_,
{GPU_ATTACHMENT_TEXTURE_LAYER_MIP(wrap(static_cast<Texture *>(this)),
static_cast<int>(dst_slice),
static_cast<int>(dst_mip)),
@@ -378,18 +371,18 @@ GPUFrameBuffer *gpu::MTLTexture::get_blit_framebuffer(unsigned int dst_slice, un
else {
/* COLOR TEX */
GPU_framebuffer_ensure_config(
- &this->blit_fb_,
+ &blit_fb_,
{GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE_LAYER_MIP(wrap(static_cast<Texture *>(this)),
static_cast<int>(dst_slice),
static_cast<int>(dst_mip))});
}
- this->blit_fb_slice_ = dst_slice;
- this->blit_fb_mip_ = dst_mip;
+ blit_fb_slice_ = dst_slice;
+ blit_fb_mip_ = dst_mip;
}
- BLI_assert(this->blit_fb_);
- return this->blit_fb_;
+ BLI_assert(blit_fb_);
+ return blit_fb_;
}
MTLSamplerState gpu::MTLTexture::get_sampler_state()
@@ -408,7 +401,7 @@ void gpu::MTLTexture::update_sub(
BLI_assert(ctx);
/* Do not update texture view. */
- BLI_assert(this->resource_mode_ != MTL_TEXTURE_MODE_TEXTURE_VIEW);
+ BLI_assert(resource_mode_ != MTL_TEXTURE_MODE_TEXTURE_VIEW);
/* Ensure mipmaps. */
this->ensure_mipmaps(mip);
@@ -418,16 +411,16 @@ void gpu::MTLTexture::update_sub(
/* Safety checks. */
#if TRUST_NO_ONE
- BLI_assert(mip >= this->mip_min_ && mip <= this->mip_max_);
- BLI_assert(mip < this->texture_.mipmapLevelCount);
- BLI_assert(this->texture_.mipmapLevelCount >= this->mip_max_);
+ BLI_assert(mip >= mip_min_ && mip <= mip_max_);
+ BLI_assert(mip < texture_.mipmapLevelCount);
+ BLI_assert(texture_.mipmapLevelCount >= mip_max_);
#endif
/* DEPTH FLAG - Depth formats cannot use direct BLIT - pass off to their own routine which will
* do a depth-only render. */
- bool is_depth_format = (this->format_flag_ & GPU_FORMAT_DEPTH);
+ bool is_depth_format = (format_flag_ & GPU_FORMAT_DEPTH);
if (is_depth_format) {
- switch (this->type_) {
+ switch (type_) {
case GPU_TEXTURE_2D: {
update_sub_depth_2d(mip, offset, extent, type, data);
@@ -444,7 +437,7 @@ void gpu::MTLTexture::update_sub(
@autoreleasepool {
/* Determine totalsize of INPUT Data. */
- int num_channels = to_component_len(this->format_);
+ int num_channels = to_component_len(format_);
int input_bytes_per_pixel = num_channels * to_bytesize(type);
int totalsize = 0;
@@ -482,29 +475,12 @@ void gpu::MTLTexture::update_sub(
BLI_assert(totalsize > 0);
/* Determine expected destination data size. */
- MTLPixelFormat destination_format = gpu_texture_format_to_metal(this->format_);
+ MTLPixelFormat destination_format = gpu_texture_format_to_metal(format_);
int expected_dst_bytes_per_pixel = get_mtl_format_bytesize(destination_format);
int destination_num_channels = get_mtl_format_num_components(destination_format);
- int destination_totalsize = 0;
- switch (this->dimensions_count()) {
- case 1:
- destination_totalsize = expected_dst_bytes_per_pixel * max_ii(expected_update_w, 1);
- break;
- case 2:
- destination_totalsize = expected_dst_bytes_per_pixel * max_ii(expected_update_w, 1) *
- max_ii(extent[1], 1);
- break;
- case 3:
- destination_totalsize = expected_dst_bytes_per_pixel * max_ii(expected_update_w, 1) *
- max_ii(extent[1], 1) * max_ii(extent[2], 1);
- break;
- default:
- BLI_assert(false);
- break;
- }
- /* Prepare specialisation struct (For texture update routine). */
- TextureUpdateRoutineSpecialisation compute_specialisation_kernel = {
+ /* Prepare specialization struct (For texture update routine). */
+ TextureUpdateRoutineSpecialisation compute_specialization_kernel = {
tex_data_format_to_msl_type_str(type), /* INPUT DATA FORMAT */
tex_data_format_to_msl_texture_template_type(type), /* TEXTURE DATA FORMAT */
num_channels,
@@ -517,21 +493,21 @@ void gpu::MTLTexture::update_sub(
can_use_direct_blit = false;
}
-#if MTL_VALIDATION_CRASH_DEPTH_1_1_1_WA
- if (this->type_ == GPU_TEXTURE_2D || this->type_ == GPU_TEXTURE_2D_ARRAY) {
- /* Workaround for crash in validation layer when blitting to depth2D target with
- * dimensions (1, 1, 1); */
- if (extent[0] == 1 && extent[1] == 1 && extent[2] == 1 && totalsize == 4) {
- can_use_direct_blit = false;
+ if (is_depth_format) {
+ if (type_ == GPU_TEXTURE_2D || type_ == GPU_TEXTURE_2D_ARRAY) {
+ /* Workaround for crash in validation layer when blitting to depth2D target with
+ * dimensions (1, 1, 1); */
+ if (extent[0] == 1 && extent[1] == 1 && extent[2] == 1 && totalsize == 4) {
+ can_use_direct_blit = false;
+ }
}
}
-#endif
- if (this->format_ == GPU_SRGB8_A8 && !can_use_direct_blit) {
+ if (format_ == GPU_SRGB8_A8 && !can_use_direct_blit) {
MTL_LOG_WARNING(
"SRGB data upload does not work correctly using compute upload. "
"texname '%s'\n",
- this->name_);
+ name_);
}
/* Safety Checks. */
@@ -573,49 +549,15 @@ void gpu::MTLTexture::update_sub(
}
}
- /* Debug hook for performing GPU capture of routine. */
- bool DO_CAPTURE = false;
-#if DEBUG_TEXTURE_UPDATE_CAPTURE == 1
- DO_CAPTURE = true;
- if (DO_CAPTURE) {
- MTLCaptureManager *capture_manager = [MTLCaptureManager sharedCaptureManager];
- MTLCaptureDescriptor *capture_descriptor = [[MTLCaptureDescriptor alloc] init];
- capture_descriptor.captureObject = ctx->device;
- NSError *error;
- if (![capture_manager startCaptureWithDescriptor:capture_descriptor error:&error]) {
- NSString *error_str = [NSString stringWithFormat:@"%@", error];
- const char *error_c_str = [error_str UTF8String];
- MTL_LOG_ERROR("Failed to start capture. Error: %s\n", error_c_str);
- }
- }
-#endif
-
- /* Fetch or Create command buffer. */
- id<MTLCommandBuffer> cmd_buffer = ctx->get_active_command_buffer();
- bool own_command_buffer = false;
- if (cmd_buffer == nil || DO_CAPTURE) {
- cmd_buffer = [ctx->queue commandBuffer];
- own_command_buffer = true;
- }
- else {
- /* Finish graphics work. */
- ctx->end_render_pass();
- }
-
/* Prepare staging buffer for data. */
id<MTLBuffer> staging_buffer = nil;
- unsigned long long staging_buffer_offset = 0;
+ uint64_t staging_buffer_offset = 0;
/* Fetch allocation from scratch buffer. */
- MTLTemporaryBufferRange allocation; /* TODO(Metal): Metal Memory manager. */
- /* = ctx->get_memory_manager().scratch_buffer_allocate_range_aligned(totalsize, 256);*/
- memcpy(allocation.host_ptr, data, totalsize);
+ MTLTemporaryBuffer allocation =
+ ctx->get_scratchbuffer_manager().scratch_buffer_allocate_range_aligned(totalsize, 256);
+ memcpy(allocation.data, data, totalsize);
staging_buffer = allocation.metal_buffer;
- if (own_command_buffer) {
- if (allocation.requires_flush()) {
- [staging_buffer didModifyRange:NSMakeRange(allocation.buffer_offset, allocation.size)];
- }
- }
staging_buffer_offset = allocation.buffer_offset;
/* Common Properties. */
@@ -629,23 +571,23 @@ void gpu::MTLTexture::update_sub(
return;
}
id<MTLTexture> texture_handle = ((compatible_write_format == destination_format)) ?
- this->texture_ :
- [this->texture_
+ texture_ :
+ [texture_
newTextureViewWithPixelFormat:compatible_write_format];
- /* Prepare encoders */
+ /* Prepare command encoders. */
id<MTLBlitCommandEncoder> blit_encoder = nil;
id<MTLComputeCommandEncoder> compute_encoder = nil;
if (can_use_direct_blit) {
- blit_encoder = [cmd_buffer blitCommandEncoder];
+ blit_encoder = ctx->main_command_buffer.ensure_begin_blit_encoder();
BLI_assert(blit_encoder != nil);
}
else {
- compute_encoder = [cmd_buffer computeCommandEncoder];
+ compute_encoder = ctx->main_command_buffer.ensure_begin_compute_encoder();
BLI_assert(compute_encoder != nil);
}
- switch (this->type_) {
+ switch (type_) {
/* 1D */
case GPU_TEXTURE_1D:
@@ -657,28 +599,28 @@ void gpu::MTLTexture::update_sub(
extent[0] :
ctx->pipeline_state.unpack_row_length);
int bytes_per_image = bytes_per_row;
- int max_array_index = ((this->type_ == GPU_TEXTURE_1D_ARRAY) ? extent[1] : 1);
+ int max_array_index = ((type_ == GPU_TEXTURE_1D_ARRAY) ? extent[1] : 1);
for (int array_index = 0; array_index < max_array_index; array_index++) {
int buffer_array_offset = staging_buffer_offset + (bytes_per_image * array_index);
- [blit_encoder copyFromBuffer:staging_buffer
- sourceOffset:buffer_array_offset
- sourceBytesPerRow:bytes_per_row
- sourceBytesPerImage:bytes_per_image
- sourceSize:MTLSizeMake(extent[0], 1, 1)
- toTexture:texture_handle
- destinationSlice:((this->type_ == GPU_TEXTURE_1D_ARRAY) ?
- (array_index + offset[1]) :
- 0)
- destinationLevel:mip
- destinationOrigin:MTLOriginMake(offset[0], 0, 0)];
+ [blit_encoder
+ copyFromBuffer:staging_buffer
+ sourceOffset:buffer_array_offset
+ sourceBytesPerRow:bytes_per_row
+ sourceBytesPerImage:bytes_per_image
+ sourceSize:MTLSizeMake(extent[0], 1, 1)
+ toTexture:texture_handle
+ destinationSlice:((type_ == GPU_TEXTURE_1D_ARRAY) ? (array_index + offset[1]) :
+ 0)
+ destinationLevel:mip
+ destinationOrigin:MTLOriginMake(offset[0], 0, 0)];
}
}
else {
/* Use Compute Based update. */
- if (this->type_ == GPU_TEXTURE_1D) {
+ if (type_ == GPU_TEXTURE_1D) {
id<MTLComputePipelineState> pso = texture_update_1d_get_kernel(
- compute_specialisation_kernel);
+ compute_specialization_kernel);
TextureUpdateParams params = {mip,
{extent[0], 1, 1},
{offset[0], 0, 0},
@@ -693,9 +635,9 @@ void gpu::MTLTexture::update_sub(
dispatchThreads:MTLSizeMake(extent[0], 1, 1) /* Width, Height, Layer */
threadsPerThreadgroup:MTLSizeMake(64, 1, 1)];
}
- else if (this->type_ == GPU_TEXTURE_1D_ARRAY) {
+ else if (type_ == GPU_TEXTURE_1D_ARRAY) {
id<MTLComputePipelineState> pso = texture_update_1d_array_get_kernel(
- compute_specialisation_kernel);
+ compute_specialization_kernel);
TextureUpdateParams params = {mip,
{extent[0], extent[1], 1},
{offset[0], offset[1], 0},
@@ -725,14 +667,14 @@ void gpu::MTLTexture::update_sub(
int bytes_per_image = bytes_per_row * extent[1];
int texture_array_relative_offset = 0;
- int base_slice = (this->type_ == GPU_TEXTURE_2D_ARRAY) ? offset[2] : 0;
- int final_slice = base_slice + ((this->type_ == GPU_TEXTURE_2D_ARRAY) ? extent[2] : 1);
+ int base_slice = (type_ == GPU_TEXTURE_2D_ARRAY) ? offset[2] : 0;
+ int final_slice = base_slice + ((type_ == GPU_TEXTURE_2D_ARRAY) ? extent[2] : 1);
for (int array_slice = base_slice; array_slice < final_slice; array_slice++) {
if (array_slice > 0) {
- BLI_assert(this->type_ == GPU_TEXTURE_2D_ARRAY);
- BLI_assert(array_slice < this->d_);
+ BLI_assert(type_ == GPU_TEXTURE_2D_ARRAY);
+ BLI_assert(array_slice < d_);
}
[blit_encoder copyFromBuffer:staging_buffer
@@ -750,9 +692,9 @@ void gpu::MTLTexture::update_sub(
}
else {
/* Use Compute texture update. */
- if (this->type_ == GPU_TEXTURE_2D) {
+ if (type_ == GPU_TEXTURE_2D) {
id<MTLComputePipelineState> pso = texture_update_2d_get_kernel(
- compute_specialisation_kernel);
+ compute_specialization_kernel);
TextureUpdateParams params = {mip,
{extent[0], extent[1], 1},
{offset[0], offset[1], 0},
@@ -768,9 +710,9 @@ void gpu::MTLTexture::update_sub(
extent[0], extent[1], 1) /* Width, Height, Layer */
threadsPerThreadgroup:MTLSizeMake(8, 8, 1)];
}
- else if (this->type_ == GPU_TEXTURE_2D_ARRAY) {
+ else if (type_ == GPU_TEXTURE_2D_ARRAY) {
id<MTLComputePipelineState> pso = texture_update_2d_array_get_kernel(
- compute_specialisation_kernel);
+ compute_specialization_kernel);
TextureUpdateParams params = {mip,
{extent[0], extent[1], extent[2]},
{offset[0], offset[1], offset[2]},
@@ -810,7 +752,7 @@ void gpu::MTLTexture::update_sub(
}
else {
id<MTLComputePipelineState> pso = texture_update_3d_get_kernel(
- compute_specialisation_kernel);
+ compute_specialization_kernel);
TextureUpdateParams params = {mip,
{extent[0], extent[1], extent[2]},
{offset[0], offset[1], offset[2]},
@@ -918,35 +860,15 @@ void gpu::MTLTexture::update_sub(
if (texture_.storageMode == MTLStorageModeManaged) {
[blit_encoder synchronizeResource:texture_buffer_];
}
-
- /* End Encoding. */
- [blit_encoder endEncoding];
}
else {
-
- /* End Encoding. */
- [compute_encoder endEncoding];
-
/* Textures which use MTLStorageModeManaged need to have updated contents
* synced back to CPU to avoid an automatic flush overwriting contents. */
if (texture_.storageMode == MTLStorageModeManaged) {
- blit_encoder = [cmd_buffer blitCommandEncoder];
+ blit_encoder = ctx->main_command_buffer.ensure_begin_blit_encoder();
[blit_encoder synchronizeResource:texture_buffer_];
- [blit_encoder endEncoding];
}
}
-
- if (own_command_buffer) {
- [cmd_buffer commit];
- }
-
-#if DEBUG_TEXTURE_UPDATE_CAPTURE == 1
- if (DO_CAPTURE) {
- [cmd_buffer waitUntilCompleted];
- MTLCaptureManager *capture_manager = [MTLCaptureManager sharedCaptureManager];
- [capture_manager stopCapture];
- }
-#endif
}
}
@@ -954,12 +876,12 @@ void gpu::MTLTexture::ensure_mipmaps(int miplvl)
{
/* Do not update texture view. */
- BLI_assert(this->resource_mode_ != MTL_TEXTURE_MODE_TEXTURE_VIEW);
+ BLI_assert(resource_mode_ != MTL_TEXTURE_MODE_TEXTURE_VIEW);
/* Clamp level to maximum. */
- int effective_h = (this->type_ == GPU_TEXTURE_1D_ARRAY) ? 0 : this->h_;
- int effective_d = (this->type_ != GPU_TEXTURE_3D) ? 0 : this->d_;
- int max_dimension = max_iii(this->w_, effective_h, effective_d);
+ int effective_h = (type_ == GPU_TEXTURE_1D_ARRAY) ? 0 : h_;
+ int effective_d = (type_ != GPU_TEXTURE_3D) ? 0 : d_;
+ int max_dimension = max_iii(w_, effective_h, effective_d);
int max_miplvl = floor(log2(max_dimension));
miplvl = min_ii(max_miplvl, miplvl);
@@ -968,15 +890,15 @@ void gpu::MTLTexture::ensure_mipmaps(int miplvl)
mipmaps_ = miplvl;
/* Check if baked. */
- if (this->is_baked_ && mipmaps_ > mtl_max_mips_) {
- this->is_dirty_ = true;
+ if (is_baked_ && mipmaps_ > mtl_max_mips_) {
+ is_dirty_ = true;
MTL_LOG_WARNING("Texture requires regenerating due to increase in mip-count\n");
}
}
this->mip_range_set(0, mipmaps_);
}
-void gpu::MTLTexture::generate_mipmap(void)
+void gpu::MTLTexture::generate_mipmap()
{
/* Fetch Active Context. */
MTLContext *ctx = reinterpret_cast<MTLContext *>(GPU_context_active_get());
@@ -993,44 +915,29 @@ void gpu::MTLTexture::generate_mipmap(void)
/* Ensure texture is baked. */
this->ensure_baked();
- BLI_assert(this->is_baked_ && this->texture_ && "MTLTexture is not valid");
+ BLI_assert(is_baked_ && texture_ && "MTLTexture is not valid");
- if (this->mipmaps_ == 1 || this->mtl_max_mips_ == 1) {
+ if (mipmaps_ == 1 || mtl_max_mips_ == 1) {
MTL_LOG_WARNING("Call to generate mipmaps on texture with 'mipmaps_=1\n'");
return;
}
/* Verify if we can perform mipmap generation. */
- if (this->format_ == GPU_DEPTH_COMPONENT32F || this->format_ == GPU_DEPTH_COMPONENT24 ||
- this->format_ == GPU_DEPTH_COMPONENT16 || this->format_ == GPU_DEPTH32F_STENCIL8 ||
- this->format_ == GPU_DEPTH24_STENCIL8) {
+ if (format_ == GPU_DEPTH_COMPONENT32F || format_ == GPU_DEPTH_COMPONENT24 ||
+ format_ == GPU_DEPTH_COMPONENT16 || format_ == GPU_DEPTH32F_STENCIL8 ||
+ format_ == GPU_DEPTH24_STENCIL8) {
MTL_LOG_WARNING("Cannot generate mipmaps for textures using DEPTH formats\n");
return;
}
@autoreleasepool {
- id<MTLCommandBuffer> cmd_buffer = ctx->get_active_command_buffer();
- bool own_command_buffer = false;
- if (cmd_buffer == nil) {
- cmd_buffer = [ctx->queue commandBuffer];
- own_command_buffer = true;
- }
- else {
- /* End active graphics work. */
- ctx->end_render_pass();
- }
-
- id<MTLBlitCommandEncoder> enc = [cmd_buffer blitCommandEncoder];
-#if MTL_DEBUG_COMMAND_BUFFER_EXECUTION
- [enc insertDebugSignpost:@"Generate MipMaps"];
-#endif
- [enc generateMipmapsForTexture:this->texture_];
- [enc endEncoding];
-
- if (own_command_buffer) {
- [cmd_buffer commit];
+ /* Fetch active BlitCommandEncoder. */
+ id<MTLBlitCommandEncoder> enc = ctx->main_command_buffer.ensure_begin_blit_encoder();
+ if (G.debug & G_DEBUG_GPU) {
+ [enc insertDebugSignpost:@"Generate MipMaps"];
}
+ [enc generateMipmapsForTexture:texture_];
}
return;
}
@@ -1055,13 +962,8 @@ void gpu::MTLTexture::copy_to(Texture *dst)
this->ensure_baked();
@autoreleasepool {
- /* End render pass. */
- ctx->end_render_pass();
-
/* Setup blit encoder. */
- id<MTLCommandBuffer> cmd_buffer = ctx->get_active_command_buffer();
- BLI_assert(cmd_buffer != nil);
- id<MTLBlitCommandEncoder> blit_encoder = [cmd_buffer blitCommandEncoder];
+ id<MTLBlitCommandEncoder> blit_encoder = ctx->main_command_buffer.ensure_begin_blit_encoder();
BLI_assert(blit_encoder != nil);
/* TODO(Metal): Consider supporting multiple mip levels IF the GL implementation
@@ -1077,7 +979,7 @@ void gpu::MTLTexture::copy_to(Texture *dst)
case GPU_TEXTURE_CUBE_ARRAY:
case GPU_TEXTURE_3D: {
/* Do full texture copy for 3D textures */
- BLI_assert(mt_dst->d_ == this->d_);
+ BLI_assert(mt_dst->d_ == d_);
[blit_encoder copyFromTexture:this->get_metal_handle_base()
toTexture:mt_dst->get_metal_handle_base()];
} break;
@@ -1100,9 +1002,6 @@ void gpu::MTLTexture::copy_to(Texture *dst)
extent[2]);
} break;
}
-
- /* End encoding */
- [blit_encoder endEncoding];
}
}
@@ -1144,8 +1043,8 @@ static MTLTextureSwizzle swizzle_to_mtl(const char swizzle)
void gpu::MTLTexture::swizzle_set(const char swizzle_mask[4])
{
- if (memcmp(this->tex_swizzle_mask_, swizzle_mask, 4) != 0) {
- memcpy(this->tex_swizzle_mask_, swizzle_mask, 4);
+ if (memcmp(tex_swizzle_mask_, swizzle_mask, 4) != 0) {
+ memcpy(tex_swizzle_mask_, swizzle_mask, 4);
/* Creating the swizzle mask and flagging as dirty if changed. */
MTLTextureSwizzleChannels new_swizzle_mask = MTLTextureSwizzleChannelsMake(
@@ -1154,8 +1053,8 @@ void gpu::MTLTexture::swizzle_set(const char swizzle_mask[4])
swizzle_to_mtl(swizzle_mask[2]),
swizzle_to_mtl(swizzle_mask[3]));
- this->mtl_swizzle_mask_ = new_swizzle_mask;
- this->texture_view_dirty_flags_ |= TEXTURE_VIEW_SWIZZLE_DIRTY;
+ mtl_swizzle_mask_ = new_swizzle_mask;
+ texture_view_dirty_flags_ |= TEXTURE_VIEW_SWIZZLE_DIRTY;
}
}
@@ -1172,25 +1071,24 @@ void gpu::MTLTexture::mip_range_set(int min, int max)
*
* TODO(Metal): Add texture initialization flag to determine whether mipmaps are used
* or not. Will be important for saving memory for big textures. */
- this->mip_min_ = min;
- this->mip_max_ = max;
+ mip_min_ = min;
+ mip_max_ = max;
- if ((this->type_ == GPU_TEXTURE_1D || this->type_ == GPU_TEXTURE_1D_ARRAY ||
- this->type_ == GPU_TEXTURE_BUFFER) &&
+ if ((type_ == GPU_TEXTURE_1D || type_ == GPU_TEXTURE_1D_ARRAY || type_ == GPU_TEXTURE_BUFFER) &&
max > 1) {
MTL_LOG_ERROR(
" MTLTexture of type TEXTURE_1D_ARRAY or TEXTURE_BUFFER cannot have a mipcount "
"greater than 1\n");
- this->mip_min_ = 0;
- this->mip_max_ = 0;
- this->mipmaps_ = 0;
+ mip_min_ = 0;
+ mip_max_ = 0;
+ mipmaps_ = 0;
BLI_assert(false);
}
/* Mip range for texture view. */
- this->mip_texture_base_level_ = this->mip_min_;
- this->mip_texture_max_level_ = this->mip_max_;
+ mip_texture_base_level_ = mip_min_;
+ mip_texture_max_level_ = mip_max_;
texture_view_dirty_flags_ |= TEXTURE_VIEW_MIP_DIRTY;
}
@@ -1199,7 +1097,7 @@ void *gpu::MTLTexture::read(int mip, eGPUDataFormat type)
/* Prepare Array for return data. */
BLI_assert(!(format_flag_ & GPU_FORMAT_COMPRESSED));
BLI_assert(mip <= mipmaps_);
- BLI_assert(validate_data_format_mtl(this->format_, type));
+ BLI_assert(validate_data_format_mtl(format_, type));
/* NOTE: mip_size_get() won't override any dimension that is equal to 0. */
int extent[3] = {1, 1, 1};
@@ -1208,12 +1106,12 @@ void *gpu::MTLTexture::read(int mip, eGPUDataFormat type)
size_t sample_len = extent[0] * extent[1] * extent[2];
size_t sample_size = to_bytesize(format_, type);
size_t texture_size = sample_len * sample_size;
- int num_channels = to_component_len(this->format_);
+ int num_channels = to_component_len(format_);
void *data = MEM_mallocN(texture_size + 8, "GPU_texture_read");
/* Ensure texture is baked. */
- if (this->is_baked_) {
+ if (is_baked_) {
this->read_internal(
mip, 0, 0, 0, extent[0], extent[1], extent[2], type, num_channels, texture_size + 8, data);
}
@@ -1239,7 +1137,7 @@ void gpu::MTLTexture::read_internal(int mip,
void *r_data)
{
/* Verify textures are baked. */
- if (!this->is_baked_) {
+ if (!is_baked_) {
MTL_LOG_WARNING("gpu::MTLTexture::read_internal - Trying to read from a non-baked texture!\n");
return;
}
@@ -1248,14 +1146,14 @@ void gpu::MTLTexture::read_internal(int mip,
BLI_assert(ctx);
/* Calculate Desired output size. */
- int num_channels = to_component_len(this->format_);
+ int num_channels = to_component_len(format_);
BLI_assert(num_output_components <= num_channels);
- unsigned int desired_output_bpp = num_output_components * to_bytesize(desired_output_format);
+ uint desired_output_bpp = num_output_components * to_bytesize(desired_output_format);
/* Calculate Metal data output for trivial copy. */
- unsigned int image_bpp = get_mtl_format_bytesize(this->texture_.pixelFormat);
- unsigned int image_components = get_mtl_format_num_components(this->texture_.pixelFormat);
- bool is_depth_format = (this->format_flag_ & GPU_FORMAT_DEPTH);
+ uint image_bpp = get_mtl_format_bytesize(texture_.pixelFormat);
+ uint image_components = get_mtl_format_num_components(texture_.pixelFormat);
+ bool is_depth_format = (format_flag_ & GPU_FORMAT_DEPTH);
/* Verify if we need to use compute read. */
eGPUDataFormat data_format = to_mtl_internal_data_format(this->format_get());
@@ -1272,12 +1170,12 @@ void gpu::MTLTexture::read_internal(int mip,
BLI_assert(num_output_components == 1);
BLI_assert(image_components == 1);
BLI_assert(data_format == GPU_DATA_FLOAT || data_format == GPU_DATA_UINT_24_8);
- BLI_assert(validate_data_format_mtl(this->format_, data_format));
+ BLI_assert(validate_data_format_mtl(format_, data_format));
}
/* SPECIAL Workaround for R11G11B10 textures requesting a read using: GPU_DATA_10_11_11_REV. */
if (desired_output_format == GPU_DATA_10_11_11_REV) {
- BLI_assert(this->format_ == GPU_R11F_G11F_B10F);
+ BLI_assert(format_ == GPU_R11F_G11F_B10F);
/* override parameters - we'll be able to use simple copy, as bpp will match at 4 bytes. */
image_bpp = sizeof(int);
@@ -1291,9 +1189,9 @@ void gpu::MTLTexture::read_internal(int mip,
}
/* Determine size of output data. */
- unsigned int bytes_per_row = desired_output_bpp * width;
- unsigned int bytes_per_image = bytes_per_row * height;
- unsigned int total_bytes = bytes_per_image * depth;
+ uint bytes_per_row = desired_output_bpp * width;
+ uint bytes_per_image = bytes_per_row * height;
+ uint total_bytes = bytes_per_image * depth;
if (can_use_simple_read) {
/* DEBUG check that if direct copy is being used, then both the expected output size matches
@@ -1307,7 +1205,7 @@ void gpu::MTLTexture::read_internal(int mip,
/* Fetch allocation from scratch buffer. */
id<MTLBuffer> destination_buffer = nil;
- unsigned int destination_offset = 0;
+ uint destination_offset = 0;
void *destination_buffer_host_ptr = nullptr;
/* TODO(Metal): Optimize buffer allocation. */
@@ -1315,10 +1213,10 @@ void gpu::MTLTexture::read_internal(int mip,
destination_buffer = [ctx->device newBufferWithLength:max_ii(total_bytes, 256)
options:bufferOptions];
destination_offset = 0;
- destination_buffer_host_ptr = (void *)((unsigned char *)([destination_buffer contents]) +
+ destination_buffer_host_ptr = (void *)((uint8_t *)([destination_buffer contents]) +
destination_offset);
- /* Prepare specialisation struct (For non-trivial texture read routine). */
+ /* Prepare specialization struct (For non-trivial texture read routine). */
int depth_format_mode = 0;
if (is_depth_format) {
depth_format_mode = 1;
@@ -1338,7 +1236,7 @@ void gpu::MTLTexture::read_internal(int mip,
}
}
- TextureReadRoutineSpecialisation compute_specialisation_kernel = {
+ TextureReadRoutineSpecialisation compute_specialization_kernel = {
tex_data_format_to_msl_texture_template_type(data_format), /* TEXTURE DATA TYPE */
tex_data_format_to_msl_type_str(desired_output_format), /* OUTPUT DATA TYPE */
num_channels, /* TEXTURE COMPONENT COUNT */
@@ -1348,53 +1246,25 @@ void gpu::MTLTexture::read_internal(int mip,
bool copy_successful = false;
@autoreleasepool {
- bool DO_CAPTURE = false;
-#if DEBUG_TEXTURE_READ_CAPTURE == 1
- DO_CAPTURE = true;
- if (DO_CAPTURE) {
- MTLCaptureManager *capture_manager = [MTLCaptureManager sharedCaptureManager];
- MTLCaptureDescriptor *capture_descriptor = [[MTLCaptureDescriptor alloc] init];
- capture_descriptor.captureObject = ctx->device;
- NSError *error;
- if (![capture_manager startCaptureWithDescriptor:capture_descriptor error:&error]) {
- NSString *error_str = [NSString stringWithFormat:@"%@", error];
- const char *error_c_str = [error_str UTF8String];
- MTL_LOG_ERROR("Failed to start capture. Error: %s\n", error_c_str);
- }
- }
-#endif
-
/* TODO(Metal): Verify whether we need some form of barrier here to ensure reads
* happen after work with associated texture is finished. */
GPU_finish();
- /* Fetch or Create command buffer. */
- id<MTLCommandBuffer> cmd_buffer = ctx->get_active_command_buffer();
- bool own_command_buffer = false;
- if (cmd_buffer == nil || DO_CAPTURE || true) {
- cmd_buffer = [ctx->queue commandBuffer];
- own_command_buffer = true;
- }
- else {
- /* End any graphics workloads. */
- ctx->end_render_pass();
- }
-
/* Texture View for SRGB special case. */
- id<MTLTexture> read_texture = this->texture_;
- if (this->format_ == GPU_SRGB8_A8) {
- read_texture = [this->texture_ newTextureViewWithPixelFormat:MTLPixelFormatRGBA8Unorm];
+ id<MTLTexture> read_texture = texture_;
+ if (format_ == GPU_SRGB8_A8) {
+ read_texture = [texture_ newTextureViewWithPixelFormat:MTLPixelFormatRGBA8Unorm];
}
/* Perform per-texture type read. */
- switch (this->type_) {
+ switch (type_) {
case GPU_TEXTURE_2D: {
if (can_use_simple_read) {
/* Use Blit Encoder READ. */
- id<MTLBlitCommandEncoder> enc = [cmd_buffer blitCommandEncoder];
-#if MTL_DEBUG_COMMAND_BUFFER_EXECUTION
- [enc insertDebugSignpost:@"GPUTextureRead"];
-#endif
+ id<MTLBlitCommandEncoder> enc = ctx->main_command_buffer.ensure_begin_blit_encoder();
+ if (G.debug & G_DEBUG_GPU) {
+ [enc insertDebugSignpost:@"GPUTextureRead"];
+ }
[enc copyFromTexture:read_texture
sourceSlice:0
sourceLevel:mip
@@ -1405,15 +1275,15 @@ void gpu::MTLTexture::read_internal(int mip,
destinationBytesPerRow:bytes_per_row
destinationBytesPerImage:bytes_per_image];
[enc synchronizeResource:destination_buffer];
- [enc endEncoding];
copy_successful = true;
}
else {
/* Use Compute READ. */
- id<MTLComputeCommandEncoder> compute_encoder = [cmd_buffer computeCommandEncoder];
+ id<MTLComputeCommandEncoder> compute_encoder =
+ ctx->main_command_buffer.ensure_begin_compute_encoder();
id<MTLComputePipelineState> pso = texture_read_2d_get_kernel(
- compute_specialisation_kernel);
+ compute_specialization_kernel);
TextureReadParams params = {
mip,
{width, height, 1},
@@ -1425,15 +1295,13 @@ void gpu::MTLTexture::read_internal(int mip,
[compute_encoder setTexture:read_texture atIndex:0];
[compute_encoder dispatchThreads:MTLSizeMake(width, height, 1) /* Width, Height, Layer */
threadsPerThreadgroup:MTLSizeMake(8, 8, 1)];
- [compute_encoder endEncoding];
/* Use Blit encoder to synchronize results back to CPU. */
- id<MTLBlitCommandEncoder> enc = [cmd_buffer blitCommandEncoder];
-#if MTL_DEBUG_COMMAND_BUFFER_EXECUTION
- [enc insertDebugSignpost:@"GPUTextureRead-syncResource"];
-#endif
+ id<MTLBlitCommandEncoder> enc = ctx->main_command_buffer.ensure_begin_blit_encoder();
+ if (G.debug & G_DEBUG_GPU) {
+ [enc insertDebugSignpost:@"GPUTextureRead-syncResource"];
+ }
[enc synchronizeResource:destination_buffer];
- [enc endEncoding];
copy_successful = true;
}
} break;
@@ -1441,10 +1309,10 @@ void gpu::MTLTexture::read_internal(int mip,
case GPU_TEXTURE_2D_ARRAY: {
if (can_use_simple_read) {
/* Use Blit Encoder READ. */
- id<MTLBlitCommandEncoder> enc = [cmd_buffer blitCommandEncoder];
-#if MTL_DEBUG_COMMAND_BUFFER_EXECUTION
- [enc insertDebugSignpost:@"GPUTextureRead"];
-#endif
+ id<MTLBlitCommandEncoder> enc = ctx->main_command_buffer.ensure_begin_blit_encoder();
+ if (G.debug & G_DEBUG_GPU) {
+ [enc insertDebugSignpost:@"GPUTextureRead"];
+ }
int base_slice = z_off;
int final_slice = base_slice + depth;
int texture_array_relative_offset = 0;
@@ -1463,15 +1331,15 @@ void gpu::MTLTexture::read_internal(int mip,
texture_array_relative_offset += bytes_per_image;
}
- [enc endEncoding];
copy_successful = true;
}
else {
/* Use Compute READ */
- id<MTLComputeCommandEncoder> compute_encoder = [cmd_buffer computeCommandEncoder];
+ id<MTLComputeCommandEncoder> compute_encoder =
+ ctx->main_command_buffer.ensure_begin_compute_encoder();
id<MTLComputePipelineState> pso = texture_read_2d_array_get_kernel(
- compute_specialisation_kernel);
+ compute_specialization_kernel);
TextureReadParams params = {
mip,
{width, height, depth},
@@ -1484,25 +1352,23 @@ void gpu::MTLTexture::read_internal(int mip,
[compute_encoder
dispatchThreads:MTLSizeMake(width, height, depth) /* Width, Height, Layer */
threadsPerThreadgroup:MTLSizeMake(8, 8, 1)];
- [compute_encoder endEncoding];
/* Use Blit encoder to synchronize results back to CPU. */
- id<MTLBlitCommandEncoder> enc = [cmd_buffer blitCommandEncoder];
-#if MTL_DEBUG_COMMAND_BUFFER_EXECUTION
- [enc insertDebugSignpost:@"GPUTextureRead-syncResource"];
-#endif
+ id<MTLBlitCommandEncoder> enc = ctx->main_command_buffer.ensure_begin_blit_encoder();
+ if (G.debug & G_DEBUG_GPU) {
+ [enc insertDebugSignpost:@"GPUTextureRead-syncResource"];
+ }
[enc synchronizeResource:destination_buffer];
- [enc endEncoding];
copy_successful = true;
}
} break;
case GPU_TEXTURE_CUBE_ARRAY: {
if (can_use_simple_read) {
- id<MTLBlitCommandEncoder> enc = [cmd_buffer blitCommandEncoder];
-#if MTL_DEBUG_COMMAND_BUFFER_EXECUTION
- [enc insertDebugSignpost:@"GPUTextureRead"];
-#endif
+ id<MTLBlitCommandEncoder> enc = ctx->main_command_buffer.ensure_begin_blit_encoder();
+ if (G.debug & G_DEBUG_GPU) {
+ [enc insertDebugSignpost:@"GPUTextureRead"];
+ }
int base_slice = z_off;
int final_slice = base_slice + depth;
int texture_array_relative_offset = 0;
@@ -1522,7 +1388,6 @@ void gpu::MTLTexture::read_internal(int mip,
texture_array_relative_offset += bytes_per_image;
}
MTL_LOG_INFO("Copying texture data to buffer GPU_TEXTURE_CUBE_ARRAY\n");
- [enc endEncoding];
copy_successful = true;
}
else {
@@ -1534,27 +1399,13 @@ void gpu::MTLTexture::read_internal(int mip,
MTL_LOG_WARNING(
"[Warning] gpu::MTLTexture::read_internal simple-copy not yet supported for texture "
"type: %d\n",
- (int)this->type_);
+ (int)type_);
break;
}
if (copy_successful) {
- /* Ensure GPU copy from texture to host-accessible buffer is complete. */
- if (own_command_buffer) {
- [cmd_buffer commit];
- [cmd_buffer waitUntilCompleted];
- }
- else {
- /* Ensure GPU copy commands have completed. */
- GPU_finish();
- }
-
-#if DEBUG_TEXTURE_READ_CAPTURE == 1
- if (DO_CAPTURE) {
- MTLCaptureManager *capture_manager = [MTLCaptureManager sharedCaptureManager];
- [capture_manager stopCapture];
- }
-#endif
+ /* Ensure GPU copy commands have completed. */
+ GPU_finish();
/* Copy data from Shared Memory into ptr. */
memcpy(r_data, destination_buffer_host_ptr, total_bytes);
@@ -1576,16 +1427,16 @@ void gpu::MTLTexture::read_internal(int mip,
}
/* Remove once no longer required -- will just return 0 for now in MTL path. */
-uint gpu::MTLTexture::gl_bindcode_get(void) const
+uint gpu::MTLTexture::gl_bindcode_get() const
{
return 0;
}
-bool gpu::MTLTexture::init_internal(void)
+bool gpu::MTLTexture::init_internal()
{
- if (this->format_ == GPU_DEPTH24_STENCIL8) {
+ if (format_ == GPU_DEPTH24_STENCIL8) {
/* Apple Silicon requires GPU_DEPTH32F_STENCIL8 instead of GPU_DEPTH24_STENCIL8. */
- this->format_ = GPU_DEPTH32F_STENCIL8;
+ format_ = GPU_DEPTH32F_STENCIL8;
}
this->prepare_internal();
@@ -1609,20 +1460,20 @@ bool gpu::MTLTexture::init_internal(const GPUTexture *src, int mip_offset, int l
this->prepare_internal();
/* Flag as using texture view. */
- this->resource_mode_ = MTL_TEXTURE_MODE_TEXTURE_VIEW;
- this->source_texture_ = src;
- this->mip_texture_base_level_ = mip_offset;
- this->mip_texture_base_layer_ = layer_offset;
+ resource_mode_ = MTL_TEXTURE_MODE_TEXTURE_VIEW;
+ source_texture_ = src;
+ mip_texture_base_level_ = mip_offset;
+ mip_texture_base_layer_ = layer_offset;
/* Assign texture as view. */
const gpu::MTLTexture *mtltex = static_cast<const gpu::MTLTexture *>(unwrap(src));
- this->texture_ = mtltex->texture_;
- BLI_assert(this->texture_);
- [this->texture_ retain];
+ texture_ = mtltex->texture_;
+ BLI_assert(texture_);
+ [texture_ retain];
/* Flag texture as baked -- we do not need explicit initialization. */
- this->is_baked_ = true;
- this->is_dirty_ = false;
+ is_baked_ = true;
+ is_dirty_ = false;
/* Bake mip swizzle view. */
bake_mip_swizzle_view();
@@ -1637,7 +1488,7 @@ bool gpu::MTLTexture::init_internal(const GPUTexture *src, int mip_offset, int l
bool gpu::MTLTexture::texture_is_baked()
{
- return this->is_baked_;
+ return is_baked_;
}
/* Prepare texture parameters after initialization, but before baking. */
@@ -1645,22 +1496,21 @@ void gpu::MTLTexture::prepare_internal()
{
/* Derive implicit usage flags for Depth/Stencil attachments. */
- if (this->format_flag_ & GPU_FORMAT_DEPTH || this->format_flag_ & GPU_FORMAT_STENCIL) {
- this->gpu_image_usage_flags_ |= GPU_TEXTURE_USAGE_ATTACHMENT;
+ if (format_flag_ & GPU_FORMAT_DEPTH || format_flag_ & GPU_FORMAT_STENCIL) {
+ gpu_image_usage_flags_ |= GPU_TEXTURE_USAGE_ATTACHMENT;
}
/* Derive maximum number of mip levels by default.
* TODO(Metal): This can be removed if max mip counts are specified upfront. */
- if (this->type_ == GPU_TEXTURE_1D || this->type_ == GPU_TEXTURE_1D_ARRAY ||
- this->type_ == GPU_TEXTURE_BUFFER) {
- this->mtl_max_mips_ = 1;
+ if (type_ == GPU_TEXTURE_1D || type_ == GPU_TEXTURE_1D_ARRAY || type_ == GPU_TEXTURE_BUFFER) {
+ mtl_max_mips_ = 1;
}
else {
- int effective_h = (this->type_ == GPU_TEXTURE_1D_ARRAY) ? 0 : this->h_;
- int effective_d = (this->type_ != GPU_TEXTURE_3D) ? 0 : this->d_;
- int max_dimension = max_iii(this->w_, effective_h, effective_d);
+ int effective_h = (type_ == GPU_TEXTURE_1D_ARRAY) ? 0 : h_;
+ int effective_d = (type_ != GPU_TEXTURE_3D) ? 0 : d_;
+ int max_dimension = max_iii(w_, effective_h, effective_d);
int max_miplvl = max_ii(floor(log2(max_dimension)) + 1, 1);
- this->mtl_max_mips_ = max_miplvl;
+ mtl_max_mips_ = max_miplvl;
}
}
@@ -1669,101 +1519,91 @@ void gpu::MTLTexture::ensure_baked()
/* If properties have changed, re-bake. */
bool copy_previous_contents = false;
- if (this->is_baked_ && this->is_dirty_) {
+ if (is_baked_ && is_dirty_) {
copy_previous_contents = true;
- id<MTLTexture> previous_texture = this->texture_;
+ id<MTLTexture> previous_texture = texture_;
[previous_texture retain];
this->reset();
}
- if (!this->is_baked_) {
+ if (!is_baked_) {
MTLContext *ctx = static_cast<MTLContext *>(unwrap(GPU_context_active_get()));
BLI_assert(ctx);
/* Ensure texture mode is valid. */
- BLI_assert(this->resource_mode_ != MTL_TEXTURE_MODE_EXTERNAL);
- BLI_assert(this->resource_mode_ != MTL_TEXTURE_MODE_TEXTURE_VIEW);
- BLI_assert(this->resource_mode_ != MTL_TEXTURE_MODE_VBO);
+ BLI_assert(resource_mode_ != MTL_TEXTURE_MODE_EXTERNAL);
+ BLI_assert(resource_mode_ != MTL_TEXTURE_MODE_TEXTURE_VIEW);
+ BLI_assert(resource_mode_ != MTL_TEXTURE_MODE_VBO);
/* Format and mip levels (TODO(Metal): Optimize mipmaps counts, specify up-front). */
- MTLPixelFormat mtl_format = gpu_texture_format_to_metal(this->format_);
+ MTLPixelFormat mtl_format = gpu_texture_format_to_metal(format_);
/* Create texture descriptor. */
- switch (this->type_) {
+ switch (type_) {
/* 1D */
case GPU_TEXTURE_1D:
case GPU_TEXTURE_1D_ARRAY: {
- BLI_assert(this->w_ > 0);
- this->texture_descriptor_ = [[MTLTextureDescriptor alloc] init];
- this->texture_descriptor_.pixelFormat = mtl_format;
- this->texture_descriptor_.textureType = (this->type_ == GPU_TEXTURE_1D_ARRAY) ?
- MTLTextureType1DArray :
- MTLTextureType1D;
- this->texture_descriptor_.width = this->w_;
- this->texture_descriptor_.height = 1;
- this->texture_descriptor_.depth = 1;
- this->texture_descriptor_.arrayLength = (this->type_ == GPU_TEXTURE_1D_ARRAY) ? this->h_ :
- 1;
- this->texture_descriptor_.mipmapLevelCount = (this->mtl_max_mips_ > 0) ?
- this->mtl_max_mips_ :
- 1;
- this->texture_descriptor_.usage =
+ BLI_assert(w_ > 0);
+ texture_descriptor_ = [[MTLTextureDescriptor alloc] init];
+ texture_descriptor_.pixelFormat = mtl_format;
+ texture_descriptor_.textureType = (type_ == GPU_TEXTURE_1D_ARRAY) ? MTLTextureType1DArray :
+ MTLTextureType1D;
+ texture_descriptor_.width = w_;
+ texture_descriptor_.height = 1;
+ texture_descriptor_.depth = 1;
+ texture_descriptor_.arrayLength = (type_ == GPU_TEXTURE_1D_ARRAY) ? h_ : 1;
+ texture_descriptor_.mipmapLevelCount = (mtl_max_mips_ > 0) ? mtl_max_mips_ : 1;
+ texture_descriptor_.usage =
MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite |
MTLTextureUsagePixelFormatView; /* TODO(Metal): Optimize usage flags. */
- this->texture_descriptor_.storageMode = MTLStorageModePrivate;
- this->texture_descriptor_.sampleCount = 1;
- this->texture_descriptor_.cpuCacheMode = MTLCPUCacheModeDefaultCache;
- this->texture_descriptor_.hazardTrackingMode = MTLHazardTrackingModeDefault;
+ texture_descriptor_.storageMode = MTLStorageModePrivate;
+ texture_descriptor_.sampleCount = 1;
+ texture_descriptor_.cpuCacheMode = MTLCPUCacheModeDefaultCache;
+ texture_descriptor_.hazardTrackingMode = MTLHazardTrackingModeDefault;
} break;
/* 2D */
case GPU_TEXTURE_2D:
case GPU_TEXTURE_2D_ARRAY: {
- BLI_assert(this->w_ > 0 && this->h_ > 0);
- this->texture_descriptor_ = [[MTLTextureDescriptor alloc] init];
- this->texture_descriptor_.pixelFormat = mtl_format;
- this->texture_descriptor_.textureType = (this->type_ == GPU_TEXTURE_2D_ARRAY) ?
- MTLTextureType2DArray :
- MTLTextureType2D;
- this->texture_descriptor_.width = this->w_;
- this->texture_descriptor_.height = this->h_;
- this->texture_descriptor_.depth = 1;
- this->texture_descriptor_.arrayLength = (this->type_ == GPU_TEXTURE_2D_ARRAY) ? this->d_ :
- 1;
- this->texture_descriptor_.mipmapLevelCount = (this->mtl_max_mips_ > 0) ?
- this->mtl_max_mips_ :
- 1;
- this->texture_descriptor_.usage =
+ BLI_assert(w_ > 0 && h_ > 0);
+ texture_descriptor_ = [[MTLTextureDescriptor alloc] init];
+ texture_descriptor_.pixelFormat = mtl_format;
+ texture_descriptor_.textureType = (type_ == GPU_TEXTURE_2D_ARRAY) ? MTLTextureType2DArray :
+ MTLTextureType2D;
+ texture_descriptor_.width = w_;
+ texture_descriptor_.height = h_;
+ texture_descriptor_.depth = 1;
+ texture_descriptor_.arrayLength = (type_ == GPU_TEXTURE_2D_ARRAY) ? d_ : 1;
+ texture_descriptor_.mipmapLevelCount = (mtl_max_mips_ > 0) ? mtl_max_mips_ : 1;
+ texture_descriptor_.usage =
MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite |
MTLTextureUsagePixelFormatView; /* TODO(Metal): Optimize usage flags. */
- this->texture_descriptor_.storageMode = MTLStorageModePrivate;
- this->texture_descriptor_.sampleCount = 1;
- this->texture_descriptor_.cpuCacheMode = MTLCPUCacheModeDefaultCache;
- this->texture_descriptor_.hazardTrackingMode = MTLHazardTrackingModeDefault;
+ texture_descriptor_.storageMode = MTLStorageModePrivate;
+ texture_descriptor_.sampleCount = 1;
+ texture_descriptor_.cpuCacheMode = MTLCPUCacheModeDefaultCache;
+ texture_descriptor_.hazardTrackingMode = MTLHazardTrackingModeDefault;
} break;
/* 3D */
case GPU_TEXTURE_3D: {
- BLI_assert(this->w_ > 0 && this->h_ > 0 && this->d_ > 0);
- this->texture_descriptor_ = [[MTLTextureDescriptor alloc] init];
- this->texture_descriptor_.pixelFormat = mtl_format;
- this->texture_descriptor_.textureType = MTLTextureType3D;
- this->texture_descriptor_.width = this->w_;
- this->texture_descriptor_.height = this->h_;
- this->texture_descriptor_.depth = this->d_;
- this->texture_descriptor_.arrayLength = 1;
- this->texture_descriptor_.mipmapLevelCount = (this->mtl_max_mips_ > 0) ?
- this->mtl_max_mips_ :
- 1;
- this->texture_descriptor_.usage =
+ BLI_assert(w_ > 0 && h_ > 0 && d_ > 0);
+ texture_descriptor_ = [[MTLTextureDescriptor alloc] init];
+ texture_descriptor_.pixelFormat = mtl_format;
+ texture_descriptor_.textureType = MTLTextureType3D;
+ texture_descriptor_.width = w_;
+ texture_descriptor_.height = h_;
+ texture_descriptor_.depth = d_;
+ texture_descriptor_.arrayLength = 1;
+ texture_descriptor_.mipmapLevelCount = (mtl_max_mips_ > 0) ? mtl_max_mips_ : 1;
+ texture_descriptor_.usage =
MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite |
MTLTextureUsagePixelFormatView; /* TODO(Metal): Optimize usage flags. */
- this->texture_descriptor_.storageMode = MTLStorageModePrivate;
- this->texture_descriptor_.sampleCount = 1;
- this->texture_descriptor_.cpuCacheMode = MTLCPUCacheModeDefaultCache;
- this->texture_descriptor_.hazardTrackingMode = MTLHazardTrackingModeDefault;
+ texture_descriptor_.storageMode = MTLStorageModePrivate;
+ texture_descriptor_.sampleCount = 1;
+ texture_descriptor_.cpuCacheMode = MTLCPUCacheModeDefaultCache;
+ texture_descriptor_.hazardTrackingMode = MTLHazardTrackingModeDefault;
} break;
/* CUBE TEXTURES */
@@ -1771,69 +1611,63 @@ void gpu::MTLTexture::ensure_baked()
case GPU_TEXTURE_CUBE_ARRAY: {
/* NOTE: For a cube-map 'Texture::d_' refers to total number of faces,
* not just array slices. */
- BLI_assert(this->w_ > 0 && this->h_ > 0);
- this->texture_descriptor_ = [[MTLTextureDescriptor alloc] init];
- this->texture_descriptor_.pixelFormat = mtl_format;
- this->texture_descriptor_.textureType = (this->type_ == GPU_TEXTURE_CUBE_ARRAY) ?
- MTLTextureTypeCubeArray :
- MTLTextureTypeCube;
- this->texture_descriptor_.width = this->w_;
- this->texture_descriptor_.height = this->h_;
- this->texture_descriptor_.depth = 1;
- this->texture_descriptor_.arrayLength = (this->type_ == GPU_TEXTURE_CUBE_ARRAY) ?
- this->d_ / 6 :
- 1;
- this->texture_descriptor_.mipmapLevelCount = (this->mtl_max_mips_ > 0) ?
- this->mtl_max_mips_ :
- 1;
- this->texture_descriptor_.usage =
+ BLI_assert(w_ > 0 && h_ > 0);
+ texture_descriptor_ = [[MTLTextureDescriptor alloc] init];
+ texture_descriptor_.pixelFormat = mtl_format;
+ texture_descriptor_.textureType = (type_ == GPU_TEXTURE_CUBE_ARRAY) ?
+ MTLTextureTypeCubeArray :
+ MTLTextureTypeCube;
+ texture_descriptor_.width = w_;
+ texture_descriptor_.height = h_;
+ texture_descriptor_.depth = 1;
+ texture_descriptor_.arrayLength = (type_ == GPU_TEXTURE_CUBE_ARRAY) ? d_ / 6 : 1;
+ texture_descriptor_.mipmapLevelCount = (mtl_max_mips_ > 0) ? mtl_max_mips_ : 1;
+ texture_descriptor_.usage =
MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite |
MTLTextureUsagePixelFormatView; /* TODO(Metal): Optimize usage flags. */
- this->texture_descriptor_.storageMode = MTLStorageModePrivate;
- this->texture_descriptor_.sampleCount = 1;
- this->texture_descriptor_.cpuCacheMode = MTLCPUCacheModeDefaultCache;
- this->texture_descriptor_.hazardTrackingMode = MTLHazardTrackingModeDefault;
+ texture_descriptor_.storageMode = MTLStorageModePrivate;
+ texture_descriptor_.sampleCount = 1;
+ texture_descriptor_.cpuCacheMode = MTLCPUCacheModeDefaultCache;
+ texture_descriptor_.hazardTrackingMode = MTLHazardTrackingModeDefault;
} break;
/* GPU_TEXTURE_BUFFER */
case GPU_TEXTURE_BUFFER: {
- this->texture_descriptor_ = [[MTLTextureDescriptor alloc] init];
- this->texture_descriptor_.pixelFormat = mtl_format;
- this->texture_descriptor_.textureType = MTLTextureTypeTextureBuffer;
- this->texture_descriptor_.width = this->w_;
- this->texture_descriptor_.height = 1;
- this->texture_descriptor_.depth = 1;
- this->texture_descriptor_.arrayLength = 1;
- this->texture_descriptor_.mipmapLevelCount = (this->mtl_max_mips_ > 0) ?
- this->mtl_max_mips_ :
- 1;
- this->texture_descriptor_.usage =
+ texture_descriptor_ = [[MTLTextureDescriptor alloc] init];
+ texture_descriptor_.pixelFormat = mtl_format;
+ texture_descriptor_.textureType = MTLTextureTypeTextureBuffer;
+ texture_descriptor_.width = w_;
+ texture_descriptor_.height = 1;
+ texture_descriptor_.depth = 1;
+ texture_descriptor_.arrayLength = 1;
+ texture_descriptor_.mipmapLevelCount = (mtl_max_mips_ > 0) ? mtl_max_mips_ : 1;
+ texture_descriptor_.usage =
MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite |
MTLTextureUsagePixelFormatView; /* TODO(Metal): Optimize usage flags. */
- this->texture_descriptor_.storageMode = MTLStorageModePrivate;
- this->texture_descriptor_.sampleCount = 1;
- this->texture_descriptor_.cpuCacheMode = MTLCPUCacheModeDefaultCache;
- this->texture_descriptor_.hazardTrackingMode = MTLHazardTrackingModeDefault;
+ texture_descriptor_.storageMode = MTLStorageModePrivate;
+ texture_descriptor_.sampleCount = 1;
+ texture_descriptor_.cpuCacheMode = MTLCPUCacheModeDefaultCache;
+ texture_descriptor_.hazardTrackingMode = MTLHazardTrackingModeDefault;
} break;
default: {
- MTL_LOG_ERROR("[METAL] Error: Cannot create texture with unknown type: %d\n", this->type_);
+ MTL_LOG_ERROR("[METAL] Error: Cannot create texture with unknown type: %d\n", type_);
return;
} break;
}
/* Determine Resource Mode. */
- this->resource_mode_ = MTL_TEXTURE_MODE_DEFAULT;
+ resource_mode_ = MTL_TEXTURE_MODE_DEFAULT;
/* Create texture. */
- this->texture_ = [ctx->device newTextureWithDescriptor:this->texture_descriptor_];
-
- [this->texture_descriptor_ release];
- this->texture_descriptor_ = nullptr;
- this->texture_.label = [NSString stringWithUTF8String:this->get_name()];
- BLI_assert(this->texture_);
- this->is_baked_ = true;
- this->is_dirty_ = false;
+ texture_ = [ctx->device newTextureWithDescriptor:texture_descriptor_];
+
+ [texture_descriptor_ release];
+ texture_descriptor_ = nullptr;
+ texture_.label = [NSString stringWithUTF8String:this->get_name()];
+ BLI_assert(texture_);
+ is_baked_ = true;
+ is_dirty_ = false;
}
/* Re-apply previous contents. */
@@ -1850,30 +1684,30 @@ void gpu::MTLTexture::reset()
MTL_LOG_INFO("Texture %s reset. Size %d, %d, %d\n", this->get_name(), w_, h_, d_);
/* Delete associated METAL resources. */
- if (this->texture_ != nil) {
- [this->texture_ release];
- this->texture_ = nil;
- this->is_baked_ = false;
- this->is_dirty_ = true;
+ if (texture_ != nil) {
+ [texture_ release];
+ texture_ = nil;
+ is_baked_ = false;
+ is_dirty_ = true;
}
- if (this->mip_swizzle_view_ != nil) {
- [this->mip_swizzle_view_ release];
- this->mip_swizzle_view_ = nil;
+ if (mip_swizzle_view_ != nil) {
+ [mip_swizzle_view_ release];
+ mip_swizzle_view_ = nil;
}
- if (this->texture_buffer_ != nil) {
- [this->texture_buffer_ release];
+ if (texture_buffer_ != nil) {
+ [texture_buffer_ release];
}
/* Blit framebuffer. */
- if (this->blit_fb_) {
- GPU_framebuffer_free(this->blit_fb_);
- this->blit_fb_ = nullptr;
+ if (blit_fb_) {
+ GPU_framebuffer_free(blit_fb_);
+ blit_fb_ = nullptr;
}
- BLI_assert(this->texture_ == nil);
- BLI_assert(this->mip_swizzle_view_ == nil);
+ BLI_assert(texture_ == nil);
+ BLI_assert(mip_swizzle_view_ == nil);
}
/** \} */