Formatting cleanup

This commit is contained in:
Isaac Marovitz 2024-07-06 22:56:04 +01:00 committed by Isaac Marovitz
parent b734c81683
commit 18a1741348
10 changed files with 192 additions and 201 deletions

View file

@ -10,15 +10,13 @@ namespace Ryujinx.Graphics.Metal
class BackgroundResource : IDisposable class BackgroundResource : IDisposable
{ {
private readonly MetalRenderer _renderer; private readonly MetalRenderer _renderer;
private readonly Pipeline _pipeline;
private CommandBufferPool _pool; private CommandBufferPool _pool;
private PersistentFlushBuffer _flushBuffer; private PersistentFlushBuffer _flushBuffer;
public BackgroundResource(MetalRenderer renderer, Pipeline pipeline) public BackgroundResource(MetalRenderer renderer)
{ {
_renderer = renderer; _renderer = renderer;
_pipeline = pipeline;
} }
public CommandBufferPool GetPool() public CommandBufferPool GetPool()
@ -35,7 +33,7 @@ namespace Ryujinx.Graphics.Metal
public PersistentFlushBuffer GetFlushBuffer() public PersistentFlushBuffer GetFlushBuffer()
{ {
_flushBuffer ??= new PersistentFlushBuffer(_renderer, _pipeline); _flushBuffer ??= new PersistentFlushBuffer(_renderer);
return _flushBuffer; return _flushBuffer;
} }
@ -51,14 +49,12 @@ namespace Ryujinx.Graphics.Metal
class BackgroundResources : IDisposable class BackgroundResources : IDisposable
{ {
private readonly MetalRenderer _renderer; private readonly MetalRenderer _renderer;
private readonly Pipeline _pipeline;
private readonly Dictionary<Thread, BackgroundResource> _resources; private readonly Dictionary<Thread, BackgroundResource> _resources;
public BackgroundResources(MetalRenderer renderer, Pipeline pipeline) public BackgroundResources(MetalRenderer renderer)
{ {
_renderer = renderer; _renderer = renderer;
_pipeline = pipeline;
_resources = new Dictionary<Thread, BackgroundResource>(); _resources = new Dictionary<Thread, BackgroundResource>();
} }
@ -88,7 +84,7 @@ namespace Ryujinx.Graphics.Metal
{ {
Cleanup(); Cleanup();
resource = new BackgroundResource(_renderer, _pipeline); resource = new BackgroundResource(_renderer);
_resources[thread] = resource; _resources[thread] = resource;
} }

View file

@ -59,7 +59,7 @@ namespace Ryujinx.Graphics.Metal
_pipeline = pipeline; _pipeline = pipeline;
_buffers = new IdList<BufferHolder>(); _buffers = new IdList<BufferHolder>();
StagingBuffer = new StagingBuffer(_renderer, _pipeline, this); StagingBuffer = new StagingBuffer(_renderer, this);
} }
public BufferHandle Create(nint pointer, int size) public BufferHandle Create(nint pointer, int size)

View file

@ -13,13 +13,13 @@ namespace Ryujinx.Graphics.Metal
struct I8ToI16CacheKey : ICacheKey struct I8ToI16CacheKey : ICacheKey
{ {
// Used to notify the pipeline that bindings have invalidated on dispose. // Used to notify the pipeline that bindings have invalidated on dispose.
private readonly MetalRenderer _renderer; // private readonly MetalRenderer _renderer;
private Auto<DisposableBuffer> _buffer; // private Auto<DisposableBuffer> _buffer;
public I8ToI16CacheKey(MetalRenderer renderer) public I8ToI16CacheKey(MetalRenderer renderer)
{ {
_renderer = renderer; // _renderer = renderer;
_buffer = null; // _buffer = null;
} }
public readonly bool KeyEqual(ICacheKey other) public readonly bool KeyEqual(ICacheKey other)
@ -27,92 +27,92 @@ namespace Ryujinx.Graphics.Metal
return other is I8ToI16CacheKey; return other is I8ToI16CacheKey;
} }
public void SetBuffer(Auto<DisposableBuffer> buffer) public readonly void SetBuffer(Auto<DisposableBuffer> buffer)
{ {
_buffer = buffer; // _buffer = buffer;
} }
public void Dispose() public readonly void Dispose()
{ {
// TODO: Tell pipeline buffer is dirty! // TODO: Tell pipeline buffer is dirty!
// _renderer.PipelineInternal.DirtyIndexBuffer(_buffer); // _renderer.PipelineInternal.DirtyIndexBuffer(_buffer);
} }
} }
[SupportedOSPlatform("macos")] // [SupportedOSPlatform("macos")]
struct AlignedVertexBufferCacheKey : ICacheKey // struct AlignedVertexBufferCacheKey : ICacheKey
{ // {
private readonly int _stride; // private readonly int _stride;
private readonly int _alignment; // private readonly int _alignment;
//
// // Used to notify the pipeline that bindings have invalidated on dispose.
// // private readonly MetalRenderer _renderer;
// // private Auto<DisposableBuffer> _buffer;
//
// public AlignedVertexBufferCacheKey(MetalRenderer renderer, int stride, int alignment)
// {
// // _renderer = renderer;
// _stride = stride;
// _alignment = alignment;
// // _buffer = null;
// }
//
// public readonly bool KeyEqual(ICacheKey other)
// {
// return other is AlignedVertexBufferCacheKey entry &&
// entry._stride == _stride &&
// entry._alignment == _alignment;
// }
//
// public void SetBuffer(Auto<DisposableBuffer> buffer)
// {
// // _buffer = buffer;
// }
//
// public readonly void Dispose()
// {
// // TODO: Tell pipeline buffer is dirty!
// // _renderer.PipelineInternal.DirtyVertexBuffer(_buffer);
// }
// }
// Used to notify the pipeline that bindings have invalidated on dispose. // [SupportedOSPlatform("macos")]
private readonly MetalRenderer _renderer; // struct TopologyConversionCacheKey : ICacheKey
private Auto<DisposableBuffer> _buffer; // {
// // TODO: Patterns
public AlignedVertexBufferCacheKey(MetalRenderer renderer, int stride, int alignment) // // private readonly IndexBufferPattern _pattern;
{ // private readonly int _indexSize;
_renderer = renderer; //
_stride = stride; // // Used to notify the pipeline that bindings have invalidated on dispose.
_alignment = alignment; // // private readonly MetalRenderer _renderer;
_buffer = null; // // private Auto<DisposableBuffer> _buffer;
} //
// public TopologyConversionCacheKey(MetalRenderer renderer, /*IndexBufferPattern pattern, */int indexSize)
public readonly bool KeyEqual(ICacheKey other) // {
{ // // _renderer = renderer;
return other is AlignedVertexBufferCacheKey entry && // // _pattern = pattern;
entry._stride == _stride && // _indexSize = indexSize;
entry._alignment == _alignment; // // _buffer = null;
} // }
//
public void SetBuffer(Auto<DisposableBuffer> buffer) // public readonly bool KeyEqual(ICacheKey other)
{ // {
_buffer = buffer; // return other is TopologyConversionCacheKey entry &&
} // // entry._pattern == _pattern &&
// entry._indexSize == _indexSize;
public readonly void Dispose() // }
{ //
// TODO: Tell pipeline buffer is dirty! // public void SetBuffer(Auto<DisposableBuffer> buffer)
// _renderer.PipelineInternal.DirtyVertexBuffer(_buffer); // {
} // // _buffer = buffer;
} // }
//
[SupportedOSPlatform("macos")] // public readonly void Dispose()
struct TopologyConversionCacheKey : ICacheKey // {
{ // // TODO: Tell pipeline buffer is dirty!
// TODO: Patterns // // _renderer.PipelineInternal.DirtyVertexBuffer(_buffer);
// private readonly IndexBufferPattern _pattern; // }
private readonly int _indexSize; // }
// Used to notify the pipeline that bindings have invalidated on dispose.
private readonly MetalRenderer _renderer;
private Auto<DisposableBuffer> _buffer;
public TopologyConversionCacheKey(MetalRenderer renderer, /*IndexBufferPattern pattern, */int indexSize)
{
_renderer = renderer;
// _pattern = pattern;
_indexSize = indexSize;
_buffer = null;
}
public readonly bool KeyEqual(ICacheKey other)
{
return other is TopologyConversionCacheKey entry &&
// entry._pattern == _pattern &&
entry._indexSize == _indexSize;
}
public void SetBuffer(Auto<DisposableBuffer> buffer)
{
_buffer = buffer;
}
public readonly void Dispose()
{
// TODO: Tell pipeline buffer is dirty!
// _renderer.PipelineInternal.DirtyVertexBuffer(_buffer);
}
}
[SupportedOSPlatform("macos")] [SupportedOSPlatform("macos")]
readonly struct Dependency readonly struct Dependency
@ -141,8 +141,8 @@ namespace Ryujinx.Graphics.Metal
{ {
private struct Entry private struct Entry
{ {
public ICacheKey Key; public readonly ICacheKey Key;
public T Value; public readonly T Value;
public List<Dependency> DependencyList; public List<Dependency> DependencyList;
public Entry(ICacheKey key, T value) public Entry(ICacheKey key, T value)

View file

@ -52,7 +52,7 @@ namespace Ryujinx.Graphics.Metal
} }
} }
public void Dispose() public readonly void Dispose()
{ {
// State // State
@ -79,7 +79,7 @@ namespace Ryujinx.Graphics.Metal
}; };
} }
public void RestorePredrawState(PredrawState state) public readonly void RestorePredrawState(PredrawState state)
{ {
_currentState.CullMode = state.CullMode; _currentState.CullMode = state.CullMode;
_currentState.DepthStencilUid = state.DepthStencilUid; _currentState.DepthStencilUid = state.DepthStencilUid;
@ -89,12 +89,12 @@ namespace Ryujinx.Graphics.Metal
_currentState.Dirty |= DirtyFlags.CullMode | DirtyFlags.DepthStencil | DirtyFlags.Viewports; _currentState.Dirty |= DirtyFlags.CullMode | DirtyFlags.DepthStencil | DirtyFlags.Viewports;
} }
public void SetClearLoadAction(bool clear) public readonly void SetClearLoadAction(bool clear)
{ {
_currentState.ClearLoadAction = clear; _currentState.ClearLoadAction = clear;
} }
public MTLRenderCommandEncoder CreateRenderCommandEncoder() public readonly MTLRenderCommandEncoder CreateRenderCommandEncoder()
{ {
// Initialise Pass & State // Initialise Pass & State
var renderPassDescriptor = new MTLRenderPassDescriptor(); var renderPassDescriptor = new MTLRenderPassDescriptor();
@ -161,7 +161,7 @@ namespace Ryujinx.Graphics.Metal
return renderCommandEncoder; return renderCommandEncoder;
} }
public MTLComputeCommandEncoder CreateComputeCommandEncoder() public readonly MTLComputeCommandEncoder CreateComputeCommandEncoder()
{ {
var descriptor = new MTLComputePassDescriptor(); var descriptor = new MTLComputePassDescriptor();
var computeCommandEncoder = _pipeline.CommandBuffer.ComputeCommandEncoder(descriptor); var computeCommandEncoder = _pipeline.CommandBuffer.ComputeCommandEncoder(descriptor);
@ -246,7 +246,7 @@ namespace Ryujinx.Graphics.Metal
_currentState.Dirty &= ~DirtyFlags.RenderAll; _currentState.Dirty &= ~DirtyFlags.RenderAll;
} }
public void RebindComputeState(MTLComputeCommandEncoder computeCommandEncoder) public readonly void RebindComputeState(MTLComputeCommandEncoder computeCommandEncoder)
{ {
if (_currentState.Dirty.HasFlag(DirtyFlags.ComputePipeline)) if (_currentState.Dirty.HasFlag(DirtyFlags.ComputePipeline))
{ {
@ -276,7 +276,7 @@ namespace Ryujinx.Graphics.Metal
_currentState.Dirty &= ~DirtyFlags.ComputeAll; _currentState.Dirty &= ~DirtyFlags.ComputeAll;
} }
private void SetRenderPipelineState(MTLRenderCommandEncoder renderCommandEncoder) private readonly void SetRenderPipelineState(MTLRenderCommandEncoder renderCommandEncoder)
{ {
MTLRenderPipelineState pipelineState = _currentState.Pipeline.CreateRenderPipeline(_device, _currentState.RenderProgram); MTLRenderPipelineState pipelineState = _currentState.Pipeline.CreateRenderPipeline(_device, _currentState.RenderProgram);
@ -289,7 +289,7 @@ namespace Ryujinx.Graphics.Metal
_currentState.BlendColor.Alpha); _currentState.BlendColor.Alpha);
} }
private void SetComputePipelineState(MTLComputeCommandEncoder computeCommandEncoder) private readonly void SetComputePipelineState(MTLComputeCommandEncoder computeCommandEncoder)
{ {
if (_currentState.ComputeProgram == null) if (_currentState.ComputeProgram == null)
{ {
@ -301,7 +301,7 @@ namespace Ryujinx.Graphics.Metal
computeCommandEncoder.SetComputePipelineState(pipelineState); computeCommandEncoder.SetComputePipelineState(pipelineState);
} }
public void UpdateIndexBuffer(BufferRange buffer, IndexType type) public readonly void UpdateIndexBuffer(BufferRange buffer, IndexType type)
{ {
if (buffer.Handle != BufferHandle.Null) if (buffer.Handle != BufferHandle.Null)
{ {
@ -320,12 +320,12 @@ namespace Ryujinx.Graphics.Metal
} }
} }
public void UpdatePrimitiveTopology(PrimitiveTopology topology) public readonly void UpdatePrimitiveTopology(PrimitiveTopology topology)
{ {
_currentState.Topology = topology; _currentState.Topology = topology;
} }
public void UpdateProgram(IProgram program) public readonly void UpdateProgram(IProgram program)
{ {
Program prg = (Program)program; Program prg = (Program)program;
@ -356,13 +356,13 @@ namespace Ryujinx.Graphics.Metal
} }
} }
public void UpdateRenderTargets(ITexture[] colors, ITexture depthStencil) public readonly void UpdateRenderTargets(ITexture[] colors, ITexture depthStencil)
{ {
_currentState.FramebufferUsingColorWriteMask = false; _currentState.FramebufferUsingColorWriteMask = false;
UpdateRenderTargetsInternal(colors, depthStencil); UpdateRenderTargetsInternal(colors, depthStencil);
} }
public void UpdateRenderTargetColorMasks(ReadOnlySpan<uint> componentMask) public readonly void UpdateRenderTargetColorMasks(ReadOnlySpan<uint> componentMask)
{ {
ref var blendState = ref _currentState.Pipeline.Internal.ColorBlendState; ref var blendState = ref _currentState.Pipeline.Internal.ColorBlendState;
@ -415,7 +415,7 @@ namespace Ryujinx.Graphics.Metal
} }
} }
private void UpdateRenderTargetsInternal(ITexture[] colors, ITexture depthStencil) private readonly void UpdateRenderTargetsInternal(ITexture[] colors, ITexture depthStencil)
{ {
// TBDR GPUs don't work properly if the same attachment is bound to multiple targets, // TBDR GPUs don't work properly if the same attachment is bound to multiple targets,
// due to each attachment being a copy of the real attachment, rather than a direct write. // due to each attachment being a copy of the real attachment, rather than a direct write.
@ -496,7 +496,7 @@ namespace Ryujinx.Graphics.Metal
} }
} }
private void MaskOut(ITexture[] colors, ITexture depthStencil) private readonly void MaskOut(ITexture[] colors, ITexture depthStencil)
{ {
if (!_currentState.FramebufferUsingColorWriteMask) if (!_currentState.FramebufferUsingColorWriteMask)
{ {
@ -508,7 +508,7 @@ namespace Ryujinx.Graphics.Metal
_currentState.FramebufferUsingColorWriteMask = true; _currentState.FramebufferUsingColorWriteMask = true;
} }
public void UpdateVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs) public readonly void UpdateVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs)
{ {
vertexAttribs.CopyTo(_currentState.VertexAttribs); vertexAttribs.CopyTo(_currentState.VertexAttribs);
@ -519,7 +519,7 @@ namespace Ryujinx.Graphics.Metal
_currentState.Dirty |= DirtyFlags.RenderPipeline; _currentState.Dirty |= DirtyFlags.RenderPipeline;
} }
public void UpdateBlendDescriptors(int index, BlendDescriptor blend) public readonly void UpdateBlendDescriptors(int index, BlendDescriptor blend)
{ {
ref var blendState = ref _currentState.Pipeline.Internal.ColorBlendState[index]; ref var blendState = ref _currentState.Pipeline.Internal.ColorBlendState[index];
@ -577,7 +577,7 @@ namespace Ryujinx.Graphics.Metal
_currentState.Dirty |= DirtyFlags.DepthStencil; _currentState.Dirty |= DirtyFlags.DepthStencil;
} }
public void UpdateDepthState(DepthTestDescriptor depthTest) public readonly void UpdateDepthState(DepthTestDescriptor depthTest)
{ {
ref DepthStencilUid uid = ref _currentState.DepthStencilUid; ref DepthStencilUid uid = ref _currentState.DepthStencilUid;
@ -589,7 +589,7 @@ namespace Ryujinx.Graphics.Metal
} }
// Inlineable // Inlineable
public void UpdateDepthClamp(bool clamp) public readonly void UpdateDepthClamp(bool clamp)
{ {
_currentState.DepthClipMode = clamp ? MTLDepthClipMode.Clamp : MTLDepthClipMode.Clip; _currentState.DepthClipMode = clamp ? MTLDepthClipMode.Clamp : MTLDepthClipMode.Clip;
@ -605,7 +605,7 @@ namespace Ryujinx.Graphics.Metal
} }
// Inlineable // Inlineable
public void UpdateDepthBias(float depthBias, float slopeScale, float clamp) public readonly void UpdateDepthBias(float depthBias, float slopeScale, float clamp)
{ {
_currentState.DepthBias = depthBias; _currentState.DepthBias = depthBias;
_currentState.SlopeScale = slopeScale; _currentState.SlopeScale = slopeScale;
@ -683,7 +683,7 @@ namespace Ryujinx.Graphics.Metal
_currentState.Dirty |= DirtyFlags.Viewports; _currentState.Dirty |= DirtyFlags.Viewports;
} }
public void UpdateVertexBuffers(ReadOnlySpan<VertexBufferDescriptor> vertexBuffers) public readonly void UpdateVertexBuffers(ReadOnlySpan<VertexBufferDescriptor> vertexBuffers)
{ {
vertexBuffers.CopyTo(_currentState.VertexBuffers); vertexBuffers.CopyTo(_currentState.VertexBuffers);
@ -694,7 +694,7 @@ namespace Ryujinx.Graphics.Metal
_currentState.Dirty |= DirtyFlags.RenderPipeline; _currentState.Dirty |= DirtyFlags.RenderPipeline;
} }
public void UpdateUniformBuffers(ReadOnlySpan<BufferAssignment> buffers) public readonly void UpdateUniformBuffers(ReadOnlySpan<BufferAssignment> buffers)
{ {
foreach (BufferAssignment assignment in buffers) foreach (BufferAssignment assignment in buffers)
{ {
@ -711,7 +711,7 @@ namespace Ryujinx.Graphics.Metal
_currentState.Dirty |= DirtyFlags.Uniforms; _currentState.Dirty |= DirtyFlags.Uniforms;
} }
public void UpdateStorageBuffers(ReadOnlySpan<BufferAssignment> buffers) public readonly void UpdateStorageBuffers(ReadOnlySpan<BufferAssignment> buffers)
{ {
foreach (BufferAssignment assignment in buffers) foreach (BufferAssignment assignment in buffers)
{ {
@ -728,7 +728,7 @@ namespace Ryujinx.Graphics.Metal
_currentState.Dirty |= DirtyFlags.Storages; _currentState.Dirty |= DirtyFlags.Storages;
} }
public void UpdateStorageBuffers(int first, ReadOnlySpan<Auto<DisposableBuffer>> buffers) public readonly void UpdateStorageBuffers(int first, ReadOnlySpan<Auto<DisposableBuffer>> buffers)
{ {
for (int i = 0; i < buffers.Length; i++) for (int i = 0; i < buffers.Length; i++)
{ {
@ -767,7 +767,7 @@ namespace Ryujinx.Graphics.Metal
} }
// Inlineable // Inlineable
public void UpdateFrontFace(FrontFace frontFace) public readonly void UpdateFrontFace(FrontFace frontFace)
{ {
_currentState.Winding = frontFace.Convert(); _currentState.Winding = frontFace.Convert();
@ -782,7 +782,7 @@ namespace Ryujinx.Graphics.Metal
_currentState.Dirty |= DirtyFlags.FrontFace; _currentState.Dirty |= DirtyFlags.FrontFace;
} }
private void UpdateStencilRefValue(int frontRef, int backRef) private readonly void UpdateStencilRefValue(int frontRef, int backRef)
{ {
_currentState.FrontRefValue = frontRef; _currentState.FrontRefValue = frontRef;
_currentState.BackRefValue = backRef; _currentState.BackRefValue = backRef;
@ -797,9 +797,9 @@ namespace Ryujinx.Graphics.Metal
_currentState.Dirty |= DirtyFlags.StencilRef; _currentState.Dirty |= DirtyFlags.StencilRef;
} }
public void UpdateTextureAndSampler(ShaderStage stage, ulong binding, TextureBase texture, Sampler sampler) public readonly void UpdateTextureAndSampler(ShaderStage stage, ulong binding, TextureBase texture, Sampler sampler)
{ {
if (texture is TextureBuffer textureBuffer) if (texture is TextureBuffer)
{ {
// TODO: Texture buffers // TODO: Texture buffers
} }
@ -853,7 +853,7 @@ namespace Ryujinx.Graphics.Metal
} }
} }
private unsafe void SetViewports(MTLRenderCommandEncoder renderCommandEncoder) private readonly unsafe void SetViewports(MTLRenderCommandEncoder renderCommandEncoder)
{ {
if (_currentState.Viewports.Length > 0) if (_currentState.Viewports.Length > 0)
{ {
@ -864,7 +864,7 @@ namespace Ryujinx.Graphics.Metal
} }
} }
private void UpdatePipelineVertexState(VertexBufferDescriptor[] bufferDescriptors, VertexAttribDescriptor[] attribDescriptors) private readonly void UpdatePipelineVertexState(VertexBufferDescriptor[] bufferDescriptors, VertexAttribDescriptor[] attribDescriptors)
{ {
ref PipelineState pipeline = ref _currentState.Pipeline; ref PipelineState pipeline = ref _currentState.Pipeline;
uint indexMask = 0; uint indexMask = 0;
@ -941,7 +941,7 @@ namespace Ryujinx.Graphics.Metal
pipeline.VertexBindingDescriptionsCount = Constants.ZeroBufferIndex + 1; // TODO: move this out? pipeline.VertexBindingDescriptionsCount = Constants.ZeroBufferIndex + 1; // TODO: move this out?
} }
private void SetVertexBuffers(MTLRenderCommandEncoder renderCommandEncoder, VertexBufferDescriptor[] bufferDescriptors) private readonly void SetVertexBuffers(MTLRenderCommandEncoder renderCommandEncoder, VertexBufferDescriptor[] bufferDescriptors)
{ {
for (int i = 0; i < bufferDescriptors.Length; i++) for (int i = 0; i < bufferDescriptors.Length; i++)
{ {
@ -974,7 +974,7 @@ namespace Ryujinx.Graphics.Metal
renderCommandEncoder.SetVertexBuffer(zeroMtlBuffer, 0, Constants.ZeroBufferIndex); renderCommandEncoder.SetVertexBuffer(zeroMtlBuffer, 0, Constants.ZeroBufferIndex);
} }
private void UpdateAndBind(MTLRenderCommandEncoder renderCommandEncoder, Program program, int setIndex) private readonly void UpdateAndBind(MTLRenderCommandEncoder renderCommandEncoder, Program program, int setIndex)
{ {
var bindingSegments = program.BindingSegments[setIndex]; var bindingSegments = program.BindingSegments[setIndex];
@ -1193,7 +1193,7 @@ namespace Ryujinx.Graphics.Metal
} }
} }
private void UpdateAndBind(MTLComputeCommandEncoder computeCommandEncoder, Program program, int setIndex) private readonly void UpdateAndBind(MTLComputeCommandEncoder computeCommandEncoder, Program program, int setIndex)
{ {
var bindingSegments = program.BindingSegments[setIndex]; var bindingSegments = program.BindingSegments[setIndex];

View file

@ -67,7 +67,7 @@ namespace Ryujinx.Graphics.Metal
_pipeline.InitEncoderStateManager(BufferManager); _pipeline.InitEncoderStateManager(BufferManager);
BackgroundResources = new BackgroundResources(this, _pipeline); BackgroundResources = new BackgroundResources(this);
HelperShader = new HelperShader(_device, this, _pipeline); HelperShader = new HelperShader(_device, this, _pipeline);
SyncManager = new SyncManager(this); SyncManager = new SyncManager(this);
} }

View file

@ -8,14 +8,12 @@ namespace Ryujinx.Graphics.Metal
internal class PersistentFlushBuffer : IDisposable internal class PersistentFlushBuffer : IDisposable
{ {
private readonly MetalRenderer _renderer; private readonly MetalRenderer _renderer;
private readonly Pipeline _pipeline;
private BufferHolder _flushStorage; private BufferHolder _flushStorage;
public PersistentFlushBuffer(MetalRenderer renderer, Pipeline pipeline) public PersistentFlushBuffer(MetalRenderer renderer)
{ {
_renderer = renderer; _renderer = renderer;
_pipeline = pipeline;
} }
private BufferHolder ResizeIfNeeded(int size) private BufferHolder ResizeIfNeeded(int size)

View file

@ -31,7 +31,6 @@ namespace Ryujinx.Graphics.Metal
private int _freeSize; private int _freeSize;
private readonly MetalRenderer _renderer; private readonly MetalRenderer _renderer;
private readonly Pipeline _pipeline;
private readonly BufferHolder _buffer; private readonly BufferHolder _buffer;
private readonly int _resourceAlignment; private readonly int _resourceAlignment;
@ -52,10 +51,9 @@ namespace Ryujinx.Graphics.Metal
private readonly Queue<PendingCopy> _pendingCopies; private readonly Queue<PendingCopy> _pendingCopies;
public StagingBuffer(MetalRenderer renderer, Pipeline pipeline, BufferManager bufferManager) public StagingBuffer(MetalRenderer renderer, BufferManager bufferManager)
{ {
_renderer = renderer; _renderer = renderer;
_pipeline = pipeline;
Handle = bufferManager.CreateWithHandle(BufferSize, out _buffer); Handle = bufferManager.CreateWithHandle(BufferSize, out _buffer);
_pendingCopies = new Queue<PendingCopy>(); _pendingCopies = new Queue<PendingCopy>();

View file

@ -12,7 +12,7 @@ namespace Ryujinx.Graphics.Metal
class Texture : TextureBase, ITexture class Texture : TextureBase, ITexture
{ {
private MTLTexture _identitySwizzleHandle; private MTLTexture _identitySwizzleHandle;
private bool _identityIsDifferent; private readonly bool _identityIsDifferent;
public Texture(MTLDevice device, MetalRenderer renderer, Pipeline pipeline, TextureCreateInfo info) : base(device, renderer, pipeline, info) public Texture(MTLDevice device, MetalRenderer renderer, Pipeline pipeline, TextureCreateInfo info) : base(device, renderer, pipeline, info)
{ {
@ -40,15 +40,15 @@ namespace Ryujinx.Graphics.Metal
MTLTextureSwizzleChannels swizzle = GetSwizzle(info, descriptor.PixelFormat); MTLTextureSwizzleChannels swizzle = GetSwizzle(info, descriptor.PixelFormat);
_identitySwizzleHandle = _device.NewTexture(descriptor); _identitySwizzleHandle = Device.NewTexture(descriptor);
if (SwizzleIsIdentity(swizzle)) if (SwizzleIsIdentity(swizzle))
{ {
_mtlTexture = _identitySwizzleHandle; MtlTexture = _identitySwizzleHandle;
} }
else else
{ {
_mtlTexture = CreateDefaultView(_identitySwizzleHandle, swizzle, descriptor); MtlTexture = CreateDefaultView(_identitySwizzleHandle, swizzle, descriptor);
_identityIsDifferent = true; _identityIsDifferent = true;
} }
@ -73,11 +73,11 @@ namespace Ryujinx.Graphics.Metal
if (SwizzleIsIdentity(swizzle)) if (SwizzleIsIdentity(swizzle))
{ {
_mtlTexture = _identitySwizzleHandle; MtlTexture = _identitySwizzleHandle;
} }
else else
{ {
_mtlTexture = sourceTexture.NewTextureView(pixelFormat, textureType, levels, slices, swizzle); MtlTexture = sourceTexture.NewTextureView(pixelFormat, textureType, levels, slices, swizzle);
_identityIsDifferent = true; _identityIsDifferent = true;
} }
@ -146,7 +146,7 @@ namespace Ryujinx.Graphics.Metal
public void CopyTo(ITexture destination, int firstLayer, int firstLevel) public void CopyTo(ITexture destination, int firstLayer, int firstLevel)
{ {
CommandBufferScoped cbs = _pipeline.Cbs; CommandBufferScoped cbs = Pipeline.Cbs;
TextureBase src = this; TextureBase src = this;
TextureBase dst = (TextureBase)destination; TextureBase dst = (TextureBase)destination;
@ -156,30 +156,30 @@ namespace Ryujinx.Graphics.Metal
if (!dst.Info.Target.IsMultisample() && Info.Target.IsMultisample()) if (!dst.Info.Target.IsMultisample() && Info.Target.IsMultisample())
{ {
//int layers = Math.Min(Info.GetLayers(), dst.Info.GetLayers() - firstLayer); // int layers = Math.Min(Info.GetLayers(), dst.Info.GetLayers() - firstLayer);
//_gd.HelperShader.CopyMSToNonMS(_gd, cbs, src, dst, 0, firstLayer, layers); // _gd.HelperShader.CopyMSToNonMS(_gd, cbs, src, dst, 0, firstLayer, layers);
} }
else if (dst.Info.Target.IsMultisample() && !Info.Target.IsMultisample()) else if (dst.Info.Target.IsMultisample() && !Info.Target.IsMultisample())
{ {
//int layers = Math.Min(Info.GetLayers(), dst.Info.GetLayers() - firstLayer); // int layers = Math.Min(Info.GetLayers(), dst.Info.GetLayers() - firstLayer);
//_gd.HelperShader.CopyNonMSToMS(_gd, cbs, src, dst, 0, firstLayer, layers); // _gd.HelperShader.CopyNonMSToMS(_gd, cbs, src, dst, 0, firstLayer, layers);
} }
else if (dst.Info.BytesPerPixel != Info.BytesPerPixel) else if (dst.Info.BytesPerPixel != Info.BytesPerPixel)
{ {
//int layers = Math.Min(Info.GetLayers(), dst.Info.GetLayers() - firstLayer); // int layers = Math.Min(Info.GetLayers(), dst.Info.GetLayers() - firstLayer);
//int levels = Math.Min(Info.Levels, dst.Info.Levels - firstLevel); // int levels = Math.Min(Info.Levels, dst.Info.Levels - firstLevel);
//_gd.HelperShader.CopyIncompatibleFormats(_gd, cbs, src, dst, 0, firstLayer, 0, firstLevel, layers, levels); // _gd.HelperShader.CopyIncompatibleFormats(_gd, cbs, src, dst, 0, firstLayer, 0, firstLevel, layers, levels);
} }
else if (src.Info.Format.IsDepthOrStencil() != dst.Info.Format.IsDepthOrStencil()) else if (src.Info.Format.IsDepthOrStencil() != dst.Info.Format.IsDepthOrStencil())
{ {
int layers = Math.Min(Info.GetLayers(), dst.Info.GetLayers() - firstLayer); // int layers = Math.Min(Info.GetLayers(), dst.Info.GetLayers() - firstLayer);
int levels = Math.Min(Info.Levels, dst.Info.Levels - firstLevel); // int levels = Math.Min(Info.Levels, dst.Info.Levels - firstLevel);
// TODO: depth copy? // TODO: depth copy?
//_gd.HelperShader.CopyColor(_gd, cbs, src, dst, 0, firstLayer, 0, FirstLevel, layers, levels); // _gd.HelperShader.CopyColor(_gd, cbs, src, dst, 0, firstLayer, 0, FirstLevel, layers, levels);
} }
else else
{ {
@ -198,7 +198,7 @@ namespace Ryujinx.Graphics.Metal
public void CopyTo(ITexture destination, int srcLayer, int dstLayer, int srcLevel, int dstLevel) public void CopyTo(ITexture destination, int srcLayer, int dstLayer, int srcLevel, int dstLevel)
{ {
CommandBufferScoped cbs = _pipeline.Cbs; CommandBufferScoped cbs = Pipeline.Cbs;
TextureBase src = this; TextureBase src = this;
TextureBase dst = (TextureBase)destination; TextureBase dst = (TextureBase)destination;
@ -208,19 +208,19 @@ namespace Ryujinx.Graphics.Metal
if (!dst.Info.Target.IsMultisample() && Info.Target.IsMultisample()) if (!dst.Info.Target.IsMultisample() && Info.Target.IsMultisample())
{ {
//_gd.HelperShader.CopyMSToNonMS(_gd, cbs, src, dst, srcLayer, dstLayer, 1); // _gd.HelperShader.CopyMSToNonMS(_gd, cbs, src, dst, srcLayer, dstLayer, 1);
} }
else if (dst.Info.Target.IsMultisample() && !Info.Target.IsMultisample()) else if (dst.Info.Target.IsMultisample() && !Info.Target.IsMultisample())
{ {
//_gd.HelperShader.CopyNonMSToMS(_gd, cbs, src, dst, srcLayer, dstLayer, 1); // _gd.HelperShader.CopyNonMSToMS(_gd, cbs, src, dst, srcLayer, dstLayer, 1);
} }
else if (dst.Info.BytesPerPixel != Info.BytesPerPixel) else if (dst.Info.BytesPerPixel != Info.BytesPerPixel)
{ {
//_gd.HelperShader.CopyIncompatibleFormats(_gd, cbs, src, dst, srcLayer, dstLayer, srcLevel, dstLevel, 1, 1); // _gd.HelperShader.CopyIncompatibleFormats(_gd, cbs, src, dst, srcLayer, dstLayer, srcLevel, dstLevel, 1, 1);
} }
else if (src.Info.Format.IsDepthOrStencil() != dst.Info.Format.IsDepthOrStencil()) else if (src.Info.Format.IsDepthOrStencil() != dst.Info.Format.IsDepthOrStencil())
{ {
//_gd.HelperShader.CopyColor(_gd, cbs, src, dst, srcLayer, dstLayer, srcLevel, dstLevel, 1, 1); // _gd.HelperShader.CopyColor(_gd, cbs, src, dst, srcLayer, dstLayer, srcLevel, dstLevel, 1, 1);
} }
else else
{ {
@ -241,7 +241,7 @@ namespace Ryujinx.Graphics.Metal
public void CopyTo(ITexture destination, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter) public void CopyTo(ITexture destination, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter)
{ {
if (!_renderer.CommandBufferPool.OwnedByCurrentThread) if (!Renderer.CommandBufferPool.OwnedByCurrentThread)
{ {
Logger.Warning?.PrintMsg(LogClass.Gpu, "Metal doesn't currently support scaled blit on background thread."); Logger.Warning?.PrintMsg(LogClass.Gpu, "Metal doesn't currently support scaled blit on background thread.");
@ -256,29 +256,29 @@ namespace Ryujinx.Graphics.Metal
Console.WriteLine("shit"); Console.WriteLine("shit");
} }
_pipeline.Blit(this, destination, srcRegion, dstRegion, isDepthOrStencil, linearFilter); Pipeline.Blit(this, destination, srcRegion, dstRegion, isDepthOrStencil, linearFilter);
} }
public void CopyTo(BufferRange range, int layer, int level, int stride) public void CopyTo(BufferRange range, int layer, int level, int stride)
{ {
var cbs = _pipeline.Cbs; var cbs = Pipeline.Cbs;
int outSize = Info.GetMipSize(level); int outSize = Info.GetMipSize(level);
int hostSize = GetBufferDataLength(outSize); int hostSize = GetBufferDataLength(outSize);
int offset = range.Offset; int offset = range.Offset;
var autoBuffer = _renderer.BufferManager.GetBuffer(range.Handle, true); var autoBuffer = Renderer.BufferManager.GetBuffer(range.Handle, true);
var mtlBuffer = autoBuffer.Get(cbs, range.Offset, outSize).Value; var mtlBuffer = autoBuffer.Get(cbs, range.Offset, outSize).Value;
// TODO: D32S8 conversion via temp copy holder // TODO: D32S8 conversion via temp copy holder
CopyFromOrToBuffer(cbs, mtlBuffer, _mtlTexture, hostSize, true, layer, level, 1, 1, singleSlice: true, offset: offset, stride: stride); CopyFromOrToBuffer(cbs, mtlBuffer, MtlTexture, hostSize, true, layer, level, 1, 1, singleSlice: true, offset: offset, stride: stride);
} }
public ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel) public ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel)
{ {
return new Texture(_device, _renderer, _pipeline, info, _identitySwizzleHandle, firstLayer, firstLevel); return new Texture(Device, Renderer, Pipeline, info, _identitySwizzleHandle, firstLayer, firstLevel);
} }
private int GetBufferDataLength(int size) private int GetBufferDataLength(int size)
@ -415,13 +415,13 @@ namespace Ryujinx.Graphics.Metal
public PinnedSpan<byte> GetData() public PinnedSpan<byte> GetData()
{ {
BackgroundResource resources = _renderer.BackgroundResources.Get(); BackgroundResource resources = Renderer.BackgroundResources.Get();
if (_renderer.CommandBufferPool.OwnedByCurrentThread) if (Renderer.CommandBufferPool.OwnedByCurrentThread)
{ {
_renderer.FlushAllCommands(); Renderer.FlushAllCommands();
return PinnedSpan<byte>.UnsafeFromSpan(GetData(_renderer.CommandBufferPool, resources.GetFlushBuffer())); return PinnedSpan<byte>.UnsafeFromSpan(GetData(Renderer.CommandBufferPool, resources.GetFlushBuffer()));
} }
return PinnedSpan<byte>.UnsafeFromSpan(GetData(resources.GetPool(), resources.GetFlushBuffer())); return PinnedSpan<byte>.UnsafeFromSpan(GetData(resources.GetPool(), resources.GetFlushBuffer()));
@ -429,13 +429,13 @@ namespace Ryujinx.Graphics.Metal
public PinnedSpan<byte> GetData(int layer, int level) public PinnedSpan<byte> GetData(int layer, int level)
{ {
BackgroundResource resources = _renderer.BackgroundResources.Get(); BackgroundResource resources = Renderer.BackgroundResources.Get();
if (_renderer.CommandBufferPool.OwnedByCurrentThread) if (Renderer.CommandBufferPool.OwnedByCurrentThread)
{ {
_renderer.FlushAllCommands(); Renderer.FlushAllCommands();
return PinnedSpan<byte>.UnsafeFromSpan(GetData(_renderer.CommandBufferPool, resources.GetFlushBuffer(), layer, level)); return PinnedSpan<byte>.UnsafeFromSpan(GetData(Renderer.CommandBufferPool, resources.GetFlushBuffer(), layer, level));
} }
return PinnedSpan<byte>.UnsafeFromSpan(GetData(resources.GetPool(), resources.GetFlushBuffer(), layer, level)); return PinnedSpan<byte>.UnsafeFromSpan(GetData(resources.GetPool(), resources.GetFlushBuffer(), layer, level));
@ -443,13 +443,13 @@ namespace Ryujinx.Graphics.Metal
public void SetData(IMemoryOwner<byte> data) public void SetData(IMemoryOwner<byte> data)
{ {
var blitCommandEncoder = _pipeline.GetOrCreateBlitEncoder(); var blitCommandEncoder = Pipeline.GetOrCreateBlitEncoder();
var dataSpan = data.Memory.Span; var dataSpan = data.Memory.Span;
var buffer = _renderer.BufferManager.Create(dataSpan.Length); var buffer = Renderer.BufferManager.Create(dataSpan.Length);
buffer.SetDataUnchecked(0, dataSpan); buffer.SetDataUnchecked(0, dataSpan);
var mtlBuffer = buffer.GetBuffer(false).Get(_pipeline.Cbs).Value; var mtlBuffer = buffer.GetBuffer(false).Get(Pipeline.Cbs).Value;
int width = Info.Width; int width = Info.Width;
int height = Info.Height; int height = Info.Height;
@ -478,7 +478,7 @@ namespace Ryujinx.Graphics.Metal
(ulong)Info.GetMipStride(level), (ulong)Info.GetMipStride(level),
(ulong)mipSize, (ulong)mipSize,
new MTLSize { width = (ulong)width, height = (ulong)height, depth = is3D ? (ulong)depth : 1 }, new MTLSize { width = (ulong)width, height = (ulong)height, depth = is3D ? (ulong)depth : 1 },
_mtlTexture, MtlTexture,
(ulong)layer, (ulong)layer,
(ulong)level, (ulong)level,
new MTLOrigin() new MTLOrigin()
@ -504,11 +504,11 @@ namespace Ryujinx.Graphics.Metal
{ {
int bufferDataLength = GetBufferDataLength(data.Length); int bufferDataLength = GetBufferDataLength(data.Length);
using var bufferHolder = _renderer.BufferManager.Create(bufferDataLength); using var bufferHolder = Renderer.BufferManager.Create(bufferDataLength);
// TODO: loadInline logic // TODO: loadInline logic
var cbs = _pipeline.Cbs; var cbs = Pipeline.Cbs;
CopyDataToBuffer(bufferHolder.GetDataStorage(0, bufferDataLength), data); CopyDataToBuffer(bufferHolder.GetDataStorage(0, bufferDataLength), data);
@ -527,20 +527,20 @@ namespace Ryujinx.Graphics.Metal
public void SetData(IMemoryOwner<byte> data, int layer, int level, Rectangle<int> region) public void SetData(IMemoryOwner<byte> data, int layer, int level, Rectangle<int> region)
{ {
var blitCommandEncoder = _pipeline.GetOrCreateBlitEncoder(); var blitCommandEncoder = Pipeline.GetOrCreateBlitEncoder();
ulong bytesPerRow = (ulong)Info.GetMipStride(level); ulong bytesPerRow = (ulong)Info.GetMipStride(level);
ulong bytesPerImage = 0; ulong bytesPerImage = 0;
if (_mtlTexture.TextureType == MTLTextureType.Type3D) if (MtlTexture.TextureType == MTLTextureType.Type3D)
{ {
bytesPerImage = bytesPerRow * (ulong)Info.Height; bytesPerImage = bytesPerRow * (ulong)Info.Height;
} }
var dataSpan = data.Memory.Span; var dataSpan = data.Memory.Span;
var buffer = _renderer.BufferManager.Create(dataSpan.Length); var buffer = Renderer.BufferManager.Create(dataSpan.Length);
buffer.SetDataUnchecked(0, dataSpan); buffer.SetDataUnchecked(0, dataSpan);
var mtlBuffer = buffer.GetBuffer(false).Get(_pipeline.Cbs).Value; var mtlBuffer = buffer.GetBuffer(false).Get(Pipeline.Cbs).Value;
blitCommandEncoder.CopyFromBuffer( blitCommandEncoder.CopyFromBuffer(
mtlBuffer, mtlBuffer,
@ -548,7 +548,7 @@ namespace Ryujinx.Graphics.Metal
bytesPerRow, bytesPerRow,
bytesPerImage, bytesPerImage,
new MTLSize { width = (ulong)region.Width, height = (ulong)region.Height, depth = 1 }, new MTLSize { width = (ulong)region.Width, height = (ulong)region.Height, depth = 1 },
_mtlTexture, MtlTexture,
(ulong)layer, (ulong)layer,
(ulong)level, (ulong)level,
new MTLOrigin { x = (ulong)region.X, y = (ulong)region.Y } new MTLOrigin { x = (ulong)region.X, y = (ulong)region.Y }

View file

@ -10,14 +10,13 @@ namespace Ryujinx.Graphics.Metal
{ {
private bool _disposed; private bool _disposed;
protected readonly TextureCreateInfo _info; protected readonly Pipeline Pipeline;
protected readonly Pipeline _pipeline; protected readonly MTLDevice Device;
protected readonly MTLDevice _device; protected readonly MetalRenderer Renderer;
protected readonly MetalRenderer _renderer;
protected MTLTexture _mtlTexture; protected MTLTexture MtlTexture;
public TextureCreateInfo Info => _info; public readonly TextureCreateInfo Info;
public int Width => Info.Width; public int Width => Info.Width;
public int Height => Info.Height; public int Height => Info.Height;
public int Depth => Info.Depth; public int Depth => Info.Depth;
@ -28,10 +27,10 @@ namespace Ryujinx.Graphics.Metal
public TextureBase(MTLDevice device, MetalRenderer renderer, Pipeline pipeline, TextureCreateInfo info) public TextureBase(MTLDevice device, MetalRenderer renderer, Pipeline pipeline, TextureCreateInfo info)
{ {
_device = device; Device = device;
_renderer = renderer; Renderer = renderer;
_pipeline = pipeline; Pipeline = pipeline;
_info = info; Info = info;
} }
public MTLTexture GetHandle() public MTLTexture GetHandle()
@ -41,7 +40,7 @@ namespace Ryujinx.Graphics.Metal
return new MTLTexture(IntPtr.Zero); return new MTLTexture(IntPtr.Zero);
} }
return _mtlTexture; return MtlTexture;
} }
public virtual void Release() public virtual void Release()
@ -51,9 +50,9 @@ namespace Ryujinx.Graphics.Metal
public void Dispose() public void Dispose()
{ {
if (_mtlTexture != IntPtr.Zero) if (MtlTexture != IntPtr.Zero)
{ {
_mtlTexture.Dispose(); MtlTexture.Dispose();
} }
_disposed = true; _disposed = true;
} }

View file

@ -37,23 +37,23 @@ namespace Ryujinx.Graphics.Metal
// Find the parent buffer, and try to build a texture from it. // Find the parent buffer, and try to build a texture from it.
// TODO: texture uses should register read/write usage on the assigned buffer. // TODO: texture uses should register read/write usage on the assigned buffer.
Auto<DisposableBuffer> bufferAuto = _renderer.BufferManager.GetBuffer(_bufferHandle, false); Auto<DisposableBuffer> bufferAuto = Renderer.BufferManager.GetBuffer(_bufferHandle, false);
if (_mtlTexture.NativePtr != 0) if (MtlTexture.NativePtr != 0)
{ {
_mtlTexture.Dispose(); MtlTexture.Dispose();
} }
if (bufferAuto == null) if (bufferAuto == null)
{ {
_mtlTexture = default; MtlTexture = default;
} }
else else
{ {
DisposableBuffer buffer = bufferAuto.Get(_pipeline.Cbs, _offset, _size); DisposableBuffer buffer = bufferAuto.Get(Pipeline.Cbs, _offset, _size);
_descriptor.Width = (uint)(_size / Info.BytesPerPixel); _descriptor.Width = (uint)(_size / Info.BytesPerPixel);
_mtlTexture = buffer.Value.NewTexture(_descriptor, (ulong)_offset, (ulong)_size); MtlTexture = buffer.Value.NewTexture(_descriptor, (ulong)_offset, (ulong)_size);
} }
} }
@ -79,7 +79,7 @@ namespace Ryujinx.Graphics.Metal
public PinnedSpan<byte> GetData() public PinnedSpan<byte> GetData()
{ {
return _renderer.GetBufferData(_bufferHandle, _offset, _size); return Renderer.GetBufferData(_bufferHandle, _offset, _size);
} }
public PinnedSpan<byte> GetData(int layer, int level) public PinnedSpan<byte> GetData(int layer, int level)
@ -94,7 +94,7 @@ namespace Ryujinx.Graphics.Metal
public void SetData(IMemoryOwner<byte> data) public void SetData(IMemoryOwner<byte> data)
{ {
_renderer.SetBufferData(_bufferHandle, _offset, data.Memory.Span); Renderer.SetBufferData(_bufferHandle, _offset, data.Memory.Span);
data.Dispose(); data.Dispose();
} }
@ -113,7 +113,7 @@ namespace Ryujinx.Graphics.Metal
if (_bufferHandle == buffer.Handle && if (_bufferHandle == buffer.Handle &&
_offset == buffer.Offset && _offset == buffer.Offset &&
_size == buffer.Size && _size == buffer.Size &&
_bufferCount == _renderer.BufferManager.BufferCount) _bufferCount == Renderer.BufferManager.BufferCount)
{ {
return; return;
} }
@ -121,7 +121,7 @@ namespace Ryujinx.Graphics.Metal
_bufferHandle = buffer.Handle; _bufferHandle = buffer.Handle;
_offset = buffer.Offset; _offset = buffer.Offset;
_size = buffer.Size; _size = buffer.Size;
_bufferCount = _renderer.BufferManager.BufferCount; _bufferCount = Renderer.BufferManager.BufferCount;
RebuildStorage(); RebuildStorage();
} }