@@ -4335,18 +4335,15 @@ void Split64bitValForStore(Type *EltTy, ArrayRef<Value *> vals, unsigned size,
43354335}
43364336
43374337void TranslateStore (DxilResource::Kind RK, Value *handle, Value *val,
4338- Value *offset, IRBuilder<> &Builder, hlsl::OP *OP ,
4339- Value *sampIdx = nullptr ) {
4338+ Value *Idx, Value * offset, IRBuilder<> &Builder,
4339+ hlsl::OP *OP, Value *sampIdx = nullptr ) {
43404340 Type *Ty = val->getType ();
4341-
4342- // This function is no longer used for lowering stores to a
4343- // structured buffer.
4344- DXASSERT_NOMSG (RK != DxilResource::Kind::StructuredBuffer);
4345-
43464341 OP::OpCode opcode = OP::OpCode::NumOpCodes;
4342+ bool isTyped = true ;
43474343 switch (RK) {
43484344 case DxilResource::Kind::RawBuffer:
43494345 case DxilResource::Kind::StructuredBuffer:
4346+ isTyped = false ;
43504347 opcode = OP::OpCode::RawBufferStore;
43514348 break ;
43524349 case DxilResource::Kind::TypedBuffer:
@@ -4364,10 +4361,6 @@ void TranslateStore(DxilResource::Kind RK, Value *handle, Value *val,
43644361 break ;
43654362 }
43664363
4367- bool isTyped = opcode == OP::OpCode::TextureStore ||
4368- opcode == OP::OpCode::TextureStoreSample ||
4369- RK == DxilResource::Kind::TypedBuffer;
4370-
43714364 Type *i32Ty = Builder.getInt32Ty ();
43724365 Type *i64Ty = Builder.getInt64Ty ();
43734366 Type *doubleTy = Builder.getDoubleTy ();
@@ -4406,38 +4399,42 @@ void TranslateStore(DxilResource::Kind RK, Value *handle, Value *val,
44064399 storeArgs.emplace_back (opArg); // opcode
44074400 storeArgs.emplace_back (handle); // resource handle
44084401
4409- unsigned offset0Idx = 0 ;
4410- if (RK == DxilResource::Kind::RawBuffer ||
4411- RK == DxilResource::Kind::TypedBuffer ) {
4412- // Offset 0
4413- if (offset ->getType ()->isVectorTy ()) {
4414- Value *scalarOffset = Builder.CreateExtractElement (offset , (uint64_t )0 );
4415- storeArgs.emplace_back (scalarOffset ); // offset
4402+ unsigned OffsetIdx = 0 ;
4403+ if (opcode == OP::OpCode::RawBufferStore ||
4404+ opcode == OP::OpCode::BufferStore ) {
4405+ // Append Coord0 (Index) value.
4406+ if (Idx ->getType ()->isVectorTy ()) {
4407+ Value *ScalarIdx = Builder.CreateExtractElement (Idx , (uint64_t )0 );
4408+ storeArgs.emplace_back (ScalarIdx ); // Coord0 (Index).
44164409 } else {
4417- storeArgs.emplace_back (offset ); // offset
4410+ storeArgs.emplace_back (Idx ); // Coord0 (Index).
44184411 }
44194412
4420- // Store offset0 for later use
4421- offset0Idx = storeArgs.size () - 1 ;
4413+ // Store OffsetIdx representing the argument that may need to be incremented
4414+ // later to load additional chunks of data.
4415+ // Only structured buffers can use the offset parameter.
4416+ // Others must increment the index.
4417+ if (RK == DxilResource::Kind::StructuredBuffer)
4418+ OffsetIdx = storeArgs.size ();
4419+ else
4420+ OffsetIdx = storeArgs.size () - 1 ;
44224421
4423- // Offset 1
4424- storeArgs.emplace_back (undefI);
4422+ // Coord1 (Offset).
4423+ // Only relevant when storing more than 4 elements to structured buffers.
4424+ storeArgs.emplace_back (offset);
44254425 } else {
44264426 // texture store
44274427 unsigned coordSize = DxilResource::GetNumCoords (RK);
44284428
44294429 // Set x first.
4430- if (offset ->getType ()->isVectorTy ())
4431- storeArgs.emplace_back (Builder.CreateExtractElement (offset , (uint64_t )0 ));
4430+ if (Idx ->getType ()->isVectorTy ())
4431+ storeArgs.emplace_back (Builder.CreateExtractElement (Idx , (uint64_t )0 ));
44324432 else
4433- storeArgs.emplace_back (offset);
4434-
4435- // Store offset0 for later use
4436- offset0Idx = storeArgs.size () - 1 ;
4433+ storeArgs.emplace_back (Idx);
44374434
44384435 for (unsigned i = 1 ; i < 3 ; i++) {
44394436 if (i < coordSize)
4440- storeArgs.emplace_back (Builder.CreateExtractElement (offset , i));
4437+ storeArgs.emplace_back (Builder.CreateExtractElement (Idx , i));
44414438 else
44424439 storeArgs.emplace_back (undefI);
44434440 }
@@ -4464,23 +4461,17 @@ void TranslateStore(DxilResource::Kind RK, Value *handle, Value *val,
44644461 }
44654462
44664463 for (unsigned j = 0 ; j < storeArgsList.size (); j++) {
4467-
4468- // For second and subsequent store calls, increment the offset0 (i.e. store
4469- // index)
4464+ // For second and subsequent store calls, increment the resource-appropriate
4465+ // index or offset parameter.
44704466 if (j > 0 ) {
4471- // Greater than four-components store is not allowed for
4472- // TypedBuffer and Textures. So greater than four elements
4473- // scenario should only get hit here for RawBuffer.
4474- DXASSERT_NOMSG (RK == DxilResource::Kind::RawBuffer);
44754467 unsigned EltSize = OP->GetAllocSizeForType (EltTy);
4476- unsigned newOffset = EltSize * MaxStoreElemCount * j;
4477- Value *newOffsetVal = ConstantInt::get (Builder.getInt32Ty (), newOffset);
4478- newOffsetVal =
4479- Builder.CreateAdd (storeArgsList[0 ][offset0Idx], newOffsetVal);
4480- storeArgsList[j][offset0Idx] = newOffsetVal;
4468+ unsigned NewCoord = EltSize * MaxStoreElemCount * j;
4469+ Value *NewCoordVal = ConstantInt::get (Builder.getInt32Ty (), NewCoord);
4470+ NewCoordVal = Builder.CreateAdd (storeArgsList[0 ][OffsetIdx], NewCoordVal);
4471+ storeArgsList[j][OffsetIdx] = NewCoordVal;
44814472 }
44824473
4483- // values
4474+ // Set value parameters.
44844475 uint8_t mask = 0 ;
44854476 if (Ty->isVectorTy ()) {
44864477 unsigned vecSize =
@@ -4576,7 +4567,8 @@ Value *TranslateResourceStore(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
45764567
45774568 Value *val = CI->getArgOperand (HLOperandIndex::kStoreValOpIdx );
45784569 Value *offset = CI->getArgOperand (HLOperandIndex::kStoreOffsetOpIdx );
4579- TranslateStore (RK, handle, val, offset, Builder, hlslOP);
4570+ Value *UndefI = UndefValue::get (Builder.getInt32Ty ());
4571+ TranslateStore (RK, handle, val, offset, UndefI, Builder, hlslOP);
45804572
45814573 return nullptr ;
45824574}
@@ -7907,40 +7899,13 @@ Value *TranslateStructBufMatLd(CallInst *CI, IRBuilder<> &Builder,
79077899void TranslateStructBufMatSt (Type *matType, IRBuilder<> &Builder, Value *handle,
79087900 hlsl::OP *OP, Value *bufIdx, Value *baseOffset,
79097901 Value *val, const DataLayout &DL) {
7902+ #ifndef NDEBUG
79107903 HLMatrixType MatTy = HLMatrixType::cast (matType);
7911- Type *EltTy = MatTy.getElementTypeForMem ();
7912-
7913- val = MatTy.emitLoweredRegToMem (val, Builder);
7914-
7915- unsigned EltSize = DL.getTypeAllocSize (EltTy);
7916- Constant *Alignment = OP->GetI32Const (EltSize);
7917- Value *offset = baseOffset;
7918- if (baseOffset == nullptr )
7919- offset = OP->GetU32Const (0 );
7920-
7921- unsigned matSize = MatTy.getNumElements ();
7922- Value *undefElt = UndefValue::get (EltTy);
7923-
7924- unsigned storeSize = matSize;
7925- if (matSize % 4 ) {
7926- storeSize = matSize + 4 - (matSize & 3 );
7927- }
7928- std::vector<Value *> elts (storeSize, undefElt);
7929- for (unsigned i = 0 ; i < matSize; i++)
7930- elts[i] = Builder.CreateExtractElement (val, i);
7931-
7932- for (unsigned i = 0 ; i < matSize; i += 4 ) {
7933- uint8_t mask = 0 ;
7934- for (unsigned j = 0 ; j < 4 && (i + j) < matSize; j++) {
7935- if (elts[i + j] != undefElt)
7936- mask |= (1 << j);
7937- }
7938- GenerateStructBufSt (handle, bufIdx, offset, EltTy, OP, Builder,
7939- {elts[i], elts[i + 1 ], elts[i + 2 ], elts[i + 3 ]}, mask,
7940- Alignment);
7941- // Update offset by 4*4bytes.
7942- offset = Builder.CreateAdd (offset, OP->GetU32Const (4 * EltSize));
7943- }
7904+ DXASSERT (MatTy.getLoweredVectorType (false /* MemRepr*/ ) == val->getType (),
7905+ " helper type should match vectorized matrix" );
7906+ #endif
7907+ TranslateStore (DxilResource::Kind::StructuredBuffer, handle, val, bufIdx,
7908+ baseOffset, Builder, OP);
79447909}
79457910
79467911void TranslateStructBufMatLdSt (CallInst *CI, Value *handle, HLResource::Kind RK,
@@ -8085,6 +8050,9 @@ void TranslateStructBufMatSubscript(CallInst *CI, Value *handle,
80858050
80868051 GEP->eraseFromParent ();
80878052 } else if (StoreInst *stUser = dyn_cast<StoreInst>(subsUser)) {
8053+ // Store elements of matrix in a struct. Needs to be done one scalar at a
8054+ // time even for vectors in the case that matrix orientation spreads the
8055+ // indexed scalars throughout the matrix vector.
80888056 IRBuilder<> stBuilder (stUser);
80898057 Value *Val = stUser->getValueOperand ();
80908058 if (Val->getType ()->isVectorTy ()) {
@@ -8108,6 +8076,9 @@ void TranslateStructBufMatSubscript(CallInst *CI, Value *handle,
81088076 LoadInst *ldUser = cast<LoadInst>(subsUser);
81098077 IRBuilder<> ldBuilder (ldUser);
81108078 Value *ldData = UndefValue::get (resultType);
8079+ // Load elements of matrix in a struct. Needs to be done one scalar at a
8080+ // time even for vectors in the case that matrix orientation spreads the
8081+ // indexed scalars throughout the matrix vector.
81118082 if (resultType->isVectorTy ()) {
81128083 for (unsigned i = 0 ; i < resultSize; i++) {
81138084 Value *ResultElt;
@@ -8248,30 +8219,9 @@ void TranslateStructBufSubscriptUser(Instruction *user, Value *handle,
82488219 LdInst->eraseFromParent ();
82498220 } else if (StoreInst *StInst = dyn_cast<StoreInst>(user)) {
82508221 // Store of scalar/vector within a struct or structured raw store.
8251- Type *Ty = StInst->getValueOperand ()->getType ();
8252- Type *pOverloadTy = Ty->getScalarType ();
8253- Value *offset = baseOffset;
8254-
82558222 Value *val = StInst->getValueOperand ();
8256- Value *undefVal = llvm::UndefValue::get (pOverloadTy);
8257- Value *vals[] = {undefVal, undefVal, undefVal, undefVal};
8258- uint8_t mask = 0 ;
8259- if (Ty->isVectorTy ()) {
8260- unsigned vectorNumElements = Ty->getVectorNumElements ();
8261- DXASSERT (vectorNumElements <= 4 , " up to 4 elements in vector" );
8262- assert (vectorNumElements <= 4 );
8263- for (unsigned i = 0 ; i < vectorNumElements; i++) {
8264- vals[i] = Builder.CreateExtractElement (val, i);
8265- mask |= (1 << i);
8266- }
8267- } else {
8268- vals[0 ] = val;
8269- mask = DXIL::kCompMask_X ;
8270- }
8271- Constant *alignment =
8272- OP->GetI32Const (DL.getTypeAllocSize (Ty->getScalarType ()));
8273- GenerateStructBufSt (handle, bufIdx, offset, pOverloadTy, OP, Builder, vals,
8274- mask, alignment);
8223+ TranslateStore (DxilResource::Kind::StructuredBuffer, handle, val, bufIdx,
8224+ baseOffset, Builder, OP);
82758225 StInst->eraseFromParent ();
82768226 } else if (BitCastInst *BCI = dyn_cast<BitCastInst>(user)) {
82778227 // Recurse users
@@ -8418,14 +8368,15 @@ void TranslateTypedBufferSubscript(CallInst *CI, HLOperationLowerHelper &helper,
84188368 User *user = *(It++);
84198369 Instruction *I = cast<Instruction>(user);
84208370 IRBuilder<> Builder (I);
8371+ Value *UndefI = UndefValue::get (Builder.getInt32Ty ());
84218372 if (LoadInst *ldInst = dyn_cast<LoadInst>(user)) {
84228373 TranslateTypedBufSubscript (CI, RK, RC, handle, ldInst, Builder, hlslOP,
84238374 helper.dataLayout );
84248375 } else if (StoreInst *stInst = dyn_cast<StoreInst>(user)) {
84258376 Value *val = stInst->getValueOperand ();
84268377 TranslateStore (RK, handle, val,
8427- CI->getArgOperand (HLOperandIndex::kStoreOffsetOpIdx ),
8428- Builder, hlslOP);
8378+ CI->getArgOperand (HLOperandIndex::kSubscriptIndexOpIdx ),
8379+ UndefI, Builder, hlslOP);
84298380 // delete the st
84308381 stInst->eraseFromParent ();
84318382 } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(user)) {
@@ -8450,9 +8401,10 @@ void TranslateTypedBufferSubscript(CallInst *CI, HLOperationLowerHelper &helper,
84508401 // Generate St.
84518402 // Reset insert point, UpdateVectorElt may move SI to different block.
84528403 StBuilder.SetInsertPoint (SI);
8453- TranslateStore (RK, handle, ldVal,
8454- CI->getArgOperand (HLOperandIndex::kStoreOffsetOpIdx ),
8455- StBuilder, hlslOP);
8404+ TranslateStore (
8405+ RK, handle, ldVal,
8406+ CI->getArgOperand (HLOperandIndex::kSubscriptIndexOpIdx ), UndefI,
8407+ StBuilder, hlslOP);
84568408 SI->eraseFromParent ();
84578409 continue ;
84588410 }
@@ -8642,9 +8594,10 @@ void TranslateHLSubscript(CallInst *CI, HLSubscriptOpcode opcode,
86428594 } else {
86438595 StoreInst *stInst = cast<StoreInst>(*U);
86448596 Value *val = stInst->getValueOperand ();
8597+ Value *UndefI = UndefValue::get (Builder.getInt32Ty ());
86458598 TranslateStore (RK, handle, val,
8646- CI->getArgOperand (HLOperandIndex::kStoreOffsetOpIdx ),
8647- Builder, hlslOP, mipLevel);
8599+ CI->getArgOperand (HLOperandIndex::kSubscriptIndexOpIdx ),
8600+ UndefI, Builder, hlslOP, mipLevel);
86488601 stInst->eraseFromParent ();
86498602 }
86508603 Translated = true ;
0 commit comments