Merge branch '7.8'
[mesa.git] / src / gallium / drivers / cell / ppu / cell_context.c
index ccbbd1d331c2c4918fa2257b7f2080c8ff11845d..afcea616d5934c8743c578742184865566d11aa5 100644 (file)
 
 #include "pipe/p_defines.h"
 #include "pipe/p_format.h"
-#include "pipe/p_util.h"
-#include "pipe/p_winsys.h"
+#include "util/u_memory.h"
 #include "pipe/p_screen.h"
 
 #include "draw/draw_context.h"
 #include "draw/draw_private.h"
 
 #include "cell/common.h"
+#include "cell_batch.h"
 #include "cell_clear.h"
 #include "cell_context.h"
 #include "cell_draw_arrays.h"
+#include "cell_fence.h"
 #include "cell_flush.h"
-#include "cell_render.h"
 #include "cell_state.h"
 #include "cell_surface.h"
 #include "cell_spu.h"
@@ -62,6 +62,8 @@ cell_destroy_context( struct pipe_context *pipe )
 {
    struct cell_context *cell = cell_context(pipe);
 
+   util_delete_keymap(cell->fragment_ops_cache, NULL);
+
    cell_spu_exit(cell);
 
    align_free(cell);
@@ -73,22 +75,58 @@ cell_draw_create(struct cell_context *cell)
 {
    struct draw_context *draw = draw_create();
 
+#if 0 /* broken */
    if (getenv("GALLIUM_CELL_VS")) {
       /* plug in SPU-based vertex transformation code */
       draw->shader_queue_flush = cell_vertex_shader_queue_flush;
       draw->driver_private = cell;
    }
+#endif
 
    return draw;
 }
 
 
+static const struct debug_named_value cell_debug_flags[] = {
+   {"checker", CELL_DEBUG_CHECKER},/**< modulate tile clear color by SPU ID */
+   {"asm", CELL_DEBUG_ASM},        /**< dump SPU asm code */
+   {"sync", CELL_DEBUG_SYNC},      /**< SPUs do synchronous DMA */
+   {"fragops", CELL_DEBUG_FRAGMENT_OPS}, /**< SPUs emit fragment ops debug messages*/
+   {"fragopfallback", CELL_DEBUG_FRAGMENT_OP_FALLBACK}, /**< SPUs use reference implementation for fragment ops*/
+   {"cmd", CELL_DEBUG_CMD},       /**< SPUs dump command buffer info */
+   {"cache", CELL_DEBUG_CACHE},   /**< report texture cache stats on exit */
+   {NULL, 0}
+};
+
+static unsigned int
+cell_is_texture_referenced( struct pipe_context *pipe,
+                           struct pipe_texture *texture,
+                           unsigned face, unsigned level)
+{
+   /**
+    * FIXME: Optimize.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+cell_is_buffer_referenced( struct pipe_context *pipe,
+                          struct pipe_buffer *buf)
+{
+   /**
+    * FIXME: Optimize.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
 struct pipe_context *
 cell_create_context(struct pipe_screen *screen,
-                    struct cell_winsys *cws)
+                    void *priv )
 {
    struct cell_context *cell;
-   uint spu, buf;
+   uint i;
 
    /* some fields need to be 16-byte aligned, so align the whole object */
    cell = (struct cell_context*) align_malloc(sizeof(struct cell_context), 16);
@@ -97,65 +135,74 @@ cell_create_context(struct pipe_screen *screen,
 
    memset(cell, 0, sizeof(*cell));
 
-   cell->winsys = cws;
-   cell->pipe.winsys = screen->winsys;
+   cell->winsys = NULL;                /* XXX: fixme - get this from screen? */
+   cell->pipe.winsys = NULL;
    cell->pipe.screen = screen;
+   cell->pipe.priv = priv;
    cell->pipe.destroy = cell_destroy_context;
 
-   /* state setters */
-   cell->pipe.set_vertex_buffer = cell_set_vertex_buffer;
-   cell->pipe.set_vertex_element = cell_set_vertex_element;
-
-   cell->pipe.draw_arrays = cell_draw_arrays;
-   cell->pipe.draw_elements = cell_draw_elements;
-
-   cell->pipe.clear = cell_clear_surface;
+   cell->pipe.clear = cell_clear;
    cell->pipe.flush = cell_flush;
 
+   cell->pipe.is_texture_referenced = cell_is_texture_referenced;
+   cell->pipe.is_buffer_referenced = cell_is_buffer_referenced;
+
 #if 0
    cell->pipe.begin_query = cell_begin_query;
    cell->pipe.end_query = cell_end_query;
    cell->pipe.wait_query = cell_wait_query;
 #endif
 
+   cell_init_draw_functions(cell);
    cell_init_state_functions(cell);
    cell_init_shader_functions(cell);
    cell_init_surface_functions(cell);
-   cell_init_texture_functions(cell);
+   cell_init_vertex_functions(cell);
 
    cell->draw = cell_draw_create(cell);
 
+   /* Create cache of fragment ops generated code */
+   cell->fragment_ops_cache =
+      util_new_keymap(sizeof(struct cell_fragment_ops_key), ~0, NULL);
+
    cell_init_vbuf(cell);
+
    draw_set_rasterize_stage(cell->draw, cell->vbuf);
 
    /* convert all points/lines to tris for the time being */
    draw_wide_point_threshold(cell->draw, 0.0);
    draw_wide_line_threshold(cell->draw, 0.0);
 
+   /* get env vars or read config file to get debug flags */
+   cell->debug_flags = debug_get_flags_option("CELL_DEBUG", 
+                                              cell_debug_flags, 
+                                              0 );
+
+   for (i = 0; i < CELL_NUM_BUFFERS; i++)
+      cell_fence_init(&cell->fenced_buffers[i].fence);
+
+
    /*
     * SPU stuff
     */
-   cell->num_spus = 6;
-   /* XXX is this in SDK 3.0 only?
-   cell->num_spus = spe_cpu_info_get(SPE_COUNT_PHYSICAL_SPES, -1);
-   */
+   /* This call only works with SDK 3.0.  Anyone still using 2.1??? */
+   cell->num_cells = spe_cpu_info_get(SPE_COUNT_PHYSICAL_CPU_NODES, -1);
+   cell->num_spus = spe_cpu_info_get(SPE_COUNT_USABLE_SPES, -1);
+   if (cell->debug_flags) {
+      printf("Cell: found %d Cell(s) with %u SPUs\n",
+             cell->num_cells, cell->num_spus);
+   }
+   if (getenv("CELL_NUM_SPUS")) {
+      cell->num_spus = atoi(getenv("CELL_NUM_SPUS"));
+      assert(cell->num_spus > 0);
+   }
 
    cell_start_spus(cell);
 
-   /* init command, vertex/index buffer info */
-   for (buf = 0; buf < CELL_NUM_BUFFERS; buf++) {
-      cell->buffer_size[buf] = 0;
-
-      /* init batch buffer status values,
-       * mark 0th buffer as used, rest as free.
-       */
-      for (spu = 0; spu < cell->num_spus; spu++) {
-         if (buf == 0)
-            cell->buffer_status[spu][buf][0] = CELL_BUFFER_STATUS_USED;
-         else
-            cell->buffer_status[spu][buf][0] = CELL_BUFFER_STATUS_FREE;
-      }
-   }
+   cell_init_batch_buffers(cell);
+
+   /* make sure SPU initializations are done before proceeding */
+   cell_flush_int(cell, CELL_FLUSH_WAIT);
 
    return &cell->pipe;
 }