Support shader gl_Color, gl_SecondaryColor and gl_TexCoord built-ins (#2817)
* Support shader gl_Color, gl_SecondaryColor and gl_TexCoord built-ins * Shader cache version bump * Fix back color value on fragment shader * Disable IPA multiplication for fixed function attributes and back color selection
This commit is contained in:
parent
3dee712164
commit
911ea38e93
8 changed files with 220 additions and 38 deletions
|
@ -42,7 +42,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
else if (op.SrcB == RegisterConsts.RegisterZeroIndex || op.P)
|
||||
{
|
||||
int offset = op.Imm11 + index * 4;
|
||||
int offset = FixedFuncToUserAttribute(context.Config, op.Imm11 + index * 4, op.O);
|
||||
|
||||
context.FlagAttributeRead(offset);
|
||||
|
||||
|
@ -57,7 +57,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
int offset = op.Imm11 + index * 4;
|
||||
int offset = FixedFuncToUserAttribute(context.Config, op.Imm11 + index * 4, op.O);
|
||||
|
||||
context.FlagAttributeRead(offset);
|
||||
|
||||
|
@ -101,6 +101,13 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
int offset = op.Imm11 + index * 4;
|
||||
|
||||
if (!context.Config.IsUsedOutputAttribute(offset))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
offset = FixedFuncToUserAttribute(context.Config, offset, isOutput: true);
|
||||
|
||||
context.FlagAttributeWritten(offset);
|
||||
|
||||
Operand dest = op.P ? AttributePerPatch(offset) : Attribute(offset);
|
||||
|
@ -118,6 +125,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
Operand res;
|
||||
|
||||
bool isFixedFunc = false;
|
||||
|
||||
if (op.Idx)
|
||||
{
|
||||
Operand userAttrOffset = context.ISubtract(GetSrcReg(context, op.SrcA), Const(AttributeConsts.UserAttributeBase));
|
||||
|
@ -130,7 +139,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
res = Attribute(op.Imm10);
|
||||
isFixedFunc = TryFixedFuncToUserAttributeIpa(context, op.Imm10, out res);
|
||||
|
||||
if (op.Imm10 >= AttributeConsts.UserAttributeBase && op.Imm10 < AttributeConsts.UserAttributeEnd)
|
||||
{
|
||||
|
@ -143,7 +152,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
if (op.IpaOp == IpaOp.Multiply)
|
||||
if (op.IpaOp == IpaOp.Multiply && !isFixedFunc)
|
||||
{
|
||||
Operand srcB = GetSrcReg(context, op.SrcB);
|
||||
|
||||
|
@ -204,5 +213,72 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
context.EndPrimitive();
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TryFixedFuncToUserAttributeIpa(EmitterContext context, int attr, out Operand selectedAttr)
|
||||
{
|
||||
if (attr >= AttributeConsts.FrontColorDiffuseR && attr < AttributeConsts.BackColorDiffuseR)
|
||||
{
|
||||
// TODO: If two sided rendering is enabled, then this should return
|
||||
// FrontColor if the fragment is front facing, and back color otherwise.
|
||||
int index = (attr - AttributeConsts.FrontColorDiffuseR) >> 4;
|
||||
int userAttrIndex = context.Config.GetFreeUserAttribute(isOutput: false, index);
|
||||
Operand frontAttr = Attribute(AttributeConsts.UserAttributeBase + userAttrIndex * 16 + (attr & 0xf));
|
||||
|
||||
context.Config.SetInputUserAttributeFixedFunc(userAttrIndex);
|
||||
|
||||
selectedAttr = frontAttr;
|
||||
return true;
|
||||
}
|
||||
else if (attr >= AttributeConsts.BackColorDiffuseR && attr < AttributeConsts.ClipDistance0)
|
||||
{
|
||||
selectedAttr = ConstF(((attr >> 2) & 3) == 3 ? 1f : 0f);
|
||||
return true;
|
||||
}
|
||||
else if (attr >= AttributeConsts.TexCoordBase && attr < AttributeConsts.TexCoordEnd)
|
||||
{
|
||||
selectedAttr = Attribute(FixedFuncToUserAttribute(context.Config, attr, AttributeConsts.TexCoordBase, 4, isOutput: false));
|
||||
return true;
|
||||
}
|
||||
|
||||
selectedAttr = Attribute(attr);
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int FixedFuncToUserAttribute(ShaderConfig config, int attr, bool isOutput)
|
||||
{
|
||||
if (attr >= AttributeConsts.FrontColorDiffuseR && attr < AttributeConsts.ClipDistance0)
|
||||
{
|
||||
attr = FixedFuncToUserAttribute(config, attr, AttributeConsts.FrontColorDiffuseR, 0, isOutput);
|
||||
}
|
||||
else if (attr >= AttributeConsts.TexCoordBase && attr < AttributeConsts.TexCoordEnd)
|
||||
{
|
||||
attr = FixedFuncToUserAttribute(config, attr, AttributeConsts.TexCoordBase, 4, isOutput);
|
||||
}
|
||||
|
||||
return attr;
|
||||
}
|
||||
|
||||
private static int FixedFuncToUserAttribute(ShaderConfig config, int attr, int baseAttr, int baseIndex, bool isOutput)
|
||||
{
|
||||
int index = (attr - baseAttr) >> 4;
|
||||
int userAttrIndex = config.GetFreeUserAttribute(isOutput, index);
|
||||
|
||||
if ((uint)userAttrIndex < Constants.MaxAttributes)
|
||||
{
|
||||
userAttrIndex += baseIndex;
|
||||
attr = AttributeConsts.UserAttributeBase + userAttrIndex * 16 + (attr & 0xf);
|
||||
|
||||
if (isOutput)
|
||||
{
|
||||
config.SetOutputUserAttributeFixedFunc(userAttrIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
config.SetInputUserAttributeFixedFunc(userAttrIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return attr;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue