i965: Add hardware context support.
[mesa.git] / src / mesa / drivers / dri / intel / intel_context.h
index eb7be7ddd0fb904cd0698e48232f089a267e889f..29ab187c3e749bf1ae9808f606eaccf985800046 100644 (file)
 #define INTELCONTEXT_INC
 
 
-
+#include <stdbool.h>
+#include <string.h>
 #include "main/mtypes.h"
 #include "main/mm.h"
-#include "texmem.h"
-#include "dri_metaops.h"
+
+#ifdef __cplusplus
+extern "C" {
+       /* Evil hack for using libdrm in a c++ compiler. */
+       #define virtual virt
+#endif
+
 #include "drm.h"
 #include "intel_bufmgr.h"
 
 #include "intel_screen.h"
 #include "intel_tex_obj.h"
 #include "i915_drm.h"
+
+#ifdef __cplusplus
+       #undef virtual
+#endif
+
 #include "tnl/t_vertex.h"
 
 #define TAG(x) intel##x
@@ -76,7 +87,7 @@ typedef void (*intel_point_func) (struct intel_context *, intelVertex *);
 /*@}*/
 
 extern void intelFallback(struct intel_context *intel, GLbitfield bit,
-                          GLboolean mode);
+                          bool mode);
 #define FALLBACK( intel, bit, mode ) intelFallback( intel, bit, mode )
 
 
