Renaming part 3

This commit is contained in:
Alex Barney 2019-03-03 11:20:57 -06:00
parent e697dbffc9
commit 6adbbc376d
16 changed files with 1069 additions and 1069 deletions

View file

@ -1,4 +1,4 @@
namespace Ryujinx.Graphics.Gal.OpenGL
{
delegate void DeleteValue<T>(T Value);
delegate void DeleteValue<T>(T value);
}

View file

@ -18,10 +18,10 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public bool HasDepth => ImageUtils.HasDepth(Image.Format);
public bool HasStencil => ImageUtils.HasStencil(Image.Format);
public ImageHandler(int Handle, GalImage Image)
public ImageHandler(int handle, GalImage image)
{
this.Handle = Handle;
this.Image = Image;
Handle = handle;
Image = image;
}
}
}

View file

@ -4,9 +4,9 @@ using System.Collections.Generic;
namespace Ryujinx.Graphics.Gal.OpenGL
{
class OGLCachedResource<T>
class OglCachedResource<T>
{
public delegate void DeleteValue(T Value);
public delegate void DeleteValue(T value);
private const int MinTimeDelta = 5 * 60000;
private const int MaxRemovalsPerRun = 10;
@ -21,171 +21,171 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public long Timestamp { get; private set; }
public CacheBucket(T Value, long DataSize, LinkedListNode<long> Node)
public CacheBucket(T value, long dataSize, LinkedListNode<long> node)
{
this.Value = Value;
this.DataSize = DataSize;
this.Node = Node;
Value = value;
DataSize = dataSize;
Node = node;
Timestamp = PerformanceCounter.ElapsedMilliseconds;
}
}
private Dictionary<long, CacheBucket> Cache;
private Dictionary<long, CacheBucket> _cache;
private LinkedList<long> SortedCache;
private LinkedList<long> _sortedCache;
private DeleteValue DeleteValueCallback;
private DeleteValue _deleteValueCallback;
private Queue<T> DeletePending;
private Queue<T> _deletePending;
private bool Locked;
private bool _locked;
private long MaxSize;
private long TotalSize;
private long _maxSize;
private long _totalSize;
public OGLCachedResource(DeleteValue DeleteValueCallback, long MaxSize)
public OglCachedResource(DeleteValue deleteValueCallback, long maxSize)
{
this.MaxSize = MaxSize;
_maxSize = maxSize;
if (DeleteValueCallback == null)
if (deleteValueCallback == null)
{
throw new ArgumentNullException(nameof(DeleteValueCallback));
throw new ArgumentNullException(nameof(deleteValueCallback));
}
this.DeleteValueCallback = DeleteValueCallback;
_deleteValueCallback = deleteValueCallback;
Cache = new Dictionary<long, CacheBucket>();
_cache = new Dictionary<long, CacheBucket>();
SortedCache = new LinkedList<long>();
_sortedCache = new LinkedList<long>();
DeletePending = new Queue<T>();
_deletePending = new Queue<T>();
}
public void Lock()
{
Locked = true;
_locked = true;
}
public void Unlock()
{
Locked = false;
_locked = false;
while (DeletePending.TryDequeue(out T Value))
while (_deletePending.TryDequeue(out T value))
{
DeleteValueCallback(Value);
_deleteValueCallback(value);
}
ClearCacheIfNeeded();
}
public void AddOrUpdate(long Key, T Value, long Size)
public void AddOrUpdate(long key, T value, long size)
{
if (!Locked)
if (!_locked)
{
ClearCacheIfNeeded();
}
LinkedListNode<long> Node = SortedCache.AddLast(Key);
LinkedListNode<long> node = _sortedCache.AddLast(key);
CacheBucket NewBucket = new CacheBucket(Value, Size, Node);
CacheBucket newBucket = new CacheBucket(value, size, node);
if (Cache.TryGetValue(Key, out CacheBucket Bucket))
if (_cache.TryGetValue(key, out CacheBucket bucket))
{
if (Locked)
if (_locked)
{
DeletePending.Enqueue(Bucket.Value);
_deletePending.Enqueue(bucket.Value);
}
else
{
DeleteValueCallback(Bucket.Value);
_deleteValueCallback(bucket.Value);
}
SortedCache.Remove(Bucket.Node);
_sortedCache.Remove(bucket.Node);
TotalSize -= Bucket.DataSize;
_totalSize -= bucket.DataSize;
Cache[Key] = NewBucket;
_cache[key] = newBucket;
}
else
{
Cache.Add(Key, NewBucket);
_cache.Add(key, newBucket);
}
TotalSize += Size;
_totalSize += size;
}
public bool TryGetValue(long Key, out T Value)
public bool TryGetValue(long key, out T value)
{
if (Cache.TryGetValue(Key, out CacheBucket Bucket))
if (_cache.TryGetValue(key, out CacheBucket bucket))
{
Value = Bucket.Value;
value = bucket.Value;
SortedCache.Remove(Bucket.Node);
_sortedCache.Remove(bucket.Node);
LinkedListNode<long> Node = SortedCache.AddLast(Key);
LinkedListNode<long> node = _sortedCache.AddLast(key);
Cache[Key] = new CacheBucket(Value, Bucket.DataSize, Node);
_cache[key] = new CacheBucket(value, bucket.DataSize, node);
return true;
}
Value = default(T);
value = default(T);
return false;
}
public bool TryGetSize(long Key, out long Size)
public bool TryGetSize(long key, out long size)
{
if (Cache.TryGetValue(Key, out CacheBucket Bucket))
if (_cache.TryGetValue(key, out CacheBucket bucket))
{
Size = Bucket.DataSize;
size = bucket.DataSize;
return true;
}
Size = 0;
size = 0;
return false;
}
private void ClearCacheIfNeeded()
{
long Timestamp = PerformanceCounter.ElapsedMilliseconds;
long timestamp = PerformanceCounter.ElapsedMilliseconds;
int Count = 0;
int count = 0;
while (Count++ < MaxRemovalsPerRun)
while (count++ < MaxRemovalsPerRun)
{
LinkedListNode<long> Node = SortedCache.First;
LinkedListNode<long> node = _sortedCache.First;
if (Node == null)
if (node == null)
{
break;
}
CacheBucket Bucket = Cache[Node.Value];
CacheBucket bucket = _cache[node.Value];
long TimeDelta = Timestamp - Bucket.Timestamp;
long timeDelta = timestamp - bucket.Timestamp;
if (TimeDelta <= MinTimeDelta && !UnderMemoryPressure())
if (timeDelta <= MinTimeDelta && !UnderMemoryPressure())
{
break;
}
SortedCache.Remove(Node);
_sortedCache.Remove(node);
Cache.Remove(Node.Value);
_cache.Remove(node.Value);
DeleteValueCallback(Bucket.Value);
_deleteValueCallback(bucket.Value);
TotalSize -= Bucket.DataSize;
_totalSize -= bucket.DataSize;
}
}
private bool UnderMemoryPressure()
{
return TotalSize >= MaxSize;
return _totalSize >= _maxSize;
}
}
}

View file

@ -3,72 +3,72 @@ using System;
namespace Ryujinx.Graphics.Gal.OpenGL
{
class OGLConstBuffer : IGalConstBuffer
class OglConstBuffer : IGalConstBuffer
{
private const long MaxConstBufferCacheSize = 64 * 1024 * 1024;
private OGLCachedResource<OGLStreamBuffer> Cache;
private OglCachedResource<OglStreamBuffer> _cache;
public OGLConstBuffer()
public OglConstBuffer()
{
Cache = new OGLCachedResource<OGLStreamBuffer>(DeleteBuffer, MaxConstBufferCacheSize);
_cache = new OglCachedResource<OglStreamBuffer>(DeleteBuffer, MaxConstBufferCacheSize);
}
public void LockCache()
{
Cache.Lock();
_cache.Lock();
}
public void UnlockCache()
{
Cache.Unlock();
_cache.Unlock();
}
public void Create(long Key, long Size)
public void Create(long key, long size)
{
OGLStreamBuffer Buffer = new OGLStreamBuffer(BufferTarget.UniformBuffer, Size);
OglStreamBuffer buffer = new OglStreamBuffer(BufferTarget.UniformBuffer, size);
Cache.AddOrUpdate(Key, Buffer, Size);
_cache.AddOrUpdate(key, buffer, size);
}
public bool IsCached(long Key, long Size)
public bool IsCached(long key, long size)
{
return Cache.TryGetSize(Key, out long CachedSize) && CachedSize == Size;
return _cache.TryGetSize(key, out long cachedSize) && cachedSize == size;
}
public void SetData(long Key, long Size, IntPtr HostAddress)
public void SetData(long key, long size, IntPtr hostAddress)
{
if (Cache.TryGetValue(Key, out OGLStreamBuffer Buffer))
if (_cache.TryGetValue(key, out OglStreamBuffer buffer))
{
Buffer.SetData(Size, HostAddress);
buffer.SetData(size, hostAddress);
}
}
public void SetData(long Key, byte[] Data)
public void SetData(long key, byte[] data)
{
if (Cache.TryGetValue(Key, out OGLStreamBuffer Buffer))
if (_cache.TryGetValue(key, out OglStreamBuffer buffer))
{
Buffer.SetData(Data);
buffer.SetData(data);
}
}
public bool TryGetUbo(long Key, out int UboHandle)
public bool TryGetUbo(long key, out int uboHandle)
{
if (Cache.TryGetValue(Key, out OGLStreamBuffer Buffer))
if (_cache.TryGetValue(key, out OglStreamBuffer buffer))
{
UboHandle = Buffer.Handle;
uboHandle = buffer.Handle;
return true;
}
UboHandle = 0;
uboHandle = 0;
return false;
}
private static void DeleteBuffer(OGLStreamBuffer Buffer)
private static void DeleteBuffer(OglStreamBuffer buffer)
{
Buffer.Dispose();
buffer.Dispose();
}
}
}

View file

@ -3,34 +3,34 @@ using System;
namespace Ryujinx.Graphics.Gal.OpenGL
{
static class OGLEnumConverter
static class OglEnumConverter
{
public static FrontFaceDirection GetFrontFace(GalFrontFace FrontFace)
public static FrontFaceDirection GetFrontFace(GalFrontFace frontFace)
{
switch (FrontFace)
switch (frontFace)
{
case GalFrontFace.CW: return FrontFaceDirection.Cw;
case GalFrontFace.CCW: return FrontFaceDirection.Ccw;
}
throw new ArgumentException(nameof(FrontFace) + " \"" + FrontFace + "\" is not valid!");
throw new ArgumentException(nameof(frontFace) + " \"" + frontFace + "\" is not valid!");
}
public static CullFaceMode GetCullFace(GalCullFace CullFace)
public static CullFaceMode GetCullFace(GalCullFace cullFace)
{
switch (CullFace)
switch (cullFace)
{
case GalCullFace.Front: return CullFaceMode.Front;
case GalCullFace.Back: return CullFaceMode.Back;
case GalCullFace.FrontAndBack: return CullFaceMode.FrontAndBack;
}
throw new ArgumentException(nameof(CullFace) + " \"" + CullFace + "\" is not valid!");
throw new ArgumentException(nameof(cullFace) + " \"" + cullFace + "\" is not valid!");
}
public static StencilOp GetStencilOp(GalStencilOp Op)
public static StencilOp GetStencilOp(GalStencilOp op)
{
switch (Op)
switch (op)
{
case GalStencilOp.Keep: return StencilOp.Keep;
case GalStencilOp.Zero: return StencilOp.Zero;
@ -42,28 +42,28 @@ namespace Ryujinx.Graphics.Gal.OpenGL
case GalStencilOp.DecrWrap: return StencilOp.DecrWrap;
}
throw new ArgumentException(nameof(Op) + " \"" + Op + "\" is not valid!");
throw new ArgumentException(nameof(op) + " \"" + op + "\" is not valid!");
}
public static DepthFunction GetDepthFunc(GalComparisonOp Func)
public static DepthFunction GetDepthFunc(GalComparisonOp func)
{
return (DepthFunction)GetFunc(Func);
return (DepthFunction)GetFunc(func);
}
public static StencilFunction GetStencilFunc(GalComparisonOp Func)
public static StencilFunction GetStencilFunc(GalComparisonOp func)
{
return (StencilFunction)GetFunc(Func);
return (StencilFunction)GetFunc(func);
}
private static All GetFunc(GalComparisonOp Func)
private static All GetFunc(GalComparisonOp func)
{
if ((int)Func >= (int)All.Never &&
(int)Func <= (int)All.Always)
if ((int)func >= (int)All.Never &&
(int)func <= (int)All.Always)
{
return (All)Func;
return (All)func;
}
switch (Func)
switch (func)
{
case GalComparisonOp.Never: return All.Never;
case GalComparisonOp.Less: return All.Less;
@ -75,24 +75,24 @@ namespace Ryujinx.Graphics.Gal.OpenGL
case GalComparisonOp.Always: return All.Always;
}
throw new ArgumentException(nameof(Func) + " \"" + Func + "\" is not valid!");
throw new ArgumentException(nameof(func) + " \"" + func + "\" is not valid!");
}
public static DrawElementsType GetDrawElementsType(GalIndexFormat Format)
public static DrawElementsType GetDrawElementsType(GalIndexFormat format)
{
switch (Format)
switch (format)
{
case GalIndexFormat.Byte: return DrawElementsType.UnsignedByte;
case GalIndexFormat.Int16: return DrawElementsType.UnsignedShort;
case GalIndexFormat.Int32: return DrawElementsType.UnsignedInt;
}
throw new ArgumentException(nameof(Format) + " \"" + Format + "\" is not valid!");
throw new ArgumentException(nameof(format) + " \"" + format + "\" is not valid!");
}
public static PrimitiveType GetPrimitiveType(GalPrimitiveType Type)
public static PrimitiveType GetPrimitiveType(GalPrimitiveType type)
{
switch (Type)
switch (type)
{
case GalPrimitiveType.Points: return PrimitiveType.Points;
case GalPrimitiveType.Lines: return PrimitiveType.Lines;
@ -109,12 +109,12 @@ namespace Ryujinx.Graphics.Gal.OpenGL
case GalPrimitiveType.Patches: return PrimitiveType.Patches;
}
throw new ArgumentException(nameof(Type) + " \"" + Type + "\" is not valid!");
throw new ArgumentException(nameof(type) + " \"" + type + "\" is not valid!");
}
public static ShaderType GetShaderType(GalShaderType Type)
public static ShaderType GetShaderType(GalShaderType type)
{
switch (Type)
switch (type)
{
case GalShaderType.Vertex: return ShaderType.VertexShader;
case GalShaderType.TessControl: return ShaderType.TessControlShader;
@ -123,12 +123,12 @@ namespace Ryujinx.Graphics.Gal.OpenGL
case GalShaderType.Fragment: return ShaderType.FragmentShader;
}
throw new ArgumentException(nameof(Type) + " \"" + Type + "\" is not valid!");
throw new ArgumentException(nameof(type) + " \"" + type + "\" is not valid!");
}
public static (PixelInternalFormat, PixelFormat, PixelType) GetImageFormat(GalImageFormat Format)
public static (PixelInternalFormat, PixelFormat, PixelType) GetImageFormat(GalImageFormat format)
{
switch (Format)
switch (format)
{
case GalImageFormat.RGBA32 | GalImageFormat.Float: return (PixelInternalFormat.Rgba32f, PixelFormat.Rgba, PixelType.Float);
case GalImageFormat.RGBA32 | GalImageFormat.Sint: return (PixelInternalFormat.Rgba32i, PixelFormat.RgbaInteger, PixelType.Int);
@ -186,12 +186,12 @@ namespace Ryujinx.Graphics.Gal.OpenGL
case GalImageFormat.D32S8 | GalImageFormat.Float: return (PixelInternalFormat.Depth32fStencil8, PixelFormat.DepthStencil, PixelType.Float32UnsignedInt248Rev);
}
throw new NotImplementedException($"{Format & GalImageFormat.FormatMask} {Format & GalImageFormat.TypeMask}");
throw new NotImplementedException($"{format & GalImageFormat.FormatMask} {format & GalImageFormat.TypeMask}");
}
public static All GetDepthCompareFunc(DepthCompareFunc DepthCompareFunc)
public static All GetDepthCompareFunc(DepthCompareFunc depthCompareFunc)
{
switch (DepthCompareFunc)
switch (depthCompareFunc)
{
case DepthCompareFunc.LEqual:
return All.Lequal;
@ -210,13 +210,13 @@ namespace Ryujinx.Graphics.Gal.OpenGL
case DepthCompareFunc.Never:
return All.Never;
default:
throw new ArgumentException(nameof(DepthCompareFunc) + " \"" + DepthCompareFunc + "\" is not valid!");
throw new ArgumentException(nameof(depthCompareFunc) + " \"" + depthCompareFunc + "\" is not valid!");
}
}
public static InternalFormat GetCompressedImageFormat(GalImageFormat Format)
public static InternalFormat GetCompressedImageFormat(GalImageFormat format)
{
switch (Format)
switch (format)
{
case GalImageFormat.BptcSfloat | GalImageFormat.Float: return InternalFormat.CompressedRgbBptcSignedFloat;
case GalImageFormat.BptcUfloat | GalImageFormat.Float: return InternalFormat.CompressedRgbBptcUnsignedFloat;
@ -234,12 +234,12 @@ namespace Ryujinx.Graphics.Gal.OpenGL
case GalImageFormat.BC5 | GalImageFormat.Unorm: return InternalFormat.CompressedRgRgtc2;
}
throw new NotImplementedException($"{Format & GalImageFormat.FormatMask} {Format & GalImageFormat.TypeMask}");
throw new NotImplementedException($"{format & GalImageFormat.FormatMask} {format & GalImageFormat.TypeMask}");
}
public static All GetTextureSwizzle(GalTextureSource Source)
public static All GetTextureSwizzle(GalTextureSource source)
{
switch (Source)
switch (source)
{
case GalTextureSource.Zero: return All.Zero;
case GalTextureSource.Red: return All.Red;
@ -250,12 +250,12 @@ namespace Ryujinx.Graphics.Gal.OpenGL
case GalTextureSource.OneFloat: return All.One;
}
throw new ArgumentException(nameof(Source) + " \"" + Source + "\" is not valid!");
throw new ArgumentException(nameof(source) + " \"" + source + "\" is not valid!");
}
public static TextureWrapMode GetTextureWrapMode(GalTextureWrap Wrap)
public static TextureWrapMode GetTextureWrapMode(GalTextureWrap wrap)
{
switch (Wrap)
switch (wrap)
{
case GalTextureWrap.Repeat: return TextureWrapMode.Repeat;
case GalTextureWrap.MirroredRepeat: return TextureWrapMode.MirroredRepeat;
@ -264,9 +264,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
case GalTextureWrap.Clamp: return TextureWrapMode.Clamp;
}
if (OGLExtension.TextureMirrorClamp)
if (OglExtension.TextureMirrorClamp)
{
switch (Wrap)
switch (wrap)
{
case GalTextureWrap.MirrorClampToEdge: return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampToEdgeExt;
case GalTextureWrap.MirrorClampToBorder: return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampToBorderExt;
@ -276,7 +276,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
else
{
//Fallback to non-mirrored clamps
switch (Wrap)
switch (wrap)
{
case GalTextureWrap.MirrorClampToEdge: return TextureWrapMode.ClampToEdge;
case GalTextureWrap.MirrorClampToBorder: return TextureWrapMode.ClampToBorder;
@ -284,37 +284,37 @@ namespace Ryujinx.Graphics.Gal.OpenGL
}
}
throw new ArgumentException(nameof(Wrap) + " \"" + Wrap + "\" is not valid!");
throw new ArgumentException(nameof(wrap) + " \"" + wrap + "\" is not valid!");
}
public static TextureMinFilter GetTextureMinFilter(
GalTextureFilter MinFilter,
GalTextureMipFilter MipFilter)
GalTextureFilter minFilter,
GalTextureMipFilter mipFilter)
{
//TODO: Mip (needs mipmap support first).
switch (MinFilter)
switch (minFilter)
{
case GalTextureFilter.Nearest: return TextureMinFilter.Nearest;
case GalTextureFilter.Linear: return TextureMinFilter.Linear;
}
throw new ArgumentException(nameof(MinFilter) + " \"" + MinFilter + "\" is not valid!");
throw new ArgumentException(nameof(minFilter) + " \"" + minFilter + "\" is not valid!");
}
public static TextureMagFilter GetTextureMagFilter(GalTextureFilter Filter)
public static TextureMagFilter GetTextureMagFilter(GalTextureFilter filter)
{
switch (Filter)
switch (filter)
{
case GalTextureFilter.Nearest: return TextureMagFilter.Nearest;
case GalTextureFilter.Linear: return TextureMagFilter.Linear;
}
throw new ArgumentException(nameof(Filter) + " \"" + Filter + "\" is not valid!");
throw new ArgumentException(nameof(filter) + " \"" + filter + "\" is not valid!");
}
public static BlendEquationMode GetBlendEquation(GalBlendEquation BlendEquation)
public static BlendEquationMode GetBlendEquation(GalBlendEquation blendEquation)
{
switch (BlendEquation)
switch (blendEquation)
{
case GalBlendEquation.FuncAdd:
case GalBlendEquation.FuncAddGl:
@ -337,12 +337,12 @@ namespace Ryujinx.Graphics.Gal.OpenGL
return BlendEquationMode.Max;
}
throw new ArgumentException(nameof(BlendEquation) + " \"" + BlendEquation + "\" is not valid!");
throw new ArgumentException(nameof(blendEquation) + " \"" + blendEquation + "\" is not valid!");
}
public static BlendingFactor GetBlendFactor(GalBlendFactor BlendFactor)
public static BlendingFactor GetBlendFactor(GalBlendFactor blendFactor)
{
switch (BlendFactor)
switch (blendFactor)
{
case GalBlendFactor.Zero:
case GalBlendFactor.ZeroGl:
@ -421,7 +421,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
return BlendingFactor.ConstantColor;
}
throw new ArgumentException(nameof(BlendFactor) + " \"" + BlendFactor + "\" is not valid!");
throw new ArgumentException(nameof(blendFactor) + " \"" + blendFactor + "\" is not valid!");
}
}
}

View file

@ -3,7 +3,7 @@ using System;
namespace Ryujinx.Graphics.Gal.OpenGL
{
static class OGLExtension
static class OglExtension
{
private static Lazy<bool> _enhancedLayouts = new Lazy<bool>(() => HasExtension("GL_ARB_enhanced_layouts"));
private static Lazy<bool> _textureMirrorClamp = new Lazy<bool>(() => HasExtension("GL_EXT_texture_mirror_clamp"));
@ -16,13 +16,13 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public static bool ViewportArray => _viewportArray.Value;
public static bool NvidiaDriver => _nvidiaDriver.Value;
private static bool HasExtension(string Name)
private static bool HasExtension(string name)
{
int NumExtensions = GL.GetInteger(GetPName.NumExtensions);
int numExtensions = GL.GetInteger(GetPName.NumExtensions);
for (int Extension = 0; Extension < NumExtensions; Extension++)
for (int extension = 0; extension < numExtensions; extension++)
{
if (GL.GetString(StringNameIndexed.Extensions, Extension) == Name)
if (GL.GetString(StringNameIndexed.Extensions, extension) == name)
{
return true;
}

View file

@ -3,10 +3,10 @@ using System;
namespace Ryujinx.Graphics.Gal.OpenGL
{
static class OGLLimit
static class OglLimit
{
private static Lazy<int> s_MaxUboSize = new Lazy<int>(() => GL.GetInteger(GetPName.MaxUniformBlockSize));
private static Lazy<int> _sMaxUboSize = new Lazy<int>(() => GL.GetInteger(GetPName.MaxUniformBlockSize));
public static int MaxUboSize => s_MaxUboSize.Value;
public static int MaxUboSize => _sMaxUboSize.Value;
}
}

View file

@ -4,9 +4,9 @@ using System.Collections.Generic;
namespace Ryujinx.Graphics.Gal.OpenGL
{
class OGLPipeline : IGalPipeline
class OglPipeline : IGalPipeline
{
private static Dictionary<GalVertexAttribSize, int> AttribElements =
private static Dictionary<GalVertexAttribSize, int> _attribElements =
new Dictionary<GalVertexAttribSize, int>()
{
{ GalVertexAttribSize._32_32_32_32, 4 },
@ -25,7 +25,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{ GalVertexAttribSize._11_11_10, 3 }
};
private static Dictionary<GalVertexAttribSize, VertexAttribPointerType> FloatAttribTypes =
private static Dictionary<GalVertexAttribSize, VertexAttribPointerType> _floatAttribTypes =
new Dictionary<GalVertexAttribSize, VertexAttribPointerType>()
{
{ GalVertexAttribSize._32_32_32_32, VertexAttribPointerType.Float },
@ -38,7 +38,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{ GalVertexAttribSize._16, VertexAttribPointerType.HalfFloat }
};
private static Dictionary<GalVertexAttribSize, VertexAttribPointerType> SignedAttribTypes =
private static Dictionary<GalVertexAttribSize, VertexAttribPointerType> _signedAttribTypes =
new Dictionary<GalVertexAttribSize, VertexAttribPointerType>()
{
{ GalVertexAttribSize._32_32_32_32, VertexAttribPointerType.Int },
@ -56,7 +56,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{ GalVertexAttribSize._10_10_10_2, VertexAttribPointerType.Int2101010Rev }
};
private static Dictionary<GalVertexAttribSize, VertexAttribPointerType> UnsignedAttribTypes =
private static Dictionary<GalVertexAttribSize, VertexAttribPointerType> _unsignedAttribTypes =
new Dictionary<GalVertexAttribSize, VertexAttribPointerType>()
{
{ GalVertexAttribSize._32_32_32_32, VertexAttribPointerType.UnsignedInt },
@ -75,28 +75,28 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{ GalVertexAttribSize._11_11_10, VertexAttribPointerType.UnsignedInt10F11F11FRev }
};
private GalPipelineState Old;
private GalPipelineState _old;
private OGLConstBuffer Buffer;
private OGLRenderTarget RenderTarget;
private OGLRasterizer Rasterizer;
private OGLShader Shader;
private OglConstBuffer _buffer;
private OglRenderTarget _renderTarget;
private OglRasterizer _rasterizer;
private OglShader _shader;
private int VaoHandle;
private int _vaoHandle;
public OGLPipeline(
OGLConstBuffer Buffer,
OGLRenderTarget RenderTarget,
OGLRasterizer Rasterizer,
OGLShader Shader)
public OglPipeline(
OglConstBuffer buffer,
OglRenderTarget renderTarget,
OglRasterizer rasterizer,
OglShader shader)
{
this.Buffer = Buffer;
this.RenderTarget = RenderTarget;
this.Rasterizer = Rasterizer;
this.Shader = Shader;
_buffer = buffer;
_renderTarget = renderTarget;
_rasterizer = rasterizer;
_shader = shader;
//These values match OpenGL's defaults
Old = new GalPipelineState
_old = new GalPipelineState
{
FrontFace = GalFrontFace.CCW,
@ -133,11 +133,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL
PrimitiveRestartIndex = 0
};
for (int Index = 0; Index < GalPipelineState.RenderTargetsCount; Index++)
for (int index = 0; index < GalPipelineState.RenderTargetsCount; index++)
{
Old.Blends[Index] = BlendState.Default;
_old.Blends[index] = BlendState.Default;
Old.ColorMasks[Index] = ColorMaskState.Default;
_old.ColorMasks[index] = ColorMaskState.Default;
}
}
@ -147,122 +147,122 @@ namespace Ryujinx.Graphics.Gal.OpenGL
BindVertexLayout(New);
if (New.FramebufferSrgb != Old.FramebufferSrgb)
if (New.FramebufferSrgb != _old.FramebufferSrgb)
{
Enable(EnableCap.FramebufferSrgb, New.FramebufferSrgb);
RenderTarget.FramebufferSrgb = New.FramebufferSrgb;
_renderTarget.FramebufferSrgb = New.FramebufferSrgb;
}
if (New.FlipX != Old.FlipX || New.FlipY != Old.FlipY || New.Instance != Old.Instance)
if (New.FlipX != _old.FlipX || New.FlipY != _old.FlipY || New.Instance != _old.Instance)
{
Shader.SetExtraData(New.FlipX, New.FlipY, New.Instance);
_shader.SetExtraData(New.FlipX, New.FlipY, New.Instance);
}
if (New.FrontFace != Old.FrontFace)
if (New.FrontFace != _old.FrontFace)
{
GL.FrontFace(OGLEnumConverter.GetFrontFace(New.FrontFace));
GL.FrontFace(OglEnumConverter.GetFrontFace(New.FrontFace));
}
if (New.CullFaceEnabled != Old.CullFaceEnabled)
if (New.CullFaceEnabled != _old.CullFaceEnabled)
{
Enable(EnableCap.CullFace, New.CullFaceEnabled);
}
if (New.CullFaceEnabled)
{
if (New.CullFace != Old.CullFace)
if (New.CullFace != _old.CullFace)
{
GL.CullFace(OGLEnumConverter.GetCullFace(New.CullFace));
GL.CullFace(OglEnumConverter.GetCullFace(New.CullFace));
}
}
if (New.DepthTestEnabled != Old.DepthTestEnabled)
if (New.DepthTestEnabled != _old.DepthTestEnabled)
{
Enable(EnableCap.DepthTest, New.DepthTestEnabled);
}
if (New.DepthWriteEnabled != Old.DepthWriteEnabled)
if (New.DepthWriteEnabled != _old.DepthWriteEnabled)
{
GL.DepthMask(New.DepthWriteEnabled);
}
if (New.DepthTestEnabled)
{
if (New.DepthFunc != Old.DepthFunc)
if (New.DepthFunc != _old.DepthFunc)
{
GL.DepthFunc(OGLEnumConverter.GetDepthFunc(New.DepthFunc));
GL.DepthFunc(OglEnumConverter.GetDepthFunc(New.DepthFunc));
}
}
if (New.DepthRangeNear != Old.DepthRangeNear ||
New.DepthRangeFar != Old.DepthRangeFar)
if (New.DepthRangeNear != _old.DepthRangeNear ||
New.DepthRangeFar != _old.DepthRangeFar)
{
GL.DepthRange(New.DepthRangeNear, New.DepthRangeFar);
}
if (New.StencilTestEnabled != Old.StencilTestEnabled)
if (New.StencilTestEnabled != _old.StencilTestEnabled)
{
Enable(EnableCap.StencilTest, New.StencilTestEnabled);
}
if (New.StencilTwoSideEnabled != Old.StencilTwoSideEnabled)
if (New.StencilTwoSideEnabled != _old.StencilTwoSideEnabled)
{
Enable((EnableCap)All.StencilTestTwoSideExt, New.StencilTwoSideEnabled);
}
if (New.StencilTestEnabled)
{
if (New.StencilBackFuncFunc != Old.StencilBackFuncFunc ||
New.StencilBackFuncRef != Old.StencilBackFuncRef ||
New.StencilBackFuncMask != Old.StencilBackFuncMask)
if (New.StencilBackFuncFunc != _old.StencilBackFuncFunc ||
New.StencilBackFuncRef != _old.StencilBackFuncRef ||
New.StencilBackFuncMask != _old.StencilBackFuncMask)
{
GL.StencilFuncSeparate(
StencilFace.Back,
OGLEnumConverter.GetStencilFunc(New.StencilBackFuncFunc),
OglEnumConverter.GetStencilFunc(New.StencilBackFuncFunc),
New.StencilBackFuncRef,
New.StencilBackFuncMask);
}
if (New.StencilBackOpFail != Old.StencilBackOpFail ||
New.StencilBackOpZFail != Old.StencilBackOpZFail ||
New.StencilBackOpZPass != Old.StencilBackOpZPass)
if (New.StencilBackOpFail != _old.StencilBackOpFail ||
New.StencilBackOpZFail != _old.StencilBackOpZFail ||
New.StencilBackOpZPass != _old.StencilBackOpZPass)
{
GL.StencilOpSeparate(
StencilFace.Back,
OGLEnumConverter.GetStencilOp(New.StencilBackOpFail),
OGLEnumConverter.GetStencilOp(New.StencilBackOpZFail),
OGLEnumConverter.GetStencilOp(New.StencilBackOpZPass));
OglEnumConverter.GetStencilOp(New.StencilBackOpFail),
OglEnumConverter.GetStencilOp(New.StencilBackOpZFail),
OglEnumConverter.GetStencilOp(New.StencilBackOpZPass));
}
if (New.StencilBackMask != Old.StencilBackMask)
if (New.StencilBackMask != _old.StencilBackMask)
{
GL.StencilMaskSeparate(StencilFace.Back, New.StencilBackMask);
}
if (New.StencilFrontFuncFunc != Old.StencilFrontFuncFunc ||
New.StencilFrontFuncRef != Old.StencilFrontFuncRef ||
New.StencilFrontFuncMask != Old.StencilFrontFuncMask)
if (New.StencilFrontFuncFunc != _old.StencilFrontFuncFunc ||
New.StencilFrontFuncRef != _old.StencilFrontFuncRef ||
New.StencilFrontFuncMask != _old.StencilFrontFuncMask)
{
GL.StencilFuncSeparate(
StencilFace.Front,
OGLEnumConverter.GetStencilFunc(New.StencilFrontFuncFunc),
OglEnumConverter.GetStencilFunc(New.StencilFrontFuncFunc),
New.StencilFrontFuncRef,
New.StencilFrontFuncMask);
}
if (New.StencilFrontOpFail != Old.StencilFrontOpFail ||
New.StencilFrontOpZFail != Old.StencilFrontOpZFail ||
New.StencilFrontOpZPass != Old.StencilFrontOpZPass)
if (New.StencilFrontOpFail != _old.StencilFrontOpFail ||
New.StencilFrontOpZFail != _old.StencilFrontOpZFail ||
New.StencilFrontOpZPass != _old.StencilFrontOpZPass)
{
GL.StencilOpSeparate(
StencilFace.Front,
OGLEnumConverter.GetStencilOp(New.StencilFrontOpFail),
OGLEnumConverter.GetStencilOp(New.StencilFrontOpZFail),
OGLEnumConverter.GetStencilOp(New.StencilFrontOpZPass));
OglEnumConverter.GetStencilOp(New.StencilFrontOpFail),
OglEnumConverter.GetStencilOp(New.StencilFrontOpZFail),
OglEnumConverter.GetStencilOp(New.StencilFrontOpZPass));
}
if (New.StencilFrontMask != Old.StencilFrontMask)
if (New.StencilFrontMask != _old.StencilFrontMask)
{
GL.StencilMaskSeparate(StencilFace.Front, New.StencilFrontMask);
}
@ -272,11 +272,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL
// Scissor Test
bool forceUpdate;
for (int Index = 0; Index < New.ScissorTestCount; Index++)
for (int index = 0; index < New.ScissorTestCount; index++)
{
forceUpdate = false;
if (New.ScissorTestEnabled[Index])
if (New.ScissorTestEnabled[index])
{
// If there is only 1 scissor test, geometry shaders are disabled so the scissor test applies to all viewports
if (New.ScissorTestCount == 1)
@ -285,32 +285,32 @@ namespace Ryujinx.Graphics.Gal.OpenGL
}
else
{
GL.Enable(IndexedEnableCap.ScissorTest, Index);
GL.Enable(IndexedEnableCap.ScissorTest, index);
}
forceUpdate = true;
}
else
{
GL.Disable(IndexedEnableCap.ScissorTest, Index);
GL.Disable(IndexedEnableCap.ScissorTest, index);
}
if (New.ScissorTestEnabled[Index] &&
(New.ScissorTestX[Index] != Old.ScissorTestX[Index] ||
New.ScissorTestY[Index] != Old.ScissorTestY[Index] ||
New.ScissorTestWidth[Index] != Old.ScissorTestWidth[Index] ||
New.ScissorTestHeight[Index] != Old.ScissorTestHeight[Index] ||
if (New.ScissorTestEnabled[index] &&
(New.ScissorTestX[index] != _old.ScissorTestX[index] ||
New.ScissorTestY[index] != _old.ScissorTestY[index] ||
New.ScissorTestWidth[index] != _old.ScissorTestWidth[index] ||
New.ScissorTestHeight[index] != _old.ScissorTestHeight[index] ||
forceUpdate)) // Force update intentionally last to reduce if comparisons
{
// If there is only 1 scissor test geometry shaders are disables so the scissor test applies to all viewports
if (New.ScissorTestCount == 1)
{
GL.Scissor(New.ScissorTestX[Index], New.ScissorTestY[Index],
New.ScissorTestWidth[Index], New.ScissorTestHeight[Index]);
GL.Scissor(New.ScissorTestX[index], New.ScissorTestY[index],
New.ScissorTestWidth[index], New.ScissorTestHeight[index]);
}
else
{
GL.ScissorIndexed(Index, New.ScissorTestX[Index], New.ScissorTestY[Index],
New.ScissorTestWidth[Index], New.ScissorTestHeight[Index]);
GL.ScissorIndexed(index, New.ScissorTestX[index], New.ScissorTestY[index],
New.ScissorTestWidth[index], New.ScissorTestHeight[index]);
}
}
}
@ -318,26 +318,26 @@ namespace Ryujinx.Graphics.Gal.OpenGL
if (New.BlendIndependent)
{
for (int Index = 0; Index < GalPipelineState.RenderTargetsCount; Index++)
for (int index = 0; index < GalPipelineState.RenderTargetsCount; index++)
{
SetBlendState(Index, New.Blends[Index], Old.Blends[Index]);
SetBlendState(index, New.Blends[index], _old.Blends[index]);
}
}
else
{
if (New.BlendIndependent != Old.BlendIndependent)
if (New.BlendIndependent != _old.BlendIndependent)
{
SetAllBlendState(New.Blends[0]);
}
else
{
SetBlendState(New.Blends[0], Old.Blends[0]);
SetBlendState(New.Blends[0], _old.Blends[0]);
}
}
if (New.ColorMaskCommon)
{
if (New.ColorMaskCommon != Old.ColorMaskCommon || !New.ColorMasks[0].Equals(Old.ColorMasks[0]))
if (New.ColorMaskCommon != _old.ColorMaskCommon || !New.ColorMasks[0].Equals(_old.ColorMasks[0]))
{
GL.ColorMask(
New.ColorMasks[0].Red,
@ -348,34 +348,34 @@ namespace Ryujinx.Graphics.Gal.OpenGL
}
else
{
for (int Index = 0; Index < GalPipelineState.RenderTargetsCount; Index++)
for (int index = 0; index < GalPipelineState.RenderTargetsCount; index++)
{
if (!New.ColorMasks[Index].Equals(Old.ColorMasks[Index]))
if (!New.ColorMasks[index].Equals(_old.ColorMasks[index]))
{
GL.ColorMask(
Index,
New.ColorMasks[Index].Red,
New.ColorMasks[Index].Green,
New.ColorMasks[Index].Blue,
New.ColorMasks[Index].Alpha);
index,
New.ColorMasks[index].Red,
New.ColorMasks[index].Green,
New.ColorMasks[index].Blue,
New.ColorMasks[index].Alpha);
}
}
}
if (New.PrimitiveRestartEnabled != Old.PrimitiveRestartEnabled)
if (New.PrimitiveRestartEnabled != _old.PrimitiveRestartEnabled)
{
Enable(EnableCap.PrimitiveRestart, New.PrimitiveRestartEnabled);
}
if (New.PrimitiveRestartEnabled)
{
if (New.PrimitiveRestartIndex != Old.PrimitiveRestartIndex)
if (New.PrimitiveRestartIndex != _old.PrimitiveRestartIndex)
{
GL.PrimitiveRestartIndex(New.PrimitiveRestartIndex);
}
}
Old = New;
_old = New;
}
private void SetAllBlendState(BlendState New)
@ -387,29 +387,29 @@ namespace Ryujinx.Graphics.Gal.OpenGL
if (New.SeparateAlpha)
{
GL.BlendEquationSeparate(
OGLEnumConverter.GetBlendEquation(New.EquationRgb),
OGLEnumConverter.GetBlendEquation(New.EquationAlpha));
OglEnumConverter.GetBlendEquation(New.EquationRgb),
OglEnumConverter.GetBlendEquation(New.EquationAlpha));
GL.BlendFuncSeparate(
(BlendingFactorSrc) OGLEnumConverter.GetBlendFactor(New.FuncSrcRgb),
(BlendingFactorDest)OGLEnumConverter.GetBlendFactor(New.FuncDstRgb),
(BlendingFactorSrc) OGLEnumConverter.GetBlendFactor(New.FuncSrcAlpha),
(BlendingFactorDest)OGLEnumConverter.GetBlendFactor(New.FuncDstAlpha));
(BlendingFactorSrc) OglEnumConverter.GetBlendFactor(New.FuncSrcRgb),
(BlendingFactorDest)OglEnumConverter.GetBlendFactor(New.FuncDstRgb),
(BlendingFactorSrc) OglEnumConverter.GetBlendFactor(New.FuncSrcAlpha),
(BlendingFactorDest)OglEnumConverter.GetBlendFactor(New.FuncDstAlpha));
}
else
{
GL.BlendEquation(OGLEnumConverter.GetBlendEquation(New.EquationRgb));
GL.BlendEquation(OglEnumConverter.GetBlendEquation(New.EquationRgb));
GL.BlendFunc(
OGLEnumConverter.GetBlendFactor(New.FuncSrcRgb),
OGLEnumConverter.GetBlendFactor(New.FuncDstRgb));
OglEnumConverter.GetBlendFactor(New.FuncSrcRgb),
OglEnumConverter.GetBlendFactor(New.FuncDstRgb));
}
}
}
private void SetBlendState(BlendState New, BlendState Old)
private void SetBlendState(BlendState New, BlendState old)
{
if (New.Enabled != Old.Enabled)
if (New.Enabled != old.Enabled)
{
Enable(EnableCap.Blend, New.Enabled);
}
@ -418,91 +418,91 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
if (New.SeparateAlpha)
{
if (New.EquationRgb != Old.EquationRgb ||
New.EquationAlpha != Old.EquationAlpha)
if (New.EquationRgb != old.EquationRgb ||
New.EquationAlpha != old.EquationAlpha)
{
GL.BlendEquationSeparate(
OGLEnumConverter.GetBlendEquation(New.EquationRgb),
OGLEnumConverter.GetBlendEquation(New.EquationAlpha));
OglEnumConverter.GetBlendEquation(New.EquationRgb),
OglEnumConverter.GetBlendEquation(New.EquationAlpha));
}
if (New.FuncSrcRgb != Old.FuncSrcRgb ||
New.FuncDstRgb != Old.FuncDstRgb ||
New.FuncSrcAlpha != Old.FuncSrcAlpha ||
New.FuncDstAlpha != Old.FuncDstAlpha)
if (New.FuncSrcRgb != old.FuncSrcRgb ||
New.FuncDstRgb != old.FuncDstRgb ||
New.FuncSrcAlpha != old.FuncSrcAlpha ||
New.FuncDstAlpha != old.FuncDstAlpha)
{
GL.BlendFuncSeparate(
(BlendingFactorSrc) OGLEnumConverter.GetBlendFactor(New.FuncSrcRgb),
(BlendingFactorDest)OGLEnumConverter.GetBlendFactor(New.FuncDstRgb),
(BlendingFactorSrc) OGLEnumConverter.GetBlendFactor(New.FuncSrcAlpha),
(BlendingFactorDest)OGLEnumConverter.GetBlendFactor(New.FuncDstAlpha));
(BlendingFactorSrc) OglEnumConverter.GetBlendFactor(New.FuncSrcRgb),
(BlendingFactorDest)OglEnumConverter.GetBlendFactor(New.FuncDstRgb),
(BlendingFactorSrc) OglEnumConverter.GetBlendFactor(New.FuncSrcAlpha),
(BlendingFactorDest)OglEnumConverter.GetBlendFactor(New.FuncDstAlpha));
}
}
else
{
if (New.EquationRgb != Old.EquationRgb)
if (New.EquationRgb != old.EquationRgb)
{
GL.BlendEquation(OGLEnumConverter.GetBlendEquation(New.EquationRgb));
GL.BlendEquation(OglEnumConverter.GetBlendEquation(New.EquationRgb));
}
if (New.FuncSrcRgb != Old.FuncSrcRgb ||
New.FuncDstRgb != Old.FuncDstRgb)
if (New.FuncSrcRgb != old.FuncSrcRgb ||
New.FuncDstRgb != old.FuncDstRgb)
{
GL.BlendFunc(
OGLEnumConverter.GetBlendFactor(New.FuncSrcRgb),
OGLEnumConverter.GetBlendFactor(New.FuncDstRgb));
OglEnumConverter.GetBlendFactor(New.FuncSrcRgb),
OglEnumConverter.GetBlendFactor(New.FuncDstRgb));
}
}
}
}
private void SetBlendState(int Index, BlendState New, BlendState Old)
private void SetBlendState(int index, BlendState New, BlendState old)
{
if (New.Enabled != Old.Enabled)
if (New.Enabled != old.Enabled)
{
Enable(IndexedEnableCap.Blend, Index, New.Enabled);
Enable(IndexedEnableCap.Blend, index, New.Enabled);
}
if (New.Enabled)
{
if (New.SeparateAlpha)
{
if (New.EquationRgb != Old.EquationRgb ||
New.EquationAlpha != Old.EquationAlpha)
if (New.EquationRgb != old.EquationRgb ||
New.EquationAlpha != old.EquationAlpha)
{
GL.BlendEquationSeparate(
Index,
OGLEnumConverter.GetBlendEquation(New.EquationRgb),
OGLEnumConverter.GetBlendEquation(New.EquationAlpha));
index,
OglEnumConverter.GetBlendEquation(New.EquationRgb),
OglEnumConverter.GetBlendEquation(New.EquationAlpha));
}
if (New.FuncSrcRgb != Old.FuncSrcRgb ||
New.FuncDstRgb != Old.FuncDstRgb ||
New.FuncSrcAlpha != Old.FuncSrcAlpha ||
New.FuncDstAlpha != Old.FuncDstAlpha)
if (New.FuncSrcRgb != old.FuncSrcRgb ||
New.FuncDstRgb != old.FuncDstRgb ||
New.FuncSrcAlpha != old.FuncSrcAlpha ||
New.FuncDstAlpha != old.FuncDstAlpha)
{
GL.BlendFuncSeparate(
Index,
(BlendingFactorSrc) OGLEnumConverter.GetBlendFactor(New.FuncSrcRgb),
(BlendingFactorDest)OGLEnumConverter.GetBlendFactor(New.FuncDstRgb),
(BlendingFactorSrc) OGLEnumConverter.GetBlendFactor(New.FuncSrcAlpha),
(BlendingFactorDest)OGLEnumConverter.GetBlendFactor(New.FuncDstAlpha));
index,
(BlendingFactorSrc) OglEnumConverter.GetBlendFactor(New.FuncSrcRgb),
(BlendingFactorDest)OglEnumConverter.GetBlendFactor(New.FuncDstRgb),
(BlendingFactorSrc) OglEnumConverter.GetBlendFactor(New.FuncSrcAlpha),
(BlendingFactorDest)OglEnumConverter.GetBlendFactor(New.FuncDstAlpha));
}
}
else
{
if (New.EquationRgb != Old.EquationRgb)
if (New.EquationRgb != old.EquationRgb)
{
GL.BlendEquation(Index, OGLEnumConverter.GetBlendEquation(New.EquationRgb));
GL.BlendEquation(index, OglEnumConverter.GetBlendEquation(New.EquationRgb));
}
if (New.FuncSrcRgb != Old.FuncSrcRgb ||
New.FuncDstRgb != Old.FuncDstRgb)
if (New.FuncSrcRgb != old.FuncSrcRgb ||
New.FuncDstRgb != old.FuncDstRgb)
{
GL.BlendFunc(
Index,
(BlendingFactorSrc) OGLEnumConverter.GetBlendFactor(New.FuncSrcRgb),
(BlendingFactorDest)OGLEnumConverter.GetBlendFactor(New.FuncDstRgb));
index,
(BlendingFactorSrc) OglEnumConverter.GetBlendFactor(New.FuncSrcRgb),
(BlendingFactorDest)OglEnumConverter.GetBlendFactor(New.FuncDstRgb));
}
}
}
@ -510,310 +510,310 @@ namespace Ryujinx.Graphics.Gal.OpenGL
private void BindConstBuffers(GalPipelineState New)
{
int FreeBinding = OGLShader.ReservedCbufCount;
int freeBinding = OglShader.ReservedCbufCount;
void BindIfNotNull(OGLShaderStage Stage)
void BindIfNotNull(OglShaderStage stage)
{
if (Stage != null)
if (stage != null)
{
foreach (ShaderDeclInfo DeclInfo in Stage.ConstBufferUsage)
foreach (ShaderDeclInfo declInfo in stage.ConstBufferUsage)
{
long Key = New.ConstBufferKeys[(int)Stage.Type][DeclInfo.Cbuf];
long key = New.ConstBufferKeys[(int)stage.Type][declInfo.Cbuf];
if (Key != 0 && Buffer.TryGetUbo(Key, out int UboHandle))
if (key != 0 && _buffer.TryGetUbo(key, out int uboHandle))
{
GL.BindBufferBase(BufferRangeTarget.UniformBuffer, FreeBinding, UboHandle);
GL.BindBufferBase(BufferRangeTarget.UniformBuffer, freeBinding, uboHandle);
}
FreeBinding++;
freeBinding++;
}
}
}
BindIfNotNull(Shader.Current.Vertex);
BindIfNotNull(Shader.Current.TessControl);
BindIfNotNull(Shader.Current.TessEvaluation);
BindIfNotNull(Shader.Current.Geometry);
BindIfNotNull(Shader.Current.Fragment);
BindIfNotNull(_shader.Current.Vertex);
BindIfNotNull(_shader.Current.TessControl);
BindIfNotNull(_shader.Current.TessEvaluation);
BindIfNotNull(_shader.Current.Geometry);
BindIfNotNull(_shader.Current.Fragment);
}
private void BindVertexLayout(GalPipelineState New)
{
foreach (GalVertexBinding Binding in New.VertexBindings)
foreach (GalVertexBinding binding in New.VertexBindings)
{
if (!Binding.Enabled || !Rasterizer.TryGetVbo(Binding.VboKey, out int VboHandle))
if (!binding.Enabled || !_rasterizer.TryGetVbo(binding.VboKey, out int vboHandle))
{
continue;
}
if (VaoHandle == 0)
if (_vaoHandle == 0)
{
VaoHandle = GL.GenVertexArray();
_vaoHandle = GL.GenVertexArray();
//Vertex arrays shouldn't be used anywhere else in OpenGL's backend
//if you want to use it, move this line out of the if
GL.BindVertexArray(VaoHandle);
GL.BindVertexArray(_vaoHandle);
}
foreach (GalVertexAttrib Attrib in Binding.Attribs)
foreach (GalVertexAttrib attrib in binding.Attribs)
{
//Skip uninitialized attributes.
if (Attrib.Size == 0)
if (attrib.Size == 0)
{
continue;
}
GL.BindBuffer(BufferTarget.ArrayBuffer, VboHandle);
GL.BindBuffer(BufferTarget.ArrayBuffer, vboHandle);
bool Unsigned =
Attrib.Type == GalVertexAttribType.Unorm ||
Attrib.Type == GalVertexAttribType.Uint ||
Attrib.Type == GalVertexAttribType.Uscaled;
bool unsigned =
attrib.Type == GalVertexAttribType.Unorm ||
attrib.Type == GalVertexAttribType.Uint ||
attrib.Type == GalVertexAttribType.Uscaled;
bool Normalize =
Attrib.Type == GalVertexAttribType.Snorm ||
Attrib.Type == GalVertexAttribType.Unorm;
bool normalize =
attrib.Type == GalVertexAttribType.Snorm ||
attrib.Type == GalVertexAttribType.Unorm;
VertexAttribPointerType Type = 0;
VertexAttribPointerType type = 0;
if (Attrib.Type == GalVertexAttribType.Float)
if (attrib.Type == GalVertexAttribType.Float)
{
Type = GetType(FloatAttribTypes, Attrib);
type = GetType(_floatAttribTypes, attrib);
}
else
{
if (Unsigned)
if (unsigned)
{
Type = GetType(UnsignedAttribTypes, Attrib);
type = GetType(_unsignedAttribTypes, attrib);
}
else
{
Type = GetType(SignedAttribTypes, Attrib);
type = GetType(_signedAttribTypes, attrib);
}
}
if (!AttribElements.TryGetValue(Attrib.Size, out int Size))
if (!_attribElements.TryGetValue(attrib.Size, out int size))
{
throw new InvalidOperationException("Invalid attribute size \"" + Attrib.Size + "\"!");
throw new InvalidOperationException("Invalid attribute size \"" + attrib.Size + "\"!");
}
int Offset = Attrib.Offset;
int offset = attrib.Offset;
if (Binding.Stride != 0)
if (binding.Stride != 0)
{
GL.EnableVertexAttribArray(Attrib.Index);
GL.EnableVertexAttribArray(attrib.Index);
if (Attrib.Type == GalVertexAttribType.Sint ||
Attrib.Type == GalVertexAttribType.Uint)
if (attrib.Type == GalVertexAttribType.Sint ||
attrib.Type == GalVertexAttribType.Uint)
{
IntPtr Pointer = new IntPtr(Offset);
IntPtr pointer = new IntPtr(offset);
VertexAttribIntegerType IType = (VertexAttribIntegerType)Type;
VertexAttribIntegerType iType = (VertexAttribIntegerType)type;
GL.VertexAttribIPointer(Attrib.Index, Size, IType, Binding.Stride, Pointer);
GL.VertexAttribIPointer(attrib.Index, size, iType, binding.Stride, pointer);
}
else
{
GL.VertexAttribPointer(Attrib.Index, Size, Type, Normalize, Binding.Stride, Offset);
GL.VertexAttribPointer(attrib.Index, size, type, normalize, binding.Stride, offset);
}
}
else
{
GL.DisableVertexAttribArray(Attrib.Index);
GL.DisableVertexAttribArray(attrib.Index);
SetConstAttrib(Attrib);
SetConstAttrib(attrib);
}
if (Binding.Instanced && Binding.Divisor != 0)
if (binding.Instanced && binding.Divisor != 0)
{
GL.VertexAttribDivisor(Attrib.Index, 1);
GL.VertexAttribDivisor(attrib.Index, 1);
}
else
{
GL.VertexAttribDivisor(Attrib.Index, 0);
GL.VertexAttribDivisor(attrib.Index, 0);
}
}
}
}
private static VertexAttribPointerType GetType(Dictionary<GalVertexAttribSize, VertexAttribPointerType> Dict, GalVertexAttrib Attrib)
private static VertexAttribPointerType GetType(Dictionary<GalVertexAttribSize, VertexAttribPointerType> dict, GalVertexAttrib attrib)
{
if (!Dict.TryGetValue(Attrib.Size, out VertexAttribPointerType Type))
if (!dict.TryGetValue(attrib.Size, out VertexAttribPointerType type))
{
ThrowUnsupportedAttrib(Attrib);
ThrowUnsupportedAttrib(attrib);
}
return Type;
return type;
}
private unsafe static void SetConstAttrib(GalVertexAttrib Attrib)
private unsafe static void SetConstAttrib(GalVertexAttrib attrib)
{
if (Attrib.Size == GalVertexAttribSize._10_10_10_2 ||
Attrib.Size == GalVertexAttribSize._11_11_10)
if (attrib.Size == GalVertexAttribSize._10_10_10_2 ||
attrib.Size == GalVertexAttribSize._11_11_10)
{
ThrowUnsupportedAttrib(Attrib);
ThrowUnsupportedAttrib(attrib);
}
fixed (byte* Ptr = Attrib.Data)
fixed (byte* ptr = attrib.Data)
{
if (Attrib.Type == GalVertexAttribType.Unorm)
if (attrib.Type == GalVertexAttribType.Unorm)
{
switch (Attrib.Size)
switch (attrib.Size)
{
case GalVertexAttribSize._8:
case GalVertexAttribSize._8_8:
case GalVertexAttribSize._8_8_8:
case GalVertexAttribSize._8_8_8_8:
GL.VertexAttrib4N((uint)Attrib.Index, Ptr);
GL.VertexAttrib4N((uint)attrib.Index, ptr);
break;
case GalVertexAttribSize._16:
case GalVertexAttribSize._16_16:
case GalVertexAttribSize._16_16_16:
case GalVertexAttribSize._16_16_16_16:
GL.VertexAttrib4N((uint)Attrib.Index, (ushort*)Ptr);
GL.VertexAttrib4N((uint)attrib.Index, (ushort*)ptr);
break;
case GalVertexAttribSize._32:
case GalVertexAttribSize._32_32:
case GalVertexAttribSize._32_32_32:
case GalVertexAttribSize._32_32_32_32:
GL.VertexAttrib4N((uint)Attrib.Index, (uint*)Ptr);
GL.VertexAttrib4N((uint)attrib.Index, (uint*)ptr);
break;
}
}
else if (Attrib.Type == GalVertexAttribType.Snorm)
else if (attrib.Type == GalVertexAttribType.Snorm)
{
switch (Attrib.Size)
switch (attrib.Size)
{
case GalVertexAttribSize._8:
case GalVertexAttribSize._8_8:
case GalVertexAttribSize._8_8_8:
case GalVertexAttribSize._8_8_8_8:
GL.VertexAttrib4N((uint)Attrib.Index, (sbyte*)Ptr);
GL.VertexAttrib4N((uint)attrib.Index, (sbyte*)ptr);
break;
case GalVertexAttribSize._16:
case GalVertexAttribSize._16_16:
case GalVertexAttribSize._16_16_16:
case GalVertexAttribSize._16_16_16_16:
GL.VertexAttrib4N((uint)Attrib.Index, (short*)Ptr);
GL.VertexAttrib4N((uint)attrib.Index, (short*)ptr);
break;
case GalVertexAttribSize._32:
case GalVertexAttribSize._32_32:
case GalVertexAttribSize._32_32_32:
case GalVertexAttribSize._32_32_32_32:
GL.VertexAttrib4N((uint)Attrib.Index, (int*)Ptr);
GL.VertexAttrib4N((uint)attrib.Index, (int*)ptr);
break;
}
}
else if (Attrib.Type == GalVertexAttribType.Uint)
else if (attrib.Type == GalVertexAttribType.Uint)
{
switch (Attrib.Size)
switch (attrib.Size)
{
case GalVertexAttribSize._8:
case GalVertexAttribSize._8_8:
case GalVertexAttribSize._8_8_8:
case GalVertexAttribSize._8_8_8_8:
GL.VertexAttribI4((uint)Attrib.Index, Ptr);
GL.VertexAttribI4((uint)attrib.Index, ptr);
break;
case GalVertexAttribSize._16:
case GalVertexAttribSize._16_16:
case GalVertexAttribSize._16_16_16:
case GalVertexAttribSize._16_16_16_16:
GL.VertexAttribI4((uint)Attrib.Index, (ushort*)Ptr);
GL.VertexAttribI4((uint)attrib.Index, (ushort*)ptr);
break;
case GalVertexAttribSize._32:
case GalVertexAttribSize._32_32:
case GalVertexAttribSize._32_32_32:
case GalVertexAttribSize._32_32_32_32:
GL.VertexAttribI4((uint)Attrib.Index, (uint*)Ptr);
GL.VertexAttribI4((uint)attrib.Index, (uint*)ptr);
break;
}
}
else if (Attrib.Type == GalVertexAttribType.Sint)
else if (attrib.Type == GalVertexAttribType.Sint)
{
switch (Attrib.Size)
switch (attrib.Size)
{
case GalVertexAttribSize._8:
case GalVertexAttribSize._8_8:
case GalVertexAttribSize._8_8_8:
case GalVertexAttribSize._8_8_8_8:
GL.VertexAttribI4((uint)Attrib.Index, (sbyte*)Ptr);
GL.VertexAttribI4((uint)attrib.Index, (sbyte*)ptr);
break;
case GalVertexAttribSize._16:
case GalVertexAttribSize._16_16:
case GalVertexAttribSize._16_16_16:
case GalVertexAttribSize._16_16_16_16:
GL.VertexAttribI4((uint)Attrib.Index, (short*)Ptr);
GL.VertexAttribI4((uint)attrib.Index, (short*)ptr);
break;
case GalVertexAttribSize._32:
case GalVertexAttribSize._32_32:
case GalVertexAttribSize._32_32_32:
case GalVertexAttribSize._32_32_32_32:
GL.VertexAttribI4((uint)Attrib.Index, (int*)Ptr);
GL.VertexAttribI4((uint)attrib.Index, (int*)ptr);
break;
}
}
else if (Attrib.Type == GalVertexAttribType.Float)
else if (attrib.Type == GalVertexAttribType.Float)
{
switch (Attrib.Size)
switch (attrib.Size)
{
case GalVertexAttribSize._32:
case GalVertexAttribSize._32_32:
case GalVertexAttribSize._32_32_32:
case GalVertexAttribSize._32_32_32_32:
GL.VertexAttrib4(Attrib.Index, (float*)Ptr);
GL.VertexAttrib4(attrib.Index, (float*)ptr);
break;
default: ThrowUnsupportedAttrib(Attrib); break;
default: ThrowUnsupportedAttrib(attrib); break;
}
}
}
}
private static void ThrowUnsupportedAttrib(GalVertexAttrib Attrib)
private static void ThrowUnsupportedAttrib(GalVertexAttrib attrib)
{
throw new NotImplementedException("Unsupported size \"" + Attrib.Size + "\" on type \"" + Attrib.Type + "\"!");
throw new NotImplementedException("Unsupported size \"" + attrib.Size + "\" on type \"" + attrib.Type + "\"!");
}
private void Enable(EnableCap Cap, bool Enabled)
private void Enable(EnableCap cap, bool enabled)
{
if (Enabled)
if (enabled)
{
GL.Enable(Cap);
GL.Enable(cap);
}
else
{
GL.Disable(Cap);
GL.Disable(cap);
}
}
private void Enable(IndexedEnableCap Cap, int Index, bool Enabled)
private void Enable(IndexedEnableCap cap, int index, bool enabled)
{
if (Enabled)
if (enabled)
{
GL.Enable(Cap, Index);
GL.Enable(cap, index);
}
else
{
GL.Disable(Cap, Index);
GL.Disable(cap, index);
}
}
public void ResetDepthMask()
{
Old.DepthWriteEnabled = true;
_old.DepthWriteEnabled = true;
}
public void ResetColorMask(int Index)
public void ResetColorMask(int index)
{
Old.ColorMasks[Index] = ColorMaskState.Default;
_old.ColorMasks[index] = ColorMaskState.Default;
}
}
}

