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> TextureBindings { get; }
public IReadOnlyCollection<int> ImageBindings { get; }
public IReadOnlyCollection<int> BufferTextureBindings { get; }
public IReadOnlyCollection<int> BufferImageBindings { get; }
public ShaderBindings(
IReadOnlyCollection<int> uniformBufferBindings,
IReadOnlyCollection<int> storageBufferBindings,
IReadOnlyCollection<int> textureBindings,
IReadOnlyCollection<int> imageBindings,
IReadOnlyCollection<int> bufferTextureBindings,
IReadOnlyCollection<int> bufferImageBindings)
IReadOnlyCollection<int> imageBindings)
{
UniformBufferBindings = uniformBufferBindings;
StorageBufferBindings = storageBufferBindings;
TextureBindings = textureBindings;
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 FileFormatVersionMinor = 2;
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 SharedDataFileName = "shared.data";

View file

@ -54,11 +54,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
}
/// <inheritdoc/>
public int QueryBindingTexture(int index)
public int QueryBindingTexture(int index, bool isBuffer)
{
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
{
@ -67,11 +72,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
}
/// <inheritdoc/>
public int QueryBindingImage(int index)
public int QueryBindingImage(int index, bool isBuffer)
{
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
{

View file

@ -661,30 +661,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
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 storageBufferBindings = info.SBuffers.Select(x => x.Binding).ToArray();
var textureBindings = info.Textures.Where(IsNotBuffer).Select(x => x.Binding).ToArray();
var imageBindings = info.Images.Where(IsNotBuffer).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();
var textureBindings = info.Textures.Select(x => x.Binding).ToArray();
var imageBindings = info.Images.Select(x => x.Binding).ToArray();
return new ShaderBindings(
uniformBufferBindings,
storageBufferBindings,
textureBindings,
imageBindings,
bufferTextureBindings,
bufferImageBindings);
imageBindings);
}
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)
{
bool isBuffer = (descriptor.Type & SamplerType.Mask) == SamplerType.TextureBuffer;
int setIndex = isBuffer ? 4 : 2;
layout = $", set = {setIndex}";
layout = ", set = 2";
}
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)
{
bool isBuffer = (descriptor.Type & SamplerType.Mask) == SamplerType.TextureBuffer;
int setIndex = isBuffer ? 5 : 3;
layout = $", set = {setIndex}{layout}";
layout = $", set = 3{layout}";
}
context.AppendLine($"layout (binding = {descriptor.Binding}{layout}) uniform {imageTypeName} {imageName};");
@ -693,7 +687,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
private static void DeclareSupportUniformBlock(CodeGenContext context, ShaderStage stage, int scaleElements)
{
bool needsSupportBlock = stage == ShaderStage.Fragment ||
bool needsSupportBlock = stage == ShaderStage.Fragment ||
(context.Config.LastInVertexPipeline && context.Config.GpuAccessor.QueryViewportTransformDisable());
if (!needsSupportBlock && scaleElements == 0)

View file

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

View file

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

View file

@ -589,7 +589,7 @@ namespace Ryujinx.Graphics.Shader.Translation
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];
@ -599,7 +599,8 @@ namespace Ryujinx.Graphics.Shader.Translation
var info = kv.Key;
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].SetFlag(meta.UsageFlags);

View file

