mesa: remove _mesa_ffs(), implement ffs() for non-GNU platforms
[mesa.git] / src / mesa / drivers / dri / intel / intel_blit.c
index def226c16b790677245cd149e0f79657ac4a0190..e484fd34bfd14b0373357bab1f9903efe8688602 100644 (file)
@@ -146,6 +146,12 @@ intelEmitCopyBlit(struct intel_context *intel,
    src_pitch *= cpp;
    dst_pitch *= cpp;
 
+   /* Blit pitch must be dword-aligned.  Otherwise, the hardware appears to drop
+    * the low bits.
+    */
+   assert(src_pitch % 4 == 0);
+   assert(dst_pitch % 4 == 0);
+
    /* For big formats (such as floating point), do the copy using 32bpp and
     * multiply the coordinates.
     */
@@ -255,19 +261,24 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
    /* Loop over all renderbuffers */
    mask &= (1 << BUFFER_COUNT) - 1;
    while (mask) {
-      GLuint buf = _mesa_ffs(mask) - 1;
+      GLuint buf = ffs(mask) - 1;
       bool is_depth_stencil = buf == BUFFER_DEPTH || buf == BUFFER_STENCIL;
       struct intel_renderbuffer *irb;
       int x1, y1, x2, y2;
       uint32_t clear_val;
       uint32_t BR13, CMD;
+      struct intel_region *region;
       int pitch, cpp;
       drm_intel_bo *aper_array[2];
 
       mask &= ~(1 << buf);
 
       irb = intel_get_renderbuffer(fb, buf);
-      if (irb == NULL || irb->region == NULL || irb->region->bo == NULL) {
+      if (irb && irb->mt) {
+        region = irb->mt->region;
+        assert(region);
+        assert(region->bo);
+      } else {
          fail_mask |= 1 << buf;
          continue;
       }
@@ -278,12 +289,12 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
       x2 = cx + cw + irb->draw_x;
       y2 = cy + ch + irb->draw_y;
 
-      pitch = irb->region->pitch;
-      cpp = irb->region->cpp;
+      pitch = region->pitch;
+      cpp = region->cpp;
 
       DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n",
          __FUNCTION__,
-         irb->region->bo, (pitch * cpp),
+         region->bo, (pitch * cpp),
          x1, y1, x2 - x1, y2 - y1);
 
       BR13 = 0xf0 << 16;
@@ -299,10 +310,10 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
         }
       }
 
-      assert(irb->region->tiling != I915_TILING_Y);
+      assert(region->tiling != I915_TILING_Y);
 
 #ifndef I915
-      if (irb->region->tiling != I915_TILING_NONE) {
+      if (region->tiling != I915_TILING_NONE) {
         CMD |= XY_DST_TILED;
         pitch /= 4;
       }
@@ -351,7 +362,7 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
 
       /* do space check before going any further */
       aper_array[0] = intel->batch.bo;
-      aper_array[1] = irb->region->bo;
+      aper_array[1] = region->bo;
 
       if (drm_intel_bufmgr_check_aperture_space(aper_array,
                                                ARRAY_SIZE(aper_array)) != 0) {
@@ -363,7 +374,7 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
       OUT_BATCH(BR13);
       OUT_BATCH((y1 << 16) | x1);
       OUT_BATCH((y2 << 16) | x2);
-      OUT_RELOC_FENCED(irb->region->bo,
+      OUT_RELOC_FENCED(region->bo,
                       I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
                       0);
       OUT_BATCH(clear_val);
@@ -480,7 +491,7 @@ intel_emit_linear_blit(struct intel_context *intel,
     * we want width to match pitch. Max width is (1 << 15 - 1),
     * rounding that down to the nearest DWORD is 1 << 15 - 4
     */
-   pitch = MIN2(size, (1 << 15) - 4);
+   pitch = ROUND_DOWN_TO(MIN2(size, (1 << 15) - 1), 4);
    height = size / pitch;
    ok = intelEmitCopyBlit(intel, 1,
                          pitch, src_bo, src_offset, I915_TILING_NONE,
@@ -495,11 +506,11 @@ intel_emit_linear_blit(struct intel_context *intel,
    dst_offset += pitch * height;
    size -= pitch * height;
    assert (size < (1 << 15));
-   assert ((size & 3) == 0); /* Pitch must be DWORD aligned */
+   pitch = ALIGN(size, 4);
    if (size != 0) {
       ok = intelEmitCopyBlit(intel, 1,
-                            size, src_bo, src_offset, I915_TILING_NONE,
-                            size, dst_bo, dst_offset, I915_TILING_NONE,
+                            pitch, src_bo, src_offset, I915_TILING_NONE,
+                            pitch, dst_bo, dst_offset, I915_TILING_NONE,
                             0, 0, /* src x/y */
                             0, 0, /* dst x/y */
                             size, 1, /* w, h */