[shader-decoder-part1-hotfix] New format support, maintenance8 support, robustness improvements, and bug fixes. This commit includes updates to the AGC exports, Gen5 SPIR-V translator, and Vulkan video presenter to enhance compatibility and performance. (#31)

This commit is contained in:
Berk
2026-07-07 21:06:04 +03:00
committed by GitHub
parent 44c43c8ebd
commit db20387502
3 changed files with 409 additions and 123 deletions
+15 -8
View File
@@ -3609,7 +3609,7 @@ public static class AgcExports
',',
draw.GlobalMemoryBindings.Select((binding, index) =>
$"{index}:0x{binding.BaseAddress:X16}:{binding.Data.Length}:" +
Convert.ToHexString(binding.Data.AsSpan(0, Math.Min(binding.Data.Length, 32)))));
Convert.ToHexString(binding.Data.AsSpan(0, Math.Min(binding.Data.Length, 256)))));
var indices = draw.IndexBuffer is { } indexBuffer
? $"{(indexBuffer.Is32Bit ? 32 : 16)}:" +
Convert.ToHexString(indexBuffer.Data.AsSpan(0, Math.Min(indexBuffer.Data.Length, 32)))
@@ -3744,7 +3744,7 @@ public static class AgcExports
descriptor.Width > 8192 ||
descriptor.Height > 8192)
{
texture = CreateFallbackGuestDrawTexture(isStorage);
texture = CreateFallbackGuestDrawTexture(isStorage, descriptor.Format, descriptor.NumberType);
return true;
}
@@ -3762,7 +3762,7 @@ public static class AgcExports
sourceByteCount > MaxPresentedTextureBytes ||
sourceByteCount > int.MaxValue)
{
texture = CreateFallbackGuestDrawTexture(isStorage);
texture = CreateFallbackGuestDrawTexture(isStorage, descriptor.Format, descriptor.NumberType);
return true;
}
@@ -3825,7 +3825,7 @@ public static class AgcExports
var source = new byte[(int)sourceByteCount];
if (!ctx.Memory.TryRead(descriptor.Address, source))
{
texture = CreateFallbackGuestDrawTexture(isStorage);
texture = CreateFallbackGuestDrawTexture(isStorage, descriptor.Format, descriptor.NumberType);
return true;
}
@@ -3868,18 +3868,25 @@ public static class AgcExports
return true;
}
private static VulkanGuestDrawTexture CreateFallbackGuestDrawTexture(bool isStorage = false) =>
new(
private static VulkanGuestDrawTexture CreateFallbackGuestDrawTexture(
bool isStorage,
uint format,
uint numberType)
{
var fallbackFormat = format == 0 ? 10u : format;
var fallbackNumberType = numberType;
return new(
0,
1,
1,
56,
NumberType: 0,
fallbackFormat,
fallbackNumberType,
[0, 0, 0, 255],
IsFallback: true,
IsStorage: isStorage,
MipLevels: 1,
MipLevel: 0);
}
private static VulkanGuestSampler ToVulkanSampler(IReadOnlyList<uint> descriptor) =>
descriptor.Count >= 4
+94 -38
View File
@@ -467,9 +467,6 @@ internal static partial class Gen5SpirvTranslator
_imageBindingByPc.TryAdd(binding.Pc, index);
var isStorage =
Gen5ShaderTranslator.IsStorageImageOperation(binding.Opcode);
var isDepth =
binding.Opcode.Contains("SampleC", StringComparison.Ordinal) ||
binding.Opcode.Contains("Gather4C", StringComparison.Ordinal);
var (format, componentKind) =
DecodeImageFormat(binding.ResourceDescriptor);
var componentType = componentKind switch
@@ -494,7 +491,7 @@ internal static partial class Gen5SpirvTranslator
var imageType = _module.TypeImage(
componentType,
SpirvImageDim.Dim2D,
depth: isDepth,
depth: false,
arrayed: false,
multisampled: false,
sampled: isStorage ? 2u : 1u,
@@ -1661,18 +1658,14 @@ internal static partial class Gen5SpirvTranslator
var offset = hasOffset ? BuildImageOffset(image, 0) : 0u;
var imageOperands =
(explicitLod ? 2u : 0u) | (hasOffset ? 0x10u : 0u);
var reference = hasCompare
? Bitcast(_floatType, LoadV(image.GetAddressRegister(hasOffset ? 1 : 0)))
: 0u;
var operands = new List<uint>
{
imageObject,
coordinates,
};
if (hasCompare)
{
operands.Add(
Bitcast(
_floatType,
LoadV(image.GetAddressRegister(hasOffset ? 1 : 0))));
}
if (imageOperands != 0)
{
@@ -1689,29 +1682,14 @@ internal static partial class Gen5SpirvTranslator
}
sampled = _module.AddInstruction(
hasCompare
? explicitLod
? SpirvOp.ImageSampleDrefExplicitLod
: SpirvOp.ImageSampleDrefImplicitLod
: explicitLod
? SpirvOp.ImageSampleExplicitLod
: SpirvOp.ImageSampleImplicitLod,
hasCompare ? resource.ComponentType : resource.VectorType,
explicitLod
? SpirvOp.ImageSampleExplicitLod
: SpirvOp.ImageSampleImplicitLod,
resource.VectorType,
[.. operands]);
if (hasCompare)
{
var scalar = sampled;
sampled = _module.AddInstruction(
SpirvOp.CompositeConstruct,
resource.VectorType,
scalar,
scalar,
scalar,
resource.ComponentKind == ImageComponentKind.Float
? Float(1)
: resource.ComponentKind == ImageComponentKind.Uint
? UInt(1)
: _module.Constant(_intType, 1));
sampled = EmitManualDepthCompare(resource, sampled, reference);
}
}
else if (instruction.Opcode.StartsWith(
@@ -1725,6 +1703,9 @@ internal static partial class Gen5SpirvTranslator
var start = (hasOffset ? 1 : 0) + (hasCompare ? 1 : 0);
var coordinates = BuildFloatCoordinates(image, start);
var offset = hasOffset ? BuildImageOffset(image, 0) : 0u;
var reference = hasCompare
? Bitcast(_floatType, LoadV(image.GetAddressRegister(hasOffset ? 1 : 0)))
: 0u;
var operands = new List<uint>
{
imageObject,
@@ -1732,10 +1713,7 @@ internal static partial class Gen5SpirvTranslator
};
if (hasCompare)
{
operands.Add(
Bitcast(
_floatType,
LoadV(image.GetAddressRegister(hasOffset ? 1 : 0))));
operands.Add(UInt(0));
}
else
{
@@ -1756,11 +1734,28 @@ internal static partial class Gen5SpirvTranslator
}
sampled = _module.AddInstruction(
hasCompare
? SpirvOp.ImageDrefGather
: SpirvOp.ImageGather,
SpirvOp.ImageGather,
resource.VectorType,
[.. operands]);
if (hasCompare)
{
var compared = new uint[4];
for (var component = 0u; component < 4; component++)
{
var texel = _module.AddInstruction(
SpirvOp.CompositeExtract,
resource.ComponentType,
sampled,
component);
compared[component] = EmitDepthCompareScalar(resource, texel, reference);
}
sampled = _module.AddInstruction(
SpirvOp.CompositeConstruct,
resource.VectorType,
compared);
}
writeAllComponents = true;
}
else
@@ -1794,6 +1789,67 @@ internal static partial class Gen5SpirvTranslator
return true;
}
private uint EmitDepthCompareScalar(
SpirvImageResource resource,
uint texel,
uint reference)
{
var texelAsFloat = resource.ComponentKind switch
{
ImageComponentKind.Uint => _module.AddInstruction(
SpirvOp.ConvertUToF, _floatType, texel),
ImageComponentKind.Sint => _module.AddInstruction(
SpirvOp.ConvertSToF, _floatType, texel),
_ => texel,
};
var passes = _module.AddInstruction(
SpirvOp.FOrdLessThanEqual,
_boolType,
reference,
texelAsFloat);
return _module.AddInstruction(
SpirvOp.Select,
resource.ComponentType,
passes,
resource.ComponentKind switch
{
ImageComponentKind.Uint => UInt(1),
ImageComponentKind.Sint => _module.Constant(_intType, 1),
_ => Float(1),
},
resource.ComponentKind switch
{
ImageComponentKind.Uint => UInt(0),
ImageComponentKind.Sint => _module.Constant(_intType, 0),
_ => Float(0),
});
}
private uint EmitManualDepthCompare(
SpirvImageResource resource,
uint sampledVector,
uint reference)
{
var texel = _module.AddInstruction(
SpirvOp.CompositeExtract,
resource.ComponentType,
sampledVector,
0u);
var scalar = EmitDepthCompareScalar(resource, texel, reference);
return _module.AddInstruction(
SpirvOp.CompositeConstruct,
resource.VectorType,
scalar,
scalar,
scalar,
resource.ComponentKind switch
{
ImageComponentKind.Uint => UInt(1),
ImageComponentKind.Sint => _module.Constant(_intType, 1),
_ => Float(1),
});
}
private uint BuildFloatCoordinates(Gen5ImageControl image, int start)
{
var x = Bitcast(