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

Multisampling not working for RenderTarget2D #1162

Open
mattwhitfield opened this issue Jan 7, 2013 · 17 comments
Open

Multisampling not working for RenderTarget2D #1162

mattwhitfield opened this issue Jan 7, 2013 · 17 comments
Labels
OpenGL OpenGL graphics backend

Comments

@mattwhitfield
Copy link

It appears that multisampling is not working when specifying a sample count > 1 on a RenderTarget2D. The expected behaviour is for anything drawn to the render target to be anti-aliased using MSAA, the resolved sample count and the standard multi-sample pattern. Note that the standard XNA behaviour for the resolved sample count may not be equal to the preferred sample count passed into the RenderTarget2D constructor depending on device support - you can specify 16 on a card that only supports 8 and you should receive an 8x MSAA render target.

I have tried this using the Windows Phone 8 and Metro builds.

Some more information from my comment on #358:

I created a RenderTarget2D (in my game code) with a multisample count of 8, surface format of Color and DepthFormat of None, 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 Windows Phone 8 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 Windows 8 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}.

Please note that this MSDN article (http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj681697(v=vs.105).aspx) suggests that it should be possible for Windows Phone 8, at least.

@KonajuGames
Copy link
Contributor

Would this have anything to do with MSAA not being available for use in the
Windows 8 swapchain?

@mattwhitfield
Copy link
Author

The MSDN article discusses the fact that MSAA is not available in the swapchain - but states that the limitation does not apply to Render Targets. It does apply to Windows Phone 8 - but does imply that the situation is the same for Windows 8 (first paragraph). Unfortunately I was unable to persuade an MSAA Render Target to be created on Windows Phone 8 - I only spent 4-5 hours trying to debug it, and in that time I wasn't really able to get a handle on exactly what mapped to where in SharpDX.

@mattwhitfield
Copy link
Author

Some further info, if you remove SharpDX.Direct3D11.BindFlags.ShaderResource from the BindFlags of the Texture2DDescription passed into new SharpDX.Direct3D11.Texture2D(), then you can give a multisample count to the render target in Windows Phone 8. However, you can't then use it as a standard texture - because it's not a shader resource any more (<- bit of a guess). So (further guess) you would need to use ResolveSubresource in order to copy the content of the MSAA render target into the back buffer, rather than drawing it in XNA client code using SpriteBatch. However, my knowledge runs out at this point. I'm sure given enough time I could work out how to replicate the code in the MSDN article within MonoGame and test it out - but I'd really appreciate it if someone could give me a bit of guidance so that I can try it, test it and report back...

@tomspilman
Copy link
Member

So (further guess) you would need to use ResolveSubresource in
order to copy the content of the MSAA render target into the back buffer

Yea... that sounds about right.

First problem is that there isn't an API in MS XNA to do that... we would have to invent one. Not a deal breaker... it is a feature that ideally we would support.

Second problem is figure out how this API maps to OpenGL platforms.

@mattwhitfield
Copy link
Author

I actually wanted to try putting the code into MonoGame's W8/WP8 builds and try it that way. Because to do it in the XNA client you would need to provide a RenderTarget2D that didn't set BindFlags.ShaderResource on the texture - which would seem to be a step away from XNA - without having an obvious benefit.

Like I said, I'm happy to try it i would just need a little guidance on how to achieve it. I figured if i got it working it would go some way to resolving #358, too.

-----Original Message-----
From: "Tom Spilman" notifications@github.com
Sent: ‎08/‎01/‎2013 01:21
To: "mono/MonoGame" MonoGame@noreply.github.com
Cc: "mattwhitfield" mattw@code9.net
Subject: Re: [MonoGame] Multisampling not working for RenderTarget2D (#1162)

So (further guess) you would need to use ResolveSubresource in
order to copy the content of the MSAA render target into the back buffer
Yea... that sounds about right.
First problem is that there isn't an API in MS XNA to do that... we would have to invent one. Not a deal breaker... it is a feature that ideally we would support.
Second problem is figure out how this API maps to OpenGL platforms.

Reply to this email directly or view it on GitHub.

@tomspilman
Copy link
Member

I am not suggesting you add the code to your client. We need to make an addition to MonoGame to allow you to "copy" a RenderTarget2D to the backbuffer.

I suggest start with something simple:

GraphicsDevice.CopyToBackbuffer(RenderTarget2D)

Just wrap it in a #if DIRECTX for now. I cannot tell you how to implement it more than that without implementing it myself.

@mattwhitfield
Copy link
Author

I could certainly write that, but it wouldn't seem right to me to do it that way, because you'd introduce the necessity for client code to understand that creating an MSAA render target would work differently and draw it in a different way. That could become more complicated if, for example, someone uses a SpriteBatch with a Matrix to draw the RenderTarget to their back buffer.

It might make sense to create the texture and an MSAA buffer within the render target, and then use ResolveSubresource in order to copy the MSAA buffer to the render target at the point that it becomes unbound through SetRenderTarget(null). I do know that would be compatible with the code that I write, but I don't know if it would be useful enough for other people to use? I will continue thinking about it. However, this is what I mean when I say I need guidance. I don't need help writing the code :) - just the top level approach in order to make it generally useful.

I did manage to make some headway on #358 - so probably the back-buffer use case becomes less important at this point.

@tomspilman
Copy link
Member

it wouldn't seem right to me to do it that way, because you'd introduce
the necessity for client code to understand that creating an MSAA render
target would work differently and draw it in a different way

There is a point at which it is better to make the user aware of the problem.

If it wasn't for the fact that this incurs a bunch of more memory use and the performance hit of making the copy I would be fine to hide it.

A similar issue exists for WP8 where there is no way to get a landscape render target... they are always in portrait. You cannot hack the projection transform in all cases as it highly depends on what the shader is doing. The only sure fire way is an offscreen render target with a rotated copy to the back buffer.

You can see why the XNA team went for a simple Reach vs. Hi-Def feature break down. Dealing with as many hardware and platform differences as we are is very difficult.

@mattwhitfield
Copy link
Author

Ha, you can say that again. I'm just looking at the CopyToBackBuffer approach now and I'm getting the clear purple screen when I copy the render target to the back buffer using:

    public void CopyToBackBuffer(RenderTarget2D renderTarget)
    {
        lock (_d3dContext)
        {
            using (var backBuffer = SharpDX.Direct3D11.Resource.FromSwapChain<SharpDX.Direct3D11.Texture2D>(_swapChain, 0))
            {
                _d3dContext.ResolveSubresource(renderTarget.Buffer, 0, backBuffer, 0, renderTarget.Format);
            }
        }
    }

Not wanting to get off-topic, but is there much appetite for a standard swap-chain implementation on WP8? That was something on my list of things to give a go to.

@tomspilman
Copy link
Member

is there much appetite for a standard swap-chain implementation on WP8

I have plans to implement SwapChains for MonoGame for all platforms in the next few weeks. We have a need to write a multi-monitor application on Windows which requires it. If you have ideas on how that would work and how it would fit into this issue i'd love to hear it.

@mattwhitfield
Copy link
Author

I will give it some thought. My use case was much simpler - porting to WP8 without using the XAML approach with it's interesting portrait limitation. So I guess that would be served by SwapChains still being internal to MonoGame.

But the reason it came to mind was because you mentioned the XAML thing, and I found it very easy to come up with a solution to #358 - because I knew where each operation was being done. In this context, I'm doing everything the same, as far as I can tell currently, and I'm getting nothing copied to the back buffer.

If the swap chain were public it would be a lot easier to integrate this sort of flow.

@tomspilman
Copy link
Member

I'm doing everything the same, as far as I can tell currently, and I'm getting nothing copied to the back buffer.

Yea. It has to be something simple like where you're calling CopyToBackBuffer() from.

@dsaf
Copy link

dsaf commented Jan 22, 2016

Is this more doable now?

@LMLB
Copy link

LMLB commented Jul 12, 2016

Any updates on this?

@Joooki
Copy link

Joooki commented Mar 24, 2017

Any updates on this???
Nobody wants Antialiasing?

@Jure-BB
Copy link
Contributor

Jure-BB commented Mar 24, 2017

There's PR #5538 that fixes this for DirectX.

@Jjagg Jjagg added the OpenGL OpenGL graphics backend label Dec 11, 2018
@damian-666

This comment was marked as abuse.

alxwest pushed a commit to alxwest/MonoGame that referenced this issue May 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
OpenGL OpenGL graphics backend
Projects
None yet
Development

No branches or pull requests

9 participants