Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
HWDetect.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2013 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "precompiled.h"
19 
22 
23 #include "lib/ogl.h"
24 #include "lib/svn_revision.h"
25 #include "lib/timer.h"
26 #include "lib/utf8.h"
29 #include "lib/sysdep/cpu.h"
30 #include "lib/sysdep/gfx.h"
31 #include "lib/sysdep/numa.h"
32 #include "lib/sysdep/os_cpu.h"
33 #include "lib/sysdep/snd.h"
34 #if ARCH_X86_X64
37 #endif
38 #include "ps/CLogger.h"
39 #include "ps/ConfigDB.h"
40 #include "ps/Filesystem.h"
41 #include "ps/UserReport.h"
42 #include "ps/VideoMode.h"
43 #include "ps/GameSetup/Config.h"
44 
45 static void ReportGLLimits(ScriptInterface& scriptInterface, CScriptValRooted settings);
46 
47 #if ARCH_X86_X64
48 CScriptVal ConvertCaches(ScriptInterface& scriptInterface, x86_x64::IdxCache idxCache)
49 {
50  CScriptVal ret;
51  scriptInterface.Eval("[]", ret);
52  for (size_t idxLevel = 0; idxLevel < x86_x64::Cache::maxLevels; ++idxLevel)
53  {
54  const x86_x64::Cache* pcache = x86_x64::Caches(idxCache+idxLevel);
55  if (pcache->type == x86_x64::Cache::kNull || pcache->numEntries == 0)
56  continue;
57  CScriptVal cache;
58  scriptInterface.Eval("({})", cache);
59  scriptInterface.SetProperty(cache.get(), "type", (u32)pcache->type);
60  scriptInterface.SetProperty(cache.get(), "level", (u32)pcache->level);
61  scriptInterface.SetProperty(cache.get(), "associativity", (u32)pcache->associativity);
62  scriptInterface.SetProperty(cache.get(), "linesize", (u32)pcache->entrySize);
63  scriptInterface.SetProperty(cache.get(), "sharedby", (u32)pcache->sharedBy);
64  scriptInterface.SetProperty(cache.get(), "totalsize", (u32)pcache->TotalSize());
65  scriptInterface.SetPropertyInt(ret.get(), idxLevel, cache);
66  }
67  return ret;
68 }
69 
70 CScriptVal ConvertTLBs(ScriptInterface& scriptInterface)
71 {
72  CScriptVal ret;
73  scriptInterface.Eval("[]", ret);
74  for(size_t i = 0; ; i++)
75  {
77  if (!ptlb)
78  break;
79  CScriptVal tlb;
80  scriptInterface.Eval("({})", tlb);
81  scriptInterface.SetProperty(tlb.get(), "type", (u32)ptlb->type);
82  scriptInterface.SetProperty(tlb.get(), "level", (u32)ptlb->level);
83  scriptInterface.SetProperty(tlb.get(), "associativity", (u32)ptlb->associativity);
84  scriptInterface.SetProperty(tlb.get(), "pagesize", (u32)ptlb->entrySize);
85  scriptInterface.SetProperty(tlb.get(), "entries", (u32)ptlb->numEntries);
86  scriptInterface.SetPropertyInt(ret.get(), i, tlb);
87  }
88  return ret;
89 }
90 #endif
91 
92 // The Set* functions will override the default behaviour, unless the user
93 // has explicitly set a config variable to override that.
94 // (TODO: This is an ugly abuse of the config system)
95 static bool IsOverridden(const char* setting)
96 {
97  EConfigNamespace ns = g_ConfigDB.GetValueNamespace(CFG_COMMAND, setting);
98  return !(ns == CFG_LAST || ns == CFG_DEFAULT);
99 }
100 
101 void SetDisableAudio(void* UNUSED(cbdata), bool disabled)
102 {
103  g_DisableAudio = disabled;
104 }
105 
106 void SetDisableS3TC(void* UNUSED(cbdata), bool disabled)
107 {
108  if (!IsOverridden("nos3tc"))
110 }
111 
112 void SetDisableShadows(void* UNUSED(cbdata), bool disabled)
113 {
114  if (!IsOverridden("shadows"))
115  g_Shadows = !disabled;
116 }
117 
118 void SetDisableShadowPCF(void* UNUSED(cbdata), bool disabled)
119 {
120  if (!IsOverridden("shadowpcf"))
121  g_ShadowPCF = !disabled;
122 }
123 
124 void SetDisableAllWater(void* UNUSED(cbdata), bool disabled)
125 {
126  if (!IsOverridden("waternormals"))
127  g_WaterNormal = !disabled;
128  if (!IsOverridden("waterrealdepth"))
129  g_WaterRealDepth = !disabled;
130  if (!IsOverridden("waterfoam"))
131  g_WaterFoam = !disabled;
132  if (!IsOverridden("watercoastalwaves"))
133  g_WaterCoastalWaves = !disabled;
134  if (!IsOverridden("waterrefraction"))
135  g_WaterRefraction = !disabled;
136  if (!IsOverridden("waterreflection"))
137  g_WaterReflection = !disabled;
138  if (!IsOverridden("watershadows"))
139  g_WaterShadows = !disabled;
140 }
141 void SetDisableFancyWater(void* UNUSED(cbdata), bool disabled)
142 {
143  if (!IsOverridden("waterrealdepth"))
144  g_WaterRealDepth = !disabled;
145  if (!IsOverridden("waterfoam"))
146  g_WaterFoam = !disabled;
147  if (!IsOverridden("watercoastalwaves"))
148  g_WaterCoastalWaves = !disabled;
149  if (!IsOverridden("watershadows"))
150  g_WaterShadows = !disabled;
151 }
152 void SetDisableFBOWater(void* UNUSED(cbdata), bool disabled)
153 {
154  if (!IsOverridden("waterfoam"))
155  g_WaterFoam = !disabled;
156  if (!IsOverridden("watercoastalwaves"))
157  g_WaterCoastalWaves = !disabled;
158 }
159 
160 void SetRenderPath(void* UNUSED(cbdata), std::string renderpath)
161 {
162  g_RenderPath = renderpath;
163 }
164 
166 {
167  TIMER(L"RunHardwareDetection");
168 
169  ScriptInterface& scriptInterface = g_ScriptingHost.GetScriptInterface();
170 
171  scriptInterface.RegisterFunction<void, bool, &SetDisableAudio>("SetDisableAudio");
172  scriptInterface.RegisterFunction<void, bool, &SetDisableS3TC>("SetDisableS3TC");
173  scriptInterface.RegisterFunction<void, bool, &SetDisableShadows>("SetDisableShadows");
174  scriptInterface.RegisterFunction<void, bool, &SetDisableShadowPCF>("SetDisableShadowPCF");
175  scriptInterface.RegisterFunction<void, bool, &SetDisableAllWater>("SetDisableAllWater");
176  scriptInterface.RegisterFunction<void, bool, &SetDisableFancyWater>("SetDisableFancyWater");
177  scriptInterface.RegisterFunction<void, bool, &SetDisableFBOWater>("SetDisableFBOWater");
178  scriptInterface.RegisterFunction<void, std::string, &SetRenderPath>("SetRenderPath");
179 
180  // Load the detection script:
181 
182  const wchar_t* scriptName = L"hwdetect/hwdetect.js";
183  CVFSFile file;
184  if (file.Load(g_VFS, scriptName) != PSRETURN_OK)
185  {
186  LOGERROR(L"Failed to load hardware detection script");
187  return;
188  }
189 
190  std::string code = file.DecodeUTF8(); // assume it's UTF-8
191  scriptInterface.LoadScript(scriptName, code);
192 
193  // Collect all the settings we'll pass to the script:
194  // (We'll use this same data for the opt-in online reporting system, so it
195  // includes some fields that aren't directly useful for the hwdetect script)
196 
197  CScriptValRooted settings;
198  scriptInterface.Eval("({})", settings);
199 
200  scriptInterface.SetProperty(settings.get(), "os_unix", OS_UNIX);
201  scriptInterface.SetProperty(settings.get(), "os_bsd", OS_BSD);
202  scriptInterface.SetProperty(settings.get(), "os_linux", OS_LINUX);
203  scriptInterface.SetProperty(settings.get(), "os_android", OS_ANDROID);
204  scriptInterface.SetProperty(settings.get(), "os_macosx", OS_MACOSX);
205  scriptInterface.SetProperty(settings.get(), "os_win", OS_WIN);
206 
207  scriptInterface.SetProperty(settings.get(), "arch_ia32", ARCH_IA32);
208  scriptInterface.SetProperty(settings.get(), "arch_amd64", ARCH_AMD64);
209  scriptInterface.SetProperty(settings.get(), "arch_arm", ARCH_ARM);
210 
211 #ifdef NDEBUG
212  scriptInterface.SetProperty(settings.get(), "build_debug", 0);
213 #else
214  scriptInterface.SetProperty(settings.get(), "build_debug", 1);
215 #endif
216  scriptInterface.SetProperty(settings.get(), "build_opengles", CONFIG2_GLES);
217 
218  scriptInterface.SetProperty(settings.get(), "build_datetime", std::string(__DATE__ " " __TIME__));
219  scriptInterface.SetProperty(settings.get(), "build_revision", std::wstring(svn_revision));
220 
221  scriptInterface.SetProperty(settings.get(), "build_msc", (int)MSC_VERSION);
222  scriptInterface.SetProperty(settings.get(), "build_icc", (int)ICC_VERSION);
223  scriptInterface.SetProperty(settings.get(), "build_gcc", (int)GCC_VERSION);
224  scriptInterface.SetProperty(settings.get(), "build_clang", (int)CLANG_VERSION);
225 
226  scriptInterface.SetProperty(settings.get(), "gfx_card", gfx::CardName());
227  scriptInterface.SetProperty(settings.get(), "gfx_drv_ver", gfx::DriverInfo());
228 
229  scriptInterface.SetProperty(settings.get(), "snd_card", std::wstring(snd_card));
230  scriptInterface.SetProperty(settings.get(), "snd_drv_ver", std::wstring(snd_drv_ver));
231 
232  ReportGLLimits(scriptInterface, settings);
233 
234  scriptInterface.SetProperty(settings.get(), "video_xres", g_VideoMode.GetXRes());
235  scriptInterface.SetProperty(settings.get(), "video_yres", g_VideoMode.GetYRes());
236  scriptInterface.SetProperty(settings.get(), "video_bpp", g_VideoMode.GetBPP());
237 
238  scriptInterface.SetProperty(settings.get(), "video_desktop_xres", g_VideoMode.GetDesktopXRes());
239  scriptInterface.SetProperty(settings.get(), "video_desktop_yres", g_VideoMode.GetDesktopYRes());
240  scriptInterface.SetProperty(settings.get(), "video_desktop_bpp", g_VideoMode.GetDesktopBPP());
241  scriptInterface.SetProperty(settings.get(), "video_desktop_freq", g_VideoMode.GetDesktopFreq());
242 
243  struct utsname un;
244  uname(&un);
245  scriptInterface.SetProperty(settings.get(), "uname_sysname", std::string(un.sysname));
246  scriptInterface.SetProperty(settings.get(), "uname_release", std::string(un.release));
247  scriptInterface.SetProperty(settings.get(), "uname_version", std::string(un.version));
248  scriptInterface.SetProperty(settings.get(), "uname_machine", std::string(un.machine));
249 
250 #if OS_LINUX
251  {
252  std::ifstream ifs("/etc/lsb-release");
253  if (ifs.good())
254  {
255  std::string str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
256  scriptInterface.SetProperty(settings.get(), "linux_release", str);
257  }
258  }
259 #endif
260 
261  scriptInterface.SetProperty(settings.get(), "cpu_identifier", std::string(cpu_IdentifierString()));
262  scriptInterface.SetProperty(settings.get(), "cpu_frequency", os_cpu_ClockFrequency());
263  scriptInterface.SetProperty(settings.get(), "cpu_pagesize", (u32)os_cpu_PageSize());
264  scriptInterface.SetProperty(settings.get(), "cpu_largepagesize", (u32)os_cpu_LargePageSize());
265  scriptInterface.SetProperty(settings.get(), "cpu_numprocs", (u32)os_cpu_NumProcessors());
266 #if ARCH_X86_X64
267  scriptInterface.SetProperty(settings.get(), "cpu_numpackages", (u32)topology::NumPackages());
268  scriptInterface.SetProperty(settings.get(), "cpu_coresperpackage", (u32)topology::CoresPerPackage());
269  scriptInterface.SetProperty(settings.get(), "cpu_logicalpercore", (u32)topology::LogicalPerCore());
270  scriptInterface.SetProperty(settings.get(), "cpu_numcaches", (u32)topology::NumCaches());
271 #endif
272 
273  scriptInterface.SetProperty(settings.get(), "numa_numnodes", (u32)numa_NumNodes());
274  scriptInterface.SetProperty(settings.get(), "numa_factor", numa_Factor());
275  scriptInterface.SetProperty(settings.get(), "numa_interleaved", numa_IsMemoryInterleaved());
276 
277  scriptInterface.SetProperty(settings.get(), "ram_total", (u32)os_cpu_MemorySize());
278  scriptInterface.SetProperty(settings.get(), "ram_total_os", (u32)os_cpu_QueryMemorySize());
279  scriptInterface.SetProperty(settings.get(), "ram_free", (u32)os_cpu_MemoryAvailable());
280 
281 #if ARCH_X86_X64
282  scriptInterface.SetProperty(settings.get(), "x86_frequency", x86_x64::ClockFrequency());
283 
284  scriptInterface.SetProperty(settings.get(), "x86_vendor", (u32)x86_x64::Vendor());
285  scriptInterface.SetProperty(settings.get(), "x86_model", (u32)x86_x64::Model());
286  scriptInterface.SetProperty(settings.get(), "x86_family", (u32)x86_x64::Family());
287 
288  u32 caps0, caps1, caps2, caps3;
289  x86_x64::GetCapBits(&caps0, &caps1, &caps2, &caps3);
290  scriptInterface.SetProperty(settings.get(), "x86_caps[0]", caps0);
291  scriptInterface.SetProperty(settings.get(), "x86_caps[1]", caps1);
292  scriptInterface.SetProperty(settings.get(), "x86_caps[2]", caps2);
293  scriptInterface.SetProperty(settings.get(), "x86_caps[3]", caps3);
294 
295  scriptInterface.SetProperty(settings.get(), "x86_icaches", ConvertCaches(scriptInterface, x86_x64::L1I));
296  scriptInterface.SetProperty(settings.get(), "x86_dcaches", ConvertCaches(scriptInterface, x86_x64::L1D));
297  scriptInterface.SetProperty(settings.get(), "x86_tlbs", ConvertTLBs(scriptInterface));
298 #endif
299 
300  scriptInterface.SetProperty(settings.get(), "timer_resolution", timer_Resolution());
301 
302  // Send the same data to the reporting system
303  g_UserReporter.SubmitReport("hwdetect", 11, scriptInterface.StringifyJSON(settings.get(), false));
304 
305  // Run the detection script:
306 
307  scriptInterface.CallFunctionVoid(scriptInterface.GetGlobalObject(), "RunHardwareDetection", settings);
308 }
309 
310 static void ReportGLLimits(ScriptInterface& scriptInterface, CScriptValRooted settings)
311 {
312  const char* errstr = "(error)";
313 
314 #define INTEGER(id) do { \
315  GLint i = -1; \
316  glGetIntegerv(GL_##id, &i); \
317  if (ogl_SquelchError(GL_INVALID_ENUM)) \
318  scriptInterface.SetProperty(settings.get(), "GL_" #id, errstr); \
319  else \
320  scriptInterface.SetProperty(settings.get(), "GL_" #id, i); \
321  } while (false)
322 
323 #define INTEGER2(id) do { \
324  GLint i[2] = { -1, -1 }; \
325  glGetIntegerv(GL_##id, i); \
326  if (ogl_SquelchError(GL_INVALID_ENUM)) { \
327  scriptInterface.SetProperty(settings.get(), "GL_" #id "[0]", errstr); \
328  scriptInterface.SetProperty(settings.get(), "GL_" #id "[1]", errstr); \
329  } else { \
330  scriptInterface.SetProperty(settings.get(), "GL_" #id "[0]", i[0]); \
331  scriptInterface.SetProperty(settings.get(), "GL_" #id "[1]", i[1]); \
332  } \
333  } while (false)
334 
335 #define FLOAT(id) do { \
336  GLfloat f = std::numeric_limits<GLfloat>::quiet_NaN(); \
337  glGetFloatv(GL_##id, &f); \
338  if (ogl_SquelchError(GL_INVALID_ENUM)) \
339  scriptInterface.SetProperty(settings.get(), "GL_" #id, errstr); \
340  else \
341  scriptInterface.SetProperty(settings.get(), "GL_" #id, f); \
342  } while (false)
343 
344 #define FLOAT2(id) do { \
345  GLfloat f[2] = { std::numeric_limits<GLfloat>::quiet_NaN(), std::numeric_limits<GLfloat>::quiet_NaN() }; \
346  glGetFloatv(GL_##id, f); \
347  if (ogl_SquelchError(GL_INVALID_ENUM)) { \
348  scriptInterface.SetProperty(settings.get(), "GL_" #id "[0]", errstr); \
349  scriptInterface.SetProperty(settings.get(), "GL_" #id "[1]", errstr); \
350  } else { \
351  scriptInterface.SetProperty(settings.get(), "GL_" #id "[0]", f[0]); \
352  scriptInterface.SetProperty(settings.get(), "GL_" #id "[1]", f[1]); \
353  } \
354  } while (false)
355 
356 #define STRING(id) do { \
357  const char* c = (const char*)glGetString(GL_##id); \
358  if (!c) c = ""; \
359  if (ogl_SquelchError(GL_INVALID_ENUM)) c = errstr; \
360  scriptInterface.SetProperty(settings.get(), "GL_" #id, std::string(c)); \
361  } while (false)
362 
363 #define QUERY(target, pname) do { \
364  GLint i = -1; \
365  pglGetQueryivARB(GL_##target, GL_##pname, &i); \
366  if (ogl_SquelchError(GL_INVALID_ENUM)) \
367  scriptInterface.SetProperty(settings.get(), "GL_" #target ".GL_" #pname, errstr); \
368  else \
369  scriptInterface.SetProperty(settings.get(), "GL_" #target ".GL_" #pname, i); \
370  } while (false)
371 
372 #define VERTEXPROGRAM(id) do { \
373  GLint i = -1; \
374  pglGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_##id, &i); \
375  if (ogl_SquelchError(GL_INVALID_ENUM)) \
376  scriptInterface.SetProperty(settings.get(), "GL_VERTEX_PROGRAM_ARB.GL_" #id, errstr); \
377  else \
378  scriptInterface.SetProperty(settings.get(), "GL_VERTEX_PROGRAM_ARB.GL_" #id, i); \
379  } while (false)
380 
381 #define FRAGMENTPROGRAM(id) do { \
382  GLint i = -1; \
383  pglGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_##id, &i); \
384  if (ogl_SquelchError(GL_INVALID_ENUM)) \
385  scriptInterface.SetProperty(settings.get(), "GL_FRAGMENT_PROGRAM_ARB.GL_" #id, errstr); \
386  else \
387  scriptInterface.SetProperty(settings.get(), "GL_FRAGMENT_PROGRAM_ARB.GL_" #id, i); \
388  } while (false)
389 
390 #define BOOL(id) INTEGER(id)
391 
392  ogl_WarnIfError();
393 
394  // Core OpenGL 1.3:
395  // (We don't bother checking extension strings for anything older than 1.3;
396  // it'll just produce harmless warnings)
397  STRING(VERSION);
398  STRING(VENDOR);
399  STRING(RENDERER);
400  STRING(EXTENSIONS);
401 #if !CONFIG2_GLES
402  INTEGER(MAX_LIGHTS);
403  INTEGER(MAX_CLIP_PLANES);
404  // Skip MAX_COLOR_MATRIX_STACK_DEPTH (only in imaging subset)
405  INTEGER(MAX_MODELVIEW_STACK_DEPTH);
406  INTEGER(MAX_PROJECTION_STACK_DEPTH);
407  INTEGER(MAX_TEXTURE_STACK_DEPTH);
408 #endif
409  INTEGER(SUBPIXEL_BITS);
410 #if !CONFIG2_GLES
411  INTEGER(MAX_3D_TEXTURE_SIZE);
412 #endif
413  INTEGER(MAX_TEXTURE_SIZE);
414  INTEGER(MAX_CUBE_MAP_TEXTURE_SIZE);
415 #if !CONFIG2_GLES
416  INTEGER(MAX_PIXEL_MAP_TABLE);
417  INTEGER(MAX_NAME_STACK_DEPTH);
418  INTEGER(MAX_LIST_NESTING);
419  INTEGER(MAX_EVAL_ORDER);
420 #endif
421  INTEGER2(MAX_VIEWPORT_DIMS);
422 #if !CONFIG2_GLES
423  INTEGER(MAX_ATTRIB_STACK_DEPTH);
424  INTEGER(MAX_CLIENT_ATTRIB_STACK_DEPTH);
425  INTEGER(AUX_BUFFERS);
426  BOOL(RGBA_MODE);
427  BOOL(INDEX_MODE);
428  BOOL(DOUBLEBUFFER);
429  BOOL(STEREO);
430 #endif
431  FLOAT2(ALIASED_POINT_SIZE_RANGE);
432 #if !CONFIG2_GLES
433  FLOAT2(SMOOTH_POINT_SIZE_RANGE);
434  FLOAT(SMOOTH_POINT_SIZE_GRANULARITY);
435 #endif
436  FLOAT2(ALIASED_LINE_WIDTH_RANGE);
437 #if !CONFIG2_GLES
438  FLOAT2(SMOOTH_LINE_WIDTH_RANGE);
439  FLOAT(SMOOTH_LINE_WIDTH_GRANULARITY);
440  // Skip MAX_CONVOLUTION_WIDTH, MAX_CONVOLUTION_HEIGHT (only in imaging subset)
441  INTEGER(MAX_ELEMENTS_INDICES);
442  INTEGER(MAX_ELEMENTS_VERTICES);
443  INTEGER(MAX_TEXTURE_UNITS);
444 #endif
445  INTEGER(SAMPLE_BUFFERS);
446  INTEGER(SAMPLES);
447  // TODO: compressed texture formats
448  INTEGER(RED_BITS);
449  INTEGER(GREEN_BITS);
450  INTEGER(BLUE_BITS);
451  INTEGER(ALPHA_BITS);
452 #if !CONFIG2_GLES
453  INTEGER(INDEX_BITS);
454 #endif
455  INTEGER(DEPTH_BITS);
456  INTEGER(STENCIL_BITS);
457 #if !CONFIG2_GLES
458  INTEGER(ACCUM_RED_BITS);
459  INTEGER(ACCUM_GREEN_BITS);
460  INTEGER(ACCUM_BLUE_BITS);
461  INTEGER(ACCUM_ALPHA_BITS);
462 #endif
463 
464 #if !CONFIG2_GLES
465 
466  // Core OpenGL 2.0 (treated as extensions):
467 
468  if (ogl_HaveExtension("GL_EXT_texture_lod_bias"))
469  {
470  FLOAT(MAX_TEXTURE_LOD_BIAS_EXT);
471  }
472 
473  if (ogl_HaveExtension("GL_ARB_occlusion_query"))
474  {
475  QUERY(SAMPLES_PASSED, QUERY_COUNTER_BITS);
476  }
477 
478  if (ogl_HaveExtension("GL_ARB_shading_language_100"))
479  {
480  STRING(SHADING_LANGUAGE_VERSION_ARB);
481  }
482 
483  if (ogl_HaveExtension("GL_ARB_vertex_shader"))
484  {
485  INTEGER(MAX_VERTEX_ATTRIBS_ARB);
486  INTEGER(MAX_VERTEX_UNIFORM_COMPONENTS_ARB);
487  INTEGER(MAX_VARYING_FLOATS_ARB);
488  INTEGER(MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB);
489  INTEGER(MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB);
490  }
491 
492  if (ogl_HaveExtension("GL_ARB_fragment_shader"))
493  {
494  INTEGER(MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB);
495  }
496 
497  if (ogl_HaveExtension("GL_ARB_vertex_shader") || ogl_HaveExtension("GL_ARB_fragment_shader") ||
498  ogl_HaveExtension("GL_ARB_vertex_program") || ogl_HaveExtension("GL_ARB_fragment_program"))
499  {
500  INTEGER(MAX_TEXTURE_IMAGE_UNITS_ARB);
501  INTEGER(MAX_TEXTURE_COORDS_ARB);
502  }
503 
504  if (ogl_HaveExtension("GL_ARB_draw_buffers"))
505  {
506  INTEGER(MAX_DRAW_BUFFERS_ARB);
507  }
508 
509  // Core OpenGL 3.0:
510 
511  if (ogl_HaveExtension("GL_EXT_gpu_shader4"))
512  {
513  INTEGER(MIN_PROGRAM_TEXEL_OFFSET); // no _EXT version of these in glext.h
514  INTEGER(MAX_PROGRAM_TEXEL_OFFSET);
515  }
516 
517  if (ogl_HaveExtension("GL_EXT_framebuffer_object"))
518  {
519  INTEGER(MAX_COLOR_ATTACHMENTS_EXT);
520  INTEGER(MAX_RENDERBUFFER_SIZE_EXT);
521  }
522 
523  if (ogl_HaveExtension("GL_EXT_framebuffer_multisample"))
524  {
525  INTEGER(MAX_SAMPLES_EXT);
526  }
527 
528  if (ogl_HaveExtension("GL_EXT_texture_array"))
529  {
530  INTEGER(MAX_ARRAY_TEXTURE_LAYERS_EXT);
531  }
532 
533  if (ogl_HaveExtension("GL_EXT_transform_feedback"))
534  {
535  INTEGER(MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT);
536  INTEGER(MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT);
537  INTEGER(MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT);
538  }
539 
540 
541  // Other interesting extensions:
542 
543  if (ogl_HaveExtension("GL_EXT_timer_query") || ogl_HaveExtension("GL_ARB_timer_query"))
544  {
545  QUERY(TIME_ELAPSED, QUERY_COUNTER_BITS);
546  }
547 
548  if (ogl_HaveExtension("GL_ARB_timer_query"))
549  {
550  QUERY(TIMESTAMP, QUERY_COUNTER_BITS);
551  }
552 
553  if (ogl_HaveExtension("GL_EXT_texture_filter_anisotropic"))
554  {
555  FLOAT(MAX_TEXTURE_MAX_ANISOTROPY_EXT);
556  }
557 
558  if (ogl_HaveExtension("GL_ARB_texture_rectangle"))
559  {
560  INTEGER(MAX_RECTANGLE_TEXTURE_SIZE_ARB);
561  }
562 
563  if (ogl_HaveExtension("GL_ARB_vertex_program") || ogl_HaveExtension("GL_ARB_fragment_program"))
564  {
565  INTEGER(MAX_PROGRAM_MATRICES_ARB);
566  INTEGER(MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB);
567  }
568 
569  if (ogl_HaveExtension("GL_ARB_vertex_program"))
570  {
571  VERTEXPROGRAM(MAX_PROGRAM_ENV_PARAMETERS_ARB);
572  VERTEXPROGRAM(MAX_PROGRAM_LOCAL_PARAMETERS_ARB);
573  VERTEXPROGRAM(MAX_PROGRAM_INSTRUCTIONS_ARB);
574  VERTEXPROGRAM(MAX_PROGRAM_TEMPORARIES_ARB);
575  VERTEXPROGRAM(MAX_PROGRAM_PARAMETERS_ARB);
576  VERTEXPROGRAM(MAX_PROGRAM_ATTRIBS_ARB);
577  VERTEXPROGRAM(MAX_PROGRAM_ADDRESS_REGISTERS_ARB);
578  VERTEXPROGRAM(MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB);
579  VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEMPORARIES_ARB);
580  VERTEXPROGRAM(MAX_PROGRAM_NATIVE_PARAMETERS_ARB);
581  VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ATTRIBS_ARB);
582  VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB);
583 
584  if (ogl_HaveExtension("GL_ARB_fragment_program"))
585  {
586  // The spec seems to say these should be supported, but
587  // Mesa complains about them so let's not bother
588  /*
589  VERTEXPROGRAM(MAX_PROGRAM_ALU_INSTRUCTIONS_ARB);
590  VERTEXPROGRAM(MAX_PROGRAM_TEX_INSTRUCTIONS_ARB);
591  VERTEXPROGRAM(MAX_PROGRAM_TEX_INDIRECTIONS_ARB);
592  VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB);
593  VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB);
594  VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB);
595  */
596  }
597  }
598 
599  if (ogl_HaveExtension("GL_ARB_fragment_program"))
600  {
601  FRAGMENTPROGRAM(MAX_PROGRAM_ENV_PARAMETERS_ARB);
602  FRAGMENTPROGRAM(MAX_PROGRAM_LOCAL_PARAMETERS_ARB);
603  FRAGMENTPROGRAM(MAX_PROGRAM_INSTRUCTIONS_ARB);
604  FRAGMENTPROGRAM(MAX_PROGRAM_ALU_INSTRUCTIONS_ARB);
605  FRAGMENTPROGRAM(MAX_PROGRAM_TEX_INSTRUCTIONS_ARB);
606  FRAGMENTPROGRAM(MAX_PROGRAM_TEX_INDIRECTIONS_ARB);
607  FRAGMENTPROGRAM(MAX_PROGRAM_TEMPORARIES_ARB);
608  FRAGMENTPROGRAM(MAX_PROGRAM_PARAMETERS_ARB);
609  FRAGMENTPROGRAM(MAX_PROGRAM_ATTRIBS_ARB);
610  FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB);
611  FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB);
612  FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB);
613  FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB);
614  FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEMPORARIES_ARB);
615  FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_PARAMETERS_ARB);
616  FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ATTRIBS_ARB);
617 
618  if (ogl_HaveExtension("GL_ARB_vertex_program"))
619  {
620  // The spec seems to say these should be supported, but
621  // Intel drivers on Windows complain about them so let's not bother
622  /*
623  FRAGMENTPROGRAM(MAX_PROGRAM_ADDRESS_REGISTERS_ARB);
624  FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB);
625  */
626  }
627  }
628 
629  if (ogl_HaveExtension("GL_ARB_geometry_shader4"))
630  {
631  INTEGER(MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB);
632  INTEGER(MAX_GEOMETRY_OUTPUT_VERTICES_ARB);
633  INTEGER(MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB);
634  INTEGER(MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB);
635  INTEGER(MAX_GEOMETRY_VARYING_COMPONENTS_ARB);
636  INTEGER(MAX_VERTEX_VARYING_COMPONENTS_ARB);
637  }
638 
639 #else // CONFIG2_GLES
640 
641  // Core OpenGL ES 2.0:
642 
643  STRING(SHADING_LANGUAGE_VERSION);
644  INTEGER(MAX_VERTEX_ATTRIBS);
645  INTEGER(MAX_VERTEX_UNIFORM_VECTORS);
646  INTEGER(MAX_VARYING_VECTORS);
647  INTEGER(MAX_COMBINED_TEXTURE_IMAGE_UNITS);
648  INTEGER(MAX_VERTEX_TEXTURE_IMAGE_UNITS);
649  INTEGER(MAX_FRAGMENT_UNIFORM_VECTORS);
650  INTEGER(MAX_TEXTURE_IMAGE_UNITS);
651  INTEGER(MAX_RENDERBUFFER_SIZE);
652 
653 #endif // CONFIG2_GLES
654 }
CStr DecodeUTF8() const
Returns contents of a UTF-8 encoded file as a string with optional BOM removed.
Definition: Filesystem.cpp:153
double os_cpu_ClockFrequency()
Definition: os_cpu.cpp:43
#define OS_ANDROID
Definition: os.h:60
size_t NumPackages()
Definition: topology.cpp:244
size_t os_cpu_QueryMemorySize()
Definition: bcpu.cpp:86
CUserReporter g_UserReporter
Definition: UserReport.cpp:73
void ogl_tex_override(OglTexOverrides what, OglTexAllow allow)
Override the default decision and force/disallow use of the given feature.
Definition: ogl_tex.cpp:711
const char * cpu_IdentifierString()
Definition: arm.cpp:46
#define BOOL(id)
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
int GetDesktopFreq()
Definition: VideoMode.cpp:500
int GetDesktopXRes()
Definition: VideoMode.cpp:482
size_t LogicalPerCore()
Definition: topology.cpp:256
#define LOGERROR
Definition: CLogger.h:35
char version[16]
Definition: wutsname.h:35
size_t os_cpu_PageSize()
Definition: bcpu.cpp:68
const x86_x64::Cache * Caches(size_t idxCache)
Definition: cache.cpp:649
const PSRETURN PSRETURN_OK
Definition: Errors.h:103
#define OS_UNIX
Definition: os.h:109
Reads a file, then gives read-only access to the contents.
Definition: Filesystem.h:69
Type type
never kNull
Definition: cache.h:52
#define CLANG_VERSION
Definition: compiler.h:63
int GetYRes()
Definition: VideoMode.cpp:470
bool CallFunctionVoid(jsval val, const char *name)
Call the named property on the given object, with void return type and 0 arguments.
void SetDisableAudio(void *cbdata, bool disabled)
Definition: HWDetect.cpp:101
#define FLOAT2(id)
void SetDisableS3TC(void *cbdata, bool disabled)
Definition: HWDetect.cpp:106
const jsval & get() const
Returns the current value.
Definition: ScriptVal.h:38
wchar_t svn_revision[]
A trivial wrapper around a jsval.
Definition: ScriptVal.h:29
LIB_API double numa_Factor()
Definition: unuma.cpp:51
bool LoadScript(const VfsPath &filename, const std::string &code)
Load and execute the given script in a new function scope.
Vendors Vendor()
Definition: x86_x64.cpp:200
size_t os_cpu_NumProcessors()
Definition: bcpu.cpp:34
std::string StringifyJSON(jsval obj, bool indent=true)
Stringify to a JSON string, UTF-8 encoded.
#define STRING(id)
size_t os_cpu_LargePageSize()
Definition: bcpu.cpp:79
bool SetPropertyInt(jsval obj, int name, const T &value, bool constant=false, bool enumerate=true)
Set the integer-named property on the given object.
bool g_WaterRefraction
Definition: Config.cpp:46
std::wstring CardName()
Definition: gfx.cpp:41
bool g_WaterShadows
Definition: Config.cpp:48
#define MSC_VERSION
Definition: compiler.h:37
size_t os_cpu_MemorySize()
Definition: os_cpu.cpp:63
std::wstring DriverInfo()
Definition: gfx.cpp:70
#define ARCH_IA32
Definition: arch.h:35
#define OS_LINUX
Definition: os.h:54
#define FLOAT(id)
#define GCC_VERSION
Definition: compiler.h:55
char machine[9]
Definition: wutsname.h:36
CVideoMode g_VideoMode
Definition: VideoMode.cpp:42
u64 TotalSize() const
Definition: cache.h:116
#define g_ScriptingHost
static void ReportGLLimits(ScriptInterface &scriptInterface, CScriptValRooted settings)
Definition: HWDetect.cpp:310
void SubmitReport(const char *type, int version, const std::string &data)
Submit a report to be transmitted to the online server.
Definition: UserReport.cpp:616
CStr g_RenderPath
Definition: Config.cpp:56
#define INTEGER(id)
size_t sharedBy
how many logical processors share this cache?
Definition: cache.h:72
#define VERTEXPROGRAM(id)
static const size_t maxLevels
Definition: cache.h:40
char release[9]
Definition: wutsname.h:34
size_t os_cpu_MemoryAvailable()
Definition: bcpu.cpp:98
bool g_WaterRealDepth
Definition: Config.cpp:43
size_t CoresPerPackage()
Definition: topology.cpp:250
size_t NumCaches()
Definition: topology.cpp:454
double ClockFrequency()
measure the CPU clock frequency via rdtsc and timer_Time.
Definition: x86_x64.cpp:429
static bool IsOverridden(const char *setting)
Definition: HWDetect.cpp:95
bool g_WaterFoam
Definition: Config.cpp:44
bool Eval(const char *code)
char sysname[9]
Definition: wutsname.h:32
bool g_WaterReflection
Definition: Config.cpp:47
void GetCapBits(u32 *d0, u32 *d1, u32 *d2, u32 *d3)
Definition: x86_x64.cpp:156
#define OS_MACOSX
Definition: os.h:66
#define g_ConfigDB
Definition: ConfigDB.h:52
int uname(struct utsname *un)
Definition: wutsname.cpp:30
void SetDisableShadowPCF(void *cbdata, bool disabled)
Definition: HWDetect.cpp:118
wchar_t snd_drv_ver[SND_DRV_VER_LEN]
sound driver identification and version.
Definition: snd.cpp:36
#define ICC_VERSION
Definition: compiler.h:43
wchar_t snd_card[SND_CARD_LEN]
description of sound card.
Definition: snd.cpp:35
#define TIMER(description)
Measures the time taken to execute code up until end of the current scope; displays it via debug_prin...
Definition: timer.h:108
bool g_WaterNormal
Definition: Config.cpp:42
void RunHardwareDetection()
Runs hardware-detection script to adjust default config settings and/or emit warnings depending on th...
Definition: HWDetect.cpp:165
size_t level
1..maxLevels
Definition: cache.h:47
void SetDisableAllWater(void *cbdata, bool disabled)
Definition: HWDetect.cpp:124
#define QUERY(target, pname)
void SetDisableShadows(void *cbdata, bool disabled)
Definition: HWDetect.cpp:112
LIB_API size_t numa_NumNodes()
Definition: unuma.cpp:29
LIB_API bool numa_IsMemoryInterleaved()
Definition: unuma.cpp:56
bool ogl_HaveExtension(const char *ext)
check if an extension is supported by the OpenGL implementation.
Definition: ogl.cpp:187
#define ARCH_ARM
Definition: arch.h:59
#define u32
Definition: types.h:41
bool g_ShadowPCF
Definition: Config.cpp:40
double timer_Resolution()
Definition: timer.cpp:145
bool g_Shadows
Definition: Config.cpp:39
void SetDisableFBOWater(void *cbdata, bool disabled)
Definition: HWDetect.cpp:152
PSRETURN Load(const PIVFS &vfs, const VfsPath &filename)
Returns either PSRETURN_OK or PSRETURN_CVFSFile_LoadFailed.
Definition: Filesystem.cpp:117
#define OS_BSD
Definition: os.h:76
int GetDesktopYRes()
Definition: VideoMode.cpp:488
int GetDesktopBPP()
Definition: VideoMode.cpp:494
size_t Family()
Definition: x86_x64.cpp:238
EConfigNamespace
Definition: ConfigDB.h:39
jsval get() const
Returns the current value (or JSVAL_VOID if uninitialised).
Definition: ScriptVal.cpp:45
Abstraction around a SpiderMonkey JSContext.
void ogl_WarnIfError()
raise a warning (break into the debugger) if an OpenGL error is pending.
Definition: ogl.cpp:398
#define FRAGMENTPROGRAM(id)
size_t numEntries
if 0, the cache is disabled and all other values are zero
Definition: cache.h:57
int GetXRes()
Definition: VideoMode.cpp:464
int GetBPP()
Definition: VideoMode.cpp:476
bool SetProperty(jsval obj, const char *name, const T &value, bool constant=false, bool enumerate=true)
Set the named property on the given object.
void SetRenderPath(void *cbdata, std::string renderpath)
Definition: HWDetect.cpp:160
bool g_DisableAudio
Definition: Config.cpp:62
#define CONFIG2_GLES
Definition: config2.h:101
PIVFS g_VFS
Definition: Filesystem.cpp:30
IdxCache
Definition: cache.h:122
size_t associativity
= fullyAssociative or the actual ways of associativity
Definition: cache.h:67
size_t entrySize
NB: cache entries are lines, TLB entries are pages.
Definition: cache.h:62
#define OS_WIN
Definition: os.h:48
void SetDisableFancyWater(void *cbdata, bool disabled)
Definition: HWDetect.cpp:141
#define ARCH_AMD64
Definition: arch.h:47
#define INTEGER2(id)
size_t Model()
Definition: x86_x64.cpp:232
bool g_WaterCoastalWaves
Definition: Config.cpp:45