@@ -200,6 +200,7 @@ void PromoteResourceToDirectAS::PromoteSamplerTextureToDirectAS(GenIntrinsicInst
200200 unsigned bufID = 0 ;
201201 BufferType bufTy;
202202 BufferAccessType accTy;
203+ bool needBufferOffset; // Unused
203204 bool canPromote = false ;
204205 Value* arrayIndex = nullptr ;
205206
@@ -229,7 +230,7 @@ void PromoteResourceToDirectAS::PromoteSamplerTextureToDirectAS(GenIntrinsicInst
229230 // If we can find it, we can promote the indirect access to direct access
230231 // by encoding the BTI as a direct addrspace
231232 if (srcPtr->getType ()->isPointerTy () &&
232- IGC::GetResourcePointerInfo (srcPtr, bufID, bufTy, accTy))
233+ IGC::GetResourcePointerInfo (srcPtr, bufID, bufTy, accTy, needBufferOffset ))
233234 {
234235 canPromote = true ;
235236 }
@@ -495,6 +496,35 @@ bool PatchInstructionAddressSpace(const std::vector<Value*>& instList, Type* dst
495496 return success;
496497}
497498
499+ Value* PromoteResourceToDirectAS::getOffsetValue (Value* srcPtr, int & bufferOffsetHandle)
500+ {
501+ auto offsetEntry = m_SrcPtrToBufferOffsetMap.find (srcPtr);
502+ if (offsetEntry != m_SrcPtrToBufferOffsetMap.end ())
503+ {
504+ GenIntrinsicInst* runtimevalue = dyn_cast<GenIntrinsicInst>(offsetEntry->second );
505+ assert (runtimevalue && " Buffer offset must be a runtime value" );
506+ bufferOffsetHandle = (int )llvm::cast<llvm::ConstantInt>(runtimevalue->getOperand (0 ))->getZExtValue ();
507+ return offsetEntry->second ;
508+ }
509+ else
510+ {
511+ Instruction* srcPtrInst;
512+ srcPtrInst = dyn_cast<Instruction>(srcPtr);
513+ assert (srcPtrInst && " source pointer must have been an instruction" );
514+ IGCIRBuilder<> builder (srcPtrInst);
515+
516+ Instruction* bufferOffset;
517+ ModuleMetaData* modMD = getAnalysis<MetaDataUtilsWrapper>().getModuleMetaData ();
518+ // Create runtime value for buffer offset
519+ Function* pFunc = GenISAIntrinsic::getDeclaration (srcPtrInst->getParent ()->getParent ()->getParent (), GenISAIntrinsic::GenISA_RuntimeValue, builder.getInt32Ty ());
520+ bufferOffset = builder.CreateCall (pFunc, builder.getInt32 (modMD->MinNOSPushConstantSize ));
521+ bufferOffsetHandle = modMD->MinNOSPushConstantSize ;
522+ modMD->MinNOSPushConstantSize ++;
523+ m_SrcPtrToBufferOffsetMap[srcPtr] = bufferOffset;
524+ return bufferOffset;
525+ }
526+ }
527+
498528void PromoteResourceToDirectAS::PromoteBufferToDirectAS (Instruction* inst, Value* resourcePtr)
499529{
500530 IGCIRBuilder<> builder (inst);
@@ -528,7 +558,8 @@ void PromoteResourceToDirectAS::PromoteBufferToDirectAS(Instruction* inst, Value
528558 unsigned bufferID;
529559 BufferType bufType;
530560 BufferAccessType accType;
531- if (!IGC::GetResourcePointerInfo (srcPtr, bufferID, bufType, accType))
561+ bool needBufferOffset;
562+ if (!IGC::GetResourcePointerInfo (srcPtr, bufferID, bufType, accType, needBufferOffset))
532563 {
533564 // Can't promote if we don't know the explicit buffer ID and type
534565 return ;
@@ -546,19 +577,30 @@ void PromoteResourceToDirectAS::PromoteBufferToDirectAS(Instruction* inst, Value
546577 return ;
547578 }
548579
580+ // If needBufferOffset set, we need to adjust stateful buffer accesses with the buffer offset from payload
581+ Value* pointerValue;
582+ int bufferOffsetHandle = -1 ;
583+ if (needBufferOffset)
584+ {
585+ pointerValue = builder.CreatePtrToInt (pBuffer, builder.getInt32Ty ());
586+ pointerValue = builder.CreateAdd (pointerValue, getOffsetValue (srcPtr, bufferOffsetHandle));
587+ pBuffer = builder.CreateIntToPtr (pointerValue, pBuffer->getType ());
588+ }
589+
590+ bool canpromote = false ;
549591 if (LoadInst * load = dyn_cast<LoadInst>(inst))
550592 {
551593 LoadInst* newload = IGC::cloneLoad (load, pBuffer);
552594 load->replaceAllUsesWith (newload);
553595 load->eraseFromParent ();
554- m_pCodeGenContext-> m_buffersPromotedToDirectAS . insert (bufferID) ;
596+ canpromote = true ;
555597 }
556598 else if (StoreInst * store = dyn_cast<StoreInst>(inst))
557599 {
558600 StoreInst* newstore = IGC::cloneStore (store, store->getOperand (0 ), pBuffer);
559601 store->replaceAllUsesWith (newstore);
560602 store->eraseFromParent ();
561- m_pCodeGenContext-> m_buffersPromotedToDirectAS . insert (bufferID) ;
603+ canpromote = true ;
562604 }
563605 else if (GenIntrinsicInst * pIntr = dyn_cast<GenIntrinsicInst>(inst))
564606 {
@@ -687,7 +729,20 @@ void PromoteResourceToDirectAS::PromoteBufferToDirectAS(Instruction* inst, Value
687729 }
688730 oldInst->replaceAllUsesWith (newInst);
689731 oldInst->eraseFromParent ();
690- m_pCodeGenContext->m_buffersPromotedToDirectAS .insert (bufferID);
732+ canpromote = true ;
733+ }
734+ }
735+ if (canpromote)
736+ {
737+ int handle = needBufferOffset ? bufferOffsetHandle : -1 ;
738+ if ((m_pCodeGenContext->m_buffersPromotedToDirectAS .find (bufferID) == m_pCodeGenContext->m_buffersPromotedToDirectAS .end ()) ||
739+ (m_pCodeGenContext->m_buffersPromotedToDirectAS [bufferID] == -1 ))
740+ {
741+ m_pCodeGenContext->m_buffersPromotedToDirectAS [bufferID] = handle;
742+ }
743+ else
744+ {
745+ assert ((m_pCodeGenContext->m_buffersPromotedToDirectAS [bufferID] == handle));
691746 }
692747 }
693748}
0 commit comments