This file provides guidance to coding assistants when working with code in this repository.
Open Shading Language (OSL) is a production shading language for VFX/animation
renderers, maintained by the Academy Software Foundation. It compiles .osl
shader source to .oso bytecode, then JIT-compiles via LLVM to native code at
render time. C++17 codebase.
Core libraries
src/liboslcomp/— Shader compiler. Flex/Bison lexer+parser → AST →.osobytecode. Entry point:oslcomp.hsrc/liboslexec/— Shader execution engine. Loads.oso, optimizes shader groups, JIT-compiles to native via LLVM. Key files:backendllvm.cpp,llvm_gen.cpp,llvm_ops.cpp,instance.cpp. Containswide/subdirectory for SIMD batched execution (SSE2/AVX/AVX-512)src/liboslquery/— Query compiled shader metadata and parameterssrc/liboslnoise/— Noise function implementationssrc/libbsdl/— BSDF/closure library
Command line tools
src/oslc/— Compiler CLI (oslc)src/oslinfo/— Shader info query tool (oslinfo)src/testshade/— Test harness that executes shaders on rectangular arrays of points, saves output as images.src/testrender/— Minimal path-tracing renderer demonstrating OSL integration.src/osltoy/— Qt-based GUI shader editor (optional)
Public APIs/headers
Headers in src/include/OSL/: oslexec.h, oslcomp.h, oslquery.h, rendererservices.h (abstract interface renderers must implement).
Namespaces:
OSL(outer),OSL::pvt(private implementation of internal-only utilities)- Versioned inner namespace:
v{MAJOR}_{MINOR}
Common build commands via the Makefile convenience wrapper:
make # configure, build, install (Release)
make debug # debug build
make clean # wipe build dir (needed when switching branches/modes)
make clang-format # format all source files
make test # full testsuite
make test TEST=<pattern> # subset matching regexOr directly with cmake:
cmake -B build -S .
cmake --build build --target install
ctest --test-dir build -R <pattern> --output-on-failureBy default, builds into ./build and installs into ./dist.
- Test output lands in
build/testsuite/<testname>/; references intestsuite/<testname>/ref/ - Read
testsuite/TESTSUITE-README.mdbefore updating references or diagnosing failures - For platform-specific diffs, add a variant ref (e.g.
out-win.txt) rather than overwriting - Be conservative loosening image diff thresholds — use the minimum needed
- Check uploaded CI artifacts before changing references when local reproduction is unclear
clang-formatenforced (.clang-format); CI rejects non-conforming code — runmake clang-formatbefore committing- Lines ~80 cols; ASCII only in code and comments;
#pragma oncefor headers - New files: standard copyright + SPDX notice
CamelCaseclasses,snake_caselocals,ALL_CAPSmacros,m_fooprivate members- 3 blank lines between free functions/classes; 1 between class methods; max 1 blank line inside a function body
//for regular comments;///Doxygen for public API- If a file has a strong local style, imitate that.
- Error handling: prefer
boolreturns, explicit status propagation, anderrorfmt()-style reporting — not exceptions — consistent with the surrounding subsystem - Preserve API, ABI, and behavior compatibility unless the task explicitly requires a break
- For hot paths: no hidden allocation in inner loops or parallel regions; precompute outside hot paths
The OpenImageIO (OIIO) project is a key dependency of OSL and the two projects are co-developed. Many utilities shared by both projects live in OpenImageIO.
Prefer C++17 std and Imath types except as noted below. Avoid introducing
new third-party dependencies without a strong reason. Rely liberally on these
classes and headers from OIIO:
OIIO::TypeDesc- light-weight description of simple types (aliased asOSL::TypeDesc)OIIO::ustringandOIIO::ustringhash- light-weight unique string heavily used in OSL. (Aliased asOSL::ustringandOSL::ustringhash).OIIO::string_view— non-owning string/char*(likestd::string_view). Aliased asOSL::string_view.OIIO::span/OIIO::cspan— non-owning contiguous data (likestd::span); use instead of pointer+length pairs. Aliased asOSL::spanandOSL::cspan.OpenImageIO/strutil.h: string processing utilitiesOIIO::Strutil::print(), also aliased asOSL::print— string formatting/output; never useprintfor<<streamsOpenImageIO/fmath.h— fast/safe math, avoids NaN/InfOIIO::Filesystem::*inOpenImageIO/filesystem.h— file/directory utilitiesOpenImageIO/simd.h— SIMD helpersOpenImageIO/parallel.h— parallel loops, etc.OpenImageIO/unittest.h— unit test macros
- Try to avoid passing raw pointers as function arguments.
- Use
std::unique_ptrandstd::shared_ptrrather than raw pointers when ownership must be expressed. - Prefer
OSL::string_viewwhen passing non-mutable strings or C-stylechar*strings. - Prefer
OSL::spanrather than passing raw pointers + a separate length, or passing a raw pointer with an implied (but not explicitly passed) length.OSL::cspanis a synonmym when the underlying data is const/non-mutable.OSL::span<std::byte>orOSL::cspan<std::byte>can be used to represent contiguous untyped data. These are our equivalent of C++std::span. - Use these guidelines always for new code, but do not churn existing code just to "modernize" it.
OSL source → (Flex/Bison) → AST → (liboslcomp) → .oso bytecode → (liboslexec) → LLVM IR → JIT native code
- clang-format config in
.clang-format(WebKit-based, 80-char line limit, 4-space indent) - Run
make clang-formatbefore submitting changes
- LLVM 14+ (JIT compilation), OpenImageIO 2.5+ (textures, image I/O, utilities), Imath 3.1+ (math types), Flex/Bison (parser generation), pybind11 (Python bindings, optional)
- Keep PRs narrow and easy to review.
- Prefix format:
type(subsystem): message— subsystem is optional but helpful. - Valid types:
fix:,feat:,perf:,api:,int:,build:,test:,ci:,docs:,refactor:,style:,admin:,revert:. - Add a subsystem tag when it helps, e.g.
fix(exr):orperf(IBA):. - Write commit messages and PR descriptions that explain why the change is needed, what behavior changes, and any non-obvious implementation choices.
Feature specifications live in docs/dev/specs/ (not at the project root).
When using speckit commands (/speckit-specify, /speckit-plan, etc.), always
use docs/dev/specs/ as the base directory for all spec paths, overriding any
default of specs/. When creating a new spec, set SPECIFY_FEATURE_DIRECTORY
to docs/dev/specs/<NNN-feature-name> and write that path to
.specify/feature.json.
The speckit bash scripts expect a specs/ directory at the project root. A
symlink satisfies this without committing speckit infrastructure to the repo.
This symlink is set up by the setup-agents script, and is not committed to
the repo. All saved specs live in docs/dev/specs.
Refer to docs/dev/AI_Policy.md.
See docs/dev/AI_Policy.md. Key rule: if AI assistance contributed materially
to a patch, the commit must include Assisted-by: <TOOL> / <MODEL>. The human
author is responsible for understanding, testing, and defending all changes.
CONTRIBUTING.md: general contribution guidelines and recap of coding conventions.