By default, a register reference in a shader expands to a reference to all of the elements of the register, in x, y, z, w order. This means that whenever you write “R” where “R” is the name of some register, it automatically gets expanded (at least conceptually) to “R.xyzw”. What I want to get across is that the specific element-by-element reference to the register is made without you having to do anything. This is merely semantic convenience and efficiency.
What this means that it cost nothing extra to re-order or even ignore specific elements of a register if it makes sense to. I’ll say it again: it costs nothing to use these masks in your shaders. They are there so you can take advantage of the single-instruction/multiple-data nature of the shader language to possibly merge similar computations or save on register usage. If in fact you don’t need to have a value stored in ever element of a register, then by all means use a destination mask and only have the value you need written to the destination register.
destination mask/write
mask
Note the word destination above. Masks can only be used to select which element of a register is to be written to. (Hence they are often referred to as write masks.) Even if an instruction usually writes to all four elements of the destination, the mask can be used to select which element(s) of the destination are written. If you leave an element out of a mask, it doesn’t get written. The element masks must be in order; x comes before y comes before z comes before w.
mov r1, c1 // use all
mov r1.xyzw, c1 // use all explicitly (default)
mov r1.xw, c1 // just move c.x and c.w
mov r1.wx, c1 // Error! – invalid order
mov r1.wzyx, c1 // Error! – invalid order
source swizzle
Note the word source above. Swizzles can only be used to select the order and the elements of a register to use as a source. A swizzle must specify four elements, though there is no restriction on the order. A swizzle consists of four letters, and each the letters must be one of “xyzw”.
mov r1, c1 // use all – same as below
mov r1, c1.xyzw // use all in order
mov r1, c1.wzyx // reverse the order
mov r1, c1.wwww // just use the w element
mov r1, c1.xyzy // replace w with y
mov r1.w, c1.zxyx // move c.x into r1.w
mov r1.z, c1.xzwy // move c.w into r1.z
mov r1, c1.x // error need 4, not 1
source negation
Negation can be used to negate an entire source register. They can be used with swizzles.
mov r1, c1 // move c1 into r1
mov r1, -c1 // move negative c1 into r1
mov r1.w, -r1 // negate just r1’s w & store it
mov r1.w, -c1.zzzy // move –c1.y into r1.w
mov -r1, c1 // Error! Can’t negate destination
address registers
Not available in shader version 1.0. Only register a0.x can be used for version 1.1. The address register can be used as a signed offset into the constant register file and it can only be used in the mov instruction. The values in the address register when used must be compute to the legal range for the constant registers (i.e. 0 to 95 for most 1.1, 1.1 vertex shaders)
vs.1.1
mov a0.x, c5.w // load a0.x
mov r1, c1 // regular move, format 1
mov r1, c[1] // same thing alternate format
mov r1, c[1+a0.x]// relative move