Share images between framebuffers and textures
This commit is contained in:
parent
65c7842d6d
commit
5ea1382aff
9 changed files with 211 additions and 146 deletions
|
@ -4,14 +4,10 @@ namespace Ryujinx.Graphics.Gal
|
|||
{
|
||||
public interface IGalFrameBuffer
|
||||
{
|
||||
void CreateColor(long Key, int Width, int Height, GalFrameBufferFormat Format);
|
||||
|
||||
void BindColor(long Key, int Attachment);
|
||||
|
||||
void UnbindColor(int Attachment);
|
||||
|
||||
void CreateZeta(long Key, int Width, int Height, GalZetaFormat Format);
|
||||
|
||||
void BindZeta(long Key);
|
||||
|
||||
void UnbindZeta();
|
||||
|
|
|
@ -7,6 +7,8 @@ namespace Ryujinx.Graphics.Gal
|
|||
|
||||
void Create(long Key, byte[] Data, GalImage Image);
|
||||
|
||||
void CreateFb(long Key, long Size, GalImage Image);
|
||||
|
||||
bool TryGetCachedTexture(long Key, long DataSize, out GalImage Image);
|
||||
|
||||
void Bind(long Key, int Index);
|
||||
|
|
|
@ -50,12 +50,22 @@ namespace Ryujinx.Graphics.Gal
|
|||
|
||||
public static GalImageFormat ConvertFrameBuffer(GalFrameBufferFormat Format)
|
||||
{
|
||||
switch (Format)
|
||||
{
|
||||
case GalFrameBufferFormat.R32Float: return GalImageFormat.R32;
|
||||
}
|
||||
|
||||
//Stubbed.
|
||||
return GalImageFormat.A8B8G8R8;
|
||||
}
|
||||
|
||||
public static GalImageFormat ConvertZeta(GalZetaFormat Format)
|
||||
{
|
||||
switch (Format)
|
||||
{
|
||||
case GalZetaFormat.Z32Float: return GalImageFormat.ZF32;
|
||||
}
|
||||
|
||||
//Stubbed.
|
||||
return GalImageFormat.Z24S8;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ using System.Collections.Generic;
|
|||
|
||||
namespace Ryujinx.Graphics.Gal.OpenGL
|
||||
{
|
||||
public class OGLFrameBuffer : IGalFrameBuffer
|
||||
class OGLFrameBuffer : IGalFrameBuffer
|
||||
{
|
||||
private struct Rect
|
||||
{
|
||||
|
@ -23,8 +23,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static readonly DrawBuffersEnum[] DrawBuffers = new DrawBuffersEnum[]
|
||||
{
|
||||
DrawBuffersEnum.ColorAttachment0,
|
||||
|
@ -42,8 +40,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
|
||||
private const GalImageFormat RawFormat = GalImageFormat.A8B8G8R8;
|
||||
|
||||
private Dictionary<long, TCE> ColorTextures;
|
||||
private Dictionary<long, TCE> ZetaTextures;
|
||||
private OGLTexture Texture;
|
||||
|
||||
private TCE RawTex;
|
||||
private TCE ReadTex;
|
||||
|
@ -64,35 +61,19 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
private int SrcFb;
|
||||
private int DstFb;
|
||||
|
||||
public OGLFrameBuffer()
|
||||
public OGLFrameBuffer(OGLTexture Texture)
|
||||
{
|
||||
ColorTextures = new Dictionary<long, TCE>();
|
||||
|
||||
ZetaTextures = new Dictionary<long, TCE>();
|
||||
}
|
||||
|
||||
public void CreateColor(long Key, int Width, int Height, GalFrameBufferFormat Format)
|
||||
{
|
||||
if (!ColorTextures.TryGetValue(Key, out TCE Tex))
|
||||
{
|
||||
Tex = new TCE();
|
||||
|
||||
ColorTextures.Add(Key, Tex);
|
||||
}
|
||||
|
||||
GalImageFormat ImageFormat = ImageFormatConverter.ConvertFrameBuffer(Format);
|
||||
|
||||
Tex.EnsureSetup(new GalImage(Width, Height, ImageFormat));
|
||||
this.Texture = Texture;
|
||||
}
|
||||
|
||||
public void BindColor(long Key, int Attachment)
|
||||
{
|
||||
if (ColorTextures.TryGetValue(Key, out TCE Tex))
|
||||
if (Texture.TryGetTCE(Key, out TCE Tex))
|
||||
{
|
||||
EnsureFrameBuffer();
|
||||
|
||||
GL.FramebufferTexture(
|
||||
FramebufferTarget.Framebuffer,
|
||||
FramebufferTarget.DrawFramebuffer,
|
||||
FramebufferAttachment.ColorAttachment0 + Attachment,
|
||||
Tex.Handle,
|
||||
0);
|
||||
|
@ -108,37 +89,58 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
EnsureFrameBuffer();
|
||||
|
||||
GL.FramebufferTexture(
|
||||
FramebufferTarget.Framebuffer,
|
||||
FramebufferTarget.DrawFramebuffer,
|
||||
FramebufferAttachment.ColorAttachment0 + Attachment,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
||||
public void CreateZeta(long Key, int Width, int Height, GalZetaFormat Format)
|
||||
{
|
||||
if (!ZetaTextures.TryGetValue(Key, out TCE Tex))
|
||||
{
|
||||
Tex = new TCE();
|
||||
|
||||
ZetaTextures.Add(Key, Tex);
|
||||
}
|
||||
|
||||
GalImageFormat ImageFormat = ImageFormatConverter.ConvertZeta(Format);
|
||||
|
||||
Tex.EnsureSetup(new GalImage(Width, Height, ImageFormat));
|
||||
}
|
||||
|
||||
|
||||
public void BindZeta(long Key)
|
||||
{
|
||||
if (ZetaTextures.TryGetValue(Key, out TCE Tex))
|
||||
if (Texture.TryGetTCE(Key, out TCE Tex))
|
||||
{
|
||||
EnsureFrameBuffer();
|
||||
|
||||
GL.FramebufferTexture(
|
||||
FramebufferTarget.Framebuffer,
|
||||
FramebufferAttachment.DepthStencilAttachment,
|
||||
Tex.Handle,
|
||||
0);
|
||||
if (Tex.HasDepth && Tex.HasStencil)
|
||||
{
|
||||
GL.FramebufferTexture(
|
||||
FramebufferTarget.DrawFramebuffer,
|
||||
FramebufferAttachment.DepthStencilAttachment,
|
||||
Tex.Handle,
|
||||
0);
|
||||
}
|
||||
else if (Tex.HasDepth)
|
||||
{
|
||||
GL.FramebufferTexture(
|
||||
FramebufferTarget.DrawFramebuffer,
|
||||
FramebufferAttachment.DepthAttachment,
|
||||
Tex.Handle,
|
||||
0);
|
||||
|
||||
GL.FramebufferTexture(
|
||||
FramebufferTarget.DrawFramebuffer,
|
||||
FramebufferAttachment.StencilAttachment,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
else if (Tex.HasStencil)
|
||||
{
|
||||
GL.FramebufferTexture(
|
||||
FramebufferTarget.DrawFramebuffer,
|
||||
FramebufferAttachment.DepthAttachment,
|
||||
Tex.Handle,
|
||||
0);
|
||||
|
||||
GL.FramebufferTexture(
|
||||
FramebufferTarget.DrawFramebuffer,
|
||||
FramebufferAttachment.StencilAttachment,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -151,7 +153,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
EnsureFrameBuffer();
|
||||
|
||||
GL.FramebufferTexture(
|
||||
FramebufferTarget.Framebuffer,
|
||||
FramebufferTarget.DrawFramebuffer,
|
||||
FramebufferAttachment.DepthStencilAttachment,
|
||||
0,
|
||||
0);
|
||||
|
@ -159,10 +161,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
|
||||
public void BindTexture(long Key, int Index)
|
||||
{
|
||||
TCE Tex;
|
||||
|
||||
if (ColorTextures.TryGetValue(Key, out Tex) ||
|
||||
ZetaTextures.TryGetValue(Key, out Tex))
|
||||
if (Texture.TryGetTCE(Key, out TCE Tex))
|
||||
{
|
||||
GL.ActiveTexture(TextureUnit.Texture0 + Index);
|
||||
|
||||
|
@ -172,7 +171,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
|
||||
public void Set(long Key)
|
||||
{
|
||||
if (ColorTextures.TryGetValue(Key, out TCE Tex))
|
||||
if (Texture.TryGetTCE(Key, out TCE Tex))
|
||||
{
|
||||
ReadTex = Tex;
|
||||
}
|
||||
|
@ -307,50 +306,72 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
int DstX1,
|
||||
int DstY1)
|
||||
{
|
||||
bool Found = false;
|
||||
|
||||
if (ColorTextures.TryGetValue(SrcKey, out TCE SrcTex) &&
|
||||
ColorTextures.TryGetValue(DstKey, out TCE DstTex))
|
||||
if (Texture.TryGetTCE(SrcKey, out TCE SrcTex) &&
|
||||
Texture.TryGetTCE(DstKey, out TCE DstTex))
|
||||
{
|
||||
CopyTextures(
|
||||
SrcX0, SrcY0, SrcX1, SrcY1,
|
||||
DstX0, DstY0, DstX1, DstY1,
|
||||
SrcTex.Handle,
|
||||
DstTex.Handle,
|
||||
FramebufferAttachment.ColorAttachment0,
|
||||
ClearBufferMask.ColorBufferBit,
|
||||
true);
|
||||
if (SrcTex.HasColor != DstTex.HasColor ||
|
||||
SrcTex.HasDepth != DstTex.HasDepth ||
|
||||
SrcTex.HasStencil != DstTex.HasStencil)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
Found = true;
|
||||
}
|
||||
if (SrcTex.HasColor)
|
||||
{
|
||||
CopyTextures(
|
||||
SrcX0, SrcY0, SrcX1, SrcY1,
|
||||
DstX0, DstY0, DstX1, DstY1,
|
||||
SrcTex.Handle,
|
||||
DstTex.Handle,
|
||||
FramebufferAttachment.ColorAttachment0,
|
||||
ClearBufferMask.ColorBufferBit,
|
||||
true);
|
||||
}
|
||||
else if (SrcTex.HasDepth && SrcTex.HasStencil)
|
||||
{
|
||||
CopyTextures(
|
||||
SrcX0, SrcY0, SrcX1, SrcY1,
|
||||
DstX0, DstY0, DstX1, DstY1,
|
||||
SrcTex.Handle,
|
||||
DstTex.Handle,
|
||||
FramebufferAttachment.DepthStencilAttachment,
|
||||
ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit,
|
||||
false);
|
||||
}
|
||||
else if (SrcTex.HasDepth)
|
||||
{
|
||||
CopyTextures(
|
||||
SrcX0, SrcY0, SrcX1, SrcY1,
|
||||
DstX0, DstY0, DstX1, DstY1,
|
||||
SrcTex.Handle,
|
||||
DstTex.Handle,
|
||||
FramebufferAttachment.DepthAttachment,
|
||||
ClearBufferMask.DepthBufferBit,
|
||||
false);
|
||||
}
|
||||
else if (SrcTex.HasStencil)
|
||||
{
|
||||
CopyTextures(
|
||||
SrcX0, SrcY0, SrcX1, SrcY1,
|
||||
DstX0, DstY0, DstX1, DstY1,
|
||||
SrcTex.Handle,
|
||||
DstTex.Handle,
|
||||
FramebufferAttachment.StencilAttachment,
|
||||
ClearBufferMask.StencilBufferBit,
|
||||
false);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
if (ZetaTextures.TryGetValue(SrcKey, out TCE ZetaSrcTex) &&
|
||||
ZetaTextures.TryGetValue(DstKey, out TCE ZetaDstTex))
|
||||
{
|
||||
CopyTextures(
|
||||
SrcX0, SrcY0, SrcX1, SrcY1,
|
||||
DstX0, DstY0, DstX1, DstY1,
|
||||
ZetaSrcTex.Handle,
|
||||
ZetaDstTex.Handle,
|
||||
FramebufferAttachment.DepthStencilAttachment,
|
||||
ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit,
|
||||
false);
|
||||
|
||||
Found = true;
|
||||
}
|
||||
|
||||
if (Found)
|
||||
{
|
||||
EnsureFrameBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
public void GetBufferData(long Key, Action<byte[]> Callback)
|
||||
{
|
||||
TCE Tex;
|
||||
|
||||
if (ColorTextures.TryGetValue(Key, out Tex) ||
|
||||
ZetaTextures.TryGetValue(Key, out Tex))
|
||||
if (Texture.TryGetTCE(Key, out TCE Tex))
|
||||
{
|
||||
byte[] Data = new byte[Tex.Width * Tex.Height * TCE.MaxBpp];
|
||||
|
||||
|
@ -373,10 +394,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
int Height,
|
||||
byte[] Buffer)
|
||||
{
|
||||
TCE Tex;
|
||||
|
||||
if (ColorTextures.TryGetValue(Key, out Tex) ||
|
||||
ZetaTextures.TryGetValue(Key, out Tex))
|
||||
if (Texture.TryGetTCE(Key, out TCE Tex))
|
||||
{
|
||||
GL.BindTexture(TextureTarget.Texture2D, Tex.Handle);
|
||||
|
||||
|
@ -403,7 +421,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
DummyFrameBuffer = GL.GenFramebuffer();
|
||||
}
|
||||
|
||||
GL.BindFramebuffer(FramebufferTarget.Framebuffer, DummyFrameBuffer);
|
||||
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, DummyFrameBuffer);
|
||||
|
||||
GL.DrawBuffers(8, DrawBuffers);
|
||||
}
|
||||
|
|
|
@ -50,33 +50,23 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
float Depth,
|
||||
int Stencil)
|
||||
{
|
||||
//TODO: Handle attachment
|
||||
|
||||
ClearBufferMask Mask = ClearBufferMask.ColorBufferBit;
|
||||
|
||||
if (Flags.HasFlag(GalClearBufferFlags.Depth))
|
||||
{
|
||||
Mask |= ClearBufferMask.DepthBufferBit;
|
||||
}
|
||||
|
||||
if (Flags.HasFlag(GalClearBufferFlags.Stencil))
|
||||
{
|
||||
Mask |= ClearBufferMask.StencilBufferBit;
|
||||
}
|
||||
|
||||
GL.ColorMask(
|
||||
Flags.HasFlag(GalClearBufferFlags.ColorRed),
|
||||
Flags.HasFlag(GalClearBufferFlags.ColorGreen),
|
||||
Flags.HasFlag(GalClearBufferFlags.ColorBlue),
|
||||
Flags.HasFlag(GalClearBufferFlags.ColorAlpha));
|
||||
|
||||
GL.ClearColor(Red, Green, Blue, Alpha);
|
||||
GL.ClearBuffer(ClearBuffer.Color, Attachment, new float[] { Red, Green, Blue, Alpha });
|
||||
|
||||
GL.ClearDepth(Depth);
|
||||
if (Flags.HasFlag(GalClearBufferFlags.Depth))
|
||||
{
|
||||
GL.ClearBuffer(ClearBuffer.Depth, 0, ref Depth);
|
||||
}
|
||||
|
||||
GL.ClearStencil(Stencil);
|
||||
|
||||
GL.Clear(Mask);
|
||||
if (Flags.HasFlag(GalClearBufferFlags.Stencil))
|
||||
{
|
||||
GL.ClearBuffer(ClearBuffer.Stencil, 0, ref Stencil);
|
||||
}
|
||||
|
||||
GL.ColorMask(true, true, true, true);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
{
|
||||
Buffer = new OGLConstBuffer();
|
||||
|
||||
FrameBuffer = new OGLFrameBuffer();
|
||||
Texture = new OGLTexture();
|
||||
|
||||
FrameBuffer = new OGLFrameBuffer(Texture as OGLTexture);
|
||||
|
||||
Rasterizer = new OGLRasterizer();
|
||||
|
||||
|
@ -31,8 +33,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
|
||||
Pipeline = new OGLPipeline(Buffer as OGLConstBuffer, Rasterizer as OGLRasterizer, Shader as OGLShader);
|
||||
|
||||
Texture = new OGLTexture();
|
||||
|
||||
ActionsQueue = new ConcurrentQueue<Action>();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ using System;
|
|||
|
||||
namespace Ryujinx.Graphics.Gal.OpenGL
|
||||
{
|
||||
public class OGLTexture : IGalTexture
|
||||
class OGLTexture : IGalTexture
|
||||
{
|
||||
private OGLCachedResource<TCE> TextureCache;
|
||||
|
||||
|
@ -95,6 +95,30 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleA, SwizzleA);
|
||||
}
|
||||
|
||||
public void CreateFb(long Key, long Size, GalImage Image)
|
||||
{
|
||||
if (!TryGetTCE(Key, out TCE Texture))
|
||||
{
|
||||
Texture = new TCE();
|
||||
|
||||
TextureCache.AddOrUpdate(Key, Texture, Size);
|
||||
}
|
||||
|
||||
Texture.EnsureSetup(Image);
|
||||
}
|
||||
|
||||
public bool TryGetTCE(long Key, out TCE CachedTexture)
|
||||
{
|
||||
if (TextureCache.TryGetValue(Key, out CachedTexture))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
CachedTexture = null;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int GetAstcBlockWidth(GalImageFormat Format)
|
||||
{
|
||||
switch (Format)
|
||||
|
|
|
@ -8,6 +8,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
//TODO: Use a variable value here
|
||||
public const int MaxBpp = 16;
|
||||
|
||||
private static int CopyBuffer = 0;
|
||||
private static int CopyBufferSize = 0;
|
||||
|
||||
public GalImage Image { get; private set; }
|
||||
|
||||
public int Width { get => Image.Width; }
|
||||
|
@ -36,31 +39,37 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
|
||||
public void EnsureSetup(GalImage Image)
|
||||
{
|
||||
if (this.Width != Image.Width ||
|
||||
this.Height != Image.Height ||
|
||||
this.Format != Image.Format ||
|
||||
if (Width != Image.Width ||
|
||||
Height != Image.Height ||
|
||||
Format != Image.Format ||
|
||||
!Initialized)
|
||||
{
|
||||
(PixelInternalFormat InternalFormat, PixelFormat PixelFormat, PixelType PixelType) =
|
||||
OGLEnumConverter.GetImageFormat(Image.Format);
|
||||
|
||||
int CopyBuffer = 0;
|
||||
|
||||
bool ChangingFormat = Initialized && this.InternalFormat != InternalFormat;
|
||||
|
||||
GL.BindTexture(TextureTarget.Texture2D, Handle);
|
||||
|
||||
if (ChangingFormat)
|
||||
if (Initialized)
|
||||
{
|
||||
CopyBuffer = GL.GenBuffer();
|
||||
if (CopyBuffer == 0)
|
||||
{
|
||||
CopyBuffer = GL.GenBuffer();
|
||||
}
|
||||
|
||||
int MaxWidth = Math.Max(Image.Width, Width);
|
||||
int MaxHeight = Math.Max(Image.Height, Height);
|
||||
|
||||
int CurrentSize = MaxWidth * MaxHeight * MaxBpp;
|
||||
|
||||
GL.BindBuffer(BufferTarget.PixelPackBuffer, CopyBuffer);
|
||||
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyBuffer);
|
||||
|
||||
int MaxWidth = Math.Max(Image.Width, this.Width);
|
||||
int MaxHeight = Math.Max(Image.Height, this.Height);
|
||||
if (CopyBufferSize < CurrentSize)
|
||||
{
|
||||
CopyBufferSize = CurrentSize;
|
||||
|
||||
GL.BufferData(BufferTarget.PixelPackBuffer, MaxWidth * MaxHeight * MaxBpp, IntPtr.Zero, BufferUsageHint.StaticCopy);
|
||||
GL.BufferData(BufferTarget.PixelPackBuffer, CurrentSize, IntPtr.Zero, BufferUsageHint.DynamicCopy);
|
||||
}
|
||||
|
||||
GL.GetTexImage(TextureTarget.Texture2D, 0, this.PixelFormat, this.PixelType, IntPtr.Zero);
|
||||
|
||||
|
@ -91,12 +100,10 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
PixelType,
|
||||
IntPtr.Zero);
|
||||
|
||||
if (ChangingFormat)
|
||||
if (Initialized)
|
||||
{
|
||||
GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
|
||||
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);
|
||||
|
||||
GL.DeleteBuffer(CopyBuffer);
|
||||
}
|
||||
|
||||
this.Image = Image;
|
||||
|
@ -108,5 +115,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
Initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasColor { get => ImageFormatConverter.HasColor(Format); }
|
||||
public bool HasDepth { get => ImageFormatConverter.HasDepth(Format); }
|
||||
public bool HasStencil { get => ImageFormatConverter.HasStencil(Format); }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,8 +102,10 @@ namespace Ryujinx.HLE.Gpu.Engines
|
|||
SetAlphaBlending(State);
|
||||
SetPrimitiveRestart(State);
|
||||
|
||||
SetFrameBuffer(Vmm, 0);
|
||||
|
||||
for (int FbIndex = 0; FbIndex < 8; FbIndex++)
|
||||
{
|
||||
SetFrameBuffer(Vmm, FbIndex);
|
||||
}
|
||||
SetZeta(Vmm);
|
||||
|
||||
long[] Keys = UploadShaders(Vmm);
|
||||
|
@ -151,6 +153,7 @@ namespace Ryujinx.HLE.Gpu.Engines
|
|||
int Stencil = ReadRegister(NvGpuEngine3dReg.ClearStencil);
|
||||
|
||||
SetFrameBuffer(Vmm, FbIndex);
|
||||
SetZeta(Vmm);
|
||||
|
||||
Gpu.Renderer.Rasterizer.ClearBuffers(
|
||||
Flags,
|
||||
|
@ -166,7 +169,7 @@ namespace Ryujinx.HLE.Gpu.Engines
|
|||
|
||||
int Format = ReadRegister(NvGpuEngine3dReg.FrameBufferNFormat + FbIndex * 0x10);
|
||||
|
||||
if (VA == 0/* || Format == 0*/)
|
||||
if (VA == 0 || Format == 0)
|
||||
{
|
||||
Gpu.Renderer.FrameBuffer.UnbindColor(FbIndex);
|
||||
|
||||
|
@ -192,7 +195,13 @@ namespace Ryujinx.HLE.Gpu.Engines
|
|||
int VpW = (int)(TX + MathF.Abs(SX)) - VpX;
|
||||
int VpH = (int)(TY + MathF.Abs(SY)) - VpY;
|
||||
|
||||
Gpu.Renderer.FrameBuffer.CreateColor(Key, Width, Height, (GalFrameBufferFormat)Format);
|
||||
GalImageFormat ImageFormat = ImageFormatConverter.ConvertFrameBuffer((GalFrameBufferFormat)Format);
|
||||
|
||||
GalImage Image = new GalImage(Width, Height, ImageFormat);
|
||||
|
||||
long Size = TextureHelper.GetTextureSize(Image);
|
||||
|
||||
Gpu.Renderer.Texture.CreateFb(Key, Size, Image);
|
||||
Gpu.Renderer.FrameBuffer.BindColor(Key, FbIndex);
|
||||
|
||||
Gpu.Renderer.FrameBuffer.SetViewport(VpX, VpY, VpW, VpH);
|
||||
|
@ -214,12 +223,17 @@ namespace Ryujinx.HLE.Gpu.Engines
|
|||
}
|
||||
|
||||
long Key = Vmm.GetPhysicalAddress(ZA);
|
||||
|
||||
|
||||
int Width = ReadRegister(NvGpuEngine3dReg.ZetaHoriz);
|
||||
int Height = ReadRegister(NvGpuEngine3dReg.ZetaVert);
|
||||
|
||||
Gpu.Renderer.FrameBuffer.CreateZeta(Key, Width, Height, (GalZetaFormat)Format);
|
||||
GalImageFormat ImageFormat = ImageFormatConverter.ConvertZeta((GalZetaFormat)Format);
|
||||
|
||||
GalImage Image = new GalImage(Width, Height, ImageFormat);
|
||||
|
||||
long Size = TextureHelper.GetTextureSize(Image);
|
||||
|
||||
Gpu.Renderer.Texture.CreateFb(Key, Size, Image);
|
||||
Gpu.Renderer.FrameBuffer.BindZeta(Key);
|
||||
}
|
||||
|
||||
|
@ -479,15 +493,15 @@ namespace Ryujinx.HLE.Gpu.Engines
|
|||
}
|
||||
else
|
||||
{
|
||||
GalImage NewTexture = TextureFactory.MakeTexture(Vmm, TicPosition);
|
||||
GalImage NewImage = TextureFactory.MakeTexture(Vmm, TicPosition);
|
||||
|
||||
long Size = (uint)TextureHelper.GetTextureSize(NewTexture);
|
||||
long Size = (uint)TextureHelper.GetTextureSize(NewImage);
|
||||
|
||||
bool HasCachedTexture = false;
|
||||
|
||||
if (Gpu.Renderer.Texture.TryGetCachedTexture(Key, Size, out GalImage Texture))
|
||||
if (Gpu.Renderer.Texture.TryGetCachedTexture(Key, Size, out GalImage Image))
|
||||
{
|
||||
if (NewTexture.Equals(Texture) && !QueryKeyUpload(Vmm, Key, Size, NvGpuBufferType.Texture))
|
||||
if (NewImage.Equals(Image) && !QueryKeyUpload(Vmm, Key, Size, NvGpuBufferType.Texture))
|
||||
{
|
||||
Gpu.Renderer.Texture.Bind(Key, TexIndex);
|
||||
|
||||
|
@ -499,7 +513,7 @@ namespace Ryujinx.HLE.Gpu.Engines
|
|||
{
|
||||
byte[] Data = TextureFactory.GetTextureData(Vmm, TicPosition);
|
||||
|
||||
Gpu.Renderer.Texture.Create(Key, Data, NewTexture);
|
||||
Gpu.Renderer.Texture.Create(Key, Data, NewImage);
|
||||
}
|
||||
|
||||
Gpu.Renderer.Texture.Bind(Key, TexIndex);
|
||||
|
|
Loading…
Add table
Reference in a new issue