@@ -762,23 +762,25 @@ Register SPIRVGlobalRegistry::buildGlobalVariable(
762762
763763static std::string GetSpirvImageTypeName (const SPIRVType *Type,
764764 MachineIRBuilder &MIRBuilder,
765- const std::string &Prefix);
765+ const std::string &Prefix,
766+ SPIRVGlobalRegistry &GR);
766767
767768static std::string buildSpirvTypeName (const SPIRVType *Type,
768- MachineIRBuilder &MIRBuilder) {
769+ MachineIRBuilder &MIRBuilder,
770+ SPIRVGlobalRegistry &GR) {
769771 switch (Type->getOpcode ()) {
770772 case SPIRV::OpTypeSampledImage: {
771- return GetSpirvImageTypeName (Type, MIRBuilder, " sampled_image_" );
773+ return GetSpirvImageTypeName (Type, MIRBuilder, " sampled_image_" , GR );
772774 }
773775 case SPIRV::OpTypeImage: {
774- return GetSpirvImageTypeName (Type, MIRBuilder, " image_" );
776+ return GetSpirvImageTypeName (Type, MIRBuilder, " image_" , GR );
775777 }
776778 case SPIRV::OpTypeArray: {
777779 MachineRegisterInfo *MRI = MIRBuilder.getMRI ();
778780 Register ElementTypeReg = Type->getOperand (1 ).getReg ();
779781 auto *ElementType = MRI->getUniqueVRegDef (ElementTypeReg);
780782 uint32_t ArraySize = getArrayComponentCount (MRI, Type);
781- return (buildSpirvTypeName (ElementType, MIRBuilder) + Twine (" [" ) +
783+ return (buildSpirvTypeName (ElementType, MIRBuilder, GR ) + Twine (" [" ) +
782784 Twine (ArraySize) + Twine (" ]" ))
783785 .str ();
784786 }
@@ -790,17 +792,35 @@ static std::string buildSpirvTypeName(const SPIRVType *Type,
790792 if (Type->getOperand (2 ).getImm ())
791793 return (" i" + Twine (Type->getOperand (1 ).getImm ())).str ();
792794 return (" u" + Twine (Type->getOperand (1 ).getImm ())).str ();
795+ case SPIRV::OpTypePointer: {
796+ uint32_t StorageClass = GR.getPointerStorageClass (Type);
797+ SPIRVType *PointeeType = GR.getPointeeType (Type);
798+ return (" p_" + Twine (StorageClass) + Twine (" _" ) +
799+ buildSpirvTypeName (PointeeType, MIRBuilder, GR))
800+ .str ();
801+ }
802+ case SPIRV::OpTypeStruct: {
803+ std::string TypeName = " {" ;
804+ for (uint32_t I = 2 ; I < Type->getNumOperands (); ++I) {
805+ SPIRVType *MemberType =
806+ GR.getSPIRVTypeForVReg (Type->getOperand (I).getReg ());
807+ TypeName = ' _' + buildSpirvTypeName (MemberType, MIRBuilder, GR);
808+ }
809+ return TypeName + " }" ;
810+ }
793811 default :
794812 llvm_unreachable (" Trying to the the name of an unknown type." );
795813 }
796814}
797815
798816static std::string GetSpirvImageTypeName (const SPIRVType *Type,
799817 MachineIRBuilder &MIRBuilder,
800- const std::string &Prefix) {
818+ const std::string &Prefix,
819+ SPIRVGlobalRegistry &GR) {
801820 Register SampledTypeReg = Type->getOperand (1 ).getReg ();
802821 auto *SampledType = MIRBuilder.getMRI ()->getUniqueVRegDef (SampledTypeReg);
803- std::string TypeName = Prefix + buildSpirvTypeName (SampledType, MIRBuilder);
822+ std::string TypeName =
823+ Prefix + buildSpirvTypeName (SampledType, MIRBuilder, GR);
804824 for (uint32_t I = 2 ; I < Type->getNumOperands (); ++I) {
805825 TypeName = (TypeName + ' _' + Twine (Type->getOperand (I).getImm ())).str ();
806826 }
@@ -810,20 +830,19 @@ static std::string GetSpirvImageTypeName(const SPIRVType *Type,
810830Register SPIRVGlobalRegistry::getOrCreateGlobalVariableWithBinding (
811831 const SPIRVType *VarType, uint32_t Set, uint32_t Binding,
812832 MachineIRBuilder &MIRBuilder) {
813- SPIRVType *VarPointerTypeReg = getOrCreateSPIRVPointerType (
814- VarType, MIRBuilder, SPIRV::StorageClass::UniformConstant);
815833 Register VarReg =
816834 MIRBuilder.getMRI ()->createVirtualRegister (&SPIRV::iIDRegClass);
817835
818836 // TODO: The name should come from the llvm-ir, but how that name will be
819837 // passed from the HLSL to the backend has not been decided. Using this place
820838 // holder for now.
821- std::string Name = (" __resource_" + buildSpirvTypeName (VarType, MIRBuilder) +
822- " _" + Twine (Set) + " _" + Twine (Binding))
823- .str ();
824- buildGlobalVariable (VarReg, VarPointerTypeReg, Name, nullptr ,
825- SPIRV::StorageClass::UniformConstant, nullptr , false ,
826- false , SPIRV::LinkageType::Import, MIRBuilder, false );
839+ std::string Name =
840+ (" __resource_" + buildSpirvTypeName (VarType, MIRBuilder, *this ) + " _" +
841+ Twine (Set) + " _" + Twine (Binding))
842+ .str ();
843+ buildGlobalVariable (VarReg, VarType, Name, nullptr ,
844+ getPointerStorageClass (VarType), nullptr , false , false ,
845+ SPIRV::LinkageType::Import, MIRBuilder, false );
827846
828847 buildOpDecorate (VarReg, MIRBuilder, SPIRV::Decoration::DescriptorSet, {Set});
829848 buildOpDecorate (VarReg, MIRBuilder, SPIRV::Decoration::Binding, {Binding});
@@ -837,13 +856,22 @@ SPIRVType *SPIRVGlobalRegistry::getOpTypeArray(uint32_t NumElems,
837856 assert ((ElemType->getOpcode () != SPIRV::OpTypeVoid) &&
838857 " Invalid array element type" );
839858 SPIRVType *SpvTypeInt32 = getOrCreateSPIRVIntegerType (32 , MIRBuilder);
840- Register NumElementsVReg =
841- buildConstantInt (NumElems, MIRBuilder, SpvTypeInt32, EmitIR);
859+
860+ if (NumElems != 0 ) {
861+ Register NumElementsVReg =
862+ buildConstantInt (NumElems, MIRBuilder, SpvTypeInt32, EmitIR);
863+ return createOpType (MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
864+ return MIRBuilder.buildInstr (SPIRV::OpTypeArray)
865+ .addDef (createTypeVReg (MIRBuilder))
866+ .addUse (getSPIRVTypeID (ElemType))
867+ .addUse (NumElementsVReg);
868+ });
869+ }
870+
842871 return createOpType (MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
843- return MIRBuilder.buildInstr (SPIRV::OpTypeArray )
872+ return MIRBuilder.buildInstr (SPIRV::OpTypeRuntimeArray )
844873 .addDef (createTypeVReg (MIRBuilder))
845- .addUse (getSPIRVTypeID (ElemType))
846- .addUse (NumElementsVReg);
874+ .addUse (getSPIRVTypeID (ElemType));
847875 });
848876}
849877
@@ -1291,6 +1319,34 @@ SPIRVGlobalRegistry::getPointerStorageClass(const SPIRVType *Type) const {
12911319 Type->getOperand (1 ).getImm ());
12921320}
12931321
1322+ SPIRVType *SPIRVGlobalRegistry::getOrCreateVulkanBufferType (
1323+ MachineIRBuilder &MIRBuilder, Type *ElemType,
1324+ SPIRV::StorageClass::StorageClass SC, bool IsWritable, bool EmitIr) {
1325+ auto Key = SPIRV::irhandle_vkbuffer (ElemType, SC, IsWritable);
1326+ if (const MachineInstr *MI = findMI (Key, &MIRBuilder.getMF ()))
1327+ return MI;
1328+
1329+ // TODO(134119): The SPIRVType for `ElemType` will not have an explicit
1330+ // layout. This generates invalid SPIR-V.
1331+ auto *T = StructType::create (ElemType);
1332+ auto *BlockType =
1333+ getOrCreateSPIRVType (T, MIRBuilder, SPIRV::AccessQualifier::None, EmitIr);
1334+
1335+ buildOpDecorate (BlockType->defs ().begin ()->getReg (), MIRBuilder,
1336+ SPIRV::Decoration::Block, {});
1337+ buildOpMemberDecorate (BlockType->defs ().begin ()->getReg (), MIRBuilder,
1338+ SPIRV::Decoration::Offset, 0 , {0 });
1339+
1340+ if (!IsWritable) {
1341+ buildOpMemberDecorate (BlockType->defs ().begin ()->getReg (), MIRBuilder,
1342+ SPIRV::Decoration::NonWritable, 0 , {});
1343+ }
1344+
1345+ SPIRVType *R = getOrCreateSPIRVPointerType (BlockType, MIRBuilder, SC);
1346+ add (Key, R);
1347+ return R;
1348+ }
1349+
12941350SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeImage (
12951351 MachineIRBuilder &MIRBuilder, SPIRVType *SampledType, SPIRV::Dim::Dim Dim,
12961352 uint32_t Depth, uint32_t Arrayed, uint32_t Multisampled, uint32_t Sampled,
0 commit comments