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