@@ -767,23 +767,25 @@ Register SPIRVGlobalRegistry::buildGlobalVariable(
767
767
768
768
static std::string GetSpirvImageTypeName (const SPIRVType *Type,
769
769
MachineIRBuilder &MIRBuilder,
770
- const std::string &Prefix);
770
+ const std::string &Prefix,
771
+ SPIRVGlobalRegistry &GR);
771
772
772
773
static std::string buildSpirvTypeName (const SPIRVType *Type,
773
- MachineIRBuilder &MIRBuilder) {
774
+ MachineIRBuilder &MIRBuilder,
775
+ SPIRVGlobalRegistry &GR) {
774
776
switch (Type->getOpcode ()) {
775
777
case SPIRV::OpTypeSampledImage: {
776
- return GetSpirvImageTypeName (Type, MIRBuilder, " sampled_image_" );
778
+ return GetSpirvImageTypeName (Type, MIRBuilder, " sampled_image_" , GR );
777
779
}
778
780
case SPIRV::OpTypeImage: {
779
- return GetSpirvImageTypeName (Type, MIRBuilder, " image_" );
781
+ return GetSpirvImageTypeName (Type, MIRBuilder, " image_" , GR );
780
782
}
781
783
case SPIRV::OpTypeArray: {
782
784
MachineRegisterInfo *MRI = MIRBuilder.getMRI ();
783
785
Register ElementTypeReg = Type->getOperand (1 ).getReg ();
784
786
auto *ElementType = MRI->getUniqueVRegDef (ElementTypeReg);
785
787
uint32_t ArraySize = getArrayComponentCount (MRI, Type);
786
- return (buildSpirvTypeName (ElementType, MIRBuilder) + Twine (" [" ) +
788
+ return (buildSpirvTypeName (ElementType, MIRBuilder, GR ) + Twine (" [" ) +
787
789
Twine (ArraySize) + Twine (" ]" ))
788
790
.str ();
789
791
}
@@ -795,17 +797,35 @@ static std::string buildSpirvTypeName(const SPIRVType *Type,
795
797
if (Type->getOperand (2 ).getImm ())
796
798
return (" i" + Twine (Type->getOperand (1 ).getImm ())).str ();
797
799
return (" u" + Twine (Type->getOperand (1 ).getImm ())).str ();
800
+ case SPIRV::OpTypePointer: {
801
+ uint32_t StorageClass = GR.getPointerStorageClass (Type);
802
+ SPIRVType *PointeeType = GR.getPointeeType (Type);
803
+ return (" p_" + Twine (StorageClass) + Twine (" _" ) +
804
+ buildSpirvTypeName (PointeeType, MIRBuilder, GR))
805
+ .str ();
806
+ }
807
+ case SPIRV::OpTypeStruct: {
808
+ std::string TypeName = " {" ;
809
+ for (uint32_t I = 2 ; I < Type->getNumOperands (); ++I) {
810
+ SPIRVType *MemberType =
811
+ GR.getSPIRVTypeForVReg (Type->getOperand (I).getReg ());
812
+ TypeName = ' _' + buildSpirvTypeName (MemberType, MIRBuilder, GR);
813
+ }
814
+ return TypeName + " }" ;
815
+ }
798
816
default :
799
817
llvm_unreachable (" Trying to the the name of an unknown type." );
800
818
}
801
819
}
802
820
803
821
static std::string GetSpirvImageTypeName (const SPIRVType *Type,
804
822
MachineIRBuilder &MIRBuilder,
805
- const std::string &Prefix) {
823
+ const std::string &Prefix,
824
+ SPIRVGlobalRegistry &GR) {
806
825
Register SampledTypeReg = Type->getOperand (1 ).getReg ();
807
826
auto *SampledType = MIRBuilder.getMRI ()->getUniqueVRegDef (SampledTypeReg);
808
- std::string TypeName = Prefix + buildSpirvTypeName (SampledType, MIRBuilder);
827
+ std::string TypeName =
828
+ Prefix + buildSpirvTypeName (SampledType, MIRBuilder, GR);
809
829
for (uint32_t I = 2 ; I < Type->getNumOperands (); ++I) {
810
830
TypeName = (TypeName + ' _' + Twine (Type->getOperand (I).getImm ())).str ();
811
831
}
@@ -815,20 +835,19 @@ static std::string GetSpirvImageTypeName(const SPIRVType *Type,
815
835
Register SPIRVGlobalRegistry::getOrCreateGlobalVariableWithBinding (
816
836
const SPIRVType *VarType, uint32_t Set, uint32_t Binding,
817
837
MachineIRBuilder &MIRBuilder) {
818
- SPIRVType *VarPointerTypeReg = getOrCreateSPIRVPointerType (
819
- VarType, MIRBuilder, SPIRV::StorageClass::UniformConstant);
820
838
Register VarReg =
821
839
MIRBuilder.getMRI ()->createVirtualRegister (&SPIRV::iIDRegClass);
822
840
823
841
// TODO: The name should come from the llvm-ir, but how that name will be
824
842
// passed from the HLSL to the backend has not been decided. Using this place
825
843
// holder for now.
826
- std::string Name = (" __resource_" + buildSpirvTypeName (VarType, MIRBuilder) +
827
- " _" + Twine (Set) + " _" + Twine (Binding))
828
- .str ();
829
- buildGlobalVariable (VarReg, VarPointerTypeReg, Name, nullptr ,
830
- SPIRV::StorageClass::UniformConstant, nullptr , false ,
831
- false , SPIRV::LinkageType::Import, MIRBuilder, false );
844
+ std::string Name =
845
+ (" __resource_" + buildSpirvTypeName (VarType, MIRBuilder, *this ) + " _" +
846
+ Twine (Set) + " _" + Twine (Binding))
847
+ .str ();
848
+ buildGlobalVariable (VarReg, VarType, Name, nullptr ,
849
+ getPointerStorageClass (VarType), nullptr , false , false ,
850
+ SPIRV::LinkageType::Import, MIRBuilder, false );
832
851
833
852
buildOpDecorate (VarReg, MIRBuilder, SPIRV::Decoration::DescriptorSet, {Set});
834
853
buildOpDecorate (VarReg, MIRBuilder, SPIRV::Decoration::Binding, {Binding});
@@ -842,13 +861,22 @@ SPIRVType *SPIRVGlobalRegistry::getOpTypeArray(uint32_t NumElems,
842
861
assert ((ElemType->getOpcode () != SPIRV::OpTypeVoid) &&
843
862
" Invalid array element type" );
844
863
SPIRVType *SpvTypeInt32 = getOrCreateSPIRVIntegerType (32 , MIRBuilder);
845
- Register NumElementsVReg =
846
- buildConstantInt (NumElems, MIRBuilder, SpvTypeInt32, EmitIR);
864
+
865
+ if (NumElems != 0 ) {
866
+ Register NumElementsVReg =
867
+ buildConstantInt (NumElems, MIRBuilder, SpvTypeInt32, EmitIR);
868
+ return createOpType (MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
869
+ return MIRBuilder.buildInstr (SPIRV::OpTypeArray)
870
+ .addDef (createTypeVReg (MIRBuilder))
871
+ .addUse (getSPIRVTypeID (ElemType))
872
+ .addUse (NumElementsVReg);
873
+ });
874
+ }
875
+
847
876
return createOpType (MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
848
- return MIRBuilder.buildInstr (SPIRV::OpTypeArray )
877
+ return MIRBuilder.buildInstr (SPIRV::OpTypeRuntimeArray )
849
878
.addDef (createTypeVReg (MIRBuilder))
850
- .addUse (getSPIRVTypeID (ElemType))
851
- .addUse (NumElementsVReg);
879
+ .addUse (getSPIRVTypeID (ElemType));
852
880
});
853
881
}
854
882
@@ -1296,6 +1324,34 @@ SPIRVGlobalRegistry::getPointerStorageClass(const SPIRVType *Type) const {
1296
1324
Type->getOperand (1 ).getImm ());
1297
1325
}
1298
1326
1327
+ SPIRVType *SPIRVGlobalRegistry::getOrCreateVulkanBufferType (
1328
+ MachineIRBuilder &MIRBuilder, Type *ElemType,
1329
+ SPIRV::StorageClass::StorageClass SC, bool IsWritable, bool EmitIr) {
1330
+ auto Key = SPIRV::irhandle_vkbuffer (ElemType, SC, IsWritable);
1331
+ if (const MachineInstr *MI = findMI (Key, &MIRBuilder.getMF ()))
1332
+ return MI;
1333
+
1334
+ // TODO: The SPIRVType for `ElemType` will not have an explicit layout.
1335
+ // This generates invalid SPIR-V.
1336
+ auto *T = StructType::create (ElemType);
1337
+ auto *BlockType =
1338
+ getOrCreateSPIRVType (T, MIRBuilder, SPIRV::AccessQualifier::None, EmitIr);
1339
+
1340
+ buildOpDecorate (BlockType->defs ().begin ()->getReg (), MIRBuilder,
1341
+ SPIRV::Decoration::Block, {});
1342
+ buildOpMemberDecorate (BlockType->defs ().begin ()->getReg (), MIRBuilder,
1343
+ SPIRV::Decoration::Offset, 0 , {0 });
1344
+
1345
+ if (!IsWritable) {
1346
+ buildOpMemberDecorate (BlockType->defs ().begin ()->getReg (), MIRBuilder,
1347
+ SPIRV::Decoration::NonWritable, 0 , {});
1348
+ }
1349
+
1350
+ SPIRVType *R = getOrCreateSPIRVPointerType (BlockType, MIRBuilder, SC);
1351
+ add (Key, R);
1352
+ return R;
1353
+ }
1354
+
1299
1355
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeImage (
1300
1356
MachineIRBuilder &MIRBuilder, SPIRVType *SampledType, SPIRV::Dim::Dim Dim,
1301
1357
uint32_t Depth, uint32_t Arrayed, uint32_t Multisampled, uint32_t Sampled,
0 commit comments