Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Antialiasing Support (GraphicsDevice.PreferMultiSampling) #358

Open
ghost opened this issue Mar 6, 2012 · 44 comments
Open

Antialiasing Support (GraphicsDevice.PreferMultiSampling) #358

ghost opened this issue Mar 6, 2012 · 44 comments
Assignees
Labels
DirectX DirectX graphics backend Help Wanted OpenGL OpenGL graphics backend
Milestone

Comments

@ghost
Copy link

ghost commented Mar 6, 2012

All platforms need to have antialiasing (re-?)enabled. Pointers here and here.

@ghost ghost self-assigned this Mar 6, 2012
@CartBlanche
Copy link
Contributor

I'm not sure our implementation of iOS ever had AA enabled. If it did I think it might have been by accident rather than design. It is very nice to have if the GPU does it for free, and we just need to flip some switches.

I don't know how the other team members feel about this, but I would suggest pushing this back to 3.0 release.

Other AA implementations to thinks about are..
FXAA - http://www.codinghorror.com/blog/2011/12/fast-approximate-anti-aliasing-fxaa.html
SMAA - http://www.iryoku.com/smaa/ and http://mrhaandi.blogspot.com/p/injectsmaa.html

But they would be CPU bound atm. But I always thought maybe this can be an option to toggle on if you are on desktop, perhaps, if we can find an elegant way to do it.

@ghost
Copy link
Author

ghost commented Mar 7, 2012

Agreed. 3.0 it is.

As for the toggle to enable/disable AA, is a different solution from GraphicsDeviceManager.PreferMultisampling needed?

@CartBlanche
Copy link
Contributor

I totally forgot about that option :S

@dellis1972
Copy link
Contributor

I think we might need to bump this to post 3.0

@totallyevil
Copy link
Contributor

I posted a bug report about this way back in June I think. @tomspilman responded to it and was looking at it I think. The platform GPUs have their own custom full screen AA that you can enable. nVidia's is CSAA, PowerVR is likely some other thing. You should definitely NOT implement a software version of this as it would perform poorly.

@tomspilman
Copy link
Member

You should definitely NOT implement a software version
of this as it would perform poorly.

That has been suggested and i agree MonoGame should never include shader based AA.

Still i see the point of this ticket is to enable the standard MSAA that is implemented in hardware on most GPUs. That is something that should be rather simple... 5 to 10 lines of code for DX11.

@tomspilman
Copy link
Member

Moved it to the 3.x milestone.

@KonajuGames
Copy link
Contributor

In my investigations yesterday (where I discovered BGR565 is not supported
as a back buffer format in Windows 8), I also found that MSAA is not
supported in Windows 8 due to the flip-model swap chain.
http://msdn.microsoft.com/en-us/library/windows/desktop/hh404528(v=vs.85).aspx

@tomspilman
Copy link
Member

I also found that MSAA is not supported in Windows 8
due to the flip-model swap chain.

Lame. I guess that sort of makes sense... the OS probably does special stuff with it that we're not aware of.

Well... one less platform to worry about then. Win8 users will need to use one of the other shader based AA techniques.

@tomspilman
Copy link
Member

Note that this is the same with Windows Phone 8 at this time. You cannot use MSAA.

@mattwhitfield
Copy link

Hi. I'm writing an XNA game for WP7/WP8/Win8 - and I found this which was published last month - http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj681697(v=vs.105).aspx - basically explaining how you can use MSAA in WP8 by setting up a render target that has MSAA specified. I'd be willing to have a go at implementing that if someone were able to give me a couple of small pointers as to where in the code base would be the best fit...

@tomspilman
Copy link
Member

@mattwhitfield

In theory you should be able to create a RenderTarget2D passing it a multisample count greater than 1 and it should work. I can't say I've ever tried it, but I did hook up the code to create MSAA targets.

If that doesn't work I suggest you start a new issue here and lets investigate.

@mattwhitfield
Copy link

Ok, so I tried it out.

I created a RenderTarget2D (in my game code) with a multisample count of 8, then drew that to the screen with a SpriteBatch. I validated the approach in my Win32 build (by setting the back buffer multisampling off) and the result was as you'd expect - multi-sampled goodness.

I had a dig around and found that the Texture2D constructor was always setting SampleDescription to {1, 0} - so I added a parameter to the internal constructor to pass down the preferredMultiSampleCount from the RenderTarget2D constructor, and set up the sample description exactly as it is for the depth buffer in RenderTarget2D (preferredMultiSampleCount, SharpDX.Direct3D11.StandardMultisampleQualityLevels.StandardMultisamplePattern).

