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