SPIR-V: Fragment shader interlock support (and image coherency)

This commit is contained in:
gdk 2022-02-19 16:55:30 -03:00 committed by riperiperi
parent f51f9e90d4
commit 387333454b
3 changed files with 40 additions and 1 deletions

View file

@ -243,7 +243,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
meta.Type.HasFlag(SamplerType.Shadow),
meta.Type.HasFlag(SamplerType.Array),
meta.Type.HasFlag(SamplerType.Multisample),
2,
AccessQualifier.ReadWrite,
GetImageFormat(meta.Format));
var nameSuffix = meta.CbufSlot < 0 ?
@ -258,6 +258,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
context.Name(imageVariable, $"{GetStagePrefix(context.Config.Stage)}_img{nameSuffix}");
context.Decorate(imageVariable, Decoration.DescriptorSet, (LiteralInteger)setIndex);
context.Decorate(imageVariable, Decoration.Binding, (LiteralInteger)descriptor.Binding);
if (descriptor.Flags.HasFlag(TextureUsageFlags.ImageCoherent))
{
context.Decorate(imageVariable, Decoration.Coherent);
}
context.AddGlobalVariable(imageVariable);
}
}

View file

@ -76,6 +76,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
Add(Instruction.EmitVertex, GenerateEmitVertex);
Add(Instruction.EndPrimitive, GenerateEndPrimitive);
Add(Instruction.ExponentB2, GenerateExponentB2);
Add(Instruction.FSIBegin, GenerateFSIBegin);
Add(Instruction.FSIEnd, GenerateFSIEnd);
Add(Instruction.FindLSB, GenerateFindLSB);
Add(Instruction.FindMSBS32, GenerateFindMSBS32);
Add(Instruction.FindMSBU32, GenerateFindMSBU32);
@ -521,6 +523,26 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
return GenerateUnary(context, operation, context.Delegates.GlslExp2, null);
}
private static OperationResult GenerateFSIBegin(CodeGenContext context, AstOperation operation)
{
if (context.Config.GpuAccessor.QueryHostSupportsFragmentShaderInterlock())
{
context.BeginInvocationInterlockEXT();
}
return OperationResult.Invalid;
}
private static OperationResult GenerateFSIEnd(CodeGenContext context, AstOperation operation)
{
if (context.Config.GpuAccessor.QueryHostSupportsFragmentShaderInterlock())
{
context.EndInvocationInterlockEXT();
}
return OperationResult.Invalid;
}
private static OperationResult GenerateFindLSB(CodeGenContext context, AstOperation operation)
{
var source = context.GetU32(operation.GetSource(0));

View file

@ -61,6 +61,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
context.AddCapability(Capability.TransformFeedback);
}
if (config.Stage == ShaderStage.Fragment && context.Config.GpuAccessor.QueryHostSupportsFragmentShaderInterlock())
{
context.AddCapability(Capability.FragmentShaderPixelInterlockEXT);
context.AddExtension("SPV_EXT_fragment_shader_interlock");
}
if (config.Stage == ShaderStage.Geometry)
{
context.AddCapability(Capability.Geometry);
@ -184,6 +190,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
{
context.AddExecutionMode(spvFunc, ExecutionMode.DepthReplacing);
}
if (context.Config.GpuAccessor.QueryHostSupportsFragmentShaderInterlock())
{
context.AddExecutionMode(spvFunc, ExecutionMode.PixelInterlockOrderedEXT);
}
}
else if (context.Config.Stage == ShaderStage.Compute)
{