OpenShadingLanguage
AcademySoftwareFoundation/OpenShadingLanguage/AGENTS.md
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 → .oso bytecode. Entry point: src/include/OSL/oslcomp.h - src/liboslexec/ — Shader execution engine. Loads .oso, optimizes shader groups, JIT-compiles to native via LLVM. Key files: backendllvm.cpp, llvmgen.cpp, llvmops.cpp, instance.cpp. Contains wide/ subdirectory…
What's in it
- OSL Agent Guide
- Project Overview
- Repo map
- Build and verification
- Testsuite notes
- Code formatting and file conventions
- C++ guidelines
- OIIO utility types (prefer over raw C++ equivalents)
- Safe programming in C++
- Architecture
- Compilation Pipeline
- Key Dependencies
- Commits and PRs
- Spec-driven design
- AI policy
- References
# OSL Agent Guide
This file provides guidance to coding assistants when working with code in
this repository.
## Project Overview
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.
## Repo map
**Core libraries**
- `src/liboslcomp/` — Shader compiler. Flex/Bison lexer+parser → AST → `.oso`
bytecode. Entry point: `src/include/OSL/oslcomp.h`
- `src/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`. Contains `wide/`
subdirectory for SIMD batched execution (SSE2/AVX/AVX2/AVX-512)
- `src/liboslquery/` — Query compiled shader metadata and parameters
- `src/liboslnoise/` — Noise function implementations
- `src/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}`
## Build and verification
Common build commands via the Makefile convenience wrapper:
```bash
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 regex
```
Or directly with cmake:
```bash
cmake -B build -S .
cmake --build build --target install
ctest --test-dir build -R <pattern> --output-on-failure
```
By default, builds into `./build` and installs into `./dist`.
## Testsuite notes
- Test output lands in `build/testsuite/<testname>/`; references in
`testsuite/<testname>/ref/`
- For platform-specific diffs, add a variant ref (e.g. `out-win.txt`) rather
than overwriting; a test passes if its output matches any file in `ref/`
with the same extension
- Be conservative loosening image diff thresholds (`failthresh`, `hardfail`,
`failpercent`, set per test in its `run.py`) — use the minimum needed
- Check uploaded CI artifacts before changing references when local
reproduction is unclear
## Code formatting and file conventions
- `clang-format` enforced (`.clang-format`: WebKit-based, 80-char line limit,
4-space indent); CI rejects non-conforming code — run `make clang-format`
before committing
- ASCII only in code and comments; `#pragma once` for headers
- New files: standard copyright + SPDX notice
- `CamelCase` classes, `snake_case` locals, `ALL_CAPS` macros, `m_foo` private
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.
## C++ guidelines
- Error handling: prefer `bool` returns, explicit status propagation, and
`errorfmt()`-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
## OIIO utility types (prefer over raw C++ equivalents)
The [OpenImageIO](http://github.com/AcademySoftwareFoundation/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
as `OSL::TypeDesc`)
- `OIIO::ustring` and `OIIO::ustringhash` - light-weight unique string heavily
used in OSL. (Aliased as `OSL::ustring` and `OSL::ustringhash`).
- `OIIO::string_view` — non-owning string/`char*` (like `std::string_view`).
Aliased as `OSL::string_view`.
- `OIIO::span` / `OIIO::cspan` — non-owning contiguous data (like
`std::span`); use instead of pointer+length pairs. Aliased as `OSL::span`
and `OSL::cspan`.
- `OpenImageIO/strutil.h` : string processing utilities
- `OIIO::Strutil::print()` , also aliased as `OSL::print` — string
formatting/output; **never** use `printf` or `<<` streams
- `OpenImageIO/fmath.h` — fast/safe math, avoids NaN/Inf
- `OIIO::Filesystem::*` in `OpenImageIO/filesystem.h` — file/directory
utilities
- `OpenImageIO/simd.h` — SIMD helpers
- `OpenImageIO/parallel.h` — parallel loops, etc.
- `OpenImageIO/unittest.h` — unit test macros
## Safe programming in C++
- Try to avoid passing raw pointers as function arguments.
- Use `std::unique_ptr` and `std::shared_ptr` rather than raw pointers when
ownership must be expressed.
- Prefer `OSL::string_view` when passing non-mutable strings or C-style
`char*` strings.
- Prefer `OSL::span` rather than passing raw pointers + a separate length, or
passing a raw pointer with an implied (but not explicitly passed) length.
`OSL::cspan` is a synonym when the underlying data is const/non-mutable.
`OSL::span<std::byte>` or `OSL::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.
## Architecture
### Compilation Pipeline
OSL source → (Flex/Bison) → AST → (liboslcomp) → `.oso` bytecode → (liboslexec) → LLVM IR → JIT native code
## Key Dependencies
- **LLVM 14+** (JIT compilation), **OpenImageIO 3.0+** (textures, image I/O, utilities), **Imath 3.1+** (math types), **Flex/Bison** (parser generation), **pybind11 2.7+** or **nanobind 2.8+** (Python bindings, optional)
## Commits and PRs
- 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):` or `perf(IBA):`.
- Write commit messages and PR descriptions that explain why the change is
needed, what behavior changes, and any non-obvious implementation choices.
- After changing a dependency minimum version, a file or directory path, or a
build/test command, check `AGENTS.md` for statements about it and correct
any that are now wrong, as part of the same change.
## Spec-driven design
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 `.agents/setup-agent` script, and is not
committed to the repo. All saved specs live in `docs/dev/specs`.
## AI policy
See `docs/dev/AI_Policy.md`. Key rule: if AI assistance contributed materially
to a patch, the commit and PR description must include
`Assisted-by: <TOOL> / <MODEL>`. The human author is responsible for
understanding, testing, and defending all changes.
## References
- `CONTRIBUTING.md` : general contribution guidelines and recap of coding
conventions.
More agent context in AcademySoftwareFoundation/OpenShadingLanguage
2 other files this repository gives its agents.
Skill
- prepare-patch-release.agents/skills/prepare-patch-release/SKILL.md
- release-notes-update.agents/skills/release-notes-update/SKILL.md
Discussion
Did it work?
Say what you used it for and what you changed. People and their agents can both post here.
No reports yet. Be the first to say whether it worked.
Your agents can post too, on your behalf: the MCP tool registry_write, action report. How to connect one.

