Example #1
0
        public void Set(int Index, GalTexture Tex)
        {
            GL.ActiveTexture(TextureUnit.Texture0 + Index);

            int Handle = EnsureTextureInitialized(Index);

            GL.BindTexture(TextureTarget.Texture2D, Handle);

            int W = Tex.Width;
            int H = Tex.Height;

            byte[] Data = Tex.Data;

            int Length = Data.Length;

            if (IsCompressedTextureFormat(Tex.Format))
            {
                PixelInternalFormat Pif = OGLEnumConverter.GetCompressedTextureFormat(Tex.Format);

                GL.CompressedTexImage2D(TextureTarget.Texture2D, 0, Pif, W, H, 0, Length, Data);
            }
            else
            {
                //TODO: Get those from Texture format.
                const PixelInternalFormat Pif = PixelInternalFormat.Rgba;

                const PixelFormat Pf = PixelFormat.Rgba;

                const PixelType Pt = PixelType.UnsignedByte;

                GL.TexImage2D(TextureTarget.Texture2D, 0, Pif, W, H, 0, Pf, Pt, Data);
            }
        }
        private void UploadTexture(AMemory Memory, long BasePosition, int TexIndex, int HndIndex)
        {
            long Position = BasePosition + HndIndex * 4;

            int TextureHandle = Memory.ReadInt32(Position);

            int TicIndex = (TextureHandle >> 0) & 0xfffff;
            int TscIndex = (TextureHandle >> 20) & 0xfff;

            TryGetCpuAddr(NvGpuEngine3dReg.TexHeaderPoolOffset, out long TicPosition);
            TryGetCpuAddr(NvGpuEngine3dReg.TexSamplerPoolOffset, out long TscPosition);

            TicPosition += TicIndex * 0x20;
            TscPosition += TscIndex * 0x20;

            GalTextureSampler Sampler = TextureFactory.MakeSampler(Gpu, Memory, TscPosition);

            long TextureAddress = Memory.ReadInt64(TicPosition + 4) & 0xffffffffffff;

            if (FrameBuffers.Contains(TextureAddress))
            {
                //This texture is a frame buffer texture,
                //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);
            }
            else
            {
                GalTexture Texture = TextureFactory.MakeTexture(Gpu, Memory, TicPosition);

                Gpu.Renderer.SetTextureAndSampler(TexIndex, Texture, Sampler);
                Gpu.Renderer.BindTexture(TexIndex);
            }
        }
Example #3
0
        public void SetTextureAndSampler(long Tag, byte[] Data, GalTexture Texture, GalTextureSampler Sampler)
        {
            ActionsQueue.Enqueue(() =>
            {
                this.Texture.Create(Tag, Data, Texture);

                OGLTexture.Set(Sampler);
            });
        }
Example #4
0
        public void SetTextureAndSampler(int Index, GalTexture Texture, GalTextureSampler Sampler)
        {
            ActionsQueue.Enqueue(() =>
            {
                this.Texture.Set(Index, Texture);

                OGLTexture.Set(Sampler);
            });
        }
Example #5
0
        public void Set(int Index, GalTexture Texture)
        {
            GL.ActiveTexture(TextureUnit.Texture0 + Index);

            Bind(Index);

            const int Level  = 0; //TODO: Support mipmap textures.
            const int Border = 0;

            if (IsCompressedTextureFormat(Texture.Format))
            {
                PixelInternalFormat InternalFmt = OGLEnumConverter.GetCompressedTextureFormat(Texture.Format);

                GL.CompressedTexImage2D(
                    TextureTarget.Texture2D,
                    Level,
                    InternalFmt,
                    Texture.Width,
                    Texture.Height,
                    Border,
                    Texture.Data.Length,
                    Texture.Data);
            }
            else
            {
                if (Texture.Format >= GalTextureFormat.Astc2D4x4)
                {
                    Texture = ConvertAstcTextureToRgba(Texture);
                }

                const PixelInternalFormat InternalFmt = PixelInternalFormat.Rgba;

                (PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(Texture.Format);

                GL.TexImage2D(
                    TextureTarget.Texture2D,
                    Level,
                    InternalFmt,
                    Texture.Width,
                    Texture.Height,
                    Border,
                    Format,
                    Type,
                    Texture.Data);
            }

            int SwizzleR = (int)OGLEnumConverter.GetTextureSwizzle(Texture.XSource);
            int SwizzleG = (int)OGLEnumConverter.GetTextureSwizzle(Texture.YSource);
            int SwizzleB = (int)OGLEnumConverter.GetTextureSwizzle(Texture.ZSource);
            int SwizzleA = (int)OGLEnumConverter.GetTextureSwizzle(Texture.WSource);

            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleR, SwizzleR);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleG, SwizzleG);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleB, SwizzleB);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleA, SwizzleA);
        }
