Add code to tweak aubfile state and primitives on replay.
authorKeith Whitwell <keith@tungstengraphics.com>
Tue, 12 Sep 2006 13:50:22 +0000 (13:50 +0000)
committerKeith Whitwell <keith@tungstengraphics.com>
Tue, 12 Sep 2006 13:50:22 +0000 (13:50 +0000)
src/mesa/drivers/dri/i965/brw_aub_playback.c

index 73743daa60cf8c058bcec6a9a7453d4d5c8ecb5e..49cc967716e1535fb63e75f93bf9b952d127f3c6 100644 (file)
@@ -7,6 +7,7 @@
 #include <fcntl.h>
 
 #include "brw_aub.h"
+#include "brw_defines.h"
 #include "brw_context.h"
 #include "intel_ioctl.h"
 #include "bufmgr.h"
@@ -22,7 +23,7 @@ struct aub_state {
 static int gobble( struct aub_state *s, int size )
 {
    if (s->csr + size > s->sz) {
-      DBG("EOF in %s\n", __FUNCTION__);
+      _mesa_printf("EOF in %s\n", __FUNCTION__);
       return 1;
    }
 
@@ -30,6 +31,284 @@ static int gobble( struct aub_state *s, int size )
    return 0;
 }
 
+static void flush_and_fence( struct aub_state *s )
+{
+   struct intel_context *intel = s->intel;
+   GLuint buf[2];
+
+   buf[0] = intel->vtbl.flush_cmd();
+   buf[1] = 0;
+
+   intel_cmd_ioctl(intel, (char *)&buf, sizeof(buf), GL_TRUE);
+      
+   intelWaitIrq( intel, intelEmitIrqLocked( intel ));
+}
+
+static void flush_cmds( struct aub_state *s,
+                       const void *data,
+                       int len )
+{
+   DBG("%s %d\n", __FUNCTION__, len);
+
+   if (len & 0x4) {
+      unsigned int *tmp = malloc(len + 4);
+      DBG("padding to octword\n");
+      memcpy(tmp, data, len);
+      tmp[len/4] = MI_NOOP;
+      flush_cmds(s, tmp, len+4);
+      free(tmp);
+      return;
+   }
+
+   /* For ring data, just send off immediately via an ioctl.
+    * This differs slightly from how the stream was executed
+    * initially as this would have been a batchbuffer.
+    */
+   intel_cmd_ioctl(s->intel, (void *)data, len, GL_TRUE);
+
+   if (1)
+      flush_and_fence(s);
+}
+
+static const char *pstrings[] = {
+   "none",
+   "POINTLIST",
+   "LINELIST",
+   "LINESTRIP",
+   "TRILIST",
+   "TRISTRIP",
+   "TRIFAN",
+   "QUADLIST",
+   "QUADSTRIP",
+   "LINELIST_ADJ",
+   "LINESTRIP_ADJ",
+   "TRILIST_ADJ",
+   "TRISTRIP_ADJ",
+   "TRISTRIP_REVERSE",
+   "POLYGON",
+   "RECTLIST",
+   "LINELOOP",
+   "POINTLIST_BF",
+   "LINESTRIP_CONT",
+   "LINESTRIP_BF",
+   "LINESTRIP_CONT_BF",
+   "TRIFAN_NOSTIPPLE",
+};
+
+static void do_3d_prim( struct aub_state *s,
+                       const void *data,
+                       int len )
+{
+   struct brw_3d_primitive prim;
+   const struct brw_3d_primitive *orig = data;
+   int i;
+
+   assert(len == sizeof(prim));
+   memcpy(&prim, data, sizeof(prim));
+
+#define START 0
+#define BLOCK (12*28)
+
+   if (orig->verts_per_instance < BLOCK)
+      flush_cmds(s, &prim, sizeof(prim));
+   else {
+      for (i = START; i + BLOCK < orig->verts_per_instance; i += BLOCK/2) {
+        prim.start_vert_location = i;
+        prim.verts_per_instance = BLOCK;
+        _mesa_printf("%sprim %d/%s verts %d..%d (of %d)\n", 
+                     prim.header.indexed ? "INDEXED " : "",
+                     prim.header.topology, pstrings[prim.header.topology%16],
+                     prim.start_vert_location, 
+                     prim.start_vert_location + prim.verts_per_instance,
+                     orig->verts_per_instance);
+        flush_cmds(s, &prim, sizeof(prim));
+      }
+   }
+}
+
+
+
+static struct {
+   int cmd;
+   const char *name;
+   int has_length;
+} cmd_info[] = {
+   { 0, "NOOP", 0 },
+   { 0x5410, "XY_COLOR_BLT_RGB", 1 },
+   { 0x5430, "XY_COLOR_BLT_RGBA", 1 },
+   { 0x54d0, "XY_SRC_COPY_BLT_RGB", 1 },
+   { 0x54f0, "XY_SRC_COPY_BLT_RGBA", 1 },
+   { CMD_URB_FENCE, "URB_FENCE",  1 },
+   { CMD_CONST_BUFFER_STATE, "CONST_BUFFER_STATE",  1 },
+   { CMD_CONST_BUFFER, "CONST_BUFFER",  1 },
+   { CMD_STATE_BASE_ADDRESS, "STATE_BASE_ADDRESS",  1 },
+   { CMD_STATE_INSN_POINTER, "STATE_INSN_POINTER",  1 },
+   { CMD_PIPELINE_SELECT, "PIPELINE_SELECT", 0, },
+   { CMD_PIPELINED_STATE_POINTERS, "PIPELINED_STATE_POINTERS", 1 },
+   { CMD_BINDING_TABLE_PTRS, "BINDING_TABLE_PTRS", 1 },
+   { CMD_VERTEX_BUFFER, "VERTEX_BUFFER", 1 },
+   { CMD_VERTEX_ELEMENT, "VERTEX_ELEMENT", 1 },
+   { CMD_INDEX_BUFFER, "INDEX_BUFFER", 1 },
+   { CMD_VF_STATISTICS, "VF_STATISTICS", 0 },
+   { CMD_DRAW_RECT, "DRAW_RECT", 1 },
+   { CMD_BLEND_CONSTANT_COLOR, "BLEND_CONSTANT_COLOR", 1 },
+   { CMD_CHROMA_KEY, "CHROMA_KEY", 1 },
+   { CMD_DEPTH_BUFFER, "DEPTH_BUFFER", 1 },
+   { CMD_POLY_STIPPLE_OFFSET, "POLY_STIPPLE_OFFSET", 1 },
+   { CMD_POLY_STIPPLE_PATTERN, "POLY_STIPPLE_PATTERN", 1 },
+   { CMD_LINE_STIPPLE_PATTERN, "LINE_STIPPLE_PATTERN", 1 },
+   { CMD_GLOBAL_DEPTH_OFFSET_CLAMP, "GLOBAL_DEPTH_OFFSET_CLAMP", 1 },
+   { CMD_PIPE_CONTROL, "PIPE_CONTROL", 1 },
+   { CMD_MI_FLUSH, "MI_FLUSH", 0 },
+   { CMD_3D_PRIM, "3D_PRIM", 1 },
+};
+
+#define NR_CMDS (sizeof(cmd_info)/sizeof(cmd_info[0]))
+
+
+static int find_command( unsigned int cmd )
+{
+   int i;
+
+   for (i = 0; i < NR_CMDS; i++) 
+      if (cmd == cmd_info[i].cmd) 
+        return i;
+
+   return -1;
+}
+
+
+
+static int parse_commands( struct aub_state *s,
+                          const unsigned int *data,
+                          int len )
+{
+   while (len) {
+      int cmd = data[0] >> 16;
+      int dwords;
+      int i;
+
+      i = find_command(cmd);
+
+      if (i < 0) {
+        _mesa_printf("couldn't find info for cmd %x\n", cmd);
+        return 1;
+      }
+
+      if (cmd_info[i].has_length)
+        dwords = (data[0] & 0xff) + 2;
+      else
+        dwords = 1;
+
+      _mesa_printf("%s (%d dwords) 0x%x\n", cmd_info[i].name, dwords, data[0]);
+
+      if (len < dwords * 4) {
+        _mesa_printf("EOF in %s (%d bytes)\n", __FUNCTION__, len);
+        return 1;
+      }
+
+
+      if (0 && cmd == CMD_3D_PRIM)
+        do_3d_prim(s, data, dwords * 4);
+      else
+        flush_cmds(s, data, dwords * 4);
+
+      data += dwords;
+      len -= dwords * 4;
+   }
+
+   return 0;
+}
+
+
+
+static void parse_data_write( struct aub_state *s,
+                            const struct aub_block_header *bh,
+                            void *dest,
+                            const unsigned int *data,
+                            int len )
+{
+   switch (bh->type) {
+   case DW_GENERAL_STATE:
+      switch (bh->general_state_type) {
+      case DWGS_VERTEX_SHADER_STATE: {
+        struct brw_vs_unit_state vs;
+        assert(len == sizeof(vs));
+
+        _mesa_printf("DWGS_VERTEX_SHADER_STATE\n");
+        memcpy(&vs, data, sizeof(vs));
+
+/*      vs.vs6.vert_cache_disable = 1;  */
+/*      vs.thread4.max_threads = 4;  */
+
+        memcpy(dest, &vs, sizeof(vs));
+        return;
+      }
+      case DWGS_CLIPPER_STATE: {
+        struct brw_clip_unit_state clip;
+        assert(len == sizeof(clip));
+
+        _mesa_printf("DWGS_CLIPPER_STATE\n");
+        memcpy(&clip, data, sizeof(clip));
+
+/*      clip.thread4.max_threads = 0; */
+/*      clip.clip5.clip_mode = BRW_CLIPMODE_REJECT_ALL;   */
+
+        memcpy(dest, &clip, sizeof(clip));
+        return;
+      }
+
+      case DWGS_NOTYPE:
+      case DWGS_GEOMETRY_SHADER_STATE:
+      case DWGS_STRIPS_FANS_STATE:
+        break;
+
+      case DWGS_WINDOWER_IZ_STATE: {
+           struct brw_wm_unit_state wm;
+           assert(len == sizeof(wm));
+
+           _mesa_printf("DWGS_WINDOWER_IZ_STATE\n");
+           memcpy(&wm, data, sizeof(wm));
+
+/*         wm.wm5.max_threads = 10; */
+
+           memcpy(dest, &wm, sizeof(wm));
+           return;
+        }
+
+      case DWGS_COLOR_CALC_STATE:
+      case DWGS_CLIPPER_VIEWPORT_STATE:
+      case DWGS_STRIPS_FANS_VIEWPORT_STATE:
+      case DWGS_COLOR_CALC_VIEWPORT_STATE:
+      case DWGS_SAMPLER_STATE:
+      case DWGS_KERNEL_INSTRUCTIONS:
+      case DWGS_SCRATCH_SPACE:
+      case DWGS_SAMPLER_DEFAULT_COLOR:
+      case DWGS_INTERFACE_DESCRIPTOR:
+      case DWGS_VLD_STATE:
+      case DWGS_VFE_STATE:
+      default:
+        break;
+      }
+      break;
+   case DW_SURFACE_STATE:
+      break;
+   case DW_1D_MAP:
+   case DW_2D_MAP:
+   case DW_CUBE_MAP:
+   case DW_VOLUME_MAP:
+   case DW_CONSTANT_BUFFER:
+   case DW_CONSTANT_URB_ENTRY:
+   case DW_VERTEX_BUFFER:
+   case DW_INDEX_BUFFER:
+   default:
+      break;
+   }
+
+   memcpy(dest, data, len);
+}
+
+
 /* In order to work, the memory layout has to be the same as the X
  * server which created the aubfile.
  */
@@ -39,10 +318,10 @@ static int parse_block_header( struct aub_state *s )
    void *data = (void *)(bh + 1);
    unsigned int len = (bh->length + 3) & ~3;
 
-   DBG("block header at 0x%x\n", s->csr);
+   _mesa_printf("block header at 0x%x\n", s->csr);
 
    if (s->csr + len + sizeof(*bh) > s->sz) {
-      DBG("EOF in data in %s\n", __FUNCTION__);
+      _mesa_printf("EOF in data in %s\n", __FUNCTION__);
       return 1;
    }
 
@@ -57,17 +336,20 @@ static int parse_block_header( struct aub_state *s )
            return 1;
         }
 
