llvmpipe: fix race between draw and setting fragment shader.
[mesa.git] / src / gallium / drivers / llvmpipe / lp_rast.c
index 9e2780ca1d72441965c2c4fd71f617694aea8ccf..3d335e2ad383e9c0d4dc94f7abd9fcd45c64ebab 100644 (file)
@@ -33,8 +33,8 @@
 #include "util/u_pack_color.h"
 #include "util/u_string.h"
 #include "util/u_thread.h"
-
-#include "os/os_time.h"
+#include "util/u_memset.h"
+#include "util/os_time.h"
 
 #include "lp_scene_queue.h"
 #include "lp_context.h"
@@ -107,7 +107,7 @@ lp_rast_tile_begin(struct lp_rasterizer_task *task,
                     task->scene->fb.height - y * TILE_SIZE : TILE_SIZE;
 
    task->thread_data.vis_counter = 0;
-   task->ps_invocations = 0;
+   task->thread_data.ps_invocations = 0;
 
    for (i = 0; i < task->scene->fb.nr_cbufs; i++) {
       if (task->scene->fb.cbufs[i]) {
@@ -211,7 +211,11 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
          switch (block_size) {
          case 1:
             assert(clear_mask == 0xff);
-            memset(dst, (uint8_t) clear_value, height * width);
+            for (i = 0; i < height; i++) {
+               uint8_t *row = (uint8_t *)dst;
+               memset(row, (uint8_t) clear_value, width);
+               dst += dst_stride;
+            }
             break;
          case 2:
             if (clear_mask == 0xffff) {
@@ -236,9 +240,7 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
          case 4:
             if (clear_mask == 0xffffffff) {
                for (i = 0; i < height; i++) {
-                  uint32_t *row = (uint32_t *)dst;
-                  for (j = 0; j < width; j++)
-                     *row++ = clear_value;
+                  util_memset32(dst, clear_value, width);
                   dst += dst_stride;
                }
             }
@@ -446,10 +448,6 @@ lp_rast_shade_quads_mask(struct lp_rasterizer_task *task,
     * allocated 4x4 blocks hence need to filter them out here.
     */
    if ((x % TILE_SIZE) < task->width && (y % TILE_SIZE) < task->height) {
-      /* not very accurate would need a popcount on the mask */
-      /* always count this not worth bothering? */
-      task->ps_invocations += 1 * variant->ps_inv_multiplier;
-
       /* Propagate non-interpolated raster state. */
       task->thread_data.raster_state.viewport_index = inputs->viewport_index;
 
@@ -491,7 +489,7 @@ lp_rast_begin_query(struct lp_rasterizer_task *task,
       pq->start[task->thread_index] = task->thread_data.vis_counter;
       break;
    case PIPE_QUERY_PIPELINE_STATISTICS:
-      pq->start[task->thread_index] = task->ps_invocations;
+      pq->start[task->thread_index] = task->thread_data.ps_invocations;
       break;
    default:
       assert(0);
@@ -524,7 +522,7 @@ lp_rast_end_query(struct lp_rasterizer_task *task,
       break;
    case PIPE_QUERY_PIPELINE_STATISTICS:
       pq->end[task->thread_index] +=
-         task->ps_invocations - pq->start[task->thread_index];
+         task->thread_data.ps_invocations - pq->start[task->thread_index];
       pq->start[task->thread_index] = 0;
       break;
    default:
@@ -632,7 +630,7 @@ rasterize_bin(struct lp_rasterizer_task *task,
 
    lp_rast_tile_end(task);
 
-
+#ifdef DEBUG
    /* Debug/Perf flags:
     */
    if (bin->head->count == 1) {
@@ -641,6 +639,7 @@ rasterize_bin(struct lp_rasterizer_task *task,
       else if (bin->head->cmd[0] == LP_RAST_OP_SHADE_TILE)
          LP_COUNT(nr_pure_shade_64);
    }
+#endif
 }
 
 
@@ -679,7 +678,7 @@ rasterize_scene(struct lp_rasterizer_task *task,
 #endif
 #endif
 
-   if (!task->rast->no_rast && !scene->discard) {
+   if (!task->rast->no_rast) {
       /* loop over scene bins, rasterize each */
       {
          struct cmd_bin *bin;
@@ -793,7 +792,7 @@ thread_function(void *init_data)
    char thread_name[16];
    unsigned fpstate;
 
-   util_snprintf(thread_name, sizeof thread_name, "llvmpipe-%u", task->thread_index);
+   snprintf(thread_name, sizeof thread_name, "llvmpipe-%u", task->thread_index);
    u_thread_setname(thread_name);
 
    /* Make sure that denorms are treated like zeros. This is 
@@ -870,6 +869,10 @@ create_rast_threads(struct lp_rasterizer *rast)
       pipe_semaphore_init(&rast->tasks[i].work_done, 0);
       rast->threads[i] = u_thread_create(thread_function,
                                             (void *) &rast->tasks[i]);
+      if (!rast->threads[i]) {
+         rast->num_threads = i; /* previous thread is max */
+         break;
+      }
    }
 }