How to detect if OGL is HW accelerated?

BlitzMax Forums/BlitzMax Programming/How to detect if OGL is HW accelerated?

Robert Cummings(Posted 2006) [#1]
Hi,

On one of my test PCs which is software rendering only, it drops down to OpenGL software mode and then runs for a while then crashes.

I actually want to detect if OpenGL is running in software mode so I can cancel that and switch to my custom software engine.

How do I detect this?

Thank you.


ImaginaryHuman(Posted 2006) [#2]
You can't at leat not by BlitzMax.

However, there is SOME CHANCE that if your system has software-only OpenGL it MIGHT be that there isn't enough video ram for fullscreen mode. You could try opening a full-screen display and if it fails this *might* indicate that full-screen is not supported, and hence there is no hardware acceleration. But that's very dubious.


JoeRetro(Posted 2006) [#3]
Another option IMHO is to test the frame rate of your application. If your app is yielding less than 5 fps this would be a good indicator (???) that your running in software-only OpenGL. It's not elegant by any means but may be an alternative solution.


Robert Cummings(Posted 2006) [#4]
Problem is it crashes after a couple of seconds on some machines. I don't know why yet - possibly because there isn't even a software ICD, or if there is, its not doing something right.


ImaginaryHuman(Posted 2006) [#5]
Framerate isn't a reliable indicator. Depends on what you're doing as to what the framerate is in software.

How about this.

Test the drawing speed of DrawImage versus DrawPixmap. Chances are that if DrawImage is about the same speed (which it is with a software renderer), you have a software render.

Although, you'd have to get the screen open and stable to do the test. Maybe it'd run long enough to test a couple of draws.

I think BRL should provide a command that lets you query the driver to at least maybe get some reliable info such as hardware acceleration, etc

You could maybe query the glString() and then make some assumptions based on the graphics card it reports - ie if there's not enough video ram on that card or that card doesn't have enough features to provide decent hardware acceleration etc. Bit of a task though and maybe not reliable.


ImaginaryHuman(Posted 2006) [#6]
Does it still crash if you wrap the Graphics/CreateGraphics/GLGraphics/SetGraphics calls in a Try-catch block?

Try
gra=CreateGraphics(wid,hig,dep,htz,flags)
if not gra then myerror()
setgraphics gra
Catch a$
myerror()
EndTry


Robert Cummings(Posted 2006) [#7]
I think I'm going to have to do a try and catch with a benchmark. I hate benchmarks though as they are totally unreliable. Older the machine, the more chance of it suddenly hiccuping. In fact some hiccup a lot :)

BRL, can you help too?


JoeRetro(Posted 2006) [#8]
Another possible alternative is to use SDL to determine if the supplied graphics mode is available in hardware acceleration -

SDL_VideoModeOK(width,height,bpp,flags)

OR SDL_HWSURFACE to the flags parameter to check for an accelerated video mode.


FlameDuck(Posted 2006) [#9]
Couldn't you use glGetString in conjunction with GL_VENDOR and GL_RENDERER?


Robert Cummings(Posted 2006) [#10]
I believe this is what noel cower suggested. Here is the code he put down:

SuperStrict
Framework Pub.OpenGL
Import Brl.StandardIO
Import Brl.GLGraphics
Try
GLGraphics( 320, 240, 0 )
Print String.FromCString(glGetString( GL_RENDERER ))
Print String.FromCString(glGetString( GL_VENDOR ))
Print String.FromCString(glGetString( GL_VERSION ))
Print String.FromCString(glGetString( GL_EXTENSIONS ))
Catch o:Object
Print o.ToString( )
End Try
End


Problem is, we have to open an opengl window, but if that fails there is always try and catch.


JoeRetro(Posted 2006) [#11]
I don't believe glGetString will provide enough information to conclude that your in software mode or at least I did not see anything returned to answer your question.


Robert Cummings(Posted 2006) [#12]
so absolutely nothing returned in the debugger output window? did you check?


JoeRetro(Posted 2006) [#13]
Yes, I did check and yes I do get some information but nothing to tell me that I'm using OpenGL Software or Hardware. Did you check?


Robert Cummings(Posted 2006) [#14]
Yes of course - I'm looking for the words generic, microsoft and gdi. You won't get these unless you go to the troubleshooting tab and disable all acceleration.


JoeRetro(Posted 2006) [#15]
Well, for whats it's worth...Based on Noel's code I get the following ouput when hardware acceleration is turned off:

Building untitled1
Compiling:untitled1.bmx
flat assembler  version 1.64
3 passes, 2259 bytes.
Linking:untitled1.debug.exe
Executing:untitled1.debug.exe
GDI Generic
Microsoft Corporation
1.1.0
GL_WIN_swap_hint GL_EXT_bgra GL_EXT_paletted_texture

Process complete


Geforce 6600GT


Robert Cummings(Posted 2006) [#16]
Are you able to play hardware accelerated opengl games?


JoeRetro(Posted 2006) [#17]
yup, I can and do and 4 of my screensavers I have written use OpenGL and run very smoothly on my system.


Robert Cummings(Posted 2006) [#18]
But not when you disable hw acceleration on the troubleshooting tab :)


JoeRetro(Posted 2006) [#19]
Well, yes, of course..Whats your point? My point is that your code (or Noels) above does not provide any information about using Software only or hardware acceleration.


Robert Cummings(Posted 2006) [#20]
Oh I see what you mean. There is one way but I am not sure how to do this in Blitzmax. Please take a look at this link from the OpenGL FAQ:

5.040 How do I know my program is using hardware acceleration on a Wintel card? I would really appreciate your thoughts on it, specifically this part:

If you are using the Win32 interface (as opposed to GLUT), call DescribePixelFormat() and check the returned dwFlags bitfield. If PFD_GENERIC_ACCELERATED is clear and PFD_GENERIC_FORMAT is set, then the pixel format is only supported by the generic implementation. Hardware acceleration is not possible for this format. For hardware acceleration, you need to choose a different format.



JoeRetro(Posted 2006) [#21]
After running a few tests I think that FAQ needs to be updated. Reading up on DescribePixelFormat and the PIXELFORMATDESCRIPTOR structure via MSDN you actually set the flags you want to use through this structure. Calling DescribePixelFormat will simply obtain information about the pixel format. So the flags returned via pfd.dwFlags will refer to the flags (ie. PFD_SUPPORT_OPENGL) you set when you initialize the struture. I don't think this will yield the results your after. I also do not have a computer system without a hardware accelerator card to test. Anyhow, here's some code I've written to test with:
Strict

?Win32
Extern "win32"
	Function GetPixelFormat:Int(hdc:Int)
	Function DescribePixelFormat:Int(hdc:Int, pixelformat:Int, nbytes:Int, pixelformatdata:Byte Ptr)
End Extern

Type PIXELFORMATDESCRIPTOR
	Field nSize:Int 
	Field nVersion:Int
	Field dwFlags:Int
	Field iPixelType:Byte 
	Field cColorBits:Byte 
	Field cRedBits:Byte 
	Field cRedShift:Byte 
	Field cGreenBits:Byte 
	Field cGreenShift:Byte 
	Field cBlueBits:Byte 
	Field cBlueShift:Byte 
	Field cAlphaBits:Byte 
	Field cAlphaShift:Byte 
	Field cAccumBits:Byte 
	Field cAccumRedBits:Byte 
	Field cAccumGreenBits:Byte 
	Field cAccumBlueBits:Byte 
	Field cAccumAlphaBits:Byte 
	Field cDepthBits:Byte 
	Field cStencilBits:Byte 
	Field cAuxBuffers:Byte 
	Field iLayerType:Byte 
	Field bReserved:Byte 
	Field dwLayerMask:Int
	Field dwVisibleMask:Int
	Field dwDamageMask:Int
End Type

Local pfd:PIXELFORMATDESCRIPTOR

pfd = New PIXELFORMATDESCRIPTOR
pfd.nSize = SizeOf(pfd)
pfd.nVersion = 1
pfd.dwFlags = PFD_SUPPORT_OPENGL

Local hdc:Int = GetDC(GetDesktopWindow())
Local iPixelFormat:Int = GetPixelFormat(hdc)

Local iMaxPixelFormatIndex = DescribePixelFormat(hdc, iPixelFormat, pfd.nSize, pfd); 

If (pfd.dwFlags & PFD_GENERIC_FORMAT And pfd.dwFlags ~ PFD_GENERIC_ACCELERATED)
    Print ("OpenGL not supported")
EndIf

Print hdc
Print iPixelFormat
Print iMaxPixelFormatIndex 
Print pfd.dwFlags
?
If glGetString(GL_VENDOR) returns something other than "Microsoft Corporation", it means you're using the board's ICD. If it returns "Microsoft Corporation", this implies you chose a pixel format that your device can't accelerate. However, glGetString(GL_VENDOR) also returns this if your device has an MCD instead of an ICD, which means you might still be hardware accelerated in this case.

The next paragraph of the FAQ may be the easiest way of checking for non-compliant OpenGL cards. I know it's not full-proof but it may be the best solution for now :>


N(Posted 2006) [#22]
I don't believe glGetString will provide enough information to conclude that your in software mode or at least I did not see anything returned to answer your question.


If glGetString(GL_VENDOR) returns something other than "Microsoft Corporation", it means you're using the board's ICD. If it returns "Microsoft Corporation", this implies you chose a pixel format that your device can't accelerate. However, glGetString(GL_VENDOR) also returns this if your device has an MCD instead of an ICD, which means you might still be hardware accelerated in this case.


The next paragraph of the FAQ may be the easiest way of checking for non-compliant OpenGL cards. I know it's not full-proof but it may be the best solution for now :>


Well, for whats it's worth...Based on Noel's code I get the following ouput when hardware acceleration is turned off:


Hey, I thought it was funny.


JoeRetro(Posted 2006) [#23]
yes, it is and my point was that it would be easier to use glString. However it will not get you the results you want. :>


Robert Cummings(Posted 2006) [#24]
Thank you Joe, you've been a great help. Brilliant stuff!