Example #6
0
        private void UploadTexture(NvGpuVmm Vmm, long BasePosition, int TexIndex, int HndIndex)
        {
            long Position = BasePosition + HndIndex * 4;

            int TextureHandle = Vmm.ReadInt32(Position);

            int TicIndex = (TextureHandle >> 0) & 0xfffff;
            int TscIndex = (TextureHandle >> 20) & 0xfff;

            long TicPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.TexHeaderPoolOffset);
            long TscPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.TexSamplerPoolOffset);

            TicPosition += TicIndex * 0x20;
            TscPosition += TscIndex * 0x20;

            GalTextureSampler Sampler = TextureFactory.MakeSampler(Gpu, Vmm, TscPosition);

            long TextureAddress = Vmm.ReadInt64(TicPosition + 4) & 0xffffffffffff;

            long Tag = TextureAddress;

            TextureAddress = Vmm.GetPhysicalAddress(TextureAddress);

            if (IsFrameBufferPosition(TextureAddress))
            {
                //This texture is a frame buffer texture,
                //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);
            }
            else
            {
                GalTexture NewTexture = TextureFactory.MakeTexture(Vmm, TicPosition);

                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);

                        return;
                    }
                }

                byte[] Data = TextureFactory.GetTextureData(Vmm, TicPosition);

                Gpu.Renderer.SetTextureAndSampler(Tag, Data, NewTexture, Sampler);

                Gpu.Renderer.BindTexture(Tag, TexIndex);
            }
        }
Example #7
0
        public static byte[] DecodeBC3(GalTexture Texture, int Offset)
        {
            int W = (Texture.Width + 3) / 4;
            int H = (Texture.Height + 3) / 4;

            byte[] Output = new byte[W * H * 64];

            SwizzleAddr Swizzle = new SwizzleAddr(W, H, 4);

            for (int Y = 0; Y < H; Y++)
            {
                for (int X = 0; X < W; X++)
                {
                    int IOffs = Offset + Swizzle.GetSwizzledAddress128(X, Y) * 16;

                    byte[] Tile = BCnDecodeTile(Texture.Data, IOffs + 8, false);

                    byte[] Alpha = new byte[8];

                    Alpha[0] = Texture.Data[IOffs + 0];
                    Alpha[1] = Texture.Data[IOffs + 1];

                    CalculateBC3Alpha(Alpha);

                    int AlphaLow  = Get32(Texture.Data, IOffs + 2);
                    int AlphaHigh = Get16(Texture.Data, IOffs + 6);

                    ulong AlphaCh = (uint)AlphaLow | (ulong)AlphaHigh << 32;

                    int TOffset = 0;

                    for (int TY = 0; TY < 4; TY++)
                    {
                        for (int TX = 0; TX < 4; TX++)
                        {
                            int OOffset = (X * 4 + TX + (Y * 4 + TY) * W * 4) * 4;

                            byte AlphaPx = Alpha[(AlphaCh >> (TY * 12 + TX * 3)) & 7];

                            Output[OOffset + 0] = Tile[TOffset + 0];
                            Output[OOffset + 1] = Tile[TOffset + 1];
                            Output[OOffset + 2] = Tile[TOffset + 2];
                            Output[OOffset + 3] = AlphaPx;

                            TOffset += 4;
                        }
                    }
                }
            }

            return(Output);
        }
