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_RENDER_H
  29. #define ILO_BUILDER_RENDER_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_STATE_SIP(struct ilo_builder *builder, uint32_t sip)
  40. {
  41.    const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 3 : 2;
  42.    uint32_t *dw;
  43.  
  44.    ILO_DEV_ASSERT(builder->dev, 6, 8);
  45.  
  46.    ilo_builder_batch_pointer(builder, cmd_len, &dw);
  47.  
  48.    dw[0] = GEN6_RENDER_CMD(COMMON, STATE_SIP) | (cmd_len - 2);
  49.    dw[1] = sip;
  50.    if (ilo_dev_gen(builder->dev) >= ILO_GEN(8))
  51.       dw[2] = 0;
  52. }
  53.  
  54. static inline void
  55. gen6_PIPELINE_SELECT(struct ilo_builder *builder, int pipeline)
  56. {
  57.    const uint8_t cmd_len = 1;
  58.    const uint32_t dw0 = GEN6_RENDER_CMD(SINGLE_DW, PIPELINE_SELECT) |
  59.                         pipeline;
  60.  
  61.    ILO_DEV_ASSERT(builder->dev, 6, 8);
  62.  
  63.    switch (pipeline) {
  64.    case GEN6_PIPELINE_SELECT_DW0_SELECT_3D:
  65.    case GEN6_PIPELINE_SELECT_DW0_SELECT_MEDIA:
  66.       break;
  67.    case GEN7_PIPELINE_SELECT_DW0_SELECT_GPGPU:
  68.       assert(ilo_dev_gen(builder->dev) >= ILO_GEN(7));
  69.       break;
  70.    default:
  71.       assert(!"unknown pipeline");
  72.       break;
  73.    }
  74.  
  75.    ilo_builder_batch_write(builder, cmd_len, &dw0);
  76. }
  77.  
  78. static inline void
  79. gen6_PIPE_CONTROL(struct ilo_builder *builder, uint32_t dw1,
  80.                   struct intel_bo *bo, uint32_t bo_offset,
  81.                   uint64_t imm)
  82. {
  83.    const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 6 : 5;
  84.    uint32_t reloc_flags = INTEL_RELOC_WRITE;
  85.    uint32_t *dw;
  86.    unsigned pos;
  87.  
  88.    ILO_DEV_ASSERT(builder->dev, 6, 8);
  89.  
  90.    if (dw1 & GEN6_PIPE_CONTROL_CS_STALL) {
  91.       /*
  92.        * From the Sandy Bridge PRM, volume 2 part 1, page 73:
  93.        *
  94.        *     "1 of the following must also be set (when CS stall is set):
  95.        *
  96.        *       * Depth Cache Flush Enable ([0] of DW1)
  97.        *       * Stall at Pixel Scoreboard ([1] of DW1)
  98.        *       * Depth Stall ([13] of DW1)
  99.        *       * Post-Sync Operation ([13] of DW1)
  100.        *       * Render Target Cache Flush Enable ([12] of DW1)
  101.        *       * Notify Enable ([8] of DW1)"
  102.        *
  103.        * From the Ivy Bridge PRM, volume 2 part 1, page 61:
  104.        *
  105.        *     "One of the following must also be set (when CS stall is set):
  106.        *
  107.        *       * Render Target Cache Flush Enable ([12] of DW1)
  108.        *       * Depth Cache Flush Enable ([0] of DW1)
  109.        *       * Stall at Pixel Scoreboard ([1] of DW1)
  110.        *       * Depth Stall ([13] of DW1)
  111.        *       * Post-Sync Operation ([13] of DW1)"
  112.        */
  113.       uint32_t bit_test = GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH |
  114.                           GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH |
  115.                           GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL |
  116.                           GEN6_PIPE_CONTROL_DEPTH_STALL;
  117.  
  118.       /* post-sync op */
  119.       bit_test |= GEN6_PIPE_CONTROL_WRITE_IMM |
  120.                   GEN6_PIPE_CONTROL_WRITE_PS_DEPTH_COUNT |
  121.                   GEN6_PIPE_CONTROL_WRITE_TIMESTAMP;
  122.  
  123.       if (ilo_dev_gen(builder->dev) == ILO_GEN(6))
  124.          bit_test |= GEN6_PIPE_CONTROL_NOTIFY_ENABLE;
  125.  
  126.       assert(dw1 & bit_test);
  127.    }
  128.  
  129.    if (dw1 & GEN6_PIPE_CONTROL_DEPTH_STALL) {
  130.       /*
  131.        * From the Sandy Bridge PRM, volume 2 part 1, page 73:
  132.        *
  133.        *     "Following bits must be clear (when Depth Stall is set):
  134.        *
  135.        *       * Render Target Cache Flush Enable ([12] of DW1)
  136.        *       * Depth Cache Flush Enable ([0] of DW1)"
  137.        */
  138.       assert(!(dw1 & (GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH |
  139.                       GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH)));
  140.    }
  141.  
  142.    switch (dw1 & GEN6_PIPE_CONTROL_WRITE__MASK) {
  143.    case GEN6_PIPE_CONTROL_WRITE_PS_DEPTH_COUNT:
  144.    case GEN6_PIPE_CONTROL_WRITE_TIMESTAMP:
  145.       assert(!imm);
  146.       break;
  147.    default:
  148.       break;
  149.    }
  150.  
  151.    assert(bo_offset % 8 == 0);
  152.  
  153.    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
  154.  
  155.    dw[0] = GEN6_RENDER_CMD(3D, PIPE_CONTROL) | (cmd_len - 2);
  156.    dw[1] = dw1;
  157.  
  158.    if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
  159.       dw[4] = (uint32_t) imm;
  160.       dw[5] = (uint32_t) (imm >> 32);
  161.  
  162.       if (bo) {
  163.          ilo_builder_batch_reloc64(builder, pos + 2,
  164.                bo, bo_offset, reloc_flags);
  165.       } else {
  166.          dw[2] = 0;
  167.          dw[3] = 0;
  168.       }
  169.  
  170.    } else {
  171.       dw[3] = (uint32_t) imm;
  172.       dw[4] = (uint32_t) (imm >> 32);
  173.  
  174.       if (bo) {
  175.          /*
  176.           * From the Sandy Bridge PRM, volume 1 part 3, page 19:
  177.           *
  178.           *     "[DevSNB] PPGTT memory writes by MI_* (such as
  179.           *      MI_STORE_DATA_IMM) and PIPE_CONTROL are not supported."
  180.           */
  181.          if (ilo_dev_gen(builder->dev) == ILO_GEN(6)) {
  182.             bo_offset |= GEN6_PIPE_CONTROL_DW2_USE_GGTT;
  183.             reloc_flags |= INTEL_RELOC_GGTT;
  184.          }
  185.  
  186.          ilo_builder_batch_reloc(builder, pos + 2,
  187.                bo, bo_offset, reloc_flags);
  188.       } else {
  189.          dw[2] = 0;
  190.       }
  191.    }
  192. }
  193.  
  194. static inline void
  195. ilo_builder_batch_patch_sba(struct ilo_builder *builder)
  196. {
  197.    const struct ilo_builder_writer *inst =
  198.       &builder->writers[ILO_BUILDER_WRITER_INSTRUCTION];
  199.  
  200.    if (!builder->sba_instruction_pos)
  201.       return;
  202.  
  203.    if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
  204.       ilo_builder_batch_reloc64(builder, builder->sba_instruction_pos,
  205.             inst->bo,
  206.             builder->mocs << GEN8_SBA_MOCS__SHIFT | GEN6_SBA_ADDR_MODIFIED,
  207.             0);
  208.    } else {
  209.       ilo_builder_batch_reloc(builder, builder->sba_instruction_pos, inst->bo,
  210.             builder->mocs << GEN6_SBA_MOCS__SHIFT | GEN6_SBA_ADDR_MODIFIED,
  211.             0);
  212.    }
  213. }
  214.  
  215. /**
  216.  * Add a STATE_BASE_ADDRESS to the batch buffer.  The relocation entry for the
  217.  * instruction buffer is not added until ilo_builder_end() or next
  218.  * gen6_state_base_address().
  219.  */
  220. static inline void
  221. gen6_state_base_address(struct ilo_builder *builder, bool init_all)
  222. {
  223.    const uint8_t cmd_len = 10;
  224.    const struct ilo_builder_writer *bat =
  225.       &builder->writers[ILO_BUILDER_WRITER_BATCH];
  226.    uint32_t *dw;
  227.    unsigned pos;
  228.  
  229.    ILO_DEV_ASSERT(builder->dev, 6, 7.5);
  230.  
  231.    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
  232.  
  233.    dw[0] = GEN6_RENDER_CMD(COMMON, STATE_BASE_ADDRESS) | (cmd_len - 2);
  234.    dw[1] = builder->mocs << GEN6_SBA_MOCS__SHIFT |
  235.            builder->mocs << GEN6_SBA_DW1_GENERAL_STATELESS_MOCS__SHIFT |
  236.            init_all;
  237.  
  238.    ilo_builder_batch_reloc(builder, pos + 2, bat->bo,
  239.          builder->mocs << GEN6_SBA_MOCS__SHIFT | GEN6_SBA_ADDR_MODIFIED,
  240.          0);
  241.    ilo_builder_batch_reloc(builder, pos + 3, bat->bo,
  242.          builder->mocs << GEN6_SBA_MOCS__SHIFT | GEN6_SBA_ADDR_MODIFIED,
  243.          0);
  244.  
  245.    dw[4] = builder->mocs << GEN6_SBA_MOCS__SHIFT | init_all;
  246.  
  247.    /*
  248.     * Since the instruction writer has WRITER_FLAG_APPEND set, it is tempting
  249.     * not to set Instruction Base Address.  The problem is that we do not know
  250.     * if the bo has been or will be moved by the kernel.  We need a relocation
  251.     * entry because of that.
  252.     *
  253.     * And since we also set WRITER_FLAG_GROW, we have to wait until
  254.     * ilo_builder_end(), when the final bo is known, to add the relocation
  255.     * entry.
  256.     */
  257.    ilo_builder_batch_patch_sba(builder);
  258.    builder->sba_instruction_pos = pos + 5;
  259.  
  260.    /* skip range checks */
  261.    dw[6] = init_all;
  262.    dw[7] = 0xfffff000 + init_all;
  263.    dw[8] = 0xfffff000 + init_all;
  264.    dw[9] = init_all;
  265. }
  266.  
  267. static inline void
  268. gen8_state_base_address(struct ilo_builder *builder, bool init_all)
  269. {
  270.    const uint8_t cmd_len = 16;
  271.    const struct ilo_builder_writer *bat =
  272.       &builder->writers[ILO_BUILDER_WRITER_BATCH];
  273.    uint32_t *dw;
  274.    unsigned pos;
  275.  
  276.    ILO_DEV_ASSERT(builder->dev, 8, 8);
  277.  
  278.    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
  279.  
  280.    dw[0] = GEN6_RENDER_CMD(COMMON, STATE_BASE_ADDRESS) | (cmd_len - 2);
  281.    dw[1] = builder->mocs << GEN8_SBA_MOCS__SHIFT | init_all;
  282.    dw[2] = 0;
  283.    dw[3] = builder->mocs << GEN8_SBA_DW3_STATELESS_MOCS__SHIFT;
  284.    ilo_builder_batch_reloc64(builder, pos + 4, bat->bo,
  285.          builder->mocs << GEN8_SBA_MOCS__SHIFT | GEN6_SBA_ADDR_MODIFIED,
  286.          0);
  287.    ilo_builder_batch_reloc64(builder, pos + 6, bat->bo,
  288.          builder->mocs << GEN8_SBA_MOCS__SHIFT | GEN6_SBA_ADDR_MODIFIED,
  289.          0);
  290.    dw[8] = builder->mocs << GEN8_SBA_MOCS__SHIFT | init_all;
  291.    dw[9] = 0;
  292.  
  293.    ilo_builder_batch_patch_sba(builder);
  294.    builder->sba_instruction_pos = pos + 10;
  295.  
  296.    /* skip range checks */
  297.    dw[12] = 0xfffff000 + init_all;
  298.    dw[13] = 0xfffff000 + init_all;
  299.    dw[14] = 0xfffff000 + init_all;
  300.    dw[15] = 0xfffff000 + init_all;
  301. }
  302.  
  303. #endif /* ILO_BUILDER_RENDER_H */
  304.