Gallium: Add format PIPE_FORMAT_R8_SRGB
[mesa.git] / src / gallium / drivers / svga / svga_draw_private.h
index 11afb59875bdc36add1807e0727cbbd7717dde1b..52a2c0f18b357ac344af56f49c8bdbba8b416528 100644 (file)
 #include "pipe/p_compiler.h"
 #include "pipe/p_defines.h"
 #include "indices/u_indices.h"
+#include "util/u_prim.h"
+#include "svga_context.h"
 #include "svga_hw_reg.h"
 #include "svga3d_shaderdefs.h"
 
 struct svga_context;
 struct u_upload_mgr;
 
-/* Should include polygon?
+/**
+ * Mask indicating which types of gallium primitives are actually
+ * handled by the svga device.  Other types will be converted to
+ * these types by the index/translation code.
  */
-static const unsigned svga_hw_prims = 
+static const unsigned svga_hw_prims =
    ((1 << PIPE_PRIM_POINTS) |
     (1 << PIPE_PRIM_LINES) |
     (1 << PIPE_PRIM_LINE_STRIP) |
     (1 << PIPE_PRIM_TRIANGLES) |
     (1 << PIPE_PRIM_TRIANGLE_STRIP) |
-    (1 << PIPE_PRIM_TRIANGLE_FAN));
-
-
-static INLINE unsigned svga_translate_prim(unsigned mode, 
-                                           unsigned count,
-                                           unsigned *out_count)
+    (1 << PIPE_PRIM_TRIANGLE_FAN) |
+    (1 << PIPE_PRIM_LINES_ADJACENCY) |
+    (1 << PIPE_PRIM_LINE_STRIP_ADJACENCY) |
+    (1 << PIPE_PRIM_TRIANGLES_ADJACENCY) |
+    (1 << PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY));
+
+
+/**
+ * Translate a gallium PIPE_PRIM_x value to an SVGA3D_PRIMITIVE_x value.
+ * Also, compute the number of primitives that'll be drawn given a
+ * vertex count.
+ * Note that this function doesn't have to handle PIPE_PRIM_LINE_LOOP,
+ * PIPE_PRIM_QUADS, PIPE_PRIM_QUAD_STRIP or PIPE_PRIM_POLYGON.  We convert
+ * those to other types of primitives with index/translation code.
+ */
+static inline SVGA3dPrimitiveType
+svga_translate_prim(unsigned mode, unsigned vcount, unsigned *prim_count)
 {
    switch (mode) {
    case PIPE_PRIM_POINTS:
-      *out_count = count;
+      *prim_count = vcount;
       return SVGA3D_PRIMITIVE_POINTLIST;
 
    case PIPE_PRIM_LINES:
-      *out_count = count / 2;
-      return SVGA3D_PRIMITIVE_LINELIST; 
+      *prim_count = vcount / 2;
+      return SVGA3D_PRIMITIVE_LINELIST;
 
    case PIPE_PRIM_LINE_STRIP:
-      *out_count = count - 1;
-      return SVGA3D_PRIMITIVE_LINESTRIP; 
+      *prim_count = vcount - 1;
+      return SVGA3D_PRIMITIVE_LINESTRIP;
 
    case PIPE_PRIM_TRIANGLES:
-      *out_count = count / 3;
-      return SVGA3D_PRIMITIVE_TRIANGLELIST; 
+      *prim_count = vcount / 3;
+      return SVGA3D_PRIMITIVE_TRIANGLELIST;
 
    case PIPE_PRIM_TRIANGLE_STRIP:
-      *out_count = count - 2;
-      return SVGA3D_PRIMITIVE_TRIANGLESTRIP; 
+      *prim_count = vcount - 2;
+      return SVGA3D_PRIMITIVE_TRIANGLESTRIP;
 
    case PIPE_PRIM_TRIANGLE_FAN:
-      *out_count = count - 2;
-      return SVGA3D_PRIMITIVE_TRIANGLEFAN; 
+      *prim_count = vcount - 2;
+      return SVGA3D_PRIMITIVE_TRIANGLEFAN;
+
+   case PIPE_PRIM_LINES_ADJACENCY:
+      *prim_count = vcount / 4;
+      return SVGA3D_PRIMITIVE_LINELIST_ADJ;
+
+   case PIPE_PRIM_LINE_STRIP_ADJACENCY:
+      *prim_count = vcount - 3;
+      return SVGA3D_PRIMITIVE_LINESTRIP_ADJ;
+
+   case PIPE_PRIM_TRIANGLES_ADJACENCY:
+      *prim_count = vcount / 6;
+      return SVGA3D_PRIMITIVE_TRIANGLELIST_ADJ;
+
+   case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
+      *prim_count = vcount / 2 - 2 ;
+      return SVGA3D_PRIMITIVE_TRIANGLESTRIP_ADJ;
 
    default:
       assert(0);
-      *out_count = 0;
+      *prim_count = 0;
       return 0;
    }
 }
