[spirv] Fix extra OpLoad when using images on lhs of assignment (#981)

When using a storage image on the lhs of a compound assignment,
we need to load the image and do the calculation with rhs first
before actually assigning back to the storage image again. That
load won't result in an OpAccessChain, actually it will result
in a rvalue.
This commit is contained in:
Lei Zhang 2018-01-09 13:41:21 -05:00 коммит произвёл GitHub
Родитель ca1df7b35c
Коммит 4e01373037
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 20 добавлений и 4 удалений

Просмотреть файл

@ -3981,8 +3981,8 @@ SpirvEvalInfo SPIRVEmitter::processBinaryOp(const Expr *lhs, const Expr *rhs,
rhsVal = doExpr(rhs);
lhsVal = lhsPtr = doExpr(lhs);
// This is a compound assignment. We need to load the lhs value if lhs
// does not generate a vector shuffle.
if (!isVectorShuffle(lhs)) {
// is not already rvalue and does not generate a vector shuffle.
if (!lhsPtr.isRValue() && !isVectorShuffle(lhs)) {
const uint32_t lhsTy = typeTranslator.translateType(lhs->getType());
lhsVal = theBuilder.createLoad(lhsTy, lhsPtr);
}

Просмотреть файл

@ -50,4 +50,20 @@ void main() {
// CHECK-NEXT: [[tex:%\d+]] = OpLoad %type_3d_image %MyRWTexture3
// CHECK-NEXT: OpImageWrite [[tex]] {{%\d+}} [[new]]
MyRWTexture3[uint3(8, 9, 10)].xy = 28;
// CHECK: [[buf:%\d+]] = OpLoad %type_buffer_image %MyRWBuffer
// CHECK-NEXT: [[old:%\d+]] = OpImageRead %v4uint [[buf]] %uint_11 None
// CHECK-NEXT: [[val:%\d+]] = OpCompositeExtract %uint [[old]] 0
// CHECK-NEXT: [[add:%\d+]] = OpIAdd %uint [[val]] %uint_30
// CHECK-NEXT: [[buf:%\d+]] = OpLoad %type_buffer_image %MyRWBuffer
// CHECK-NEXT: OpImageWrite [[buf]] %uint_11 [[add]]
MyRWBuffer[11] += 30;
// CHECK: [[tex:%\d+]] = OpLoad %type_2d_image %MyRWTexture
// CHECK-NEXT: [[old:%\d+]] = OpImageRead %v4int [[tex]] {{%\d+}} None
// CHECK-NEXT: [[val:%\d+]] = OpCompositeExtract %int [[old]] 0
// CHECK-NEXT: [[mul:%\d+]] = OpIMul %int [[val]] %int_31
// CHECK-NEXT: [[tex:%\d+]] = OpLoad %type_2d_image %MyRWTexture
// CHECK-NEXT: OpImageWrite [[tex]] {{%\d+}} [[mul]]
MyRWTexture[uint2(12, 13)] *= 31;
}

Просмотреть файл

@ -156,8 +156,8 @@ TEST_F(FileTest, UnaryOpLogicalNot) {
// For assignments
TEST_F(FileTest, BinaryOpAssign) { runFileTest("binary-op.assign.hlsl"); }
TEST_F(FileTest, BinaryOpAssignVector) {
runFileTest("binary-op.assign.vector.hlsl");
TEST_F(FileTest, BinaryOpAssignImage) {
runFileTest("binary-op.assign.image.hlsl");
}
TEST_F(FileTest, BinaryOpAssignComposite) {
runFileTest("binary-op.assign.composite.hlsl");