diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_blit.c | 299 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_blit.h | 16 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_screen.h | 1 |
3 files changed, 149 insertions, 167 deletions
diff --git a/src/mesa/drivers/dri/i915/intel_blit.c b/src/mesa/drivers/dri/i915/intel_blit.c index 551f18ffd2e..98cffaf2483 100644 --- a/src/mesa/drivers/dri/i915/intel_blit.c +++ b/src/mesa/drivers/dri/i915/intel_blit.c @@ -72,144 +72,23 @@ br13_for_cpp(int cpp) } } -/** - * 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; @@ -320,6 +199,126 @@ intelEmitCopyBlit(struct intel_context *intel, 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'. @@ -589,13 +588,13 @@ intel_emit_linear_blit(struct intel_context *intel, */ 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); @@ -605,13 +604,13 @@ intel_emit_linear_blit(struct intel_context *intel, 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); } diff --git a/src/mesa/drivers/dri/i915/intel_blit.h b/src/mesa/drivers/dri/i915/intel_blit.h index 5c0d3597f16..61de411b387 100644 --- a/src/mesa/drivers/dri/i915/intel_blit.h +++ b/src/mesa/drivers/dri/i915/intel_blit.h @@ -35,22 +35,6 @@ extern void intelCopyBuffer(const __DRIdrawable * dpriv, extern GLbitfield intelClearWithBlit(struct gl_context * ctx, GLbitfield mask); -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 srcx, GLshort srcy, - GLshort dstx, GLshort dsty, - GLshort w, GLshort h, - enum gl_logicop_mode logicop); - bool intel_miptree_blit(struct intel_context *intel, struct intel_mipmap_tree *src_mt, int src_level, int src_slice, diff --git a/src/mesa/drivers/dri/i915/intel_screen.h b/src/mesa/drivers/dri/i915/intel_screen.h index ec4592d1e10..ac70d36553e 100644 --- a/src/mesa/drivers/dri/i915/intel_screen.h +++ b/src/mesa/drivers/dri/i915/intel_screen.h @@ -117,7 +117,6 @@ struct intel_screen #define intel_check_front_buffer_rendering old_intel_check_front_buffer_rendering #define intelInitBufferFuncs old_intelInitBufferFuncs #define intelClearWithBlit old_intelClearWithBlit -#define intelEmitCopyBlit old_intelEmitCopyBlit #define intelEmitImmediateColorExpandBlit old_intelEmitImmediateColorExpandBlit #define intel_emit_linear_blit old_intel_emit_linear_blit #define intel_miptree_blit old_intel_miptree_blit |