mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-01-07 16:33:05 +00:00
OpenGL namespace is all done!
This commit is contained in:
parent
15978d9c55
commit
5db3568305
10 changed files with 471 additions and 417 deletions
|
@ -78,7 +78,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
return new PinnedSpan<byte>(IntPtr.Add(ptr, offset).ToPointer(), size);
|
return new PinnedSpan<byte>(IntPtr.Add(ptr, offset).ToPointer(), size);
|
||||||
}
|
}
|
||||||
else if (HwCapabilities.UsePersistentBufferForFlush)
|
else if (gd.Capabilities.UsePersistentBufferForFlush)
|
||||||
{
|
{
|
||||||
return PinnedSpan<byte>.UnsafeFromSpan(gd.PersistentBuffers.Default.GetBufferData(buffer, offset, size));
|
return PinnedSpan<byte>.UnsafeFromSpan(gd.PersistentBuffers.Default.GetBufferData(buffer, offset, size));
|
||||||
}
|
}
|
||||||
|
|
161
src/Ryujinx.Graphics.OpenGL/HardwareCapabilities.cs
Normal file
161
src/Ryujinx.Graphics.OpenGL/HardwareCapabilities.cs
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
using Silk.NET.OpenGL.Legacy;
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.OpenGL
|
||||||
|
{
|
||||||
|
public enum GpuVendor
|
||||||
|
{
|
||||||
|
Unknown,
|
||||||
|
AmdWindows,
|
||||||
|
AmdUnix,
|
||||||
|
IntelWindows,
|
||||||
|
IntelUnix,
|
||||||
|
Nvidia,
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly struct HardwareCapabilities
|
||||||
|
{
|
||||||
|
public readonly bool SupportsAlphaToCoverageDitherControl;
|
||||||
|
public readonly bool SupportsAstcCompression;
|
||||||
|
public readonly bool SupportsBlendEquationAdvanced;
|
||||||
|
public readonly bool SupportsDrawTexture;
|
||||||
|
public readonly bool SupportsFragmentShaderInterlock;
|
||||||
|
public readonly bool SupportsFragmentShaderOrdering;
|
||||||
|
public readonly bool SupportsGeometryShaderPassthrough;
|
||||||
|
public readonly bool SupportsImageLoadFormatted;
|
||||||
|
public readonly bool SupportsIndirectParameters;
|
||||||
|
public readonly bool SupportsParallelShaderCompile;
|
||||||
|
public readonly bool SupportsPolygonOffsetClamp;
|
||||||
|
public readonly bool SupportsQuads;
|
||||||
|
public readonly bool SupportsSeamlessCubemapPerTexture;
|
||||||
|
public readonly bool SupportsShaderBallot;
|
||||||
|
public readonly bool SupportsShaderViewportLayerArray;
|
||||||
|
public readonly bool SupportsViewportArray2;
|
||||||
|
public readonly bool SupportsTextureCompressionBptc;
|
||||||
|
public readonly bool SupportsTextureCompressionRgtc;
|
||||||
|
public readonly bool SupportsTextureCompressionS3tc;
|
||||||
|
public readonly bool SupportsTextureShadowLod;
|
||||||
|
public readonly bool SupportsViewportSwizzle;
|
||||||
|
|
||||||
|
public bool SupportsMismatchingViewFormat => GpuVendor != GpuVendor.AmdWindows && GpuVendor != GpuVendor.IntelWindows;
|
||||||
|
public bool SupportsNonConstantTextureOffset => GpuVendor == GpuVendor.Nvidia;
|
||||||
|
public bool RequiresSyncFlush => GpuVendor == GpuVendor.AmdWindows || IsIntel;
|
||||||
|
public bool UsePersistentBufferForFlush => GpuVendor == GpuVendor.AmdWindows || GpuVendor == GpuVendor.Nvidia;
|
||||||
|
|
||||||
|
public readonly int MaximumComputeSharedMemorySize;
|
||||||
|
public readonly int StorageBufferOffsetAlignment;
|
||||||
|
public readonly int TextureBufferOffsetAlignment;
|
||||||
|
|
||||||
|
public readonly float MaximumSupportedAnisotropy;
|
||||||
|
|
||||||
|
public readonly GpuVendor GpuVendor;
|
||||||
|
|
||||||
|
public HardwareCapabilities(
|
||||||
|
bool supportsAlphaToCoverageDitherControl,
|
||||||
|
bool supportsAstcCompression,
|
||||||
|
bool supportsBlendEquationAdvanced,
|
||||||
|
bool supportsDrawTexture,
|
||||||
|
bool supportsFragmentShaderInterlock,
|
||||||
|
bool supportsFragmentShaderOrdering,
|
||||||
|
bool supportsGeometryShaderPassthrough,
|
||||||
|
bool supportsImageLoadFormatted,
|
||||||
|
bool supportsIndirectParameters,
|
||||||
|
bool supportsParallelShaderCompile,
|
||||||
|
bool supportsPolygonOffsetClamp,
|
||||||
|
bool supportsQuads,
|
||||||
|
bool supportsSeamlessCubemapPerTexture,
|
||||||
|
bool supportsShaderBallot,
|
||||||
|
bool supportsShaderViewportLayerArray,
|
||||||
|
bool supportsViewportArray2,
|
||||||
|
bool supportsTextureCompressionBptc,
|
||||||
|
bool supportsTextureCompressionRgtc,
|
||||||
|
bool supportsTextureCompressionS3Tc,
|
||||||
|
bool supportsTextureShadowLod,
|
||||||
|
bool supportsViewportSwizzle,
|
||||||
|
int maximumComputeSharedMemorySize,
|
||||||
|
int storageBufferOffsetAlignment,
|
||||||
|
int textureBufferOffsetAlignment,
|
||||||
|
float maximumSupportedAnisotropy,
|
||||||
|
GpuVendor gpuVendor)
|
||||||
|
{
|
||||||
|
SupportsAlphaToCoverageDitherControl = supportsAlphaToCoverageDitherControl;
|
||||||
|
SupportsAstcCompression = supportsAstcCompression;
|
||||||
|
SupportsBlendEquationAdvanced = supportsBlendEquationAdvanced;
|
||||||
|
SupportsDrawTexture = supportsDrawTexture;
|
||||||
|
SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock;
|
||||||
|
SupportsFragmentShaderOrdering = supportsFragmentShaderOrdering;
|
||||||
|
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
|
||||||
|
SupportsImageLoadFormatted = supportsImageLoadFormatted;
|
||||||
|
SupportsIndirectParameters = supportsIndirectParameters;
|
||||||
|
SupportsParallelShaderCompile = supportsParallelShaderCompile;
|
||||||
|
SupportsPolygonOffsetClamp = supportsPolygonOffsetClamp;
|
||||||
|
SupportsQuads = supportsQuads;
|
||||||
|
SupportsSeamlessCubemapPerTexture = supportsSeamlessCubemapPerTexture;
|
||||||
|
SupportsShaderBallot = supportsShaderBallot;
|
||||||
|
SupportsShaderViewportLayerArray = supportsShaderViewportLayerArray;
|
||||||
|
SupportsViewportArray2 = supportsViewportArray2;
|
||||||
|
SupportsTextureCompressionBptc = supportsTextureCompressionBptc;
|
||||||
|
SupportsTextureCompressionRgtc = supportsTextureCompressionRgtc;
|
||||||
|
SupportsTextureCompressionS3tc = supportsTextureCompressionS3Tc;
|
||||||
|
SupportsTextureShadowLod = supportsTextureShadowLod;
|
||||||
|
SupportsViewportSwizzle = supportsViewportSwizzle;
|
||||||
|
MaximumComputeSharedMemorySize = maximumComputeSharedMemorySize;
|
||||||
|
StorageBufferOffsetAlignment = storageBufferOffsetAlignment;
|
||||||
|
TextureBufferOffsetAlignment = textureBufferOffsetAlignment;
|
||||||
|
MaximumSupportedAnisotropy = maximumSupportedAnisotropy;
|
||||||
|
GpuVendor = gpuVendor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsIntel => GpuVendor == GpuVendor.IntelWindows || GpuVendor == GpuVendor.IntelUnix;
|
||||||
|
|
||||||
|
public static unsafe bool HasExtension(GL api, string name)
|
||||||
|
{
|
||||||
|
int numExtensions = api.GetInteger(GetPName.NumExtensions);
|
||||||
|
|
||||||
|
for (uint extension = 0; extension < numExtensions; extension++)
|
||||||
|
{
|
||||||
|
if (Marshal.PtrToStringAnsi((IntPtr)api.GetString(StringName.Extensions, extension)) == name)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe GpuVendor GetGpuVendor(GL api)
|
||||||
|
{
|
||||||
|
string vendor = Marshal.PtrToStringAnsi((IntPtr)api.GetString(StringName.Vendor)).ToLowerInvariant();
|
||||||
|
|
||||||
|
switch (vendor)
|
||||||
|
{
|
||||||
|
case "nvidia corporation":
|
||||||
|
return GpuVendor.Nvidia;
|
||||||
|
case "intel":
|
||||||
|
{
|
||||||
|
string renderer = Marshal.PtrToStringAnsi((IntPtr)api.GetString(StringName.Renderer)).ToLowerInvariant();
|
||||||
|
|
||||||
|
return renderer.Contains("mesa") ? GpuVendor.IntelUnix : GpuVendor.IntelWindows;
|
||||||
|
}
|
||||||
|
case "ati technologies inc.":
|
||||||
|
case "advanced micro devices, inc.":
|
||||||
|
return GpuVendor.AmdWindows;
|
||||||
|
case "amd":
|
||||||
|
case "x.org":
|
||||||
|
return GpuVendor.AmdUnix;
|
||||||
|
default:
|
||||||
|
return GpuVendor.Unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool SupportsQuadsCheck(GL api)
|
||||||
|
{
|
||||||
|
api.GetError(); // Clear any existing error.
|
||||||
|
api.Begin(PrimitiveType.Quads);
|
||||||
|
api.End();
|
||||||
|
|
||||||
|
return api.GetError() == GLEnum.NoError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,143 +0,0 @@
|
||||||
using Silk.NET.OpenGL.Legacy;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.OpenGL
|
|
||||||
{
|
|
||||||
static class HwCapabilities
|
|
||||||
{
|
|
||||||
private static readonly Lazy<bool> _supportsAlphaToCoverageDitherControl = new(() => HasExtension("GL_NV_alpha_to_coverage_dither_control"));
|
|
||||||
private static readonly Lazy<bool> _supportsAstcCompression = new(() => HasExtension("GL_KHR_texture_compression_astc_ldr"));
|
|
||||||
private static readonly Lazy<bool> _supportsBlendEquationAdvanced = new(() => HasExtension("GL_NV_blend_equation_advanced"));
|
|
||||||
private static readonly Lazy<bool> _supportsDrawTexture = new(() => HasExtension("GL_NV_draw_texture"));
|
|
||||||
private static readonly Lazy<bool> _supportsFragmentShaderInterlock = new(() => HasExtension("GL_ARB_fragment_shader_interlock"));
|
|
||||||
private static readonly Lazy<bool> _supportsFragmentShaderOrdering = new(() => HasExtension("GL_INTEL_fragment_shader_ordering"));
|
|
||||||
private static readonly Lazy<bool> _supportsGeometryShaderPassthrough = new(() => HasExtension("GL_NV_geometry_shader_passthrough"));
|
|
||||||
private static readonly Lazy<bool> _supportsImageLoadFormatted = new(() => HasExtension("GL_EXT_shader_image_load_formatted"));
|
|
||||||
private static readonly Lazy<bool> _supportsIndirectParameters = new(() => HasExtension("GL_ARB_indirect_parameters"));
|
|
||||||
private static readonly Lazy<bool> _supportsParallelShaderCompile = new(() => HasExtension("GL_ARB_parallel_shader_compile"));
|
|
||||||
private static readonly Lazy<bool> _supportsPolygonOffsetClamp = new(() => HasExtension("GL_EXT_polygon_offset_clamp"));
|
|
||||||
private static readonly Lazy<bool> _supportsQuads = new(SupportsQuadsCheck);
|
|
||||||
private static readonly Lazy<bool> _supportsSeamlessCubemapPerTexture = new(() => HasExtension("GL_ARB_seamless_cubemap_per_texture"));
|
|
||||||
private static readonly Lazy<bool> _supportsShaderBallot = new(() => HasExtension("GL_ARB_shader_ballot"));
|
|
||||||
private static readonly Lazy<bool> _supportsShaderViewportLayerArray = new(() => HasExtension("GL_ARB_shader_viewport_layer_array"));
|
|
||||||
private static readonly Lazy<bool> _supportsViewportArray2 = new(() => HasExtension("GL_NV_viewport_array2"));
|
|
||||||
private static readonly Lazy<bool> _supportsTextureCompressionBptc = new(() => HasExtension("GL_EXT_texture_compression_bptc"));
|
|
||||||
private static readonly Lazy<bool> _supportsTextureCompressionRgtc = new(() => HasExtension("GL_EXT_texture_compression_rgtc"));
|
|
||||||
private static readonly Lazy<bool> _supportsTextureCompressionS3tc = new(() => HasExtension("GL_EXT_texture_compression_s3tc"));
|
|
||||||
private static readonly Lazy<bool> _supportsTextureShadowLod = new(() => HasExtension("GL_EXT_texture_shadow_lod"));
|
|
||||||
private static readonly Lazy<bool> _supportsViewportSwizzle = new(() => HasExtension("GL_NV_viewport_swizzle"));
|
|
||||||
|
|
||||||
private static readonly Lazy<int> _maximumComputeSharedMemorySize = new(() => GetLimit(GLEnum.MaxComputeSharedMemorySize));
|
|
||||||
private static readonly Lazy<int> _storageBufferOffsetAlignment = new(() => GetLimit(GLEnum.ShaderStorageBufferOffsetAlignment));
|
|
||||||
private static readonly Lazy<int> _textureBufferOffsetAlignment = new(() => GetLimit(GLEnum.TextureBufferOffsetAlignment));
|
|
||||||
|
|
||||||
public enum GpuVendor
|
|
||||||
{
|
|
||||||
Unknown,
|
|
||||||
AmdWindows,
|
|
||||||
AmdUnix,
|
|
||||||
IntelWindows,
|
|
||||||
IntelUnix,
|
|
||||||
Nvidia,
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly Lazy<GpuVendor> _gpuVendor = new(GetGpuVendor);
|
|
||||||
|
|
||||||
private static bool IsIntel => _gpuVendor.Value == GpuVendor.IntelWindows || _gpuVendor.Value == GpuVendor.IntelUnix;
|
|
||||||
|
|
||||||
public static GpuVendor Vendor => _gpuVendor.Value;
|
|
||||||
|
|
||||||
private static readonly Lazy<float> _maxSupportedAnisotropy = new(GL.GetFloat((GetPName)GLEnum.MaxTextureMaxAnisotropy));
|
|
||||||
|
|
||||||
public static bool UsePersistentBufferForFlush => _gpuVendor.Value == GpuVendor.AmdWindows || _gpuVendor.Value == GpuVendor.Nvidia;
|
|
||||||
|
|
||||||
public static bool SupportsAlphaToCoverageDitherControl => _supportsAlphaToCoverageDitherControl.Value;
|
|
||||||
public static bool SupportsAstcCompression => _supportsAstcCompression.Value;
|
|
||||||
public static bool SupportsBlendEquationAdvanced => _supportsBlendEquationAdvanced.Value;
|
|
||||||
public static bool SupportsDrawTexture => _supportsDrawTexture.Value;
|
|
||||||
public static bool SupportsFragmentShaderInterlock => _supportsFragmentShaderInterlock.Value;
|
|
||||||
public static bool SupportsFragmentShaderOrdering => _supportsFragmentShaderOrdering.Value;
|
|
||||||
public static bool SupportsGeometryShaderPassthrough => _supportsGeometryShaderPassthrough.Value;
|
|
||||||
public static bool SupportsImageLoadFormatted => _supportsImageLoadFormatted.Value;
|
|
||||||
public static bool SupportsIndirectParameters => _supportsIndirectParameters.Value;
|
|
||||||
public static bool SupportsParallelShaderCompile => _supportsParallelShaderCompile.Value;
|
|
||||||
public static bool SupportsPolygonOffsetClamp => _supportsPolygonOffsetClamp.Value;
|
|
||||||
public static bool SupportsQuads => _supportsQuads.Value;
|
|
||||||
public static bool SupportsSeamlessCubemapPerTexture => _supportsSeamlessCubemapPerTexture.Value;
|
|
||||||
public static bool SupportsShaderBallot => _supportsShaderBallot.Value;
|
|
||||||
public static bool SupportsShaderViewportLayerArray => _supportsShaderViewportLayerArray.Value;
|
|
||||||
public static bool SupportsViewportArray2 => _supportsViewportArray2.Value;
|
|
||||||
public static bool SupportsTextureCompressionBptc => _supportsTextureCompressionBptc.Value;
|
|
||||||
public static bool SupportsTextureCompressionRgtc => _supportsTextureCompressionRgtc.Value;
|
|
||||||
public static bool SupportsTextureCompressionS3tc => _supportsTextureCompressionS3tc.Value;
|
|
||||||
public static bool SupportsTextureShadowLod => _supportsTextureShadowLod.Value;
|
|
||||||
public static bool SupportsViewportSwizzle => _supportsViewportSwizzle.Value;
|
|
||||||
|
|
||||||
public static bool SupportsMismatchingViewFormat => _gpuVendor.Value != GpuVendor.AmdWindows && _gpuVendor.Value != GpuVendor.IntelWindows;
|
|
||||||
public static bool SupportsNonConstantTextureOffset => _gpuVendor.Value == GpuVendor.Nvidia;
|
|
||||||
public static bool RequiresSyncFlush => _gpuVendor.Value == GpuVendor.AmdWindows || IsIntel;
|
|
||||||
|
|
||||||
public static int MaximumComputeSharedMemorySize => _maximumComputeSharedMemorySize.Value;
|
|
||||||
public static int StorageBufferOffsetAlignment => _storageBufferOffsetAlignment.Value;
|
|
||||||
public static int TextureBufferOffsetAlignment => _textureBufferOffsetAlignment.Value;
|
|
||||||
|
|
||||||
public static float MaximumSupportedAnisotropy => _maxSupportedAnisotropy.Value;
|
|
||||||
|
|
||||||
private static bool HasExtension(string name)
|
|
||||||
{
|
|
||||||
int numExtensions = GL.GetInteger(GetPName.NumExtensions);
|
|
||||||
|
|
||||||
for (int extension = 0; extension < numExtensions; extension++)
|
|
||||||
{
|
|
||||||
if (GL.GetString(StringNameIndexed.Extensions, extension) == name)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int GetLimit(GLEnum name)
|
|
||||||
{
|
|
||||||
return GL.GetInteger((GetPName)name);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static GpuVendor GetGpuVendor()
|
|
||||||
{
|
|
||||||
string vendor = GL.GetString(StringName.Vendor).ToLowerInvariant();
|
|
||||||
|
|
||||||
if (vendor == "nvidia corporation")
|
|
||||||
{
|
|
||||||
return GpuVendor.Nvidia;
|
|
||||||
}
|
|
||||||
else if (vendor == "intel")
|
|
||||||
{
|
|
||||||
string renderer = GL.GetString(StringName.Renderer).ToLowerInvariant();
|
|
||||||
|
|
||||||
return renderer.Contains("mesa") ? GpuVendor.IntelUnix : GpuVendor.IntelWindows;
|
|
||||||
}
|
|
||||||
else if (vendor == "ati technologies inc." || vendor == "advanced micro devices, inc.")
|
|
||||||
{
|
|
||||||
return GpuVendor.AmdWindows;
|
|
||||||
}
|
|
||||||
else if (vendor == "amd" || vendor == "x.org")
|
|
||||||
{
|
|
||||||
return GpuVendor.AmdUnix;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return GpuVendor.Unknown;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool SupportsQuadsCheck(GL api)
|
|
||||||
{
|
|
||||||
api.GetError(); // Clear any existing error.
|
|
||||||
api.Begin(PrimitiveType.Quads);
|
|
||||||
api.End();
|
|
||||||
|
|
||||||
return api.GetError() == ErrorCode.NoError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,27 +6,27 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
||||||
class Sampler : ISampler
|
class Sampler : ISampler
|
||||||
{
|
{
|
||||||
public uint Handle { get; private set; }
|
public uint Handle { get; private set; }
|
||||||
private readonly GL _api;
|
private readonly OpenGLRenderer _gd;
|
||||||
|
|
||||||
public Sampler(GL api, SamplerCreateInfo info)
|
public Sampler(OpenGLRenderer gd, SamplerCreateInfo info)
|
||||||
{
|
{
|
||||||
_api = api;
|
_gd = gd;
|
||||||
Handle = _api.GenSampler();
|
Handle = _gd.Api.GenSampler();
|
||||||
|
|
||||||
_api.SamplerParameter(Handle, SamplerParameterI.MinFilter, (int)info.MinFilter.Convert());
|
_gd.Api.SamplerParameter(Handle, SamplerParameterI.MinFilter, (int)info.MinFilter.Convert());
|
||||||
_api.SamplerParameter(Handle, SamplerParameterI.MagFilter, (int)info.MagFilter.Convert());
|
_gd.Api.SamplerParameter(Handle, SamplerParameterI.MagFilter, (int)info.MagFilter.Convert());
|
||||||
|
|
||||||
if (HwCapabilities.SupportsSeamlessCubemapPerTexture)
|
if (_gd.Capabilities.SupportsSeamlessCubemapPerTexture)
|
||||||
{
|
{
|
||||||
_api.SamplerParameter(Handle, GLEnum.TextureCubeMapSeamless, info.SeamlessCubemap ? 1 : 0);
|
_gd.Api.SamplerParameter(Handle, GLEnum.TextureCubeMapSeamless, info.SeamlessCubemap ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
_api.SamplerParameter(Handle, SamplerParameterI.WrapS, (int)info.AddressU.Convert());
|
_gd.Api.SamplerParameter(Handle, SamplerParameterI.WrapS, (int)info.AddressU.Convert());
|
||||||
_api.SamplerParameter(Handle, SamplerParameterI.WrapT, (int)info.AddressV.Convert());
|
_gd.Api.SamplerParameter(Handle, SamplerParameterI.WrapT, (int)info.AddressV.Convert());
|
||||||
_api.SamplerParameter(Handle, SamplerParameterI.WrapR, (int)info.AddressP.Convert());
|
_gd.Api.SamplerParameter(Handle, SamplerParameterI.WrapR, (int)info.AddressP.Convert());
|
||||||
|
|
||||||
_api.SamplerParameter(Handle, SamplerParameterI.CompareMode, (int)info.CompareMode.Convert());
|
_gd.Api.SamplerParameter(Handle, SamplerParameterI.CompareMode, (int)info.CompareMode.Convert());
|
||||||
_api.SamplerParameter(Handle, SamplerParameterI.CompareFunc, (int)info.CompareOp.Convert());
|
_gd.Api.SamplerParameter(Handle, SamplerParameterI.CompareFunc, (int)info.CompareOp.Convert());
|
||||||
|
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
|
@ -38,26 +38,26 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
||||||
info.BorderColor.Alpha,
|
info.BorderColor.Alpha,
|
||||||
};
|
};
|
||||||
|
|
||||||
_api.SamplerParameter(Handle, SamplerParameterF.BorderColor, borderColor);
|
_gd.Api.SamplerParameter(Handle, SamplerParameterF.BorderColor, borderColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
_api.SamplerParameter(Handle, SamplerParameterF.MinLod, info.MinLod);
|
_gd.Api.SamplerParameter(Handle, SamplerParameterF.MinLod, info.MinLod);
|
||||||
_api.SamplerParameter(Handle, SamplerParameterF.MaxLod, info.MaxLod);
|
_gd.Api.SamplerParameter(Handle, SamplerParameterF.MaxLod, info.MaxLod);
|
||||||
_api.SamplerParameter(Handle, SamplerParameterF.LodBias, info.MipLodBias);
|
_gd.Api.SamplerParameter(Handle, SamplerParameterF.LodBias, info.MipLodBias);
|
||||||
|
|
||||||
_api.SamplerParameter(Handle, SamplerParameterF.MaxAnisotropy, info.MaxAnisotropy);
|
_gd.Api.SamplerParameter(Handle, SamplerParameterF.MaxAnisotropy, info.MaxAnisotropy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Bind(uint unit)
|
public void Bind(uint unit)
|
||||||
{
|
{
|
||||||
_api.BindSampler(unit, Handle);
|
_gd.Api.BindSampler(unit, Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (Handle != 0)
|
if (Handle != 0)
|
||||||
{
|
{
|
||||||
_api.DeleteSampler(Handle);
|
_gd.Api.DeleteSampler(Handle);
|
||||||
|
|
||||||
Handle = 0;
|
Handle = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,7 +238,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
||||||
int copyWidth = sizeInBlocks ? BitUtils.DivRoundUp(width, blockWidth) : width;
|
int copyWidth = sizeInBlocks ? BitUtils.DivRoundUp(width, blockWidth) : width;
|
||||||
int copyHeight = sizeInBlocks ? BitUtils.DivRoundUp(height, blockHeight) : height;
|
int copyHeight = sizeInBlocks ? BitUtils.DivRoundUp(height, blockHeight) : height;
|
||||||
|
|
||||||
if (HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows)
|
if (_gd.Capabilities.GpuVendor == GpuVendor.IntelWindows)
|
||||||
{
|
{
|
||||||
_gd.Api.CopyImageSubData(
|
_gd.Api.CopyImageSubData(
|
||||||
src.Storage.Handle,
|
src.Storage.Handle,
|
||||||
|
|
|
@ -273,7 +273,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
||||||
|
|
||||||
ReadOnlySpan<byte> data;
|
ReadOnlySpan<byte> data;
|
||||||
|
|
||||||
if (HwCapabilities.UsePersistentBufferForFlush)
|
if (_gd.Capabilities.UsePersistentBufferForFlush)
|
||||||
{
|
{
|
||||||
data = _gd.PersistentBuffers.Default.GetTextureData(this, size);
|
data = _gd.PersistentBuffers.Default.GetTextureData(this, size);
|
||||||
}
|
}
|
||||||
|
@ -298,7 +298,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
||||||
{
|
{
|
||||||
int size = Info.GetMipSize(level);
|
int size = Info.GetMipSize(level);
|
||||||
|
|
||||||
if (HwCapabilities.UsePersistentBufferForFlush)
|
if (_gd.Capabilities.UsePersistentBufferForFlush)
|
||||||
{
|
{
|
||||||
return PinnedSpan<byte>.UnsafeFromSpan(_gd.PersistentBuffers.Default.GetTextureData(this, size, layer, level));
|
return PinnedSpan<byte>.UnsafeFromSpan(_gd.PersistentBuffers.Default.GetTextureData(this, size, layer, level));
|
||||||
}
|
}
|
||||||
|
@ -719,7 +719,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
||||||
uint baseLevel = 0;
|
uint baseLevel = 0;
|
||||||
|
|
||||||
// glTexSubImage on cubemap views is broken on Intel, we have to use the storage instead.
|
// glTexSubImage on cubemap views is broken on Intel, we have to use the storage instead.
|
||||||
if (Target == Target.Cubemap && HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows)
|
if (Target == Target.Cubemap && _gd.Capabilities.GpuVendor == GpuVendor.IntelWindows)
|
||||||
{
|
{
|
||||||
_gd.Api.ActiveTexture(TextureUnit.Texture0);
|
_gd.Api.ActiveTexture(TextureUnit.Texture0);
|
||||||
_gd.Api.BindTexture(target, Storage.Handle);
|
_gd.Api.BindTexture(target, Storage.Handle);
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
using Silk.NET.OpenGL.Legacy;
|
using Silk.NET.OpenGL.Legacy;
|
||||||
|
using Silk.NET.OpenGL.Legacy.Extensions.ARB;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.OpenGL.Image;
|
using Ryujinx.Graphics.OpenGL.Image;
|
||||||
using Ryujinx.Graphics.OpenGL.Queries;
|
using Ryujinx.Graphics.OpenGL.Queries;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
using Silk.NET.OpenGL.Legacy.Extensions.ARB;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Sampler = Ryujinx.Graphics.OpenGL.Image.Sampler;
|
using Sampler = Ryujinx.Graphics.OpenGL.Image.Sampler;
|
||||||
|
@ -41,6 +41,8 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
internal int BufferCount { get; private set; }
|
internal int BufferCount { get; private set; }
|
||||||
|
|
||||||
|
internal HardwareCapabilities Capabilities;
|
||||||
|
|
||||||
public string GpuVendor { get; private set; }
|
public string GpuVendor { get; private set; }
|
||||||
public string GpuRenderer { get; private set; }
|
public string GpuRenderer { get; private set; }
|
||||||
public string GpuVersion { get; private set; }
|
public string GpuVersion { get; private set; }
|
||||||
|
@ -50,14 +52,14 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
public OpenGLRenderer(GL api)
|
public OpenGLRenderer(GL api)
|
||||||
{
|
{
|
||||||
Api = api;
|
Api = api;
|
||||||
_pipeline = new Pipeline(Api);
|
_pipeline = new Pipeline(this);
|
||||||
_counters = new Counters(Api);
|
_counters = new Counters(Api);
|
||||||
_window = new Window(this);
|
_window = new Window(this);
|
||||||
_textureCopy = new TextureCopy(this);
|
_textureCopy = new TextureCopy(this);
|
||||||
_backgroundTextureCopy = new TextureCopy(this);
|
_backgroundTextureCopy = new TextureCopy(this);
|
||||||
TextureCopyIncompatible = new TextureCopyIncompatible(this);
|
TextureCopyIncompatible = new TextureCopyIncompatible(this);
|
||||||
TextureCopyMS = new TextureCopyMS(this);
|
TextureCopyMS = new TextureCopyMS(this);
|
||||||
_sync = new Sync(Api);
|
_sync = new Sync(this);
|
||||||
PersistentBuffers = new PersistentBuffers(Api);
|
PersistentBuffers = new PersistentBuffers(Api);
|
||||||
ResourcePool = new ResourcePool();
|
ResourcePool = new ResourcePool();
|
||||||
}
|
}
|
||||||
|
@ -102,12 +104,12 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info)
|
public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info)
|
||||||
{
|
{
|
||||||
return new Program(Api, shaders, info.FragmentOutputMap);
|
return new Program(this, shaders, info.FragmentOutputMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ISampler CreateSampler(SamplerCreateInfo info)
|
public ISampler CreateSampler(SamplerCreateInfo info)
|
||||||
{
|
{
|
||||||
return new Sampler(Api, info);
|
return new Sampler(this, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ITexture CreateTexture(TextureCreateInfo info)
|
public ITexture CreateTexture(TextureCreateInfo info)
|
||||||
|
@ -146,9 +148,9 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
public Capabilities GetCapabilities()
|
public Capabilities GetCapabilities()
|
||||||
{
|
{
|
||||||
bool intelWindows = HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows;
|
bool intelWindows = Capabilities.GpuVendor == OpenGL.GpuVendor.IntelWindows;
|
||||||
bool intelUnix = HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelUnix;
|
bool intelUnix = Capabilities.GpuVendor == OpenGL.GpuVendor.IntelUnix;
|
||||||
bool amdWindows = HwCapabilities.Vendor == HwCapabilities.GpuVendor.AmdWindows;
|
bool amdWindows = Capabilities.GpuVendor == OpenGL.GpuVendor.AmdWindows;
|
||||||
|
|
||||||
return new Capabilities(
|
return new Capabilities(
|
||||||
api: TargetApi.OpenGL,
|
api: TargetApi.OpenGL,
|
||||||
|
@ -157,9 +159,9 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
hasVectorIndexingBug: amdWindows,
|
hasVectorIndexingBug: amdWindows,
|
||||||
needsFragmentOutputSpecialization: false,
|
needsFragmentOutputSpecialization: false,
|
||||||
reduceShaderPrecision: false,
|
reduceShaderPrecision: false,
|
||||||
supportsAstcCompression: HwCapabilities.SupportsAstcCompression,
|
supportsAstcCompression: Capabilities.SupportsAstcCompression,
|
||||||
supportsBc123Compression: HwCapabilities.SupportsTextureCompressionS3tc,
|
supportsBc123Compression: Capabilities.SupportsTextureCompressionS3tc,
|
||||||
supportsBc45Compression: HwCapabilities.SupportsTextureCompressionRgtc,
|
supportsBc45Compression: Capabilities.SupportsTextureCompressionRgtc,
|
||||||
supportsBc67Compression: true, // Should check BPTC extension, but for some reason NVIDIA is not exposing the extension.
|
supportsBc67Compression: true, // Should check BPTC extension, but for some reason NVIDIA is not exposing the extension.
|
||||||
supportsEtc2Compression: true,
|
supportsEtc2Compression: true,
|
||||||
supports3DTextureCompression: false,
|
supports3DTextureCompression: false,
|
||||||
|
@ -169,39 +171,39 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
supportsSnormBufferTextureFormat: false,
|
supportsSnormBufferTextureFormat: false,
|
||||||
supports5BitComponentFormat: true,
|
supports5BitComponentFormat: true,
|
||||||
supportsSparseBuffer: false,
|
supportsSparseBuffer: false,
|
||||||
supportsBlendEquationAdvanced: HwCapabilities.SupportsBlendEquationAdvanced,
|
supportsBlendEquationAdvanced: Capabilities.SupportsBlendEquationAdvanced,
|
||||||
supportsFragmentShaderInterlock: HwCapabilities.SupportsFragmentShaderInterlock,
|
supportsFragmentShaderInterlock: Capabilities.SupportsFragmentShaderInterlock,
|
||||||
supportsFragmentShaderOrderingIntel: HwCapabilities.SupportsFragmentShaderOrdering,
|
supportsFragmentShaderOrderingIntel: Capabilities.SupportsFragmentShaderOrdering,
|
||||||
supportsGeometryShader: true,
|
supportsGeometryShader: true,
|
||||||
supportsGeometryShaderPassthrough: HwCapabilities.SupportsGeometryShaderPassthrough,
|
supportsGeometryShaderPassthrough: Capabilities.SupportsGeometryShaderPassthrough,
|
||||||
supportsTransformFeedback: true,
|
supportsTransformFeedback: true,
|
||||||
supportsImageLoadFormatted: HwCapabilities.SupportsImageLoadFormatted,
|
supportsImageLoadFormatted: Capabilities.SupportsImageLoadFormatted,
|
||||||
supportsLayerVertexTessellation: HwCapabilities.SupportsShaderViewportLayerArray,
|
supportsLayerVertexTessellation: Capabilities.SupportsShaderViewportLayerArray,
|
||||||
supportsMismatchingViewFormat: HwCapabilities.SupportsMismatchingViewFormat,
|
supportsMismatchingViewFormat: Capabilities.SupportsMismatchingViewFormat,
|
||||||
supportsCubemapView: true,
|
supportsCubemapView: true,
|
||||||
supportsNonConstantTextureOffset: HwCapabilities.SupportsNonConstantTextureOffset,
|
supportsNonConstantTextureOffset: Capabilities.SupportsNonConstantTextureOffset,
|
||||||
supportsScaledVertexFormats: true,
|
supportsScaledVertexFormats: true,
|
||||||
supportsSeparateSampler: false,
|
supportsSeparateSampler: false,
|
||||||
supportsShaderBallot: HwCapabilities.SupportsShaderBallot,
|
supportsShaderBallot: Capabilities.SupportsShaderBallot,
|
||||||
supportsShaderBarrierDivergence: !(intelWindows || intelUnix),
|
supportsShaderBarrierDivergence: !(intelWindows || intelUnix),
|
||||||
supportsShaderFloat64: true,
|
supportsShaderFloat64: true,
|
||||||
supportsTextureGatherOffsets: true,
|
supportsTextureGatherOffsets: true,
|
||||||
supportsTextureShadowLod: HwCapabilities.SupportsTextureShadowLod,
|
supportsTextureShadowLod: Capabilities.SupportsTextureShadowLod,
|
||||||
supportsVertexStoreAndAtomics: true,
|
supportsVertexStoreAndAtomics: true,
|
||||||
supportsViewportIndexVertexTessellation: HwCapabilities.SupportsShaderViewportLayerArray,
|
supportsViewportIndexVertexTessellation: Capabilities.SupportsShaderViewportLayerArray,
|
||||||
supportsViewportMask: HwCapabilities.SupportsViewportArray2,
|
supportsViewportMask: Capabilities.SupportsViewportArray2,
|
||||||
supportsViewportSwizzle: HwCapabilities.SupportsViewportSwizzle,
|
supportsViewportSwizzle: Capabilities.SupportsViewportSwizzle,
|
||||||
supportsIndirectParameters: HwCapabilities.SupportsIndirectParameters,
|
supportsIndirectParameters: Capabilities.SupportsIndirectParameters,
|
||||||
supportsDepthClipControl: true,
|
supportsDepthClipControl: true,
|
||||||
maximumUniformBuffersPerStage: 13, // TODO: Avoid hardcoding those limits here and get from driver?
|
maximumUniformBuffersPerStage: 13, // TODO: Avoid hardcoding those limits here and get from driver?
|
||||||
maximumStorageBuffersPerStage: 16,
|
maximumStorageBuffersPerStage: 16,
|
||||||
maximumTexturesPerStage: 32,
|
maximumTexturesPerStage: 32,
|
||||||
maximumImagesPerStage: 8,
|
maximumImagesPerStage: 8,
|
||||||
maximumComputeSharedMemorySize: HwCapabilities.MaximumComputeSharedMemorySize,
|
maximumComputeSharedMemorySize: Capabilities.MaximumComputeSharedMemorySize,
|
||||||
maximumSupportedAnisotropy: HwCapabilities.MaximumSupportedAnisotropy,
|
maximumSupportedAnisotropy: Capabilities.MaximumSupportedAnisotropy,
|
||||||
shaderSubgroupSize: Constants.MaxSubgroupSize,
|
shaderSubgroupSize: Constants.MaxSubgroupSize,
|
||||||
storageBufferOffsetAlignment: HwCapabilities.StorageBufferOffsetAlignment,
|
storageBufferOffsetAlignment: Capabilities.StorageBufferOffsetAlignment,
|
||||||
textureBufferOffsetAlignment: HwCapabilities.TextureBufferOffsetAlignment,
|
textureBufferOffsetAlignment: Capabilities.TextureBufferOffsetAlignment,
|
||||||
gatherBiasPrecision: intelWindows || amdWindows ? 8 : 0); // Precision is 8 for these vendors on Vulkan.
|
gatherBiasPrecision: intelWindows || amdWindows ? 8 : 0); // Precision is 8 for these vendors on Vulkan.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,9 +232,11 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
Debugger.Initialize(Api, glLogLevel);
|
Debugger.Initialize(Api, glLogLevel);
|
||||||
|
|
||||||
|
LoadFeatures();
|
||||||
|
|
||||||
PrintGpuInformation();
|
PrintGpuInformation();
|
||||||
|
|
||||||
if (HwCapabilities.SupportsParallelShaderCompile)
|
if (Capabilities.SupportsParallelShaderCompile)
|
||||||
{
|
{
|
||||||
Api.TryGetExtension(out ArbParallelShaderCompile arbParallelShaderCompile);
|
Api.TryGetExtension(out ArbParallelShaderCompile arbParallelShaderCompile);
|
||||||
|
|
||||||
|
@ -244,10 +248,41 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
// This is required to disable [0, 1] clamping for SNorm outputs on compatibility profiles.
|
// This is required to disable [0, 1] clamping for SNorm outputs on compatibility profiles.
|
||||||
// This call is expected to fail if we're running with a core profile,
|
// This call is expected to fail if we're running with a core profile,
|
||||||
// as this clamp target was deprecated, but that's fine as a core profile
|
// as this clamp target was deprecated, but that's fine as a core profile
|
||||||
// should already have the desired behaviour were outputs are not clamped.
|
// should already have the desired behaviour when outputs are not clamped.
|
||||||
Api.ClampColor(ClampColorTargetARB.FragmentColorArb, ClampColorModeARB.False);
|
Api.ClampColor(ClampColorTargetARB.FragmentColorArb, ClampColorModeARB.False);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void LoadFeatures()
|
||||||
|
{
|
||||||
|
Capabilities = new HardwareCapabilities(
|
||||||
|
HardwareCapabilities.HasExtension(Api, "GL_NV_alpha_to_coverage_dither_control"),
|
||||||
|
HardwareCapabilities.HasExtension(Api, "GL_KHR_texture_compression_astc_ldr"),
|
||||||
|
HardwareCapabilities.HasExtension(Api, "GL_NV_blend_equation_advanced"),
|
||||||
|
HardwareCapabilities.HasExtension(Api, "GL_NV_draw_texture"),
|
||||||
|
HardwareCapabilities.HasExtension(Api, "GL_ARB_fragment_shader_interlock"),
|
||||||
|
HardwareCapabilities.HasExtension(Api, "GL_INTEL_fragment_shader_ordering"),
|
||||||
|
HardwareCapabilities.HasExtension(Api, "GL_NV_geometry_shader_passthrough"),
|
||||||
|
HardwareCapabilities.HasExtension(Api, "GL_EXT_shader_image_load_formatted"),
|
||||||
|
HardwareCapabilities.HasExtension(Api, "GL_ARB_indirect_parameters"),
|
||||||
|
HardwareCapabilities.HasExtension(Api, "GL_ARB_parallel_shader_compile"),
|
||||||
|
HardwareCapabilities.HasExtension(Api, "GL_EXT_polygon_offset_clamp"),
|
||||||
|
HardwareCapabilities.SupportsQuadsCheck(Api),
|
||||||
|
HardwareCapabilities.HasExtension(Api, "GL_ARB_seamless_cubemap_per_texture"),
|
||||||
|
HardwareCapabilities.HasExtension(Api, "GL_ARB_shader_ballot"),
|
||||||
|
HardwareCapabilities.HasExtension(Api, "GL_ARB_shader_viewport_layer_array"),
|
||||||
|
HardwareCapabilities.HasExtension(Api, "GL_NV_viewport_array2"),
|
||||||
|
HardwareCapabilities.HasExtension(Api, "GL_EXT_texture_compression_bptc"),
|
||||||
|
HardwareCapabilities.HasExtension(Api, "GL_EXT_texture_compression_rgtc"),
|
||||||
|
HardwareCapabilities.HasExtension(Api, "GL_EXT_texture_compression_s3tc"),
|
||||||
|
HardwareCapabilities.HasExtension(Api, "GL_EXT_texture_shadow_lod"),
|
||||||
|
HardwareCapabilities.HasExtension(Api, "GL_NV_viewport_swizzle"),
|
||||||
|
Api.GetInteger(GLEnum.MaxComputeSharedMemorySize),
|
||||||
|
Api.GetInteger(GLEnum.ShaderStorageBufferOffsetAlignment),
|
||||||
|
Api.GetInteger(GLEnum.TextureBufferOffsetAlignment),
|
||||||
|
Api.GetFloat(GLEnum.MaxTextureMaxAnisotropy),
|
||||||
|
HardwareCapabilities.GetGpuVendor(Api));
|
||||||
|
}
|
||||||
|
|
||||||
private unsafe void PrintGpuInformation()
|
private unsafe void PrintGpuInformation()
|
||||||
{
|
{
|
||||||
GpuVendor = Marshal.PtrToStringAnsi((IntPtr)Api.GetString(StringName.Vendor));
|
GpuVendor = Marshal.PtrToStringAnsi((IntPtr)Api.GetString(StringName.Vendor));
|
||||||
|
@ -296,7 +331,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
public IProgram LoadProgramBinary(byte[] programBinary, bool hasFragmentShader, ShaderInfo info)
|
public IProgram LoadProgramBinary(byte[] programBinary, bool hasFragmentShader, ShaderInfo info)
|
||||||
{
|
{
|
||||||
return new Program(Api, programBinary, hasFragmentShader, info.FragmentOutputMap);
|
return new Program(this, programBinary, hasFragmentShader, info.FragmentOutputMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CreateSync(ulong id, bool strict)
|
public void CreateSync(ulong id, bool strict)
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -28,18 +28,18 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly GL _api;
|
private readonly OpenGLRenderer _gd;
|
||||||
private ProgramLinkStatus _status = ProgramLinkStatus.Incomplete;
|
private ProgramLinkStatus _status = ProgramLinkStatus.Incomplete;
|
||||||
private uint[] _shaderHandles;
|
private uint[] _shaderHandles;
|
||||||
|
|
||||||
public int FragmentOutputMap { get; }
|
public int FragmentOutputMap { get; }
|
||||||
|
|
||||||
public unsafe Program(GL api, ShaderSource[] shaders, int fragmentOutputMap)
|
public unsafe Program(OpenGLRenderer gd, ShaderSource[] shaders, int fragmentOutputMap)
|
||||||
{
|
{
|
||||||
_api = api;
|
_gd = gd;
|
||||||
Handle = _api.CreateProgram();
|
Handle = _gd.Api.CreateProgram();
|
||||||
|
|
||||||
_api.ProgramParameter(Handle, ProgramParameterPName.BinaryRetrievableHint, 1);
|
_gd.Api.ProgramParameter(Handle, ProgramParameterPName.BinaryRetrievableHint, 1);
|
||||||
|
|
||||||
_shaderHandles = new uint[shaders.Length];
|
_shaderHandles = new uint[shaders.Length];
|
||||||
bool hasFragmentShader = false;
|
bool hasFragmentShader = false;
|
||||||
|
@ -53,37 +53,37 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
hasFragmentShader = true;
|
hasFragmentShader = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint shaderHandle = _api.CreateShader(shader.Stage.Convert());
|
uint shaderHandle = _gd.Api.CreateShader(shader.Stage.Convert());
|
||||||
|
|
||||||
switch (shader.Language)
|
switch (shader.Language)
|
||||||
{
|
{
|
||||||
case TargetLanguage.Glsl:
|
case TargetLanguage.Glsl:
|
||||||
_api.ShaderSource(shaderHandle, shader.Code);
|
_gd.Api.ShaderSource(shaderHandle, shader.Code);
|
||||||
_api.CompileShader(shaderHandle);
|
_gd.Api.CompileShader(shaderHandle);
|
||||||
break;
|
break;
|
||||||
case TargetLanguage.Spirv:
|
case TargetLanguage.Spirv:
|
||||||
fixed (byte* ptr = shader.BinaryCode.AsSpan())
|
fixed (byte* ptr = shader.BinaryCode.AsSpan())
|
||||||
{
|
{
|
||||||
_api.ShaderBinary(1, in shaderHandle, ShaderBinaryFormat.ShaderBinaryFormatSpirV, ptr, (uint)shader.BinaryCode.Length);
|
_gd.Api.ShaderBinary(1, in shaderHandle, ShaderBinaryFormat.ShaderBinaryFormatSpirV, ptr, (uint)shader.BinaryCode.Length);
|
||||||
}
|
}
|
||||||
_api.SpecializeShader(shaderHandle, "main", 0, (uint[])null, (uint[])null);
|
_gd.Api.SpecializeShader(shaderHandle, "main", 0, (uint[])null, (uint[])null);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_api.AttachShader(Handle, shaderHandle);
|
_gd.Api.AttachShader(Handle, shaderHandle);
|
||||||
|
|
||||||
_shaderHandles[index] = shaderHandle;
|
_shaderHandles[index] = shaderHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
_api.LinkProgram(Handle);
|
_gd.Api.LinkProgram(Handle);
|
||||||
|
|
||||||
FragmentOutputMap = hasFragmentShader ? fragmentOutputMap : 0;
|
FragmentOutputMap = hasFragmentShader ? fragmentOutputMap : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Program(GL api, ReadOnlySpan<byte> code, bool hasFragmentShader, int fragmentOutputMap)
|
public Program(OpenGLRenderer gd, ReadOnlySpan<byte> code, bool hasFragmentShader, int fragmentOutputMap)
|
||||||
{
|
{
|
||||||
_api = api;
|
_gd = gd;
|
||||||
Handle = _api.CreateProgram();
|
Handle = _gd.Api.CreateProgram();
|
||||||
|
|
||||||
if (code.Length >= 4)
|
if (code.Length >= 4)
|
||||||
{
|
{
|
||||||
|
@ -93,7 +93,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = code)
|
fixed (byte* ptr = code)
|
||||||
{
|
{
|
||||||
_api.ProgramBinary(Handle, (GLEnum)binaryFormat, (IntPtr)ptr, (uint)code.Length - 4);
|
_gd.Api.ProgramBinary(Handle, (GLEnum)binaryFormat, (IntPtr)ptr, (uint)code.Length - 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,14 +103,14 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
public void Bind()
|
public void Bind()
|
||||||
{
|
{
|
||||||
_api.UseProgram(Handle);
|
_gd.Api.UseProgram(Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProgramLinkStatus CheckProgramLink(bool blocking)
|
public ProgramLinkStatus CheckProgramLink(bool blocking)
|
||||||
{
|
{
|
||||||
if (!blocking && HwCapabilities.SupportsParallelShaderCompile)
|
if (!blocking && _gd.Capabilities.SupportsParallelShaderCompile)
|
||||||
{
|
{
|
||||||
_api.GetProgram(Handle, (GLEnum)ARB.CompletionStatusArb, out int completed);
|
_gd.Api.GetProgram(Handle, (GLEnum)ARB.CompletionStatusArb, out int completed);
|
||||||
|
|
||||||
if (completed == 0)
|
if (completed == 0)
|
||||||
{
|
{
|
||||||
|
@ -118,14 +118,14 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_api.GetProgram(Handle, ProgramPropertyARB.LinkStatus, out int status);
|
_gd.Api.GetProgram(Handle, ProgramPropertyARB.LinkStatus, out int status);
|
||||||
DeleteShaders();
|
DeleteShaders();
|
||||||
|
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
{
|
{
|
||||||
_status = ProgramLinkStatus.Failure;
|
_status = ProgramLinkStatus.Failure;
|
||||||
|
|
||||||
string log = _api.GetProgramInfoLog(Handle);
|
string log = _gd.Api.GetProgramInfoLog(Handle);
|
||||||
|
|
||||||
if (log.Length > MaxShaderLogLength)
|
if (log.Length > MaxShaderLogLength)
|
||||||
{
|
{
|
||||||
|
@ -144,14 +144,14 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
public unsafe byte[] GetBinary()
|
public unsafe byte[] GetBinary()
|
||||||
{
|
{
|
||||||
_api.GetProgram(Handle, ProgramPropertyARB.ProgramBinaryLength, out int size);
|
_gd.Api.GetProgram(Handle, ProgramPropertyARB.ProgramBinaryLength, out int size);
|
||||||
|
|
||||||
byte[] data = new byte[size];
|
byte[] data = new byte[size];
|
||||||
GLEnum binFormat;
|
GLEnum binFormat;
|
||||||
|
|
||||||
fixed (byte* ptr = data)
|
fixed (byte* ptr = data)
|
||||||
{
|
{
|
||||||
_api.GetProgramBinary(Handle, (uint)size, out _, out binFormat, ptr);
|
_gd.Api.GetProgramBinary(Handle, (uint)size, out _, out binFormat, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
BinaryPrimitives.WriteInt32LittleEndian(data, (int)binFormat);
|
BinaryPrimitives.WriteInt32LittleEndian(data, (int)binFormat);
|
||||||
|
@ -165,8 +165,8 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
foreach (uint shaderHandle in _shaderHandles)
|
foreach (uint shaderHandle in _shaderHandles)
|
||||||
{
|
{
|
||||||
_api.DetachShader(Handle, shaderHandle);
|
_gd.Api.DetachShader(Handle, shaderHandle);
|
||||||
_api.DeleteShader(shaderHandle);
|
_gd.Api.DeleteShader(shaderHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
_shaderHandles = null;
|
_shaderHandles = null;
|
||||||
|
@ -178,7 +178,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
if (Handle != 0)
|
if (Handle != 0)
|
||||||
{
|
{
|
||||||
DeleteShaders();
|
DeleteShaders();
|
||||||
_api.DeleteProgram(Handle);
|
_gd.Api.DeleteProgram(Handle);
|
||||||
|
|
||||||
Handle = 0;
|
Handle = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,15 +14,15 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
public IntPtr Handle;
|
public IntPtr Handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ulong _firstHandle = 0;
|
private ulong _firstHandle;
|
||||||
private static SyncObjectMask SyncFlags => HwCapabilities.RequiresSyncFlush ? 0 : SyncObjectMask.Bit;
|
private SyncObjectMask SyncFlags => _gd.Capabilities.RequiresSyncFlush ? 0 : SyncObjectMask.Bit;
|
||||||
|
|
||||||
private readonly List<SyncHandle> _handles = new();
|
private readonly List<SyncHandle> _handles = new();
|
||||||
private readonly GL _api;
|
private readonly OpenGLRenderer _gd;
|
||||||
|
|
||||||
public Sync(GL api)
|
public Sync(OpenGLRenderer gd)
|
||||||
{
|
{
|
||||||
_api = api;
|
_gd = gd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Create(ulong id)
|
public void Create(ulong id)
|
||||||
|
@ -30,14 +30,14 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
SyncHandle handle = new()
|
SyncHandle handle = new()
|
||||||
{
|
{
|
||||||
ID = id,
|
ID = id,
|
||||||
Handle = _api.FenceSync(SyncCondition.SyncGpuCommandsComplete, SyncBehaviorFlags.None),
|
Handle = _gd.Api.FenceSync(SyncCondition.SyncGpuCommandsComplete, SyncBehaviorFlags.None),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
if (HwCapabilities.RequiresSyncFlush)
|
if (_gd.Capabilities.RequiresSyncFlush)
|
||||||
{
|
{
|
||||||
// Force commands to flush up to the syncpoint.
|
// Force commands to flush up to the syncpoint.
|
||||||
_api.ClientWaitSync(handle.Handle, SyncObjectMask.Bit, 0);
|
_gd.Api.ClientWaitSync(handle.Handle, SyncObjectMask.Bit, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (_handles)
|
lock (_handles)
|
||||||
|
@ -63,7 +63,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
if (handle.ID > lastHandle)
|
if (handle.ID > lastHandle)
|
||||||
{
|
{
|
||||||
GLEnum syncResult = _api.ClientWaitSync(handle.Handle, SyncFlags, 0);
|
GLEnum syncResult = _gd.Api.ClientWaitSync(handle.Handle, SyncFlags, 0);
|
||||||
|
|
||||||
if (syncResult == GLEnum.AlreadySignaled)
|
if (syncResult == GLEnum.AlreadySignaled)
|
||||||
{
|
{
|
||||||
|
@ -107,7 +107,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLEnum syncResult = _api.ClientWaitSync(result.Handle, SyncFlags, 1000000000);
|
GLEnum syncResult = _gd.Api.ClientWaitSync(result.Handle, SyncFlags, 1000000000);
|
||||||
|
|
||||||
if (syncResult == GLEnum.TimeoutExpired)
|
if (syncResult == GLEnum.TimeoutExpired)
|
||||||
{
|
{
|
||||||
|
@ -134,7 +134,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLEnum syncResult = _api.ClientWaitSync(first.Handle, SyncFlags, 0);
|
GLEnum syncResult = _gd.Api.ClientWaitSync(first.Handle, SyncFlags, 0);
|
||||||
|
|
||||||
if (syncResult == GLEnum.AlreadySignaled)
|
if (syncResult == GLEnum.AlreadySignaled)
|
||||||
{
|
{
|
||||||
|
@ -145,7 +145,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
_firstHandle = first.ID + 1;
|
_firstHandle = first.ID + 1;
|
||||||
_handles.RemoveAt(0);
|
_handles.RemoveAt(0);
|
||||||
_api.DeleteSync(first.Handle);
|
_gd.Api.DeleteSync(first.Handle);
|
||||||
first.Handle = IntPtr.Zero;
|
first.Handle = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
lock (handle)
|
lock (handle)
|
||||||
{
|
{
|
||||||
_api.DeleteSync(handle.Handle);
|
_gd.Api.DeleteSync(handle.Handle);
|
||||||
handle.Handle = IntPtr.Zero;
|
handle.Handle = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue