gallium: add new float comparison instructions returning integer masks
[mesa.git] / src / gallium / docs / source / tgsi.rst
index 0a5b2274a9a5e210ee4ea59ed2bd7bcc452bb1d2..41f2798d7043ecdda6ae53f1155bc752a24a9366 100644 (file)
@@ -32,11 +32,8 @@ For inputs which have a floating point type, both absolute value and negation
 modifiers are supported (with absolute value being applied first).
 TGSI_OPCODE_MOV is considered to have float input type for applying modifiers.
 
-For inputs which have signed type only the negate modifier is supported. This
-includes instructions which are otherwise ignorant if the type is signed or
-unsigned, such as TGSI_OPCODE_UADD.
-
-For inputs with unsigned type no modifiers are allowed.
+For inputs which have signed or unsigned type only the negate modifier is
+supported.
 
 Instruction Set
 ---------------
@@ -97,16 +94,16 @@ This instruction replicates its result.
 
 .. opcode:: RSQ - Reciprocal Square Root
 
-This instruction replicates its result.
+This instruction replicates its result. The results are undefined for src <= 0.
 
 .. math::
 
-  dst = \frac{1}{\sqrt{|src.x|}}
+  dst = \frac{1}{\sqrt{src.x}}
 
 
 .. opcode:: SQRT - Square Root
 
-This instruction replicates its result.
+This instruction replicates its result. The results are undefined for src < 0.
 
 .. math::
 
@@ -474,11 +471,6 @@ This instruction replicates its result.
   dst.w = partialy(src.w)
 
 
-.. opcode:: KILP - Predicated Discard
-
-  discard
-
-
 .. opcode:: PK2H - Pack Two 16-bit Floats
 
   TBD
@@ -520,13 +512,13 @@ This instruction replicates its result.
 
 .. math::
 
-  dst.x = (src0.x == src1.x) ? 1 : 0
+  dst.x = (src0.x == src1.x) ? 1.0F : 0.0F
 
-  dst.y = (src0.y == src1.y) ? 1 : 0
+  dst.y = (src0.y == src1.y) ? 1.0F : 0.0F
 
-  dst.z = (src0.z == src1.z) ? 1 : 0
+  dst.z = (src0.z == src1.z) ? 1.0F : 0.0F
 
-  dst.w = (src0.w == src1.w) ? 1 : 0
+  dst.w = (src0.w == src1.w) ? 1.0F : 0.0F
 
 
 .. opcode:: SFL - Set On False
@@ -546,13 +538,13 @@ This instruction replicates its result.
 
 .. math::
 
-  dst.x = (src0.x > src1.x) ? 1 : 0
+  dst.x = (src0.x > src1.x) ? 1.0F : 0.0F
 
-  dst.y = (src0.y > src1.y) ? 1 : 0
+  dst.y = (src0.y > src1.y) ? 1.0F : 0.0F
 
-  dst.z = (src0.z > src1.z) ? 1 : 0
+  dst.z = (src0.z > src1.z) ? 1.0F : 0.0F
 
-  dst.w = (src0.w > src1.w) ? 1 : 0
+  dst.w = (src0.w > src1.w) ? 1.0F : 0.0F
 
 
 .. opcode:: SIN - Sine
@@ -568,26 +560,26 @@ This instruction replicates its result.
 
 .. math::
 
-  dst.x = (src0.x <= src1.x) ? 1 : 0
+  dst.x = (src0.x <= src1.x) ? 1.0F : 0.0F
 
-  dst.y = (src0.y <= src1.y) ? 1 : 0
+  dst.y = (src0.y <= src1.y) ? 1.0F : 0.0F
 
-  dst.z = (src0.z <= src1.z) ? 1 : 0
+  dst.z = (src0.z <= src1.z) ? 1.0F : 0.0F
 
-  dst.w = (src0.w <= src1.w) ? 1 : 0
+  dst.w = (src0.w <= src1.w) ? 1.0F : 0.0F
 
 
 .. opcode:: SNE - Set On Not Equal
 
 .. math::
 
-  dst.x = (src0.x != src1.x) ? 1 : 0
+  dst.x = (src0.x != src1.x) ? 1.0F : 0.0F
 
-  dst.y = (src0.y != src1.y) ? 1 : 0
+  dst.y = (src0.y != src1.y) ? 1.0F : 0.0F
 
-  dst.z = (src0.z != src1.z) ? 1 : 0
+  dst.z = (src0.z != src1.z) ? 1.0F : 0.0F
 
-  dst.w = (src0.w != src1.w) ? 1 : 0
+  dst.w = (src0.w != src1.w) ? 1.0F : 0.0F
 
 
 .. opcode:: STR - Set On True
@@ -723,25 +715,6 @@ This instruction replicates its result.
   dst.w = round(src.w)
 
 
-.. opcode:: BRA - Branch
-
-  pc = target
-
-.. note::
-
-   Considered for removal.
-
-.. opcode:: CAL - Subroutine Call
-
-  push(pc)
-  pc = target
-
-
-.. opcode:: RET - Subroutine Call Return
-
-  pc = pop()
-
-
 .. opcode:: SSG - Set Sign
 
 .. math::
@@ -768,7 +741,9 @@ This instruction replicates its result.
   dst.w = (src0.w < 0) ? src1.w : src2.w
 
 
-.. opcode:: KIL - Conditional Discard
+.. opcode:: KILL_IF - Conditional Discard
+
+  Conditional discard.  Allowed in fragment shaders only.
 
 .. math::
 
@@ -777,6 +752,11 @@ This instruction replicates its result.
   endif
 
 
+.. opcode:: KILL - Discard
+
+  Unconditional discard.  Allowed in fragment shaders only.
+
+
 .. opcode:: SCS - Sine Cosine
 
 .. math::
@@ -859,340 +839,656 @@ This instruction replicates its result.
   dst = texture_sample(unit, coord, lod)
 
 
-.. opcode:: BRK - Break
+.. opcode:: PUSHA - Push Address Register On Stack
 
-  Unconditionally moves the point of execution to the instruction after the
-  next endloop or endswitch. The instruction must appear within a loop/endloop
-  or switch/endswitch.
+  push(src.x)
+  push(src.y)
+  push(src.z)
+  push(src.w)
 
+.. note::
 
-.. opcode:: BREAKC - Break Conditional
+   Considered for cleanup.
 
-  Conditionally moves the point of execution to the instruction after the
-  next endloop or endswitch. The instruction must appear within a loop/endloop
-  or switch/endswitch.
-  Condition evaluates to true if src0.x != 0 where src0.x is interpreted
-  as an integer register.
+.. note::
 
+   Considered for removal.
 
-.. opcode:: IF - Float If
+.. opcode:: POPA - Pop Address Register From Stack
 
-  Start an IF ... ELSE .. ENDIF block.  Condition evaluates to true if
+  dst.w = pop()
+  dst.z = pop()
+  dst.y = pop()
+  dst.x = pop()
 
-    src0.x != 0.0
+.. note::
 
-  where src0.x is interpreted as a floating point register.
+   Considered for cleanup.
 
+.. note::
 
-.. opcode:: UIF - Bitwise If
+   Considered for removal.
 
-  Start an UIF ... ELSE .. ENDIF block. Condition evaluates to true if
 
-    src0.x != 0
+.. opcode:: BRA - Branch
 
-  where src0.x is interpreted as an integer register.
+  pc = target
 
+.. note::
 
-.. opcode:: ELSE - Else
+   Considered for removal.
 
-  Starts an else block, after an IF or UIF statement.
 
+.. opcode:: CALLNZ - Subroutine Call If Not Zero
 
-.. opcode:: ENDIF - End If
+   TBD
 
-  Ends an IF or UIF block.
+.. note::
 
+   Considered for cleanup.
 
-.. opcode:: SWITCH - Switch
+.. note::
 
-   Starts a C-style switch expression. The switch consists of one or multiple
-   CASE statements, and at most one DEFAULT statement. Execution of a statement
-   ends when a BRK is hit, but just like in C falling through to other cases
-   without a break is allowed. Similarly, DEFAULT label is allowed anywhere not
-   just as last statement, and fallthrough is allowed into/from it.
-   CASE src arguments are evaluated at bit level against the SWITCH src argument.
+   Considered for removal.
 
-   Example:
-   SWITCH src[0].x
-   CASE src[0].x
-   (some instructions here)
-   (optional BRK here)
-   DEFAULT
-   (some instructions here)
-   (optional BRK here)
-   CASE src[0].x
-   (some instructions here)
-   (optional BRK here)
-   ENDSWITCH
 
+Compute ISA
+^^^^^^^^^^^^^^^^^^^^^^^^
 
-.. opcode:: CASE - Switch case
+These opcodes are primarily provided for special-use computational shaders.
+Support for these opcodes indicated by a special pipe capability bit (TBD).
 
-   This represents a switch case label. The src arg must be an integer immediate.
+XXX doesn't look like most of the opcodes really belong here.
 
+.. opcode:: CEIL - Ceiling
 
-.. opcode:: DEFAULT - Switch default
+.. math::
 
-   This represents the default case in the switch, which is taken if no other
-   case matches.
+  dst.x = \lceil src.x\rceil
 
+  dst.y = \lceil src.y\rceil
 
-.. opcode:: ENDSWITCH - End of switch
+  dst.z = \lceil src.z\rceil
 
-   Ends a switch expression.
+  dst.w = \lceil src.w\rceil
 
 
-.. opcode:: PUSHA - Push Address Register On Stack
+.. opcode:: TRUNC - Truncate
 
