• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
gen6_MI_STORE_DATA_IMM(struct ilo_builder * builder,struct intel_bo * bo,uint32_t bo_offset,uint64_t val)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
gen6_MI_LOAD_REGISTER_IMM(struct ilo_builder * builder,uint32_t reg,uint32_t val)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
gen6_MI_STORE_REGISTER_MEM(struct ilo_builder * builder,uint32_t reg,struct intel_bo * bo,uint32_t bo_offset)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
gen6_MI_FLUSH_DW(struct ilo_builder * builder)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
gen6_MI_REPORT_PERF_COUNT(struct ilo_builder * builder,struct intel_bo * bo,uint32_t bo_offset,uint32_t report_id)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
gen7_MI_LOAD_REGISTER_MEM(struct ilo_builder * builder,uint32_t reg,struct intel_bo * bo,uint32_t bo_offset)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
gen6_mi_batch_buffer_end(struct ilo_builder * builder)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