[SpirvTranslator] Declare vgprPackedHalf only when a shader uses it (#901)

Every translated module declared the 4 KiB private vgprPackedHalf array,
even when no packed-half instruction reads it. AMD's Windows compiler
keeps the unused array as a named .bss global; linking two stages then
fails and the driver copies the NOBITS section as file data, reading
past the end of the ELF. The result is a 0xC0000005 access violation
inside amdvlk64.dll during vkCreateGraphicsPipelines /
vkCreateComputePipelines.

The array is now created on first use by PackedHalfRegisters().
This commit is contained in:
Astell 2026-09-24 01:00:23 +02:00 committed by GitHub
parent f70e333c08
commit 22e73fbea1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 21 additions and 10 deletions

View File

@ -493,13 +493,10 @@ public static partial class Gen5SpirvTranslator
var scalarArrayType = _module.TypeArray(_uintType, ScalarRegisterCount);
var vectorArrayType = _module.TypeArray(_uintType, VectorRegisterCount);
var packedHalfArrayType = _module.TypeArray(_vec2Type, VectorRegisterCount);
var privateScalarArrayPointer =
_module.TypePointer(SpirvStorageClass.Private, scalarArrayType);
var privateVectorArrayPointer =
_module.TypePointer(SpirvStorageClass.Private, vectorArrayType);
var privatePackedHalfArrayPointer =
_module.TypePointer(SpirvStorageClass.Private, packedHalfArrayType);
_scalarRegisters = _module.AddGlobalVariable(
privateScalarArrayPointer,
SpirvStorageClass.Private,
@ -508,10 +505,6 @@ public static partial class Gen5SpirvTranslator
privateVectorArrayPointer,
SpirvStorageClass.Private,
_module.ConstantNull(vectorArrayType));
_packedHalfRegisters = _module.AddGlobalVariable(
privatePackedHalfArrayPointer,
SpirvStorageClass.Private,
_module.ConstantNull(packedHalfArrayType));
_scc = _module.AddGlobalVariable(
_privateBoolPointer,
SpirvStorageClass.Private,
@ -555,7 +548,6 @@ public static partial class Gen5SpirvTranslator
_interfaces.Add(_scalarRegisters);
_interfaces.Add(_vectorRegisters);
_interfaces.Add(_packedHalfRegisters);
_interfaces.Add(_scc);
_interfaces.Add(_vcc);
_interfaces.Add(_exec);
@ -569,7 +561,6 @@ public static partial class Gen5SpirvTranslator
_interfaces.Add(_programActive);
_module.AddName(_scalarRegisters, "sgpr");
_module.AddName(_vectorRegisters, "vgpr");
_module.AddName(_packedHalfRegisters, "vgprPackedHalf");
{
DeclareLayoutBindings();
@ -5980,9 +5971,29 @@ public static partial class Gen5SpirvTranslator
_module.AddInstruction(
SpirvOp.AccessChain,
_privateVec2Pointer,
_packedHalfRegisters,
PackedHalfRegisters(),
UInt(register));
// Declared on first use. AMD's compiler keeps an unused 4 KiB private array as a
// named .bss global: two stages then fail to link, and the driver copies the
// NOBITS section as file data and reads past the end of the ELF.
private uint PackedHalfRegisters()
{
if (_packedHalfRegisters != 0)
{
return _packedHalfRegisters;
}
var arrayType = _module.TypeArray(_vec2Type, VectorRegisterCount);
_packedHalfRegisters = _module.AddGlobalVariable(
_module.TypePointer(SpirvStorageClass.Private, arrayType),
SpirvStorageClass.Private,
_module.ConstantNull(arrayType));
_interfaces.Add(_packedHalfRegisters);
_module.AddName(_packedHalfRegisters, "vgprPackedHalf");
return _packedHalfRegisters;
}
private uint LoadS(uint register) => Load(_uintType, ScalarPointer(register));
private uint LoadV(uint register) => Load(_uintType, VectorPointer(register));