]> git.cworth.org Git - vogl/blob - src/voglcore/vogl_utils.cpp
Initial vogl checkin
[vogl] / src / voglcore / vogl_utils.cpp
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
4  * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
5  * All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  *
25  **************************************************************************/
26
27 // File: vogl_utils.cpp
28 #include "vogl_core.h"
29 #include "vogl_utils.h"
30 #include "vogl_file_utils.h"
31
32 namespace vogl
33 {
34     namespace utils
35     {
36         const int64_t s_signed_mins[9] = { 0, cINT8_MIN, cINT16_MIN, static_cast<int64_t>(0xFFFFFFFFFF800000), cINT32_MIN, static_cast<int64_t>(0xFFFFFF8000000000), static_cast<int64_t>(0xFFFF800000000000), static_cast<int64_t>(0xFF80000000000000), cINT64_MIN };
37         const int64_t s_signed_maxs[9] = { 0, cINT8_MAX, cINT16_MAX, 0x7FFFFFLL, cINT32_MAX, 0x7FFFFFFFFFLL, 0x7FFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFLL, cINT64_MAX };
38         const uint64_t s_unsigned_maxes[9] = { 0, cUINT8_MAX, cUINT16_MAX, 0xFFFFFFULL, cUINT32_MAX, 0xFFFFFFFFFFULL, 0xFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFULL, cUINT64_MAX };
39
40 #if defined(VOGL_USE_LINUX_API)
41         int g_reliable_rdtsc = -1;
42 #endif
43         bool init_rdtsc()
44         {
45 #if defined(VOGL_USE_LINUX_API)
46             if (g_reliable_rdtsc == -1)
47             {
48                 g_reliable_rdtsc = 0;
49
50                 vogl::growable_array<char, 2048> current_clocksource;
51                 if (file_utils::read_proc_file("/sys/devices/system/clocksource/clocksource0/current_clocksource", current_clocksource))
52                 {
53                     const char *clock_source = current_clocksource.get_ptr();
54                     g_reliable_rdtsc = (clock_source[0] == 't' && clock_source[1] == 's' && clock_source[2] == 'c');
55                 }
56             }
57             // return true for reliable rdtsc.
58             return !!g_reliable_rdtsc;
59 #endif
60             return true;
61         }
62
63         class check_for_sse_4_1
64         {
65         public:
66             check_for_sse_4_1()
67             {
68                 if (!utils::check_for_sse_4_1_support())
69                 {
70                     fprintf(stderr, "This program requires SSE 4.1, which is supported by Intel Core 2 (\"Penryn\"), Intel Core i7 (\"Nehalem\"), AMD Bulldozer, and later CPU's\n");
71                     exit(EXIT_FAILURE);
72                 }
73             }
74         } g_check_for_sse_4_1_obj;
75
76         bool check_for_sse_4_1_support()
77         {
78             bool sse4_1 = false;
79             bool sse4_2 = false;
80
81 #ifdef _WIN32
82             int CPUInfo[4] = { -1 };
83             __cpuid(CPUInfo, 0);
84
85             if (CPUInfo[0] > 0)
86             {
87                 __cpuid(CPUInfo, 1);
88                 sse4_1 = (CPUInfo[2] & 0x80000) != 0;
89                 sse4_2 = (CPUInfo[2] & 0x100000) != 0;
90             }
91 #else
92             //         #warning Create linux implementation of check_for_sse_4_1_support
93             sse4_1 = sse4_2 = true;
94 #endif
95
96             return sse4_1;
97         }
98
99         void endian_switch_words(uint16 *p, uint num)
100         {
101             uint16 *p_end = p + num;
102             while (p != p_end)
103             {
104                 uint16 k = *p;
105                 *p++ = swap16(k);
106             }
107         }
108
109         void endian_switch_dwords(uint32 *p, uint num)
110         {
111             uint32 *p_end = p + num;
112             while (p != p_end)
113             {
114                 uint32 k = *p;
115                 *p++ = swap32(k);
116             }
117         }
118
119         void copy_words(uint16 *pDst, const uint16 *pSrc, uint num, bool endian_switch)
120         {
121             if (!endian_switch)
122                 memcpy(pDst, pSrc, num << 1U);
123             else
124             {
125                 uint16 *pDst_end = pDst + num;
126                 while (pDst != pDst_end)
127                     *pDst++ = swap16(*pSrc++);
128             }
129         }
130
131         void copy_dwords(uint32 *pDst, const uint32 *pSrc, uint num, bool endian_switch)
132         {
133             if (!endian_switch)
134                 memcpy(pDst, pSrc, num << 2U);
135             else
136             {
137                 uint32 *pDst_end = pDst + num;
138                 while (pDst != pDst_end)
139                     *pDst++ = swap32(*pSrc++);
140             }
141         }
142
143         uint compute_max_mips(uint width, uint height, uint min_width, uint min_height)
144         {
145             if ((width | height) == 0)
146                 return 0;
147
148             uint total_mips = 1;
149
150             while ((width > min_width) || (height > min_height))
151             {
152                 width >>= 1U;
153                 height >>= 1U;
154                 total_mips++;
155             }
156
157             return total_mips;
158         }
159
160         uint compute_max_mips3D(uint width, uint height, uint depth, uint min_width, uint min_height, uint min_depth)
161         {
162             if ((width | height | depth) == 0)
163                 return 0;
164
165             uint total_mips = 1;
166
167             while ((width > min_width) || (height > min_height) || (depth > min_depth))
168             {
169                 width >>= 1U;
170                 height >>= 1U;
171                 depth >>= 1U;
172                 total_mips++;
173             }
174
175             return total_mips;
176         }
177
178         bool is_buffer_printable(const void *pBuf, uint buf_size, bool allow_crlf, bool expect_null_terminator)
179         {
180             if (!pBuf)
181                 return false;
182             if (!buf_size)
183                 return true;
184
185             uint scan_size = expect_null_terminator ? (buf_size - 1) : buf_size;
186
187             for (uint i = 0; i < scan_size; i++)
188             {
189                 uint8 c = reinterpret_cast<const uint8 *>(pBuf)[i];
190                 if (allow_crlf)
191                 {
192                     if ((c == 0x0A) || (c == 0x0D))
193                         continue;
194                 }
195
196                 if ((c < 32) || (c > 127))
197                     return false;
198             }
199
200             if (expect_null_terminator)
201             {
202                 if (reinterpret_cast<const uint8 *>(pBuf)[buf_size - 1] != 0)
203                     return false;
204             }
205
206             return true;
207         }
208
209     } // namespace utils
210
211 } // namespace vogl