OSDN Git Service

Fix OpVectorShuffle with mixed vector widths
authorChris Forbes <chrisforbes@google.com>
Fri, 8 Mar 2019 18:41:05 +0000 (10:41 -0800)
committerChris Forbes <chrisforbes@google.com>
Fri, 8 Mar 2019 19:23:35 +0000 (19:23 +0000)
There is a subtle trap here -- almost all SPIRV instructions require vector
widths to match, but for OpVectorShuffle, the widths of the result
vector and the two sources are completely independent.

Fixes dEQP-VK.glsl.operator.unary_operator.plus.highp_vec2_vertex and many others.

Bug: b/127959969
Change-Id: Iaa2cc09fb510fa2ab07a6f53599af8dade553a9a
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/26570
Presubmit-Ready: Chris Forbes <chrisforbes@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Tested-by: Chris Forbes <chrisforbes@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
src/Pipeline/SpirvShader.cpp

index 037085f..7d293f7 100644 (file)
@@ -1412,6 +1412,10 @@ namespace sw
                auto &type = getType(insn.word(1));
                auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents);
 
+               // Note: number of components in result type, first half type, and second
+               // half type are all independent.
+               auto &firstHalfType = getType(getObject(insn.word(3)).type);
+
                GenericValue firstHalfAccess(this, routine, insn.word(3));
                GenericValue secondHalfAccess(this, routine, insn.word(4));
 
@@ -1424,13 +1428,13 @@ namespace sw
                                // a value as any
                                dst.emplace(i, RValue<SIMD::Float>(0.0f));
                        }
-                       else if (selector < type.sizeInComponents)
+                       else if (selector < firstHalfType.sizeInComponents)
                        {
                                dst.emplace(i, firstHalfAccess[selector]);
                        }
                        else
                        {
-                               dst.emplace(i, secondHalfAccess[selector - type.sizeInComponents]);
+                               dst.emplace(i, secondHalfAccess[selector - firstHalfType.sizeInComponents]);
                        }
                }
        }