[ShaderCompiler] Widen host-evaluable scalar operations for descriptors
A resource descriptor the host materializes is built by replaying the shader's scalar operations on the host. The validator that decides whether a value can be replayed listed only part of what the scalar evaluator implements, so a descriptor computed through any of the others was rejected even though the host can compute it exactly. The list now covers every pure scalar function the evaluator supports: the remaining integer maximum, absolute value and high multiplies, the signed and unsigned comparisons, 64-bit equality, the bit-counting and bit-scanning operations, the quad mask, the integer/float conversions, and the float arithmetic and comparisons. Anything with side effects or a lane-varying result is still rejected.
This commit is contained in:
parent
ed08311ce4
commit
7c50c31988
|
|
@ -49,6 +49,15 @@ public sealed class RuntimeValueValidator
|
|||
ScalarOperation.LogicalOr or ScalarOperation.LogicalAnd or ScalarOperation.LogicalXor or ScalarOperation.LogicalNot or
|
||||
ScalarOperation.FLessThanEqual or ScalarOperation.FGreaterThanEqual or ScalarOperation.FIsNan or
|
||||
ScalarOperation.FMul or ScalarOperation.FTrunc => true,
|
||||
// Every other pure scalar function ScalarOperationSemantics evaluates is as uniform as the
|
||||
// ones above; a descriptor built through them was rejected although the host can compute it.
|
||||
ScalarOperation.UMax32 or ScalarOperation.IAbs32 or ScalarOperation.SMulHi32 or ScalarOperation.UMulHi32 or
|
||||
ScalarOperation.SLessThan32 or ScalarOperation.SLessThanEqual32 or ScalarOperation.SGreaterThan32 or ScalarOperation.SGreaterThanEqual32 or
|
||||
ScalarOperation.ULessThanEqual32 or ScalarOperation.UGreaterThanEqual32 or ScalarOperation.IEqual64 or ScalarOperation.INotEqual64 or
|
||||
ScalarOperation.BitCount32 or ScalarOperation.BitReverse32 or ScalarOperation.FindLowestBit32 or ScalarOperation.FindHighestBit32 or
|
||||
ScalarOperation.QuadMask32 or ScalarOperation.ConvertF32S32 or ScalarOperation.ConvertS32F32 or
|
||||
ScalarOperation.FAdd or ScalarOperation.FSub or ScalarOperation.FMin or ScalarOperation.FMax or
|
||||
ScalarOperation.FEqual or ScalarOperation.FNotEqual or ScalarOperation.FLessThan or ScalarOperation.FGreaterThan => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (C) 2026 SharpEmu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
using SharpEmu.ShaderCompiler.Resources;
|
||||
using Xunit;
|
||||
|
||||
namespace SharpEmu.ShaderCompiler.Tests;
|
||||
|
||||
public sealed class RuntimeValueValidatorTests
|
||||
{
|
||||
// The host evaluates runtime descriptor values with ScalarOperationSemantics, so the validator must
|
||||
// not reject an operation the evaluator can compute (Silent Hill's compute plans failed that way).
|
||||
[Fact]
|
||||
public void EveryEvaluableOperationIsAcceptedAsUniform()
|
||||
{
|
||||
ulong[] operands = [1, 2, 3, 4];
|
||||
foreach (var operation in Enum.GetValues<ScalarOperation>())
|
||||
{
|
||||
bool evaluable;
|
||||
try
|
||||
{
|
||||
evaluable = ScalarOperationSemantics.TryEvaluate(operation, operands, out _);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
evaluable = false;
|
||||
}
|
||||
|
||||
if (evaluable)
|
||||
{
|
||||
Assert.True(RuntimeValueValidator.IsUniformOperation(operation), $"{operation} is evaluable but not uniform.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue