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

Support for RenderTarget2D multisampling under DirectX. #5538

Merged
merged 24 commits into from Jun 27, 2017

Conversation

Jure-BB
Copy link
Contributor

@Jure-BB Jure-BB commented Mar 3, 2017

Added RenderTarget2D multisampling for DirectX. Code is based of this post.

Changes in first commit are

  • Multisampled resource is now created
  • Added RenderTarget2D field to RenderTarget2D class. It serves as non-multisampled destination for resolving multisampled RT.
  • Basic resolving logic

First commit is just to get it working with little consideration to performance. Resolving probably needs to be optimized (resolve only if needed).

This depends on #5477

@Jure-BB Jure-BB changed the title RenderTarget2D Multisampling [DirectX] RenderTarget2D Multisampling Mar 3, 2017
@Jure-BB
Copy link
Contributor Author

Jure-BB commented Mar 3, 2017

Is there any way of knowing if RT has been written to? So it could be marked as dirty and resolved only in that case.

Right now RTs are resolved when they are unset. It would be possible to improve performance in some cases if RT was resolved only when its data is used: when it is used as a source texture for drawing or on GetData. And of course only if its data has changed since last resolve.

Any thoughts on this?

@KonajuGames
Copy link
Contributor

Is there any way of knowing if RT has been written to? So it could be marked as dirty and resolved only in that case.

If a render target has been set, assume it is dirty. It will lose contents when being set anyway, unless RenderTargetUsage.PreserveContents has been used (do we even support flag properly?). If a developer sets and unsets a render target without drawing to it, that is a bad move on their part and the render target now has undefined contents.

@@ -27,33 +28,33 @@ public IntPtr GetSharedHandle()

internal abstract SharpDX.Direct3D11.Resource CreateTexture();

internal SharpDX.Direct3D11.Resource GetTexture()
internal virtual SharpDX.Direct3D11.Resource GetTexture()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method was made virtual, but I don't see anything that overrides it. We try to keep the use of virtual to a minimum because it takes longer to call a virtual than a regular method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its a leftover from debugging. I forgot to remove it.

@Jure-BB
Copy link
Contributor Author

Jure-BB commented Mar 3, 2017

If a render target has been set, assume it is dirty.

Then resolving logic is done too, I think.

do we even support flag properly?

Check here It seems OK to me.

@hach-que
Copy link
Contributor

Can this get merged? We have a need for multisampled render targets in Protogame because of how our render pipeline works.

I'm going to temporarily merge this changes into our patched version of MonoGame, but it'd be great to have this fixed properly upstream.

@hach-que
Copy link
Contributor

(I have a rebased version of this PR that no longer has merge conflicts if anyone is interested)

@Jure-BB
Copy link
Contributor Author

Jure-BB commented May 11, 2017

There are no known issues, so I think it can be merged. (I'll just rebase it)

@Jure-BB
Copy link
Contributor Author

Jure-BB commented May 11, 2017

Hmm does anyone have any idea why there is a change "Submodule Dependencies updated from 3aee60 to 979abf" under "Files Changed" tab? I didn't make any submodule dependencies changes for this PR.

@hach-que
Copy link
Contributor

I can confirm that this change works as intended. The way I rebased it was I hard reset to the RenderTarget2D_Multisampling branch (before that merge that just occurred), then soft reset to the parent on the develop parent so that it would only contain the branches changes. Then I committed it, and rebased that single commit, which gave me just the four files that were changed (rebasing the whole history turned out to be hard with lots of conflicts).

@KonajuGames
Copy link
Contributor

There has been no response to my code review comments re. GetShaderResourceView().

@KonajuGames
Copy link
Contributor

And unnecessary changing of field names.

@Jure-BB
Copy link
Contributor Author

Jure-BB commented May 13, 2017

@KonajuGames where can I see those review comments? I can only see comment about virtual GetTexture() method

@Jure-BB
Copy link
Contributor Author

Jure-BB commented May 13, 2017

And unnecessary changing of field names.

Some fields were renamed because they were changed from private to protected. Should I revert to old names with "_" prefix for protected fields?

@@ -35,25 +36,25 @@ internal SharpDX.Direct3D11.Resource GetTexture()
return _texture;
}

internal SharpDX.Direct3D11.ShaderResourceView GetShaderResourceView()
internal virtual SharpDX.Direct3D11.ShaderResourceView GetShaderResourceView()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than making this commonly used property a virtual, create a new virtual method for the allocation of the ShaderResourceView and override that method in the RenderTarget2D class. Then we only pay the cost of the virtual call when the ShaderResourceView needs to be allocated.

In Texture.DirectX.cs

internal SharpDX.Direct3D11.ShaderResourceView GetShaderResourceView()
{
    if (_resourceView != null)
        return _resourceView;
    return CreateShaderResourceView();
}

protected internal virtual SharpDX.Direct3D11.ShaderResourceView CreateShaderResourceView()
{
    _resourceView = new SharpDX.Direct3D11.ShaderResourceView(GraphicsDevice._d3dDevice, GetTexture());
    return _resourceView;
}

In RenderTarget2D.DirectX.cs

protected internal override SharpDX.Direct3D11.ShaderResourceView CreateShaderResourceView()
{
    if (MultiSampleCount <= 1)
        return base.CreateShaderResourceView();
    _resourceView = new SharpDX.Direct3D11.ShaderResourceView(GraphicsDevice._d3dDevice, _resolvedTexture.GetTexture());
    return _resourceView;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And please don't change the naming of existing fields. We have the leading underscore for a reason. See the coding standards.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The number of changes would be a far bit smaller if the naming was reverted back to what it was. A smaller PR is a lot easier to accept.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it OK if I do it like this, as I changed _resourceView back to private?

internal SharpDX.Direct3D11.ShaderResourceView GetShaderResourceView()
{
    if (_resourceView == null)
        _resourceView = CreateShaderResourceView();

    return _resourceView;
}

protected internal virtual SharpDX.Direct3D11.ShaderResourceView
    CreateShaderResourceView()
{
    return new SharpDX.Direct3D11.ShaderResourceView(GraphicsDevice._d3dDevice, GetTexture());
}


private SampleDescription _sampleDescription;
protected internal bool shared;
protected internal bool mipmap;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another unnecessary change of existing field names.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Microsoft's design guidelines don't actually allow public or protected instance fields, so they don't have a naming convention for them. Though R# likes to PascalCase them by default. That's what I always do too. I thought the most applied convention was to only prefix private fields with an underscore.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be fine with those fields staying private and with the underscore prefix (as they were before this PR), and a adding new protected PascalCase property used by derived classes that returns the private field.

@KonajuGames
Copy link
Contributor

KonajuGames commented May 13, 2017

Ahh, it appears I had to click another button to actually submit the review comments. Learning to use the new GitHub features.

Yes, those fields should remain named as they were.

@Jure-BB
Copy link
Contributor Author

Jure-BB commented May 13, 2017

OK, I see review comments now. I'll make the changes :)

@Jure-BB
Copy link
Contributor Author

Jure-BB commented May 14, 2017

Any ideas why Package Mac and Linux fails, as only changes made are to .DirectX.cs files?

@KonajuGames
Copy link
Contributor

KonajuGames commented May 14, 2017 via email

@Jure-BB
Copy link
Contributor Author

Jure-BB commented Jun 11, 2017

Resolved new merge conflicts. Added dispose call for _resolvedTexture.
Can this PR be merged, so I don't waste time resolving new conflicts?

@Jure-BB
Copy link
Contributor Author

Jure-BB commented Jun 22, 2017

I think I discovered a possible bug, so I'll need to test it before this PR is ready.

@Jure-BB
Copy link
Contributor Author

Jure-BB commented Jun 23, 2017

I just found out that bug had already been fixed in #5766. So this is good to go IMO.

@hach-que
Copy link
Contributor

@tomspilman @KonajuGames Can this please be merged so I don't have to keep rebasing and squashing it on the Redpoint fork?


internal void ResolveSubresource()
{
GraphicsDevice._d3dContext.ResolveSubresource(this._texture, 0, _resolvedTexture._texture, 0,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GraphicsDevice._d3dContext needs to be lockd here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I also add null and/or IsDisposed checks for _texture & _resolvedTexture, before calling _d3dContext.ResolveSubresource() method? I am not sure if there can be any scenario where null/disposed can happen, but I also don't want to add unnecessary checks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I also add null and/or IsDisposed checks

I don't think we have to do that right now.

@tomspilman
Copy link
Member

Thanks @zigzag312 ... merging.

Funny enough I implemented this same feature for XB1 a week or two ago.

@tomspilman tomspilman changed the title [DirectX] RenderTarget2D Multisampling Support for RenderTarget2D multisampling under DirectX. Jun 27, 2017
@tomspilman tomspilman merged commit fe465e1 into MonoGame:develop Jun 27, 2017
nkast pushed a commit to nkast/MonoGame that referenced this pull request Jun 26, 2018
Support for RenderTarget2D multisampling under DirectX.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants