Add support for bindless textures from shader input (vertex buffer) on Vulkan (#6577)
* Add support for bindless textures from shader input (vertex buffer) * Shader cache version bump * Format whitespace * Remove cache entries on pool removal, disable for OpenGL * PR feedback
This commit is contained in:
parent
9b94662b4b
commit
c6f8bfed90
39 changed files with 1091 additions and 311 deletions
|
@ -6,7 +6,6 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||
{
|
||||
|
@ -352,7 +351,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
|||
arrayDecl = "[]";
|
||||
}
|
||||
|
||||
string samplerTypeName = definition.Type.ToGlslSamplerType();
|
||||
string samplerTypeName = definition.Separate ? definition.Type.ToGlslTextureType() : definition.Type.ToGlslSamplerType();
|
||||
|
||||
string layout = string.Empty;
|
||||
|
||||
|
|
|
@ -639,14 +639,27 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||
|
||||
private static string GetSamplerName(CodeGenContext context, AstTextureOperation texOp, ref int srcIndex)
|
||||
{
|
||||
TextureDefinition definition = context.Properties.Textures[texOp.Binding];
|
||||
string name = definition.Name;
|
||||
TextureDefinition textureDefinition = context.Properties.Textures[texOp.Binding];
|
||||
string name = textureDefinition.Name;
|
||||
|
||||
if (definition.ArrayLength != 1)
|
||||
if (textureDefinition.ArrayLength != 1)
|
||||
{
|
||||
name = $"{name}[{GetSourceExpr(context, texOp.GetSource(srcIndex++), AggregateType.S32)}]";
|
||||
}
|
||||
|
||||
if (texOp.IsSeparate)
|
||||
{
|
||||
TextureDefinition samplerDefinition = context.Properties.Textures[texOp.SamplerBinding];
|
||||
string samplerName = samplerDefinition.Name;
|
||||
|
||||
if (samplerDefinition.ArrayLength != 1)
|
||||
{
|
||||
samplerName = $"{samplerName}[{GetSourceExpr(context, texOp.GetSource(srcIndex++), AggregateType.S32)}]";
|
||||
}
|
||||
|
||||
name = $"{texOp.Type.ToGlslSamplerType()}({name}, {samplerName})";
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
|
|
|
@ -160,37 +160,49 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
{
|
||||
int setIndex = context.TargetApi == TargetApi.Vulkan ? sampler.Set : 0;
|
||||
|
||||
var dim = (sampler.Type & SamplerType.Mask) switch
|
||||
SpvInstruction imageType;
|
||||
SpvInstruction sampledImageType;
|
||||
|
||||
if (sampler.Type != SamplerType.None)
|
||||
{
|
||||
SamplerType.Texture1D => Dim.Dim1D,
|
||||
SamplerType.Texture2D => Dim.Dim2D,
|
||||
SamplerType.Texture3D => Dim.Dim3D,
|
||||
SamplerType.TextureCube => Dim.Cube,
|
||||
SamplerType.TextureBuffer => Dim.Buffer,
|
||||
_ => throw new InvalidOperationException($"Invalid sampler type \"{sampler.Type & SamplerType.Mask}\"."),
|
||||
};
|
||||
var dim = (sampler.Type & SamplerType.Mask) switch
|
||||
{
|
||||
SamplerType.Texture1D => Dim.Dim1D,
|
||||
SamplerType.Texture2D => Dim.Dim2D,
|
||||
SamplerType.Texture3D => Dim.Dim3D,
|
||||
SamplerType.TextureCube => Dim.Cube,
|
||||
SamplerType.TextureBuffer => Dim.Buffer,
|
||||
_ => throw new InvalidOperationException($"Invalid sampler type \"{sampler.Type & SamplerType.Mask}\"."),
|
||||
};
|
||||
|
||||
var imageType = context.TypeImage(
|
||||
context.TypeFP32(),
|
||||
dim,
|
||||
sampler.Type.HasFlag(SamplerType.Shadow),
|
||||
sampler.Type.HasFlag(SamplerType.Array),
|
||||
sampler.Type.HasFlag(SamplerType.Multisample),
|
||||
1,
|
||||
ImageFormat.Unknown);
|
||||
imageType = context.TypeImage(
|
||||
context.TypeFP32(),
|
||||
dim,
|
||||
sampler.Type.HasFlag(SamplerType.Shadow),
|
||||
sampler.Type.HasFlag(SamplerType.Array),
|
||||
sampler.Type.HasFlag(SamplerType.Multisample),
|
||||
1,
|
||||
ImageFormat.Unknown);
|
||||
|
||||
var sampledImageType = context.TypeSampledImage(imageType);
|
||||
var sampledImagePointerType = context.TypePointer(StorageClass.UniformConstant, sampledImageType);
|
||||
sampledImageType = context.TypeSampledImage(imageType);
|
||||
}
|
||||
else
|
||||
{
|
||||
imageType = sampledImageType = context.TypeSampler();
|
||||
}
|
||||
|
||||
var sampledOrSeparateImageType = sampler.Separate ? imageType : sampledImageType;
|
||||
var sampledImagePointerType = context.TypePointer(StorageClass.UniformConstant, sampledOrSeparateImageType);
|
||||
var sampledImageArrayPointerType = sampledImagePointerType;
|
||||
|
||||
if (sampler.ArrayLength == 0)
|
||||
{
|
||||
var sampledImageArrayType = context.TypeRuntimeArray(sampledImageType);
|
||||
var sampledImageArrayType = context.TypeRuntimeArray(sampledOrSeparateImageType);
|
||||
sampledImageArrayPointerType = context.TypePointer(StorageClass.UniformConstant, sampledImageArrayType);
|
||||
}
|
||||
else if (sampler.ArrayLength != 1)
|
||||
{
|
||||
var sampledImageArrayType = context.TypeArray(sampledImageType, context.Constant(context.TypeU32(), sampler.ArrayLength));
|
||||
var sampledImageArrayType = context.TypeArray(sampledOrSeparateImageType, context.Constant(context.TypeU32(), sampler.ArrayLength));
|
||||
sampledImageArrayPointerType = context.TypePointer(StorageClass.UniformConstant, sampledImageArrayType);
|
||||
}
|
||||
|
||||
|
|
|
@ -838,16 +838,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
}
|
||||
|
||||
SamplerDeclaration declaration = context.Samplers[texOp.Binding];
|
||||
SpvInstruction image = declaration.Image;
|
||||
|
||||
if (declaration.IsIndexed)
|
||||
{
|
||||
SpvInstruction textureIndex = Src(AggregateType.S32);
|
||||
|
||||
image = context.AccessChain(declaration.SampledImagePointerType, image, textureIndex);
|
||||
}
|
||||
|
||||
image = context.Load(declaration.SampledImageType, image);
|
||||
SpvInstruction image = GenerateSampledImageLoad(context, texOp, declaration, ref srcIndex);
|
||||
|
||||
int pCount = texOp.Type.GetDimensions();
|
||||
|
||||
|
@ -1171,16 +1162,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
}
|
||||
|
||||
SamplerDeclaration declaration = context.Samplers[texOp.Binding];
|
||||
SpvInstruction image = declaration.Image;
|
||||
|
||||
if (declaration.IsIndexed)
|
||||
{
|
||||
SpvInstruction textureIndex = Src(AggregateType.S32);
|
||||
|
||||
image = context.AccessChain(declaration.SampledImagePointerType, image, textureIndex);
|
||||
}
|
||||
|
||||
image = context.Load(declaration.SampledImageType, image);
|
||||
SpvInstruction image = GenerateSampledImageLoad(context, texOp, declaration, ref srcIndex);
|
||||
|
||||
int coordsCount = texOp.Type.GetDimensions();
|
||||
|
||||
|
@ -1449,17 +1431,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
{
|
||||
AstTextureOperation texOp = (AstTextureOperation)operation;
|
||||
|
||||
int srcIndex = 0;
|
||||
|
||||
SamplerDeclaration declaration = context.Samplers[texOp.Binding];
|
||||
SpvInstruction image = declaration.Image;
|
||||
SpvInstruction image = GenerateSampledImageLoad(context, texOp, declaration, ref srcIndex);
|
||||
|
||||
if (declaration.IsIndexed)
|
||||
{
|
||||
SpvInstruction textureIndex = context.GetS32(texOp.GetSource(0));
|
||||
|
||||
image = context.AccessChain(declaration.SampledImagePointerType, image, textureIndex);
|
||||
}
|
||||
|
||||
image = context.Load(declaration.SampledImageType, image);
|
||||
image = context.Image(declaration.ImageType, image);
|
||||
|
||||
SpvInstruction result = context.ImageQuerySamples(context.TypeS32(), image);
|
||||
|
@ -1471,17 +1447,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
{
|
||||
AstTextureOperation texOp = (AstTextureOperation)operation;
|
||||
|
||||
int srcIndex = 0;
|
||||
|
||||
SamplerDeclaration declaration = context.Samplers[texOp.Binding];
|
||||
SpvInstruction image = declaration.Image;
|
||||
SpvInstruction image = GenerateSampledImageLoad(context, texOp, declaration, ref srcIndex);
|
||||
|
||||
if (declaration.IsIndexed)
|
||||
{
|
||||
SpvInstruction textureIndex = context.GetS32(texOp.GetSource(0));
|
||||
|
||||
image = context.AccessChain(declaration.SampledImagePointerType, image, textureIndex);
|
||||
}
|
||||
|
||||
image = context.Load(declaration.SampledImageType, image);
|
||||
image = context.Image(declaration.ImageType, image);
|
||||
|
||||
if (texOp.Index == 3)
|
||||
|
@ -1506,8 +1476,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
if (hasLod)
|
||||
{
|
||||
int lodSrcIndex = declaration.IsIndexed ? 1 : 0;
|
||||
var lod = context.GetS32(operation.GetSource(lodSrcIndex));
|
||||
var lod = context.GetS32(operation.GetSource(srcIndex));
|
||||
result = context.ImageQuerySizeLod(resultType, image, lod);
|
||||
}
|
||||
else
|
||||
|
@ -1905,6 +1874,43 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
}
|
||||
}
|
||||
|
||||
private static SpvInstruction GenerateSampledImageLoad(CodeGenContext context, AstTextureOperation texOp, SamplerDeclaration declaration, ref int srcIndex)
|
||||
{
|
||||
SpvInstruction image = declaration.Image;
|
||||
|
||||
if (declaration.IsIndexed)
|
||||
{
|
||||
SpvInstruction textureIndex = context.Get(AggregateType.S32, texOp.GetSource(srcIndex++));
|
||||
|
||||
image = context.AccessChain(declaration.SampledImagePointerType, image, textureIndex);
|
||||
}
|
||||
|
||||
if (texOp.IsSeparate)
|
||||
{
|
||||
image = context.Load(declaration.ImageType, image);
|
||||
|
||||
SamplerDeclaration samplerDeclaration = context.Samplers[texOp.SamplerBinding];
|
||||
|
||||
SpvInstruction sampler = samplerDeclaration.Image;
|
||||
|
||||
if (samplerDeclaration.IsIndexed)
|
||||
{
|
||||
SpvInstruction samplerIndex = context.Get(AggregateType.S32, texOp.GetSource(srcIndex++));
|
||||
|
||||
sampler = context.AccessChain(samplerDeclaration.SampledImagePointerType, sampler, samplerIndex);
|
||||
}
|
||||
|
||||
sampler = context.Load(samplerDeclaration.ImageType, sampler);
|
||||
image = context.SampledImage(declaration.SampledImageType, image, sampler);
|
||||
}
|
||||
else
|
||||
{
|
||||
image = context.Load(declaration.SampledImageType, image);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
private static OperationResult GenerateUnary(
|
||||
CodeGenContext context,
|
||||
AstOperation operation,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue