texenvprogram: fix for ARB_draw_buffers.
[mesa.git] / src / gallium / winsys / drm / i965 / xlib / xlib_i965.c
index 4ce22a5a49ab402f770d4f02bf7705b3c662406e..74501eeb16f7e87af4de21e50fd535f65c835e27 100644 (file)
@@ -35,6 +35,7 @@
 
 #include "util/u_memory.h"
 #include "util/u_math.h"
+#include "pipe/p_error.h"
 #include "pipe/p_context.h"
 
 #include "xm_winsys.h"
 #include "i965/brw_winsys.h"
 #include "i965/brw_screen.h"
 #include "i965/brw_reg.h"
+#include "i965/brw_structs_dump.h"
 
 #define MAX_VRAM (128*1024*1024)
 
+
+
+extern int brw_disasm (FILE *file, 
+                       const struct brw_instruction *inst,
+                       unsigned count );
+
+extern int intel_decode(const uint32_t *data, 
+                        int count,
+                        uint32_t hw_offset,
+                        uint32_t devid);
+
 struct xlib_brw_buffer
 {
    struct brw_winsys_buffer base;
+   char *virtual;
    unsigned offset;
    unsigned type;
-   char *virtual;
-   unsigned cheesy_refcount;
    int map_count;
+   boolean modified;
 };
 
 
@@ -62,7 +75,10 @@ struct xlib_brw_buffer
 struct xlib_brw_winsys
 {
    struct brw_winsys_screen base;
-   unsigned offset;
+   struct brw_chipset chipset;
+
+   unsigned size;
+   unsigned used;
 };
 
 static struct xlib_brw_winsys *
@@ -81,98 +97,124 @@ xlib_brw_buffer( struct brw_winsys_buffer *buffer )
 
 
 const char *names[BRW_BUFFER_TYPE_MAX] = {
-   "texture",
-   "scanout",
-   "vertex",
-   "curbe",
-   "query",
-   "shader_constants",
-   "wm_scratch",
-   "batch",
-   "state_cache",
-   "pixel",
-   "generic",
+   "TEXTURE",
+   "SCANOUT",
+   "VERTEX",
+   "CURBE",
+   "QUERY",
+   "SHADER_CONSTANTS",
+   "WM_SCRATCH",
+   "BATCH",
+   "GENERAL_STATE",
+   "SURFACE_STATE",
+   "PIXEL",
+   "GENERIC",
 };
 
 const char *usages[BRW_USAGE_MAX] = {
-   "state",
-   "query_result",
-   "render_target",
-   "depth_buffer",
-   "blit_source",
-   "blit_dest",
-   "sampler",
-   "vertex",
-   "scratch"
+   "STATE",
+   "QUERY_RESULT",
+   "RENDER_TARGET",
+   "DEPTH_BUFFER",
+   "BLIT_SOURCE",
+   "BLIT_DEST",
+   "SAMPLER",
+   "VERTEX",
+   "SCRATCH"
 };
 
-static struct brw_winsys_buffer *
+
+const char *data_types[BRW_DATA_MAX] =
+{
+   "GS: CC_VP",
+   "GS: CC_UNIT",
+   "GS: WM_PROG",
+   "GS: SAMPLER_DEFAULT_COLOR",
+   "GS: SAMPLER",
+   "GS: WM_UNIT",
+   "GS: SF_PROG",
+   "GS: SF_VP",
+   "GS: SF_UNIT",
+   "GS: VS_UNIT",
+   "GS: VS_PROG",
+   "GS: GS_UNIT",
+   "GS: GS_PROG",
+   "GS: CLIP_VP",
+   "GS: CLIP_UNIT",
+   "GS: CLIP_PROG",
+   "SS: SURFACE",
+   "SS: SURF_BIND",
+   "CONSTANT DATA",
+   "BATCH DATA",
+   "(untyped)"
+};
+
+
+static enum pipe_error
 xlib_brw_bo_alloc( struct brw_winsys_screen *sws,
-                     enum brw_buffer_type type,
-                     unsigned size,
-                     unsigned alignment )
+                   enum brw_buffer_type type,
+                   unsigned size,
+                   unsigned alignment,
+                   struct brw_winsys_buffer **bo_out )
 {
    struct xlib_brw_winsys *xbw = xlib_brw_winsys(sws);
    struct xlib_brw_buffer *buf;
 
-   debug_printf("%s type %d sz %d align %d\n",
-                __FUNCTION__, type, size, alignment );
+   if (BRW_DEBUG & DEBUG_WINSYS)
+      debug_printf("%s type %s sz %d align %d\n",
+                   __FUNCTION__, names[type], size, alignment );
 
    buf = CALLOC_STRUCT(xlib_brw_buffer);
    if (!buf)
-      return NULL;
+      return PIPE_ERROR_OUT_OF_MEMORY;
 
-   buf->offset = align(xbw->offset, alignment);
+   pipe_reference_init(&buf->base.reference, 1);
+
+   buf->offset = align(xbw->used, alignment);
    buf->type = type;
    buf->virtual = MALLOC(size);
-   buf->cheesy_refcount = 1;
-   buf->base.offset = &buf->offset; /* hmm, cheesy */
    buf->base.size = size;
+   buf->base.sws = sws;
 
-   xbw->offset = align(xbw->offset, alignment) + size;
-   if (xbw->offset > MAX_VRAM)
+   xbw->used = align(xbw->used, alignment) + size;
+   if (xbw->used > MAX_VRAM)
       goto err;
 
-   return &buf->base;
+   /* XXX: possibly rentrant call to bo_destroy:
+    */
+   bo_reference(bo_out, &buf->base);
+   return PIPE_OK;
 
 err:
    assert(0);
+   FREE(buf->virtual);
    FREE(buf);
-   return NULL;
+   return PIPE_ERROR_OUT_OF_MEMORY;
 }
 
 static void 
-xlib_brw_bo_reference( struct brw_winsys_buffer *buffer )
+xlib_brw_bo_destroy( struct brw_winsys_buffer *buffer )
 {
    struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
 
-   buf->cheesy_refcount++;
-}
-
-static void 
-xlib_brw_bo_unreference( struct brw_winsys_buffer *buffer )
-{
-   struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
-
-   if (--buf->cheesy_refcount == 0) {
-      FREE(buffer);
-   }
+   FREE(buf);
 }
 
 static int 
 xlib_brw_bo_emit_reloc( struct brw_winsys_buffer *buffer,
-                          enum brw_buffer_usage usage,
-                          unsigned delta,
-                          unsigned offset,
-                          struct brw_winsys_buffer *buffer2)
+                        enum brw_buffer_usage usage,
+                        unsigned delta,
+                        unsigned offset,
+                        struct brw_winsys_buffer *buffer2)
 {
    struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
    struct xlib_brw_buffer *buf2 = xlib_brw_buffer(buffer2);
 
-   debug_printf("%s buf %p offset %x val %x + %x buf2 %p/%s/%s\n",
-                __FUNCTION__, (void *)buffer, offset,
-                buf2->offset, delta,
-                (void *)buffer2, names[buf2->type], usages[usage]);
+   if (BRW_DEBUG & DEBUG_WINSYS)
+      debug_printf("%s buf %p offset %x val %x + %x buf2 %p/%s/%s\n",
+                   __FUNCTION__, (void *)buffer, offset,
+                   buf2->offset, delta,
+                   (void *)buffer2, names[buf2->type], usages[usage]);
 
    *(uint32_t *)(buf->virtual + offset) = buf2->offset + delta;
 
@@ -183,24 +225,57 @@ static int
 xlib_brw_bo_exec( struct brw_winsys_buffer *buffer,
                     unsigned bytes_used )
 {
-   debug_printf("execute buffer %p, bytes %d\n", (void *)buffer, bytes_used);
+   if (BRW_DEBUG & DEBUG_WINSYS)
+      debug_printf("execute buffer %p, bytes %d\n", (void *)buffer, bytes_used);
 
    return 0;
 }
 
+
+
+
 static int
 xlib_brw_bo_subdata(struct brw_winsys_buffer *buffer,
-                      size_t offset,
-                      size_t size,
-                      const void *data)
+                    enum brw_buffer_data_type data_type,
+                    size_t offset,
+                    size_t size,
+                    const void *data,
+                    const struct brw_winsys_reloc *reloc,
+                    unsigned nr_relocs)
 {
    struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
+   struct xlib_brw_winsys *xbw = xlib_brw_winsys(buffer->sws);
+   unsigned i;
 
-   debug_printf("%s buf %p off %d sz %d data %p\n", 
-                __FUNCTION__, 
-                (void *)buffer, offset, size, data);
+   if (BRW_DEBUG & DEBUG_WINSYS)
+      debug_printf("%s buf %p off %d sz %d %s relocs: %d\n", 
+                   __FUNCTION__, 
+                   (void *)buffer, offset, size, 
+                   data_types[data_type],
+                   nr_relocs);
 
+   assert(buf->base.size >= offset + size);
    memcpy(buf->virtual + offset, data, size);
+
+   /* Apply the relocations:
+    */
+   for (i = 0; i < nr_relocs; i++) {
+      if (BRW_DEBUG & DEBUG_WINSYS)
+         debug_printf("\treloc[%d] usage %s off %d value %x+%x\n", 
+                      i, usages[reloc[i].usage], reloc[i].offset,
+                      xlib_brw_buffer(reloc[i].bo)->offset, reloc[i].delta);
+
+      *(unsigned *)(buf->virtual + offset + reloc[i].offset) = 
+         xlib_brw_buffer(reloc[i].bo)->offset + reloc[i].delta;
+   }
+
+   if (BRW_DUMP)
+      brw_dump_data( xbw->chipset.pci_id,
+                    data_type,
+                    buf->offset + offset, 
+                    buf->virtual + offset, size );
+
+
    return 0;
 }
 
@@ -208,7 +283,8 @@ xlib_brw_bo_subdata(struct brw_winsys_buffer *buffer,
 static boolean 
 xlib_brw_bo_is_busy(struct brw_winsys_buffer *buffer)
 {
-   debug_printf("%s %p\n", __FUNCTION__, (void *)buffer);
+   if (BRW_DEBUG & DEBUG_WINSYS)
+      debug_printf("%s %p\n", __FUNCTION__, (void *)buffer);
    return TRUE;
 }
 
@@ -216,11 +292,12 @@ static boolean
 xlib_brw_bo_references(struct brw_winsys_buffer *a,
                          struct brw_winsys_buffer *b)
 {
-   debug_printf("%s %p %p\n", __FUNCTION__, (void *)a, (void *)b);
+   if (BRW_DEBUG & DEBUG_WINSYS)
+      debug_printf("%s %p %p\n", __FUNCTION__, (void *)a, (void *)b);
    return TRUE;
 }
 
-static boolean 
+static enum pipe_error
 xlib_brw_check_aperture_space( struct brw_winsys_screen *iws,
                                 struct brw_winsys_buffer **buffers,
                                 unsigned count )
@@ -231,43 +308,81 @@ xlib_brw_check_aperture_space( struct brw_winsys_screen *iws,
    for (i = 0; i < count; i++)
       tot_size += buffers[i]->size;
 
-   debug_printf("%s %d bufs, tot_size: %d kb\n", 
-                __FUNCTION__, count, 
-                (tot_size + 1023) / 1024);
+   if (BRW_DEBUG & DEBUG_WINSYS)
+      debug_printf("%s %d bufs, tot_size: %d kb\n", 
+                   __FUNCTION__, count, 
+                   (tot_size + 1023) / 1024);
 
-   return TRUE;
+   return PIPE_OK;
 }
 
 static void *
 xlib_brw_bo_map(struct brw_winsys_buffer *buffer,
-                  boolean write)
+                enum brw_buffer_data_type data_type,
+                unsigned offset,
+                unsigned length,
+                boolean write,
+                boolean discard,
+                boolean explicit)
 {
    struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
 
-   debug_printf("%s %p %s\n", __FUNCTION__, (void *)buffer, 
-                write ? "read/write" : "read");
+   if (BRW_DEBUG & DEBUG_WINSYS)
+      debug_printf("%s %p %s %s\n", __FUNCTION__, (void *)buffer, 
+                   write ? "read/write" : "read",
+                   write ? data_types[data_type] : "");
+
+   if (write)
+      buf->modified = 1;
 
    buf->map_count++;
    return buf->virtual;
 }
 
+
+static void
+xlib_brw_bo_flush_range( struct brw_winsys_buffer *buffer,
+                         unsigned offset,
+                         unsigned length )
+{
+}
+
+
 static void 
 xlib_brw_bo_unmap(struct brw_winsys_buffer *buffer)
 {
    struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
 
-   debug_printf("%s %p\n", __FUNCTION__, (void *)buffer);
+   if (BRW_DEBUG & DEBUG_WINSYS)
+      debug_printf("%s %p\n", __FUNCTION__, (void *)buffer);
 
    --buf->map_count;
    assert(buf->map_count >= 0);
+
+   if (buf->map_count == 0 &&
+       buf->modified) {
+
+      buf->modified = 0;
+      
+      /* Consider dumping new buffer contents here, using the
+       * flush-range info to minimize verbosity.
+       */
+   }
+}
+
+
+static void
+xlib_brw_bo_wait_idle( struct brw_winsys_buffer *buffer )
+{
 }
 
 
 static void
-xlib_brw_winsys_destroy( struct brw_winsys_screen *screen )
+xlib_brw_winsys_destroy( struct brw_winsys_screen *sws )
 {
-   /* XXX: free all buffers */
-   FREE(screen);
+   struct xlib_brw_winsys *xbw = xlib_brw_winsys(sws);
+
+   FREE(xbw);
 }
 
 static struct brw_winsys_screen *
@@ -279,10 +394,11 @@ xlib_create_brw_winsys_screen( void )
    if (!ws)
       return NULL;
 
+   ws->used = 0;
+
    ws->base.destroy              = xlib_brw_winsys_destroy;
    ws->base.bo_alloc             = xlib_brw_bo_alloc;
-   ws->base.bo_reference         = xlib_brw_bo_reference;
-   ws->base.bo_unreference       = xlib_brw_bo_unreference;
+   ws->base.bo_destroy           = xlib_brw_bo_destroy;
    ws->base.bo_emit_reloc        = xlib_brw_bo_emit_reloc;
    ws->base.bo_exec              = xlib_brw_bo_exec;
    ws->base.bo_subdata           = xlib_brw_bo_subdata;
@@ -290,7 +406,9 @@ xlib_create_brw_winsys_screen( void )
    ws->base.bo_references        = xlib_brw_bo_references;
    ws->base.check_aperture_space = xlib_brw_check_aperture_space;
    ws->base.bo_map               = xlib_brw_bo_map;
+   ws->base.bo_flush_range       = xlib_brw_bo_flush_range;
    ws->base.bo_unmap             = xlib_brw_bo_unmap;
+   ws->base.bo_wait_idle         = xlib_brw_bo_wait_idle;
 
    return &ws->base;
 }
@@ -304,12 +422,15 @@ static void
 xlib_i965_display_surface(struct xmesa_buffer *xm_buffer,
                           struct pipe_surface *surf)
 {
-   /* struct brw_texture *texture = brw_texture(surf->texture); */
-
-   debug_printf("%s tex %p, sz %dx%d\n", __FUNCTION__, 
-                (void *)surf->texture,
-                surf->texture->width[0],
-                surf->texture->height[0]);
+   struct brw_surface *surface = brw_surface(surf);
+   struct xlib_brw_buffer *bo = xlib_brw_buffer(surface->bo);
+
+   if (BRW_DEBUG & DEBUG_WINSYS)
+      debug_printf("%s offset %x+%x sz %dx%d\n", __FUNCTION__, 
+                   bo->offset,
+                   surface->draw_offset,
+                   surf->width,
+                   surf->height);
 }
 
 static void
@@ -335,6 +456,8 @@ xlib_create_i965_screen( void )
    if (screen == NULL)
       goto fail;
 
+   xlib_brw_winsys(winsys)->chipset = brw_screen(screen)->chipset;
+
    screen->flush_frontbuffer = xlib_i965_flush_frontbuffer;
    return screen;
 
@@ -346,31 +469,12 @@ fail:
 }
 
 
-static struct pipe_context *
-xlib_create_i965_context( struct pipe_screen *screen,
-                          void *context_private )
-{
-   struct pipe_context *pipe;
-   
-   pipe = brw_create_context(screen);
-   if (pipe == NULL)
-      goto fail;
-
-   pipe->priv = context_private;
-   return pipe;
-
-fail:
-   /* Free stuff here */
-   return NULL;
-}
-
 
 
 
 struct xm_driver xlib_i965_driver = 
 {
    .create_pipe_screen = xlib_create_i965_screen,
-   .create_pipe_context = xlib_create_i965_context,
    .display_surface = xlib_i965_display_surface
 };