Stop identifying shader textures with handle and cbuf, use binding instead (#5266)

* Stop identifying shader textures with handle and cbuf, use binding instead

* Remove now unused code

* Consider image operations as having accurate type information too

I don't know why that was not the case before

* Fix missing unscale on InsertCoordNormalization, stop calling SetUsageFlagsForTextureQuery when not needed

* Shader cache version bump

* Change get texture methods to return descriptors created from ResourceManager state

 This is required to ensure that reserved textures and images will not be bound as a guest texture/image

* Fix BindlessElimination.SetHandle inserting coords at the wrong place
This commit is contained in:
gdkchan 2023-07-03 14:29:27 -03:00 committed by GitHub
parent 3b46bb73f7
commit 1c7a90ef35
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 656 additions and 659 deletions

View file

@ -324,16 +324,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
int handle = !isBindless ? imm : 0;
TextureOperation operation = context.CreateTextureOperation(
Instruction.TextureSample,
type,
flags,
handle,
componentMask,
dests,
sources);
context.Add(operation);
EmitTextureSample(context, type, flags, handle, componentMask, dests, sources);
}
private static void EmitTexs(
@ -657,16 +648,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
Array.Resize(ref dests, outputIndex);
}
TextureOperation operation = context.CreateTextureOperation(
Instruction.TextureSample,
type,
flags,
handle,
componentMask,
dests,
sources);
context.Add(operation);
EmitTextureSample(context, type, flags, handle, componentMask, dests, sources);
if (isF16)
{
@ -812,18 +794,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
Array.Resize(ref dests, outputIndex);
}
int handle = imm;
TextureOperation operation = context.CreateTextureOperation(
Instruction.TextureSample,
type,
flags,
handle,
componentMask,
dests,
sources);
context.Add(operation);
EmitTextureSample(context, type, flags, imm, componentMask, dests, sources);
}
private static void EmitTmml(
@ -913,15 +884,21 @@ namespace Ryujinx.Graphics.Shader.Instructions
return Register(dest++, RegisterType.Gpr);
}
int handle = imm;
int binding = isBindless ? 0 : context.Config.ResourceManager.GetTextureOrImageBinding(
Instruction.Lod,
type,
TextureFormat.Unknown,
flags,
TextureOperation.DefaultCbufSlot,
imm);
for (int compMask = componentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
{
if ((compMask & 1) != 0)
{
Operand destOperand = GetDest();
Operand d = GetDest();
if (destOperand == null)
if (d == null)
{
break;
}
@ -930,28 +907,18 @@ namespace Ryujinx.Graphics.Shader.Instructions
if (compIndex >= 2)
{
context.Add(new CommentNode("Unsupported component z or w found"));
context.Copy(destOperand, Const(0));
context.Copy(d, Const(0));
}
else
{
Operand tempDest = Local();
// The instruction component order is the inverse of GLSL's.
Operand res = context.Lod(type, flags, binding, compIndex ^ 1, sources);
TextureOperation operation = context.CreateTextureOperation(
Instruction.Lod,
type,
flags,
handle,
compIndex ^ 1, // The instruction component order is the inverse of GLSL's.
new[] { tempDest },
sources);
res = context.FPMultiply(res, ConstF(256.0f));
context.Add(operation);
Operand fixedPointValue = context.FP32ConvertToS32(res);
tempDest = context.FPMultiply(tempDest, ConstF(256.0f));
Operand fixedPointValue = context.FP32ConvertToS32(tempDest);
context.Copy(destOperand, fixedPointValue);
context.Copy(d, fixedPointValue);
}
}
}
@ -1081,18 +1048,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
Array.Resize(ref dests, outputIndex);
}
int handle = imm;
TextureOperation operation = context.CreateTextureOperation(
Instruction.TextureSample,
type,
flags,
handle,
componentMask,
dests,
sources);
context.Add(operation);
EmitTextureSample(context, type, flags, imm, componentMask, dests, sources);
}
private static void EmitTxq(
@ -1111,10 +1067,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
context.Config.SetUsedFeature(FeatureFlags.IntegerSampling);
// TODO: Validate and use query.
Instruction inst = Instruction.TextureSize;
TextureFlags flags = isBindless ? TextureFlags.Bindless : TextureFlags.None;
Operand Ra()
{
if (srcA > RegisterConsts.RegisterZeroIndex)
@ -1157,31 +1109,55 @@ namespace Ryujinx.Graphics.Shader.Instructions
type = context.Config.GpuAccessor.QuerySamplerType(imm);
}
TextureFlags flags = isBindless ? TextureFlags.Bindless : TextureFlags.None;
int binding = isBindless ? 0 : context.Config.ResourceManager.GetTextureOrImageBinding(
Instruction.TextureSize,
type,
TextureFormat.Unknown,
flags,
TextureOperation.DefaultCbufSlot,
imm);
for (int compMask = componentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
{
if ((compMask & 1) != 0)
{
Operand destOperand = GetDest();
Operand d = GetDest();
if (destOperand == null)
if (d == null)
{
break;
}
TextureOperation operation = context.CreateTextureOperation(
inst,
type,
flags,
imm,
compIndex,
new[] { destOperand },
sources);
// TODO: Validate and use query parameter.
Operand res = context.TextureSize(type, flags, binding, compIndex, sources);
context.Add(operation);
context.Copy(d, res);
}
}
}
private static void EmitTextureSample(
EmitterContext context,
SamplerType type,
TextureFlags flags,
int handle,
int componentMask,
Operand[] dests,
Operand[] sources)
{
int binding = flags.HasFlag(TextureFlags.Bindless) ? 0 : context.Config.ResourceManager.GetTextureOrImageBinding(
Instruction.TextureSample,
type,
TextureFormat.Unknown,
flags,
TextureOperation.DefaultCbufSlot,
handle);
context.TextureSample(type, flags, binding, componentMask, dests, sources);
}
private static SamplerType ConvertSamplerType(TexDim dimensions)
{
return dimensions switch