blob: a21ebb56c256cb12be1916d0007dc88027cfb18d [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
Courtney Goeltzenleuchter3d72e8c2014-08-29 16:27:47 -06001583 cmd_batch_reserve(cmd, cmd_len);
1584 cmd_batch_write(cmd, dw0);
1585 cmd_batch_write(cmd, cmd->bind.vs.kernel_pos);
1586 cmd_batch_write(cmd, dw2);
1587 cmd_batch_write(cmd, 0); /* scratch */
1588 cmd_batch_write(cmd, dw4);
1589 cmd_batch_write(cmd, dw5);
1590}
1591
Chia-I Wu52500102014-08-22 00:46:04 +08001592static void emit_bounded_states(struct intel_cmd *cmd)
1593{
1594 const struct intel_msaa_state *msaa = cmd->bind.state.msaa;
1595
1596 /* TODO more states */
1597
Chia-I Wu1744cca2014-08-22 11:10:17 +08001598 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
Chia-I Wu302742d2014-08-22 10:28:29 +08001599 gen7_cc_states(cmd);
Chia-I Wu1744cca2014-08-22 11:10:17 +08001600 gen7_viewport_states(cmd);
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001601
1602 gen7_pcb(cmd, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS,
1603 &cmd->bind.pipeline.graphics->vs);
1604 gen7_pcb(cmd, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_PS,
1605 &cmd->bind.pipeline.graphics->fs);
Chia-I Wu1f2fd292014-08-29 15:07:09 +08001606
Chia-I Wuc3f9c092014-08-30 14:29:29 +08001607 gen6_3DSTATE_CLIP(cmd);
Chia-I Wu8016a172014-08-29 18:31:32 +08001608 gen7_3DSTATE_SF(cmd);
1609 gen7_3DSTATE_SBE(cmd);
Chia-I Wu1f2fd292014-08-29 15:07:09 +08001610 gen7_3DSTATE_WM(cmd);
1611 gen7_3DSTATE_PS(cmd);
Chia-I Wu1744cca2014-08-22 11:10:17 +08001612 } else {
Chia-I Wu302742d2014-08-22 10:28:29 +08001613 gen6_cc_states(cmd);
Chia-I Wu1744cca2014-08-22 11:10:17 +08001614 gen6_viewport_states(cmd);
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001615
1616 gen6_pcb(cmd, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS,
1617 &cmd->bind.pipeline.graphics->vs);
1618 gen6_pcb(cmd, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_PS,
1619 &cmd->bind.pipeline.graphics->fs);
Chia-I Wu1f2fd292014-08-29 15:07:09 +08001620
Chia-I Wuc3f9c092014-08-30 14:29:29 +08001621 gen6_3DSTATE_CLIP(cmd);
Chia-I Wu8016a172014-08-29 18:31:32 +08001622 gen6_3DSTATE_SF(cmd);
Chia-I Wu1f2fd292014-08-29 15:07:09 +08001623 gen6_3DSTATE_WM(cmd);
Chia-I Wu1744cca2014-08-22 11:10:17 +08001624 }
Chia-I Wu302742d2014-08-22 10:28:29 +08001625
Chia-I Wuc3ddee62014-09-02 10:53:20 +08001626 emit_ps_resources(cmd, cmd->bind.pipeline.graphics->fs.rmap);
Chia-I Wu42a56202014-08-23 16:47:48 +08001627
Chia-I Wu8370b402014-08-29 12:28:37 +08001628 cmd_wa_gen6_pre_depth_stall_write(cmd);
1629 cmd_wa_gen6_pre_multisample_depth_flush(cmd);
Chia-I Wu9cb84ee2014-08-28 10:12:34 +08001630 /* 3DSTATE_MULTISAMPLE and 3DSTATE_SAMPLE_MASK */
Chia-I Wu52500102014-08-22 00:46:04 +08001631 cmd_batch_reserve(cmd, msaa->cmd_len);
1632 cmd_batch_write_n(cmd, msaa->cmd, msaa->cmd_len);
Courtney Goeltzenleuchter3d72e8c2014-08-29 16:27:47 -06001633
1634 gen6_3DSTATE_VS(cmd);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001635}
1636
1637static void emit_shader(struct intel_cmd *cmd,
Chia-I Wuf2b6d722014-09-02 08:52:27 +08001638 const struct intel_pipeline_shader *shader,
Courtney Goeltzenleuchterba305812014-08-28 17:27:47 -06001639 struct intel_cmd_shader *pCmdShader)
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001640{
1641 uint32_t i;
1642 struct intel_cmd_shader *cmdShader;
1643
1644 for (i=0; i<cmd->bind.shaderCache.used; i++) {
Chia-I Wu338fe642014-08-28 10:43:04 +08001645 if (cmd->bind.shaderCache.shaderArray[i].shader == shader) {
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001646 /* shader is already part of pipeline */
1647 return;
1648 }
1649 }
1650
Chia-I Wu338fe642014-08-28 10:43:04 +08001651 if (cmd->bind.shaderCache.used == cmd->bind.shaderCache.count) {
1652 const XGL_UINT new_count = cmd->bind.shaderCache.count + 16;
1653
1654 cmdShader = cmd->bind.shaderCache.shaderArray;
1655
1656 cmd->bind.shaderCache.shaderArray =
1657 icd_alloc(sizeof(*cmdShader) * new_count,
1658 0, XGL_SYSTEM_ALLOC_INTERNAL);
1659 if (cmd->bind.shaderCache.shaderArray == NULL) {
1660 cmd->bind.shaderCache.shaderArray = cmdShader;
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001661 cmd->result = XGL_ERROR_OUT_OF_MEMORY;
1662 return;
1663 }
Chia-I Wu338fe642014-08-28 10:43:04 +08001664
1665 if (cmdShader) {
1666 memcpy(cmd->bind.shaderCache.shaderArray, cmdShader,
1667 sizeof(*cmdShader) * cmd->bind.shaderCache.used);
1668 icd_free(cmdShader);
1669 }
1670
1671 cmd->bind.shaderCache.count = new_count;
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001672 }
1673
Chia-I Wu338fe642014-08-28 10:43:04 +08001674 cmdShader = &cmd->bind.shaderCache.shaderArray[cmd->bind.shaderCache.used];
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001675 cmdShader->shader = shader;
1676 cmdShader->kernel_pos = cmd_kernel_copy(cmd, shader->pCode, shader->codeSize);
Courtney Goeltzenleuchterba305812014-08-28 17:27:47 -06001677 *pCmdShader = *cmdShader;
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001678 cmd->bind.shaderCache.used++;
1679 return;
1680}
1681
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001682static void cmd_bind_graphics_pipeline(struct intel_cmd *cmd,
Chia-I Wu338fe642014-08-28 10:43:04 +08001683 const struct intel_pipeline *pipeline)
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001684{
1685 cmd->bind.pipeline.graphics = pipeline;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001686
Chia-I Wu8370b402014-08-29 12:28:37 +08001687 if (pipeline->wa_flags & INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE)
1688 cmd_wa_gen6_pre_depth_stall_write(cmd);
1689 if (pipeline->wa_flags & INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL)
1690 cmd_wa_gen6_pre_command_scoreboard_stall(cmd);
1691 if (pipeline->wa_flags & INTEL_CMD_WA_GEN7_PRE_VS_DEPTH_STALL_WRITE)
1692 cmd_wa_gen7_pre_vs_depth_stall_write(cmd);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001693
1694 /* 3DSTATE_URB_VS and etc. */
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -06001695 assert(pipeline->cmd_len);
Chia-I Wub08727d2014-08-29 14:54:54 +08001696 cmd_batch_reserve(cmd, pipeline->cmd_len);
Courtney Goeltzenleuchterba305812014-08-28 17:27:47 -06001697 cmd_batch_write_n(cmd, pipeline->cmds, pipeline->cmd_len);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001698
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001699 if (pipeline->active_shaders & SHADER_VERTEX_FLAG) {
Chia-I Wuc3ddee62014-09-02 10:53:20 +08001700 emit_shader(cmd, &pipeline->vs, &cmd->bind.vs);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001701 }
1702 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
Courtney Goeltzenleuchterba305812014-08-28 17:27:47 -06001703 emit_shader(cmd, &pipeline->gs, &cmd->bind.gs);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001704 }
1705 if (pipeline->active_shaders & SHADER_FRAGMENT_FLAG) {
Chia-I Wuc3ddee62014-09-02 10:53:20 +08001706 emit_shader(cmd, &pipeline->fs, &cmd->bind.fs);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001707 }
1708 if (pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) {
Chia-I Wu95959fb2014-09-02 11:01:03 +08001709 emit_shader(cmd, &pipeline->tcs, &cmd->bind.tcs);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001710 }
1711 if (pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) {
Chia-I Wu95959fb2014-09-02 11:01:03 +08001712 emit_shader(cmd, &pipeline->tes, &cmd->bind.tes);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001713 }
Courtney Goeltzenleuchter68d9bef2014-08-28 17:35:03 -06001714
Chia-I Wud95aa2b2014-08-29 12:07:47 +08001715 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
1716 gen7_3DSTATE_GS(cmd);
1717 } else {
1718 gen6_3DSTATE_GS(cmd);
1719 }
Courtney Goeltzenleuchterf782a852014-08-28 17:44:53 -06001720
Chia-I Wu8370b402014-08-29 12:28:37 +08001721 if (pipeline->wa_flags & INTEL_CMD_WA_GEN7_POST_COMMAND_CS_STALL)
1722 cmd_wa_gen7_post_command_cs_stall(cmd);
1723 if (pipeline->wa_flags & INTEL_CMD_WA_GEN7_POST_COMMAND_DEPTH_STALL)
1724 cmd_wa_gen7_post_command_depth_stall(cmd);
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001725}
1726
1727static void cmd_bind_compute_pipeline(struct intel_cmd *cmd,
1728 const struct intel_pipeline *pipeline)
1729{
1730 cmd->bind.pipeline.compute = pipeline;
1731}
1732
1733static void cmd_bind_graphics_delta(struct intel_cmd *cmd,
1734 const struct intel_pipeline_delta *delta)
1735{
1736 cmd->bind.pipeline.graphics_delta = delta;
1737}
1738
1739static void cmd_bind_compute_delta(struct intel_cmd *cmd,
1740 const struct intel_pipeline_delta *delta)
1741{
1742 cmd->bind.pipeline.compute_delta = delta;
1743}
1744
1745static void cmd_bind_graphics_dset(struct intel_cmd *cmd,
1746 const struct intel_dset *dset,
1747 XGL_UINT slot_offset)
1748{
1749 cmd->bind.dset.graphics = dset;
1750 cmd->bind.dset.graphics_offset = slot_offset;
1751}
1752
1753static void cmd_bind_compute_dset(struct intel_cmd *cmd,
1754 const struct intel_dset *dset,
1755 XGL_UINT slot_offset)
1756{
1757 cmd->bind.dset.compute = dset;
1758 cmd->bind.dset.compute_offset = slot_offset;
1759}
1760
1761static void cmd_bind_graphics_dyn_view(struct intel_cmd *cmd,
1762 const XGL_MEMORY_VIEW_ATTACH_INFO *info)
1763{
1764 intel_mem_view_init(&cmd->bind.dyn_view.graphics, cmd->dev, info);
1765}
1766
1767static void cmd_bind_compute_dyn_view(struct intel_cmd *cmd,
1768 const XGL_MEMORY_VIEW_ATTACH_INFO *info)
1769{
1770 intel_mem_view_init(&cmd->bind.dyn_view.compute, cmd->dev, info);
1771}
1772
1773static void cmd_bind_index_data(struct intel_cmd *cmd,
1774 const struct intel_mem *mem,
1775 XGL_GPU_SIZE offset, XGL_INDEX_TYPE type)
1776{
1777 if (cmd_gen(cmd) >= INTEL_GEN(7.5)) {
1778 gen6_3DSTATE_INDEX_BUFFER(cmd, mem, offset, type, false);
1779 } else {
1780 cmd->bind.index.mem = mem;
1781 cmd->bind.index.offset = offset;
1782 cmd->bind.index.type = type;
1783 }
1784}
1785
1786static void cmd_bind_rt(struct intel_cmd *cmd,
1787 const XGL_COLOR_ATTACHMENT_BIND_INFO *attachments,
1788 XGL_UINT count)
1789{
Chia-I Wud88e02d2014-08-25 10:56:13 +08001790 XGL_UINT width = 0, height = 0;
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001791 XGL_UINT i;
1792
1793 for (i = 0; i < count; i++) {
1794 const XGL_COLOR_ATTACHMENT_BIND_INFO *att = &attachments[i];
1795 const struct intel_rt_view *rt = intel_rt_view(att->view);
Chia-I Wud88e02d2014-08-25 10:56:13 +08001796 const struct intel_layout *layout = &rt->img->layout;
1797
1798 if (i == 0) {
1799 width = layout->width0;
1800 height = layout->height0;
1801 } else {
1802 if (width > layout->width0)
1803 width = layout->width0;
1804 if (height > layout->height0)
1805 height = layout->height0;
1806 }
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001807
1808 cmd->bind.att.rt[i] = rt;
1809 }
1810
1811 cmd->bind.att.rt_count = count;
Chia-I Wud88e02d2014-08-25 10:56:13 +08001812
Chia-I Wu8370b402014-08-29 12:28:37 +08001813 cmd_wa_gen6_pre_depth_stall_write(cmd);
Chia-I Wud88e02d2014-08-25 10:56:13 +08001814 gen6_3DSTATE_DRAWING_RECTANGLE(cmd, width, height);
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001815}
1816
1817static void cmd_bind_ds(struct intel_cmd *cmd,
1818 const XGL_DEPTH_STENCIL_BIND_INFO *info)
1819{
1820 const struct intel_ds_view *ds;
1821
1822 if (info) {
1823 cmd->bind.att.ds = intel_ds_view(info->view);
1824 ds = cmd->bind.att.ds;
1825 } else {
1826 /* all zeros */
1827 static const struct intel_ds_view null_ds;
1828 ds = &null_ds;
1829 }
1830
Chia-I Wu8370b402014-08-29 12:28:37 +08001831 cmd_wa_gen6_pre_ds_flush(cmd);
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001832 gen6_3DSTATE_DEPTH_BUFFER(cmd, ds);
1833 gen6_3DSTATE_STENCIL_BUFFER(cmd, ds);
1834 gen6_3DSTATE_HIER_DEPTH_BUFFER(cmd, ds);
Chia-I Wuf8231032014-08-25 10:44:45 +08001835
1836 if (cmd_gen(cmd) >= INTEL_GEN(7))
1837 gen7_3DSTATE_CLEAR_PARAMS(cmd, 0);
1838 else
1839 gen6_3DSTATE_CLEAR_PARAMS(cmd, 0);
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001840}
1841
1842static void cmd_bind_viewport_state(struct intel_cmd *cmd,
1843 const struct intel_viewport_state *state)
1844{
1845 cmd->bind.state.viewport = state;
1846}
1847
1848static void cmd_bind_raster_state(struct intel_cmd *cmd,
1849 const struct intel_raster_state *state)
1850{
1851 cmd->bind.state.raster = state;
1852}
1853
1854static void cmd_bind_ds_state(struct intel_cmd *cmd,
1855 const struct intel_ds_state *state)
1856{
1857 cmd->bind.state.ds = state;
1858}
1859
1860static void cmd_bind_blend_state(struct intel_cmd *cmd,
1861 const struct intel_blend_state *state)
1862{
1863 cmd->bind.state.blend = state;
1864}
1865
1866static void cmd_bind_msaa_state(struct intel_cmd *cmd,
1867 const struct intel_msaa_state *state)
1868{
1869 cmd->bind.state.msaa = state;
1870}
1871
1872static void cmd_draw(struct intel_cmd *cmd,
1873 XGL_UINT vertex_start,
1874 XGL_UINT vertex_count,
1875 XGL_UINT instance_start,
1876 XGL_UINT instance_count,
1877 bool indexed,
1878 XGL_UINT vertex_base)
1879{
1880 const struct intel_pipeline *p = cmd->bind.pipeline.graphics;
1881
1882 emit_bounded_states(cmd);
1883
1884 if (indexed) {
1885 if (p->primitive_restart && !gen6_can_primitive_restart(cmd))
1886 cmd->result = XGL_ERROR_UNKNOWN;
1887
1888 if (cmd_gen(cmd) >= INTEL_GEN(7.5)) {
1889 gen75_3DSTATE_VF(cmd, p->primitive_restart,
1890 p->primitive_restart_index);
1891 } else {
1892 gen6_3DSTATE_INDEX_BUFFER(cmd, cmd->bind.index.mem,
1893 cmd->bind.index.offset, cmd->bind.index.type,
1894 p->primitive_restart);
1895 }
1896 } else {
1897 assert(!vertex_base);
1898 }
1899
1900 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
1901 gen7_3DPRIMITIVE(cmd, p->prim_type, indexed, vertex_count,
1902 vertex_start, instance_count, instance_start, vertex_base);
1903 } else {
1904 gen6_3DPRIMITIVE(cmd, p->prim_type, indexed, vertex_count,
1905 vertex_start, instance_count, instance_start, vertex_base);
1906 }
Chia-I Wu48c283d2014-08-25 23:13:46 +08001907
Chia-I Wu707a29e2014-08-27 12:51:47 +08001908 cmd->bind.draw_count++;
Chia-I Wu48c283d2014-08-25 23:13:46 +08001909 /* need to re-emit all workarounds */
1910 cmd->bind.wa_flags = 0;
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001911}
1912
Chia-I Wub2755562014-08-20 13:38:52 +08001913XGL_VOID XGLAPI intelCmdBindPipeline(
1914 XGL_CMD_BUFFER cmdBuffer,
1915 XGL_PIPELINE_BIND_POINT pipelineBindPoint,
1916 XGL_PIPELINE pipeline)
1917{
1918 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
1919
1920 switch (pipelineBindPoint) {
1921 case XGL_PIPELINE_BIND_POINT_COMPUTE:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001922 cmd_bind_compute_pipeline(cmd, intel_pipeline(pipeline));
Chia-I Wub2755562014-08-20 13:38:52 +08001923 break;
1924 case XGL_PIPELINE_BIND_POINT_GRAPHICS:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001925 cmd_bind_graphics_pipeline(cmd, intel_pipeline(pipeline));
Chia-I Wub2755562014-08-20 13:38:52 +08001926 break;
1927 default:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001928 cmd->result = XGL_ERROR_INVALID_VALUE;
Chia-I Wub2755562014-08-20 13:38:52 +08001929 break;
1930 }
1931}
1932
1933XGL_VOID XGLAPI intelCmdBindPipelineDelta(
1934 XGL_CMD_BUFFER cmdBuffer,
1935 XGL_PIPELINE_BIND_POINT pipelineBindPoint,
1936 XGL_PIPELINE_DELTA delta)
1937{
1938 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
1939
1940 switch (pipelineBindPoint) {
1941 case XGL_PIPELINE_BIND_POINT_COMPUTE:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001942 cmd_bind_compute_delta(cmd, delta);
Chia-I Wub2755562014-08-20 13:38:52 +08001943 break;
1944 case XGL_PIPELINE_BIND_POINT_GRAPHICS:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001945 cmd_bind_graphics_delta(cmd, delta);
Chia-I Wub2755562014-08-20 13:38:52 +08001946 break;
1947 default:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001948 cmd->result = XGL_ERROR_INVALID_VALUE;
Chia-I Wub2755562014-08-20 13:38:52 +08001949 break;
1950 }
1951}
1952
1953XGL_VOID XGLAPI intelCmdBindStateObject(
1954 XGL_CMD_BUFFER cmdBuffer,
1955 XGL_STATE_BIND_POINT stateBindPoint,
1956 XGL_STATE_OBJECT state)
1957{
1958 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
1959
1960 switch (stateBindPoint) {
1961 case XGL_STATE_BIND_VIEWPORT:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001962 cmd_bind_viewport_state(cmd,
1963 intel_viewport_state((XGL_VIEWPORT_STATE_OBJECT) state));
Chia-I Wub2755562014-08-20 13:38:52 +08001964 break;
1965 case XGL_STATE_BIND_RASTER:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001966 cmd_bind_raster_state(cmd,
1967 intel_raster_state((XGL_RASTER_STATE_OBJECT) state));
Chia-I Wub2755562014-08-20 13:38:52 +08001968 break;
1969 case XGL_STATE_BIND_DEPTH_STENCIL:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001970 cmd_bind_ds_state(cmd,
1971 intel_ds_state((XGL_DEPTH_STENCIL_STATE_OBJECT) state));
Chia-I Wub2755562014-08-20 13:38:52 +08001972 break;
1973 case XGL_STATE_BIND_COLOR_BLEND:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001974 cmd_bind_blend_state(cmd,
1975 intel_blend_state((XGL_COLOR_BLEND_STATE_OBJECT) state));
Chia-I Wub2755562014-08-20 13:38:52 +08001976 break;
1977 case XGL_STATE_BIND_MSAA:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001978 cmd_bind_msaa_state(cmd,
1979 intel_msaa_state((XGL_MSAA_STATE_OBJECT) state));
Chia-I Wub2755562014-08-20 13:38:52 +08001980 break;
1981 default:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001982 cmd->result = XGL_ERROR_INVALID_VALUE;
Chia-I Wub2755562014-08-20 13:38:52 +08001983 break;
1984 }
1985}
1986
1987XGL_VOID XGLAPI intelCmdBindDescriptorSet(
1988 XGL_CMD_BUFFER cmdBuffer,
1989 XGL_PIPELINE_BIND_POINT pipelineBindPoint,
1990 XGL_UINT index,
1991 XGL_DESCRIPTOR_SET descriptorSet,
1992 XGL_UINT slotOffset)
1993{
1994 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
1995 struct intel_dset *dset = intel_dset(descriptorSet);
1996
1997 assert(!index);
1998
1999 switch (pipelineBindPoint) {
2000 case XGL_PIPELINE_BIND_POINT_COMPUTE:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002001 cmd_bind_compute_dset(cmd, dset, slotOffset);
Chia-I Wub2755562014-08-20 13:38:52 +08002002 break;
2003 case XGL_PIPELINE_BIND_POINT_GRAPHICS:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002004 cmd_bind_graphics_dset(cmd, dset, slotOffset);
Chia-I Wub2755562014-08-20 13:38:52 +08002005 break;
2006 default:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002007 cmd->result = XGL_ERROR_INVALID_VALUE;
Chia-I Wub2755562014-08-20 13:38:52 +08002008 break;
2009 }
2010}
2011
2012XGL_VOID XGLAPI intelCmdBindDynamicMemoryView(
2013 XGL_CMD_BUFFER cmdBuffer,
2014 XGL_PIPELINE_BIND_POINT pipelineBindPoint,
2015 const XGL_MEMORY_VIEW_ATTACH_INFO* pMemView)
2016{
2017 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
2018
2019 switch (pipelineBindPoint) {
2020 case XGL_PIPELINE_BIND_POINT_COMPUTE:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002021 cmd_bind_compute_dyn_view(cmd, pMemView);
Chia-I Wub2755562014-08-20 13:38:52 +08002022 break;
2023 case XGL_PIPELINE_BIND_POINT_GRAPHICS:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002024 cmd_bind_graphics_dyn_view(cmd, pMemView);
Chia-I Wub2755562014-08-20 13:38:52 +08002025 break;
2026 default:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002027 cmd->result = XGL_ERROR_INVALID_VALUE;
Chia-I Wub2755562014-08-20 13:38:52 +08002028 break;
2029 }
2030}
2031
2032XGL_VOID XGLAPI intelCmdBindIndexData(
2033 XGL_CMD_BUFFER cmdBuffer,
2034 XGL_GPU_MEMORY mem_,
2035 XGL_GPU_SIZE offset,
2036 XGL_INDEX_TYPE indexType)
2037{
2038 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
2039 struct intel_mem *mem = intel_mem(mem_);
2040
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002041 cmd_bind_index_data(cmd, mem, offset, indexType);
Chia-I Wub2755562014-08-20 13:38:52 +08002042}
2043
2044XGL_VOID XGLAPI intelCmdBindAttachments(
2045 XGL_CMD_BUFFER cmdBuffer,
2046 XGL_UINT colorAttachmentCount,
2047 const XGL_COLOR_ATTACHMENT_BIND_INFO* pColorAttachments,
2048 const XGL_DEPTH_STENCIL_BIND_INFO* pDepthStencilAttachment)
2049{
2050 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
Chia-I Wub2755562014-08-20 13:38:52 +08002051
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002052 cmd_bind_rt(cmd, pColorAttachments, colorAttachmentCount);
2053 cmd_bind_ds(cmd, pDepthStencilAttachment);
Chia-I Wub2755562014-08-20 13:38:52 +08002054}
2055
2056XGL_VOID XGLAPI intelCmdDraw(
2057 XGL_CMD_BUFFER cmdBuffer,
2058 XGL_UINT firstVertex,
2059 XGL_UINT vertexCount,
2060 XGL_UINT firstInstance,
2061 XGL_UINT instanceCount)
2062{
Chia-I Wu59c097e2014-08-21 10:51:07 +08002063 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
Chia-I Wu59c097e2014-08-21 10:51:07 +08002064
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002065 cmd_draw(cmd, firstVertex, vertexCount,
2066 firstInstance, instanceCount, false, 0);
Chia-I Wub2755562014-08-20 13:38:52 +08002067}
2068
2069XGL_VOID XGLAPI intelCmdDrawIndexed(
2070 XGL_CMD_BUFFER cmdBuffer,
2071 XGL_UINT firstIndex,
2072 XGL_UINT indexCount,
2073 XGL_INT vertexOffset,
2074 XGL_UINT firstInstance,
2075 XGL_UINT instanceCount)
2076{
Chia-I Wu59c097e2014-08-21 10:51:07 +08002077 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
Chia-I Wu59c097e2014-08-21 10:51:07 +08002078
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002079 cmd_draw(cmd, firstIndex, indexCount,
2080 firstInstance, instanceCount, true, vertexOffset);
Chia-I Wub2755562014-08-20 13:38:52 +08002081}
2082
2083XGL_VOID XGLAPI intelCmdDrawIndirect(
2084 XGL_CMD_BUFFER cmdBuffer,
2085 XGL_GPU_MEMORY mem,
2086 XGL_GPU_SIZE offset,
2087 XGL_UINT32 count,
2088 XGL_UINT32 stride)
2089{
Chia-I Wu59c097e2014-08-21 10:51:07 +08002090 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
2091
2092 cmd->result = XGL_ERROR_UNKNOWN;
Chia-I Wub2755562014-08-20 13:38:52 +08002093}
2094
2095XGL_VOID XGLAPI intelCmdDrawIndexedIndirect(
2096 XGL_CMD_BUFFER cmdBuffer,
2097 XGL_GPU_MEMORY mem,
2098 XGL_GPU_SIZE offset,
2099 XGL_UINT32 count,
2100 XGL_UINT32 stride)
2101{
Chia-I Wu59c097e2014-08-21 10:51:07 +08002102 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
2103
2104 cmd->result = XGL_ERROR_UNKNOWN;
Chia-I Wub2755562014-08-20 13:38:52 +08002105}
2106
2107XGL_VOID XGLAPI intelCmdDispatch(
2108 XGL_CMD_BUFFER cmdBuffer,
2109 XGL_UINT x,
2110 XGL_UINT y,
2111 XGL_UINT z)
2112{
Chia-I Wu59c097e2014-08-21 10:51:07 +08002113 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
2114
2115 cmd->result = XGL_ERROR_UNKNOWN;
Chia-I Wub2755562014-08-20 13:38:52 +08002116}
2117
2118XGL_VOID XGLAPI intelCmdDispatchIndirect(
2119 XGL_CMD_BUFFER cmdBuffer,
2120 XGL_GPU_MEMORY mem,
2121 XGL_GPU_SIZE offset)
2122{
Chia-I Wu59c097e2014-08-21 10:51:07 +08002123 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
2124
2125 cmd->result = XGL_ERROR_UNKNOWN;
Chia-I Wub2755562014-08-20 13:38:52 +08002126}