-  push(src.x)
-  push(src.y)
-  push(src.z)
-  push(src.w)
+.. math::
+
+  dst.x = trunc(src.x)
+
+  dst.y = trunc(src.y)
+
+  dst.z = trunc(src.z)
+
+  dst.w = trunc(src.w)
+
+
+.. opcode:: MOD - Modulus
+
+.. math::
+
+  dst.x = src0.x \bmod src1.x
+
+  dst.y = src0.y \bmod src1.y
+
+  dst.z = src0.z \bmod src1.z
+
+  dst.w = src0.w \bmod src1.w
+
+
+.. opcode:: UARL - Integer Address Register Load
+
+  Moves the contents of the source register, assumed to be an integer, into the
+  destination register, which is assumed to be an address (ADDR) register.
+
+
+.. opcode:: SAD - Sum Of Absolute Differences
+
+.. math::
+
+  dst.x = |src0.x - src1.x| + src2.x
+
+  dst.y = |src0.y - src1.y| + src2.y
+
+  dst.z = |src0.z - src1.z| + src2.z
+
+  dst.w = |src0.w - src1.w| + src2.w
+
+
+.. opcode:: TXF - Texel Fetch (as per NV_gpu_shader4), extract a single texel
+                  from a specified texture image. The source sampler may
+                 not be a CUBE or SHADOW.
+                  src 0 is a four-component signed integer vector used to
+                 identify the single texel accessed. 3 components + level.
+                 src 1 is a 3 component constant signed integer vector,
+                 with each component only have a range of
+                 -8..+8 (hw only seems to deal with this range, interface
+                 allows for up to unsigned int).
+                 TXF(uint_vec coord, int_vec offset).
+
+
+.. opcode:: TXQ - Texture Size Query (as per NV_gpu_program4)
+                  retrieve the dimensions of the texture
+                  depending on the target. For 1D (width), 2D/RECT/CUBE
+                 (width, height), 3D (width, height, depth),
+                 1D array (width, layers), 2D array (width, height, layers)
+
+.. math::
+
+  lod = src0.x
+
+  dst.x = texture_width(unit, lod)
+
+  dst.y = texture_height(unit, lod)
+
+  dst.z = texture_depth(unit, lod)
+
+
+Integer ISA
+^^^^^^^^^^^^^^^^^^^^^^^^
+These opcodes are used for integer operations.
+Support for these opcodes indicated by PIPE_SHADER_CAP_INTEGERS (all of them?)
+
+
+.. opcode:: I2F - Signed Integer To Float
+
+   Rounding is unspecified (round to nearest even suggested).
+
+.. math::
+
+  dst.x = (float) src.x
+
+  dst.y = (float) src.y
+
+  dst.z = (float) src.z
+
+  dst.w = (float) src.w
+
+
+.. opcode:: U2F - Unsigned Integer To Float
+
+   Rounding is unspecified (round to nearest even suggested).
+
+.. math::
+
+  dst.x = (float) src.x
+
+  dst.y = (float) src.y
+
+  dst.z = (float) src.z
+
+  dst.w = (float) src.w
+
+
+.. opcode:: F2I - Float to Signed Integer
+
+   Rounding is towards zero (truncate).
+   Values outside signed range (including NaNs) produce undefined results.
+
+.. math::
+
+  dst.x = (int) src.x
+
+  dst.y = (int) src.y
+
+  dst.z = (int) src.z
+
+  dst.w = (int) src.w
+
+
+.. opcode:: F2U - Float to Unsigned Integer
+
+   Rounding is towards zero (truncate).
+   Values outside unsigned range (including NaNs) produce undefined results.
+
+.. math::
+
+  dst.x = (unsigned) src.x
+
+  dst.y = (unsigned) src.y
+
+  dst.z = (unsigned) src.z
+
+  dst.w = (unsigned) src.w
+
+
+.. opcode:: UADD - Integer Add
+
+   This instruction works the same for signed and unsigned integers.
+   The low 32bit of the result is returned.
+
+.. math::
+
+  dst.x = src0.x + src1.x
+
+  dst.y = src0.y + src1.y
+
+  dst.z = src0.z + src1.z
+
+  dst.w = src0.w + src1.w
+
+
+.. opcode:: UMAD - Integer Multiply And Add
+
+   This instruction works the same for signed and unsigned integers.
+   The multiplication returns the low 32bit (as does the result itself).
+
+.. math::
+
+  dst.x = src0.x \times src1.x + src2.x
+
+  dst.y = src0.y \times src1.y + src2.y
+
+  dst.z = src0.z \times src1.z + src2.z
+
+  dst.w = src0.w \times src1.w + src2.w
+
+
+.. opcode:: UMUL - Integer Multiply
+
+   This instruction works the same for signed and unsigned integers.
+   The low 32bit of the result is returned.
+
+.. math::
+
+  dst.x = src0.x \times src1.x
+
+  dst.y = src0.y \times src1.y
+
+  dst.z = src0.z \times src1.z
+
+  dst.w = src0.w \times src1.w
+
+
+.. opcode:: IDIV - Signed Integer Division
+
+   TBD: behavior for division by zero.
+
+.. math::
+
+  dst.x = src0.x \ src1.x
+
+  dst.y = src0.y \ src1.y
+
+  dst.z = src0.z \ src1.z
+
+  dst.w = src0.w \ src1.w
+
+
+.. opcode:: UDIV - Unsigned Integer Division
+
+   For division by zero, 0xffffffff is returned.
+
+.. math::
+
+  dst.x = src0.x \ src1.x
+
+  dst.y = src0.y \ src1.y
+
+  dst.z = src0.z \ src1.z
+
+  dst.w = src0.w \ src1.w
+
+
+.. opcode:: UMOD - Unsigned Integer Remainder
+
+   If second arg is zero, 0xffffffff is returned.
+
+.. math::
+
+  dst.x = src0.x \ src1.x
+
+  dst.y = src0.y \ src1.y
+
+  dst.z = src0.z \ src1.z
+
+  dst.w = src0.w \ src1.w
+
+
+.. opcode:: NOT - Bitwise Not
+
+.. math::
+
+  dst.x = ~src.x
+
+  dst.y = ~src.y
+
+  dst.z = ~src.z
+
+  dst.w = ~src.w
+
+
+.. opcode:: AND - Bitwise And
+
+.. math::
+
+  dst.x = src0.x & src1.x
+
+  dst.y = src0.y & src1.y
+
+  dst.z = src0.z & src1.z
+
+  dst.w = src0.w & src1.w
+
+
+.. opcode:: OR - Bitwise Or
+
+.. math::
+
+  dst.x = src0.x | src1.x
+
+  dst.y = src0.y | src1.y
+
+  dst.z = src0.z | src1.z
+
+  dst.w = src0.w | src1.w
+
+
+.. opcode:: XOR - Bitwise Xor
+
+.. math::
+
+  dst.x = src0.x \oplus src1.x
+
+  dst.y = src0.y \oplus src1.y
+
+  dst.z = src0.z \oplus src1.z
+
+  dst.w = src0.w \oplus src1.w
+
+
+.. opcode:: IMAX - Maximum of Signed Integers
+
+.. math::
+
+  dst.x = max(src0.x, src1.x)
+
+  dst.y = max(src0.y, src1.y)
+
+  dst.z = max(src0.z, src1.z)
+
+  dst.w = max(src0.w, src1.w)
+
+
+.. opcode:: UMAX - Maximum of Unsigned Integers
+
+.. math::
+
+  dst.x = max(src0.x, src1.x)
+
+  dst.y = max(src0.y, src1.y)
+
+  dst.z = max(src0.z, src1.z)
+
+  dst.w = max(src0.w, src1.w)
+
+
+.. opcode:: IMIN - Minimum of Signed Integers
+
+.. math::
+
+  dst.x = min(src0.x, src1.x)
+
+  dst.y = min(src0.y, src1.y)
+
+  dst.z = min(src0.z, src1.z)
+
+  dst.w = min(src0.w, src1.w)
+
+
+.. opcode:: UMIN - Minimum of Unsigned Integers
+
+.. math::
+
+  dst.x = min(src0.x, src1.x)
+
+  dst.y = min(src0.y, src1.y)
+
+  dst.z = min(src0.z, src1.z)
+
+  dst.w = min(src0.w, src1.w)
+
+
+.. opcode:: SHL - Shift Left
+
+   The shift count is masked with 0x1f before the shift is applied.
+
+.. math::
 
-.. note::
+  dst.x = src0.x << (0x1f & src1.x)
 
-   Considered for cleanup.
+  dst.y = src0.y << (0x1f & src1.y)
 
-.. note::
+  dst.z = src0.z << (0x1f & src1.z)
 
-   Considered for removal.
+  dst.w = src0.w << (0x1f & src1.w)
 
-.. opcode:: POPA - Pop Address Register From Stack
 
-  dst.w = pop()
-  dst.z = pop()
-  dst.y = pop()
-  dst.x = pop()
+.. opcode:: ISHR - Arithmetic Shift Right (of Signed Integer)
 
-.. note::
+   The shift count is masked with 0x1f before the shift is applied.
 
-   Considered for cleanup.
+.. math::
 
-.. note::
+  dst.x = src0.x >> (0x1f & src1.x)
 
-   Considered for removal.
+  dst.y = src0.y >> (0x1f & src1.y)
 
+  dst.z = src0.z >> (0x1f & src1.z)
 
-Compute ISA
-^^^^^^^^^^^^^^^^^^^^^^^^
+  dst.w = src0.w >> (0x1f & src1.w)
 
-These opcodes are primarily provided for special-use computational shaders.
-Support for these opcodes indicated by a special pipe capability bit (TBD).
 
-XXX so let's discuss it, yeah?
+.. opcode:: USHR - Logical Shift Right
 
