mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-05-23 13:02:08 +00:00
Fix NRE in Vulkan TextureArray/ImageArray for buffer-targeted arrays
When isBuffer=true the array allocates _bufferTextureRefs and leaves _textureRefs null. SetSamplers and QueueWriteToReadBarriers dereferenced _textureRefs unconditionally, and the TextureView branch of SetTextures and SetImages did the same when a non-buffer view landed in a buffer-targeted array. Reached in practice when shaders sample from texel-buffer-typed array bindings with mixed contents. Branch SetTextures and SetImages on _isBuffer first, then on input type. A TextureView in a buffer-mode array, and a TextureBuffer in a non-buffer-mode array, are both dropped to null. The latter was a pre-existing mirror bug, unreached by current callers. Early-return from SetSamplers and QueueWriteToReadBarriers for buffer-mode arrays: texel-buffer descriptors carry no sampler state and storage barriers do not apply.
This commit is contained in:
parent
81468c1d25
commit
e2952ee6db
2 changed files with 49 additions and 34 deletions
|
|
@ -53,27 +53,27 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
public void SetImages(int index, ITexture[] images)
|
||||
{
|
||||
for (int i = 0; i < images.Length; i++)
|
||||
if (_isBuffer)
|
||||
{
|
||||
ITexture image = images[i];
|
||||
|
||||
if (image is TextureBuffer textureBuffer)
|
||||
for (int i = 0; i < images.Length; i++)
|
||||
{
|
||||
_bufferTextureRefs[index + i] = textureBuffer;
|
||||
_bufferTextureRefs[index + i] = images[i] as TextureBuffer;
|
||||
}
|
||||
else if (image is TextureView view)
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < images.Length; i++)
|
||||
{
|
||||
_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;
|
||||
if (images[i] is TextureView view)
|
||||
{
|
||||
_textureRefs[index + i].Storage = view.Storage;
|
||||
_textureRefs[index + i].View = view;
|
||||
}
|
||||
else
|
||||
{
|
||||
_textureRefs[index + i].Storage = null;
|
||||
_textureRefs[index + i].View = default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -89,6 +89,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
public void QueueWriteToReadBarriers(CommandBufferScoped cbs, PipelineStageFlags stageFlags)
|
||||
{
|
||||
if (_isBuffer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HashSet<TextureStorage> storages = _storages;
|
||||
|
||||
if (storages == null)
|
||||
|
|
|
|||
|
|
@ -54,6 +54,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
public void SetSamplers(int index, ISampler[] samplers)
|
||||
{
|
||||
if (_isBuffer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < samplers.Length; i++)
|
||||
{
|
||||
ISampler sampler = samplers[i];
|
||||
|
|
@ -73,27 +78,27 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
public void SetTextures(int index, ITexture[] textures)
|
||||
{
|
||||
for (int i = 0; i < textures.Length; i++)
|
||||
if (_isBuffer)
|
||||
{
|
||||
ITexture texture = textures[i];
|
||||
|
||||
if (texture is TextureBuffer textureBuffer)
|
||||
for (int i = 0; i < textures.Length; i++)
|
||||
{
|
||||
_bufferTextureRefs[index + i] = textureBuffer;
|
||||
_bufferTextureRefs[index + i] = textures[i] as TextureBuffer;
|
||||
}
|
||||
else if (texture is TextureView view)
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < textures.Length; i++)
|
||||
{
|
||||
_textureRefs[index + i].Storage = view.Storage;
|
||||
_textureRefs[index + i].View = view.GetImageView();
|
||||
}
|
||||
else if (!_isBuffer)
|
||||
{
|
||||
_textureRefs[index + i].Storage = null;
|
||||
_textureRefs[index + i].View = default;
|
||||
}
|
||||
else
|
||||
{
|
||||
_bufferTextureRefs[index + i] = null;
|
||||
if (textures[i] is TextureView view)
|
||||
{
|
||||
_textureRefs[index + i].Storage = view.Storage;
|
||||
_textureRefs[index + i].View = view.GetImageView();
|
||||
}
|
||||
else
|
||||
{
|
||||
_textureRefs[index + i].Storage = null;
|
||||
_textureRefs[index + i].View = default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,6 +114,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
|
||||
public void QueueWriteToReadBarriers(CommandBufferScoped cbs, PipelineStageFlags stageFlags)
|
||||
{
|
||||
if (_isBuffer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HashSet<TextureStorage> storages = _storages;
|
||||
|
||||
if (storages == null)
|
||||
|
|
|
|||
Loading…
Reference in a new issue