From 48938f288090cf061445ad81a2b538aaff46736f Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 18 Sep 2014 22:09:56 +1000 Subject: [PATCH] Started to add GL limits to the statistics. Work in progress. --- src/config/hardware_stats.cpp | 15 +- src/graphics/glwrap.cpp | 372 +++++++++++++++++++++++++++++++++- src/graphics/glwrap.hpp | 16 +- 3 files changed, 388 insertions(+), 15 deletions(-) diff --git a/src/config/hardware_stats.cpp b/src/config/hardware_stats.cpp index 8f92a3f9b..8137db2f0 100644 --- a/src/config/hardware_stats.cpp +++ b/src/config/hardware_stats.cpp @@ -37,6 +37,8 @@ int getRAM() const uint64_t memorySize = (uint64_t)sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE); return long(memorySize / (1024*1024)); +#endif +#ifdef WIN32 #endif return 0; @@ -83,12 +85,12 @@ void reportHardwareStats() json.add("gfx_drv_ver", "OpenGL "+vendor); std::string card_name = vendor; - if(StringUtils::startsWith(card_name, "ATI Technologies Inc.")) - card_name="ATI"; - else if (StringUtils::startsWith(card_name, "NVIDIA Corporation")) - card_name="NVIDIA"; - else if(StringUtils::startsWith(card_name, "S3 Graphics")) - card_name="S3"; + if(StringUtils::startsWith(card_name, "ATI Technologies Inc.")) + card_name="ATI"; + else if (StringUtils::startsWith(card_name, "NVIDIA Corporation")) + card_name="NVIDIA"; + else if(StringUtils::startsWith(card_name, "S3 Graphics")) + card_name="S3"; json.add("gfx_card", card_name+" "+renderer); json.add("video_xres", UserConfigParams::m_width ); @@ -100,6 +102,7 @@ void reportHardwareStats() // Too long for debugging atm //json.add("GL_EXTENSIONS", getGLExtensions()); + getGLLimits(&json); json.finish(); Log::verbose("json", "'%s'", json.toString().c_str()); diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 7b3f5847b..9accaf85c 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -1,14 +1,18 @@ #include "graphics/glwrap.hpp" -#include -#include + #include "config/user_config.hpp" +#include "config/hardware_stats.hpp" +#include "graphics/stkmesh.hpp" #include "utils/profiler.hpp" #include "utils/cpp2011.hpp" -#include "graphics/stkmesh.hpp" #include "../../lib/irrlicht/source/Irrlicht/COpenGLTexture.h" +#include +#include +#include + static bool is_gl_init = false; #if DEBUG @@ -762,4 +766,364 @@ const std::string getGLExtensions() } return result; -} // getGLExtensions \ No newline at end of file +} // getGLExtensions + +// ---------------------------------------------------------------------------- +/** Adds GL limits to the json data structure. + * Thanks to Wildfire Games / 0.A.D. for allowing us to port their sources. + */ +void getGLLimits(HardwareStats::Json *json) +{ + // Various macros to make the data assembly shorter. +#define INTEGER(id) \ + do { \ + GLint i = -1; \ + glGetIntegerv(GL_##id, &i); \ + if (glGetError()==GL_NO_ERROR) \ + json->add("GL_"#id, i); \ + } while (false) +#define INTEGER2(id) \ + do { \ + GLint i[2] = { -1, -1 }; \ + glGetIntegerv(GL_##id, i); \ + if (glGetError()==GL_NO_ERROR) { \ + json->add("GL_"#id"[0]", i[0]); \ + json->add("GL_"#id"[1]", i[1]); \ + } \ + } while (false) +#define FLOAT(id) \ + do { \ + GLfloat f = -1.0f; \ + glGetFloatv(GL_##id, &f); \ + if (glGetError()==GL_NO_ERROR) \ + json->add("GL_"#id, f); \ + } while (false) +#define FLOAT2(id) \ + do { \ + GLfloat f[2] = {-1.0f, -1.0f}; \ + glGetFloatv(GL_##id, f); \ + if (glGetError()==GL_NO_ERROR) { \ + json->add("GL_"#id"[0]", f[0]); \ + json->add("GL_"#id"[1]", f[1]); \ + } \ + } while (false) +#define STRING(id) \ + do { \ + const char* c = (const char*)glGetString(GL_##id); \ + if(!c) c=""; \ + json->add("GL_"#id, c); \ + } while (false) + + + STRING(VERSION); + STRING(VENDOR); + STRING(RENDERER); + STRING(EXTENSIONS); + INTEGER(SUBPIXEL_BITS); + INTEGER(MAX_TEXTURE_SIZE); + INTEGER(MAX_CUBE_MAP_TEXTURE_SIZE); + INTEGER2(MAX_VIEWPORT_DIMS); + FLOAT2(ALIASED_POINT_SIZE_RANGE); + FLOAT2(ALIASED_LINE_WIDTH_RANGE); + INTEGER(SAMPLE_BUFFERS); + INTEGER(SAMPLES); + // TODO: compressed texture formats + INTEGER(RED_BITS); + INTEGER(GREEN_BITS); + INTEGER(BLUE_BITS); + INTEGER(ALPHA_BITS); + INTEGER(DEPTH_BITS); + INTEGER(STENCIL_BITS); + + return; + +#ifdef NOT_DONE_YET +#define QUERY(target, pname) do { \ + GLint i = -1; \ + pglGetQueryivARB(GL_##target, GL_##pname, &i); \ + if (ogl_SquelchError(GL_INVALID_ENUM)) \ + scriptInterface.SetProperty(settings, "GL_" #target ".GL_" #pname, errstr); \ +else \ + scriptInterface.SetProperty(settings, "GL_" #target ".GL_" #pname, i); \ + } while (false) +#define VERTEXPROGRAM(id) do { \ + GLint i = -1; \ + pglGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_##id, &i); \ + if (ogl_SquelchError(GL_INVALID_ENUM)) \ + scriptInterface.SetProperty(settings, "GL_VERTEX_PROGRAM_ARB.GL_" #id, errstr); \ +else \ + scriptInterface.SetProperty(settings, "GL_VERTEX_PROGRAM_ARB.GL_" #id, i); \ + } while (false) +#define FRAGMENTPROGRAM(id) do { \ + GLint i = -1; \ + pglGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_##id, &i); \ + if (ogl_SquelchError(GL_INVALID_ENUM)) \ + scriptInterface.SetProperty(settings, "GL_FRAGMENT_PROGRAM_ARB.GL_" #id, errstr); \ +else \ + scriptInterface.SetProperty(settings, "GL_FRAGMENT_PROGRAM_ARB.GL_" #id, i); \ + } while (false) +#define BOOL(id) INTEGER(id) + + +#if !CONFIG2_GLES + INTEGER(MAX_LIGHTS); + INTEGER(MAX_CLIP_PLANES); + // Skip MAX_COLOR_MATRIX_STACK_DEPTH (only in imaging subset) + INTEGER(MAX_MODELVIEW_STACK_DEPTH); + INTEGER(MAX_PROJECTION_STACK_DEPTH); + INTEGER(MAX_TEXTURE_STACK_DEPTH); +#endif +#if !CONFIG2_GLES + INTEGER(MAX_3D_TEXTURE_SIZE); +#endif +#if !CONFIG2_GLES + INTEGER(MAX_PIXEL_MAP_TABLE); + INTEGER(MAX_NAME_STACK_DEPTH); + INTEGER(MAX_LIST_NESTING); + INTEGER(MAX_EVAL_ORDER); +#endif +#if !CONFIG2_GLES + INTEGER(MAX_ATTRIB_STACK_DEPTH); + INTEGER(MAX_CLIENT_ATTRIB_STACK_DEPTH); + INTEGER(AUX_BUFFERS); + BOOL(RGBA_MODE); + BOOL(INDEX_MODE); + BOOL(DOUBLEBUFFER); + BOOL(STEREO); +#endif +#if !CONFIG2_GLES + FLOAT2(SMOOTH_POINT_SIZE_RANGE); + FLOAT(SMOOTH_POINT_SIZE_GRANULARITY); +#endif +#if !CONFIG2_GLES + FLOAT2(SMOOTH_LINE_WIDTH_RANGE); + FLOAT(SMOOTH_LINE_WIDTH_GRANULARITY); + // Skip MAX_CONVOLUTION_WIDTH, MAX_CONVOLUTION_HEIGHT (only in imaging subset) + INTEGER(MAX_ELEMENTS_INDICES); + INTEGER(MAX_ELEMENTS_VERTICES); + INTEGER(MAX_TEXTURE_UNITS); +#endif +#if !CONFIG2_GLES + INTEGER(INDEX_BITS); +#endif +#if !CONFIG2_GLES + INTEGER(ACCUM_RED_BITS); + INTEGER(ACCUM_GREEN_BITS); + INTEGER(ACCUM_BLUE_BITS); + INTEGER(ACCUM_ALPHA_BITS); +#endif +#if !CONFIG2_GLES + // Core OpenGL 2.0 (treated as extensions): + if (ogl_HaveExtension("GL_EXT_texture_lod_bias")) + { + FLOAT(MAX_TEXTURE_LOD_BIAS_EXT); + } + if (ogl_HaveExtension("GL_ARB_occlusion_query")) + { + QUERY(SAMPLES_PASSED, QUERY_COUNTER_BITS); + } + if (ogl_HaveExtension("GL_ARB_shading_language_100")) + { + STRING(SHADING_LANGUAGE_VERSION_ARB); + } + if (ogl_HaveExtension("GL_ARB_vertex_shader")) + { + INTEGER(MAX_VERTEX_ATTRIBS_ARB); + INTEGER(MAX_VERTEX_UNIFORM_COMPONENTS_ARB); + INTEGER(MAX_VARYING_FLOATS_ARB); + INTEGER(MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB); + INTEGER(MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB); + } + if (ogl_HaveExtension("GL_ARB_fragment_shader")) + { + INTEGER(MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB); + } + if (ogl_HaveExtension("GL_ARB_vertex_shader") || ogl_HaveExtension("GL_ARB_fragment_shader") || + ogl_HaveExtension("GL_ARB_vertex_program") || ogl_HaveExtension("GL_ARB_fragment_program")) + { + INTEGER(MAX_TEXTURE_IMAGE_UNITS_ARB); + INTEGER(MAX_TEXTURE_COORDS_ARB); + } + if (ogl_HaveExtension("GL_ARB_draw_buffers")) + { + INTEGER(MAX_DRAW_BUFFERS_ARB); + } + // Core OpenGL 3.0: + if (ogl_HaveExtension("GL_EXT_gpu_shader4")) + { + INTEGER(MIN_PROGRAM_TEXEL_OFFSET); // no _EXT version of these in glext.h + INTEGER(MAX_PROGRAM_TEXEL_OFFSET); + } + if (ogl_HaveExtension("GL_EXT_framebuffer_object")) + { + INTEGER(MAX_COLOR_ATTACHMENTS_EXT); + INTEGER(MAX_RENDERBUFFER_SIZE_EXT); + } + if (ogl_HaveExtension("GL_EXT_framebuffer_multisample")) + { + INTEGER(MAX_SAMPLES_EXT); + } + if (ogl_HaveExtension("GL_EXT_texture_array")) + { + INTEGER(MAX_ARRAY_TEXTURE_LAYERS_EXT); + } + if (ogl_HaveExtension("GL_EXT_transform_feedback")) + { + INTEGER(MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT); + INTEGER(MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT); + INTEGER(MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT); + } + // Other interesting extensions: + if (ogl_HaveExtension("GL_EXT_timer_query") || ogl_HaveExtension("GL_ARB_timer_query")) + { + QUERY(TIME_ELAPSED, QUERY_COUNTER_BITS); + } + if (ogl_HaveExtension("GL_ARB_timer_query")) + { + QUERY(TIMESTAMP, QUERY_COUNTER_BITS); + } + if (ogl_HaveExtension("GL_EXT_texture_filter_anisotropic")) + { + FLOAT(MAX_TEXTURE_MAX_ANISOTROPY_EXT); + } + if (ogl_HaveExtension("GL_ARB_texture_rectangle")) + { + INTEGER(MAX_RECTANGLE_TEXTURE_SIZE_ARB); + } + if (ogl_HaveExtension("GL_ARB_vertex_program") || ogl_HaveExtension("GL_ARB_fragment_program")) + { + INTEGER(MAX_PROGRAM_MATRICES_ARB); + INTEGER(MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB); + } + if (ogl_HaveExtension("GL_ARB_vertex_program")) + { + VERTEXPROGRAM(MAX_PROGRAM_ENV_PARAMETERS_ARB); + VERTEXPROGRAM(MAX_PROGRAM_LOCAL_PARAMETERS_ARB); + VERTEXPROGRAM(MAX_PROGRAM_INSTRUCTIONS_ARB); + VERTEXPROGRAM(MAX_PROGRAM_TEMPORARIES_ARB); + VERTEXPROGRAM(MAX_PROGRAM_PARAMETERS_ARB); + VERTEXPROGRAM(MAX_PROGRAM_ATTRIBS_ARB); + VERTEXPROGRAM(MAX_PROGRAM_ADDRESS_REGISTERS_ARB); + VERTEXPROGRAM(MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB); + VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEMPORARIES_ARB); + VERTEXPROGRAM(MAX_PROGRAM_NATIVE_PARAMETERS_ARB); + VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ATTRIBS_ARB); + VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB); + if (ogl_HaveExtension("GL_ARB_fragment_program")) + { + // The spec seems to say these should be supported, but + // Mesa complains about them so let's not bother + /* + VERTEXPROGRAM(MAX_PROGRAM_ALU_INSTRUCTIONS_ARB); + VERTEXPROGRAM(MAX_PROGRAM_TEX_INSTRUCTIONS_ARB); + VERTEXPROGRAM(MAX_PROGRAM_TEX_INDIRECTIONS_ARB); + VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB); + VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB); + VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB); + */ + } + } + if (ogl_HaveExtension("GL_ARB_fragment_program")) + { + FRAGMENTPROGRAM(MAX_PROGRAM_ENV_PARAMETERS_ARB); + FRAGMENTPROGRAM(MAX_PROGRAM_LOCAL_PARAMETERS_ARB); + FRAGMENTPROGRAM(MAX_PROGRAM_INSTRUCTIONS_ARB); + FRAGMENTPROGRAM(MAX_PROGRAM_ALU_INSTRUCTIONS_ARB); + FRAGMENTPROGRAM(MAX_PROGRAM_TEX_INSTRUCTIONS_ARB); + FRAGMENTPROGRAM(MAX_PROGRAM_TEX_INDIRECTIONS_ARB); + FRAGMENTPROGRAM(MAX_PROGRAM_TEMPORARIES_ARB); + FRAGMENTPROGRAM(MAX_PROGRAM_PARAMETERS_ARB); + FRAGMENTPROGRAM(MAX_PROGRAM_ATTRIBS_ARB); + FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB); + FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB); + FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB); + FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB); + FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEMPORARIES_ARB); + FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_PARAMETERS_ARB); + FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ATTRIBS_ARB); + if (ogl_HaveExtension("GL_ARB_vertex_program")) + { + // The spec seems to say these should be supported, but + // Intel drivers on Windows complain about them so let's not bother + /* + FRAGMENTPROGRAM(MAX_PROGRAM_ADDRESS_REGISTERS_ARB); + FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB); + */ + } + } + if (ogl_HaveExtension("GL_ARB_geometry_shader4")) + { + INTEGER(MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB); + INTEGER(MAX_GEOMETRY_OUTPUT_VERTICES_ARB); + INTEGER(MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB); + INTEGER(MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB); + INTEGER(MAX_GEOMETRY_VARYING_COMPONENTS_ARB); + INTEGER(MAX_VERTEX_VARYING_COMPONENTS_ARB); + } +#else // CONFIG2_GLES + // Core OpenGL ES 2.0: + STRING(SHADING_LANGUAGE_VERSION); + INTEGER(MAX_VERTEX_ATTRIBS); + INTEGER(MAX_VERTEX_UNIFORM_VECTORS); + INTEGER(MAX_VARYING_VECTORS); + INTEGER(MAX_COMBINED_TEXTURE_IMAGE_UNITS); + INTEGER(MAX_VERTEX_TEXTURE_IMAGE_UNITS); + INTEGER(MAX_FRAGMENT_UNIFORM_VECTORS); + INTEGER(MAX_TEXTURE_IMAGE_UNITS); + INTEGER(MAX_RENDERBUFFER_SIZE); +#endif // CONFIG2_GLES +#ifdef SDL_VIDEO_DRIVER_X11 +#define GLXQCR_INTEGER(id) do { \ + unsigned int i = UINT_MAX; \ + if (pglXQueryCurrentRendererIntegerMESA(id, &i)) \ + scriptInterface.SetProperty(settings, #id, i); \ + } while (false) +#define GLXQCR_INTEGER2(id) do { \ + unsigned int i[2] = { UINT_MAX, UINT_MAX }; \ + if (pglXQueryCurrentRendererIntegerMESA(id, i)) { \ + scriptInterface.SetProperty(settings, #id "[0]", i[0]); \ + scriptInterface.SetProperty(settings, #id "[1]", i[1]); \ + } \ + } while (false) +#define GLXQCR_INTEGER3(id) do { \ + unsigned int i[3] = { UINT_MAX, UINT_MAX, UINT_MAX }; \ + if (pglXQueryCurrentRendererIntegerMESA(id, i)) { \ + scriptInterface.SetProperty(settings, #id "[0]", i[0]); \ + scriptInterface.SetProperty(settings, #id "[1]", i[1]); \ + scriptInterface.SetProperty(settings, #id "[2]", i[2]); \ + } \ + } while (false) +#define GLXQCR_STRING(id) do { \ + const char* str = pglXQueryCurrentRendererStringMESA(id); \ + if (str) \ + scriptInterface.SetProperty(settings, #id ".string", str); \ + } while (false) + SDL_SysWMinfo wminfo; + SDL_VERSION(&wminfo.version); + if (SDL_GetWMInfo(&wminfo) && wminfo.subsystem == SDL_SYSWM_X11) + { + Display* dpy = wminfo.info.x11.gfxdisplay; + int scrnum = DefaultScreen(dpy); + const char* glxexts = glXQueryExtensionsString(dpy, scrnum); + scriptInterface.SetProperty(settings, "glx_extensions", glxexts); + if (strstr(glxexts, "GLX_MESA_query_renderer") && pglXQueryCurrentRendererIntegerMESA && pglXQueryCurrentRendererStringMESA) + { + GLXQCR_INTEGER(GLX_RENDERER_VENDOR_ID_MESA); + GLXQCR_INTEGER(GLX_RENDERER_DEVICE_ID_MESA); + GLXQCR_INTEGER3(GLX_RENDERER_VERSION_MESA); + GLXQCR_INTEGER(GLX_RENDERER_ACCELERATED_MESA); + GLXQCR_INTEGER(GLX_RENDERER_VIDEO_MEMORY_MESA); + GLXQCR_INTEGER(GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA); + GLXQCR_INTEGER(GLX_RENDERER_PREFERRED_PROFILE_MESA); + GLXQCR_INTEGER2(GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA); + GLXQCR_INTEGER2(GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA); + GLXQCR_INTEGER2(GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA); + GLXQCR_INTEGER2(GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA); + GLXQCR_STRING(GLX_RENDERER_VENDOR_ID_MESA); + GLXQCR_STRING(GLX_RENDERER_DEVICE_ID_MESA); + } + } +#endif // SDL_VIDEO_DRIVER_X11 + +#endif // ifdef XX +} // getGLLimits \ No newline at end of file diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index 910366277..af824b681 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -1,12 +1,18 @@ #ifndef GLWRAP_HEADER_H #define GLWRAP_HEADER_H -#include "gl_headers.hpp" +#include "graphics/gl_headers.hpp" + +#include "graphics/irr_driver.hpp" +#include "graphics/vaomanager.hpp" +#include "utils/log.hpp" #include -#include "irr_driver.hpp" -#include "utils/log.hpp" -#include "vaomanager.hpp" + +namespace HardwareStats +{ + class Json; +} void initGL(); GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount); @@ -152,6 +158,6 @@ void GL32_draw2DRectangle(irr::video::SColor color, const irr::core::rect& bool hasGLExtension(const char* extension); const std::string getGLExtensions(); - +void getGLLimits(HardwareStats::Json *json); #endif