aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Gal/OpenGL
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics/Gal/OpenGL')
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs1
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs25
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs7
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs55
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs2
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs256
6 files changed, 289 insertions, 57 deletions
diff --git a/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs b/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs
index 8db0b8a8..5714f3d8 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs
@@ -8,6 +8,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public int Width => Image.Width;
public int Height => Image.Height;
+ public int Depth => Image.Depth;
public GalImageFormat Format => Image.Format;
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs
index f2afe7b5..3a25fff7 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs
@@ -189,6 +189,31 @@ namespace Ryujinx.Graphics.Gal.OpenGL
throw new NotImplementedException($"{Format & GalImageFormat.FormatMask} {Format & GalImageFormat.TypeMask}");
}
+ public static All GetDepthCompareFunc(DepthCompareFunc DepthCompareFunc)
+ {
+ switch (DepthCompareFunc)
+ {
+ case DepthCompareFunc.LEqual:
+ return All.Lequal;
+ case DepthCompareFunc.GEqual:
+ return All.Gequal;
+ case DepthCompareFunc.Less:
+ return All.Less;
+ case DepthCompareFunc.Greater:
+ return All.Greater;
+ case DepthCompareFunc.Equal:
+ return All.Equal;
+ case DepthCompareFunc.NotEqual:
+ return All.Notequal;
+ case DepthCompareFunc.Always:
+ return All.Always;
+ case DepthCompareFunc.Never:
+ return All.Never;
+ default:
+ throw new ArgumentException(nameof(DepthCompareFunc) + " \"" + DepthCompareFunc + "\" is not valid!");
+ }
+ }
+
public static InternalFormat GetCompressedImageFormat(GalImageFormat Format)
{
switch (Format)
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs
index 11daeb59..52b3d0ce 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs
@@ -9,9 +9,12 @@ namespace Ryujinx.Graphics.Gal.OpenGL
private static Lazy<bool> s_TextureMirrorClamp = new Lazy<bool>(() => HasExtension("GL_EXT_texture_mirror_clamp"));
private static Lazy<bool> s_ViewportArray = new Lazy<bool>(() => HasExtension("GL_ARB_viewport_array"));
+ private static Lazy<bool> s_NvidiaDriver = new Lazy<bool>(() => IsNvidiaDriver());
+
public static bool EnhancedLayouts => s_EnhancedLayouts.Value;
public static bool TextureMirrorClamp => s_TextureMirrorClamp.Value;
public static bool ViewportArray => s_ViewportArray.Value;
+ public static bool NvidiaDrvier => s_NvidiaDriver.Value;
private static bool HasExtension(string Name)
{
@@ -27,5 +30,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
return false;
}
+
+ private static bool IsNvidiaDriver() {
+ return GL.GetString(StringName.Vendor).Equals("NVIDIA Corporation");
+ }
}
} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs
index 0d7bb3cd..8dd3b37f 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs
@@ -389,16 +389,20 @@ namespace Ryujinx.Graphics.Gal.OpenGL
}
public void Copy(
- long SrcKey,
- long DstKey,
- int SrcX0,
- int SrcY0,
- int SrcX1,
- int SrcY1,
- int DstX0,
- int DstY0,
- int DstX1,
- int DstY1)
+ GalImage SrcImage,
+ GalImage DstImage,
+ long SrcKey,
+ long DstKey,
+ int SrcLayer,
+ int DstLayer,
+ int SrcX0,
+ int SrcY0,
+ int SrcX1,
+ int SrcY1,
+ int DstX0,
+ int DstY0,
+ int DstX1,
+ int DstY1)
{
if (Texture.TryGetImageHandler(SrcKey, out ImageHandler SrcTex) &&
Texture.TryGetImageHandler(DstKey, out ImageHandler DstTex))
@@ -425,8 +429,24 @@ namespace Ryujinx.Graphics.Gal.OpenGL
FramebufferAttachment Attachment = GetAttachment(SrcTex);
- GL.FramebufferTexture(FramebufferTarget.ReadFramebuffer, Attachment, SrcTex.Handle, 0);
- GL.FramebufferTexture(FramebufferTarget.DrawFramebuffer, Attachment, DstTex.Handle, 0);
+ if (ImageUtils.IsArray(SrcImage.TextureTarget) && SrcLayer > 0)
+ {
+ GL.FramebufferTextureLayer(FramebufferTarget.ReadFramebuffer, Attachment, SrcTex.Handle, 0, SrcLayer);
+ }
+ else
+ {
+ GL.FramebufferTexture(FramebufferTarget.ReadFramebuffer, Attachment, SrcTex.Handle, 0);
+ }
+
+ if (ImageUtils.IsArray(DstImage.TextureTarget) && DstLayer > 0)
+ {
+ GL.FramebufferTextureLayer(FramebufferTarget.DrawFramebuffer, Attachment, DstTex.Handle, 0, DstLayer);
+ }
+ else
+ {
+ GL.FramebufferTexture(FramebufferTarget.DrawFramebuffer, Attachment, DstTex.Handle, 0);
+ }
+
BlitFramebufferFilter Filter = BlitFramebufferFilter.Nearest;
@@ -452,7 +472,10 @@ namespace Ryujinx.Graphics.Gal.OpenGL
if (NewImage.Format == OldImage.Format &&
NewImage.Width == OldImage.Width &&
- NewImage.Height == OldImage.Height)
+ NewImage.Height == OldImage.Height &&
+ NewImage.Depth == OldImage.Depth &&
+ NewImage.LayerCount == OldImage.LayerCount &&
+ NewImage.TextureTarget == OldImage.TextureTarget)
{
return;
}
@@ -477,9 +500,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL
(_, PixelFormat Format, PixelType Type) = OGLEnumConverter.GetImageFormat(CachedImage.Format);
- GL.BindTexture(TextureTarget.Texture2D, CachedImage.Handle);
+ TextureTarget Target = ImageUtils.GetTextureTarget(NewImage.TextureTarget);
+
+ GL.BindTexture(Target, CachedImage.Handle);
- GL.GetTexImage(TextureTarget.Texture2D, 0, Format, Type, IntPtr.Zero);
+ GL.GetTexImage(Target, 0, Format, Type, IntPtr.Zero);
GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyPBO);
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs
index 10a9120d..dc168ff9 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs
@@ -53,7 +53,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
GlslProgram Program;
- GlslDecompiler Decompiler = new GlslDecompiler(OGLLimit.MaxUboSize);
+ GlslDecompiler Decompiler = new GlslDecompiler(OGLLimit.MaxUboSize, OGLExtension.NvidiaDrvier);
int ShaderDumpIndex = ShaderDumper.DumpIndex;
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs
index ef984b1e..4fef11d2 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs
@@ -38,7 +38,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
int Handle = GL.GenTexture();
- GL.BindTexture(TextureTarget.Texture2D, Handle);
+ TextureTarget Target = ImageUtils.GetTextureTarget(Image.TextureTarget);
+
+ GL.BindTexture(Target, Handle);
const int Level = 0; //TODO: Support mipmap textures.
const int Border = 0;
@@ -54,23 +56,70 @@ namespace Ryujinx.Graphics.Gal.OpenGL
PixelFormat Format,
PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format);
- GL.TexImage2D(
- TextureTarget.Texture2D,
- Level,
- InternalFmt,
- Image.Width,
- Image.Height,
- Border,
- Format,
- Type,
- IntPtr.Zero);
+ switch (Target)
+ {
+ case TextureTarget.Texture1D:
+ GL.TexImage1D(
+ Target,
+ Level,
+ InternalFmt,
+ Image.Width,
+ Border,
+ Format,
+ Type,
+ IntPtr.Zero);
+ break;
+
+ case TextureTarget.Texture2D:
+ GL.TexImage2D(
+ Target,
+ Level,
+ InternalFmt,
+ Image.Width,
+ Image.Height,
+ Border,
+ Format,
+ Type,
+ IntPtr.Zero);
+ break;
+ case TextureTarget.Texture3D:
+ GL.TexImage3D(
+ Target,
+ Level,
+ InternalFmt,
+ Image.Width,
+ Image.Height,
+ Image.Depth,
+ Border,
+ Format,
+ Type,
+ IntPtr.Zero);
+ break;
+ case TextureTarget.Texture2DArray:
+ GL.TexImage3D(
+ Target,
+ Level,
+ InternalFmt,
+ Image.Width,
+ Image.Height,
+ Image.LayerCount,
+ Border,
+ Format,
+ Type,
+ IntPtr.Zero);
+ break;
+ default:
+ throw new NotImplementedException($"Unsupported texture target type: {Target}");
+ }
}
public void Create(long Key, byte[] Data, GalImage Image)
{
int Handle = GL.GenTexture();
- GL.BindTexture(TextureTarget.Texture2D, Handle);
+ TextureTarget Target = ImageUtils.GetTextureTarget(Image.TextureTarget);
+
+ GL.BindTexture(Target, Handle);
const int Level = 0; //TODO: Support mipmap textures.
const int Border = 0;
@@ -81,15 +130,56 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
InternalFormat InternalFmt = OGLEnumConverter.GetCompressedImageFormat(Image.Format);
- GL.CompressedTexImage2D(
- TextureTarget.Texture2D,
- Level,
- InternalFmt,
- Image.Width,
- Image.Height,
- Border,
- Data.Length,
- Data);
+ switch (Target)
+ {
+ case TextureTarget.Texture1D:
+ GL.CompressedTexImage1D(
+ Target,
+ Level,
+ InternalFmt,
+ Image.Width,
+ Border,
+ Data.Length,
+ Data);
+ break;
+ case TextureTarget.Texture2D:
+ GL.CompressedTexImage2D(
+ Target,
+ Level,
+ InternalFmt,
+ Image.Width,
+ Image.Height,
+ Border,
+ Data.Length,
+ Data);
+ break;
+ case TextureTarget.Texture3D:
+ GL.CompressedTexImage3D(
+ Target,
+ Level,
+ InternalFmt,
+ Image.Width,
+ Image.Height,
+ Image.Depth,
+ Border,
+ Data.Length,
+ Data);
+ break;
+ case TextureTarget.Texture2DArray:
+ GL.CompressedTexImage3D(
+ Target,
+ Level,
+ InternalFmt,
+ Image.Width,
+ Image.Height,
+ Image.LayerCount,
+ Border,
+ Data.Length,
+ Data);
+ break;
+ default:
+ throw new NotImplementedException($"Unsupported texture target type: {Target}");
+ }
}
else
{
@@ -98,13 +188,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
int TextureBlockWidth = ImageUtils.GetBlockWidth(Image.Format);
int TextureBlockHeight = ImageUtils.GetBlockHeight(Image.Format);
+ int TextureBlockDepth = ImageUtils.GetBlockDepth(Image.Format);
Data = ASTCDecoder.DecodeToRGBA8888(
Data,
TextureBlockWidth,
- TextureBlockHeight, 1,
+ TextureBlockHeight,
+ TextureBlockDepth,
Image.Width,
- Image.Height, 1);
+ Image.Height,
+ Image.Depth);
Image.Format = GalImageFormat.RGBA8 | (Image.Format & GalImageFormat.TypeMask);
}
@@ -113,16 +206,80 @@ namespace Ryujinx.Graphics.Gal.OpenGL
PixelFormat Format,
PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format);
- GL.TexImage2D(
- TextureTarget.Texture2D,
- Level,
- InternalFmt,
- Image.Width,
- Image.Height,
- Border,
- Format,
- Type,
- Data);
+
+ switch (Target)
+ {
+ case TextureTarget.Texture1D:
+ GL.TexImage1D(
+ Target,
+ Level,
+ InternalFmt,
+ Image.Width,
+ Border,
+ Format,
+ Type,
+ Data);
+ break;
+ case TextureTarget.Texture2D:
+ GL.TexImage2D(
+ Target,
+ Level,
+ InternalFmt,
+ Image.Width,
+ Image.Height,
+ Border,
+ Format,
+ Type,
+ Data);
+ break;
+ case TextureTarget.Texture3D:
+ GL.TexImage3D(
+ Target,
+ Level,
+ InternalFmt,
+ Image.Width,
+ Image.Height,
+ Image.Depth,
+ Border,
+ Format,
+ Type,
+ Data);
+ break;
+ case TextureTarget.Texture2DArray:
+ GL.TexImage3D(
+ Target,
+ Level,
+ InternalFmt,
+ Image.Width,
+ Image.Height,
+ Image.LayerCount,
+ Border,
+ Format,
+ Type,
+ Data);
+ break;
+ case TextureTarget.TextureCubeMap:
+ Span<byte> Array = new Span<byte>(Data);
+
+ int FaceSize = ImageUtils.GetSize(Image) / 6;
+
+ for (int Face = 0; Face < 6; Face++)
+ {
+ GL.TexImage2D(
+ TextureTarget.TextureCubeMapPositiveX + Face,
+ Level,
+ InternalFmt,
+ Image.Width,
+ Image.Height,
+ Border,
+ Format,
+ Type,
+ Array.Slice(Face * FaceSize, FaceSize).ToArray());
+ }
+ break;
+ default:
+ throw new NotImplementedException($"Unsupported texture target type: {Target}");
+ }
}
}
@@ -165,7 +322,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
GL.ActiveTexture(TextureUnit.Texture0 + Index);
- GL.BindTexture(TextureTarget.Texture2D, CachedImage.Handle);
+ TextureTarget Target = ImageUtils.GetTextureTarget(Image.TextureTarget);
+
+ GL.BindTexture(Target, CachedImage.Handle);
int[] SwizzleRgba = new int[]
{
@@ -175,23 +334,27 @@ namespace Ryujinx.Graphics.Gal.OpenGL
(int)OGLEnumConverter.GetTextureSwizzle(Image.WSource)
};
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleRgba, SwizzleRgba);
+ GL.TexParameter(Target, TextureParameterName.TextureSwizzleRgba, SwizzleRgba);
}
}
- public void SetSampler(GalTextureSampler Sampler)
+ public void SetSampler(GalImage Image, GalTextureSampler Sampler)
{
int WrapS = (int)OGLEnumConverter.GetTextureWrapMode(Sampler.AddressU);
int WrapT = (int)OGLEnumConverter.GetTextureWrapMode(Sampler.AddressV);
+ int WrapR = (int)OGLEnumConverter.GetTextureWrapMode(Sampler.AddressP);
int MinFilter = (int)OGLEnumConverter.GetTextureMinFilter(Sampler.MinFilter, Sampler.MipFilter);
int MagFilter = (int)OGLEnumConverter.GetTextureMagFilter(Sampler.MagFilter);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, WrapS);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, WrapT);
+ TextureTarget Target = ImageUtils.GetTextureTarget(Image.TextureTarget);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, MinFilter);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, MagFilter);
+ GL.TexParameter(Target, TextureParameterName.TextureWrapS, WrapS);
+ GL.TexParameter(Target, TextureParameterName.TextureWrapT, WrapT);
+ GL.TexParameter(Target, TextureParameterName.TextureWrapR, WrapR);
+
+ GL.TexParameter(Target, TextureParameterName.TextureMinFilter, MinFilter);
+ GL.TexParameter(Target, TextureParameterName.TextureMagFilter, MagFilter);
float[] Color = new float[]
{
@@ -201,7 +364,18 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Sampler.BorderColor.Alpha
};
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBorderColor, Color);
+ GL.TexParameter(Target, TextureParameterName.TextureBorderColor, Color);
+
+ if (Sampler.DepthCompare)
+ {
+ GL.TexParameter(Target, TextureParameterName.TextureCompareMode, (int)All.CompareRToTexture);
+ GL.TexParameter(Target, TextureParameterName.TextureCompareFunc, (int)OGLEnumConverter.GetDepthCompareFunc(Sampler.DepthCompareFunc));
+ }
+ else
+ {
+ GL.TexParameter(Target, TextureParameterName.TextureCompareMode, (int)All.None);
+ GL.TexParameter(Target, TextureParameterName.TextureCompareFunc, (int)All.Never);
+ }
}
}
}