Skip to content

Commit 5a60210

Browse files
committed
Reimplement object lifetimes to fix orphan objects (GraphicsResource)
* Expands and enhances documentation * Minor cleanups
1 parent 1e9660d commit 5a60210

2 files changed

Lines changed: 72 additions & 46 deletions

File tree

sources/engine/Stride.Graphics/Direct3D/GraphicsResource.Direct3D.cs

Lines changed: 54 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,90 +3,109 @@
33

44
#if STRIDE_GRAPHICS_API_DIRECT3D11
55

6+
using Silk.NET.Core.Native;
67
using Silk.NET.Direct3D11;
7-
8-
using static Stride.Graphics.DebugHelpers;
8+
using Stride.Core;
99

1010
namespace Stride.Graphics
1111
{
12-
/// <summary>
13-
/// GraphicsResource class
14-
/// </summary>
1512
public abstract unsafe partial class GraphicsResource
1613
{
17-
private ID3D11ShaderResourceView* shaderResourceView;
18-
private ID3D11UnorderedAccessView* unorderedAccessView;
14+
private ComPtr<ID3D11ShaderResourceView> shaderResourceView;
15+
private ComPtr<ID3D11UnorderedAccessView> unorderedAccessView;
1916

20-
// Used to internally force a WriteDiscard (to force a rename) with the GraphicsResourceAllocator
17+
/// <summary>
18+
/// Used to internally force a <c>WriteDiscard</c> (to force a rename) with the <see cref="GraphicsResourceAllocator"/>.
19+
/// </summary>
2120
internal bool DiscardNextMap;
2221

22+
/// <summary>
23+
/// Gets a value indicating whether this graphics resource is in "Debug mode".
24+
/// </summary>
25+
/// <value>
26+
/// <see langword="true"/> if this graphics resource is initialized in "Debug mode"; otherwise, <see langword="false"/>.
27+
/// </value>
2328
protected bool IsDebugMode => GraphicsDevice?.IsDebugMode == true;
2429

30+
/// <inheritdoc/>
2531
protected override void OnNameChanged()
2632
{
2733
base.OnNameChanged();
2834

2935
if (IsDebugMode)
3036
{
31-
if (shaderResourceView != null)
37+
if (shaderResourceView.Handle != null)
3238
{
33-
SetDebugName((ID3D11DeviceChild*) shaderResourceView, Name is null ? null : $"{Name} SRV");
39+
using var srv = shaderResourceView.QueryInterface<ID3D11DeviceChild>();
40+
srv.SetDebugName(Name is null ? null : $"{Name} SRV", owningObject: this);
3441
}
35-
if (unorderedAccessView != null)
42+
if (unorderedAccessView.Handle != null)
3643
{
37-
SetDebugName((ID3D11DeviceChild*) unorderedAccessView, Name is null ? null : $"{Name} UAV");
44+
using var uav = unorderedAccessView.QueryInterface<ID3D11DeviceChild>();
45+
uav.SetDebugName(Name is null ? null : $"{Name} UAV", owningObject: this);
3846
}
3947
}
4048
}
4149

4250
/// <summary>
43-
/// Gets or sets the ShaderResourceView attached to this GraphicsResource.
44-
/// Note that only Texture, Texture3D, RenderTarget2D, RenderTarget3D, DepthStencil are using this ShaderResourceView
51+
/// Gets or sets the <see cref="ID3D11ShaderResourceView"/> attached to this <see cref="GraphicsResource"/>.
4552
/// </summary>
46-
/// <value>The device child.</value>
47-
protected internal ID3D11ShaderResourceView* NativeShaderResourceView
53+
/// <value>The Shader Resource View associated with this graphics resource.</value>
54+
/// <remarks>
55+
/// Only <see cref="Texture"/>s are using this Shader Resource View.
56+
/// </remarks>
57+
protected internal ComPtr<ID3D11ShaderResourceView> NativeShaderResourceView
4858
{
4959
get => shaderResourceView;
50-
5160
set
5261
{
62+
var previousShaderResourceView = shaderResourceView;
63+
5364
shaderResourceView = value;
5465

55-
if (IsDebugMode && shaderResourceView != null)
66+
if (shaderResourceView.Handle != previousShaderResourceView.Handle)
67+
{
68+
previousShaderResourceView.RemoveDisposeBy(this);
69+
previousShaderResourceView.Release();
70+
71+
shaderResourceView.DisposeBy(this);
72+
}
73+
74+
if (IsDebugMode && shaderResourceView.Handle != null)
5675
{
57-
SetDebugName((ID3D11DeviceChild*)shaderResourceView, Name is null ? null : $"{Name} SRV");
76+
using var srv = shaderResourceView.QueryInterface<ID3D11DeviceChild>();
77+
srv.SetDebugName(Name is null ? null : $"{Name} SRV", owningObject: this);
5878
}
5979
}
6080
}
6181

6282
/// <summary>
63-
/// Gets or sets the UnorderedAccessView attached to this GraphicsResource.
83+
/// Gets or sets the <see cref="ID3D11UnorderedAccessView"/> attached to this <see cref="GraphicsResource"/>.
6484
/// </summary>
65-
/// <value>The device child.</value>
85+
/// <value>The Unordered Access View associated with this graphics resource.</value>
6686
protected internal ID3D11UnorderedAccessView* NativeUnorderedAccessView
6787
{
6888
get => unorderedAccessView;
69-
7089
set
7190
{
91+
var previousUnorderedAccessView = unorderedAccessView;
92+
7293
unorderedAccessView = value;
7394

74-
if (IsDebugMode && unorderedAccessView != null)
95+
if (unorderedAccessView.Handle != previousUnorderedAccessView.Handle)
7596
{
76-
SetDebugName((ID3D11DeviceChild*)unorderedAccessView, Name is null ? null : $"{Name} UAV");
77-
}
78-
}
79-
}
97+
previousUnorderedAccessView.RemoveDisposeBy(this);
98+
previousUnorderedAccessView.Release();
8099

81-
protected internal override void OnDestroyed()
82-
{
83-
if (shaderResourceView != null)
84-
shaderResourceView->Release();
85-
86-
if (unorderedAccessView != null)
87-
unorderedAccessView->Release();
100+
unorderedAccessView.DisposeBy(this);
101+
}
88102

89-
base.OnDestroyed();
103+
if (IsDebugMode && unorderedAccessView.Handle != null)
104+
{
105+
using var uav = unorderedAccessView.QueryInterface<ID3D11DeviceChild>();
106+
uav.SetDebugName(Name is null ? null : $"{Name} UAV", owningObject: this);
107+
}
108+
}
90109
}
91110
}
92111
}
Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,29 @@
11
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
22
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
3+
34
namespace Stride.Graphics
4-
{
5+
{
56
/// <summary>
6-
/// GraphicsResource abstract class
7+
/// Represents an abstract resource that depends on a <see cref="GraphicsDevice"/>.
78
/// </summary>
89
public abstract partial class GraphicsResource : GraphicsResourceBase
910
{
10-
protected GraphicsResource()
11-
{
12-
}
11+
/// <summary>
12+
/// Initializes a new instance of the <see cref="GraphicsResource"/> class.
13+
/// </summary>
14+
protected GraphicsResource() { }
1315

14-
protected GraphicsResource(GraphicsDevice device) : base(device)
15-
{
16-
}
16+
/// <summary>
17+
/// Initializes a new instance of the <see cref="GraphicsResource"/> class attached to a graphics device.
18+
/// </summary>
19+
/// <param name="device">The <see cref="GraphicsDevice"/> this resource belongs to.</param>
20+
protected GraphicsResource(GraphicsDevice device) : base(device) { }
1721

18-
protected GraphicsResource(GraphicsDevice device, string name) : base(device, name)
19-
{
20-
}
22+
/// <summary>
23+
/// Initializes a new instance of the <see cref="GraphicsResource"/> class attached to a graphics device.
24+
/// </summary>
25+
/// <param name="device">The <see cref="GraphicsDevice"/> this resource belongs to.</param>
26+
/// <param name="name">A string to use as a name for identifying the resource. Useful when debugging.</param>
27+
protected GraphicsResource(GraphicsDevice device, string name) : base(device, name) { }
2128
}
2229
}

0 commit comments

Comments
 (0)