| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- using Ryujinx.Graphics.GAL;
- using Silk.NET.Vulkan;
- using System;
- using System.Collections.Generic;
- namespace Ryujinx.Graphics.Vulkan
- {
- class ImageArray : IImageArray
- {
- private readonly VulkanRenderer _gd;
- private record struct TextureRef
- {
- public TextureStorage Storage;
- public TextureView View;
- public GAL.Format ImageFormat;
- }
- private readonly TextureRef[] _textureRefs;
- private readonly TextureBuffer[] _bufferTextureRefs;
- private readonly DescriptorImageInfo[] _textures;
- private readonly BufferView[] _bufferTextures;
- private HashSet<TextureStorage> _storages;
- private int _cachedCommandBufferIndex;
- private int _cachedSubmissionCount;
- private readonly bool _isBuffer;
- public bool Bound;
- public ImageArray(VulkanRenderer gd, int size, bool isBuffer)
- {
- _gd = gd;
- if (isBuffer)
- {
- _bufferTextureRefs = new TextureBuffer[size];
- _bufferTextures = new BufferView[size];
- }
- else
- {
- _textureRefs = new TextureRef[size];
- _textures = new DescriptorImageInfo[size];
- }
- _storages = null;
- _cachedCommandBufferIndex = -1;
- _cachedSubmissionCount = 0;
- _isBuffer = isBuffer;
- }
- public void SetFormats(int index, GAL.Format[] imageFormats)
- {
- for (int i = 0; i < imageFormats.Length; i++)
- {
- _textureRefs[index + i].ImageFormat = imageFormats[i];
- }
- SetDirty();
- }
- public void SetImages(int index, ITexture[] images)
- {
- for (int i = 0; i < images.Length; i++)
- {
- ITexture image = images[i];
- if (image is TextureBuffer textureBuffer)
- {
- _bufferTextureRefs[index + i] = textureBuffer;
- }
- else if (image is TextureView view)
- {
- _textureRefs[index + i].Storage = view.Storage;
- _textureRefs[index + i].View = view;
- }
- else if (!_isBuffer)
- {
- _textureRefs[index + i].Storage = null;
- _textureRefs[index + i].View = default;
- }
- else
- {
- _bufferTextureRefs[index + i] = null;
- }
- }
- SetDirty();
- }
- private void SetDirty()
- {
- _cachedCommandBufferIndex = -1;
- _storages = null;
- _gd.PipelineInternal.ForceImageDirty();
- }
- public void QueueWriteToReadBarriers(CommandBufferScoped cbs, PipelineStageFlags stageFlags)
- {
- HashSet<TextureStorage> storages = _storages;
- if (storages == null)
- {
- storages = new HashSet<TextureStorage>();
- for (int index = 0; index < _textureRefs.Length; index++)
- {
- if (_textureRefs[index].Storage != null)
- {
- storages.Add(_textureRefs[index].Storage);
- }
- }
- _storages = storages;
- }
- foreach (TextureStorage storage in storages)
- {
- storage.QueueWriteToReadBarrier(cbs, AccessFlags.ShaderReadBit, stageFlags);
- }
- }
- public ReadOnlySpan<DescriptorImageInfo> GetImageInfos(VulkanRenderer gd, CommandBufferScoped cbs, TextureView dummyTexture)
- {
- int submissionCount = gd.CommandBufferPool.GetSubmissionCount(cbs.CommandBufferIndex);
- Span<DescriptorImageInfo> textures = _textures;
- if (cbs.CommandBufferIndex == _cachedCommandBufferIndex && submissionCount == _cachedSubmissionCount)
- {
- return textures;
- }
- _cachedCommandBufferIndex = cbs.CommandBufferIndex;
- _cachedSubmissionCount = submissionCount;
- for (int i = 0; i < textures.Length; i++)
- {
- ref var texture = ref textures[i];
- ref var refs = ref _textureRefs[i];
- if (i > 0 && _textureRefs[i - 1].View == refs.View && _textureRefs[i - 1].ImageFormat == refs.ImageFormat)
- {
- texture = textures[i - 1];
- continue;
- }
- texture.ImageLayout = ImageLayout.General;
- texture.ImageView = refs.View?.GetView(refs.ImageFormat).GetIdentityImageView().Get(cbs).Value ?? default;
- if (texture.ImageView.Handle == 0)
- {
- texture.ImageView = dummyTexture.GetImageView().Get(cbs).Value;
- }
- }
- return textures;
- }
- public ReadOnlySpan<BufferView> GetBufferViews(CommandBufferScoped cbs)
- {
- Span<BufferView> bufferTextures = _bufferTextures;
- for (int i = 0; i < bufferTextures.Length; i++)
- {
- bufferTextures[i] = _bufferTextureRefs[i]?.GetBufferView(cbs, _textureRefs[i].ImageFormat, true) ?? default;
- }
- return bufferTextures;
- }
- }
- }
|