RenderReport: Add option to add platform specific overrides.
Reference images in the reference_override_dir will be chosen before images in reference_dir. This allows platform specific reference images, with a common base. Ignored when set to None. The caller is responsible of setting the reference override dir as the unit test is more aware what the definition of a platform is. Patch adds `gpu.platform.device_type_get` function to get the device type that blender has detected. Reviewed By: brecht Maniphest Tasks: T99046 Differential Revision: https://developer.blender.org/D15265
This commit is contained in:
parent
6749a4a8f0
commit
3393b7137e
Notes:
blender-bot
2023-02-14 03:13:26 +01:00
Referenced by issue #99046, Regression tests: Platform specific reference images
|
@ -55,6 +55,34 @@ static PyObject *pygpu_platform_version_get(PyObject *UNUSED(self))
|
|||
return PyUnicode_FromString(GPU_platform_version());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
pygpu_platform_device_type_get_doc,
|
||||
".. function:: device_type_get()\n"
|
||||
"\n"
|
||||
" Get GPU device type.\n"
|
||||
"\n"
|
||||
" :return: Device type ('APPLE', 'NVIDIA', 'AMD', 'INTEL', 'SOFTWARE', 'UNKNOWN').\n"
|
||||
" :rtype: str\n");
|
||||
static PyObject *pygpu_platform_device_type_get(PyObject *UNUSED(self))
|
||||
{
|
||||
if (GPU_type_matches(GPU_DEVICE_APPLE, GPU_OS_ANY, GPU_DRIVER_ANY)) {
|
||||
return PyUnicode_FromString("APPLE");
|
||||
}
|
||||
if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY)) {
|
||||
return PyUnicode_FromString("NVIDIA");
|
||||
}
|
||||
if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) {
|
||||
return PyUnicode_FromString("AMD");
|
||||
}
|
||||
if (GPU_type_matches(GPU_DEVICE_INTEL | GPU_DEVICE_INTEL_UHD, GPU_OS_ANY, GPU_DRIVER_ANY)) {
|
||||
return PyUnicode_FromString("INTEL");
|
||||
}
|
||||
if (GPU_type_matches(GPU_DEVICE_SOFTWARE, GPU_OS_ANY, GPU_DRIVER_ANY)) {
|
||||
return PyUnicode_FromString("SOFTWARE");
|
||||
}
|
||||
return PyUnicode_FromString("UNKNOWN");
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -74,6 +102,10 @@ static struct PyMethodDef pygpu_platform__tp_methods[] = {
|
|||
(PyCFunction)pygpu_platform_version_get,
|
||||
METH_NOARGS,
|
||||
pygpu_platform_version_get_doc},
|
||||
{"device_type_get",
|
||||
(PyCFunction)pygpu_platform_device_type_get,
|
||||
METH_NOARGS,
|
||||
pygpu_platform_device_type_get_doc},
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import argparse
|
||||
import os
|
||||
import pathlib
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
|
@ -98,6 +99,26 @@ if inside_blender:
|
|||
print(e)
|
||||
sys.exit(1)
|
||||
|
||||
def get_gpu_device_type(blender):
|
||||
command = [
|
||||
blender,
|
||||
"-noaudio",
|
||||
"--background"
|
||||
"--factory-startup",
|
||||
"--python",
|
||||
str(pathlib.Path(__file__).parent / "gpu_info.py")
|
||||
]
|
||||
try:
|
||||
completed_process = subprocess.run(command, stdout=subprocess.PIPE)
|
||||
for line in completed_process.stdout.read_text():
|
||||
if line.startswith("GPU_DEVICE_TYPE:"):
|
||||
vendor = line.split(':')[1]
|
||||
return vendor
|
||||
except BaseException as e:
|
||||
return None
|
||||
return None
|
||||
|
||||
|
||||
|
||||
def get_arguments(filepath, output_filepath):
|
||||
return [
|
||||
|
@ -134,10 +155,16 @@ def main():
|
|||
idiff = args.idiff[0]
|
||||
output_dir = args.outdir[0]
|
||||
|
||||
gpu_device_type = get_gpu_device_type(blender)
|
||||
reference_override_dir = None
|
||||
if gpu_device_type == "AMD":
|
||||
reference_override_dir = "eevee_renders/amd"
|
||||
|
||||
from modules import render_report
|
||||
report = render_report.Report("Eevee", output_dir, idiff)
|
||||
report.set_pixelated(True)
|
||||
report.set_reference_dir("eevee_renders")
|
||||
report.set_reference_override_dir(reference_override_dir)
|
||||
report.set_compare_engine('cycles', 'CPU')
|
||||
|
||||
test_dir_name = Path(test_dir).name
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
Prints GPU backend information to the console and exits.
|
||||
|
||||
Use this script as `blender --background --python gpu_info.py`.
|
||||
"""
|
||||
import bpy
|
||||
import gpu
|
||||
import sys
|
||||
|
||||
# Render with workbench to initialize the GPU backend otherwise it would fail when running in
|
||||
# background mode as the GPU backend won't be initialized.
|
||||
scene = bpy.context.scene
|
||||
scene.render.resolution_x = 1
|
||||
scene.render.resolution_y = 1
|
||||
scene.render.engine = "BLENDER_WORKBENCH"
|
||||
bpy.ops.render.render(animation=False, write_still=False)
|
||||
|
||||
|
||||
print('GPU_VENDOR:' + gpu.platform.vendor_get())
|
||||
print('GPU_RENDERER:' + gpu.platform.renderer_get())
|
||||
print('GPU_VERSION:' + gpu.platform.version_get())
|
||||
print('GPU_DEVICE_TYPE:' + gpu.platform.device_type_get())
|
||||
|
||||
sys.exit(0)
|
|
@ -78,12 +78,18 @@ def test_get_name(filepath):
|
|||
return os.path.splitext(filename)[0]
|
||||
|
||||
|
||||
def test_get_images(output_dir, filepath, reference_dir):
|
||||
def test_get_images(output_dir, filepath, reference_dir, reference_override_dir):
|
||||
testname = test_get_name(filepath)
|
||||
dirpath = os.path.dirname(filepath)
|
||||
|
||||
old_dirpath = os.path.join(dirpath, reference_dir)
|
||||
old_img = os.path.join(old_dirpath, testname + ".png")
|
||||
if reference_override_dir:
|
||||
override_dirpath = os.path.join(dirpath, reference_override_dir)
|
||||
override_img = os.path.join(override_dirpath, testname + ".png")
|
||||
if os.path.exists(override_img):
|
||||
old_dirpath = override_dirpath
|
||||
old_img = override_img
|
||||
|
||||
ref_dirpath = os.path.join(output_dir, os.path.basename(dirpath), "ref")
|
||||
ref_img = os.path.join(ref_dirpath, testname + ".png")
|
||||
|
@ -108,6 +114,7 @@ class Report:
|
|||
'output_dir',
|
||||
'global_dir',
|
||||
'reference_dir',
|
||||
'reference_override_dir',
|
||||
'idiff',
|
||||
'pixelated',
|
||||
'fail_threshold',
|
||||
|
@ -127,6 +134,7 @@ class Report:
|
|||
self.output_dir = output_dir
|
||||
self.global_dir = os.path.dirname(output_dir)
|
||||
self.reference_dir = 'reference_renders'
|
||||
self.reference_override_dir = None
|
||||
self.idiff = idiff
|
||||
self.compare_engine = None
|
||||
self.fail_threshold = 0.016
|
||||
|
@ -161,6 +169,9 @@ class Report:
|
|||
def set_reference_dir(self, reference_dir):
|
||||
self.reference_dir = reference_dir
|
||||
|
||||
def set_reference_override_dir(self, reference_override_dir):
|
||||
self.reference_override_dir = reference_override_dir
|
||||
|
||||
def set_compare_engine(self, other_engine, other_device=None):
|
||||
self.compare_engine = (other_engine, other_device)
|
||||
|
||||
|
@ -343,7 +354,7 @@ class Report:
|
|||
name = test_get_name(filepath)
|
||||
name = name.replace('_', ' ')
|
||||
|
||||
old_img, ref_img, new_img, diff_img = test_get_images(self.output_dir, filepath, self.reference_dir)
|
||||
old_img, ref_img, new_img, diff_img = test_get_images(self.output_dir, filepath, self.reference_dir, self.reference_override_dir)
|
||||
|
||||
status = error if error else ""
|
||||
tr_style = """ class="table-danger" """ if error else ""
|
||||
|
@ -390,7 +401,7 @@ class Report:
|
|||
self.compare_tests += test_html
|
||||
|
||||
def _diff_output(self, filepath, tmp_filepath):
|
||||
old_img, ref_img, new_img, diff_img = test_get_images(self.output_dir, filepath, self.reference_dir)
|
||||
old_img, ref_img, new_img, diff_img = test_get_images(self.output_dir, filepath, self.reference_dir, self.reference_override_dir)
|
||||
|
||||
# Create reference render directory.
|
||||
old_dirpath = os.path.dirname(old_img)
|
||||
|
|
Loading…
Reference in New Issue