mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
Merge branch 'blender-v5.2-release'
# Conflicts: # source/blender/sequencer/intern/utils.cc
This commit is contained in:
commit
01ff4fb425
10 changed files with 262 additions and 72 deletions
|
|
@ -322,6 +322,15 @@ void Film::init(const int2 &extent, const rcti *output_rect)
|
|||
enabled_passes_ = enabled_passes(inst_.view_layer);
|
||||
}
|
||||
|
||||
/* Force enable color passes if light passes are enabled.
|
||||
* This is needed since we need to pre-divide by them. */
|
||||
if (enabled_passes_ & EEVEE_RENDER_PASS_DIFFUSE_LIGHT) {
|
||||
enabled_passes_ |= EEVEE_RENDER_PASS_DIFFUSE_COLOR;
|
||||
}
|
||||
if (enabled_passes_ & EEVEE_RENDER_PASS_SPECULAR_LIGHT) {
|
||||
enabled_passes_ |= EEVEE_RENDER_PASS_SPECULAR_COLOR;
|
||||
}
|
||||
|
||||
/* Filter obsolete passes. */
|
||||
enabled_passes_ &= ~(EEVEE_RENDER_PASS_UNUSED_8 | EEVEE_RENDER_PASS_UNUSED_14);
|
||||
|
||||
|
|
@ -393,11 +402,11 @@ void Film::init(const int2 &extent, const rcti *output_rect)
|
|||
EEVEE_RENDER_PASS_POSITION |
|
||||
EEVEE_RENDER_PASS_VECTOR;
|
||||
const eViewLayerEEVEEPassType color_passes_1 = EEVEE_RENDER_PASS_DIFFUSE_LIGHT |
|
||||
EEVEE_RENDER_PASS_DIFFUSE_COLOR |
|
||||
EEVEE_RENDER_PASS_SPECULAR_LIGHT |
|
||||
EEVEE_RENDER_PASS_VOLUME_LIGHT |
|
||||
EEVEE_RENDER_PASS_EMIT;
|
||||
const eViewLayerEEVEEPassType color_passes_2 = EEVEE_RENDER_PASS_DIFFUSE_COLOR |
|
||||
EEVEE_RENDER_PASS_SPECULAR_COLOR |
|
||||
EEVEE_RENDER_PASS_SPECULAR_COLOR;
|
||||
const eViewLayerEEVEEPassType color_passes_2 = EEVEE_RENDER_PASS_VOLUME_LIGHT |
|
||||
EEVEE_RENDER_PASS_EMIT |
|
||||
EEVEE_RENDER_PASS_ENVIRONMENT |
|
||||
EEVEE_RENDER_PASS_MIST |
|
||||
EEVEE_RENDER_PASS_SHADOW | EEVEE_RENDER_PASS_AO;
|
||||
|
|
|
|||
|
|
@ -138,15 +138,15 @@ void combine_frag([[resource_table]] Combine &srt,
|
|||
case CLOSURE_BSSRDF_BURLEY_ID:
|
||||
case CLOSURE_BSDF_DIFFUSE_ID:
|
||||
diffuse_color += cl.color;
|
||||
diffuse_direct += closure_direct_light;
|
||||
diffuse_indirect += closure_indirect_light;
|
||||
diffuse_direct += closure_direct_light * cl.color;
|
||||
diffuse_indirect += closure_indirect_light * cl.color;
|
||||
break;
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_REFLECTION_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
|
||||
case CLOSURE_BSDF_THIN_GLASS_TRANSMISSION_ID:
|
||||
specular_color += cl.color;
|
||||
specular_direct += closure_direct_light;
|
||||
specular_indirect += closure_indirect_light;
|
||||
specular_direct += closure_direct_light * cl.color;
|
||||
specular_indirect += closure_indirect_light * cl.color;
|
||||
break;
|
||||
case CLOSURE_NONE_ID:
|
||||
assert(false);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include "gpu_shader_fullscreen_lib.glsl"
|
||||
#include "gpu_shader_math_safe_lib.glsl"
|
||||
#include "gpu_shader_math_vector_lib.glsl"
|
||||
#include "gpu_shader_math_vector_safe_lib.glsl"
|
||||
|
||||
namespace eevee::film {
|
||||
|
||||
|
|
@ -77,6 +78,38 @@ float patch_float_for_16f_storage(float value)
|
|||
return uintBitsToFloat(floatBitsToUint(value) + 0x1000);
|
||||
}
|
||||
|
||||
float4 safe_divide_even_color(float4 a, float4 b)
|
||||
{
|
||||
a *= safe_rcp(b);
|
||||
/* Try to get gray even if b is zero. */
|
||||
if (b.x == 0.0f) {
|
||||
if (b.y == 0.0f) {
|
||||
a.x = a.z;
|
||||
a.y = a.z;
|
||||
}
|
||||
else if (b.z == 0.0f) {
|
||||
a.x = a.y;
|
||||
a.z = a.y;
|
||||
}
|
||||
else {
|
||||
a.x = 0.5f * (a.y + a.z);
|
||||
}
|
||||
}
|
||||
else if (b.y == 0.0f) {
|
||||
if (b.z == 0.0f) {
|
||||
a.y = a.x;
|
||||
a.z = a.x;
|
||||
}
|
||||
else {
|
||||
a.y = 0.5f * (a.x + a.z);
|
||||
}
|
||||
}
|
||||
else if (b.z == 0.0f) {
|
||||
a.z = 0.5f * (a.x + a.y);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
struct Film {
|
||||
[[resource_table]] srt_t<CameraVelocity> camera;
|
||||
[[resource_table]] srt_t<draw::View> views_;
|
||||
|
|
@ -630,20 +663,9 @@ struct Film {
|
|||
imageStoreFast(out_combined_img, dst.texel, color);
|
||||
}
|
||||
|
||||
void store_color(FilmSample dst,
|
||||
int pass_id,
|
||||
float4 color,
|
||||
float4 &display,
|
||||
bool do_clamp_negative_values = true)
|
||||
void store_color_ex(
|
||||
FilmSample dst, int pass_id, float4 color, float4 &display, bool do_clamp_negative_values)
|
||||
{
|
||||
if (pass_id == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
float4 data_film = imageLoadFast(color_accum_img, int3(dst.texel, pass_id));
|
||||
|
||||
color = (data_film * dst.weight + color) * dst.weight_sum_inv;
|
||||
|
||||
/* Filter NaNs. */
|
||||
if (any(isnan(color))) {
|
||||
color = float4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
|
@ -666,6 +688,50 @@ struct Film {
|
|||
imageStoreFast(color_accum_img, int3(dst.texel, pass_id), color);
|
||||
}
|
||||
|
||||
void store_color(FilmSample dst,
|
||||
int pass_id,
|
||||
float4 color,
|
||||
float4 &display,
|
||||
bool do_clamp_negative_values = true)
|
||||
{
|
||||
if (pass_id == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
float4 data_film = imageLoadFast(color_accum_img, int3(dst.texel, pass_id));
|
||||
|
||||
color = (data_film * dst.weight + color) * dst.weight_sum_inv;
|
||||
|
||||
store_color_ex(dst, pass_id, color, display, do_clamp_negative_values);
|
||||
}
|
||||
|
||||
void store_color_and_light(FilmSample dst,
|
||||
int color_pass_id,
|
||||
int light_pass_id,
|
||||
float4 color,
|
||||
float4 light,
|
||||
float4 &display)
|
||||
{
|
||||
if (color_pass_id == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
float4 color_film = imageLoadFast(color_accum_img, int3(dst.texel, color_pass_id));
|
||||
color = (color_film * dst.weight + color) * dst.weight_sum_inv;
|
||||
store_color_ex(dst, color_pass_id, color, display, true);
|
||||
|
||||
if (light_pass_id == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
float4 light_film = imageLoadFast(color_accum_img, int3(dst.texel, light_pass_id));
|
||||
/* Undivide. */
|
||||
light_film *= color_film;
|
||||
light = (light_film * dst.weight + light) * dst.weight_sum_inv;
|
||||
light = safe_divide_even_color(light, color);
|
||||
store_color_ex(dst, light_pass_id, light, display, true);
|
||||
}
|
||||
|
||||
void store_value(FilmSample dst, int pass_id, float value, float4 &display)
|
||||
{
|
||||
if (pass_id == -1) {
|
||||
|
|
@ -807,47 +873,10 @@ struct Film {
|
|||
}
|
||||
|
||||
if (flag_test(enabled_categories, PASS_CATEGORY_COLOR_1)) {
|
||||
float4 diffuse_light_accum = float4(0.0f);
|
||||
float4 specular_light_accum = float4(0.0f);
|
||||
float4 volume_light_accum = float4(0.0f);
|
||||
float4 emission_accum = float4(0.0f);
|
||||
|
||||
for (int i = 0; i < samples_len; i++) {
|
||||
FilmSample src = sample_get(i, texel_film);
|
||||
sample_accum(src,
|
||||
uni.uniform_buf.film.diffuse_light_id,
|
||||
uni.uniform_buf.render_pass.diffuse_light_id,
|
||||
rp_color_tx,
|
||||
diffuse_light_accum);
|
||||
sample_accum(src,
|
||||
uni.uniform_buf.film.specular_light_id,
|
||||
uni.uniform_buf.render_pass.specular_light_id,
|
||||
rp_color_tx,
|
||||
specular_light_accum);
|
||||
sample_accum(src,
|
||||
uni.uniform_buf.film.volume_light_id,
|
||||
uni.uniform_buf.render_pass.volume_light_id,
|
||||
rp_color_tx,
|
||||
volume_light_accum);
|
||||
sample_accum(src,
|
||||
uni.uniform_buf.film.emission_id,
|
||||
uni.uniform_buf.render_pass.emission_id,
|
||||
rp_color_tx,
|
||||
emission_accum);
|
||||
}
|
||||
store_color(dst, uni.uniform_buf.film.diffuse_light_id, diffuse_light_accum, out_color);
|
||||
store_color(dst, uni.uniform_buf.film.specular_light_id, specular_light_accum, out_color);
|
||||
store_color(dst, uni.uniform_buf.film.volume_light_id, volume_light_accum, out_color);
|
||||
store_color(dst, uni.uniform_buf.film.emission_id, emission_accum, out_color);
|
||||
}
|
||||
|
||||
if (flag_test(enabled_categories, PASS_CATEGORY_COLOR_2)) {
|
||||
float4 diffuse_color_accum = float4(0.0f);
|
||||
float4 specular_color_accum = float4(0.0f);
|
||||
float4 environment_accum = float4(0.0f);
|
||||
float mist_accum = 0.0f;
|
||||
float shadow_accum = 0.0f;
|
||||
float ao_accum = 0.0f;
|
||||
float4 diffuse_light_accum = float4(0.0f);
|
||||
float4 specular_light_accum = float4(0.0f);
|
||||
|
||||
for (int i = 0; i < samples_len; i++) {
|
||||
FilmSample src = sample_get(i, texel_film);
|
||||
|
|
@ -861,6 +890,52 @@ struct Film {
|
|||
uni.uniform_buf.render_pass.specular_color_id,
|
||||
rp_color_tx,
|
||||
specular_color_accum);
|
||||
sample_accum(src,
|
||||
uni.uniform_buf.film.diffuse_light_id,
|
||||
uni.uniform_buf.render_pass.diffuse_light_id,
|
||||
rp_color_tx,
|
||||
diffuse_light_accum);
|
||||
sample_accum(src,
|
||||
uni.uniform_buf.film.specular_light_id,
|
||||
uni.uniform_buf.render_pass.specular_light_id,
|
||||
rp_color_tx,
|
||||
specular_light_accum);
|
||||
}
|
||||
|
||||
store_color_and_light(dst,
|
||||
uni.uniform_buf.film.diffuse_color_id,
|
||||
uni.uniform_buf.film.diffuse_light_id,
|
||||
diffuse_color_accum,
|
||||
diffuse_light_accum,
|
||||
out_color);
|
||||
store_color_and_light(dst,
|
||||
uni.uniform_buf.film.specular_color_id,
|
||||
uni.uniform_buf.film.specular_light_id,
|
||||
specular_color_accum,
|
||||
specular_light_accum,
|
||||
out_color);
|
||||
}
|
||||
|
||||
if (flag_test(enabled_categories, PASS_CATEGORY_COLOR_2)) {
|
||||
float4 environment_accum = float4(0.0f);
|
||||
float4 volume_light_accum = float4(0.0f);
|
||||
float4 emission_accum = float4(0.0f);
|
||||
float mist_accum = 0.0f;
|
||||
float shadow_accum = 0.0f;
|
||||
float ao_accum = 0.0f;
|
||||
|
||||
for (int i = 0; i < samples_len; i++) {
|
||||
FilmSample src = sample_get(i, texel_film);
|
||||
sample_accum(src,
|
||||
uni.uniform_buf.film.volume_light_id,
|
||||
uni.uniform_buf.render_pass.volume_light_id,
|
||||
rp_color_tx,
|
||||
volume_light_accum);
|
||||
sample_accum(src,
|
||||
uni.uniform_buf.film.emission_id,
|
||||
uni.uniform_buf.render_pass.emission_id,
|
||||
rp_color_tx,
|
||||
emission_accum);
|
||||
sample_accum(src,
|
||||
uni.uniform_buf.film.environment_id,
|
||||
uni.uniform_buf.render_pass.environment_id,
|
||||
|
|
@ -882,8 +957,8 @@ struct Film {
|
|||
float4 shadow_accum_color = float4(float3(shadow_accum), weight_accum);
|
||||
float4 ao_accum_color = float4(float3(ao_accum), weight_accum);
|
||||
|
||||
store_color(dst, uni.uniform_buf.film.diffuse_color_id, diffuse_color_accum, out_color);
|
||||
store_color(dst, uni.uniform_buf.film.specular_color_id, specular_color_accum, out_color);
|
||||
store_color(dst, uni.uniform_buf.film.volume_light_id, volume_light_accum, out_color);
|
||||
store_color(dst, uni.uniform_buf.film.emission_id, emission_accum, out_color);
|
||||
store_color(dst, uni.uniform_buf.film.environment_id, environment_accum, out_color);
|
||||
store_color(dst, uni.uniform_buf.film.shadow_id, shadow_accum_color, out_color);
|
||||
store_color(dst, uni.uniform_buf.film.ambient_occlusion_id, ao_accum_color, out_color);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "BLI_path_utils.hh"
|
||||
#include "BLI_string.hh"
|
||||
#include "BLI_string_utf8.hh"
|
||||
#include "BLI_string_utils.hh"
|
||||
|
||||
#include "BLT_translation.hh"
|
||||
|
||||
|
|
@ -87,13 +88,12 @@ void strip_unique_name_set(Scene *scene, ListBaseT<Strip> *seqbasep, Strip *stri
|
|||
sui.count = 1;
|
||||
sui.match = 1; /* assume the worst to start the loop */
|
||||
|
||||
/* Strip off the suffix */
|
||||
/* Strip off the suffix only if it is purely numeric. */
|
||||
if ((dot = strrchr(sui.name_src, '.'))) {
|
||||
*dot = '\0';
|
||||
dot++;
|
||||
|
||||
if (*dot) {
|
||||
sui.count = atoi(dot) + 1;
|
||||
char *suffix = dot + 1;
|
||||
if (BLI_string_is_decimal(suffix)) {
|
||||
*dot = '\0';
|
||||
sui.count = atoi(suffix) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3a6b0a9e9c73daa37c8074efccd5b8150132f3ddcccd028bd09525b3e94250d6
|
||||
size 13955
|
||||
oid sha256:7fa6e99f3dd1d19231e0fe51567a96cd6f594e9066d013b3cf2e33418ce94d4f
|
||||
size 12939
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2f11d0a612c752f745605788ea8c1cea06b875d33b46a192e3289c23d5dd0ade
|
||||
size 7135
|
||||
oid sha256:d45818cf24a988eed08695c26fe2dd959984be915e1fb6b81be716cf8a4d599a
|
||||
size 6598
|
||||
|
|
|
|||
|
|
@ -1526,6 +1526,11 @@ if(TEST_SRC_DIR_EXISTS)
|
|||
--testdir "${TEST_SRC_DIR}/sequence_editing"
|
||||
)
|
||||
|
||||
add_blender_test(
|
||||
sequencer_strip_naming
|
||||
--python ${CMAKE_CURRENT_LIST_DIR}/sequencer_strip_naming.py
|
||||
)
|
||||
|
||||
add_blender_test(
|
||||
sequencer_load_meta_stack
|
||||
${TEST_SRC_DIR}/sequence_editing/vse_load_meta_stack.blend
|
||||
|
|
|
|||
|
|
@ -101,6 +101,12 @@ BLOCKLIST_AMD_WINDOWS_VK = [
|
|||
"implicit_volume.blend"
|
||||
]
|
||||
|
||||
# Block list for Linux/AMD official driver. On buildbot this driver can fail and the artifacts are likely
|
||||
# caused by incorrect index buffer synchronization or vertex shader execution.
|
||||
BLOCKLIST_AMD_LINUX_VK = [
|
||||
".*"
|
||||
]
|
||||
|
||||
BLOCKLIST_INTEL_WINDOWS_GL = [
|
||||
# Fails sporadically and causes all subsequent volume tests to fail (See #153612).
|
||||
"volume_instance.blend"
|
||||
|
|
@ -295,6 +301,8 @@ def main():
|
|||
blocklist += BLOCKLIST_NVIDIA_GL
|
||||
if gpu_vendor == "AMD" and sys.platform == "win32" and args.gpu_backend == "vulkan":
|
||||
blocklist += BLOCKLIST_AMD_WINDOWS_VK
|
||||
if gpu_vendor == "AMD" and sys.platform == "linux" and args.gpu_backend == "vulkan":
|
||||
blocklist += BLOCKLIST_AMD_LINUX_VK
|
||||
|
||||
report = EEVEEReport("EEVEE", args.outdir, args.oiiotool, variation=args.gpu_backend, blocklist=blocklist)
|
||||
if args.gpu_backend == "vulkan":
|
||||
|
|
|
|||
81
tests/python/sequencer_strip_naming.py
Normal file
81
tests/python/sequencer_strip_naming.py
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
# SPDX-FileCopyrightText: 2026 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# ./blender.bin --background --factory-startup --python tests/python/sequencer_strip_naming.py
|
||||
|
||||
import bpy
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
|
||||
class StripNamingTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
bpy.context.scene.sequence_editor_create()
|
||||
self.strips = bpy.context.scene.sequence_editor.strips
|
||||
|
||||
def tearDown(self):
|
||||
bpy.context.scene.sequence_editor_clear()
|
||||
|
||||
def test_duplicate_name_gets_numeric_suffix(self):
|
||||
# identical names get .001, .002, ...
|
||||
s1 = self.strips.new_meta("Meta", 1, 1)
|
||||
s2 = self.strips.new_meta("Meta", 2, 1)
|
||||
s3 = self.strips.new_meta("Meta", 3, 1)
|
||||
self.assertEqual(s1.name, "Meta")
|
||||
self.assertEqual(s2.name, "Meta.001")
|
||||
self.assertEqual(s3.name, "Meta.002")
|
||||
|
||||
def test_purely_numeric_suffix_increments(self):
|
||||
# strip name already ends in .###: the number should be increased
|
||||
s1 = self.strips.new_meta("Clip.012", 1, 1)
|
||||
s2 = self.strips.new_meta("Clip.012", 2, 1)
|
||||
self.assertEqual(s1.name, "Clip.012")
|
||||
self.assertEqual(s2.name, "Clip.013")
|
||||
|
||||
def test_dot_number_nonnumeric_suffix_not_stripped(self):
|
||||
# a ".###" followed by more characters should not be stripped
|
||||
name = "name.123_anything_456"
|
||||
s1 = self.strips.new_meta(name, 1, 1)
|
||||
s2 = self.strips.new_meta(name, 2, 1)
|
||||
s3 = self.strips.new_meta(name, 3, 1)
|
||||
self.assertEqual(s1.name, "name.123_anything_456")
|
||||
self.assertEqual(s2.name, "name.123_anything_456.001")
|
||||
self.assertEqual(s3.name, "name.123_anything_456.002")
|
||||
|
||||
def test_isoformat_name_not_stripped(self):
|
||||
# naming case from #160144:
|
||||
# datetime.isoformat() produces names like YYYY-MM-DDTHH:MM:SS.ffffff+HH:MM
|
||||
# The ".ffffff+HH:MM" part must be preserved, not stripped
|
||||
name = "2024-01-15T12:30:45.123456+02:00"
|
||||
s1 = self.strips.new_meta(name, 1, 1)
|
||||
s2 = self.strips.new_meta(name, 2, 1)
|
||||
self.assertEqual(s1.name, name)
|
||||
self.assertEqual(s2.name, name + ".001")
|
||||
|
||||
def test_multiple_dots_last_numeric_increments(self):
|
||||
# "a.b.002": last suffix is purely numeric, so it should increment
|
||||
s1 = self.strips.new_meta("a.b.002", 1, 1)
|
||||
s2 = self.strips.new_meta("a.b.002", 2, 1)
|
||||
self.assertEqual(s1.name, "a.b.002")
|
||||
self.assertEqual(s2.name, "a.b.003")
|
||||
|
||||
def test_multiple_dots_last_nonnumeric_appends(self):
|
||||
# "a.b.c": last suffix is non-numeric, whole name is the base
|
||||
s1 = self.strips.new_meta("a.b.c", 1, 1)
|
||||
s2 = self.strips.new_meta("a.b.c", 2, 1)
|
||||
self.assertEqual(s1.name, "a.b.c")
|
||||
self.assertEqual(s2.name, "a.b.c.001")
|
||||
|
||||
|
||||
def main():
|
||||
argv = [sys.argv[0]]
|
||||
if '--' in sys.argv:
|
||||
argv += sys.argv[sys.argv.index('--') + 1:]
|
||||
|
||||
unittest.main(argv=argv)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -31,6 +31,12 @@ BLOCKLIST_VULKAN = [
|
|||
"image_log.blend",
|
||||
]
|
||||
|
||||
# Block list for Linux/AMD official driver. On buildbot this driver can fail and the artifacts are likely
|
||||
# caused by incorrect index buffer synchronization or vertex shader execution.
|
||||
BLOCKLIST_AMD_LINUX_VK = [
|
||||
".*"
|
||||
]
|
||||
|
||||
|
||||
def setup():
|
||||
import bpy
|
||||
|
|
@ -107,6 +113,12 @@ def main():
|
|||
if args.gpu_backend == "vulkan":
|
||||
blocklist += BLOCKLIST_VULKAN
|
||||
|
||||
# AMD Linux Vulkan driver blocks all tests due to index/vertex shader sync issues.
|
||||
gpu_vendor = render_report.get_gpu_device_vendor(args.blender)
|
||||
if os.getenv("BLENDER_TEST_IGNORE_VENDOR_BLOCKLIST") is None:
|
||||
if gpu_vendor == "AMD" and sys.platform == "linux" and args.gpu_backend == "vulkan":
|
||||
blocklist += BLOCKLIST_AMD_LINUX_VK
|
||||
|
||||
report = WorkbenchReport("Workbench", args.outdir, args.oiiotool, variation=args.gpu_backend, blocklist=blocklist)
|
||||
if args.gpu_backend == "vulkan":
|
||||
report.set_compare_engine('workbench', 'opengl')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue