Merge branch 'blender-v4.5-release'

This commit is contained in:
Miguel Pozo
2025-07-09 15:16:46 +02:00
5 changed files with 56 additions and 19 deletions

View File

@@ -132,13 +132,20 @@ void DRW_render_gpencil(RenderEngine *engine, Depsgraph *depsgraph);
void DRW_render_context_enable(Render *render);
void DRW_render_context_disable(Render *render);
void DRW_mutexes_init();
void DRW_mutexes_exit();
/* Mutex to lock the drw manager and avoid concurrent context usage.
* Equivalent to the old DST lock.
* Brought back to 4.5 due to unforeseen issues causing data races and race conditions with Images
* and GPUTextures. (See #141253) */
void DRW_lock_start();
void DRW_lock_end();
/* Critical section for GPUShader usage. Can be removed when we have threadsafe GPUShader class. */
void DRW_submission_start();
void DRW_submission_end();
void DRW_submission_mutex_init();
void DRW_submission_mutex_exit();
void DRW_gpu_context_create();
void DRW_gpu_context_destroy();
/**

View File

@@ -209,13 +209,17 @@ void MaterialModule::end_sync()
for (auto i : range) {
GPUMaterialTexture *tex = texture_loading_queue_[i];
ImageUser *iuser = tex->iuser_available ? &tex->iuser : nullptr;
BKE_image_tag_time(tex->ima);
BKE_image_get_tile(tex->ima, 0);
ImBuf *imbuf = BKE_image_acquire_ibuf(tex->ima, iuser, nullptr);
BKE_image_release_ibuf(tex->ima, imbuf, nullptr);
}
});
/* Tag time is not thread-safe. */
for (GPUMaterialTexture *tex : texture_loading_queue_) {
BKE_image_tag_time(tex->ima);
}
/* Upload to the GPU (create GPUTexture). This part still requires a valid GPU context and
* is not easily parallelized. */
for (GPUMaterialTexture *tex : texture_loading_queue_) {

View File

@@ -28,18 +28,33 @@
* between render engine instances, we cannot allow pass submissions in a concurrent manner.
* \{ */
static TicketMutex *draw_mutex = nullptr;
static TicketMutex *submission_mutex = nullptr;
void DRW_submission_mutex_init()
void DRW_mutexes_init()
{
draw_mutex = BLI_ticket_mutex_alloc();
submission_mutex = BLI_ticket_mutex_alloc();
}
void DRW_submission_mutex_exit()
void DRW_mutexes_exit()
{
BLI_ticket_mutex_free(draw_mutex);
BLI_ticket_mutex_free(submission_mutex);
}
void DRW_lock_start()
{
bool locked = BLI_ticket_mutex_lock_check_recursive(draw_mutex);
BLI_assert(locked);
UNUSED_VARS_NDEBUG(locked);
}
void DRW_lock_end()
{
BLI_ticket_mutex_unlock(draw_mutex);
}
void DRW_submission_start()
{
bool locked = BLI_ticket_mutex_lock_check_recursive(submission_mutex);
@@ -95,6 +110,7 @@ class ContextShared {
void enable()
{
DRW_lock_start();
/* IMPORTANT: We don't support immediate mode in render mode!
* This shall remain in effect until immediate mode supports
* multiple threads. */
@@ -124,6 +140,7 @@ class ContextShared {
GPU_render_end();
BLI_ticket_mutex_unlock(mutex_);
DRW_lock_end();
}
};
@@ -145,7 +162,7 @@ void DRW_gpu_context_create()
{
BLI_assert(viewport_context == nullptr); /* Ensure it's called once */
DRW_submission_mutex_init();
DRW_mutexes_init();
viewport_context = MEM_new<ContextShared>(__func__);
preview_context = MEM_new<ContextShared>(__func__);
@@ -164,7 +181,7 @@ void DRW_gpu_context_destroy()
if (viewport_context == nullptr) {
return;
}
DRW_submission_mutex_exit();
DRW_mutexes_exit();
MEM_SAFE_DELETE(viewport_context);
MEM_SAFE_DELETE(preview_context);
@@ -237,12 +254,14 @@ void DRW_system_gpu_render_context_enable(void *re_system_gpu_context)
/* If thread is main you should use DRW_gpu_context_enable(). */
BLI_assert(!BLI_thread_is_main());
DRW_lock_start();
WM_system_gpu_context_activate(re_system_gpu_context);
}
void DRW_system_gpu_render_context_disable(void *re_system_gpu_context)
{
WM_system_gpu_context_release(re_system_gpu_context);
DRW_lock_end();
}
void DRW_blender_gpu_render_context_enable(void *re_gpu_context)
@@ -346,6 +365,7 @@ void DRW_xr_drawing_begin()
{
/* XXX: See comment on #DRW_system_gpu_context_get(). */
DRW_lock_start();
BLI_ticket_mutex_lock(viewport_context->mutex_);
}
@@ -354,6 +374,7 @@ void DRW_xr_drawing_end()
/* XXX: See comment on #DRW_system_gpu_context_get(). */
BLI_ticket_mutex_unlock(viewport_context->mutex_);
DRW_lock_end();
}
#endif

View File

@@ -14,12 +14,12 @@ namespace blender::draw {
void DrawOpenGLTest::SetUp()
{
GPUOpenGLTest::SetUp();
DRW_submission_mutex_init();
DRW_mutexes_init();
}
void DrawOpenGLTest::TearDown()
{
DRW_submission_mutex_exit();
DRW_mutexes_exit();
GPUOpenGLTest::TearDown();
}
#endif
@@ -28,12 +28,12 @@ void DrawOpenGLTest::TearDown()
void DrawMetalTest::SetUp()
{
GPUMetalTest::SetUp();
DRW_submission_mutex_init();
DRW_mutexes_init();
}
void DrawMetalTest::TearDown()
{
DRW_submission_mutex_exit();
DRW_mutexes_exit();
GPUMetalTest::TearDown();
}
#endif
@@ -42,12 +42,12 @@ void DrawMetalTest::TearDown()
void DrawVulkanTest::SetUp()
{
GPUVulkanTest::SetUp();
DRW_submission_mutex_init();
DRW_mutexes_init();
}
void DrawVulkanTest::TearDown()
{
DRW_submission_mutex_exit();
DRW_mutexes_exit();
GPUVulkanTest::TearDown();
}
#endif

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# SPDX-FileCopyrightText: 2015-2022 Blender Authors
# SPDX-FileCopyrightText: 2015-2025 Blender Authors
#
# SPDX-License-Identifier: Apache-2.0
@@ -20,7 +20,7 @@ def get_compositor_device_setter_script(execution_device):
return f"import bpy; bpy.data.scenes[0].render.compositor_device = '{execution_device}'"
def get_arguments(filepath, output_filepath, execution_device):
def get_arguments(filepath, output_filepath, backend):
arguments = [
"--background",
"--factory-startup",
@@ -28,6 +28,11 @@ def get_arguments(filepath, output_filepath, execution_device):
"--debug-memory",
"--debug-exit-on-error"]
execution_device = "CPU"
if backend != "CPU":
execution_device = "GPU"
arguments.extend(["--gpu-backend", backend])
arguments.extend([
filepath,
"-P", os.path.realpath(__file__),
@@ -56,8 +61,8 @@ def main():
args = parser.parse_args()
from modules import render_report
execution_device = "GPU" if args.gpu_backend else "CPU"
report_title = f"Compositor {execution_device}"
backend = args.gpu_backend if args.gpu_backend else "CPU"
report_title = f"Compositor {backend.upper()}"
report = render_report.Report(report_title, args.outdir, args.oiiotool)
report.set_pixelated(True)
report.set_reference_dir("compositor_renders")
@@ -73,7 +78,7 @@ def main():
report.set_fail_threshold(0.06)
report.set_fail_percent(2)
def arguments_callback(filepath, output_filepath): return get_arguments(filepath, output_filepath, execution_device)
def arguments_callback(filepath, output_filepath): return get_arguments(filepath, output_filepath, backend)
ok = report.run(args.testdir, args.blender, arguments_callback, batch=args.batch)
sys.exit(not ok)