Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
1dcd44b94f | ||
|
61b1ce252f | ||
|
5f38086f94 |
@@ -474,6 +474,13 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
{
|
{
|
||||||
address = memoryManager.Translate(info.GpuAddress);
|
address = memoryManager.Translate(info.GpuAddress);
|
||||||
|
|
||||||
|
// If the start address is unmapped, let's try to find a page of memory that is mapped.
|
||||||
|
if (address == MemoryManager.PteUnmapped)
|
||||||
|
{
|
||||||
|
address = memoryManager.TranslateFirstMapped(info.GpuAddress, (ulong)info.CalculateSizeInfo(layerSize).TotalSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If address is still invalid, the texture is fully unmapped, so it has no data, just return null.
|
||||||
if (address == MemoryManager.PteUnmapped)
|
if (address == MemoryManager.PteUnmapped)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
@@ -583,6 +583,38 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
return UnpackPaFromPte(pte) + (va & PageMask);
|
return UnpackPaFromPte(pte) + (va & PageMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Translates a GPU virtual address to a CPU virtual address on the first mapped page of memory
|
||||||
|
/// on the specified region.
|
||||||
|
/// If no page is mapped on the specified region, <see cref="PteUnmapped"/> is returned.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="va">GPU virtual address to be translated</param>
|
||||||
|
/// <param name="size">Size of the range to be translated</param>
|
||||||
|
/// <returns>CPU virtual address, or <see cref="PteUnmapped"/> if unmapped</returns>
|
||||||
|
public ulong TranslateFirstMapped(ulong va, ulong size)
|
||||||
|
{
|
||||||
|
if (!ValidateAddress(va))
|
||||||
|
{
|
||||||
|
return PteUnmapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong endVa = va + size;
|
||||||
|
|
||||||
|
ulong pte = GetPte(va);
|
||||||
|
|
||||||
|
for (; va < endVa && pte == PteUnmapped; va += PageSize - (va & PageMask))
|
||||||
|
{
|
||||||
|
pte = GetPte(va);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pte == PteUnmapped)
|
||||||
|
{
|
||||||
|
return PteUnmapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UnpackPaFromPte(pte) + (va & PageMask);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the kind of a given memory page.
|
/// Gets the kind of a given memory page.
|
||||||
/// This might indicate the type of resource that can be allocated on the page, and also texture tiling.
|
/// This might indicate the type of resource that can be allocated on the page, and also texture tiling.
|
||||||
|
@@ -397,20 +397,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
private static void DeclareInputAttributes(CodeGenContext context, StructuredProgramInfo info, bool perPatch)
|
private static void DeclareInputAttributes(CodeGenContext context, StructuredProgramInfo info, bool perPatch)
|
||||||
{
|
{
|
||||||
bool iaIndexing = context.Config.UsedFeatures.HasFlag(FeatureFlags.IaIndexing);
|
bool iaIndexing = context.Config.UsedFeatures.HasFlag(FeatureFlags.IaIndexing);
|
||||||
var inputs = perPatch ? info.InputsPerPatch : info.Inputs;
|
|
||||||
|
|
||||||
foreach (int attr in inputs)
|
if (iaIndexing && !perPatch)
|
||||||
{
|
|
||||||
if (!AttributeInfo.Validate(context.Config, attr, isOutAttr: false, perPatch))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isUserAttr = attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd;
|
|
||||||
|
|
||||||
if (iaIndexing && isUserAttr && !perPatch)
|
|
||||||
{
|
|
||||||
if (context.InputsArray == null)
|
|
||||||
{
|
{
|
||||||
var attrType = context.TypeVector(context.TypeFP32(), (LiteralInteger)4);
|
var attrType = context.TypeVector(context.TypeFP32(), (LiteralInteger)4);
|
||||||
attrType = context.TypeArray(attrType, context.Constant(context.TypeU32(), (LiteralInteger)MaxAttributes));
|
attrType = context.TypeArray(attrType, context.Constant(context.TypeU32(), (LiteralInteger)MaxAttributes));
|
||||||
@@ -433,9 +421,23 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
context.AddGlobalVariable(spvVar);
|
context.AddGlobalVariable(spvVar);
|
||||||
context.InputsArray = spvVar;
|
context.InputsArray = spvVar;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
var inputs = perPatch ? info.InputsPerPatch : info.Inputs;
|
||||||
|
|
||||||
|
foreach (int attr in inputs)
|
||||||
{
|
{
|
||||||
|
if (!AttributeInfo.Validate(context.Config, attr, isOutAttr: false, perPatch))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isUserAttr = attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd;
|
||||||
|
|
||||||
|
if (iaIndexing && isUserAttr && !perPatch)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
PixelImap iq = PixelImap.Unused;
|
PixelImap iq = PixelImap.Unused;
|
||||||
|
|
||||||
if (context.Config.Stage == ShaderStage.Fragment)
|
if (context.Config.Stage == ShaderStage.Fragment)
|
||||||
@@ -459,25 +461,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
DeclareInputOrOutput(context, attr, perPatch, isOutAttr: false, iq);
|
DeclareInputOrOutput(context, attr, perPatch, isOutAttr: false, iq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private static void DeclareOutputAttributes(CodeGenContext context, StructuredProgramInfo info, bool perPatch)
|
private static void DeclareOutputAttributes(CodeGenContext context, StructuredProgramInfo info, bool perPatch)
|
||||||
{
|
{
|
||||||
bool oaIndexing = context.Config.UsedFeatures.HasFlag(FeatureFlags.OaIndexing);
|
bool oaIndexing = context.Config.UsedFeatures.HasFlag(FeatureFlags.OaIndexing);
|
||||||
var outputs = perPatch ? info.OutputsPerPatch : info.Outputs;
|
|
||||||
|
|
||||||
foreach (int attr in outputs)
|
if (oaIndexing && !perPatch)
|
||||||
{
|
|
||||||
if (!AttributeInfo.Validate(context.Config, attr, isOutAttr: true, perPatch))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isUserAttr = attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd;
|
|
||||||
|
|
||||||
if (oaIndexing && isUserAttr && !perPatch)
|
|
||||||
{
|
|
||||||
if (context.OutputsArray == null)
|
|
||||||
{
|
{
|
||||||
var attrType = context.TypeVector(context.TypeFP32(), (LiteralInteger)4);
|
var attrType = context.TypeVector(context.TypeFP32(), (LiteralInteger)4);
|
||||||
attrType = context.TypeArray(attrType, context.Constant(context.TypeU32(), (LiteralInteger)MaxAttributes));
|
attrType = context.TypeArray(attrType, context.Constant(context.TypeU32(), (LiteralInteger)MaxAttributes));
|
||||||
@@ -495,11 +484,24 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
context.AddGlobalVariable(spvVar);
|
context.AddGlobalVariable(spvVar);
|
||||||
context.OutputsArray = spvVar;
|
context.OutputsArray = spvVar;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
var outputs = perPatch ? info.OutputsPerPatch : info.Outputs;
|
||||||
|
|
||||||
|
foreach (int attr in outputs)
|
||||||
{
|
{
|
||||||
DeclareOutputAttribute(context, attr, perPatch);
|
if (!AttributeInfo.Validate(context.Config, attr, isOutAttr: true, perPatch))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isUserAttr = attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd;
|
||||||
|
|
||||||
|
if (oaIndexing && isUserAttr && !perPatch)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeclareOutputAttribute(context, attr, perPatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.Config.Stage == ShaderStage.Vertex)
|
if (context.Config.Stage == ShaderStage.Vertex)
|
||||||
|
@@ -38,7 +38,9 @@ namespace Ryujinx.HLE.HOS.Services.Hid.HidServer
|
|||||||
|
|
||||||
public static bool IsValidNpadIdType(NpadIdType npadIdType)
|
public static bool IsValidNpadIdType(NpadIdType npadIdType)
|
||||||
{
|
{
|
||||||
return npadIdType <= NpadIdType.Player8 || npadIdType == NpadIdType.Handheld || npadIdType == NpadIdType.Unknown;
|
return (npadIdType >= NpadIdType.Player1 && npadIdType <= NpadIdType.Player8) ||
|
||||||
|
npadIdType == NpadIdType.Handheld ||
|
||||||
|
npadIdType == NpadIdType.Unknown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -722,7 +722,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
|||||||
|
|
||||||
for (int i = 0; i < supportedPlayerIds.Length; ++i)
|
for (int i = 0; i < supportedPlayerIds.Length; ++i)
|
||||||
{
|
{
|
||||||
if (supportedPlayerIds[i] >= 0)
|
if (HidUtils.IsValidNpadIdType(supportedPlayerIds[i]))
|
||||||
{
|
{
|
||||||
context.Device.Hid.Npads.SetSupportedPlayer(HidUtils.GetIndexFromNpadIdType(supportedPlayerIds[i]));
|
context.Device.Hid.Npads.SetSupportedPlayer(HidUtils.GetIndexFromNpadIdType(supportedPlayerIds[i]));
|
||||||
}
|
}
|
||||||
@@ -1101,7 +1101,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
|||||||
|
|
||||||
if (deviceType < NpadStyleIndex.System || deviceType >= NpadStyleIndex.FullKey)
|
if (deviceType < NpadStyleIndex.System || deviceType >= NpadStyleIndex.FullKey)
|
||||||
{
|
{
|
||||||
if (npadIdType >= (NpadIdType.Player8 + 1) && npadIdType != NpadIdType.Handheld && npadIdType != NpadIdType.Unknown)
|
if (!HidUtils.IsValidNpadIdType(npadIdType))
|
||||||
{
|
{
|
||||||
return ResultCode.InvalidNpadIdType;
|
return ResultCode.InvalidNpadIdType;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user