1 /*
2 * Copyright 2011-2013 Blender Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef __UTIL_DEBUG_H__
18 #define __UTIL_DEBUG_H__
19
20 #include <cassert>
21 #include <iostream>
22
23 #include "bvh/bvh_params.h"
24
25 CCL_NAMESPACE_BEGIN
26
27 /* Global storage for all sort of flags used to fine-tune behavior of particular
28 * areas for the development purposes, without officially exposing settings to
29 * the interface.
30 */
31 class DebugFlags {
32 public:
33 /* Use static BVH in viewport, to match final render exactly. */
34 bool viewport_static_bvh;
35
36 bool running_inside_blender;
37
38 /* Descriptor of CPU feature-set to be used. */
39 struct CPU {
40 CPU();
41
42 /* Reset flags to their defaults. */
43 void reset();
44
45 /* Flags describing which instructions sets are allowed for use. */
46 bool avx2;
47 bool avx;
48 bool sse41;
49 bool sse3;
50 bool sse2;
51
52 /* Check functions to see whether instructions up to the given one
53 * are allowed for use.
54 */
has_avx2CPU55 bool has_avx2()
56 {
57 return has_avx() && avx2;
58 }
has_avxCPU59 bool has_avx()
60 {
61 return has_sse41() && avx;
62 }
has_sse41CPU63 bool has_sse41()
64 {
65 return has_sse3() && sse41;
66 }
has_sse3CPU67 bool has_sse3()
68 {
69 return has_sse2() && sse3;
70 }
has_sse2CPU71 bool has_sse2()
72 {
73 return sse2;
74 }
75
76 /* Requested BVH layout.
77 *
78 * By default the fastest will be used. For debugging the BVH used by other
79 * CPUs and GPUs can be selected here instead.
80 */
81 BVHLayout bvh_layout;
82
83 /* Whether split kernel is used */
84 bool split_kernel;
85 };
86
87 /* Descriptor of CUDA feature-set to be used. */
88 struct CUDA {
89 CUDA();
90
91 /* Reset flags to their defaults. */
92 void reset();
93
94 /* Whether adaptive feature based runtime compile is enabled or not.
95 * Requires the CUDA Toolkit and only works on Linux atm. */
96 bool adaptive_compile;
97
98 /* Whether split kernel is used */
99 bool split_kernel;
100 };
101
102 /* Descriptor of OptiX feature-set to be used. */
103 struct OptiX {
104 OptiX();
105
106 /* Reset flags to their defaults. */
107 void reset();
108
109 /* Number of CUDA streams to launch kernels concurrently from. */
110 int cuda_streams;
111
112 /* Use OptiX curves API for hair instead of custom implementation. */
113 bool curves_api;
114 };
115
116 /* Descriptor of OpenCL feature-set to be used. */
117 struct OpenCL {
118 OpenCL();
119
120 /* Reset flags to their defaults. */
121 void reset();
122
123 /* Available device types.
124 * Only gives a hint which devices to let user to choose from, does not
125 * try to use any sort of optimal device or so.
126 */
127 enum DeviceType {
128 /* None of OpenCL devices will be used. */
129 DEVICE_NONE,
130 /* All OpenCL devices will be used. */
131 DEVICE_ALL,
132 /* Default system OpenCL device will be used. */
133 DEVICE_DEFAULT,
134 /* Host processor will be used. */
135 DEVICE_CPU,
136 /* GPU devices will be used. */
137 DEVICE_GPU,
138 /* Dedicated OpenCL accelerator device will be used. */
139 DEVICE_ACCELERATOR,
140 };
141
142 /* Available kernel types. */
143 enum KernelType {
144 /* Do automated guess which kernel to use, based on the officially
145 * supported GPUs and such.
146 */
147 KERNEL_DEFAULT,
148 /* Force mega kernel to be used. */
149 KERNEL_MEGA,
150 /* Force split kernel to be used. */
151 KERNEL_SPLIT,
152 };
153
154 /* Requested device type. */
155 DeviceType device_type;
156
157 /* Use debug version of the kernel. */
158 bool debug;
159
160 /* TODO(mai): Currently this is only for OpenCL, but we should have it implemented for all
161 * devices. */
162 /* Artificial memory limit in bytes (0 if disabled). */
163 size_t mem_limit;
164 };
165
166 /* Get instance of debug flags registry. */
get()167 static DebugFlags &get()
168 {
169 static DebugFlags instance;
170 return instance;
171 }
172
173 /* Reset flags to their defaults. */
174 void reset();
175
176 /* Requested CPU flags. */
177 CPU cpu;
178
179 /* Requested CUDA flags. */
180 CUDA cuda;
181
182 /* Requested OptiX flags. */
183 OptiX optix;
184
185 /* Requested OpenCL flags. */
186 OpenCL opencl;
187
188 private:
189 DebugFlags();
190
191 #if (__cplusplus > 199711L)
192 public:
193 explicit DebugFlags(DebugFlags const & /*other*/) = delete;
194 void operator=(DebugFlags const & /*other*/) = delete;
195 #else
196 private:
197 explicit DebugFlags(DebugFlags const & /*other*/);
198 void operator=(DebugFlags const & /*other*/);
199 #endif
200 };
201
202 typedef DebugFlags &DebugFlagsRef;
203 typedef const DebugFlags &DebugFlagsConstRef;
204
DebugFlags()205 inline DebugFlags &DebugFlags()
206 {
207 return DebugFlags::get();
208 }
209
210 std::ostream &operator<<(std::ostream &os, DebugFlagsConstRef debug_flags);
211
212 CCL_NAMESPACE_END
213
214 #endif /* __UTIL_DEBUG_H__ */
215