@@ -86,6 +97,16 @@ extern void intelFallback(struct intel_context *intel, GLbitfield bit,
 
 #define INTEL_MAX_FIXUP 64
 
+#ifndef likely
+#ifdef __GNUC__
+#define likely(expr) (__builtin_expect(expr, 1))
+#define unlikely(expr) (__builtin_expect(expr, 0))
+#else
+#define likely(expr) (expr)
+#define unlikely(expr) (expr)
+#endif
+#endif
+
 struct intel_sync_object {
    struct gl_sync_object Base;
 
@@ -93,12 +114,40 @@ struct intel_sync_object {
    drm_intel_bo *bo;
 };
 
+struct brw_context;
+
+struct intel_batchbuffer {
+   /** Current batchbuffer being queued up. */
+   drm_intel_bo *bo;
+   /** Last BO submitted to the hardware.  Used for glFinish(). */
+   drm_intel_bo *last_bo;
+   /** BO for post-sync nonzero writes for gen6 workaround. */
+   drm_intel_bo *workaround_bo;
+   bool need_workaround_flush;
+
+   struct cached_batch_item *cached_items;
+
+   uint16_t emit, total;
+   uint16_t used, reserved_space;
+   uint32_t map[8192];
+#define BATCH_SZ (8192*sizeof(uint32_t))
+
+   uint32_t state_batch_offset;
+   bool is_blit;
+   bool needs_sol_reset;
+
+   struct {
+      uint16_t used;
+      int reloc_count;
+   } saved;
+};
+
 /**
- * intel_context is derived from Mesa's context class: GLcontext.
+ * intel_context is derived from Mesa's context class: struct gl_context.
  */
 struct intel_context
 {
-   GLcontext ctx;  /**< base class, must be first field */
+   struct gl_context ctx;  /**< base class, must be first field */
 
    struct
    {
@@ -107,7 +156,6 @@ struct intel_context
       void (*finish_batch) (struct intel_context * intel);
       void (*new_batch) (struct intel_context * intel);
       void (*emit_invarient_state) (struct intel_context * intel);
-      void (*note_fence) (struct intel_context *intel, GLuint fence);
       void (*update_texture_state) (struct intel_context * intel);
 
       void (*render_start) (struct intel_context * intel);
@@ -116,63 +164,43 @@ struct intel_context
                                struct intel_region * draw_regions[],
                                struct intel_region * depth_region,
                               GLuint num_regions);
+      void (*update_draw_buffer)(struct intel_context *intel);
 
       void (*reduced_primitive_state) (struct intel_context * intel,
                                        GLenum rprim);
 
-      GLboolean (*check_vertex_size) (struct intel_context * intel,
+      bool (*check_vertex_size) (struct intel_context * intel,
                                      GLuint expected);
       void (*invalidate_state) (struct intel_context *intel,
                                GLuint new_state);
 
-
-      /* Metaops: 
-       */
-      void (*install_meta_state) (struct intel_context * intel);
-      void (*leave_meta_state) (struct intel_context * intel);
-
-      void (*meta_draw_region) (struct intel_context * intel,
-                                struct intel_region * draw_region,
-                                struct intel_region * depth_region);
-
-      void (*meta_draw_quad)(struct intel_context *intel,
-                            GLfloat x0, GLfloat x1,
-                            GLfloat y0, GLfloat y1,
-                            GLfloat z,
-                            GLuint color, /* ARGB32 */
-                            GLfloat s0, GLfloat s1,
-                            GLfloat t0, GLfloat t1);
-
-      void (*meta_color_mask) (struct intel_context * intel, GLboolean);
-
-      void (*meta_stencil_replace) (struct intel_context * intel,
-                                    GLuint mask, GLuint clear);
-
-      void (*meta_depth_replace) (struct intel_context * intel);
-
-      void (*meta_texture_blend_replace) (struct intel_context * intel);
-
-      void (*meta_no_stencil_write) (struct intel_context * intel);
-      void (*meta_no_depth_write) (struct intel_context * intel);
-      void (*meta_no_texture) (struct intel_context * intel);
-
-      void (*meta_import_pixel_state) (struct intel_context * intel);
-      void (*meta_frame_buffer_texture) (struct intel_context *intel,
-                                        GLint xoff, GLint yoff);
-
-      GLboolean(*meta_tex_rect_source) (struct intel_context * intel,
-                                       dri_bo * buffer,
-                                       GLuint offset,
-                                       GLuint pitch,
-                                       GLuint height,
-                                       GLenum format, GLenum type);
-
       void (*assert_not_dirty) (struct intel_context *intel);
 
       void (*debug_batch)(struct intel_context *intel);
-   } vtbl;
+      void (*annotate_aub)(struct intel_context *intel);
+      bool (*render_target_supported)(struct intel_context *intel,
+                                     struct gl_renderbuffer *rb);
 
-   struct dri_metaops meta;
+      /** Can HiZ be enabled on a depthbuffer of the given format? */
+      bool (*is_hiz_depth_format)(struct intel_context *intel,
+                                 gl_format format);
+
+      /**
+       * Surface state operations (i965+ only)
+       * \{
+       */
+      void (*update_texture_surface)(struct gl_context *ctx, unsigned unit);
+      void (*update_renderbuffer_surface)(struct brw_context *brw,
+                                         struct gl_renderbuffer *rb,
+                                         unsigned unit);
+      void (*update_null_renderbuffer_surface)(struct brw_context *brw,
+                                              unsigned unit);
+      void (*create_constant_surface)(struct brw_context *brw,
+                                     drm_intel_bo *bo,
+                                     int width,
+                                     uint32_t *out_offset);
+      /** \} */
+   } vtbl;
 
    GLbitfield Fallback;  /**< mask of INTEL_FALLBACK_x bits */
    GLuint NewGLState;
@@ -184,74 +212,74 @@ struct intel_context
     * Generation number of the hardware: 2 is 8xx, 3 is 9xx pre-965, 4 is 965.
     */
    int gen;
+   int gt;
+   bool needs_ff_sync;
+   bool is_haswell;
+   bool is_g4x;
+   bool is_945;
+   bool has_separate_stencil;
+   bool must_use_separate_stencil;
+   bool has_hiz;
+   bool has_llc;
+   bool has_swizzling;
 
-   struct intel_region *front_region;
-   struct intel_region *back_region;
-   struct intel_region *depth_region;
+   int urb_size;
 
-   /**
-    * This value indicates that the kernel memory manager is being used
-    * instead of the fake client-side memory manager.
-    */
-   GLboolean ttm;
+   drm_intel_context *hw_ctx;
+
+   struct intel_batchbuffer batch;
 
-   struct intel_batchbuffer *batch;
    drm_intel_bo *first_post_swapbuffers_batch;
-   GLboolean no_batch_wrap;
+   bool need_throttle;
+   bool no_batch_wrap;
+   bool tnl_pipeline_running; /**< Set while i915's _tnl_run_pipeline. */
 
    struct
    {
       GLuint id;
+      uint32_t start_ptr; /**< for i8xx */
       uint32_t primitive;      /**< Current hardware primitive type */
       void (*flush) (struct intel_context *);
-      GLubyte *start_ptr; /**< for i8xx */
-      dri_bo *vb_bo;
+      drm_intel_bo *vb_bo;
       uint8_t *vb;
       unsigned int start_offset; /**< Byte offset of primitive sequence */
       unsigned int current_offset; /**< Byte offset of next vertex */
       unsigned int count;      /**< Number of vertices in current primitive */
    } prim;
 
-   GLuint stats_wm;
-   GLboolean locked;
-   char *prevLockFile;
-   int prevLockLine;
-
-   GLuint ClearColor565;
-   GLuint ClearColor8888;
+   struct {
+      drm_intel_bo *bo;
+      GLuint offset;
+      uint32_t buffer_len;
+      uint32_t buffer_offset;
+      char buffer[4096];
+   } upload;
 
+   GLuint stats_wm;
 
    /* Offsets of fields within the current vertex:
     */
    GLuint coloroffset;
    GLuint specoffset;
    GLuint wpos_offset;
-   GLuint wpos_size;
 
    struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX];
    GLuint vertex_attr_count;
 
    GLfloat polygon_offset_scale;        /* dependent on depth_scale, bpp */
 
-   GLboolean hw_stencil;
-   GLboolean hw_stipple;
-   GLboolean depth_buffer_is_float;
-   GLboolean no_rast;
-   GLboolean always_flush_batch;
-   GLboolean always_flush_cache;
-
-   /* 0 - nonconformant, best performance;
-    * 1 - fallback to sw for known conformance bugs
-    * 2 - always fallback to sw
-    */
-   GLuint conformance_mode;
+   bool hw_stencil;
+   bool hw_stipple;
+   bool no_rast;
+   bool always_flush_batch;
+   bool always_flush_cache;
 
    /* State for intelvb.c and inteltris.c.
     */
    GLuint RenderIndex;
    GLmatrix ViewportMatrix;
    GLenum render_primitive;
-   GLenum reduced_primitive;
+   GLenum reduced_primitive; /*< Only gen < 6 */
    GLuint vertex_size;
    GLubyte *verts;              /* points to tnl->clipspace.vertex_buf */
 
@@ -261,26 +289,13 @@ struct intel_context
    intel_line_func draw_line;
    intel_tri_func draw_tri;
 
-   /**
-    * Set to true if a single constant cliprect should be used in the
-    * batchbuffer.  Otherwise, cliprects must be calculated at batchbuffer
-    * flush time while the lock is held.
-    */
-   GLboolean constant_cliprect;
-
-   /**
-    * In !constant_cliprect mode, set to true if the front cliprects should be
-    * used instead of back.
-    */
-   GLboolean front_cliprects;
-
    /**
     * Set if rendering has occured to the drawable's front buffer.
     *
     * This is used in the DRI2 case to detect that glFlush should also copy
     * the contents of the fake front buffer to the real front buffer.
     */
-   GLboolean front_buffer_dirty;
+   bool front_buffer_dirty;
 
    /**
     * Track whether front-buffer rendering is currently enabled
@@ -288,7 +303,7 @@ struct intel_context
     * A separate flag is used to track this in order to support MRT more
     * easily.
     */
-   GLboolean is_front_buffer_rendering;
+   bool is_front_buffer_rendering;
    /**
     * Track whether front-buffer is the current read target.
     *
@@ -296,54 +311,32 @@ struct intel_context
     * be set separately.  The DRI2 fake front buffer must be referenced
     * either way.
     */
-   GLboolean is_front_buffer_reading;
+   bool is_front_buffer_reading;
 
-   GLboolean use_texture_tiling;
-   GLboolean use_early_z;
-   drm_clip_rect_t fboRect;     /**< cliprect for FBO rendering */
-
-   int perf_boxes;
-
-   GLuint do_usleeps;
-   int do_irqs;
-   GLuint irqsEmitted;
+   /**
+    * Count of intel_regions that are mapped.
+    *
+    * This allows us to assert that no batch buffer is emitted if a
+    * region is mapped.
+    */
+   int num_mapped_regions;
 
-   GLboolean scissor;
-   drm_clip_rect_t draw_rect;
-   drm_clip_rect_t scissor_rect;
+   bool use_texture_tiling;
+   bool use_early_z;
 
-   drm_context_t hHWContext;
-   drmLock *driHwLock;
    int driFd;
 
-   __DRIcontextPrivate *driContext;
-   __DRIdrawablePrivate *driDrawable;
-   __DRIdrawablePrivate *driReadDrawable;
-   __DRIscreenPrivate *driScreen;
-   intelScreenPrivate *intelScreen;
-   volatile drm_i915_sarea_t *sarea;
-
-   GLuint lastStamp;
-
-   GLboolean no_hw;
+   __DRIcontext *driContext;
+   struct intel_screen *intelScreen;
+   void (*saved_viewport)(struct gl_context * ctx,
+                         GLint x, GLint y, GLsizei width, GLsizei height);
 
    /**
     * Configuration cache
     */
    driOptionCache optionCache;
-
-   int64_t swap_ust;
-   int64_t swap_missed_ust;
-
-   GLuint swap_count;
-   GLuint swap_missed_count;
 };
 
-/* These are functions now:
- */
-void LOCK_HARDWARE( struct intel_context *intel );
-void UNLOCK_HARDWARE( struct intel_context *intel );
-
 extern char *__progname;
 
 
@@ -351,17 +344,43 @@ extern char *__progname;
 #define SUBPIXEL_Y 0.125
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
-#define ALIGN(value, alignment)  ((value + alignment - 1) & ~(alignment - 1))
+
+/**
+ * Align a value up to an alignment value
+ *
+ * If \c value is not already aligned to the requested alignment value, it
+ * will be rounded up.
+ *
+ * \param value  Value to be rounded
+ * \param alignment  Alignment value to be used.  This must be a power of two.
+ *
+ * \sa ROUND_DOWN_TO()
+ */
+#define ALIGN(value, alignment)  (((value) + alignment - 1) & ~(alignment - 1))
+
+/**
+ * Align a value down to an alignment value
+ *
+ * If \c value is not already aligned to the requested alignment value, it
+ * will be rounded down.
+ *
+ * \param value  Value to be rounded
+ * \param alignment  Alignment value to be used.  This must be a power of two.
+ *
+ * \sa ALIGN()
+ */
+#define ROUND_DOWN_TO(value, alignment) ((value) & ~(alignment - 1))
+
 #define IS_POWER_OF_TWO(val) (((val) & (val - 1)) == 0)
 
-static inline uint32_t
+static INLINE uint32_t
 U_FIXED(float value, uint32_t frac_bits)
 {
    value *= (1 << frac_bits);
    return value < 0 ? 0 : value;
 }
 
-static inline uint32_t
+static INLINE uint32_t
 S_FIXED(float value, uint32_t frac_bits)
 {
    return value * (1 << frac_bits);
@@ -373,29 +392,6 @@ do {                                               \
       (intel)->prim.flush(intel);              \
 } while (0)
 
-/* ================================================================
- * Color packing:
- */
-
-#define INTEL_PACKCOLOR4444(r,g,b,a) \
-  ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
-
-#define INTEL_PACKCOLOR1555(r,g,b,a) \
-  ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
-    ((a) ? 0x8000 : 0))
-
-#define INTEL_PACKCOLOR565(r,g,b) \
-  ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
-
-#define INTEL_PACKCOLOR8888(r,g,b,a) \
-  ((a<<24) | (r<<16) | (g<<8) | b)
-
-#define INTEL_PACKCOLOR(format, r,  g,  b, a)          \
-(format == DV_PF_555 ? INTEL_PACKCOLOR1555(r,g,b,a) :  \
- (format == DV_PF_565 ? INTEL_PACKCOLOR565(r,g,b) :    \
-  (format == DV_PF_8888 ? INTEL_PACKCOLOR8888(r,g,b,a) :       \
-   0)))
-
 /* ================================================================
  * From linux kernel i386 header files, copes with odd sizes better
  * than COPY_DWORDS would:
@@ -441,24 +437,30 @@ extern int INTEL_DEBUG;
 #define DEBUG_BUFMGR    0x200
 #define DEBUG_REGION    0x400
 #define DEBUG_FBO       0x800
-#define DEBUG_LOCK      0x1000
+#define DEBUG_GS        0x1000
 #define DEBUG_SYNC     0x2000
 #define DEBUG_PRIMS    0x4000
 #define DEBUG_VERTS    0x8000
 #define DEBUG_DRI       0x10000
-#define DEBUG_DMA       0x20000
+#define DEBUG_SF        0x20000
 #define DEBUG_SANITY    0x40000
 #define DEBUG_SLEEP     0x80000
 #define DEBUG_STATS     0x100000
 #define DEBUG_TILE      0x200000
-#define DEBUG_SINGLE_THREAD   0x400000
-#define DEBUG_WM        0x800000
-#define DEBUG_URB       0x1000000
-#define DEBUG_VS        0x2000000
+#define DEBUG_WM        0x400000
+#define DEBUG_URB       0x800000
+#define DEBUG_VS        0x1000000
+#define DEBUG_CLIP      0x2000000
+#define DEBUG_AUB       0x4000000
 
 #define DBG(...) do {                                          \
-       if (INTEL_DEBUG & FILE_DEBUG_FLAG)                      \
-               _mesa_printf(__VA_ARGS__);                      \
+       if (unlikely(INTEL_DEBUG & FILE_DEBUG_FLAG))            \
+               printf(__VA_ARGS__);                    \
+} while(0)
+
+#define fallback_debug(...) do {                               \
+       if (unlikely(INTEL_DEBUG & DEBUG_FALLBACKS))            \
+               printf(__VA_ARGS__);                            \
 } while(0)
 
 #define PCI_CHIP_845_G                 0x2562
@@ -479,16 +481,18 @@ extern int INTEL_DEBUG;
  * intel_context.c:
  */
 
-extern GLboolean intelInitContext(struct intel_context *intel,
-                                  const __GLcontextModes * mesaVis,
-                                  __DRIcontextPrivate * driContextPriv,
+extern bool intelInitContext(struct intel_context *intel,
+                                 int api,
+                                  const struct gl_config * mesaVis,
+                                  __DRIcontext * driContextPriv,
                                   void *sharedContextPrivate,
                                   struct dd_function_table *functions);
 
-extern void intelGetLock(struct intel_context *intel, GLuint flags);
+extern void intelFinish(struct gl_context * ctx);
+extern void intel_flush_rendering_to_batch(struct gl_context *ctx);
+extern void _intel_flush(struct gl_context * ctx, const char *file, int line);
 
-extern void intelFinish(GLcontext * ctx);
-extern void intelFlush(GLcontext * ctx);
+#define intel_flush(ctx) _intel_flush(ctx, __FILE__, __LINE__)
 
 extern void intelInitDriverFunctions(struct dd_function_table *functions);
 
@@ -563,50 +567,32 @@ extern int intel_translate_stencil_op(GLenum op);
 extern int intel_translate_blend_factor(GLenum factor);
 extern int intel_translate_logic_op(GLenum opcode);
 
-void intel_viewport(GLcontext * ctx, GLint x, GLint y,
-                   GLsizei width, GLsizei height);
-
 void intel_update_renderbuffers(__DRIcontext *context,
                                __DRIdrawable *drawable);
+void intel_prepare_render(struct intel_context *intel);
 
 void i915_set_buf_info_for_region(uint32_t *state, struct intel_region *region,
                                  uint32_t buffer_id);
+void intel_init_texture_formats(struct gl_context *ctx);
 
 /*======================================================================
  * Inline conversion functions.  
  * These are better-typed than the macros used previously:
  */
 static INLINE struct intel_context *
-intel_context(GLcontext * ctx)
+intel_context(struct gl_context * ctx)
 {
    return (struct intel_context *) ctx;
 }
 
-static INLINE GLboolean
+static INLINE bool
 is_power_of_two(uint32_t value)
 {
    return (value & (value - 1)) == 0;
 }
 
-static inline void
-intel_bo_map_gtt_preferred(struct intel_context *intel,
-                          drm_intel_bo *bo,
-                          GLboolean write)
-{
-   if (intel->intelScreen->kernel_exec_fencing)
-      drm_intel_gem_bo_map_gtt(bo);
-   else
-      drm_intel_bo_map(bo, write);
-}
-
-static inline void
-intel_bo_unmap_gtt_preferred(struct intel_context *intel,
-                            drm_intel_bo *bo)
-{
-   if (intel->intelScreen->kernel_exec_fencing)
-      drm_intel_gem_bo_unmap_gtt(bo);
-   else
-      drm_intel_bo_unmap(bo);
+#ifdef __cplusplus
 }
+#endif
 
 #endif