mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-07-25 21:27:14 +02:00
Revert the Metal Experiment (#701)
Metal sounded like a good idea to get in the emulator but frankly I underestimated just how experimental and not ready it was. From my write up in the Discord: ``` As is, Metal supports only a few games. The games it does support freeze on first use of not playing them via Vulkan, because shader translation is broken. So you need to use a dirty hack to not delete all your shaders. Not to mention it breaks many games via MoltenVK because of changes to the shared GPU code. Merging Metal seemed like a great idea, because of the few games it does support. But I don't think it's worth it. Many of the games it breaks via MoltenVK *don't work via Metal*. Which effectively makes current Ryubing worse for Mac users than Ryujinx 1.1.1403. I think what I'm gonna do is revert Metal, and reopen it as a PR. That way, you can still take advantage of the Metal backend as is, but without making other games worse with no solution. ``` For what it's worth, the shader translation part could at least be "fixed" by always applying a 30ms delay for shader translation to Metal. That being said, that solution sucks ass. The MoltenVK regressions are even worse. I hope this is not a let down to the Mac users. I hope you realize I'm reverting this because you're actively getting a worse experience with it in the emulator.
This commit is contained in:
parent
eb6b0e9adc
commit
fe1617ffea
135 changed files with 302 additions and 15077 deletions
|
@ -26,6 +26,5 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
SharedMemory = 1 << 11,
|
||||
Store = 1 << 12,
|
||||
VtgAsCompute = 1 << 13,
|
||||
Precise = 1 << 14,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
private const int DefaultLocalMemorySize = 128;
|
||||
private const int DefaultSharedMemorySize = 4096;
|
||||
|
||||
private static readonly string[] _stagePrefixes = ["cp", "vp", "tcp", "tep", "gp", "fp"];
|
||||
private static readonly string[] _stagePrefixes = new string[] { "cp", "vp", "tcp", "tep", "gp", "fp" };
|
||||
|
||||
private readonly IGpuAccessor _gpuAccessor;
|
||||
private readonly ShaderStage _stage;
|
||||
|
@ -43,11 +43,6 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
private readonly Dictionary<TextureInfo, TextureMeta> _usedTextures;
|
||||
private readonly Dictionary<TextureInfo, TextureMeta> _usedImages;
|
||||
|
||||
private readonly List<BufferDefinition> _vacConstantBuffers;
|
||||
private readonly List<BufferDefinition> _vacStorageBuffers;
|
||||
private readonly List<TextureDefinition> _vacTextures;
|
||||
private readonly List<TextureDefinition> _vacImages;
|
||||
|
||||
public int LocalMemoryId { get; private set; }
|
||||
public int SharedMemoryId { get; private set; }
|
||||
|
||||
|
@ -78,16 +73,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
_sbSlots = new();
|
||||
_sbSlotsReverse = new();
|
||||
|
||||
_usedConstantBufferBindings = [];
|
||||
_usedConstantBufferBindings = new();
|
||||
|
||||
_usedTextures = new();
|
||||
_usedImages = new();
|
||||
|
||||
_vacConstantBuffers = [];
|
||||
_vacStorageBuffers = [];
|
||||
_vacTextures = [];
|
||||
_vacImages = [];
|
||||
|
||||
Properties.AddOrUpdateConstantBuffer(new(BufferLayout.Std140, 0, SupportBuffer.Binding, "support_buffer", SupportBuffer.GetStructureType()));
|
||||
|
||||
LocalMemoryId = -1;
|
||||
|
@ -103,7 +93,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
size = DefaultLocalMemorySize;
|
||||
}
|
||||
|
||||
MemoryDefinition lmem = new("local_memory", AggregateType.Array | AggregateType.U32, BitUtils.DivRoundUp(size, sizeof(uint)));
|
||||
var lmem = new MemoryDefinition("local_memory", AggregateType.Array | AggregateType.U32, BitUtils.DivRoundUp(size, sizeof(uint)));
|
||||
|
||||
LocalMemoryId = Properties.AddLocalMemory(lmem);
|
||||
}
|
||||
|
@ -122,7 +112,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
size = DefaultSharedMemorySize;
|
||||
}
|
||||
|
||||
MemoryDefinition smem = new("shared_memory", AggregateType.Array | AggregateType.U32, BitUtils.DivRoundUp(size, sizeof(uint)));
|
||||
var smem = new MemoryDefinition("shared_memory", AggregateType.Array | AggregateType.U32, BitUtils.DivRoundUp(size, sizeof(uint)));
|
||||
|
||||
SharedMemoryId = Properties.AddSharedMemory(smem);
|
||||
}
|
||||
|
@ -283,16 +273,16 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
bool coherent,
|
||||
bool separate)
|
||||
{
|
||||
int dimensions = type == SamplerType.None ? 0 : type.GetDimensions();
|
||||
Dictionary<TextureInfo, TextureMeta> dict = isImage ? _usedImages : _usedTextures;
|
||||
var dimensions = type == SamplerType.None ? 0 : type.GetDimensions();
|
||||
var dict = isImage ? _usedImages : _usedTextures;
|
||||
|
||||
TextureUsageFlags usageFlags = TextureUsageFlags.None;
|
||||
var usageFlags = TextureUsageFlags.None;
|
||||
|
||||
if (intCoords)
|
||||
{
|
||||
usageFlags |= TextureUsageFlags.NeedsScaleValue;
|
||||
|
||||
bool canScale = _stage.SupportsRenderScale() && arrayLength == 1 && !write && dimensions == 2;
|
||||
var canScale = _stage.SupportsRenderScale() && arrayLength == 1 && !write && dimensions == 2;
|
||||
|
||||
if (!canScale)
|
||||
{
|
||||
|
@ -314,9 +304,9 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
// For array textures, we also want to use type as key,
|
||||
// since we may have texture handles stores in the same buffer, but for textures with different types.
|
||||
SamplerType keyType = arrayLength > 1 ? type : SamplerType.None;
|
||||
TextureInfo info = new(cbufSlot, handle, arrayLength, separate, keyType, format);
|
||||
TextureMeta meta = new()
|
||||
var keyType = arrayLength > 1 ? type : SamplerType.None;
|
||||
var info = new TextureInfo(cbufSlot, handle, arrayLength, separate, keyType, format);
|
||||
var meta = new TextureMeta()
|
||||
{
|
||||
AccurateType = accurateType,
|
||||
Type = type,
|
||||
|
@ -326,7 +316,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
int setIndex;
|
||||
int binding;
|
||||
|
||||
if (dict.TryGetValue(info, out TextureMeta existingMeta))
|
||||
if (dict.TryGetValue(info, out var existingMeta))
|
||||
{
|
||||
dict[info] = MergeTextureMeta(meta, existingMeta);
|
||||
setIndex = existingMeta.Set;
|
||||
|
@ -383,7 +373,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
nameSuffix = cbufSlot < 0 ? $"{prefix}_tcb_{handle:X}" : $"{prefix}_cb{cbufSlot}_{handle:X}";
|
||||
}
|
||||
|
||||
TextureDefinition definition = new(
|
||||
var definition = new TextureDefinition(
|
||||
setIndex,
|
||||
binding,
|
||||
arrayLength,
|
||||
|
@ -443,8 +433,8 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
{
|
||||
selectedMeta.UsageFlags |= TextureUsageFlags.NeedsScaleValue;
|
||||
|
||||
int dimensions = type.GetDimensions();
|
||||
bool canScale = _stage.SupportsRenderScale() && selectedInfo.ArrayLength == 1 && dimensions == 2;
|
||||
var dimensions = type.GetDimensions();
|
||||
var canScale = _stage.SupportsRenderScale() && selectedInfo.ArrayLength == 1 && dimensions == 2;
|
||||
|
||||
if (!canScale)
|
||||
{
|
||||
|
@ -464,7 +454,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
public BufferDescriptor[] GetConstantBufferDescriptors()
|
||||
{
|
||||
BufferDescriptor[] descriptors = new BufferDescriptor[_usedConstantBufferBindings.Count];
|
||||
var descriptors = new BufferDescriptor[_usedConstantBufferBindings.Count];
|
||||
|
||||
int descriptorIndex = 0;
|
||||
|
||||
|
@ -488,7 +478,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
public BufferDescriptor[] GetStorageBufferDescriptors()
|
||||
{
|
||||
BufferDescriptor[] descriptors = new BufferDescriptor[_sbSlots.Count];
|
||||
var descriptors = new BufferDescriptor[_sbSlots.Count];
|
||||
|
||||
int descriptorIndex = 0;
|
||||
|
||||
|
@ -524,7 +514,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
private static TextureDescriptor[] GetDescriptors(IReadOnlyDictionary<TextureInfo, TextureMeta> usedResources, bool includeArrays)
|
||||
{
|
||||
List<TextureDescriptor> descriptors = [];
|
||||
List<TextureDescriptor> descriptors = new();
|
||||
|
||||
bool hasAnyArray = false;
|
||||
|
||||
|
@ -573,75 +563,6 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
return descriptors.ToArray();
|
||||
}
|
||||
|
||||
public ShaderProgramInfo GetVertexAsComputeInfo(bool isVertex = false)
|
||||
{
|
||||
BufferDescriptor[] cbDescriptors = new BufferDescriptor[_vacConstantBuffers.Count];
|
||||
int cbDescriptorIndex = 0;
|
||||
|
||||
foreach (BufferDefinition definition in _vacConstantBuffers)
|
||||
{
|
||||
cbDescriptors[cbDescriptorIndex++] = new BufferDescriptor(definition.Set, definition.Binding, 0, 0, 0, BufferUsageFlags.None);
|
||||
}
|
||||
|
||||
BufferDescriptor[] sbDescriptors = new BufferDescriptor[_vacStorageBuffers.Count];
|
||||
int sbDescriptorIndex = 0;
|
||||
|
||||
foreach (BufferDefinition definition in _vacStorageBuffers)
|
||||
{
|
||||
sbDescriptors[sbDescriptorIndex++] = new BufferDescriptor(definition.Set, definition.Binding, 0, 0, 0, BufferUsageFlags.Write);
|
||||
}
|
||||
|
||||
TextureDescriptor[] tDescriptors = new TextureDescriptor[_vacTextures.Count];
|
||||
int tDescriptorIndex = 0;
|
||||
|
||||
foreach (TextureDefinition definition in _vacTextures)
|
||||
{
|
||||
tDescriptors[tDescriptorIndex++] = new TextureDescriptor(
|
||||
definition.Set,
|
||||
definition.Binding,
|
||||
definition.Type,
|
||||
definition.Format,
|
||||
0,
|
||||
0,
|
||||
definition.ArrayLength,
|
||||
definition.Separate,
|
||||
definition.Flags);
|
||||
}
|
||||
|
||||
TextureDescriptor[] iDescriptors = new TextureDescriptor[_vacImages.Count];
|
||||
int iDescriptorIndex = 0;
|
||||
|
||||
foreach (TextureDefinition definition in _vacImages)
|
||||
{
|
||||
iDescriptors[iDescriptorIndex++] = new TextureDescriptor(
|
||||
definition.Set,
|
||||
definition.Binding,
|
||||
definition.Type,
|
||||
definition.Format,
|
||||
0,
|
||||
0,
|
||||
definition.ArrayLength,
|
||||
definition.Separate,
|
||||
definition.Flags);
|
||||
}
|
||||
|
||||
return new ShaderProgramInfo(
|
||||
cbDescriptors,
|
||||
sbDescriptors,
|
||||
tDescriptors,
|
||||
iDescriptors,
|
||||
isVertex ? ShaderStage.Vertex : ShaderStage.Compute,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
||||
public bool TryGetCbufSlotAndHandleForTexture(int binding, out int cbufSlot, out int handle)
|
||||
{
|
||||
foreach ((TextureInfo info, TextureMeta meta) in _usedTextures)
|
||||
|
@ -690,46 +611,24 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
private void AddNewConstantBuffer(int setIndex, int binding, string name)
|
||||
{
|
||||
StructureType type = new([
|
||||
new StructureField(AggregateType.Array | AggregateType.Vector4 | AggregateType.FP32, "data", Constants.ConstantBufferSize / 16)
|
||||
]);
|
||||
StructureType type = new(new[]
|
||||
{
|
||||
new StructureField(AggregateType.Array | AggregateType.Vector4 | AggregateType.FP32, "data", Constants.ConstantBufferSize / 16),
|
||||
});
|
||||
|
||||
Properties.AddOrUpdateConstantBuffer(new(BufferLayout.Std140, setIndex, binding, name, type));
|
||||
}
|
||||
|
||||
private void AddNewStorageBuffer(int setIndex, int binding, string name)
|
||||
{
|
||||
StructureType type = new([
|
||||
new StructureField(AggregateType.Array | AggregateType.U32, "data", 0)
|
||||
]);
|
||||
StructureType type = new(new[]
|
||||
{
|
||||
new StructureField(AggregateType.Array | AggregateType.U32, "data", 0),
|
||||
});
|
||||
|
||||
Properties.AddOrUpdateStorageBuffer(new(BufferLayout.Std430, setIndex, binding, name, type));
|
||||
}
|
||||
|
||||
public void AddVertexAsComputeConstantBuffer(BufferDefinition definition)
|
||||
{
|
||||
_vacConstantBuffers.Add(definition);
|
||||
Properties.AddOrUpdateConstantBuffer(definition);
|
||||
}
|
||||
|
||||
public void AddVertexAsComputeStorageBuffer(BufferDefinition definition)
|
||||
{
|
||||
_vacStorageBuffers.Add(definition);
|
||||
Properties.AddOrUpdateStorageBuffer(definition);
|
||||
}
|
||||
|
||||
public void AddVertexAsComputeTexture(TextureDefinition definition)
|
||||
{
|
||||
_vacTextures.Add(definition);
|
||||
Properties.AddOrUpdateTexture(definition);
|
||||
}
|
||||
|
||||
public void AddVertexAsComputeImage(TextureDefinition definition)
|
||||
{
|
||||
_vacImages.Add(definition);
|
||||
Properties.AddOrUpdateImage(definition);
|
||||
}
|
||||
|
||||
public static string GetShaderStagePrefix(ShaderStage stage)
|
||||
{
|
||||
uint index = (uint)stage;
|
||||
|
|
|
@ -4,6 +4,5 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
{
|
||||
OpenGL,
|
||||
Vulkan,
|
||||
Metal
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,6 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
{
|
||||
Glsl,
|
||||
Spirv,
|
||||
Msl
|
||||
Arb,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,8 +27,6 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
addOp.Inst == (Instruction.FP32 | Instruction.Add) &&
|
||||
addOp.GetSource(1).Type == OperandType.Constant)
|
||||
{
|
||||
context.UsedFeatures |= FeatureFlags.Precise;
|
||||
|
||||
addOp.ForcePrecise = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using Ryujinx.Graphics.Shader.CodeGen;
|
||||
using Ryujinx.Graphics.Shader.CodeGen.Glsl;
|
||||
using Ryujinx.Graphics.Shader.CodeGen.Msl;
|
||||
using Ryujinx.Graphics.Shader.CodeGen.Spirv;
|
||||
using Ryujinx.Graphics.Shader.Decoders;
|
||||
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
|
||||
|
@ -243,8 +242,8 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
usedFeatures |= FeatureFlags.VtgAsCompute;
|
||||
}
|
||||
|
||||
ControlFlowGraph[] cfgs = new ControlFlowGraph[functions.Length];
|
||||
RegisterUsage.FunctionRegisterUsage[] frus = new RegisterUsage.FunctionRegisterUsage[functions.Length];
|
||||
var cfgs = new ControlFlowGraph[functions.Length];
|
||||
var frus = new RegisterUsage.FunctionRegisterUsage[functions.Length];
|
||||
|
||||
for (int i = 0; i < functions.Length; i++)
|
||||
{
|
||||
|
@ -267,14 +266,14 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
for (int i = 0; i < functions.Length; i++)
|
||||
{
|
||||
ControlFlowGraph cfg = cfgs[i];
|
||||
var cfg = cfgs[i];
|
||||
|
||||
int inArgumentsCount = 0;
|
||||
int outArgumentsCount = 0;
|
||||
|
||||
if (i != 0)
|
||||
{
|
||||
RegisterUsage.FunctionRegisterUsage fru = frus[i];
|
||||
var fru = frus[i];
|
||||
|
||||
inArgumentsCount = fru.InArguments.Length;
|
||||
outArgumentsCount = fru.OutArguments.Length;
|
||||
|
@ -326,13 +325,12 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
FeatureFlags usedFeatures,
|
||||
byte clipDistancesWritten)
|
||||
{
|
||||
StructuredProgramInfo sInfo = StructuredProgram.MakeStructuredProgram(
|
||||
var sInfo = StructuredProgram.MakeStructuredProgram(
|
||||
funcs,
|
||||
attributeUsage,
|
||||
definitions,
|
||||
resourceManager,
|
||||
Options.TargetLanguage,
|
||||
usedFeatures.HasFlag(FeatureFlags.Precise),
|
||||
Options.Flags.HasFlag(TranslationFlags.DebugMode));
|
||||
|
||||
int geometryVerticesPerPrimitive = Definitions.OutputTopology switch
|
||||
|
@ -342,7 +340,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
_ => 1
|
||||
};
|
||||
|
||||
ShaderProgramInfo info = new(
|
||||
var info = new ShaderProgramInfo(
|
||||
resourceManager.GetConstantBufferDescriptors(),
|
||||
resourceManager.GetStorageBufferDescriptors(),
|
||||
resourceManager.GetTextureDescriptors(),
|
||||
|
@ -358,7 +356,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
clipDistancesWritten,
|
||||
originalDefinitions.OmapTargets);
|
||||
|
||||
HostCapabilities hostCapabilities = new(
|
||||
var hostCapabilities = new HostCapabilities(
|
||||
GpuAccessor.QueryHostReducedPrecision(),
|
||||
GpuAccessor.QueryHostSupportsFragmentShaderInterlock(),
|
||||
GpuAccessor.QueryHostSupportsFragmentShaderOrderingIntel(),
|
||||
|
@ -369,13 +367,12 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
GpuAccessor.QueryHostSupportsTextureShadowLod(),
|
||||
GpuAccessor.QueryHostSupportsViewportMask());
|
||||
|
||||
CodeGenParameters parameters = new(attributeUsage, definitions, resourceManager.Properties, hostCapabilities, GpuAccessor, Options.TargetApi);
|
||||
var parameters = new CodeGenParameters(attributeUsage, definitions, resourceManager.Properties, hostCapabilities, GpuAccessor, Options.TargetApi);
|
||||
|
||||
return Options.TargetLanguage switch
|
||||
{
|
||||
TargetLanguage.Glsl => new ShaderProgram(info, TargetLanguage.Glsl, GlslGenerator.Generate(sInfo, parameters)),
|
||||
TargetLanguage.Spirv => new ShaderProgram(info, TargetLanguage.Spirv, SpirvGenerator.Generate(sInfo, parameters)),
|
||||
TargetLanguage.Msl => new ShaderProgram(info, TargetLanguage.Msl, MslGenerator.Generate(sInfo, parameters)),
|
||||
_ => throw new NotImplementedException(Options.TargetLanguage.ToString()),
|
||||
};
|
||||
}
|
||||
|
@ -386,15 +383,16 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
if (IsTransformFeedbackEmulated)
|
||||
{
|
||||
StructureType tfeDataStruct = new([
|
||||
new(AggregateType.Array | AggregateType.U32, "data", 0)
|
||||
]);
|
||||
StructureType tfeDataStruct = new(new StructureField[]
|
||||
{
|
||||
new StructureField(AggregateType.Array | AggregateType.U32, "data", 0)
|
||||
});
|
||||
|
||||
for (int i = 0; i < ResourceReservations.TfeBuffersCount; i++)
|
||||
{
|
||||
int binding = resourceManager.Reservations.GetTfeBufferStorageBufferBinding(i);
|
||||
BufferDefinition tfeDataBuffer = new(BufferLayout.Std430, 1, binding, $"tfe_data{i}", tfeDataStruct);
|
||||
resourceManager.AddVertexAsComputeStorageBuffer(tfeDataBuffer);
|
||||
resourceManager.Properties.AddOrUpdateStorageBuffer(tfeDataBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -402,21 +400,22 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
{
|
||||
int vertexInfoCbBinding = resourceManager.Reservations.VertexInfoConstantBufferBinding;
|
||||
BufferDefinition vertexInfoBuffer = new(BufferLayout.Std140, 0, vertexInfoCbBinding, "vb_info", VertexInfoBuffer.GetStructureType());
|
||||
resourceManager.AddVertexAsComputeConstantBuffer(vertexInfoBuffer);
|
||||
resourceManager.Properties.AddOrUpdateConstantBuffer(vertexInfoBuffer);
|
||||
|
||||
StructureType vertexOutputStruct = new([
|
||||
new(AggregateType.Array | AggregateType.FP32, "data", 0)
|
||||
]);
|
||||
StructureType vertexOutputStruct = new(new StructureField[]
|
||||
{
|
||||
new StructureField(AggregateType.Array | AggregateType.FP32, "data", 0)
|
||||
});
|
||||
|
||||
int vertexOutputSbBinding = resourceManager.Reservations.VertexOutputStorageBufferBinding;
|
||||
BufferDefinition vertexOutputBuffer = new(BufferLayout.Std430, 1, vertexOutputSbBinding, "vertex_output", vertexOutputStruct);
|
||||
resourceManager.AddVertexAsComputeStorageBuffer(vertexOutputBuffer);
|
||||
resourceManager.Properties.AddOrUpdateStorageBuffer(vertexOutputBuffer);
|
||||
|
||||
if (Stage == ShaderStage.Vertex)
|
||||
{
|
||||
SetBindingPair ibSetAndBinding = resourceManager.Reservations.GetIndexBufferTextureSetAndBinding();
|
||||
TextureDefinition indexBuffer = new(ibSetAndBinding.SetIndex, ibSetAndBinding.Binding, "ib_data", SamplerType.TextureBuffer);
|
||||
resourceManager.AddVertexAsComputeTexture(indexBuffer);
|
||||
resourceManager.Properties.AddOrUpdateTexture(indexBuffer);
|
||||
|
||||
int inputMap = _program.AttributeUsage.UsedInputAttributes;
|
||||
|
||||
|
@ -425,7 +424,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
int location = BitOperations.TrailingZeroCount(inputMap);
|
||||
SetBindingPair setAndBinding = resourceManager.Reservations.GetVertexBufferTextureSetAndBinding(location);
|
||||
TextureDefinition vaBuffer = new(setAndBinding.SetIndex, setAndBinding.Binding, $"vb_data{location}", SamplerType.TextureBuffer);
|
||||
resourceManager.AddVertexAsComputeTexture(vaBuffer);
|
||||
resourceManager.Properties.AddOrUpdateTexture(vaBuffer);
|
||||
|
||||
inputMap &= ~(1 << location);
|
||||
}
|
||||
|
@ -434,19 +433,20 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
{
|
||||
SetBindingPair trbSetAndBinding = resourceManager.Reservations.GetTopologyRemapBufferTextureSetAndBinding();
|
||||
TextureDefinition remapBuffer = new(trbSetAndBinding.SetIndex, trbSetAndBinding.Binding, "trb_data", SamplerType.TextureBuffer);
|
||||
resourceManager.AddVertexAsComputeTexture(remapBuffer);
|
||||
resourceManager.Properties.AddOrUpdateTexture(remapBuffer);
|
||||
|
||||
int geometryVbOutputSbBinding = resourceManager.Reservations.GeometryVertexOutputStorageBufferBinding;
|
||||
BufferDefinition geometryVbOutputBuffer = new(BufferLayout.Std430, 1, geometryVbOutputSbBinding, "geometry_vb_output", vertexOutputStruct);
|
||||
resourceManager.AddVertexAsComputeStorageBuffer(geometryVbOutputBuffer);
|
||||
resourceManager.Properties.AddOrUpdateStorageBuffer(geometryVbOutputBuffer);
|
||||
|
||||
StructureType geometryIbOutputStruct = new([
|
||||
new(AggregateType.Array | AggregateType.U32, "data", 0)
|
||||
]);
|
||||
StructureType geometryIbOutputStruct = new(new StructureField[]
|
||||
{
|
||||
new StructureField(AggregateType.Array | AggregateType.U32, "data", 0)
|
||||
});
|
||||
|
||||
int geometryIbOutputSbBinding = resourceManager.Reservations.GeometryIndexOutputStorageBufferBinding;
|
||||
BufferDefinition geometryIbOutputBuffer = new(BufferLayout.Std430, 1, geometryIbOutputSbBinding, "geometry_ib_output", geometryIbOutputStruct);
|
||||
resourceManager.AddVertexAsComputeStorageBuffer(geometryIbOutputBuffer);
|
||||
resourceManager.Properties.AddOrUpdateStorageBuffer(geometryIbOutputBuffer);
|
||||
}
|
||||
|
||||
resourceManager.SetVertexAsComputeLocalMemories(Definitions.Stage, Definitions.InputTopology);
|
||||
|
@ -479,40 +479,36 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
return new ResourceReservations(GpuAccessor, IsTransformFeedbackEmulated, vertexAsCompute: true, _vertexOutput, ioUsage);
|
||||
}
|
||||
|
||||
public ShaderProgramInfo GetVertexAsComputeInfo()
|
||||
{
|
||||
return CreateResourceManager(true).GetVertexAsComputeInfo();
|
||||
}
|
||||
|
||||
public void SetVertexOutputMapForGeometryAsCompute(TranslatorContext vertexContext)
|
||||
{
|
||||
_vertexOutput = vertexContext._program.GetIoUsage();
|
||||
}
|
||||
|
||||
public (ShaderProgram, ShaderProgramInfo) GenerateVertexPassthroughForCompute()
|
||||
public ShaderProgram GenerateVertexPassthroughForCompute()
|
||||
{
|
||||
AttributeUsage attributeUsage = new(GpuAccessor);
|
||||
ResourceManager resourceManager = new(ShaderStage.Vertex, GpuAccessor);
|
||||
var attributeUsage = new AttributeUsage(GpuAccessor);
|
||||
var resourceManager = new ResourceManager(ShaderStage.Vertex, GpuAccessor);
|
||||
|
||||
ResourceReservations reservations = GetResourceReservations();
|
||||
var reservations = GetResourceReservations();
|
||||
|
||||
int vertexInfoCbBinding = reservations.VertexInfoConstantBufferBinding;
|
||||
|
||||
if (Stage == ShaderStage.Vertex)
|
||||
{
|
||||
BufferDefinition vertexInfoBuffer = new(BufferLayout.Std140, 0, vertexInfoCbBinding, "vb_info", VertexInfoBuffer.GetStructureType());
|
||||
resourceManager.AddVertexAsComputeConstantBuffer(vertexInfoBuffer);
|
||||
resourceManager.Properties.AddOrUpdateConstantBuffer(vertexInfoBuffer);
|
||||
}
|
||||
|
||||
StructureType vertexInputStruct = new([
|
||||
new(AggregateType.Array | AggregateType.FP32, "data", 0)
|
||||
]);
|
||||
StructureType vertexInputStruct = new(new StructureField[]
|
||||
{
|
||||
new StructureField(AggregateType.Array | AggregateType.FP32, "data", 0)
|
||||
});
|
||||
|
||||
int vertexDataSbBinding = reservations.VertexOutputStorageBufferBinding;
|
||||
BufferDefinition vertexOutputBuffer = new(BufferLayout.Std430, 1, vertexDataSbBinding, "vb_input", vertexInputStruct);
|
||||
resourceManager.AddVertexAsComputeStorageBuffer(vertexOutputBuffer);
|
||||
resourceManager.Properties.AddOrUpdateStorageBuffer(vertexOutputBuffer);
|
||||
|
||||
EmitterContext context = new();
|
||||
var context = new EmitterContext();
|
||||
|
||||
Operand vertexIndex = Options.TargetApi == TargetApi.OpenGL
|
||||
? context.Load(StorageKind.Input, IoVariable.VertexId)
|
||||
|
@ -557,25 +553,25 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
}
|
||||
}
|
||||
|
||||
Operation[] operations = context.GetOperations();
|
||||
ControlFlowGraph cfg = ControlFlowGraph.Create(operations);
|
||||
Function function = new(cfg.Blocks, "main", false, 0, 0);
|
||||
var operations = context.GetOperations();
|
||||
var cfg = ControlFlowGraph.Create(operations);
|
||||
var function = new Function(cfg.Blocks, "main", false, 0, 0);
|
||||
|
||||
TransformFeedbackOutput[] transformFeedbackOutputs = GetTransformFeedbackOutputs(GpuAccessor, out ulong transformFeedbackVecMap);
|
||||
var transformFeedbackOutputs = GetTransformFeedbackOutputs(GpuAccessor, out ulong transformFeedbackVecMap);
|
||||
|
||||
ShaderDefinitions definitions = new(ShaderStage.Vertex, transformFeedbackVecMap, transformFeedbackOutputs)
|
||||
var definitions = new ShaderDefinitions(ShaderStage.Vertex, transformFeedbackVecMap, transformFeedbackOutputs)
|
||||
{
|
||||
LastInVertexPipeline = true
|
||||
};
|
||||
|
||||
return (Generate(
|
||||
[function],
|
||||
return Generate(
|
||||
new[] { function },
|
||||
attributeUsage,
|
||||
definitions,
|
||||
definitions,
|
||||
resourceManager,
|
||||
FeatureFlags.None,
|
||||
0), resourceManager.GetVertexAsComputeInfo(isVertex: true));
|
||||
0);
|
||||
}
|
||||
|
||||
public ShaderProgram GenerateGeometryPassthrough()
|
||||
|
@ -608,10 +604,10 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
break;
|
||||
}
|
||||
|
||||
AttributeUsage attributeUsage = new(GpuAccessor);
|
||||
ResourceManager resourceManager = new(ShaderStage.Geometry, GpuAccessor);
|
||||
var attributeUsage = new AttributeUsage(GpuAccessor);
|
||||
var resourceManager = new ResourceManager(ShaderStage.Geometry, GpuAccessor);
|
||||
|
||||
EmitterContext context = new();
|
||||
var context = new EmitterContext();
|
||||
|
||||
for (int v = 0; v < maxOutputVertices; v++)
|
||||
{
|
||||
|
@ -652,11 +648,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
context.EndPrimitive();
|
||||
|
||||
Operation[] operations = context.GetOperations();
|
||||
ControlFlowGraph cfg = ControlFlowGraph.Create(operations);
|
||||
Function function = new(cfg.Blocks, "main", false, 0, 0);
|
||||
var operations = context.GetOperations();
|
||||
var cfg = ControlFlowGraph.Create(operations);
|
||||
var function = new Function(cfg.Blocks, "main", false, 0, 0);
|
||||
|
||||
ShaderDefinitions definitions = new(
|
||||
var definitions = new ShaderDefinitions(
|
||||
ShaderStage.Geometry,
|
||||
GpuAccessor.QueryGraphicsState(),
|
||||
false,
|
||||
|
@ -665,7 +661,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
maxOutputVertices);
|
||||
|
||||
return Generate(
|
||||
[function],
|
||||
new[] { function },
|
||||
attributeUsage,
|
||||
definitions,
|
||||
definitions,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue