CloseGraphics bug with D3D9Max2DDriver
Archives Forums/BlitzMax Bug Reports/CloseGraphics bug with D3D9Max2DDriver
| ||
As far as I'm aware, there should be no functional difference between using Graphics() and CreateGraphics() but I get a crash if I handle graphics contexts myself with the D3D9 driver. I don't get the issue with the D3D7 or GL drivers, though I have had some issues with image corruption under GL unless I use GLShareContexts (even if I reload all the images after the new context is created). This code crashes: SuperStrict Local gfx:TGraphics Local pix:TPixmap = LoadPixmap("smile.jpg") Local img:TImage Local counter:Int = 0 SetGraphicsDriver(D3D9Max2DDriver()) gfx = CreateGraphics(640, 480, 0, 60, GRAPHICS_BACKBUFFER) SetGraphics(gfx) img = LoadImage(pix) EnablePolledInput() Repeat CloseGraphics(gfx) gfx = CreateGraphics(640, 480, 0, 60, GRAPHICS_BACKBUFFER) SetGraphics(gfx) img = LoadImage(pix) Cls DrawImage(img, 0, 0) DrawText(GCMemAlloced(), 0, 240) Flip counter = counter + 1 Print counter Until counter = 10000 But this code doesn't: SuperStrict Local pix:TPixmap = LoadPixmap("smile.jpg") Local img:TImage Local counter:Int = 0 SetGraphicsDriver(D3D9Max2DDriver()) Graphics(640, 480) img = LoadImage(pix) EnablePolledInput() Repeat EndGraphics() Graphics(640, 480) img = LoadImage(pix) Cls DrawImage(img, 0, 0) DrawText(GCMemAlloced(), 0, 240) Flip counter = counter + 1 Print counter Until counter = 10000 And neither does this: SuperStrict Local gfx:TGraphics Local pix:TPixmap = LoadPixmap("smile.jpg") Local img:TImage Local counter:Int = 0 SetGraphicsDriver(D3D9Max2DDriver()) gfx = CreateGraphics(640, 480, 0, 60, GRAPHICS_BACKBUFFER) SetGraphics(gfx) img = LoadImage(pix) EnablePolledInput() Repeat CloseGraphics(gfx) SetGraphicsDriver(D3D9Max2DDriver()) gfx = CreateGraphics(640, 480, 0, 60, GRAPHICS_BACKBUFFER) SetGraphics(gfx) img = LoadImage(pix) Cls DrawImage(img, 0, 0) DrawText(GCMemAlloced(), 0, 240) Flip counter = counter + 1 Print counter Until counter = 10000 You shouldn't have to re-set the driver for a new context, right? |
| ||
I've noticed this happens with OpenGL on Windows too - but not in Linux or Mac. This was with using the maxgui demo with Openb3d (or Minib3d), where SetGraphicsDriver was required before CreateCanvas or you got a black screen. |
| ||
Hiya, In Max2d.bmx -> TMax2DGraphics -> Close try BumpGraphicsSeq as the last statement before the EndMethod. Then rebuild the modules. Would need some good wide spread testing before committing as a permanent fix. Reason for the D3D9 crash in dan_uprights' examples is that the default_font TImageFrame(s) are holding onto D3D texture pointers that were created before the CloseGraphics. Then when you want to DrawText after a new CreateGraphics, Max2D is using those old textures pointers but with a new underlying hardware IDirect3DDevice9 instance. @Munch On Windows Max2D defaults to using a D3D9 driver. On Linux and Mac D3D9 doesnt exist so will default to the OpenGL driver. I believe MiniB3D is OpenGL only hence why you need to set the driver to OpenGL before seeing anything. |
| ||
Awesome! Thanks Dave. |
| ||
Nice one Dave, that seems to do the trick for me. Can I ask why the BumpGraphicsSeq goes in that specific method and not in CloseGraphics itself (in brl.graphics)? EndGraphics performs an inline BumpGraphicsSeq but CloseGraphics doesn't, so it seems like there should be parity there, no? I'm not trying to nitpick, I'd just like to learn so I can have a stab at fixing stuff myself in future. |
| ||
Hey dan_upright, The graphics drivers have had a fair few number of bug fixes over the years ( especially the D3D9 one ) and I'd imagine there are possible remnants of fixes that could do with tidying. BRL seems to be just about holding onto maintenance fixes at the mo so I highly doubt this kind of work would get a look-in. The Max2D graphics systems isn't too complicated once you learn how its all put together. If you want to learn it feel free to pull it apart to see how it works :-) |
| ||
The one feature I want more than anything else is to get a borderless fullscreen window without using MaxGUI and a canvas. I had a stab at it the other day but I just blew everything up and it wouldn't have worked on linux/mac anyway. I really need to get a linux install going again. |
| ||
The actual window is created in TD3D9Graphics->Create for D3D, so I'd imagine it the same for OpenGl but in the bbGLGraphicsCreateGraphics function in glgraphics.linux.c/glgraphics.win32.c/glgraphics.macos.m. EDIT: I had a quick glance and I might be wrong? I suppose you could utilize the flags parameter to modify the window creation style. A very quick D3D9 example that would need testing some more... In graphics.bmx add this with the other similar definitions around lines 43 to 47 Const GRAPHICS_BORDERLESS = $40 In d3d9graphics.bmx :: TD3D9Graphics->Create modify the top couple of lines to Local wstyle If depth wstyle=WS_VISIBLE|WS_POPUP Else If flags & GRAPHICS_BORDERLESS wstyle = WS_VISIBLE|WS_POPUP Else wstyle=WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX EndIf EndIf Then you can use Graphics 800,600,,,GRAPHICS_BORDERLESS to get a borderless D3D9 window. This is just a quick hack up for an example for you and the flags parameter doesn't feel the right place for it. I mean if you were to allow changes to the window style then you may as well allow for various types of border/system icons as well. This would then be better with its own flag for window style creation variations, and leave the original flag as it is for a 'hardware graphics' setting flag. |
| ||
I got borderless windows working for all 3 drivers (under win32 at least), thanks for pointing me in the right direction mate. |