#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"
}
+/**
+ * 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 )
LIST_INITHEAD(&svga->dirty_buffers);
+ check_for_workarounds(svga);
+
return &svga->pipe;
no_state:
/** 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:
* 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;
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.
}
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;