diff options
-rw-r--r-- | source/blender/imbuf/intern/openexr/openexr_api.cpp | 15 | ||||
-rw-r--r-- | source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc | 7 | ||||
-rw-r--r-- | tests/python/CMakeLists.txt | 4 | ||||
-rw-r--r-- | tests/python/cycles_render_tests.py | 58 | ||||
-rwxr-xr-x | tests/python/modules/render_report.py | 71 |
5 files changed, 85 insertions, 70 deletions
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index 9726eaeed2c..979e7703e81 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -324,6 +324,11 @@ struct _RGBAZ { using RGBAZ = _RGBAZ; +static half float_to_half_safe(const float value) +{ + return half(clamp_f(value, -HALF_MAX, HALF_MAX)); +} + extern "C" { /** @@ -472,10 +477,10 @@ static bool imb_save_openexr_half(ImBuf *ibuf, const char *name, const int flags from = ibuf->rect_float + channels * i * width; for (int j = ibuf->x; j > 0; j--) { - to->r = from[0]; - to->g = (channels >= 2) ? from[1] : from[0]; - to->b = (channels >= 3) ? from[2] : from[0]; - to->a = (channels >= 4) ? from[3] : 1.0f; + to->r = float_to_half_safe(from[0]); + to->g = float_to_half_safe((channels >= 2) ? from[1] : from[0]); + to->b = float_to_half_safe((channels >= 3) ? from[2] : from[0]); + to->a = float_to_half_safe((channels >= 4) ? from[3] : 1.0f); to++; from += channels; } @@ -1116,7 +1121,7 @@ void IMB_exr_write_channels(void *handle) float *rect = echan->rect; half *cur = current_rect_half; for (size_t i = 0; i < num_pixels; i++, cur++) { - *cur = rect[i * echan->xstride]; + *cur = float_to_half_safe(rect[i * echan->xstride]); } half *rect_to_write = current_rect_half + (data->height - 1L) * data->width; frameBuffer.insert( diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc index 5d126328988..2aca9ed581c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc @@ -37,9 +37,10 @@ static void execute_on_component(const GeoNodeExecParams ¶ms, GeometryCompon const bNode &bnode = params.node(); NodeAttributeColorRamp *node_storage = (NodeAttributeColorRamp *)bnode.storage; - /* Use the type of the input attribute, but create a color attribute if it doesn't exist yet. */ - const CustomDataType result_type = params.get_input_attribute_data_type( - "Attribute", component, CD_PROP_COLOR); + /* Always output a color attribute for now. We might want to allow users to customize. + * Using the type of an existing attribute could work, but does not have a real benefit + * currently. */ + const CustomDataType result_type = CD_PROP_COLOR; const std::string result_name = params.get_input<std::string>("Result"); /* Once we support more domains at the user level, we have to decide how the result domain is diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index 2ca21a315e4..d8bc5be40d7 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -651,6 +651,9 @@ if(WITH_CYCLES OR WITH_OPENGL_RENDER_TESTS) # Cycles if(WITH_CYCLES) + if(NOT WITH_CYCLES_OSL) + set(_cycles_blacklist OSL) + endif() foreach(_cycles_device ${CYCLES_TEST_DEVICES}) string(TOLOWER "${_cycles_device}" _cycles_device_lower) set(_cycles_render_tests bake;${render_tests};osl) @@ -664,6 +667,7 @@ if(WITH_CYCLES OR WITH_OPENGL_RENDER_TESTS) -idiff "${OPENIMAGEIO_IDIFF}" -outdir "${TEST_OUT_DIR}/cycles" -device ${_cycles_device} + -blacklist ${_cycles_blacklist} ) endforeach() endforeach() diff --git a/tests/python/cycles_render_tests.py b/tests/python/cycles_render_tests.py index 9153a2732b5..36c3f7d9fe5 100644 --- a/tests/python/cycles_render_tests.py +++ b/tests/python/cycles_render_tests.py @@ -9,6 +9,53 @@ import subprocess import sys from pathlib import Path +# List of .blend files that are known to be failing and are not ready to be +# tested, or that only make sense on some devices. Accepts regular expressions. +BLACKLIST_OSL = [ + # OSL only supported on CPU. + '.*_osl.blend', + 'osl_.*.blend', +] + +BLACKLIST_OPTIX = [ + # No branched path on Optix. + 'T53854.blend', + 'T50164.blend', + 'portal.blend', + 'denoise_sss.blend', + 'denoise_passes.blend', + 'distant_light.blend', + 'aov_position.blend', + 'subsurface_branched_path.blend', + 'T43865.blend', +] + +BLACKLIST_GPU = [ + # Missing equiangular sampling on GPU. + 'area_light.blend', + 'denoise_hair.blend', + 'point_density_.*.blend', + 'point_light.blend', + 'shadow_catcher_bpt_.*.blend', + 'sphere_light.blend', + 'spot_light.blend', + 'T48346.blend', + 'world_volume.blend', + # Uninvestigated differences with GPU. + 'image_log.blend', + 'subsurface_behind_glass_branched.blend', + 'T40964.blend', + 'T45609.blend', + 'T48860.blend', + 'smoke_color.blend', + 'bevel_mblur.blend', + # Inconsistency between Embree and Hair primitive on GPU. + 'hair_basemesh_intercept.blend', + 'hair_instancer_uv.blend', + 'hair_particle_random.blend', + 'principled_hair_.*.blend', + 'transparent_shadow_hair.*.blend', +] def get_arguments(filepath, output_filepath): dirname = os.path.dirname(filepath) @@ -51,6 +98,7 @@ def create_argparse(): parser.add_argument("-outdir", nargs=1) parser.add_argument("-idiff", nargs=1) parser.add_argument("-device", nargs=1) + parser.add_argument("-blacklist", nargs="*") return parser @@ -64,8 +112,16 @@ def main(): output_dir = args.outdir[0] device = args.device[0] + blacklist = [] + if device != 'CPU': + blacklist += BLACKLIST_GPU + if device != 'CPU' or 'OSL' in args.blacklist: + blacklist += BLACKLIST_OSL + if device == 'OPTIX': + blacklist += BLACKLIST_OPTIX + from modules import render_report - report = render_report.Report('Cycles', output_dir, idiff, device) + report = render_report.Report('Cycles', output_dir, idiff, device, blacklist) report.set_pixelated(True) report.set_reference_dir("cycles_renders") if device == 'CPU': diff --git a/tests/python/modules/render_report.py b/tests/python/modules/render_report.py index 9db2162b1ff..c1ae0b05fcd 100755 --- a/tests/python/modules/render_report.py +++ b/tests/python/modules/render_report.py @@ -29,57 +29,6 @@ class COLORS_DUMMY: COLORS = COLORS_DUMMY -# List of .blend files that are known to be failing and are not ready to be -# tested, or that only make sense on some devices. Accepts regular expressions. -BLACKLIST = ( - # OSL only supported on CPU. - ('.*_osl.blend', '(?!CPU)'), - ('osl_.*.blend', '(?!CPU)'), - - # No baking, branched path and shader raytrace on Optix. - ('bake_.*.blend', 'OPTIX'), - ('ambient_occlusion.blend', 'OPTIX'), - ('ambient_occlusion_only_local.blend', 'OPTIX'), - ('bevel.blend', 'OPTIX'), - ('bevel_mblur.blend', 'OPTIX'), - ('T53854.blend', 'OPTIX'), - ('T50164.blend', 'OPTIX'), - ('portal.blend', 'OPTIX'), - ('denoise_sss.blend', 'OPTIX'), - ('denoise_passes.blend', 'OPTIX'), - ('distant_light.blend', 'OPTIX'), - ('aov_position.blend', 'OPTIX'), - ('subsurface_branched_path.blend', 'OPTIX'), - - # Missing equiangular sampling on GPU. - ('area_light.blend', '(?!CPU)'), - ('denoise_hair.blend', '(?!CPU)'), - ('point_density_.*.blend', '(?!CPU)'), - ('point_light.blend', '(?!CPU)'), - ('shadow_catcher_bpt_.*.blend', '(?!CPU)'), - ('sphere_light.blend', '(?!CPU)'), - ('spot_light.blend', '(?!CPU)'), - ('T48346.blend', '(?!CPU)'), - ('world_volume.blend', '(?!CPU)'), - - # Inconsistency between Embree and Hair primitive on GPU. - ('hair_basemesh_intercept.blend', '(?!CPU)'), - ('hair_instancer_uv.blend', '(?!CPU)'), - ('hair_particle_random.blend', '(?!CPU)'), - ('principled_hair_.*.blend', '(?!CPU)'), - ('transparent_shadow_hair.*.blend', '(?!CPU)'), - - # Uninvestigated differences with GPU. - ('image_log.blend', '(?!CPU)'), - ('subsurface_behind_glass_branched.blend', '(?!CPU)'), - ('T40964.blend', '(?!CPU)'), - ('T45609.blend', '(?!CPU)'), - ('T48860.blend', '(?!CPU)'), - ('smoke_color.blend', '(?!CPU)'), - ('T43865.blend', 'OPTIX') -) - - def print_message(message, type=None, status=''): if type == 'SUCCESS': print(COLORS.GREEN, end="") @@ -103,7 +52,7 @@ def print_message(message, type=None, status=''): sys.stdout.flush() -def blend_list(dirpath, device): +def blend_list(dirpath, device, blacklist): import re for root, dirs, files in os.walk(dirpath): @@ -112,12 +61,10 @@ def blend_list(dirpath, device): continue skip = False - for blacklist in BLACKLIST: - if not re.match(blacklist[0], filename): - continue - if device and blacklist[1] and not re.match(blacklist[1], device): - continue - skip = True + for blacklist_entry in blacklist: + if re.match(blacklist_entry, filename): + skip = True + break if not skip: filepath = os.path.join(root, filename) @@ -169,10 +116,11 @@ class Report: 'passed_tests', 'compare_tests', 'compare_engine', - 'device' + 'device', + 'blacklist', ) - def __init__(self, title, output_dir, idiff, device=None): + def __init__(self, title, output_dir, idiff, device=None, blacklist=[]): self.title = title self.output_dir = output_dir self.global_dir = os.path.dirname(output_dir) @@ -182,6 +130,7 @@ class Report: self.fail_threshold = 0.016 self.fail_percent = 1 self.device = device + self.blacklist = blacklist if device: self.title = self._engine_title(title, device) @@ -575,7 +524,7 @@ class Report: def _run_all_tests(self, dirname, dirpath, blender, arguments_cb, batch): passed_tests = [] failed_tests = [] - all_files = list(blend_list(dirpath, self.device)) + all_files = list(blend_list(dirpath, self.device, self.blacklist)) all_files.sort() print_message("Running {} tests from 1 test case." . format(len(all_files)), |