Blender V4.3
kernel/osl/osl.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009-2010 Sony Pictures Imageworks Inc., et al. All Rights Reserved.
2 * SPDX-FileCopyrightText: 2011-2022 Blender Foundation
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 * Adapted code from Open Shading Language. */
7
8#pragma once
9
10/* OSL Shader Engine
11 *
12 * Holds all variables to execute and use OSL shaders from the kernel.
13 */
14
15#include "kernel/osl/types.h"
16
18
20
23 uint32_t path_flag,
25{
26 const differential3 dP = differential_from_compact(sd->Ng, sd->dP);
27 const differential3 dI = differential_from_compact(sd->wi, sd->dI);
28
29 /* copy from shader data to shader globals */
30 globals->P = sd->P;
31 globals->dPdx = dP.dx;
32 globals->dPdy = dP.dy;
33 globals->I = sd->wi;
34 globals->dIdx = dI.dx;
35 globals->dIdy = dI.dy;
36 globals->N = sd->N;
37 globals->Ng = sd->Ng;
38 globals->u = sd->u;
39 globals->dudx = sd->du.dx;
40 globals->dudy = sd->du.dy;
41 globals->v = sd->v;
42 globals->dvdx = sd->dv.dx;
43 globals->dvdy = sd->dv.dy;
44 globals->dPdu = sd->dPdu;
45 globals->dPdv = sd->dPdv;
46 globals->time = sd->time;
47 globals->dtime = 1.0f;
48 globals->surfacearea = 1.0f;
49 globals->raytype = path_flag;
50 globals->flipHandedness = 0;
51 globals->backfacing = (sd->flag & SD_BACKFACING);
52
53 /* shader data to be used in services callbacks */
54 globals->renderstate = sd;
55#if OSL_LIBRARY_VERSION_CODE >= 11304
56 globals->shadingStateUniform = nullptr;
57 globals->thread_index = 0;
58 globals->shade_index = 0;
59#endif
60
61 /* hacky, we leave it to services to fetch actual object matrix */
62 globals->shader2common = sd;
63 globals->object2common = sd;
64
65 /* must be set to NULL before execute */
66 globals->Ci = nullptr;
67}
68
71 uint32_t path_flag,
72 ccl_private const OSLClosure *closure)
73{
74 int stack_size = 0;
75 float3 weight = one_float3();
76 float3 weight_stack[16];
77 ccl_private const OSLClosure *closure_stack[16];
78 int layer_stack_level = -1;
79 float3 layer_albedo = zero_float3();
80
81 while (true) {
82 switch (closure->id) {
83 case OSL_CLOSURE_MUL_ID: {
84 ccl_private const OSLClosureMul *mul = static_cast<ccl_private const OSLClosureMul *>(
85 closure);
86 weight *= mul->weight;
87 closure = mul->closure;
88 continue;
89 }
90 case OSL_CLOSURE_ADD_ID: {
91 if (stack_size >= 16) {
92 kernel_assert(!"Exhausted OSL closure stack");
93 break;
94 }
95 ccl_private const OSLClosureAdd *add = static_cast<ccl_private const OSLClosureAdd *>(
96 closure);
97 closure = add->closureA;
98 weight_stack[stack_size] = weight;
99 closure_stack[stack_size++] = add->closureB;
100 continue;
101 }
103 ccl_private const OSLClosureComponent *comp =
104 static_cast<ccl_private const OSLClosureComponent *>(closure);
105 ccl_private const LayerClosure *layer = reinterpret_cast<ccl_private const LayerClosure *>(
106 comp + 1);
107
108 /* Layer closures may not appear in the top layer subtree of another layer closure. */
109 kernel_assert(layer_stack_level == -1);
110
111 if (layer->top != nullptr) {
112 /* Push base layer onto the stack, will be handled after the top layers */
113 weight_stack[stack_size] = weight;
114 closure_stack[stack_size] = layer->base;
115 /* Start accumulating albedo of the top layers */
116 layer_stack_level = stack_size++;
117 layer_albedo = zero_float3();
118 /* Continue with the top layers */
119 closure = layer->top;
120 }
121 else {
122 /* No top layer, just continue with base. */
123 closure = layer->base;
124 }
125 continue;
126 }
127#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \
128 case OSL_CLOSURE_##Upper##_ID: { \
129 ccl_private const OSLClosureComponent *comp = \
130 static_cast<ccl_private const OSLClosureComponent *>(closure); \
131 float3 albedo = one_float3(); \
132 osl_closure_##lower##_setup(kg, \
133 sd, \
134 path_flag, \
135 weight * comp->weight, \
136 reinterpret_cast<ccl_private const Upper##Closure *>(comp + 1), \
137 (layer_stack_level >= 0) ? &albedo : NULL); \
138 if (layer_stack_level >= 0) { \
139 layer_albedo += albedo; \
140 } \
141 break; \
142 }
143#include "closures_template.h"
144 default:
145 break;
146 }
147
148 /* Pop the next closure from the stack (or return if we're done). */
149 do {
150 if (stack_size == 0) {
151 return;
152 }
153
154 weight = weight_stack[--stack_size];
155 closure = closure_stack[stack_size];
156 if (stack_size == layer_stack_level) {
157 /* We just finished processing the top layers of a Layer closure, so adjust the weight to
158 * account for the layering. */
159 weight = closure_layering_weight(layer_albedo, weight);
160 layer_stack_level = -1;
161 /* If it's fully occluded, skip the base layer we just popped from the stack and grab
162 * the next entry instead. */
163 if (is_zero(weight)) {
164 continue;
165 }
166 }
167 } while (closure == nullptr);
168 }
169}
170
171#ifndef __KERNEL_GPU__
172
173template<ShaderType type>
175 const void *state,
176 ShaderData *sd,
177 uint32_t path_flag);
178
179#else
180
181template<ShaderType type, typename ConstIntegratorGenericState>
183 ConstIntegratorGenericState state,
185 uint32_t path_flag)
186{
187 ShaderGlobals globals;
188 shaderdata_to_shaderglobals(kg, sd, path_flag, &globals);
189
190 const int shader = sd->shader & SHADER_MASK;
191
192# ifdef __KERNEL_OPTIX__
193 uint8_t group_data[2048];
194 uint8_t closure_pool[1024];
195 sd->osl_closure_pool = closure_pool;
196
197 unsigned int optix_dc_index = 2 /* NUM_CALLABLE_PROGRAM_GROUPS */ +
198 (shader + type * kernel_data.max_shaders) * 2;
199 optixDirectCall<void>(optix_dc_index + 0,
200 /* shaderglobals_ptr = */ &globals,
201 /* groupdata_ptr = */ (void *)group_data,
202 /* userdata_base_ptr = */ (void *)nullptr,
203 /* output_base_ptr = */ (void *)nullptr,
204 /* shadeindex = */ 0);
205 optixDirectCall<void>(optix_dc_index + 1,
206 /* shaderglobals_ptr = */ &globals,
207 /* groupdata_ptr = */ (void *)group_data,
208 /* userdata_base_ptr = */ (void *)nullptr,
209 /* output_base_ptr = */ (void *)nullptr,
210 /* shadeindex = */ 0);
211# endif
212
213# if __cplusplus < 201703L
214 if (type == SHADER_TYPE_DISPLACEMENT) {
215# else
216 if constexpr (type == SHADER_TYPE_DISPLACEMENT) {
217# endif
218 sd->P = globals.P;
219 }
220 else if (globals.Ci) {
221 flatten_closure_tree(kg, sd, path_flag, globals.Ci);
222 }
223}
224
225#endif
226
ccl_device_inline Spectrum closure_layering_weight(const Spectrum layer_albedo, const Spectrum weight)
Definition bsdf_util.h:261
static void mul(btAlignedObjectArray< T > &items, const Q &value)
#define kernel_assert(cond)
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define ccl_device
#define ccl_private
#define ccl_device_inline
#define CCL_NAMESPACE_END
ccl_device_forceinline differential3 differential_from_compact(const float3 D, const float dD)
ccl_device void flatten_closure_tree(KernelGlobals kg, ccl_private ShaderData *sd, uint32_t path_flag, ccl_private const OSLClosure *closure)
CCL_NAMESPACE_BEGIN ccl_device_inline void shaderdata_to_shaderglobals(KernelGlobals kg, ccl_private ShaderData *sd, uint32_t path_flag, ccl_private ShaderGlobals *globals)
void osl_eval_nodes(const KernelGlobalsCPU *kg, const void *state, ShaderData *sd, uint32_t path_flag)
@ OSL_CLOSURE_MUL_ID
@ OSL_CLOSURE_LAYER_ID
@ OSL_CLOSURE_ADD_ID
@ SHADER_TYPE_DISPLACEMENT
@ SD_BACKFACING
ShaderData
@ SHADER_MASK
ccl_device_inline bool is_zero(const float2 a)
ccl_device_inline float3 one_float3()
Definition math_float3.h:24
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:15
static ulong state[N]
unsigned int uint32_t
Definition stdint.h:80
unsigned char uint8_t
Definition stdint.h:78
ccl_private OSLClosure * Ci
packed_float3 P