aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu/Image
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2020-05-27 11:07:10 -0300
committerGitHub <noreply@github.com>2020-05-27 16:07:10 +0200
commit5795bb15282498b3824a5d15fe1ff78b85a18c23 (patch)
tree6d4ee54c218e81fc6efaad279a5b1ade3ca8ec59 /Ryujinx.Graphics.Gpu/Image
parent0b6d206daad7202d4e271118b631feb7dd363bbc (diff)
Support separate textures and samplers (#1216)
* Support separate textures and samplers * Add missing bindless flag, fix SNORM format on buffer textures * Add missing separation * Add comments about the new handles
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Image')
-rw-r--r--Ryujinx.Graphics.Gpu/Image/SamplerPool.cs9
-rw-r--r--Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs23
-rw-r--r--Ryujinx.Graphics.Gpu/Image/TextureManager.cs16
-rw-r--r--Ryujinx.Graphics.Gpu/Image/TexturePool.cs12
4 files changed, 36 insertions, 24 deletions
diff --git a/Ryujinx.Graphics.Gpu/Image/SamplerPool.cs b/Ryujinx.Graphics.Gpu/Image/SamplerPool.cs
index 2abf96de..ca13a7d6 100644
--- a/Ryujinx.Graphics.Gpu/Image/SamplerPool.cs
+++ b/Ryujinx.Graphics.Gpu/Image/SamplerPool.cs
@@ -1,6 +1,3 @@
-using System;
-using System.Runtime.InteropServices;
-
namespace Ryujinx.Graphics.Gpu.Image
{
/// <summary>
@@ -41,11 +38,7 @@ namespace Ryujinx.Graphics.Gpu.Image
if (sampler == null)
{
- ulong address = Address + (ulong)(uint)id * DescriptorSize;
-
- ReadOnlySpan<byte> data = Context.PhysicalMemory.GetSpan(address, DescriptorSize);
-
- SamplerDescriptor descriptor = MemoryMarshal.Cast<byte, SamplerDescriptor>(data)[0];
+ SamplerDescriptor descriptor = Context.PhysicalMemory.Read<SamplerDescriptor>(Address + (ulong)id * DescriptorSize);
sampler = new Sampler(Context, descriptor);
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs
index 612ec5ca..67254440 100644
--- a/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs
@@ -1,8 +1,6 @@
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu.State;
using Ryujinx.Graphics.Shader;
-using System;
-using System.Runtime.InteropServices;
namespace Ryujinx.Graphics.Gpu.Image
{
@@ -11,6 +9,9 @@ namespace Ryujinx.Graphics.Gpu.Image
/// </summary>
class TextureBindingsManager
{
+ private const int HandleHigh = 16;
+ private const int HandleMask = (1 << HandleHigh) - 1;
+
private GpuContext _context;
private bool _isCompute;
@@ -114,7 +115,6 @@ namespace Ryujinx.Graphics.Gpu.Image
}
_samplerPool = new SamplerPool(_context, address, maximumId);
-
_samplerIndex = samplerIndex;
}
@@ -195,7 +195,7 @@ namespace Ryujinx.Graphics.Gpu.Image
address = bufferManager.GetGraphicsUniformBufferAddress(stageIndex, binding.CbufSlot);
}
- packedId = MemoryMarshal.Cast<byte, int>(_context.PhysicalMemory.GetSpan(address + (ulong)binding.CbufOffset * 4, 4))[0];
+ packedId = _context.PhysicalMemory.Read<int>(address + (ulong)binding.CbufOffset * 4);
}
else
{
@@ -324,9 +324,20 @@ namespace Ryujinx.Graphics.Gpu.Image
address = bufferManager.GetGraphicsUniformBufferAddress(stageIndex, textureBufferIndex);
}
- address += (uint)wordOffset * 4;
+ int handle = _context.PhysicalMemory.Read<int>(address + (ulong)(wordOffset & HandleMask) * 4);
+
+ // The "wordOffset" (which is really the immediate value used on texture instructions on the shader)
+ // is a 13-bit value. However, in order to also support separate samplers and textures (which uses
+ // bindless textures on the shader), we extend it with another value on the higher 16 bits with
+ // another offset for the sampler.
+ // The shader translator has code to detect separate texture and sampler uses with a bindless texture,
+ // turn that into a regular texture access and produce those special handles with values on the higher 16 bits.
+ if (wordOffset >> HandleHigh != 0)
+ {
+ handle |= _context.PhysicalMemory.Read<int>(address + (ulong)(wordOffset >> HandleHigh) * 4);
+ }
- return BitConverter.ToInt32(_context.PhysicalMemory.GetSpan(address, 4));
+ return handle;
}
/// <summary>
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs
index 600e2f5b..c0eeb068 100644
--- a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs
@@ -773,6 +773,22 @@ namespace Ryujinx.Graphics.Gpu.Image
}
}
+ if (info.Target == Target.TextureBuffer)
+ {
+ // We assume that the host does not support signed normalized format
+ // (as is the case with OpenGL), so we just use a unsigned format.
+ // The shader will need the appropriate conversion code to compensate.
+ switch (formatInfo.Format)
+ {
+ case Format.R8Snorm: formatInfo = new FormatInfo(Format.R8Sint, 1, 1, 1); break;
+ case Format.R16Snorm: formatInfo = new FormatInfo(Format.R16Sint, 1, 1, 2); break;
+ case Format.R8G8Snorm: formatInfo = new FormatInfo(Format.R8G8Sint, 1, 1, 2); break;
+ case Format.R16G16Snorm: formatInfo = new FormatInfo(Format.R16G16Sint, 1, 1, 4); break;
+ case Format.R8G8B8A8Snorm: formatInfo = new FormatInfo(Format.R8G8B8A8Sint, 1, 1, 4); break;
+ case Format.R16G16B16A16Snorm: formatInfo = new FormatInfo(Format.R16G16B16A16Sint, 1, 1, 8); break;
+ }
+ }
+
int width = info.Width / info.SamplesInX;
int height = info.Height / info.SamplesInY;
diff --git a/Ryujinx.Graphics.Gpu/Image/TexturePool.cs b/Ryujinx.Graphics.Gpu/Image/TexturePool.cs
index f81c67ef..1f0ae75a 100644
--- a/Ryujinx.Graphics.Gpu/Image/TexturePool.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TexturePool.cs
@@ -1,9 +1,7 @@
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu.Memory;
-using System;
using System.Collections.Generic;
-using System.Runtime.InteropServices;
namespace Ryujinx.Graphics.Gpu.Image
{
@@ -83,11 +81,7 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <returns>The texture descriptor</returns>
public TextureDescriptor GetDescriptor(int id)
{
- ulong address = Address + (ulong)(uint)id * DescriptorSize;
-
- ReadOnlySpan<byte> data = Context.PhysicalMemory.GetSpan(address, DescriptorSize);
-
- return MemoryMarshal.Cast<byte, TextureDescriptor>(data)[0];
+ return Context.PhysicalMemory.Read<TextureDescriptor>(Address + (ulong)id * DescriptorSize);
}
/// <summary>
@@ -107,9 +101,7 @@ namespace Ryujinx.Graphics.Gpu.Image
if (texture != null)
{
- ReadOnlySpan<byte> data = Context.PhysicalMemory.GetSpan(address, DescriptorSize);
-
- TextureDescriptor descriptor = MemoryMarshal.Cast<byte, TextureDescriptor>(data)[0];
+ TextureDescriptor descriptor = Context.PhysicalMemory.Read<TextureDescriptor>(address);
// If the descriptors are the same, the texture is the same,
// we don't need to remove as it was not modified. Just continue.