i965: Allow C++ type safety in the use of enum brw_urb_write_flags.
authorPaul Berry <stereotype441@gmail.com>
Fri, 23 Aug 2013 20:19:19 +0000 (13:19 -0700)
committerPaul Berry <stereotype441@gmail.com>
Mon, 26 Aug 2013 17:15:51 +0000 (10:15 -0700)
(From a suggestion by Francisco Jerez)

If an enum represents a bitfield of flags, e.g.:

enum E {
  A = 1,
  B = 2,
  C = 4,
  D = 8,
};

then C++ normally prohibits statements like this:

enum E x = A | B;

because A and B are implicitly converted to ints before OR-ing them,
and an int can't be stored in an enum without a type cast.  C, on the
other hand, allows an int to be implicitly converted to an enum
without casting.

In the past we've dealt with this situation by storing flag bitfields
as ints.  This avoids ugly casting at the expense of some type safety
that C++ would normally have offered (e.g. we get no warning if we
accidentally use the wrong enum type).

However, we can get the best of both worlds if we override the |
operator.  The ugly casting is confined to the operator overload, and
we still get the benefit of C++ making sure we don't use the wrong
enum type.

v2: Remove unnecessary comment and unnecessary use of "enum" keyword.
Use static_cast.

Reviewed-by: Chad Versace <chad.versace@linux.intel.com>
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
src/mesa/drivers/dri/i965/brw_clip.h
src/mesa/drivers/dri/i965/brw_clip_util.c
src/mesa/drivers/dri/i965/brw_eu.h
src/mesa/drivers/dri/i965/brw_eu_emit.c
src/mesa/drivers/dri/i965/brw_sf_emit.c
src/mesa/drivers/dri/i965/brw_vec4.h
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp

index 5af0ad3429b9ffd4bc20723d41486572c5671512..41f5c75d1aa0045d24b78a59719125ae9629cfe3 100644 (file)
@@ -173,7 +173,7 @@ void brw_clip_init_planes( struct brw_clip_compile *c );
 
 void brw_clip_emit_vue(struct brw_clip_compile *c, 
                       struct brw_indirect vert,
-                       unsigned flags,
+                       enum brw_urb_write_flags flags,
                       GLuint header);
 
 void brw_clip_kill_thread(struct brw_clip_compile *c);
index d5c50d7a8901f27d51e8031775bbbe25d44112c1..24d053eaea6ad727bc9f6c20afdd54901494c3e5 100644 (file)
@@ -313,7 +313,7 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,
 
 void brw_clip_emit_vue(struct brw_clip_compile *c, 
                       struct brw_indirect vert,
-                       unsigned flags,
+                       enum brw_urb_write_flags flags,
                       GLuint header)
 {
    struct brw_compile *p = &c->func;
index 9053ea2f86b6b36c32abceb5f6c2f8af1b2c01bb..387450bb025c892e5d1c0bcd88f18918a2c654d8 100644 (file)
@@ -229,6 +229,8 @@ void brw_set_dp_write_message(struct brw_compile *p,
                              GLuint send_commit_msg);
 
 enum brw_urb_write_flags {
+   BRW_URB_WRITE_NO_FLAGS = 0,
+
    /**
     * Causes a new URB entry to be allocated, and its address stored in the
     * destination register (gen < 7).
@@ -271,11 +273,23 @@ enum brw_urb_write_flags {
       BRW_URB_WRITE_ALLOCATE | BRW_URB_WRITE_COMPLETE,
 };
 
+#ifdef __cplusplus
+/**
+ * Allow brw_urb_write_flags enums to be ORed together.
+ */
+inline brw_urb_write_flags
+operator|(brw_urb_write_flags x, brw_urb_write_flags y)
+{
+   return static_cast<brw_urb_write_flags>(static_cast<int>(x) |
+                                           static_cast<int>(y));
+}
+#endif
+
 void brw_urb_WRITE(struct brw_compile *p,
                   struct brw_reg dest,
                   GLuint msg_reg_nr,
                   struct brw_reg src0,
-                   unsigned flags,
+                   enum brw_urb_write_flags flags,
                   GLuint msg_length,
                   GLuint response_length,
                   GLuint offset,
index b55b57e2e82480a4ba65e1eab0a771716ec4ecda..ecf8597823f9234c7450915d190c9b97c8c2bb27 100644 (file)
@@ -515,7 +515,7 @@ static void brw_set_ff_sync_message(struct brw_compile *p,
 
 static void brw_set_urb_message( struct brw_compile *p,
                                 struct brw_instruction *insn,
-                                 unsigned flags,
+                                 enum brw_urb_write_flags flags,
                                 GLuint msg_length,
                                 GLuint response_length,
                                 GLuint offset,
@@ -2213,7 +2213,7 @@ void brw_urb_WRITE(struct brw_compile *p,
                   struct brw_reg dest,
                   GLuint msg_reg_nr,
                   struct brw_reg src0,
-                   unsigned flags,
+                   enum brw_urb_write_flags flags,
                   GLuint msg_length,
                   GLuint response_length,
                   GLuint offset,
index d329bef1aef8663cb40887526f1fe45b9036f530..b206797f756bff25f1dcdc658a33e8d0d1ddd8af 100644 (file)
@@ -491,7 +491,8 @@ void brw_emit_tri_setup(struct brw_sf_compile *c, bool allocate)
                       brw_null_reg(),
                       0,
                       brw_vec8_grf(0, 0), /* r0, will be copied to m0 */
-                       last ? BRW_URB_WRITE_EOT_COMPLETE : 0,
+                       last ? BRW_URB_WRITE_EOT_COMPLETE
+                       : BRW_URB_WRITE_NO_FLAGS,
                       4,       /* msg len */
                       0,       /* response len */
                       i*4,     /* offset */
@@ -562,7 +563,8 @@ void brw_emit_line_setup(struct brw_sf_compile *c, bool allocate)
                       brw_null_reg(),
                       0,
                       brw_vec8_grf(0, 0),
-                       last ? BRW_URB_WRITE_EOT_COMPLETE : 0,
+                       last ? BRW_URB_WRITE_EOT_COMPLETE
+                       : BRW_URB_WRITE_NO_FLAGS,
                       4,       /* msg len */
                       0,       /* response len */
                       i*4,     /* urb destination offset */
@@ -649,7 +651,8 @@ void brw_emit_point_sprite_setup(struct brw_sf_compile *c, bool allocate)
                    brw_null_reg(),
                    0,
                    brw_vec8_grf(0, 0),
-                    last ? BRW_URB_WRITE_EOT_COMPLETE : 0,
+                    last ? BRW_URB_WRITE_EOT_COMPLETE
+                    : BRW_URB_WRITE_NO_FLAGS,
                    4,  /* msg len */
                    0,  /* response len */
                    i*4,        /* urb destination offset */
@@ -706,7 +709,8 @@ void brw_emit_point_setup(struct brw_sf_compile *c, bool allocate)
                       brw_null_reg(),
                       0,
                       brw_vec8_grf(0, 0),
-                       last ? BRW_URB_WRITE_EOT_COMPLETE : 0,
+                       last ? BRW_URB_WRITE_EOT_COMPLETE
+                       : BRW_URB_WRITE_NO_FLAGS,
                       4,       /* msg len */
                       0,       /* response len */
                       i*4,     /* urb destination offset */
index a39dc505cfa935475610eba1d7f55cf4efbff9d7..1f9cb954dc47ebb628612a18b356f8fe6f55ccee 100644 (file)
@@ -222,7 +222,7 @@ public:
    int target; /**< MRT target. */
    bool shadow_compare;
 
-   unsigned urb_write_flags;
+   enum brw_urb_write_flags urb_write_flags;
    bool header_present;
    int mlen; /**< SEND message length */
    int base_mrf; /**< First MRF in the SEND message, if mlen is nonzero. */
index 72841e7e7fa85f770dfb83ac840bcfc0e4aea03c..d0959b7333fe9e2fb9bd6d554b51f4bdf78d6f28 100644 (file)
@@ -2788,7 +2788,8 @@ vec4_vs_visitor::emit_urb_write_opcode(bool complete)
    }
 
    vec4_instruction *inst = emit(VS_OPCODE_URB_WRITE);
-   inst->urb_write_flags = complete ? BRW_URB_WRITE_EOT_COMPLETE : 0;
+   inst->urb_write_flags = complete ?
+      BRW_URB_WRITE_EOT_COMPLETE : BRW_URB_WRITE_NO_FLAGS;
 
    return inst;
 }