@@ -762,23 +762,25 @@ Register SPIRVGlobalRegistry::buildGlobalVariable(
762
762
763
763
static std::string GetSpirvImageTypeName (const SPIRVType *Type,
764
764
MachineIRBuilder &MIRBuilder,
765
- const std::string &Prefix);
765
+ const std::string &Prefix,
766
+ SPIRVGlobalRegistry &GR);
766
767
767
768
static std::string buildSpirvTypeName (const SPIRVType *Type,
768
- MachineIRBuilder &MIRBuilder) {
769
+ MachineIRBuilder &MIRBuilder,
770
+ SPIRVGlobalRegistry &GR) {
769
771
switch (Type->getOpcode ()) {
770
772
case SPIRV::OpTypeSampledImage: {
771
- return GetSpirvImageTypeName (Type, MIRBuilder, " sampled_image_" );
773
+ return GetSpirvImageTypeName (Type, MIRBuilder, " sampled_image_" , GR );
772
774
}
773
775
case SPIRV::OpTypeImage: {
774
- return GetSpirvImageTypeName (Type, MIRBuilder, " image_" );
776
+ return GetSpirvImageTypeName (Type, MIRBuilder, " image_" , GR );
775
777
}
776
778
case SPIRV::OpTypeArray: {
777
779
MachineRegisterInfo *MRI = MIRBuilder.getMRI ();
778
780
Register ElementTypeReg = Type->getOperand (1 ).getReg ();
779
781
auto *ElementType = MRI->getUniqueVRegDef (ElementTypeReg);
780
782
uint32_t ArraySize = getArrayComponentCount (MRI, Type);
781
- return (buildSpirvTypeName (ElementType, MIRBuilder) + Twine (" [" ) +
783
+ return (buildSpirvTypeName (ElementType, MIRBuilder, GR ) + Twine (" [" ) +
782
784
Twine (ArraySize) + Twine (" ]" ))
783
785
.str ();
784
786
}
@@ -790,17 +792,35 @@ static std::string buildSpirvTypeName(const SPIRVType *Type,
790
792
if (Type->getOperand (2 ).getImm ())
791
793
return (" i" + Twine (Type->getOperand (1 ).getImm ())).str ();
792
794
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
+ }
793
811
default :
794
812
llvm_unreachable (" Trying to the the name of an unknown type." );
795
813
}
796
814
}
797
815
798
816
static std::string GetSpirvImageTypeName (const SPIRVType *Type,
799
817
MachineIRBuilder &MIRBuilder,
800
- const std::string &Prefix) {
818
+ const std::string &Prefix,
819
+ SPIRVGlobalRegistry &GR) {
801
820
Register SampledTypeReg = Type->getOperand (1 ).getReg ();
802
821
auto *SampledType = MIRBuilder.getMRI ()->getUniqueVRegDef (SampledTypeReg);
803
- std::string TypeName = Prefix + buildSpirvTypeName (SampledType, MIRBuilder);
822
+ std::string TypeName =
823
+ Prefix + buildSpirvTypeName (SampledType, MIRBuilder, GR);
804
824
for (uint32_t I = 2 ; I < Type->getNumOperands (); ++I) {
805
825
TypeName = (TypeName + ' _' + Twine (Type->getOperand (I).getImm ())).str ();
806
826
}
@@ -810,20 +830,19 @@ static std::string GetSpirvImageTypeName(const SPIRVType *Type,
810
830
Register SPIRVGlobalRegistry::getOrCreateGlobalVariableWithBinding (
811
831
const SPIRVType *VarType, uint32_t Set, uint32_t Binding,
812
832
MachineIRBuilder &MIRBuilder) {
813
- SPIRVType *VarPointerTypeReg = getOrCreateSPIRVPointerType (
814
- VarType, MIRBuilder, SPIRV::StorageClass::UniformConstant);
815
833
Register VarReg =
816
834
MIRBuilder.getMRI ()->createVirtualRegister (&SPIRV::iIDRegClass);
817
835
818
836
// TODO: The name should come from the llvm-ir, but how that name will be
819
837
// passed from the HLSL to the backend has not been decided. Using this place
820
838
// 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 );
827
846
828
847
buildOpDecorate (VarReg, MIRBuilder, SPIRV::Decoration::DescriptorSet, {Set});
829
848
buildOpDecorate (VarReg, MIRBuilder, SPIRV::Decoration::Binding, {Binding});
@@ -837,13 +856,22 @@ SPIRVType *SPIRVGlobalRegistry::getOpTypeArray(uint32_t NumElems,
837
856
assert ((ElemType->getOpcode () != SPIRV::OpTypeVoid) &&
838
857
" Invalid array element type" );
839
858
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
+
842
871
return createOpType (MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
843
- return MIRBuilder.buildInstr (SPIRV::OpTypeArray )
872
+ return MIRBuilder.buildInstr (SPIRV::OpTypeRuntimeArray )
844
873
.addDef (createTypeVReg (MIRBuilder))
845
- .addUse (getSPIRVTypeID (ElemType))
846
- .addUse (NumElementsVReg);
874
+ .addUse (getSPIRVTypeID (ElemType));
847
875
});
848
876
}
849
877
@@ -1291,6 +1319,34 @@ SPIRVGlobalRegistry::getPointerStorageClass(const SPIRVType *Type) const {
1291
1319
Type->getOperand (1 ).getImm ());
1292
1320
}
1293
1321
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
+
1294
1350
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeImage (
1295
1351
MachineIRBuilder &MIRBuilder, SPIRVType *SampledType, SPIRV::Dim::Dim Dim,
1296
1352
uint32_t Depth, uint32_t Arrayed, uint32_t Multisampled, uint32_t Sampled,
0 commit comments