Example #8
0
        public static byte[] Decode(GalTexture Texture)
        {
            switch (Texture.Format)
            {
            case GalTextureFormat.BC1: return(BCn.DecodeBC1(Texture, 0));

            case GalTextureFormat.BC2: return(BCn.DecodeBC2(Texture, 0));

            case GalTextureFormat.BC3: return(BCn.DecodeBC3(Texture, 0));
            }

            throw new NotImplementedException(Texture.Format.ToString());
        }
Example #9
0
        public static byte[] DecodeBC4(GalTexture Texture, int Offset)
        {
            int W = (Texture.Width + 3) / 4;
            int H = (Texture.Height + 3) / 4;

            byte[] Output = new byte[W * H * 64];

            SwizzleAddr Swizzle = new SwizzleAddr(W, H, 8);

            for (int Y = 0; Y < H; Y++)
            {
                for (int X = 0; X < W; X++)
                {
                    int IOffs = Swizzle.GetSwizzledAddress64(X, Y) * 8;

                    byte[] Red = new byte[8];

                    Red[0] = Texture.Data[IOffs + 0];
                    Red[1] = Texture.Data[IOffs + 1];

                    CalculateBC3Alpha(Red);

                    int RedLow  = Get32(Texture.Data, IOffs + 2);
                    int RedHigh = Get16(Texture.Data, IOffs + 6);

                    ulong RedCh = (uint)RedLow | (ulong)RedHigh << 32;

                    int TOffset = 0;

                    for (int TY = 0; TY < 4; TY++)
                    {
                        for (int TX = 0; TX < 4; TX++)
                        {
                            int OOffset = (X * 4 + TX + (Y * 4 + TY) * W * 4) * 4;

                            byte RedPx = Red[(RedCh >> (TY * 12 + TX * 3)) & 7];

                            Output[OOffset + 0] = RedPx;
                            Output[OOffset + 1] = RedPx;
                            Output[OOffset + 2] = RedPx;
                            Output[OOffset + 3] = 0xff;

                            TOffset += 4;
                        }
                    }
                }
            }

            return(Output);
        }
Example #10
0
        private static GalTexture ConvertAstcTextureToRgba(GalTexture Texture)
        {
            int TextureBlockWidth  = GetAstcBlockWidth(Texture.Format);
            int TextureBlockHeight = GetAstcBlockHeight(Texture.Format);

            Texture.Data = ASTCDecoder.DecodeToRGBA8888(
                Texture.Data,
                TextureBlockWidth,
                TextureBlockHeight, 1,
                Texture.Width,
                Texture.Height, 1);

            Texture.Format = GalTextureFormat.A8B8G8R8;

            return(Texture);
        }
Example #11
0
        public bool TryGetCachedTexture(long Key, long DataSize, out GalTexture Texture)
        {
            if (TextureCache.TryGetSize(Key, out long Size) && Size == DataSize)
            {
                if (TextureCache.TryGetValue(Key, out TCE CachedTexture))
                {
                    Texture = CachedTexture.Texture;

                    return(true);
                }
            }

            Texture = default(GalTexture);

            return(false);
        }
Example #12
0
        public static int GetTextureSize(GalTexture Texture)
        {
            switch (Texture.Format)
            {
            case GalTextureFormat.R32G32B32A32: return(Texture.Width * Texture.Height * 16);

            case GalTextureFormat.R16G16B16A16: return(Texture.Width * Texture.Height * 8);

            case GalTextureFormat.A8B8G8R8:     return(Texture.Width * Texture.Height * 4);

            case GalTextureFormat.R32:          return(Texture.Width * Texture.Height * 4);

            case GalTextureFormat.A1B5G5R5:     return(Texture.Width * Texture.Height * 2);

            case GalTextureFormat.B5G6R5:       return(Texture.Width * Texture.Height * 2);

            case GalTextureFormat.G8R8:         return(Texture.Width * Texture.Height * 2);

            case GalTextureFormat.R16:          return(Texture.Width * Texture.Height * 2);

            case GalTextureFormat.R8:           return(Texture.Width * Texture.Height);

            case GalTextureFormat.BC1:
            case GalTextureFormat.BC4:
            {
                int W = (Texture.Width + 3) / 4;
                int H = (Texture.Height + 3) / 4;

                return(W * H * 8);
            }

            case GalTextureFormat.BC7U:
            case GalTextureFormat.BC2:
            case GalTextureFormat.BC3:
            case GalTextureFormat.BC5:
            case GalTextureFormat.Astc2D4x4:
            {
                int W = (Texture.Width + 3) / 4;
                int H = (Texture.Height + 3) / 4;

                return(W * H * 16);
            }
            }

            throw new NotImplementedException(Texture.Format.ToString());
        }
Example #13
0
        public static byte[] DecodeBC2(GalTexture Texture, int Offset)
        {
            int W = (Texture.Width + 3) / 4;
            int H = (Texture.Height + 3) / 4;

            byte[] Output = new byte[W * H * 64];

            SwizzleAddr Swizzle = new SwizzleAddr(W, H, 4);

            for (int Y = 0; Y < H; Y++)
            {
                for (int X = 0; X < W; X++)
                {
                    int IOffs = Offset + Swizzle.GetSwizzledAddress128(X, Y) * 16;

                    byte[] Tile = BCnDecodeTile(Texture.Data, IOffs + 8, false);

                    int AlphaLow  = Get32(Texture.Data, IOffs + 0);
                    int AlphaHigh = Get32(Texture.Data, IOffs + 4);

                    ulong AlphaCh = (uint)AlphaLow | (ulong)AlphaHigh << 32;

                    int TOffset = 0;

                    for (int TY = 0; TY < 4; TY++)
                    {
                        for (int TX = 0; TX < 4; TX++)
                        {
                            ulong Alpha = (AlphaCh >> (TY * 16 + TX * 4)) & 0xf;

                            int OOffset = (X * 4 + TX + (Y * 4 + TY) * W * 4) * 4;

                            Output[OOffset + 0] = Tile[TOffset + 0];
                            Output[OOffset + 1] = Tile[TOffset + 1];
                            Output[OOffset + 2] = Tile[TOffset + 2];
                            Output[OOffset + 3] = (byte)(Alpha | (Alpha << 4));

                            TOffset += 4;
                        }
                    }
                }
            }

            return(Output);
        }
