mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-02-19 07:43:35 +00:00
Combine non-buffer with buffer image descriptor sets
This commit is contained in:
parent
8a1bdf1f1e
commit
572759a4ac
15 changed files with 123 additions and 378 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)];
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue