1 // Copyright Contributors to the Open Shading Language project.
2 // SPDX-License-Identifier: BSD-3-Clause
3 // https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
4 
5 #pragma once
6 
7 #if (OPTIX_VERSION < 70000)
8 #include <optix_math.h>
9 #endif
10 #include <OSL/device_string.h>
11 
12 OSL_NAMESPACE_ENTER
13 // Create an OptiX variable for each of the 'standard' strings declared in
14 // <OSL/strdecls.h>.
15 namespace DeviceStrings {
16 #if (OPTIX_VERSION < 70000)
17 #define STRDECL(str,var_name)                           \
18     rtDeclareVariable(OSL_NAMESPACE::DeviceString, var_name, , );
19 #else
20 #define STRDECL(str,var_name)                           \
21     extern __device__ OSL_NAMESPACE::DeviceString var_name;
22 #endif
23 
24 #include <OSL/strdecls.h>
25 #undef STRDECL
26 }
27 OSL_NAMESPACE_EXIT
28 
29 namespace {  // anonymous namespace
30 
31 #if (OPTIX_VERSION < 70000)
32 #ifdef __cplusplus
33     typedef optix::float3 float3;
34 #endif
35 #endif
36 
37 // These are CUDA variants of various OSL options structs. Their layouts and
38 // default values are identical to the host versions, but they might differ in
39 // how they are constructed. They are duplicated here as a convenience and to
40 // avoid including additional host headers.
41 
42 struct NoiseOptCUDA {
43     int    anisotropic;
44     int    do_filter;
45     float3 direction;
46     float  bandwidth;
47     float  impulses;
48 
49     __device__
NoiseOptCUDANoiseOptCUDA50     NoiseOptCUDA ()
51         : anisotropic (0),
52           do_filter   (true),
53           direction   (make_float3(1.0f,0.0f,0.0f)),
54           bandwidth   (1.0f),
55           impulses    (16.0f)
56     {
57     }
58 };
59 
60 
61 struct TextureOptCUDA {
62     // TO BE IMPLEMENTED
63 };
64 
65 
66 struct TraceOptCUDA {
67     // TO BE IMPLEMENTED
68 };
69 
70 
71 // This isn't really a CUDA version of the host-side ShadingContext class;
72 // instead, it is used as a container for a handful of pointers accessed during
73 // shader executions that are accessed via the ShadingContext.
74 struct ShadingContextCUDA {
75     NoiseOptCUDA*   m_noiseopt;
76     TextureOptCUDA* m_textureopt;
77     TraceOptCUDA*   m_traceopt;
78 
noise_options_ptrShadingContextCUDA79     __device__ void* noise_options_ptr ()   { return m_noiseopt; }
texture_options_ptrShadingContextCUDA80     __device__ void* texture_options_ptr () { return m_textureopt; }
trace_options_ptrShadingContextCUDA81     __device__ void* trace_options_ptr ()   { return m_traceopt; }
82 };
83 
84 
85 struct ShaderGlobals {
86     float3 P, dPdx, dPdy;
87     float3 dPdz;
88     float3 I, dIdx, dIdy;
89     float3 N;
90     float3 Ng;
91     float  u, dudx, dudy;
92     float  v, dvdx, dvdy;
93     float3 dPdu, dPdv;
94     float  time;
95     float  dtime;
96     float3 dPdtime;
97     float3 Ps, dPsdx, dPsdy;
98     void*  renderstate;
99     void*  tracedata;
100     void*  objdata;
101     void*  context;
102     void*  renderer;
103     void*  object2common;
104     void*  shader2common;
105     void*  Ci;
106     float  surfacearea;
107     int    raytype;
108     int    flipHandedness;
109     int    backfacing;
110     int    shaderID;
111 };
112 
113 
114 enum RayType {
115     CAMERA       = 1,
116     SHADOW       = 2,
117     REFLECTION   = 4,
118     REFRACTION   = 8,
119     DIFFUSE      = 16,
120     GLOSSY       = 32,
121     SUBSURFACE   = 64,
122     DISPLACEMENT = 128
123 };
124 
125 
126 // Closures supported by the OSL sample renderer.  This list is mostly aspirational.
127 enum ClosureIDs {
128     EMISSION_ID = 1,
129     BACKGROUND_ID,
130     DIFFUSE_ID,
131     OREN_NAYAR_ID,
132     TRANSLUCENT_ID,
133     PHONG_ID,
134     WARD_ID,
135     MICROFACET_ID,
136     REFLECTION_ID,
137     FRESNEL_REFLECTION_ID,
138     REFRACTION_ID,
139     TRANSPARENT_ID,
140     DEBUG_ID,
141     HOLDOUT_ID,
142 };
143 
144 #if (OPTIX_VERSION >= 70000)
145 // ========================================
146 //
147 // Some helper vector functions
148 //
149 static __forceinline__ __device__ float3 operator*(const float a, const float3& b)
150 {
151       return make_float3(a * b.x, a * b.y, a * b.z);
152 }
153 
154 static __forceinline__ __device__ float3 operator*(const float3 & a, const float b)
155 {
156       return make_float3(a.x * b, a.y * b, a.z * b);
157 }
158 
159 static __forceinline__ __device__ float3 operator+(const float3& a, const float3& b)
160 {
161       return make_float3(a.x + b.x, a.y + b.y, a.z + b.z);
162 }
163 
164 static __forceinline__ __device__ float3 operator-(const float3& a, const float3& b)
165 {
166       return make_float3(a.x - b.x, a.y - b.y, a.z - b.z);
167 }
168 
169 static __forceinline__ __device__ float3 operator-(const float3& a)
170 {
171       return make_float3(-a.x, -a.y, -a.z);
172 }
173 
dot(const float3 & a,const float3 & b)174 static __forceinline__ __device__ float dot(const float3& a, const float3& b)
175 {
176     return a.x * b.x + a.y * b.y + a.z * b.z;
177 }
178 
normalize(const float3 & v)179 static __forceinline__ __device__ float3 normalize(const float3& v)
180 {
181     float invLen = 1.0f / sqrtf(dot(v, v));
182     return invLen * v;
183 }
184 //
185 // ========================================
186 #endif //#if (OPTIX_VERSION >= 70000)
187 
188 }  // anonymous namespace
189