Example #14
0
        public void Set(int Index, GalTexture Texture)
        {
            GL.ActiveTexture(TextureUnit.Texture0 + Index);

            Bind(Index);

            const int Level  = 0; //TODO: Support mipmap textures.
            const int Border = 0;

            if (IsCompressedTextureFormat(Texture.Format))
            {
                PixelInternalFormat InternalFmt = OGLEnumConverter.GetCompressedTextureFormat(Texture.Format);

                GL.CompressedTexImage2D(
                    TextureTarget.Texture2D,
                    Level,
                    InternalFmt,
                    Texture.Width,
                    Texture.Height,
                    Border,
                    Texture.Data.Length,
                    Texture.Data);
            }
            else
            {
                const PixelInternalFormat InternalFmt = PixelInternalFormat.Rgba;

                (PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(Texture.Format);

                GL.TexImage2D(
                    TextureTarget.Texture2D,
                    Level,
                    InternalFmt,
                    Texture.Width,
                    Texture.Height,
                    Border,
                    Format,
                    Type,
                    Texture.Data);
            }
        }
Example #15
0
        public static byte[] DecodeBC1(GalTexture Texture, int Offset)
        {
            int W = (Texture.Width + 3) / 4;
            int H = (Texture.Height + 3) / 4;

            byte[] Output = new byte[W * H * 64];

            SwizzleAddr Swizzle = new SwizzleAddr(W, H, 8);

            for (int Y = 0; Y < H; Y++)
            {
                for (int X = 0; X < W; X++)
                {
                    int IOffs = Offset + Swizzle.GetSwizzledAddress64(X, Y) * 8;

                    byte[] Tile = BCnDecodeTile(Texture.Data, IOffs, true);

                    int TOffset = 0;

                    for (int TY = 0; TY < 4; TY++)
                    {
                        for (int TX = 0; TX < 4; TX++)
                        {
                            int OOffset = (X * 4 + TX + (Y * 4 + TY) * W * 4) * 4;

                            Output[OOffset + 0] = Tile[TOffset + 0];
                            Output[OOffset + 1] = Tile[TOffset + 1];
                            Output[OOffset + 2] = Tile[TOffset + 2];
                            Output[OOffset + 3] = Tile[TOffset + 3];

                            TOffset += 4;
                        }
                    }
                }
            }

            return(Output);
        }
Example #16
0
        public void Create(long Key, byte[] Data, GalTexture Texture)
        {
            int Handle = GL.GenTexture();

            TextureCache.AddOrUpdate(Key, new TCE(Handle, Texture), (uint)Data.Length);

            GL.BindTexture(TextureTarget.Texture2D, Handle);

            const int Level  = 0; //TODO: Support mipmap textures.
            const int Border = 0;

            if (IsCompressedTextureFormat(Texture.Format))
            {
                InternalFormat InternalFmt = OGLEnumConverter.GetCompressedTextureFormat(Texture.Format);

                GL.CompressedTexImage2D(
                    TextureTarget.Texture2D,
                    Level,
                    InternalFmt,
                    Texture.Width,
                    Texture.Height,
                    Border,
                    Data.Length,
                    Data);
            }
            else
            {
                if (Texture.Format >= GalTextureFormat.Astc2D4x4)
                {
                    int TextureBlockWidth  = GetAstcBlockWidth(Texture.Format);
                    int TextureBlockHeight = GetAstcBlockHeight(Texture.Format);

                    Data = ASTCDecoder.DecodeToRGBA8888(
                        Data,
                        TextureBlockWidth,
                        TextureBlockHeight, 1,
                        Texture.Width,
                        Texture.Height, 1);

                    Texture.Format = GalTextureFormat.A8B8G8R8;
                }

                const PixelInternalFormat InternalFmt = PixelInternalFormat.Rgba;

                (PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(Texture.Format);

                GL.TexImage2D(
                    TextureTarget.Texture2D,
                    Level,
                    InternalFmt,
                    Texture.Width,
                    Texture.Height,
                    Border,
                    Format,
                    Type,
                    Data);
            }

            int SwizzleR = (int)OGLEnumConverter.GetTextureSwizzle(Texture.XSource);
            int SwizzleG = (int)OGLEnumConverter.GetTextureSwizzle(Texture.YSource);
            int SwizzleB = (int)OGLEnumConverter.GetTextureSwizzle(Texture.ZSource);
            int SwizzleA = (int)OGLEnumConverter.GetTextureSwizzle(Texture.WSource);

            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleR, SwizzleR);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleG, SwizzleG);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleB, SwizzleB);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleA, SwizzleA);
        }
