Hi,
this series implements initial support for Haswell align16 FP64, and with that we can enable FP64 and OpenGL 4.0 in Haswell. Gen8+ is now fully scalar, so the patches focus on gen7 and Haswell specifically (although they do mention what things are not expected to work outside gen7 for future reference). IvyBridge is not covered in this series (that needs more work).
These patches are available in our repository for testing. You can clone it using the following command:
$ git clone -b i965-fp64-gen7-scalar-vec4-rc1 https://github.com/Igalia/mesa.git
The only feature missing in this series would be register spilling of 64-bit data. We are working on it but we think that can be added later. With this series all existing FP64 tests in Piglit pass on Haswell, except for ~40 tests that fail to spill registers (mostly the same varying-packing tests that failed in the scalar backend before Curro fixed the scalar spilling implementation for SIMD32).
The main issue with align16 / fp64 is that the hardware only supports 32-bit swizzles. This means that dvec components Z/W are not directly accesible using regions with a width of 4 (also, it seems that the hardware will fix DF regions to use a width of 2 anyway). In the past we have tried to split DF instructions with 3/4 components into dvec2 instructions (XY on one instruction, ZW on another) to overcome this restriction, but that won't work in cases of non-uniform control-flow, so that option was eventually discarded.
The current solution proposed by Curro keeps an exec size of 8 for DF instructions (that is, normal dvec4 SIMD4x2 execution) and does not do any kind of splitting by default. In this scenario, using source regions with a width of 2 we have 2-element rows and we can address either of the 2 elements in the row using 32-bit swizzles (XY selects the first DF component in the row, ZW the second). The problem is that not all swizzle combinations are supported. For example, we can't implement a logical swizzle like XXXX because a region such as g0<2,2,1>.XYXY would instead select the logical swizzle XXZZ. This is because with 2-wide rows the swizzle we apply is the same for both the first half of a dvec4 and the second half. There are many other problematic swizzles combinations. Dealing with this requires different combinations of instruction splitting and / or temporaries depending on the incoming swizzles.
With that strategy, accessing components Z/W in a dvec4 is still not trivial, it would require some work and probably also instruction splitting to avoid violating register region restrictions. Instead, we take advantage of a gen7 hardware decompression bug that allows us to implement Z/W swizzles without requiring instruction splitting. This behavior is documented in the corresponding patches and is activated via a specific flag (force_vstride0) that is only set in a particular lowerig pass, so that we keep this hack limited to a particular place in the driver code, should we decide to change that in the future (for example if we want to support gen8/align16). See the commit log on patch "i965/vec4: implement access to DF source components Z/W" for a detailed explanation.
To make things worse, although writemasks mostly work as 64-bit it seems that XY and ZW writemasks in particular are 32-bit, which means that there is no native representation of XY/ZW 64-bit writemasks at all and if we find these we have to split the instructions to work around them.
Because of all this, we decided that an initial implementation could just scalarize all DF instructions to work around most of these issues, with the plan of having a functioning fp64/align16 implementation as soon as possible which would still have some room for improvement in the future. This is what this series implements (with the exception of XYZW swizzles that just work). There are some "easy" swizzles we can let through without scalarization too and the plan is to add them later, and then there are some more complex scenarios that require some level of non-full scalarizarion that we can add later on too with some extra work. Curro wrote an excellent summary of the different situations we can find here [1].
Then there are also a number of relevant hardware bugs and restrictions that require additional instruction splitting. Because of that we had to implement a SIMD splitting pass similar to the one we have for the FS backend but much simpler, since we only really need to split some cases of DF instructions from an execsize of 8 to an execsize of 4.
Special thanks to Curro for all his help and insight!
[1] https://bugs.freedesktop.org/show_bug.cgi?id=92760#c82
Connor Abbott (7):
i965/vec4/nir: simplify glsl_type_for_nir_alu_type()
i965/vec4/nir: allocate two registers for dvec3/dvec4
i965/vec4/nir: fix nir_intrinsic_load_uniform for doubles
i965/vec4/nir: set the right type for 64-bit registers
i965/vec4: add support for printing DF immediates
i965: add brw_vecn_grf()
i965/vec4: don't constant propagate 64-bit immediates
Iago Toral Quiroga (81):
i965/vec4/nir: Add bit-size information to types
i965/vec4/nir: support doubles in ALU operations
i965/vec4/nir: fix emitting 64-bit immediates
i965/vec4: add double/float conversion pseudo-opcodes
i965/vec4: translate d2f/f2d
i965/vec4: set correct register regions for 32-bit and 64-bit
i965/disasm: align16 DF source regions have a width of 2
i965/vec4: We only support 32-bit integer ALU operations for now
i965/vec4: add dst_null_df()
i965/vec4: add VEC4_OPCODE_PICK_{LOW,HIGH}_32BIT opcodes
i965/vec4: add VEC4_OPCODE_SET_{LOW,HIGH}_32BIT opcodes
i965/vec4: Fix DCE for VEC4_OPCODE_SET_{LOW,HIGH}_32BIT
i965/vec4: don't copy propagate vector opcodes that operate in align1
mode
i965/vec4: implement double unpacking
i965/vec4: implement double packing
i965/vec4/nir: implement double comparisons
i965/vec4: fix base offset for nir_registers with doubles
i965/vec4: fix get_nir_dest() to use DF type for 64-bit destinations
i965/vec4: make opt_vector_float ignore doubles
i965/vec4: fix register allocation for 64-bit undef sources
i965/vec4: Rename DF to/from F generator opcodes
i965/vec4: add helpers for conversions to/from doubles
i965/vec4: implement hardware workaround for align16 double to float
conversion
i965/vec4: implement d2i, d2u, i2d and u2d
i965/vec4: implement d2b
i965/vec4: implement fsign() for doubles
i965/vec4: fix optimize predicate for doubles
i965/vec4: add a helper function to create double immediates
i965/vec4: allow the vec4 IR to indicate the execution size of
instructions
i965/vec4: dump the instruction execution size
i965/vec4: add a SIMD lowering pass
i965/vec4: make the generator set correct NibCtrl for SIMD4 DF
instructions
i965/vec4: dump NibCtrl for instructions with execsize 4
i965/disasm: print NibCtrl for instructions with execsize 4
i965/vec4: teach CSE about exec_size, group and doubles
i965/vec4: split double-precision bcsel
i965/vec4: add a scalarization pass for double-precision instructions
i965/vec4: translate 64-bit swizzles to 32-bit
i965/vec4: add a force_vstride0 flag to src_reg
i965/vec4: implement access to DF source components Z/W
i965/vec4: Use force_vstride0 to fix DF Z/W writes from X/Y channels
i965/vec4: add a sanity check for force_vstride0
i965/vec4: print subnr in dump_instruction()
i965/disasm: fix subreg for dst in Align16 mode
i965/vec4: fix regs_read() for doubles
i965/vec4: teach register coalescing about 64-bit
i965/vec4: fix regs_written for doubles
i965/vec4: fix pack_uniform_registers for doubles
i965/vec4: fix indentation in pack_uniform_registers
i965/vec4: Skip swizzle to subnr in 3src instructions with DF operands
i965/vec4/nir: do not emit 64-bit MAD
i965/vec4: do not emit 64-bit MAD
i965/vec4: Add a shuffle_64bit_data helper
i965/vec4: Fix UBO loads for 64-bit data
i965/vec4: Fix SSBO loads for 64-bit data
i965/vec4: Fix SSBO stores for 64-bit data
i965/vec4: prevent copy-propagation from values with a different type
size
i965/vec4: Prevent copy propagation from violating pre-gen8
restrictions
i965/vec4: don't propagate single-precision uniforms into 4-wide
instructions
i965/vec4: extend the DWORD multiply DepCtrl restriction to all gen8
platforms
i965/vec4: Do not use DepCtrl with 64-bit instructions
i965/vec4: do not split scratch read/write opcodes
i965/vec4: fix scratch offset for 64bit data
i965/vec4: fix scratch reads for 64bit data
i965/vec4: fix scratch writes for 64bit data
i965/vec4: fix move_uniform_array_access_to_pull_constant() for 64-bit
data
i965/vec4: fix indentation in move_push_constants_to_pull_constants()
i965/vec4: fix move_push_constants_to_pull_constants() for 64-bit data
i965/vec4: make emit_pull_constant_load support 64-bit loads
i965/vec4: fix store output for 64-bit types
i965/vec4/tcs: fix input loading for 64-bit data
i965/vec4/tcs: fix outputs for 64-bit data
i965/vec4/tes: fix input loading for 64bit data types
i965/vec4/tes: fix setup_payload() for 64bit data types
i965/vec4: split instructions that read 64-bit attrs in TessEval
i965/vec4: fix writes to Z/W:DF from a FIXED_GRF
i965/vec4: dump subnr for FIXED_GRF
i965/vec4/scalarize_df: do not scalarize instructions with identity
swizzles
i965/vec4/scalarize_df: Always scalarize XY / ZW writemasks
i965/vec4: enable ARB_gpu_shader_fp64 for Haswell
i965/gen7: expose OpenGL 4.0 on Haswell
Juan A. Suarez Romero (1):
i965/vec4: handle 32 and 64 bit channels in liveness analysis
Samuel Iglesias Gonsálvez (6):
i965/nir: double/dvec2 uniforms only need to be padded to a single
vec4 slot
i965/vec4: use the new helper function to create double immediates
i965/vec4: don't copy propagate if subnr is set
i965/vec4: set force_vstride0 on any 64-bit source that has subnr > 0
i965/vec4/gs: fix input loading for 64bit data
i965/vec4: implement force_vstride0 for FIXED_GRF
src/mesa/drivers/dri/i965/brw_defines.h | 6 +
src/mesa/drivers/dri/i965/brw_disasm.c | 15 +-
src/mesa/drivers/dri/i965/brw_ir_vec4.h | 4 +
src/mesa/drivers/dri/i965/brw_nir_uniforms.cpp | 3 +-
src/mesa/drivers/dri/i965/brw_reg.h | 6 +
src/mesa/drivers/dri/i965/brw_shader.cpp | 12 +
src/mesa/drivers/dri/i965/brw_vec4.cpp | 645 ++++++++++++++++++---
src/mesa/drivers/dri/i965/brw_vec4.h | 22 +
.../drivers/dri/i965/brw_vec4_copy_propagation.cpp | 59 ++
src/mesa/drivers/dri/i965/brw_vec4_cse.cpp | 30 +-
.../dri/i965/brw_vec4_dead_code_eliminate.cpp | 39 +-
src/mesa/drivers/dri/i965/brw_vec4_generator.cpp | 110 +++-
src/mesa/drivers/dri/i965/brw_vec4_gs_nir.cpp | 43 +-
.../drivers/dri/i965/brw_vec4_live_variables.cpp | 36 +-
.../drivers/dri/i965/brw_vec4_live_variables.h | 7 +-
src/mesa/drivers/dri/i965/brw_vec4_nir.cpp | 629 ++++++++++++++++----
src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp | 56 +-
src/mesa/drivers/dri/i965/brw_vec4_tes.cpp | 83 ++-
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 167 ++++--
src/mesa/drivers/dri/i965/intel_extensions.c | 5 +
src/mesa/drivers/dri/i965/intel_screen.c | 8 +
21 files changed, 1707 insertions(+), 278 deletions(-)
--
2.7.4