From c875d6e57a817bb6a8163a8a98ebd2768ee91848 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 24 Mar 2014 17:24:01 -0600 Subject: [PATCH] svga: add work-around for Sauerbraten Z fighting issue Reviewed-by: Jose Fonseca --- src/gallium/drivers/svga/svga_context.c | 33 +++++++++++++++++++ src/gallium/drivers/svga/svga_context.h | 5 +++ .../drivers/svga/svga_state_need_swtnl.c | 13 ++++++-- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c index 4da9a6551f6..0ba09ce2ebc 100644 --- a/src/gallium/drivers/svga/svga_context.c +++ b/src/gallium/drivers/svga/svga_context.c @@ -25,11 +25,13 @@ #include "svga_cmd.h" +#include "os/os_process.h" #include "pipe/p_defines.h" #include "util/u_inlines.h" #include "pipe/p_screen.h" #include "util/u_memory.h" #include "util/u_bitmask.h" +#include "util/u_string.h" #include "svga_context.h" #include "svga_screen.h" @@ -80,6 +82,35 @@ static void svga_destroy( struct pipe_context *pipe ) } +/** + * Check the process name to see if we're running with an app that + * needs any particular work-arounds. + */ +static void +check_for_workarounds(struct svga_context *svga) +{ + char name[1000]; + + if (!os_get_process_name(name, sizeof(name))) + return; + + if (util_strcmp(name, "sauer_client") == 0) { + /* + * Sauerbraten uses a two-pass rendering algorithm. The first pass + * draws a depth map. The second pass draws the colors. On the second + * pass we wind up using the swtnl path because the game tries to use + * a GLbyte[3] normal vector array (which the SVGA3D protocol does not + * support.) The vertices of the first and second passes don't quite + * match so we see some depth/Z-fighting issues. This work-around + * causes us to map GLbyte[3] to SVGA3D_DECLTYPE_UBYTE4N and avoid the + * swtnl path. Despite not correctly converting normal vectors from + * GLbyte[3] to float[4], the rendering looks OK. + */ + debug_printf("Enabling sauerbraten GLbyte[3] work-around\n"); + svga->workaround.use_decltype_ubyte4n = TRUE; + } +} + struct pipe_context *svga_context_create( struct pipe_screen *screen, void *priv ) @@ -156,6 +187,8 @@ struct pipe_context *svga_context_create( struct pipe_screen *screen, LIST_INITHEAD(&svga->dirty_buffers); + check_for_workarounds(svga); + return &svga->pipe; no_state: diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h index 0daab0b3229..1e93b024f9f 100644 --- a/src/gallium/drivers/svga/svga_context.h +++ b/src/gallium/drivers/svga/svga_context.h @@ -389,6 +389,11 @@ struct svga_context /** performance / info queries */ uint64_t num_draw_calls; /**< SVGA_QUERY_DRAW_CALLS */ uint64_t num_fallbacks; /**< SVGA_QUERY_FALLBACKS */ + + /** quirks / work-around flags for particular apps */ + struct { + boolean use_decltype_ubyte4n; + } workaround; }; /* A flag for each state_tracker state object: diff --git a/src/gallium/drivers/svga/svga_state_need_swtnl.c b/src/gallium/drivers/svga/svga_state_need_swtnl.c index c0bfd2c14d0..6f1d802bced 100644 --- a/src/gallium/drivers/svga/svga_state_need_swtnl.c +++ b/src/gallium/drivers/svga/svga_state_need_swtnl.c @@ -36,7 +36,8 @@ * format. Return SVGA3D_DECLTYPE_MAX for unsupported gallium formats. */ static INLINE SVGA3dDeclType -svga_translate_vertex_format(enum pipe_format format) +svga_translate_vertex_format(const struct svga_context *svga, + enum pipe_format format) { switch (format) { case PIPE_FORMAT_R32_FLOAT: return SVGA3D_DECLTYPE_FLOAT1; @@ -57,6 +58,12 @@ svga_translate_vertex_format(enum pipe_format format) case PIPE_FORMAT_R16G16_FLOAT: return SVGA3D_DECLTYPE_FLOAT16_2; case PIPE_FORMAT_R16G16B16A16_FLOAT: return SVGA3D_DECLTYPE_FLOAT16_4; + case PIPE_FORMAT_R8G8B8_SNORM: + if (svga->workaround.use_decltype_ubyte4n) { + return SVGA3D_DECLTYPE_UBYTE4N; + } + /* fall-through */ + default: /* There are many formats without hardware support. This case * will be hit regularly, meaning we'll need swvfetch. @@ -78,7 +85,9 @@ update_need_swvfetch(struct svga_context *svga, unsigned dirty) } for (i = 0; i < svga->curr.velems->count; i++) { - svga->state.sw.ve_format[i] = svga_translate_vertex_format(svga->curr.velems->velem[i].src_format); + svga->state.sw.ve_format[i] = + svga_translate_vertex_format(svga, + svga->curr.velems->velem[i].src_format); if (svga->state.sw.ve_format[i] == SVGA3D_DECLTYPE_MAX) { /* Unsupported format - use software fetch */ need_swvfetch = TRUE; -- 2.30.2