[Bug 92760] Add FP64 support to the i965 shader backends
bugzilla-daemon at freedesktop.org
bugzilla-daemon at freedesktop.org
Mon Mar 28 12:25:18 UTC 2016
--- Comment #66 from Iago Toral <itoral at igalia.com> ---
last week Curro spent some time looking at our fp64 branch and testing some
things and we have been discussing some aspects of the hardware in fp64 that
are not all that well documented (or not even documented at all :)) and that
may have some important implications in the implementation, specifically for
the vec4 backend.
I am sharing the main take aways from that discussion here so we can have them
documented for future reference. For some of these we need to discuss
solutions, Curro has some suggestions that I share below so I'd like to know
your thoughts on them.
1. It seems that IVB requires that fp64 instruction have their execsize
unlike HSW+ where the execsize matches the actual number of fp64 elements
processed. I think we might be able to do this in brw_set_dest at the same
where we adjust the execution size of normal instructions, acting only when we
detect a dst that is a 64-bit type.
2. It seems that the ExecMask in fp64 instructions is interpreted as 1-bit per
fp64 component and not as 1-bit per 32-bit component. This has implications for
non-uniform control flow. For example, in a gen7 VS SIMD4x2 execution (2
logical threads, one for each vertex) of a dvec2 fp64 ALU operation subject to
control-flow, the execution of the operation for the first vertex is done
according to the ExecMask bits 0 and 1, which map components X/Y of the first
logical thread and execution of the second vertex will consider bits 2 and 3 of
the ExecMask which map to components Z/W , also of the first thread. This means
that the operation will execute for the second vertex or not depending on
whether the operation executes for the first vertex. Piglit does have any
instances of fp64 tests involving non-uniform control flow like this which is
why we did not observe this behavior before, but we did write an ad-hoc test
that seems to verify that this problem exists.
Curro suggested that we can work around this problem in HSW+ by taking
advantage of the fact that in these gens it is possible to process 8 DF
elements in ALU operations, so we can simply not split dvec4 operations in
dvec2 chunks, which would fix the problem automatically. Unfortunately, this
also means that we need to figure out a solution to the problem with swizzles
and writemasks working on 32-bit elements (more on that topic below).
Unfortunately, that solution would not work for IVB, since that hardware cannot
run ALU instructions operating on more than 4 DF components. Curro thinks that
in this case we could divide the SIMD4x2 execution in 2 SIMD4x1 instructions.
That is, we generate one dvec4 instruction for each logical thread and use
NibCtrl to fixup execution masking for the second instruction.
3. If we implement any solution that involves getting rid of the double
splitting pass like the ones suggested above, we need to figure out a new
solution to address the fact that swizzles operate in 32-bit elements, since we
are back to a situation where we have to deal with dvec4 operands.
Below is a quick reference of the layout of a full dvec4 operand on a SIMD8
register (the l/h suffixes stand for high/low 32-bit).
low dvec2 high dvec2
0 1 2 3 | 4 5 6 7 <- 32-bit channels
xl xh yl yh zl zh wl wh
My understanding here is that the hardware is going to replicate the swizzle we
use across both dvec2 boundaries so we should be able to represent a logical
swizzle like XZ as XY (which would select the first 2 32-bit channels on each
side of the dvec2 boundary) directly, but there will be a lot of combinations
that would not be directly representable. Also, we can't operate logical
channels that belong to different sides of the dvec2 boundary (i.e. add
vgrf1.x:df vgrf2.x:df vgrf3.w:df). To do something like this I think we might
need to use Align1 mode to "align" the data to be on the same side of the dvec2
boundary. This only gets more complicated if we think about all the
permutations of swizzles that are possible... I suppose we will need something
to break the swizzles into separate things we can handle individually, etc and
then something else to recombine the results.
4. Apparently, in fp64 some writemaks operate in 64-bit elements and others
operate in 32-bit elements (!). Specifcially, Curro says that XY and ZW operate
as 32-bit and map to components XZ and YW whereas any other writemask
represents 64-bit components. This means that our current code that uses the
splitting pass and XY/ZW writemasks is actually operating with 32-bit channels
as we thought but it is not really writing to the channels we thought it was
:). This is probably irrelevant in the current implementation because we only
ever use one of these 2 writemaks and they both write to different channels.
However, if we start working with full dvec4 elements, this is going to matter.
In fact, this means that logical writemasks XY and ZW cannot be represented in
hardware (!) and that we would need to work around these by using temporaries
and swizzling data around, which immediatly combines with the issue above to
create a small version of hell :(.
5) It seems that gen7 hardware has a bug by which writes that span more than
one register and operate on 32-bit components won't work. Unfortunately, we use
this all the time in fp64 since accessing data in 32-bit element chunks is a
common pattern, Curro verified this in the simulator, apparently there is
inconsistent execmasking in this situation with the second half of the
instruction which results in the second part of the write not happening
reliably. Curro thinks that the best way to deal with this is to split the
operations in two, each one operating on a single register, which would require
to monkey with NibCtrl again.
You are receiving this mail because:
You are the QA Contact for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the intel-3d-bugs