Giovanni Mascellani (@giomasce) commented about libs/vkd3d-shader/spirv.c:
|| instruction->handler_idx == VKD3DSIH_FIRSTBIT_SHI) { /* In D3D bits are numbered from the most significant bit. */
component_count = vsir_write_mask_component_count(dst->write_mask); val_id = vkd3d_spirv_build_op_isub(builder, type_id,
spirv_compiler_get_constant_uint(compiler, 31), val_id);
spirv_compiler_get_constant_uint_vector(compiler, 31, component_count), val_id);
I guess this is wrong when `~0u` is returned (because the input is 0 or, for the `shi` variant, -1).
It seems that the tests don't trip on this because the HLSL compiler already covers for this. The emitted code is something like: ``` vkd3d:3227409:trace:vkd3d_shader_trace firstbit_shi r0.x v4:uint, cb0[0].y v4:int vkd3d:3227409:trace:vkd3d_shader_trace ieq r0.y v4:uint, r0.x v4:int, l(-1) <s:int> vkd3d:3227409:trace:vkd3d_shader_trace iadd r0.x v4:int, l(31) <s:int>, -r0.x v4:int vkd3d:3227409:trace:vkd3d_shader_trace movc o0.w v4:float, r0.y v4:uint, l(-nan) <s:float>, r0.x v4:float ```
So even if we emit `31 - ~0u` the code immediately makes up for that and converts that back to `~0u`. However this is still wrong, because we're supposed to translate the TPF code correctly even if the HLSL compiler isn't covering up for us.
I realize that's orthogonal to what this MR is doing, but if you could fix that while you're at it it would be great. I guess the hardest part is getting a TPF shader without the fixup instructions. Maybe we'll have to edit the bytecode by hand for that. It would be nice to have a D3DBC/TPF assembler for instruction tests.