-        /* Just copy the data to the indicated place in agp memory:
-         */
+#if 1
+        parse_data_write(s, bh, dest, data, len);
+#else
         memcpy(dest, data, len);
+#endif
         break;
       }
       case BH_COMMAND_WRITE:
-        /* For ring data, just send off immediately via an ioctl.
-         * This differs slightly from how the stream was executed
-         * initially as this would have been a batchbuffer.
-         */
-        intel_cmd_ioctl(s->intel, data, len, GL_TRUE);
+#if 0
+        intel_cmd_ioctl(s->intel, (void *)data, len, GL_TRUE);
+#else
+        if (parse_commands(s, data, len) != 0)
+           _mesa_printf("parse_commands failed\n");
+#endif
         break;
       default:
         break;
@@ -96,12 +378,12 @@ int brw_playback_aubfile(struct brw_context *brw,
 
    fd = open(filename, O_RDONLY, 0);
    if (fd < 0) {
-      DBG("couldn't open aubfile: %s\n", filename);
+      _mesa_printf("couldn't open aubfile: %s\n", filename);
       return 1;
    }
 
    if (fstat(fd, &sb) != 0) {
-      DBG("couldn't open %s\n", filename);
+      _mesa_printf("couldn't open %s\n", filename);
       return 1;
    }
 
@@ -110,7 +392,7 @@ int brw_playback_aubfile(struct brw_context *brw,
    state.map = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
    
    if (state.map == NULL) {
-      DBG("couldn't mmap %s\n", filename);
+      _mesa_printf("couldn't mmap %s\n", filename);
       return 1;
    }
 
@@ -143,7 +425,7 @@ int brw_playback_aubfile(struct brw_context *brw,
            break;
         
         default:
-           DBG("unknown instruction %x\n", insn);
+           _mesa_printf("unknown instruction %x\n", insn);
            retval = 1;
            break;
         }