Merge commit 'origin/master' into gallium-0.2
[mesa.git] / src / gallium / drivers / cell / ppu / cell_context.c
index bb1838409fcccb188ffcd3f1bb86944930429050..22d552d8e3d8fd98bfa7f14a739429b964d490b0 100644 (file)
@@ -35,7 +35,7 @@
 
 #include "pipe/p_defines.h"
 #include "pipe/p_format.h"
-#include "pipe/p_util.h"
+#include "util/u_memory.h"
 #include "pipe/p_winsys.h"
 #include "pipe/p_screen.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"
 
 
 
-static boolean
-cell_is_format_supported( struct pipe_context *pipe,
-                          enum pipe_format format, uint type )
-{
-   /*struct cell_context *cell = cell_context( pipe );*/
-
-   switch (type) {
-   case PIPE_TEXTURE:
-      /* cell supports all texture formats, XXX for now anyway */
-      return TRUE;
-   case PIPE_SURFACE:
-      /* cell supports all (off-screen) surface formats, XXX for now */
-      return TRUE;
-   default:
-      assert(0);
-      return FALSE;
-   }
-}
-
-
-static int cell_get_param(struct pipe_context *pipe, int param)
-{
-   return pipe->screen->get_param(pipe->screen, param);
-}
-
-static float cell_get_paramf(struct pipe_context *pipe, int param)
-{
-   return pipe->screen->get_paramf(pipe->screen, param);
-}
-
-static const char *
-cell_get_name( struct pipe_context *pipe )
-{
-   return pipe->screen->get_name(pipe->screen);
-}
-
-static const char *
-cell_get_vendor( struct pipe_context *pipe )
-{
-   return pipe->screen->get_vendor(pipe->screen);
-}
-
-
-
 static void
 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);
@@ -117,22 +76,36 @@ 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}
+};
+
+
 struct pipe_context *
 cell_create_context(struct pipe_screen *screen,
                     struct cell_winsys *cws)
 {
    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);
@@ -146,21 +119,6 @@ cell_create_context(struct pipe_screen *screen,
    cell->pipe.screen = screen;
    cell->pipe.destroy = cell_destroy_context;
 
-   /* queries */
-   cell->pipe.is_format_supported = cell_is_format_supported;
-   cell->pipe.get_name = cell_get_name;
-   cell->pipe.get_vendor = cell_get_vendor;
-   cell->pipe.get_param = cell_get_param;
-   cell->pipe.get_paramf = cell_get_paramf;
-
-
-   /* 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.flush = cell_flush;
 
@@ -170,40 +128,56 @@ cell_create_context(struct pipe_screen *screen,
    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, 0);
+   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;
 }