View file

@ -3,15 +3,15 @@ using System;
namespace Ryujinx.Graphics.Gal.OpenGL
{
class OGLRasterizer : IGalRasterizer
class OglRasterizer : IGalRasterizer
{
private const long MaxVertexBufferCacheSize = 128 * 1024 * 1024;
private const long MaxIndexBufferCacheSize = 64 * 1024 * 1024;
private int[] VertexBuffers;
private int[] _vertexBuffers;
private OGLCachedResource<int> VboCache;
private OGLCachedResource<int> IboCache;
private OglCachedResource<int> _vboCache;
private OglCachedResource<int> _iboCache;
private struct IbInfo
{
@ -21,187 +21,187 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public DrawElementsType Type;
}
private IbInfo IndexBuffer;
private IbInfo _indexBuffer;
public OGLRasterizer()
public OglRasterizer()
{
VertexBuffers = new int[32];
_vertexBuffers = new int[32];
VboCache = new OGLCachedResource<int>(GL.DeleteBuffer, MaxVertexBufferCacheSize);
IboCache = new OGLCachedResource<int>(GL.DeleteBuffer, MaxIndexBufferCacheSize);
_vboCache = new OglCachedResource<int>(GL.DeleteBuffer, MaxVertexBufferCacheSize);
_iboCache = new OglCachedResource<int>(GL.DeleteBuffer, MaxIndexBufferCacheSize);
IndexBuffer = new IbInfo();
_indexBuffer = new IbInfo();
}
public void LockCaches()
{
VboCache.Lock();
IboCache.Lock();
_vboCache.Lock();
_iboCache.Lock();
}
public void UnlockCaches()
{
VboCache.Unlock();
IboCache.Unlock();
_vboCache.Unlock();
_iboCache.Unlock();
}
public void ClearBuffers(
GalClearBufferFlags Flags,
int Attachment,
float Red,
float Green,
float Blue,
float Alpha,
float Depth,
int Stencil)
GalClearBufferFlags flags,
int attachment,
float red,
float green,
float blue,
float alpha,
float depth,
int stencil)
{
GL.ColorMask(
Attachment,
Flags.HasFlag(GalClearBufferFlags.ColorRed),
Flags.HasFlag(GalClearBufferFlags.ColorGreen),
Flags.HasFlag(GalClearBufferFlags.ColorBlue),
Flags.HasFlag(GalClearBufferFlags.ColorAlpha));
attachment,
flags.HasFlag(GalClearBufferFlags.ColorRed),
flags.HasFlag(GalClearBufferFlags.ColorGreen),
flags.HasFlag(GalClearBufferFlags.ColorBlue),
flags.HasFlag(GalClearBufferFlags.ColorAlpha));
GL.ClearBuffer(ClearBuffer.Color, Attachment, new float[] { Red, Green, Blue, Alpha });
GL.ClearBuffer(ClearBuffer.Color, attachment, new float[] { red, green, blue, alpha });
GL.ColorMask(Attachment, true, true, true, true);
GL.ColorMask(attachment, true, true, true, true);
GL.DepthMask(true);
if (Flags.HasFlag(GalClearBufferFlags.Depth))
if (flags.HasFlag(GalClearBufferFlags.Depth))
{
GL.ClearBuffer(ClearBuffer.Depth, 0, ref Depth);
GL.ClearBuffer(ClearBuffer.Depth, 0, ref depth);
}
if (Flags.HasFlag(GalClearBufferFlags.Stencil))
if (flags.HasFlag(GalClearBufferFlags.Stencil))
{
GL.ClearBuffer(ClearBuffer.Stencil, 0, ref Stencil);
GL.ClearBuffer(ClearBuffer.Stencil, 0, ref stencil);
}
}
public bool IsVboCached(long Key, long DataSize)
public bool IsVboCached(long key, long dataSize)
{
return VboCache.TryGetSize(Key, out long Size) && Size == DataSize;
return _vboCache.TryGetSize(key, out long size) && size == dataSize;
}
public bool IsIboCached(long Key, long DataSize)
public bool IsIboCached(long key, long dataSize)
{
return IboCache.TryGetSize(Key, out long Size) && Size == DataSize;
return _iboCache.TryGetSize(key, out long size) && size == dataSize;
}
public void CreateVbo(long Key, int DataSize, IntPtr HostAddress)
public void CreateVbo(long key, int dataSize, IntPtr hostAddress)
{
int Handle = GL.GenBuffer();
int handle = GL.GenBuffer();
VboCache.AddOrUpdate(Key, Handle, DataSize);
_vboCache.AddOrUpdate(key, handle, dataSize);
IntPtr Length = new IntPtr(DataSize);
IntPtr length = new IntPtr(dataSize);
GL.BindBuffer(BufferTarget.ArrayBuffer, Handle);
GL.BufferData(BufferTarget.ArrayBuffer, Length, HostAddress, BufferUsageHint.StreamDraw);
GL.BindBuffer(BufferTarget.ArrayBuffer, handle);
GL.BufferData(BufferTarget.ArrayBuffer, length, hostAddress, BufferUsageHint.StreamDraw);
}
public void CreateVbo(long Key, byte[] Data)
public void CreateVbo(long key, byte[] data)
{
int Handle = GL.GenBuffer();
int handle = GL.GenBuffer();
VboCache.AddOrUpdate(Key, Handle, Data.Length);
_vboCache.AddOrUpdate(key, handle, data.Length);
IntPtr Length = new IntPtr(Data.Length);
IntPtr length = new IntPtr(data.Length);
GL.BindBuffer(BufferTarget.ArrayBuffer, Handle);
GL.BufferData(BufferTarget.ArrayBuffer, Length, Data, BufferUsageHint.StreamDraw);
GL.BindBuffer(BufferTarget.ArrayBuffer, handle);
GL.BufferData(BufferTarget.ArrayBuffer, length, data, BufferUsageHint.StreamDraw);
}
public void CreateIbo(long Key, int DataSize, IntPtr HostAddress)
public void CreateIbo(long key, int dataSize, IntPtr hostAddress)
{
int Handle = GL.GenBuffer();
int handle = GL.GenBuffer();
IboCache.AddOrUpdate(Key, Handle, (uint)DataSize);
_iboCache.AddOrUpdate(key, handle, (uint)dataSize);
IntPtr Length = new IntPtr(DataSize);
IntPtr length = new IntPtr(dataSize);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, Handle);
GL.BufferData(BufferTarget.ElementArrayBuffer, Length, HostAddress, BufferUsageHint.StreamDraw);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, handle);
GL.BufferData(BufferTarget.ElementArrayBuffer, length, hostAddress, BufferUsageHint.StreamDraw);
}
public void CreateIbo(long Key, int DataSize, byte[] Buffer)
public void CreateIbo(long key, int dataSize, byte[] buffer)
{
int Handle = GL.GenBuffer();
int handle = GL.GenBuffer();
IboCache.AddOrUpdate(Key, Handle, DataSize);
_iboCache.AddOrUpdate(key, handle, dataSize);
IntPtr Length = new IntPtr(Buffer.Length);
IntPtr length = new IntPtr(buffer.Length);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, Handle);
GL.BufferData(BufferTarget.ElementArrayBuffer, Length, Buffer, BufferUsageHint.StreamDraw);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, handle);
GL.BufferData(BufferTarget.ElementArrayBuffer, length, buffer, BufferUsageHint.StreamDraw);
}
public void SetIndexArray(int Size, GalIndexFormat Format)
public void SetIndexArray(int size, GalIndexFormat format)
{
IndexBuffer.Type = OGLEnumConverter.GetDrawElementsType(Format);
_indexBuffer.Type = OglEnumConverter.GetDrawElementsType(format);
IndexBuffer.Count = Size >> (int)Format;
_indexBuffer.Count = size >> (int)format;
IndexBuffer.ElemSizeLog2 = (int)Format;
_indexBuffer.ElemSizeLog2 = (int)format;
}
public void DrawArrays(int First, int Count, GalPrimitiveType PrimType)
public void DrawArrays(int first, int count, GalPrimitiveType primType)
{
if (Count == 0)
if (count == 0)
{
return;
}
if (PrimType == GalPrimitiveType.Quads)
if (primType == GalPrimitiveType.Quads)
{
for (int Offset = 0; Offset < Count; Offset += 4)
for (int offset = 0; offset < count; offset += 4)
{
GL.DrawArrays(PrimitiveType.TriangleFan, First + Offset, 4);
GL.DrawArrays(PrimitiveType.TriangleFan, first + offset, 4);
}
}
else if (PrimType == GalPrimitiveType.QuadStrip)
else if (primType == GalPrimitiveType.QuadStrip)
{
GL.DrawArrays(PrimitiveType.TriangleFan, First, 4);
GL.DrawArrays(PrimitiveType.TriangleFan, first, 4);
for (int Offset = 2; Offset < Count; Offset += 2)
for (int offset = 2; offset < count; offset += 2)
{
GL.DrawArrays(PrimitiveType.TriangleFan, First + Offset, 4);
GL.DrawArrays(PrimitiveType.TriangleFan, first + offset, 4);
}
}
else
{
GL.DrawArrays(OGLEnumConverter.GetPrimitiveType(PrimType), First, Count);
GL.DrawArrays(OglEnumConverter.GetPrimitiveType(primType), first, count);
}
}
public void DrawElements(long IboKey, int First, int VertexBase, GalPrimitiveType PrimType)
public void DrawElements(long iboKey, int first, int vertexBase, GalPrimitiveType primType)
{
if (!IboCache.TryGetValue(IboKey, out int IboHandle))
if (!_iboCache.TryGetValue(iboKey, out int iboHandle))
{
return;
}
PrimitiveType Mode = OGLEnumConverter.GetPrimitiveType(PrimType);
PrimitiveType mode = OglEnumConverter.GetPrimitiveType(primType);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, IboHandle);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, iboHandle);
First <<= IndexBuffer.ElemSizeLog2;
first <<= _indexBuffer.ElemSizeLog2;
if (VertexBase != 0)
if (vertexBase != 0)
{
IntPtr Indices = new IntPtr(First);
IntPtr indices = new IntPtr(first);
GL.DrawElementsBaseVertex(Mode, IndexBuffer.Count, IndexBuffer.Type, Indices, VertexBase);
GL.DrawElementsBaseVertex(mode, _indexBuffer.Count, _indexBuffer.Type, indices, vertexBase);
}
else
{
GL.DrawElements(Mode, IndexBuffer.Count, IndexBuffer.Type, First);
GL.DrawElements(mode, _indexBuffer.Count, _indexBuffer.Type, first);
}
}
public bool TryGetVbo(long VboKey, out int VboHandle)
public bool TryGetVbo(long vboKey, out int vboHandle)
{
return VboCache.TryGetValue(VboKey, out VboHandle);
return _vboCache.TryGetValue(vboKey, out vboHandle);
}
}
}

