summaryrefslogtreecommitdiff
path: root/appframework/glmdisplaydb_linuxwin.inl
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /appframework/glmdisplaydb_linuxwin.inl
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'appframework/glmdisplaydb_linuxwin.inl')
-rw-r--r--appframework/glmdisplaydb_linuxwin.inl630
1 files changed, 630 insertions, 0 deletions
diff --git a/appframework/glmdisplaydb_linuxwin.inl b/appframework/glmdisplaydb_linuxwin.inl
new file mode 100644
index 0000000..3e1d76a
--- /dev/null
+++ b/appframework/glmdisplaydb_linuxwin.inl
@@ -0,0 +1,630 @@
+//========= Copyright 1996-2009, Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Defines a group of app systems that all have the same lifetime
+// that need to be connected/initialized, etc. in a well-defined order
+//
+// $Revision: $
+// $NoKeywords: $
+//=============================================================================//
+
+//===============================================================================
+
+GLMRendererInfo::GLMRendererInfo( void )
+{
+ m_display = NULL;
+ Q_memset( &m_info, 0, sizeof( m_info ) );
+}
+
+GLMRendererInfo::~GLMRendererInfo( void )
+{
+ SDLAPP_FUNC;
+
+ if (m_display)
+ {
+ delete m_display;
+ m_display = NULL;
+ }
+}
+
+// !!! FIXME: sync this function with the Mac version in case anything important has changed.
+void GLMRendererInfo::Init( GLMRendererInfoFields *info )
+{
+ SDLAPP_FUNC;
+
+ m_info = *info;
+ m_display = NULL;
+
+ m_info.m_fullscreen = 0;
+ m_info.m_accelerated = 1;
+ m_info.m_windowed = 1;
+
+ m_info.m_ati = true;
+ m_info.m_atiNewer = true;
+
+ m_info.m_hasGammaWrites = true;
+
+ // If you haven't created a GL context by now (and initialized gGL), you're about to crash.
+
+ m_info.m_hasMixedAttachmentSizes = gGL->m_bHave_GL_ARB_framebuffer_object;
+ m_info.m_hasBGRA = gGL->m_bHave_GL_EXT_vertex_array_bgra;
+
+ // !!! FIXME: what do these do on the Mac?
+ m_info.m_hasNewFullscreenMode = false;
+ m_info.m_hasNativeClipVertexMode = true;
+
+ // if user disabled them
+ if (CommandLine()->FindParm("-glmdisableclipplanes"))
+ {
+ m_info.m_hasNativeClipVertexMode = false;
+ }
+
+ // or maybe enabled them..
+ if (CommandLine()->FindParm("-glmenableclipplanes"))
+ {
+ m_info.m_hasNativeClipVertexMode = true;
+ }
+
+ m_info.m_hasOcclusionQuery = gGL->m_bHave_GL_ARB_occlusion_query;
+ m_info.m_hasFramebufferBlit = gGL->m_bHave_GL_EXT_framebuffer_blit || gGL->m_bHave_GL_ARB_framebuffer_object;
+
+ GLint nMaxAniso = 0;
+ gGL->glGetIntegerv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &nMaxAniso );
+ m_info.m_maxAniso = clamp<int>( nMaxAniso, 0, 16 );
+
+ // We don't currently used bindable uniforms, but I've been experimenting with them so I might as well check this in just in case they turn out to be useful.
+ m_info.m_hasBindableUniforms = gGL->m_bHave_GL_EXT_bindable_uniform;
+ m_info.m_hasBindableUniforms = false; // !!! FIXME hardwiring this path to false until we see how to accelerate it properly
+ m_info.m_maxVertexBindableUniforms = 0;
+ m_info.m_maxFragmentBindableUniforms = 0;
+ m_info.m_maxBindableUniformSize = 0;
+
+ if (m_info.m_hasBindableUniforms)
+ {
+ gGL->glGetIntegerv(GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT, &m_info.m_maxVertexBindableUniforms);
+ gGL->glGetIntegerv(GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT, &m_info.m_maxFragmentBindableUniforms);
+ gGL->glGetIntegerv(GL_MAX_BINDABLE_UNIFORM_SIZE_EXT, &m_info.m_maxBindableUniformSize);
+ if ( ( m_info.m_maxVertexBindableUniforms < 1 ) || ( m_info.m_maxFragmentBindableUniforms < 1 ) || ( m_info.m_maxBindableUniformSize < ( sizeof( float ) * 4 * 256 ) ) )
+ {
+ m_info.m_hasBindableUniforms = false;
+ }
+ }
+
+ m_info.m_hasUniformBuffers = gGL->m_bHave_GL_ARB_uniform_buffer;
+ m_info.m_hasPerfPackage1 = true; // this flag is Mac-specific. We do slower things if you don't have Mac OS X 10.x.y or later. Linux always does the fast path!
+
+ //-------------------------------------------------------------------
+ // runtime options that aren't negotiable once set
+
+ m_info.m_hasDualShaders = CommandLine()->FindParm("-glmdualshaders") != 0;
+
+ //-------------------------------------------------------------------
+ // "can'ts "
+
+#if defined( OSX )
+ m_info.m_cantBlitReliably = m_info.m_intel; //FIXME X3100&10.6.3 has problems blitting.. adjust this if bug fixed in 10.6.4
+#else
+ // m_cantBlitReliably path doesn't work right now, and the Intel path is different for us on Linux/Win7 anyway
+ m_info.m_cantBlitReliably = false;
+#endif
+
+ if (CommandLine()->FindParm("-glmenabletrustblit"))
+ {
+ m_info.m_cantBlitReliably = false; // we trust the blit, so set the cant-blit cap to false
+ }
+ if (CommandLine()->FindParm("-glmdisabletrustblit"))
+ {
+ m_info.m_cantBlitReliably = true; // we do not trust the blit, so set the cant-blit cap to true
+ }
+
+ // MSAA resolve issues
+ m_info.m_cantResolveFlipped = false;
+
+
+#if defined( OSX )
+ m_info.m_cantResolveScaled = true; // generally true until new extension ships
+#else
+ // DON'T just slam this to false and run without first testing with -gl_debug enabled on NVidia/AMD/etc.
+ // This path needs the m_bHave_GL_EXT_framebuffer_multisample_blit_scaled extension.
+ m_info.m_cantResolveScaled = true;
+
+ if ( gGL->m_bHave_GL_EXT_framebuffer_multisample_blit_scaled )
+ {
+ m_info.m_cantResolveScaled = false;
+ }
+#endif
+
+ // gamma decode impacting shader codegen
+ m_info.m_costlyGammaFlips = false;
+}
+
+void GLMRendererInfo::PopulateDisplays()
+{
+ SDLAPP_FUNC;
+
+ Assert( !m_display );
+ m_display = new GLMDisplayInfo;
+
+ // Populate display mode table.
+ m_display->PopulateModes();
+}
+
+
+void GLMRendererInfo::Dump( int which )
+{
+ SDLAPP_FUNC;
+
+ GLMPRINTF(("\n #%d: GLMRendererInfo @ %p, renderer-id=(%08x) display-mask=%08x vram=%dMB",
+ which, this,
+ m_info.m_rendererID,
+ m_info.m_displayMask,
+ m_info.m_vidMemory >> 20
+ ));
+ GLMPRINTF(("\n VendorID=%04x DeviceID=%04x Model=%s",
+ m_info.m_pciVendorID,
+ m_info.m_pciDeviceID,
+ m_info.m_pciModelString
+ ));
+
+ m_display->Dump( which );
+}
+
+
+
+
+GLMDisplayDB::GLMDisplayDB ()
+{
+ SDLAPP_FUNC;
+
+ m_renderer.m_display = NULL;
+}
+
+GLMDisplayDB::~GLMDisplayDB ( void )
+{
+ SDLAPP_FUNC;
+
+ if ( m_renderer.m_display )
+ {
+ delete m_renderer.m_display;
+ m_renderer.m_display = NULL;
+ }
+}
+
+#ifndef GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX
+#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047
+#endif
+
+#ifndef GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX
+#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048
+#endif
+
+#ifndef GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX
+#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049
+#endif
+
+#ifndef GL_VBO_FREE_MEMORY_ATI
+#define GL_VBO_FREE_MEMORY_ATI 0x87FB
+#endif
+
+#ifndef GL_TEXTURE_FREE_MEMORY_ATI
+#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC
+#endif
+
+#ifndef GL_RENDERBUFFER_FREE_MEMORY_ATI
+#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
+#endif
+
+void GLMDisplayDB::PopulateRenderers( void )
+{
+ SDLAPP_FUNC;
+
+ Assert( !m_renderer.m_display );
+
+ GLMRendererInfoFields fields;
+ memset( &fields, 0, sizeof(fields) );
+
+ // Assume 512MB of available video memory
+ fields.m_vidMemory = 512 * 1024 * 1024;
+
+ DebugPrintf( "GL_NVX_gpu_memory_info: %s\n", gGL->m_bHave_GL_NVX_gpu_memory_info ? "AVAILABLE" : "UNAVAILABLE" );
+ DebugPrintf( "GL_ATI_meminfo: %s\n", gGL->m_bHave_GL_ATI_meminfo ? "AVAILABLE" : "UNAVAILABLE" );
+
+ if ( gGL->m_bHave_GL_NVX_gpu_memory_info )
+ {
+ gGL->glGetError();
+
+ GLint nTotalDedicated = 0, nTotalAvail = 0, nCurrentAvail = 0;
+ gGL->glGetIntegerv( GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &nTotalDedicated );
+ gGL->glGetIntegerv( GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &nTotalAvail );
+ gGL->glGetIntegerv( GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &nCurrentAvail );
+
+ if ( gGL->glGetError() )
+ {
+ DebugPrintf( "GL_NVX_gpu_memory_info: Failed retrieving available GPU memory\n" );
+ }
+ else
+ {
+ DebugPrintf( "GL_NVX_gpu_memory_info: Total Dedicated: %u, Total Avail: %u, Current Avail: %u\n", nTotalDedicated, nTotalAvail, nCurrentAvail );
+
+ // Try to do something reasonable. Should we report dedicated or total available to the engine here?
+ // For now, just take the MAX of both.
+ uint64 nActualAvail = static_cast<uint64>( MAX( nTotalAvail, nTotalDedicated ) ) * 1024;
+ fields.m_vidMemory = static_cast< GLint >( MIN( nActualAvail, 0x7FFFFFFF ) );
+ }
+ }
+ else if ( gGL->m_bHave_GL_ATI_meminfo )
+ {
+ // As of 10/8/12 this extension is only available under Linux and Windows FireGL parts.
+ gGL->glGetError();
+
+ GLint nAvail[4] = { 0, 0, 0, 0 };
+ gGL->glGetIntegerv( GL_TEXTURE_FREE_MEMORY_ATI, nAvail );
+
+ if ( gGL->glGetError() )
+ {
+ DebugPrintf( "GL_ATI_meminfo: Failed retrieving available GPU memory\n" );
+ }
+ else
+ {
+ // param[0] - total memory free in the pool
+ // param[1] - largest available free block in the pool
+ // param[2] - total auxiliary memory free
+ // param[3] - largest auxiliary free block
+
+ DebugPrintf( "GL_ATI_meminfo: GL_TEXTURE_FREE_MEMORY_ATI: Total Free: %i, Largest Avail: %i, Total Aux: %i, Largest Aux Avail: %i\n",
+ nAvail[0], nAvail[1], nAvail[2], nAvail[3] );
+
+ uint64 nActualAvail = static_cast<uint64>( nAvail[0] ) * 1024;
+ fields.m_vidMemory = static_cast< GLint >( MIN( nActualAvail, 0x7FFFFFFF ) );
+ }
+ }
+
+ // Clamp the min amount of video memory to 256MB in case a query returned something bogus, or we interpreted it badly.
+ fields.m_vidMemory = MAX( fields.m_vidMemory, 128 * 1024 * 1024 );
+ fields.m_texMemory = fields.m_vidMemory;
+
+ fields.m_pciVendorID = GLM_OPENGL_VENDOR_ID;
+ fields.m_pciDeviceID = GLM_OPENGL_DEFAULT_DEVICE_ID;
+ if ( ( gGL->m_nDriverProvider == cGLDriverProviderIntel ) || ( gGL->m_nDriverProvider == cGLDriverProviderIntelOpenSource ) )
+ {
+ fields.m_pciDeviceID = GLM_OPENGL_LOW_PERF_DEVICE_ID;
+ }
+
+/* fields.m_colorModes = (uint)-1;
+ fields.m_bufferModes = (uint)-1;
+ fields.m_depthModes = (uint)-1;
+ fields.m_stencilModes = (uint)-1;
+ fields.m_maxAuxBuffers = (uint)128;
+ fields.m_maxSampleBuffers = (uint)128;
+ fields.m_maxSamples = (uint)2048;
+ fields.m_sampleModes = (uint)128;
+ fields.m_sampleAlpha = (uint)32;
+*/
+
+ GLint nMaxMultiSamples = 0;
+ gGL->glGetIntegerv( GL_MAX_SAMPLES_EXT, &nMaxMultiSamples );
+ fields.m_maxSamples = clamp<int>( nMaxMultiSamples, 0, 8 );
+ DebugPrintf( "GL_MAX_SAMPLES_EXT: %i\n", nMaxMultiSamples );
+
+ // We only have one GLMRendererInfo on Linux, unlike Mac OS X. Whatever libGL.so wants to do, we go with it.
+ m_renderer.Init( &fields );
+
+ // then go back and ask each renderer to populate its display info table.
+ m_renderer.PopulateDisplays();
+}
+
+
+
+void GLMDisplayDB::PopulateFakeAdapters( uint realRendererIndex ) // fake adapters = one real adapter times however many displays are on it
+{
+ SDLAPP_FUNC;
+
+ Assert( realRendererIndex == 0 );
+}
+
+void GLMDisplayDB::Populate(void)
+{
+ SDLAPP_FUNC;
+
+ this->PopulateRenderers();
+
+ this->PopulateFakeAdapters( 0 );
+
+ #if GLMDEBUG
+ this->Dump();
+ #endif
+}
+
+
+
+int GLMDisplayDB::GetFakeAdapterCount( void )
+{
+ SDLAPP_FUNC;
+
+ return 1;
+}
+
+bool GLMDisplayDB::GetFakeAdapterInfo( int fakeAdapterIndex, int *rendererOut, int *displayOut, GLMRendererInfoFields *rendererInfoOut, GLMDisplayInfoFields *displayInfoOut )
+{
+ SDLAPP_FUNC;
+
+ if (fakeAdapterIndex >= GetFakeAdapterCount() )
+ {
+ *rendererOut = 0;
+ *displayOut = 0;
+ return true; // fail
+ }
+
+ *rendererOut = 0;
+ *displayOut = 0;
+
+ bool rendResult = GetRendererInfo( *rendererOut, rendererInfoOut );
+ bool dispResult = GetDisplayInfo( *rendererOut, *displayOut, displayInfoOut );
+
+ return rendResult || dispResult;
+}
+
+
+int GLMDisplayDB::GetRendererCount( void )
+{
+ SDLAPP_FUNC;
+
+ return 1;
+}
+
+bool GLMDisplayDB::GetRendererInfo( int rendererIndex, GLMRendererInfoFields *infoOut )
+{
+ SDLAPP_FUNC;
+
+ memset( infoOut, 0, sizeof( GLMRendererInfoFields ) );
+
+ if (rendererIndex >= GetRendererCount())
+ return true; // fail
+
+ *infoOut = m_renderer.m_info;
+
+ return false;
+}
+
+int GLMDisplayDB::GetDisplayCount( int rendererIndex )
+{
+ SDLAPP_FUNC;
+
+ if (rendererIndex >= GetRendererCount())
+ {
+ Assert( 0 );
+ return 0; // fail
+ }
+
+ return 1;
+}
+
+bool GLMDisplayDB::GetDisplayInfo( int rendererIndex, int displayIndex, GLMDisplayInfoFields *infoOut )
+{
+ SDLAPP_FUNC;
+
+ memset( infoOut, 0, sizeof( GLMDisplayInfoFields ) );
+
+ if (rendererIndex >= GetRendererCount())
+ return true; // fail
+
+ if (displayIndex >= GetDisplayCount(rendererIndex))
+ return true; // fail
+
+ *infoOut = m_renderer.m_display->m_info;
+
+ return false;
+}
+
+int GLMDisplayDB::GetModeCount( int rendererIndex, int displayIndex )
+{
+ SDLAPP_FUNC;
+
+ if (rendererIndex >= GetRendererCount())
+ return 0; // fail
+
+ if (displayIndex >= GetDisplayCount(rendererIndex))
+ return 0; // fail
+
+ return m_renderer.m_display->m_modes->Count();
+}
+
+bool GLMDisplayDB::GetModeInfo( int rendererIndex, int displayIndex, int modeIndex, GLMDisplayModeInfoFields *infoOut )
+{
+ SDLAPP_FUNC;
+
+ memset( infoOut, 0, sizeof( GLMDisplayModeInfoFields ) );
+
+ if ( rendererIndex >= GetRendererCount())
+ return true; // fail
+
+ if (displayIndex >= GetDisplayCount( rendererIndex ) )
+ return true; // fail
+
+ if ( modeIndex >= GetModeCount( rendererIndex, displayIndex ) )
+ return true; // fail
+
+ if ( modeIndex >= 0 )
+ {
+ GLMDisplayMode *displayModeInfo = m_renderer.m_display->m_modes->Element( modeIndex );
+
+ *infoOut = displayModeInfo->m_info;
+ }
+ else
+ {
+ const GLMDisplayInfoFields &info = m_renderer.m_display->m_info;
+
+ infoOut->m_modePixelWidth = info.m_displayPixelWidth;
+ infoOut->m_modePixelHeight = info.m_displayPixelHeight;
+ infoOut->m_modeRefreshHz = 0;
+
+ //return true; // fail
+ }
+
+ return false;
+}
+
+
+void GLMDisplayDB::Dump( void )
+{
+ SDLAPP_FUNC;
+
+ GLMPRINTF(("\n GLMDisplayDB @ %p ",this ));
+
+ m_renderer.Dump( 0 );
+}
+
+//===============================================================================
+
+GLMDisplayInfo::GLMDisplayInfo()
+{
+ SDLAPP_FUNC;
+
+ m_modes = NULL;
+
+ int Width, Height;
+ GetLargestDisplaySize( Width, Height );
+
+ m_info.m_displayPixelWidth = ( uint )Width;
+ m_info.m_displayPixelHeight = ( uint )Height;
+}
+
+GLMDisplayInfo::~GLMDisplayInfo( void )
+{
+ SDLAPP_FUNC;
+}
+
+extern "C" int DisplayModeSortFunction( GLMDisplayMode * const *A, GLMDisplayMode * const *B )
+{
+ SDLAPP_FUNC;
+
+ int bigger = -1;
+ int smaller = 1; // adjust these for desired ordering
+
+ // check refreshrate - higher should win
+ if ( (*A)->m_info.m_modeRefreshHz > (*B)->m_info.m_modeRefreshHz )
+ {
+ return bigger;
+ }
+ else if ( (*A)->m_info.m_modeRefreshHz < (*B)->m_info.m_modeRefreshHz )
+ {
+ return smaller;
+ }
+
+ // check area - larger mode should win
+ int areaa = (*A)->m_info.m_modePixelWidth * (*A)->m_info.m_modePixelHeight;
+ int areab = (*B)->m_info.m_modePixelWidth * (*B)->m_info.m_modePixelHeight;
+
+ if ( areaa > areab )
+ {
+ return bigger;
+ }
+ else if ( areaa < areab )
+ {
+ return smaller;
+ }
+
+ return 0; // equal rank
+}
+
+
+void GLMDisplayInfo::PopulateModes( void )
+{
+ SDLAPP_FUNC;
+
+ Assert( !m_modes );
+ m_modes = new CUtlVector< GLMDisplayMode* >;
+
+ int nummodes = SDL_GetNumVideoDisplays();
+
+ for ( int i = 0; i < nummodes; i++ )
+ {
+ SDL_Rect rect = { 0, 0, 0, 0 };
+
+ if ( !SDL_GetDisplayBounds( i, &rect ) && rect.w && rect.h )
+ {
+ m_modes->AddToTail( new GLMDisplayMode( rect.w, rect.h, 0 ) );
+ }
+ }
+
+ // Add a big pile of window resolutions.
+ static const struct
+ {
+ uint w;
+ uint h;
+ } s_Resolutions[] =
+ {
+ { 640, 480 }, // 4x3
+ { 800, 600 },
+ { 1024, 768 },
+ { 1152, 864 },
+ { 1280, 960 },
+ { 1600, 1200 },
+ { 1920, 1440 },
+ { 2048, 1536 },
+
+ { 1280, 720 }, // 16x9
+ { 1366, 768 },
+ { 1600, 900 },
+ { 1920, 1080 },
+
+ { 720, 480 }, // 16x10
+ { 1280, 800 },
+ { 1680, 1050 },
+ { 1920, 1200 },
+ { 2560, 1600 },
+ };
+
+ for ( int i = 0; i < ARRAYSIZE( s_Resolutions ); i++ )
+ {
+ uint w = s_Resolutions[ i ].w;
+ uint h = s_Resolutions[ i ].h;
+
+ if ( ( w <= m_info.m_displayPixelWidth ) && ( h <= m_info.m_displayPixelHeight ) )
+ {
+ m_modes->AddToTail( new GLMDisplayMode( w, h, 0 ) );
+
+ if ( ( w * 2 <= m_info.m_displayPixelWidth ) && ( h * 2 < m_info.m_displayPixelHeight ) )
+ {
+ // Add double of everything also - Retina proofing hopefully.
+ m_modes->AddToTail( new GLMDisplayMode( w * 2, h * 2, 0 ) );
+ }
+ }
+ }
+
+ m_modes->Sort( DisplayModeSortFunction );
+
+ // remove dupes.
+ nummodes = m_modes->Count();
+ int i = 1; // not zero!
+ while (i < nummodes)
+ {
+ GLMDisplayModeInfoFields& info0 = m_modes->Element( i - 1 )->m_info;
+ GLMDisplayModeInfoFields& info1 = m_modes->Element( i )->m_info;
+
+ if ( ( info0.m_modePixelWidth == info1.m_modePixelWidth ) &&
+ ( info0.m_modePixelHeight == info1.m_modePixelHeight ) &&
+ ( info0.m_modeRefreshHz == info1.m_modeRefreshHz ) )
+ {
+ m_modes->Remove(i);
+ nummodes--;
+ }
+ else
+ {
+ i++;
+ }
+ }
+}
+
+
+void GLMDisplayInfo::Dump( int which )
+{
+ SDLAPP_FUNC;
+
+ GLMPRINTF(("\n #%d: GLMDisplayInfo @ %08x, pixwidth=%d pixheight=%d",
+ which, (int)this, m_info.m_displayPixelWidth, m_info.m_displayPixelHeight ));
+
+ FOR_EACH_VEC( *m_modes, i )
+ {
+ ( *m_modes )[i]->Dump(i);
+ }
+}