DXERROR err=SURFACELOST

BlitzMax Forums/BlitzMax Programming/DXERROR err=SURFACELOST

Grey Alien(Posted 2011) [#1]
Firstly, sorry I if missed something in the past year or so about this issue, but I tried searching and couldn't find anything conclusive.

Basically, when I first made my framework I was sure that I made it so that full-screen games could alt+tab and withstand control+alt+del without crashing or coming back to a blank screen. But now my games crash when I restore them after minimizing them. Specifically they crash with DXERROR err=SURFACELOST in the BlitzMax console.

Note that my games use DX7 and the crash can be duplicated by running the following code and alt+tabbing out/in. If you comment out the line that sets the driver, it works fine!

SetGraphicsDriver D3D7Max2DDriver()
Graphics 800,600,32

Local counter:Int=0

While Not KeyHit(key_escape)
	Cls
	DrawText counter,0,0
	counter:+1
	Flip 1
Wend


The plot thickens, because I went back and tested some of my old compiles from around the time I was sure I had this working, and they don't crash when you restore them BUT I do see a black screen. They haven't frozen because I can hear mouse over sounds and keys work. Since I wrote those old builds I have changed my video card so I don't know if that is having an effect for some reason. I could swear this stuff used to work fine. Am I going mad?

Portals won't accept a game that fails alt+tab, so it may be I have to convert over to DX9, but what happened to DX7? (or perhaps it's my video card which is an NVidia Geforce GTX 275)

If you can test the code above and tell me if it works/crashes on your machine that would be great thanks!

Does anyone have any further information about this? Many thanks in advance!

[edit]I'm running BMax 1.41 on DX 9.0c on XP SP3.

Last edited 2011


