Fix incorrect tessellation inputs/outputs (#3728)
* Fix incorrect tessellation inputs/outputs * Shader cache version bump
This commit is contained in:
parent
dbe43c1719
commit
9c2500de5f
16 changed files with 284 additions and 164 deletions
|
@ -382,17 +382,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
public Instruction GetAttributePerPatchElemPointer(int attr, bool isOutAttr, out AggregateType elemType)
|
||||
{
|
||||
var storageClass = isOutAttr ? StorageClass.Output : StorageClass.Input;
|
||||
var attrInfo = AttributeInfo.From(Config, attr, isOutAttr);
|
||||
var attrInfo = AttributeInfo.FromPatch(Config, attr, isOutAttr);
|
||||
|
||||
int attrOffset = attrInfo.BaseValue;
|
||||
Instruction ioVariable;
|
||||
|
||||
bool isUserAttr = attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd;
|
||||
Instruction ioVariable = isOutAttr ? OutputsPerPatch[attrOffset] : InputsPerPatch[attrOffset];
|
||||
|
||||
elemType = attrInfo.Type & AggregateType.ElementTypeMask;
|
||||
|
||||
ioVariable = isOutAttr ? OutputsPerPatch[attrOffset] : InputsPerPatch[attrOffset];
|
||||
|
||||
if ((attrInfo.Type & (AggregateType.Array | AggregateType.Vector)) == 0)
|
||||
{
|
||||
return ioVariable;
|
||||
|
@ -404,7 +400,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
public Instruction GetAttributePerPatch(AggregateType type, int attr, bool isOutAttr)
|
||||
{
|
||||
if (!AttributeInfo.Validate(Config, attr, isOutAttr: false))
|
||||
if (!AttributeInfo.ValidatePerPatch(Config, attr, isOutAttr: false))
|
||||
{
|
||||
return GetConstant(type, new AstOperand(IrOperandType.Constant, 0));
|
||||
}
|
||||
|
|
|
@ -403,7 +403,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
foreach (int attr in inputs)
|
||||
{
|
||||
if (!AttributeInfo.Validate(context.Config, attr, isOutAttr: false))
|
||||
if (!AttributeInfo.Validate(context.Config, attr, isOutAttr: false, perPatch))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -459,7 +459,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
foreach (int attr in outputs)
|
||||
{
|
||||
if (!AttributeInfo.Validate(context.Config, attr, isOutAttr: true))
|
||||
if (!AttributeInfo.Validate(context.Config, attr, isOutAttr: true, perPatch))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -519,7 +519,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
? (isOutAttr ? context.OutputsPerPatch : context.InputsPerPatch)
|
||||
: (isOutAttr ? context.Outputs : context.Inputs);
|
||||
|
||||
var attrInfo = AttributeInfo.From(context.Config, attr, isOutAttr);
|
||||
var attrInfo = perPatch
|
||||
? AttributeInfo.FromPatch(context.Config, attr, isOutAttr)
|
||||
: AttributeInfo.From(context.Config, attr, isOutAttr);
|
||||
|
||||
if (dict.ContainsKey(attrInfo.BaseValue))
|
||||
{
|
||||
|
@ -544,11 +546,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
var spvType = context.TypePointer(storageClass, attrType);
|
||||
var spvVar = context.Variable(spvType, storageClass);
|
||||
|
||||
if (perPatch)
|
||||
{
|
||||
context.Decorate(spvVar, Decoration.Patch);
|
||||
}
|
||||
|
||||
if (builtInPassthrough)
|
||||
{
|
||||
context.Decorate(spvVar, Decoration.PassthroughNV);
|
||||
|
@ -556,6 +553,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
|
||||
if (attrInfo.IsBuiltin)
|
||||
{
|
||||
if (perPatch)
|
||||
{
|
||||
context.Decorate(spvVar, Decoration.Patch);
|
||||
}
|
||||
|
||||
context.Decorate(spvVar, Decoration.BuiltIn, (LiteralInteger)GetBuiltIn(context, attrInfo.BaseValue));
|
||||
|
||||
if (context.Config.TransformFeedbackEnabled && context.Config.LastInVertexPipeline && isOutAttr)
|
||||
|
@ -569,6 +571,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (perPatch)
|
||||
{
|
||||
context.Decorate(spvVar, Decoration.Patch);
|
||||
|
||||
int location = context.Config.GetPerPatchAttributeLocation((attr - AttributeConsts.UserAttributePerPatchBase) / 16);
|
||||
|
||||
context.Decorate(spvVar, Decoration.Location, (LiteralInteger)location);
|
||||
}
|
||||
else if (isUserAttr)
|
||||
{
|
||||
int location = (attr - AttributeConsts.UserAttributeBase) / 16;
|
||||
|
|
|
@ -882,7 +882,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
if (src2 is AstOperand operand && operand.Type == OperandType.Constant)
|
||||
{
|
||||
int attrOffset = (baseAttr.Value & AttributeConsts.Mask) + (operand.Value << 2);
|
||||
return new OperationResult(resultType, context.GetAttribute(resultType, attrOffset, isOutAttr: false, index));
|
||||
bool isOutAttr = (baseAttr.Value & AttributeConsts.LoadOutputMask) != 0;
|
||||
return new OperationResult(resultType, context.GetAttribute(resultType, attrOffset, isOutAttr, index));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -191,7 +191,15 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
break;
|
||||
}
|
||||
|
||||
if (context.Config.GpuAccessor.QueryTessCw())
|
||||
bool tessCw = context.Config.GpuAccessor.QueryTessCw();
|
||||
|
||||
if (context.Config.Options.TargetApi == TargetApi.Vulkan)
|
||||
{
|
||||
// We invert the front face on Vulkan backend, so we need to do that here aswell.
|
||||
tessCw = !tessCw;
|
||||
}
|
||||
|
||||
if (tessCw)
|
||||
{
|
||||
context.AddExecutionMode(spvFunc, ExecutionMode.VertexOrderCw);
|
||||
}
|
||||
|
@ -375,9 +383,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
}
|
||||
else if (dest.Type == OperandType.Attribute || dest.Type == OperandType.AttributePerPatch)
|
||||
{
|
||||
if (AttributeInfo.Validate(context.Config, dest.Value, isOutAttr: true))
|
||||
bool perPatch = dest.Type == OperandType.AttributePerPatch;
|
||||
|
||||
if (AttributeInfo.Validate(context.Config, dest.Value, isOutAttr: true, perPatch))
|
||||
{
|
||||
bool perPatch = dest.Type == OperandType.AttributePerPatch;
|
||||
AggregateType elemType;
|
||||
|
||||
var elemPointer = perPatch
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue