D3D9 Virtual Resolutions

Archives Forums/BlitzMax Bug Reports/D3D9 Virtual Resolutions

col(Posted 2011) [#1]
Hiya

During the initialising phases of using virtual resolutions in d3d9, the values internally passed into the SetViewport sometimes get incorrect values if the virtual resolution is larger than the viewport. This problem only shows under certain conditions, like if windowed and Flip 1 is used, or in fullscreen and Flip is used without parameters.

[EDIT] :- An example showing the problem

[/EDIT]

Its easily solved by the coder putting in an extra SetViewport after SetVirtualResolution to correct the issue, but the real problem can be fixed by modifying the SetViewport function at Line 641 in brl.mod/max2d.mod/max2d.bmx to this:-


Use the fix a couple of posts down.....


Last edited 2011


therevills(Posted 2011) [#2]
Hi Dave - is this the same issue:

http://www.blitzbasic.com/Community/posts.php?topic=93081

?


col(Posted 2011) [#3]
Hi therevills,

It looks like it is the same issue.
Its requires a specific scenario for it to show up - probably why its not been resolved!

It seems easier to reproduce on D3D9 as the the internal validation checks get checked twice upon certain conditions during the first 4-5 frames of initialising. Because of this second check, its where the error is creeping in. If you do something in D3D7 or GL to cause the same scenario of checks then it show up in those drivers too, but the second checks are rarely needed.

A little techie run down of whats happening...

Using the example above ( specifically D3D9 ):-

1. Graphics 800,600 - This sets up the window and display to use 800x600
2. SetVirtualResolution - This setups up the internal virtual resolution variables using a scaling factor and sets the projection matrix according to the virtual width and height (1024x768).
3. Flip 1 - Calls the D3D9 Present to flip the display ( hence the momentary flash of it working correctly )
4. Because of the Flip 1 parameter ( the SYNC parameter ) is different from how the device was initialised, it need to change the graphicss card sync parameter internally for D3D9. Which means it needs to reset the device.
5. Internally the device is reset with no problems. After all, it is needed :-)
6. After some more bits and pieces of keeping the D3D9Max2D code together, it then drops into some validation code.
7. During the validation process SetVirtualResolution ( with 1024x768 ) updates the Dx projection matrix, and SetViewport are called to keep things in check.
8. But during this SetViewport call it uses internal parameters that are still tied to the 800x600.
9. Now inside the SetViewport code it uses a division to get the correct viewport size to send to the graphics card. It assumes the virtual resolution is LOWER than the true screen resolution ( the viewport resolution ). This is where its hiccuping. Maybe somewhere along the lines this 800x600 should actually be 1024x768, maybe this ( or Step 8 ) is another place the code be altered to fix the problem? I haven't tried this, but it seems risky to alter it at step 8?

Anyway whats happening is the 800x600 gets divided by the virtual resolution scalings ( which are:- 1024 / 800 = 1.28, 768 / 600 = 1.28 ) causing the viewport of ( 800 / 1.28 = 625, and 600/1.28 = 468.75 ) 625x468.75

Remember the real screen is still 800x600, but now we have a viewport of 625x468.75. Because the projection matrix is set to the virtual resolution of 1024x768, this makes it look like you have an 800x600 window on the 1024x768 screen.

Altering the Max2D SetViewport ( as opposed to the D3D7,D3D9 or GL SetViewport ) code 'should' rule out any problems with all virtual resolution combinations in all drivers.


col(Posted 2011) [#4]
Hey,

You know, after looking at what I just wrote and checking through the code as I was writing it...

My pervious fix was actually making the viewport larger than the screen!. To be honest it will still work ok, but it kind of reverses the effect of being too small and makes it bigger! I've removed it to save any confusions.

Not a major blunder but still... I'm glad you queried it as I wouldn't have checked this out again!

This one is the correct fix:-

brl/max2d.mod/max2d.bmx at Line 149

Change

SetViewport viewport_x,viewport_y,viewport_w,viewport_h

to

SetViewport viewport_x,viewport_y,vres_width,vres_height


This 'should' resolve all issues, but because the viewport is tied in to other functions and features would you mind testing this?? I don't have any game code that uses the viewport and virtual resolutions to extensively test it myself.

Last edited 2011


therevills(Posted 2011) [#5]
Just been testing your fix Dave and it works fine...

Just a couple of quick qs:

If I am reading the code correctly in max2d.TMax2DGraphics.Validate max2d uses a viewport and virtual resolution everytime a graphics object is created?

Where does max2d.TMax2DGraphics.MakeCurrent (which calls Validate) get called?


col(Posted 2011) [#6]
Thanks for testing it. Thats the fix that I thought would be a bit risky!
Glad its working ok.

MakeCurrent is called in all drivers from SetGraphics, although the D3D9 and D3D7 drivers call it from Flip if needed. D3D7 just calls Validate directly from the Flip.


therevills(Posted 2011) [#7]
Thanks Dave... I did a search on the source code and I couldnt find it... strange... Ah I had a file filter on - doh!


therevills(Posted 2011) [#8]
Just found an issue with Dave's fix, when the developer is setting a viewport themselves it doesnt work.

I've been adding aspect ratio stuff to my game, so I am setting the virtual resolution, then setting the viewport (to take into account the ratio) and then setting the origin. With Dave's fix, the right hand side and the bottom was not set to the viewport I set.

Last edited 2011


col(Posted 2011) [#9]
Hiya,
I thought something would show up eventually.
Would you mind posting a source?

Cheers


therevills(Posted 2011) [#10]
Heres a code sample:



I believe the issue is with the vsync flip (as it took me ages to reproduce this, and it only happens with Flip 1).

Last edited 2011


col(Posted 2011) [#11]
Yep.
The default for the Flip parameter is -1, so changing it to 1 runs a little code path that resets the Max2D settings, as explained in #3. Something silly is not quite right in there.

Cheers for the test case. I'll take another look when I get home from work and see if I can come up with something, If not, then its one for Mark or just set the Viewport manually when using the D3D9 driver :-)