|
|
@@ -311,7 +311,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|
|
flags |= TextureSearchFlags.NoCreate;
|
|
|
}
|
|
|
|
|
|
- Texture texture = FindOrCreateTexture(memoryManager, flags, info, 0);
|
|
|
+ Texture texture = FindOrCreateTexture(memoryManager, flags, info, 0, sizeHint: sizeHint);
|
|
|
|
|
|
texture?.SynchronizeMemory();
|
|
|
|
|
|
@@ -324,6 +324,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|
|
/// <param name="memoryManager">GPU memory manager where the texture is mapped</param>
|
|
|
/// <param name="colorState">Color buffer texture to find or create</param>
|
|
|
/// <param name="layered">Indicates if the texture might be accessed with a non-zero layer index</param>
|
|
|
+ /// <param name="discard">Indicates that the sizeHint region's data will be overwritten</param>
|
|
|
/// <param name="samplesInX">Number of samples in the X direction, for MSAA</param>
|
|
|
/// <param name="samplesInY">Number of samples in the Y direction, for MSAA</param>
|
|
|
/// <param name="sizeHint">A hint indicating the minimum used size for the texture</param>
|
|
|
@@ -332,6 +333,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|
|
MemoryManager memoryManager,
|
|
|
RtColorState colorState,
|
|
|
bool layered,
|
|
|
+ bool discard,
|
|
|
int samplesInX,
|
|
|
int samplesInY,
|
|
|
Size sizeHint)
|
|
|
@@ -398,7 +400,14 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|
|
|
|
|
int layerSize = !isLinear ? colorState.LayerSize * 4 : 0;
|
|
|
|
|
|
- Texture texture = FindOrCreateTexture(memoryManager, TextureSearchFlags.WithUpscale, info, layerSize);
|
|
|
+ var flags = TextureSearchFlags.WithUpscale;
|
|
|
+
|
|
|
+ if (discard)
|
|
|
+ {
|
|
|
+ flags |= TextureSearchFlags.DiscardData;
|
|
|
+ }
|
|
|
+
|
|
|
+ Texture texture = FindOrCreateTexture(memoryManager, flags, info, layerSize, sizeHint: sizeHint);
|
|
|
|
|
|
texture?.SynchronizeMemory();
|
|
|
|
|
|
@@ -412,6 +421,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|
|
/// <param name="dsState">Depth-stencil buffer texture to find or create</param>
|
|
|
/// <param name="size">Size of the depth-stencil texture</param>
|
|
|
/// <param name="layered">Indicates if the texture might be accessed with a non-zero layer index</param>
|
|
|
+ /// <param name="discard">Indicates that the sizeHint region's data will be overwritten</param>
|
|
|
/// <param name="samplesInX">Number of samples in the X direction, for MSAA</param>
|
|
|
/// <param name="samplesInY">Number of samples in the Y direction, for MSAA</param>
|
|
|
/// <param name="sizeHint">A hint indicating the minimum used size for the texture</param>
|
|
|
@@ -421,6 +431,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|
|
RtDepthStencilState dsState,
|
|
|
Size3D size,
|
|
|
bool layered,
|
|
|
+ bool discard,
|
|
|
int samplesInX,
|
|
|
int samplesInY,
|
|
|
Size sizeHint)
|
|
|
@@ -465,7 +476,14 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|
|
target,
|
|
|
formatInfo);
|
|
|
|
|
|
- Texture texture = FindOrCreateTexture(memoryManager, TextureSearchFlags.WithUpscale, info, dsState.LayerSize * 4);
|
|
|
+ var flags = TextureSearchFlags.WithUpscale;
|
|
|
+
|
|
|
+ if (discard)
|
|
|
+ {
|
|
|
+ flags |= TextureSearchFlags.DiscardData;
|
|
|
+ }
|
|
|
+
|
|
|
+ Texture texture = FindOrCreateTexture(memoryManager, flags, info, dsState.LayerSize * 4, sizeHint: sizeHint);
|
|
|
|
|
|
texture?.SynchronizeMemory();
|
|
|
|
|
|
@@ -500,6 +518,37 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|
|
return Math.Clamp(widthAligned - alignment + 1, minimumWidth, widthAligned);
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// Determines if texture data should be fully discarded
|
|
|
+ /// based on the size hint region and whether it is set to be discarded.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="discard">Whether the size hint region should be discarded</param>
|
|
|
+ /// <param name="texture">The texture being discarded</param>
|
|
|
+ /// <param name="sizeHint">A hint indicating the minimum used size for the texture</param>
|
|
|
+ /// <returns>True if the data should be discarded, false otherwise</returns>
|
|
|
+ private static bool ShouldDiscard(bool discard, Texture texture, Size? sizeHint)
|
|
|
+ {
|
|
|
+ return discard &&
|
|
|
+ texture.Info.DepthOrLayers == 1 &&
|
|
|
+ sizeHint != null &&
|
|
|
+ texture.Width <= sizeHint.Value.Width &&
|
|
|
+ texture.Height <= sizeHint.Value.Height;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Discards texture data if requested and possible.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="discard">Whether the size hint region should be discarded</param>
|
|
|
+ /// <param name="texture">The texture being discarded</param>
|
|
|
+ /// <param name="sizeHint">A hint indicating the minimum used size for the texture</param>
|
|
|
+ private static void DiscardIfNeeded(bool discard, Texture texture, Size? sizeHint)
|
|
|
+ {
|
|
|
+ if (ShouldDiscard(discard, texture, sizeHint))
|
|
|
+ {
|
|
|
+ texture.DiscardData();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// Tries to find an existing texture, or create a new one if not found.
|
|
|
/// </summary>
|
|
|
@@ -507,6 +556,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|
|
/// <param name="flags">The texture search flags, defines texture comparison rules</param>
|
|
|
/// <param name="info">Texture information of the texture to be found or created</param>
|
|
|
/// <param name="layerSize">Size in bytes of a single texture layer</param>
|
|
|
+ /// <param name="sizeHint">A hint indicating the minimum used size for the texture</param>
|
|
|
/// <param name="range">Optional ranges of physical memory where the texture data is located</param>
|
|
|
/// <returns>The texture</returns>
|
|
|
public Texture FindOrCreateTexture(
|
|
|
@@ -514,9 +564,11 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|
|
TextureSearchFlags flags,
|
|
|
TextureInfo info,
|
|
|
int layerSize = 0,
|
|
|
+ Size? sizeHint = null,
|
|
|
MultiRange? range = null)
|
|
|
{
|
|
|
bool isSamplerTexture = (flags & TextureSearchFlags.ForSampler) != 0;
|
|
|
+ bool discard = (flags & TextureSearchFlags.DiscardData) != 0;
|
|
|
|
|
|
TextureScaleMode scaleMode = IsUpscaleCompatible(info, (flags & TextureSearchFlags.WithUpscale) != 0);
|
|
|
|
|
|
@@ -612,6 +664,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|
|
|
|
|
if (texture != null)
|
|
|
{
|
|
|
+ DiscardIfNeeded(discard, texture, sizeHint);
|
|
|
+
|
|
|
texture.SynchronizeMemory();
|
|
|
|
|
|
return texture;
|
|
|
@@ -907,7 +961,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|
|
|
|
|
// We need to synchronize before copying the old view data to the texture,
|
|
|
// otherwise the copied data would be overwritten by a future synchronization.
|
|
|
- texture.InitializeData(false, setData);
|
|
|
+ texture.InitializeData(false, setData && !ShouldDiscard(discard, texture, sizeHint));
|
|
|
|
|
|
texture.Group.InitializeOverlaps();
|
|
|
|