Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 2014 LunarG, Inc.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22.  * DEALINGS IN THE SOFTWARE.
  23.  *
  24.  * Authors:
  25.  *    Chia-I Wu <olv@lunarg.com>
  26.  */
  27.  
  28. #ifndef ILO_BUILDER_BLT_H
  29. #define ILO_BUILDER_BLT_H
  30.  
  31. #include "genhw/genhw.h"
  32. #include "intel_winsys.h"
  33.  
  34. #include "ilo_core.h"
  35. #include "ilo_dev.h"
  36. #include "ilo_builder.h"
  37.  
  38. enum gen6_blt_mask {
  39.    GEN6_BLT_MASK_8,
  40.    GEN6_BLT_MASK_16,
  41.    GEN6_BLT_MASK_32,
  42.    GEN6_BLT_MASK_32_LO,
  43.    GEN6_BLT_MASK_32_HI,
  44. };
  45.  
  46. struct gen6_blt_bo {
  47.    struct intel_bo *bo;
  48.    uint32_t offset;
  49.    int16_t pitch;
  50. };
  51.  
  52. struct gen6_blt_xy_bo {
  53.    struct intel_bo *bo;
  54.    uint32_t offset;
  55.    int16_t pitch;
  56.  
  57.    enum gen_surface_tiling tiling;
  58.    int16_t x, y;
  59. };
  60.  
  61. /*
  62.  * From the Sandy Bridge PRM, volume 1 part 5, page 7:
  63.  *
  64.  *     "The BLT engine is capable of transferring very large quantities of
  65.  *      graphics data. Any graphics data read from and written to the
  66.  *      destination is permitted to represent a number of pixels that occupies
  67.  *      up to 65,536 scan lines and up to 32,768 bytes per scan line at the
  68.  *      destination. The maximum number of pixels that may be represented per
  69.  *      scan line's worth of graphics data depends on the color depth."
  70.  */
  71. static const int gen6_blt_max_bytes_per_scanline = 32768;
  72. static const int gen6_blt_max_scanlines = 65536;
  73.  
  74. static inline uint32_t
  75. gen6_blt_translate_value_mask(enum gen6_blt_mask value_mask)
  76. {
  77.    switch (value_mask) {
  78.    case GEN6_BLT_MASK_8:  return GEN6_BLITTER_BR13_FORMAT_8;
  79.    case GEN6_BLT_MASK_16: return GEN6_BLITTER_BR13_FORMAT_565;
  80.    default:               return GEN6_BLITTER_BR13_FORMAT_8888;
  81.    }
  82. }
  83.  
  84. static inline uint32_t
  85. gen6_blt_translate_value_cpp(enum gen6_blt_mask value_mask)
  86. {
  87.    switch (value_mask) {
  88.    case GEN6_BLT_MASK_8:  return 1;
  89.    case GEN6_BLT_MASK_16: return 2;
  90.    default:               return 4;
  91.    }
  92. }
  93.  
  94. static inline uint32_t
  95. gen6_blt_translate_write_mask(enum gen6_blt_mask write_mask)
  96. {
  97.    switch (write_mask) {
  98.    case GEN6_BLT_MASK_32:    return GEN6_BLITTER_BR00_WRITE_RGB |
  99.                                     GEN6_BLITTER_BR00_WRITE_A;
  100.    case GEN6_BLT_MASK_32_LO: return GEN6_BLITTER_BR00_WRITE_RGB;
  101.    case GEN6_BLT_MASK_32_HI: return GEN6_BLITTER_BR00_WRITE_A;
  102.    default:                  return 0;
  103.    }
  104. }
  105.  
  106. static inline void
  107. gen6_COLOR_BLT(struct ilo_builder *builder,
  108.                const struct gen6_blt_bo *dst, uint32_t pattern,
  109.                uint16_t width, uint16_t height, uint8_t rop,
  110.                enum gen6_blt_mask value_mask,
  111.                enum gen6_blt_mask write_mask)
  112. {
  113.    const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 6 : 5;
  114.    const int cpp = gen6_blt_translate_value_cpp(value_mask);
  115.    uint32_t *dw;
  116.    unsigned pos;
  117.  
  118.    ILO_DEV_ASSERT(builder->dev, 6, 8);
  119.  
  120.    assert(width < gen6_blt_max_bytes_per_scanline);
  121.    assert(height < gen6_blt_max_scanlines);
  122.    /* offsets are naturally aligned and pitches are dword-aligned */
  123.    assert(dst->offset % cpp == 0 && dst->pitch % 4 == 0);
  124.  
  125.    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
  126.  
  127.    dw[0] = GEN6_BLITTER_CMD(COLOR_BLT) |
  128.            gen6_blt_translate_write_mask(write_mask) |
  129.            (cmd_len - 2);
  130.    dw[1] = rop << GEN6_BLITTER_BR13_ROP__SHIFT |
  131.            gen6_blt_translate_value_mask(value_mask) |
  132.            dst->pitch;
  133.    dw[2] = height << 16 | width;
  134.  
  135.    if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
  136.       dw[5] = pattern;
  137.  
  138.       ilo_builder_batch_reloc64(builder, pos + 3,
  139.             dst->bo, dst->offset, INTEL_RELOC_WRITE);
  140.    } else {
  141.       dw[4] = pattern;
  142.  
  143.       ilo_builder_batch_reloc(builder, pos + 3,
  144.             dst->bo, dst->offset, INTEL_RELOC_WRITE);
  145.    }
  146. }
  147.  
  148. static inline void
  149. gen6_XY_COLOR_BLT(struct ilo_builder *builder,
  150.                   const struct gen6_blt_xy_bo *dst, uint32_t pattern,
  151.                   uint16_t width, uint16_t height, uint8_t rop,
  152.                   enum gen6_blt_mask value_mask,
  153.                   enum gen6_blt_mask write_mask)
  154. {
  155.    const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 7 : 6;
  156.    const int cpp = gen6_blt_translate_value_cpp(value_mask);
  157.    int dst_align = 4, dst_pitch_shift = 0;
  158.    uint32_t *dw;
  159.    unsigned pos;
  160.  
  161.    ILO_DEV_ASSERT(builder->dev, 6, 8);
  162.  
  163.    assert(width * cpp < gen6_blt_max_bytes_per_scanline);
  164.    assert(height < gen6_blt_max_scanlines);
  165.    /* INT16_MAX */
  166.    assert(dst->x + width <= 32767 && dst->y + height <= 32767);
  167.  
  168.    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
  169.  
  170.    dw[0] = GEN6_BLITTER_CMD(XY_COLOR_BLT) |
  171.            gen6_blt_translate_write_mask(write_mask) |
  172.            (cmd_len - 2);
  173.  
  174.    if (dst->tiling != GEN6_TILING_NONE) {
  175.       dw[0] |= GEN6_BLITTER_BR00_DST_TILED;
  176.  
  177.       assert(dst->tiling == GEN6_TILING_X || dst->tiling == GEN6_TILING_Y);
  178.       dst_align = (dst->tiling == GEN6_TILING_Y) ? 128 : 512;
  179.       /* in dwords when tiled */
  180.       dst_pitch_shift = 2;
  181.    }
  182.  
  183.    assert(dst->offset % dst_align == 0 && dst->pitch % dst_align == 0);
  184.  
  185.    dw[1] = rop << GEN6_BLITTER_BR13_ROP__SHIFT |
  186.            gen6_blt_translate_value_mask(value_mask) |
  187.            dst->pitch >> dst_pitch_shift;
  188.    dw[2] = dst->y << 16 | dst->x;
  189.    dw[3] = (dst->y + height) << 16 | (dst->x + width);
  190.  
  191.    if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
  192.       dw[6] = pattern;
  193.  
  194.       ilo_builder_batch_reloc64(builder, pos + 4,
  195.             dst->bo, dst->offset, INTEL_RELOC_WRITE);
  196.    } else {
  197.       dw[5] = pattern;
  198.  
  199.       ilo_builder_batch_reloc(builder, pos + 4,
  200.             dst->bo, dst->offset, INTEL_RELOC_WRITE);
  201.    }
  202. }
  203.  
  204. static inline void
  205. gen6_SRC_COPY_BLT(struct ilo_builder *builder,
  206.                   const struct gen6_blt_bo *dst,
  207.                   const struct gen6_blt_bo *src,
  208.                   uint16_t width, uint16_t height, uint8_t rop,
  209.                   enum gen6_blt_mask value_mask,
  210.                   enum gen6_blt_mask write_mask)
  211. {
  212.    const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 8 : 6;
  213.    const int cpp = gen6_blt_translate_value_cpp(value_mask);
  214.    uint32_t *dw;
  215.    unsigned pos;
  216.  
  217.    ILO_DEV_ASSERT(builder->dev, 6, 8);
  218.  
  219.    assert(width < gen6_blt_max_bytes_per_scanline);
  220.    assert(height < gen6_blt_max_scanlines);
  221.    /* offsets are naturally aligned and pitches are dword-aligned */
  222.    assert(dst->offset % cpp == 0 && dst->pitch % 4 == 0);
  223.    assert(src->offset % cpp == 0 && src->pitch % 4 == 0);
  224.  
  225.    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
  226.  
  227.    dw[0] = GEN6_BLITTER_CMD(SRC_COPY_BLT) |
  228.            gen6_blt_translate_write_mask(write_mask) |
  229.            (cmd_len - 2);
  230.    dw[1] = rop << GEN6_BLITTER_BR13_ROP__SHIFT |
  231.            gen6_blt_translate_value_mask(value_mask) |
  232.            dst->pitch;
  233.    dw[2] = height << 16 | width;
  234.  
  235.    if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
  236.       dw[5] = src->pitch;
  237.  
  238.       ilo_builder_batch_reloc64(builder, pos + 3,
  239.             dst->bo, dst->offset, INTEL_RELOC_WRITE);
  240.       ilo_builder_batch_reloc64(builder, pos + 6, src->bo, src->offset, 0);
  241.    } else {
  242.       dw[4] = src->pitch;
  243.  
  244.       ilo_builder_batch_reloc(builder, pos + 3,
  245.             dst->bo, dst->offset, INTEL_RELOC_WRITE);
  246.       ilo_builder_batch_reloc(builder, pos + 5, src->bo, src->offset, 0);
  247.    }
  248. }
  249.  
  250. static inline void
  251. gen6_XY_SRC_COPY_BLT(struct ilo_builder *builder,
  252.                      const struct gen6_blt_xy_bo *dst,
  253.                      const struct gen6_blt_xy_bo *src,
  254.                      uint16_t width, uint16_t height, uint8_t rop,
  255.                      enum gen6_blt_mask value_mask,
  256.                      enum gen6_blt_mask write_mask)
  257. {
  258.    const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 10 : 8;
  259.    const int cpp = gen6_blt_translate_value_cpp(value_mask);
  260.    int dst_align = 4, dst_pitch_shift = 0;
  261.    int src_align = 4, src_pitch_shift = 0;
  262.    uint32_t *dw;
  263.    unsigned pos;
  264.  
  265.    ILO_DEV_ASSERT(builder->dev, 6, 8);
  266.  
  267.    assert(width * cpp < gen6_blt_max_bytes_per_scanline);
  268.    assert(height < gen6_blt_max_scanlines);
  269.    /* INT16_MAX */
  270.    assert(dst->x + width <= 32767 && dst->y + height <= 32767);
  271.  
  272.    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
  273.  
  274.    dw[0] = GEN6_BLITTER_CMD(XY_SRC_COPY_BLT) |
  275.            gen6_blt_translate_write_mask(write_mask) |
  276.            (cmd_len - 2);
  277.  
  278.    if (dst->tiling != GEN6_TILING_NONE) {
  279.       dw[0] |= GEN6_BLITTER_BR00_DST_TILED;
  280.  
  281.       assert(dst->tiling == GEN6_TILING_X || dst->tiling == GEN6_TILING_Y);
  282.       dst_align = (dst->tiling == GEN6_TILING_Y) ? 128 : 512;
  283.       /* in dwords when tiled */
  284.       dst_pitch_shift = 2;
  285.    }
  286.  
  287.    if (src->tiling != GEN6_TILING_NONE) {
  288.       dw[0] |= GEN6_BLITTER_BR00_SRC_TILED;
  289.  
  290.       assert(src->tiling == GEN6_TILING_X || src->tiling == GEN6_TILING_Y);
  291.       src_align = (src->tiling == GEN6_TILING_Y) ? 128 : 512;
  292.       /* in dwords when tiled */
  293.       src_pitch_shift = 2;
  294.    }
  295.  
  296.    assert(dst->offset % dst_align == 0 && dst->pitch % dst_align == 0);
  297.    assert(src->offset % src_align == 0 && src->pitch % src_align == 0);
  298.  
  299.    dw[1] = rop << GEN6_BLITTER_BR13_ROP__SHIFT |
  300.            gen6_blt_translate_value_mask(value_mask) |
  301.            dst->pitch >> dst_pitch_shift;
  302.    dw[2] = dst->y << 16 | dst->x;
  303.    dw[3] = (dst->y + height) << 16 | (dst->x + width);
  304.  
  305.    if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
  306.       dw[6] = src->y << 16 | src->x;
  307.       dw[7] = src->pitch >> src_pitch_shift;
  308.  
  309.       ilo_builder_batch_reloc64(builder, pos + 4,
  310.             dst->bo, dst->offset, INTEL_RELOC_WRITE);
  311.       ilo_builder_batch_reloc64(builder, pos + 8, src->bo, src->offset, 0);
  312.    } else {
  313.       dw[5] = src->y << 16 | src->x;
  314.       dw[6] = src->pitch >> src_pitch_shift;
  315.  
  316.       ilo_builder_batch_reloc(builder, pos + 4,
  317.             dst->bo, dst->offset, INTEL_RELOC_WRITE);
  318.       ilo_builder_batch_reloc(builder, pos + 7, src->bo, src->offset, 0);
  319.    }
  320. }
  321.  
  322. #endif /* ILO_BUILDER_BLT_H */
  323.