2013-06-23 07:49:34 +00:00
/*
* * r_opengl . cpp
* *
* * OpenGL system interface
* *
* * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* * Copyright 2005 Tim Stump
2013-08-18 12:16:33 +00:00
* * Copyright 2005 - 2013 Christoph Oelckers
2013-06-23 07:49:34 +00:00
* * All rights reserved .
* *
* * Redistribution and use in source and binary forms , with or without
* * modification , are permitted provided that the following conditions
* * are met :
* *
* * 1. Redistributions of source code must retain the above copyright
* * notice , this list of conditions and the following disclaimer .
* * 2. Redistributions in binary form must reproduce the above copyright
* * notice , this list of conditions and the following disclaimer in the
* * documentation and / or other materials provided with the distribution .
* * 3. The name of the author may not be used to endorse or promote products
* * derived from this software without specific prior written permission .
* * 4. Full disclosure of the entire project ' s source code , except for third
* * party libraries is mandatory . ( NOTE : This clause is non - negotiable ! )
* *
* * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* * IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* * INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* * NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* * DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* * THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* * THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* *
*/
# include "gl/system/gl_system.h"
# include "tarray.h"
# include "doomtype.h"
# include "m_argv.h"
# include "zstring.h"
# include "version.h"
# include "i_system.h"
2013-09-02 06:43:56 +00:00
# include "v_text.h"
2013-09-03 16:29:39 +00:00
# include "gl/system/gl_interface.h"
2013-06-23 07:49:34 +00:00
# include "gl/system/gl_cvars.h"
static TArray < FString > m_Extensions ;
2013-08-18 13:41:52 +00:00
RenderContext gl ;
2013-06-23 07:49:34 +00:00
int occlusion_type = 0 ;
//==========================================================================
//
//
//
//==========================================================================
static void CollectExtensions ( )
{
2014-07-15 00:26:23 +00:00
const char * extension ;
2013-06-23 07:49:34 +00:00
2014-07-15 00:26:23 +00:00
int max = 0 ;
glGetIntegerv ( GL_NUM_EXTENSIONS , & max ) ;
2013-06-23 07:49:34 +00:00
2014-07-15 00:26:23 +00:00
for ( int i = 0 ; i < max ; i + + )
2013-06-23 07:49:34 +00:00
{
2014-07-15 00:26:23 +00:00
extension = ( const char * ) glGetStringi ( GL_EXTENSIONS , i ) ;
m_Extensions . Push ( FString ( extension ) ) ;
2013-06-23 07:49:34 +00:00
}
}
//==========================================================================
//
//
//
//==========================================================================
static bool CheckExtension ( const char * ext )
{
for ( unsigned int i = 0 ; i < m_Extensions . Size ( ) ; + + i )
{
if ( m_Extensions [ i ] . CompareNoCase ( ext ) = = 0 ) return true ;
}
return false ;
}
2013-08-18 13:41:52 +00:00
2013-06-23 07:49:34 +00:00
//==========================================================================
//
//
//
//==========================================================================
2013-08-18 13:41:52 +00:00
static void InitContext ( )
2013-06-23 07:49:34 +00:00
{
2013-08-18 13:41:52 +00:00
gl . flags = 0 ;
}
//==========================================================================
//
//
//
//==========================================================================
void gl_LoadExtensions ( )
{
InitContext ( ) ;
2013-06-23 07:49:34 +00:00
CollectExtensions ( ) ;
2014-06-13 23:24:28 +00:00
const char * version = Args - > CheckValue ( " -glversion " ) ;
if ( version = = NULL ) version = ( const char * ) glGetString ( GL_VERSION ) ;
else Printf ( " Emulating OpenGL v %s \n " , version ) ;
2014-06-21 13:50:32 +00:00
// Don't even start if it's lower than 3.0
2014-09-14 19:43:42 +00:00
if ( strcmp ( version , " 3.0 " ) < 0 )
2013-06-23 07:49:34 +00:00
{
2014-09-14 19:43:42 +00:00
I_FatalError ( " Unsupported OpenGL version. \n At least OpenGL 3.0 is required to run " GAMENAME " . \n " ) ;
2013-06-23 07:49:34 +00:00
}
2014-07-15 00:26:23 +00:00
// add 0.01 to account for roundoff errors making the number a tad smaller than the actual version
gl . version = strtod ( version , NULL ) + 0.01f ;
gl . glslversion = strtod ( ( char * ) glGetString ( GL_SHADING_LANGUAGE_VERSION ) , NULL ) + 0.01f ;
2013-06-23 07:49:34 +00:00
2014-07-27 11:46:35 +00:00
gl . vendorstring = ( char * ) glGetString ( GL_VENDOR ) ;
2013-06-23 07:49:34 +00:00
2015-07-13 07:49:02 +00:00
if ( gl . version < 3.3f & & ! CheckExtension ( " GL_ARB_sampler_objects " ) )
{
I_FatalError ( " 'GL_ARB_sampler_objects' extension not found. Please update your graphics driver. " ) ;
}
2013-08-18 13:41:52 +00:00
if ( CheckExtension ( " GL_ARB_texture_compression " ) ) gl . flags | = RFL_TEXTURE_COMPRESSION ;
if ( CheckExtension ( " GL_EXT_texture_compression_s3tc " ) ) gl . flags | = RFL_TEXTURE_COMPRESSION_S3TC ;
2014-08-19 13:56:33 +00:00
if ( ! Args - > CheckParm ( " -gl3 " ) )
{
// don't use GL 4.x features when running in GL 3 emulation mode.
2014-09-17 07:01:16 +00:00
if ( CheckExtension ( " GL_ARB_buffer_storage " ) )
{
// work around a problem with older AMD drivers: Their implementation of shader storage buffer objects is piss-poor and does not match uniform buffers even closely.
// Recent drivers, GL 4.4 don't have this problem, these can easily be recognized by also supporting the GL_ARB_buffer_storage extension.
if ( CheckExtension ( " GL_ARB_shader_storage_buffer_object " ) )
{
2014-12-01 08:58:23 +00:00
// Shader storage buffer objects are broken on current Intel drivers.
if ( strstr ( gl . vendorstring , " Intel " ) = = NULL )
{
gl . flags | = RFL_SHADER_STORAGE_BUFFER ;
}
2014-09-17 07:01:16 +00:00
}
gl . flags | = RFL_BUFFER_STORAGE ;
}
2014-08-19 13:56:33 +00:00
}
2014-07-15 00:48:59 +00:00
2014-09-14 21:01:57 +00:00
int v ;
glGetIntegerv ( GL_MAX_FRAGMENT_UNIFORM_COMPONENTS , & v ) ;
gl . maxuniforms = v ;
glGetIntegerv ( GL_MAX_UNIFORM_BLOCK_SIZE , & v ) ;
gl . maxuniformblock = v ;
glGetIntegerv ( GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT , & v ) ;
gl . uniformblockalignment = v ;
2013-08-18 13:41:52 +00:00
glGetIntegerv ( GL_MAX_TEXTURE_SIZE , & gl . max_texturesize ) ;
2013-06-23 07:49:34 +00:00
glPixelStorei ( GL_UNPACK_ALIGNMENT , 1 ) ;
}
//==========================================================================
//
//
//
//==========================================================================
2013-08-18 13:41:52 +00:00
void gl_PrintStartupLog ( )
2013-06-23 07:49:34 +00:00
{
2015-04-27 19:25:16 +00:00
int v = 0 ;
2014-08-23 23:09:44 +00:00
glGetIntegerv ( GL_CONTEXT_PROFILE_MASK , & v ) ;
2013-06-23 07:49:34 +00:00
Printf ( " GL_VENDOR: %s \n " , glGetString ( GL_VENDOR ) ) ;
Printf ( " GL_RENDERER: %s \n " , glGetString ( GL_RENDERER ) ) ;
2014-08-23 23:09:44 +00:00
Printf ( " GL_VERSION: %s (%s profile) \n " , glGetString ( GL_VERSION ) , ( v & GL_CONTEXT_CORE_PROFILE_BIT ) ? " Core " : " Compatibility " ) ;
2013-06-23 07:49:34 +00:00
Printf ( " GL_SHADING_LANGUAGE_VERSION: %s \n " , glGetString ( GL_SHADING_LANGUAGE_VERSION ) ) ;
2014-07-15 00:26:23 +00:00
Printf ( " GL_EXTENSIONS: " ) ;
for ( unsigned i = 0 ; i < m_Extensions . Size ( ) ; i + + )
{
Printf ( " %s " , m_Extensions [ i ] . GetChars ( ) ) ;
}
2013-06-23 07:49:34 +00:00
2014-04-06 12:35:44 +00:00
glGetIntegerv ( GL_MAX_TEXTURE_SIZE , & v ) ;
2014-07-15 00:26:23 +00:00
Printf ( " \n Max. texture size: %d \n " , v ) ;
2013-06-23 07:49:34 +00:00
glGetIntegerv ( GL_MAX_TEXTURE_IMAGE_UNITS , & v ) ;
Printf ( " Max. texture units: %d \n " , v ) ;
glGetIntegerv ( GL_MAX_FRAGMENT_UNIFORM_COMPONENTS , & v ) ;
Printf ( " Max. fragment uniforms: %d \n " , v ) ;
glGetIntegerv ( GL_MAX_VERTEX_UNIFORM_COMPONENTS , & v ) ;
Printf ( " Max. vertex uniforms: %d \n " , v ) ;
2014-07-30 21:13:16 +00:00
glGetIntegerv ( GL_MAX_UNIFORM_BLOCK_SIZE , & v ) ;
Printf ( " Max. uniform block size: %d \n " , v ) ;
2014-08-01 18:59:39 +00:00
glGetIntegerv ( GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT , & v ) ;
Printf ( " Uniform block alignment: %d \n " , v ) ;
2013-06-23 07:49:34 +00:00
glGetIntegerv ( GL_MAX_VARYING_FLOATS , & v ) ;
Printf ( " Max. varying: %d \n " , v ) ;
2014-05-11 19:47:54 +00:00
glGetIntegerv ( GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS , & v ) ;
Printf ( " Max. combined shader storage blocks: %d \n " , v ) ;
glGetIntegerv ( GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS , & v ) ;
Printf ( " Max. vertex shader storage blocks: %d \n " , v ) ;
2013-06-23 07:49:34 +00:00
2014-07-30 21:13:16 +00:00
2013-06-23 07:49:34 +00:00
}