Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
04d68ca616 | ||
|
050f22977f | ||
|
319507f2a1 | ||
|
d717aef2be | ||
|
24ee8c39f1 |
4
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
4
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -23,7 +23,7 @@ body:
|
||||
attributes:
|
||||
label: Log file
|
||||
description: A log file will help our developers to better diagnose and fix the issue.
|
||||
placeholder: Logs files can be found under "Logs" folder in Ryujinx program folder. You can drag and drop the log on to the text area
|
||||
placeholder: Logs files can be found under "Logs" folder in Ryujinx program folder. They can also be accessed by opening Ryujinx, then going to File > Open Logs Folder. You can drag and drop the log on to the text area (do not copy paste).
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
@@ -83,4 +83,4 @@ body:
|
||||
- Additional info about your environment:
|
||||
- Any other information relevant to your issue.
|
||||
validations:
|
||||
required: false
|
||||
required: false
|
||||
|
@@ -13,6 +13,11 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// </summary>
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// True if the sampler has sRGB conversion enabled, false otherwise.
|
||||
/// </summary>
|
||||
public bool IsSrgb { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Host sampler object.
|
||||
/// </summary>
|
||||
@@ -30,6 +35,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// <param name="descriptor">The Maxwell sampler descriptor</param>
|
||||
public Sampler(GpuContext context, SamplerDescriptor descriptor)
|
||||
{
|
||||
IsSrgb = descriptor.UnpackSrgb();
|
||||
|
||||
MinFilter minFilter = descriptor.UnpackMinFilter();
|
||||
MagFilter magFilter = descriptor.UnpackMagFilter();
|
||||
|
||||
|
@@ -113,6 +113,15 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
return (CompareOp)(((Word0 >> 10) & 7) + 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks the sampler sRGB format flag.
|
||||
/// </summary>
|
||||
/// <returns>True if the has sampler is sRGB conversion enabled, false otherwise</returns>
|
||||
public readonly bool UnpackSrgb()
|
||||
{
|
||||
return (Word0 & (1 << 13)) != 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks and converts the maximum anisotropy value used for texture anisotropic filtering.
|
||||
/// </summary>
|
||||
|
@@ -187,7 +187,9 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
{
|
||||
(TexturePool texturePool, SamplerPool samplerPool) = GetPools();
|
||||
|
||||
return (texturePool.Get(textureId), samplerPool.Get(samplerId));
|
||||
Sampler sampler = samplerPool?.Get(samplerId);
|
||||
|
||||
return (texturePool.Get(textureId, sampler?.IsSrgb ?? true), sampler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -508,12 +510,12 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
state.TextureHandle = textureId;
|
||||
state.SamplerHandle = samplerId;
|
||||
|
||||
ref readonly TextureDescriptor descriptor = ref texturePool.GetForBinding(textureId, out Texture texture);
|
||||
Sampler sampler = samplerPool?.Get(samplerId);
|
||||
|
||||
ref readonly TextureDescriptor descriptor = ref texturePool.GetForBinding(textureId, sampler?.IsSrgb ?? true, out Texture texture);
|
||||
|
||||
specStateMatches &= specState.MatchesTexture(stage, index, descriptor);
|
||||
|
||||
Sampler sampler = samplerPool?.Get(samplerId);
|
||||
|
||||
ITexture hostTexture = texture?.GetTargetTexture(bindingInfo.Target);
|
||||
ISampler hostSampler = sampler?.GetHostSampler(texture);
|
||||
|
||||
|
@@ -227,6 +227,17 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// <param name="id">ID of the texture. This is effectively a zero-based index</param>
|
||||
/// <returns>The texture with the given ID</returns>
|
||||
public override Texture Get(int id)
|
||||
{
|
||||
return Get(id, srgbSampler: true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the texture with the given ID.
|
||||
/// </summary>
|
||||
/// <param name="id">ID of the texture. This is effectively a zero-based index</param>
|
||||
/// <param name="srgbSampler">Whether the texture is being accessed with a sampler that has sRGB conversion enabled</param>
|
||||
/// <returns>The texture with the given ID</returns>
|
||||
public Texture Get(int id, bool srgbSampler)
|
||||
{
|
||||
if ((uint)id >= Items.Length)
|
||||
{
|
||||
@@ -240,7 +251,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
SynchronizeMemory();
|
||||
}
|
||||
|
||||
GetInternal(id, out Texture texture);
|
||||
GetForBinding(id, srgbSampler, out Texture texture);
|
||||
|
||||
return texture;
|
||||
}
|
||||
@@ -252,9 +263,10 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// This method assumes that the pool has been manually synchronized before doing binding.
|
||||
/// </remarks>
|
||||
/// <param name="id">ID of the texture. This is effectively a zero-based index</param>
|
||||
/// <param name="srgbSampler">Whether the texture is being accessed with a sampler that has sRGB conversion enabled</param>
|
||||
/// <param name="texture">The texture with the given ID</param>
|
||||
/// <returns>The texture descriptor with the given ID</returns>
|
||||
public ref readonly TextureDescriptor GetForBinding(int id, out Texture texture)
|
||||
public ref readonly TextureDescriptor GetForBinding(int id, bool srgbSampler, out Texture texture)
|
||||
{
|
||||
if ((uint)id >= Items.Length)
|
||||
{
|
||||
@@ -264,6 +276,18 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
// When getting for binding, assume the pool has already been synchronized.
|
||||
|
||||
if (!srgbSampler)
|
||||
{
|
||||
// If the sampler does not have the sRGB bit enabled, then the texture can't use a sRGB format.
|
||||
ref readonly TextureDescriptor tempDescriptor = ref GetDescriptorRef(id);
|
||||
|
||||
if (tempDescriptor.UnpackSrgb() && FormatTable.TryGetTextureFormat(tempDescriptor.UnpackFormat(), isSrgb: false, out FormatInfo formatInfo))
|
||||
{
|
||||
// Get a view of the texture with the right format.
|
||||
return ref GetForBinding(id, formatInfo, out texture);
|
||||
}
|
||||
}
|
||||
|
||||
return ref GetInternal(id, out texture);
|
||||
}
|
||||
|
||||
|
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
||||
private const ushort FileFormatVersionMajor = 1;
|
||||
private const ushort FileFormatVersionMinor = 2;
|
||||
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
|
||||
private const uint CodeGenVersion = 7320;
|
||||
private const uint CodeGenVersion = 7353;
|
||||
|
||||
private const string SharedTocFileName = "shared.toc";
|
||||
private const string SharedDataFileName = "shared.data";
|
||||
|
@@ -138,6 +138,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
||||
// Ensure that conditions met for that branch are also met for the current one.
|
||||
// Prefer the latest sources for the phi node.
|
||||
|
||||
int undefCount = 0;
|
||||
|
||||
for (int i = phiNode.SourcesCount - 1; i >= 0; i--)
|
||||
{
|
||||
BasicBlock phiBlock = phiNode.GetBlock(i);
|
||||
@@ -159,6 +161,26 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
||||
return match;
|
||||
}
|
||||
}
|
||||
else if (phiSource.Type == OperandType.Undefined)
|
||||
{
|
||||
undefCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// If all sources but one are undefined, we can assume that the one
|
||||
// that is not undefined is the right one.
|
||||
|
||||
if (undefCount == phiNode.SourcesCount - 1)
|
||||
{
|
||||
for (int i = phiNode.SourcesCount - 1; i >= 0; i--)
|
||||
{
|
||||
Operand phiSource = phiNode.GetSource(i);
|
||||
|
||||
if (phiSource.Type != OperandType.Undefined)
|
||||
{
|
||||
return phiSource;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -190,7 +190,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||
|
||||
if (stage == ShaderStage.Vertex)
|
||||
{
|
||||
InitializePositionOutput(context);
|
||||
InitializeVertexOutputs(context);
|
||||
}
|
||||
|
||||
UInt128 usedAttributes = context.TranslatorContext.AttributeUsage.NextInputAttributesComponents;
|
||||
@@ -236,12 +236,20 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||
}
|
||||
}
|
||||
|
||||
private static void InitializePositionOutput(EmitterContext context)
|
||||
private static void InitializeVertexOutputs(EmitterContext context)
|
||||
{
|
||||
for (int c = 0; c < 4; c++)
|
||||
{
|
||||
context.Store(StorageKind.Output, IoVariable.Position, null, Const(c), ConstF(c == 3 ? 1f : 0f));
|
||||
}
|
||||
|
||||
if (context.Program.ClipDistancesWritten != 0)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
context.Store(StorageKind.Output, IoVariable.ClipDistance, null, Const(i), ConstF(0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void InitializeOutput(EmitterContext context, int location, bool perPatch)
|
||||
|
@@ -636,9 +636,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
var oldStencilTestEnable = _newState.StencilTestEnable;
|
||||
var oldDepthTestEnable = _newState.DepthTestEnable;
|
||||
var oldDepthWriteEnable = _newState.DepthWriteEnable;
|
||||
var oldTopology = _newState.Topology;
|
||||
var oldViewports = DynamicState.Viewports;
|
||||
var oldViewportsCount = _newState.ViewportsCount;
|
||||
var oldTopology = _topology;
|
||||
|
||||
_newState.CullMode = CullModeFlags.None;
|
||||
_newState.StencilTestEnable = false;
|
||||
@@ -658,7 +658,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_newState.StencilTestEnable = oldStencilTestEnable;
|
||||
_newState.DepthTestEnable = oldDepthTestEnable;
|
||||
_newState.DepthWriteEnable = oldDepthWriteEnable;
|
||||
_newState.Topology = oldTopology;
|
||||
SetPrimitiveTopology(oldTopology);
|
||||
|
||||
DynamicState.SetViewports(ref oldViewports, oldViewportsCount);
|
||||
|
||||
|
Reference in New Issue
Block a user