|
|
@@ -36,22 +36,6 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|
|
return new TranslatorContext(address, cfg, config);
|
|
|
}
|
|
|
|
|
|
- private static void ScanForBindless(BasicBlock[] blocks, ShaderConfig config)
|
|
|
- {
|
|
|
- for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++)
|
|
|
- {
|
|
|
- // Right now the guest shader cache cannot handle bindless textures correctly.
|
|
|
- for (LinkedListNode<INode> node = blocks[blkIndex].Operations.First; node != null; node = node.Next)
|
|
|
- {
|
|
|
- if (node.Value is TextureOperation texOp && (texOp.Flags & TextureFlags.Bindless) != 0)
|
|
|
- {
|
|
|
- config.SetUsedFeature(FeatureFlags.Bindless);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
internal static ShaderProgram Translate(FunctionCode[] functions, ShaderConfig config, out ShaderProgramInfo shaderProgramInfo)
|
|
|
{
|
|
|
var cfgs = new ControlFlowGraph[functions.Length];
|
|
|
@@ -91,8 +75,6 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|
|
Dominance.FindDominators(cfg);
|
|
|
Dominance.FindDominanceFrontiers(cfg.Blocks);
|
|
|
|
|
|
- ScanForBindless(cfg.Blocks, config);
|
|
|
-
|
|
|
Ssa.Rename(cfg.Blocks);
|
|
|
|
|
|
Optimizer.RunPass(cfg.Blocks, config);
|
|
|
@@ -129,35 +111,44 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|
|
Block[][] cfg;
|
|
|
ulong maxEndAddress = 0;
|
|
|
|
|
|
+ bool hasBindless = false;
|
|
|
+
|
|
|
if ((flags & TranslationFlags.Compute) != 0)
|
|
|
{
|
|
|
config = new ShaderConfig(gpuAccessor, flags, counts);
|
|
|
|
|
|
- cfg = Decoder.Decode(gpuAccessor, address);
|
|
|
+ cfg = Decoder.Decode(gpuAccessor, address, out hasBindless);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
config = new ShaderConfig(new ShaderHeader(gpuAccessor, address), gpuAccessor, flags, counts);
|
|
|
|
|
|
- cfg = Decoder.Decode(gpuAccessor, address + HeaderSize);
|
|
|
+ cfg = Decoder.Decode(gpuAccessor, address + HeaderSize, out hasBindless);
|
|
|
}
|
|
|
|
|
|
- for (int funcIndex = 0; funcIndex < cfg.Length; funcIndex++)
|
|
|
+ if (hasBindless)
|
|
|
{
|
|
|
- for (int blkIndex = 0; blkIndex < cfg[funcIndex].Length; blkIndex++)
|
|
|
+ config.SetUsedFeature(FeatureFlags.Bindless);
|
|
|
+ }
|
|
|
+ else // Not bindless, fill up texture handles
|
|
|
+ {
|
|
|
+ for (int funcIndex = 0; funcIndex < cfg.Length; funcIndex++)
|
|
|
{
|
|
|
- Block block = cfg[funcIndex][blkIndex];
|
|
|
-
|
|
|
- if (maxEndAddress < block.EndAddress)
|
|
|
+ for (int blkIndex = 0; blkIndex < cfg[funcIndex].Length; blkIndex++)
|
|
|
{
|
|
|
- maxEndAddress = block.EndAddress;
|
|
|
- }
|
|
|
+ Block block = cfg[funcIndex][blkIndex];
|
|
|
|
|
|
- for (int index = 0; index < block.OpCodes.Count; index++)
|
|
|
- {
|
|
|
- if (block.OpCodes[index] is OpCodeTextureBase texture)
|
|
|
+ if (maxEndAddress < block.EndAddress)
|
|
|
+ {
|
|
|
+ maxEndAddress = block.EndAddress;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int index = 0; index < block.OpCodes.Count; index++)
|
|
|
{
|
|
|
- config.TextureHandlesForCache.Add(texture.HandleOffset);
|
|
|
+ if (block.OpCodes[index] is OpCodeTextureBase texture)
|
|
|
+ {
|
|
|
+ config.TextureHandlesForCache.Add(texture.HandleOffset);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|