@@ -87,24 +119,31 @@ struct index_cache {
    u_generate_func generate;
    unsigned gen_nr;
 
-   /* If non-null, this buffer is filled by calling 
-    *   generate(nr, map(buffer))
+   /* If non-null, this buffer is filled by calling generate(nr, map(buffer))
     */
    struct pipe_resource *buffer;
 };
 
-#define QSZ 32
+
+/** Max number of primitives per draw call */
+#define QSZ SVGA3D_MAX_DRAW_PRIMITIVE_RANGES
 
 struct draw_cmd {
    struct svga_winsys_context *swc;
 
+   /* vertex layout info */
    SVGA3dVertexDecl vdecl[SVGA3D_INPUTREG_MAX];
-   struct pipe_resource *vdecl_vb[SVGA3D_INPUTREG_MAX];
    unsigned vdecl_count;
+   SVGA3dElementLayoutId vdecl_layout_id;
+   unsigned vdecl_buffer_index[SVGA3D_INPUTREG_MAX];
+
+   /* vertex buffer info */
+   struct pipe_vertex_buffer vbufs[SVGA3D_INPUTREG_MAX];
+   unsigned vbuf_count;
 
    SVGA3dPrimitiveRange prim[QSZ];
    struct pipe_resource *prim_ib[QSZ];
-   unsigned prim_count;
+   unsigned prim_count;   /**< number of primitives for this draw */
    unsigned min_index[QSZ];
    unsigned max_index[QSZ];
 };
@@ -114,11 +153,22 @@ struct draw_cmd {
 struct svga_hwtnl {
    struct svga_context *svga;
    struct u_upload_mgr *upload_ib;
-   
-   /* Flatshade information:
+
+   /* Additional negative index bias due to partial buffer uploads
+    * This is compensated for in the offset associated with all
+    * vertex buffers.
+    */
+   int index_bias;
+
+   /* Provoking vertex information (for flat shading). */
+   unsigned api_pv;  /**< app-requested PV mode (PV_FIRST or PV_LAST) */
+   unsigned hw_pv;   /**< device-supported PV mode (PV_FIRST or PV_LAST) */
+
+   /* The triangle fillmode for the device (one of PIPE_POLYGON_MODE_{FILL,
+    * LINE,POINT}).  If the polygon front mode matches the back mode,
+    * api_fillmode will be that mode.  Otherwise, api_fillmode will be
+    * PIPE_POLYGON_MODE_FILL.
     */
-   unsigned api_pv;
-   unsigned hw_pv;
    unsigned api_fillmode;
 
    /* Cache the results of running a particular generate func on each
@@ -133,26 +183,54 @@ struct svga_hwtnl {
 
 
 
-/***********************************************************************
- * Internal functions
+/**
+ * Do we need to use the gallium 'indices' helper to render unfilled
+ * triangles?
  */
-enum pipe_error 
-svga_hwtnl_prim( struct svga_hwtnl *hwtnl,
-                 const SVGA3dPrimitiveRange *range,
-                 unsigned min_index,
-                 unsigned max_index,
-                 struct pipe_resource *ib );
+static inline boolean
+svga_need_unfilled_fallback(const struct svga_hwtnl *hwtnl,
+                            enum pipe_prim_type prim)
+{
+   if (u_reduced_prim(prim) != PIPE_PRIM_TRIANGLES) {
+      /* if we're drawing points or lines, no fallback needed */
+      return FALSE;
+   }
+
+   if ((prim == PIPE_PRIM_QUADS ||
+        prim == PIPE_PRIM_QUAD_STRIP ||
+        prim == PIPE_PRIM_POLYGON) &&
+       hwtnl->api_fillmode == PIPE_POLYGON_MODE_LINE) {
+      /* We can't directly render quads or polygons.  They're
+       * converted to triangles.  If we let the device draw the triangle
+       * outlines we'll get an extra, stray lines in the interiors.
+       * So, to draw unfilled quads correctly, we need the fallback.
+       */
+      return true;
+   }
+   return false;
+}
+
 
 enum pipe_error
-svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl *hwtnl,
-                                       struct pipe_resource *indexBuffer,
-                                       unsigned index_size,
-                                       int index_bias,
-                                       unsigned min_index,
-                                       unsigned max_index,
-                                       unsigned prim, 
-                                       unsigned start,
-                                       unsigned count );
+svga_hwtnl_prim(struct svga_hwtnl *hwtnl,
+                const SVGA3dPrimitiveRange *range,
+                unsigned vcount,
+                unsigned min_index,
+                unsigned max_index,
+                struct pipe_resource *ib,
+                unsigned start_instance, unsigned instance_count);
 
+enum pipe_error
+svga_hwtnl_simple_draw_range_elements(struct svga_hwtnl *hwtnl,
+                                      struct pipe_resource *indexBuffer,
+                                      unsigned index_size,
+                                      int index_bias,
+                                      unsigned min_index,
+                                      unsigned max_index,
+                                      enum pipe_prim_type prim,
+                                      unsigned start,
+                                      unsigned count,
+                                      unsigned start_instance,
+                                      unsigned instance_count);
 
 #endif