{ 0, 0, 0, 0, 0, 0, 0, NONE, "BRK", TGSI_OPCODE_BRK },
{ 0, 1, 0, 0, 1, 0, 1, NONE, "IF", TGSI_OPCODE_IF },
{ 0, 1, 0, 0, 1, 0, 1, NONE, "UIF", TGSI_OPCODE_UIF },
- { 0, 1, 0, 0, 0, 0, 1, NONE, "", 76 }, /* removed */
+ { 1, 2, 0, 0, 0, 0, 0, COMP, "READ_INVOC", TGSI_OPCODE_READ_INVOC },
{ 0, 0, 0, 0, 1, 1, 1, NONE, "ELSE", TGSI_OPCODE_ELSE },
{ 0, 0, 0, 0, 0, 1, 0, NONE, "ENDIF", TGSI_OPCODE_ENDIF },
{ 1, 1, 0, 0, 0, 0, 0, COMP, "DDX_FINE", TGSI_OPCODE_DDX_FINE },
{ 1, 1, 0, 0, 0, 0, 0, COMP, "NOT", TGSI_OPCODE_NOT },
{ 1, 1, 0, 0, 0, 0, 0, COMP, "TRUNC", TGSI_OPCODE_TRUNC },
{ 1, 2, 0, 0, 0, 0, 0, COMP, "SHL", TGSI_OPCODE_SHL },
- { 0, 0, 0, 0, 0, 0, 0, NONE, "", 88 }, /* removed */
+ { 1, 1, 0, 0, 0, 0, 0, OTHR, "BALLOT", TGSI_OPCODE_BALLOT },
{ 1, 2, 0, 0, 0, 0, 0, COMP, "AND", TGSI_OPCODE_AND },
{ 1, 2, 0, 0, 0, 0, 0, COMP, "OR", TGSI_OPCODE_OR },
{ 1, 2, 0, 0, 0, 0, 0, COMP, "MOD", TGSI_OPCODE_MOD },
{ 1, 1, 1, 0, 0, 0, 0, OTHR, "TXQ_LZ", TGSI_OPCODE_TXQ_LZ },
{ 1, 1, 1, 0, 0, 0, 0, OTHR, "TXQS", TGSI_OPCODE_TXQS },
{ 1, 1, 0, 0, 0, 0, 0, OTHR, "RESQ", TGSI_OPCODE_RESQ },
- { 0, 0, 0, 0, 0, 0, 0, NONE, "", 106 }, /* removed */
+ { 1, 1, 0, 0, 0, 0, 0, COMP, "READ_FIRST", TGSI_OPCODE_READ_FIRST },
{ 0, 0, 0, 0, 0, 0, 0, NONE, "NOP", TGSI_OPCODE_NOP },
{ 1, 2, 0, 0, 0, 0, 0, COMP, "FSEQ", TGSI_OPCODE_FSEQ },
{ 1, 2, 0, 0, 0, 0, 0, COMP, "FSGE", TGSI_OPCODE_FSGE },
resource[offset] = (dst_x > src_x ? dst_x : src_x)
-.. _voteopcodes:
+.. _interlaneopcodes:
+
+Inter-lane opcodes
+^^^^^^^^^^^^^^^^^^
+
+These opcodes reduce the given value across the shader invocations
+running in the current SIMD group. Every thread in the subgroup will receive
+the same result. The BALLOT operations accept a single-channel argument that
+is treated as a boolean and produce a 64-bit value.
+
+.. opcode:: VOTE_ANY - Value is set in any of the active invocations
+
+ Syntax: ``VOTE_ANY dst, value``
+
+ Example: ``VOTE_ANY TEMP[0].x, TEMP[1].x``
+
+
+.. opcode:: VOTE_ALL - Value is set in all of the active invocations
+
+ Syntax: ``VOTE_ALL dst, value``
+
+ Example: ``VOTE_ALL TEMP[0].x, TEMP[1].x``
+
+
+.. opcode:: VOTE_EQ - Value is the same in all of the active invocations
+
+ Syntax: ``VOTE_EQ dst, value``
+
+ Example: ``VOTE_EQ TEMP[0].x, TEMP[1].x``
+
+
+.. opcode:: BALLOT - Lanemask of whether the value is set in each active
+ invocation
+
+ Syntax: ``BALLOT dst, value``
+
+ Example: ``BALLOT TEMP[0].xy, TEMP[1].x``
+
+ When the argument is a constant true, this produces a bitmask of active
+ invocations. In fragment shaders, this can include helper invocations
+ (invocations whose outputs and writes to memory are discarded, but which
+ are used to compute derivatives).
+
+
+.. opcode:: READ_FIRST - Broadcast the value from the first active
+ invocation to all active lanes
+
+ Syntax: ``READ_FIRST dst, value``
+
+ Example: ``READ_FIRST TEMP[0], TEMP[1]``
-Vote opcodes
-^^^^^^^^^^^^
-These opcodes compare the given value across the shader invocations
-running in the current SIMD group. The details of exactly which
-invocations get compared are implementation-defined, and it would be a
-correct implementation to only ever consider the current thread's
-value. (i.e. SIMD group of 1). The argument is treated as a boolean.
+.. opcode:: READ_INVOC - Retrieve the value from the given invocation
+ (need not be uniform)
-.. opcode:: VOTE_ANY - Value is set in any of the current invocations
+ Syntax: ``READ_INVOC dst, value, invocation``
-.. opcode:: VOTE_ALL - Value is set in all of the current invocations
+ Example: ``READ_INVOC TEMP[0].xy, TEMP[1].xy, TEMP[2].x``
-.. opcode:: VOTE_EQ - Value is the same in all of the current invocations
+ invocation.x controls the invocation number to read from for all channels.
+ The invocation number must be the same across all active invocations in a
+ sub-group; otherwise, the results are undefined.
Explanation of symbols used