blob: 50f6c534c53426a46c118b85105085869953cd28 [file] [log] [blame]
Chia-I Wub2755562014-08-20 13:38:52 +08001/*
2 * XGL
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.
Chia-I Wu44e42362014-09-02 08:32:09 +080023 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
26 * Courtney Goeltzenleuchter <courtney@lunarg.com>
Chia-I Wub2755562014-08-20 13:38:52 +080027 */
28
Chia-I Wu9f039862014-08-20 15:39:56 +080029#include "genhw/genhw.h"
Chia-I Wub2755562014-08-20 13:38:52 +080030#include "dset.h"
Chia-I Wu7fae4e32014-08-21 11:39:44 +080031#include "img.h"
Chia-I Wub2755562014-08-20 13:38:52 +080032#include "mem.h"
Chia-I Wu018a3962014-08-21 10:37:52 +080033#include "pipeline.h"
Chia-I Wu1f2fd292014-08-29 15:07:09 +080034#include "shader.h"
Chia-I Wub2755562014-08-20 13:38:52 +080035#include "state.h"
36#include "view.h"
37#include "cmd_priv.h"
38
Chia-I Wu59c097e2014-08-21 10:51:07 +080039static void gen6_3DPRIMITIVE(struct intel_cmd *cmd,
Chia-I Wu254db422014-08-21 11:54:29 +080040 int prim_type, bool indexed,
Chia-I Wu59c097e2014-08-21 10:51:07 +080041 uint32_t vertex_count,
42 uint32_t vertex_start,
43 uint32_t instance_count,
44 uint32_t instance_start,
45 uint32_t vertex_base)
46{
47 const uint8_t cmd_len = 6;
48 uint32_t dw0;
49
50 CMD_ASSERT(cmd, 6, 6);
51
Chia-I Wu426072d2014-08-26 14:31:55 +080052 dw0 = GEN6_RENDER_CMD(3D, 3DPRIMITIVE) |
Chia-I Wu254db422014-08-21 11:54:29 +080053 prim_type << GEN6_3DPRIM_DW0_TYPE__SHIFT |
Chia-I Wu59c097e2014-08-21 10:51:07 +080054 (cmd_len - 2);
55
56 if (indexed)
57 dw0 |= GEN6_3DPRIM_DW0_ACCESS_RANDOM;
58
Chia-I Wue24c3292014-08-21 14:05:23 +080059 cmd_batch_reserve(cmd, cmd_len);
60 cmd_batch_write(cmd, dw0);
61 cmd_batch_write(cmd, vertex_count);
62 cmd_batch_write(cmd, vertex_start);
63 cmd_batch_write(cmd, instance_count);
64 cmd_batch_write(cmd, instance_start);
65 cmd_batch_write(cmd, vertex_base);
Chia-I Wu59c097e2014-08-21 10:51:07 +080066}
67
68static void gen7_3DPRIMITIVE(struct intel_cmd *cmd,
Chia-I Wu254db422014-08-21 11:54:29 +080069 int prim_type, bool indexed,
Chia-I Wu59c097e2014-08-21 10:51:07 +080070 uint32_t vertex_count,
71 uint32_t vertex_start,
72 uint32_t instance_count,
73 uint32_t instance_start,
74 uint32_t vertex_base)
75{
76 const uint8_t cmd_len = 7;
77 uint32_t dw0, dw1;
78
79 CMD_ASSERT(cmd, 7, 7.5);
80
Chia-I Wu426072d2014-08-26 14:31:55 +080081 dw0 = GEN6_RENDER_CMD(3D, 3DPRIMITIVE) | (cmd_len - 2);
Chia-I Wu254db422014-08-21 11:54:29 +080082 dw1 = prim_type << GEN7_3DPRIM_DW1_TYPE__SHIFT;
Chia-I Wu59c097e2014-08-21 10:51:07 +080083
84 if (indexed)
85 dw1 |= GEN7_3DPRIM_DW1_ACCESS_RANDOM;
86
Chia-I Wue24c3292014-08-21 14:05:23 +080087 cmd_batch_reserve(cmd, cmd_len);
88 cmd_batch_write(cmd, dw0);
89 cmd_batch_write(cmd, dw1);
90 cmd_batch_write(cmd, vertex_count);
91 cmd_batch_write(cmd, vertex_start);
92 cmd_batch_write(cmd, instance_count);
93 cmd_batch_write(cmd, instance_start);
94 cmd_batch_write(cmd, vertex_base);
Chia-I Wu59c097e2014-08-21 10:51:07 +080095}
96
Chia-I Wu270b1e82014-08-25 15:53:39 +080097static void gen6_PIPE_CONTROL(struct intel_cmd *cmd, uint32_t dw1,
Chia-I Wud6d079d2014-08-31 13:14:21 +080098 struct intel_bo *bo, uint32_t bo_offset,
99 uint64_t imm)
Chia-I Wu270b1e82014-08-25 15:53:39 +0800100{
101 const uint8_t cmd_len = 5;
Chia-I Wu426072d2014-08-26 14:31:55 +0800102 const uint32_t dw0 = GEN6_RENDER_CMD(3D, PIPE_CONTROL) |
Chia-I Wu270b1e82014-08-25 15:53:39 +0800103 (cmd_len - 2);
Chia-I Wu2caf7492014-08-31 12:28:38 +0800104 uint32_t reloc_flags = INTEL_RELOC_WRITE;
Chia-I Wu270b1e82014-08-25 15:53:39 +0800105
106 CMD_ASSERT(cmd, 6, 7.5);
107
108 assert(bo_offset % 8 == 0);
109
110 if (dw1 & GEN6_PIPE_CONTROL_CS_STALL) {
111 /*
112 * From the Sandy Bridge PRM, volume 2 part 1, page 73:
113 *
114 * "1 of the following must also be set (when CS stall is set):
115 *
116 * * Depth Cache Flush Enable ([0] of DW1)
117 * * Stall at Pixel Scoreboard ([1] of DW1)
118 * * Depth Stall ([13] of DW1)
119 * * Post-Sync Operation ([13] of DW1)
120 * * Render Target Cache Flush Enable ([12] of DW1)
121 * * Notify Enable ([8] of DW1)"
122 *
123 * From the Ivy Bridge PRM, volume 2 part 1, page 61:
124 *
125 * "One of the following must also be set (when CS stall is set):
126 *
127 * * Render Target Cache Flush Enable ([12] of DW1)
128 * * Depth Cache Flush Enable ([0] of DW1)
129 * * Stall at Pixel Scoreboard ([1] of DW1)
130 * * Depth Stall ([13] of DW1)
131 * * Post-Sync Operation ([13] of DW1)"
132 */
133 uint32_t bit_test = GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH |
134 GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH |
135 GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL |
136 GEN6_PIPE_CONTROL_DEPTH_STALL;
137
138 /* post-sync op */
139 bit_test |= GEN6_PIPE_CONTROL_WRITE_IMM |
140 GEN6_PIPE_CONTROL_WRITE_PS_DEPTH_COUNT |
141 GEN6_PIPE_CONTROL_WRITE_TIMESTAMP;
142
143 if (cmd_gen(cmd) == INTEL_GEN(6))
144 bit_test |= GEN6_PIPE_CONTROL_NOTIFY_ENABLE;
145
146 assert(dw1 & bit_test);
147 }
148
149 if (dw1 & GEN6_PIPE_CONTROL_DEPTH_STALL) {
150 /*
151 * From the Sandy Bridge PRM, volume 2 part 1, page 73:
152 *
153 * "Following bits must be clear (when Depth Stall is set):
154 *
155 * * Render Target Cache Flush Enable ([12] of DW1)
156 * * Depth Cache Flush Enable ([0] of DW1)"
157 */
158 assert(!(dw1 & (GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH |
159 GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH)));
160 }
161
162 /*
163 * From the Sandy Bridge PRM, volume 1 part 3, page 19:
164 *
165 * "[DevSNB] PPGTT memory writes by MI_* (such as MI_STORE_DATA_IMM)
166 * and PIPE_CONTROL are not supported."
167 *
168 * The kernel will add the mapping automatically (when write domain is
169 * INTEL_DOMAIN_INSTRUCTION).
170 */
Chia-I Wu2caf7492014-08-31 12:28:38 +0800171 if (cmd_gen(cmd) == INTEL_GEN(6) && bo) {
Chia-I Wu270b1e82014-08-25 15:53:39 +0800172 bo_offset |= GEN6_PIPE_CONTROL_DW2_USE_GGTT;
Chia-I Wu2caf7492014-08-31 12:28:38 +0800173 reloc_flags |= INTEL_RELOC_GGTT;
174 }
Chia-I Wu270b1e82014-08-25 15:53:39 +0800175
176 cmd_batch_reserve_reloc(cmd, cmd_len, (bool) bo);
177 cmd_batch_write(cmd, dw0);
178 cmd_batch_write(cmd, dw1);
Chia-I Wu2caf7492014-08-31 12:28:38 +0800179 if (bo)
180 cmd_batch_reloc(cmd, bo_offset, bo, reloc_flags);
181 else
Chia-I Wu270b1e82014-08-25 15:53:39 +0800182 cmd_batch_write(cmd, 0);
Chia-I Wud6d079d2014-08-31 13:14:21 +0800183 cmd_batch_write(cmd, (uint32_t) imm);
184 cmd_batch_write(cmd, (uint32_t) (imm >> 32));
Chia-I Wu270b1e82014-08-25 15:53:39 +0800185}
186
Chia-I Wu254db422014-08-21 11:54:29 +0800187static bool gen6_can_primitive_restart(const struct intel_cmd *cmd)
188{
189 const struct intel_pipeline *p = cmd->bind.pipeline.graphics;
190 bool supported;
191
192 CMD_ASSERT(cmd, 6, 7.5);
193
194 if (cmd_gen(cmd) >= INTEL_GEN(7.5))
195 return (p->prim_type != GEN6_3DPRIM_RECTLIST);
196
197 switch (p->prim_type) {
198 case GEN6_3DPRIM_POINTLIST:
199 case GEN6_3DPRIM_LINELIST:
200 case GEN6_3DPRIM_LINESTRIP:
201 case GEN6_3DPRIM_TRILIST:
202 case GEN6_3DPRIM_TRISTRIP:
203 supported = true;
204 break;
205 default:
206 supported = false;
207 break;
208 }
209
210 if (!supported)
211 return false;
212
213 switch (cmd->bind.index.type) {
214 case XGL_INDEX_8:
215 supported = (p->primitive_restart_index != 0xffu);
216 break;
217 case XGL_INDEX_16:
218 supported = (p->primitive_restart_index != 0xffffu);
219 break;
220 case XGL_INDEX_32:
221 supported = (p->primitive_restart_index != 0xffffffffu);
222 break;
223 default:
224 supported = false;
225 break;
226 }
227
228 return supported;
229}
230
Chia-I Wu59c097e2014-08-21 10:51:07 +0800231static void gen6_3DSTATE_INDEX_BUFFER(struct intel_cmd *cmd,
Chia-I Wu958d1b72014-08-21 11:28:11 +0800232 const struct intel_mem *mem,
Chia-I Wu59c097e2014-08-21 10:51:07 +0800233 XGL_GPU_SIZE offset,
234 XGL_INDEX_TYPE type,
235 bool enable_cut_index)
236{
237 const uint8_t cmd_len = 3;
238 uint32_t dw0, end_offset;
239 unsigned offset_align;
240
241 CMD_ASSERT(cmd, 6, 7.5);
242
Chia-I Wu426072d2014-08-26 14:31:55 +0800243 dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_INDEX_BUFFER) | (cmd_len - 2);
Chia-I Wu59c097e2014-08-21 10:51:07 +0800244
245 /* the bit is moved to 3DSTATE_VF */
246 if (cmd_gen(cmd) >= INTEL_GEN(7.5))
247 assert(!enable_cut_index);
248 if (enable_cut_index)
249 dw0 |= GEN6_IB_DW0_CUT_INDEX_ENABLE;
250
251 switch (type) {
252 case XGL_INDEX_8:
253 dw0 |= GEN6_IB_DW0_FORMAT_BYTE;
254 offset_align = 1;
255 break;
256 case XGL_INDEX_16:
257 dw0 |= GEN6_IB_DW0_FORMAT_WORD;
258 offset_align = 2;
259 break;
260 case XGL_INDEX_32:
261 dw0 |= GEN6_IB_DW0_FORMAT_DWORD;
262 offset_align = 4;
263 break;
264 default:
265 cmd->result = XGL_ERROR_INVALID_VALUE;
266 return;
267 break;
268 }
269
270 if (offset % offset_align) {
271 cmd->result = XGL_ERROR_INVALID_VALUE;
272 return;
273 }
274
275 /* aligned and inclusive */
276 end_offset = mem->size - (mem->size % offset_align) - 1;
277
Chia-I Wu2de65d02014-08-25 10:02:53 +0800278 cmd_batch_reserve_reloc(cmd, cmd_len, 2);
Chia-I Wue24c3292014-08-21 14:05:23 +0800279 cmd_batch_write(cmd, dw0);
Chia-I Wu32a22462014-08-26 14:13:46 +0800280 cmd_batch_reloc(cmd, offset, mem->bo, 0);
281 cmd_batch_reloc(cmd, end_offset, mem->bo, 0);
Chia-I Wu59c097e2014-08-21 10:51:07 +0800282}
283
Chia-I Wu62a7f252014-08-29 11:31:16 +0800284static void gen75_3DSTATE_VF(struct intel_cmd *cmd,
285 bool enable_cut_index,
286 uint32_t cut_index)
Chia-I Wu254db422014-08-21 11:54:29 +0800287{
288 const uint8_t cmd_len = 2;
289 uint32_t dw0;
290
291 CMD_ASSERT(cmd, 7.5, 7.5);
292
Chia-I Wu426072d2014-08-26 14:31:55 +0800293 dw0 = GEN75_RENDER_CMD(3D, 3DSTATE_VF) | (cmd_len - 2);
Chia-I Wu254db422014-08-21 11:54:29 +0800294 if (enable_cut_index)
295 dw0 |= GEN75_VF_DW0_CUT_INDEX_ENABLE;
296
Chia-I Wue24c3292014-08-21 14:05:23 +0800297 cmd_batch_reserve(cmd, cmd_len);
298 cmd_batch_write(cmd, dw0);
299 cmd_batch_write(cmd, cut_index);
Chia-I Wu254db422014-08-21 11:54:29 +0800300}
301
Courtney Goeltzenleuchter3d72e8c2014-08-29 16:27:47 -0600302
Chia-I Wud95aa2b2014-08-29 12:07:47 +0800303static void gen6_3DSTATE_GS(struct intel_cmd *cmd)
304{
305 const uint8_t cmd_len = 7;
306 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
307
308 CMD_ASSERT(cmd, 6, 6);
309
310 assert(cmd->bind.gs.shader == NULL);
311
312 cmd_batch_reserve(cmd, cmd_len);
313 cmd_batch_write(cmd, dw0);
314 cmd_batch_write(cmd, 0);
315 cmd_batch_write(cmd, 0);
316 cmd_batch_write(cmd, 0);
317 cmd_batch_write(cmd, 1 << GEN6_GS_DW4_URB_READ_LEN__SHIFT);
318 cmd_batch_write(cmd, GEN6_GS_DW5_STATISTICS);
319 cmd_batch_write(cmd, 0);
320}
321
Chia-I Wu62a7f252014-08-29 11:31:16 +0800322static void gen7_3DSTATE_GS(struct intel_cmd *cmd)
323{
324 const uint8_t cmd_len = 7;
325 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
326
327 CMD_ASSERT(cmd, 7, 7.5);
328
329 assert(cmd->bind.gs.shader == NULL);
330
331 cmd_batch_reserve(cmd, cmd_len);
332 cmd_batch_write(cmd, dw0);
333 cmd_batch_write(cmd, 0);
334 cmd_batch_write(cmd, 0);
335 cmd_batch_write(cmd, 0);
336 cmd_batch_write(cmd, 0);
337 cmd_batch_write(cmd, GEN6_GS_DW5_STATISTICS);
338 cmd_batch_write(cmd, 0);
339}
340
Chia-I Wud88e02d2014-08-25 10:56:13 +0800341static void gen6_3DSTATE_DRAWING_RECTANGLE(struct intel_cmd *cmd,
342 XGL_UINT width, XGL_UINT height)
343{
344 const uint8_t cmd_len = 4;
Chia-I Wu426072d2014-08-26 14:31:55 +0800345 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_DRAWING_RECTANGLE) |
Chia-I Wud88e02d2014-08-25 10:56:13 +0800346 (cmd_len - 2);
347
348 CMD_ASSERT(cmd, 6, 7.5);
349
350 cmd_batch_reserve(cmd, cmd_len);
351 cmd_batch_write(cmd, dw0);
352 if (width && height) {
353 cmd_batch_write(cmd, 0);
354 cmd_batch_write(cmd, (height - 1) << 16 |
355 (width - 1));
356 } else {
357 cmd_batch_write(cmd, 1);
358 cmd_batch_write(cmd, 0);
359 }
360 cmd_batch_write(cmd, 0);
361}
362
Chia-I Wu8016a172014-08-29 18:31:32 +0800363static void gen7_fill_3DSTATE_SF_body(const struct intel_cmd *cmd,
364 uint32_t body[6])
365{
366 const struct intel_pipeline *pipeline = cmd->bind.pipeline.graphics;
367 const struct intel_viewport_state *viewport = cmd->bind.state.viewport;
368 const struct intel_raster_state *raster = cmd->bind.state.raster;
369 const struct intel_msaa_state *msaa = cmd->bind.state.msaa;
370 uint32_t dw1, dw2, dw3;
371 int point_width;
372
373 CMD_ASSERT(cmd, 6, 7.5);
374
375 dw1 = GEN7_SF_DW1_STATISTICS |
376 GEN7_SF_DW1_DEPTH_OFFSET_SOLID |
377 GEN7_SF_DW1_DEPTH_OFFSET_WIREFRAME |
378 GEN7_SF_DW1_DEPTH_OFFSET_POINT |
379 GEN7_SF_DW1_VIEWPORT_ENABLE |
380 raster->cmd_sf_fill;
381
382 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
383 int format;
384
385 switch (pipeline->db_format.channelFormat) {
386 case XGL_CH_FMT_R16:
387 format = GEN6_ZFORMAT_D16_UNORM;
388 break;
389 case XGL_CH_FMT_R32:
390 case XGL_CH_FMT_R32G8:
391 format = GEN6_ZFORMAT_D32_FLOAT;
392 break;
393 default:
394 assert(!"unknown depth format");
395 format = 0;
396 break;
397 }
398
399 dw1 |= format << GEN7_SF_DW1_DEPTH_FORMAT__SHIFT;
400 }
401
402 dw2 = raster->cmd_sf_cull;
403
404 if (msaa->sample_count > 1) {
405 dw2 |= 128 << GEN7_SF_DW2_LINE_WIDTH__SHIFT |
406 GEN7_SF_DW2_MSRASTMODE_ON_PATTERN;
407 } else {
408 dw2 |= 0 << GEN7_SF_DW2_LINE_WIDTH__SHIFT |
409 GEN7_SF_DW2_MSRASTMODE_OFF_PIXEL;
410 }
411
412 if (viewport->scissor_enable)
413 dw2 |= GEN7_SF_DW2_SCISSOR_ENABLE;
414
415 /* in U8.3 */
416 point_width = (int) (pipeline->pointSize * 8.0f + 0.5f);
417 point_width = U_CLAMP(point_width, 1, 2047);
418
419 dw3 = pipeline->provoking_vertex_tri << GEN7_SF_DW3_TRI_PROVOKE__SHIFT |
420 pipeline->provoking_vertex_line << GEN7_SF_DW3_LINE_PROVOKE__SHIFT |
421 pipeline->provoking_vertex_trifan << GEN7_SF_DW3_TRIFAN_PROVOKE__SHIFT |
422 GEN7_SF_DW3_SUBPIXEL_8BITS |
423 GEN7_SF_DW3_USE_POINT_WIDTH |
424 point_width;
425
426 body[0] = dw1;
427 body[1] = dw2;
428 body[2] = dw3;
429 body[3] = raster->cmd_depth_offset_const;
430 body[4] = raster->cmd_depth_offset_scale;
431 body[5] = raster->cmd_depth_offset_clamp;
432}
433
434static void gen7_fill_3DSTATE_SBE_body(const struct intel_cmd *cmd,
435 uint32_t body[13])
436{
Chia-I Wuf2b6d722014-09-02 08:52:27 +0800437 const struct intel_pipeline_shader *vs = &cmd->bind.pipeline.graphics->vs;
438 const struct intel_pipeline_shader *fs = &cmd->bind.pipeline.graphics->fs;
Chia-I Wu8016a172014-08-29 18:31:32 +0800439 XGL_UINT attr_skip, attr_count;
440 XGL_UINT vue_offset, vue_len;
441 XGL_UINT i;
442 uint32_t dw1;
443
444 CMD_ASSERT(cmd, 6, 7.5);
445
446 /* VS outputs VUE header and position additionally */
447 assert(vs->out_count >= 2);
448 attr_skip = 2;
449 attr_count = vs->out_count - attr_skip;
450 assert(fs->in_count == attr_count);
451 assert(fs->in_count <= 32);
452
453 vue_offset = attr_skip / 2;
454 vue_len = (attr_count + 1) / 2;
455 if (!vue_len)
456 vue_len = 1;
457
458 dw1 = fs->in_count << GEN7_SBE_DW1_ATTR_COUNT__SHIFT |
459 vue_len << GEN7_SBE_DW1_URB_READ_LEN__SHIFT |
460 vue_offset << GEN7_SBE_DW1_URB_READ_OFFSET__SHIFT;
461
462 body[0] = dw1;
463
464 for (i = 0; i < 8; i++) {
465 uint16_t hi, lo;
466
467 /* no attr swizzles */
468 if (i * 2 + 1 < fs->in_count) {
469 hi = i * 2 + 1;
470 lo = i * 2;
471 } else if (i * 2 < fs->in_count) {
472 hi = 0;
473 lo = i * 2;
474 } else {
475 hi = 0;
476 lo = 0;
477 }
478
479 body[1 + i] = hi << GEN7_SBE_ATTR_HIGH__SHIFT | lo;
480 }
481
482 body[9] = 0; /* point sprite enables */
483 body[10] = 0; /* constant interpolation enables */
484 body[11] = 0; /* WrapShortest enables */
485 body[12] = 0;
486}
487
488static void gen6_3DSTATE_SF(struct intel_cmd *cmd)
489{
490 const uint8_t cmd_len = 20;
491 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_SF) |
492 (cmd_len - 2);
493 uint32_t sf[6];
494 uint32_t sbe[13];
495
496 CMD_ASSERT(cmd, 6, 6);
497
498 gen7_fill_3DSTATE_SF_body(cmd, sf);
499 gen7_fill_3DSTATE_SBE_body(cmd, sbe);
500
501 cmd_batch_reserve(cmd, cmd_len);
502 cmd_batch_write(cmd, dw0);
503 cmd_batch_write(cmd, sbe[0]);
504 cmd_batch_write_n(cmd, sf, 6);
505 cmd_batch_write_n(cmd, &sbe[1], 12);
506}
507
508static void gen7_3DSTATE_SF(struct intel_cmd *cmd)
509{
510 const uint8_t cmd_len = 7;
511 uint32_t dw[7];
512
513 CMD_ASSERT(cmd, 7, 7.5);
514
515 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SF) |
516 (cmd_len - 2);
517 gen7_fill_3DSTATE_SF_body(cmd, &dw[1]);
518
519 cmd_batch_reserve(cmd, cmd_len);
520 cmd_batch_write_n(cmd, dw, cmd_len);
521}
522
523static void gen7_3DSTATE_SBE(struct intel_cmd *cmd)
524{
525 const uint8_t cmd_len = 14;
526 uint32_t dw[14];
527
528 CMD_ASSERT(cmd, 7, 7.5);
529
530 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SBE) |
531 (cmd_len - 2);
532 gen7_fill_3DSTATE_SBE_body(cmd, &dw[1]);
533
534 cmd_batch_reserve(cmd, cmd_len);
535 cmd_batch_write_n(cmd, dw, cmd_len);
536}
537
Chia-I Wuc3f9c092014-08-30 14:29:29 +0800538static void gen6_3DSTATE_CLIP(struct intel_cmd *cmd)
539{
540 const uint8_t cmd_len = 4;
541 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_CLIP) |
542 (cmd_len - 2);
543 const struct intel_pipeline *pipeline = cmd->bind.pipeline.graphics;
Chia-I Wuf2b6d722014-09-02 08:52:27 +0800544 const struct intel_pipeline_shader *fs = &pipeline->fs;
Chia-I Wuc3f9c092014-08-30 14:29:29 +0800545 const struct intel_viewport_state *viewport = cmd->bind.state.viewport;
546 const struct intel_raster_state *raster = cmd->bind.state.raster;
547 uint32_t dw1, dw2, dw3;
548
549 CMD_ASSERT(cmd, 6, 7.5);
550
551 dw1 = GEN6_CLIP_DW1_STATISTICS;
552 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
553 dw1 |= GEN7_CLIP_DW1_SUBPIXEL_8BITS |
554 GEN7_CLIP_DW1_EARLY_CULL_ENABLE |
555 raster->cmd_clip_cull;
556 }
557
558 dw2 = GEN6_CLIP_DW2_CLIP_ENABLE |
559 GEN6_CLIP_DW2_XY_TEST_ENABLE |
560 GEN6_CLIP_DW2_APIMODE_OGL |
561 pipeline->provoking_vertex_tri << GEN6_CLIP_DW2_TRI_PROVOKE__SHIFT |
562 pipeline->provoking_vertex_line << GEN6_CLIP_DW2_LINE_PROVOKE__SHIFT |
563 pipeline->provoking_vertex_trifan << GEN6_CLIP_DW2_TRIFAN_PROVOKE__SHIFT;
564
565 if (pipeline->rasterizerDiscardEnable)
566 dw2 |= GEN6_CLIP_DW2_CLIPMODE_REJECT_ALL;
567 else
568 dw2 |= GEN6_CLIP_DW2_CLIPMODE_NORMAL;
569
570 if (pipeline->depthClipEnable)
571 dw2 |= GEN6_CLIP_DW2_Z_TEST_ENABLE;
572
573 if (fs->barycentric_interps & (GEN6_INTERP_NONPERSPECTIVE_PIXEL |
574 GEN6_INTERP_NONPERSPECTIVE_CENTROID |
575 GEN6_INTERP_NONPERSPECTIVE_SAMPLE))
576 dw2 |= GEN6_CLIP_DW2_NONPERSPECTIVE_BARYCENTRIC_ENABLE;
577
578 dw3 = 0x1 << GEN6_CLIP_DW3_MIN_POINT_WIDTH__SHIFT |
579 0x7ff << GEN6_CLIP_DW3_MAX_POINT_WIDTH__SHIFT |
580 (viewport->viewport_count - 1);
581
582 cmd_batch_reserve(cmd, cmd_len);
583 cmd_batch_write(cmd, dw0);
584 cmd_batch_write(cmd, dw1);
585 cmd_batch_write(cmd, dw2);
586 cmd_batch_write(cmd, dw3);
587}
588
Chia-I Wu1f2fd292014-08-29 15:07:09 +0800589static void gen6_3DSTATE_WM(struct intel_cmd *cmd)
590{
591 const int max_threads = (cmd->dev->gpu->gt == 2) ? 80 : 40;
592 const struct intel_pipeline *pipeline = cmd->bind.pipeline.graphics;
Chia-I Wuf2b6d722014-09-02 08:52:27 +0800593 const struct intel_pipeline_shader *fs = &pipeline->fs;
Chia-I Wu1f2fd292014-08-29 15:07:09 +0800594 const struct intel_msaa_state *msaa = cmd->bind.state.msaa;
595 const uint8_t cmd_len = 9;
596 uint32_t dw0, dw2, dw4, dw5, dw6;
597
598 CMD_ASSERT(cmd, 6, 6);
599
600 dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
601
602 dw2 = (fs->sampler_count + 3) / 4 << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT |
603 fs->surface_count << GEN6_THREADDISP_BINDING_TABLE_SIZE__SHIFT;
604
605 dw4 = GEN6_WM_DW4_STATISTICS |
606 fs->urb_grf_start << GEN6_WM_DW4_URB_GRF_START0__SHIFT |
607 0 << GEN6_WM_DW4_URB_GRF_START1__SHIFT |
608 0 << GEN6_WM_DW4_URB_GRF_START2__SHIFT;
609
610 dw5 = (max_threads - 1) << GEN6_WM_DW5_MAX_THREADS__SHIFT |
611 GEN6_WM_DW5_PS_ENABLE |
612 GEN6_WM_DW5_8_PIXEL_DISPATCH;
613
614 if (fs->uses & INTEL_SHADER_USE_KILL ||
615 pipeline->cb_state.alphaToCoverageEnable)
616 dw5 |= GEN6_WM_DW5_PS_KILL;
617
618 if (fs->uses & INTEL_SHADER_USE_COMPUTED_DEPTH)
619 dw5 |= GEN6_WM_DW5_PS_COMPUTE_DEPTH;
620 if (fs->uses & INTEL_SHADER_USE_DEPTH)
621 dw5 |= GEN6_WM_DW5_PS_USE_DEPTH;
622 if (fs->uses & INTEL_SHADER_USE_W)
623 dw5 |= GEN6_WM_DW5_PS_USE_W;
624
625 if (pipeline->cb_state.dualSourceBlendEnable)
626 dw5 |= GEN6_WM_DW5_DUAL_SOURCE_BLEND;
627
628 dw6 = fs->in_count << GEN6_WM_DW6_SF_ATTR_COUNT__SHIFT |
629 GEN6_WM_DW6_POSOFFSET_NONE |
630 GEN6_WM_DW6_ZW_INTERP_PIXEL |
631 fs->barycentric_interps << GEN6_WM_DW6_BARYCENTRIC_INTERP__SHIFT |
632 GEN6_WM_DW6_POINT_RASTRULE_UPPER_RIGHT;
633
634 if (msaa->sample_count > 1) {
635 dw6 |= GEN6_WM_DW6_MSRASTMODE_ON_PATTERN |
636 GEN6_WM_DW6_MSDISPMODE_PERPIXEL;
637 } else {
638 dw6 |= GEN6_WM_DW6_MSRASTMODE_OFF_PIXEL |
639 GEN6_WM_DW6_MSDISPMODE_PERSAMPLE;
640 }
641
642 cmd_batch_reserve(cmd, cmd_len);
643 cmd_batch_write(cmd, dw0);
644 cmd_batch_write(cmd, cmd->bind.fs.kernel_pos << 2);
645 cmd_batch_write(cmd, dw2);
646 cmd_batch_write(cmd, 0); /* scratch */
647 cmd_batch_write(cmd, dw4);
648 cmd_batch_write(cmd, dw5);
649 cmd_batch_write(cmd, dw6);
650 cmd_batch_write(cmd, 0); /* kernel 1 */
651 cmd_batch_write(cmd, 0); /* kernel 2 */
652}
653
654static void gen7_3DSTATE_WM(struct intel_cmd *cmd)
655{
656 const struct intel_pipeline *pipeline = cmd->bind.pipeline.graphics;
Chia-I Wuf2b6d722014-09-02 08:52:27 +0800657 const struct intel_pipeline_shader *fs = &pipeline->fs;
Chia-I Wu1f2fd292014-08-29 15:07:09 +0800658 const struct intel_msaa_state *msaa = cmd->bind.state.msaa;
659 const uint8_t cmd_len = 3;
660 uint32_t dw0, dw1, dw2;
661
662 CMD_ASSERT(cmd, 7, 7.5);
663
664 dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
665
666 dw1 = GEN7_WM_DW1_STATISTICS |
667 GEN7_WM_DW1_PS_ENABLE |
668 GEN7_WM_DW1_ZW_INTERP_PIXEL |
669 fs->barycentric_interps << GEN7_WM_DW1_BARYCENTRIC_INTERP__SHIFT |
670 GEN7_WM_DW1_POINT_RASTRULE_UPPER_RIGHT;
671
672 if (fs->uses & INTEL_SHADER_USE_KILL ||
673 pipeline->cb_state.alphaToCoverageEnable)
674 dw1 |= GEN7_WM_DW1_PS_KILL;
675
676 if (fs->uses & INTEL_SHADER_USE_COMPUTED_DEPTH)
677 dw1 |= GEN7_WM_DW1_PSCDEPTH_ON;
678 if (fs->uses & INTEL_SHADER_USE_DEPTH)
679 dw1 |= GEN7_WM_DW1_PS_USE_DEPTH;
680 if (fs->uses & INTEL_SHADER_USE_W)
681 dw1 |= GEN7_WM_DW1_PS_USE_W;
682
683 dw2 = 0;
684
685 if (msaa->sample_count > 1) {
686 dw1 |= GEN7_WM_DW1_MSRASTMODE_ON_PATTERN;
687 dw2 |= GEN7_WM_DW2_MSDISPMODE_PERPIXEL;
688 } else {
689 dw1 |= GEN7_WM_DW1_MSRASTMODE_OFF_PIXEL;
690 dw2 |= GEN7_WM_DW2_MSDISPMODE_PERSAMPLE;
691 }
692
693 cmd_batch_reserve(cmd, cmd_len);
694 cmd_batch_write(cmd, dw0);
695 cmd_batch_write(cmd, dw1);
696 cmd_batch_write(cmd, dw2);
697}
698
699static void gen7_3DSTATE_PS(struct intel_cmd *cmd)
700{
701 const struct intel_pipeline *pipeline = cmd->bind.pipeline.graphics;
Chia-I Wuf2b6d722014-09-02 08:52:27 +0800702 const struct intel_pipeline_shader *fs = &pipeline->fs;
Chia-I Wu1f2fd292014-08-29 15:07:09 +0800703 const struct intel_msaa_state *msaa = cmd->bind.state.msaa;
704 const uint8_t cmd_len = 8;
705 uint32_t dw0, dw2, dw4, dw5;
706
707 CMD_ASSERT(cmd, 7, 7.5);
708
709 dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_PS) | (cmd_len - 2);
710
711 dw2 = (fs->sampler_count + 3) / 4 << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT |
712 fs->surface_count << GEN6_THREADDISP_BINDING_TABLE_SIZE__SHIFT;
713
714 dw4 = GEN7_PS_DW4_POSOFFSET_NONE |
715 GEN7_PS_DW4_8_PIXEL_DISPATCH;
716
717 if (cmd_gen(cmd) >= INTEL_GEN(7.5)) {
718 const int max_threads =
719 (cmd->dev->gpu->gt == 3) ? 408 :
720 (cmd->dev->gpu->gt == 2) ? 204 : 102;
721 dw4 |= (max_threads - 1) << GEN75_PS_DW4_MAX_THREADS__SHIFT;
722 dw4 |= msaa->cmd[msaa->cmd_len - 1] << GEN75_PS_DW4_SAMPLE_MASK__SHIFT;
723 } else {
724 const int max_threads = (cmd->dev->gpu->gt == 2) ? 172 : 48;
725 dw4 |= (max_threads - 1) << GEN7_PS_DW4_MAX_THREADS__SHIFT;
726 }
727
Chia-I Wuc3ddee62014-09-02 10:53:20 +0800728 if (fs->pcb_size)
Chia-I Wu1f2fd292014-08-29 15:07:09 +0800729 dw4 |= GEN7_PS_DW4_PUSH_CONSTANT_ENABLE;
730
731 if (fs->in_count)
732 dw4 |= GEN7_PS_DW4_ATTR_ENABLE;
733
734 if (pipeline->cb_state.dualSourceBlendEnable)
735 dw4 |= GEN7_PS_DW4_DUAL_SOURCE_BLEND;
736
737 dw5 = fs->urb_grf_start << GEN7_PS_DW5_URB_GRF_START0__SHIFT |
738 0 << GEN7_PS_DW5_URB_GRF_START1__SHIFT |
739 0 << GEN7_PS_DW5_URB_GRF_START2__SHIFT;
740
741 cmd_batch_reserve(cmd, cmd_len);
742 cmd_batch_write(cmd, dw0);
743 cmd_batch_write(cmd, cmd->bind.fs.kernel_pos << 2);
744 cmd_batch_write(cmd, dw2);
745 cmd_batch_write(cmd, 0); /* scratch */
746 cmd_batch_write(cmd, dw4);
747 cmd_batch_write(cmd, dw5);
748 cmd_batch_write(cmd, 0); /* kernel 1 */
749 cmd_batch_write(cmd, 0); /* kernel 2 */
750}
751
Chia-I Wu7fae4e32014-08-21 11:39:44 +0800752static void gen6_3DSTATE_DEPTH_BUFFER(struct intel_cmd *cmd,
753 const struct intel_ds_view *view)
754{
755 const uint8_t cmd_len = 7;
756 uint32_t dw0;
757
758 CMD_ASSERT(cmd, 6, 7.5);
759
760 dw0 = (cmd_gen(cmd) >= INTEL_GEN(7)) ?
Chia-I Wu426072d2014-08-26 14:31:55 +0800761 GEN7_RENDER_CMD(3D, 3DSTATE_DEPTH_BUFFER) :
762 GEN6_RENDER_CMD(3D, 3DSTATE_DEPTH_BUFFER);
Chia-I Wu7fae4e32014-08-21 11:39:44 +0800763 dw0 |= (cmd_len - 2);
764
Chia-I Wu2de65d02014-08-25 10:02:53 +0800765 cmd_batch_reserve_reloc(cmd, cmd_len, (bool) view->img);
Chia-I Wue24c3292014-08-21 14:05:23 +0800766 cmd_batch_write(cmd, dw0);
767 cmd_batch_write(cmd, view->cmd[0]);
Courtney Goeltzenleuchtere316d972014-08-22 16:25:24 -0600768 if (view->img) {
Chia-I Wu9ee38722014-08-25 12:11:36 +0800769 cmd_batch_reloc(cmd, view->cmd[1], view->img->obj.mem->bo,
Chia-I Wu32a22462014-08-26 14:13:46 +0800770 INTEL_RELOC_WRITE);
Courtney Goeltzenleuchtere316d972014-08-22 16:25:24 -0600771 } else {
772 cmd_batch_write(cmd, 0);
773 }
Chia-I Wue24c3292014-08-21 14:05:23 +0800774 cmd_batch_write(cmd, view->cmd[2]);
775 cmd_batch_write(cmd, view->cmd[3]);
776 cmd_batch_write(cmd, view->cmd[4]);
777 cmd_batch_write(cmd, view->cmd[5]);
Chia-I Wu7fae4e32014-08-21 11:39:44 +0800778}
779
780static void gen6_3DSTATE_STENCIL_BUFFER(struct intel_cmd *cmd,
781 const struct intel_ds_view *view)
782{
783 const uint8_t cmd_len = 3;
784 uint32_t dw0;
785
786 CMD_ASSERT(cmd, 6, 7.5);
787
788 dw0 = (cmd_gen(cmd) >= INTEL_GEN(7)) ?
Chia-I Wu426072d2014-08-26 14:31:55 +0800789 GEN7_RENDER_CMD(3D, 3DSTATE_STENCIL_BUFFER) :
790 GEN6_RENDER_CMD(3D, 3DSTATE_STENCIL_BUFFER);
Chia-I Wu7fae4e32014-08-21 11:39:44 +0800791 dw0 |= (cmd_len - 2);
792
Chia-I Wu2de65d02014-08-25 10:02:53 +0800793 cmd_batch_reserve_reloc(cmd, cmd_len, (bool) view->img);
Chia-I Wue24c3292014-08-21 14:05:23 +0800794 cmd_batch_write(cmd, dw0);
795 cmd_batch_write(cmd, view->cmd[6]);
Courtney Goeltzenleuchtere316d972014-08-22 16:25:24 -0600796 if (view->img) {
Chia-I Wu9ee38722014-08-25 12:11:36 +0800797 cmd_batch_reloc(cmd, view->cmd[7], view->img->obj.mem->bo,
Chia-I Wu32a22462014-08-26 14:13:46 +0800798 INTEL_RELOC_WRITE);
Courtney Goeltzenleuchtere316d972014-08-22 16:25:24 -0600799 } else {
800 cmd_batch_write(cmd, 0);
801 }
Chia-I Wu7fae4e32014-08-21 11:39:44 +0800802}
803
804static void gen6_3DSTATE_HIER_DEPTH_BUFFER(struct intel_cmd *cmd,
805 const struct intel_ds_view *view)
806{
807 const uint8_t cmd_len = 3;
808 uint32_t dw0;
809
810 CMD_ASSERT(cmd, 6, 7.5);
811
812 dw0 = (cmd_gen(cmd) >= INTEL_GEN(7)) ?
Chia-I Wu426072d2014-08-26 14:31:55 +0800813 GEN7_RENDER_CMD(3D, 3DSTATE_HIER_DEPTH_BUFFER) :
814 GEN6_RENDER_CMD(3D, 3DSTATE_HIER_DEPTH_BUFFER);
Chia-I Wu7fae4e32014-08-21 11:39:44 +0800815 dw0 |= (cmd_len - 2);
816
Chia-I Wu2de65d02014-08-25 10:02:53 +0800817 cmd_batch_reserve_reloc(cmd, cmd_len, (bool) view->img);
Chia-I Wue24c3292014-08-21 14:05:23 +0800818 cmd_batch_write(cmd, dw0);
819 cmd_batch_write(cmd, view->cmd[8]);
Courtney Goeltzenleuchtere316d972014-08-22 16:25:24 -0600820 if (view->img) {
Chia-I Wu9ee38722014-08-25 12:11:36 +0800821 cmd_batch_reloc(cmd, view->cmd[9], view->img->obj.mem->bo,
Chia-I Wu32a22462014-08-26 14:13:46 +0800822 INTEL_RELOC_WRITE);
Courtney Goeltzenleuchtere316d972014-08-22 16:25:24 -0600823 } else {
824 cmd_batch_write(cmd, 0);
825 }
Chia-I Wu7fae4e32014-08-21 11:39:44 +0800826}
827
Chia-I Wuf8231032014-08-25 10:44:45 +0800828static void gen6_3DSTATE_CLEAR_PARAMS(struct intel_cmd *cmd,
829 uint32_t clear_val)
830{
831 const uint8_t cmd_len = 2;
Chia-I Wu426072d2014-08-26 14:31:55 +0800832 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_CLEAR_PARAMS) |
Chia-I Wuf8231032014-08-25 10:44:45 +0800833 GEN6_CLEAR_PARAMS_DW0_VALID |
834 (cmd_len - 2);
835
836 CMD_ASSERT(cmd, 6, 6);
837
838 cmd_batch_reserve(cmd, cmd_len);
839 cmd_batch_write(cmd, dw0);
840 cmd_batch_write(cmd, clear_val);
841}
842
843static void gen7_3DSTATE_CLEAR_PARAMS(struct intel_cmd *cmd,
844 uint32_t clear_val)
845{
846 const uint8_t cmd_len = 3;
Chia-I Wu426072d2014-08-26 14:31:55 +0800847 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_CLEAR_PARAMS) |
Chia-I Wuf8231032014-08-25 10:44:45 +0800848 (cmd_len - 2);
849
850 CMD_ASSERT(cmd, 7, 7.5);
851
852 cmd_batch_reserve(cmd, cmd_len);
853 cmd_batch_write(cmd, dw0);
854 cmd_batch_write(cmd, clear_val);
855 cmd_batch_write(cmd, 1);
856}
857
Chia-I Wu302742d2014-08-22 10:28:29 +0800858static void gen6_3DSTATE_CC_STATE_POINTERS(struct intel_cmd *cmd,
859 XGL_UINT blend_pos,
860 XGL_UINT ds_pos,
861 XGL_UINT cc_pos)
862{
863 const uint8_t cmd_len = 4;
864 uint32_t dw0;
865
866 CMD_ASSERT(cmd, 6, 6);
867
Chia-I Wu426072d2014-08-26 14:31:55 +0800868 dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_CC_STATE_POINTERS) |
Chia-I Wu302742d2014-08-22 10:28:29 +0800869 (cmd_len - 2);
870
871 cmd_batch_reserve(cmd, cmd_len);
872 cmd_batch_write(cmd, dw0);
873 cmd_batch_write(cmd, (blend_pos << 2) | 1);
874 cmd_batch_write(cmd, (ds_pos << 2) | 1);
875 cmd_batch_write(cmd, (cc_pos << 2) | 1);
876}
877
Chia-I Wu1744cca2014-08-22 11:10:17 +0800878static void gen6_3DSTATE_VIEWPORT_STATE_POINTERS(struct intel_cmd *cmd,
879 XGL_UINT clip_pos,
880 XGL_UINT sf_pos,
881 XGL_UINT cc_pos)
882{
883 const uint8_t cmd_len = 4;
884 uint32_t dw0;
885
886 CMD_ASSERT(cmd, 6, 6);
887
Chia-I Wu426072d2014-08-26 14:31:55 +0800888 dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_VIEWPORT_STATE_POINTERS) |
Chia-I Wu1744cca2014-08-22 11:10:17 +0800889 GEN6_PTR_VP_DW0_CLIP_CHANGED |
890 GEN6_PTR_VP_DW0_SF_CHANGED |
891 GEN6_PTR_VP_DW0_CC_CHANGED |
892 (cmd_len - 2);
893
894 cmd_batch_reserve(cmd, cmd_len);
895 cmd_batch_write(cmd, dw0);
896 cmd_batch_write(cmd, clip_pos << 2);
897 cmd_batch_write(cmd, sf_pos << 2);
898 cmd_batch_write(cmd, cc_pos << 2);
899}
900
901static void gen6_3DSTATE_SCISSOR_STATE_POINTERS(struct intel_cmd *cmd,
902 XGL_UINT scissor_pos)
903{
904 const uint8_t cmd_len = 2;
905 uint32_t dw0;
906
907 CMD_ASSERT(cmd, 6, 6);
908
Chia-I Wu426072d2014-08-26 14:31:55 +0800909 dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_SCISSOR_STATE_POINTERS) |
Chia-I Wu1744cca2014-08-22 11:10:17 +0800910 (cmd_len - 2);
911
912 cmd_batch_reserve(cmd, cmd_len);
913 cmd_batch_write(cmd, dw0);
914 cmd_batch_write(cmd, scissor_pos << 2);
915}
916
Chia-I Wu42a56202014-08-23 16:47:48 +0800917static void gen6_3DSTATE_BINDING_TABLE_POINTERS(struct intel_cmd *cmd,
918 XGL_UINT vs_pos,
919 XGL_UINT gs_pos,
920 XGL_UINT ps_pos)
921{
922 const uint8_t cmd_len = 4;
923 uint32_t dw0;
924
925 CMD_ASSERT(cmd, 6, 6);
926
Chia-I Wu426072d2014-08-26 14:31:55 +0800927 dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_BINDING_TABLE_POINTERS) |
Chia-I Wu42a56202014-08-23 16:47:48 +0800928 GEN6_PTR_BINDING_TABLE_DW0_VS_CHANGED |
929 GEN6_PTR_BINDING_TABLE_DW0_GS_CHANGED |
930 GEN6_PTR_BINDING_TABLE_DW0_PS_CHANGED |
931 (cmd_len - 2);
932
933 cmd_batch_reserve(cmd, cmd_len);
934 cmd_batch_write(cmd, dw0);
935 cmd_batch_write(cmd, vs_pos << 2);
936 cmd_batch_write(cmd, gs_pos << 2);
937 cmd_batch_write(cmd, ps_pos << 2);
938}
939
Chia-I Wu257e75e2014-08-29 14:06:35 +0800940static void gen6_3DSTATE_SAMPLER_STATE_POINTERS(struct intel_cmd *cmd,
941 XGL_UINT vs_pos,
942 XGL_UINT gs_pos,
943 XGL_UINT ps_pos)
944{
945 const uint8_t cmd_len = 4;
946 uint32_t dw0;
947
948 CMD_ASSERT(cmd, 6, 6);
949
950 dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_SAMPLER_STATE_POINTERS) |
951 GEN6_PTR_SAMPLER_DW0_VS_CHANGED |
952 GEN6_PTR_SAMPLER_DW0_GS_CHANGED |
953 GEN6_PTR_SAMPLER_DW0_PS_CHANGED |
954 (cmd_len - 2);
955
956 cmd_batch_reserve(cmd, cmd_len);
957 cmd_batch_write(cmd, dw0);
958 cmd_batch_write(cmd, vs_pos << 2);
959 cmd_batch_write(cmd, gs_pos << 2);
960 cmd_batch_write(cmd, ps_pos << 2);
961}
962
Chia-I Wu302742d2014-08-22 10:28:29 +0800963static void gen7_3dstate_pointer(struct intel_cmd *cmd,
964 int subop, XGL_UINT pos)
965{
966 const uint8_t cmd_len = 2;
967 const uint32_t dw0 = GEN6_RENDER_TYPE_RENDER |
968 GEN6_RENDER_SUBTYPE_3D |
969 subop | (cmd_len - 2);
970
971 cmd_batch_reserve(cmd, cmd_len);
972 cmd_batch_write(cmd, dw0);
973 cmd_batch_write(cmd, pos << 2);
974}
975
976static XGL_UINT gen6_BLEND_STATE(struct intel_cmd *cmd,
977 const struct intel_blend_state *state)
978{
979 const uint8_t cmd_align = GEN6_ALIGNMENT_BLEND_STATE;
980 const uint8_t cmd_len = XGL_MAX_COLOR_ATTACHMENTS * 2;
981
982 CMD_ASSERT(cmd, 6, 7.5);
983 STATIC_ASSERT(ARRAY_SIZE(state->cmd) >= cmd_len);
984
985 return cmd_state_copy(cmd, state->cmd, cmd_len, cmd_align);
986}
987
988static XGL_UINT gen6_DEPTH_STENCIL_STATE(struct intel_cmd *cmd,
989 const struct intel_ds_state *state)
990{
991 const uint8_t cmd_align = GEN6_ALIGNMENT_DEPTH_STENCIL_STATE;
992 const uint8_t cmd_len = 3;
993
994 CMD_ASSERT(cmd, 6, 7.5);
995 STATIC_ASSERT(ARRAY_SIZE(state->cmd) >= cmd_len);
996
997 return cmd_state_copy(cmd, state->cmd, cmd_len, cmd_align);
998}
999
1000static XGL_UINT gen6_COLOR_CALC_STATE(struct intel_cmd *cmd,
1001 uint32_t stencil_ref,
1002 const uint32_t blend_color[4])
1003{
1004 const uint8_t cmd_align = GEN6_ALIGNMENT_COLOR_CALC_STATE;
1005 const uint8_t cmd_len = 6;
1006 XGL_UINT pos;
1007 uint32_t *dw;
1008
1009 CMD_ASSERT(cmd, 6, 7.5);
1010
1011 dw = cmd_state_reserve(cmd, cmd_len, cmd_align, &pos);
1012 dw[0] = stencil_ref;
1013 dw[1] = 0;
1014 dw[2] = blend_color[0];
1015 dw[3] = blend_color[1];
1016 dw[4] = blend_color[2];
1017 dw[5] = blend_color[3];
1018 cmd_state_advance(cmd, cmd_len);
1019
1020 return pos;
1021}
1022
Chia-I Wu8370b402014-08-29 12:28:37 +08001023static void cmd_wa_gen6_pre_depth_stall_write(struct intel_cmd *cmd)
Chia-I Wu48c283d2014-08-25 23:13:46 +08001024{
Chia-I Wu8370b402014-08-29 12:28:37 +08001025 CMD_ASSERT(cmd, 6, 7.5);
1026
Chia-I Wu707a29e2014-08-27 12:51:47 +08001027 if (!cmd->bind.draw_count)
1028 return;
1029
Chia-I Wu8370b402014-08-29 12:28:37 +08001030 if (cmd->bind.wa_flags & INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE)
Chia-I Wu48c283d2014-08-25 23:13:46 +08001031 return;
1032
Chia-I Wu8370b402014-08-29 12:28:37 +08001033 cmd->bind.wa_flags |= INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE;
Chia-I Wu48c283d2014-08-25 23:13:46 +08001034
1035 /*
1036 * From the Sandy Bridge PRM, volume 2 part 1, page 60:
1037 *
1038 * "Pipe-control with CS-stall bit set must be sent BEFORE the
1039 * pipe-control with a post-sync op and no write-cache flushes."
1040 *
1041 * The workaround below necessitates this workaround.
1042 */
1043 gen6_PIPE_CONTROL(cmd,
1044 GEN6_PIPE_CONTROL_CS_STALL |
1045 GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL,
Chia-I Wud6d079d2014-08-31 13:14:21 +08001046 NULL, 0, 0);
Chia-I Wu48c283d2014-08-25 23:13:46 +08001047
Chia-I Wud6d079d2014-08-31 13:14:21 +08001048 gen6_PIPE_CONTROL(cmd, GEN6_PIPE_CONTROL_WRITE_IMM,
1049 cmd->scratch_bo, 0, 0);
Chia-I Wu48c283d2014-08-25 23:13:46 +08001050}
1051
Chia-I Wu8370b402014-08-29 12:28:37 +08001052static void cmd_wa_gen6_pre_command_scoreboard_stall(struct intel_cmd *cmd)
Courtney Goeltzenleuchterf9e1a412014-08-27 13:59:36 -06001053{
Chia-I Wu48c283d2014-08-25 23:13:46 +08001054 CMD_ASSERT(cmd, 6, 7.5);
1055
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001056 if (!cmd->bind.draw_count)
1057 return;
1058
Chia-I Wud6d079d2014-08-31 13:14:21 +08001059 gen6_PIPE_CONTROL(cmd, GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL,
1060 NULL, 0, 0);
Chia-I Wu8370b402014-08-29 12:28:37 +08001061}
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001062
Chia-I Wu8370b402014-08-29 12:28:37 +08001063static void cmd_wa_gen7_pre_vs_depth_stall_write(struct intel_cmd *cmd)
1064{
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001065 CMD_ASSERT(cmd, 7, 7.5);
1066
Chia-I Wu8370b402014-08-29 12:28:37 +08001067 if (!cmd->bind.draw_count)
1068 return;
1069
1070 cmd_wa_gen6_pre_depth_stall_write(cmd);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001071
1072 gen6_PIPE_CONTROL(cmd,
1073 GEN6_PIPE_CONTROL_DEPTH_STALL | GEN6_PIPE_CONTROL_WRITE_IMM,
Chia-I Wud6d079d2014-08-31 13:14:21 +08001074 cmd->scratch_bo, 0, 0);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001075}
1076
Chia-I Wu8370b402014-08-29 12:28:37 +08001077static void cmd_wa_gen7_post_command_cs_stall(struct intel_cmd *cmd)
1078{
1079 CMD_ASSERT(cmd, 7, 7.5);
1080
1081 if (!cmd->bind.draw_count)
1082 return;
1083
1084 /*
1085 * From the Ivy Bridge PRM, volume 2 part 1, page 61:
1086 *
1087 * "One of the following must also be set (when CS stall is set):
1088 *
1089 * * Render Target Cache Flush Enable ([12] of DW1)
1090 * * Depth Cache Flush Enable ([0] of DW1)
1091 * * Stall at Pixel Scoreboard ([1] of DW1)
1092 * * Depth Stall ([13] of DW1)
1093 * * Post-Sync Operation ([13] of DW1)"
1094 */
1095 gen6_PIPE_CONTROL(cmd,
1096 GEN6_PIPE_CONTROL_CS_STALL |
1097 GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL,
Chia-I Wud6d079d2014-08-31 13:14:21 +08001098 NULL, 0, 0);
Chia-I Wu8370b402014-08-29 12:28:37 +08001099}
1100
1101static void cmd_wa_gen7_post_command_depth_stall(struct intel_cmd *cmd)
1102{
1103 CMD_ASSERT(cmd, 7, 7.5);
1104
1105 if (!cmd->bind.draw_count)
1106 return;
1107
1108 cmd_wa_gen6_pre_depth_stall_write(cmd);
1109
Chia-I Wud6d079d2014-08-31 13:14:21 +08001110 gen6_PIPE_CONTROL(cmd, GEN6_PIPE_CONTROL_DEPTH_STALL, NULL, 0, 0);
Chia-I Wu8370b402014-08-29 12:28:37 +08001111}
1112
1113static void cmd_wa_gen6_pre_multisample_depth_flush(struct intel_cmd *cmd)
1114{
1115 CMD_ASSERT(cmd, 6, 7.5);
1116
1117 if (!cmd->bind.draw_count)
1118 return;
1119
1120 /*
1121 * From the Sandy Bridge PRM, volume 2 part 1, page 305:
1122 *
1123 * "Driver must guarentee that all the caches in the depth pipe are
1124 * flushed before this command (3DSTATE_MULTISAMPLE) is parsed. This
1125 * requires driver to send a PIPE_CONTROL with a CS stall along with
1126 * a Depth Flush prior to this command."
1127 *
1128 * From the Ivy Bridge PRM, volume 2 part 1, page 304:
1129 *
1130 * "Driver must ierarchi that all the caches in the depth pipe are
1131 * flushed before this command (3DSTATE_MULTISAMPLE) is parsed. This
1132 * requires driver to send a PIPE_CONTROL with a CS stall along with
1133 * a Depth Flush prior to this command.
1134 */
1135 gen6_PIPE_CONTROL(cmd,
1136 GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH |
1137 GEN6_PIPE_CONTROL_CS_STALL,
Chia-I Wud6d079d2014-08-31 13:14:21 +08001138 NULL, 0, 0);
Chia-I Wu8370b402014-08-29 12:28:37 +08001139}
1140
1141static void cmd_wa_gen6_pre_ds_flush(struct intel_cmd *cmd)
1142{
1143 CMD_ASSERT(cmd, 6, 7.5);
1144
1145 if (!cmd->bind.draw_count)
1146 return;
1147
1148 /*
1149 * From the Ivy Bridge PRM, volume 2 part 1, page 315:
1150 *
1151 * "Driver must send a least one PIPE_CONTROL command with CS Stall
1152 * and a post sync operation prior to the group of depth
1153 * commands(3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS,
1154 * 3DSTATE_STENCIL_BUFFER, and 3DSTATE_HIER_DEPTH_BUFFER)."
1155 *
1156 * This workaround satifies all the conditions.
1157 */
1158 cmd_wa_gen6_pre_depth_stall_write(cmd);
1159
1160 /*
1161 * From the Ivy Bridge PRM, volume 2 part 1, page 315:
1162 *
1163 * "Restriction: Prior to changing Depth/Stencil Buffer state (i.e.,
1164 * any combination of 3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS,
1165 * 3DSTATE_STENCIL_BUFFER, 3DSTATE_HIER_DEPTH_BUFFER) SW must first
1166 * issue a pipelined depth stall (PIPE_CONTROL with Depth Stall bit
1167 * set), followed by a pipelined depth cache flush (PIPE_CONTROL with
1168 * Depth Flush Bit set, followed by another pipelined depth stall
1169 * (PIPE_CONTROL with Depth Stall Bit set), unless SW can otherwise
1170 * guarantee that the pipeline from WM onwards is already flushed
1171 * (e.g., via a preceding MI_FLUSH)."
1172 */
Chia-I Wud6d079d2014-08-31 13:14:21 +08001173 gen6_PIPE_CONTROL(cmd, GEN6_PIPE_CONTROL_DEPTH_STALL, NULL, 0, 0);
1174 gen6_PIPE_CONTROL(cmd, GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH, NULL, 0, 0);
1175 gen6_PIPE_CONTROL(cmd, GEN6_PIPE_CONTROL_DEPTH_STALL, NULL, 0, 0);
Chia-I Wu8370b402014-08-29 12:28:37 +08001176}
1177
Chia-I Wu525c6602014-08-27 10:22:34 +08001178void cmd_batch_flush(struct intel_cmd *cmd, uint32_t pipe_control_dw0)
1179{
1180 if (!cmd->bind.draw_count)
1181 return;
1182
1183 assert(!(pipe_control_dw0 & GEN6_PIPE_CONTROL_WRITE__MASK));
1184
Chia-I Wu8370b402014-08-29 12:28:37 +08001185 /*
1186 * From the Sandy Bridge PRM, volume 2 part 1, page 60:
1187 *
1188 * "Before a PIPE_CONTROL with Write Cache Flush Enable =1, a
1189 * PIPE_CONTROL with any non-zero post-sync-op is required."
1190 */
Chia-I Wu525c6602014-08-27 10:22:34 +08001191 if (pipe_control_dw0 & GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH)
Chia-I Wu8370b402014-08-29 12:28:37 +08001192 cmd_wa_gen6_pre_depth_stall_write(cmd);
Chia-I Wu525c6602014-08-27 10:22:34 +08001193
Chia-I Wu092279a2014-08-30 19:05:30 +08001194 /*
1195 * From the Ivy Bridge PRM, volume 2 part 1, page 61:
1196 *
1197 * "One of the following must also be set (when CS stall is set):
1198 *
1199 * * Render Target Cache Flush Enable ([12] of DW1)
1200 * * Depth Cache Flush Enable ([0] of DW1)
1201 * * Stall at Pixel Scoreboard ([1] of DW1)
1202 * * Depth Stall ([13] of DW1)
1203 * * Post-Sync Operation ([13] of DW1)"
1204 */
1205 if ((pipe_control_dw0 & GEN6_PIPE_CONTROL_CS_STALL) &&
1206 !(pipe_control_dw0 & (GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH |
1207 GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH |
1208 GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL |
1209 GEN6_PIPE_CONTROL_DEPTH_STALL)))
1210 pipe_control_dw0 |= GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL;
1211
Chia-I Wud6d079d2014-08-31 13:14:21 +08001212 gen6_PIPE_CONTROL(cmd, pipe_control_dw0, NULL, 0, 0);
Chia-I Wu525c6602014-08-27 10:22:34 +08001213}
1214
Chia-I Wu759fa2e2014-08-30 18:44:47 +08001215void cmd_batch_depth_count(struct intel_cmd *cmd,
1216 struct intel_bo *bo,
1217 XGL_GPU_SIZE offset)
1218{
1219 cmd_wa_gen6_pre_depth_stall_write(cmd);
1220
1221 gen6_PIPE_CONTROL(cmd,
1222 GEN6_PIPE_CONTROL_DEPTH_STALL |
1223 GEN6_PIPE_CONTROL_WRITE_PS_DEPTH_COUNT,
Chia-I Wud6d079d2014-08-31 13:14:21 +08001224 bo, offset, 0);
Chia-I Wu759fa2e2014-08-30 18:44:47 +08001225}
1226
Chia-I Wue8dbd5d2014-08-31 13:15:58 +08001227void cmd_batch_timestamp(struct intel_cmd *cmd,
1228 struct intel_bo *bo,
1229 XGL_GPU_SIZE offset)
1230{
1231 /* need any WA or stall? */
1232 gen6_PIPE_CONTROL(cmd, GEN6_PIPE_CONTROL_WRITE_TIMESTAMP, bo, offset, 0);
1233}
1234
1235void cmd_batch_immediate(struct intel_cmd *cmd,
1236 struct intel_bo *bo,
1237 XGL_GPU_SIZE offset,
1238 uint64_t val)
1239{
1240 /* need any WA or stall? */
1241 gen6_PIPE_CONTROL(cmd, GEN6_PIPE_CONTROL_WRITE_IMM, bo, offset, val);
1242}
1243
Chia-I Wu302742d2014-08-22 10:28:29 +08001244static void gen6_cc_states(struct intel_cmd *cmd)
1245{
1246 const struct intel_blend_state *blend = cmd->bind.state.blend;
1247 const struct intel_ds_state *ds = cmd->bind.state.ds;
1248 XGL_UINT blend_pos, ds_pos, cc_pos;
Chia-I Wuce9f11f2014-08-22 10:38:51 +08001249 uint32_t stencil_ref;
1250 uint32_t blend_color[4];
Chia-I Wu302742d2014-08-22 10:28:29 +08001251
1252 CMD_ASSERT(cmd, 6, 6);
1253
Chia-I Wuce9f11f2014-08-22 10:38:51 +08001254 if (blend) {
1255 blend_pos = gen6_BLEND_STATE(cmd, blend);
1256 memcpy(blend_color, blend->cmd_blend_color, sizeof(blend_color));
1257 } else {
1258 blend_pos = 0;
1259 memset(blend_color, 0, sizeof(blend_color));
1260 }
1261
1262 if (ds) {
1263 ds_pos = gen6_DEPTH_STENCIL_STATE(cmd, ds);
1264 stencil_ref = ds->cmd_stencil_ref;
1265 } else {
1266 ds_pos = 0;
1267 stencil_ref = 0;
1268 }
1269
1270 cc_pos = gen6_COLOR_CALC_STATE(cmd, stencil_ref, blend_color);
Chia-I Wu302742d2014-08-22 10:28:29 +08001271
1272 gen6_3DSTATE_CC_STATE_POINTERS(cmd, blend_pos, ds_pos, cc_pos);
1273}
1274
Chia-I Wu1744cca2014-08-22 11:10:17 +08001275static void gen6_viewport_states(struct intel_cmd *cmd)
1276{
1277 const struct intel_viewport_state *viewport = cmd->bind.state.viewport;
1278 XGL_UINT pos;
1279
1280 if (!viewport)
1281 return;
1282
1283 pos = cmd_state_copy(cmd, viewport->cmd, viewport->cmd_len,
1284 viewport->cmd_align);
1285
1286 gen6_3DSTATE_VIEWPORT_STATE_POINTERS(cmd,
1287 pos + viewport->cmd_clip_offset,
1288 pos,
1289 pos + viewport->cmd_cc_offset);
1290
1291 pos = (viewport->scissor_enable) ?
1292 pos + viewport->cmd_scissor_rect_offset : 0;
1293
1294 gen6_3DSTATE_SCISSOR_STATE_POINTERS(cmd, pos);
1295}
1296
Chia-I Wu302742d2014-08-22 10:28:29 +08001297static void gen7_cc_states(struct intel_cmd *cmd)
1298{
1299 const struct intel_blend_state *blend = cmd->bind.state.blend;
1300 const struct intel_ds_state *ds = cmd->bind.state.ds;
Chia-I Wuce9f11f2014-08-22 10:38:51 +08001301 uint32_t stencil_ref;
1302 uint32_t blend_color[4];
Chia-I Wu302742d2014-08-22 10:28:29 +08001303 XGL_UINT pos;
1304
1305 CMD_ASSERT(cmd, 7, 7.5);
1306
Chia-I Wuce9f11f2014-08-22 10:38:51 +08001307 if (!blend && !ds)
1308 return;
Chia-I Wu302742d2014-08-22 10:28:29 +08001309
Chia-I Wuce9f11f2014-08-22 10:38:51 +08001310 if (blend) {
1311 pos = gen6_BLEND_STATE(cmd, blend);
1312 gen7_3dstate_pointer(cmd,
1313 GEN7_RENDER_OPCODE_3DSTATE_BLEND_STATE_POINTERS, pos);
Chia-I Wu302742d2014-08-22 10:28:29 +08001314
Chia-I Wuce9f11f2014-08-22 10:38:51 +08001315 memcpy(blend_color, blend->cmd_blend_color, sizeof(blend_color));
1316 } else {
1317 memset(blend_color, 0, sizeof(blend_color));
1318 }
1319
1320 if (ds) {
1321 pos = gen6_DEPTH_STENCIL_STATE(cmd, ds);
1322 gen7_3dstate_pointer(cmd,
1323 GEN7_RENDER_OPCODE_3DSTATE_DEPTH_STENCIL_STATE_POINTERS, pos);
1324 } else {
1325 stencil_ref = 0;
1326 }
1327
1328 pos = gen6_COLOR_CALC_STATE(cmd, stencil_ref, blend_color);
Chia-I Wu302742d2014-08-22 10:28:29 +08001329 gen7_3dstate_pointer(cmd,
1330 GEN6_RENDER_OPCODE_3DSTATE_CC_STATE_POINTERS, pos);
1331}
1332
Chia-I Wu1744cca2014-08-22 11:10:17 +08001333static void gen7_viewport_states(struct intel_cmd *cmd)
1334{
1335 const struct intel_viewport_state *viewport = cmd->bind.state.viewport;
1336 XGL_UINT pos;
1337
1338 if (!viewport)
1339 return;
1340
1341 pos = cmd_state_copy(cmd, viewport->cmd, viewport->cmd_len,
1342 viewport->cmd_align);
1343
1344 gen7_3dstate_pointer(cmd,
1345 GEN7_RENDER_OPCODE_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP, pos);
1346 gen7_3dstate_pointer(cmd,
1347 GEN7_RENDER_OPCODE_3DSTATE_VIEWPORT_STATE_POINTERS_CC,
1348 pos + viewport->cmd_cc_offset);
1349 if (viewport->scissor_enable) {
1350 gen7_3dstate_pointer(cmd,
1351 GEN6_RENDER_OPCODE_3DSTATE_SCISSOR_STATE_POINTERS,
1352 pos + viewport->cmd_scissor_rect_offset);
1353 }
1354}
1355
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001356static void gen6_pcb(struct intel_cmd *cmd, int subop,
Chia-I Wuf2b6d722014-09-02 08:52:27 +08001357 const struct intel_pipeline_shader *sh)
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001358{
1359 const uint8_t cmd_len = 5;
Chia-I Wuc3ddee62014-09-02 10:53:20 +08001360 /*
1361 * TODO It is actually 2048 for non-VS PCB. But we need to upload the
1362 * data to multiple PCBs when the size is greater than 1024.
1363 */
1364 const XGL_UINT max_size = 1024;
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001365 uint32_t dw0;
Chia-I Wuc3ddee62014-09-02 10:53:20 +08001366 XGL_UINT pos;
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001367
Chia-I Wuc3ddee62014-09-02 10:53:20 +08001368 if (sh->pcb_size > max_size) {
1369 cmd->result = XGL_ERROR_UNKNOWN;
1370 return;
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001371 }
1372
1373 dw0 = GEN6_RENDER_TYPE_RENDER |
1374 GEN6_RENDER_SUBTYPE_3D |
1375 subop |
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001376 (cmd_len - 2);
Chia-I Wuc3ddee62014-09-02 10:53:20 +08001377 pos = 0;
1378
1379 if (sh->pcb_size) {
1380 const XGL_UINT alignment = 32;
1381 const XGL_SIZE size = u_align(sh->pcb_size, alignment);
1382 void *ptr;
1383
1384 ptr = cmd_state_reserve(cmd, size / sizeof(uint32_t),
1385 alignment / sizeof(uint32_t), &pos);
1386 memcpy(ptr, sh->pcb, sh->pcb_size);
1387 cmd_state_advance(cmd, size / sizeof(uint32_t));
1388
1389 dw0 |= GEN6_PCB_ANY_DW0_PCB0_VALID;
1390 pos |= size / alignment - 1;
1391 }
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001392
1393 cmd_batch_reserve(cmd, cmd_len);
1394 cmd_batch_write(cmd, dw0);
Chia-I Wuc3ddee62014-09-02 10:53:20 +08001395 cmd_batch_write(cmd, pos);
1396 cmd_batch_write(cmd, 0);
1397 cmd_batch_write(cmd, 0);
1398 cmd_batch_write(cmd, 0);
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001399}
1400
1401static void gen7_pcb(struct intel_cmd *cmd, int subop,
Chia-I Wuf2b6d722014-09-02 08:52:27 +08001402 const struct intel_pipeline_shader *sh)
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001403{
1404 const uint8_t cmd_len = 7;
1405 const uint32_t dw0 = GEN6_RENDER_TYPE_RENDER |
1406 GEN6_RENDER_SUBTYPE_3D |
1407 subop |
1408 (cmd_len - 2);
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001409 const XGL_UINT max_size = 2048;
Chia-I Wuc3ddee62014-09-02 10:53:20 +08001410 XGL_UINT pcb_len = 0;
1411 XGL_UINT pos = 0;
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001412
Chia-I Wuc3ddee62014-09-02 10:53:20 +08001413 if (sh->pcb_size > max_size) {
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001414 cmd->result = XGL_ERROR_UNKNOWN;
1415 return;
1416 }
1417
Chia-I Wuc3ddee62014-09-02 10:53:20 +08001418 if (sh->pcb_size) {
1419 const XGL_UINT alignment = 32;
1420 const XGL_SIZE size = u_align(sh->pcb_size, alignment);
1421 void *ptr;
1422
1423 pcb_len = size / alignment;
1424
1425 ptr = cmd_state_reserve(cmd, size / sizeof(uint32_t),
1426 alignment / sizeof(uint32_t), &pos);
1427 memcpy(ptr, sh->pcb, sh->pcb_size);
1428 cmd_state_advance(cmd, size / sizeof(uint32_t));
1429 }
1430
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001431 cmd_batch_reserve(cmd, cmd_len);
1432 cmd_batch_write(cmd, dw0);
Chia-I Wuc3ddee62014-09-02 10:53:20 +08001433 cmd_batch_write(cmd, pcb_len);
1434 cmd_batch_write(cmd, 0);
1435 cmd_batch_write(cmd, pos);
1436 cmd_batch_write(cmd, 0);
1437 cmd_batch_write(cmd, 0);
1438 cmd_batch_write(cmd, 0);
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001439}
1440
Chia-I Wu42a56202014-08-23 16:47:48 +08001441static void emit_ps_resources(struct intel_cmd *cmd,
Chia-I Wu20983762014-09-02 12:07:28 +08001442 const struct intel_pipeline_rmap *rmap)
Chia-I Wu42a56202014-08-23 16:47:48 +08001443{
1444 const XGL_UINT surface_count = rmap->rt_count +
1445 rmap->resource_count + rmap->uav_count;
1446 uint32_t binding_table[256];
1447 XGL_UINT pos, i;
1448
1449 assert(surface_count <= ARRAY_SIZE(binding_table));
1450
1451 for (i = 0; i < surface_count; i++) {
Chia-I Wu20983762014-09-02 12:07:28 +08001452 const struct intel_pipeline_rmap_slot *slot = &rmap->slots[i];
Chia-I Wu42a56202014-08-23 16:47:48 +08001453 uint32_t *dw;
1454
1455 switch (slot->path_len) {
1456 case 0:
1457 pos = 0;
1458 break;
Chia-I Wu20983762014-09-02 12:07:28 +08001459 case INTEL_PIPELINE_RMAP_SLOT_RT:
Chia-I Wu42a56202014-08-23 16:47:48 +08001460 {
1461 const struct intel_rt_view *view = cmd->bind.att.rt[i];
1462
1463 dw = cmd_state_reserve_reloc(cmd, view->cmd_len, 1,
1464 GEN6_ALIGNMENT_SURFACE_STATE, &pos);
1465
1466 memcpy(dw, view->cmd, sizeof(uint32_t) * view->cmd_len);
Chia-I Wubda55fd2014-08-25 12:46:10 +08001467 cmd_state_reloc(cmd, 1, view->cmd[1], view->img->obj.mem->bo,
Chia-I Wu32a22462014-08-26 14:13:46 +08001468 INTEL_RELOC_WRITE);
Chia-I Wu42a56202014-08-23 16:47:48 +08001469 cmd_state_advance(cmd, view->cmd_len);
1470 }
1471 break;
Chia-I Wu20983762014-09-02 12:07:28 +08001472 case INTEL_PIPELINE_RMAP_SLOT_DYN:
Chia-I Wu42a56202014-08-23 16:47:48 +08001473 {
1474 const struct intel_mem_view *view =
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001475 &cmd->bind.dyn_view.graphics;
Chia-I Wu42a56202014-08-23 16:47:48 +08001476
1477 dw = cmd_state_reserve_reloc(cmd, view->cmd_len, 1,
1478 GEN6_ALIGNMENT_SURFACE_STATE, &pos);
1479
1480 memcpy(dw, view->cmd, sizeof(uint32_t) * view->cmd_len);
Chia-I Wubda55fd2014-08-25 12:46:10 +08001481 cmd_state_reloc(cmd, 1, view->cmd[1], view->mem->bo,
Chia-I Wu32a22462014-08-26 14:13:46 +08001482 INTEL_RELOC_WRITE);
Chia-I Wu42a56202014-08-23 16:47:48 +08001483 cmd_state_advance(cmd, view->cmd_len);
1484 }
1485 break;
1486 case 1:
1487 default:
1488 /* TODO */
1489 assert(!"no dset support");
1490 break;
1491 }
1492
1493 binding_table[i] = pos << 2;
1494 }
1495
1496 pos = cmd_state_copy(cmd, binding_table, surface_count,
1497 GEN6_ALIGNMENT_BINDING_TABLE_STATE);
1498
1499 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
1500 gen7_3dstate_pointer(cmd,
1501 GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_PS, pos);
Chia-I Wu257e75e2014-08-29 14:06:35 +08001502
1503 gen7_3dstate_pointer(cmd,
1504 GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_VS, 0);
1505 gen7_3dstate_pointer(cmd,
1506 GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_HS, 0);
1507 gen7_3dstate_pointer(cmd,
1508 GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_DS, 0);
1509 gen7_3dstate_pointer(cmd,
1510 GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_GS, 0);
1511
1512 gen7_3dstate_pointer(cmd,
1513 GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_VS, 0);
1514 gen7_3dstate_pointer(cmd,
1515 GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_HS, 0);
1516 gen7_3dstate_pointer(cmd,
1517 GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_DS, 0);
1518 gen7_3dstate_pointer(cmd,
1519 GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_GS, 0);
1520 gen7_3dstate_pointer(cmd,
1521 GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_PS, 0);
Chia-I Wu42a56202014-08-23 16:47:48 +08001522 } else {
1523 gen6_3DSTATE_BINDING_TABLE_POINTERS(cmd, 0, 0, pos);
Chia-I Wu257e75e2014-08-29 14:06:35 +08001524 gen6_3DSTATE_SAMPLER_STATE_POINTERS(cmd, 0, 0, 0);
Chia-I Wu42a56202014-08-23 16:47:48 +08001525 }
1526}
1527
Courtney Goeltzenleuchter3d72e8c2014-08-29 16:27:47 -06001528static void gen6_3DSTATE_VS(struct intel_cmd *cmd)
1529{
Chia-I Wu72f9b8d2014-09-02 13:27:48 +08001530 const struct intel_pipeline *pipeline = cmd->bind.pipeline.graphics;
1531 const struct intel_pipeline_shader *vs = &pipeline->vs;
1532 const uint8_t cmd_len = 6;
Courtney Goeltzenleuchter3d72e8c2014-08-29 16:27:47 -06001533 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_VS) | (cmd_len - 2);
1534 uint32_t dw2, dw4, dw5;
Chia-I Wu72f9b8d2014-09-02 13:27:48 +08001535 int vue_read_len, max_threads;
Courtney Goeltzenleuchter3d72e8c2014-08-29 16:27:47 -06001536
1537 CMD_ASSERT(cmd, 6, 7.5);
1538
Courtney Goeltzenleuchter3d72e8c2014-08-29 16:27:47 -06001539 /*
Chia-I Wu72f9b8d2014-09-02 13:27:48 +08001540 * From the Sandy Bridge PRM, volume 2 part 1, page 135:
1541 *
1542 * "(Vertex URB Entry Read Length) Specifies the number of pairs of
1543 * 128-bit vertex elements to be passed into the payload for each
1544 * vertex."
1545 *
1546 * "It is UNDEFINED to set this field to 0 indicating no Vertex URB
1547 * data to be read and passed to the thread."
Courtney Goeltzenleuchter3d72e8c2014-08-29 16:27:47 -06001548 */
Chia-I Wu72f9b8d2014-09-02 13:27:48 +08001549 vue_read_len = (vs->in_count + 1) / 2;
1550 if (!vue_read_len)
1551 vue_read_len = 1;
1552
1553 dw2 = (vs->sampler_count + 3) / 4 << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT |
1554 vs->surface_count << GEN6_THREADDISP_BINDING_TABLE_SIZE__SHIFT;
1555
1556 dw4 = vs->urb_grf_start << GEN6_VS_DW4_URB_GRF_START__SHIFT |
1557 vue_read_len << GEN6_VS_DW4_URB_READ_LEN__SHIFT |
1558 0 << GEN6_VS_DW4_URB_READ_OFFSET__SHIFT;
Courtney Goeltzenleuchter3d72e8c2014-08-29 16:27:47 -06001559
1560 dw5 = GEN6_VS_DW5_STATISTICS |
1561 GEN6_VS_DW5_VS_ENABLE;
Chia-I Wu72f9b8d2014-09-02 13:27:48 +08001562
1563 switch (cmd_gen(cmd)) {
1564 case INTEL_GEN(7.5):
1565 max_threads = (cmd->dev->gpu->gt >= 2) ? 280 : 70;
1566 break;
1567 case INTEL_GEN(7):
1568 max_threads = (cmd->dev->gpu->gt == 2) ? 128 : 36;
1569 break;
1570 case INTEL_GEN(6):
1571 max_threads = (cmd->dev->gpu->gt == 2) ? 60 : 24;
1572 break;
1573 default:
1574 max_threads = 1;
1575 break;
Courtney Goeltzenleuchter3d72e8c2014-08-29 16:27:47 -06001576 }
1577
Chia-I Wu72f9b8d2014-09-02 13:27:48 +08001578 if (cmd_gen(cmd) >= INTEL_GEN(7.5))
1579 dw5 |= (max_threads - 1) << GEN75_VS_DW5_MAX_THREADS__SHIFT;
1580 else
1581 dw5 |= (max_threads - 1) << GEN6_VS_DW5_MAX_THREADS__SHIFT;
1582
Chia-I Wube0a3d92014-09-02 13:20:59 +08001583 if (pipeline->disable_vs_cache)
1584 dw5 |= GEN6_VS_DW5_CACHE_DISABLE;
1585
Courtney Goeltzenleuchter3d72e8c2014-08-29 16:27:47 -06001586 cmd_batch_reserve(cmd, cmd_len);
1587 cmd_batch_write(cmd, dw0);
1588 cmd_batch_write(cmd, cmd->bind.vs.kernel_pos);
1589 cmd_batch_write(cmd, dw2);
1590 cmd_batch_write(cmd, 0); /* scratch */
1591 cmd_batch_write(cmd, dw4);
1592 cmd_batch_write(cmd, dw5);
1593}
1594
Chia-I Wu52500102014-08-22 00:46:04 +08001595static void emit_bounded_states(struct intel_cmd *cmd)
1596{
1597 const struct intel_msaa_state *msaa = cmd->bind.state.msaa;
1598
1599 /* TODO more states */
1600
Chia-I Wu1744cca2014-08-22 11:10:17 +08001601 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
Chia-I Wu302742d2014-08-22 10:28:29 +08001602 gen7_cc_states(cmd);
Chia-I Wu1744cca2014-08-22 11:10:17 +08001603 gen7_viewport_states(cmd);
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001604
1605 gen7_pcb(cmd, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS,
1606 &cmd->bind.pipeline.graphics->vs);
1607 gen7_pcb(cmd, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_PS,
1608 &cmd->bind.pipeline.graphics->fs);
Chia-I Wu1f2fd292014-08-29 15:07:09 +08001609
Chia-I Wuc3f9c092014-08-30 14:29:29 +08001610 gen6_3DSTATE_CLIP(cmd);
Chia-I Wu8016a172014-08-29 18:31:32 +08001611 gen7_3DSTATE_SF(cmd);
1612 gen7_3DSTATE_SBE(cmd);
Chia-I Wu1f2fd292014-08-29 15:07:09 +08001613 gen7_3DSTATE_WM(cmd);
1614 gen7_3DSTATE_PS(cmd);
Chia-I Wu1744cca2014-08-22 11:10:17 +08001615 } else {
Chia-I Wu302742d2014-08-22 10:28:29 +08001616 gen6_cc_states(cmd);
Chia-I Wu1744cca2014-08-22 11:10:17 +08001617 gen6_viewport_states(cmd);
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001618
1619 gen6_pcb(cmd, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS,
1620 &cmd->bind.pipeline.graphics->vs);
1621 gen6_pcb(cmd, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_PS,
1622 &cmd->bind.pipeline.graphics->fs);
Chia-I Wu1f2fd292014-08-29 15:07:09 +08001623
Chia-I Wuc3f9c092014-08-30 14:29:29 +08001624 gen6_3DSTATE_CLIP(cmd);
Chia-I Wu8016a172014-08-29 18:31:32 +08001625 gen6_3DSTATE_SF(cmd);
Chia-I Wu1f2fd292014-08-29 15:07:09 +08001626 gen6_3DSTATE_WM(cmd);
Chia-I Wu1744cca2014-08-22 11:10:17 +08001627 }
Chia-I Wu302742d2014-08-22 10:28:29 +08001628
Chia-I Wuc3ddee62014-09-02 10:53:20 +08001629 emit_ps_resources(cmd, cmd->bind.pipeline.graphics->fs.rmap);
Chia-I Wu42a56202014-08-23 16:47:48 +08001630
Chia-I Wu8370b402014-08-29 12:28:37 +08001631 cmd_wa_gen6_pre_depth_stall_write(cmd);
1632 cmd_wa_gen6_pre_multisample_depth_flush(cmd);
Chia-I Wu9cb84ee2014-08-28 10:12:34 +08001633 /* 3DSTATE_MULTISAMPLE and 3DSTATE_SAMPLE_MASK */
Chia-I Wu52500102014-08-22 00:46:04 +08001634 cmd_batch_reserve(cmd, msaa->cmd_len);
1635 cmd_batch_write_n(cmd, msaa->cmd, msaa->cmd_len);
Courtney Goeltzenleuchter3d72e8c2014-08-29 16:27:47 -06001636
1637 gen6_3DSTATE_VS(cmd);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001638}
1639
1640static void emit_shader(struct intel_cmd *cmd,
Chia-I Wuf2b6d722014-09-02 08:52:27 +08001641 const struct intel_pipeline_shader *shader,
Courtney Goeltzenleuchterba305812014-08-28 17:27:47 -06001642 struct intel_cmd_shader *pCmdShader)
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001643{
1644 uint32_t i;
1645 struct intel_cmd_shader *cmdShader;
1646
1647 for (i=0; i<cmd->bind.shaderCache.used; i++) {
Chia-I Wu338fe642014-08-28 10:43:04 +08001648 if (cmd->bind.shaderCache.shaderArray[i].shader == shader) {
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001649 /* shader is already part of pipeline */
1650 return;
1651 }
1652 }
1653
Chia-I Wu338fe642014-08-28 10:43:04 +08001654 if (cmd->bind.shaderCache.used == cmd->bind.shaderCache.count) {
1655 const XGL_UINT new_count = cmd->bind.shaderCache.count + 16;
1656
1657 cmdShader = cmd->bind.shaderCache.shaderArray;
1658
1659 cmd->bind.shaderCache.shaderArray =
1660 icd_alloc(sizeof(*cmdShader) * new_count,
1661 0, XGL_SYSTEM_ALLOC_INTERNAL);
1662 if (cmd->bind.shaderCache.shaderArray == NULL) {
1663 cmd->bind.shaderCache.shaderArray = cmdShader;
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001664 cmd->result = XGL_ERROR_OUT_OF_MEMORY;
1665 return;
1666 }
Chia-I Wu338fe642014-08-28 10:43:04 +08001667
1668 if (cmdShader) {
1669 memcpy(cmd->bind.shaderCache.shaderArray, cmdShader,
1670 sizeof(*cmdShader) * cmd->bind.shaderCache.used);
1671 icd_free(cmdShader);
1672 }
1673
1674 cmd->bind.shaderCache.count = new_count;
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001675 }
1676
Chia-I Wu338fe642014-08-28 10:43:04 +08001677 cmdShader = &cmd->bind.shaderCache.shaderArray[cmd->bind.shaderCache.used];
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001678 cmdShader->shader = shader;
1679 cmdShader->kernel_pos = cmd_kernel_copy(cmd, shader->pCode, shader->codeSize);
Courtney Goeltzenleuchterba305812014-08-28 17:27:47 -06001680 *pCmdShader = *cmdShader;
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001681 cmd->bind.shaderCache.used++;
1682 return;
1683}
1684
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001685static void cmd_bind_graphics_pipeline(struct intel_cmd *cmd,
Chia-I Wu338fe642014-08-28 10:43:04 +08001686 const struct intel_pipeline *pipeline)
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001687{
1688 cmd->bind.pipeline.graphics = pipeline;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001689
Chia-I Wu8370b402014-08-29 12:28:37 +08001690 if (pipeline->wa_flags & INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE)
1691 cmd_wa_gen6_pre_depth_stall_write(cmd);
1692 if (pipeline->wa_flags & INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL)
1693 cmd_wa_gen6_pre_command_scoreboard_stall(cmd);
1694 if (pipeline->wa_flags & INTEL_CMD_WA_GEN7_PRE_VS_DEPTH_STALL_WRITE)
1695 cmd_wa_gen7_pre_vs_depth_stall_write(cmd);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001696
1697 /* 3DSTATE_URB_VS and etc. */
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -06001698 assert(pipeline->cmd_len);
Chia-I Wub08727d2014-08-29 14:54:54 +08001699 cmd_batch_reserve(cmd, pipeline->cmd_len);
Courtney Goeltzenleuchterba305812014-08-28 17:27:47 -06001700 cmd_batch_write_n(cmd, pipeline->cmds, pipeline->cmd_len);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001701
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001702 if (pipeline->active_shaders & SHADER_VERTEX_FLAG) {
Chia-I Wuc3ddee62014-09-02 10:53:20 +08001703 emit_shader(cmd, &pipeline->vs, &cmd->bind.vs);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001704 }
1705 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
Courtney Goeltzenleuchterba305812014-08-28 17:27:47 -06001706 emit_shader(cmd, &pipeline->gs, &cmd->bind.gs);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001707 }
1708 if (pipeline->active_shaders & SHADER_FRAGMENT_FLAG) {
Chia-I Wuc3ddee62014-09-02 10:53:20 +08001709 emit_shader(cmd, &pipeline->fs, &cmd->bind.fs);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001710 }
1711 if (pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) {
Chia-I Wu95959fb2014-09-02 11:01:03 +08001712 emit_shader(cmd, &pipeline->tcs, &cmd->bind.tcs);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001713 }
1714 if (pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) {
Chia-I Wu95959fb2014-09-02 11:01:03 +08001715 emit_shader(cmd, &pipeline->tes, &cmd->bind.tes);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001716 }
Courtney Goeltzenleuchter68d9bef2014-08-28 17:35:03 -06001717
Chia-I Wud95aa2b2014-08-29 12:07:47 +08001718 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
1719 gen7_3DSTATE_GS(cmd);
1720 } else {
1721 gen6_3DSTATE_GS(cmd);
1722 }
Courtney Goeltzenleuchterf782a852014-08-28 17:44:53 -06001723
Chia-I Wu8370b402014-08-29 12:28:37 +08001724 if (pipeline->wa_flags & INTEL_CMD_WA_GEN7_POST_COMMAND_CS_STALL)
1725 cmd_wa_gen7_post_command_cs_stall(cmd);
1726 if (pipeline->wa_flags & INTEL_CMD_WA_GEN7_POST_COMMAND_DEPTH_STALL)
1727 cmd_wa_gen7_post_command_depth_stall(cmd);
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001728}
1729
1730static void cmd_bind_compute_pipeline(struct intel_cmd *cmd,
1731 const struct intel_pipeline *pipeline)
1732{
1733 cmd->bind.pipeline.compute = pipeline;
1734}
1735
1736static void cmd_bind_graphics_delta(struct intel_cmd *cmd,
1737 const struct intel_pipeline_delta *delta)
1738{
1739 cmd->bind.pipeline.graphics_delta = delta;
1740}
1741
1742static void cmd_bind_compute_delta(struct intel_cmd *cmd,
1743 const struct intel_pipeline_delta *delta)
1744{
1745 cmd->bind.pipeline.compute_delta = delta;
1746}
1747
1748static void cmd_bind_graphics_dset(struct intel_cmd *cmd,
1749 const struct intel_dset *dset,
1750 XGL_UINT slot_offset)
1751{
1752 cmd->bind.dset.graphics = dset;
1753 cmd->bind.dset.graphics_offset = slot_offset;
1754}
1755
1756static void cmd_bind_compute_dset(struct intel_cmd *cmd,
1757 const struct intel_dset *dset,
1758 XGL_UINT slot_offset)
1759{
1760 cmd->bind.dset.compute = dset;
1761 cmd->bind.dset.compute_offset = slot_offset;
1762}
1763
1764static void cmd_bind_graphics_dyn_view(struct intel_cmd *cmd,
1765 const XGL_MEMORY_VIEW_ATTACH_INFO *info)
1766{
1767 intel_mem_view_init(&cmd->bind.dyn_view.graphics, cmd->dev, info);
1768}
1769
1770static void cmd_bind_compute_dyn_view(struct intel_cmd *cmd,
1771 const XGL_MEMORY_VIEW_ATTACH_INFO *info)
1772{
1773 intel_mem_view_init(&cmd->bind.dyn_view.compute, cmd->dev, info);
1774}
1775
1776static void cmd_bind_index_data(struct intel_cmd *cmd,
1777 const struct intel_mem *mem,
1778 XGL_GPU_SIZE offset, XGL_INDEX_TYPE type)
1779{
1780 if (cmd_gen(cmd) >= INTEL_GEN(7.5)) {
1781 gen6_3DSTATE_INDEX_BUFFER(cmd, mem, offset, type, false);
1782 } else {
1783 cmd->bind.index.mem = mem;
1784 cmd->bind.index.offset = offset;
1785 cmd->bind.index.type = type;
1786 }
1787}
1788
1789static void cmd_bind_rt(struct intel_cmd *cmd,
1790 const XGL_COLOR_ATTACHMENT_BIND_INFO *attachments,
1791 XGL_UINT count)
1792{
Chia-I Wud88e02d2014-08-25 10:56:13 +08001793 XGL_UINT width = 0, height = 0;
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001794 XGL_UINT i;
1795
1796 for (i = 0; i < count; i++) {
1797 const XGL_COLOR_ATTACHMENT_BIND_INFO *att = &attachments[i];
1798 const struct intel_rt_view *rt = intel_rt_view(att->view);
Chia-I Wud88e02d2014-08-25 10:56:13 +08001799 const struct intel_layout *layout = &rt->img->layout;
1800
1801 if (i == 0) {
1802 width = layout->width0;
1803 height = layout->height0;
1804 } else {
1805 if (width > layout->width0)
1806 width = layout->width0;
1807 if (height > layout->height0)
1808 height = layout->height0;
1809 }
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001810
1811 cmd->bind.att.rt[i] = rt;
1812 }
1813
1814 cmd->bind.att.rt_count = count;
Chia-I Wud88e02d2014-08-25 10:56:13 +08001815
Chia-I Wu8370b402014-08-29 12:28:37 +08001816 cmd_wa_gen6_pre_depth_stall_write(cmd);
Chia-I Wud88e02d2014-08-25 10:56:13 +08001817 gen6_3DSTATE_DRAWING_RECTANGLE(cmd, width, height);
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001818}
1819
1820static void cmd_bind_ds(struct intel_cmd *cmd,
1821 const XGL_DEPTH_STENCIL_BIND_INFO *info)
1822{
1823 const struct intel_ds_view *ds;
1824
1825 if (info) {
1826 cmd->bind.att.ds = intel_ds_view(info->view);
1827 ds = cmd->bind.att.ds;
1828 } else {
1829 /* all zeros */
1830 static const struct intel_ds_view null_ds;
1831 ds = &null_ds;
1832 }
1833
Chia-I Wu8370b402014-08-29 12:28:37 +08001834 cmd_wa_gen6_pre_ds_flush(cmd);
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001835 gen6_3DSTATE_DEPTH_BUFFER(cmd, ds);
1836 gen6_3DSTATE_STENCIL_BUFFER(cmd, ds);
1837 gen6_3DSTATE_HIER_DEPTH_BUFFER(cmd, ds);
Chia-I Wuf8231032014-08-25 10:44:45 +08001838
1839 if (cmd_gen(cmd) >= INTEL_GEN(7))
1840 gen7_3DSTATE_CLEAR_PARAMS(cmd, 0);
1841 else
1842 gen6_3DSTATE_CLEAR_PARAMS(cmd, 0);
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001843}
1844
1845static void cmd_bind_viewport_state(struct intel_cmd *cmd,
1846 const struct intel_viewport_state *state)
1847{
1848 cmd->bind.state.viewport = state;
1849}
1850
1851static void cmd_bind_raster_state(struct intel_cmd *cmd,
1852 const struct intel_raster_state *state)
1853{
1854 cmd->bind.state.raster = state;
1855}
1856
1857static void cmd_bind_ds_state(struct intel_cmd *cmd,
1858 const struct intel_ds_state *state)
1859{
1860 cmd->bind.state.ds = state;
1861}
1862
1863static void cmd_bind_blend_state(struct intel_cmd *cmd,
1864 const struct intel_blend_state *state)
1865{
1866 cmd->bind.state.blend = state;
1867}
1868
1869static void cmd_bind_msaa_state(struct intel_cmd *cmd,
1870 const struct intel_msaa_state *state)
1871{
1872 cmd->bind.state.msaa = state;
1873}
1874
1875static void cmd_draw(struct intel_cmd *cmd,
1876 XGL_UINT vertex_start,
1877 XGL_UINT vertex_count,
1878 XGL_UINT instance_start,
1879 XGL_UINT instance_count,
1880 bool indexed,
1881 XGL_UINT vertex_base)
1882{
1883 const struct intel_pipeline *p = cmd->bind.pipeline.graphics;
1884
1885 emit_bounded_states(cmd);
1886
1887 if (indexed) {
1888 if (p->primitive_restart && !gen6_can_primitive_restart(cmd))
1889 cmd->result = XGL_ERROR_UNKNOWN;
1890
1891 if (cmd_gen(cmd) >= INTEL_GEN(7.5)) {
1892 gen75_3DSTATE_VF(cmd, p->primitive_restart,
1893 p->primitive_restart_index);
1894 } else {
1895 gen6_3DSTATE_INDEX_BUFFER(cmd, cmd->bind.index.mem,
1896 cmd->bind.index.offset, cmd->bind.index.type,
1897 p->primitive_restart);
1898 }
1899 } else {
1900 assert(!vertex_base);
1901 }
1902
1903 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
1904 gen7_3DPRIMITIVE(cmd, p->prim_type, indexed, vertex_count,
1905 vertex_start, instance_count, instance_start, vertex_base);
1906 } else {
1907 gen6_3DPRIMITIVE(cmd, p->prim_type, indexed, vertex_count,
1908 vertex_start, instance_count, instance_start, vertex_base);
1909 }
Chia-I Wu48c283d2014-08-25 23:13:46 +08001910
Chia-I Wu707a29e2014-08-27 12:51:47 +08001911 cmd->bind.draw_count++;
Chia-I Wu48c283d2014-08-25 23:13:46 +08001912 /* need to re-emit all workarounds */
1913 cmd->bind.wa_flags = 0;
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001914}
1915
Chia-I Wub2755562014-08-20 13:38:52 +08001916XGL_VOID XGLAPI intelCmdBindPipeline(
1917 XGL_CMD_BUFFER cmdBuffer,
1918 XGL_PIPELINE_BIND_POINT pipelineBindPoint,
1919 XGL_PIPELINE pipeline)
1920{
1921 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
1922
1923 switch (pipelineBindPoint) {
1924 case XGL_PIPELINE_BIND_POINT_COMPUTE:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001925 cmd_bind_compute_pipeline(cmd, intel_pipeline(pipeline));
Chia-I Wub2755562014-08-20 13:38:52 +08001926 break;
1927 case XGL_PIPELINE_BIND_POINT_GRAPHICS:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001928 cmd_bind_graphics_pipeline(cmd, intel_pipeline(pipeline));
Chia-I Wub2755562014-08-20 13:38:52 +08001929 break;
1930 default:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001931 cmd->result = XGL_ERROR_INVALID_VALUE;
Chia-I Wub2755562014-08-20 13:38:52 +08001932 break;
1933 }
1934}
1935
1936XGL_VOID XGLAPI intelCmdBindPipelineDelta(
1937 XGL_CMD_BUFFER cmdBuffer,
1938 XGL_PIPELINE_BIND_POINT pipelineBindPoint,
1939 XGL_PIPELINE_DELTA delta)
1940{
1941 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
1942
1943 switch (pipelineBindPoint) {
1944 case XGL_PIPELINE_BIND_POINT_COMPUTE:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001945 cmd_bind_compute_delta(cmd, delta);
Chia-I Wub2755562014-08-20 13:38:52 +08001946 break;
1947 case XGL_PIPELINE_BIND_POINT_GRAPHICS:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001948 cmd_bind_graphics_delta(cmd, delta);
Chia-I Wub2755562014-08-20 13:38:52 +08001949 break;
1950 default:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001951 cmd->result = XGL_ERROR_INVALID_VALUE;
Chia-I Wub2755562014-08-20 13:38:52 +08001952 break;
1953 }
1954}
1955
1956XGL_VOID XGLAPI intelCmdBindStateObject(
1957 XGL_CMD_BUFFER cmdBuffer,
1958 XGL_STATE_BIND_POINT stateBindPoint,
1959 XGL_STATE_OBJECT state)
1960{
1961 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
1962
1963 switch (stateBindPoint) {
1964 case XGL_STATE_BIND_VIEWPORT:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001965 cmd_bind_viewport_state(cmd,
1966 intel_viewport_state((XGL_VIEWPORT_STATE_OBJECT) state));
Chia-I Wub2755562014-08-20 13:38:52 +08001967 break;
1968 case XGL_STATE_BIND_RASTER:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001969 cmd_bind_raster_state(cmd,
1970 intel_raster_state((XGL_RASTER_STATE_OBJECT) state));
Chia-I Wub2755562014-08-20 13:38:52 +08001971 break;
1972 case XGL_STATE_BIND_DEPTH_STENCIL:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001973 cmd_bind_ds_state(cmd,
1974 intel_ds_state((XGL_DEPTH_STENCIL_STATE_OBJECT) state));
Chia-I Wub2755562014-08-20 13:38:52 +08001975 break;
1976 case XGL_STATE_BIND_COLOR_BLEND:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001977 cmd_bind_blend_state(cmd,
1978 intel_blend_state((XGL_COLOR_BLEND_STATE_OBJECT) state));
Chia-I Wub2755562014-08-20 13:38:52 +08001979 break;
1980 case XGL_STATE_BIND_MSAA:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001981 cmd_bind_msaa_state(cmd,
1982 intel_msaa_state((XGL_MSAA_STATE_OBJECT) state));
Chia-I Wub2755562014-08-20 13:38:52 +08001983 break;
1984 default:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001985 cmd->result = XGL_ERROR_INVALID_VALUE;
Chia-I Wub2755562014-08-20 13:38:52 +08001986 break;
1987 }
1988}
1989
1990XGL_VOID XGLAPI intelCmdBindDescriptorSet(
1991 XGL_CMD_BUFFER cmdBuffer,
1992 XGL_PIPELINE_BIND_POINT pipelineBindPoint,
1993 XGL_UINT index,
1994 XGL_DESCRIPTOR_SET descriptorSet,
1995 XGL_UINT slotOffset)
1996{
1997 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
1998 struct intel_dset *dset = intel_dset(descriptorSet);
1999
2000 assert(!index);
2001
2002 switch (pipelineBindPoint) {
2003 case XGL_PIPELINE_BIND_POINT_COMPUTE:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002004 cmd_bind_compute_dset(cmd, dset, slotOffset);
Chia-I Wub2755562014-08-20 13:38:52 +08002005 break;
2006 case XGL_PIPELINE_BIND_POINT_GRAPHICS:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002007 cmd_bind_graphics_dset(cmd, dset, slotOffset);
Chia-I Wub2755562014-08-20 13:38:52 +08002008 break;
2009 default:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002010 cmd->result = XGL_ERROR_INVALID_VALUE;
Chia-I Wub2755562014-08-20 13:38:52 +08002011 break;
2012 }
2013}
2014
2015XGL_VOID XGLAPI intelCmdBindDynamicMemoryView(
2016 XGL_CMD_BUFFER cmdBuffer,
2017 XGL_PIPELINE_BIND_POINT pipelineBindPoint,
2018 const XGL_MEMORY_VIEW_ATTACH_INFO* pMemView)
2019{
2020 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
2021
2022 switch (pipelineBindPoint) {
2023 case XGL_PIPELINE_BIND_POINT_COMPUTE:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002024 cmd_bind_compute_dyn_view(cmd, pMemView);
Chia-I Wub2755562014-08-20 13:38:52 +08002025 break;
2026 case XGL_PIPELINE_BIND_POINT_GRAPHICS:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002027 cmd_bind_graphics_dyn_view(cmd, pMemView);
Chia-I Wub2755562014-08-20 13:38:52 +08002028 break;
2029 default:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002030 cmd->result = XGL_ERROR_INVALID_VALUE;
Chia-I Wub2755562014-08-20 13:38:52 +08002031 break;
2032 }
2033}
2034
2035XGL_VOID XGLAPI intelCmdBindIndexData(
2036 XGL_CMD_BUFFER cmdBuffer,
2037 XGL_GPU_MEMORY mem_,
2038 XGL_GPU_SIZE offset,
2039 XGL_INDEX_TYPE indexType)
2040{
2041 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
2042 struct intel_mem *mem = intel_mem(mem_);
2043
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002044 cmd_bind_index_data(cmd, mem, offset, indexType);
Chia-I Wub2755562014-08-20 13:38:52 +08002045}
2046
2047XGL_VOID XGLAPI intelCmdBindAttachments(
2048 XGL_CMD_BUFFER cmdBuffer,
2049 XGL_UINT colorAttachmentCount,
2050 const XGL_COLOR_ATTACHMENT_BIND_INFO* pColorAttachments,
2051 const XGL_DEPTH_STENCIL_BIND_INFO* pDepthStencilAttachment)
2052{
2053 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
Chia-I Wub2755562014-08-20 13:38:52 +08002054
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002055 cmd_bind_rt(cmd, pColorAttachments, colorAttachmentCount);
2056 cmd_bind_ds(cmd, pDepthStencilAttachment);
Chia-I Wub2755562014-08-20 13:38:52 +08002057}
2058
2059XGL_VOID XGLAPI intelCmdDraw(
2060 XGL_CMD_BUFFER cmdBuffer,
2061 XGL_UINT firstVertex,
2062 XGL_UINT vertexCount,
2063 XGL_UINT firstInstance,
2064 XGL_UINT instanceCount)
2065{
Chia-I Wu59c097e2014-08-21 10:51:07 +08002066 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
Chia-I Wu59c097e2014-08-21 10:51:07 +08002067
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002068 cmd_draw(cmd, firstVertex, vertexCount,
2069 firstInstance, instanceCount, false, 0);
Chia-I Wub2755562014-08-20 13:38:52 +08002070}
2071
2072XGL_VOID XGLAPI intelCmdDrawIndexed(
2073 XGL_CMD_BUFFER cmdBuffer,
2074 XGL_UINT firstIndex,
2075 XGL_UINT indexCount,
2076 XGL_INT vertexOffset,
2077 XGL_UINT firstInstance,
2078 XGL_UINT instanceCount)
2079{
Chia-I Wu59c097e2014-08-21 10:51:07 +08002080 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
Chia-I Wu59c097e2014-08-21 10:51:07 +08002081
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002082 cmd_draw(cmd, firstIndex, indexCount,
2083 firstInstance, instanceCount, true, vertexOffset);
Chia-I Wub2755562014-08-20 13:38:52 +08002084}
2085
2086XGL_VOID XGLAPI intelCmdDrawIndirect(
2087 XGL_CMD_BUFFER cmdBuffer,
2088 XGL_GPU_MEMORY mem,
2089 XGL_GPU_SIZE offset,
2090 XGL_UINT32 count,
2091 XGL_UINT32 stride)
2092{
Chia-I Wu59c097e2014-08-21 10:51:07 +08002093 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
2094
2095 cmd->result = XGL_ERROR_UNKNOWN;
Chia-I Wub2755562014-08-20 13:38:52 +08002096}
2097
2098XGL_VOID XGLAPI intelCmdDrawIndexedIndirect(
2099 XGL_CMD_BUFFER cmdBuffer,
2100 XGL_GPU_MEMORY mem,
2101 XGL_GPU_SIZE offset,
2102 XGL_UINT32 count,
2103 XGL_UINT32 stride)
2104{
Chia-I Wu59c097e2014-08-21 10:51:07 +08002105 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
2106
2107 cmd->result = XGL_ERROR_UNKNOWN;
Chia-I Wub2755562014-08-20 13:38:52 +08002108}
2109
2110XGL_VOID XGLAPI intelCmdDispatch(
2111 XGL_CMD_BUFFER cmdBuffer,
2112 XGL_UINT x,
2113 XGL_UINT y,
2114 XGL_UINT z)
2115{
Chia-I Wu59c097e2014-08-21 10:51:07 +08002116 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
2117
2118 cmd->result = XGL_ERROR_UNKNOWN;
Chia-I Wub2755562014-08-20 13:38:52 +08002119}
2120
2121XGL_VOID XGLAPI intelCmdDispatchIndirect(
2122 XGL_CMD_BUFFER cmdBuffer,
2123 XGL_GPU_MEMORY mem,
2124 XGL_GPU_SIZE offset)
2125{
Chia-I Wu59c097e2014-08-21 10:51:07 +08002126 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
2127
2128 cmd->result = XGL_ERROR_UNKNOWN;
Chia-I Wub2755562014-08-20 13:38:52 +08002129}