aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs
diff options
context:
space:
mode:
authorriperiperi <rhy3756547@hotmail.com>2023-02-12 09:30:26 +0000
committerGitHub <noreply@github.com>2023-02-12 10:30:26 +0100
commite4f68592c3a6e51414e5f78eef096f21bf735eb1 (patch)
tree4b94f4e828e35a133c89cd0384ac8c565ffd762a /Ryujinx.Graphics.Gpu/Image/TextureGroup.cs
parent1dcd44b94fcba10e9f78f8352557d46ea84b80ab (diff)
Fix partial updates for textures. (#4401)1.1.617
I was forcing some types of texture to partially update when investigating performance with games that stream in data, and noticed that partially loading texture data was really broken on both backends. Fixes Vulkan texture set by getting the correct expected size for the texture. Fixes partial upload on both backends for both Texture 2D Array and Cubemap using the wrong offset and uploading to the first layer/level for a handle. 3D might also be affected. This might fix textures randomly having incorrect data in games that render to it - jumbled in the case of OpenGL, and outdated/black in the case of Vulkan. This case typically happens in UE4 games.
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Image/TextureGroup.cs')
-rw-r--r--Ryujinx.Graphics.Gpu/Image/TextureGroup.cs9
1 files changed, 4 insertions, 5 deletions
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs b/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs
index 942fa2f8..1040b394 100644
--- a/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs
@@ -336,24 +336,23 @@ namespace Ryujinx.Graphics.Gpu.Image
if (_loadNeeded[baseHandle + i])
{
var info = GetHandleInformation(baseHandle + i);
- int offsetIndex = info.Index;
// Only one of these will be greater than 1, as partial sync is only called when there are sub-image views.
for (int layer = 0; layer < info.Layers; layer++)
{
for (int level = 0; level < info.Levels; level++)
{
+ int offsetIndex = GetOffsetIndex(info.BaseLayer + layer, info.BaseLevel + level);
+
int offset = _allOffsets[offsetIndex];
int endOffset = Math.Min(offset + _sliceSizes[info.BaseLevel + level], (int)Storage.Size);
int size = endOffset - offset;
ReadOnlySpan<byte> data = _physicalMemory.GetSpan(Storage.Range.GetSlice((ulong)offset, (ulong)size));
- SpanOrArray<byte> result = Storage.ConvertToHostCompatibleFormat(data, info.BaseLevel, true);
-
- Storage.SetData(result, info.BaseLayer, info.BaseLevel);
+ SpanOrArray<byte> result = Storage.ConvertToHostCompatibleFormat(data, info.BaseLevel + level, true);
- offsetIndex++;
+ Storage.SetData(result, info.BaseLayer + layer, info.BaseLevel + level);
}
}
}