[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:
Родитель
ca1df7b35c
Коммит
4e01373037
|
@ -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");
|
||||
|
|
Загрузка…
Ссылка в новой задаче