llvmpipe/fs: hook up the interpolation APIs.
[mesa.git] / src / gallium / drivers / llvmpipe / lp_scene.c
index e05ea753b4b36436c2277b49c6994520479b2c7f..59eed4145504942a08f6250f37cb72dd2af5ebb3 100644 (file)
@@ -29,8 +29,8 @@
 #include "util/u_math.h"
 #include "util/u_memory.h"
 #include "util/u_inlines.h"
-#include "util/u_simple_list.h"
-#include "util/u_format.h"
+#include "util/simple_list.h"
+#include "util/format/u_format.h"
 #include "lp_scene.h"
 #include "lp_fence.h"
 #include "lp_debug.h"
@@ -62,7 +62,7 @@ lp_scene_create( struct pipe_context *pipe )
    scene->data.head =
       CALLOC_STRUCT(data_block);
 
-   pipe_mutex_init(scene->mutex);
+   (void) mtx_init(&scene->mutex, mtx_plain);
 
 #ifdef DEBUG
    /* Do some scene limit sanity checks here */
@@ -90,7 +90,7 @@ void
 lp_scene_destroy(struct lp_scene *scene)
 {
    lp_fence_reference(&scene->fence, NULL);
-   pipe_mutex_destroy(scene->mutex);
+   mtx_destroy(&scene->mutex);
    assert(scene->data.head->next == NULL);
    FREE(scene->data.head);
    FREE(scene);
@@ -106,8 +106,8 @@ lp_scene_is_empty(struct lp_scene *scene )
 {
    unsigned x, y;
 
-   for (y = 0; y < TILES_Y; y++) {
-      for (x = 0; x < TILES_X; x++) {
+   for (y = 0; y < scene->tiles_y; y++) {
+      for (x = 0; x < scene->tiles_x; x++) {
          const struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
          if (bin->head) {
             return FALSE;
@@ -156,36 +156,54 @@ lp_scene_begin_rasterization(struct lp_scene *scene)
 
    for (i = 0; i < scene->fb.nr_cbufs; i++) {
       struct pipe_surface *cbuf = scene->fb.cbufs[i];
+
+      if (!cbuf) {
+         scene->cbufs[i].stride = 0;
+         scene->cbufs[i].layer_stride = 0;
+         scene->cbufs[i].sample_stride = 0;
+         scene->cbufs[i].nr_samples = 0;
+         scene->cbufs[i].map = NULL;
+         continue;
+      }
+
       if (llvmpipe_resource_is_texture(cbuf->texture)) {
          scene->cbufs[i].stride = llvmpipe_resource_stride(cbuf->texture,
                                                            cbuf->u.tex.level);
+         scene->cbufs[i].layer_stride = llvmpipe_layer_stride(cbuf->texture,
+                                                              cbuf->u.tex.level);
+         scene->cbufs[i].sample_stride = llvmpipe_sample_stride(cbuf->texture);
 
          scene->cbufs[i].map = llvmpipe_resource_map(cbuf->texture,
                                                      cbuf->u.tex.level,
                                                      cbuf->u.tex.first_layer,
-                                                     LP_TEX_USAGE_READ_WRITE,
-                                                     LP_TEX_LAYOUT_LINEAR);
+                                                     LP_TEX_USAGE_READ_WRITE);
+         scene->cbufs[i].format_bytes = util_format_get_blocksize(cbuf->format);
+         scene->cbufs[i].nr_samples = util_res_sample_count(cbuf->texture);
       }
       else {
          struct llvmpipe_resource *lpr = llvmpipe_resource(cbuf->texture);
          unsigned pixstride = util_format_get_blocksize(cbuf->format);
          scene->cbufs[i].stride = cbuf->texture->width0;
+         scene->cbufs[i].layer_stride = 0;
+         scene->cbufs[i].sample_stride = 0;
+         scene->cbufs[i].nr_samples = 1;
          scene->cbufs[i].map = lpr->data;
          scene->cbufs[i].map += cbuf->u.buf.first_element * pixstride;
+         scene->cbufs[i].format_bytes = util_format_get_blocksize(cbuf->format);
       }
    }
 
    if (fb->zsbuf) {
       struct pipe_surface *zsbuf = scene->fb.zsbuf;
       scene->zsbuf.stride = llvmpipe_resource_stride(zsbuf->texture, zsbuf->u.tex.level);
-      scene->zsbuf.blocksize = 
-         util_format_get_blocksize(zsbuf->texture->format);
-
+      scene->zsbuf.layer_stride = llvmpipe_layer_stride(zsbuf->texture, zsbuf->u.tex.level);
+      scene->zsbuf.sample_stride = llvmpipe_sample_stride(zsbuf->texture);
+      scene->zsbuf.nr_samples = util_res_sample_count(zsbuf->texture);
       scene->zsbuf.map = llvmpipe_resource_map(zsbuf->texture,
                                                zsbuf->u.tex.level,
                                                zsbuf->u.tex.first_layer,
-                                               LP_TEX_USAGE_READ_WRITE,
-                                               LP_TEX_LAYOUT_LINEAR);
+                                               LP_TEX_USAGE_READ_WRITE);
+      scene->zsbuf.format_bytes = util_format_get_blocksize(zsbuf->format);
    }
 }
 
@@ -284,7 +302,6 @@ lp_scene_end_rasterization(struct lp_scene *scene )
    scene->scene_size = 0;
    scene->resource_reference_size = 0;
 
-   scene->has_depthstencil_clear = FALSE;
    scene->alloc_failed = FALSE;
 
    util_unreference_framebuffer_state( &scene->fb );
@@ -327,7 +344,7 @@ lp_scene_new_data_block( struct lp_scene *scene )
    }
    else {
       struct data_block *block = MALLOC_STRUCT(data_block);
-      if (block == NULL)
+      if (!block)
          return NULL;
       
       scene->scene_size += sizeof *block;
@@ -470,11 +487,11 @@ lp_scene_bin_iter_begin( struct lp_scene *scene )
  * of work (a bin) to work on.
  */
 struct cmd_bin *
-lp_scene_bin_iter_next( struct lp_scene *scene )
+lp_scene_bin_iter_next( struct lp_scene *scene , int *x, int *y)
 {
    struct cmd_bin *bin = NULL;
 
-   pipe_mutex_lock(scene->mutex);
+   mtx_lock(&scene->mutex);
 
    if (scene->curr_x < 0) {
       /* first bin */
@@ -487,27 +504,61 @@ lp_scene_bin_iter_next( struct lp_scene *scene )
    }
 
    bin = lp_scene_get_bin(scene, scene->curr_x, scene->curr_y);
+   *x = scene->curr_x;
+   *y = scene->curr_y;
 
 end:
    /*printf("return bin %p at %d, %d\n", (void *) bin, *bin_x, *bin_y);*/
-   pipe_mutex_unlock(scene->mutex);
+   mtx_unlock(&scene->mutex);
    return bin;
 }
 
 
-void lp_scene_begin_binning( struct lp_scene *scene,
-                             struct pipe_framebuffer_state *fb, boolean discard )
+void lp_scene_begin_binning(struct lp_scene *scene,
+                            struct pipe_framebuffer_state *fb)
 {
+   int i;
+   unsigned max_layer = ~0;
+
    assert(lp_scene_is_empty(scene));
 
-   scene->discard = discard;
    util_copy_framebuffer_state(&scene->fb, fb);
 
    scene->tiles_x = align(fb->width, TILE_SIZE) / TILE_SIZE;
    scene->tiles_y = align(fb->height, TILE_SIZE) / TILE_SIZE;
-
    assert(scene->tiles_x <= TILES_X);
    assert(scene->tiles_y <= TILES_Y);
+
+   /*
+    * Determine how many layers the fb has (used for clamping layer value).
+    * OpenGL (but not d3d10) permits different amount of layers per rt, however
+    * results are undefined if layer exceeds the amount of layers of ANY
+    * attachment hence don't need separate per cbuf and zsbuf max.
+    */
+   for (i = 0; i < scene->fb.nr_cbufs; i++) {
+      struct pipe_surface *cbuf = scene->fb.cbufs[i];
+      if (cbuf) {
+         if (llvmpipe_resource_is_texture(cbuf->texture)) {
+            max_layer = MIN2(max_layer,
+                             cbuf->u.tex.last_layer - cbuf->u.tex.first_layer);
+         }
+         else {
+            max_layer = 0;
+         }
+      }
+   }
+   if (fb->zsbuf) {
+      struct pipe_surface *zsbuf = scene->fb.zsbuf;
+      max_layer = MIN2(max_layer, zsbuf->u.tex.last_layer - zsbuf->u.tex.first_layer);
+   }
+   scene->fb_max_layer = max_layer;
+   scene->fb_max_samples = util_framebuffer_get_num_samples(fb);
+   if (scene->fb_max_samples == 4) {
+      for (unsigned i = 0; i < 4; i++) {
+         scene->fixed_sample_pos[i][0] = util_iround(lp_sample_pos_4x[i][0] * FIXED_ONE);
+         scene->fixed_sample_pos[i][1] = util_iround(lp_sample_pos_4x[i][1] * FIXED_ONE);
+      }
+   }
 }