Combine non-buffer with buffer image descriptor sets

This commit is contained in:
gdk 2022-06-02 23:51:27 -03:00 committed by riperiperi
parent 8a1bdf1f1e
commit 572759a4ac
15 changed files with 123 additions and 378 deletions

View file

@ -8,23 +8,17 @@ namespace Ryujinx.Graphics.GAL
public IReadOnlyCollection<int> StorageBufferBindings { get; } public IReadOnlyCollection<int> StorageBufferBindings { get; }
public IReadOnlyCollection<int> TextureBindings { get; } public IReadOnlyCollection<int> TextureBindings { get; }
public IReadOnlyCollection<int> ImageBindings { get; } public IReadOnlyCollection<int> ImageBindings { get; }
public IReadOnlyCollection<int> BufferTextureBindings { get; }
public IReadOnlyCollection<int> BufferImageBindings { get; }
public ShaderBindings( public ShaderBindings(
IReadOnlyCollection<int> uniformBufferBindings, IReadOnlyCollection<int> uniformBufferBindings,
IReadOnlyCollection<int> storageBufferBindings, IReadOnlyCollection<int> storageBufferBindings,
IReadOnlyCollection<int> textureBindings, IReadOnlyCollection<int> textureBindings,
IReadOnlyCollection<int> imageBindings, IReadOnlyCollection<int> imageBindings)
IReadOnlyCollection<int> bufferTextureBindings,
IReadOnlyCollection<int> bufferImageBindings)
{ {
UniformBufferBindings = uniformBufferBindings; UniformBufferBindings = uniformBufferBindings;
StorageBufferBindings = storageBufferBindings; StorageBufferBindings = storageBufferBindings;
TextureBindings = textureBindings; TextureBindings = textureBindings;
ImageBindings = imageBindings; ImageBindings = imageBindings;
BufferTextureBindings = bufferTextureBindings;
BufferImageBindings = bufferImageBindings;
} }
} }
} }

View file

@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
private const ushort FileFormatVersionMajor = 1; private const ushort FileFormatVersionMajor = 1;
private const ushort FileFormatVersionMinor = 2; private const ushort FileFormatVersionMinor = 2;
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor; private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
private const uint CodeGenVersion = 8; private const uint CodeGenVersion = 9;
private const string SharedTocFileName = "shared.toc"; private const string SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data"; private const string SharedDataFileName = "shared.data";

View file

