forked from blender/blender
main sync #3
@ -147,6 +147,18 @@ void immDrawPixelsTexTiled_scaling_clipping(IMMDrawPixelsTexState *state,
|
|||||||
const float color[4])
|
const float color[4])
|
||||||
{
|
{
|
||||||
int subpart_x, subpart_y, tex_w = 256, tex_h = 256;
|
int subpart_x, subpart_y, tex_w = 256, tex_h = 256;
|
||||||
|
#ifdef __APPLE__
|
||||||
|
if (GPU_backend_get_type() == GPU_BACKEND_METAL) {
|
||||||
|
/* NOTE(Metal): The Metal backend will keep all temporary texture memory within a command
|
||||||
|
* submission in-flight, so using a partial tile size does not provide any tangible memory
|
||||||
|
* reduction, but does incur additional API overhead and significant cache inefficiency on AMD
|
||||||
|
* platforms.
|
||||||
|
* The Metal API also provides smart resource paging such that the application can
|
||||||
|
* still efficiently swap memory, even if system is low in physical memory. */
|
||||||
|
tex_w = img_w;
|
||||||
|
tex_h = img_h;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
int seamless, offset_x, offset_y, nsubparts_x, nsubparts_y;
|
int seamless, offset_x, offset_y, nsubparts_x, nsubparts_y;
|
||||||
int components;
|
int components;
|
||||||
const bool use_clipping = ((clip_min_x < clip_max_x) && (clip_min_y < clip_max_y));
|
const bool use_clipping = ((clip_min_x < clip_max_x) && (clip_min_y < clip_max_y));
|
||||||
|
@ -594,17 +594,6 @@ void gpu::MTLTexture::update_sub(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare staging buffer for data. */
|
|
||||||
id<MTLBuffer> staging_buffer = nil;
|
|
||||||
uint64_t staging_buffer_offset = 0;
|
|
||||||
|
|
||||||
/* Fetch allocation from scratch buffer. */
|
|
||||||
MTLTemporaryBuffer allocation =
|
|
||||||
ctx->get_scratchbuffer_manager().scratch_buffer_allocate_range_aligned(totalsize, 256);
|
|
||||||
memcpy(allocation.data, data, totalsize);
|
|
||||||
staging_buffer = allocation.metal_buffer;
|
|
||||||
staging_buffer_offset = allocation.buffer_offset;
|
|
||||||
|
|
||||||
/* Common Properties. */
|
/* Common Properties. */
|
||||||
MTLPixelFormat compatible_write_format = mtl_format_get_writeable_view_format(
|
MTLPixelFormat compatible_write_format = mtl_format_get_writeable_view_format(
|
||||||
destination_format);
|
destination_format);
|
||||||
@ -616,6 +605,12 @@ void gpu::MTLTexture::update_sub(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fetch allocation from memory pool. */
|
||||||
|
MTLBuffer *temp_allocation = MTLContext::get_global_memory_manager()->allocate_with_data(
|
||||||
|
totalsize, true, data);
|
||||||
|
id<MTLBuffer> staging_buffer = temp_allocation->get_metal_buffer();
|
||||||
|
BLI_assert(staging_buffer != nil);
|
||||||
|
|
||||||
/* Prepare command encoders. */
|
/* Prepare command encoders. */
|
||||||
id<MTLBlitCommandEncoder> blit_encoder = nil;
|
id<MTLBlitCommandEncoder> blit_encoder = nil;
|
||||||
id<MTLComputeCommandEncoder> compute_encoder = nil;
|
id<MTLComputeCommandEncoder> compute_encoder = nil;
|
||||||
@ -697,7 +692,7 @@ void gpu::MTLTexture::update_sub(
|
|||||||
int max_array_index = ((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++) {
|
for (int array_index = 0; array_index < max_array_index; array_index++) {
|
||||||
|
|
||||||
int buffer_array_offset = staging_buffer_offset + (bytes_per_image * array_index);
|
int buffer_array_offset = (bytes_per_image * array_index);
|
||||||
[blit_encoder
|
[blit_encoder
|
||||||
copyFromBuffer:staging_buffer
|
copyFromBuffer:staging_buffer
|
||||||
sourceOffset:buffer_array_offset
|
sourceOffset:buffer_array_offset
|
||||||
@ -727,7 +722,7 @@ void gpu::MTLTexture::update_sub(
|
|||||||
MTLComputeState &cs = ctx->main_command_buffer.get_compute_state();
|
MTLComputeState &cs = ctx->main_command_buffer.get_compute_state();
|
||||||
cs.bind_pso(pso);
|
cs.bind_pso(pso);
|
||||||
cs.bind_compute_bytes(¶ms, sizeof(params), 0);
|
cs.bind_compute_bytes(¶ms, sizeof(params), 0);
|
||||||
cs.bind_compute_buffer(staging_buffer, staging_buffer_offset, 1);
|
cs.bind_compute_buffer(staging_buffer, 0, 1);
|
||||||
cs.bind_compute_texture(texture_handle, 0);
|
cs.bind_compute_texture(texture_handle, 0);
|
||||||
[compute_encoder
|
[compute_encoder
|
||||||
dispatchThreads:MTLSizeMake(extent[0], 1, 1) /* Width, Height, Layer */
|
dispatchThreads:MTLSizeMake(extent[0], 1, 1) /* Width, Height, Layer */
|
||||||
@ -747,7 +742,7 @@ void gpu::MTLTexture::update_sub(
|
|||||||
MTLComputeState &cs = ctx->main_command_buffer.get_compute_state();
|
MTLComputeState &cs = ctx->main_command_buffer.get_compute_state();
|
||||||
cs.bind_pso(pso);
|
cs.bind_pso(pso);
|
||||||
cs.bind_compute_bytes(¶ms, sizeof(params), 0);
|
cs.bind_compute_bytes(¶ms, sizeof(params), 0);
|
||||||
cs.bind_compute_buffer(staging_buffer, staging_buffer_offset, 1);
|
cs.bind_compute_buffer(staging_buffer, 0, 1);
|
||||||
cs.bind_compute_texture(texture_handle, 0);
|
cs.bind_compute_texture(texture_handle, 0);
|
||||||
[compute_encoder
|
[compute_encoder
|
||||||
dispatchThreads:MTLSizeMake(extent[0], extent[1], 1) /* Width, layers, nil */
|
dispatchThreads:MTLSizeMake(extent[0], extent[1], 1) /* Width, layers, nil */
|
||||||
@ -779,7 +774,7 @@ void gpu::MTLTexture::update_sub(
|
|||||||
}
|
}
|
||||||
|
|
||||||
[blit_encoder copyFromBuffer:staging_buffer
|
[blit_encoder copyFromBuffer:staging_buffer
|
||||||
sourceOffset:staging_buffer_offset + texture_array_relative_offset
|
sourceOffset:texture_array_relative_offset
|
||||||
sourceBytesPerRow:bytes_per_row
|
sourceBytesPerRow:bytes_per_row
|
||||||
sourceBytesPerImage:bytes_per_image
|
sourceBytesPerImage:bytes_per_image
|
||||||
sourceSize:MTLSizeMake(extent[0], extent[1], 1)
|
sourceSize:MTLSizeMake(extent[0], extent[1], 1)
|
||||||
@ -807,7 +802,7 @@ void gpu::MTLTexture::update_sub(
|
|||||||
MTLComputeState &cs = ctx->main_command_buffer.get_compute_state();
|
MTLComputeState &cs = ctx->main_command_buffer.get_compute_state();
|
||||||
cs.bind_pso(pso);
|
cs.bind_pso(pso);
|
||||||
cs.bind_compute_bytes(¶ms, sizeof(params), 0);
|
cs.bind_compute_bytes(¶ms, sizeof(params), 0);
|
||||||
cs.bind_compute_buffer(staging_buffer, staging_buffer_offset, 1);
|
cs.bind_compute_buffer(staging_buffer, 0, 1);
|
||||||
cs.bind_compute_texture(texture_handle, 0);
|
cs.bind_compute_texture(texture_handle, 0);
|
||||||
[compute_encoder
|
[compute_encoder
|
||||||
dispatchThreads:MTLSizeMake(
|
dispatchThreads:MTLSizeMake(
|
||||||
@ -828,7 +823,7 @@ void gpu::MTLTexture::update_sub(
|
|||||||
MTLComputeState &cs = ctx->main_command_buffer.get_compute_state();
|
MTLComputeState &cs = ctx->main_command_buffer.get_compute_state();
|
||||||
cs.bind_pso(pso);
|
cs.bind_pso(pso);
|
||||||
cs.bind_compute_bytes(¶ms, sizeof(params), 0);
|
cs.bind_compute_bytes(¶ms, sizeof(params), 0);
|
||||||
cs.bind_compute_buffer(staging_buffer, staging_buffer_offset, 1);
|
cs.bind_compute_buffer(staging_buffer, 0, 1);
|
||||||
cs.bind_compute_texture(texture_handle, 0);
|
cs.bind_compute_texture(texture_handle, 0);
|
||||||
[compute_encoder dispatchThreads:MTLSizeMake(extent[0],
|
[compute_encoder dispatchThreads:MTLSizeMake(extent[0],
|
||||||
extent[1],
|
extent[1],
|
||||||
@ -848,7 +843,7 @@ void gpu::MTLTexture::update_sub(
|
|||||||
ctx->pipeline_state.unpack_row_length);
|
ctx->pipeline_state.unpack_row_length);
|
||||||
int bytes_per_image = bytes_per_row * extent[1];
|
int bytes_per_image = bytes_per_row * extent[1];
|
||||||
[blit_encoder copyFromBuffer:staging_buffer
|
[blit_encoder copyFromBuffer:staging_buffer
|
||||||
sourceOffset:staging_buffer_offset
|
sourceOffset:0
|
||||||
sourceBytesPerRow:bytes_per_row
|
sourceBytesPerRow:bytes_per_row
|
||||||
sourceBytesPerImage:bytes_per_image
|
sourceBytesPerImage:bytes_per_image
|
||||||
sourceSize:MTLSizeMake(extent[0], extent[1], extent[2])
|
sourceSize:MTLSizeMake(extent[0], extent[1], extent[2])
|
||||||
@ -871,7 +866,7 @@ void gpu::MTLTexture::update_sub(
|
|||||||
MTLComputeState &cs = ctx->main_command_buffer.get_compute_state();
|
MTLComputeState &cs = ctx->main_command_buffer.get_compute_state();
|
||||||
cs.bind_pso(pso);
|
cs.bind_pso(pso);
|
||||||
cs.bind_compute_bytes(¶ms, sizeof(params), 0);
|
cs.bind_compute_bytes(¶ms, sizeof(params), 0);
|
||||||
cs.bind_compute_buffer(staging_buffer, staging_buffer_offset, 1);
|
cs.bind_compute_buffer(staging_buffer, 0, 1);
|
||||||
cs.bind_compute_texture(texture_handle, 0);
|
cs.bind_compute_texture(texture_handle, 0);
|
||||||
[compute_encoder
|
[compute_encoder
|
||||||
dispatchThreads:MTLSizeMake(
|
dispatchThreads:MTLSizeMake(
|
||||||
@ -896,7 +891,7 @@ void gpu::MTLTexture::update_sub(
|
|||||||
int face_index = offset[2] + i;
|
int face_index = offset[2] + i;
|
||||||
|
|
||||||
[blit_encoder copyFromBuffer:staging_buffer
|
[blit_encoder copyFromBuffer:staging_buffer
|
||||||
sourceOffset:staging_buffer_offset + texture_array_relative_offset
|
sourceOffset:texture_array_relative_offset
|
||||||
sourceBytesPerRow:bytes_per_row
|
sourceBytesPerRow:bytes_per_row
|
||||||
sourceBytesPerImage:bytes_per_image
|
sourceBytesPerImage:bytes_per_image
|
||||||
sourceSize:MTLSizeMake(extent[0], extent[1], 1)
|
sourceSize:MTLSizeMake(extent[0], extent[1], 1)
|
||||||
@ -930,7 +925,7 @@ void gpu::MTLTexture::update_sub(
|
|||||||
for (int i = 0; i < extent[2]; i++) {
|
for (int i = 0; i < extent[2]; i++) {
|
||||||
int face_index = offset[2] + i;
|
int face_index = offset[2] + i;
|
||||||
[blit_encoder copyFromBuffer:staging_buffer
|
[blit_encoder copyFromBuffer:staging_buffer
|
||||||
sourceOffset:staging_buffer_offset + texture_array_relative_offset
|
sourceOffset:texture_array_relative_offset
|
||||||
sourceBytesPerRow:bytes_per_row
|
sourceBytesPerRow:bytes_per_row
|
||||||
sourceBytesPerImage:bytes_per_image
|
sourceBytesPerImage:bytes_per_image
|
||||||
sourceSize:MTLSizeMake(extent[0], extent[1], 1)
|
sourceSize:MTLSizeMake(extent[0], extent[1], 1)
|
||||||
@ -1058,6 +1053,11 @@ void gpu::MTLTexture::update_sub(
|
|||||||
|
|
||||||
/* Decrement texture reference counts. This ensures temporary texture views are released. */
|
/* Decrement texture reference counts. This ensures temporary texture views are released. */
|
||||||
[texture_handle release];
|
[texture_handle release];
|
||||||
|
|
||||||
|
/* Release temporary staging buffer allocation.
|
||||||
|
* NOTE: Allocation will be tracked with command submission and released once no longer in use.
|
||||||
|
*/
|
||||||
|
temp_allocation->free();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user