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_MI_H
  29. #define ILO_BUILDER_MI_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. static inline void
  39. gen6_MI_STORE_DATA_IMM(struct ilo_builder *builder,
  40.                        struct intel_bo *bo, uint32_t bo_offset,
  41.                        uint64_t val)
  42. {
  43.    const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 6 : 5;
  44.    uint32_t reloc_flags = INTEL_RELOC_WRITE;
  45.    uint32_t *dw;
  46.    unsigned pos;
  47.  
  48.    ILO_DEV_ASSERT(builder->dev, 6, 8);
  49.  
  50.    assert(bo_offset % 8 == 0);
  51.  
  52.    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
  53.  
  54.    dw[0] = GEN6_MI_CMD(MI_STORE_DATA_IMM) | (cmd_len - 2);
  55.    /* must use GGTT on GEN6 as in PIPE_CONTROL */
  56.    if (ilo_dev_gen(builder->dev) == ILO_GEN(6)) {
  57.       dw[0] |= GEN6_MI_STORE_DATA_IMM_DW0_USE_GGTT;
  58.       reloc_flags |= INTEL_RELOC_GGTT;
  59.    }
  60.  
  61.    dw[1] = 0; /* MBZ */
  62.  
  63.    if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
  64.       dw[4] = (uint32_t) val;
  65.       dw[5] = (uint32_t) (val >> 32);
  66.  
  67.       ilo_builder_batch_reloc64(builder, pos + 2, bo, bo_offset, reloc_flags);
  68.    } else {
  69.       dw[3] = (uint32_t) val;
  70.       dw[4] = (uint32_t) (val >> 32);
  71.  
  72.       ilo_builder_batch_reloc(builder, pos + 2, bo, bo_offset, reloc_flags);
  73.    }
  74. }
  75.  
  76. static inline void
  77. gen6_MI_LOAD_REGISTER_IMM(struct ilo_builder *builder,
  78.                           uint32_t reg, uint32_t val)
  79. {
  80.    const uint8_t cmd_len = 3;
  81.    uint32_t *dw;
  82.  
  83.    ILO_DEV_ASSERT(builder->dev, 6, 8);
  84.  
  85.    assert(reg % 4 == 0);
  86.  
  87.    ilo_builder_batch_pointer(builder, cmd_len, &dw);
  88.  
  89.    dw[0] = GEN6_MI_CMD(MI_LOAD_REGISTER_IMM) | (cmd_len - 2);
  90.    dw[1] = reg;
  91.    dw[2] = val;
  92. }
  93.  
  94. static inline void
  95. gen6_MI_STORE_REGISTER_MEM(struct ilo_builder *builder, uint32_t reg,
  96.                            struct intel_bo *bo, uint32_t bo_offset)
  97. {
  98.    const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 4 : 3;
  99.    uint32_t reloc_flags = INTEL_RELOC_WRITE;
  100.    uint32_t *dw;
  101.    unsigned pos;
  102.  
  103.    ILO_DEV_ASSERT(builder->dev, 6, 8);
  104.  
  105.    assert(reg % 4 == 0 && bo_offset % 4 == 0);
  106.  
  107.    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
  108.  
  109.    dw[0] = GEN6_MI_CMD(MI_STORE_REGISTER_MEM) | (cmd_len - 2);
  110.    dw[1] = reg;
  111.  
  112.    if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
  113.       ilo_builder_batch_reloc64(builder, pos + 2, bo, bo_offset, reloc_flags);
  114.    } else {
  115.       /* must use GGTT on Gen6 as in PIPE_CONTROL */
  116.       if (ilo_dev_gen(builder->dev) == ILO_GEN(6)) {
  117.          dw[0] |= GEN6_MI_STORE_REGISTER_MEM_DW0_USE_GGTT;
  118.          reloc_flags |= INTEL_RELOC_GGTT;
  119.       }
  120.  
  121.       ilo_builder_batch_reloc(builder, pos + 2, bo, bo_offset, reloc_flags);
  122.    }
  123. }
  124.  
  125. static inline void
  126. gen6_MI_FLUSH_DW(struct ilo_builder *builder)
  127. {
  128.    const uint8_t cmd_len = 4;
  129.    uint32_t *dw;
  130.  
  131.    ILO_DEV_ASSERT(builder->dev, 6, 8);
  132.  
  133.    ilo_builder_batch_pointer(builder, cmd_len, &dw);
  134.  
  135.    dw[0] = GEN6_MI_CMD(MI_FLUSH_DW) | (cmd_len - 2);
  136.    dw[1] = 0;
  137.    dw[2] = 0;
  138.    dw[3] = 0;
  139. }
  140.  
  141. static inline void
  142. gen6_MI_REPORT_PERF_COUNT(struct ilo_builder *builder,
  143.                           struct intel_bo *bo, uint32_t bo_offset,
  144.                           uint32_t report_id)
  145. {
  146.    const uint8_t cmd_len = 3;
  147.    uint32_t reloc_flags = INTEL_RELOC_WRITE;
  148.    uint32_t *dw;
  149.    unsigned pos;
  150.  
  151.    ILO_DEV_ASSERT(builder->dev, 6, 7.5);
  152.  
  153.    assert(bo_offset % 64 == 0);
  154.  
  155.    /* must use GGTT on GEN6 as in PIPE_CONTROL */
  156.    if (ilo_dev_gen(builder->dev) == ILO_GEN(6)) {
  157.       bo_offset |= GEN6_MI_REPORT_PERF_COUNT_DW1_USE_GGTT;
  158.       reloc_flags |= INTEL_RELOC_GGTT;
  159.    }
  160.  
  161.    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
  162.  
  163.    dw[0] = GEN6_MI_CMD(MI_REPORT_PERF_COUNT) | (cmd_len - 2);
  164.    dw[2] = report_id;
  165.  
  166.    ilo_builder_batch_reloc(builder, pos + 1, bo, bo_offset, reloc_flags);
  167. }
  168.  
  169. static inline void
  170. gen7_MI_LOAD_REGISTER_MEM(struct ilo_builder *builder, uint32_t reg,
  171.                           struct intel_bo *bo, uint32_t bo_offset)
  172. {
  173.    const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 4 : 3;
  174.    uint32_t *dw;
  175.    unsigned pos;
  176.  
  177.    ILO_DEV_ASSERT(builder->dev, 7, 8);
  178.  
  179.    assert(reg % 4 == 0 && bo_offset % 4 == 0);
  180.  
  181.    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
  182.  
  183.    dw[0] = GEN7_MI_CMD(MI_LOAD_REGISTER_MEM) | (cmd_len - 2);
  184.    dw[1] = reg;
  185.  
  186.    if (ilo_dev_gen(builder->dev) >= ILO_GEN(8))
  187.       ilo_builder_batch_reloc64(builder, pos + 2, bo, bo_offset, 0);
  188.    else
  189.       ilo_builder_batch_reloc(builder, pos + 2, bo, bo_offset, 0);
  190. }
  191.  
  192. /**
  193.  * Add a MI_BATCH_BUFFER_END to the batch buffer.  Pad with MI_NOOP if
  194.  * necessary.
  195.  */
  196. static inline void
  197. gen6_mi_batch_buffer_end(struct ilo_builder *builder)
  198. {
  199.    /*
  200.     * From the Sandy Bridge PRM, volume 1 part 1, page 107:
  201.     *
  202.     *     "The batch buffer must be QWord aligned and a multiple of QWords in
  203.     *      length."
  204.     */
  205.    const bool pad = !(builder->writers[ILO_BUILDER_WRITER_BATCH].used & 0x7);
  206.    uint32_t *dw;
  207.  
  208.    ILO_DEV_ASSERT(builder->dev, 6, 8);
  209.  
  210.    if (pad) {
  211.       ilo_builder_batch_pointer(builder, 2, &dw);
  212.       dw[0] = GEN6_MI_CMD(MI_BATCH_BUFFER_END);
  213.       dw[1] = GEN6_MI_CMD(MI_NOOP);
  214.    } else {
  215.       ilo_builder_batch_pointer(builder, 1, &dw);
  216.       dw[0] = GEN6_MI_CMD(MI_BATCH_BUFFER_END);
  217.    }
  218. }
  219.  
  220. #endif /* ILO_BUILDER_MI_H */
  221.