-.. opcode:: CEIL - Ceiling
+   The shift count is masked with 0x1f before the shift is applied.
 
 .. math::
 
-  dst.x = \lceil src.x\rceil
+  dst.x = src0.x >> (unsigned) (0x1f & src1.x)
 
-  dst.y = \lceil src.y\rceil
+  dst.y = src0.y >> (unsigned) (0x1f & src1.y)
 
-  dst.z = \lceil src.z\rceil
+  dst.z = src0.z >> (unsigned) (0x1f & src1.z)
 
-  dst.w = \lceil src.w\rceil
+  dst.w = src0.w >> (unsigned) (0x1f & src1.w)
 
 
-.. opcode:: I2F - Integer To Float
+.. opcode:: UCMP - Integer Conditional Move
 
 .. math::
 
-  dst.x = (float) src.x
+  dst.x = src0.x ? src1.x : src2.x
 
-  dst.y = (float) src.y
+  dst.y = src0.y ? src1.y : src2.y
 
-  dst.z = (float) src.z
+  dst.z = src0.z ? src1.z : src2.z
 
-  dst.w = (float) src.w
+  dst.w = src0.w ? src1.w : src2.w
 
 
-.. opcode:: NOT - Bitwise Not
+
+.. opcode:: ISSG - Integer Set Sign
 
 .. math::
 
-  dst.x = ~src.x
+  dst.x = (src0.x < 0) ? -1 : (src0.x > 0) ? 1 : 0
 
-  dst.y = ~src.y
+  dst.y = (src0.y < 0) ? -1 : (src0.y > 0) ? 1 : 0
 
-  dst.z = ~src.z
+  dst.z = (src0.z < 0) ? -1 : (src0.z > 0) ? 1 : 0
 
-  dst.w = ~src.w
+  dst.w = (src0.w < 0) ? -1 : (src0.w > 0) ? 1 : 0
 
 
-.. opcode:: TRUNC - Truncate
+
+.. opcode:: FSLT - Float Set On Less Than (ordered)
+
+   Same comparison as SLT but returns integer instead of 1.0/0.0 float
 
 .. math::
 
-  dst.x = trunc(src.x)
+  dst.x = (src0.x < src1.x) ? ~0 : 0
 
-  dst.y = trunc(src.y)
+  dst.y = (src0.y < src1.y) ? ~0 : 0
 
-  dst.z = trunc(src.z)
+  dst.z = (src0.z < src1.z) ? ~0 : 0
 
-  dst.w = trunc(src.w)
+  dst.w = (src0.w < src1.w) ? ~0 : 0
 
 
-.. opcode:: SHL - Shift Left
+.. opcode:: ISLT - Signed Integer Set On Less Than
 
 .. math::
 
-  dst.x = src0.x << src1.x
+  dst.x = (src0.x < src1.x) ? ~0 : 0
 
-  dst.y = src0.y << src1.x
+  dst.y = (src0.y < src1.y) ? ~0 : 0
 
-  dst.z = src0.z << src1.x
+  dst.z = (src0.z < src1.z) ? ~0 : 0
 
-  dst.w = src0.w << src1.x
+  dst.w = (src0.w < src1.w) ? ~0 : 0
 
 
-.. opcode:: SHR - Shift Right
+.. opcode:: USLT - Unsigned Integer Set On Less Than
 
 .. math::
 
-  dst.x = src0.x >> src1.x
+  dst.x = (src0.x < src1.x) ? ~0 : 0
 
-  dst.y = src0.y >> src1.x
+  dst.y = (src0.y < src1.y) ? ~0 : 0
 
-  dst.z = src0.z >> src1.x
+  dst.z = (src0.z < src1.z) ? ~0 : 0
 
-  dst.w = src0.w >> src1.x
+  dst.w = (src0.w < src1.w) ? ~0 : 0
 
 
-.. opcode:: AND - Bitwise And
+.. opcode:: FSGE - Float Set On Greater Equal Than (ordered)
+
+   Same comparison as SGE but returns integer instead of 1.0/0.0 float
 
 .. math::
 
-  dst.x = src0.x & src1.x
+  dst.x = (src0.x >= src1.x) ? ~0 : 0
 
-  dst.y = src0.y & src1.y
+  dst.y = (src0.y >= src1.y) ? ~0 : 0
 
-  dst.z = src0.z & src1.z
+  dst.z = (src0.z >= src1.z) ? ~0 : 0
 
-  dst.w = src0.w & src1.w
+  dst.w = (src0.w >= src1.w) ? ~0 : 0
 
 
-.. opcode:: OR - Bitwise Or
+.. opcode:: ISGE - Signed Integer Set On Greater Equal Than
 
 .. math::
 
-  dst.x = src0.x | src1.x
+  dst.x = (src0.x >= src1.x) ? ~0 : 0
 
-  dst.y = src0.y | src1.y
+  dst.y = (src0.y >= src1.y) ? ~0 : 0
 
