@@ -3130,31 +3130,15 @@ Id Builder::createLoad(Id lValue, spv::Decoration precision, spv::MemoryAccessMa
31303130
31313131Instruction* Builder::createDescHeapLoadStoreBaseRemap (Id baseId, Op op)
31323132{
3133- // could only be untypedAccessChain or BufferPointerEXT op.
3133+ // could only be untypedAccessChain op.
31343134 spv::Op instOp = module .getInstruction (baseId)->getOpCode ();
31353135 spv::Id baseVal = baseId;
31363136 // base type (from run time array)
31373137 spv::Id resultTy = getIdOperand (baseId, 0 );
31383138 // Descriptor heap using run time array.
31393139 if (accessChain.descHeapInfo .descHeapStorageClass != StorageClass::Max)
31403140 resultTy = getIdOperand (resultTy, 0 );
3141- if (instOp == Op::OpBufferPointerEXT) {
3142- // get base structure type from run time array of buffer structure type.
3143- // create an extra untyped access chain for buffer pointer.
3144- resultTy = accessChain.descHeapInfo .descHeapBaseTy ;
3145- Instruction* chain = new Instruction (getUniqueId (), getTypeId (baseId), Op::OpUntypedAccessChainKHR);
3146- // base type.
3147- chain->addIdOperand (resultTy);
3148- // base
3149- chain->addIdOperand (baseId);
3150- // index
3151- for (int i = 0 ; i < (int )accessChain.indexChain .size (); ++i) {
3152- chain->addIdOperand (accessChain.indexChain [i]);
3153- }
3154- addInstruction (std::unique_ptr<Instruction>(chain));
3155- baseVal = chain->getResultId ();
3156- clearAccessChain ();
3157- } else if (instOp != Op::OpUntypedAccessChainKHR) {
3141+ if (instOp != Op::OpUntypedAccessChainKHR) {
31583142 assert (false && " Not a untyped load type" );
31593143 }
31603144
@@ -3223,15 +3207,12 @@ Id Builder::createDescHeapAccessChain()
32233207 if (rsrcOffsetIdx != 0 )
32243208 accessChain.base = accessChain.descHeapInfo .structRemappedBase ;
32253209 Id base = accessChain.base ;
3226- Id untypedResultTy = accessChain.descHeapInfo .descHeapBaseTy ;
3210+ Id baseTy = accessChain.descHeapInfo .descHeapBaseTy ;
32273211 uint32_t explicitArrayStride = accessChain.descHeapInfo .descHeapBaseArrayStride ;
32283212 std::vector<Id>& offsets = accessChain.indexChain ;
32293213 uint32_t firstArrIndex = accessChain.descHeapInfo .structRsrcTyFirstArrIndex ;
32303214 // both typeBufferEXT and UntypedPointer only contains storage class info.
32313215 StorageClass storageClass = (StorageClass)accessChain.descHeapInfo .descHeapStorageClass ;
3232- Id resultTy = makeUntypedPointer (storageClass == spv::StorageClass::StorageBuffer ? spv::StorageClass::StorageBuffer
3233- : spv::StorageClass::Uniform);
3234-
32353216 // Make the untyped access chain instruction
32363217 Instruction* chain = new Instruction (getUniqueId (), makeUntypedPointer (getStorageClass (base)), Op::OpUntypedAccessChainKHR);
32373218
@@ -3269,21 +3250,38 @@ Id Builder::createDescHeapAccessChain()
32693250 offsets.pop_back ();
32703251 addInstruction (std::unique_ptr<Instruction>(chain));
32713252 // Create OpBufferPointer for loading target buffer descriptor.
3272- Instruction* bufferUntypedDataPtr = new Instruction (getUniqueId (), resultTy, Op::OpBufferPointerEXT);
3273- bufferUntypedDataPtr->addIdOperand (chain->getResultId ());
3274- addInstruction (std::unique_ptr<Instruction>(bufferUntypedDataPtr));
3275- // Final/Second untyped access chain loading will be created during loading, current results only
3276- // refer to the loading 'base'.
3277- return bufferUntypedDataPtr->getResultId ();
3253+ Id bufferPtrTy = makePointer (storageClass, baseTy);
3254+ Instruction* bufferDataPtr = new Instruction (getUniqueId (), bufferPtrTy, Op::OpBufferPointerEXT);
3255+ bufferDataPtr->addIdOperand (chain->getResultId ());
3256+ addInstruction (std::unique_ptr<Instruction>(bufferDataPtr));
3257+
3258+ // Form a second, typed access chain for accessing buffer data.
3259+ Id resultTy = baseTy;
3260+ for (int i = 0 ; i < (int )offsets.size (); ++i) {
3261+ if (isStructType (resultTy)) {
3262+ assert (isConstantScalar (offsets[i]));
3263+ resultTy = getContainedTypeId (resultTy, getConstantScalar (offsets[i]));
3264+ } else
3265+ resultTy = getContainedTypeId (resultTy, offsets[i]);
3266+ }
3267+ resultTy = makePointer (storageClass, resultTy);
3268+
3269+ Instruction* bufferChain = new Instruction (getUniqueId (), resultTy, Op::OpAccessChain);
3270+ bufferChain->reserveOperands (offsets.size () + 1 );
3271+ bufferChain->addIdOperand (bufferDataPtr->getResultId ());
3272+ for (int i = 0 ; i < (int )offsets.size (); ++i)
3273+ bufferChain->addIdOperand (offsets[i]);
3274+ addInstruction (std::unique_ptr<Instruction>(bufferChain));
3275+ return bufferChain->getResultId ();
32783276 } else {
32793277 // image/sampler heap
32803278 Id strideId = NoResult;
32813279 if (explicitArrayStride == 0 ) {
3282- strideId = createConstantSizeOfEXT (untypedResultTy );
3280+ strideId = createConstantSizeOfEXT (baseTy );
32833281 } else {
32843282 strideId = makeUintConstant (explicitArrayStride);
32853283 }
3286- Id runtimeArrTy = makeRuntimeArray (untypedResultTy );
3284+ Id runtimeArrTy = makeRuntimeArray (baseTy );
32873285 addDecorationId (runtimeArrTy, spv::Decoration::ArrayStrideIdEXT, strideId);
32883286 chain->addIdOperand (runtimeArrTy);
32893287 chain->addIdOperand (base);
0 commit comments