aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/TextureHandle.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Shader/TextureHandle.cs')
-rw-r--r--Ryujinx.Graphics.Shader/TextureHandle.cs59
1 files changed, 59 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.Shader/TextureHandle.cs b/Ryujinx.Graphics.Shader/TextureHandle.cs
index b3712e6b..d468188b 100644
--- a/Ryujinx.Graphics.Shader/TextureHandle.cs
+++ b/Ryujinx.Graphics.Shader/TextureHandle.cs
@@ -1,3 +1,4 @@
+using System;
using System.Runtime.CompilerServices;
namespace Ryujinx.Graphics.Shader
@@ -50,5 +51,63 @@ namespace Ryujinx.Graphics.Shader
{
return (handle & 0x3fff, (handle >> 14) & 0x3fff, (TextureHandleType)((uint)handle >> 28));
}
+
+ /// <summary>
+ /// Unpacks the texture ID from the real texture handle.
+ /// </summary>
+ /// <param name="packedId">The real texture handle</param>
+ /// <returns>The texture ID</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int UnpackTextureId(int packedId)
+ {
+ return (packedId >> 0) & 0xfffff;
+ }
+
+ /// <summary>
+ /// Unpacks the sampler ID from the real texture handle.
+ /// </summary>
+ /// <param name="packedId">The real texture handle</param>
+ /// <returns>The sampler ID</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int UnpackSamplerId(int packedId)
+ {
+ return (packedId >> 20) & 0xfff;
+ }
+
+ /// <summary>
+ /// Reads a packed texture and sampler ID (basically, the real texture handle)
+ /// from a given texture/sampler constant buffer.
+ /// </summary>
+ /// <param name="wordOffset">A word offset of the handle on the buffer (the "fake" shader handle)</param>
+ /// <param name="cachedTextureBuffer">The constant buffer to fetch texture IDs from</param>
+ /// <param name="cachedSamplerBuffer">The constant buffer to fetch sampler IDs from</param>
+ /// <returns>The packed texture and sampler ID (the real texture handle)</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int ReadPackedId(int wordOffset, ReadOnlySpan<int> cachedTextureBuffer, ReadOnlySpan<int> cachedSamplerBuffer)
+ {
+ (int textureWordOffset, int samplerWordOffset, TextureHandleType handleType) = UnpackOffsets(wordOffset);
+
+ int handle = cachedTextureBuffer[textureWordOffset];
+
+ // 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 (handleType != TextureHandleType.CombinedSampler)
+ {
+ int samplerHandle = cachedSamplerBuffer[samplerWordOffset];
+
+ if (handleType == TextureHandleType.SeparateSamplerId)
+ {
+ samplerHandle <<= 20;
+ }
+
+ handle |= samplerHandle;
+ }
+
+ return handle;
+ }
}
}