diff --git a/Ryujinx.Graphics.GAL/SamplerCreateInfo.cs b/Ryujinx.Graphics.GAL/SamplerCreateInfo.cs index 33d80af5..7a68450e 100644 --- a/Ryujinx.Graphics.GAL/SamplerCreateInfo.cs +++ b/Ryujinx.Graphics.GAL/SamplerCreateInfo.cs @@ -5,6 +5,8 @@ namespace Ryujinx.Graphics.GAL public MinFilter MinFilter { get; } public MagFilter MagFilter { get; } + public bool SeamlessCubemap { get; } + public AddressMode AddressU { get; } public AddressMode AddressV { get; } public AddressMode AddressP { get; } @@ -22,6 +24,7 @@ namespace Ryujinx.Graphics.GAL public SamplerCreateInfo( MinFilter minFilter, MagFilter magFilter, + bool seamlessCubemap, AddressMode addressU, AddressMode addressV, AddressMode addressP, @@ -33,18 +36,19 @@ namespace Ryujinx.Graphics.GAL float mipLodBias, float maxAnisotropy) { - MinFilter = minFilter; - MagFilter = magFilter; - AddressU = addressU; - AddressV = addressV; - AddressP = addressP; - CompareMode = compareMode; - CompareOp = compareOp; - BorderColor = borderColor; - MinLod = minLod; - MaxLod = maxLod; - MipLodBias = mipLodBias; - MaxAnisotropy = maxAnisotropy; + MinFilter = minFilter; + MagFilter = magFilter; + SeamlessCubemap = seamlessCubemap; + AddressU = addressU; + AddressV = addressV; + AddressP = addressP; + CompareMode = compareMode; + CompareOp = compareOp; + BorderColor = borderColor; + MinLod = minLod; + MaxLod = maxLod; + MipLodBias = mipLodBias; + MaxAnisotropy = maxAnisotropy; } } } \ No newline at end of file diff --git a/Ryujinx.Graphics.Gpu/Image/Sampler.cs b/Ryujinx.Graphics.Gpu/Image/Sampler.cs index 92c255e5..4c05329a 100644 --- a/Ryujinx.Graphics.Gpu/Image/Sampler.cs +++ b/Ryujinx.Graphics.Gpu/Image/Sampler.cs @@ -23,6 +23,8 @@ namespace Ryujinx.Graphics.Gpu.Image MinFilter minFilter = descriptor.UnpackMinFilter(); MagFilter magFilter = descriptor.UnpackMagFilter(); + bool seamlessCubemap = descriptor.UnpackSeamlessCubemap(); + AddressMode addressU = descriptor.UnpackAddressU(); AddressMode addressV = descriptor.UnpackAddressV(); AddressMode addressP = descriptor.UnpackAddressP(); @@ -49,6 +51,7 @@ namespace Ryujinx.Graphics.Gpu.Image HostSampler = context.Renderer.CreateSampler(new SamplerCreateInfo( minFilter, magFilter, + seamlessCubemap, addressU, addressV, addressP, diff --git a/Ryujinx.Graphics.Gpu/Image/SamplerDescriptor.cs b/Ryujinx.Graphics.Gpu/Image/SamplerDescriptor.cs index 9f5a847b..2c28b743 100644 --- a/Ryujinx.Graphics.Gpu/Image/SamplerDescriptor.cs +++ b/Ryujinx.Graphics.Gpu/Image/SamplerDescriptor.cs @@ -184,6 +184,15 @@ namespace Ryujinx.Graphics.Gpu.Image return MinFilter.Nearest; } + /// + /// Unpacks the seamless cubemap flag. + /// + /// The seamless cubemap flag + public bool UnpackSeamlessCubemap() + { + return (Word1 & (1 << 9)) != 0; + } + /// /// Unpacks the reduction filter, used with texture minification linear filtering. /// This describes how the final value will be computed from neighbouring pixels. diff --git a/Ryujinx.Graphics.OpenGL/HwCapabilities.cs b/Ryujinx.Graphics.OpenGL/HwCapabilities.cs index 9278c59e..b0d9a71e 100644 --- a/Ryujinx.Graphics.OpenGL/HwCapabilities.cs +++ b/Ryujinx.Graphics.OpenGL/HwCapabilities.cs @@ -5,10 +5,11 @@ namespace Ryujinx.Graphics.OpenGL { static class HwCapabilities { - private static readonly Lazy _supportsAstcCompression = new Lazy(() => HasExtension("GL_KHR_texture_compression_astc_ldr")); - private static readonly Lazy _supportsImageLoadFormatted = new Lazy(() => HasExtension("GL_EXT_shader_image_load_formatted")); - private static readonly Lazy _supportsPolygonOffsetClamp = new Lazy(() => HasExtension("GL_EXT_polygon_offset_clamp")); - private static readonly Lazy _supportsViewportSwizzle = new Lazy(() => HasExtension("GL_NV_viewport_swizzle")); + private static readonly Lazy _supportsAstcCompression = new Lazy(() => HasExtension("GL_KHR_texture_compression_astc_ldr")); + private static readonly Lazy _supportsImageLoadFormatted = new Lazy(() => HasExtension("GL_EXT_shader_image_load_formatted")); + private static readonly Lazy _supportsPolygonOffsetClamp = new Lazy(() => HasExtension("GL_EXT_polygon_offset_clamp")); + private static readonly Lazy _supportsViewportSwizzle = new Lazy(() => HasExtension("GL_NV_viewport_swizzle")); + private static readonly Lazy _supportsSeamlessCubemapPerTexture = new Lazy(() => HasExtension("GL_ARB_seamless_cubemap_per_texture")); private static readonly Lazy _maximumComputeSharedMemorySize = new Lazy(() => GetLimit(All.MaxComputeSharedMemorySize)); private static readonly Lazy _storageBufferOffsetAlignment = new Lazy(() => GetLimit(All.ShaderStorageBufferOffsetAlignment)); @@ -27,11 +28,12 @@ namespace Ryujinx.Graphics.OpenGL private static Lazy _maxSupportedAnisotropy = new Lazy(GL.GetFloat((GetPName)All.MaxTextureMaxAnisotropy)); - public static bool SupportsAstcCompression => _supportsAstcCompression.Value; - public static bool SupportsImageLoadFormatted => _supportsImageLoadFormatted.Value; - public static bool SupportsPolygonOffsetClamp => _supportsPolygonOffsetClamp.Value; - public static bool SupportsViewportSwizzle => _supportsViewportSwizzle.Value; - public static bool SupportsNonConstantTextureOffset => _gpuVendor.Value == GpuVendor.Nvidia; + public static bool SupportsAstcCompression => _supportsAstcCompression.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 SupportsNonConstantTextureOffset => _gpuVendor.Value == GpuVendor.Nvidia; public static int MaximumComputeSharedMemorySize => _maximumComputeSharedMemorySize.Value; public static int StorageBufferOffsetAlignment => _storageBufferOffsetAlignment.Value; diff --git a/Ryujinx.Graphics.OpenGL/Image/Sampler.cs b/Ryujinx.Graphics.OpenGL/Image/Sampler.cs index e13f0da3..f705aa3e 100644 --- a/Ryujinx.Graphics.OpenGL/Image/Sampler.cs +++ b/Ryujinx.Graphics.OpenGL/Image/Sampler.cs @@ -14,6 +14,11 @@ namespace Ryujinx.Graphics.OpenGL.Image GL.SamplerParameter(Handle, SamplerParameterName.TextureMinFilter, (int)info.MinFilter.Convert()); GL.SamplerParameter(Handle, SamplerParameterName.TextureMagFilter, (int)info.MagFilter.Convert()); + if (HwCapabilities.SupportsSeamlessCubemapPerTexture) + { + GL.SamplerParameter(Handle, (SamplerParameterName)ArbSeamlessCubemapPerTexture.TextureCubeMapSeamless, info.SeamlessCubemap ? 1 : 0); + } + GL.SamplerParameter(Handle, SamplerParameterName.TextureWrapS, (int)info.AddressU.Convert()); GL.SamplerParameter(Handle, SamplerParameterName.TextureWrapT, (int)info.AddressV.Convert()); GL.SamplerParameter(Handle, SamplerParameterName.TextureWrapR, (int)info.AddressP.Convert());