mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-02-22 17:10:19 +00:00
SPIR-V: Fragment shader interlock support (and image coherency)
This commit is contained in:
parent
f51f9e90d4
commit
387333454b
3 changed files with 40 additions and 1 deletions
|
@ -243,7 +243,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||||
meta.Type.HasFlag(SamplerType.Shadow),
|
meta.Type.HasFlag(SamplerType.Shadow),
|
||||||
meta.Type.HasFlag(SamplerType.Array),
|
meta.Type.HasFlag(SamplerType.Array),
|
||||||
meta.Type.HasFlag(SamplerType.Multisample),
|
meta.Type.HasFlag(SamplerType.Multisample),
|
||||||
2,
|
AccessQualifier.ReadWrite,
|
||||||
GetImageFormat(meta.Format));
|
GetImageFormat(meta.Format));
|
||||||
|
|
||||||
var nameSuffix = meta.CbufSlot < 0 ?
|
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.Name(imageVariable, $"{GetStagePrefix(context.Config.Stage)}_img{nameSuffix}");
|
||||||
context.Decorate(imageVariable, Decoration.DescriptorSet, (LiteralInteger)setIndex);
|
context.Decorate(imageVariable, Decoration.DescriptorSet, (LiteralInteger)setIndex);
|
||||||
context.Decorate(imageVariable, Decoration.Binding, (LiteralInteger)descriptor.Binding);
|
context.Decorate(imageVariable, Decoration.Binding, (LiteralInteger)descriptor.Binding);
|
||||||
|
|
||||||
|
if (descriptor.Flags.HasFlag(TextureUsageFlags.ImageCoherent))
|
||||||
|
{
|
||||||
|
context.Decorate(imageVariable, Decoration.Coherent);
|
||||||
|
}
|
||||||
|
|
||||||
context.AddGlobalVariable(imageVariable);
|
context.AddGlobalVariable(imageVariable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||||
Add(Instruction.EmitVertex, GenerateEmitVertex);
|
Add(Instruction.EmitVertex, GenerateEmitVertex);
|
||||||
Add(Instruction.EndPrimitive, GenerateEndPrimitive);
|
Add(Instruction.EndPrimitive, GenerateEndPrimitive);
|
||||||
Add(Instruction.ExponentB2, GenerateExponentB2);
|
Add(Instruction.ExponentB2, GenerateExponentB2);
|
||||||
|
Add(Instruction.FSIBegin, GenerateFSIBegin);
|
||||||
|
Add(Instruction.FSIEnd, GenerateFSIEnd);
|
||||||
Add(Instruction.FindLSB, GenerateFindLSB);
|
Add(Instruction.FindLSB, GenerateFindLSB);
|
||||||
Add(Instruction.FindMSBS32, GenerateFindMSBS32);
|
Add(Instruction.FindMSBS32, GenerateFindMSBS32);
|
||||||
Add(Instruction.FindMSBU32, GenerateFindMSBU32);
|
Add(Instruction.FindMSBU32, GenerateFindMSBU32);
|
||||||
|
@ -521,6 +523,26 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||||
return GenerateUnary(context, operation, context.Delegates.GlslExp2, null);
|
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)
|
private static OperationResult GenerateFindLSB(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
var source = context.GetU32(operation.GetSource(0));
|
var source = context.GetU32(operation.GetSource(0));
|
||||||
|
|
|
@ -61,6 +61,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||||
context.AddCapability(Capability.TransformFeedback);
|
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)
|
if (config.Stage == ShaderStage.Geometry)
|
||||||
{
|
{
|
||||||
context.AddCapability(Capability.Geometry);
|
context.AddCapability(Capability.Geometry);
|
||||||
|
@ -184,6 +190,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||||
{
|
{
|
||||||
context.AddExecutionMode(spvFunc, ExecutionMode.DepthReplacing);
|
context.AddExecutionMode(spvFunc, ExecutionMode.DepthReplacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context.Config.GpuAccessor.QueryHostSupportsFragmentShaderInterlock())
|
||||||
|
{
|
||||||
|
context.AddExecutionMode(spvFunc, ExecutionMode.PixelInterlockOrderedEXT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (context.Config.Stage == ShaderStage.Compute)
|
else if (context.Config.Stage == ShaderStage.Compute)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue