141 lines
		
	
	
		
			No EOL
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			141 lines
		
	
	
		
			No EOL
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using Ryujinx.Common;
 | |
| using System;
 | |
| using System.Runtime.CompilerServices;
 | |
| using static Ryujinx.Graphics.Texture.BlockLinearConstants;
 | |
| 
 | |
| namespace Ryujinx.Graphics.Texture
 | |
| {
 | |
|     public class OffsetCalculator
 | |
|     {
 | |
|         private int  _width;
 | |
|         private int  _height;
 | |
|         private int  _stride;
 | |
|         private bool _isLinear;
 | |
|         private int  _bytesPerPixel;
 | |
| 
 | |
|         private BlockLinearLayout _layoutConverter;
 | |
| 
 | |
|         // Variables for built in iteration.
 | |
|         private int _yPart;
 | |
| 
 | |
|         public OffsetCalculator(
 | |
|             int  width,
 | |
|             int  height,
 | |
|             int  stride,
 | |
|             bool isLinear,
 | |
|             int  gobBlocksInY,
 | |
|             int  gobBlocksInZ,
 | |
|             int  bytesPerPixel)
 | |
|         {
 | |
|             _width         = width;
 | |
|             _height        = height;
 | |
|             _stride        = stride;
 | |
|             _isLinear      = isLinear;
 | |
|             _bytesPerPixel = bytesPerPixel;
 | |
| 
 | |
|             int wAlignment = GobStride / bytesPerPixel;
 | |
| 
 | |
|             int wAligned = BitUtils.AlignUp(width, wAlignment);
 | |
| 
 | |
|             if (!isLinear)
 | |
|             {
 | |
|                 _layoutConverter = new BlockLinearLayout(
 | |
|                     wAligned,
 | |
|                     height,
 | |
|                     gobBlocksInY,
 | |
|                     gobBlocksInZ,
 | |
|                     bytesPerPixel);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public OffsetCalculator(
 | |
|             int width,
 | |
|             int height,
 | |
|             int stride,
 | |
|             bool isLinear,
 | |
|             int gobBlocksInY,
 | |
|             int bytesPerPixel) : this(width, height, stride, isLinear, gobBlocksInY, 1, bytesPerPixel)
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         public void SetY(int y)
 | |
|         {
 | |
|             if (_isLinear)
 | |
|             {
 | |
|                 _yPart = y * _stride;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 _layoutConverter.SetY(y);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public int GetOffset(int x, int y)
 | |
|         {
 | |
|             if (_isLinear)
 | |
|             {
 | |
|                 return x * _bytesPerPixel + y * _stride;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 return _layoutConverter.GetOffset(x, y, 0);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [MethodImpl(MethodImplOptions.AggressiveInlining)]
 | |
|         public int GetOffset(int x)
 | |
|         {
 | |
|             if (_isLinear)
 | |
|             {
 | |
|                 return x * _bytesPerPixel + _yPart;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 return _layoutConverter.GetOffset(x);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [MethodImpl(MethodImplOptions.AggressiveInlining)]
 | |
|         public int GetOffsetWithLineOffset64(int x)
 | |
|         {
 | |
|             if (_isLinear)
 | |
|             {
 | |
|                 return x + _yPart;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 return _layoutConverter.GetOffsetWithLineOffset64(x);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public (int offset, int size) GetRectangleRange(int x, int y, int width, int height)
 | |
|         {
 | |
|             if (_isLinear)
 | |
|             {
 | |
|                 int start = y * Math.Abs(_stride) + x * _bytesPerPixel;
 | |
|                 int end = (y + height - 1) * Math.Abs(_stride) + (x + width) * _bytesPerPixel;
 | |
|                 return (y * _stride + x * _bytesPerPixel, end - start);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 return _layoutConverter.GetRectangleRange(x, y, width, height);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public bool LayoutMatches(OffsetCalculator other)
 | |
|         {
 | |
|             if (_isLinear)
 | |
|             {
 | |
|                 return other._isLinear &&
 | |
|                        _width == other._width &&
 | |
|                        _height == other._height &&
 | |
|                        _stride == other._stride &&
 | |
|                        _bytesPerPixel == other._bytesPerPixel;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 return !other._isLinear && _layoutConverter.LayoutMatches(other._layoutConverter);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| } | 