@ -54,11 +54,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
} }
/// <inheritdoc/> /// <inheritdoc/>
public int QueryBindingTexture(int index) public int QueryBindingTexture(int index, bool isBuffer)
{ {
if (_context.Capabilities.Api == TargetApi.Vulkan) if (_context.Capabilities.Api == TargetApi.Vulkan)
{ {
return GetBindingFromIndex(index, _context.Capabilities.MaximumTexturesPerStage, "Texture"); if (isBuffer)
{
index += (int)_context.Capabilities.MaximumTexturesPerStage;
}
return GetBindingFromIndex(index, _context.Capabilities.MaximumTexturesPerStage * 2, "Texture");
} }
else else
{ {
@ -67,11 +72,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
} }
/// <inheritdoc/> /// <inheritdoc/>
public int QueryBindingImage(int index) public int QueryBindingImage(int index, bool isBuffer)
{ {
if (_context.Capabilities.Api == TargetApi.Vulkan) if (_context.Capabilities.Api == TargetApi.Vulkan)
{ {
return GetBindingFromIndex(index, _context.Capabilities.MaximumImagesPerStage, "Image"); if (isBuffer)
{
index += (int)_context.Capabilities.MaximumImagesPerStage;
}
return GetBindingFromIndex(index, _context.Capabilities.MaximumImagesPerStage * 2, "Image");
} }
else else
{ {

View file

@ -661,30 +661,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
public static ShaderBindings GetBindings(ShaderProgramInfo info) public static ShaderBindings GetBindings(ShaderProgramInfo info)
{ {
static bool IsBuffer(Graphics.Shader.TextureDescriptor descriptor)
{
return (descriptor.Type & SamplerType.Mask) == SamplerType.TextureBuffer;
}
static bool IsNotBuffer(Graphics.Shader.TextureDescriptor descriptor)
{
return !IsBuffer(descriptor);
}
var uniformBufferBindings = info.CBuffers.Select(x => x.Binding).ToArray(); var uniformBufferBindings = info.CBuffers.Select(x => x.Binding).ToArray();
var storageBufferBindings = info.SBuffers.Select(x => x.Binding).ToArray(); var storageBufferBindings = info.SBuffers.Select(x => x.Binding).ToArray();
var textureBindings = info.Textures.Where(IsNotBuffer).Select(x => x.Binding).ToArray(); var textureBindings = info.Textures.Select(x => x.Binding).ToArray();
var imageBindings = info.Images.Where(IsNotBuffer).Select(x => x.Binding).ToArray(); var imageBindings = info.Images.Select(x => x.Binding).ToArray();
var bufferTextureBindings = info.Textures.Where(IsBuffer).Select(x => x.Binding).ToArray();
var bufferImageBindings = info.Images.Where(IsBuffer).Select(x => x.Binding).ToArray();
return new ShaderBindings( return new ShaderBindings(
uniformBufferBindings, uniformBufferBindings,
storageBufferBindings, storageBufferBindings,
textureBindings, textureBindings,
imageBindings, imageBindings);
bufferTextureBindings,
bufferImageBindings);
} }
private static TranslationOptions CreateTranslationOptions(TargetApi api, TranslationFlags flags) private static TranslationOptions CreateTranslationOptions(TargetApi api, TranslationFlags flags)

View file

@ -458,10 +458,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
if (context.Config.Options.TargetApi == TargetApi.Vulkan) if (context.Config.Options.TargetApi == TargetApi.Vulkan)
{ {
bool isBuffer = (descriptor.Type & SamplerType.Mask) == SamplerType.TextureBuffer; layout = ", set = 2";
int setIndex = isBuffer ? 4 : 2;
layout = $", set = {setIndex}";
} }
context.AppendLine($"layout (binding = {descriptor.Binding}{layout}) uniform {samplerTypeName} {samplerName};"); context.AppendLine($"layout (binding = {descriptor.Binding}{layout}) uniform {samplerTypeName} {samplerName};");
@ -511,10 +508,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
if (context.Config.Options.TargetApi == TargetApi.Vulkan) if (context.Config.Options.TargetApi == TargetApi.Vulkan)
{ {
bool isBuffer = (descriptor.Type & SamplerType.Mask) == SamplerType.TextureBuffer; layout = $", set = 3{layout}";
int setIndex = isBuffer ? 5 : 3;
layout = $", set = {setIndex}{layout}";
} }
context.AppendLine($"layout (binding = {descriptor.Binding}{layout}) uniform {imageTypeName} {imageName};"); context.AppendLine($"layout (binding = {descriptor.Binding}{layout}) uniform {imageTypeName} {imageName};");

View file

@ -252,8 +252,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
continue; continue;
} }
bool isBuffer = (descriptor.Type & SamplerType.Mask) == SamplerType.TextureBuffer; int setIndex = context.Config.Options.TargetApi == TargetApi.Vulkan ? 2 : 0;
int setIndex = context.Config.Options.TargetApi == TargetApi.Vulkan ? (isBuffer ? 4 : 2) : 0;
var dim = (descriptor.Type & SamplerType.Mask) switch var dim = (descriptor.Type & SamplerType.Mask) switch
{ {
@ -301,8 +300,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
continue; continue;
} }
bool isBuffer = (descriptor.Type & SamplerType.Mask) == SamplerType.TextureBuffer; int setIndex = context.Config.Options.TargetApi == TargetApi.Vulkan ? 3 : 0;
int setIndex = context.Config.Options.TargetApi == TargetApi.Vulkan ? (isBuffer ? 5 : 3) : 0;
var dim = GetDim(descriptor.Type); var dim = GetDim(descriptor.Type);

View file

@ -73,8 +73,9 @@ namespace Ryujinx.Graphics.Shader
/// Queries the binding number of a texture. /// Queries the binding number of a texture.
/// </summary> /// </summary>
/// <param name="index">Texture index</param> /// <param name="index">Texture index</param>
/// <param name="isBuffer">Indicates if the texture is a buffer texture</param>
/// <returns>Binding number</returns> /// <returns>Binding number</returns>
int QueryBindingTexture(int index) int QueryBindingTexture(int index, bool isBuffer)
{ {
return index; return index;
} }
@ -83,8 +84,9 @@ namespace Ryujinx.Graphics.Shader
/// Queries the binding number of an image. /// Queries the binding number of an image.
/// </summary> /// </summary>
/// <param name="index">Image index</param> /// <param name="index">Image index</param>
/// <param name="isBuffer">Indicates if the image is a buffer image</param>
/// <returns>Binding number</returns> /// <returns>Binding number</returns>
int QueryBindingImage(int index) int QueryBindingImage(int index, bool isBuffer)
{ {
return index; return index;
} }

View file

@ -589,7 +589,7 @@ namespace Ryujinx.Graphics.Shader.Translation
return _cachedImageDescriptors ??= GetTextureOrImageDescriptors(_usedImages, GpuAccessor.QueryBindingImage); return _cachedImageDescriptors ??= GetTextureOrImageDescriptors(_usedImages, GpuAccessor.QueryBindingImage);
} }
private static TextureDescriptor[] GetTextureOrImageDescriptors(Dictionary<TextureInfo, TextureMeta> dict, Func<int, int> getBindingCallback) private static TextureDescriptor[] GetTextureOrImageDescriptors(Dictionary<TextureInfo, TextureMeta> dict, Func<int, bool, int> getBindingCallback)
{ {
var descriptors = new TextureDescriptor[dict.Count]; var descriptors = new TextureDescriptor[dict.Count];
@ -599,7 +599,8 @@ namespace Ryujinx.Graphics.Shader.Translation
var info = kv.Key; var info = kv.Key;
var meta = kv.Value; var meta = kv.Value;
int binding = getBindingCallback(i); bool isBuffer = (meta.Type & SamplerType.Mask) == SamplerType.TextureBuffer;
int binding = getBindingCallback(i, isBuffer);
descriptors[i] = new TextureDescriptor(binding, meta.Type, info.Format, info.CbufSlot, info.Handle); descriptors[i] = new TextureDescriptor(binding, meta.Type, info.Format, info.CbufSlot, info.Handle);
descriptors[i].SetFlag(meta.UsageFlags); descriptors[i].SetFlag(meta.UsageFlags);

View file

@ -38,9 +38,7 @@ namespace Ryujinx.Graphics.Vulkan
Storage = 1 << 1, Storage = 1 << 1,
Texture = 1 << 2, Texture = 1 << 2,
Image = 1 << 3, Image = 1 << 3,
BufferTexture = 1 << 4, All = Uniform | Storage | Texture | Image
BufferImage = 1 << 5,
All = Uniform | Storage | Texture | Image | BufferTexture | BufferImage
} }
private DirtyFlags _dirty; private DirtyFlags _dirty;
@ -56,9 +54,9 @@ namespace Ryujinx.Graphics.Vulkan
_uniformBuffers = Array.Empty<DescriptorBufferInfo>(); _uniformBuffers = Array.Empty<DescriptorBufferInfo>();
_storageBuffers = Array.Empty<DescriptorBufferInfo>(); _storageBuffers = Array.Empty<DescriptorBufferInfo>();
_textures = new DescriptorImageInfo[32 * 5]; _textures = new DescriptorImageInfo[Constants.MaxTexturesPerStage * Constants.MaxShaderStages];
_textureRefs = new Auto<DisposableImageView>[32 * 5]; _textureRefs = new Auto<DisposableImageView>[Constants.MaxTexturesPerStage * Constants.MaxShaderStages];
_samplerRefs = new Auto<DisposableSampler>[32 * 5]; _samplerRefs = new Auto<DisposableSampler>[Constants.MaxTexturesPerStage * Constants.MaxShaderStages];
_images = Array.Empty<DescriptorImageInfo>(); _images = Array.Empty<DescriptorImageInfo>();
_bufferTextures = Array.Empty<BufferView>(); _bufferTextures = Array.Empty<BufferView>();
_bufferImages = Array.Empty<BufferView>(); _bufferImages = Array.Empty<BufferView>();
@ -131,8 +129,6 @@ namespace Ryujinx.Graphics.Vulkan
_bufferImageRefs[binding] = imageBuffer; _bufferImageRefs[binding] = imageBuffer;
_bufferImageFormats[binding] = imageFormat; _bufferImageFormats[binding] = imageFormat;
SignalDirty(DirtyFlags.BufferImage);
} }
else else
{ {
@ -150,9 +146,9 @@ namespace Ryujinx.Graphics.Vulkan
ImageLayout = ImageLayout.General ImageLayout = ImageLayout.General
}; };
} }
SignalDirty(DirtyFlags.Image);
} }
SignalDirty(DirtyFlags.Image);
} }
public void SetStorageBuffers(CommandBuffer commandBuffer, int first, ReadOnlySpan<BufferRange> buffers) public void SetStorageBuffers(CommandBuffer commandBuffer, int first, ReadOnlySpan<BufferRange> buffers)
@ -195,8 +191,6 @@ namespace Ryujinx.Graphics.Vulkan
} }
_bufferTextureRefs[binding] = textureBuffer; _bufferTextureRefs[binding] = textureBuffer;
SignalDirty(DirtyFlags.BufferTexture);
} }
else else
{ {
@ -218,9 +212,9 @@ namespace Ryujinx.Graphics.Vulkan
{ {
ImageLayout = ImageLayout.General ImageLayout = ImageLayout.General
}; };
SignalDirty(DirtyFlags.Texture);
} }
SignalDirty(DirtyFlags.Texture);
} }
public void SetUniformBuffers(CommandBuffer commandBuffer, int first, ReadOnlySpan<BufferRange> buffers) public void SetUniformBuffers(CommandBuffer commandBuffer, int first, ReadOnlySpan<BufferRange> buffers)
@ -281,16 +275,6 @@ namespace Ryujinx.Graphics.Vulkan
UpdateAndBind(cbs, PipelineBase.ImageSetIndex, DirtyFlags.Image, pbp); UpdateAndBind(cbs, PipelineBase.ImageSetIndex, DirtyFlags.Image, pbp);
} }
if (_dirty.HasFlag(DirtyFlags.BufferTexture))
{
UpdateAndBind(cbs, PipelineBase.BufferTextureSetIndex, DirtyFlags.BufferTexture, pbp);
}
if (_dirty.HasFlag(DirtyFlags.BufferImage))
{
UpdateAndBind(cbs, PipelineBase.BufferImageSetIndex, DirtyFlags.BufferImage, pbp);
}
_dirty = DirtyFlags.None; _dirty = DirtyFlags.None;
} }
@ -396,78 +380,84 @@ namespace Ryujinx.Graphics.Vulkan
} }
else if (setIndex == PipelineBase.TextureSetIndex) else if (setIndex == PipelineBase.TextureSetIndex)
{ {
for (int i = 0; i < count; i++) if ((binding % (Constants.MaxTexturesPerStage * 2)) < Constants.MaxTexturesPerStage)
{ {
ref var texture = ref _textures[binding + i]; for (int i = 0; i < count; i++)
texture.ImageView = _textureRefs[binding + i]?.Get(cbs).Value ?? default;
texture.Sampler = _samplerRefs[binding + i]?.Get(cbs).Value ?? default;
texture.ImageLayout = ImageLayout.General;
if (texture.ImageView.Handle == 0)
{ {
texture.ImageView = _dummyTexture.GetImageView().Get(cbs).Value; ref var texture = ref _textures[binding + i];
texture.ImageView = _textureRefs[binding + i]?.Get(cbs).Value ?? default;
texture.Sampler = _samplerRefs[binding + i]?.Get(cbs).Value ?? default;
texture.ImageLayout = ImageLayout.General;
if (texture.ImageView.Handle == 0)
{
texture.ImageView = _dummyTexture.GetImageView().Get(cbs).Value;
}
if (texture.Sampler.Handle == 0)
{
texture.Sampler = _dummySampler.GetSampler().Get(cbs).Value;
}
} }
if (texture.Sampler.Handle == 0) ReadOnlySpan<DescriptorImageInfo> textures = _textures;
{ dsc.UpdateImages(0, binding, textures.Slice(binding, count), DescriptorType.CombinedImageSampler);
texture.Sampler = _dummySampler.GetSampler().Get(cbs).Value;
}
} }
else
{
count = Math.Min(count, _bufferTextures.Length - binding);
ReadOnlySpan<DescriptorImageInfo> textures = _textures; if (count <= 0)
dsc.UpdateImages(0, binding, textures.Slice(binding, count), DescriptorType.CombinedImageSampler); {
break;
}
for (int i = 0; i < count; i++)
{
_bufferTextures[binding + i] = _bufferTextureRefs[binding + i]?.GetBufferView(cbs) ?? default;
}
ReadOnlySpan<BufferView> bufferTextures = _bufferTextures;
dsc.UpdateBufferImages(0, binding, bufferTextures.Slice(binding, count), DescriptorType.UniformTexelBuffer);
}
} }
else if (setIndex == PipelineBase.ImageSetIndex) else if (setIndex == PipelineBase.ImageSetIndex)
{ {
count = Math.Min(count, _images.Length - binding); if ((binding % (Constants.MaxImagesPerStage * 2)) < Constants.MaxImagesPerStage)
if (count <= 0)
{ {
break; count = Math.Min(count, _images.Length - binding);
}
for (int i = 0; i < count; i++) if (count <= 0)
{
break;
}
for (int i = 0; i < count; i++)
{
_images[binding + i].ImageView = _imageRefs[binding + i]?.Get(cbs).Value ?? default;
}
ReadOnlySpan<DescriptorImageInfo> images = _images;
dsc.UpdateImages(0, binding, images.Slice(binding, count), DescriptorType.StorageImage);
}
else
{ {
_images[binding + i].ImageView = _imageRefs[binding + i]?.Get(cbs).Value ?? default; count = Math.Min(count, _bufferImages.Length - binding);
if (count <= 0)
{
break;
}
for (int i = 0; i < count; i++)
{
_bufferImages[binding + i] = _bufferImageRefs[binding + i]?.GetBufferView(cbs, _bufferImageFormats[binding + i]) ?? default;
}
ReadOnlySpan<BufferView> bufferImages = _bufferImages;
dsc.UpdateBufferImages(0, binding, bufferImages.Slice(binding, count), DescriptorType.StorageTexelBuffer);
} }
ReadOnlySpan<DescriptorImageInfo> images = _images;
dsc.UpdateImages(0, binding, images.Slice(binding, count), DescriptorType.StorageImage);
}
else if (setIndex == PipelineBase.BufferTextureSetIndex)
{
count = Math.Min(count, _bufferTextures.Length - binding);
if (count <= 0)
{
break;
}
for (int i = 0; i < count; i++)
{
_bufferTextures[binding + i] = _bufferTextureRefs[binding + i]?.GetBufferView(cbs) ?? default;
}
ReadOnlySpan<BufferView> bufferTextures = _bufferTextures;
dsc.UpdateBufferImages(0, binding, bufferTextures.Slice(binding, count), DescriptorType.UniformTexelBuffer);
}
else if (setIndex == PipelineBase.BufferImageSetIndex)
{
count = Math.Min(count, _bufferImages.Length - binding);
if (count <= 0)
{
break;
}
for (int i = 0; i < count; i++)
{
_bufferImages[binding + i] = _bufferImageRefs[binding + i]?.GetBufferView(cbs, _bufferImageFormats[binding + i]) ?? default;
}
ReadOnlySpan<BufferView> bufferImages = _bufferImages;
dsc.UpdateBufferImages(0, binding, bufferImages.Slice(binding, count), DescriptorType.StorageTexelBuffer);
} }
} }
} }

