We're explicitly replacing zero with one in the only place where the
plane count being zero or one makes a difference. It also make sense:
UNKNOWN is used for buffers, which for all intents and purposes have one
plane.
Uncovered by the ininf() test in the next commit. This is why we insist
on test coverage; unfortunately this one slipped through in
fd1beedc07becc7e5e49b64273f7bde7f9a8b2a0.
Vertex shaders do not have CMP, so we use SLT and MAD.
For example, this vertex shader:
uniform float4 f;
void main(inout float4 pos : position, out float4 t1 : TEXCOORD1)
{
t1 = (int4)f;
}
results in:
vs_2_0
dcl_position v0
slt r0, c0, -c0
frc r1, c0
add r2, -r1, c0
slt r1, -r1, r1
mad oT1, r0, r1, r2
mov oPos, v0
while we have the lower_cmp() pass, each time it is applied many
instructions are generated, so this patch introduces a specialized
version of the cast-to-int lowering for efficiency.
Otherwise ubsan reports these errors on the bitwise.shader_test:
libs/vkd3d-shader/hlsl_constant_ops.c:970:50: runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
libs/vkd3d-shader/hlsl_constant_ops.c:970:50: runtime error: left shift of negative value -12
Otherwise ubsan reports errors such as:
libs/vkd3d-shader/spirv.c:7266:5: runtime error: null pointer passed as argument 1, which is declared to never be null
Otherwise ubsan reports runtime errors such as:
libs/vkd3d-shader/ir.c:4731:5: runtime error: null pointer passed as argument 1, which is declared to never be null
Otherwise when passing "-fsanitize=undefined" to the compiler, ubsan
reports such as:
libs/vkd3d-shader/ir.c:3794:5: runtime error: null pointer passed as argument 1, which is declared to never be null
Since we have -Wswitch, this forces the developer to update all relevant
switches when an enum case is added.
Places where the default is just a FIXME are left alone.
We apply distributivity to applicable expressions, specifically with
the following rewrite rules:
(x OPL a) OPR (x OPL b) -> x OPL (a OPR b)
(y OPR (x OPL a)) OPR (x OPL b) -> y OPR (x OPL (a OPR b))
((x OPL a) OPR y) OPR (x OPL b) -> (x OPL (a OPR b)) OPR y
(x OPL a) OPR ((x OPL b) OPR y) -> (x OPL (a OPR b)) OPR y
(x OPL a) OPR (y OPR (x OPL b)) -> (x OPL (a OPR b)) OPR y
where a, b are constants.
The two branches do essentially the same thing, but in different
ways and each one omitting different details. In particular there
is no need to discriminate on whether the register is a relative
address, we can just copy the NULL pointer.
The hull shader control point normalisation pass already ensures
that output registers in the control point phase have two
indices (the control point index and the register index).
Consistent with how D3DXFindShaderComment() allows looking up comments
by tag. This also makes it a little easier to move CTAB generation out
of d3dbc.c.