Example #17
0
        public static byte[] DecodeBC5(GalTexture Texture, int Offset, bool SNorm)
        {
            int W = (Texture.Width + 3) / 4;
            int H = (Texture.Height + 3) / 4;

            byte[] Output = new byte[W * H * 64];

            SwizzleAddr Swizzle = new SwizzleAddr(W, H, 4);

            for (int Y = 0; Y < H; Y++)
            {
                for (int X = 0; X < W; X++)
                {
                    int IOffs = Swizzle.GetSwizzledAddress128(X, Y) * 16;

                    byte[] Red   = new byte[8];
                    byte[] Green = new byte[8];

                    Red[0] = Texture.Data[IOffs + 0];
                    Red[1] = Texture.Data[IOffs + 1];

                    Green[0] = Texture.Data[IOffs + 8];
                    Green[1] = Texture.Data[IOffs + 9];

                    if (SNorm)
                    {
                        CalculateBC3AlphaS(Red);
                        CalculateBC3AlphaS(Green);
                    }
                    else
                    {
                        CalculateBC3Alpha(Red);
                        CalculateBC3Alpha(Green);
                    }

                    int RedLow  = Get32(Texture.Data, IOffs + 2);
                    int RedHigh = Get16(Texture.Data, IOffs + 6);

                    int GreenLow  = Get32(Texture.Data, IOffs + 10);
                    int GreenHigh = Get16(Texture.Data, IOffs + 14);

                    ulong RedCh   = (uint)RedLow | (ulong)RedHigh << 32;
                    ulong GreenCh = (uint)GreenLow | (ulong)GreenHigh << 32;

                    int TOffset = 0;

                    if (SNorm)
                    {
                        for (int TY = 0; TY < 4; TY++)
                        {
                            for (int TX = 0; TX < 4; TX++)
                            {
                                int Shift = TY * 12 + TX * 3;

                                int OOffset = (X * 4 + TX + (Y * 4 + TY) * W * 4) * 4;

                                byte RedPx   = Red  [(RedCh >> Shift) & 7];
                                byte GreenPx = Green[(GreenCh >> Shift) & 7];

                                RedPx   += 0x80;
                                GreenPx += 0x80;

                                float NX = (RedPx / 255f) * 2 - 1;
                                float NY = (GreenPx / 255f) * 2 - 1;

                                float NZ = (float)Math.Sqrt(1 - (NX * NX + NY * NY));

                                Output[OOffset + 0] = Clamp((NZ + 1) * 0.5f);
                                Output[OOffset + 1] = Clamp((NY + 1) * 0.5f);
                                Output[OOffset + 2] = Clamp((NX + 1) * 0.5f);
                                Output[OOffset + 3] = 0xff;

                                TOffset += 4;
                            }
                        }
                    }
                    else
                    {
                        for (int TY = 0; TY < 4; TY++)
                        {
                            for (int TX = 0; TX < 4; TX++)
                            {
                                int Shift = TY * 12 + TX * 3;

                                int OOffset = (X * 4 + TX + (Y * 4 + TY) * W * 4) * 4;

                                byte RedPx   = Red  [(RedCh >> Shift) & 7];
                                byte GreenPx = Green[(GreenCh >> Shift) & 7];

                                Output[OOffset + 0] = RedPx;
                                Output[OOffset + 1] = RedPx;
                                Output[OOffset + 2] = RedPx;
                                Output[OOffset + 3] = GreenPx;

                                TOffset += 4;
                            }
                        }
                    }
                }
            }

            return(Output);
        }
Example #18
0
 public TCE(int Handle, GalTexture Texture)
 {
     this.Handle  = Handle;
     this.Texture = Texture;
 }
Example #19
0
        private void UploadTexture(NvGpuVmm Vmm, long BasePosition, int TexIndex, int HndIndex)
        {
            long Position = BasePosition + HndIndex * 4;

            int TextureHandle = Vmm.ReadInt32(Position);

            if (TextureHandle == 0)
            {
                //TODO: Is this correct?
                //Some games like puyo puyo will have 0 handles.
                //It may be just normal behaviour or a bug caused by sync issues.
                //The game does initialize the value properly after through.
                return;
            }

            int TicIndex = (TextureHandle >> 0) & 0xfffff;
            int TscIndex = (TextureHandle >> 20) & 0xfff;

            long TicPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.TexHeaderPoolOffset);
            long TscPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.TexSamplerPoolOffset);

            TicPosition += TicIndex * 0x20;
            TscPosition += TscIndex * 0x20;

            GalTextureSampler Sampler = TextureFactory.MakeSampler(Gpu, Vmm, TscPosition);

            long Key = Vmm.ReadInt64(TicPosition + 4) & 0xffffffffffff;

            Key = Vmm.GetPhysicalAddress(Key);

            if (IsFrameBufferPosition(Key))
            {
                //This texture is a frame buffer texture,
                //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.FrameBuffer.BindTexture(Key, TexIndex);
            }
            else
            {
                GalTexture NewTexture = TextureFactory.MakeTexture(Vmm, TicPosition);

                long Size = (uint)TextureHelper.GetTextureSize(NewTexture);

                bool HasCachedTexture = false;

                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;
                    }
                }

                if (!HasCachedTexture)
                {
                    byte[] Data = TextureFactory.GetTextureData(Vmm, TicPosition);

                    Gpu.Renderer.Texture.Create(Key, Data, NewTexture);
                }

                Gpu.Renderer.Texture.Bind(Key, TexIndex);
            }

            Gpu.Renderer.Texture.SetSampler(Sampler);
        }
Example #20
0
 public bool TryGetCachedTexture(long Tag, long DataSize, out GalTexture Texture)
 {
     return(this.Texture.TryGetCachedTexture(Tag, DataSize, out Texture));
 }
Example #21
0
        public static int GetTextureSize(GalTexture Texture)
        {
            switch (Texture.Format)
            {
            case GalTextureFormat.R32G32B32A32:
                return(Texture.Width * Texture.Height * 16);

            case GalTextureFormat.R16G16B16A16:
                return(Texture.Width * Texture.Height * 8);

            case GalTextureFormat.A8B8G8R8:
            case GalTextureFormat.R32:
            case GalTextureFormat.ZF32:
                return(Texture.Width * Texture.Height * 4);

            case GalTextureFormat.A1B5G5R5:
            case GalTextureFormat.B5G6R5:
            case GalTextureFormat.G8R8:
            case GalTextureFormat.R16:
                return(Texture.Width * Texture.Height * 2);

            case GalTextureFormat.R8:
                return(Texture.Width * Texture.Height);

            case GalTextureFormat.BC1:
            case GalTextureFormat.BC4:
            {
                return(CompressedTextureSize(Texture.Width, Texture.Height, 4, 4, 8));
            }

            case GalTextureFormat.BC7U:
            case GalTextureFormat.BC2:
            case GalTextureFormat.BC3:
            case GalTextureFormat.BC5:
            case GalTextureFormat.Astc2D4x4:
            {
                return(CompressedTextureSize(Texture.Width, Texture.Height, 4, 4, 16));
            }

            case GalTextureFormat.Astc2D5x5:
            {
                return(CompressedTextureSize(Texture.Width, Texture.Height, 5, 5, 16));
            }

            case GalTextureFormat.Astc2D6x6:
            {
                return(CompressedTextureSize(Texture.Width, Texture.Height, 6, 6, 16));
            }

            case GalTextureFormat.Astc2D8x8:
            {
                return(CompressedTextureSize(Texture.Width, Texture.Height, 8, 8, 16));
            }

            case GalTextureFormat.Astc2D10x10:
            {
                return(CompressedTextureSize(Texture.Width, Texture.Height, 10, 10, 16));
            }

            case GalTextureFormat.Astc2D12x12:
            {
                return(CompressedTextureSize(Texture.Width, Texture.Height, 12, 12, 16));
            }

            case GalTextureFormat.Astc2D5x4:
            {
                return(CompressedTextureSize(Texture.Width, Texture.Height, 5, 4, 16));
            }

            case GalTextureFormat.Astc2D6x5:
            {
                return(CompressedTextureSize(Texture.Width, Texture.Height, 6, 5, 16));
            }

            case GalTextureFormat.Astc2D8x6:
            {
                return(CompressedTextureSize(Texture.Width, Texture.Height, 8, 6, 16));
            }

            case GalTextureFormat.Astc2D10x8:
            {
                return(CompressedTextureSize(Texture.Width, Texture.Height, 10, 8, 16));
            }

            case GalTextureFormat.Astc2D12x10:
            {
                return(CompressedTextureSize(Texture.Width, Texture.Height, 12, 10, 16));
            }

            case GalTextureFormat.Astc2D8x5:
            {
                return(CompressedTextureSize(Texture.Width, Texture.Height, 8, 5, 16));
            }

            case GalTextureFormat.Astc2D10x5:
            {
                return(CompressedTextureSize(Texture.Width, Texture.Height, 10, 5, 16));
            }

            case GalTextureFormat.Astc2D10x6:
            {
                return(CompressedTextureSize(Texture.Width, Texture.Height, 10, 6, 16));
            }
            }

            throw new NotImplementedException(Texture.Format.ToString());
        }
Example #22
0
 public void SetTexture(int Index, GalTexture Tex)
 {
     ActionsQueue.Enqueue(() => Texture.Set(Index, Tex));
 }