@ -38,9 +38,7 @@ namespace Ryujinx.Graphics.Vulkan
Storage = 1 << 1,
Texture = 1 << 2,
Image = 1 << 3,
BufferTexture = 1 << 4,
BufferImage = 1 << 5,
All = Uniform | Storage | Texture | Image | BufferTexture | BufferImage
All = Uniform | Storage | Texture | Image
}
private DirtyFlags _dirty;
@ -56,9 +54,9 @@ namespace Ryujinx.Graphics.Vulkan
_uniformBuffers = Array.Empty<DescriptorBufferInfo>();
_storageBuffers = Array.Empty<DescriptorBufferInfo>();
_textures = new DescriptorImageInfo[32 * 5];
_textureRefs = new Auto<DisposableImageView>[32 * 5];
_samplerRefs = new Auto<DisposableSampler>[32 * 5];
_textures = new DescriptorImageInfo[Constants.MaxTexturesPerStage * Constants.MaxShaderStages];
_textureRefs = new Auto<DisposableImageView>[Constants.MaxTexturesPerStage * Constants.MaxShaderStages];
_samplerRefs = new Auto<DisposableSampler>[Constants.MaxTexturesPerStage * Constants.MaxShaderStages];
_images = Array.Empty<DescriptorImageInfo>();
_bufferTextures = Array.Empty<BufferView>();
_bufferImages = Array.Empty<BufferView>();
@ -131,8 +129,6 @@ namespace Ryujinx.Graphics.Vulkan
_bufferImageRefs[binding] = imageBuffer;
_bufferImageFormats[binding] = imageFormat;
SignalDirty(DirtyFlags.BufferImage);
}
else
{
@ -150,9 +146,9 @@ namespace Ryujinx.Graphics.Vulkan
ImageLayout = ImageLayout.General
};
}
SignalDirty(DirtyFlags.Image);
}
SignalDirty(DirtyFlags.Image);
}
public void SetStorageBuffers(CommandBuffer commandBuffer, int first, ReadOnlySpan<BufferRange> buffers)
@ -195,8 +191,6 @@ namespace Ryujinx.Graphics.Vulkan
}
_bufferTextureRefs[binding] = textureBuffer;
SignalDirty(DirtyFlags.BufferTexture);
}
else
{
@ -218,9 +212,9 @@ namespace Ryujinx.Graphics.Vulkan
{
ImageLayout = ImageLayout.General
};
SignalDirty(DirtyFlags.Texture);
}
SignalDirty(DirtyFlags.Texture);
}
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);
}
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;
}
@ -396,78 +380,84 @@ namespace Ryujinx.Graphics.Vulkan
}
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];
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)
for (int i = 0; i < count; i++)
{
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)
{
texture.Sampler = _dummySampler.GetSampler().Get(cbs).Value;
}
ReadOnlySpan<DescriptorImageInfo> textures = _textures;
dsc.UpdateImages(0, binding, textures.Slice(binding, count), DescriptorType.CombinedImageSampler);
}
else
{
count = Math.Min(count, _bufferTextures.Length - binding);
ReadOnlySpan<DescriptorImageInfo> textures = _textures;
dsc.UpdateImages(0, binding, textures.Slice(binding, count), DescriptorType.CombinedImageSampler);
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.ImageSetIndex)
{
count = Math.Min(count, _images.Length - binding);
if (count <= 0)
if ((binding % (Constants.MaxImagesPerStage * 2)) < Constants.MaxImagesPerStage)
{
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
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) out vec4 colour;
@ -43,7 +43,7 @@ void main()
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) out vec4 colour;
@ -119,16 +119,12 @@ void main()
new[] { 1 },
Array.Empty<int>(),
Array.Empty<int>(),
Array.Empty<int>(),
Array.Empty<int>(),
Array.Empty<int>());
var fragmentBindings = new ShaderBindings(
Array.Empty<int>(),
Array.Empty<int>(),
new[] { Constants.MaxTexturesPerStage },
Array.Empty<int>(),
Array.Empty<int>(),
new[] { Constants.MaxTexturesPerStage * 2 },
Array.Empty<int>());
var colorBlitVertexShader = gd.CompileShader(ShaderStage.Vertex, vertexBindings, ColorBlitVertexShaderSource);
@ -139,8 +135,6 @@ void main()
_programColorBlitClearAlpha = gd.CreateProgram(new[] { colorBlitVertexShader, colorBlitClearAlphaFragmentShader }, new ShaderInfo(-1));
var fragmentBindings2 = new ShaderBindings(
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;
_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)];
@ -327,7 +321,7 @@ void main()
{
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)];

View file

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

View file

@ -45,144 +45,6 @@ namespace Ryujinx.Graphics.Vulkan
_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)
{
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)
{
CreateFramebuffer(view, width, height, isDepthStencil, format);

View file

@ -10,17 +10,13 @@ namespace Ryujinx.Graphics.Vulkan
int stagesCount = BitOperations.PopCount(stages);
int uCount = Constants.MaxUniformBuffersPerStage * stagesCount + 1;
int tCount = Constants.MaxTexturesPerStage * stagesCount;
int iCount = Constants.MaxImagesPerStage * stagesCount;
int bTCount = tCount;
int bICount = iCount;
int tCount = Constants.MaxTexturesPerStage * 2 * stagesCount;
int iCount = Constants.MaxImagesPerStage * 2 * stagesCount;
DescriptorSetLayoutBinding* uLayoutBindings = stackalloc DescriptorSetLayoutBinding[uCount];
DescriptorSetLayoutBinding* sLayoutBindings = stackalloc DescriptorSetLayoutBinding[stagesCount];
DescriptorSetLayoutBinding* tLayoutBindings = stackalloc DescriptorSetLayoutBinding[tCount];
DescriptorSetLayoutBinding* iLayoutBindings = stackalloc DescriptorSetLayoutBinding[iCount];
DescriptorSetLayoutBinding* bTLayoutBindings = stackalloc DescriptorSetLayoutBinding[bTCount];
DescriptorSetLayoutBinding* bILayoutBindings = stackalloc DescriptorSetLayoutBinding[bICount];
uLayoutBindings[0] = new DescriptorSetLayoutBinding
{
@ -46,13 +42,15 @@ namespace Ryujinx.Graphics.Vulkan
_ => 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++)
{
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,
DescriptorCount = 1,
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);
Set(tLayoutBindings, Constants.MaxTexturesPerStage, DescriptorType.CombinedImageSampler);
Set(iLayoutBindings, Constants.MaxImagesPerStage, DescriptorType.StorageImage);
Set(bTLayoutBindings, Constants.MaxTexturesPerStage, DescriptorType.UniformTexelBuffer);
Set(bILayoutBindings, Constants.MaxImagesPerStage, DescriptorType.StorageTexelBuffer);
Set(tLayoutBindings, Constants.MaxTexturesPerStage, DescriptorType.CombinedImageSampler, 0, 2);
Set(tLayoutBindings, Constants.MaxTexturesPerStage, DescriptorType.UniformTexelBuffer, Constants.MaxTexturesPerStage, 2);
Set(iLayoutBindings, Constants.MaxImagesPerStage, DescriptorType.StorageImage, 0, 2);
Set(iLayoutBindings, Constants.MaxImagesPerStage, DescriptorType.StorageTexelBuffer, Constants.MaxImagesPerStage, 2);
iter++;
}
@ -111,26 +109,10 @@ namespace Ryujinx.Graphics.Vulkan
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, sDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.StorageSetIndex]).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, bTDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.BufferTextureSetIndex]).ThrowOnError();
gd.Api.CreateDescriptorSetLayout(device, bIDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.BufferImageSetIndex]).ThrowOnError();
fixed (DescriptorSetLayout* pLayouts = layouts)
{

View file

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