1 //******************************************************************************
2 ///
3 /// @file unix/povconfig/syspovconfig.h
4 ///
5 /// Unix-specific general POV-Ray compile-time configuration.
6 ///
7 /// This header file configures module-independent aspects of POV-Ray for
8 /// running properly on a Unix platform.
9 ///
10 /// @copyright
11 /// @parblock
12 ///
13 /// Persistence of Vision Ray Tracer ('POV-Ray') version 3.8.
14 /// Copyright 1991-2018 Persistence of Vision Raytracer Pty. Ltd.
15 ///
16 /// POV-Ray is free software: you can redistribute it and/or modify
17 /// it under the terms of the GNU Affero General Public License as
18 /// published by the Free Software Foundation, either version 3 of the
19 /// License, or (at your option) any later version.
20 ///
21 /// POV-Ray is distributed in the hope that it will be useful,
22 /// but WITHOUT ANY WARRANTY; without even the implied warranty of
23 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 /// GNU Affero General Public License for more details.
25 ///
26 /// You should have received a copy of the GNU Affero General Public License
27 /// along with this program.  If not, see <http://www.gnu.org/licenses/>.
28 ///
29 /// ----------------------------------------------------------------------------
30 ///
31 /// POV-Ray is based on the popular DKB raytracer version 2.12.
32 /// DKBTrace was originally written by David K. Buck.
33 /// DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
34 ///
35 /// @endparblock
36 ///
37 //******************************************************************************
38 
39 #ifndef POVRAY_UNIX_SYSPOVCONFIG_H
40 #define POVRAY_UNIX_SYSPOVCONFIG_H
41 
42 #define _FILE_OFFSET_BITS 64 // Required for some Unix flavors to get a 64-bit off_t type on 32-bit systems.
43 
44 // C++ variants of C standard headers
45 #include <cmath>
46 #include <cstdarg>
47 
48 // C++ standard headers
49 #include <algorithm>
50 #include <exception>
51 #include <limits>
52 #include <list>
53 #include <memory>
54 #include <stdexcept>
55 #include <string>
56 #include <vector>
57 
58 // boost headers
59 #include <boost/intrusive_ptr.hpp>
60 
61 #ifdef HAVE_CONFIG_H
62 // from directory "." (generated by ./configure)
63 # include "config.h"
64 #else
65 # error "!!!!! config.h is required !!!!!"
66 #endif
67 
68 #ifdef HAVE_STDINT_H
69 #include "stdint.h"
70 #endif
71 
72 using std::max;
73 using std::min;
74 
75 #ifndef STD_TYPES_DECLARED
76 #define STD_TYPES_DECLARED
77 
78 // the following types are used extensively throughout the POV source and hence are
79 // included and named here for reasons of clarity and convenience.
80 
81 // when we say 'string' we mean std::string
82 using std::string;
83 
84 // and vector is a std::vector
85 using std::vector;
86 
87 // yup, list too
88 using std::list;
89 
90 // runtime_error is the base of our Exception class, plus is referred
91 // to in a few other places.
92 using std::runtime_error;
93 
94 // we use the C++11 standard shared pointers
95 using std::shared_ptr;
96 using std::weak_ptr;
97 using std::dynamic_pointer_cast;
98 using std::static_pointer_cast;
99 using std::const_pointer_cast;
100 
101 using boost::intrusive_ptr;
102 
103 #endif // STD_POV_TYPES_DECLARED
104 
105 // After Stroustrup in _The C++ Programming Language, 3rd Ed_ p. 88
106 #ifndef NULL
107 const int NULL=0;
108 #endif
109 
110 #define POV_DELETE_FILE(name)  unlink(name)
111 
112 #if defined (PATH_MAX)
113     // Use the system's actual limit if known.
114     // NB: PATH_MAX is understood including a terminating NUL character.
115     #define POV_FILENAME_BUFFER_CHARS   (PATH_MAX-1)
116 #elif defined (_POSIX_PATH_MAX)
117     // Otherwise, use the most restrictive limit allowed by POSIX if defined.
118     // NB: _POSIX_PATH_MAX is understood including a terminating NUL character.
119     #define POV_FILENAME_BUFFER_CHARS   (_POSIX_PATH_MAX-1)
120 #else
121     // As a fallback, use an even more conservative limit.
122     #define POV_FILENAME_BUFFER_CHARS   199
123 #endif
124 
125 #define DEFAULT_OUTPUT_FORMAT       kPOVList_FileType_PNG
126 #define DEFAULT_DISPLAY_GAMMA_TYPE  kPOVList_GammaType_SRGB
127 #define DEFAULT_DISPLAY_GAMMA       2.2
128 
129 #define METADATA_PLATFORM_STRING BUILD_ARCH
130 #define METADATA_COMPILER_STRING COMPILER_VERSION
131 
132 #ifdef BUILD_X86
133 
134 #define POV_CPUINFO         CPUInfo::GetFeatures()
135 #define POV_CPUINFO_DETAILS CPUInfo::GetDetails()
136 #define POV_CPUINFO_H       "cpuid.h"
137 
138 // Test which enhanced instruction sets the compiler is generally able to support.
139 
140 #if defined(__INTEL_COMPILER)
141     // Intel compiler
142     #if (__INTEL_COMPILER >= 1110) // 11.1
143         #define HAVE_ASM_AVX
144     #endif
145     #if (__INTEL_COMPILER >= 1400) // 14.0
146         #define HAVE_ASM_AVX2
147         #define HAVE_ASM_FMA3
148     #endif
149 #elif defined(__GNUC__)
150     // GCC compiler (or yet another compiler imitating GCC)
151     #if (__GNUC__ == 4) // 4.x
152         #if (__GNUC_MINOR__ >= 5) // 4.5 or later
153             #define HAVE_ASM_FMA4
154         #endif
155         #if (__GNUC_MINOR__ >= 6) // 4.6 or later
156             #define HAVE_ASM_AVX
157         #endif
158         #if (__GNUC_MINOR__ >= 7) // 4.7 or later
159             #define HAVE_ASM_AVX2
160             #define HAVE_ASM_FMA3
161         #endif
162     #elif (__GNUC__ >= 5) // 5.x or later
163         #define HAVE_ASM_AVX
164         #define HAVE_ASM_AVX2
165         #define HAVE_ASM_FMA3
166         #define HAVE_ASM_FMA4
167     #endif
168 #endif
169 
170 // Test which enhanced instruction sets are actually enabled.
171 
172 // NOTE: The following tests may yield different results for individual translation units,
173 // most notably platform-specific optimized implementations.
174 #if defined (__GNUC__)
175     // GCC compiler (or any compiler imitating GCC)
176     #if !defined (__AVX__)
177         #define DISABLE_AVX
178     #endif
179     #if !defined (__AVX2__)
180         #define DISABLE_AVX2
181     #endif
182     #if !defined (__FMA__)
183         #define DISABLE_FMA3
184     #endif
185     #if !defined (__FMA4__)
186         #define DISABLE_FMA4
187     #endif
188 #endif
189 
190 // Decide which optimized code to enable.
191 
192 #if defined(HAVE_ASM_AVX)
193     #define TRY_OPTIMIZED_NOISE                 // optimized noise master switch.
194     #define TRY_OPTIMIZED_NOISE_AVX_PORTABLE    // AVX-only compiler-optimized noise.
195     #define TRY_OPTIMIZED_NOISE_AVX             // AVX-only hand-optimized noise (Intel).
196 #endif
197 
198 #if defined(__GNUC__) && __GNUC__ == 8
199 #define DISABLE_AVX
200 #define DISABLE_AVX2
201 #endif
202 
203 #if defined(DISABLE_AVX)
204     #define DISABLE_OPTIMIZED_NOISE_AVX
205     #define DISABLE_OPTIMIZED_NOISE_AVX_PORTABLE
206 #endif
207 
208 #if defined(HAVE_ASM_AVX) && defined(HAVE_ASM_FMA4)
209     #define TRY_OPTIMIZED_NOISE                 // optimized noise master switch.
210     #define TRY_OPTIMIZED_NOISE_AVXFMA4         // AVX/FMA4 hand-optimized noise (AMD).
211 #endif
212 
213 #if defined(DISABLE_AVX) || defined(DISABLE_FMA4)
214     #define DISABLE_OPTIMIZED_NOISE_AVXFMA4
215 #endif
216 
217 #if defined(HAVE_ASM_AVX2) && defined(HAVE_ASM_FMA3)
218     #define TRY_OPTIMIZED_NOISE                 // optimized noise master switch.
219     #define TRY_OPTIMIZED_NOISE_AVX2FMA3        // AVX2/FMA3 hand-optimized noise (Intel).
220 #endif
221 
222 #if defined(DISABLE_AVX2) || defined(DISABLE_FMA3)
223     #define DISABLE_OPTIMIZED_NOISE_AVX2FMA3
224 #endif
225 
226 #endif // BUILD_X86
227 
228 
229 #ifdef HAVE_NAN
230     #if defined(HAVE_STD_ISNAN)
231         #define POV_ISNAN(x) std::isnan(x)
232     #elif defined(HAVE_ISNAN)
233         #define POV_ISNAN(x) isnan(x)
234     #elif defined(HAVE_EMULATED_ISNAN)
235         template<typename T>
pov_isnan(T x)236         inline bool pov_isnan(T x) { volatile T v = x; return (v != x); }
237         #define POV_ISNAN(x) pov_isnan(x)
238     #else
239         #error "Someone must have found an alternative way of identifying NaNs but failed to implement it here."
240     #endif
241 #else
242     #define POV_ISNAN(x) (false)
243 #endif
244 
245 #ifdef HAVE_INF
246     #if defined(HAVE_STD_ISINF)
247         #define POV_ISINF(x) std::isinf(x)
248     #elif defined(HAVE_ISINF)
249         #define POV_ISINF(x) isinf(x)
250     #elif defined(HAVE_EMULATED_ISINF)
251         template<typename T>
pov_isinf(T x)252         inline bool pov_isinf(T x) { volatile T v = std::numeric_limits<T>::max(); return std::fabs(x) > v; }
253         #define POV_ISINF(x) pov_isinf(x)
254     #else
255         #error "Someone must have found an alternative way of identifying infinities but failed to implement it here."
256     #endif
257 #else
258     #define POV_ISINF(x) (false)
259 #endif
260 
261 #define POV_ISFINITE(x) (!POV_ISNAN(x) && !POV_ISINF(x))
262 
263 #if defined INT8_MAX || defined int8_t
264     #define POV_INT8 int8_t
265 #else
266     // Autoconf is convinced that there's no signed integer type exactly 8 bits wide. We won't pick a type here.
267 #endif
268 
269 #if defined UINT8_MAX || defined uint8_t
270     #define POV_UINT8 uint8_t
271 #else
272     // Autoconf is convinced that there's no unsigned integer type exactly 8 bits wide. We won't pick a type here.
273 #endif
274 
275 #if defined INT16_MAX || defined int16_t
276     #define POV_INT16 int16_t
277 #else
278     // Autoconf is convinced that there's no signed integer type exactly 16 bits wide. We won't pick a type here.
279 #endif
280 
281 #if defined UINT16_MAX || defined uint16_t
282     #define POV_UINT16 uint16_t
283 #else
284     // Autoconf is convinced that there's no unsigned integer type exactly 16 bits wide. We won't pick a type here.
285 #endif
286 
287 #if defined INT32_MAX || defined int32_t
288     #define POV_INT32 int32_t
289 #else
290     // Autoconf is convinced that there's no signed integer type exactly 32 bits wide. We won't pick a type here.
291 #endif
292 
293 #if defined UINT32_MAX || defined uint32_t
294     #define POV_UINT32 uint32_t
295 #else
296     // Autoconf is convinced that there's no unsigned integer type exactly 32 bits wide. We won't pick a type here.
297 #endif
298 
299 #if defined INT64_MAX || defined int64_t
300     #define POV_INT64 int64_t
301 #else
302     // Autoconf is convinced that there's no signed integer type exactly 64 bits wide. We won't pick a type here.
303 #endif
304 
305 #if defined UINT64_MAX || defined uint64_t
306     #define POV_UINT64 uint64_t
307 #else
308     // Autoconf is convinced that there's no unsigned integer type exactly 64 bits wide. We won't pick a type here.
309 #endif
310 
311 // Pull in additional settings depending on Unix flavor
312 
313 #if defined(_AIX)
314     // IBM AIX detected.
315     // Not officially supported yet; comment-out the following line to try with default POSIX settings.
316     #error "IBM AIX detected, but not explicitly supported yet; proceed at your own risk."
317     #include "syspovconfig_posix.h"
318 #elif defined(__hpux)
319     // Hewlett-Packard HP-UX detected.
320     // Not officially supported yet; comment-out the following line to try with default POSIX settings.
321     #error "Hewlett-Packard HP-UX detected, but not explicitly supported yet; proceed at your own risk."
322     #include "syspovconfig_posix.h"
323 #elif defined(__linux__)
324     // GNU/Linux detected.
325     #include "syspovconfig_gnu.h"
326 #elif defined(__APPLE__) && defined(__MACH__)
327     // Apple Mac OS X detected.
328     #include "syspovconfig_osx.h"
329 #elif defined(__sun) && defined(__SVR4)
330     // Sun/Oracle Solaris detected.
331     // Not officially supported yet; comment-out the following line to try with default POSIX settings.
332     #error "Sun/Oracle Solaris detected, but not explicitly supported yet; proceed at your own risk."
333     #include "syspovconfig_posix.h"
334 #elif defined(__CYGWIN__)
335     // Cygwin detected.
336     // Not officially supported yet; comment-out the following line to try with default POSIX settings.
337     #error "Cygwin detected, but not explicitly supported yet; proceed at your own risk."
338     #include "syspovconfig_posix.h"
339 #elif defined(__unix__)
340     // Some Unix other than the above detected.
341     #include <sys/param.h>
342     #if defined(BSD)
343         // BSD-style Unix detected.
344         #include "syspovconfig_bsd.h"
345     #else
346         // Not officially supported yet; comment-out the following line to try with default POSIX settings.
347         #error "Unix detected, but flavor not identified; proceed at your own risk."
348         #include "syspovconfig_posix.h"
349     #endif
350 #else
351     // Doesn't look like a Unix at all.
352     // Comment-out the following line to try with default POSIX settings.
353     #error "No Unix detected; proceed at your own risk."
354     #include "syspovconfig_posix.h"
355 #endif
356 
357 #endif // POVRAY_UNIX_SYSPOVCONFIG_H
358