vkd3d-shader/hlsl: Document some possibly obscure HLSL opcodes.
Merge request reports
Activity
- Resolved by Giovanni Mascellani
- Resolved by Giovanni Mascellani
+ /* MOVC(a, b, c) returns c is bitwise zero and b otherwise.
I think you meant "MOVC(a, b, c) returns c if a is bitwise zero and b otherwise." above.
Alternatively:
"MOVC(x, y, z) evaluates to `z' when `x' is bitwise zero and to `y' otherwise."
At the risk of rehashing a discussion we've been over before, this does suggest that "MOVC" is perhaps not the most appropriate name for operation; this sounds like what some other languages might call "if". (I.e., "MOVC(x, y, z)" is essentially "(if x y z)".)
Are both "y" and "z" always evaluated, or is that conditional on "x" as well?
+ * TERNARY(a, b, c) returns c if a == 0 and b otherwise. + * They differ for floating point numbers, because + * -0.0 == 0.0, but it is not bitwise zero. */
So "TERNARY(a, b, c)" is equivalent to "MOVC(EQUAL(a, 0), b, c)", right?
I think you meant "MOVC(a, b, c) returns c if a is bitwise zero and b otherwise." above.
Ah, yes...
Alternatively:
"MOVC(x, y, z) evaluates to `z' when `x' is bitwise zero and to `y' otherwise."
I deliberately avoided using
x
,y
andz
because they easily confuse with swizzle letters. Of coursea
andb
are used for swizzles too, but the fact thatc
andd
are not arguably makes it harder to fall for it.At the risk of rehashing a discussion we've been over before, this does suggest that "MOVC" is perhaps not the most appropriate name for operation; this sounds like what some other languages might call "if". (I.e., "MOVC(x, y, z)" is essentially "(if x y z)".)
Both
MOVC
andTERNARY
are a form ofif
, soif
looks precisely like the thing you'd want to avoid to name either of them. They just differ by a technicality in how they evaluate trueness. The names still make some sense, given the context:MOVC
is designed to reproduce the raw behavior of, well, theMOVC
operator in TPF, whileTERNARY
is designed to reproduce the behavior of the ternary operator in C.Are both "y" and "z" always evaluated, or is that conditional on "x" as well?
From my point of view the HLSL IR doesn't have a concept of evaluating nodes. Nodes purely forward a value and have no side effects.
So "TERNARY(a, b, c)" is equivalent to "MOVC(EQUAL(a, 0), b, c)", right?
Rather
MOVC(NEQUAL(a, 0), b, c)
, unless I am missing something, where0
is assumed to be of the same type asa
. As the comment notices, they only differ fora == -0.0
:MOVC(-0.0, b, c) == b
, whileTERNARY(-0.0, b, c) == c
.Rather
MOVC(NEQUAL(a, 0), b, c)
BTW, I'm assuming that
NEQUAL
is always the opposite ofEQUAL
, an in particular thatNEQUAL(0.0, -0.0)
evaluates to false andNEQUAL(NAN, NAN)
evaluates to true. This seems to be the case for IEEE 754 from a brief check, but I might have missed something.
added 1 commit
- a1a271fb - vkd3d-shader/hlsl: Document some possibly obscure HLSL opcodes.
Alternatively:
"MOVC(x, y, z) evaluates to `z' when `x' is bitwise zero and to `y' otherwise."
I deliberately avoided using
x
,y
andz
because they easily confuse with swizzle letters. Of coursea
andb
are used for swizzles too, but the fact thatc
andd
are not arguably makes it harder to fall for it.Fair enough, although "a" in particular has the annoying property that it's also a word in English. (As well as in a number of other languages, for that matter.)
At the risk of rehashing a discussion we've been over before, this does suggest that "MOVC" is perhaps not the most appropriate name for operation; this sounds like what some other languages might call "if". (I.e., "MOVC(x, y, z)" is essentially "(if x y z)".)
Both
MOVC
andTERNARY
are a form ofif
, soif
looks precisely like the thing you'd want to avoid to name either of them. They just differ by a technicality in how they evaluate trueness. The names still make some sense, given the context:MOVC
is designed to reproduce the raw behavior of, well, theMOVC
operator in TPF, whileTERNARY
is designed to reproduce the behavior of the ternary operator in C.Are both "y" and "z" always evaluated, or is that conditional on "x" as well?
From my point of view the HLSL IR doesn't have a concept of evaluating nodes. Nodes purely forward a value and have no side effects.
HLSL_IR_STORE and HLSL_IR_RESOURCE_STORE exist though. I don't think you can use those as HLSL_IR_EXPR sources (right?), but that might not necessarily be obvious. It does touch a bit on what I think the issue with "MOVC" is as well though; "MOVC" sounds suspiciously like something that might be called a conditional store operation.
So "TERNARY(a, b, c)" is equivalent to "MOVC(EQUAL(a, 0), b, c)", right?
Rather
MOVC(NEQUAL(a, 0), b, c)
, unless I am missing something, where0
is assumed to be of the same type asa
. As the comment notices, they only differ fora == -0.0
:MOVC(-0.0, b, c) == b
, whileTERNARY(-0.0, b, c) == c
.Right, NEQUAL(), and that's indeed what lower_ternary() does.
Anyway, I think this MR is fine like this.
HLSL_IR_STORE and HLSL_IR_RESOURCE_STORE exist though. I don't think you can use those as HLSL_IR_EXPR sources (right?), but that might not necessarily be obvious.
As this MR proves, we're not in an overabundance of documentation about the HLSL IR, that's sure.
In my interpretation, the fact that
HLSL_IR_STORE
andHLSL_IR_RESOURCE_STORE
don't evaluate to a value is of little relevance. Even if they did, they are executed if the control flow reach them, not if their result is used.I realize that my sentence "Nodes purely forward a value and have no side effects" has probably a poor choice of words: of course nodes, which we use essentially as a synonym for "instructions", of course do have side effects (in general, at least). What I wanted to say is probably more like "References purely forward a value [etc]": the act of recalling the value produced by an earlier node/instruction has no side effect, therefore the question if
MOVC
evaluates the operand which is not selected is empty: the operand doesn't bear any side effect, be it selected or not; and the referenced node/instruction is evaluated (possibly with side effects) independently of its value being selected byMOVC
or not, simply by virtue of being in the control flow; it would have been evaluated even ifMOVC
didn't have it as an operand at all.
HLSL_IR_STORE and HLSL_IR_RESOURCE_STORE exist though. I don't think you can use those as HLSL_IR_EXPR sources (right?), but that might not necessarily be obvious. It does touch a bit on what I think the issue with "MOVC" is as well though; "MOVC" sounds suspiciously like something that might be called a conditional store operation.
Yes, those have a side effect, but they don't yield a value.
Naming is hard and I don't think that we're going to have a perfect name here, which is why we need this documentation.
added 41 commits
-
a1a271fb...3113f167 - 39 commits from branch
wine:master
- f251da57 - vkd3d-shader/hlsl: Remove HLSL_OP3_LERP.
- ee288618 - vkd3d-shader/hlsl: Document some possibly obscure HLSL opcodes.
-
a1a271fb...3113f167 - 39 commits from branch