-  dst.z = src0.z | src1.z
+  dst.z = (src0.z >= src1.z) ? ~0 : 0
 
-  dst.w = src0.w | src1.w
+  dst.w = (src0.w >= src1.w) ? ~0 : 0
 
 
-.. opcode:: MOD - Modulus
+.. opcode:: USGE - Unsigned Integer Set On Greater Equal Than
 
 .. math::
 
-  dst.x = src0.x \bmod src1.x
+  dst.x = (src0.x >= src1.x) ? ~0 : 0
 
-  dst.y = src0.y \bmod src1.y
+  dst.y = (src0.y >= src1.y) ? ~0 : 0
 
-  dst.z = src0.z \bmod src1.z
+  dst.z = (src0.z >= src1.z) ? ~0 : 0
 
-  dst.w = src0.w \bmod src1.w
+  dst.w = (src0.w >= src1.w) ? ~0 : 0
 
 
-.. opcode:: XOR - Bitwise Xor
+.. opcode:: FSEQ - Float Set On Equal (ordered)
+
+   Same comparison as SEQ but returns integer instead of 1.0/0.0 float
 
 .. math::
 
-  dst.x = src0.x \oplus src1.x
+  dst.x = (src0.x == src1.x) ? ~0 : 0
 
-  dst.y = src0.y \oplus src1.y
+  dst.y = (src0.y == src1.y) ? ~0 : 0
 
-  dst.z = src0.z \oplus src1.z
+  dst.z = (src0.z == src1.z) ? ~0 : 0
 
-  dst.w = src0.w \oplus src1.w
+  dst.w = (src0.w == src1.w) ? ~0 : 0
 
 
-.. opcode:: UCMP - Integer Conditional Move
+.. opcode:: USEQ - Integer Set On Equal
 
 .. math::
 
-  dst.x = src0.x ? src1.x : src2.x
-
-  dst.y = src0.y ? src1.y : src2.y
-
-  dst.z = src0.z ? src1.z : src2.z
+  dst.x = (src0.x == src1.x) ? ~0 : 0
 
-  dst.w = src0.w ? src1.w : src2.w
+  dst.y = (src0.y == src1.y) ? ~0 : 0
 
+  dst.z = (src0.z == src1.z) ? ~0 : 0
 
-.. opcode:: UARL - Integer Address Register Load
+  dst.w = (src0.w == src1.w) ? ~0 : 0
 
-  Moves the contents of the source register, assumed to be an integer, into the
-  destination register, which is assumed to be an address (ADDR) register.
 
+.. opcode:: FSNE - Float Set On Not Equal (unordered)
 
-.. opcode:: IABS - Integer Absolute Value
+   Same comparison as SNE but returns integer instead of 1.0/0.0 float
 
 .. math::
 
-  dst.x = |src.x|
+  dst.x = (src0.x != src1.x) ? ~0 : 0
 
-  dst.y = |src.y|
+  dst.y = (src0.y != src1.y) ? ~0 : 0
 
-  dst.z = |src.z|
+  dst.z = (src0.z != src1.z) ? ~0 : 0
 
-  dst.w = |src.w|
+  dst.w = (src0.w != src1.w) ? ~0 : 0
 
 
-.. opcode:: SAD - Sum Of Absolute Differences
+.. opcode:: USNE - Integer Set On Not Equal
 
 .. math::
 
-  dst.x = |src0.x - src1.x| + src2.x
-
-  dst.y = |src0.y - src1.y| + src2.y
+  dst.x = (src0.x != src1.x) ? ~0 : 0
 
-  dst.z = |src0.z - src1.z| + src2.z
+  dst.y = (src0.y != src1.y) ? ~0 : 0
 
-  dst.w = |src0.w - src1.w| + src2.w
+  dst.z = (src0.z != src1.z) ? ~0 : 0
 
+  dst.w = (src0.w != src1.w) ? ~0 : 0
 
-.. opcode:: TXF - Texel Fetch (as per NV_gpu_shader4), extract a single texel
-                  from a specified texture image. The source sampler may
-                 not be a CUBE or SHADOW.
-                  src 0 is a four-component signed integer vector used to
-                 identify the single texel accessed. 3 components + level.
-                 src 1 is a 3 component constant signed integer vector,
-                 with each component only have a range of
-                 -8..+8 (hw only seems to deal with this range, interface
-                 allows for up to unsigned int).
-                 TXF(uint_vec coord, int_vec offset).
 
+.. opcode:: INEG - Integer Negate
 
-.. opcode:: TXQ - Texture Size Query (as per NV_gpu_program4)
-                  retrieve the dimensions of the texture
-                  depending on the target. For 1D (width), 2D/RECT/CUBE
-                 (width, height), 3D (width, height, depth),
-                 1D array (width, layers), 2D array (width, height, layers)
+  Two's complement.
 
 .. math::
 
-  lod = src0
+  dst.x = -src.x
 