View file

@ -31,7 +31,7 @@ void main()
private const string ColorBlitFragmentShaderSource = @"#version 450 core private const string ColorBlitFragmentShaderSource = @"#version 450 core
layout (binding = 64, set = 2) uniform sampler2D tex; layout (binding = 128, set = 2) uniform sampler2D tex;
layout (location = 0) in vec2 tex_coord; layout (location = 0) in vec2 tex_coord;
layout (location = 0) out vec4 colour; layout (location = 0) out vec4 colour;
@ -43,7 +43,7 @@ void main()
private const string ColorBlitClearAlphaFragmentShaderSource = @"#version 450 core private const string ColorBlitClearAlphaFragmentShaderSource = @"#version 450 core
layout (binding = 64, set = 2) uniform sampler2D tex; layout (binding = 128, set = 2) uniform sampler2D tex;
layout (location = 0) in vec2 tex_coord; layout (location = 0) in vec2 tex_coord;
layout (location = 0) out vec4 colour; layout (location = 0) out vec4 colour;
@ -119,16 +119,12 @@ void main()
new[] { 1 }, new[] { 1 },
Array.Empty<int>(), Array.Empty<int>(),
Array.Empty<int>(), Array.Empty<int>(),
Array.Empty<int>(),
Array.Empty<int>(),
Array.Empty<int>()); Array.Empty<int>());
var fragmentBindings = new ShaderBindings( var fragmentBindings = new ShaderBindings(
Array.Empty<int>(), Array.Empty<int>(),
Array.Empty<int>(), Array.Empty<int>(),
new[] { Constants.MaxTexturesPerStage }, new[] { Constants.MaxTexturesPerStage * 2 },
Array.Empty<int>(),
Array.Empty<int>(),
Array.Empty<int>()); Array.Empty<int>());
var colorBlitVertexShader = gd.CompileShader(ShaderStage.Vertex, vertexBindings, ColorBlitVertexShaderSource); var colorBlitVertexShader = gd.CompileShader(ShaderStage.Vertex, vertexBindings, ColorBlitVertexShaderSource);
@ -139,8 +135,6 @@ void main()
_programColorBlitClearAlpha = gd.CreateProgram(new[] { colorBlitVertexShader, colorBlitClearAlphaFragmentShader }, new ShaderInfo(-1)); _programColorBlitClearAlpha = gd.CreateProgram(new[] { colorBlitVertexShader, colorBlitClearAlphaFragmentShader }, new ShaderInfo(-1));
var fragmentBindings2 = new ShaderBindings( var fragmentBindings2 = new ShaderBindings(
Array.Empty<int>(),
Array.Empty<int>(),
Array.Empty<int>(), Array.Empty<int>(),
Array.Empty<int>(), Array.Empty<int>(),
Array.Empty<int>(), Array.Empty<int>(),
@ -190,7 +184,7 @@ void main()
var sampler = linearFilter ? _samplerLinear : _samplerNearest; var sampler = linearFilter ? _samplerLinear : _samplerNearest;
_pipeline.SetTextureAndSampler(ShaderStage.Fragment, Constants.MaxTexturesPerStage, src, sampler); _pipeline.SetTextureAndSampler(ShaderStage.Fragment, Constants.MaxTexturesPerStage * 2, src, sampler);
Span<float> region = stackalloc float[RegionBufferSize / sizeof(float)]; Span<float> region = stackalloc float[RegionBufferSize / sizeof(float)];
@ -327,7 +321,7 @@ void main()
{ {
const int RegionBufferSize = 16; const int RegionBufferSize = 16;
pipeline.SetTextureAndSampler(ShaderStage.Fragment, Constants.MaxTexturesPerStage, src, srcSampler); pipeline.SetTextureAndSampler(ShaderStage.Fragment, Constants.MaxTexturesPerStage * 2, src, srcSampler);
Span<float> region = stackalloc float[RegionBufferSize / sizeof(float)]; Span<float> region = stackalloc float[RegionBufferSize / sizeof(float)];

View file

@ -7,14 +7,12 @@ namespace Ryujinx.Graphics.Vulkan
{ {
class PipelineBase : IDisposable class PipelineBase : IDisposable
{ {
public const int DescriptorSetLayouts = 6; public const int DescriptorSetLayouts = 4;
public const int UniformSetIndex = 0; public const int UniformSetIndex = 0;
public const int StorageSetIndex = 1; public const int StorageSetIndex = 1;
public const int TextureSetIndex = 2; public const int TextureSetIndex = 2;
public const int ImageSetIndex = 3; public const int ImageSetIndex = 3;
public const int BufferTextureSetIndex = 4;
public const int BufferImageSetIndex = 5;
protected readonly VulkanGraphicsDevice Gd; protected readonly VulkanGraphicsDevice Gd;
protected readonly Device Device; protected readonly Device Device;
@ -103,11 +101,6 @@ namespace Ryujinx.Graphics.Vulkan
_newState.SamplesCount = 1; _newState.SamplesCount = 1;
} }
protected virtual DescriptorSetLayout[] CreateDescriptorSetLayouts(VulkanGraphicsDevice gd, Device device, out PipelineLayout layout)
{
throw new NotSupportedException();
}
public unsafe void Barrier() public unsafe void Barrier()
{ {
MemoryBarrier memoryBarrier = new MemoryBarrier() MemoryBarrier memoryBarrier = new MemoryBarrier()

View file

@ -45,144 +45,6 @@ namespace Ryujinx.Graphics.Vulkan
_pendingQueryCopies.Clear(); _pendingQueryCopies.Clear();
} }
protected override unsafe DescriptorSetLayout[] CreateDescriptorSetLayouts(VulkanGraphicsDevice gd, Device device, out PipelineLayout layout)
{
DescriptorSetLayoutBinding* uLayoutBindings = stackalloc DescriptorSetLayoutBinding[Constants.MaxUniformBufferBindings];
DescriptorSetLayoutBinding* sLayoutBindings = stackalloc DescriptorSetLayoutBinding[Constants.MaxStorageBufferBindings];
DescriptorSetLayoutBinding* tLayoutBindings = stackalloc DescriptorSetLayoutBinding[Constants.MaxTextureBindings];
DescriptorSetLayoutBinding* iLayoutBindings = stackalloc DescriptorSetLayoutBinding[Constants.MaxImageBindings];
DescriptorSetLayoutBinding* bTLayoutBindings = stackalloc DescriptorSetLayoutBinding[Constants.MaxTextureBindings];
DescriptorSetLayoutBinding* bILayoutBindings = stackalloc DescriptorSetLayoutBinding[Constants.MaxImageBindings];
DescriptorBindingFlags* pUBindingsFlags = stackalloc DescriptorBindingFlags[Constants.MaxUniformBufferBindings];
DescriptorBindingFlags* pSBindingsFlags = stackalloc DescriptorBindingFlags[Constants.MaxStorageBufferBindings];
DescriptorBindingFlags* pTBindingsFlags = stackalloc DescriptorBindingFlags[Constants.MaxTextureBindings];
DescriptorBindingFlags* pIBindingsFlags = stackalloc DescriptorBindingFlags[Constants.MaxImageBindings];
DescriptorBindingFlags* pBTBindingsFlags = stackalloc DescriptorBindingFlags[Constants.MaxTextureBindings];
DescriptorBindingFlags* pBIBindingsFlags = stackalloc DescriptorBindingFlags[Constants.MaxImageBindings];
static DescriptorSetLayoutBindingFlagsCreateInfo CreateFlagsInfo(DescriptorBindingFlags* pBindingFlags, uint count)
{
return new DescriptorSetLayoutBindingFlagsCreateInfo()
{
SType = StructureType.DescriptorSetLayoutBindingFlagsCreateInfo,
PBindingFlags = pBindingFlags,
BindingCount = count
};
}
var uLayoutBindingFlags = CreateFlagsInfo(pUBindingsFlags, Constants.MaxUniformBufferBindings);
var sLayoutBindingFlags = CreateFlagsInfo(pSBindingsFlags, Constants.MaxStorageBufferBindings);
var tLayoutBindingFlags = CreateFlagsInfo(pTBindingsFlags, Constants.MaxTextureBindings);
var iLayoutBindingFlags = CreateFlagsInfo(pIBindingsFlags, Constants.MaxImageBindings);
var bTLayoutBindingFlags = CreateFlagsInfo(pBTBindingsFlags, Constants.MaxTextureBindings);
var bILayoutBindingFlags = CreateFlagsInfo(pBIBindingsFlags, Constants.MaxImageBindings);
for (int stage = 0; stage < Constants.MaxShaderStages; stage++)
{
var stageFlags = (ShaderStageFlags)(1 << stage);
if (stage == 0)
{
stageFlags |= ShaderStageFlags.ShaderStageComputeBit;
}
void Set(
DescriptorSetLayoutBinding* bindings,
DescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsCreateInfo,
int maxPerStage,
DescriptorType type)
{
for (int i = 0; i < maxPerStage; i++)
{
int j = stage * maxPerStage + i;
bindings[j] = new DescriptorSetLayoutBinding
{
Binding = (uint)j,
DescriptorType = type,
DescriptorCount = 1,
StageFlags = stageFlags
};
bindingFlagsCreateInfo.PBindingFlags[j] = DescriptorBindingFlags.DescriptorBindingPartiallyBoundBit;
}
}
Set(uLayoutBindings, uLayoutBindingFlags, Constants.MaxUniformBuffersPerStage, DescriptorType.UniformBuffer);
Set(sLayoutBindings, sLayoutBindingFlags, Constants.MaxStorageBuffersPerStage, DescriptorType.StorageBuffer);
Set(tLayoutBindings, tLayoutBindingFlags, Constants.MaxTexturesPerStage, DescriptorType.CombinedImageSampler);
Set(iLayoutBindings, iLayoutBindingFlags, Constants.MaxImagesPerStage, DescriptorType.StorageImage);
Set(bTLayoutBindings, bTLayoutBindingFlags, Constants.MaxTexturesPerStage, DescriptorType.UniformTexelBuffer);
Set(bILayoutBindings, bILayoutBindingFlags, Constants.MaxImagesPerStage, DescriptorType.StorageTexelBuffer);
}
DescriptorSetLayout[] layouts = new DescriptorSetLayout[DescriptorSetLayouts];
var uDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
{
SType = StructureType.DescriptorSetLayoutCreateInfo,
PBindings = uLayoutBindings,
BindingCount = Constants.MaxUniformBufferBindings
};
var sDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
{
SType = StructureType.DescriptorSetLayoutCreateInfo,
PBindings = sLayoutBindings,
BindingCount = Constants.MaxStorageBufferBindings
};
var tDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
{
SType = StructureType.DescriptorSetLayoutCreateInfo,
PBindings = tLayoutBindings,
BindingCount = Constants.MaxTextureBindings
};
var iDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
{
SType = StructureType.DescriptorSetLayoutCreateInfo,
PBindings = iLayoutBindings,
BindingCount = Constants.MaxImageBindings
};
var bTDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
{
SType = StructureType.DescriptorSetLayoutCreateInfo,
PBindings = bTLayoutBindings,
BindingCount = Constants.MaxTextureBindings
};
var bIDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
{
SType = StructureType.DescriptorSetLayoutCreateInfo,
PBindings = bILayoutBindings,
BindingCount = Constants.MaxImageBindings
};
gd.Api.CreateDescriptorSetLayout(device, uDescriptorSetLayoutCreateInfo, null, out layouts[UniformSetIndex]).ThrowOnError();
gd.Api.CreateDescriptorSetLayout(device, sDescriptorSetLayoutCreateInfo, null, out layouts[StorageSetIndex]).ThrowOnError();
gd.Api.CreateDescriptorSetLayout(device, tDescriptorSetLayoutCreateInfo, null, out layouts[TextureSetIndex]).ThrowOnError();
gd.Api.CreateDescriptorSetLayout(device, iDescriptorSetLayoutCreateInfo, null, out layouts[ImageSetIndex]).ThrowOnError();
gd.Api.CreateDescriptorSetLayout(device, bTDescriptorSetLayoutCreateInfo, null, out layouts[BufferTextureSetIndex]).ThrowOnError();
gd.Api.CreateDescriptorSetLayout(device, bIDescriptorSetLayoutCreateInfo, null, out layouts[BufferImageSetIndex]).ThrowOnError();
fixed (DescriptorSetLayout* pLayouts = layouts)
{
var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo()
{
SType = StructureType.PipelineLayoutCreateInfo,
PSetLayouts = pLayouts,
SetLayoutCount = DescriptorSetLayouts
};
gd.Api.CreatePipelineLayout(device, &pipelineLayoutCreateInfo, null, out layout).ThrowOnError();
}
return layouts;
}
public void ClearRenderTargetColor(int index, uint componentMask, ColorF color) public void ClearRenderTargetColor(int index, uint componentMask, ColorF color)
{ {
if (FramebufferParams == null) if (FramebufferParams == null)

View file

@ -9,65 +9,6 @@ namespace Ryujinx.Graphics.Vulkan
{ {
} }
protected override unsafe DescriptorSetLayout[] CreateDescriptorSetLayouts(VulkanGraphicsDevice gd, Device device, out PipelineLayout layout)
{
DescriptorSetLayoutBinding uLayoutBindings = new DescriptorSetLayoutBinding
{
Binding = 0,
DescriptorType = DescriptorType.UniformBuffer,
DescriptorCount = 1,
StageFlags = ShaderStageFlags.ShaderStageVertexBit
};
DescriptorSetLayoutBinding tLayoutBindings = new DescriptorSetLayoutBinding
{
Binding = 0,
DescriptorType = DescriptorType.CombinedImageSampler,
DescriptorCount = 1,
StageFlags = ShaderStageFlags.ShaderStageFragmentBit
};
DescriptorSetLayout[] layouts = new DescriptorSetLayout[3];
var uDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
{
SType = StructureType.DescriptorSetLayoutCreateInfo,
PBindings = &uLayoutBindings,
BindingCount = 1
};
var sDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
{
SType = StructureType.DescriptorSetLayoutCreateInfo,
BindingCount = 0
};
var tDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
{
SType = StructureType.DescriptorSetLayoutCreateInfo,
PBindings = &tLayoutBindings,
BindingCount = 1
};
gd.Api.CreateDescriptorSetLayout(device, uDescriptorSetLayoutCreateInfo, null, out layouts[0]).ThrowOnError();
gd.Api.CreateDescriptorSetLayout(device, sDescriptorSetLayoutCreateInfo, null, out layouts[1]).ThrowOnError();
gd.Api.CreateDescriptorSetLayout(device, tDescriptorSetLayoutCreateInfo, null, out layouts[2]).ThrowOnError();
fixed (DescriptorSetLayout* pLayouts = layouts)
{
var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo()
{
SType = StructureType.PipelineLayoutCreateInfo,
PSetLayouts = pLayouts,
SetLayoutCount = 3
};
gd.Api.CreatePipelineLayout(device, &pipelineLayoutCreateInfo, null, out layout).ThrowOnError();
}
return layouts;
}
public void SetRenderTarget(Auto<DisposableImageView> view, uint width, uint height, bool isDepthStencil, VkFormat format) public void SetRenderTarget(Auto<DisposableImageView> view, uint width, uint height, bool isDepthStencil, VkFormat format)
{ {
CreateFramebuffer(view, width, height, isDepthStencil, format); CreateFramebuffer(view, width, height, isDepthStencil, format);

View file

@ -10,17 +10,13 @@ namespace Ryujinx.Graphics.Vulkan
int stagesCount = BitOperations.PopCount(stages); int stagesCount = BitOperations.PopCount(stages);
int uCount = Constants.MaxUniformBuffersPerStage * stagesCount + 1; int uCount = Constants.MaxUniformBuffersPerStage * stagesCount + 1;
int tCount = Constants.MaxTexturesPerStage * stagesCount; int tCount = Constants.MaxTexturesPerStage * 2 * stagesCount;
int iCount = Constants.MaxImagesPerStage * stagesCount; int iCount = Constants.MaxImagesPerStage * 2 * stagesCount;
int bTCount = tCount;
int bICount = iCount;
DescriptorSetLayoutBinding* uLayoutBindings = stackalloc DescriptorSetLayoutBinding[uCount]; DescriptorSetLayoutBinding* uLayoutBindings = stackalloc DescriptorSetLayoutBinding[uCount];
DescriptorSetLayoutBinding* sLayoutBindings = stackalloc DescriptorSetLayoutBinding[stagesCount]; DescriptorSetLayoutBinding* sLayoutBindings = stackalloc DescriptorSetLayoutBinding[stagesCount];
DescriptorSetLayoutBinding* tLayoutBindings = stackalloc DescriptorSetLayoutBinding[tCount]; DescriptorSetLayoutBinding* tLayoutBindings = stackalloc DescriptorSetLayoutBinding[tCount];
DescriptorSetLayoutBinding* iLayoutBindings = stackalloc DescriptorSetLayoutBinding[iCount]; DescriptorSetLayoutBinding* iLayoutBindings = stackalloc DescriptorSetLayoutBinding[iCount];
DescriptorSetLayoutBinding* bTLayoutBindings = stackalloc DescriptorSetLayoutBinding[bTCount];
DescriptorSetLayoutBinding* bILayoutBindings = stackalloc DescriptorSetLayoutBinding[bICount];
uLayoutBindings[0] = new DescriptorSetLayoutBinding uLayoutBindings[0] = new DescriptorSetLayoutBinding
{ {
@ -46,13 +42,15 @@ namespace Ryujinx.Graphics.Vulkan
_ => ShaderStageFlags.ShaderStageVertexBit | ShaderStageFlags.ShaderStageComputeBit _ => ShaderStageFlags.ShaderStageVertexBit | ShaderStageFlags.ShaderStageComputeBit
}; };
void Set(DescriptorSetLayoutBinding* bindings, int maxPerStage, DescriptorType type, int start = 0) void Set(DescriptorSetLayoutBinding* bindings, int maxPerStage, DescriptorType type, int start, int skip)
{ {
int totalPerStage = maxPerStage * skip;
for (int i = 0; i < maxPerStage; i++) for (int i = 0; i < maxPerStage; i++)
{ {
bindings[start + iter * maxPerStage + i] = new DescriptorSetLayoutBinding bindings[start + iter * totalPerStage + i] = new DescriptorSetLayoutBinding
{ {
Binding = (uint)(start + stage * maxPerStage + i), Binding = (uint)(start + stage * totalPerStage + i),
DescriptorType = type, DescriptorType = type,
DescriptorCount = 1, DescriptorCount = 1,
StageFlags = stageFlags StageFlags = stageFlags
@ -71,12 +69,12 @@ namespace Ryujinx.Graphics.Vulkan
}; };
} }
Set(uLayoutBindings, Constants.MaxUniformBuffersPerStage, DescriptorType.UniformBuffer, 1); Set(uLayoutBindings, Constants.MaxUniformBuffersPerStage, DescriptorType.UniformBuffer, 1, 1);
SetStorage(sLayoutBindings, Constants.MaxStorageBuffersPerStage); SetStorage(sLayoutBindings, Constants.MaxStorageBuffersPerStage);
Set(tLayoutBindings, Constants.MaxTexturesPerStage, DescriptorType.CombinedImageSampler); Set(tLayoutBindings, Constants.MaxTexturesPerStage, DescriptorType.CombinedImageSampler, 0, 2);
Set(iLayoutBindings, Constants.MaxImagesPerStage, DescriptorType.StorageImage); Set(tLayoutBindings, Constants.MaxTexturesPerStage, DescriptorType.UniformTexelBuffer, Constants.MaxTexturesPerStage, 2);
Set(bTLayoutBindings, Constants.MaxTexturesPerStage, DescriptorType.UniformTexelBuffer); Set(iLayoutBindings, Constants.MaxImagesPerStage, DescriptorType.StorageImage, 0, 2);
Set(bILayoutBindings, Constants.MaxImagesPerStage, DescriptorType.StorageTexelBuffer); Set(iLayoutBindings, Constants.MaxImagesPerStage, DescriptorType.StorageTexelBuffer, Constants.MaxImagesPerStage, 2);
iter++; iter++;
} }
@ -111,26 +109,10 @@ namespace Ryujinx.Graphics.Vulkan
BindingCount = (uint)iCount BindingCount = (uint)iCount
}; };
var bTDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
{
SType = StructureType.DescriptorSetLayoutCreateInfo,
PBindings = bTLayoutBindings,
BindingCount = (uint)bTCount
};
var bIDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
{
SType = StructureType.DescriptorSetLayoutCreateInfo,
PBindings = bILayoutBindings,
BindingCount = (uint)bICount
};
gd.Api.CreateDescriptorSetLayout(device, uDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.UniformSetIndex]).ThrowOnError(); gd.Api.CreateDescriptorSetLayout(device, uDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.UniformSetIndex]).ThrowOnError();
gd.Api.CreateDescriptorSetLayout(device, sDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.StorageSetIndex]).ThrowOnError(); gd.Api.CreateDescriptorSetLayout(device, sDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.StorageSetIndex]).ThrowOnError();
gd.Api.CreateDescriptorSetLayout(device, tDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.TextureSetIndex]).ThrowOnError(); gd.Api.CreateDescriptorSetLayout(device, tDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.TextureSetIndex]).ThrowOnError();
gd.Api.CreateDescriptorSetLayout(device, iDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.ImageSetIndex]).ThrowOnError(); gd.Api.CreateDescriptorSetLayout(device, iDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.ImageSetIndex]).ThrowOnError();
gd.Api.CreateDescriptorSetLayout(device, bTDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.BufferTextureSetIndex]).ThrowOnError();
gd.Api.CreateDescriptorSetLayout(device, bIDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.BufferImageSetIndex]).ThrowOnError();
fixed (DescriptorSetLayout* pLayouts = layouts) fixed (DescriptorSetLayout* pLayouts = layouts)
{ {

View file

@ -110,9 +110,7 @@ namespace Ryujinx.Graphics.Vulkan
GrabAll(x => x.UniformBufferBindings), GrabAll(x => x.UniformBufferBindings),
GrabAll(x => x.StorageBufferBindings), GrabAll(x => x.StorageBufferBindings),
GrabAll(x => x.TextureBindings), GrabAll(x => x.TextureBindings),
GrabAll(x => x.ImageBindings), GrabAll(x => x.ImageBindings)
GrabAll(x => x.BufferTextureBindings),
GrabAll(x => x.BufferImageBindings)
}; };
_compileTask = Task.CompletedTask; _compileTask = Task.CompletedTask;