mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-07-18 22:56:29 +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
|
@ -324,11 +324,6 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||
|
||||
bool loadHostCache = header.CodeGenVersion == CodeGenVersion;
|
||||
|
||||
if (context.Capabilities.Api == TargetApi.Metal)
|
||||
{
|
||||
loadHostCache = false;
|
||||
}
|
||||
|
||||
int programIndex = 0;
|
||||
|
||||
DataEntry entry = new();
|
||||
|
@ -397,8 +392,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||
context,
|
||||
shaders,
|
||||
specState.PipelineState,
|
||||
specState.TransformFeedbackDescriptors != null,
|
||||
specState.ComputeState.GetLocalSize());
|
||||
specState.TransformFeedbackDescriptors != null);
|
||||
|
||||
IProgram hostProgram;
|
||||
|
||||
|
@ -635,10 +629,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||
return;
|
||||
}
|
||||
|
||||
if (context.Capabilities.Api != TargetApi.Metal)
|
||||
{
|
||||
WriteHostCode(context, hostCode, program.Shaders, streams, timestamp);
|
||||
}
|
||||
WriteHostCode(context, hostCode, program.Shaders, streams, timestamp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
|
@ -367,9 +366,6 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||
{
|
||||
try
|
||||
{
|
||||
if (_context.Capabilities.Api == TargetApi.Metal && _context.DirtyHacks.IsEnabled(DirtyHack.ShaderTranslationDelay))
|
||||
Thread.Sleep(_context.DirtyHacks[DirtyHack.ShaderTranslationDelay]);
|
||||
|
||||
AsyncProgramTranslation asyncTranslation = new(guestShaders, specState, programIndex, isCompute);
|
||||
_asyncTranslationQueue.Add(asyncTranslation, _cancellationToken);
|
||||
}
|
||||
|
@ -494,12 +490,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||
{
|
||||
ShaderSource[] shaderSources = new ShaderSource[compilation.TranslatedStages.Length];
|
||||
|
||||
ref GpuChannelComputeState computeState = ref compilation.SpecializationState.ComputeState;
|
||||
|
||||
ShaderInfoBuilder shaderInfoBuilder = new(
|
||||
_context,
|
||||
compilation.SpecializationState.TransformFeedbackDescriptors != null,
|
||||
computeLocalSize: computeState.GetLocalSize());
|
||||
ShaderInfoBuilder shaderInfoBuilder = new(_context, compilation.SpecializationState.TransformFeedbackDescriptors != null);
|
||||
|
||||
for (int index = 0; index < compilation.TranslatedStages.Length; index++)
|
||||
{
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
private readonly GpuAccessorState _state;
|
||||
private readonly int _stageIndex;
|
||||
private readonly bool _compute;
|
||||
private readonly bool _isOpenGL;
|
||||
private readonly bool _isVulkan;
|
||||
private readonly bool _hasGeometryShader;
|
||||
private readonly bool _supportsQuads;
|
||||
|
||||
|
@ -39,7 +39,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
_channel = channel;
|
||||
_state = state;
|
||||
_stageIndex = stageIndex;
|
||||
_isOpenGL = context.Capabilities.Api == TargetApi.OpenGL;
|
||||
_isVulkan = context.Capabilities.Api == TargetApi.Vulkan;
|
||||
_hasGeometryShader = hasGeometryShader;
|
||||
_supportsQuads = context.Capabilities.SupportsQuads;
|
||||
|
||||
|
@ -117,10 +117,10 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
public GpuGraphicsState QueryGraphicsState()
|
||||
{
|
||||
return _state.GraphicsState.CreateShaderGraphicsState(
|
||||
_isOpenGL,
|
||||
!_isVulkan,
|
||||
_supportsQuads,
|
||||
_hasGeometryShader,
|
||||
!_isOpenGL || _state.GraphicsState.YNegateEnabled);
|
||||
_isVulkan || _state.GraphicsState.YNegateEnabled);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
{
|
||||
int binding;
|
||||
|
||||
if (_context.Capabilities.Api != TargetApi.OpenGL)
|
||||
if (_context.Capabilities.Api == TargetApi.Vulkan)
|
||||
{
|
||||
binding = GetBindingFromIndex(index, _context.Capabilities.MaximumUniformBuffersPerStage, "Uniform buffer");
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
{
|
||||
int binding;
|
||||
|
||||
if (_context.Capabilities.Api != TargetApi.OpenGL)
|
||||
if (_context.Capabilities.Api == TargetApi.Vulkan)
|
||||
{
|
||||
if (count == 1)
|
||||
{
|
||||
|
@ -103,7 +103,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
{
|
||||
int binding;
|
||||
|
||||
if (_context.Capabilities.Api != TargetApi.OpenGL)
|
||||
if (_context.Capabilities.Api == TargetApi.Vulkan)
|
||||
{
|
||||
binding = GetBindingFromIndex(index, _context.Capabilities.MaximumStorageBuffersPerStage, "Storage buffer");
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
{
|
||||
int binding;
|
||||
|
||||
if (_context.Capabilities.Api != TargetApi.OpenGL)
|
||||
if (_context.Capabilities.Api == TargetApi.Vulkan)
|
||||
{
|
||||
if (count == 1)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
using Ryujinx.Graphics.GAL;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Shader
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -63,14 +61,5 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
SharedMemorySize = sharedMemorySize;
|
||||
HasUnalignedStorageBuffer = hasUnalignedStorageBuffer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the local group size of the shader in a GAL compatible struct.
|
||||
/// </summary>
|
||||
/// <returns>Local group size</returns>
|
||||
public ComputeSize GetLocalSize()
|
||||
{
|
||||
return new ComputeSize(LocalSizeX, LocalSizeY, LocalSizeZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
private static string GetDiskCachePath()
|
||||
{
|
||||
return GraphicsConfig.EnableShaderCache && GraphicsConfig.TitleId != null
|
||||
? Path.Combine(AppDataManager.GamesDirPath, GraphicsConfig.TitleId.ToLower(), "cache", "shader")
|
||||
? Path.Combine(AppDataManager.GamesDirPath, GraphicsConfig.TitleId, "cache", "shader")
|
||||
: null;
|
||||
}
|
||||
|
||||
|
@ -204,7 +204,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
GpuChannelComputeState computeState,
|
||||
ulong gpuVa)
|
||||
{
|
||||
if (_cpPrograms.TryGetValue(gpuVa, out CachedShaderProgram cpShader) && IsShaderEqual(channel, poolState, computeState, cpShader, gpuVa))
|
||||
if (_cpPrograms.TryGetValue(gpuVa, out var cpShader) && IsShaderEqual(channel, poolState, computeState, cpShader, gpuVa))
|
||||
{
|
||||
return cpShader;
|
||||
}
|
||||
|
@ -223,11 +223,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
TranslatorContext translatorContext = DecodeComputeShader(gpuAccessor, _context.Capabilities.Api, gpuVa);
|
||||
TranslatedShader translatedShader = TranslateShader(_dumper, channel, translatorContext, cachedGuestCode, asCompute: false);
|
||||
|
||||
ShaderSource[] shaderSourcesArray = [CreateShaderSource(translatedShader.Program)];
|
||||
ShaderInfo info = ShaderInfoBuilder.BuildForCompute(
|
||||
_context,
|
||||
translatedShader.Program.Info,
|
||||
computeState.GetLocalSize());
|
||||
ShaderSource[] shaderSourcesArray = new ShaderSource[] { CreateShaderSource(translatedShader.Program) };
|
||||
ShaderInfo info = ShaderInfoBuilder.BuildForCompute(_context, translatedShader.Program.Info);
|
||||
IProgram hostProgram = _context.Renderer.CreateProgram(shaderSourcesArray, info);
|
||||
|
||||
cpShader = new CachedShaderProgram(hostProgram, specState, translatedShader.Shader);
|
||||
|
@ -254,8 +251,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
{
|
||||
channel.TextureManager.UpdateRenderTargets();
|
||||
|
||||
RtControl rtControl = state.RtControl;
|
||||
TextureMsaaMode msaaMode = state.RtMsaaMode;
|
||||
var rtControl = state.RtControl;
|
||||
var msaaMode = state.RtMsaaMode;
|
||||
|
||||
pipeline.SamplesCount = msaaMode.SamplesInX() * msaaMode.SamplesInY();
|
||||
|
||||
|
@ -265,7 +262,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
{
|
||||
int rtIndex = rtControl.UnpackPermutationIndex(index);
|
||||
|
||||
RtColorState colorState = state.RtColorState[rtIndex];
|
||||
var colorState = state.RtColorState[rtIndex];
|
||||
|
||||
if (index >= count || colorState.Format == 0 || colorState.WidthOrStride == 0)
|
||||
{
|
||||
|
@ -310,12 +307,12 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
ref GpuChannelGraphicsState graphicsState,
|
||||
ShaderAddresses addresses)
|
||||
{
|
||||
if (_gpPrograms.TryGetValue(addresses, out CachedShaderProgram gpShaders) && IsShaderEqual(channel, ref poolState, ref graphicsState, gpShaders, addresses))
|
||||
if (_gpPrograms.TryGetValue(addresses, out var gpShaders) && IsShaderEqual(channel, ref poolState, ref graphicsState, gpShaders, addresses))
|
||||
{
|
||||
return gpShaders;
|
||||
}
|
||||
|
||||
if (_graphicsShaderCache.TryFind(channel, ref poolState, ref graphicsState, addresses, out gpShaders, out CachedGraphicsGuestCode cachedGuestCode))
|
||||
if (_graphicsShaderCache.TryFind(channel, ref poolState, ref graphicsState, addresses, out gpShaders, out var cachedGuestCode))
|
||||
{
|
||||
_gpPrograms[addresses] = gpShaders;
|
||||
return gpShaders;
|
||||
|
@ -368,7 +365,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
bool geometryToCompute = ShouldConvertGeometryToCompute(_context, geometryHasStore);
|
||||
|
||||
CachedShaderStage[] shaders = new CachedShaderStage[Constants.ShaderStages + 1];
|
||||
List<ShaderSource> shaderSources = [];
|
||||
List<ShaderSource> shaderSources = new();
|
||||
|
||||
TranslatorContext previousStage = null;
|
||||
ShaderInfoBuilder infoBuilder = new(_context, transformFeedbackDescriptors != null, vertexToCompute);
|
||||
|
@ -428,8 +425,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
|
||||
TranslatorContext lastInVertexPipeline = geometryToCompute ? translatorContexts[4] ?? currentStage : currentStage;
|
||||
|
||||
(program, ShaderProgramInfo vacInfo) = lastInVertexPipeline.GenerateVertexPassthroughForCompute();
|
||||
infoBuilder.AddStageInfoVac(vacInfo);
|
||||
program = lastInVertexPipeline.GenerateVertexPassthroughForCompute();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -534,9 +530,9 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
private ShaderAsCompute CreateHostVertexAsComputeProgram(ShaderProgram program, TranslatorContext context, bool tfEnabled)
|
||||
{
|
||||
ShaderSource source = new(program.Code, program.BinaryCode, ShaderStage.Compute, program.Language);
|
||||
ShaderInfo info = ShaderInfoBuilder.BuildForVertexAsCompute(_context, program.Info, context.GetVertexAsComputeInfo(), tfEnabled);
|
||||
ShaderInfo info = ShaderInfoBuilder.BuildForVertexAsCompute(_context, program.Info, tfEnabled);
|
||||
|
||||
return new(_context.Renderer.CreateProgram([source], info), program.Info, context.GetResourceReservations());
|
||||
return new(_context.Renderer.CreateProgram(new[] { source }, info), program.Info, context.GetResourceReservations());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -586,7 +582,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
|
||||
for (int i = 0; i < Constants.TotalTransformFeedbackBuffers; i++)
|
||||
{
|
||||
TfState tf = state.TfState[i];
|
||||
var tf = state.TfState[i];
|
||||
|
||||
descs[i] = new TransformFeedbackDescriptor(
|
||||
tf.BufferIndex,
|
||||
|
@ -692,7 +688,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// <returns>The generated translator context</returns>
|
||||
public static TranslatorContext DecodeComputeShader(IGpuAccessor gpuAccessor, TargetApi api, ulong gpuVa)
|
||||
{
|
||||
TranslationOptions options = CreateTranslationOptions(api, DefaultFlags | TranslationFlags.Compute);
|
||||
var options = CreateTranslationOptions(api, DefaultFlags | TranslationFlags.Compute);
|
||||
return Translator.CreateContext(gpuVa, gpuAccessor, options);
|
||||
}
|
||||
|
||||
|
@ -709,7 +705,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// <returns>The generated translator context</returns>
|
||||
public static TranslatorContext DecodeGraphicsShader(IGpuAccessor gpuAccessor, TargetApi api, TranslationFlags flags, ulong gpuVa)
|
||||
{
|
||||
TranslationOptions options = CreateTranslationOptions(api, flags);
|
||||
var options = CreateTranslationOptions(api, flags);
|
||||
return Translator.CreateContext(gpuVa, gpuAccessor, options);
|
||||
}
|
||||
|
||||
|
@ -735,7 +731,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
{
|
||||
ulong cb1DataAddress = channel.BufferManager.GetGraphicsUniformBufferAddress(0, 1);
|
||||
|
||||
MemoryManager memoryManager = channel.MemoryManager;
|
||||
var memoryManager = channel.MemoryManager;
|
||||
|
||||
codeA ??= memoryManager.GetSpan(vertexA.Address, vertexA.Size).ToArray();
|
||||
codeB ??= memoryManager.GetSpan(currentStage.Address, currentStage.Size).ToArray();
|
||||
|
@ -773,7 +769,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// <returns>Compiled graphics shader code</returns>
|
||||
private static TranslatedShader TranslateShader(ShaderDumper dumper, GpuChannel channel, TranslatorContext context, byte[] code, bool asCompute)
|
||||
{
|
||||
MemoryManager memoryManager = channel.MemoryManager;
|
||||
var memoryManager = channel.MemoryManager;
|
||||
|
||||
ulong cb1DataAddress = context.Stage == ShaderStage.Compute
|
||||
? channel.BufferManager.GetComputeUniformBufferAddress(1)
|
||||
|
@ -801,7 +797,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
{
|
||||
if (address == MemoryManager.PteUnmapped || size == 0)
|
||||
{
|
||||
return [];
|
||||
return Array.Empty<byte>();
|
||||
}
|
||||
|
||||
return memoryManager.Physical.GetSpan(address, size).ToArray();
|
||||
|
@ -826,20 +822,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
|
||||
/// <summary>
|
||||
/// Creates shader translation options with the requested graphics API and flags.
|
||||
/// The shader language is chosen based on the current configuration and graphics API.
|
||||
/// The shader language is choosen based on the current configuration and graphics API.
|
||||
/// </summary>
|
||||
/// <param name="api">Target graphics API</param>
|
||||
/// <param name="flags">Translation flags</param>
|
||||
/// <returns>Translation options</returns>
|
||||
private static TranslationOptions CreateTranslationOptions(TargetApi api, TranslationFlags flags)
|
||||
{
|
||||
TargetLanguage lang = api switch
|
||||
{
|
||||
TargetApi.OpenGL => TargetLanguage.Glsl,
|
||||
TargetApi.Vulkan => GraphicsConfig.EnableSpirvCompilationOnVulkan ? TargetLanguage.Spirv : TargetLanguage.Glsl,
|
||||
TargetApi.Metal => TargetLanguage.Msl,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
TargetLanguage lang = GraphicsConfig.EnableSpirvCompilationOnVulkan && api == TargetApi.Vulkan
|
||||
? TargetLanguage.Spirv
|
||||
: TargetLanguage.Glsl;
|
||||
|
||||
return new TranslationOptions(lang, api, flags);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
ResourceStages.Geometry;
|
||||
|
||||
private readonly GpuContext _context;
|
||||
private readonly ComputeSize _computeLocalSize;
|
||||
|
||||
private int _fragmentOutputMap;
|
||||
|
||||
|
@ -40,11 +39,9 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// <param name="context">GPU context that owns the shaders that will be added to the builder</param>
|
||||
/// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param>
|
||||
/// <param name="vertexAsCompute">Indicates that the vertex shader will be emulated on a compute shader</param>
|
||||
/// <param name="computeLocalSize">Indicates the local thread size for a compute shader</param>
|
||||
public ShaderInfoBuilder(GpuContext context, bool tfEnabled, bool vertexAsCompute = false, ComputeSize computeLocalSize = default)
|
||||
public ShaderInfoBuilder(GpuContext context, bool tfEnabled, bool vertexAsCompute = false)
|
||||
{
|
||||
_context = context;
|
||||
_computeLocalSize = computeLocalSize;
|
||||
|
||||
_fragmentOutputMap = -1;
|
||||
|
||||
|
@ -98,7 +95,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
private void PopulateDescriptorAndUsages(ResourceStages stages, ResourceType type, int setIndex, int start, int count, bool write = false)
|
||||
{
|
||||
AddDescriptor(stages, type, setIndex, start, count);
|
||||
// AddUsage(stages, type, setIndex, start, count, write);
|
||||
AddUsage(stages, type, setIndex, start, count, write);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -162,25 +159,6 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
AddUsage(info.Images, stages, isImage: true);
|
||||
}
|
||||
|
||||
public void AddStageInfoVac(ShaderProgramInfo info)
|
||||
{
|
||||
ResourceStages stages = info.Stage switch
|
||||
{
|
||||
ShaderStage.Compute => ResourceStages.Compute,
|
||||
ShaderStage.Vertex => ResourceStages.Vertex,
|
||||
ShaderStage.TessellationControl => ResourceStages.TessellationControl,
|
||||
ShaderStage.TessellationEvaluation => ResourceStages.TessellationEvaluation,
|
||||
ShaderStage.Geometry => ResourceStages.Geometry,
|
||||
ShaderStage.Fragment => ResourceStages.Fragment,
|
||||
_ => ResourceStages.None,
|
||||
};
|
||||
|
||||
AddUsage(info.CBuffers, stages, isStorage: false);
|
||||
AddUsage(info.SBuffers, stages, isStorage: true);
|
||||
AddUsage(info.Textures, stages, isImage: false);
|
||||
AddUsage(info.Images, stages, isImage: true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a resource descriptor to the list of descriptors.
|
||||
/// </summary>
|
||||
|
@ -383,7 +361,14 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
|
||||
ResourceLayout resourceLayout = new(descriptors.AsReadOnly(), usages.AsReadOnly());
|
||||
|
||||
return new ShaderInfo(_fragmentOutputMap, resourceLayout, _computeLocalSize, pipeline, fromCache);
|
||||
if (pipeline.HasValue)
|
||||
{
|
||||
return new ShaderInfo(_fragmentOutputMap, resourceLayout, pipeline.Value, fromCache);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ShaderInfo(_fragmentOutputMap, resourceLayout, fromCache);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -393,16 +378,14 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// <param name="programs">Shaders from the disk cache</param>
|
||||
/// <param name="pipeline">Optional pipeline for background compilation</param>
|
||||
/// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param>
|
||||
/// <param name="computeLocalSize">Compute local thread size</param>
|
||||
/// <returns>Shader information</returns>
|
||||
public static ShaderInfo BuildForCache(
|
||||
GpuContext context,
|
||||
IEnumerable<CachedShaderStage> programs,
|
||||
ProgramPipelineState? pipeline,
|
||||
bool tfEnabled,
|
||||
ComputeSize computeLocalSize)
|
||||
bool tfEnabled)
|
||||
{
|
||||
ShaderInfoBuilder builder = new(context, tfEnabled, computeLocalSize: computeLocalSize);
|
||||
ShaderInfoBuilder builder = new(context, tfEnabled);
|
||||
|
||||
foreach (CachedShaderStage program in programs)
|
||||
{
|
||||
|
@ -420,12 +403,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// </summary>
|
||||
/// <param name="context">GPU context that owns the shader</param>
|
||||
/// <param name="info">Compute shader information</param>
|
||||
/// <param name="computeLocalSize">Compute local thread size</param>
|
||||
/// <param name="fromCache">True if the compute shader comes from a disk cache, false otherwise</param>
|
||||
/// <returns>Shader information</returns>
|
||||
public static ShaderInfo BuildForCompute(GpuContext context, ShaderProgramInfo info, ComputeSize computeLocalSize, bool fromCache = false)
|
||||
public static ShaderInfo BuildForCompute(GpuContext context, ShaderProgramInfo info, bool fromCache = false)
|
||||
{
|
||||
ShaderInfoBuilder builder = new(context, tfEnabled: false, vertexAsCompute: false, computeLocalSize: computeLocalSize);
|
||||
ShaderInfoBuilder builder = new(context, tfEnabled: false, vertexAsCompute: false);
|
||||
|
||||
builder.AddStageInfo(info);
|
||||
|
||||
|
@ -440,11 +422,10 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param>
|
||||
/// <param name="fromCache">True if the compute shader comes from a disk cache, false otherwise</param>
|
||||
/// <returns>Shader information</returns>
|
||||
public static ShaderInfo BuildForVertexAsCompute(GpuContext context, ShaderProgramInfo info, ShaderProgramInfo info2, bool tfEnabled, bool fromCache = false)
|
||||
public static ShaderInfo BuildForVertexAsCompute(GpuContext context, ShaderProgramInfo info, bool tfEnabled, bool fromCache = false)
|
||||
{
|
||||
ShaderInfoBuilder builder = new(context, tfEnabled, vertexAsCompute: true, computeLocalSize: ComputeSize.VtgAsCompute);
|
||||
ShaderInfoBuilder builder = new(context, tfEnabled, vertexAsCompute: true);
|
||||
|
||||
builder.AddStageInfoVac(info2);
|
||||
builder.AddStageInfo(info, vertexAsCompute: true);
|
||||
|
||||
return builder.Build(null, fromCache);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue