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. -- https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/548#note_57055