Now on WP8 that blew up - I couldn't find any combination of values for the SampleDescription that didn't result in a SharpDXException with 'The parameter is incorrect'.

On W8 Metro it created the texture & render target just fine. However, it still wasn't multi-sampled. Using the debugger to look at the 'Description' member of the _texture object for the suggested that the sample description was correct {8,-1}.

So - given that, do you want me to go ahead and create a new issue about MSAA on render targets?

Edit -> sorry, forgot to mention - the RenderTarget2D I used had a DepthFormat of None - just to avoid confusion.

@tomspilman
Copy link
Member

do you want me to go ahead and create a new issue about MSAA on render targets?

Yes... lets move this to an issue specific to it.

@mattwhitfield
Copy link

I did a bit of further work on this and got it working in Win8, at least. This is the commit: duncangrist@0f7540a

I have no idea if that fits in with the 'right way', or even if there is such a thing?

@ghost
Copy link
Author

ghost commented Jan 9, 2013

Confirming that your change worked on Win8 but not WinRT (Surface RT).

@mattwhitfield
Copy link

@alexyakobovich Not sure if you saw - I made a further commit last night because my friend noticed the same. I don't have one so wasn't able to verify the fix and he wasn't available. That commit is here: duncangrist@74e149f

I will be looking at it further on Thursday evening, and hopefully persuading some sort of AA to work on Surface RT - because the Tegra 3 doesn't support MSAA, but supposedly does support NVidia's own CSAA.

@ghost
Copy link
Author

ghost commented Feb 20, 2013

Did anyone touch this since the last post?

@tomspilman
Copy link
Member

Not I.

@mattwhitfield
Copy link

I did fix up the code in that branch a bit, so it's at a point where I'm happy with it. I couldn't find any combination of parameters that would persuade AA to work on Surface RT, unfortunately.

However, I can't submit a pull request because I look at framework sources all the time - which forbids me from submitting pull requests. If I've misunderstood the rules, let me know and I will have a go.

@tomspilman
Copy link
Member

I suspect the trick for getting Win8 to give you a AA surface isn't XNA specific in any way. Can you just tell us here what that one or two lines of code is?

@mattwhitfield
Copy link

All I did was follow the article I mentioned above: http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj681697(v=vs.105).aspx

And that works fine for Win8 - I just couldn't find any combination of values for the SampleDesc that resulted in an AA surface on Surface RT. However, it's pretty simple to make it degrade gracefully - you just call CheckMultisampleQualityLevels with a decreasing multi-sample count until pNumQualityLevels is > 0. Under SharpDX, that value is returned from CheckMultisampleQualityLevels.

@tomspilman
Copy link
Member

@mattwhitfield

That makes sense.

To be clear when you say Win8 do you mean "Windows Store App" or do you mean "Windows 8 Desktop"?

@mattwhitfield
Copy link

I mean Windows Store App. Our game uses what I wrote, runs happily as a Windows Store App on both Win8 and Surface RT - you just don't get any AA on Surface RT.

@tomspilman
Copy link
Member

Thanks. So another reason to support offscreen render targets to deal with orientation on WP8. I don't think they could have made things more complex if they tried.

@mattwhitfield
Copy link

Agreed.

I'd be very happy to help with the WP8 orientation testing, I have a device and a build that targets WP8 so please do call on me if you need assistance.

@tomspilman tomspilman modified the milestones: 3.6 Release, 3.x Release Mar 16, 2016
@aienabled
Copy link
Contributor

I'm using DirectX11 and changing GraphicsDevice.PresentationParameters.MultiSampleCount during runtime has no effect (Apply() is called).
However, if I set this in MonoGame source code (method GraphicsDeviceManager.Initialize()) before creating the graphics device, it works fine.
So the issue is only with applying the multi-sampling after initialization.

@GuiAmPm
Copy link

GuiAmPm commented Jun 25, 2016

I'm using DirectX11 too,
But changing it during Game.Initialize() with
GraphicsDevice.PresentationParameters.MultiSampleCount = 8;
GraphicsDeviceManager.Apply();
causes nothing to be rendered.

Any value other than 1 causes this to happen.

@Noemata
Copy link

Noemata commented Oct 28, 2016

Latest build still has this issue.