View file

@ -4,7 +4,7 @@ using System;
namespace Ryujinx.Graphics.Gal.OpenGL
{
class OGLRenderTarget : IGalRenderTarget
class OglRenderTarget : IGalRenderTarget
{
private const int NativeWidth = 1280;
private const int NativeHeight = 720;
@ -18,12 +18,12 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public int Width { get; private set; }
public int Height { get; private set; }
public Rect(int X, int Y, int Width, int Height)
public Rect(int x, int y, int width, int height)
{
this.X = X;
this.Y = Y;
this.Width = Width;
this.Height = Height;
X = x;
Y = y;
Width = width;
Height = height;
}
}
@ -44,141 +44,141 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Map = new DrawBuffersEnum[RenderTargetsCount];
}
public void Update(FrameBufferAttachments Source)
public void Update(FrameBufferAttachments source)
{
for (int Index = 0; Index < RenderTargetsCount; Index++)
for (int index = 0; index < RenderTargetsCount; index++)
{
Map[Index] = Source.Map[Index];
Map[index] = source.Map[index];
Colors[Index] = Source.Colors[Index];
Colors[index] = source.Colors[index];
}
MapCount = Source.MapCount;
Zeta = Source.Zeta;
MapCount = source.MapCount;
Zeta = source.Zeta;
}
}
private int[] ColorHandles;
private int ZetaHandle;
private int[] _colorHandles;
private int _zetaHandle;
private OGLTexture Texture;
private OglTexture _texture;
private ImageHandler ReadTex;
private ImageHandler _readTex;
private Rect Window;
private Rect _window;
private float[] Viewports;
private float[] _viewports;
private bool FlipX;
private bool FlipY;
private bool _flipX;
private bool _flipY;
private int CropTop;
private int CropLeft;
private int CropRight;
private int CropBottom;
private int _cropTop;
private int _cropLeft;
private int _cropRight;
private int _cropBottom;
//This framebuffer is used to attach guest rendertargets,
//think of it as a dummy OpenGL VAO
private int DummyFrameBuffer;
private int _dummyFrameBuffer;
//These framebuffers are used to blit images
private int SrcFb;
private int DstFb;
private int _srcFb;
private int _dstFb;
private FrameBufferAttachments Attachments;
private FrameBufferAttachments OldAttachments;
private FrameBufferAttachments _attachments;
private FrameBufferAttachments _oldAttachments;
private int CopyPBO;
private int _copyPbo;
public bool FramebufferSrgb { get; set; }
public OGLRenderTarget(OGLTexture Texture)
public OglRenderTarget(OglTexture texture)
{
Attachments = new FrameBufferAttachments();
_attachments = new FrameBufferAttachments();
OldAttachments = new FrameBufferAttachments();
_oldAttachments = new FrameBufferAttachments();
ColorHandles = new int[RenderTargetsCount];
_colorHandles = new int[RenderTargetsCount];
Viewports = new float[RenderTargetsCount * 4];
_viewports = new float[RenderTargetsCount * 4];
this.Texture = Texture;
_texture = texture;
Texture.TextureDeleted += TextureDeletionHandler;
texture.TextureDeleted += TextureDeletionHandler;
}
private void TextureDeletionHandler(object Sender, int Handle)
private void TextureDeletionHandler(object sender, int handle)
{
//Texture was deleted, the handle is no longer valid, so
//reset all uses of this handle on a render target.
for (int Attachment = 0; Attachment < RenderTargetsCount; Attachment++)
for (int attachment = 0; attachment < RenderTargetsCount; attachment++)
{
if (ColorHandles[Attachment] == Handle)
if (_colorHandles[attachment] == handle)
{
ColorHandles[Attachment] = 0;
_colorHandles[attachment] = 0;
}
}
if (ZetaHandle == Handle)
if (_zetaHandle == handle)
{
ZetaHandle = 0;
_zetaHandle = 0;
}
}
public void Bind()
{
if (DummyFrameBuffer == 0)
if (_dummyFrameBuffer == 0)
{
DummyFrameBuffer = GL.GenFramebuffer();
_dummyFrameBuffer = GL.GenFramebuffer();
}
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, DummyFrameBuffer);
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, _dummyFrameBuffer);
ImageHandler CachedImage;
ImageHandler cachedImage;
for (int Attachment = 0; Attachment < RenderTargetsCount; Attachment++)
for (int attachment = 0; attachment < RenderTargetsCount; attachment++)
{
long Key = Attachments.Colors[Attachment];
long key = _attachments.Colors[attachment];
int Handle = 0;
int handle = 0;
if (Key != 0 && Texture.TryGetImageHandler(Key, out CachedImage))
if (key != 0 && _texture.TryGetImageHandler(key, out cachedImage))
{
Handle = CachedImage.Handle;
handle = cachedImage.Handle;
}
if (Handle == ColorHandles[Attachment])
if (handle == _colorHandles[attachment])
{
continue;
}
GL.FramebufferTexture(
FramebufferTarget.DrawFramebuffer,
FramebufferAttachment.ColorAttachment0 + Attachment,
Handle,
FramebufferAttachment.ColorAttachment0 + attachment,
handle,
0);
ColorHandles[Attachment] = Handle;
_colorHandles[attachment] = handle;
}
if (Attachments.Zeta != 0 && Texture.TryGetImageHandler(Attachments.Zeta, out CachedImage))
if (_attachments.Zeta != 0 && _texture.TryGetImageHandler(_attachments.Zeta, out cachedImage))
{
if (CachedImage.Handle != ZetaHandle)
if (cachedImage.Handle != _zetaHandle)
{
if (CachedImage.HasDepth && CachedImage.HasStencil)
if (cachedImage.HasDepth && cachedImage.HasStencil)
{
GL.FramebufferTexture(
FramebufferTarget.DrawFramebuffer,
FramebufferAttachment.DepthStencilAttachment,
CachedImage.Handle,
cachedImage.Handle,
0);
}
else if (CachedImage.HasDepth)
else if (cachedImage.HasDepth)
{
GL.FramebufferTexture(
FramebufferTarget.DrawFramebuffer,
FramebufferAttachment.DepthAttachment,
CachedImage.Handle,
cachedImage.Handle,
0);
GL.FramebufferTexture(
@ -189,13 +189,13 @@ namespace Ryujinx.Graphics.Gal.OpenGL
}
else
{
throw new InvalidOperationException("Invalid image format \"" + CachedImage.Format + "\" used as Zeta!");
throw new InvalidOperationException("Invalid image format \"" + cachedImage.Format + "\" used as Zeta!");
}
ZetaHandle = CachedImage.Handle;
_zetaHandle = cachedImage.Handle;
}
}
else if (ZetaHandle != 0)
else if (_zetaHandle != 0)
{
GL.FramebufferTexture(
FramebufferTarget.DrawFramebuffer,
@ -203,163 +203,163 @@ namespace Ryujinx.Graphics.Gal.OpenGL
0,
0);
ZetaHandle = 0;
_zetaHandle = 0;
}
if (OGLExtension.ViewportArray)
if (OglExtension.ViewportArray)
{
GL.ViewportArray(0, RenderTargetsCount, Viewports);
GL.ViewportArray(0, RenderTargetsCount, _viewports);
}
else
{
GL.Viewport(
(int)Viewports[0],
(int)Viewports[1],
(int)Viewports[2],
(int)Viewports[3]);
(int)_viewports[0],
(int)_viewports[1],
(int)_viewports[2],
(int)_viewports[3]);
}
if (Attachments.MapCount > 1)
if (_attachments.MapCount > 1)
{
GL.DrawBuffers(Attachments.MapCount, Attachments.Map);
GL.DrawBuffers(_attachments.MapCount, _attachments.Map);
}
else if (Attachments.MapCount == 1)
else if (_attachments.MapCount == 1)
{
GL.DrawBuffer((DrawBufferMode)Attachments.Map[0]);
GL.DrawBuffer((DrawBufferMode)_attachments.Map[0]);
}
else
{
GL.DrawBuffer(DrawBufferMode.None);
}
OldAttachments.Update(Attachments);
_oldAttachments.Update(_attachments);
}
public void BindColor(long Key, int Attachment)
public void BindColor(long key, int attachment)
{
Attachments.Colors[Attachment] = Key;
_attachments.Colors[attachment] = key;
}
public void UnbindColor(int Attachment)
public void UnbindColor(int attachment)
{
Attachments.Colors[Attachment] = 0;
_attachments.Colors[attachment] = 0;
}
public void BindZeta(long Key)
public void BindZeta(long key)
{
Attachments.Zeta = Key;
_attachments.Zeta = key;
}
public void UnbindZeta()
{
Attachments.Zeta = 0;
_attachments.Zeta = 0;
}
public void Present(long Key)
public void Present(long key)
{
Texture.TryGetImageHandler(Key, out ReadTex);
_texture.TryGetImageHandler(key, out _readTex);
}
public void SetMap(int[] Map)
public void SetMap(int[] map)
{
if (Map != null)
if (map != null)
{
Attachments.MapCount = Map.Length;
_attachments.MapCount = map.Length;
for (int Attachment = 0; Attachment < Attachments.MapCount; Attachment++)
for (int attachment = 0; attachment < _attachments.MapCount; attachment++)
{
Attachments.Map[Attachment] = DrawBuffersEnum.ColorAttachment0 + Map[Attachment];
_attachments.Map[attachment] = DrawBuffersEnum.ColorAttachment0 + map[attachment];
}
}
else
{
Attachments.MapCount = 0;
_attachments.MapCount = 0;
}
}
public void SetTransform(bool FlipX, bool FlipY, int Top, int Left, int Right, int Bottom)
public void SetTransform(bool flipX, bool flipY, int top, int left, int right, int bottom)
{
this.FlipX = FlipX;
this.FlipY = FlipY;
_flipX = flipX;
_flipY = flipY;
CropTop = Top;
CropLeft = Left;
CropRight = Right;
CropBottom = Bottom;
_cropTop = top;
_cropLeft = left;
_cropRight = right;
_cropBottom = bottom;
}
public void SetWindowSize(int Width, int Height)
public void SetWindowSize(int width, int height)
{
Window = new Rect(0, 0, Width, Height);
_window = new Rect(0, 0, width, height);
}
public void SetViewport(int Attachment, int X, int Y, int Width, int Height)
public void SetViewport(int attachment, int x, int y, int width, int height)
{
int Offset = Attachment * 4;
int offset = attachment * 4;
Viewports[Offset + 0] = X;
Viewports[Offset + 1] = Y;
Viewports[Offset + 2] = Width;
Viewports[Offset + 3] = Height;
_viewports[offset + 0] = x;
_viewports[offset + 1] = y;
_viewports[offset + 2] = width;
_viewports[offset + 3] = height;
}
public void Render()
{
if (ReadTex == null)
if (_readTex == null)
{
return;
}
int SrcX0, SrcX1, SrcY0, SrcY1;
int srcX0, srcX1, srcY0, srcY1;
if (CropLeft == 0 && CropRight == 0)
if (_cropLeft == 0 && _cropRight == 0)
{
SrcX0 = 0;
SrcX1 = ReadTex.Width;
srcX0 = 0;
srcX1 = _readTex.Width;
}
else
{
SrcX0 = CropLeft;
SrcX1 = CropRight;
srcX0 = _cropLeft;
srcX1 = _cropRight;
}
if (CropTop == 0 && CropBottom == 0)
if (_cropTop == 0 && _cropBottom == 0)
{
SrcY0 = 0;
SrcY1 = ReadTex.Height;
srcY0 = 0;
srcY1 = _readTex.Height;
}
else
{
SrcY0 = CropTop;
SrcY1 = CropBottom;
srcY0 = _cropTop;
srcY1 = _cropBottom;
}
float RatioX = MathF.Min(1f, (Window.Height * (float)NativeWidth) / ((float)NativeHeight * Window.Width));
float RatioY = MathF.Min(1f, (Window.Width * (float)NativeHeight) / ((float)NativeWidth * Window.Height));
float ratioX = MathF.Min(1f, (_window.Height * (float)NativeWidth) / ((float)NativeHeight * _window.Width));
float ratioY = MathF.Min(1f, (_window.Width * (float)NativeHeight) / ((float)NativeWidth * _window.Height));
int DstWidth = (int)(Window.Width * RatioX);
int DstHeight = (int)(Window.Height * RatioY);
int dstWidth = (int)(_window.Width * ratioX);
int dstHeight = (int)(_window.Height * ratioY);
int DstPaddingX = (Window.Width - DstWidth) / 2;
int DstPaddingY = (Window.Height - DstHeight) / 2;
int dstPaddingX = (_window.Width - dstWidth) / 2;
int dstPaddingY = (_window.Height - dstHeight) / 2;
int DstX0 = FlipX ? Window.Width - DstPaddingX : DstPaddingX;
int DstX1 = FlipX ? DstPaddingX : Window.Width - DstPaddingX;
int dstX0 = _flipX ? _window.Width - dstPaddingX : dstPaddingX;
int dstX1 = _flipX ? dstPaddingX : _window.Width - dstPaddingX;
int DstY0 = FlipY ? DstPaddingY : Window.Height - DstPaddingY;
int DstY1 = FlipY ? Window.Height - DstPaddingY : DstPaddingY;
int dstY0 = _flipY ? dstPaddingY : _window.Height - dstPaddingY;
int dstY1 = _flipY ? _window.Height - dstPaddingY : dstPaddingY;
GL.Viewport(0, 0, Window.Width, Window.Height);
GL.Viewport(0, 0, _window.Width, _window.Height);
if (SrcFb == 0)
if (_srcFb == 0)
{
SrcFb = GL.GenFramebuffer();
_srcFb = GL.GenFramebuffer();
}
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, SrcFb);
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, _srcFb);
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, 0);
GL.FramebufferTexture(FramebufferTarget.ReadFramebuffer, FramebufferAttachment.ColorAttachment0, ReadTex.Handle, 0);
GL.FramebufferTexture(FramebufferTarget.ReadFramebuffer, FramebufferAttachment.ColorAttachment0, _readTex.Handle, 0);
GL.ReadBuffer(ReadBufferMode.ColorAttachment0);
@ -371,14 +371,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL
GL.Disable(EnableCap.ScissorTest);
GL.BlitFramebuffer(
SrcX0,
SrcY0,
SrcX1,
SrcY1,
DstX0,
DstY0,
DstX1,
DstY1,
srcX0,
srcY0,
srcX1,
srcY1,
dstX0,
dstY0,
dstX1,
dstY1,
ClearBufferMask.ColorBufferBit,
BlitFramebufferFilter.Linear);
@ -389,150 +389,150 @@ namespace Ryujinx.Graphics.Gal.OpenGL
}
public void Copy(
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)
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))
if (_texture.TryGetImageHandler(srcKey, out ImageHandler srcTex) &&
_texture.TryGetImageHandler(dstKey, out ImageHandler dstTex))
{
if (SrcTex.HasColor != DstTex.HasColor ||
SrcTex.HasDepth != DstTex.HasDepth ||
SrcTex.HasStencil != DstTex.HasStencil)
if (srcTex.HasColor != dstTex.HasColor ||
srcTex.HasDepth != dstTex.HasDepth ||
srcTex.HasStencil != dstTex.HasStencil)
{
throw new NotImplementedException();
}
if (SrcFb == 0)
if (_srcFb == 0)
{
SrcFb = GL.GenFramebuffer();
_srcFb = GL.GenFramebuffer();
}
if (DstFb == 0)
if (_dstFb == 0)
{
DstFb = GL.GenFramebuffer();
_dstFb = GL.GenFramebuffer();
}
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, SrcFb);
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, DstFb);
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, _srcFb);
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, _dstFb);
FramebufferAttachment Attachment = GetAttachment(SrcTex);
FramebufferAttachment attachment = GetAttachment(srcTex);
if (ImageUtils.IsArray(SrcImage.TextureTarget) && SrcLayer > 0)
if (ImageUtils.IsArray(srcImage.TextureTarget) && srcLayer > 0)
{
GL.FramebufferTextureLayer(FramebufferTarget.ReadFramebuffer, Attachment, SrcTex.Handle, 0, SrcLayer);
GL.FramebufferTextureLayer(FramebufferTarget.ReadFramebuffer, attachment, srcTex.Handle, 0, srcLayer);
}
else
{
GL.FramebufferTexture(FramebufferTarget.ReadFramebuffer, Attachment, SrcTex.Handle, 0);
GL.FramebufferTexture(FramebufferTarget.ReadFramebuffer, attachment, srcTex.Handle, 0);
}
if (ImageUtils.IsArray(DstImage.TextureTarget) && DstLayer > 0)
if (ImageUtils.IsArray(dstImage.TextureTarget) && dstLayer > 0)
{
GL.FramebufferTextureLayer(FramebufferTarget.DrawFramebuffer, Attachment, DstTex.Handle, 0, DstLayer);
GL.FramebufferTextureLayer(FramebufferTarget.DrawFramebuffer, attachment, dstTex.Handle, 0, dstLayer);
}
else
{
GL.FramebufferTexture(FramebufferTarget.DrawFramebuffer, Attachment, DstTex.Handle, 0);
GL.FramebufferTexture(FramebufferTarget.DrawFramebuffer, attachment, dstTex.Handle, 0);
}
BlitFramebufferFilter Filter = BlitFramebufferFilter.Nearest;
BlitFramebufferFilter filter = BlitFramebufferFilter.Nearest;
if (SrcTex.HasColor)
if (srcTex.HasColor)
{
GL.DrawBuffer(DrawBufferMode.ColorAttachment0);
Filter = BlitFramebufferFilter.Linear;
filter = BlitFramebufferFilter.Linear;
}
ClearBufferMask Mask = GetClearMask(SrcTex);
ClearBufferMask mask = GetClearMask(srcTex);
GL.BlitFramebuffer(SrcX0, SrcY0, SrcX1, SrcY1, DstX0, DstY0, DstX1, DstY1, Mask, Filter);
GL.BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
}
}
public void Reinterpret(long Key, GalImage NewImage)
public void Reinterpret(long key, GalImage newImage)
{
if (!Texture.TryGetImage(Key, out GalImage OldImage))
if (!_texture.TryGetImage(key, out GalImage oldImage))
{
return;
}
if (NewImage.Format == OldImage.Format &&
NewImage.Width == OldImage.Width &&
NewImage.Height == OldImage.Height &&
NewImage.Depth == OldImage.Depth &&
NewImage.LayerCount == OldImage.LayerCount &&
NewImage.TextureTarget == OldImage.TextureTarget)
if (newImage.Format == oldImage.Format &&
newImage.Width == oldImage.Width &&
newImage.Height == oldImage.Height &&
newImage.Depth == oldImage.Depth &&
newImage.LayerCount == oldImage.LayerCount &&
newImage.TextureTarget == oldImage.TextureTarget)
{
return;
}
if (CopyPBO == 0)
if (_copyPbo == 0)
{
CopyPBO = GL.GenBuffer();
_copyPbo = GL.GenBuffer();
}
GL.BindBuffer(BufferTarget.PixelPackBuffer, CopyPBO);
GL.BindBuffer(BufferTarget.PixelPackBuffer, _copyPbo);
//The buffer should be large enough to hold the largest texture.
int BufferSize = Math.Max(ImageUtils.GetSize(OldImage),
ImageUtils.GetSize(NewImage));
int bufferSize = Math.Max(ImageUtils.GetSize(oldImage),
ImageUtils.GetSize(newImage));
GL.BufferData(BufferTarget.PixelPackBuffer, BufferSize, IntPtr.Zero, BufferUsageHint.StreamCopy);
GL.BufferData(BufferTarget.PixelPackBuffer, bufferSize, IntPtr.Zero, BufferUsageHint.StreamCopy);
if (!Texture.TryGetImageHandler(Key, out ImageHandler CachedImage))
if (!_texture.TryGetImageHandler(key, out ImageHandler cachedImage))
{
throw new InvalidOperationException();
}
(_, PixelFormat Format, PixelType Type) = OGLEnumConverter.GetImageFormat(CachedImage.Format);
(_, PixelFormat format, PixelType type) = OglEnumConverter.GetImageFormat(cachedImage.Format);
TextureTarget Target = ImageUtils.GetTextureTarget(NewImage.TextureTarget);
TextureTarget target = ImageUtils.GetTextureTarget(newImage.TextureTarget);
GL.BindTexture(Target, CachedImage.Handle);
GL.BindTexture(target, cachedImage.Handle);
GL.GetTexImage(Target, 0, Format, Type, IntPtr.Zero);
GL.GetTexImage(target, 0, format, type, IntPtr.Zero);
GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyPBO);
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, _copyPbo);
GL.PixelStore(PixelStoreParameter.UnpackRowLength, OldImage.Width);
GL.PixelStore(PixelStoreParameter.UnpackRowLength, oldImage.Width);
Texture.Create(Key, ImageUtils.GetSize(NewImage), NewImage);
_texture.Create(key, ImageUtils.GetSize(newImage), newImage);
GL.PixelStore(PixelStoreParameter.UnpackRowLength, 0);
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);
}
private static FramebufferAttachment GetAttachment(ImageHandler CachedImage)
private static FramebufferAttachment GetAttachment(ImageHandler cachedImage)
{
if (CachedImage.HasColor)
if (cachedImage.HasColor)
{
return FramebufferAttachment.ColorAttachment0;
}
else if (CachedImage.HasDepth && CachedImage.HasStencil)
else if (cachedImage.HasDepth && cachedImage.HasStencil)
{
return FramebufferAttachment.DepthStencilAttachment;
}
else if (CachedImage.HasDepth)
else if (cachedImage.HasDepth)
{
return FramebufferAttachment.DepthAttachment;
}
else if (CachedImage.HasStencil)
else if (cachedImage.HasStencil)
{
return FramebufferAttachment.StencilAttachment;
}
@ -542,11 +542,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL
}
}
private static ClearBufferMask GetClearMask(ImageHandler CachedImage)
private static ClearBufferMask GetClearMask(ImageHandler cachedImage)
{
return (CachedImage.HasColor ? ClearBufferMask.ColorBufferBit : 0) |
(CachedImage.HasDepth ? ClearBufferMask.DepthBufferBit : 0) |
(CachedImage.HasStencil ? ClearBufferMask.StencilBufferBit : 0);
return (cachedImage.HasColor ? ClearBufferMask.ColorBufferBit : 0) |
(cachedImage.HasDepth ? ClearBufferMask.DepthBufferBit : 0) |
(cachedImage.HasStencil ? ClearBufferMask.StencilBufferBit : 0);
}
}
}

