mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-27 13:11:04 +08:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e11d8a15c3 |
@@ -3493,6 +3493,29 @@ public static class AgcExports
|
|||||||
$"{drawViewport.Width:0.###}x{drawViewport.Height:0.###}:" +
|
$"{drawViewport.Width:0.###}x{drawViewport.Height:0.###}:" +
|
||||||
$"{drawViewport.MinDepth:0.###}-{drawViewport.MaxDepth:0.###}"
|
$"{drawViewport.MinDepth:0.###}-{drawViewport.MaxDepth:0.###}"
|
||||||
: "full";
|
: "full";
|
||||||
|
var rasterRegisters = new (string Name, uint Offset)[]
|
||||||
|
{
|
||||||
|
("screen_tl", PaScScreenScissorTl),
|
||||||
|
("screen_br", PaScScreenScissorBr),
|
||||||
|
("window_off", PaScWindowOffset),
|
||||||
|
("window_tl", PaScWindowScissorTl),
|
||||||
|
("window_br", PaScWindowScissorBr),
|
||||||
|
("generic_tl", PaScGenericScissorTl),
|
||||||
|
("generic_br", PaScGenericScissorBr),
|
||||||
|
("vport_tl", PaScVportScissor0Tl),
|
||||||
|
("vport_br", PaScVportScissor0Br),
|
||||||
|
("mode", PaScModeCntl0),
|
||||||
|
("xscale", PaClVportXScale),
|
||||||
|
("xoffset", PaClVportXOffset),
|
||||||
|
("yscale", PaClVportYScale),
|
||||||
|
("yoffset", PaClVportYOffset),
|
||||||
|
};
|
||||||
|
var raster = string.Join(
|
||||||
|
',',
|
||||||
|
rasterRegisters.Select(entry =>
|
||||||
|
state.CxRegisters.TryGetValue(entry.Offset, out var value)
|
||||||
|
? $"{entry.Name}=0x{value:X8}"
|
||||||
|
: $"{entry.Name}=missing"));
|
||||||
var blend = draw.RenderState.Blend;
|
var blend = draw.RenderState.Blend;
|
||||||
TraceAgcShader(
|
TraceAgcShader(
|
||||||
$"agc.shader_draw es=0x{draw.ExportShaderAddress:X16} " +
|
$"agc.shader_draw es=0x{draw.ExportShaderAddress:X16} " +
|
||||||
@@ -3500,6 +3523,7 @@ public static class AgcExports
|
|||||||
$"primitive=0x{draw.PrimitiveType:X} " +
|
$"primitive=0x{draw.PrimitiveType:X} " +
|
||||||
$"blend={(blend.Enable ? 1 : 0)}:{blend.ColorSrcFactor}/{blend.ColorDstFactor}/{blend.ColorFunc} " +
|
$"blend={(blend.Enable ? 1 : 0)}:{blend.ColorSrcFactor}/{blend.ColorDstFactor}/{blend.ColorFunc} " +
|
||||||
$"write_mask=0x{blend.WriteMask:X} scissor={scissor} viewport={viewport} " +
|
$"write_mask=0x{blend.WriteMask:X} scissor={scissor} viewport={viewport} " +
|
||||||
|
$"raster=[{raster}] " +
|
||||||
$"ps_ena=0x{psInputEna:X8} ps_addr=0x{psInputAddr:X8} " +
|
$"ps_ena=0x{psInputEna:X8} ps_addr=0x{psInputAddr:X8} " +
|
||||||
$"targets=[{targets}] textures=[{textures}] " +
|
$"targets=[{targets}] textures=[{textures}] " +
|
||||||
$"buffers=[{buffers}] vertex=[{vertexInputs}] indices=[{indices}]");
|
$"buffers=[{buffers}] vertex=[{vertexInputs}] indices=[{indices}]");
|
||||||
|
|||||||
@@ -812,7 +812,11 @@ internal static class Gen5ShaderScalarEvaluator
|
|||||||
"SFF1I32B32" => left == 0 ? uint.MaxValue : (uint)BitOperations.TrailingZeroCount(left),
|
"SFF1I32B32" => left == 0 ? uint.MaxValue : (uint)BitOperations.TrailingZeroCount(left),
|
||||||
_ => registers[destination.Value] | (1u << ((int)left & 31)),
|
_ => registers[destination.Value] | (1u << ((int)left & 31)),
|
||||||
};
|
};
|
||||||
|
if (instruction.Opcode != "SBitset1B32")
|
||||||
|
{
|
||||||
scalarConditionCode = registers[destination.Value] != 0;
|
scalarConditionCode = registers[destination.Value] != 0;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -838,13 +842,15 @@ internal static class Gen5ShaderScalarEvaluator
|
|||||||
}
|
}
|
||||||
case "SSubU32":
|
case "SSubU32":
|
||||||
result = left - right;
|
result = left - right;
|
||||||
scalarConditionCode = left >= right;
|
scalarConditionCode = right > left;
|
||||||
break;
|
break;
|
||||||
case "SAddI32":
|
case "SAddI32":
|
||||||
result = unchecked((uint)((int)left + (int)right));
|
result = unchecked((uint)((int)left + (int)right));
|
||||||
|
scalarConditionCode = SignedAddOverflow(left, right, result);
|
||||||
break;
|
break;
|
||||||
case "SSubI32":
|
case "SSubI32":
|
||||||
result = unchecked((uint)((int)left - (int)right));
|
result = unchecked((uint)((int)left - (int)right));
|
||||||
|
scalarConditionCode = SignedSubOverflow(left, right, result);
|
||||||
break;
|
break;
|
||||||
case "SAddcU32":
|
case "SAddcU32":
|
||||||
{
|
{
|
||||||
@@ -855,23 +861,27 @@ internal static class Gen5ShaderScalarEvaluator
|
|||||||
}
|
}
|
||||||
case "SSubbU32":
|
case "SSubbU32":
|
||||||
{
|
{
|
||||||
var borrow = scalarConditionCode ? 0UL : 1UL;
|
var borrow = scalarConditionCode ? 1UL : 0UL;
|
||||||
var subtrahend = (ulong)right + borrow;
|
var subtrahend = (ulong)right + borrow;
|
||||||
result = unchecked(left - (uint)subtrahend);
|
result = unchecked(left - (uint)subtrahend);
|
||||||
scalarConditionCode = left >= subtrahend;
|
scalarConditionCode = subtrahend > left;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "SMinI32":
|
case "SMinI32":
|
||||||
result = unchecked((uint)Math.Min((int)left, (int)right));
|
result = unchecked((uint)Math.Min((int)left, (int)right));
|
||||||
|
scalarConditionCode = (int)left < (int)right;
|
||||||
break;
|
break;
|
||||||
case "SMinU32":
|
case "SMinU32":
|
||||||
result = Math.Min(left, right);
|
result = Math.Min(left, right);
|
||||||
|
scalarConditionCode = left < right;
|
||||||
break;
|
break;
|
||||||
case "SMaxI32":
|
case "SMaxI32":
|
||||||
result = unchecked((uint)Math.Max((int)left, (int)right));
|
result = unchecked((uint)Math.Max((int)left, (int)right));
|
||||||
|
scalarConditionCode = (int)left > (int)right;
|
||||||
break;
|
break;
|
||||||
case "SMaxU32":
|
case "SMaxU32":
|
||||||
result = Math.Max(left, right);
|
result = Math.Max(left, right);
|
||||||
|
scalarConditionCode = left > right;
|
||||||
break;
|
break;
|
||||||
case "SCselectB32":
|
case "SCselectB32":
|
||||||
result = scalarConditionCode ? left : right;
|
result = scalarConditionCode ? left : right;
|
||||||
@@ -935,6 +945,7 @@ internal static class Gen5ShaderScalarEvaluator
|
|||||||
var offset = (int)right & 31;
|
var offset = (int)right & 31;
|
||||||
var width = Math.Min(((int)right >> 16) & 0x7F, 32 - offset);
|
var width = Math.Min(((int)right >> 16) & 0x7F, 32 - offset);
|
||||||
result = width == 0 ? 0 : left >> offset & (uint.MaxValue >> (32 - width));
|
result = width == 0 ? 0 : left >> offset & (uint.MaxValue >> (32 - width));
|
||||||
|
scalarConditionCode = result != 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "SBfeI32":
|
case "SBfeI32":
|
||||||
@@ -944,23 +955,41 @@ internal static class Gen5ShaderScalarEvaluator
|
|||||||
result = width == 0
|
result = width == 0
|
||||||
? 0
|
? 0
|
||||||
: unchecked((uint)(((int)(left << (32 - width - offset))) >> (32 - width)));
|
: unchecked((uint)(((int)(left << (32 - width - offset))) >> (32 - width)));
|
||||||
|
scalarConditionCode = result != 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "SAbsdiffI32":
|
case "SAbsdiffI32":
|
||||||
result = unchecked((uint)Math.Abs((long)(int)left - (int)right));
|
result = unchecked((uint)Math.Abs((long)(int)left - (int)right));
|
||||||
|
scalarConditionCode = result != 0;
|
||||||
break;
|
break;
|
||||||
case "SLshl1AddU32":
|
case "SLshl1AddU32":
|
||||||
result = (left << 1) + right;
|
{
|
||||||
|
var wide = ((ulong)left << 1) + right;
|
||||||
|
result = (uint)wide;
|
||||||
|
scalarConditionCode = wide > uint.MaxValue;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case "SLshl2AddU32":
|
case "SLshl2AddU32":
|
||||||
result = (left << 2) + right;
|
{
|
||||||
|
var wide = ((ulong)left << 2) + right;
|
||||||
|
result = (uint)wide;
|
||||||
|
scalarConditionCode = wide > uint.MaxValue;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case "SLshl3AddU32":
|
case "SLshl3AddU32":
|
||||||
result = (left << 3) + right;
|
{
|
||||||
|
var wide = ((ulong)left << 3) + right;
|
||||||
|
result = (uint)wide;
|
||||||
|
scalarConditionCode = wide > uint.MaxValue;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case "SLshl4AddU32":
|
case "SLshl4AddU32":
|
||||||
result = (left << 4) + right;
|
{
|
||||||
|
var wide = ((ulong)left << 4) + right;
|
||||||
|
result = (uint)wide;
|
||||||
|
scalarConditionCode = wide > uint.MaxValue;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case "SPackLlB32B16":
|
case "SPackLlB32B16":
|
||||||
result = (left & 0xFFFFu) | (right << 16);
|
result = (left & 0xFFFFu) | (right << 16);
|
||||||
break;
|
break;
|
||||||
@@ -1002,7 +1031,8 @@ internal static class Gen5ShaderScalarEvaluator
|
|||||||
"SNandSaveexecB64" or
|
"SNandSaveexecB64" or
|
||||||
"SNorSaveexecB64" or
|
"SNorSaveexecB64" or
|
||||||
"SXnorSaveexecB64" or
|
"SXnorSaveexecB64" or
|
||||||
"SAndn1SaveexecB64"))
|
"SAndn1SaveexecB64" or
|
||||||
|
"SOrn1SaveexecB64"))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1030,11 +1060,12 @@ internal static class Gen5ShaderScalarEvaluator
|
|||||||
"SAndSaveexecB64" => oldExec & source,
|
"SAndSaveexecB64" => oldExec & source,
|
||||||
"SOrSaveexecB64" => oldExec | source,
|
"SOrSaveexecB64" => oldExec | source,
|
||||||
"SXorSaveexecB64" => oldExec ^ source,
|
"SXorSaveexecB64" => oldExec ^ source,
|
||||||
"SAndn1SaveexecB64" => ~oldExec & source,
|
"SAndn1SaveexecB64" => ~source & oldExec,
|
||||||
"SAndn2SaveexecB64" => oldExec & ~source,
|
"SAndn2SaveexecB64" => source & ~oldExec,
|
||||||
"SOrn2SaveexecB64" => oldExec | ~source,
|
"SOrn1SaveexecB64" => ~source | oldExec,
|
||||||
"SNandSaveexecB64" => ~(oldExec & source),
|
"SOrn2SaveexecB64" => source | ~oldExec,
|
||||||
"SNorSaveexecB64" => ~(oldExec | source),
|
"SNandSaveexecB64" => ~(source & oldExec),
|
||||||
|
"SNorSaveexecB64" => ~(source | oldExec),
|
||||||
_ => ~(oldExec ^ source),
|
_ => ~(oldExec ^ source),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1104,6 +1135,12 @@ internal static class Gen5ShaderScalarEvaluator
|
|||||||
|
|
||||||
private static ulong MaskWaveValue(ulong value) => value & RdnaWaveMask;
|
private static ulong MaskWaveValue(ulong value) => value & RdnaWaveMask;
|
||||||
|
|
||||||
|
private static bool SignedAddOverflow(uint left, uint right, uint result) =>
|
||||||
|
((left ^ result) & (right ^ result) & 0x80000000u) != 0;
|
||||||
|
|
||||||
|
private static bool SignedSubOverflow(uint left, uint right, uint result) =>
|
||||||
|
((left ^ right) & (left ^ result) & 0x80000000u) != 0;
|
||||||
|
|
||||||
private static bool TryExecuteScalarCompare(
|
private static bool TryExecuteScalarCompare(
|
||||||
Gen5ShaderInstruction instruction,
|
Gen5ShaderInstruction instruction,
|
||||||
uint[] registers,
|
uint[] registers,
|
||||||
|
|||||||
@@ -452,6 +452,7 @@ internal static class Gen5ShaderTranslator
|
|||||||
0x2A => "SNorSaveexecB64",
|
0x2A => "SNorSaveexecB64",
|
||||||
0x2B => "SXnorSaveexecB64",
|
0x2B => "SXnorSaveexecB64",
|
||||||
0x37 => "SAndn1SaveexecB64",
|
0x37 => "SAndn1SaveexecB64",
|
||||||
|
0x38 => "SOrn1SaveexecB64",
|
||||||
_ => string.Empty,
|
_ => string.Empty,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -649,6 +649,20 @@ internal static partial class Gen5SpirvTranslator
|
|||||||
width);
|
width);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "VBfiB32":
|
||||||
|
{
|
||||||
|
var mask = GetRawSource(instruction, 0);
|
||||||
|
var insert = GetRawSource(instruction, 1);
|
||||||
|
var source = GetRawSource(instruction, 2);
|
||||||
|
result = _module.AddInstruction(
|
||||||
|
SpirvOp.BitwiseOr,
|
||||||
|
_uintType,
|
||||||
|
BitwiseAnd(mask, insert),
|
||||||
|
BitwiseAnd(
|
||||||
|
_module.AddInstruction(SpirvOp.Not, _uintType, mask),
|
||||||
|
source));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "VCvtPkrtzF16F32":
|
case "VCvtPkrtzF16F32":
|
||||||
{
|
{
|
||||||
var first = TruncateFloat32ForPack(GetFloatSource(instruction, 0));
|
var first = TruncateFloat32ForPack(GetFloatSource(instruction, 0));
|
||||||
@@ -961,6 +975,16 @@ internal static partial class Gen5SpirvTranslator
|
|||||||
StoreS(destination, result);
|
StoreS(destination, result);
|
||||||
Store(_scc, IsNotZero(result));
|
Store(_scc, IsNotZero(result));
|
||||||
return true;
|
return true;
|
||||||
|
case "SBitset1B32":
|
||||||
|
result = _module.AddInstruction(
|
||||||
|
SpirvOp.BitFieldInsert,
|
||||||
|
_uintType,
|
||||||
|
LoadS(destination),
|
||||||
|
UInt(1),
|
||||||
|
BitwiseAnd(left, UInt(31)),
|
||||||
|
UInt(1));
|
||||||
|
StoreS(destination, result);
|
||||||
|
return true;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
if (instruction.Sources.Count < 2)
|
if (instruction.Sources.Count < 2)
|
||||||
@@ -987,13 +1011,14 @@ internal static partial class Gen5SpirvTranslator
|
|||||||
left,
|
left,
|
||||||
right);
|
right);
|
||||||
Store(_scc, _module.AddInstruction(
|
Store(_scc, _module.AddInstruction(
|
||||||
SpirvOp.UGreaterThanEqual,
|
SpirvOp.UGreaterThan,
|
||||||
_boolType,
|
_boolType,
|
||||||
left,
|
right,
|
||||||
right));
|
left));
|
||||||
break;
|
break;
|
||||||
case "SAddI32":
|
case "SAddI32":
|
||||||
result = IAdd(left, right);
|
result = IAdd(left, right);
|
||||||
|
Store(_scc, SignedAddOverflow(left, right, result));
|
||||||
break;
|
break;
|
||||||
case "SSubI32":
|
case "SSubI32":
|
||||||
result = _module.AddInstruction(
|
result = _module.AddInstruction(
|
||||||
@@ -1001,6 +1026,7 @@ internal static partial class Gen5SpirvTranslator
|
|||||||
_uintType,
|
_uintType,
|
||||||
left,
|
left,
|
||||||
right);
|
right);
|
||||||
|
Store(_scc, SignedSubOverflow(left, right, result));
|
||||||
break;
|
break;
|
||||||
case "SAddcU32":
|
case "SAddcU32":
|
||||||
{
|
{
|
||||||
@@ -1037,8 +1063,8 @@ internal static partial class Gen5SpirvTranslator
|
|||||||
SpirvOp.Select,
|
SpirvOp.Select,
|
||||||
_uintType,
|
_uintType,
|
||||||
Load(_boolType, _scc),
|
Load(_boolType, _scc),
|
||||||
UInt(0),
|
UInt(1),
|
||||||
UInt(1));
|
UInt(0));
|
||||||
var partial = _module.AddInstruction(
|
var partial = _module.AddInstruction(
|
||||||
SpirvOp.ISub,
|
SpirvOp.ISub,
|
||||||
_uintType,
|
_uintType,
|
||||||
@@ -1049,23 +1075,31 @@ internal static partial class Gen5SpirvTranslator
|
|||||||
_uintType,
|
_uintType,
|
||||||
partial,
|
partial,
|
||||||
borrow);
|
borrow);
|
||||||
var firstNoBorrow = _module.AddInstruction(
|
var firstBorrow = _module.AddInstruction(
|
||||||
SpirvOp.UGreaterThanEqual,
|
SpirvOp.UGreaterThan,
|
||||||
_boolType,
|
_boolType,
|
||||||
left,
|
right,
|
||||||
right);
|
left);
|
||||||
var secondNoBorrow = _module.AddInstruction(
|
var secondBorrow = _module.AddInstruction(
|
||||||
SpirvOp.UGreaterThanEqual,
|
SpirvOp.LogicalAnd,
|
||||||
_boolType,
|
_boolType,
|
||||||
partial,
|
_module.AddInstruction(
|
||||||
borrow);
|
SpirvOp.IEqual,
|
||||||
|
_boolType,
|
||||||
|
borrow,
|
||||||
|
UInt(1)),
|
||||||
|
_module.AddInstruction(
|
||||||
|
SpirvOp.IEqual,
|
||||||
|
_boolType,
|
||||||
|
right,
|
||||||
|
left));
|
||||||
Store(
|
Store(
|
||||||
_scc,
|
_scc,
|
||||||
_module.AddInstruction(
|
_module.AddInstruction(
|
||||||
SpirvOp.LogicalAnd,
|
SpirvOp.LogicalOr,
|
||||||
_boolType,
|
_boolType,
|
||||||
firstNoBorrow,
|
firstBorrow,
|
||||||
secondNoBorrow));
|
secondBorrow));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "SMulI32":
|
case "SMulI32":
|
||||||
@@ -1077,6 +1111,7 @@ internal static partial class Gen5SpirvTranslator
|
|||||||
break;
|
break;
|
||||||
case "SAndB32":
|
case "SAndB32":
|
||||||
result = BitwiseAnd(left, right);
|
result = BitwiseAnd(left, right);
|
||||||
|
Store(_scc, IsNotZero(result));
|
||||||
break;
|
break;
|
||||||
case "SOrB32":
|
case "SOrB32":
|
||||||
result = _module.AddInstruction(
|
result = _module.AddInstruction(
|
||||||
@@ -1084,6 +1119,7 @@ internal static partial class Gen5SpirvTranslator
|
|||||||
_uintType,
|
_uintType,
|
||||||
left,
|
left,
|
||||||
right);
|
right);
|
||||||
|
Store(_scc, IsNotZero(result));
|
||||||
break;
|
break;
|
||||||
case "SXorB32":
|
case "SXorB32":
|
||||||
result = _module.AddInstruction(
|
result = _module.AddInstruction(
|
||||||
@@ -1091,22 +1127,64 @@ internal static partial class Gen5SpirvTranslator
|
|||||||
_uintType,
|
_uintType,
|
||||||
left,
|
left,
|
||||||
right);
|
right);
|
||||||
|
Store(_scc, IsNotZero(result));
|
||||||
break;
|
break;
|
||||||
case "SAndn2B32":
|
case "SAndn2B32":
|
||||||
result = BitwiseAnd(
|
result = BitwiseAnd(
|
||||||
left,
|
left,
|
||||||
_module.AddInstruction(SpirvOp.Not, _uintType, right));
|
_module.AddInstruction(SpirvOp.Not, _uintType, right));
|
||||||
|
Store(_scc, IsNotZero(result));
|
||||||
|
break;
|
||||||
|
case "SOrn2B32":
|
||||||
|
result = _module.AddInstruction(
|
||||||
|
SpirvOp.BitwiseOr,
|
||||||
|
_uintType,
|
||||||
|
left,
|
||||||
|
_module.AddInstruction(SpirvOp.Not, _uintType, right));
|
||||||
|
Store(_scc, IsNotZero(result));
|
||||||
|
break;
|
||||||
|
case "SNandB32":
|
||||||
|
result = _module.AddInstruction(
|
||||||
|
SpirvOp.Not,
|
||||||
|
_uintType,
|
||||||
|
BitwiseAnd(left, right));
|
||||||
|
Store(_scc, IsNotZero(result));
|
||||||
|
break;
|
||||||
|
case "SNorB32":
|
||||||
|
result = _module.AddInstruction(
|
||||||
|
SpirvOp.Not,
|
||||||
|
_uintType,
|
||||||
|
_module.AddInstruction(
|
||||||
|
SpirvOp.BitwiseOr,
|
||||||
|
_uintType,
|
||||||
|
left,
|
||||||
|
right));
|
||||||
|
Store(_scc, IsNotZero(result));
|
||||||
|
break;
|
||||||
|
case "SXnorB32":
|
||||||
|
result = _module.AddInstruction(
|
||||||
|
SpirvOp.Not,
|
||||||
|
_uintType,
|
||||||
|
_module.AddInstruction(
|
||||||
|
SpirvOp.BitwiseXor,
|
||||||
|
_uintType,
|
||||||
|
left,
|
||||||
|
right));
|
||||||
|
Store(_scc, IsNotZero(result));
|
||||||
break;
|
break;
|
||||||
case "SLshlB32":
|
case "SLshlB32":
|
||||||
result = ShiftLeftLogical(left, right);
|
result = ShiftLeftLogical(left, right);
|
||||||
|
Store(_scc, IsNotZero(result));
|
||||||
break;
|
break;
|
||||||
case "SLshrB32":
|
case "SLshrB32":
|
||||||
result = ShiftRightLogical(
|
result = ShiftRightLogical(
|
||||||
left,
|
left,
|
||||||
BitwiseAnd(right, UInt(31)));
|
BitwiseAnd(right, UInt(31)));
|
||||||
|
Store(_scc, IsNotZero(result));
|
||||||
break;
|
break;
|
||||||
case "SAshrI32":
|
case "SAshrI32":
|
||||||
result = ShiftRightArithmetic(left, right);
|
result = ShiftRightArithmetic(left, right);
|
||||||
|
Store(_scc, IsNotZero(result));
|
||||||
break;
|
break;
|
||||||
case "SBfmB32":
|
case "SBfmB32":
|
||||||
result = _module.AddInstruction(
|
result = _module.AddInstruction(
|
||||||
@@ -1149,6 +1227,7 @@ internal static partial class Gen5SpirvTranslator
|
|||||||
left,
|
left,
|
||||||
offset,
|
offset,
|
||||||
width);
|
width);
|
||||||
|
Store(_scc, IsNotZero(result));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "SCselectB32":
|
case "SCselectB32":
|
||||||
@@ -1161,9 +1240,47 @@ internal static partial class Gen5SpirvTranslator
|
|||||||
break;
|
break;
|
||||||
case "SMinU32":
|
case "SMinU32":
|
||||||
result = Ext(38, _uintType, left, right);
|
result = Ext(38, _uintType, left, right);
|
||||||
|
Store(
|
||||||
|
_scc,
|
||||||
|
_module.AddInstruction(
|
||||||
|
SpirvOp.ULessThan,
|
||||||
|
_boolType,
|
||||||
|
left,
|
||||||
|
right));
|
||||||
|
break;
|
||||||
|
case "SMinI32":
|
||||||
|
result = Bitcast(
|
||||||
|
_uintType,
|
||||||
|
Ext(39, _intType, Bitcast(_intType, left), Bitcast(_intType, right)));
|
||||||
|
Store(
|
||||||
|
_scc,
|
||||||
|
_module.AddInstruction(
|
||||||
|
SpirvOp.SLessThan,
|
||||||
|
_boolType,
|
||||||
|
Bitcast(_intType, left),
|
||||||
|
Bitcast(_intType, right)));
|
||||||
break;
|
break;
|
||||||
case "SMaxU32":
|
case "SMaxU32":
|
||||||
result = Ext(41, _uintType, left, right);
|
result = Ext(41, _uintType, left, right);
|
||||||
|
Store(
|
||||||
|
_scc,
|
||||||
|
_module.AddInstruction(
|
||||||
|
SpirvOp.UGreaterThan,
|
||||||
|
_boolType,
|
||||||
|
left,
|
||||||
|
right));
|
||||||
|
break;
|
||||||
|
case "SMaxI32":
|
||||||
|
result = Bitcast(
|
||||||
|
_uintType,
|
||||||
|
Ext(42, _intType, Bitcast(_intType, left), Bitcast(_intType, right)));
|
||||||
|
Store(
|
||||||
|
_scc,
|
||||||
|
_module.AddInstruction(
|
||||||
|
SpirvOp.SGreaterThan,
|
||||||
|
_boolType,
|
||||||
|
Bitcast(_intType, left),
|
||||||
|
Bitcast(_intType, right)));
|
||||||
break;
|
break;
|
||||||
case "SLshl1AddU32":
|
case "SLshl1AddU32":
|
||||||
case "SLshl2AddU32":
|
case "SLshl2AddU32":
|
||||||
@@ -1308,17 +1425,55 @@ internal static partial class Gen5SpirvTranslator
|
|||||||
"SXorSaveexecB64" => _module.AddInstruction(
|
"SXorSaveexecB64" => _module.AddInstruction(
|
||||||
SpirvOp.BitwiseXor, _ulongType, oldExec, left),
|
SpirvOp.BitwiseXor, _ulongType, oldExec, left),
|
||||||
"SAndn2SaveexecB64" => _module.AddInstruction(
|
"SAndn2SaveexecB64" => _module.AddInstruction(
|
||||||
SpirvOp.BitwiseAnd, _ulongType, oldExec, notLeft),
|
|
||||||
"SAndn1SaveexecB64" => _module.AddInstruction(
|
|
||||||
SpirvOp.BitwiseAnd,
|
SpirvOp.BitwiseAnd,
|
||||||
_ulongType,
|
_ulongType,
|
||||||
|
left,
|
||||||
_module.AddInstruction(
|
_module.AddInstruction(
|
||||||
SpirvOp.Not,
|
SpirvOp.Not,
|
||||||
_ulongType,
|
_ulongType,
|
||||||
|
oldExec)),
|
||||||
|
"SAndn1SaveexecB64" => _module.AddInstruction(
|
||||||
|
SpirvOp.BitwiseAnd,
|
||||||
|
_ulongType,
|
||||||
|
notLeft,
|
||||||
|
oldExec),
|
||||||
|
"SOrn1SaveexecB64" => _module.AddInstruction(
|
||||||
|
SpirvOp.BitwiseOr,
|
||||||
|
_ulongType,
|
||||||
|
notLeft,
|
||||||
oldExec),
|
oldExec),
|
||||||
left),
|
|
||||||
"SOrn2SaveexecB64" => _module.AddInstruction(
|
"SOrn2SaveexecB64" => _module.AddInstruction(
|
||||||
SpirvOp.BitwiseOr, _ulongType, oldExec, notLeft),
|
SpirvOp.BitwiseOr,
|
||||||
|
_ulongType,
|
||||||
|
left,
|
||||||
|
_module.AddInstruction(
|
||||||
|
SpirvOp.Not,
|
||||||
|
_ulongType,
|
||||||
|
oldExec)),
|
||||||
|
"SNandSaveexecB64" => _module.AddInstruction(
|
||||||
|
SpirvOp.Not,
|
||||||
|
_ulongType,
|
||||||
|
_module.AddInstruction(
|
||||||
|
SpirvOp.BitwiseAnd,
|
||||||
|
_ulongType,
|
||||||
|
left,
|
||||||
|
oldExec)),
|
||||||
|
"SNorSaveexecB64" => _module.AddInstruction(
|
||||||
|
SpirvOp.Not,
|
||||||
|
_ulongType,
|
||||||
|
_module.AddInstruction(
|
||||||
|
SpirvOp.BitwiseOr,
|
||||||
|
_ulongType,
|
||||||
|
left,
|
||||||
|
oldExec)),
|
||||||
|
"SXnorSaveexecB64" => _module.AddInstruction(
|
||||||
|
SpirvOp.Not,
|
||||||
|
_ulongType,
|
||||||
|
_module.AddInstruction(
|
||||||
|
SpirvOp.BitwiseXor,
|
||||||
|
_ulongType,
|
||||||
|
left,
|
||||||
|
oldExec)),
|
||||||
_ => 0u,
|
_ => 0u,
|
||||||
};
|
};
|
||||||
if (newExec == 0)
|
if (newExec == 0)
|
||||||
@@ -1524,6 +1679,22 @@ internal static partial class Gen5SpirvTranslator
|
|||||||
}
|
}
|
||||||
|
|
||||||
StoreS64(destination, value);
|
StoreS64(destination, value);
|
||||||
|
if (instruction.Opcode is
|
||||||
|
"SNotB64" or
|
||||||
|
"SAndB64" or
|
||||||
|
"SOrB64" or
|
||||||
|
"SXorB64" or
|
||||||
|
"SAndn1B64" or
|
||||||
|
"SAndn2B64" or
|
||||||
|
"SOrn1B64" or
|
||||||
|
"SOrn2B64" or
|
||||||
|
"SNandB64" or
|
||||||
|
"SNorB64" or
|
||||||
|
"SXnorB64")
|
||||||
|
{
|
||||||
|
Store(_scc, IsNotZero64(value));
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2110,6 +2281,53 @@ internal static partial class Gen5SpirvTranslator
|
|||||||
value,
|
value,
|
||||||
_module.Constant64(_ulongType, 0));
|
_module.Constant64(_ulongType, 0));
|
||||||
|
|
||||||
|
private uint SignBit(uint value) =>
|
||||||
|
ShiftRightLogical(value, UInt(31));
|
||||||
|
|
||||||
|
private uint SignedAddOverflow(uint left, uint right, uint result)
|
||||||
|
{
|
||||||
|
var leftSign = SignBit(left);
|
||||||
|
var rightSign = SignBit(right);
|
||||||
|
var resultSign = SignBit(result);
|
||||||
|
var sameSourceSign = _module.AddInstruction(
|
||||||
|
SpirvOp.IEqual,
|
||||||
|
_boolType,
|
||||||
|
leftSign,
|
||||||
|
rightSign);
|
||||||
|
var resultSignChanged = _module.AddInstruction(
|
||||||
|
SpirvOp.INotEqual,
|
||||||
|
_boolType,
|
||||||
|
leftSign,
|
||||||
|
resultSign);
|
||||||
|
return _module.AddInstruction(
|
||||||
|
SpirvOp.LogicalAnd,
|
||||||
|
_boolType,
|
||||||
|
sameSourceSign,
|
||||||
|
resultSignChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
private uint SignedSubOverflow(uint left, uint right, uint result)
|
||||||
|
{
|
||||||
|
var leftSign = SignBit(left);
|
||||||
|
var rightSign = SignBit(right);
|
||||||
|
var resultSign = SignBit(result);
|
||||||
|
var differentSourceSign = _module.AddInstruction(
|
||||||
|
SpirvOp.INotEqual,
|
||||||
|
_boolType,
|
||||||
|
leftSign,
|
||||||
|
rightSign);
|
||||||
|
var resultSignChanged = _module.AddInstruction(
|
||||||
|
SpirvOp.INotEqual,
|
||||||
|
_boolType,
|
||||||
|
leftSign,
|
||||||
|
resultSign);
|
||||||
|
return _module.AddInstruction(
|
||||||
|
SpirvOp.LogicalAnd,
|
||||||
|
_boolType,
|
||||||
|
differentSourceSign,
|
||||||
|
resultSignChanged);
|
||||||
|
}
|
||||||
|
|
||||||
private static bool TryDecodeInlineConstant(uint encoded, out uint value)
|
private static bool TryDecodeInlineConstant(uint encoded, out uint value)
|
||||||
{
|
{
|
||||||
if (encoded == 125)
|
if (encoded == 125)
|
||||||
|
|||||||
Reference in New Issue
Block a user