ilo: rename ilo_3d.[ch] to ilo_draw.[ch]
authorChia-I Wu <olvaffe@gmail.com>
Wed, 24 Sep 2014 05:06:45 +0000 (13:06 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Fri, 26 Sep 2014 13:15:55 +0000 (21:15 +0800)
There is not much left in struct ilo_3d.  We want to kill it and ilo_3d.[ch]
will be bad names.

Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
src/gallium/drivers/ilo/Makefile.sources
src/gallium/drivers/ilo/ilo_3d.c [deleted file]
src/gallium/drivers/ilo/ilo_3d.h [deleted file]
src/gallium/drivers/ilo/ilo_blitter_rectlist.c
src/gallium/drivers/ilo/ilo_context.c
src/gallium/drivers/ilo/ilo_draw.c [new file with mode: 0644]
src/gallium/drivers/ilo/ilo_draw.h [new file with mode: 0644]
src/gallium/drivers/ilo/ilo_query.c

index 0cc56688b7a80d927f64f0ee97bcf2a27c46ec6e..a6477e76b394c40058a3d9c092602a95d8dccaff 100644 (file)
@@ -1,6 +1,4 @@
 C_SOURCES := \
-       ilo_3d.c \
-       ilo_3d.h \
        ilo_3d_pipeline.c \
        ilo_3d_pipeline_gen6.c \
        ilo_3d_pipeline_gen6.h \
@@ -29,6 +27,8 @@ C_SOURCES := \
        ilo_context.h \
        ilo_cp.c \
        ilo_cp.h \
+       ilo_draw.c \
+       ilo_draw.h \
        ilo_format.c \
        ilo_format.h \
        ilo_gpgpu.c \
diff --git a/src/gallium/drivers/ilo/ilo_3d.c b/src/gallium/drivers/ilo/ilo_3d.c
deleted file mode 100644 (file)
index e708cbc..0000000
+++ /dev/null
@@ -1,701 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2012-2013 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Chia-I Wu <olv@lunarg.com>
- */
-
-#include "util/u_prim.h"
-#include "intel_winsys.h"
-
-#include "ilo_3d_pipeline.h"
-#include "ilo_blit.h"
-#include "ilo_context.h"
-#include "ilo_cp.h"
-#include "ilo_query.h"
-#include "ilo_shader.h"
-#include "ilo_state.h"
-#include "ilo_3d.h"
-
-static void
-ilo_3d_own_render_ring(struct ilo_3d *hw3d)
-{
-   ilo_cp_set_owner(hw3d->cp, INTEL_RING_RENDER, &hw3d->owner);
-}
-
-static uint64_t
-query_timestamp_to_ns(const struct ilo_3d *hw3d, uint64_t timestamp)
-{
-   /* see ilo_get_timestamp() */
-   return (timestamp & 0xffffffff) * 80;
-}
-
-/**
- * Process the bo and accumulate the result.  The bo is emptied.
- */
-static void
-query_process_bo(const struct ilo_3d *hw3d, struct ilo_query *q)
-{
-   const uint64_t *vals;
-   uint64_t tmp;
-   int i;
-
-   if (!q->used)
-      return;
-
-   vals = intel_bo_map(q->bo, false);
-   if (!vals) {
-      q->used = 0;
-      return;
-   }
-
-   switch (q->type) {
-   case PIPE_QUERY_OCCLUSION_COUNTER:
-   case PIPE_QUERY_TIME_ELAPSED:
-   case PIPE_QUERY_PRIMITIVES_GENERATED:
-   case PIPE_QUERY_PRIMITIVES_EMITTED:
-      assert(q->stride == sizeof(*vals) * 2);
-
-      tmp = 0;
-      for (i = 0; i < q->used; i++)
-         tmp += vals[2 * i + 1] - vals[2 * i];
-
-      if (q->type == PIPE_QUERY_TIME_ELAPSED)
-         tmp = query_timestamp_to_ns(hw3d, tmp);
-
-      q->result.u64 += tmp;
-      break;
-   case PIPE_QUERY_TIMESTAMP:
-      assert(q->stride == sizeof(*vals));
-
-      q->result.u64 = query_timestamp_to_ns(hw3d, vals[q->used - 1]);
-      break;
-   case PIPE_QUERY_PIPELINE_STATISTICS:
-      assert(q->stride == sizeof(*vals) * 22);
-
-      for (i = 0; i < q->used; i++) {
-         struct pipe_query_data_pipeline_statistics *stats =
-            &q->result.pipeline_statistics;
-         const uint64_t *begin = vals + 22 * i;
-         const uint64_t *end = begin + 11;
-
-         stats->ia_vertices    += end[0] - begin[0];
-         stats->ia_primitives  += end[1] - begin[1];
-         stats->vs_invocations += end[2] - begin[2];
-         stats->gs_invocations += end[3] - begin[3];
-         stats->gs_primitives  += end[4] - begin[4];
-         stats->c_invocations  += end[5] - begin[5];
-         stats->c_primitives   += end[6] - begin[6];
-         stats->ps_invocations += end[7] - begin[7];
-         stats->hs_invocations += end[8] - begin[8];
-         stats->ds_invocations += end[9] - begin[9];
-         stats->cs_invocations += end[10] - begin[10];
-      }
-      break;
-   default:
-      break;
-   }
-
-   intel_bo_unmap(q->bo);
-
-   q->used = 0;
-}
-
-static void
-query_begin_bo(struct ilo_3d *hw3d, struct ilo_query *q)
-{
-   /* bo is full */
-   if (q->used >= q->count)
-      query_process_bo(hw3d, q);
-
-   /* write the beginning value to the bo */
-   if (q->in_pairs)
-      ilo_3d_pipeline_emit_query(hw3d->pipeline, q, q->stride * q->used);
-}
-
-static void
-query_end_bo(struct ilo_3d *hw3d, struct ilo_query *q)
-{
-   uint32_t offset;
-
-   assert(q->used < q->count);
-
-   offset = q->stride * q->used;
-   if (q->in_pairs)
-      offset += q->stride >> 1;
-
-   q->used++;
-
-   /* write the ending value to the bo */
-   ilo_3d_pipeline_emit_query(hw3d->pipeline, q, offset);
-}
-
-bool
-ilo_3d_init_query(struct pipe_context *pipe, struct ilo_query *q)
-{
-   struct ilo_context *ilo = ilo_context(pipe);
-   unsigned bo_size;
-
-   switch (q->type) {
-   case PIPE_QUERY_OCCLUSION_COUNTER:
-   case PIPE_QUERY_TIME_ELAPSED:
-   case PIPE_QUERY_PRIMITIVES_GENERATED:
-   case PIPE_QUERY_PRIMITIVES_EMITTED:
-      q->stride = sizeof(uint64_t);
-      q->in_pairs = true;
-      break;
-   case PIPE_QUERY_TIMESTAMP:
-      q->stride = sizeof(uint64_t);
-      q->in_pairs = false;
-      break;
-   case PIPE_QUERY_PIPELINE_STATISTICS:
-      q->stride = sizeof(uint64_t) * 11;
-      q->in_pairs = true;
-      break;
-   default:
-      return false;
-      break;
-   }
-
-   q->cmd_len = ilo_3d_pipeline_estimate_size(ilo->hw3d->pipeline,
-         ILO_3D_PIPELINE_QUERY, q);
-
-   /* double cmd_len and stride if in pairs */
-   q->cmd_len <<= q->in_pairs;
-   q->stride <<= q->in_pairs;
-
-   bo_size = (q->stride > 4096) ? q->stride : 4096;
-   q->bo = intel_winsys_alloc_buffer(ilo->winsys, "query", bo_size, false);
-   if (!q->bo)
-      return false;
-
-   q->count = bo_size / q->stride;
-
-   return true;
-}
-
-void
-ilo_3d_begin_query(struct pipe_context *pipe, struct ilo_query *q)
-{
-   struct ilo_3d *hw3d = ilo_context(pipe)->hw3d;
-
-   ilo_3d_own_render_ring(hw3d);
-
-   /* need to submit first */
-   if (!ilo_builder_validate(&hw3d->cp->builder, 1, &q->bo) ||
-         ilo_cp_space(hw3d->cp) < q->cmd_len) {
-      ilo_cp_submit(hw3d->cp, "out of aperture or space");
-
-      assert(ilo_builder_validate(&hw3d->cp->builder, 1, &q->bo));
-      assert(ilo_cp_space(hw3d->cp) >= q->cmd_len);
-
-      ilo_3d_own_render_ring(hw3d);
-   }
-
-   /* reserve the space for ending/pausing the query */
-   hw3d->owner.reserve += q->cmd_len >> q->in_pairs;
-
-   query_begin_bo(hw3d, q);
-
-   if (q->in_pairs)
-      list_add(&q->list, &hw3d->queries);
-}
-
-void
-ilo_3d_end_query(struct pipe_context *pipe, struct ilo_query *q)
-{
-   struct ilo_3d *hw3d = ilo_context(pipe)->hw3d;
-
-   ilo_3d_own_render_ring(hw3d);
-
-   /* reclaim the reserved space */
-   hw3d->owner.reserve -= q->cmd_len >> q->in_pairs;
-   assert(hw3d->owner.reserve >= 0);
-
-   query_end_bo(hw3d, q);
-
-   list_delinit(&q->list);
-}
-
-/**
- * Process the raw query data.
- */
-void
-ilo_3d_process_query(struct pipe_context *pipe, struct ilo_query *q)
-{
-   struct ilo_3d *hw3d = ilo_context(pipe)->hw3d;
-
-   query_process_bo(hw3d, q);
-}
-
-static void
-ilo_3d_own_cp(struct ilo_cp *cp, void *data)
-{
-   struct ilo_3d *hw3d = data;
-
-   /* multiply by 2 for both resuming and pausing */
-   if (ilo_cp_space(hw3d->cp) < hw3d->owner.reserve * 2) {
-      ilo_cp_submit(hw3d->cp, "out of space");
-      assert(ilo_cp_space(hw3d->cp) >= hw3d->owner.reserve * 2);
-   }
-
-   while (true) {
-      struct ilo_builder_snapshot snapshot;
-      struct ilo_query *q;
-
-      ilo_builder_batch_snapshot(&hw3d->cp->builder, &snapshot);
-
-      /* resume queries */
-      LIST_FOR_EACH_ENTRY(q, &hw3d->queries, list)
-         query_begin_bo(hw3d, q);
-
-      if (!ilo_builder_validate(&hw3d->cp->builder, 0, NULL)) {
-         ilo_builder_batch_restore(&hw3d->cp->builder, &snapshot);
-
-         if (ilo_builder_batch_used(&hw3d->cp->builder)) {
-            ilo_cp_submit(hw3d->cp, "out of aperture");
-            continue;
-         }
-      }
-
-      break;
-   }
-
-   assert(ilo_cp_space(hw3d->cp) >= hw3d->owner.reserve);
-}
-
-static void
-ilo_3d_release_cp(struct ilo_cp *cp, void *data)
-{
-   struct ilo_3d *hw3d = data;
-   struct ilo_query *q;
-
-   assert(ilo_cp_space(hw3d->cp) >= hw3d->owner.reserve);
-
-   /* pause queries */
-   LIST_FOR_EACH_ENTRY(q, &hw3d->queries, list)
-      query_end_bo(hw3d, q);
-}
-
-/**
- * Hook for CP new-batch.
- */
-void
-ilo_3d_cp_submitted(struct ilo_3d *hw3d)
-{
-   /* invalidate the pipeline */
-   ilo_3d_pipeline_invalidate(hw3d->pipeline,
-         ILO_3D_PIPELINE_INVALIDATE_BATCH_BO |
-         ILO_3D_PIPELINE_INVALIDATE_STATE_BO |
-         ILO_3D_PIPELINE_INVALIDATE_KERNEL_BO);
-
-   hw3d->new_batch = true;
-}
-
-/**
- * Create a 3D context.
- */
-struct ilo_3d *
-ilo_3d_create(struct ilo_cp *cp, const struct ilo_dev_info *dev)
-{
-   struct ilo_3d *hw3d;
-
-   hw3d = CALLOC_STRUCT(ilo_3d);
-   if (!hw3d)
-      return NULL;
-
-   hw3d->cp = cp;
-   hw3d->owner.own = ilo_3d_own_cp;
-   hw3d->owner.release = ilo_3d_release_cp;
-   hw3d->owner.data = hw3d;
-   hw3d->owner.reserve = 0;
-
-   hw3d->new_batch = true;
-
-   list_inithead(&hw3d->queries);
-
-   hw3d->pipeline = ilo_3d_pipeline_create(&cp->builder);
-   if (!hw3d->pipeline) {
-      FREE(hw3d);
-      return NULL;
-   }
-
-   return hw3d;
-}
-
-/**
- * Destroy a 3D context.
- */
-void
-ilo_3d_destroy(struct ilo_3d *hw3d)
-{
-   ilo_3d_pipeline_destroy(hw3d->pipeline);
-   FREE(hw3d);
-}
-
-static bool
-draw_vbo(struct ilo_3d *hw3d, const struct ilo_state_vector *vec)
-{
-   bool need_flush = false;
-   bool success = true;
-   int max_len, before_space;
-
-   /* on GEN7+, we need SOL_RESET to reset the SO write offsets */
-   if (ilo_dev_gen(hw3d->pipeline->dev) >= ILO_GEN(7) &&
-       (vec->dirty & ILO_DIRTY_SO) && vec->so.enabled &&
-       !vec->so.append_bitmask) {
-      ilo_cp_submit(hw3d->cp, "SOL_RESET");
-      ilo_cp_set_one_off_flags(hw3d->cp, INTEL_EXEC_GEN7_SOL_RESET);
-   }
-
-   ilo_3d_own_render_ring(hw3d);
-
-   if (!hw3d->new_batch) {
-      /*
-       * Without a better tracking mechanism, when the framebuffer changes, we
-       * have to assume that the old framebuffer may be sampled from.  If that
-       * happens in the middle of a batch buffer, we need to insert manual
-       * flushes.
-       */
-      need_flush = (vec->dirty & ILO_DIRTY_FB);
-
-      /* same to SO target changes */
-      need_flush |= (vec->dirty & ILO_DIRTY_SO);
-   }
-
-   /* make sure there is enough room first */
-   max_len = ilo_3d_pipeline_estimate_size(hw3d->pipeline,
-         ILO_3D_PIPELINE_DRAW, vec);
-   if (need_flush) {
-      max_len += ilo_3d_pipeline_estimate_size(hw3d->pipeline,
-            ILO_3D_PIPELINE_FLUSH, NULL);
-   }
-
-   if (max_len > ilo_cp_space(hw3d->cp)) {
-      ilo_cp_submit(hw3d->cp, "out of space");
-      need_flush = false;
-      assert(max_len <= ilo_cp_space(hw3d->cp));
-   }
-
-   /* space available before emission */
-   before_space = ilo_cp_space(hw3d->cp);
-
-   if (need_flush)
-      ilo_3d_pipeline_emit_flush(hw3d->pipeline);
-
-   while (true) {
-      struct ilo_builder_snapshot snapshot;
-
-      ilo_builder_batch_snapshot(&hw3d->cp->builder, &snapshot);
-
-      ilo_3d_pipeline_emit_draw(hw3d->pipeline, vec);
-
-      if (!ilo_builder_validate(&hw3d->cp->builder, 0, NULL)) {
-         ilo_builder_batch_restore(&hw3d->cp->builder, &snapshot);
-
-         /* flush and try again */
-         if (ilo_builder_batch_used(&hw3d->cp->builder)) {
-            ilo_cp_submit(hw3d->cp, "out of aperture");
-            continue;
-         }
-
-         success = false;
-      }
-
-      break;
-   }
-
-   hw3d->pipeline->invalidate_flags = 0x0;
-
-   /* sanity check size estimation */
-   assert(before_space - ilo_cp_space(hw3d->cp) <= max_len);
-
-   return success;
-}
-
-void
-ilo_3d_draw_rectlist(struct ilo_3d *hw3d, const struct ilo_blitter *blitter)
-{
-   int max_len, before_space;
-
-   ilo_3d_own_render_ring(hw3d);
-
-   max_len = ilo_3d_pipeline_estimate_size(hw3d->pipeline,
-         ILO_3D_PIPELINE_RECTLIST, blitter);
-   max_len += ilo_3d_pipeline_estimate_size(hw3d->pipeline,
-         ILO_3D_PIPELINE_FLUSH, NULL) * 2;
-
-   if (max_len > ilo_cp_space(hw3d->cp)) {
-      ilo_cp_submit(hw3d->cp, "out of space");
-      assert(max_len <= ilo_cp_space(hw3d->cp));
-   }
-
-   before_space = ilo_cp_space(hw3d->cp);
-
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 313:
-    *
-    *     "If other rendering operations have preceded this clear, a
-    *      PIPE_CONTROL with write cache flush enabled and Z-inhibit
-    *      disabled must be issued before the rectangle primitive used for
-    *      the depth buffer clear operation."
-    *
-    * From the Sandy Bridge PRM, volume 2 part 1, page 314:
-    *
-    *     "Depth buffer clear pass must be followed by a PIPE_CONTROL
-    *      command with DEPTH_STALL bit set and Then followed by Depth
-    *      FLUSH"
-    *
-    * But the pipeline has to be flushed both before and after not only
-    * because of these workarounds.  We need them for reasons such as
-    *
-    *  - we may sample from a texture that was rendered to
-    *  - we may sample from the fb shortly after
-    *
-    * Skip checking blitter->op and do the flushes.
-    */
-   if (!hw3d->new_batch)
-      ilo_3d_pipeline_emit_flush(hw3d->pipeline);
-
-   while (true) {
-      struct ilo_builder_snapshot snapshot;
-
-      ilo_builder_batch_snapshot(&hw3d->cp->builder, &snapshot);
-
-      ilo_3d_pipeline_emit_rectlist(hw3d->pipeline, blitter);
-
-      if (!ilo_builder_validate(&hw3d->cp->builder, 0, NULL)) {
-         ilo_builder_batch_restore(&hw3d->cp->builder, &snapshot);
-
-         /* flush and try again */
-         if (ilo_builder_batch_used(&hw3d->cp->builder)) {
-            ilo_cp_submit(hw3d->cp, "out of aperture");
-            continue;
-         }
-      }
-
-      break;
-   }
-
-   ilo_3d_pipeline_invalidate(hw3d->pipeline, ILO_3D_PIPELINE_INVALIDATE_HW);
-
-   ilo_3d_pipeline_emit_flush(hw3d->pipeline);
-
-   /* sanity check size estimation */
-   assert(before_space - ilo_cp_space(hw3d->cp) <= max_len);
-
-   hw3d->new_batch = false;
-}
-
-static void
-draw_vbo_with_sw_restart(struct ilo_context *ilo,
-                         const struct pipe_draw_info *info)
-{
-   const struct ilo_ib_state *ib = &ilo->state_vector.ib;
-   union {
-      const void *ptr;
-      const uint8_t *u8;
-      const uint16_t *u16;
-      const uint32_t *u32;
-   } u;
-
-   /* we will draw with IB mapped */
-   if (ib->buffer) {
-      u.ptr = intel_bo_map(ilo_buffer(ib->buffer)->bo, false);
-      if (u.ptr)
-         u.u8 += ib->offset;
-   } else {
-      u.ptr = ib->user_buffer;
-   }
-
-   if (!u.ptr)
-      return;
-
-#define DRAW_VBO_WITH_SW_RESTART(pipe, info, ptr) do {   \
-   const unsigned end = (info)->start + (info)->count;   \
-   struct pipe_draw_info subinfo;                        \
-   unsigned i;                                           \
-                                                         \
-   subinfo = *(info);                                    \
-   subinfo.primitive_restart = false;                    \
-   for (i = (info)->start; i < end; i++) {               \
-      if ((ptr)[i] == (info)->restart_index) {           \
-         subinfo.count = i - subinfo.start;              \
-         if (subinfo.count)                              \
-            (pipe)->draw_vbo(pipe, &subinfo);            \
-         subinfo.start = i + 1;                          \
-      }                                                  \
-   }                                                     \
-   subinfo.count = i - subinfo.start;                    \
-   if (subinfo.count)                                    \
-      (pipe)->draw_vbo(pipe, &subinfo);                  \
-} while (0)
-
-   switch (ib->index_size) {
-   case 1:
-      DRAW_VBO_WITH_SW_RESTART(&ilo->base, info, u.u8);
-      break;
-   case 2:
-      DRAW_VBO_WITH_SW_RESTART(&ilo->base, info, u.u16);
-      break;
-   case 4:
-      DRAW_VBO_WITH_SW_RESTART(&ilo->base, info, u.u32);
-      break;
-   default:
-      assert(!"unsupported index size");
-      break;
-   }
-
-#undef DRAW_VBO_WITH_SW_RESTART
-
-   if (ib->buffer)
-      intel_bo_unmap(ilo_buffer(ib->buffer)->bo);
-}
-
-static bool
-draw_vbo_need_sw_restart(const struct ilo_context *ilo,
-                         const struct pipe_draw_info *info)
-{
-   /* the restart index is fixed prior to GEN7.5 */
-   if (ilo_dev_gen(ilo->dev) < ILO_GEN(7.5)) {
-      const unsigned cut_index =
-         (ilo->state_vector.ib.index_size == 1) ? 0xff :
-         (ilo->state_vector.ib.index_size == 2) ? 0xffff :
-         (ilo->state_vector.ib.index_size == 4) ? 0xffffffff : 0;
-
-      if (info->restart_index < cut_index)
-         return true;
-   }
-
-   switch (info->mode) {
-   case PIPE_PRIM_POINTS:
-   case PIPE_PRIM_LINES:
-   case PIPE_PRIM_LINE_STRIP:
-   case PIPE_PRIM_TRIANGLES:
-   case PIPE_PRIM_TRIANGLE_STRIP:
-      /* these never need software fallback */
-      return false;
-   case PIPE_PRIM_LINE_LOOP:
-   case PIPE_PRIM_POLYGON:
-   case PIPE_PRIM_QUAD_STRIP:
-   case PIPE_PRIM_QUADS:
-   case PIPE_PRIM_TRIANGLE_FAN:
-      /* these need software fallback prior to GEN7.5 */
-      return (ilo_dev_gen(ilo->dev) < ILO_GEN(7.5));
-   default:
-      /* the rest always needs software fallback */
-      return true;
-   }
-}
-
-static void
-ilo_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
-{
-   struct ilo_context *ilo = ilo_context(pipe);
-   struct ilo_3d *hw3d = ilo->hw3d;
-
-   if (ilo_debug & ILO_DEBUG_DRAW) {
-      if (info->indexed) {
-         ilo_printf("indexed draw %s: "
-               "index start %d, count %d, vertex range [%d, %d]\n",
-               u_prim_name(info->mode), info->start, info->count,
-               info->min_index, info->max_index);
-      }
-      else {
-         ilo_printf("draw %s: vertex start %d, count %d\n",
-               u_prim_name(info->mode), info->start, info->count);
-      }
-
-      ilo_state_vector_dump_dirty(&ilo->state_vector);
-   }
-
-   if (ilo_skip_rendering(ilo))
-      return;
-
-   if (info->primitive_restart && info->indexed &&
-       draw_vbo_need_sw_restart(ilo, info)) {
-      draw_vbo_with_sw_restart(ilo, info);
-      return;
-   }
-
-   ilo_finalize_3d_states(ilo, info);
-
-   ilo_shader_cache_upload(ilo->shader_cache, &hw3d->cp->builder);
-
-   ilo_blit_resolve_framebuffer(ilo);
-
-   /* If draw_vbo ever fails, return immediately. */
-   if (!draw_vbo(hw3d, &ilo->state_vector))
-      return;
-
-   /* clear dirty status */
-   ilo->state_vector.dirty = 0x0;
-   hw3d->new_batch = false;
-
-   /* avoid dangling pointer reference */
-   ilo->state_vector.draw = NULL;
-
-   if (ilo_debug & ILO_DEBUG_NOCACHE)
-      ilo_3d_pipeline_emit_flush(hw3d->pipeline);
-}
-
-static void
-ilo_texture_barrier(struct pipe_context *pipe)
-{
-   struct ilo_context *ilo = ilo_context(pipe);
-   struct ilo_3d *hw3d = ilo->hw3d;
-
-   if (ilo->cp->ring != INTEL_RING_RENDER)
-      return;
-
-   ilo_3d_pipeline_emit_flush(hw3d->pipeline);
-
-   /* don't know why */
-   if (ilo_dev_gen(ilo->dev) >= ILO_GEN(7))
-      ilo_cp_submit(hw3d->cp, "texture barrier");
-}
-
-static void
-ilo_get_sample_position(struct pipe_context *pipe,
-                        unsigned sample_count,
-                        unsigned sample_index,
-                        float *out_value)
-{
-   struct ilo_context *ilo = ilo_context(pipe);
-   struct ilo_3d *hw3d = ilo->hw3d;
-
-   ilo_3d_pipeline_get_sample_position(hw3d->pipeline,
-         sample_count, sample_index,
-         &out_value[0], &out_value[1]);
-}
-
-/**
- * Initialize 3D-related functions.
- */
-void
-ilo_init_3d_functions(struct ilo_context *ilo)
-{
-   ilo->base.draw_vbo = ilo_draw_vbo;
-   ilo->base.texture_barrier = ilo_texture_barrier;
-   ilo->base.get_sample_position = ilo_get_sample_position;
-}
diff --git a/src/gallium/drivers/ilo/ilo_3d.h b/src/gallium/drivers/ilo/ilo_3d.h
deleted file mode 100644 (file)
index 5650238..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2012-2013 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Chia-I Wu <olv@lunarg.com>
- */
-
-#ifndef ILO_3D_H
-#define ILO_3D_H
-
-#include "ilo_common.h"
-#include "ilo_cp.h"
-
-struct ilo_3d_pipeline;
-struct ilo_blitter;
-struct ilo_context;
-struct ilo_query;
-
-/**
- * 3D context.
- */
-struct ilo_3d {
-   struct ilo_cp *cp;
-   struct ilo_cp_owner owner;
-
-   bool new_batch;
-
-   struct list_head queries;
-
-   struct ilo_3d_pipeline *pipeline;
-};
-
-struct ilo_3d *
-ilo_3d_create(struct ilo_cp *cp, const struct ilo_dev_info *dev);
-
-void
-ilo_3d_destroy(struct ilo_3d *hw3d);
-
-void
-ilo_3d_cp_submitted(struct ilo_3d *hw3d);
-
-void
-ilo_3d_draw_rectlist(struct ilo_3d *hw3d, const struct ilo_blitter *blitter);
-
-bool
-ilo_3d_init_query(struct pipe_context *pipe, struct ilo_query *q);
-
-void
-ilo_3d_begin_query(struct pipe_context *pipe, struct ilo_query *q);
-
-void
-ilo_3d_end_query(struct pipe_context *pipe, struct ilo_query *q);
-
-void
-ilo_3d_process_query(struct pipe_context *pipe, struct ilo_query *q);
-
-void
-ilo_init_3d_functions(struct ilo_context *ilo);
-
-#endif /* ILO_3D_H */
index 989b2f377cefb279612eae4fe84daa8cf24ebcf9..3b988682058ff7aa66ae07da44167c345ddf810c 100644 (file)
@@ -28,8 +28,8 @@
 #include "util/u_draw.h"
 #include "util/u_pack_color.h"
 
-#include "ilo_3d.h"
 #include "ilo_builder_3d_top.h" /* for ve_init_cso_with_components() */
+#include "ilo_draw.h"
 #include "ilo_state.h"
 #include "ilo_state_gen.h" /* for zs_align_surface() */
 #include "ilo_blit.h"
index a4a4dc2986b43b4637d9ac4cb9d4d93485a970fd..7b6b27e74d009945872c017125818442c1087b65 100644 (file)
 
 #include "util/u_upload_mgr.h"
 
-#include "ilo_3d.h"
 #include "ilo_blit.h"
 #include "ilo_blitter.h"
 #include "ilo_cp.h"
+#include "ilo_draw.h"
 #include "ilo_gpgpu.h"
 #include "ilo_query.h"
 #include "ilo_resource.h"
diff --git a/src/gallium/drivers/ilo/ilo_draw.c b/src/gallium/drivers/ilo/ilo_draw.c
new file mode 100644 (file)
index 0000000..a155a41
--- /dev/null
@@ -0,0 +1,701 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2012-2013 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "util/u_prim.h"
+#include "intel_winsys.h"
+
+#include "ilo_3d_pipeline.h"
+#include "ilo_blit.h"
+#include "ilo_context.h"
+#include "ilo_cp.h"
+#include "ilo_query.h"
+#include "ilo_shader.h"
+#include "ilo_state.h"
+#include "ilo_draw.h"
+
+static void
+ilo_3d_own_render_ring(struct ilo_3d *hw3d)
+{
+   ilo_cp_set_owner(hw3d->cp, INTEL_RING_RENDER, &hw3d->owner);
+}
+
+static uint64_t
+query_timestamp_to_ns(const struct ilo_3d *hw3d, uint64_t timestamp)
+{
+   /* see ilo_get_timestamp() */
+   return (timestamp & 0xffffffff) * 80;
+}
+
+/**
+ * Process the bo and accumulate the result.  The bo is emptied.
+ */
+static void
+query_process_bo(const struct ilo_3d *hw3d, struct ilo_query *q)
+{
+   const uint64_t *vals;
+   uint64_t tmp;
+   int i;
+
+   if (!q->used)
+      return;
+
+   vals = intel_bo_map(q->bo, false);
+   if (!vals) {
+      q->used = 0;
+      return;
+   }
+
+   switch (q->type) {
+   case PIPE_QUERY_OCCLUSION_COUNTER:
+   case PIPE_QUERY_TIME_ELAPSED:
+   case PIPE_QUERY_PRIMITIVES_GENERATED:
+   case PIPE_QUERY_PRIMITIVES_EMITTED:
+      assert(q->stride == sizeof(*vals) * 2);
+
+      tmp = 0;
+      for (i = 0; i < q->used; i++)
+         tmp += vals[2 * i + 1] - vals[2 * i];
+
+      if (q->type == PIPE_QUERY_TIME_ELAPSED)
+         tmp = query_timestamp_to_ns(hw3d, tmp);
+
+      q->result.u64 += tmp;
+      break;
+   case PIPE_QUERY_TIMESTAMP:
+      assert(q->stride == sizeof(*vals));
+
+      q->result.u64 = query_timestamp_to_ns(hw3d, vals[q->used - 1]);
+      break;
+   case PIPE_QUERY_PIPELINE_STATISTICS:
+      assert(q->stride == sizeof(*vals) * 22);
+
+      for (i = 0; i < q->used; i++) {
+         struct pipe_query_data_pipeline_statistics *stats =
+            &q->result.pipeline_statistics;
+         const uint64_t *begin = vals + 22 * i;
+         const uint64_t *end = begin + 11;
+
+         stats->ia_vertices    += end[0] - begin[0];
+         stats->ia_primitives  += end[1] - begin[1];
+         stats->vs_invocations += end[2] - begin[2];
+         stats->gs_invocations += end[3] - begin[3];
+         stats->gs_primitives  += end[4] - begin[4];
+         stats->c_invocations  += end[5] - begin[5];
+         stats->c_primitives   += end[6] - begin[6];
+         stats->ps_invocations += end[7] - begin[7];
+         stats->hs_invocations += end[8] - begin[8];
+         stats->ds_invocations += end[9] - begin[9];
+         stats->cs_invocations += end[10] - begin[10];
+      }
+      break;
+   default:
+      break;
+   }
+
+   intel_bo_unmap(q->bo);
+
+   q->used = 0;
+}
+
+static void
+query_begin_bo(struct ilo_3d *hw3d, struct ilo_query *q)
+{
+   /* bo is full */
+   if (q->used >= q->count)
+      query_process_bo(hw3d, q);
+
+   /* write the beginning value to the bo */
+   if (q->in_pairs)
+      ilo_3d_pipeline_emit_query(hw3d->pipeline, q, q->stride * q->used);
+}
+
+static void
+query_end_bo(struct ilo_3d *hw3d, struct ilo_query *q)
+{
+   uint32_t offset;
+
+   assert(q->used < q->count);
+
+   offset = q->stride * q->used;
+   if (q->in_pairs)
+      offset += q->stride >> 1;
+
+   q->used++;
+
+   /* write the ending value to the bo */
+   ilo_3d_pipeline_emit_query(hw3d->pipeline, q, offset);
+}
+
+bool
+ilo_3d_init_query(struct pipe_context *pipe, struct ilo_query *q)
+{
+   struct ilo_context *ilo = ilo_context(pipe);
+   unsigned bo_size;
+
+   switch (q->type) {
+   case PIPE_QUERY_OCCLUSION_COUNTER:
+   case PIPE_QUERY_TIME_ELAPSED:
+   case PIPE_QUERY_PRIMITIVES_GENERATED:
+   case PIPE_QUERY_PRIMITIVES_EMITTED:
+      q->stride = sizeof(uint64_t);
+      q->in_pairs = true;
+      break;
+   case PIPE_QUERY_TIMESTAMP:
+      q->stride = sizeof(uint64_t);
+      q->in_pairs = false;
+      break;
+   case PIPE_QUERY_PIPELINE_STATISTICS:
+      q->stride = sizeof(uint64_t) * 11;
+      q->in_pairs = true;
+      break;
+   default:
+      return false;
+      break;
+   }
+
+   q->cmd_len = ilo_3d_pipeline_estimate_size(ilo->hw3d->pipeline,
+         ILO_3D_PIPELINE_QUERY, q);
+
+   /* double cmd_len and stride if in pairs */
+   q->cmd_len <<= q->in_pairs;
+   q->stride <<= q->in_pairs;
+
+   bo_size = (q->stride > 4096) ? q->stride : 4096;
+   q->bo = intel_winsys_alloc_buffer(ilo->winsys, "query", bo_size, false);
+   if (!q->bo)
+      return false;
+
+   q->count = bo_size / q->stride;
+
+   return true;
+}
+
+void
+ilo_3d_begin_query(struct pipe_context *pipe, struct ilo_query *q)
+{
+   struct ilo_3d *hw3d = ilo_context(pipe)->hw3d;
+
+   ilo_3d_own_render_ring(hw3d);
+
+   /* need to submit first */
+   if (!ilo_builder_validate(&hw3d->cp->builder, 1, &q->bo) ||
+         ilo_cp_space(hw3d->cp) < q->cmd_len) {
+      ilo_cp_submit(hw3d->cp, "out of aperture or space");
+
+      assert(ilo_builder_validate(&hw3d->cp->builder, 1, &q->bo));
+      assert(ilo_cp_space(hw3d->cp) >= q->cmd_len);
+
+      ilo_3d_own_render_ring(hw3d);
+   }
+
+   /* reserve the space for ending/pausing the query */
+   hw3d->owner.reserve += q->cmd_len >> q->in_pairs;
+
+   query_begin_bo(hw3d, q);
+
+   if (q->in_pairs)
+      list_add(&q->list, &hw3d->queries);
+}
+
+void
+ilo_3d_end_query(struct pipe_context *pipe, struct ilo_query *q)
+{
+   struct ilo_3d *hw3d = ilo_context(pipe)->hw3d;
+
+   ilo_3d_own_render_ring(hw3d);
+
+   /* reclaim the reserved space */
+   hw3d->owner.reserve -= q->cmd_len >> q->in_pairs;
+   assert(hw3d->owner.reserve >= 0);
+
+   query_end_bo(hw3d, q);
+
+   list_delinit(&q->list);
+}
+
+/**
+ * Process the raw query data.
+ */
+void
+ilo_3d_process_query(struct pipe_context *pipe, struct ilo_query *q)
+{
+   struct ilo_3d *hw3d = ilo_context(pipe)->hw3d;
+
+   query_process_bo(hw3d, q);
+}
+
+static void
+ilo_3d_own_cp(struct ilo_cp *cp, void *data)
+{
+   struct ilo_3d *hw3d = data;
+
+   /* multiply by 2 for both resuming and pausing */
+   if (ilo_cp_space(hw3d->cp) < hw3d->owner.reserve * 2) {
+      ilo_cp_submit(hw3d->cp, "out of space");
+      assert(ilo_cp_space(hw3d->cp) >= hw3d->owner.reserve * 2);
+   }
+
+   while (true) {
+      struct ilo_builder_snapshot snapshot;
+      struct ilo_query *q;
+
+      ilo_builder_batch_snapshot(&hw3d->cp->builder, &snapshot);
+
+      /* resume queries */
+      LIST_FOR_EACH_ENTRY(q, &hw3d->queries, list)
+         query_begin_bo(hw3d, q);
+
+      if (!ilo_builder_validate(&hw3d->cp->builder, 0, NULL)) {
+         ilo_builder_batch_restore(&hw3d->cp->builder, &snapshot);
+
+         if (ilo_builder_batch_used(&hw3d->cp->builder)) {
+            ilo_cp_submit(hw3d->cp, "out of aperture");
+            continue;
+         }
+      }
+
+      break;
+   }
+
+   assert(ilo_cp_space(hw3d->cp) >= hw3d->owner.reserve);
+}
+
+static void
+ilo_3d_release_cp(struct ilo_cp *cp, void *data)
+{
+   struct ilo_3d *hw3d = data;
+   struct ilo_query *q;
+
+   assert(ilo_cp_space(hw3d->cp) >= hw3d->owner.reserve);
+
+   /* pause queries */
+   LIST_FOR_EACH_ENTRY(q, &hw3d->queries, list)
+      query_end_bo(hw3d, q);
+}
+
+/**
+ * Hook for CP new-batch.
+ */
+void
+ilo_3d_cp_submitted(struct ilo_3d *hw3d)
+{
+   /* invalidate the pipeline */
+   ilo_3d_pipeline_invalidate(hw3d->pipeline,
+         ILO_3D_PIPELINE_INVALIDATE_BATCH_BO |
+         ILO_3D_PIPELINE_INVALIDATE_STATE_BO |
+         ILO_3D_PIPELINE_INVALIDATE_KERNEL_BO);
+
+   hw3d->new_batch = true;
+}
+
+/**
+ * Create a 3D context.
+ */
+struct ilo_3d *
+ilo_3d_create(struct ilo_cp *cp, const struct ilo_dev_info *dev)
+{
+   struct ilo_3d *hw3d;
+
+   hw3d = CALLOC_STRUCT(ilo_3d);
+   if (!hw3d)
+      return NULL;
+
+   hw3d->cp = cp;
+   hw3d->owner.own = ilo_3d_own_cp;
+   hw3d->owner.release = ilo_3d_release_cp;
+   hw3d->owner.data = hw3d;
+   hw3d->owner.reserve = 0;
+
+   hw3d->new_batch = true;
+
+   list_inithead(&hw3d->queries);
+
+   hw3d->pipeline = ilo_3d_pipeline_create(&cp->builder);
+   if (!hw3d->pipeline) {
+      FREE(hw3d);
+      return NULL;
+   }
+
+   return hw3d;
+}
+
+/**
+ * Destroy a 3D context.
+ */
+void
+ilo_3d_destroy(struct ilo_3d *hw3d)
+{
+   ilo_3d_pipeline_destroy(hw3d->pipeline);
+   FREE(hw3d);
+}
+
+static bool
+draw_vbo(struct ilo_3d *hw3d, const struct ilo_state_vector *vec)
+{
+   bool need_flush = false;
+   bool success = true;
+   int max_len, before_space;
+
+   /* on GEN7+, we need SOL_RESET to reset the SO write offsets */
+   if (ilo_dev_gen(hw3d->pipeline->dev) >= ILO_GEN(7) &&
+       (vec->dirty & ILO_DIRTY_SO) && vec->so.enabled &&
+       !vec->so.append_bitmask) {
+      ilo_cp_submit(hw3d->cp, "SOL_RESET");
+      ilo_cp_set_one_off_flags(hw3d->cp, INTEL_EXEC_GEN7_SOL_RESET);
+   }
+
+   ilo_3d_own_render_ring(hw3d);
+
+   if (!hw3d->new_batch) {
+      /*
+       * Without a better tracking mechanism, when the framebuffer changes, we
+       * have to assume that the old framebuffer may be sampled from.  If that
+       * happens in the middle of a batch buffer, we need to insert manual
+       * flushes.
+       */
+      need_flush = (vec->dirty & ILO_DIRTY_FB);
+
+      /* same to SO target changes */
+      need_flush |= (vec->dirty & ILO_DIRTY_SO);
+   }
+
+   /* make sure there is enough room first */
+   max_len = ilo_3d_pipeline_estimate_size(hw3d->pipeline,
+         ILO_3D_PIPELINE_DRAW, vec);
+   if (need_flush) {
+      max_len += ilo_3d_pipeline_estimate_size(hw3d->pipeline,
+            ILO_3D_PIPELINE_FLUSH, NULL);
+   }
+
+   if (max_len > ilo_cp_space(hw3d->cp)) {
+      ilo_cp_submit(hw3d->cp, "out of space");
+      need_flush = false;
+      assert(max_len <= ilo_cp_space(hw3d->cp));
+   }
+
+   /* space available before emission */
+   before_space = ilo_cp_space(hw3d->cp);
+
+   if (need_flush)
+      ilo_3d_pipeline_emit_flush(hw3d->pipeline);
+
+   while (true) {
+      struct ilo_builder_snapshot snapshot;
+
+      ilo_builder_batch_snapshot(&hw3d->cp->builder, &snapshot);
+
+      ilo_3d_pipeline_emit_draw(hw3d->pipeline, vec);
+
+      if (!ilo_builder_validate(&hw3d->cp->builder, 0, NULL)) {
+         ilo_builder_batch_restore(&hw3d->cp->builder, &snapshot);
+
+         /* flush and try again */
+         if (ilo_builder_batch_used(&hw3d->cp->builder)) {
+            ilo_cp_submit(hw3d->cp, "out of aperture");
+            continue;
+         }
+
+         success = false;
+      }
+
+      break;
+   }
+
+   hw3d->pipeline->invalidate_flags = 0x0;
+
+   /* sanity check size estimation */
+   assert(before_space - ilo_cp_space(hw3d->cp) <= max_len);
+
+   return success;
+}
+
+void
+ilo_3d_draw_rectlist(struct ilo_3d *hw3d, const struct ilo_blitter *blitter)
+{
+   int max_len, before_space;
+
+   ilo_3d_own_render_ring(hw3d);
+
+   max_len = ilo_3d_pipeline_estimate_size(hw3d->pipeline,
+         ILO_3D_PIPELINE_RECTLIST, blitter);
+   max_len += ilo_3d_pipeline_estimate_size(hw3d->pipeline,
+         ILO_3D_PIPELINE_FLUSH, NULL) * 2;
+
+   if (max_len > ilo_cp_space(hw3d->cp)) {
+      ilo_cp_submit(hw3d->cp, "out of space");
+      assert(max_len <= ilo_cp_space(hw3d->cp));
+   }
+
+   before_space = ilo_cp_space(hw3d->cp);
+
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 313:
+    *
+    *     "If other rendering operations have preceded this clear, a
+    *      PIPE_CONTROL with write cache flush enabled and Z-inhibit
+    *      disabled must be issued before the rectangle primitive used for
+    *      the depth buffer clear operation."
+    *
+    * From the Sandy Bridge PRM, volume 2 part 1, page 314:
+    *
+    *     "Depth buffer clear pass must be followed by a PIPE_CONTROL
+    *      command with DEPTH_STALL bit set and Then followed by Depth
+    *      FLUSH"
+    *
+    * But the pipeline has to be flushed both before and after not only
+    * because of these workarounds.  We need them for reasons such as
+    *
+    *  - we may sample from a texture that was rendered to
+    *  - we may sample from the fb shortly after
+    *
+    * Skip checking blitter->op and do the flushes.
+    */
+   if (!hw3d->new_batch)
+      ilo_3d_pipeline_emit_flush(hw3d->pipeline);
+
+   while (true) {
+      struct ilo_builder_snapshot snapshot;
+
+      ilo_builder_batch_snapshot(&hw3d->cp->builder, &snapshot);
+
+      ilo_3d_pipeline_emit_rectlist(hw3d->pipeline, blitter);
+
+      if (!ilo_builder_validate(&hw3d->cp->builder, 0, NULL)) {
+         ilo_builder_batch_restore(&hw3d->cp->builder, &snapshot);
+
+         /* flush and try again */
+         if (ilo_builder_batch_used(&hw3d->cp->builder)) {
+            ilo_cp_submit(hw3d->cp, "out of aperture");
+            continue;
+         }
+      }
+
+      break;
+   }
+
+   ilo_3d_pipeline_invalidate(hw3d->pipeline, ILO_3D_PIPELINE_INVALIDATE_HW);
+
+   ilo_3d_pipeline_emit_flush(hw3d->pipeline);
+
+   /* sanity check size estimation */
+   assert(before_space - ilo_cp_space(hw3d->cp) <= max_len);
+
+   hw3d->new_batch = false;
+}
+
+static void
+draw_vbo_with_sw_restart(struct ilo_context *ilo,
+                         const struct pipe_draw_info *info)
+{
+   const struct ilo_ib_state *ib = &ilo->state_vector.ib;
+   union {
+      const void *ptr;
+      const uint8_t *u8;
+      const uint16_t *u16;
+      const uint32_t *u32;
+   } u;
+
+   /* we will draw with IB mapped */
+   if (ib->buffer) {
+      u.ptr = intel_bo_map(ilo_buffer(ib->buffer)->bo, false);
+      if (u.ptr)
+         u.u8 += ib->offset;
+   } else {
+      u.ptr = ib->user_buffer;
+   }
+
+   if (!u.ptr)
+      return;
+
+#define DRAW_VBO_WITH_SW_RESTART(pipe, info, ptr) do {   \
+   const unsigned end = (info)->start + (info)->count;   \
+   struct pipe_draw_info subinfo;                        \
+   unsigned i;                                           \
+                                                         \
+   subinfo = *(info);                                    \
+   subinfo.primitive_restart = false;                    \
+   for (i = (info)->start; i < end; i++) {               \
+      if ((ptr)[i] == (info)->restart_index) {           \
+         subinfo.count = i - subinfo.start;              \
+         if (subinfo.count)                              \
+            (pipe)->draw_vbo(pipe, &subinfo);            \
+         subinfo.start = i + 1;                          \
+      }                                                  \
+   }                                                     \
+   subinfo.count = i - subinfo.start;                    \
+   if (subinfo.count)                                    \
+      (pipe)->draw_vbo(pipe, &subinfo);                  \
+} while (0)
+
+   switch (ib->index_size) {
+   case 1:
+      DRAW_VBO_WITH_SW_RESTART(&ilo->base, info, u.u8);
+      break;
+   case 2:
+      DRAW_VBO_WITH_SW_RESTART(&ilo->base, info, u.u16);
+      break;
+   case 4:
+      DRAW_VBO_WITH_SW_RESTART(&ilo->base, info, u.u32);
+      break;
+   default:
+      assert(!"unsupported index size");
+      break;
+   }
+
+#undef DRAW_VBO_WITH_SW_RESTART
+
+   if (ib->buffer)
+      intel_bo_unmap(ilo_buffer(ib->buffer)->bo);
+}
+
+static bool
+draw_vbo_need_sw_restart(const struct ilo_context *ilo,
+                         const struct pipe_draw_info *info)
+{
+   /* the restart index is fixed prior to GEN7.5 */
+   if (ilo_dev_gen(ilo->dev) < ILO_GEN(7.5)) {
+      const unsigned cut_index =
+         (ilo->state_vector.ib.index_size == 1) ? 0xff :
+         (ilo->state_vector.ib.index_size == 2) ? 0xffff :
+         (ilo->state_vector.ib.index_size == 4) ? 0xffffffff : 0;
+
+      if (info->restart_index < cut_index)
+         return true;
+   }
+
+   switch (info->mode) {
+   case PIPE_PRIM_POINTS:
+   case PIPE_PRIM_LINES:
+   case PIPE_PRIM_LINE_STRIP:
+   case PIPE_PRIM_TRIANGLES:
+   case PIPE_PRIM_TRIANGLE_STRIP:
+      /* these never need software fallback */
+      return false;
+   case PIPE_PRIM_LINE_LOOP:
+   case PIPE_PRIM_POLYGON:
+   case PIPE_PRIM_QUAD_STRIP:
+   case PIPE_PRIM_QUADS:
+   case PIPE_PRIM_TRIANGLE_FAN:
+      /* these need software fallback prior to GEN7.5 */
+      return (ilo_dev_gen(ilo->dev) < ILO_GEN(7.5));
+   default:
+      /* the rest always needs software fallback */
+      return true;
+   }
+}
+
+static void
+ilo_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
+{
+   struct ilo_context *ilo = ilo_context(pipe);
+   struct ilo_3d *hw3d = ilo->hw3d;
+
+   if (ilo_debug & ILO_DEBUG_DRAW) {
+      if (info->indexed) {
+         ilo_printf("indexed draw %s: "
+               "index start %d, count %d, vertex range [%d, %d]\n",
+               u_prim_name(info->mode), info->start, info->count,
+               info->min_index, info->max_index);
+      }
+      else {
+         ilo_printf("draw %s: vertex start %d, count %d\n",
+               u_prim_name(info->mode), info->start, info->count);
+      }
+
+      ilo_state_vector_dump_dirty(&ilo->state_vector);
+   }
+
+   if (ilo_skip_rendering(ilo))
+      return;
+
+   if (info->primitive_restart && info->indexed &&
+       draw_vbo_need_sw_restart(ilo, info)) {
+      draw_vbo_with_sw_restart(ilo, info);
+      return;
+   }
+
+   ilo_finalize_3d_states(ilo, info);
+
+   ilo_shader_cache_upload(ilo->shader_cache, &hw3d->cp->builder);
+
+   ilo_blit_resolve_framebuffer(ilo);
+
+   /* If draw_vbo ever fails, return immediately. */
+   if (!draw_vbo(hw3d, &ilo->state_vector))
+      return;
+
+   /* clear dirty status */
+   ilo->state_vector.dirty = 0x0;
+   hw3d->new_batch = false;
+
+   /* avoid dangling pointer reference */
+   ilo->state_vector.draw = NULL;
+
+   if (ilo_debug & ILO_DEBUG_NOCACHE)
+      ilo_3d_pipeline_emit_flush(hw3d->pipeline);
+}
+
+static void
+ilo_texture_barrier(struct pipe_context *pipe)
+{
+   struct ilo_context *ilo = ilo_context(pipe);
+   struct ilo_3d *hw3d = ilo->hw3d;
+
+   if (ilo->cp->ring != INTEL_RING_RENDER)
+      return;
+
+   ilo_3d_pipeline_emit_flush(hw3d->pipeline);
+
+   /* don't know why */
+   if (ilo_dev_gen(ilo->dev) >= ILO_GEN(7))
+      ilo_cp_submit(hw3d->cp, "texture barrier");
+}
+
+static void
+ilo_get_sample_position(struct pipe_context *pipe,
+                        unsigned sample_count,
+                        unsigned sample_index,
+                        float *out_value)
+{
+   struct ilo_context *ilo = ilo_context(pipe);
+   struct ilo_3d *hw3d = ilo->hw3d;
+
+   ilo_3d_pipeline_get_sample_position(hw3d->pipeline,
+         sample_count, sample_index,
+         &out_value[0], &out_value[1]);
+}
+
+/**
+ * Initialize 3D-related functions.
+ */
+void
+ilo_init_3d_functions(struct ilo_context *ilo)
+{
+   ilo->base.draw_vbo = ilo_draw_vbo;
+   ilo->base.texture_barrier = ilo_texture_barrier;
+   ilo->base.get_sample_position = ilo_get_sample_position;
+}
diff --git a/src/gallium/drivers/ilo/ilo_draw.h b/src/gallium/drivers/ilo/ilo_draw.h
new file mode 100644 (file)
index 0000000..2f68c5e
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2012-2013 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ILO_DRAW_H
+#define ILO_DRAW_H
+
+#include "ilo_common.h"
+#include "ilo_cp.h"
+
+struct ilo_3d_pipeline;
+struct ilo_blitter;
+struct ilo_context;
+struct ilo_query;
+
+/**
+ * 3D context.
+ */
+struct ilo_3d {
+   struct ilo_cp *cp;
+   struct ilo_cp_owner owner;
+
+   bool new_batch;
+
+   struct list_head queries;
+
+   struct ilo_3d_pipeline *pipeline;
+};
+
+struct ilo_3d *
+ilo_3d_create(struct ilo_cp *cp, const struct ilo_dev_info *dev);
+
+void
+ilo_3d_destroy(struct ilo_3d *hw3d);
+
+void
+ilo_3d_cp_submitted(struct ilo_3d *hw3d);
+
+void
+ilo_3d_draw_rectlist(struct ilo_3d *hw3d, const struct ilo_blitter *blitter);
+
+bool
+ilo_3d_init_query(struct pipe_context *pipe, struct ilo_query *q);
+
+void
+ilo_3d_begin_query(struct pipe_context *pipe, struct ilo_query *q);
+
+void
+ilo_3d_end_query(struct pipe_context *pipe, struct ilo_query *q);
+
+void
+ilo_3d_process_query(struct pipe_context *pipe, struct ilo_query *q);
+
+void
+ilo_init_3d_functions(struct ilo_context *ilo);
+
+#endif /* ILO_DRAW_H */
index e0cd4ee755438444bae84aadfcbcbb36022284d6..8ab333e43c622043caff7bee1b95dfd8d125c207 100644 (file)
@@ -27,9 +27,9 @@
 
 #include "intel_winsys.h"
 
-#include "ilo_3d.h"
 #include "ilo_context.h"
 #include "ilo_cp.h"
+#include "ilo_draw.h"
 #include "ilo_query.h"
 
 static const struct {