Cycles: Metal: Fix occasional anim corruption (KernelData MD5 refresh bug)
This fixes an issue where animation frames occasionally get corrupted (e.g. when rendering "Pokedstudio" Blender 2.77 splash screen). This happens when the KernelData is refreshed but the MD5 isn't immediately regenerated which can cause the wrong PSO to be selected. Pull Request: https://projects.blender.org/blender/blender/pulls/114153
This commit is contained in:
committed by
Michael Jones (Apple)
parent
a5cf5a00fb
commit
af9ffee152
@@ -122,7 +122,7 @@ class MetalDevice : public Device {
|
||||
const uint kernel_features,
|
||||
string *source = nullptr);
|
||||
|
||||
bool make_source_and_check_if_compile_needed(MetalPipelineType pso_type);
|
||||
void refresh_source_and_kernels_md5(MetalPipelineType pso_type);
|
||||
|
||||
void make_source(MetalPipelineType pso_type, const uint kernel_features);
|
||||
|
||||
|
||||
@@ -455,7 +455,8 @@ bool MetalDevice::load_kernels(const uint _kernel_features)
|
||||
motion_blur = kernel_features & KERNEL_FEATURE_OBJECT_MOTION;
|
||||
|
||||
/* Only request generic kernels if they aren't cached in memory. */
|
||||
if (make_source_and_check_if_compile_needed(PSO_GENERIC)) {
|
||||
refresh_source_and_kernels_md5(PSO_GENERIC);
|
||||
if (MetalDeviceKernels::should_load_kernels(this, PSO_GENERIC)) {
|
||||
/* If needed, load them asynchronously in order to responsively message progress to the user.
|
||||
*/
|
||||
int this_device_id = this->device_id;
|
||||
@@ -470,7 +471,7 @@ bool MetalDevice::load_kernels(const uint _kernel_features)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MetalDevice::make_source_and_check_if_compile_needed(MetalPipelineType pso_type)
|
||||
void MetalDevice::refresh_source_and_kernels_md5(MetalPipelineType pso_type)
|
||||
{
|
||||
string defines_md5 = preprocess_source(pso_type, kernel_features);
|
||||
|
||||
@@ -514,8 +515,6 @@ bool MetalDevice::make_source_and_check_if_compile_needed(MetalPipelineType pso_
|
||||
md5.append(string_printf("metalrt_features=%d", kernel_features & METALRT_FEATURE_MASK));
|
||||
}
|
||||
kernels_md5[pso_type] = md5.get_hex();
|
||||
|
||||
return MetalDeviceKernels::should_load_kernels(this, pso_type);
|
||||
}
|
||||
|
||||
void MetalDevice::compile_and_load(int device_id, MetalPipelineType pso_type)
|
||||
@@ -540,7 +539,7 @@ void MetalDevice::compile_and_load(int device_id, MetalPipelineType pso_type)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!instance->make_source_and_check_if_compile_needed(pso_type)) {
|
||||
if (!MetalDeviceKernels::should_load_kernels(instance, pso_type)) {
|
||||
/* We already have a full set of matching pipelines which are cached or queued. Return
|
||||
* early to avoid redundant MTLLibrary compilation. */
|
||||
metal_printf("Ignoreing %s compilation request - kernels already requested\n",
|
||||
@@ -1041,6 +1040,11 @@ void MetalDevice::const_copy_to(const char *name, void *host, size_t size)
|
||||
if (strcmp(name, "data") == 0) {
|
||||
assert(size == sizeof(KernelData));
|
||||
memcpy((uint8_t *)&launch_params.data, host, sizeof(KernelData));
|
||||
|
||||
/* Refresh the kernels_md5 checksums for specialized kernel sets. */
|
||||
for (int level = 1; level <= int(kernel_specialization_level); level++) {
|
||||
refresh_source_and_kernels_md5(MetalPipelineType(level));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user