-  dst.x = texture_width(unit, lod)
+  dst.y = -src.y
 
-  dst.y = texture_height(unit, lod)
+  dst.z = -src.z
 
-  dst.z = texture_depth(unit, lod)
+  dst.w = -src.w
 
 
-.. opcode:: CONT - Continue
+.. opcode:: IABS - Integer Absolute Value
 
-  TBD
+.. math::
 
-.. note::
+  dst.x = |src.x|
 
-   Support for CONT is determined by a special capability bit,
-   ``TGSI_CONT_SUPPORTED``. See :ref:`Screen` for more information.
+  dst.y = |src.y|
+
+  dst.z = |src.z|
+
+  dst.w = |src.w|
 
 
 Geometry ISA
@@ -1203,12 +1499,14 @@ in any other type of shader.
 
 .. opcode:: EMIT - Emit
 
-  TBD
+  Generate a new vertex for the current primitive using the values in the
+  output registers.
 
 
 .. opcode:: ENDPRIM - End Primitive
 
-  TBD
+  Complete the current primitive (consisting of the emitted vertices),
+  and start a new one.
 
 
 GLSL ISA
@@ -1216,25 +1514,48 @@ GLSL ISA
 
 These opcodes are part of :term:`GLSL`'s opcode set. Support for these
 opcodes is determined by a special capability bit, ``GLSL``.
+Some require glsl version 1.30 (UIF/BREAKC/SWITCH/CASE/DEFAULT/ENDSWITCH).
+
+.. opcode:: CAL - Subroutine Call
+
+  push(pc)
+  pc = target
+
+
+.. opcode:: RET - Subroutine Call Return
+
+  pc = pop()
+
+
+.. opcode:: CONT - Continue
+
+  Unconditionally moves the point of execution to the instruction after the
+  last bgnloop. The instruction must appear within a bgnloop/endloop.
+
+.. note::
+
+   Support for CONT is determined by a special capability bit,
+   ``TGSI_CONT_SUPPORTED``. See :ref:`Screen` for more information.
+
 
 .. opcode:: BGNLOOP - Begin a Loop
 
-  TBD
+  Start a loop. Must have a matching endloop.
 
 
 .. opcode:: BGNSUB - Begin Subroutine
 
-  TBD
+  Starts definition of a subroutine. Must have a matching endsub.
 
 
 .. opcode:: ENDLOOP - End a Loop
 
-  TBD
+  End a loop started with bgnloop.
 
 
 .. opcode:: ENDSUB - End Subroutine
 
-  TBD
+  Ends definition of a subroutine.
 
 
 .. opcode:: NOP - No Operation
@@ -1242,23 +1563,102 @@ opcodes is determined by a special capability bit, ``GLSL``.
   Do nothing.
 
 
-.. opcode:: NRM4 - 4-component Vector Normalise
+.. opcode:: BRK - Break
 
-This instruction replicates its result.
+  Unconditionally moves the point of execution to the instruction after the
+  next endloop or endswitch. The instruction must appear within a loop/endloop
+  or switch/endswitch.
 
-.. math::
 
-  dst = \frac{src.x}{src.x \times src.x + src.y \times src.y + src.z \times src.z + src.w \times src.w}
+.. opcode:: BREAKC - Break Conditional
+
+  Conditionally moves the point of execution to the instruction after the
+  next endloop or endswitch. The instruction must appear within a loop/endloop
+  or switch/endswitch.
+  Condition evaluates to true if src0.x != 0 where src0.x is interpreted
+  as an integer register.
 
+.. note::
 
-ps_2_x
-^^^^^^^^^^^^
+   Considered for removal as it's quite inconsistent wrt other opcodes
+   (could emulate with UIF/BRK/ENDIF). 
 
-XXX wait what
 
-.. opcode:: CALLNZ - Subroutine Call If Not Zero
+.. opcode:: IF - Float If
+
+  Start an IF ... ELSE .. ENDIF block.  Condition evaluates to true if
+
+    src0.x != 0.0
+
+  where src0.x is interpreted as a floating point register.
+
+
+.. opcode:: UIF - Bitwise If
+
+  Start an UIF ... ELSE .. ENDIF block. Condition evaluates to true if
+
+    src0.x != 0
+
+  where src0.x is interpreted as an integer register.
+
+
+.. opcode:: ELSE - Else
+
+  Starts an else block, after an IF or UIF statement.
+
+
+.. opcode:: ENDIF - End If
+
+  Ends an IF or UIF block.
+
+
+.. opcode:: SWITCH - Switch
+
+   Starts a C-style switch expression. The switch consists of one or multiple
+   CASE statements, and at most one DEFAULT statement. Execution of a statement
+   ends when a BRK is hit, but just like in C falling through to other cases
+   without a break is allowed. Similarly, DEFAULT label is allowed anywhere not
+   just as last statement, and fallthrough is allowed into/from it.
+   CASE src arguments are evaluated at bit level against the SWITCH src argument.
+
+   Example:
+   SWITCH src[0].x
+   CASE src[0].x
+   (some instructions here)
+   (optional BRK here)
+   DEFAULT
+   (some instructions here)
+   (optional BRK here)
+   CASE src[0].x
+   (some instructions here)
+   (optional BRK here)
+   ENDSWITCH
+
+
+.. opcode:: CASE - Switch case
+
+   This represents a switch case label. The src arg must be an integer immediate.
+
+
+.. opcode:: DEFAULT - Switch default
+
+   This represents the default case in the switch, which is taken if no other
+   case matches.
+
+
+.. opcode:: ENDSWITCH - End of switch
+
+   Ends a switch expression.
+
+
+.. opcode:: NRM4 - 4-component Vector Normalise
+
+This instruction replicates its result.
+
+.. math::
+
+  dst = \frac{src.x}{src.x \times src.x + src.y \times src.y + src.z \times src.z + src.w \times src.w}
 
