Small OpenGL Renderer refactoring (#177)

* Call OpenGL functions directly, remove the pfifo thread, some refactoring

* Fix PerformanceStatistics calculating the wrong host fps, remove wait event on PFIFO as this wasn't exactly was causing the freezes (may replace with an exception later)

* Organized the Gpu folder a bit more, renamed a few things, address PR feedback

* Make PerformanceStatistics thread safe

* Remove unused constant

* Use unlimited update rate for better pref
This commit is contained in:
gdkchan
2018-06-23 21:39:25 -03:00
committed by GitHub
parent 69697957e6
commit e7559f128f
58 changed files with 518 additions and 633 deletions

View File

@ -1,4 +1,6 @@
namespace Ryujinx.HLE.Gpu
using Ryujinx.HLE.Gpu.Memory;
namespace Ryujinx.HLE.Gpu.Engines
{
interface INvGpuEngine
{

View File

@ -1,10 +1,16 @@
using Ryujinx.HLE.Gpu.Exceptions;
using Ryujinx.HLE.Gpu.Memory;
using System;
using System.Collections.Generic;
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Engines
{
class MacroInterpreter
{
private const int MaxCallCountPerRun = 500;
private int CallCount;
private enum AssignmentOperation
{
IgnoreAndFetch = 0,
@ -96,6 +102,8 @@ namespace Ryujinx.HLE.Gpu
MethIncr = 0;
Carry = false;
CallCount = 0;
}
private bool Step(NvGpuVmm Vmm, int[] Mme)
@ -407,6 +415,15 @@ namespace Ryujinx.HLE.Gpu
private void Send(NvGpuVmm Vmm, int Value)
{
//This is an artificial limit that prevents excessive calls
//to VertexEndGl since that triggers rendering, and in the
//case that something is bugged and causes an absurd amount of
//draw calls, this prevents the system from freezing (and throws instead).
if (MethAddr == 0x585 && ++CallCount > MaxCallCountPerRun)
{
GpuExceptionHelper.ThrowCallCoundExceeded();
}
NvGpuPBEntry PBEntry = new NvGpuPBEntry(MethAddr, 0, Value);
Engine.CallMethod(Vmm, PBEntry);

View File

@ -1,4 +1,4 @@
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Engines
{
enum NvGpuEngine
{

View File

@ -1,7 +1,9 @@
using Ryujinx.Graphics.Gal;
using Ryujinx.HLE.Gpu.Memory;
using Ryujinx.HLE.Gpu.Texture;
using System.Collections.Generic;
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Engines
{
class NvGpuEngine2d : INvGpuEngine
{
@ -75,19 +77,19 @@ namespace Ryujinx.HLE.Gpu
int DstBlockHeight = 1 << ((DstBlkDim >> 4) & 0xf);
long Tag = Vmm.GetPhysicalAddress(MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress));
long Key = Vmm.GetPhysicalAddress(MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress));
long SrcAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress);
long DstAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.DstAddress);
bool IsFbTexture = Gpu.Engine3d.IsFrameBufferPosition(Tag);
bool IsFbTexture = Gpu.Engine3d.IsFrameBufferPosition(Key);
if (IsFbTexture && DstLinear)
{
DstSwizzle = TextureSwizzle.BlockLinear;
}
Texture DstTexture = new Texture(
TextureInfo DstTexture = new TextureInfo(
DstAddress,
DstWidth,
DstHeight,
@ -103,7 +105,7 @@ namespace Ryujinx.HLE.Gpu
SrcWidth = 1280;
SrcHeight = 720;
Gpu.Renderer.GetFrameBufferData(Tag, (byte[] Buffer) =>
Gpu.Renderer.FrameBuffer.GetBufferData(Key, (byte[] Buffer) =>
{
CopyTexture(
Vmm,
@ -129,11 +131,11 @@ namespace Ryujinx.HLE.Gpu
}
private void CopyTexture(
NvGpuVmm Vmm,
Texture Texture,
byte[] Buffer,
int Width,
int Height)
NvGpuVmm Vmm,
TextureInfo Texture,
byte[] Buffer,
int Width,
int Height)
{
TextureWriter.Write(Vmm, Texture, Buffer, Width, Height);
}

View File

@ -1,4 +1,4 @@
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Engines
{
enum NvGpuEngine2dReg
{

View File

@ -1,8 +1,10 @@
using Ryujinx.Graphics.Gal;
using Ryujinx.HLE.Gpu.Memory;
using Ryujinx.HLE.Gpu.Texture;
using System;
using System.Collections.Generic;
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Engines
{
class NvGpuEngine3d : INvGpuEngine
{
@ -73,13 +75,13 @@ namespace Ryujinx.HLE.Gpu
{
SetFrameBuffer(Vmm, 0);
long[] Tags = UploadShaders(Vmm);
long[] Keys = UploadShaders(Vmm);
Gpu.Renderer.BindProgram();
Gpu.Renderer.Shader.BindProgram();
SetAlphaBlending();
UploadTextures(Vmm, Tags);
UploadTextures(Vmm, Keys);
UploadUniforms(Vmm);
UploadVertexArrays(Vmm);
}
@ -113,13 +115,13 @@ namespace Ryujinx.HLE.Gpu
//Note: Using the Width/Height results seems to give incorrect results.
//Maybe the size of all frame buffers is hardcoded to screen size? This seems unlikely.
Gpu.Renderer.CreateFrameBuffer(PA, 1280, 720);
Gpu.Renderer.BindFrameBuffer(PA);
Gpu.Renderer.FrameBuffer.Create(PA, 1280, 720);
Gpu.Renderer.FrameBuffer.Bind(PA);
}
private long[] UploadShaders(NvGpuVmm Vmm)
{
long[] Tags = new long[5];
long[] Keys = new long[5];
long BasePosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress);
@ -136,14 +138,14 @@ namespace Ryujinx.HLE.Gpu
continue;
}
long Tag = BasePosition + (uint)Offset;
long Key = BasePosition + (uint)Offset;
GalShaderType ShaderType = GetTypeFromProgram(Index);
Tags[(int)ShaderType] = Tag;
Keys[(int)ShaderType] = Key;
Gpu.Renderer.CreateShader(Vmm, Tag, ShaderType);
Gpu.Renderer.BindShader(Tag);
Gpu.Renderer.Shader.Create(Vmm, Key, ShaderType);
Gpu.Renderer.Shader.Bind(Key);
}
int RawSX = ReadRegister(NvGpuEngine3dReg.ViewportScaleX);
@ -155,9 +157,9 @@ namespace Ryujinx.HLE.Gpu
float SignX = MathF.Sign(SX);
float SignY = MathF.Sign(SY);
Gpu.Renderer.SetUniform2F(GalConsts.FlipUniformName, SignX, SignY);
Gpu.Renderer.Shader.SetFlip(SignX, SignY);
return Tags;
return Keys;
}
private static GalShaderType GetTypeFromProgram(int Program)
@ -180,7 +182,14 @@ namespace Ryujinx.HLE.Gpu
//TODO: Support independent blend properly.
bool Enable = (ReadRegister(NvGpuEngine3dReg.IBlendNEnable) & 1) != 0;
Gpu.Renderer.SetBlendEnable(Enable);
if (Enable)
{
Gpu.Renderer.Blend.Enable();
}
else
{
Gpu.Renderer.Blend.Disable();
}
if (!Enable)
{
@ -203,7 +212,7 @@ namespace Ryujinx.HLE.Gpu
GalBlendFactor FuncSrcAlpha = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncSrcAlpha);
GalBlendFactor FuncDstAlpha = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncDstAlpha);
Gpu.Renderer.SetBlendSeparate(
Gpu.Renderer.Blend.SetSeparate(
EquationRgb,
EquationAlpha,
FuncSrcRgb,
@ -213,11 +222,11 @@ namespace Ryujinx.HLE.Gpu
}
else
{
Gpu.Renderer.SetBlend(EquationRgb, FuncSrcRgb, FuncDstRgb);
Gpu.Renderer.Blend.Set(EquationRgb, FuncSrcRgb, FuncDstRgb);
}
}
private void UploadTextures(NvGpuVmm Vmm, long[] Tags)
private void UploadTextures(NvGpuVmm Vmm, long[] Keys)
{
long BaseShPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress);
@ -227,15 +236,15 @@ namespace Ryujinx.HLE.Gpu
//reserved for drawing the frame buffer.
int TexIndex = 1;
for (int Index = 0; Index < Tags.Length; Index++)
for (int Index = 0; Index < Keys.Length; Index++)
{
foreach (ShaderDeclInfo DeclInfo in Gpu.Renderer.GetTextureUsage(Tags[Index]))
foreach (ShaderDeclInfo DeclInfo in Gpu.Renderer.Shader.GetTextureUsage(Keys[Index]))
{
long Position = ConstBuffers[Index][TextureCbIndex].Position;
UploadTexture(Vmm, Position, TexIndex, DeclInfo.Index);
Gpu.Renderer.SetUniform1(DeclInfo.Name, TexIndex);
Gpu.Renderer.Shader.EnsureTextureBinding(DeclInfo.Name, TexIndex);
TexIndex++;
}
@ -270,7 +279,7 @@ namespace Ryujinx.HLE.Gpu
long TextureAddress = Vmm.ReadInt64(TicPosition + 4) & 0xffffffffffff;
long Tag = TextureAddress;
long Key = TextureAddress;
TextureAddress = Vmm.GetPhysicalAddress(TextureAddress);
@ -280,7 +289,7 @@ namespace Ryujinx.HLE.Gpu
//we shouldn't read anything from memory and bind
//the frame buffer texture instead, since we're not
//really writing anything to memory.
Gpu.Renderer.BindFrameBufferTexture(TextureAddress, TexIndex, Sampler);
Gpu.Renderer.FrameBuffer.BindTexture(TextureAddress, TexIndex);
}
else
{
@ -288,22 +297,29 @@ namespace Ryujinx.HLE.Gpu
long Size = (uint)TextureHelper.GetTextureSize(NewTexture);
if (Gpu.Renderer.TryGetCachedTexture(Tag, Size, out GalTexture Texture))
{
if (NewTexture.Equals(Texture) && !Vmm.IsRegionModified(Tag, Size, NvGpuBufferType.Texture))
{
Gpu.Renderer.BindTexture(Tag, TexIndex);
bool HasCachedTexture = false;
return;
if (Gpu.Renderer.Texture.TryGetCachedTexture(Key, Size, out GalTexture Texture))
{
if (NewTexture.Equals(Texture) && !Vmm.IsRegionModified(Key, Size, NvGpuBufferType.Texture))
{
Gpu.Renderer.Texture.Bind(Key, TexIndex);
HasCachedTexture = true;
}
}
byte[] Data = TextureFactory.GetTextureData(Vmm, TicPosition);
if (!HasCachedTexture)
{
byte[] Data = TextureFactory.GetTextureData(Vmm, TicPosition);
Gpu.Renderer.SetTextureAndSampler(Tag, Data, NewTexture, Sampler);
Gpu.Renderer.Texture.Create(Key, Data, NewTexture);
}
Gpu.Renderer.BindTexture(Tag, TexIndex);
Gpu.Renderer.Texture.Bind(Key, TexIndex);
}
Gpu.Renderer.Texture.SetSampler(Sampler);
}
private void UploadUniforms(NvGpuVmm Vmm)
@ -331,7 +347,7 @@ namespace Ryujinx.HLE.Gpu
{
byte[] Data = Vmm.ReadBytes(Cb.Position, (uint)Cb.Size);
Gpu.Renderer.SetConstBuffer(BasePosition + (uint)Offset, Cbuf, Data);
Gpu.Renderer.Shader.SetConstBuffer(BasePosition + (uint)Offset, Cbuf, Data);
}
}
}
@ -341,33 +357,33 @@ namespace Ryujinx.HLE.Gpu
{
long IndexPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.IndexArrayAddress);
int IndexSize = ReadRegister(NvGpuEngine3dReg.IndexArrayFormat);
int IndexFirst = ReadRegister(NvGpuEngine3dReg.IndexBatchFirst);
int IndexCount = ReadRegister(NvGpuEngine3dReg.IndexBatchCount);
int IndexEntryFmt = ReadRegister(NvGpuEngine3dReg.IndexArrayFormat);
int IndexFirst = ReadRegister(NvGpuEngine3dReg.IndexBatchFirst);
int IndexCount = ReadRegister(NvGpuEngine3dReg.IndexBatchCount);
GalIndexFormat IndexFormat = (GalIndexFormat)IndexSize;
GalIndexFormat IndexFormat = (GalIndexFormat)IndexEntryFmt;
IndexSize = 1 << IndexSize;
int IndexEntrySize = 1 << IndexEntryFmt;
if (IndexSize > 4)
if (IndexEntrySize > 4)
{
throw new InvalidOperationException();
}
if (IndexCount != 0)
{
int IbSize = IndexCount * IndexSize;
int IbSize = IndexCount * IndexEntrySize;
bool IboCached = Gpu.Renderer.IsIboCached(IndexPosition, (uint)IbSize);
bool IboCached = Gpu.Renderer.Rasterizer.IsIboCached(IndexPosition, (uint)IbSize);
if (!IboCached || Vmm.IsRegionModified(IndexPosition, (uint)IbSize, NvGpuBufferType.Index))
{
byte[] Data = Vmm.ReadBytes(IndexPosition, (uint)IbSize);
Gpu.Renderer.CreateIbo(IndexPosition, Data);
Gpu.Renderer.Rasterizer.CreateIbo(IndexPosition, Data);
}
Gpu.Renderer.SetIndexArray(IndexPosition, IbSize, IndexFormat);
Gpu.Renderer.Rasterizer.SetIndexArray(IndexPosition, IbSize, IndexFormat);
}
List<GalVertexAttrib>[] Attribs = new List<GalVertexAttrib>[32];
@ -429,27 +445,27 @@ namespace Ryujinx.HLE.Gpu
VbSize = VertexCount * Stride;
}
bool VboCached = Gpu.Renderer.IsVboCached(VertexPosition, VbSize);
bool VboCached = Gpu.Renderer.Rasterizer.IsVboCached(VertexPosition, VbSize);
if (!VboCached || Vmm.IsRegionModified(VertexPosition, VbSize, NvGpuBufferType.Vertex))
{
byte[] Data = Vmm.ReadBytes(VertexPosition, VbSize);
Gpu.Renderer.CreateVbo(VertexPosition, Data);
Gpu.Renderer.Rasterizer.CreateVbo(VertexPosition, Data);
}
Gpu.Renderer.SetVertexArray(Index, Stride, VertexPosition, Attribs[Index].ToArray());
Gpu.Renderer.Rasterizer.SetVertexArray(Index, Stride, VertexPosition, Attribs[Index].ToArray());
}
GalPrimitiveType PrimType = (GalPrimitiveType)(PrimCtrl & 0xffff);
if (IndexCount != 0)
{
Gpu.Renderer.DrawElements(IndexPosition, IndexFirst, PrimType);
Gpu.Renderer.Rasterizer.DrawElements(IndexPosition, IndexFirst, PrimType);
}
else
{
Gpu.Renderer.DrawArrays(VertexFirst, VertexCount, PrimType);
Gpu.Renderer.Rasterizer.DrawArrays(VertexFirst, VertexCount, PrimType);
}
}

View File

@ -1,4 +1,4 @@
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Engines
{
enum NvGpuEngine3dReg
{

View File

@ -1,6 +1,8 @@
using Ryujinx.HLE.Gpu.Memory;
using Ryujinx.HLE.Gpu.Texture;
using System.Collections.Generic;
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Engines
{
class NvGpuEngineDma : INvGpuEngine
{

View File

@ -1,4 +1,4 @@
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Engines
{
enum NvGpuEngineDmaReg
{

View File

@ -1,6 +1,7 @@
using Ryujinx.HLE.Gpu.Memory;
using System.Collections.Concurrent;
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Engines
{
class NvGpuFifo
{

View File

@ -1,4 +1,4 @@
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Engines
{
enum NvGpuFifoMeth
{

View File

@ -1,4 +1,6 @@
namespace Ryujinx.HLE.Gpu
using Ryujinx.HLE.Gpu.Memory;
namespace Ryujinx.HLE.Gpu.Engines
{
delegate void NvGpuMethod(NvGpuVmm Vmm, NvGpuPBEntry PBEntry);
}

View File

@ -0,0 +1,11 @@
using System;
namespace Ryujinx.HLE.Gpu.Exceptions
{
class GpuException : Exception
{
public GpuException() : base() { }
public GpuException(string ExMsg) : base(ExMsg) { }
}
}

View File

@ -0,0 +1,12 @@
namespace Ryujinx.HLE.Gpu.Exceptions
{
static class GpuExceptionHelper
{
private const string CallCountExceeded = "Method call count exceeded the limit allowed per run!";
public static void ThrowCallCoundExceeded()
{
throw new GpuException(CallCountExceeded);
}
}
}

View File

@ -1,4 +1,4 @@
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Memory
{
enum NvGpuBufferType
{

View File

@ -1,7 +1,7 @@
using System;
using System.Collections.ObjectModel;
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Memory
{
struct NvGpuPBEntry
{

View File

@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.IO;
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Memory
{
static class NvGpuPushBuffer
{

View File

@ -2,7 +2,7 @@ using ChocolArm64.Memory;
using Ryujinx.Graphics.Gal;
using System.Collections.Concurrent;
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Memory
{
class NvGpuVmm : IAMemory, IGalMemory
{

View File

@ -2,7 +2,7 @@ using ChocolArm64.Memory;
using System;
using System.Collections.Generic;
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Memory
{
class NvGpuVmmCache
{

View File

@ -1,5 +1,5 @@
using Ryujinx.Graphics.Gal;
using System.Threading;
using Ryujinx.HLE.Gpu.Engines;
namespace Ryujinx.HLE.Gpu
{
@ -13,10 +13,6 @@ namespace Ryujinx.HLE.Gpu
public NvGpuEngine3d Engine3d { get; private set; }
public NvGpuEngineDma EngineDma { get; private set; }
private Thread FifoProcessing;
private bool KeepRunning;
public NvGpu(IGalRenderer Renderer)
{
this.Renderer = Renderer;
@ -26,22 +22,6 @@ namespace Ryujinx.HLE.Gpu
Engine2d = new NvGpuEngine2d(this);
Engine3d = new NvGpuEngine3d(this);
EngineDma = new NvGpuEngineDma(this);
KeepRunning = true;
FifoProcessing = new Thread(ProcessFifo);
FifoProcessing.Start();
}
private void ProcessFifo()
{
while (KeepRunning)
{
Fifo.DispatchCalls();
Thread.Yield();
}
}
}
}

View File

@ -1,6 +1,6 @@
using System;
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Texture
{
class BlockLinearSwizzle : ISwizzle
{

View File

@ -1,4 +1,4 @@
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Texture
{
interface ISwizzle
{

View File

@ -1,4 +1,4 @@
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Texture
{
class LinearSwizzle : ISwizzle
{

View File

@ -1,7 +1,8 @@
using Ryujinx.Graphics.Gal;
using Ryujinx.HLE.Gpu.Memory;
using System;
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Texture
{
static class TextureFactory
{
@ -61,7 +62,7 @@ namespace Ryujinx.HLE.Gpu
int Width = (Tic[4] & 0xffff) + 1;
int Height = (Tic[5] & 0xffff) + 1;
Texture Texture = new Texture(
TextureInfo Texture = new TextureInfo(
TextureAddress,
Width,
Height,

View File

@ -1,12 +1,13 @@
using ChocolArm64.Memory;
using Ryujinx.Graphics.Gal;
using Ryujinx.HLE.Gpu.Memory;
using System;
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Texture
{
static class TextureHelper
{
public static ISwizzle GetSwizzle(Texture Texture, int Width, int Bpp)
public static ISwizzle GetSwizzle(TextureInfo Texture, int Width, int Bpp)
{
switch (Texture.Swizzle)
{

View File

@ -1,8 +1,8 @@
using Ryujinx.Graphics.Gal;
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Texture
{
struct Texture
struct TextureInfo
{
public long Position { get; private set; }
@ -16,7 +16,7 @@ namespace Ryujinx.HLE.Gpu
public GalTextureFormat Format { get; private set; }
public Texture(
public TextureInfo(
long Position,
int Width,
int Height)
@ -34,7 +34,7 @@ namespace Ryujinx.HLE.Gpu
Format = GalTextureFormat.A8B8G8R8;
}
public Texture(
public TextureInfo(
long Position,
int Width,
int Height,

View File

@ -2,11 +2,11 @@ using ChocolArm64.Memory;
using Ryujinx.Graphics.Gal;
using System;
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Texture
{
static class TextureReader
{
public static byte[] Read(IAMemory Memory, Texture Texture)
public static byte[] Read(IAMemory Memory, TextureInfo Texture)
{
switch (Texture.Format)
{
@ -31,7 +31,7 @@ namespace Ryujinx.HLE.Gpu
throw new NotImplementedException(Texture.Format.ToString());
}
private unsafe static byte[] Read1Bpp(IAMemory Memory, Texture Texture)
private unsafe static byte[] Read1Bpp(IAMemory Memory, TextureInfo Texture)
{
int Width = Texture.Width;
int Height = Texture.Height;
@ -64,7 +64,7 @@ namespace Ryujinx.HLE.Gpu
return Output;
}
private unsafe static byte[] Read5551(IAMemory Memory, Texture Texture)
private unsafe static byte[] Read5551(IAMemory Memory, TextureInfo Texture)
{
int Width = Texture.Width;
int Height = Texture.Height;
@ -102,7 +102,7 @@ namespace Ryujinx.HLE.Gpu
return Output;
}
private unsafe static byte[] Read565(IAMemory Memory, Texture Texture)
private unsafe static byte[] Read565(IAMemory Memory, TextureInfo Texture)
{
int Width = Texture.Width;
int Height = Texture.Height;
@ -139,7 +139,7 @@ namespace Ryujinx.HLE.Gpu
return Output;
}
private unsafe static byte[] Read2Bpp(IAMemory Memory, Texture Texture)
private unsafe static byte[] Read2Bpp(IAMemory Memory, TextureInfo Texture)
{
int Width = Texture.Width;
int Height = Texture.Height;
@ -172,7 +172,7 @@ namespace Ryujinx.HLE.Gpu
return Output;
}
private unsafe static byte[] Read4Bpp(IAMemory Memory, Texture Texture)
private unsafe static byte[] Read4Bpp(IAMemory Memory, TextureInfo Texture)
{
int Width = Texture.Width;
int Height = Texture.Height;
@ -205,7 +205,7 @@ namespace Ryujinx.HLE.Gpu
return Output;
}
private unsafe static byte[] Read8Bpp(IAMemory Memory, Texture Texture)
private unsafe static byte[] Read8Bpp(IAMemory Memory, TextureInfo Texture)
{
int Width = Texture.Width;
int Height = Texture.Height;
@ -238,7 +238,7 @@ namespace Ryujinx.HLE.Gpu
return Output;
}
private unsafe static byte[] Read16Bpp(IAMemory Memory, Texture Texture)
private unsafe static byte[] Read16Bpp(IAMemory Memory, TextureInfo Texture)
{
int Width = Texture.Width;
int Height = Texture.Height;
@ -273,7 +273,7 @@ namespace Ryujinx.HLE.Gpu
return Output;
}
private unsafe static byte[] Read8Bpt4x4(IAMemory Memory, Texture Texture)
private unsafe static byte[] Read8Bpt4x4(IAMemory Memory, TextureInfo Texture)
{
int Width = (Texture.Width + 3) / 4;
int Height = (Texture.Height + 3) / 4;
@ -306,7 +306,7 @@ namespace Ryujinx.HLE.Gpu
return Output;
}
private unsafe static byte[] Read16Bpt4x4(IAMemory Memory, Texture Texture)
private unsafe static byte[] Read16Bpt4x4(IAMemory Memory, TextureInfo Texture)
{
int Width = (Texture.Width + 3) / 4;
int Height = (Texture.Height + 3) / 4;

View File

@ -1,4 +1,4 @@
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Texture
{
enum TextureSwizzle
{

View File

@ -2,16 +2,16 @@ using ChocolArm64.Memory;
using Ryujinx.Graphics.Gal;
using System;
namespace Ryujinx.HLE.Gpu
namespace Ryujinx.HLE.Gpu.Texture
{
static class TextureWriter
{
public static void Write(
IAMemory Memory,
Texture Texture,
byte[] Data,
int Width,
int Height)
IAMemory Memory,
TextureInfo Texture,
byte[] Data,
int Width,
int Height)
{
switch (Texture.Format)
{
@ -22,11 +22,11 @@ namespace Ryujinx.HLE.Gpu
}
private unsafe static void Write4Bpp(
IAMemory Memory,
Texture Texture,
byte[] Data,
int Width,
int Height)
IAMemory Memory,
TextureInfo Texture,
byte[] Data,
int Width,
int Height)
{
ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, Width, 4);