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:
gdkchan 2021-06-24 19:54:50 -03:00 committed by GitHub
parent eac659e37b
commit ed2f5ede0f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 55 additions and 25 deletions

View file

@ -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;

View file

@ -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>

View file

@ -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;

View file

@ -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.")

View file

@ -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,

View file

@ -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;");

View file

@ -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)

View file

@ -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;