-  TBD
 
 .. _doubleopcodes:
 
@@ -1396,6 +1796,8 @@ Resource Sampling Opcodes
 
 Those opcodes follow very closely semantics of the respective Direct3D
 instructions. If in doubt double check Direct3D documentation.
+Note that the swizzle on SVIEW (src1) determines texel swizzling
+after lookup.
 
 .. opcode:: SAMPLE - Using provided address, sample data from the
                specified texture using the filtering mode identified
@@ -1526,7 +1928,15 @@ instructions. If in doubt double check Direct3D documentation.
                the mipmap level selected by the src_mip_level and
                are in the number of texels.
                For 1d texture array width is in dst.x, array size
-               is in dst.y and dst.zw are always 0.
+               is in dst.y and dst.z is 0. The number of mipmaps
+               is still in dst.w.
+               In contrast to d3d10 resinfo, there's no way in the
+               tgsi instruction encoding to specify the return type
+               (float/rcpfloat/uint), hence always using uint. Also,
+               unlike the SAMPLE instructions, the swizzle on src1
+               resinfo allowing swizzling dst values is ignored (due
+               to the interaction with rcpfloat modifier which requires
+               some swizzle handling in the state tracker anyway).
 
 .. opcode:: SAMPLE_POS - query the position of a given sample.
                dst receives float4 (x, y, 0, 0) indicated where the
@@ -2068,14 +2478,66 @@ Edge flags are used to control which lines or points are actually
 drawn when the polygon mode converts triangles/quads/polygons into
 points or lines.
 
+
 TGSI_SEMANTIC_STENCIL
-""""""""""""""""""""""
+"""""""""""""""""""""
 
-For fragment shaders, this semantic label indicates than an output
+For fragment shaders, this semantic label indicates that an output
 is a writable stencil reference value. Only the Y component is writable.
 This allows the fragment shader to change the fragments stencilref value.
 
 
+TGSI_SEMANTIC_VIEWPORT_INDEX
+""""""""""""""""""""""""""""
+
+For geometry shaders, this semantic label indicates that an output
+contains the index of the viewport (and scissor) to use.
+Only the X value is used.
+
+
+TGSI_SEMANTIC_LAYER
+"""""""""""""""""""
+
+For geometry shaders, this semantic label indicates that an output
+contains the layer value to use for the color and depth/stencil surfaces.
+Only the X value is used. (Also known as rendertarget array index.)
+
+
+TGSI_SEMANTIC_CULLDIST
+""""""""""""""""""""""
+
+Used as distance to plane for performing application-defined culling
+of individual primitives against a plane. When components of vertex
+elements are given this label, these values are assumed to be a
+float32 signed distance to a plane. Primitives will be completely
+discarded if the plane distance for all of the vertices in the
+primitive are < 0. If a vertex has a cull distance of NaN, that
+vertex counts as "out" (as if its < 0);
+The limits on both clip and cull distances are bound
+by the PIPE_MAX_CLIP_OR_CULL_DISTANCE_COUNT define which defines
+the maximum number of components that can be used to hold the
+distances and by the PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT
+which specifies the maximum number of registers which can be
+annotated with those semantics.
+
+
+TGSI_SEMANTIC_CLIPDIST
+""""""""""""""""""""""
+
+When components of vertex elements are identified this way, these
+values are each assumed to be a float32 signed distance to a plane.
+Primitive setup only invokes rasterization on pixels for which
+the interpolated plane distances are >= 0. Multiple clip planes
+can be implemented simultaneously, by annotating multiple
+components of one or more vertex elements with the above specified
+semantic. The limits on both clip and cull distances are bound
+by the PIPE_MAX_CLIP_OR_CULL_DISTANCE_COUNT define which defines
+the maximum number of components that can be used to hold the
+distances and by the PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT
+which specifies the maximum number of registers which can be
+annotated with those semantics.
+
+
 Declaration Interpolate
 ^^^^^^^^^^^^^^^^^^^^^^^