Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28.  
  29. #include "main/mtypes.h"
  30. #include "main/context.h"
  31. #include "main/enums.h"
  32. #include "main/colormac.h"
  33. #include "main/fbobject.h"
  34.  
  35. #include "brw_context.h"
  36. #include "intel_blit.h"
  37. #include "intel_buffers.h"
  38. #include "intel_fbo.h"
  39. #include "intel_reg.h"
  40. #include "intel_regions.h"
  41. #include "intel_batchbuffer.h"
  42. #include "intel_mipmap_tree.h"
  43.  
  44. #define FILE_DEBUG_FLAG DEBUG_BLIT
  45.  
  46. static void
  47. intel_miptree_set_alpha_to_one(struct brw_context *brw,
  48.                                struct intel_mipmap_tree *mt,
  49.                                int x, int y, int width, int height);
  50.  
  51. static GLuint translate_raster_op(GLenum logicop)
  52. {
  53.    switch(logicop) {
  54.    case GL_CLEAR: return 0x00;
  55.    case GL_AND: return 0x88;
  56.    case GL_AND_REVERSE: return 0x44;
  57.    case GL_COPY: return 0xCC;
  58.    case GL_AND_INVERTED: return 0x22;
  59.    case GL_NOOP: return 0xAA;
  60.    case GL_XOR: return 0x66;
  61.    case GL_OR: return 0xEE;
  62.    case GL_NOR: return 0x11;
  63.    case GL_EQUIV: return 0x99;
  64.    case GL_INVERT: return 0x55;
  65.    case GL_OR_REVERSE: return 0xDD;
  66.    case GL_COPY_INVERTED: return 0x33;
  67.    case GL_OR_INVERTED: return 0xBB;
  68.    case GL_NAND: return 0x77;
  69.    case GL_SET: return 0xFF;
  70.    default: return 0;
  71.    }
  72. }
  73.  
  74. static uint32_t
  75. br13_for_cpp(int cpp)
  76. {
  77.    switch (cpp) {
  78.    case 4:
  79.       return BR13_8888;
  80.       break;
  81.    case 2:
  82.       return BR13_565;
  83.       break;
  84.    case 1:
  85.       return BR13_8;
  86.       break;
  87.    default:
  88.       assert(0);
  89.       return 0;
  90.    }
  91. }
  92.  
  93. /**
  94.  * Emits the packet for switching the blitter from X to Y tiled or back.
  95.  *
  96.  * This has to be called in a single BEGIN_BATCH_BLT_TILED() /
  97.  * ADVANCE_BATCH_TILED().  This is because BCS_SWCTRL is saved and restored as
  98.  * part of the power context, not a render context, and if the batchbuffer was
  99.  * to get flushed between setting and blitting, or blitting and restoring, our
  100.  * tiling state would leak into other unsuspecting applications (like the X
  101.  * server).
  102.  */
  103. static void
  104. set_blitter_tiling(struct brw_context *brw,
  105.                    bool dst_y_tiled, bool src_y_tiled)
  106. {
  107.    assert(brw->gen >= 6);
  108.  
  109.    /* Idle the blitter before we update how tiling is interpreted. */
  110.    OUT_BATCH(MI_FLUSH_DW);
  111.    OUT_BATCH(0);
  112.    OUT_BATCH(0);
  113.    OUT_BATCH(0);
  114.  
  115.    OUT_BATCH(MI_LOAD_REGISTER_IMM | (3 - 2));
  116.    OUT_BATCH(BCS_SWCTRL);
  117.    OUT_BATCH((BCS_SWCTRL_DST_Y | BCS_SWCTRL_SRC_Y) << 16 |
  118.              (dst_y_tiled ? BCS_SWCTRL_DST_Y : 0) |
  119.              (src_y_tiled ? BCS_SWCTRL_SRC_Y : 0));
  120. }
  121.  
  122. #define BEGIN_BATCH_BLT_TILED(n, dst_y_tiled, src_y_tiled) do {         \
  123.       BEGIN_BATCH_BLT(n + ((dst_y_tiled || src_y_tiled) ? 14 : 0));     \
  124.       if (dst_y_tiled || src_y_tiled)                                   \
  125.          set_blitter_tiling(brw, dst_y_tiled, src_y_tiled);             \
  126.    } while (0)
  127.  
  128. #define ADVANCE_BATCH_TILED(dst_y_tiled, src_y_tiled) do {              \
  129.       if (dst_y_tiled || src_y_tiled)                                   \
  130.          set_blitter_tiling(brw, false, false);                         \
  131.       ADVANCE_BATCH();                                                  \
  132.    } while (0)
  133.  
  134. /**
  135.  * Implements a rectangular block transfer (blit) of pixels between two
  136.  * miptrees.
  137.  *
  138.  * Our blitter can operate on 1, 2, or 4-byte-per-pixel data, with generous,
  139.  * but limited, pitches and sizes allowed.
  140.  *
  141.  * The src/dst coordinates are relative to the given level/slice of the
  142.  * miptree.
  143.  *
  144.  * If @src_flip or @dst_flip is set, then the rectangle within that miptree
  145.  * will be inverted (including scanline order) when copying.  This is common
  146.  * in GL when copying between window system and user-created
  147.  * renderbuffers/textures.
  148.  */
  149. bool
  150. intel_miptree_blit(struct brw_context *brw,
  151.                    struct intel_mipmap_tree *src_mt,
  152.                    int src_level, int src_slice,
  153.                    uint32_t src_x, uint32_t src_y, bool src_flip,
  154.                    struct intel_mipmap_tree *dst_mt,
  155.                    int dst_level, int dst_slice,
  156.                    uint32_t dst_x, uint32_t dst_y, bool dst_flip,
  157.                    uint32_t width, uint32_t height,
  158.                    GLenum logicop)
  159. {
  160.    /* No sRGB decode or encode is done by the hardware blitter, which is
  161.     * consistent with what we want in the callers (glCopyTexSubImage(),
  162.     * glBlitFramebuffer(), texture validation, etc.).
  163.     */
  164.    gl_format src_format = _mesa_get_srgb_format_linear(src_mt->format);
  165.    gl_format dst_format = _mesa_get_srgb_format_linear(dst_mt->format);
  166.  
  167.    /* The blitter doesn't support doing any format conversions.  We do also
  168.     * support blitting ARGB8888 to XRGB8888 (trivial, the values dropped into
  169.     * the X channel don't matter), and XRGB8888 to ARGB8888 by setting the A
  170.     * channel to 1.0 at the end.
  171.     */
  172.    if (src_format != dst_format &&
  173.       ((src_format != MESA_FORMAT_ARGB8888 &&
  174.         src_format != MESA_FORMAT_XRGB8888) ||
  175.        (dst_format != MESA_FORMAT_ARGB8888 &&
  176.         dst_format != MESA_FORMAT_XRGB8888))) {
  177.       perf_debug("%s: Can't use hardware blitter from %s to %s, "
  178.                  "falling back.\n", __FUNCTION__,
  179.                  _mesa_get_format_name(src_format),
  180.                  _mesa_get_format_name(dst_format));
  181.       return false;
  182.    }
  183.  
  184.    /* According to the Ivy Bridge PRM, Vol1 Part4, section 1.2.1.2 (Graphics
  185.     * Data Size Limitations):
  186.     *
  187.     *    The BLT engine is capable of transferring very large quantities of
  188.     *    graphics data. Any graphics data read from and written to the
  189.     *    destination is permitted to represent a number of pixels that
  190.     *    occupies up to 65,536 scan lines and up to 32,768 bytes per scan line
  191.     *    at the destination. The maximum number of pixels that may be
  192.     *    represented per scan line’s worth of graphics data depends on the
  193.     *    color depth.
  194.     *
  195.     * Furthermore, intelEmitCopyBlit (which is called below) uses a signed
  196.     * 16-bit integer to represent buffer pitch, so it can only handle buffer
  197.     * pitches < 32k.
  198.     *
  199.     * As a result of these two limitations, we can only use the blitter to do
  200.     * this copy when the region's pitch is less than 32k.
  201.     */
  202.    if (src_mt->region->pitch > 32768 ||
  203.        dst_mt->region->pitch > 32768) {
  204.       perf_debug("Falling back due to >32k pitch\n");
  205.       return false;
  206.    }
  207.  
  208.    /* The blitter has no idea about HiZ or fast color clears, so we need to
  209.     * resolve the miptrees before we do anything.
  210.     */
  211.    intel_miptree_slice_resolve_depth(brw, src_mt, src_level, src_slice);
  212.    intel_miptree_slice_resolve_depth(brw, dst_mt, dst_level, dst_slice);
  213.    intel_miptree_resolve_color(brw, src_mt);
  214.    intel_miptree_resolve_color(brw, dst_mt);
  215.  
  216.    if (src_flip)
  217.       src_y = src_mt->level[src_level].height - src_y - height;
  218.  
  219.    if (dst_flip)
  220.       dst_y = dst_mt->level[dst_level].height - dst_y - height;
  221.  
  222.    int src_pitch = src_mt->region->pitch;
  223.    if (src_flip != dst_flip)
  224.       src_pitch = -src_pitch;
  225.  
  226.    uint32_t src_image_x, src_image_y;
  227.    intel_miptree_get_image_offset(src_mt, src_level, src_slice,
  228.                                   &src_image_x, &src_image_y);
  229.    src_x += src_image_x;
  230.    src_y += src_image_y;
  231.  
  232.    uint32_t dst_image_x, dst_image_y;
  233.    intel_miptree_get_image_offset(dst_mt, dst_level, dst_slice,
  234.                                   &dst_image_x, &dst_image_y);
  235.    dst_x += dst_image_x;
  236.    dst_y += dst_image_y;
  237.  
  238.    if (!intelEmitCopyBlit(brw,
  239.                           src_mt->cpp,
  240.                           src_pitch,
  241.                           src_mt->region->bo, src_mt->offset,
  242.                           src_mt->region->tiling,
  243.                           dst_mt->region->pitch,
  244.                           dst_mt->region->bo, dst_mt->offset,
  245.                           dst_mt->region->tiling,
  246.                           src_x, src_y,
  247.                           dst_x, dst_y,
  248.                           width, height,
  249.                           logicop)) {
  250.       return false;
  251.    }
  252.  
  253.    if (src_mt->format == MESA_FORMAT_XRGB8888 &&
  254.        dst_mt->format == MESA_FORMAT_ARGB8888) {
  255.       intel_miptree_set_alpha_to_one(brw, dst_mt,
  256.                                      dst_x, dst_y,
  257.                                      width, height);
  258.    }
  259.  
  260.    return true;
  261. }
  262.  
  263. /* Copy BitBlt
  264.  */
  265. bool
  266. intelEmitCopyBlit(struct brw_context *brw,
  267.                   GLuint cpp,
  268.                   GLshort src_pitch,
  269.                   drm_intel_bo *src_buffer,
  270.                   GLuint src_offset,
  271.                   uint32_t src_tiling,
  272.                   GLshort dst_pitch,
  273.                   drm_intel_bo *dst_buffer,
  274.                   GLuint dst_offset,
  275.                   uint32_t dst_tiling,
  276.                   GLshort src_x, GLshort src_y,
  277.                   GLshort dst_x, GLshort dst_y,
  278.                   GLshort w, GLshort h,
  279.                   GLenum logic_op)
  280. {
  281.    GLuint CMD, BR13, pass = 0;
  282.    int dst_y2 = dst_y + h;
  283.    int dst_x2 = dst_x + w;
  284.    drm_intel_bo *aper_array[3];
  285.    bool dst_y_tiled = dst_tiling == I915_TILING_Y;
  286.    bool src_y_tiled = src_tiling == I915_TILING_Y;
  287.    BATCH_LOCALS;
  288.  
  289.    if (dst_tiling != I915_TILING_NONE) {
  290.       if (dst_offset & 4095)
  291.          return false;
  292.    }
  293.    if (src_tiling != I915_TILING_NONE) {
  294.       if (src_offset & 4095)
  295.          return false;
  296.    }
  297.    if ((dst_y_tiled || src_y_tiled) && brw->gen < 6)
  298.       return false;
  299.  
  300.    /* do space check before going any further */
  301.    do {
  302.        aper_array[0] = brw->batch.bo;
  303.        aper_array[1] = dst_buffer;
  304.        aper_array[2] = src_buffer;
  305.  
  306.        if (dri_bufmgr_check_aperture_space(aper_array, 3) != 0) {
  307.            intel_batchbuffer_flush(brw);
  308.            pass++;
  309.        } else
  310.            break;
  311.    } while (pass < 2);
  312.  
  313.    if (pass >= 2)
  314.       return false;
  315.  
  316.    intel_batchbuffer_require_space(brw, 8 * 4, true);
  317.    DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
  318.        __FUNCTION__,
  319.        src_buffer, src_pitch, src_offset, src_x, src_y,
  320.        dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h);
  321.  
  322.    /* Blit pitch must be dword-aligned.  Otherwise, the hardware appears to drop
  323.     * the low bits.
  324.     */
  325.    if (src_pitch % 4 != 0 || dst_pitch % 4 != 0)
  326.       return false;
  327.  
  328.    /* For big formats (such as floating point), do the copy using 16 or 32bpp
  329.     * and multiply the coordinates.
  330.     */
  331.    if (cpp > 4) {
  332.       if (cpp % 4 == 2) {
  333.          dst_x *= cpp / 2;
  334.          dst_x2 *= cpp / 2;
  335.          src_x *= cpp / 2;
  336.          cpp = 2;
  337.       } else {
  338.          assert(cpp % 4 == 0);
  339.          dst_x *= cpp / 4;
  340.          dst_x2 *= cpp / 4;
  341.          src_x *= cpp / 4;
  342.          cpp = 4;
  343.       }
  344.    }
  345.  
  346.    BR13 = br13_for_cpp(cpp) | translate_raster_op(logic_op) << 16;
  347.  
  348.    switch (cpp) {
  349.    case 1:
  350.    case 2:
  351.       CMD = XY_SRC_COPY_BLT_CMD;
  352.       break;
  353.    case 4:
  354.       CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
  355.       break;
  356.    default:
  357.       return false;
  358.    }
  359.  
  360.    if (dst_tiling != I915_TILING_NONE) {
  361.       CMD |= XY_DST_TILED;
  362.       dst_pitch /= 4;
  363.    }
  364.    if (src_tiling != I915_TILING_NONE) {
  365.       CMD |= XY_SRC_TILED;
  366.       src_pitch /= 4;
  367.    }
  368.  
  369.    if (dst_y2 <= dst_y || dst_x2 <= dst_x) {
  370.       return true;
  371.    }
  372.  
  373.    assert(dst_x < dst_x2);
  374.    assert(dst_y < dst_y2);
  375.  
  376.    BEGIN_BATCH_BLT_TILED(8, dst_y_tiled, src_y_tiled);
  377.  
  378.    OUT_BATCH(CMD | (8 - 2));
  379.    OUT_BATCH(BR13 | (uint16_t)dst_pitch);
  380.    OUT_BATCH((dst_y << 16) | dst_x);
  381.    OUT_BATCH((dst_y2 << 16) | dst_x2);
  382.    OUT_RELOC_FENCED(dst_buffer,
  383.                     I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
  384.                     dst_offset);
  385.    OUT_BATCH((src_y << 16) | src_x);
  386.    OUT_BATCH((uint16_t)src_pitch);
  387.    OUT_RELOC_FENCED(src_buffer,
  388.                     I915_GEM_DOMAIN_RENDER, 0,
  389.                     src_offset);
  390.  
  391.    ADVANCE_BATCH_TILED(dst_y_tiled, src_y_tiled);
  392.  
  393.    intel_batchbuffer_emit_mi_flush(brw);
  394.  
  395.    return true;
  396. }
  397.  
  398. bool
  399. intelEmitImmediateColorExpandBlit(struct brw_context *brw,
  400.                                   GLuint cpp,
  401.                                   GLubyte *src_bits, GLuint src_size,
  402.                                   GLuint fg_color,
  403.                                   GLshort dst_pitch,
  404.                                   drm_intel_bo *dst_buffer,
  405.                                   GLuint dst_offset,
  406.                                   uint32_t dst_tiling,
  407.                                   GLshort x, GLshort y,
  408.                                   GLshort w, GLshort h,
  409.                                   GLenum logic_op)
  410. {
  411.    int dwords = ALIGN(src_size, 8) / 4;
  412.    uint32_t opcode, br13, blit_cmd;
  413.  
  414.    if (dst_tiling != I915_TILING_NONE) {
  415.       if (dst_offset & 4095)
  416.          return false;
  417.       if (dst_tiling == I915_TILING_Y)
  418.          return false;
  419.    }
  420.  
  421.    assert( logic_op - GL_CLEAR >= 0 );
  422.    assert( logic_op - GL_CLEAR < 0x10 );
  423.    assert(dst_pitch > 0);
  424.  
  425.    if (w < 0 || h < 0)
  426.       return true;
  427.  
  428.    DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d, %d bytes %d dwords\n",
  429.        __FUNCTION__,
  430.        dst_buffer, dst_pitch, dst_offset, x, y, w, h, src_size, dwords);
  431.  
  432.    intel_batchbuffer_require_space(brw, (8 * 4) + (3 * 4) + dwords * 4, true);
  433.  
  434.    opcode = XY_SETUP_BLT_CMD;
  435.    if (cpp == 4)
  436.       opcode |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
  437.    if (dst_tiling != I915_TILING_NONE) {
  438.       opcode |= XY_DST_TILED;
  439.       dst_pitch /= 4;
  440.    }
  441.  
  442.    br13 = dst_pitch | (translate_raster_op(logic_op) << 16) | (1 << 29);
  443.    br13 |= br13_for_cpp(cpp);
  444.  
  445.    blit_cmd = XY_TEXT_IMMEDIATE_BLIT_CMD | XY_TEXT_BYTE_PACKED; /* packing? */
  446.    if (dst_tiling != I915_TILING_NONE)
  447.       blit_cmd |= XY_DST_TILED;
  448.  
  449.    BEGIN_BATCH_BLT(8 + 3);
  450.    OUT_BATCH(opcode | (8 - 2));
  451.    OUT_BATCH(br13);
  452.    OUT_BATCH((0 << 16) | 0); /* clip x1, y1 */
  453.    OUT_BATCH((100 << 16) | 100); /* clip x2, y2 */
  454.    OUT_RELOC_FENCED(dst_buffer,
  455.                     I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
  456.                     dst_offset);
  457.    OUT_BATCH(0); /* bg */
  458.    OUT_BATCH(fg_color); /* fg */
  459.    OUT_BATCH(0); /* pattern base addr */
  460.  
  461.    OUT_BATCH(blit_cmd | ((3 - 2) + dwords));
  462.    OUT_BATCH((y << 16) | x);
  463.    OUT_BATCH(((y + h) << 16) | (x + w));
  464.    ADVANCE_BATCH();
  465.  
  466.    intel_batchbuffer_data(brw, src_bits, dwords * 4, true);
  467.  
  468.    intel_batchbuffer_emit_mi_flush(brw);
  469.  
  470.    return true;
  471. }
  472.  
  473. /* We don't have a memmove-type blit like some other hardware, so we'll do a
  474.  * rectangular blit covering a large space, then emit 1-scanline blit at the
  475.  * end to cover the last if we need.
  476.  */
  477. void
  478. intel_emit_linear_blit(struct brw_context *brw,
  479.                        drm_intel_bo *dst_bo,
  480.                        unsigned int dst_offset,
  481.                        drm_intel_bo *src_bo,
  482.                        unsigned int src_offset,
  483.                        unsigned int size)
  484. {
  485.    struct gl_context *ctx = &brw->ctx;
  486.    GLuint pitch, height;
  487.    bool ok;
  488.  
  489.    /* The pitch given to the GPU must be DWORD aligned, and
  490.     * we want width to match pitch. Max width is (1 << 15 - 1),
  491.     * rounding that down to the nearest DWORD is 1 << 15 - 4
  492.     */
  493.    pitch = ROUND_DOWN_TO(MIN2(size, (1 << 15) - 1), 4);
  494.    height = (pitch == 0) ? 1 : size / pitch;
  495.    ok = intelEmitCopyBlit(brw, 1,
  496.                           pitch, src_bo, src_offset, I915_TILING_NONE,
  497.                           pitch, dst_bo, dst_offset, I915_TILING_NONE,
  498.                           0, 0, /* src x/y */
  499.                           0, 0, /* dst x/y */
  500.                           pitch, height, /* w, h */
  501.                           GL_COPY);
  502.    if (!ok)
  503.       _mesa_problem(ctx, "Failed to linear blit %dx%d\n", pitch, height);
  504.  
  505.    src_offset += pitch * height;
  506.    dst_offset += pitch * height;
  507.    size -= pitch * height;
  508.    assert (size < (1 << 15));
  509.    pitch = ALIGN(size, 4);
  510.    if (size != 0) {
  511.       ok = intelEmitCopyBlit(brw, 1,
  512.                              pitch, src_bo, src_offset, I915_TILING_NONE,
  513.                              pitch, dst_bo, dst_offset, I915_TILING_NONE,
  514.                              0, 0, /* src x/y */
  515.                              0, 0, /* dst x/y */
  516.                              size, 1, /* w, h */
  517.                              GL_COPY);
  518.       if (!ok)
  519.          _mesa_problem(ctx, "Failed to linear blit %dx%d\n", size, 1);
  520.    }
  521. }
  522.  
  523. /**
  524.  * Used to initialize the alpha value of an ARGB8888 miptree after copying
  525.  * into it from an XRGB8888 source.
  526.  *
  527.  * This is very common with glCopyTexImage2D().  Note that the coordinates are
  528.  * relative to the start of the miptree, not relative to a slice within the
  529.  * miptree.
  530.  */
  531. static void
  532. intel_miptree_set_alpha_to_one(struct brw_context *brw,
  533.                               struct intel_mipmap_tree *mt,
  534.                               int x, int y, int width, int height)
  535. {
  536.    struct intel_region *region = mt->region;
  537.    uint32_t BR13, CMD;
  538.    int pitch, cpp;
  539.    drm_intel_bo *aper_array[2];
  540.    BATCH_LOCALS;
  541.  
  542.    pitch = region->pitch;
  543.    cpp = region->cpp;
  544.  
  545.    DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n",
  546.        __FUNCTION__, region->bo, pitch, x, y, width, height);
  547.  
  548.    BR13 = br13_for_cpp(cpp) | 0xf0 << 16;
  549.    CMD = XY_COLOR_BLT_CMD;
  550.    CMD |= XY_BLT_WRITE_ALPHA;
  551.  
  552.    if (region->tiling != I915_TILING_NONE) {
  553.       CMD |= XY_DST_TILED;
  554.       pitch /= 4;
  555.    }
  556.    BR13 |= pitch;
  557.  
  558.    /* do space check before going any further */
  559.    aper_array[0] = brw->batch.bo;
  560.    aper_array[1] = region->bo;
  561.  
  562.    if (drm_intel_bufmgr_check_aperture_space(aper_array,
  563.                                              ARRAY_SIZE(aper_array)) != 0) {
  564.       intel_batchbuffer_flush(brw);
  565.    }
  566.  
  567.    bool dst_y_tiled = region->tiling == I915_TILING_Y;
  568.  
  569.    BEGIN_BATCH_BLT_TILED(6, dst_y_tiled, false);
  570.    OUT_BATCH(CMD | (6 - 2));
  571.    OUT_BATCH(BR13);
  572.    OUT_BATCH((y << 16) | x);
  573.    OUT_BATCH(((y + height) << 16) | (x + width));
  574.    OUT_RELOC_FENCED(region->bo,
  575.                     I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
  576.                     0);
  577.    OUT_BATCH(0xffffffff); /* white, but only alpha gets written */
  578.    ADVANCE_BATCH_TILED(dst_y_tiled, false);
  579.  
  580.    intel_batchbuffer_emit_mi_flush(brw);
  581. }
  582.