Skip to content

Commit 34e8685

Browse files
author
Greg Roth
committed
Consolidate buffer store translation
Added structured buffer support to TranslateStore and used it for all such lowerings.
1 parent 9e8a698 commit 34e8685

1 file changed

Lines changed: 60 additions & 107 deletions

File tree

lib/HLSL/HLOperationLower.cpp

Lines changed: 60 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -4335,18 +4335,15 @@ void Split64bitValForStore(Type *EltTy, ArrayRef<Value *> vals, unsigned size,
43354335
}
43364336

43374337
void 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,
79077899
void 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

79467911
void 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

Comments
 (0)