[Mesa-dev] [PATCH 05/16] st/nine: Workaround barycentrics issue on some cards
Ilia Mirkin
imirkin at alum.mit.edu
Fri Apr 24 14:19:53 PDT 2015
On Fri, Apr 24, 2015 at 4:09 PM, Axel Davy <axel.davy at ens.fr> wrote:
> Signed-off-by: Axel Davy <axel.davy at ens.fr>
> ---
> src/gallium/state_trackers/nine/device9.c | 4 +++-
> src/gallium/state_trackers/nine/device9.h | 4 ++++
> src/gallium/state_trackers/nine/nine_state.c | 24 ++++++++++++++++++++++++
> 3 files changed, 31 insertions(+), 1 deletion(-)
>
> diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c
> index 43eb7e6..9ca1bb9 100644
> --- a/src/gallium/state_trackers/nine/device9.c
> +++ b/src/gallium/state_trackers/nine/device9.c
> @@ -310,8 +310,10 @@ NineDevice9_ctor( struct NineDevice9 *This,
> return E_OUTOFMEMORY;
>
> if (strstr(pScreen->get_name(pScreen), "AMD") ||
> - strstr(pScreen->get_name(pScreen), "ATI"))
> + strstr(pScreen->get_name(pScreen), "ATI")) {
> This->prefer_user_constbuf = TRUE;
> + This->driver_bugs.buggy_barycentrics = TRUE;
> + }
>
> tmpl.target = PIPE_BUFFER;
> tmpl.format = PIPE_FORMAT_R8_UNORM;
> diff --git a/src/gallium/state_trackers/nine/device9.h b/src/gallium/state_trackers/nine/device9.h
> index f412088..d662f83 100644
> --- a/src/gallium/state_trackers/nine/device9.h
> +++ b/src/gallium/state_trackers/nine/device9.h
> @@ -118,6 +118,10 @@ struct NineDevice9
> boolean ps_integer;
> } driver_caps;
>
> + struct {
> + boolean buggy_barycentrics;
Might I suggest either describing the bug or the solution to the bug? e.g.
boolean shift_viewport;
Perhaps there's another different buggy barycentric problem which is
solved in an entirely different way.
Either way,
Acked-by: Ilia Mirkin <imirkin at alum.mit.edu>
(I don't sufficiently understand the problem to verify that your
solution is correct.)
BTW, have you thought about FBO flipping? Do you have to translate in
the other direction in that case? Or I guess the scaling takes care of
that...
> + } driver_bugs;
> +
> struct u_upload_mgr *upload;
>
> struct nine_range_pool range_pool;
> diff --git a/src/gallium/state_trackers/nine/nine_state.c b/src/gallium/state_trackers/nine/nine_state.c
> index 495cc86..6c7eab3 100644
> --- a/src/gallium/state_trackers/nine/nine_state.c
> +++ b/src/gallium/state_trackers/nine/nine_state.c
> @@ -150,6 +150,30 @@ update_viewport(struct NineDevice9 *device)
> pvport.translate[1] = (float)vport->Height * 0.5f + (float)vport->Y;
> pvport.translate[2] = vport->MinZ;
>
> + /* We found R600 and SI cards have some imprecision
> + * on the barycentric coordinates used for interpolation.
> + * Some shaders rely on having something precise.
> + * We found that the proprietary driver has the imprecision issue,
> + * except when the render target width and height are powers of two.
> + * It is using some sort of workaround for these cases
> + * which covers likely all the cases the applications rely
> + * on something precise.
> + * We haven't found the workaround, but it seems like it's better
> + * for applications if the imprecision is biased towards infinity
> + * instead of -infinity (which is what measured). So shift slightly
> + * the viewport: not enough to change rasterization result (in particular
> + * for multisampling), but enough to make the imprecision biased
> + * towards infinity. We do this shift only if render target width and
> + * height are powers of two.
> + * Solves 'red shadows' bug on UE3 games.
> + */
> + if (device->driver_bugs.buggy_barycentrics &&
> + ((vport->Width & (vport->Width-1)) == 0) &&
> + ((vport->Height & (vport->Height-1)) == 0)) {
> + pvport.translate[0] -= 1.0f / 128.0f;
> + pvport.translate[1] -= 1.0f / 128.0f;
> + }
> +
> pipe->set_viewport_states(pipe, 0, 1, &pvport);
> }
>
> --
> 2.1.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list