From: Nicolai Hähnle Date: Thu, 27 Oct 2016 08:32:27 +0000 (+0200) Subject: tgsi: align the definition of BFI & [UI]BFE with GLSL X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6526977306ae013a3ab4946229168a30015393ec;p=mesa.git tgsi: align the definition of BFI & [UI]BFE with GLSL As previously written, these opcodes use the SM5 semantics which is incompatible with GLSL when bits == 0, offset == 32. At some point we may want to add BFI_SM5 etc. opcodes, but all users currently either want (and expect!) the GLSL semantics or don't care. Bitfield inserts are generated by the GLSL lower_instructions and lower_packing_builtins passes with constant bits and offset arguments, so any workaround code that drivers may have to emit to follow GLSL semantics should be optimized away easily for those uses. Reviewed-by: Marek Olšák --- diff --git a/src/gallium/docs/source/tgsi.rst b/src/gallium/docs/source/tgsi.rst index 5068285aaee..d2d30b41d00 100644 --- a/src/gallium/docs/source/tgsi.rst +++ b/src/gallium/docs/source/tgsi.rst @@ -1583,48 +1583,43 @@ These opcodes are used for bit-level manipulation of integers. .. opcode:: IBFE - Signed Bitfield Extract - See SM5 instruction of the same name. Extracts a set of bits from the input, - and sign-extends them if the high bit of the extracted window is set. + Like GLSL bitfieldExtract. Extracts a set of bits from the input, and + sign-extends them if the high bit of the extracted window is set. Pseudocode:: def ibfe(value, offset, bits): - offset = offset & 0x1f - bits = bits & 0x1f + if offset < 0 or bits < 0 or offset + bits > 32: + return undefined if bits == 0: return 0 # Note: >> sign-extends - if width + offset < 32: - return (value << (32 - offset - bits)) >> (32 - bits) - else: - return value >> offset + return (value << (32 - offset - bits)) >> (32 - bits) .. opcode:: UBFE - Unsigned Bitfield Extract - See SM5 instruction of the same name. Extracts a set of bits from the input, - without any sign-extension. + Like GLSL bitfieldExtract. Extracts a set of bits from the input, without + any sign-extension. Pseudocode:: def ubfe(value, offset, bits): - offset = offset & 0x1f - bits = bits & 0x1f + if offset < 0 or bits < 0 or offset + bits > 32: + return undefined if bits == 0: return 0 # Note: >> does not sign-extend - if width + offset < 32: - return (value << (32 - offset - bits)) >> (32 - bits) - else: - return value >> offset + return (value << (32 - offset - bits)) >> (32 - bits) .. opcode:: BFI - Bitfield Insert - See SM5 instruction of the same name. Replaces a bit region of 'base' with - the low bits of 'insert'. + Like GLSL bitfieldInsert. Replaces a bit region of 'base' with the low bits + of 'insert'. Pseudocode:: def bfi(base, insert, offset, bits): - offset = offset & 0x1f - bits = bits & 0x1f + if offset < 0 or bits < 0 or offset + bits > 32: + return undefined + # << defined such that mask == ~0 when bits == 32, offset == 0 mask = ((1 << bits) - 1) << offset return ((insert << offset) & mask) | (base & ~mask)