View file

@ -3,7 +3,7 @@ using System.Collections.Concurrent;
namespace Ryujinx.Graphics.Gal.OpenGL
{
public class OGLRenderer : IGalRenderer
public class OglRenderer : IGalRenderer
{
public IGalConstBuffer Buffer { get; private set; }
@ -17,41 +17,41 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public IGalTexture Texture { get; private set; }
private ConcurrentQueue<Action> ActionsQueue;
private ConcurrentQueue<Action> _actionsQueue;
public OGLRenderer()
public OglRenderer()
{
Buffer = new OGLConstBuffer();
Buffer = new OglConstBuffer();
Texture = new OGLTexture();
Texture = new OglTexture();
RenderTarget = new OGLRenderTarget(Texture as OGLTexture);
RenderTarget = new OglRenderTarget(Texture as OglTexture);
Rasterizer = new OGLRasterizer();
Rasterizer = new OglRasterizer();
Shader = new OGLShader(Buffer as OGLConstBuffer);
Shader = new OglShader(Buffer as OglConstBuffer);
Pipeline = new OGLPipeline(
Buffer as OGLConstBuffer,
RenderTarget as OGLRenderTarget,
Rasterizer as OGLRasterizer,
Shader as OGLShader);
Pipeline = new OglPipeline(
Buffer as OglConstBuffer,
RenderTarget as OglRenderTarget,
Rasterizer as OglRasterizer,
Shader as OglShader);
ActionsQueue = new ConcurrentQueue<Action>();
_actionsQueue = new ConcurrentQueue<Action>();
}
public void QueueAction(Action ActionMthd)
public void QueueAction(Action actionMthd)
{
ActionsQueue.Enqueue(ActionMthd);
_actionsQueue.Enqueue(actionMthd);
}
public void RunActions()
{
int Count = ActionsQueue.Count;
int count = _actionsQueue.Count;
while (Count-- > 0 && ActionsQueue.TryDequeue(out Action RenderAction))
while (count-- > 0 && _actionsQueue.TryDequeue(out Action renderAction))
{
RenderAction();
renderAction();
}
}
}

View file

@ -7,152 +7,152 @@ using System.Linq;
namespace Ryujinx.Graphics.Gal.OpenGL
{
class OGLShader : IGalShader
class OglShader : IGalShader
{
public const int ReservedCbufCount = 1;
private const int ExtraDataSize = 4;
public OGLShaderProgram Current;
public OglShaderProgram Current;
private ConcurrentDictionary<long, OGLShaderStage> Stages;
private ConcurrentDictionary<long, OglShaderStage> _stages;
private Dictionary<OGLShaderProgram, int> Programs;
private Dictionary<OglShaderProgram, int> _programs;
public int CurrentProgramHandle { get; private set; }
private OGLConstBuffer Buffer;
private OglConstBuffer _buffer;
private int ExtraUboHandle;
private int _extraUboHandle;
public OGLShader(OGLConstBuffer Buffer)
public OglShader(OglConstBuffer buffer)
{
this.Buffer = Buffer;
_buffer = buffer;
Stages = new ConcurrentDictionary<long, OGLShaderStage>();
_stages = new ConcurrentDictionary<long, OglShaderStage>();
Programs = new Dictionary<OGLShaderProgram, int>();
_programs = new Dictionary<OglShaderProgram, int>();
}
public void Create(IGalMemory Memory, long Key, GalShaderType Type)
public void Create(IGalMemory memory, long key, GalShaderType type)
{
Stages.GetOrAdd(Key, (Stage) => ShaderStageFactory(Memory, Key, 0, false, Type));
_stages.GetOrAdd(key, (stage) => ShaderStageFactory(memory, key, 0, false, type));
}
public void Create(IGalMemory Memory, long VpAPos, long Key, GalShaderType Type)
public void Create(IGalMemory memory, long vpAPos, long key, GalShaderType type)
{
Stages.GetOrAdd(Key, (Stage) => ShaderStageFactory(Memory, VpAPos, Key, true, Type));
_stages.GetOrAdd(key, (stage) => ShaderStageFactory(memory, vpAPos, key, true, type));
}
private OGLShaderStage ShaderStageFactory(
IGalMemory Memory,
long Position,
long PositionB,
bool IsDualVp,
GalShaderType Type)
private OglShaderStage ShaderStageFactory(
IGalMemory memory,
long position,
long positionB,
bool isDualVp,
GalShaderType type)
{
GlslProgram Program;
GlslProgram program;
GlslDecompiler Decompiler = new GlslDecompiler(OGLLimit.MaxUboSize, OGLExtension.NvidiaDriver);
GlslDecompiler decompiler = new GlslDecompiler(OglLimit.MaxUboSize, OglExtension.NvidiaDriver);
int ShaderDumpIndex = ShaderDumper.DumpIndex;
int shaderDumpIndex = ShaderDumper.DumpIndex;
if (IsDualVp)
if (isDualVp)
{
ShaderDumper.Dump(Memory, Position, Type, "a");
ShaderDumper.Dump(Memory, PositionB, Type, "b");
ShaderDumper.Dump(memory, position, type, "a");
ShaderDumper.Dump(memory, positionB, type, "b");
Program = Decompiler.Decompile(Memory, Position, PositionB, Type);
program = decompiler.Decompile(memory, position, positionB, type);
}
else
{
ShaderDumper.Dump(Memory, Position, Type);
ShaderDumper.Dump(memory, position, type);
Program = Decompiler.Decompile(Memory, Position, Type);
program = decompiler.Decompile(memory, position, type);
}
string Code = Program.Code;
string code = program.Code;
if (ShaderDumper.IsDumpEnabled())
{
Code = "//Shader " + ShaderDumpIndex + Environment.NewLine + Code;
code = "//Shader " + shaderDumpIndex + Environment.NewLine + code;
}
return new OGLShaderStage(Type, Code, Program.Uniforms, Program.Textures);
return new OglShaderStage(type, code, program.Uniforms, program.Textures);
}
public IEnumerable<ShaderDeclInfo> GetConstBufferUsage(long Key)
public IEnumerable<ShaderDeclInfo> GetConstBufferUsage(long key)
{
if (Stages.TryGetValue(Key, out OGLShaderStage Stage))
if (_stages.TryGetValue(key, out OglShaderStage stage))
{
return Stage.ConstBufferUsage;
return stage.ConstBufferUsage;
}
return Enumerable.Empty<ShaderDeclInfo>();
}
public IEnumerable<ShaderDeclInfo> GetTextureUsage(long Key)
public IEnumerable<ShaderDeclInfo> GetTextureUsage(long key)
{
if (Stages.TryGetValue(Key, out OGLShaderStage Stage))
if (_stages.TryGetValue(key, out OglShaderStage stage))
{
return Stage.TextureUsage;
return stage.TextureUsage;
}
return Enumerable.Empty<ShaderDeclInfo>();
}
public unsafe void SetExtraData(float FlipX, float FlipY, int Instance)
public unsafe void SetExtraData(float flipX, float flipY, int instance)
{
BindProgram();
EnsureExtraBlock();
GL.BindBuffer(BufferTarget.UniformBuffer, ExtraUboHandle);
GL.BindBuffer(BufferTarget.UniformBuffer, _extraUboHandle);
float* Data = stackalloc float[ExtraDataSize];
Data[0] = FlipX;
Data[1] = FlipY;
Data[2] = BitConverter.Int32BitsToSingle(Instance);
float* data = stackalloc float[ExtraDataSize];
data[0] = flipX;
data[1] = flipY;
data[2] = BitConverter.Int32BitsToSingle(instance);
//Invalidate buffer
GL.BufferData(BufferTarget.UniformBuffer, ExtraDataSize * sizeof(float), IntPtr.Zero, BufferUsageHint.StreamDraw);
GL.BufferSubData(BufferTarget.UniformBuffer, IntPtr.Zero, ExtraDataSize * sizeof(float), (IntPtr)Data);
GL.BufferSubData(BufferTarget.UniformBuffer, IntPtr.Zero, ExtraDataSize * sizeof(float), (IntPtr)data);
}
public void Bind(long Key)
public void Bind(long key)
{
if (Stages.TryGetValue(Key, out OGLShaderStage Stage))
if (_stages.TryGetValue(key, out OglShaderStage stage))
{
Bind(Stage);
Bind(stage);
}
}
private void Bind(OGLShaderStage Stage)
private void Bind(OglShaderStage stage)
{
if (Stage.Type == GalShaderType.Geometry)
if (stage.Type == GalShaderType.Geometry)
{
//Enhanced layouts are required for Geometry shaders
//skip this stage if current driver has no ARB_enhanced_layouts
if (!OGLExtension.EnhancedLayouts)
if (!OglExtension.EnhancedLayouts)
{
return;
}
}
switch (Stage.Type)
switch (stage.Type)
{
case GalShaderType.Vertex: Current.Vertex = Stage; break;
case GalShaderType.TessControl: Current.TessControl = Stage; break;
case GalShaderType.TessEvaluation: Current.TessEvaluation = Stage; break;
case GalShaderType.Geometry: Current.Geometry = Stage; break;
case GalShaderType.Fragment: Current.Fragment = Stage; break;
case GalShaderType.Vertex: Current.Vertex = stage; break;
case GalShaderType.TessControl: Current.TessControl = stage; break;
case GalShaderType.TessEvaluation: Current.TessEvaluation = stage; break;
case GalShaderType.Geometry: Current.Geometry = stage; break;
case GalShaderType.Fragment: Current.Fragment = stage; break;
}
}
public void Unbind(GalShaderType Type)
public void Unbind(GalShaderType type)
{
switch (Type)
switch (type)
{
case GalShaderType.Vertex: Current.Vertex = null; break;
case GalShaderType.TessControl: Current.TessControl = null; break;
@ -170,80 +170,80 @@ namespace Ryujinx.Graphics.Gal.OpenGL
return;
}
if (!Programs.TryGetValue(Current, out int Handle))
if (!_programs.TryGetValue(Current, out int handle))
{
Handle = GL.CreateProgram();
handle = GL.CreateProgram();
AttachIfNotNull(Handle, Current.Vertex);
AttachIfNotNull(Handle, Current.TessControl);
AttachIfNotNull(Handle, Current.TessEvaluation);
AttachIfNotNull(Handle, Current.Geometry);
AttachIfNotNull(Handle, Current.Fragment);
AttachIfNotNull(handle, Current.Vertex);
AttachIfNotNull(handle, Current.TessControl);
AttachIfNotNull(handle, Current.TessEvaluation);
AttachIfNotNull(handle, Current.Geometry);
AttachIfNotNull(handle, Current.Fragment);
GL.LinkProgram(Handle);
GL.LinkProgram(handle);
CheckProgramLink(Handle);
CheckProgramLink(handle);
BindUniformBlocks(Handle);
BindTextureLocations(Handle);
BindUniformBlocks(handle);
BindTextureLocations(handle);
Programs.Add(Current, Handle);
_programs.Add(Current, handle);
}
GL.UseProgram(Handle);
GL.UseProgram(handle);
CurrentProgramHandle = Handle;
CurrentProgramHandle = handle;
}
private void EnsureExtraBlock()
{
if (ExtraUboHandle == 0)
if (_extraUboHandle == 0)
{
ExtraUboHandle = GL.GenBuffer();
_extraUboHandle = GL.GenBuffer();
GL.BindBuffer(BufferTarget.UniformBuffer, ExtraUboHandle);
GL.BindBuffer(BufferTarget.UniformBuffer, _extraUboHandle);
GL.BufferData(BufferTarget.UniformBuffer, ExtraDataSize * sizeof(float), IntPtr.Zero, BufferUsageHint.StreamDraw);
GL.BindBufferBase(BufferRangeTarget.UniformBuffer, 0, ExtraUboHandle);
GL.BindBufferBase(BufferRangeTarget.UniformBuffer, 0, _extraUboHandle);
}
}
private void AttachIfNotNull(int ProgramHandle, OGLShaderStage Stage)
private void AttachIfNotNull(int programHandle, OglShaderStage stage)
{
if (Stage != null)
if (stage != null)
{
Stage.Compile();
stage.Compile();
GL.AttachShader(ProgramHandle, Stage.Handle);
GL.AttachShader(programHandle, stage.Handle);
}
}
private void BindUniformBlocks(int ProgramHandle)
private void BindUniformBlocks(int programHandle)
{
int ExtraBlockindex = GL.GetUniformBlockIndex(ProgramHandle, GlslDecl.ExtraUniformBlockName);
int extraBlockindex = GL.GetUniformBlockIndex(programHandle, GlslDecl.ExtraUniformBlockName);
GL.UniformBlockBinding(ProgramHandle, ExtraBlockindex, 0);
GL.UniformBlockBinding(programHandle, extraBlockindex, 0);
int FreeBinding = ReservedCbufCount;
int freeBinding = ReservedCbufCount;
void BindUniformBlocksIfNotNull(OGLShaderStage Stage)
void BindUniformBlocksIfNotNull(OglShaderStage stage)
{
if (Stage != null)
if (stage != null)
{
foreach (ShaderDeclInfo DeclInfo in Stage.ConstBufferUsage)
foreach (ShaderDeclInfo declInfo in stage.ConstBufferUsage)
{
int BlockIndex = GL.GetUniformBlockIndex(ProgramHandle, DeclInfo.Name);
int blockIndex = GL.GetUniformBlockIndex(programHandle, declInfo.Name);
if (BlockIndex < 0)
if (blockIndex < 0)
{
//It is expected that its found, if it's not then driver might be in a malfunction
throw new InvalidOperationException();
}
GL.UniformBlockBinding(ProgramHandle, BlockIndex, FreeBinding);
GL.UniformBlockBinding(programHandle, blockIndex, freeBinding);
FreeBinding++;
freeBinding++;
}
}
}
@ -255,26 +255,26 @@ namespace Ryujinx.Graphics.Gal.OpenGL
BindUniformBlocksIfNotNull(Current.Fragment);
}
private void BindTextureLocations(int ProgramHandle)
private void BindTextureLocations(int programHandle)
{
int Index = 0;
int index = 0;
void BindTexturesIfNotNull(OGLShaderStage Stage)
void BindTexturesIfNotNull(OglShaderStage stage)
{
if (Stage != null)
if (stage != null)
{
foreach (ShaderDeclInfo Decl in Stage.TextureUsage)
foreach (ShaderDeclInfo decl in stage.TextureUsage)
{
int Location = GL.GetUniformLocation(ProgramHandle, Decl.Name);
int location = GL.GetUniformLocation(programHandle, decl.Name);
GL.Uniform1(Location, Index);
GL.Uniform1(location, index);
Index++;
index++;
}
}
}
GL.UseProgram(ProgramHandle);
GL.UseProgram(programHandle);
BindTexturesIfNotNull(Current.Vertex);
BindTexturesIfNotNull(Current.TessControl);
@ -283,15 +283,15 @@ namespace Ryujinx.Graphics.Gal.OpenGL
BindTexturesIfNotNull(Current.Fragment);
}
private static void CheckProgramLink(int Handle)
private static void CheckProgramLink(int handle)
{
int Status = 0;
int status = 0;
GL.GetProgram(Handle, GetProgramParameterName.LinkStatus, out Status);
GL.GetProgram(handle, GetProgramParameterName.LinkStatus, out status);
if (Status == 0)
if (status == 0)
{
throw new ShaderException(GL.GetProgramInfoLog(Handle));
throw new ShaderException(GL.GetProgramInfoLog(handle));
}
}
}

View file

@ -4,16 +4,16 @@ using System.Collections.Generic;
namespace Ryujinx.Graphics.Gal.OpenGL
{
struct OGLShaderProgram
struct OglShaderProgram
{
public OGLShaderStage Vertex;
public OGLShaderStage TessControl;
public OGLShaderStage TessEvaluation;
public OGLShaderStage Geometry;
public OGLShaderStage Fragment;
public OglShaderStage Vertex;
public OglShaderStage TessControl;
public OglShaderStage TessEvaluation;
public OglShaderStage Geometry;
public OglShaderStage Fragment;
}
class OGLShaderStage : IDisposable
class OglShaderStage : IDisposable
{
public int Handle { get; private set; }
@ -26,23 +26,23 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public IEnumerable<ShaderDeclInfo> ConstBufferUsage { get; private set; }
public IEnumerable<ShaderDeclInfo> TextureUsage { get; private set; }
public OGLShaderStage(
GalShaderType Type,
string Code,
IEnumerable<ShaderDeclInfo> ConstBufferUsage,
IEnumerable<ShaderDeclInfo> TextureUsage)
public OglShaderStage(
GalShaderType type,
string code,
IEnumerable<ShaderDeclInfo> constBufferUsage,
IEnumerable<ShaderDeclInfo> textureUsage)
{
this.Type = Type;
this.Code = Code;
this.ConstBufferUsage = ConstBufferUsage;
this.TextureUsage = TextureUsage;
Type = type;
Code = code;
ConstBufferUsage = constBufferUsage;
TextureUsage = textureUsage;
}
public void Compile()
{
if (Handle == 0)
{
Handle = GL.CreateShader(OGLEnumConverter.GetShaderType(Type));
Handle = GL.CreateShader(OglEnumConverter.GetShaderType(Type));
CompileAndCheck(Handle, Code);
}
@ -53,9 +53,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
protected virtual void Dispose(bool disposing)
{
if (Disposing && Handle != 0)
if (disposing && Handle != 0)
{
GL.DeleteShader(Handle);
@ -63,23 +63,23 @@ namespace Ryujinx.Graphics.Gal.OpenGL
}
}
public static void CompileAndCheck(int Handle, string Code)
public static void CompileAndCheck(int handle, string code)
{
GL.ShaderSource(Handle, Code);
GL.CompileShader(Handle);
GL.ShaderSource(handle, code);
GL.CompileShader(handle);
CheckCompilation(Handle);
CheckCompilation(handle);
}
private static void CheckCompilation(int Handle)
private static void CheckCompilation(int handle)
{
int Status = 0;
int status = 0;
GL.GetShader(Handle, ShaderParameter.CompileStatus, out Status);
GL.GetShader(handle, ShaderParameter.CompileStatus, out status);
if (Status == 0)
if (status == 0)
{
throw new ShaderException(GL.GetShaderInfoLog(Handle));
throw new ShaderException(GL.GetShaderInfoLog(handle));
}
}
}

View file

@ -3,7 +3,7 @@ using System;
namespace Ryujinx.Graphics.Gal.OpenGL
{
class OGLStreamBuffer : IDisposable
class OglStreamBuffer : IDisposable
{
public int Handle { get; protected set; }
@ -11,30 +11,30 @@ namespace Ryujinx.Graphics.Gal.OpenGL
protected BufferTarget Target { get; private set; }
public OGLStreamBuffer(BufferTarget Target, long Size)
public OglStreamBuffer(BufferTarget target, long size)
{
this.Target = Target;
this.Size = Size;
Target = target;
Size = size;
Handle = GL.GenBuffer();
GL.BindBuffer(Target, Handle);
GL.BindBuffer(target, Handle);
GL.BufferData(Target, (IntPtr)Size, IntPtr.Zero, BufferUsageHint.StreamDraw);
GL.BufferData(target, (IntPtr)size, IntPtr.Zero, BufferUsageHint.StreamDraw);
}
public void SetData(long Size, IntPtr HostAddress)
public void SetData(long size, IntPtr hostAddress)
{
GL.BindBuffer(Target, Handle);
GL.BufferSubData(Target, IntPtr.Zero, (IntPtr)Size, HostAddress);
GL.BufferSubData(Target, IntPtr.Zero, (IntPtr)size, hostAddress);
}
public void SetData(byte[] Data)
public void SetData(byte[] data)
{
GL.BindBuffer(Target, Handle);
GL.BufferSubData(Target, IntPtr.Zero, (IntPtr)Data.Length, Data);
GL.BufferSubData(Target, IntPtr.Zero, (IntPtr)data.Length, data);
}
public void Dispose()
@ -42,9 +42,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
protected virtual void Dispose(bool disposing)
{
if (Disposing && Handle != 0)
if (disposing && Handle != 0)
{
GL.DeleteBuffer(Handle);

View file

@ -4,377 +4,377 @@ using System;
namespace Ryujinx.Graphics.Gal.OpenGL
{
class OGLTexture : IGalTexture
class OglTexture : IGalTexture
{
private const long MaxTextureCacheSize = 768 * 1024 * 1024;
private OGLCachedResource<ImageHandler> TextureCache;
private OglCachedResource<ImageHandler> _textureCache;
public EventHandler<int> TextureDeleted { get; set; }
public OGLTexture()
public OglTexture()
{
TextureCache = new OGLCachedResource<ImageHandler>(DeleteTexture, MaxTextureCacheSize);
_textureCache = new OglCachedResource<ImageHandler>(DeleteTexture, MaxTextureCacheSize);
}
public void LockCache()
{
TextureCache.Lock();
_textureCache.Lock();
}
public void UnlockCache()
{
TextureCache.Unlock();
_textureCache.Unlock();
}
private void DeleteTexture(ImageHandler CachedImage)
private void DeleteTexture(ImageHandler cachedImage)
{
TextureDeleted?.Invoke(this, CachedImage.Handle);
TextureDeleted?.Invoke(this, cachedImage.Handle);
GL.DeleteTexture(CachedImage.Handle);
GL.DeleteTexture(cachedImage.Handle);
}
public void Create(long Key, int Size, GalImage Image)
public void Create(long key, int size, GalImage image)
{
int Handle = GL.GenTexture();
int handle = GL.GenTexture();
TextureTarget Target = ImageUtils.GetTextureTarget(Image.TextureTarget);
TextureTarget target = ImageUtils.GetTextureTarget(image.TextureTarget);
GL.BindTexture(Target, Handle);
GL.BindTexture(target, handle);
const int Level = 0; //TODO: Support mipmap textures.
const int Border = 0;
const int level = 0; //TODO: Support mipmap textures.
const int border = 0;
TextureCache.AddOrUpdate(Key, new ImageHandler(Handle, Image), (uint)Size);
_textureCache.AddOrUpdate(key, new ImageHandler(handle, image), (uint)size);
if (ImageUtils.IsCompressed(Image.Format))
if (ImageUtils.IsCompressed(image.Format))
{
throw new InvalidOperationException("Surfaces with compressed formats are not supported!");
}
(PixelInternalFormat InternalFmt,
PixelFormat Format,
PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format);
(PixelInternalFormat internalFmt,
PixelFormat format,
PixelType type) = OglEnumConverter.GetImageFormat(image.Format);
switch (Target)
switch (target)
{
case TextureTarget.Texture1D:
GL.TexImage1D(
Target,
Level,
InternalFmt,
Image.Width,
Border,
Format,
Type,
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,
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,
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,
target,
level,
internalFmt,
image.Width,
image.Height,
image.LayerCount,
border,
format,
type,
IntPtr.Zero);
break;
default:
throw new NotImplementedException($"Unsupported texture target type: {Target}");
throw new NotImplementedException($"Unsupported texture target type: {target}");
}
}
public void Create(long Key, byte[] Data, GalImage Image)
public void Create(long key, byte[] data, GalImage image)
{
int Handle = GL.GenTexture();
int handle = GL.GenTexture();
TextureTarget Target = ImageUtils.GetTextureTarget(Image.TextureTarget);
TextureTarget target = ImageUtils.GetTextureTarget(image.TextureTarget);
GL.BindTexture(Target, Handle);
GL.BindTexture(target, handle);
const int Level = 0; //TODO: Support mipmap textures.
const int Border = 0;
const int level = 0; //TODO: Support mipmap textures.
const int border = 0;
TextureCache.AddOrUpdate(Key, new ImageHandler(Handle, Image), (uint)Data.Length);
_textureCache.AddOrUpdate(key, new ImageHandler(handle, image), (uint)data.Length);
if (ImageUtils.IsCompressed(Image.Format) && !IsAstc(Image.Format))
if (ImageUtils.IsCompressed(image.Format) && !IsAstc(image.Format))
{
InternalFormat InternalFmt = OGLEnumConverter.GetCompressedImageFormat(Image.Format);
InternalFormat internalFmt = OglEnumConverter.GetCompressedImageFormat(image.Format);
switch (Target)
switch (target)
{
case TextureTarget.Texture1D:
GL.CompressedTexImage1D(
Target,
Level,
InternalFmt,
Image.Width,
Border,
Data.Length,
Data);
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);
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);
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);
target,
level,
internalFmt,
image.Width,
image.Height,
image.LayerCount,
border,
data.Length,
data);
break;
default:
throw new NotImplementedException($"Unsupported texture target type: {Target}");
throw new NotImplementedException($"Unsupported texture target type: {target}");
}
}
else
{
//TODO: Use KHR_texture_compression_astc_hdr when available
if (IsAstc(Image.Format))
if (IsAstc(image.Format))
{
int TextureBlockWidth = ImageUtils.GetBlockWidth(Image.Format);
int TextureBlockHeight = ImageUtils.GetBlockHeight(Image.Format);
int TextureBlockDepth = ImageUtils.GetBlockDepth(Image.Format);
int textureBlockWidth = ImageUtils.GetBlockWidth(image.Format);
int textureBlockHeight = ImageUtils.GetBlockHeight(image.Format);
int textureBlockDepth = ImageUtils.GetBlockDepth(image.Format);
Data = ASTCDecoder.DecodeToRGBA8888(
Data,
TextureBlockWidth,
TextureBlockHeight,
TextureBlockDepth,
Image.Width,
Image.Height,
Image.Depth);
data = ASTCDecoder.DecodeToRGBA8888(
data,
textureBlockWidth,
textureBlockHeight,
textureBlockDepth,
image.Width,
image.Height,
image.Depth);
Image.Format = GalImageFormat.RGBA8 | (Image.Format & GalImageFormat.TypeMask);
image.Format = GalImageFormat.RGBA8 | (image.Format & GalImageFormat.TypeMask);
}
(PixelInternalFormat InternalFmt,
PixelFormat Format,
PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format);
(PixelInternalFormat internalFmt,
PixelFormat format,
PixelType type) = OglEnumConverter.GetImageFormat(image.Format);
switch (Target)
switch (target)
{
case TextureTarget.Texture1D:
GL.TexImage1D(
Target,
Level,
InternalFmt,
Image.Width,
Border,
Format,
Type,
Data);
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);
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);
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);
target,
level,
internalFmt,
image.Width,
image.Height,
image.LayerCount,
border,
format,
type,
data);
break;
case TextureTarget.TextureCubeMap:
Span<byte> Array = new Span<byte>(Data);
Span<byte> array = new Span<byte>(data);
int FaceSize = ImageUtils.GetSize(Image) / 6;
int faceSize = ImageUtils.GetSize(image) / 6;
for (int Face = 0; Face < 6; Face++)
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());
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}");
throw new NotImplementedException($"Unsupported texture target type: {target}");
}
}
}
private static bool IsAstc(GalImageFormat Format)
private static bool IsAstc(GalImageFormat format)
{
Format &= GalImageFormat.FormatMask;
format &= GalImageFormat.FormatMask;
return Format > GalImageFormat.Astc2DStart && Format < GalImageFormat.Astc2DEnd;
return format > GalImageFormat.Astc2DStart && format < GalImageFormat.Astc2DEnd;
}
public bool TryGetImage(long Key, out GalImage Image)
public bool TryGetImage(long key, out GalImage image)
{
if (TextureCache.TryGetValue(Key, out ImageHandler CachedImage))
if (_textureCache.TryGetValue(key, out ImageHandler cachedImage))
{
Image = CachedImage.Image;
image = cachedImage.Image;
return true;
}
Image = default(GalImage);
image = default(GalImage);
return false;
}
public bool TryGetImageHandler(long Key, out ImageHandler CachedImage)
public bool TryGetImageHandler(long key, out ImageHandler cachedImage)
{
if (TextureCache.TryGetValue(Key, out CachedImage))
if (_textureCache.TryGetValue(key, out cachedImage))
{
return true;
}
CachedImage = null;
cachedImage = null;
return false;
}
public void Bind(long Key, int Index, GalImage Image)
public void Bind(long key, int index, GalImage image)
{
if (TextureCache.TryGetValue(Key, out ImageHandler CachedImage))
if (_textureCache.TryGetValue(key, out ImageHandler cachedImage))
{
GL.ActiveTexture(TextureUnit.Texture0 + Index);
GL.ActiveTexture(TextureUnit.Texture0 + index);
TextureTarget Target = ImageUtils.GetTextureTarget(Image.TextureTarget);
TextureTarget target = ImageUtils.GetTextureTarget(image.TextureTarget);
GL.BindTexture(Target, CachedImage.Handle);
GL.BindTexture(target, cachedImage.Handle);
int[] SwizzleRgba = new int[]
int[] swizzleRgba = new int[]
{
(int)OGLEnumConverter.GetTextureSwizzle(Image.XSource),
(int)OGLEnumConverter.GetTextureSwizzle(Image.YSource),
(int)OGLEnumConverter.GetTextureSwizzle(Image.ZSource),
(int)OGLEnumConverter.GetTextureSwizzle(Image.WSource)
(int)OglEnumConverter.GetTextureSwizzle(image.XSource),
(int)OglEnumConverter.GetTextureSwizzle(image.YSource),
(int)OglEnumConverter.GetTextureSwizzle(image.ZSource),
(int)OglEnumConverter.GetTextureSwizzle(image.WSource)
};
GL.TexParameter(Target, TextureParameterName.TextureSwizzleRgba, SwizzleRgba);
GL.TexParameter(target, TextureParameterName.TextureSwizzleRgba, swizzleRgba);
}
}
public void SetSampler(GalImage Image, 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 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);
int minFilter = (int)OglEnumConverter.GetTextureMinFilter(sampler.MinFilter, sampler.MipFilter);
int magFilter = (int)OglEnumConverter.GetTextureMagFilter(sampler.MagFilter);
TextureTarget Target = ImageUtils.GetTextureTarget(Image.TextureTarget);
TextureTarget target = ImageUtils.GetTextureTarget(image.TextureTarget);
GL.TexParameter(Target, TextureParameterName.TextureWrapS, WrapS);
GL.TexParameter(Target, TextureParameterName.TextureWrapT, WrapT);
GL.TexParameter(Target, TextureParameterName.TextureWrapR, WrapR);
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);
GL.TexParameter(target, TextureParameterName.TextureMinFilter, minFilter);
GL.TexParameter(target, TextureParameterName.TextureMagFilter, magFilter);
float[] Color = new float[]
float[] color = new float[]
{
Sampler.BorderColor.Red,
Sampler.BorderColor.Green,
Sampler.BorderColor.Blue,
Sampler.BorderColor.Alpha
sampler.BorderColor.Red,
sampler.BorderColor.Green,
sampler.BorderColor.Blue,
sampler.BorderColor.Alpha
};
GL.TexParameter(Target, TextureParameterName.TextureBorderColor, Color);
GL.TexParameter(target, TextureParameterName.TextureBorderColor, color);
if (Sampler.DepthCompare)
if (sampler.DepthCompare)
{
GL.TexParameter(Target, TextureParameterName.TextureCompareMode, (int)All.CompareRToTexture);
GL.TexParameter(Target, TextureParameterName.TextureCompareFunc, (int)OGLEnumConverter.GetDepthCompareFunc(Sampler.DepthCompareFunc));
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);
GL.TexParameter(target, TextureParameterName.TextureCompareMode, (int)All.None);
GL.TexParameter(target, TextureParameterName.TextureCompareFunc, (int)All.Never);
}
}
}

View file

@ -16,7 +16,7 @@ namespace Ryujinx
{
Console.Title = "Ryujinx Console";
IGalRenderer renderer = new OGLRenderer();
IGalRenderer renderer = new OglRenderer();
IAalOutput audioOut = InitializeAudioEngine();