diff --git a/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.Resources.cs b/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.Resources.cs index 9d682a8..4cd192e 100644 --- a/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.Resources.cs +++ b/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.Resources.cs @@ -203,6 +203,15 @@ public static partial class Gen5SpirvTranslator _interfaces.Add(_runtimeBufferBiases); } + if (_request.Bindings.BufferWordCount != 0) + { + var wordArrayType = _module.TypeArray(_uintType, _request.Bindings.BufferWordCount); + _portableBufferWords = _module.AddGlobalVariable( + _module.TypePointer(SpirvStorageClass.Private, wordArrayType), SpirvStorageClass.Private, _module.ConstantNull(wordArrayType)); + _module.AddName(_portableBufferWords, "guestBufferWords"); + _interfaces.Add(_portableBufferWords); + } + if (info.UsesDeviceAddresses) { _module.AddCapability(SpirvCapability.PhysicalStorageBufferAddresses); @@ -394,8 +403,18 @@ public static partial class Gen5SpirvTranslator var bias = BitwiseAnd(ShiftRightLogical(packed, UInt((buffer % 4) * 8)), UInt(0xFF)); Store(RuntimeBufferBiasPointer((int)buffer), bias); } + + for (uint dword = 0; dword < layout.BufferWordCount; dword++) + { + Store(PortableBufferWordPointer((int)dword), LoadShaderDataDword(UInt(layout.BufferWordDword + dword))); + } } + private uint _portableBufferWords; + + private uint PortableBufferWordPointer(int dword) => + _module.AddInstruction(SpirvOp.AccessChain, _privateUintPointer, _portableBufferWords, UInt(checked((uint)dword))); + private uint LoadShaderDataDword(uint dwordIndex) { var layout = _request.Bindings; diff --git a/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.cs b/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.cs index 73a8a16..491dd83 100644 --- a/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.cs +++ b/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.cs @@ -3144,9 +3144,22 @@ public static partial class Gen5SpirvTranslator } var specialized = info.Buffers[bindingIndex]; - var stride = UInt(specialized.PackedStride & 0x3FFF); var descriptorFormat = specialized.DescriptorFormat; - var descriptorWord3 = UInt((specialized.DescriptorFormat << 12) | (specialized.DescriptorSwizzle & 0xFFF)); + uint stride; + uint descriptorWord3; + if (_portableBufferWords != 0) + { + var portableDword = bindingIndex * PortableBufferWord.DwordCount; + stride = Load(_uintType, PortableBufferWordPointer(portableDword)); + descriptorWord3 = PortableBufferWord.ReadsFormatAtRuntime(specialized) + ? Load(_uintType, PortableBufferWordPointer(portableDword + 1)) + : UInt((specialized.DescriptorFormat << 12) | (specialized.DescriptorSwizzle & 0xFFF)); + } + else + { + stride = UInt(specialized.PackedStride & 0x3FFF); + descriptorWord3 = UInt((specialized.DescriptorFormat << 12) | (specialized.DescriptorSwizzle & 0xFFF)); + } var scalarOffset = instruction.Sources.Count > 2 ? GetRawSource(instruction, 2)