}
}
-/**
- * Implements a rectangular block transfer (blit) of pixels between two
- * miptrees.
- *
- * Our blitter can operate on 1, 2, or 4-byte-per-pixel data, with generous,
- * but limited, pitches and sizes allowed.
- *
- * The src/dst coordinates are relative to the given level/slice of the
- * miptree.
- *
- * If @src_flip or @dst_flip is set, then the rectangle within that miptree
- * will be inverted (including scanline order) when copying. This is common
- * in GL when copying between window system and user-created
- * renderbuffers/textures.
- */
-bool
-intel_miptree_blit(struct intel_context *intel,
- struct intel_mipmap_tree *src_mt,
- int src_level, int src_slice,
- uint32_t src_x, uint32_t src_y, bool src_flip,
- struct intel_mipmap_tree *dst_mt,
- int dst_level, int dst_slice,
- uint32_t dst_x, uint32_t dst_y, bool dst_flip,
- uint32_t width, uint32_t height,
- enum gl_logicop_mode logicop)
-{
- /* No sRGB decode or encode is done by the hardware blitter, which is
- * consistent with what we want in the callers (glCopyTexSubImage(),
- * glBlitFramebuffer(), texture validation, etc.).
- */
- mesa_format src_format = _mesa_get_srgb_format_linear(src_mt->format);
- mesa_format dst_format = _mesa_get_srgb_format_linear(dst_mt->format);
-
- /* The blitter doesn't support doing any format conversions. We do also
- * support blitting ARGB8888 to XRGB8888 (trivial, the values dropped into
- * the X channel don't matter), and XRGB8888 to ARGB8888 by setting the A
- * channel to 1.0 at the end.
- */
- if (src_format != dst_format &&
- ((src_format != MESA_FORMAT_B8G8R8A8_UNORM &&
- src_format != MESA_FORMAT_B8G8R8X8_UNORM) ||
- (dst_format != MESA_FORMAT_B8G8R8A8_UNORM &&
- dst_format != MESA_FORMAT_B8G8R8X8_UNORM))) {
- perf_debug("%s: Can't use hardware blitter from %s to %s, "
- "falling back.\n", __func__,
- _mesa_get_format_name(src_format),
- _mesa_get_format_name(dst_format));
- return false;
- }
-
- /* According to the Ivy Bridge PRM, Vol1 Part4, section 1.2.1.2 (Graphics
- * Data Size Limitations):
- *
- * The BLT engine is capable of transferring very large quantities of
- * graphics data. Any graphics data read from and written to the
- * destination is permitted to represent a number of pixels that
- * occupies up to 65,536 scan lines and up to 32,768 bytes per scan line
- * at the destination. The maximum number of pixels that may be
- * represented per scan line’s worth of graphics data depends on the
- * color depth.
- *
- * Furthermore, intelEmitCopyBlit (which is called below) uses a signed
- * 16-bit integer to represent buffer pitch, so it can only handle buffer
- * pitches < 32k.
- *
- * As a result of these two limitations, we can only use the blitter to do
- * this copy when the region's pitch is less than 32k.
- */
- if (src_mt->region->pitch > 32768 ||
- dst_mt->region->pitch > 32768) {
- perf_debug("Falling back due to >32k pitch\n");
- return false;
- }
-
- if (src_flip)
- src_y = src_mt->level[src_level].height - src_y - height;
-
- if (dst_flip)
- dst_y = dst_mt->level[dst_level].height - dst_y - height;
-
- int src_pitch = src_mt->region->pitch;
- if (src_flip != dst_flip)
- src_pitch = -src_pitch;
-
- uint32_t src_image_x, src_image_y;
- intel_miptree_get_image_offset(src_mt, src_level, src_slice,
- &src_image_x, &src_image_y);
- src_x += src_image_x;
- src_y += src_image_y;
-
- uint32_t dst_image_x, dst_image_y;
- intel_miptree_get_image_offset(dst_mt, dst_level, dst_slice,
- &dst_image_x, &dst_image_y);
- dst_x += dst_image_x;
- dst_y += dst_image_y;
-
- if (!intelEmitCopyBlit(intel,
- src_mt->cpp,
- src_pitch,
- src_mt->region->bo, src_mt->offset,
- src_mt->region->tiling,
- dst_mt->region->pitch,
- dst_mt->region->bo, dst_mt->offset,
- dst_mt->region->tiling,
- src_x, src_y,
- dst_x, dst_y,
- width, height,
- logicop)) {
- return false;
- }
-
- if (src_mt->format == MESA_FORMAT_B8G8R8X8_UNORM &&
- dst_mt->format == MESA_FORMAT_B8G8R8A8_UNORM) {
- intel_miptree_set_alpha_to_one(intel, dst_mt,
- dst_x, dst_y,
- width, height);
- }
-
- return true;
-}
-
/* Copy BitBlt
*/
-bool
-intelEmitCopyBlit(struct intel_context *intel,
- GLuint cpp,
- GLshort src_pitch,
- drm_intel_bo *src_buffer,
- GLuint src_offset,
- uint32_t src_tiling,
- GLshort dst_pitch,
- drm_intel_bo *dst_buffer,
- GLuint dst_offset,
- uint32_t dst_tiling,
- GLshort src_x, GLshort src_y,
- GLshort dst_x, GLshort dst_y,
- GLshort w, GLshort h,
- enum gl_logicop_mode logic_op)
+static bool
+emit_copy_blit(struct intel_context *intel,
+ GLuint cpp,
+ GLshort src_pitch,
+ drm_intel_bo *src_buffer,
+ GLuint src_offset,
+ uint32_t src_tiling,
+ GLshort dst_pitch,
+ drm_intel_bo *dst_buffer,
+ GLuint dst_offset,
+ uint32_t dst_tiling,
+ GLshort src_x, GLshort src_y,
+ GLshort dst_x, GLshort dst_y,
+ GLshort w, GLshort h,
+ enum gl_logicop_mode logic_op)
{
GLuint CMD, BR13, pass = 0;
int dst_y2 = dst_y + h;
return true;
}
+/**
+ * Implements a rectangular block transfer (blit) of pixels between two
+ * miptrees.
+ *
+ * Our blitter can operate on 1, 2, or 4-byte-per-pixel data, with generous,
+ * but limited, pitches and sizes allowed.
+ *
+ * The src/dst coordinates are relative to the given level/slice of the
+ * miptree.
+ *
+ * If @src_flip or @dst_flip is set, then the rectangle within that miptree
+ * will be inverted (including scanline order) when copying. This is common
+ * in GL when copying between window system and user-created
+ * renderbuffers/textures.
+ */
+bool
+intel_miptree_blit(struct intel_context *intel,
+ struct intel_mipmap_tree *src_mt,
+ int src_level, int src_slice,
+ uint32_t src_x, uint32_t src_y, bool src_flip,
+ struct intel_mipmap_tree *dst_mt,
+ int dst_level, int dst_slice,
+ uint32_t dst_x, uint32_t dst_y, bool dst_flip,
+ uint32_t width, uint32_t height,
+ enum gl_logicop_mode logicop)
+{
+ /* No sRGB decode or encode is done by the hardware blitter, which is
+ * consistent with what we want in the callers (glCopyTexSubImage(),
+ * glBlitFramebuffer(), texture validation, etc.).
+ */
+ mesa_format src_format = _mesa_get_srgb_format_linear(src_mt->format);
+ mesa_format dst_format = _mesa_get_srgb_format_linear(dst_mt->format);
+
+ /* The blitter doesn't support doing any format conversions. We do also
+ * support blitting ARGB8888 to XRGB8888 (trivial, the values dropped into
+ * the X channel don't matter), and XRGB8888 to ARGB8888 by setting the A
+ * channel to 1.0 at the end.
+ */
+ if (src_format != dst_format &&
+ ((src_format != MESA_FORMAT_B8G8R8A8_UNORM &&
+ src_format != MESA_FORMAT_B8G8R8X8_UNORM) ||
+ (dst_format != MESA_FORMAT_B8G8R8A8_UNORM &&
+ dst_format != MESA_FORMAT_B8G8R8X8_UNORM))) {
+ perf_debug("%s: Can't use hardware blitter from %s to %s, "
+ "falling back.\n", __func__,
+ _mesa_get_format_name(src_format),
+ _mesa_get_format_name(dst_format));
+ return false;
+ }
+
+ /* According to the Ivy Bridge PRM, Vol1 Part4, section 1.2.1.2 (Graphics
+ * Data Size Limitations):
+ *
+ * The BLT engine is capable of transferring very large quantities of
+ * graphics data. Any graphics data read from and written to the
+ * destination is permitted to represent a number of pixels that
+ * occupies up to 65,536 scan lines and up to 32,768 bytes per scan line
+ * at the destination. The maximum number of pixels that may be
+ * represented per scan line’s worth of graphics data depends on the
+ * color depth.
+ *
+ * Furthermore, emit_copy_blit (which is called below) uses a signed
+ * 16-bit integer to represent buffer pitch, so it can only handle buffer
+ * pitches < 32k.
+ *
+ * As a result of these two limitations, we can only use the blitter to do
+ * this copy when the region's pitch is less than 32k.
+ */
+ if (src_mt->region->pitch > 32768 ||
+ dst_mt->region->pitch > 32768) {
+ perf_debug("Falling back due to >32k pitch\n");
+ return false;
+ }
+
+ if (src_flip)
+ src_y = src_mt->level[src_level].height - src_y - height;
+
+ if (dst_flip)
+ dst_y = dst_mt->level[dst_level].height - dst_y - height;
+
+ int src_pitch = src_mt->region->pitch;
+ if (src_flip != dst_flip)
+ src_pitch = -src_pitch;
+
+ uint32_t src_image_x, src_image_y;
+ intel_miptree_get_image_offset(src_mt, src_level, src_slice,
+ &src_image_x, &src_image_y);
+ src_x += src_image_x;
+ src_y += src_image_y;
+
+ uint32_t dst_image_x, dst_image_y;
+ intel_miptree_get_image_offset(dst_mt, dst_level, dst_slice,
+ &dst_image_x, &dst_image_y);
+ dst_x += dst_image_x;
+ dst_y += dst_image_y;
+
+ if (!emit_copy_blit(intel,
+ src_mt->cpp,
+ src_pitch,
+ src_mt->region->bo, src_mt->offset,
+ src_mt->region->tiling,
+ dst_mt->region->pitch,
+ dst_mt->region->bo, dst_mt->offset,
+ dst_mt->region->tiling,
+ src_x, src_y,
+ dst_x, dst_y,
+ width, height,
+ logicop)) {
+ return false;
+ }
+
+ if (src_mt->format == MESA_FORMAT_B8G8R8X8_UNORM &&
+ dst_mt->format == MESA_FORMAT_B8G8R8A8_UNORM) {
+ intel_miptree_set_alpha_to_one(intel, dst_mt,
+ dst_x, dst_y,
+ width, height);
+ }
+
+ return true;
+}
/**
* Use blitting to clear the renderbuffers named by 'flags'.
*/
pitch = ROUND_DOWN_TO(MIN2(size, (1 << 15) - 1), 4);
height = (pitch == 0) ? 1 : size / pitch;
- ok = intelEmitCopyBlit(intel, 1,
- 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 */
- pitch, height, /* w, h */
- COLOR_LOGICOP_COPY);
+ ok = emit_copy_blit(intel, 1,
+ 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 */
+ pitch, height, /* w, h */
+ COLOR_LOGICOP_COPY);
if (!ok)
_mesa_problem(ctx, "Failed to linear blit %dx%d\n", pitch, height);
assert (size < (1 << 15));
pitch = ALIGN(size, 4);
if (size != 0) {
- ok = intelEmitCopyBlit(intel, 1,
- 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 */
- COLOR_LOGICOP_COPY);
+ ok = emit_copy_blit(intel, 1,
+ 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 */
+ COLOR_LOGICOP_COPY);
if (!ok)
_mesa_problem(ctx, "Failed to linear blit %dx%d\n", size, 1);
}