BladeRunner(Posted 2011) [#2]
Works fine here, without any crash.
GF 9700GTM, BMax 1.37 (oops, I should run a update.)


Grey Alien(Posted 2011) [#3]
Interesting. Well if it still works after the update then it's my video card. Perhaps it's just not built for DX7 support. I wonder how many other cards have the issue and if we should be looking to support them with a tweak to the BMax DX7 code?

Last edited 2011


therevills(Posted 2011) [#4]
Works fine on my machine (specs in my sig)...

Also Pirate Solitaire uses GAF v1.11 (which uses DX7 driver) and BlitzMax v1.41 - and Im sure BFG would have picked up something in their testing...

Last edited 2011


Grey Alien(Posted 2011) [#5]
Thanks. It must be my video card then. So I guess the question is, what % of modern cards does it crash on?

Can anyone else test?


Matthew Smith(Posted 2011) [#6]
Jake,

Works fine on both my laptop and desktop - see sigs for info.

Oh - latest version of BlitzMax.

Last edited 2011


GfK(Posted 2011) [#7]
Works fine on my laptop - Intel GMA965, 2GB RAM, Windows 7, DX11.

BTW: I have an 8500GT I can test on but I'm going out for a while now - will give it a go when I get back.

Last edited 2011


Czar Flavius(Posted 2011) [#8]
Unless you have a big limitation, offer users a choice of driver and in your readme/troubleshoot explain it is a fix.


GfK(Posted 2011) [#9]
offer users a choice of driver and in your readme/troubleshoot explain it is a fix.
In casual games, advanced options like that are a big no-no.

just checked on my 8500GT (Windows 7, DX11, 2GB RAM) - works fine.

[edit] Oh yeah - I'm using Blitzmax 1.41.

Last edited 2011


HrdNutz(Posted 2011) [#10]
Reloading the graphics from file or pixmaps should refresh the device textures, not sure how to reload the built-in image font.

Alternatively, calling Graphics() and recreating the window should force an internal texture refresh. As far as I know, bmax keeps parallel pixmaps to all the TImage data.

I haven't personally tried this, just speculating.


SLotman(Posted 2011) [#11]
No error here either on ATI X1300. But I didn't update blitzmax in ages :P~


Czar Flavius(Posted 2011) [#12]
In casual games, advanced options like that are a big no-no.

That's why you hide it, or dress it up as some kind of "safe mode" option or something. You don't need to include a book on it!


Grey Alien(Posted 2011) [#13]
Thanks for testing everyone. Hmm, well at least it's rare (only my PC), that's reassuring. Not sure how easy a fix is to be honest. May try recreating graphics.


Grey Alien(Posted 2012) [#14]
So I finally fixed this by testing if the driver is DX7 and the game is fullscreen and it is being returned to from an alt+tab (I'm testing for the game being unsuspended). All I do is call Graphics() again as per HrdNutz's suggestion and it works fine!

Probably wasn't worth adding this fix as most people will be using the DX9 driver (which is fine) but my framework falls back to DX7 if DX9 is not available and I didn't want it to crash on some graphics cards. It's possible some casual players may have similar setups as some of my games have over 1 Million demo downloads.


*(Posted 2012) [#15]
Tbh being in the casual game market means you have to support every conceivable version of dx from 7 and up. This being the case maybe posting the fix somewhere so others dont fall into the trap might help other blitzers.

Its a very good point tho and one that we will have to keep a very close eye on as to when driver manufacturers stop supporting legacy direct x versions seeing as its four revisions over 7 now?


Grey Alien(Posted 2012) [#16]
The fix is entwined quite deeply into my framework so isn't easy to extract and post. But basically you check for EVENT_APPRESUME and then you call Graphics again instead of doing nothing. You only do this when the BMax DX7 Driver is being used and the game is full-screen.


matibee(Posted 2012) [#17]
(with some help) I came up with this a couple of years ago...
http://www.blitzbasic.com/Community/posts.php?topic=88279#1002201

and added it to my framework as a separate module because of its depedency on MaxGUI (which at the time wasn't free).

As you'll see, it is calling endgraphics() graphics() when the user moves away from full screen. I can't recall if I got it to handle Alt+tabbing in and out in the same way tho.


therevills(Posted 2012) [#18]
Hey Jake, mind if you share your GAF change?

I guess its in Commontypes:

	Method DoPeekEvent()
		While PeekEvent()
...
			Case EVENT_APPRESUME
			  	SuspendedEvent = 0
			End Select
		Wend 	


So what do we do in EVENT_APPRESUME?


Grey Alien(Posted 2012) [#19]
Sure thing. It's in CheckWindow() after then main else:

			If Suspended = True
				'To avoid a hang on some graphics cards with DX7, we should recreate the graphics.
				If DriverDX7 And FullScreen Then
					GraphicsCreate()
				EndIf



Grey Alien(Posted 2012) [#20]
btw I also updated SetDXDriver to avoid it using DX9 before testing for it. You may not be using a ForceDX7 flag. I only really added that for testing and perhaps to set on older games if I don't want to update them to DX9 and add in custom cursor toggle etc.

	Method SetDXDriver(ForceDX7:Int)
		?Win32
		If ForceDX7 Then
			DriverDX7 = 1
			DriverDX9 = 0
			SetGraphicsDriver D3D7Max2DDriver()
		Else
			'Double check DX9 is available.
			If D3D9Max2DDriver()			
				DriverDX7 = 0
				DriverDX9 = 1
				SetGraphicsDriver D3D9Max2DDriver()
			Else
				DriverDX7 = 1
				DriverDX9 = 0
  				SetGraphicsDriver(D3D7Max2DDriver())
				'This may mean that DoSetVirtualResolution() fails due to DX7, but the small netbooks it is required on are all DX9 anyway.
			EndIf
		EndIf
		?
	End Method


Last edited 2012


Grey Alien(Posted 2012) [#21]
I also added in more direct versions based on a wikipedia article to ccGetDirectXVersion in PublicDomain.bmx. I basically realised there were some versions missing from the list and was worried it could mean the game would choose the wrong driver or something.

Function ccCheckDirectXVersionUpTo9$()
	Local strVersion:String = ""

	?win32
	Local hbank:TBank = CreateBank(4)
	RegOpenKey(HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\DirectX",BankBuf(hbank))
	Local hKey% = PeekInt(hbank,0)
	
	Local value_bank:TBank = CreateBank(100)
	Local value_bank_size:TBank = CreateBank(4)
	Local type_bank:TBank = CreateBank(4)
	
	PokeInt(type_bank,0,0)
	PokeInt(value_bank_size,0,100)
	   
	RegQueryValueEx(hKey,"Version",0,BankBuf(type_bank),BankBuf(value_bank),BankBuf(value_bank_size))
	
	Local dx_version:String = ""
	For Local char%=0 To PeekInt(value_bank_size,0)-1
		If PeekByte(value_bank,char)=0 Then Exit
		dx_version = dx_version + Chr(PeekByte(value_bank,char))
	Next
	
	RegCloseKey(hKey)
	
	Select dx_version
	    Case "4.02.0095"
	        strVersion = "1.0"
	    Case "4.03.00.1096"
	        strVersion = "2.0a"
	    Case "4.04.00.0068"
	        strVersion = "3.0"
	    Case "4.04.00.0069"
	        strVersion = "3.0"
	    Case "4.04.00.0070"
	        strVersion = "3.0a"
	    Case "4.05.00.0155"
	        strVersion = "5.0"
	    Case "4.05.01.1600"
	        strVersion = "5.0"
	    Case "4.05.01.1998"
	        strVersion = "5.2"
	    Case "4.06.02.0436"
	        strVersion = "6.1"
	    Case "4.06.03.0518"
	        strVersion = "6.1a"
	    Case "4.07.00.0700"
	        strVersion = "7.0"
	    Case "4.07.00.0716"
	        strVersion = "7.0a"
	    Case "4.07.01.3000"
	        strVersion = "7.1"
	    Case "4.08.00.0400"
	        strVersion = "8.0"
	    Case "4.08.01.0810"
	        strVersion = "8.1"
	    Case "4.08.01.0881"
	        strVersion = "8.1"
	    Case "4.08.01.0901"
	        strVersion = "8.1a"
	    Case "4.08.02.0134"
	        strVersion = "8.2"
	    Case "4.09.0000.0900"
	        strVersion = "9.0"
	    Case "4.09.00.0900"
	        strVersion = "9.0"
	    Case "4.09.0000.0901"
	        strVersion = "9.0a"
	    Case "4.09.00.0901"
	        strVersion = "9.0a"
	    Case "4.09.0000.0902"
	        strVersion = "9.0b"
	    Case "4.09.00.0902"
	        strVersion = "9.0b"
	    Case "4.09.00.0903"
	        strVersion = "9.0c"
	    Case "4.09.0000.0903"
	        strVersion = "9.0c"
	    Case "4.09.00.0904"
	        strVersion = "9.0c"
	    Case "4.09.0000.0904"
	        strVersion = "9.0c"
	End Select
	?
	
	Return strVersion
End Function


I also updated ccDirectXVersionIsValid() in CommonCode to take into account the updated GetDirectXVersion as follows (it only checks first digit now):

' -----------------------------------------------------------------------------
' ccDirectXVersionIsValid: Returns 1 if DirectX Version is >=7 (which is required for BlitzMax)
' -----------------------------------------------------------------------------
Function ccDirectXVersionIsValid%()
	Local v$ = ccGetDirectXVersion()
	v$ = ccFirstStringToSub(v$,".")
	Local valid%=1
	'There is no 4.0!
	If v$ = "1" Or v$="2" Or v$="3" Or v$="5" Or v$="6" Then 'There was no version 4.
		valid=0
	EndIf
	Return valid
End Function


Last edited 2012


Grey Alien(Posted 2012) [#22]
Plus I updated ccGetVersionString in publicdomain.bmx to take windows 8 into account (untested)

Function ccGetVersionString:String()
	Const VER_PLATFORM_WIN32s% = 0
	Const VER_PLATFORM_WIN32_WINDOWS% = 1
	Const VER_PLATFORM_WIN32_NT% = 2

	Local versionName:String

	?win32
	Local VersionInfo:TOSVersionInfoEx=New TOSVersionInfoEx
	VersionInfo.dwOSVersionInfoSize=SizeOf(VersionInfo)
	
	GetVersionExA(VersionInfo)
	Select versionInfo.dwPlatformID
		Case VER_PLATFORM_WIN32s; VersionName = "Win32s"
		Case VER_PLATFORM_WIN32_NT; VersionName = "Windows NT"
	         
		Select versionInfo.dwVerMajor
			Case 4; VersionName = "Windows NT"
			Case 5;
				Select versionInfo.dwVerMinor
					Case 0; VersionName = "Windows 2000"
					Case 1; VersionName = "Windows XP"
					Case 2; VersionName = "Windows XP" '64-bit, but returns just "Windows XP" to be compatible with TGame.Init()
				End Select
			Case 6;
				Select versionInfo.dwVerMinor
					Case 0; VersionName = "Windows Vista"
					Case 1; VersionName = "Windows 7"
					Case 2; VersionName = "Windows 8"
				End Select 
		End Select
	                  
		Case VER_PLATFORM_WIN32_WINDOWS
			Select versionInfo.dwVerMinor
				Case 0; VersionName = "Windows 95"
				Case 90; VersionName = "Windows ME"
				Case 10; VersionName = "Windows 98"
			End Select
	End Select
	?
	Return VersionName
End Function



therevills(Posted 2012) [#23]
Thanks a lot Jake :)

I'll be adding that lot to my version for sure!


Grey Alien(Posted 2012) [#24]
@therevills: just realised that ccDirectXVersionIsValid has a bug, change the v$ = mid(V$,1,1) to v$ = ccFirstStringToSub(v$,".")

So that it works for DX10+

Edited above post with fix.