forked from Mirror/Ryujinx
Fix texture sampling with depth compare and LOD level or bias (#2404)
* Fix texture sampling with depth compare and LOD level or bias * Shader cache version bump * nit: Sorting
This commit is contained in:
parent
eac659e37b
commit
ed2f5ede0f
8 changed files with 55 additions and 25 deletions
|
@ -4,8 +4,9 @@ namespace Ryujinx.Graphics.GAL
|
||||||
{
|
{
|
||||||
public bool SupportsAstcCompression { get; }
|
public bool SupportsAstcCompression { get; }
|
||||||
public bool SupportsImageLoadFormatted { get; }
|
public bool SupportsImageLoadFormatted { get; }
|
||||||
public bool SupportsNonConstantTextureOffset { get; }
|
|
||||||
public bool SupportsMismatchingViewFormat { get; }
|
public bool SupportsMismatchingViewFormat { get; }
|
||||||
|
public bool SupportsNonConstantTextureOffset { get; }
|
||||||
|
public bool SupportsTextureShadowLod { get; }
|
||||||
public bool SupportsViewportSwizzle { get; }
|
public bool SupportsViewportSwizzle { get; }
|
||||||
|
|
||||||
public int MaximumComputeSharedMemorySize { get; }
|
public int MaximumComputeSharedMemorySize { get; }
|
||||||
|
@ -15,8 +16,9 @@ namespace Ryujinx.Graphics.GAL
|
||||||
public Capabilities(
|
public Capabilities(
|
||||||
bool supportsAstcCompression,
|
bool supportsAstcCompression,
|
||||||
bool supportsImageLoadFormatted,
|
bool supportsImageLoadFormatted,
|
||||||
bool supportsNonConstantTextureOffset,
|
|
||||||
bool supportsMismatchingViewFormat,
|
bool supportsMismatchingViewFormat,
|
||||||
|
bool supportsNonConstantTextureOffset,
|
||||||
|
bool supportsTextureShadowLod,
|
||||||
bool supportsViewportSwizzle,
|
bool supportsViewportSwizzle,
|
||||||
int maximumComputeSharedMemorySize,
|
int maximumComputeSharedMemorySize,
|
||||||
float maximumSupportedAnisotropy,
|
float maximumSupportedAnisotropy,
|
||||||
|
@ -24,8 +26,9 @@ namespace Ryujinx.Graphics.GAL
|
||||||
{
|
{
|
||||||
SupportsAstcCompression = supportsAstcCompression;
|
SupportsAstcCompression = supportsAstcCompression;
|
||||||
SupportsImageLoadFormatted = supportsImageLoadFormatted;
|
SupportsImageLoadFormatted = supportsImageLoadFormatted;
|
||||||
SupportsNonConstantTextureOffset = supportsNonConstantTextureOffset;
|
|
||||||
SupportsMismatchingViewFormat = supportsMismatchingViewFormat;
|
SupportsMismatchingViewFormat = supportsMismatchingViewFormat;
|
||||||
|
SupportsNonConstantTextureOffset = supportsNonConstantTextureOffset;
|
||||||
|
SupportsTextureShadowLod = supportsTextureShadowLod;
|
||||||
SupportsViewportSwizzle = supportsViewportSwizzle;
|
SupportsViewportSwizzle = supportsViewportSwizzle;
|
||||||
MaximumComputeSharedMemorySize = maximumComputeSharedMemorySize;
|
MaximumComputeSharedMemorySize = maximumComputeSharedMemorySize;
|
||||||
MaximumSupportedAnisotropy = maximumSupportedAnisotropy;
|
MaximumSupportedAnisotropy = maximumSupportedAnisotropy;
|
||||||
|
|
|
@ -180,6 +180,12 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
/// <returns>True if the GPU and driver supports non-constant texture offsets, false otherwise</returns>
|
/// <returns>True if the GPU and driver supports non-constant texture offsets, false otherwise</returns>
|
||||||
public bool QuerySupportsNonConstantTextureOffset() => _context.Capabilities.SupportsNonConstantTextureOffset;
|
public bool QuerySupportsNonConstantTextureOffset() => _context.Capabilities.SupportsNonConstantTextureOffset;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queries host GPU texture shadow LOD support.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if the GPU and driver supports texture shadow LOD, false otherwise</returns>
|
||||||
|
public bool QuerySupportsTextureShadowLod() => _context.Capabilities.SupportsTextureShadowLod;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the texture descriptor for a given texture on the pool.
|
/// Gets the texture descriptor for a given texture on the pool.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Version of the codegen (to be changed when codegen or guest format change).
|
/// Version of the codegen (to be changed when codegen or guest format change).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const ulong ShaderCodeGenVersion = 2397;
|
private const ulong ShaderCodeGenVersion = 2404;
|
||||||
|
|
||||||
// Progress reporting helpers
|
// Progress reporting helpers
|
||||||
private volatile int _shaderCount;
|
private volatile int _shaderCount;
|
||||||
|
|
|
@ -7,11 +7,12 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
private static readonly Lazy<bool> _supportsAstcCompression = new Lazy<bool>(() => HasExtension("GL_KHR_texture_compression_astc_ldr"));
|
private static readonly Lazy<bool> _supportsAstcCompression = new Lazy<bool>(() => HasExtension("GL_KHR_texture_compression_astc_ldr"));
|
||||||
private static readonly Lazy<bool> _supportsImageLoadFormatted = new Lazy<bool>(() => HasExtension("GL_EXT_shader_image_load_formatted"));
|
private static readonly Lazy<bool> _supportsImageLoadFormatted = new Lazy<bool>(() => HasExtension("GL_EXT_shader_image_load_formatted"));
|
||||||
private static readonly Lazy<bool> _supportsPolygonOffsetClamp = new Lazy<bool>(() => HasExtension("GL_EXT_polygon_offset_clamp"));
|
|
||||||
private static readonly Lazy<bool> _supportsViewportSwizzle = new Lazy<bool>(() => HasExtension("GL_NV_viewport_swizzle"));
|
|
||||||
private static readonly Lazy<bool> _supportsSeamlessCubemapPerTexture = new Lazy<bool>(() => HasExtension("GL_ARB_seamless_cubemap_per_texture"));
|
|
||||||
private static readonly Lazy<bool> _supportsParallelShaderCompile = new Lazy<bool>(() => HasExtension("GL_ARB_parallel_shader_compile"));
|
private static readonly Lazy<bool> _supportsParallelShaderCompile = new Lazy<bool>(() => HasExtension("GL_ARB_parallel_shader_compile"));
|
||||||
|
private static readonly Lazy<bool> _supportsPolygonOffsetClamp = new Lazy<bool>(() => HasExtension("GL_EXT_polygon_offset_clamp"));
|
||||||
private static readonly Lazy<bool> _supportsQuads = new Lazy<bool>(SupportsQuadsCheck);
|
private static readonly Lazy<bool> _supportsQuads = new Lazy<bool>(SupportsQuadsCheck);
|
||||||
|
private static readonly Lazy<bool> _supportsSeamlessCubemapPerTexture = new Lazy<bool>(() => HasExtension("GL_ARB_seamless_cubemap_per_texture"));
|
||||||
|
private static readonly Lazy<bool> _supportsTextureShadowLod = new Lazy<bool>(() => HasExtension("GL_EXT_texture_shadow_lod"));
|
||||||
|
private static readonly Lazy<bool> _supportsViewportSwizzle = new Lazy<bool>(() => HasExtension("GL_NV_viewport_swizzle"));
|
||||||
|
|
||||||
private static readonly Lazy<int> _maximumComputeSharedMemorySize = new Lazy<int>(() => GetLimit(All.MaxComputeSharedMemorySize));
|
private static readonly Lazy<int> _maximumComputeSharedMemorySize = new Lazy<int>(() => GetLimit(All.MaxComputeSharedMemorySize));
|
||||||
private static readonly Lazy<int> _storageBufferOffsetAlignment = new Lazy<int>(() => GetLimit(All.ShaderStorageBufferOffsetAlignment));
|
private static readonly Lazy<int> _storageBufferOffsetAlignment = new Lazy<int>(() => GetLimit(All.ShaderStorageBufferOffsetAlignment));
|
||||||
|
@ -33,14 +34,16 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
public static bool SupportsAstcCompression => _supportsAstcCompression.Value;
|
public static bool SupportsAstcCompression => _supportsAstcCompression.Value;
|
||||||
public static bool SupportsImageLoadFormatted => _supportsImageLoadFormatted.Value;
|
public static bool SupportsImageLoadFormatted => _supportsImageLoadFormatted.Value;
|
||||||
public static bool SupportsPolygonOffsetClamp => _supportsPolygonOffsetClamp.Value;
|
|
||||||
public static bool SupportsViewportSwizzle => _supportsViewportSwizzle.Value;
|
|
||||||
public static bool SupportsSeamlessCubemapPerTexture => _supportsSeamlessCubemapPerTexture.Value;
|
|
||||||
public static bool SupportsParallelShaderCompile => _supportsParallelShaderCompile.Value;
|
public static bool SupportsParallelShaderCompile => _supportsParallelShaderCompile.Value;
|
||||||
|
public static bool SupportsPolygonOffsetClamp => _supportsPolygonOffsetClamp.Value;
|
||||||
public static bool SupportsQuads => _supportsQuads.Value;
|
public static bool SupportsQuads => _supportsQuads.Value;
|
||||||
public static bool SupportsNonConstantTextureOffset => _gpuVendor.Value == GpuVendor.Nvidia;
|
public static bool SupportsSeamlessCubemapPerTexture => _supportsSeamlessCubemapPerTexture.Value;
|
||||||
public static bool RequiresSyncFlush => _gpuVendor.Value == GpuVendor.Amd || _gpuVendor.Value == GpuVendor.IntelWindows || _gpuVendor.Value == GpuVendor.IntelUnix;
|
public static bool SupportsTextureShadowLod => _supportsTextureShadowLod.Value;
|
||||||
public static bool SupportsMismatchingViewFormat => _gpuVendor.Value != GpuVendor.Amd && _gpuVendor.Value != GpuVendor.IntelWindows;
|
public static bool SupportsViewportSwizzle => _supportsViewportSwizzle.Value;
|
||||||
|
|
||||||
|
public static bool SupportsMismatchingViewFormat => _gpuVendor.Value != GpuVendor.Amd && _gpuVendor.Value != GpuVendor.IntelWindows;
|
||||||
|
public static bool SupportsNonConstantTextureOffset => _gpuVendor.Value == GpuVendor.Nvidia;
|
||||||
|
public static bool RequiresSyncFlush => _gpuVendor.Value == GpuVendor.Amd || _gpuVendor.Value == GpuVendor.IntelWindows || _gpuVendor.Value == GpuVendor.IntelUnix;
|
||||||
|
|
||||||
public static int MaximumComputeSharedMemorySize => _maximumComputeSharedMemorySize.Value;
|
public static int MaximumComputeSharedMemorySize => _maximumComputeSharedMemorySize.Value;
|
||||||
public static int StorageBufferOffsetAlignment => _storageBufferOffsetAlignment.Value;
|
public static int StorageBufferOffsetAlignment => _storageBufferOffsetAlignment.Value;
|
||||||
|
@ -78,7 +81,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
else if (vendor == "intel")
|
else if (vendor == "intel")
|
||||||
{
|
{
|
||||||
string renderer = GL.GetString(StringName.Renderer).ToLower();
|
string renderer = GL.GetString(StringName.Renderer).ToLower();
|
||||||
|
|
||||||
return renderer.Contains("mesa") ? GpuVendor.IntelUnix : GpuVendor.IntelWindows;
|
return renderer.Contains("mesa") ? GpuVendor.IntelUnix : GpuVendor.IntelWindows;
|
||||||
}
|
}
|
||||||
else if (vendor == "ati technologies inc." || vendor == "advanced micro devices, inc.")
|
else if (vendor == "ati technologies inc." || vendor == "advanced micro devices, inc.")
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
|
@ -96,8 +96,9 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
return new Capabilities(
|
return new Capabilities(
|
||||||
HwCapabilities.SupportsAstcCompression,
|
HwCapabilities.SupportsAstcCompression,
|
||||||
HwCapabilities.SupportsImageLoadFormatted,
|
HwCapabilities.SupportsImageLoadFormatted,
|
||||||
HwCapabilities.SupportsNonConstantTextureOffset,
|
|
||||||
HwCapabilities.SupportsMismatchingViewFormat,
|
HwCapabilities.SupportsMismatchingViewFormat,
|
||||||
|
HwCapabilities.SupportsNonConstantTextureOffset,
|
||||||
|
HwCapabilities.SupportsTextureShadowLod,
|
||||||
HwCapabilities.SupportsViewportSwizzle,
|
HwCapabilities.SupportsViewportSwizzle,
|
||||||
HwCapabilities.MaximumComputeSharedMemorySize,
|
HwCapabilities.MaximumComputeSharedMemorySize,
|
||||||
HwCapabilities.MaximumSupportedAnisotropy,
|
HwCapabilities.MaximumSupportedAnisotropy,
|
||||||
|
|
|
@ -20,6 +20,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||||
context.AppendLine("#extension GL_ARB_shader_ballot : enable");
|
context.AppendLine("#extension GL_ARB_shader_ballot : enable");
|
||||||
context.AppendLine("#extension GL_ARB_shader_group_vote : enable");
|
context.AppendLine("#extension GL_ARB_shader_group_vote : enable");
|
||||||
context.AppendLine("#extension GL_EXT_shader_image_load_formatted : enable");
|
context.AppendLine("#extension GL_EXT_shader_image_load_formatted : enable");
|
||||||
|
context.AppendLine("#extension GL_EXT_texture_shadow_lod : enable");
|
||||||
|
|
||||||
if (context.Config.Stage == ShaderStage.Compute)
|
if (context.Config.Stage == ShaderStage.Compute)
|
||||||
{
|
{
|
||||||
|
@ -32,7 +33,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||||
}
|
}
|
||||||
|
|
||||||
context.AppendLine("#pragma optionNV(fastmath off)");
|
context.AppendLine("#pragma optionNV(fastmath off)");
|
||||||
|
|
||||||
context.AppendLine();
|
context.AppendLine();
|
||||||
|
|
||||||
context.AppendLine($"const int {DefaultNames.UndefinedName} = 0;");
|
context.AppendLine($"const int {DefaultNames.UndefinedName} = 0;");
|
||||||
|
|
|
@ -309,20 +309,32 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||||
bool isMultisample = (texOp.Type & SamplerType.Multisample) != 0;
|
bool isMultisample = (texOp.Type & SamplerType.Multisample) != 0;
|
||||||
bool isShadow = (texOp.Type & SamplerType.Shadow) != 0;
|
bool isShadow = (texOp.Type & SamplerType.Shadow) != 0;
|
||||||
|
|
||||||
|
SamplerType type = texOp.Type & SamplerType.Mask;
|
||||||
|
|
||||||
|
bool is2D = type == SamplerType.Texture2D;
|
||||||
|
bool isCube = type == SamplerType.TextureCube;
|
||||||
|
|
||||||
|
// 2D Array and Cube shadow samplers with LOD level or bias requires an extension.
|
||||||
|
// If the extension is not supported, just remove the LOD parameter.
|
||||||
|
if (isArray && isShadow && (is2D || isCube) && !context.Config.GpuAccessor.QuerySupportsTextureShadowLod())
|
||||||
|
{
|
||||||
|
hasLodBias = false;
|
||||||
|
hasLodLevel = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cube shadow samplers with LOD level requires an extension.
|
||||||
|
// If the extension is not supported, just remove the LOD level parameter.
|
||||||
|
if (isShadow && isCube && !context.Config.GpuAccessor.QuerySupportsTextureShadowLod())
|
||||||
|
{
|
||||||
|
hasLodLevel = false;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Bindless texture support. For now we just return 0.
|
// TODO: Bindless texture support. For now we just return 0.
|
||||||
if (isBindless)
|
if (isBindless)
|
||||||
{
|
{
|
||||||
return NumberFormatter.FormatFloat(0);
|
return NumberFormatter.FormatFloat(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This combination is valid, but not available on GLSL.
|
|
||||||
// For now, ignore the LOD level and do a normal sample.
|
|
||||||
// TODO: How to implement it properly?
|
|
||||||
if (hasLodLevel && isArray && isShadow)
|
|
||||||
{
|
|
||||||
hasLodLevel = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
string texCall = intCoords ? "texelFetch" : "texture";
|
string texCall = intCoords ? "texelFetch" : "texture";
|
||||||
|
|
||||||
if (isGather)
|
if (isGather)
|
||||||
|
|
|
@ -74,6 +74,11 @@
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QuerySupportsTextureShadowLod()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
TextureFormat QueryTextureFormat(int handle, int cbufSlot = -1)
|
TextureFormat QueryTextureFormat(int handle, int cbufSlot = -1)
|
||||||
{
|
{
|
||||||
return TextureFormat.R8G8B8A8Unorm;
|
return TextureFormat.R8G8B8A8Unorm;
|
||||||
|
|
Loading…
Reference in a new issue