465 lines
16 KiB
C++
465 lines
16 KiB
C++
// SuperTuxKart - a fun racing game with go-kart
|
|
// Copyright (C) 2014-2015 SuperTuxKart-Team
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License
|
|
// as published by the Free Software Foundation; either version 3
|
|
// of the License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
#ifndef SERVER_ONLY
|
|
#include "graphics/central_settings.hpp"
|
|
|
|
#include "config/user_config.hpp"
|
|
#include "modes/profile_world.hpp"
|
|
#include "graphics/sp/sp_base.hpp"
|
|
#include "graphics/gl_headers.hpp"
|
|
#include "graphics/glwrap.hpp"
|
|
#include "graphics/graphics_restrictions.hpp"
|
|
|
|
bool CentralVideoSettings::m_supports_sp = true;
|
|
|
|
CentralVideoSettings *CVS = new CentralVideoSettings();
|
|
|
|
void CentralVideoSettings::init()
|
|
{
|
|
m_gl_major_version = 2;
|
|
m_gl_minor_version = 1;
|
|
|
|
// Parse extensions
|
|
hasBufferStorage = false;
|
|
hasComputeShaders = false;
|
|
hasArraysOfArrays = false;
|
|
hasTextureStorage = false;
|
|
hasTextureView = false;
|
|
hasAtomics = false;
|
|
hasSSBO = false;
|
|
hasImageLoadStore = false;
|
|
hasTextureCompression = false;
|
|
hasTextureCompressionSRGB = false;
|
|
hasUBO = false;
|
|
hasExplicitAttribLocation = false;
|
|
hasGS = false;
|
|
hasTextureFilterAnisotropic = false;
|
|
hasTextureSwizzle = false;
|
|
hasPixelBufferObject = false;
|
|
hasSamplerObjects = false;
|
|
hasVertexType2101010Rev = false;
|
|
hasInstancedArrays = false;
|
|
hasBGRA = false;
|
|
hasColorBufferFloat = false;
|
|
hasTextureBufferObject = false;
|
|
m_need_vertex_id_workaround = false;
|
|
|
|
// Call to glGetIntegerv should not be made if --no-graphics is used
|
|
if (!ProfileWorld::isNoGraphics())
|
|
{
|
|
glGetIntegerv(GL_MAJOR_VERSION, &m_gl_major_version);
|
|
glGetIntegerv(GL_MINOR_VERSION, &m_gl_minor_version);
|
|
Log::info("IrrDriver", "OpenGL version: %d.%d", m_gl_major_version, m_gl_minor_version);
|
|
Log::info("IrrDriver", "OpenGL vendor: %s", glGetString(GL_VENDOR));
|
|
Log::info("IrrDriver", "OpenGL renderer: %s", glGetString(GL_RENDERER));
|
|
Log::info("IrrDriver", "OpenGL version string: %s", glGetString(GL_VERSION));
|
|
}
|
|
#if !defined(USE_GLES2)
|
|
m_glsl = (m_gl_major_version > 3 || (m_gl_major_version == 3 && m_gl_minor_version >= 1))
|
|
&& !UserConfigParams::m_force_legacy_device && m_supports_sp;
|
|
#else
|
|
m_glsl = m_gl_major_version >= 3 && !UserConfigParams::m_force_legacy_device;
|
|
#endif
|
|
if (!ProfileWorld::isNoGraphics())
|
|
initGL();
|
|
|
|
if (!ProfileWorld::isNoGraphics())
|
|
{
|
|
std::string driver((char*)(glGetString(GL_VERSION)));
|
|
std::string card((char*)(glGetString(GL_RENDERER)));
|
|
std::string vendor((char*)(glGetString(GL_VENDOR)));
|
|
GraphicsRestrictions::init(driver, card, vendor);
|
|
|
|
if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_FORCE_LEGACY_DEVICE))
|
|
{
|
|
m_glsl = false;
|
|
}
|
|
|
|
#if !defined(USE_GLES2)
|
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_BUFFER_STORAGE) &&
|
|
hasGLExtension("GL_ARB_buffer_storage") )
|
|
{
|
|
hasBufferStorage = true;
|
|
Log::info("GLDriver", "ARB Buffer Storage Present");
|
|
}
|
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_COMPUTE_SHADER) &&
|
|
hasGLExtension("GL_ARB_compute_shader")) {
|
|
hasComputeShaders = true;
|
|
Log::info("GLDriver", "ARB Compute Shader Present");
|
|
}
|
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_ARRAYS_OF_ARRAYS) &&
|
|
hasGLExtension("GL_ARB_arrays_of_arrays")) {
|
|
hasArraysOfArrays = true;
|
|
Log::info("GLDriver", "ARB Arrays of Arrays Present");
|
|
}
|
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_TEXTURE_STORAGE) &&
|
|
hasGLExtension("GL_ARB_texture_storage")) {
|
|
hasTextureStorage = true;
|
|
Log::info("GLDriver", "ARB Texture Storage Present");
|
|
}
|
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_TEXTURE_VIEW) &&
|
|
hasGLExtension("GL_ARB_texture_view")) {
|
|
hasTextureView = true;
|
|
Log::info("GLDriver", "ARB Texture View Present");
|
|
}
|
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_IMAGE_LOAD_STORE) &&
|
|
hasGLExtension("GL_ARB_shader_image_load_store")) {
|
|
hasImageLoadStore = true;
|
|
Log::info("GLDriver", "ARB Image Load Store Present");
|
|
}
|
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_SHADER_ATOMIC_COUNTERS) &&
|
|
hasGLExtension("GL_ARB_shader_atomic_counters")) {
|
|
hasAtomics = true;
|
|
Log::info("GLDriver", "ARB Shader Atomic Counters Present");
|
|
}
|
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_SHADER_STORAGE_BUFFER_OBJECT) &&
|
|
hasGLExtension("GL_ARB_shader_storage_buffer_object")) {
|
|
hasSSBO = true;
|
|
Log::info("GLDriver", "ARB Shader Storage Buffer Object Present");
|
|
}
|
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_EXT_TEXTURE_COMPRESSION_S3TC) &&
|
|
hasGLExtension("GL_EXT_texture_compression_s3tc"))
|
|
{
|
|
hasTextureCompression = true;
|
|
Log::info("GLDriver", "EXT Texture Compression S3TC Present");
|
|
}
|
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_UNIFORM_BUFFER_OBJECT) &&
|
|
hasGLExtension("GL_ARB_uniform_buffer_object")) {
|
|
hasUBO = true;
|
|
Log::info("GLDriver", "ARB Uniform Buffer Object Present");
|
|
}
|
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_EXPLICIT_ATTRIB_LOCATION) &&
|
|
hasGLExtension("GL_ARB_explicit_attrib_location")) {
|
|
hasExplicitAttribLocation = true;
|
|
Log::info("GLDriver", "ARB Explicit Attrib Location Present");
|
|
}
|
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_TEXTURE_FILTER_ANISOTROPIC) &&
|
|
hasGLExtension("GL_EXT_texture_filter_anisotropic")) {
|
|
hasTextureFilterAnisotropic = true;
|
|
Log::info("GLDriver", "EXT Texture Filter Anisotropic Present");
|
|
}
|
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_GEOMETRY_SHADER) &&
|
|
(m_gl_major_version > 3 || (m_gl_major_version == 3 && m_gl_minor_version >= 2))) {
|
|
hasGS = true;
|
|
Log::info("GLDriver", "Geometry Shaders Present");
|
|
}
|
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_TEXTURE_BUFFER_OBJECT) &&
|
|
m_glsl == true)
|
|
{
|
|
hasTextureBufferObject = true;
|
|
Log::info("GLDriver", "ARB Texture Buffer Object Present");
|
|
}
|
|
if (hasGLExtension("GL_ARB_texture_swizzle"))
|
|
{
|
|
hasTextureSwizzle = true;
|
|
Log::info("GLDriver", "ARB Texture Swizzle Present");
|
|
}
|
|
if (hasGLExtension("GL_ARB_pixel_buffer_object"))
|
|
{
|
|
hasPixelBufferObject = true;
|
|
Log::info("GLDriver", "ARB Pixel Buffer Object Present");
|
|
}
|
|
if (hasGLExtension("GL_ARB_sampler_objects"))
|
|
{
|
|
hasSamplerObjects = true;
|
|
Log::info("GLDriver", "ARB Sampler Objects Present");
|
|
}
|
|
if (hasGLExtension("GL_ARB_vertex_type_2_10_10_10_rev"))
|
|
{
|
|
hasVertexType2101010Rev = true;
|
|
Log::info("GLDriver", "ARB Vertex Type 2_10_10_10_rev Present");
|
|
}
|
|
if (hasGLExtension("GL_ARB_instanced_arrays"))
|
|
{
|
|
hasInstancedArrays = true;
|
|
Log::info("GLDriver", "ARB Instanced Arrays Present");
|
|
}
|
|
|
|
// Check all extensions required by SP
|
|
m_supports_sp = isARBInstancedArraysUsable() &&
|
|
isARBVertexType2101010RevUsable() && isARBSamplerObjectsUsable() &&
|
|
isARBExplicitAttribLocationUsable();
|
|
|
|
hasTextureCompressionSRGB = true;
|
|
hasBGRA = true;
|
|
hasColorBufferFloat = true;
|
|
|
|
#else
|
|
if (m_glsl == true)
|
|
{
|
|
hasTextureStorage = true;
|
|
hasTextureSwizzle = true;
|
|
hasSamplerObjects = true;
|
|
hasVertexType2101010Rev = true;
|
|
hasInstancedArrays = true;
|
|
hasPixelBufferObject = true;
|
|
}
|
|
|
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_EXPLICIT_ATTRIB_LOCATION) &&
|
|
m_glsl == true)
|
|
{
|
|
Log::info("GLDriver", "Explicit Attrib Location Present");
|
|
hasExplicitAttribLocation = true;
|
|
}
|
|
|
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_UNIFORM_BUFFER_OBJECT) &&
|
|
m_glsl == true)
|
|
{
|
|
hasUBO = true;
|
|
Log::info("GLDriver", "ARB Uniform Buffer Object Present");
|
|
}
|
|
|
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_TEXTURE_FORMAT_BGRA8888) &&
|
|
(hasGLExtension("GL_IMG_texture_format_BGRA8888") ||
|
|
hasGLExtension("GL_EXT_texture_format_BGRA8888")))
|
|
{
|
|
hasBGRA = true;
|
|
Log::info("GLDriver", "EXT texture format BGRA8888 Present");
|
|
}
|
|
|
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_COLOR_BUFFER_FLOAT) &&
|
|
hasGLExtension("GL_EXT_color_buffer_float"))
|
|
{
|
|
hasColorBufferFloat = true;
|
|
Log::info("GLDriver", "EXT Color Buffer Float Present");
|
|
}
|
|
|
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_EXT_TEXTURE_COMPRESSION_S3TC) &&
|
|
(hasGLExtension("GL_EXT_texture_compression_s3tc") ||
|
|
hasGLExtension("GL_ANGLE_texture_compression_dxt5")))
|
|
{
|
|
hasTextureCompression = true;
|
|
Log::info("GLDriver", "EXT Texture Compression S3TC Present");
|
|
}
|
|
|
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_EXT_TEXTURE_COMPRESSION_S3TC) &&
|
|
(hasGLExtension("GL_EXT_texture_compression_s3tc_srgb") ||
|
|
hasGLExtension("GL_NV_sRGB_formats")))
|
|
{
|
|
hasTextureCompressionSRGB = true;
|
|
Log::info("GLDriver", "EXT Texture Compression S3TC sRGB Present");
|
|
}
|
|
|
|
if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_VERTEX_ID_WORKING))
|
|
{
|
|
m_need_vertex_id_workaround = true;
|
|
}
|
|
#endif
|
|
|
|
// Only unset the high def textures if they are set as default. If the
|
|
// user has enabled them (bit 1 set), then leave them enabled.
|
|
if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_HIGHDEFINITION_TEXTURES) &&
|
|
(UserConfigParams::m_high_definition_textures & 0x02) == 0)
|
|
{
|
|
UserConfigParams::m_high_definition_textures = 0x00;
|
|
}
|
|
|
|
if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_HIGHDEFINITION_TEXTURES_256))
|
|
{
|
|
UserConfigParams::m_high_definition_textures = 0;
|
|
if (UserConfigParams::m_max_texture_size > 256)
|
|
{
|
|
UserConfigParams::m_max_texture_size = 256;
|
|
}
|
|
}
|
|
#ifndef ANDROID
|
|
if (SP::sp_apitrace)
|
|
{
|
|
Log::info("IrrDriver", "Writing GPU query strings to apitrace and"
|
|
" disable buffer storage");
|
|
hasBufferStorage = false;
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
unsigned CentralVideoSettings::getGLSLVersion() const
|
|
{
|
|
#if defined(USE_GLES2)
|
|
if (m_gl_major_version >= 3)
|
|
return 300;
|
|
else
|
|
return 100;
|
|
#else
|
|
if (m_gl_major_version > 3 || (m_gl_major_version == 3 && m_gl_minor_version == 3))
|
|
return m_gl_major_version * 100 + m_gl_minor_version * 10;
|
|
else if (m_gl_major_version == 3)
|
|
return 100 + (m_gl_minor_version + 3) * 10;
|
|
else
|
|
return 120;
|
|
#endif
|
|
}
|
|
|
|
bool CentralVideoSettings::isGLSL() const
|
|
{
|
|
return m_glsl;
|
|
}
|
|
|
|
bool CentralVideoSettings::needsVertexIdWorkaround() const
|
|
{
|
|
return m_need_vertex_id_workaround;
|
|
}
|
|
|
|
bool CentralVideoSettings::isARBGeometryShadersUsable() const
|
|
{
|
|
return hasGS;
|
|
}
|
|
|
|
bool CentralVideoSettings::isARBUniformBufferObjectUsable() const
|
|
{
|
|
return hasUBO ||
|
|
(m_gl_major_version > 3 || (m_gl_major_version == 3 && m_gl_minor_version >= 1));
|
|
}
|
|
|
|
bool CentralVideoSettings::isARBExplicitAttribLocationUsable() const
|
|
{
|
|
return hasExplicitAttribLocation ||
|
|
(m_gl_major_version > 3 || (m_gl_major_version == 3 && m_gl_minor_version >= 3));
|
|
}
|
|
|
|
bool CentralVideoSettings::isEXTTextureCompressionS3TCUsable() const
|
|
{
|
|
return hasTextureCompression;
|
|
}
|
|
|
|
bool CentralVideoSettings::isEXTTextureCompressionS3TCSRGBUsable() const
|
|
{
|
|
return hasTextureCompression && hasTextureCompressionSRGB;
|
|
}
|
|
|
|
|
|
bool CentralVideoSettings::isARBBufferStorageUsable() const
|
|
{
|
|
return hasBufferStorage;
|
|
}
|
|
|
|
bool CentralVideoSettings::isARBComputeShaderUsable() const
|
|
{
|
|
return hasComputeShaders;
|
|
}
|
|
|
|
bool CentralVideoSettings::isARBArraysOfArraysUsable() const
|
|
{
|
|
return hasArraysOfArrays;
|
|
}
|
|
|
|
bool CentralVideoSettings::isARBTextureStorageUsable() const
|
|
{
|
|
return hasTextureStorage;
|
|
}
|
|
|
|
bool CentralVideoSettings::isARBTextureViewUsable() const
|
|
{
|
|
return hasTextureView;
|
|
}
|
|
|
|
bool CentralVideoSettings::isARBShaderAtomicCountersUsable() const
|
|
{
|
|
return hasAtomics;
|
|
}
|
|
|
|
bool CentralVideoSettings::isARBShaderStorageBufferObjectUsable() const
|
|
{
|
|
return hasSSBO;
|
|
}
|
|
|
|
bool CentralVideoSettings::isARBImageLoadStoreUsable() const
|
|
{
|
|
return hasImageLoadStore;
|
|
}
|
|
|
|
bool CentralVideoSettings::isEXTTextureFilterAnisotropicUsable() const
|
|
{
|
|
return hasTextureFilterAnisotropic;
|
|
}
|
|
|
|
bool CentralVideoSettings::isEXTTextureFormatBGRA8888Usable() const
|
|
{
|
|
return hasBGRA;
|
|
}
|
|
|
|
bool CentralVideoSettings::isEXTColorBufferFloatUsable() const
|
|
{
|
|
return hasColorBufferFloat;
|
|
}
|
|
|
|
bool CentralVideoSettings::supportsComputeShadersFiltering() const
|
|
{
|
|
return isARBBufferStorageUsable() && isARBImageLoadStoreUsable() && isARBComputeShaderUsable() && isARBArraysOfArraysUsable();
|
|
}
|
|
|
|
bool CentralVideoSettings::supportsTextureCompression() const
|
|
{
|
|
return isEXTTextureCompressionS3TCUsable();
|
|
}
|
|
|
|
bool CentralVideoSettings::isShadowEnabled() const
|
|
{
|
|
return UserConfigParams::m_shadows_resolution > 0;
|
|
}
|
|
|
|
bool CentralVideoSettings::isTextureCompressionEnabled() const
|
|
{
|
|
return supportsTextureCompression() && UserConfigParams::m_texture_compression;
|
|
}
|
|
|
|
bool CentralVideoSettings::isDeferredEnabled() const
|
|
{
|
|
return UserConfigParams::m_dynamic_lights && !GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_ADVANCED_PIPELINE);
|
|
}
|
|
|
|
bool CentralVideoSettings::supportsHardwareSkinning() const
|
|
{
|
|
return !GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_HARDWARE_SKINNING);
|
|
}
|
|
|
|
bool CentralVideoSettings::isARBTextureSwizzleUsable() const
|
|
{
|
|
return m_glsl && hasTextureSwizzle;
|
|
}
|
|
|
|
bool CentralVideoSettings::isARBPixelBufferObjectUsable() const
|
|
{
|
|
return hasPixelBufferObject;
|
|
}
|
|
|
|
bool CentralVideoSettings::isARBSamplerObjectsUsable() const
|
|
{
|
|
return hasSamplerObjects ||
|
|
(m_gl_major_version > 3 || (m_gl_major_version == 3 && m_gl_minor_version >= 3));
|
|
}
|
|
|
|
bool CentralVideoSettings::isARBVertexType2101010RevUsable() const
|
|
{
|
|
return hasVertexType2101010Rev ||
|
|
(m_gl_major_version > 3 || (m_gl_major_version == 3 && m_gl_minor_version >= 3));
|
|
}
|
|
|
|
bool CentralVideoSettings::isARBInstancedArraysUsable() const
|
|
{
|
|
return hasInstancedArrays ||
|
|
(m_gl_major_version > 3 || (m_gl_major_version == 3 && m_gl_minor_version >= 2));
|
|
}
|
|
|
|
bool CentralVideoSettings::isARBTextureBufferObjectUsable() const
|
|
{
|
|
return hasTextureBufferObject;
|
|
}
|
|
|
|
#endif // !SERVER_ONLY
|