@@ -799,16 +799,18 @@ Register SPIRVGlobalRegistry::buildGlobalVariable(
799799
800800static std::string GetSpirvImageTypeName (const SPIRVType *Type,
801801 MachineIRBuilder &MIRBuilder,
802- const std::string &Prefix);
802+ const std::string &Prefix,
803+ SPIRVGlobalRegistry &GR);
803804
804805static std::string buildSpirvTypeName (const SPIRVType *Type,
805- MachineIRBuilder &MIRBuilder) {
806+ MachineIRBuilder &MIRBuilder,
807+ SPIRVGlobalRegistry &GR) {
806808 switch (Type->getOpcode ()) {
807809 case SPIRV::OpTypeSampledImage: {
808- return GetSpirvImageTypeName (Type, MIRBuilder, " sampled_image_" );
810+ return GetSpirvImageTypeName (Type, MIRBuilder, " sampled_image_" , GR );
809811 }
810812 case SPIRV::OpTypeImage: {
811- return GetSpirvImageTypeName (Type, MIRBuilder, " image_" );
813+ return GetSpirvImageTypeName (Type, MIRBuilder, " image_" , GR );
812814 }
813815 case SPIRV::OpTypeArray: {
814816 MachineRegisterInfo *MRI = MIRBuilder.getMRI ();
@@ -819,7 +821,7 @@ static std::string buildSpirvTypeName(const SPIRVType *Type,
819821 MachineInstr *ImmInst = MRI->getVRegDef (TypeInst->getOperand (1 ).getReg ());
820822 assert (ImmInst->getOpcode () == TargetOpcode::G_CONSTANT);
821823 uint32_t ArraySize = ImmInst->getOperand (1 ).getCImm ()->getZExtValue ();
822- return (buildSpirvTypeName (ElementType, MIRBuilder) + Twine (" [" ) +
824+ return (buildSpirvTypeName (ElementType, MIRBuilder, GR ) + Twine (" [" ) +
823825 Twine (ArraySize) + Twine (" ]" ))
824826 .str ();
825827 }
@@ -831,17 +833,35 @@ static std::string buildSpirvTypeName(const SPIRVType *Type,
831833 if (Type->getOperand (2 ).getImm ())
832834 return (" i" + Twine (Type->getOperand (1 ).getImm ())).str ();
833835 return (" u" + Twine (Type->getOperand (1 ).getImm ())).str ();
836+ case SPIRV::OpTypePointer: {
837+ uint32_t StorageClass = GR.getPointerStorageClass (Type);
838+ SPIRVType *PointeeType = GR.getPointeeType (Type);
839+ return (" p_" + Twine (StorageClass) + Twine (" _" ) +
840+ buildSpirvTypeName (PointeeType, MIRBuilder, GR))
841+ .str ();
842+ }
843+ case SPIRV::OpTypeStruct: {
844+ std::string TypeName = " {" ;
845+ for (uint32_t I = 2 ; I < Type->getNumOperands (); ++I) {
846+ SPIRVType *MemberType =
847+ GR.getSPIRVTypeForVReg (Type->getOperand (I).getReg ());
848+ TypeName = ' _' + buildSpirvTypeName (MemberType, MIRBuilder, GR);
849+ }
850+ return TypeName + " }" ;
851+ }
834852 default :
835853 llvm_unreachable (" Trying to the the name of an unknown type." );
836854 }
837855}
838856
839857static std::string GetSpirvImageTypeName (const SPIRVType *Type,
840858 MachineIRBuilder &MIRBuilder,
841- const std::string &Prefix) {
859+ const std::string &Prefix,
860+ SPIRVGlobalRegistry &GR) {
842861 Register SampledTypeReg = Type->getOperand (1 ).getReg ();
843862 auto *SampledType = MIRBuilder.getMRI ()->getUniqueVRegDef (SampledTypeReg);
844- std::string TypeName = Prefix + buildSpirvTypeName (SampledType, MIRBuilder);
863+ std::string TypeName =
864+ Prefix + buildSpirvTypeName (SampledType, MIRBuilder, GR);
845865 for (uint32_t I = 2 ; I < Type->getNumOperands (); ++I) {
846866 TypeName = (TypeName + ' _' + Twine (Type->getOperand (I).getImm ())).str ();
847867 }
@@ -851,20 +871,19 @@ static std::string GetSpirvImageTypeName(const SPIRVType *Type,
851871Register SPIRVGlobalRegistry::getOrCreateGlobalVariableWithBinding (
852872 const SPIRVType *VarType, uint32_t Set, uint32_t Binding,
853873 MachineIRBuilder &MIRBuilder) {
854- SPIRVType *VarPointerTypeReg = getOrCreateSPIRVPointerType (
855- VarType, MIRBuilder, SPIRV::StorageClass::UniformConstant);
856874 Register VarReg =
857875 MIRBuilder.getMRI ()->createVirtualRegister (&SPIRV::iIDRegClass);
858876
859877 // TODO: The name should come from the llvm-ir, but how that name will be
860878 // passed from the HLSL to the backend has not been decided. Using this place
861879 // holder for now.
862- std::string Name = (" __resource_" + buildSpirvTypeName (VarType, MIRBuilder) +
863- " _" + Twine (Set) + " _" + Twine (Binding))
864- .str ();
865- buildGlobalVariable (VarReg, VarPointerTypeReg, Name, nullptr ,
866- SPIRV::StorageClass::UniformConstant, nullptr , false ,
867- false , SPIRV::LinkageType::Import, MIRBuilder, false );
880+ std::string Name =
881+ (" __resource_" + buildSpirvTypeName (VarType, MIRBuilder, *this ) + " _" +
882+ Twine (Set) + " _" + Twine (Binding))
883+ .str ();
884+ buildGlobalVariable (VarReg, VarType, Name, nullptr ,
885+ getPointerStorageClass (VarType), nullptr , false , false ,
886+ SPIRV::LinkageType::Import, MIRBuilder, false );
868887
869888 buildOpDecorate (VarReg, MIRBuilder, SPIRV::Decoration::DescriptorSet, {Set});
870889 buildOpDecorate (VarReg, MIRBuilder, SPIRV::Decoration::Binding, {Binding});
@@ -878,14 +897,23 @@ SPIRVType *SPIRVGlobalRegistry::getOpTypeArray(uint32_t NumElems,
878897 assert ((ElemType->getOpcode () != SPIRV::OpTypeVoid) &&
879898 " Invalid array element type" );
880899 SPIRVType *SpvTypeInt32 = getOrCreateSPIRVIntegerType (32 , MIRBuilder);
881- Register NumElementsVReg =
882- buildConstantInt (NumElems, MIRBuilder, SpvTypeInt32, EmitIR);
883- return createOpType (MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
884- return MIRBuilder.buildInstr (SPIRV::OpTypeArray)
885- .addDef (createTypeVReg (MIRBuilder))
886- .addUse (getSPIRVTypeID (ElemType))
887- .addUse (NumElementsVReg);
888- });
900+
901+ if (NumElems != 0 ) {
902+ Register NumElementsVReg =
903+ buildConstantInt (NumElems, MIRBuilder, SpvTypeInt32, EmitIR);
904+ return createOpType (MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
905+ return MIRBuilder.buildInstr (SPIRV::OpTypeArray)
906+ .addDef (createTypeVReg (MIRBuilder))
907+ .addUse (getSPIRVTypeID (ElemType))
908+ .addUse (NumElementsVReg);
909+ });
910+ } else {
911+ return createOpType (MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
912+ return MIRBuilder.buildInstr (SPIRV::OpTypeRuntimeArray)
913+ .addDef (createTypeVReg (MIRBuilder))
914+ .addUse (getSPIRVTypeID (ElemType));
915+ });
916+ }
889917}
890918
891919SPIRVType *SPIRVGlobalRegistry::getOpTypeOpaque (const StructType *Ty,
0 commit comments