On Fri, Sep 10, 2021 at 1:32 AM Zebediah Figura (she/her) zfigura@codeweavers.com wrote:
On 9/9/21 6:16 PM, Matteo Bruni wrote:
On Thu, Sep 9, 2021 at 6:02 AM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl_sm4.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 160da47fd..cac71ef7e 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -981,6 +981,40 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, { switch (expr->op) {
case HLSL_OP1_CAST:
{
const struct hlsl_type *src_type = arg1->data_type;
/* Narrowing casts need to be lowered. */
if (src_type->dimx != expr->node.data_type->dimx)
hlsl_fixme(ctx, expr->node.loc, "Narrowing cast.\n");
switch (src_type->base_type)
{
case HLSL_TYPE_HALF:
case HLSL_TYPE_FLOAT:
write_sm4_unary_op(buffer, VKD3D_SM4_OP_MOV, &expr->node, arg1, 0);
break;
case HLSL_TYPE_BOOL:
case HLSL_TYPE_INT:
write_sm4_unary_op(buffer, VKD3D_SM4_OP_ITOF, &expr->node, arg1, 0);
break;
As far as I'm aware, booleans in SM4+ are represented in quite a peculiar way: false is represented as 0, true is canonically 0xffffffff. I think the idea is to be able to use the result of a conditional expression directly as a mask and such, but don't quote me on that. For sure it's different from SM1-3, which use the traditional 0 and 1 values for false and true.
That's probably the reason why native uses MOVC to convert from bool (to float or anything else) and, most importantly, NE for the opposite direction (with 0 as the other comparand).
"(int)(bool)true" evaluates to 1 in anything I've been able to test. Under what circumstances do you have it evaluating to ~0?
Yeah, the bool -> int conversion explicitly makes sure to give you 1 (by means of the MOVC instruction). You need to look at the generated shader bytecode. Try with this shader:
bool4 main(uniform int i, uniform uint u, uniform bool b, uniform float f) : sv_target { return bool4(((float)(bool)i) + 1.5, ((float)(bool)u) - 2.5, ((float)(bool)b) / 2, f); }