@tomspilman tomspilman modified the milestones: 3.6 Release, 3.7 Release Mar 9, 2017
@SeriousMartin
Copy link
Contributor

This problem still persists with the current version (dd2e6cb with #5477 merged). Any idea what could cause this?

@Jure-BB
Copy link
Contributor

Jure-BB commented Mar 23, 2017

@SeriousMartin On what platform and are you using render targets? #5477 fixes only one small part of AA issues.

@Jjagg
Copy link
Contributor

Jjagg commented Mar 23, 2017

@SeriousMartin You mean for a DirectX project? If so can you check the value of MaxMultiSampleCount in GraphicsDevice.GraphicsCapabilities for your GraphicsDevice using a debugger. Are you setting GraphicsDeviceManager.PreferMultiSampling = true (either in your constructor or by calling ApplyChanges afterwards) or using the OnPreparingDeviceSettings event? Note that the method mentioned above that directly changes GraphicsDevice.PresentationParameters.MultiSampleCount does not and should not work.
The three correct ways for modifying multisample count - and PresentationParameters in general - are the following:

  • Setting GraphicsDeviceManager.PreferMultiSampling will set multisample count to the maximum supported by the GPU
  • Subscribing to the GraphicsDeviceManager.PreparingDeviceSettings event and modifying the PresentationParameters.MultiSampleCount on the event args will set the ms count to the minimum of that value and what's supported by the device.
  • To modify PresentationParameters of a GraphicsDevice, first prepare a PresentationParameters instance with whatever MultiSampleCount you want, then call GraphicsDevice.Reset(PresentationParameters) with that instance. This will have the same effect as the previous option.

All three of these should work for DirectX (there's some issues with the last two options for DesktopGL because the GameWindow needs to be recreated), if they don't something is borken™.

@Jjagg
Copy link
Contributor

Jjagg commented Mar 23, 2017

On what platform and are you using render targets

This issue is about multisampling on the back buffer, there's separate issues for RenderTargets.

@SeriousMartin
Copy link
Contributor

SeriousMartin commented Mar 23, 2017

Yes, DirectX. What I'm trying to do is to activate/deactivate multi sampling during runtime.

I have create a new MonoGame project rendering only a sprite onto the screen.
Then I added the following code to the Update method:

        if (Keyboard.GetState().IsKeyDown(Keys.M) && !graphics.PreferMultiSampling)
        {
            graphics.PreferMultiSampling = true;
            graphics.ApplyChanges();
        }
        if (Keyboard.GetState().IsKeyDown(Keys.N) && graphics.PreferMultiSampling)
        {
            graphics.PreferMultiSampling = false;
            graphics.ApplyChanges();
        }

The game starts with multi sampling deactivated. When I press M once the sprite is no longer visible. When I press N it's visible again.

If I start the game with multi sampling activated it's vice versa.

I'd expect this to work. Did I get something wrong?

@Jjagg
Copy link
Contributor

Jjagg commented Mar 23, 2017

Did I get something wrong?

No, that should work. This is still bugged then...

@Jure-BB
Copy link
Contributor

Jure-BB commented Mar 23, 2017

@SeriousMartin Would you mind uploading that sample somewhere?

@SeriousMartin
Copy link
Contributor

@zigzag312 https://www.dropbox.com/s/yzlbem61wtp09rn/Game1.zip?dl=0
It's a visual studio 2015 solution

@Jure-BB
Copy link
Contributor

Jure-BB commented Mar 24, 2017

@SeriousMartin Thanks for the sample. I have found source of your problem.
This bug only happens when changing multisampling mid-game.

In GraphicsDevice.DirectX.cs -> CreateSizeDependentResources() _swapChain is only resized if it already exists, but depth buffer is always created form scratch. This results in mismatch between swap chain and depth buffer, because SampleDescription is not correctly updated for swap chain. End result is that nothing is visible.

I'll create PR fix for this.

@tomspilman tomspilman modified the milestones: 3.7 Release, 3.8 Release Feb 20, 2018
@harry-cpp harry-cpp modified the milestones: 3.8 Release, 3.9 Release Jun 14, 2020
alxwest pushed a commit to alxwest/MonoGame that referenced this issue May 3, 2024
* concrete Song .ctor

* Song FromUri(...)

* SongReader

* iOSPlatformInitialize
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DirectX DirectX graphics backend Help Wanted OpenGL OpenGL graphics backend
Projects
None yet
Development

No branches or pull requests