Cycles: Add OSL compilation test

The test explicitly requests an OSL script to be compiled, without
relying on possibly cached bytecode in a node, or an oso file on a
disk.

It is aimed to catch issues line the ones in the referenced issue
and pull-request.

The reason why the compilation error was not caught before is because
render tests were using bytecode that was cached in the node storage.

This change uses internal Cycles API to test OSL compilation. This
seems to be the easiest way to hook up to this API. The operators from
node or text editor requires a context override, which is a bit tedious
to setup.
Alternative could be to use an external OSL script, but the issue with
that is Cycles would store OSO next to the input, so we can't have a
script stored in the tests folder and it'll need to be saved in a temp
directory anyway.

The test code might be a bit too verbose, but it just follows the
typical boiler plate code from other Python tests, preparing for the
future where we might want to store input scripts outside of the
python script.

The reason why comment line compilation using oslc succeeded is because
it is not really required to pass include to the "system" `shaders`
directory: the oslc/liboslcomp has a special logic that looks for the
`share/OSL/shaders`: `oslc ~/script.osl -o ~/script.oso` works just
fine.

Ref #154476
Ref #154576

Pull Request: https://projects.blender.org/blender/blender/pulls/154623
This commit is contained in:
Sergey Sharybin 2026-02-20 10:26:59 +01:00 • committed by Sergey Sharybin
parent 9e75725f10
commit 4f050d82dc
2 changed files with 77 additions and 0 deletions

View file

@ -938,6 +938,15 @@ if((WITH_CYCLES OR WITH_GPU_RENDER_TESTS) AND TEST_SRC_DIR_EXISTS)
endif()
endif()
if(WITH_CYCLES AND WITH_CYCLES_OSL)
add_blender_test(
cycles_osl_compile_test
--python ${CMAKE_CURRENT_LIST_DIR}/cycles_osl_compile_test.py
--
--testdir "${TEST_SRC_DIR}/render"
)
endif()
# ------------------------------------------------------------------------------
# COMPOSITOR TESTS
# ------------------------------------------------------------------------------

View file

@ -0,0 +1,68 @@
# SPDX-FileCopyrightText: 2015-2026 Blender Authors
#
# SPDX-License-Identifier: Apache-2.0
import sys
import tempfile
import unittest
from pathlib import Path
import bpy
import _cycles
args = None
class AbstractOSLCompileTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls._tempdir = tempfile.TemporaryDirectory()
cls.testdir = args.testdir
cls.tempdir = Path(cls._tempdir.name)
def setUp(self):
self.assertTrue(self.testdir.exists(), "Test dir {0} should exist".format(self.testdir))
def tearDown(self):
self._tempdir.cleanup()
class OSLCompileTest(AbstractOSLCompileTest):
def test_compile_simple(self):
input_file = self.tempdir / "input.osl"
output_file = self.tempdir / "output.oso"
input_file.write_text("""
shader basic_shader(
float in_float = 1.0,
color in_color = color(1.0, 1.0, 1.0),
output float out_float = 0.0,
output color out_color = color(0.0, 0.0, 0.0)
)
{
out_float = in_float * 2.0;
out_color = in_color * 2.0;
}""")
self.assertTrue(_cycles.osl_compile(str(input_file), str(output_file)))
def main():
global args
import argparse
if "--" in sys.argv:
argv = [sys.argv[0]] + sys.argv[sys.argv.index("--") + 1:]
else:
argv = sys.argv
parser = argparse.ArgumentParser()
parser.add_argument("--testdir", required=True, type=Path)
args, remaining = parser.parse_known_args(argv)
unittest.main(argv=remaining, verbosity=0)
if __name__ == "__main__":
main()