protonscr

SM5 ibfe and OpBitFieldSExtract have different semantic when (width + offset) >= 32

vkd3dclosed
HansKristian-Work/vkd3d-proton#829 · opened 2021-10-04 by werman · updated 2021-10-05 · 0 comments · github
Wwerman 2021-10-04 github

ibfe - https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/ibfe--sm5---asm-:

else if( width + offset < 32 ) {
   shl dest, src2, 32-(width+offset)
   ishr dest, dest, 32-width
} else  {
   ishr dest, src2, offset
}

OpBitFieldSExtract - https://www.khronos.org/registry/SPIR-V/specs/1.2/SPIRV.html#OpBitFieldSExtract:

The resulting value is undefined if Count or Offset or their sum is greater
than the number of bits in the result.

RADV seems to be fine since it has native ibfe instruction. Turnip however, lowers this instruction in NIR and doesn't handle the case of "(width + offset) >= 32" thus failing tests:

test_shader_instructions:2807:41:ibfe: Test failed: Got {0xfffe0000, 0xfffe0000, 0xfffe0000, 0xfffe0000}, expected {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff} at (0, 0).
test_shader_instructions:2807:42:ibfe: Test failed: Got {0xfffffffe, 0xfffffffe, 0xfffffffe, 0xfffffffe}, expected {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff} at (0, 0).
test_shader_instructions:2807:43:ibfe: Test failed: Got {0x00000000, 0x00000000, 0x00000000, 0x00000000}, expected {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff} at (0, 0).
test_shader_instructions:2807:44:ibfe: Test failed: Got {0xfffffffe, 0xfffffffe, 0xfffffffe, 0xfffffffe}, expected {0x00000000, 0x00000000, 0x00000000, 0x00000000} at (0, 0).

Nothing extracted yet.