i965: Use SET_FIELD to safety check our x/y offsets in blits.
authorEric Anholt <eric@anholt.net>
Mon, 23 Dec 2013 09:48:09 +0000 (01:48 -0800)
committerEric Anholt <eric@anholt.net>
Thu, 9 Jan 2014 07:30:11 +0000 (15:30 +0800)
The earlier assert made sure that our math didn't exceed our bounds, but
this makes sure that we don't overflow from the high bits X into the low
bits of Y.  We've already put checks in intel_miptree_blit(), but I've
wanted to expand the type in our protoype from short to uint32_t, and we
could get in trouble with intel_emit_linear_blit() if we did.

v2: Add Ken's comment about the funny language extension used.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> (v1)
Reviewed-by: Anuj Phogat <anuj.phogat@gmail.com> (v1)
src/mesa/drivers/dri/i965/brw_defines.h
src/mesa/drivers/dri/i965/intel_blit.c

index 78df0b896727978c98015e1192cab4012257e3d4..142b2db967de3bd5d7e01c6106642e7a218c0abc 100644 (file)
@@ -30,6 +30,7 @@
   */
 
 #define INTEL_MASK(high, low) (((1<<((high)-(low)+1))-1)<<(low))
+/* Using the GNU statement expression extension */
 #define SET_FIELD(value, field)                                         \
    ({                                                                   \
       uint32_t fieldval = (value) << field ## _SHIFT;                   \
@@ -1919,6 +1920,11 @@ enum brw_wm_barycentric_interp_mode {
 
 #define CMD_MI_FLUSH                  0x0200
 
+# define BLT_X_SHIFT                                   0
+# define BLT_X_MASK                                    INTEL_MASK(15, 0)
+# define BLT_Y_SHIFT                                   16
+# define BLT_Y_MASK                                    INTEL_MASK(31, 16)
+
 #define GEN5_MI_REPORT_PERF_COUNT ((0x26 << 23) | (3 - 2))
 /* DW0 */
 # define GEN5_MI_COUNTER_SET_0      (0 << 6)
index 9162b1fc336077d42f0c511614760e039e8efc1e..330bac44a5a197dc8119ba08452785c7a55a69ce 100644 (file)
@@ -33,6 +33,7 @@
 #include "main/fbobject.h"
 
 #include "brw_context.h"
+#include "brw_defines.h"
 #include "intel_blit.h"
 #include "intel_buffers.h"
 #include "intel_fbo.h"
@@ -400,12 +401,12 @@ intelEmitCopyBlit(struct brw_context *brw,
 
    OUT_BATCH(CMD | (8 - 2));
    OUT_BATCH(BR13 | (uint16_t)dst_pitch);
-   OUT_BATCH((dst_y << 16) | dst_x);
-   OUT_BATCH((dst_y2 << 16) | dst_x2);
+   OUT_BATCH(SET_FIELD(dst_y, BLT_Y) | SET_FIELD(dst_x, BLT_X));
+   OUT_BATCH(SET_FIELD(dst_y2, BLT_Y) | SET_FIELD(dst_x2, BLT_X));
    OUT_RELOC(dst_buffer,
              I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
              dst_offset);
-   OUT_BATCH((src_y << 16) | src_x);
+   OUT_BATCH(SET_FIELD(src_y, BLT_Y) | SET_FIELD(src_x, BLT_X));
    OUT_BATCH((uint16_t)src_pitch);
    OUT_RELOC(src_buffer, I915_GEM_DOMAIN_RENDER, 0, src_offset);
 
@@ -479,8 +480,8 @@ intelEmitImmediateColorExpandBlit(struct brw_context *brw,
    OUT_BATCH(0); /* pattern base addr */
 
    OUT_BATCH(blit_cmd | ((3 - 2) + dwords));
-   OUT_BATCH((y << 16) | x);
-   OUT_BATCH(((y + h) << 16) | (x + w));
+   OUT_BATCH(SET_FIELD(y, BLT_Y) | SET_FIELD(x, BLT_X));
+   OUT_BATCH(SET_FIELD(y + h, BLT_Y) | SET_FIELD(x + w, BLT_X));
    ADVANCE_BATCH();
 
    intel_batchbuffer_data(brw, src_bits, dwords * 4, BLT_RING);
@@ -588,8 +589,8 @@ intel_miptree_set_alpha_to_one(struct brw_context *brw,
    BEGIN_BATCH_BLT_TILED(6, dst_y_tiled, false);
    OUT_BATCH(CMD | (6 - 2));
    OUT_BATCH(BR13);
-   OUT_BATCH((y << 16) | x);
-   OUT_BATCH(((y + height) << 16) | (x + width));
+   OUT_BATCH(SET_FIELD(y, BLT_Y) | SET_FIELD(x, BLT_X));
+   OUT_BATCH(SET_FIELD(y + height, BLT_Y) | SET_FIELD(x + width, BLT_X));
    OUT_RELOC(region->bo,
              I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
              0);