main sync #3

Merged
Patrick Busch merged 318 commits from blender/blender:main into main 2023-03-17 15:52:21 +01:00
5 changed files with 123 additions and 76 deletions
Showing only changes of commit 023524765a - Show all commits

View File

@ -161,25 +161,12 @@ ShaderCache::~ShaderCache()
running = false; running = false;
cond_var.notify_all(); cond_var.notify_all();
int num_incomplete = int(incomplete_requests); metal_printf("Waiting for ShaderCache threads... (incomplete_requests = %d)\n",
if (num_incomplete) { int(incomplete_requests));
/* Shutting down the app with incomplete shader compilation requests. Give 1 second's grace for
* clean shutdown. */
metal_printf("ShaderCache busy (incomplete_requests = %d)...\n", num_incomplete);
std::this_thread::sleep_for(std::chrono::seconds(1));
num_incomplete = int(incomplete_requests);
}
if (num_incomplete && !MetalDeviceKernels::is_benchmark_warmup()) {
metal_printf("ShaderCache still busy (incomplete_requests = %d). Terminating...\n",
num_incomplete);
std::terminate();
}
metal_printf("ShaderCache idle. Shutting down.\n");
for (auto &thread : compile_threads) { for (auto &thread : compile_threads) {
thread.join(); thread.join();
} }
metal_printf("ShaderCache shut down.\n");
} }
void ShaderCache::wait_for_all() void ShaderCache::wait_for_all()
@ -675,7 +662,9 @@ void MetalKernelPipeline::compile()
} }
} }
__block bool creating_new_archive = false; bool creating_new_archive = false;
bool recreate_archive = false;
if (@available(macOS 11.0, *)) { if (@available(macOS 11.0, *)) {
if (use_binary_archive) { if (use_binary_archive) {
if (!archive) { if (!archive) {
@ -684,51 +673,101 @@ void MetalKernelPipeline::compile()
archive = [mtlDevice newBinaryArchiveWithDescriptor:archiveDesc error:nil]; archive = [mtlDevice newBinaryArchiveWithDescriptor:archiveDesc error:nil];
creating_new_archive = true; creating_new_archive = true;
} }
computePipelineStateDescriptor.binaryArchives = [NSArray arrayWithObjects:archive, nil]; else {
pipelineOptions = MTLPipelineOptionFailOnBinaryArchiveMiss; pipelineOptions = MTLPipelineOptionFailOnBinaryArchiveMiss;
computePipelineStateDescriptor.binaryArchives = [NSArray arrayWithObjects:archive, nil];
}
} }
} }
/* Lambda to do the actual pipeline compilation. */
auto do_compilation = [&]() {
__block bool compilation_finished = false;
__block string error_str;
if (archive && path_exists(metalbin_path)) {
/* Use the blocking variant of newComputePipelineStateWithDescriptor if an archive exists on
* disk. It should load almost instantaneously, and will fail gracefully when loading a
* corrupt archive (unlike the async variant). */
NSError *error = nil;
pipeline = [mtlDevice newComputePipelineStateWithDescriptor:computePipelineStateDescriptor
options:pipelineOptions
reflection:nullptr
error:&error];
const char *err = error ? [[error localizedDescription] UTF8String] : nullptr;
error_str = err ? err : "nil";
}
else {
/* Use the async variant of newComputePipelineStateWithDescriptor if no archive exists on
* disk. This allows us responds to app shutdown. */
[mtlDevice
newComputePipelineStateWithDescriptor:computePipelineStateDescriptor
options:pipelineOptions
completionHandler:^(id<MTLComputePipelineState> computePipelineState,
MTLComputePipelineReflection *reflection,
NSError *error) {
pipeline = computePipelineState;
/* Retain the pipeline so we can use it safely past the completion
* handler. */
if (pipeline) {
[pipeline retain];
}
const char *err = error ?
[[error localizedDescription] UTF8String] :
nullptr;
error_str = err ? err : "nil";
compilation_finished = true;
}];
/* Immediately wait for either the compilation to finish or for app shutdown. */
while (ShaderCache::running && !compilation_finished) {
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
}
if (creating_new_archive && pipeline && ShaderCache::running) {
/* Add pipeline into the new archive. It should be instantaneous following
* newComputePipelineStateWithDescriptor. */
NSError *error;
computePipelineStateDescriptor.binaryArchives = [NSArray arrayWithObjects:archive, nil];
if (![archive addComputePipelineFunctionsWithDescriptor:computePipelineStateDescriptor
error:&error]) {
NSString *errStr = [error localizedDescription];
metal_printf("Failed to add PSO to archive:\n%s\n", errStr ? [errStr UTF8String] : "nil");
}
}
else if (!pipeline) {
metal_printf(
"newComputePipelineStateWithDescriptor failed for \"%s\"%s. "
"Error:\n%s\n",
device_kernel_as_string((DeviceKernel)device_kernel),
(archive && !recreate_archive) ? " Archive may be incomplete or corrupt - attempting "
"recreation.." :
"",
error_str.c_str());
}
};
double starttime = time_dt(); double starttime = time_dt();
/* Block on load to ensure we continue with a valid kernel function */ do_compilation();
if (creating_new_archive) {
starttime = time_dt();
NSError *error;
if (![archive addComputePipelineFunctionsWithDescriptor:computePipelineStateDescriptor
error:&error]) {
NSString *errStr = [error localizedDescription];
metal_printf("Failed to add PSO to archive:\n%s\n", errStr ? [errStr UTF8String] : "nil");
}
}
pipeline = [mtlDevice newComputePipelineStateWithDescriptor:computePipelineStateDescriptor /* An archive might have a corrupt entry and fail to materialize the pipeline. This shouldn't
options:pipelineOptions * happen, but if it does we recreate it. */
reflection:nullptr
error:&error];
bool recreate_archive = false;
if (pipeline == nil && archive) { if (pipeline == nil && archive) {
NSString *errStr = [error localizedDescription];
metal_printf(
"Failed to create compute pipeline state \"%s\" from archive - attempting recreation... "
"(error: %s)\n",
device_kernel_as_string((DeviceKernel)device_kernel),
errStr ? [errStr UTF8String] : "nil");
pipeline = [mtlDevice newComputePipelineStateWithDescriptor:computePipelineStateDescriptor
options:MTLPipelineOptionNone
reflection:nullptr
error:&error];
recreate_archive = true; recreate_archive = true;
pipelineOptions = MTLPipelineOptionNone;
path_remove(metalbin_path);
do_compilation();
} }
double duration = time_dt() - starttime; double duration = time_dt() - starttime;
if (pipeline == nil) { if (pipeline == nil) {
NSString *errStr = [error localizedDescription];
error_str = string_printf("Failed to create compute pipeline state \"%s\", error: \n",
device_kernel_as_string((DeviceKernel)device_kernel));
error_str += (errStr ? [errStr UTF8String] : "nil");
metal_printf("%16s | %2d | %-55s | %7.2fs | FAILED!\n", metal_printf("%16s | %2d | %-55s | %7.2fs | FAILED!\n",
kernel_type_as_string(pso_type), kernel_type_as_string(pso_type),
device_kernel, device_kernel,
@ -748,7 +787,8 @@ void MetalKernelPipeline::compile()
if (creating_new_archive || recreate_archive) { if (creating_new_archive || recreate_archive) {
if (![archive serializeToURL:[NSURL fileURLWithPath:@(metalbin_path.c_str())] if (![archive serializeToURL:[NSURL fileURLWithPath:@(metalbin_path.c_str())]
error:&error]) { error:&error]) {
metal_printf("Failed to save binary archive, error:\n%s\n", metal_printf("Failed to save binary archive to %s, error:\n%s\n",
metalbin_path.c_str(),
[[error localizedDescription] UTF8String]); [[error localizedDescription] UTF8String]);
} }
else { else {

View File

@ -13,6 +13,7 @@
#ifndef __FFMPEG_COMPAT_H__ #ifndef __FFMPEG_COMPAT_H__
#define __FFMPEG_COMPAT_H__ #define __FFMPEG_COMPAT_H__
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h> #include <libavformat/avformat.h>
/* Check if our ffmpeg is new enough, avoids user complaints. /* Check if our ffmpeg is new enough, avoids user complaints.

View File

@ -5912,7 +5912,8 @@ static bool ui_layout_has_panel_label(const uiLayout *layout, const PanelType *p
LISTBASE_FOREACH (uiItem *, subitem, &layout->items) { LISTBASE_FOREACH (uiItem *, subitem, &layout->items) {
if (subitem->type == ITEM_BUTTON) { if (subitem->type == ITEM_BUTTON) {
uiButtonItem *bitem = (uiButtonItem *)subitem; uiButtonItem *bitem = (uiButtonItem *)subitem;
if (!(bitem->but->flag & UI_HIDDEN) && STREQ(bitem->but->str, pt->label)) { if (!(bitem->but->flag & UI_HIDDEN) &&
STREQ(bitem->but->str, CTX_IFACE_(pt->translation_context, pt->label))) {
return true; return true;
} }
} }

View File

@ -62,11 +62,24 @@ template<> uint denormalize<uint>(float val)
return uint(float(DEPTH_SCALE_FACTOR) * val); return uint(float(DEPTH_SCALE_FACTOR) * val);
} }
/* Float to other type case. */
template<typename T> T convert_type(float type) template<typename T> T convert_type(float type)
{ {
return T(type); return T(type);
} }
/* Uint to other types. */
template<typename T> T convert_type(uint type)
{
return T(type);
}
/* Int to other types. */
template<typename T> T convert_type(int type)
{
return T(type);
}
template<> uchar convert_type<uchar>(float val) template<> uchar convert_type<uchar>(float val)
{ {
return uchar(val * float(0xFF)); return uchar(val * float(0xFF));
@ -141,8 +154,8 @@ kernel void compute_texture_read(constant TextureReadParams &params [[buffer(0)]
uint xx = position[0]; uint xx = position[0];
uint yy = position[1]; uint yy = position[1];
uint zz = position[2]; uint zz = position[2];
int index = (zz * (params.extent[0] * params.extent[1]) + yy * params.extnt[0] + xx) * int index = (zz * (params.extent[0] * params.extent[1]) + yy * params.extent[0] + xx) *
COMPONENT_COUNT_INPUT; COMPONENT_COUNT_OUTPUT;
read_colour = read_tex.read(uint3(params.offset[0], params.offset[1], params.offset[2]) + read_colour = read_tex.read(uint3(params.offset[0], params.offset[1], params.offset[2]) +
uint3(xx, yy, zz)); uint3(xx, yy, zz));
@ -163,7 +176,7 @@ kernel void compute_texture_read(constant TextureReadParams &params [[buffer(0)]
uint yy = position[1]; uint yy = position[1];
uint layer = position[2]; uint layer = position[2];
int index = (layer * (params.extent[0] * params.extent[1]) + yy * params.extent[0] + xx) * int index = (layer * (params.extent[0] * params.extent[1]) + yy * params.extent[0] + xx) *
COMPONENT_COUNT_INPUT; COMPONENT_COUNT_OUTPUT;
/* Read data */ /* Read data */
# if IS_DEPTH_FORMAT == 1 # if IS_DEPTH_FORMAT == 1

View File

@ -606,17 +606,6 @@ void MTLFrameBuffer::update_attachments(bool update_viewport)
if (!dirty_attachments_) { if (!dirty_attachments_) {
return; return;
} }
/* Cache viewport and scissor (If we have existing attachments). */
int t_viewport[4], t_scissor[4];
update_viewport = update_viewport &&
(this->get_attachment_count() > 0 && this->has_depth_attachment() &&
this->has_stencil_attachment());
if (update_viewport) {
this->viewport_get(t_viewport);
this->scissor_get(t_scissor);
}
/* Clear current attachments state. */ /* Clear current attachments state. */
this->remove_all_attachments(); this->remove_all_attachments();
@ -738,22 +727,25 @@ void MTLFrameBuffer::update_attachments(bool update_viewport)
} }
} }
/* Check whether the first attachment is SRGB. */ /* Extract attachment size and determine if framebuffer is SRGB. */
if (first_attachment != GPU_FB_MAX_ATTACHMENT) { if (first_attachment != GPU_FB_MAX_ATTACHMENT) {
srgb_ = (first_attachment_mtl.texture->format_get() == GPU_SRGB8_A8); /* Ensure size is correctly assigned. */
} GPUAttachment &attach = attachments_[first_attachment];
int size[3];
/* Reset viewport and Scissor (If viewport is smaller or equal to the framebuffer size). */ GPU_texture_get_mipmap_size(attach.tex, attach.mip, size);
if (update_viewport && t_viewport[2] <= width_ && t_viewport[3] <= height_) { this->size_set(size[0], size[1]);
srgb_ = (GPU_texture_format(attach.tex) == GPU_SRGB8_A8);
this->viewport_set(t_viewport);
this->scissor_set(t_viewport);
} }
else { else {
this->viewport_reset(); /* Empty frame-buffer. */
this->scissor_reset(); width_ = 0;
height_ = 0;
} }
/* Reset viewport and Scissor. */
this->viewport_reset();
this->scissor_reset();
/* We have now updated our internal structures. */ /* We have now updated our internal structures. */
dirty_attachments_ = false; dirty_attachments_ = false;
} }