blob: 3bc9ce7c1019fed8815674774b2716a951c0c1c3 [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{
437 const struct intel_shader *vs =
438 intel_shader(cmd->bind.pipeline.graphics->vs.shader);
439 const struct intel_shader *fs =
440 intel_shader(cmd->bind.pipeline.graphics->fs.shader);
441 XGL_UINT attr_skip, attr_count;
442 XGL_UINT vue_offset, vue_len;
443 XGL_UINT i;
444 uint32_t dw1;
445
446 CMD_ASSERT(cmd, 6, 7.5);
447
448 /* VS outputs VUE header and position additionally */
449 assert(vs->out_count >= 2);
450 attr_skip = 2;
451 attr_count = vs->out_count - attr_skip;
452 assert(fs->in_count == attr_count);
453 assert(fs->in_count <= 32);
454
455 vue_offset = attr_skip / 2;
456 vue_len = (attr_count + 1) / 2;
457 if (!vue_len)
458 vue_len = 1;
459
460 dw1 = fs->in_count << GEN7_SBE_DW1_ATTR_COUNT__SHIFT |
461 vue_len << GEN7_SBE_DW1_URB_READ_LEN__SHIFT |
462 vue_offset << GEN7_SBE_DW1_URB_READ_OFFSET__SHIFT;
463
464 body[0] = dw1;
465
466 for (i = 0; i < 8; i++) {
467 uint16_t hi, lo;
468
469 /* no attr swizzles */
470 if (i * 2 + 1 < fs->in_count) {
471 hi = i * 2 + 1;
472 lo = i * 2;
473 } else if (i * 2 < fs->in_count) {
474 hi = 0;
475 lo = i * 2;
476 } else {
477 hi = 0;
478 lo = 0;
479 }
480
481 body[1 + i] = hi << GEN7_SBE_ATTR_HIGH__SHIFT | lo;
482 }
483
484 body[9] = 0; /* point sprite enables */
485 body[10] = 0; /* constant interpolation enables */
486 body[11] = 0; /* WrapShortest enables */
487 body[12] = 0;
488}
489
490static void gen6_3DSTATE_SF(struct intel_cmd *cmd)
491{
492 const uint8_t cmd_len = 20;
493 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_SF) |
494 (cmd_len - 2);
495 uint32_t sf[6];
496 uint32_t sbe[13];
497
498 CMD_ASSERT(cmd, 6, 6);
499
500 gen7_fill_3DSTATE_SF_body(cmd, sf);
501 gen7_fill_3DSTATE_SBE_body(cmd, sbe);
502
503 cmd_batch_reserve(cmd, cmd_len);
504 cmd_batch_write(cmd, dw0);
505 cmd_batch_write(cmd, sbe[0]);
506 cmd_batch_write_n(cmd, sf, 6);
507 cmd_batch_write_n(cmd, &sbe[1], 12);
508}
509
510static void gen7_3DSTATE_SF(struct intel_cmd *cmd)
511{
512 const uint8_t cmd_len = 7;
513 uint32_t dw[7];
514
515 CMD_ASSERT(cmd, 7, 7.5);
516
517 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SF) |
518 (cmd_len - 2);
519 gen7_fill_3DSTATE_SF_body(cmd, &dw[1]);
520
521 cmd_batch_reserve(cmd, cmd_len);
522 cmd_batch_write_n(cmd, dw, cmd_len);
523}
524
525static void gen7_3DSTATE_SBE(struct intel_cmd *cmd)
526{
527 const uint8_t cmd_len = 14;
528 uint32_t dw[14];
529
530 CMD_ASSERT(cmd, 7, 7.5);
531
532 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SBE) |
533 (cmd_len - 2);
534 gen7_fill_3DSTATE_SBE_body(cmd, &dw[1]);
535
536 cmd_batch_reserve(cmd, cmd_len);
537 cmd_batch_write_n(cmd, dw, cmd_len);
538}
539
Chia-I Wuc3f9c092014-08-30 14:29:29 +0800540static void gen6_3DSTATE_CLIP(struct intel_cmd *cmd)
541{
542 const uint8_t cmd_len = 4;
543 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_CLIP) |
544 (cmd_len - 2);
545 const struct intel_pipeline *pipeline = cmd->bind.pipeline.graphics;
546 const struct intel_shader *fs = intel_shader(pipeline->fs.shader);
547 const struct intel_viewport_state *viewport = cmd->bind.state.viewport;
548 const struct intel_raster_state *raster = cmd->bind.state.raster;
549 uint32_t dw1, dw2, dw3;
550
551 CMD_ASSERT(cmd, 6, 7.5);
552
553 dw1 = GEN6_CLIP_DW1_STATISTICS;
554 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
555 dw1 |= GEN7_CLIP_DW1_SUBPIXEL_8BITS |
556 GEN7_CLIP_DW1_EARLY_CULL_ENABLE |
557 raster->cmd_clip_cull;
558 }
559
560 dw2 = GEN6_CLIP_DW2_CLIP_ENABLE |
561 GEN6_CLIP_DW2_XY_TEST_ENABLE |
562 GEN6_CLIP_DW2_APIMODE_OGL |
563 pipeline->provoking_vertex_tri << GEN6_CLIP_DW2_TRI_PROVOKE__SHIFT |
564 pipeline->provoking_vertex_line << GEN6_CLIP_DW2_LINE_PROVOKE__SHIFT |
565 pipeline->provoking_vertex_trifan << GEN6_CLIP_DW2_TRIFAN_PROVOKE__SHIFT;
566
567 if (pipeline->rasterizerDiscardEnable)
568 dw2 |= GEN6_CLIP_DW2_CLIPMODE_REJECT_ALL;
569 else
570 dw2 |= GEN6_CLIP_DW2_CLIPMODE_NORMAL;
571
572 if (pipeline->depthClipEnable)
573 dw2 |= GEN6_CLIP_DW2_Z_TEST_ENABLE;
574
575 if (fs->barycentric_interps & (GEN6_INTERP_NONPERSPECTIVE_PIXEL |
576 GEN6_INTERP_NONPERSPECTIVE_CENTROID |
577 GEN6_INTERP_NONPERSPECTIVE_SAMPLE))
578 dw2 |= GEN6_CLIP_DW2_NONPERSPECTIVE_BARYCENTRIC_ENABLE;
579
580 dw3 = 0x1 << GEN6_CLIP_DW3_MIN_POINT_WIDTH__SHIFT |
581 0x7ff << GEN6_CLIP_DW3_MAX_POINT_WIDTH__SHIFT |
582 (viewport->viewport_count - 1);
583
584 cmd_batch_reserve(cmd, cmd_len);
585 cmd_batch_write(cmd, dw0);
586 cmd_batch_write(cmd, dw1);
587 cmd_batch_write(cmd, dw2);
588 cmd_batch_write(cmd, dw3);
589}
590
Chia-I Wu1f2fd292014-08-29 15:07:09 +0800591static void gen6_3DSTATE_WM(struct intel_cmd *cmd)
592{
593 const int max_threads = (cmd->dev->gpu->gt == 2) ? 80 : 40;
594 const struct intel_pipeline *pipeline = cmd->bind.pipeline.graphics;
595 const struct intel_shader *fs = intel_shader(pipeline->fs.shader);
596 const struct intel_msaa_state *msaa = cmd->bind.state.msaa;
597 const uint8_t cmd_len = 9;
598 uint32_t dw0, dw2, dw4, dw5, dw6;
599
600 CMD_ASSERT(cmd, 6, 6);
601
602 dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
603
604 dw2 = (fs->sampler_count + 3) / 4 << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT |
605 fs->surface_count << GEN6_THREADDISP_BINDING_TABLE_SIZE__SHIFT;
606
607 dw4 = GEN6_WM_DW4_STATISTICS |
608 fs->urb_grf_start << GEN6_WM_DW4_URB_GRF_START0__SHIFT |
609 0 << GEN6_WM_DW4_URB_GRF_START1__SHIFT |
610 0 << GEN6_WM_DW4_URB_GRF_START2__SHIFT;
611
612 dw5 = (max_threads - 1) << GEN6_WM_DW5_MAX_THREADS__SHIFT |
613 GEN6_WM_DW5_PS_ENABLE |
614 GEN6_WM_DW5_8_PIXEL_DISPATCH;
615
616 if (fs->uses & INTEL_SHADER_USE_KILL ||
617 pipeline->cb_state.alphaToCoverageEnable)
618 dw5 |= GEN6_WM_DW5_PS_KILL;
619
620 if (fs->uses & INTEL_SHADER_USE_COMPUTED_DEPTH)
621 dw5 |= GEN6_WM_DW5_PS_COMPUTE_DEPTH;
622 if (fs->uses & INTEL_SHADER_USE_DEPTH)
623 dw5 |= GEN6_WM_DW5_PS_USE_DEPTH;
624 if (fs->uses & INTEL_SHADER_USE_W)
625 dw5 |= GEN6_WM_DW5_PS_USE_W;
626
627 if (pipeline->cb_state.dualSourceBlendEnable)
628 dw5 |= GEN6_WM_DW5_DUAL_SOURCE_BLEND;
629
630 dw6 = fs->in_count << GEN6_WM_DW6_SF_ATTR_COUNT__SHIFT |
631 GEN6_WM_DW6_POSOFFSET_NONE |
632 GEN6_WM_DW6_ZW_INTERP_PIXEL |
633 fs->barycentric_interps << GEN6_WM_DW6_BARYCENTRIC_INTERP__SHIFT |
634 GEN6_WM_DW6_POINT_RASTRULE_UPPER_RIGHT;
635
636 if (msaa->sample_count > 1) {
637 dw6 |= GEN6_WM_DW6_MSRASTMODE_ON_PATTERN |
638 GEN6_WM_DW6_MSDISPMODE_PERPIXEL;
639 } else {
640 dw6 |= GEN6_WM_DW6_MSRASTMODE_OFF_PIXEL |
641 GEN6_WM_DW6_MSDISPMODE_PERSAMPLE;
642 }
643
644 cmd_batch_reserve(cmd, cmd_len);
645 cmd_batch_write(cmd, dw0);
646 cmd_batch_write(cmd, cmd->bind.fs.kernel_pos << 2);
647 cmd_batch_write(cmd, dw2);
648 cmd_batch_write(cmd, 0); /* scratch */
649 cmd_batch_write(cmd, dw4);
650 cmd_batch_write(cmd, dw5);
651 cmd_batch_write(cmd, dw6);
652 cmd_batch_write(cmd, 0); /* kernel 1 */
653 cmd_batch_write(cmd, 0); /* kernel 2 */
654}
655
656static void gen7_3DSTATE_WM(struct intel_cmd *cmd)
657{
658 const struct intel_pipeline *pipeline = cmd->bind.pipeline.graphics;
659 const struct intel_shader *fs = intel_shader(pipeline->fs.shader);
660 const struct intel_msaa_state *msaa = cmd->bind.state.msaa;
661 const uint8_t cmd_len = 3;
662 uint32_t dw0, dw1, dw2;
663
664 CMD_ASSERT(cmd, 7, 7.5);
665
666 dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
667
668 dw1 = GEN7_WM_DW1_STATISTICS |
669 GEN7_WM_DW1_PS_ENABLE |
670 GEN7_WM_DW1_ZW_INTERP_PIXEL |
671 fs->barycentric_interps << GEN7_WM_DW1_BARYCENTRIC_INTERP__SHIFT |
672 GEN7_WM_DW1_POINT_RASTRULE_UPPER_RIGHT;
673
674 if (fs->uses & INTEL_SHADER_USE_KILL ||
675 pipeline->cb_state.alphaToCoverageEnable)
676 dw1 |= GEN7_WM_DW1_PS_KILL;
677
678 if (fs->uses & INTEL_SHADER_USE_COMPUTED_DEPTH)
679 dw1 |= GEN7_WM_DW1_PSCDEPTH_ON;
680 if (fs->uses & INTEL_SHADER_USE_DEPTH)
681 dw1 |= GEN7_WM_DW1_PS_USE_DEPTH;
682 if (fs->uses & INTEL_SHADER_USE_W)
683 dw1 |= GEN7_WM_DW1_PS_USE_W;
684
685 dw2 = 0;
686
687 if (msaa->sample_count > 1) {
688 dw1 |= GEN7_WM_DW1_MSRASTMODE_ON_PATTERN;
689 dw2 |= GEN7_WM_DW2_MSDISPMODE_PERPIXEL;
690 } else {
691 dw1 |= GEN7_WM_DW1_MSRASTMODE_OFF_PIXEL;
692 dw2 |= GEN7_WM_DW2_MSDISPMODE_PERSAMPLE;
693 }
694
695 cmd_batch_reserve(cmd, cmd_len);
696 cmd_batch_write(cmd, dw0);
697 cmd_batch_write(cmd, dw1);
698 cmd_batch_write(cmd, dw2);
699}
700
701static void gen7_3DSTATE_PS(struct intel_cmd *cmd)
702{
703 const struct intel_pipeline *pipeline = cmd->bind.pipeline.graphics;
704 const struct intel_shader *fs = intel_shader(pipeline->fs.shader);
705 const struct intel_msaa_state *msaa = cmd->bind.state.msaa;
706 const uint8_t cmd_len = 8;
707 uint32_t dw0, dw2, dw4, dw5;
708
709 CMD_ASSERT(cmd, 7, 7.5);
710
711 dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_PS) | (cmd_len - 2);
712
713 dw2 = (fs->sampler_count + 3) / 4 << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT |
714 fs->surface_count << GEN6_THREADDISP_BINDING_TABLE_SIZE__SHIFT;
715
716 dw4 = GEN7_PS_DW4_POSOFFSET_NONE |
717 GEN7_PS_DW4_8_PIXEL_DISPATCH;
718
719 if (cmd_gen(cmd) >= INTEL_GEN(7.5)) {
720 const int max_threads =
721 (cmd->dev->gpu->gt == 3) ? 408 :
722 (cmd->dev->gpu->gt == 2) ? 204 : 102;
723 dw4 |= (max_threads - 1) << GEN75_PS_DW4_MAX_THREADS__SHIFT;
724 dw4 |= msaa->cmd[msaa->cmd_len - 1] << GEN75_PS_DW4_SAMPLE_MASK__SHIFT;
725 } else {
726 const int max_threads = (cmd->dev->gpu->gt == 2) ? 172 : 48;
727 dw4 |= (max_threads - 1) << GEN7_PS_DW4_MAX_THREADS__SHIFT;
728 }
729
730 if (pipeline->fs.linkConstBufferCount)
731 dw4 |= GEN7_PS_DW4_PUSH_CONSTANT_ENABLE;
732
733 if (fs->in_count)
734 dw4 |= GEN7_PS_DW4_ATTR_ENABLE;
735
736 if (pipeline->cb_state.dualSourceBlendEnable)
737 dw4 |= GEN7_PS_DW4_DUAL_SOURCE_BLEND;
738
739 dw5 = fs->urb_grf_start << GEN7_PS_DW5_URB_GRF_START0__SHIFT |
740 0 << GEN7_PS_DW5_URB_GRF_START1__SHIFT |
741 0 << GEN7_PS_DW5_URB_GRF_START2__SHIFT;
742
743 cmd_batch_reserve(cmd, cmd_len);
744 cmd_batch_write(cmd, dw0);
745 cmd_batch_write(cmd, cmd->bind.fs.kernel_pos << 2);
746 cmd_batch_write(cmd, dw2);
747 cmd_batch_write(cmd, 0); /* scratch */
748 cmd_batch_write(cmd, dw4);
749 cmd_batch_write(cmd, dw5);
750 cmd_batch_write(cmd, 0); /* kernel 1 */
751 cmd_batch_write(cmd, 0); /* kernel 2 */
752}
753
Chia-I Wu7fae4e32014-08-21 11:39:44 +0800754static void gen6_3DSTATE_DEPTH_BUFFER(struct intel_cmd *cmd,
755 const struct intel_ds_view *view)
756{
757 const uint8_t cmd_len = 7;
758 uint32_t dw0;
759
760 CMD_ASSERT(cmd, 6, 7.5);
761
762 dw0 = (cmd_gen(cmd) >= INTEL_GEN(7)) ?
Chia-I Wu426072d2014-08-26 14:31:55 +0800763 GEN7_RENDER_CMD(3D, 3DSTATE_DEPTH_BUFFER) :
764 GEN6_RENDER_CMD(3D, 3DSTATE_DEPTH_BUFFER);
Chia-I Wu7fae4e32014-08-21 11:39:44 +0800765 dw0 |= (cmd_len - 2);
766
Chia-I Wu2de65d02014-08-25 10:02:53 +0800767 cmd_batch_reserve_reloc(cmd, cmd_len, (bool) view->img);
Chia-I Wue24c3292014-08-21 14:05:23 +0800768 cmd_batch_write(cmd, dw0);
769 cmd_batch_write(cmd, view->cmd[0]);
Courtney Goeltzenleuchtere316d972014-08-22 16:25:24 -0600770 if (view->img) {
Chia-I Wu9ee38722014-08-25 12:11:36 +0800771 cmd_batch_reloc(cmd, view->cmd[1], view->img->obj.mem->bo,
Chia-I Wu32a22462014-08-26 14:13:46 +0800772 INTEL_RELOC_WRITE);
Courtney Goeltzenleuchtere316d972014-08-22 16:25:24 -0600773 } else {
774 cmd_batch_write(cmd, 0);
775 }
Chia-I Wue24c3292014-08-21 14:05:23 +0800776 cmd_batch_write(cmd, view->cmd[2]);
777 cmd_batch_write(cmd, view->cmd[3]);
778 cmd_batch_write(cmd, view->cmd[4]);
779 cmd_batch_write(cmd, view->cmd[5]);
Chia-I Wu7fae4e32014-08-21 11:39:44 +0800780}
781
782static void gen6_3DSTATE_STENCIL_BUFFER(struct intel_cmd *cmd,
783 const struct intel_ds_view *view)
784{
785 const uint8_t cmd_len = 3;
786 uint32_t dw0;
787
788 CMD_ASSERT(cmd, 6, 7.5);
789
790 dw0 = (cmd_gen(cmd) >= INTEL_GEN(7)) ?
Chia-I Wu426072d2014-08-26 14:31:55 +0800791 GEN7_RENDER_CMD(3D, 3DSTATE_STENCIL_BUFFER) :
792 GEN6_RENDER_CMD(3D, 3DSTATE_STENCIL_BUFFER);
Chia-I Wu7fae4e32014-08-21 11:39:44 +0800793 dw0 |= (cmd_len - 2);
794
Chia-I Wu2de65d02014-08-25 10:02:53 +0800795 cmd_batch_reserve_reloc(cmd, cmd_len, (bool) view->img);
Chia-I Wue24c3292014-08-21 14:05:23 +0800796 cmd_batch_write(cmd, dw0);
797 cmd_batch_write(cmd, view->cmd[6]);
Courtney Goeltzenleuchtere316d972014-08-22 16:25:24 -0600798 if (view->img) {
Chia-I Wu9ee38722014-08-25 12:11:36 +0800799 cmd_batch_reloc(cmd, view->cmd[7], view->img->obj.mem->bo,
Chia-I Wu32a22462014-08-26 14:13:46 +0800800 INTEL_RELOC_WRITE);
Courtney Goeltzenleuchtere316d972014-08-22 16:25:24 -0600801 } else {
802 cmd_batch_write(cmd, 0);
803 }
Chia-I Wu7fae4e32014-08-21 11:39:44 +0800804}
805
806static void gen6_3DSTATE_HIER_DEPTH_BUFFER(struct intel_cmd *cmd,
807 const struct intel_ds_view *view)
808{
809 const uint8_t cmd_len = 3;
810 uint32_t dw0;
811
812 CMD_ASSERT(cmd, 6, 7.5);
813
814 dw0 = (cmd_gen(cmd) >= INTEL_GEN(7)) ?
Chia-I Wu426072d2014-08-26 14:31:55 +0800815 GEN7_RENDER_CMD(3D, 3DSTATE_HIER_DEPTH_BUFFER) :
816 GEN6_RENDER_CMD(3D, 3DSTATE_HIER_DEPTH_BUFFER);
Chia-I Wu7fae4e32014-08-21 11:39:44 +0800817 dw0 |= (cmd_len - 2);
818
Chia-I Wu2de65d02014-08-25 10:02:53 +0800819 cmd_batch_reserve_reloc(cmd, cmd_len, (bool) view->img);
Chia-I Wue24c3292014-08-21 14:05:23 +0800820 cmd_batch_write(cmd, dw0);
821 cmd_batch_write(cmd, view->cmd[8]);
Courtney Goeltzenleuchtere316d972014-08-22 16:25:24 -0600822 if (view->img) {
Chia-I Wu9ee38722014-08-25 12:11:36 +0800823 cmd_batch_reloc(cmd, view->cmd[9], view->img->obj.mem->bo,
Chia-I Wu32a22462014-08-26 14:13:46 +0800824 INTEL_RELOC_WRITE);
Courtney Goeltzenleuchtere316d972014-08-22 16:25:24 -0600825 } else {
826 cmd_batch_write(cmd, 0);
827 }
Chia-I Wu7fae4e32014-08-21 11:39:44 +0800828}
829
Chia-I Wuf8231032014-08-25 10:44:45 +0800830static void gen6_3DSTATE_CLEAR_PARAMS(struct intel_cmd *cmd,
831 uint32_t clear_val)
832{
833 const uint8_t cmd_len = 2;
Chia-I Wu426072d2014-08-26 14:31:55 +0800834 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_CLEAR_PARAMS) |
Chia-I Wuf8231032014-08-25 10:44:45 +0800835 GEN6_CLEAR_PARAMS_DW0_VALID |
836 (cmd_len - 2);
837
838 CMD_ASSERT(cmd, 6, 6);
839
840 cmd_batch_reserve(cmd, cmd_len);
841 cmd_batch_write(cmd, dw0);
842 cmd_batch_write(cmd, clear_val);
843}
844
845static void gen7_3DSTATE_CLEAR_PARAMS(struct intel_cmd *cmd,
846 uint32_t clear_val)
847{
848 const uint8_t cmd_len = 3;
Chia-I Wu426072d2014-08-26 14:31:55 +0800849 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_CLEAR_PARAMS) |
Chia-I Wuf8231032014-08-25 10:44:45 +0800850 (cmd_len - 2);
851
852 CMD_ASSERT(cmd, 7, 7.5);
853
854 cmd_batch_reserve(cmd, cmd_len);
855 cmd_batch_write(cmd, dw0);
856 cmd_batch_write(cmd, clear_val);
857 cmd_batch_write(cmd, 1);
858}
859
Chia-I Wu302742d2014-08-22 10:28:29 +0800860static void gen6_3DSTATE_CC_STATE_POINTERS(struct intel_cmd *cmd,
861 XGL_UINT blend_pos,
862 XGL_UINT ds_pos,
863 XGL_UINT cc_pos)
864{
865 const uint8_t cmd_len = 4;
866 uint32_t dw0;
867
868 CMD_ASSERT(cmd, 6, 6);
869
Chia-I Wu426072d2014-08-26 14:31:55 +0800870 dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_CC_STATE_POINTERS) |
Chia-I Wu302742d2014-08-22 10:28:29 +0800871 (cmd_len - 2);
872
873 cmd_batch_reserve(cmd, cmd_len);
874 cmd_batch_write(cmd, dw0);
875 cmd_batch_write(cmd, (blend_pos << 2) | 1);
876 cmd_batch_write(cmd, (ds_pos << 2) | 1);
877 cmd_batch_write(cmd, (cc_pos << 2) | 1);
878}
879
Chia-I Wu1744cca2014-08-22 11:10:17 +0800880static void gen6_3DSTATE_VIEWPORT_STATE_POINTERS(struct intel_cmd *cmd,
881 XGL_UINT clip_pos,
882 XGL_UINT sf_pos,
883 XGL_UINT cc_pos)
884{
885 const uint8_t cmd_len = 4;
886 uint32_t dw0;
887
888 CMD_ASSERT(cmd, 6, 6);
889
Chia-I Wu426072d2014-08-26 14:31:55 +0800890 dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_VIEWPORT_STATE_POINTERS) |
Chia-I Wu1744cca2014-08-22 11:10:17 +0800891 GEN6_PTR_VP_DW0_CLIP_CHANGED |
892 GEN6_PTR_VP_DW0_SF_CHANGED |
893 GEN6_PTR_VP_DW0_CC_CHANGED |
894 (cmd_len - 2);
895
896 cmd_batch_reserve(cmd, cmd_len);
897 cmd_batch_write(cmd, dw0);
898 cmd_batch_write(cmd, clip_pos << 2);
899 cmd_batch_write(cmd, sf_pos << 2);
900 cmd_batch_write(cmd, cc_pos << 2);
901}
902
903static void gen6_3DSTATE_SCISSOR_STATE_POINTERS(struct intel_cmd *cmd,
904 XGL_UINT scissor_pos)
905{
906 const uint8_t cmd_len = 2;
907 uint32_t dw0;
908
909 CMD_ASSERT(cmd, 6, 6);
910
Chia-I Wu426072d2014-08-26 14:31:55 +0800911 dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_SCISSOR_STATE_POINTERS) |
Chia-I Wu1744cca2014-08-22 11:10:17 +0800912 (cmd_len - 2);
913
914 cmd_batch_reserve(cmd, cmd_len);
915 cmd_batch_write(cmd, dw0);
916 cmd_batch_write(cmd, scissor_pos << 2);
917}
918
Chia-I Wu42a56202014-08-23 16:47:48 +0800919static void gen6_3DSTATE_BINDING_TABLE_POINTERS(struct intel_cmd *cmd,
920 XGL_UINT vs_pos,
921 XGL_UINT gs_pos,
922 XGL_UINT ps_pos)
923{
924 const uint8_t cmd_len = 4;
925 uint32_t dw0;
926
927 CMD_ASSERT(cmd, 6, 6);
928
Chia-I Wu426072d2014-08-26 14:31:55 +0800929 dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_BINDING_TABLE_POINTERS) |
Chia-I Wu42a56202014-08-23 16:47:48 +0800930 GEN6_PTR_BINDING_TABLE_DW0_VS_CHANGED |
931 GEN6_PTR_BINDING_TABLE_DW0_GS_CHANGED |
932 GEN6_PTR_BINDING_TABLE_DW0_PS_CHANGED |
933 (cmd_len - 2);
934
935 cmd_batch_reserve(cmd, cmd_len);
936 cmd_batch_write(cmd, dw0);
937 cmd_batch_write(cmd, vs_pos << 2);
938 cmd_batch_write(cmd, gs_pos << 2);
939 cmd_batch_write(cmd, ps_pos << 2);
940}
941
Chia-I Wu257e75e2014-08-29 14:06:35 +0800942static void gen6_3DSTATE_SAMPLER_STATE_POINTERS(struct intel_cmd *cmd,
943 XGL_UINT vs_pos,
944 XGL_UINT gs_pos,
945 XGL_UINT ps_pos)
946{
947 const uint8_t cmd_len = 4;
948 uint32_t dw0;
949
950 CMD_ASSERT(cmd, 6, 6);
951
952 dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_SAMPLER_STATE_POINTERS) |
953 GEN6_PTR_SAMPLER_DW0_VS_CHANGED |
954 GEN6_PTR_SAMPLER_DW0_GS_CHANGED |
955 GEN6_PTR_SAMPLER_DW0_PS_CHANGED |
956 (cmd_len - 2);
957
958 cmd_batch_reserve(cmd, cmd_len);
959 cmd_batch_write(cmd, dw0);
960 cmd_batch_write(cmd, vs_pos << 2);
961 cmd_batch_write(cmd, gs_pos << 2);
962 cmd_batch_write(cmd, ps_pos << 2);
963}
964
Chia-I Wu302742d2014-08-22 10:28:29 +0800965static void gen7_3dstate_pointer(struct intel_cmd *cmd,
966 int subop, XGL_UINT pos)
967{
968 const uint8_t cmd_len = 2;
969 const uint32_t dw0 = GEN6_RENDER_TYPE_RENDER |
970 GEN6_RENDER_SUBTYPE_3D |
971 subop | (cmd_len - 2);
972
973 cmd_batch_reserve(cmd, cmd_len);
974 cmd_batch_write(cmd, dw0);
975 cmd_batch_write(cmd, pos << 2);
976}
977
978static XGL_UINT gen6_BLEND_STATE(struct intel_cmd *cmd,
979 const struct intel_blend_state *state)
980{
981 const uint8_t cmd_align = GEN6_ALIGNMENT_BLEND_STATE;
982 const uint8_t cmd_len = XGL_MAX_COLOR_ATTACHMENTS * 2;
983
984 CMD_ASSERT(cmd, 6, 7.5);
985 STATIC_ASSERT(ARRAY_SIZE(state->cmd) >= cmd_len);
986
987 return cmd_state_copy(cmd, state->cmd, cmd_len, cmd_align);
988}
989
990static XGL_UINT gen6_DEPTH_STENCIL_STATE(struct intel_cmd *cmd,
991 const struct intel_ds_state *state)
992{
993 const uint8_t cmd_align = GEN6_ALIGNMENT_DEPTH_STENCIL_STATE;
994 const uint8_t cmd_len = 3;
995
996 CMD_ASSERT(cmd, 6, 7.5);
997 STATIC_ASSERT(ARRAY_SIZE(state->cmd) >= cmd_len);
998
999 return cmd_state_copy(cmd, state->cmd, cmd_len, cmd_align);
1000}
1001
1002static XGL_UINT gen6_COLOR_CALC_STATE(struct intel_cmd *cmd,
1003 uint32_t stencil_ref,
1004 const uint32_t blend_color[4])
1005{
1006 const uint8_t cmd_align = GEN6_ALIGNMENT_COLOR_CALC_STATE;
1007 const uint8_t cmd_len = 6;
1008 XGL_UINT pos;
1009 uint32_t *dw;
1010
1011 CMD_ASSERT(cmd, 6, 7.5);
1012
1013 dw = cmd_state_reserve(cmd, cmd_len, cmd_align, &pos);
1014 dw[0] = stencil_ref;
1015 dw[1] = 0;
1016 dw[2] = blend_color[0];
1017 dw[3] = blend_color[1];
1018 dw[4] = blend_color[2];
1019 dw[5] = blend_color[3];
1020 cmd_state_advance(cmd, cmd_len);
1021
1022 return pos;
1023}
1024
Chia-I Wu8370b402014-08-29 12:28:37 +08001025static void cmd_wa_gen6_pre_depth_stall_write(struct intel_cmd *cmd)
Chia-I Wu48c283d2014-08-25 23:13:46 +08001026{
Chia-I Wu8370b402014-08-29 12:28:37 +08001027 CMD_ASSERT(cmd, 6, 7.5);
1028
Chia-I Wu707a29e2014-08-27 12:51:47 +08001029 if (!cmd->bind.draw_count)
1030 return;
1031
Chia-I Wu8370b402014-08-29 12:28:37 +08001032 if (cmd->bind.wa_flags & INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE)
Chia-I Wu48c283d2014-08-25 23:13:46 +08001033 return;
1034
Chia-I Wu8370b402014-08-29 12:28:37 +08001035 cmd->bind.wa_flags |= INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE;
Chia-I Wu48c283d2014-08-25 23:13:46 +08001036
1037 /*
1038 * From the Sandy Bridge PRM, volume 2 part 1, page 60:
1039 *
1040 * "Pipe-control with CS-stall bit set must be sent BEFORE the
1041 * pipe-control with a post-sync op and no write-cache flushes."
1042 *
1043 * The workaround below necessitates this workaround.
1044 */
1045 gen6_PIPE_CONTROL(cmd,
1046 GEN6_PIPE_CONTROL_CS_STALL |
1047 GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL,
Chia-I Wud6d079d2014-08-31 13:14:21 +08001048 NULL, 0, 0);
Chia-I Wu48c283d2014-08-25 23:13:46 +08001049
Chia-I Wud6d079d2014-08-31 13:14:21 +08001050 gen6_PIPE_CONTROL(cmd, GEN6_PIPE_CONTROL_WRITE_IMM,
1051 cmd->scratch_bo, 0, 0);
Chia-I Wu48c283d2014-08-25 23:13:46 +08001052}
1053
Chia-I Wu8370b402014-08-29 12:28:37 +08001054static void cmd_wa_gen6_pre_command_scoreboard_stall(struct intel_cmd *cmd)
Courtney Goeltzenleuchterf9e1a412014-08-27 13:59:36 -06001055{
Chia-I Wu48c283d2014-08-25 23:13:46 +08001056 CMD_ASSERT(cmd, 6, 7.5);
1057
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001058 if (!cmd->bind.draw_count)
1059 return;
1060
Chia-I Wud6d079d2014-08-31 13:14:21 +08001061 gen6_PIPE_CONTROL(cmd, GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL,
1062 NULL, 0, 0);
Chia-I Wu8370b402014-08-29 12:28:37 +08001063}
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001064
Chia-I Wu8370b402014-08-29 12:28:37 +08001065static void cmd_wa_gen7_pre_vs_depth_stall_write(struct intel_cmd *cmd)
1066{
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001067 CMD_ASSERT(cmd, 7, 7.5);
1068
Chia-I Wu8370b402014-08-29 12:28:37 +08001069 if (!cmd->bind.draw_count)
1070 return;
1071
1072 cmd_wa_gen6_pre_depth_stall_write(cmd);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001073
1074 gen6_PIPE_CONTROL(cmd,
1075 GEN6_PIPE_CONTROL_DEPTH_STALL | GEN6_PIPE_CONTROL_WRITE_IMM,
Chia-I Wud6d079d2014-08-31 13:14:21 +08001076 cmd->scratch_bo, 0, 0);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001077}
1078
Chia-I Wu8370b402014-08-29 12:28:37 +08001079static void cmd_wa_gen7_post_command_cs_stall(struct intel_cmd *cmd)
1080{
1081 CMD_ASSERT(cmd, 7, 7.5);
1082
1083 if (!cmd->bind.draw_count)
1084 return;
1085
1086 /*
1087 * From the Ivy Bridge PRM, volume 2 part 1, page 61:
1088 *
1089 * "One of the following must also be set (when CS stall is set):
1090 *
1091 * * Render Target Cache Flush Enable ([12] of DW1)
1092 * * Depth Cache Flush Enable ([0] of DW1)
1093 * * Stall at Pixel Scoreboard ([1] of DW1)
1094 * * Depth Stall ([13] of DW1)
1095 * * Post-Sync Operation ([13] of DW1)"
1096 */
1097 gen6_PIPE_CONTROL(cmd,
1098 GEN6_PIPE_CONTROL_CS_STALL |
1099 GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL,
Chia-I Wud6d079d2014-08-31 13:14:21 +08001100 NULL, 0, 0);
Chia-I Wu8370b402014-08-29 12:28:37 +08001101}
1102
1103static void cmd_wa_gen7_post_command_depth_stall(struct intel_cmd *cmd)
1104{
1105 CMD_ASSERT(cmd, 7, 7.5);
1106
1107 if (!cmd->bind.draw_count)
1108 return;
1109
1110 cmd_wa_gen6_pre_depth_stall_write(cmd);
1111
Chia-I Wud6d079d2014-08-31 13:14:21 +08001112 gen6_PIPE_CONTROL(cmd, GEN6_PIPE_CONTROL_DEPTH_STALL, NULL, 0, 0);
Chia-I Wu8370b402014-08-29 12:28:37 +08001113}
1114
1115static void cmd_wa_gen6_pre_multisample_depth_flush(struct intel_cmd *cmd)
1116{
1117 CMD_ASSERT(cmd, 6, 7.5);
1118
1119 if (!cmd->bind.draw_count)
1120 return;
1121
1122 /*
1123 * From the Sandy Bridge PRM, volume 2 part 1, page 305:
1124 *
1125 * "Driver must guarentee that all the caches in the depth pipe are
1126 * flushed before this command (3DSTATE_MULTISAMPLE) is parsed. This
1127 * requires driver to send a PIPE_CONTROL with a CS stall along with
1128 * a Depth Flush prior to this command."
1129 *
1130 * From the Ivy Bridge PRM, volume 2 part 1, page 304:
1131 *
1132 * "Driver must ierarchi that all the caches in the depth pipe are
1133 * flushed before this command (3DSTATE_MULTISAMPLE) is parsed. This
1134 * requires driver to send a PIPE_CONTROL with a CS stall along with
1135 * a Depth Flush prior to this command.
1136 */
1137 gen6_PIPE_CONTROL(cmd,
1138 GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH |
1139 GEN6_PIPE_CONTROL_CS_STALL,
Chia-I Wud6d079d2014-08-31 13:14:21 +08001140 NULL, 0, 0);
Chia-I Wu8370b402014-08-29 12:28:37 +08001141}
1142
1143static void cmd_wa_gen6_pre_ds_flush(struct intel_cmd *cmd)
1144{
1145 CMD_ASSERT(cmd, 6, 7.5);
1146
1147 if (!cmd->bind.draw_count)
1148 return;
1149
1150 /*
1151 * From the Ivy Bridge PRM, volume 2 part 1, page 315:
1152 *
1153 * "Driver must send a least one PIPE_CONTROL command with CS Stall
1154 * and a post sync operation prior to the group of depth
1155 * commands(3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS,
1156 * 3DSTATE_STENCIL_BUFFER, and 3DSTATE_HIER_DEPTH_BUFFER)."
1157 *
1158 * This workaround satifies all the conditions.
1159 */
1160 cmd_wa_gen6_pre_depth_stall_write(cmd);
1161
1162 /*
1163 * From the Ivy Bridge PRM, volume 2 part 1, page 315:
1164 *
1165 * "Restriction: Prior to changing Depth/Stencil Buffer state (i.e.,
1166 * any combination of 3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS,
1167 * 3DSTATE_STENCIL_BUFFER, 3DSTATE_HIER_DEPTH_BUFFER) SW must first
1168 * issue a pipelined depth stall (PIPE_CONTROL with Depth Stall bit
1169 * set), followed by a pipelined depth cache flush (PIPE_CONTROL with
1170 * Depth Flush Bit set, followed by another pipelined depth stall
1171 * (PIPE_CONTROL with Depth Stall Bit set), unless SW can otherwise
1172 * guarantee that the pipeline from WM onwards is already flushed
1173 * (e.g., via a preceding MI_FLUSH)."
1174 */
Chia-I Wud6d079d2014-08-31 13:14:21 +08001175 gen6_PIPE_CONTROL(cmd, GEN6_PIPE_CONTROL_DEPTH_STALL, NULL, 0, 0);
1176 gen6_PIPE_CONTROL(cmd, GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH, NULL, 0, 0);
1177 gen6_PIPE_CONTROL(cmd, GEN6_PIPE_CONTROL_DEPTH_STALL, NULL, 0, 0);
Chia-I Wu8370b402014-08-29 12:28:37 +08001178}
1179
Chia-I Wu525c6602014-08-27 10:22:34 +08001180void cmd_batch_flush(struct intel_cmd *cmd, uint32_t pipe_control_dw0)
1181{
1182 if (!cmd->bind.draw_count)
1183 return;
1184
1185 assert(!(pipe_control_dw0 & GEN6_PIPE_CONTROL_WRITE__MASK));
1186
Chia-I Wu8370b402014-08-29 12:28:37 +08001187 /*
1188 * From the Sandy Bridge PRM, volume 2 part 1, page 60:
1189 *
1190 * "Before a PIPE_CONTROL with Write Cache Flush Enable =1, a
1191 * PIPE_CONTROL with any non-zero post-sync-op is required."
1192 */
Chia-I Wu525c6602014-08-27 10:22:34 +08001193 if (pipe_control_dw0 & GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH)
Chia-I Wu8370b402014-08-29 12:28:37 +08001194 cmd_wa_gen6_pre_depth_stall_write(cmd);
Chia-I Wu525c6602014-08-27 10:22:34 +08001195
Chia-I Wu092279a2014-08-30 19:05:30 +08001196 /*
1197 * From the Ivy Bridge PRM, volume 2 part 1, page 61:
1198 *
1199 * "One of the following must also be set (when CS stall is set):
1200 *
1201 * * Render Target Cache Flush Enable ([12] of DW1)
1202 * * Depth Cache Flush Enable ([0] of DW1)
1203 * * Stall at Pixel Scoreboard ([1] of DW1)
1204 * * Depth Stall ([13] of DW1)
1205 * * Post-Sync Operation ([13] of DW1)"
1206 */
1207 if ((pipe_control_dw0 & GEN6_PIPE_CONTROL_CS_STALL) &&
1208 !(pipe_control_dw0 & (GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH |
1209 GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH |
1210 GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL |
1211 GEN6_PIPE_CONTROL_DEPTH_STALL)))
1212 pipe_control_dw0 |= GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL;
1213
Chia-I Wud6d079d2014-08-31 13:14:21 +08001214 gen6_PIPE_CONTROL(cmd, pipe_control_dw0, NULL, 0, 0);
Chia-I Wu525c6602014-08-27 10:22:34 +08001215}
1216
Chia-I Wu759fa2e2014-08-30 18:44:47 +08001217void cmd_batch_depth_count(struct intel_cmd *cmd,
1218 struct intel_bo *bo,
1219 XGL_GPU_SIZE offset)
1220{
1221 cmd_wa_gen6_pre_depth_stall_write(cmd);
1222
1223 gen6_PIPE_CONTROL(cmd,
1224 GEN6_PIPE_CONTROL_DEPTH_STALL |
1225 GEN6_PIPE_CONTROL_WRITE_PS_DEPTH_COUNT,
Chia-I Wud6d079d2014-08-31 13:14:21 +08001226 bo, offset, 0);
Chia-I Wu759fa2e2014-08-30 18:44:47 +08001227}
1228
Chia-I Wue8dbd5d2014-08-31 13:15:58 +08001229void cmd_batch_timestamp(struct intel_cmd *cmd,
1230 struct intel_bo *bo,
1231 XGL_GPU_SIZE offset)
1232{
1233 /* need any WA or stall? */
1234 gen6_PIPE_CONTROL(cmd, GEN6_PIPE_CONTROL_WRITE_TIMESTAMP, bo, offset, 0);
1235}
1236
1237void cmd_batch_immediate(struct intel_cmd *cmd,
1238 struct intel_bo *bo,
1239 XGL_GPU_SIZE offset,
1240 uint64_t val)
1241{
1242 /* need any WA or stall? */
1243 gen6_PIPE_CONTROL(cmd, GEN6_PIPE_CONTROL_WRITE_IMM, bo, offset, val);
1244}
1245
Chia-I Wu302742d2014-08-22 10:28:29 +08001246static void gen6_cc_states(struct intel_cmd *cmd)
1247{
1248 const struct intel_blend_state *blend = cmd->bind.state.blend;
1249 const struct intel_ds_state *ds = cmd->bind.state.ds;
1250 XGL_UINT blend_pos, ds_pos, cc_pos;
Chia-I Wuce9f11f2014-08-22 10:38:51 +08001251 uint32_t stencil_ref;
1252 uint32_t blend_color[4];
Chia-I Wu302742d2014-08-22 10:28:29 +08001253
1254 CMD_ASSERT(cmd, 6, 6);
1255
Chia-I Wuce9f11f2014-08-22 10:38:51 +08001256 if (blend) {
1257 blend_pos = gen6_BLEND_STATE(cmd, blend);
1258 memcpy(blend_color, blend->cmd_blend_color, sizeof(blend_color));
1259 } else {
1260 blend_pos = 0;
1261 memset(blend_color, 0, sizeof(blend_color));
1262 }
1263
1264 if (ds) {
1265 ds_pos = gen6_DEPTH_STENCIL_STATE(cmd, ds);
1266 stencil_ref = ds->cmd_stencil_ref;
1267 } else {
1268 ds_pos = 0;
1269 stencil_ref = 0;
1270 }
1271
1272 cc_pos = gen6_COLOR_CALC_STATE(cmd, stencil_ref, blend_color);
Chia-I Wu302742d2014-08-22 10:28:29 +08001273
1274 gen6_3DSTATE_CC_STATE_POINTERS(cmd, blend_pos, ds_pos, cc_pos);
1275}
1276
Chia-I Wu1744cca2014-08-22 11:10:17 +08001277static void gen6_viewport_states(struct intel_cmd *cmd)
1278{
1279 const struct intel_viewport_state *viewport = cmd->bind.state.viewport;
1280 XGL_UINT pos;
1281
1282 if (!viewport)
1283 return;
1284
1285 pos = cmd_state_copy(cmd, viewport->cmd, viewport->cmd_len,
1286 viewport->cmd_align);
1287
1288 gen6_3DSTATE_VIEWPORT_STATE_POINTERS(cmd,
1289 pos + viewport->cmd_clip_offset,
1290 pos,
1291 pos + viewport->cmd_cc_offset);
1292
1293 pos = (viewport->scissor_enable) ?
1294 pos + viewport->cmd_scissor_rect_offset : 0;
1295
1296 gen6_3DSTATE_SCISSOR_STATE_POINTERS(cmd, pos);
1297}
1298
Chia-I Wu302742d2014-08-22 10:28:29 +08001299static void gen7_cc_states(struct intel_cmd *cmd)
1300{
1301 const struct intel_blend_state *blend = cmd->bind.state.blend;
1302 const struct intel_ds_state *ds = cmd->bind.state.ds;
Chia-I Wuce9f11f2014-08-22 10:38:51 +08001303 uint32_t stencil_ref;
1304 uint32_t blend_color[4];
Chia-I Wu302742d2014-08-22 10:28:29 +08001305 XGL_UINT pos;
1306
1307 CMD_ASSERT(cmd, 7, 7.5);
1308
Chia-I Wuce9f11f2014-08-22 10:38:51 +08001309 if (!blend && !ds)
1310 return;
Chia-I Wu302742d2014-08-22 10:28:29 +08001311
Chia-I Wuce9f11f2014-08-22 10:38:51 +08001312 if (blend) {
1313 pos = gen6_BLEND_STATE(cmd, blend);
1314 gen7_3dstate_pointer(cmd,
1315 GEN7_RENDER_OPCODE_3DSTATE_BLEND_STATE_POINTERS, pos);
Chia-I Wu302742d2014-08-22 10:28:29 +08001316
Chia-I Wuce9f11f2014-08-22 10:38:51 +08001317 memcpy(blend_color, blend->cmd_blend_color, sizeof(blend_color));
1318 } else {
1319 memset(blend_color, 0, sizeof(blend_color));
1320 }
1321
1322 if (ds) {
1323 pos = gen6_DEPTH_STENCIL_STATE(cmd, ds);
1324 gen7_3dstate_pointer(cmd,
1325 GEN7_RENDER_OPCODE_3DSTATE_DEPTH_STENCIL_STATE_POINTERS, pos);
1326 } else {
1327 stencil_ref = 0;
1328 }
1329
1330 pos = gen6_COLOR_CALC_STATE(cmd, stencil_ref, blend_color);
Chia-I Wu302742d2014-08-22 10:28:29 +08001331 gen7_3dstate_pointer(cmd,
1332 GEN6_RENDER_OPCODE_3DSTATE_CC_STATE_POINTERS, pos);
1333}
1334
Chia-I Wu1744cca2014-08-22 11:10:17 +08001335static void gen7_viewport_states(struct intel_cmd *cmd)
1336{
1337 const struct intel_viewport_state *viewport = cmd->bind.state.viewport;
1338 XGL_UINT pos;
1339
1340 if (!viewport)
1341 return;
1342
1343 pos = cmd_state_copy(cmd, viewport->cmd, viewport->cmd_len,
1344 viewport->cmd_align);
1345
1346 gen7_3dstate_pointer(cmd,
1347 GEN7_RENDER_OPCODE_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP, pos);
1348 gen7_3dstate_pointer(cmd,
1349 GEN7_RENDER_OPCODE_3DSTATE_VIEWPORT_STATE_POINTERS_CC,
1350 pos + viewport->cmd_cc_offset);
1351 if (viewport->scissor_enable) {
1352 gen7_3dstate_pointer(cmd,
1353 GEN6_RENDER_OPCODE_3DSTATE_SCISSOR_STATE_POINTERS,
1354 pos + viewport->cmd_scissor_rect_offset);
1355 }
1356}
1357
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001358static void gen6_pcb(struct intel_cmd *cmd, int subop,
1359 const XGL_PIPELINE_SHADER *sh)
1360{
1361 const uint8_t cmd_len = 5;
1362 const XGL_UINT alignment = 32;
1363 const XGL_UINT max_size =
1364 (subop == GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS) ? 1024 : 2048;
1365 const XGL_UINT max_pcb = 4;
1366 uint32_t pcb[4] = { 0, 0, 0, 0 };
1367 XGL_FLAGS pcb_enables = 0;
1368 XGL_SIZE total_size = 0;
1369 uint32_t dw0;
1370 XGL_UINT i;
1371
1372 for (i = 0; i < sh->linkConstBufferCount; i++) {
1373 const XGL_LINK_CONST_BUFFER *info = &sh->pLinkConstBufferInfo[i];
1374 const XGL_SIZE size = u_align(info->bufferSize, alignment);
1375 void *ptr;
1376
1377 if (info->bufferId >= max_pcb ||
1378 pcb_enables & ((1 << info->bufferId)) ||
1379 total_size + info->bufferSize > max_size) {
1380 cmd->result = XGL_ERROR_UNKNOWN;
1381 return;
1382 }
1383 if (!size)
1384 continue;
1385
1386 pcb_enables |= 1 << info->bufferId;
1387 total_size += size;
1388
1389 ptr = cmd_state_reserve(cmd, size / sizeof(uint32_t),
1390 alignment / sizeof(uint32_t), &pcb[info->bufferId]);
1391 memcpy(ptr, info->pBufferData, info->bufferSize);
1392 cmd_state_advance(cmd, size / sizeof(uint32_t));
1393
1394 pcb[info->bufferId] |= size / alignment - 1;
1395 }
1396
1397 dw0 = GEN6_RENDER_TYPE_RENDER |
1398 GEN6_RENDER_SUBTYPE_3D |
1399 subop |
1400 pcb_enables << 12 |
1401 (cmd_len - 2);
1402
1403 cmd_batch_reserve(cmd, cmd_len);
1404 cmd_batch_write(cmd, dw0);
1405 cmd_batch_write(cmd, pcb[0]);
1406 cmd_batch_write(cmd, pcb[1]);
1407 cmd_batch_write(cmd, pcb[2]);
1408 cmd_batch_write(cmd, pcb[3]);
1409}
1410
1411static void gen7_pcb(struct intel_cmd *cmd, int subop,
1412 const XGL_PIPELINE_SHADER *sh)
1413{
1414 const uint8_t cmd_len = 7;
1415 const uint32_t dw0 = GEN6_RENDER_TYPE_RENDER |
1416 GEN6_RENDER_SUBTYPE_3D |
1417 subop |
1418 (cmd_len - 2);
1419 const XGL_UINT alignment = 32;
1420 const XGL_UINT max_size = 2048;
1421 const XGL_UINT max_pcb = 4;
1422 uint16_t pcb_len[4] = { 0, 0, 0, 0 };
1423 uint32_t pcb[4] = { 0, 0, 0, 0 };
1424 XGL_FLAGS pcb_enables = 0;
1425 XGL_SIZE total_size = 0;
1426 XGL_UINT i;
1427
1428 for (i = 0; i < sh->linkConstBufferCount; i++) {
1429 const XGL_LINK_CONST_BUFFER *info = &sh->pLinkConstBufferInfo[i];
1430 const XGL_SIZE size = u_align(info->bufferSize, alignment);
1431 void *ptr;
1432
1433 if (info->bufferId >= max_pcb ||
1434 pcb_enables & ((1 << info->bufferId)) ||
1435 total_size + info->bufferSize > max_size) {
1436 cmd->result = XGL_ERROR_UNKNOWN;
1437 return;
1438 }
1439 if (!size)
1440 continue;
1441
1442 pcb_enables |= 1 << info->bufferId;
1443 total_size += size;
1444
1445 pcb_len[info->bufferId] = size / alignment;
1446
1447 ptr = cmd_state_reserve(cmd, size / sizeof(uint32_t),
1448 alignment / sizeof(uint32_t), &pcb[info->bufferId]);
1449 memcpy(ptr, info->pBufferData, info->bufferSize);
1450 cmd_state_advance(cmd, size / sizeof(uint32_t));
1451 }
1452
1453 /* no holes */
1454 if (!u_is_pow2(pcb_enables + 1)) {
1455 cmd->result = XGL_ERROR_UNKNOWN;
1456 return;
1457 }
1458
1459 cmd_batch_reserve(cmd, cmd_len);
1460 cmd_batch_write(cmd, dw0);
1461 cmd_batch_write(cmd, pcb_len[1] << 16 | pcb_len[0]);
1462 cmd_batch_write(cmd, pcb_len[3] << 16 | pcb_len[2]);
1463 cmd_batch_write(cmd, pcb[0]);
1464 cmd_batch_write(cmd, pcb[1]);
1465 cmd_batch_write(cmd, pcb[2]);
1466 cmd_batch_write(cmd, pcb[3]);
1467}
1468
Chia-I Wu42a56202014-08-23 16:47:48 +08001469static void emit_ps_resources(struct intel_cmd *cmd,
1470 const struct intel_rmap *rmap)
1471{
1472 const XGL_UINT surface_count = rmap->rt_count +
1473 rmap->resource_count + rmap->uav_count;
1474 uint32_t binding_table[256];
1475 XGL_UINT pos, i;
1476
1477 assert(surface_count <= ARRAY_SIZE(binding_table));
1478
1479 for (i = 0; i < surface_count; i++) {
1480 const struct intel_rmap_slot *slot = &rmap->slots[i];
1481 uint32_t *dw;
1482
1483 switch (slot->path_len) {
1484 case 0:
1485 pos = 0;
1486 break;
1487 case INTEL_RMAP_SLOT_RT:
1488 {
1489 const struct intel_rt_view *view = cmd->bind.att.rt[i];
1490
1491 dw = cmd_state_reserve_reloc(cmd, view->cmd_len, 1,
1492 GEN6_ALIGNMENT_SURFACE_STATE, &pos);
1493
1494 memcpy(dw, view->cmd, sizeof(uint32_t) * view->cmd_len);
Chia-I Wubda55fd2014-08-25 12:46:10 +08001495 cmd_state_reloc(cmd, 1, view->cmd[1], view->img->obj.mem->bo,
Chia-I Wu32a22462014-08-26 14:13:46 +08001496 INTEL_RELOC_WRITE);
Chia-I Wu42a56202014-08-23 16:47:48 +08001497 cmd_state_advance(cmd, view->cmd_len);
1498 }
1499 break;
1500 case INTEL_RMAP_SLOT_DYN:
1501 {
1502 const struct intel_mem_view *view =
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001503 &cmd->bind.dyn_view.graphics;
Chia-I Wu42a56202014-08-23 16:47:48 +08001504
1505 dw = cmd_state_reserve_reloc(cmd, view->cmd_len, 1,
1506 GEN6_ALIGNMENT_SURFACE_STATE, &pos);
1507
1508 memcpy(dw, view->cmd, sizeof(uint32_t) * view->cmd_len);
Chia-I Wubda55fd2014-08-25 12:46:10 +08001509 cmd_state_reloc(cmd, 1, view->cmd[1], view->mem->bo,
Chia-I Wu32a22462014-08-26 14:13:46 +08001510 INTEL_RELOC_WRITE);
Chia-I Wu42a56202014-08-23 16:47:48 +08001511 cmd_state_advance(cmd, view->cmd_len);
1512 }
1513 break;
1514 case 1:
1515 default:
1516 /* TODO */
1517 assert(!"no dset support");
1518 break;
1519 }
1520
1521 binding_table[i] = pos << 2;
1522 }
1523
1524 pos = cmd_state_copy(cmd, binding_table, surface_count,
1525 GEN6_ALIGNMENT_BINDING_TABLE_STATE);
1526
1527 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
1528 gen7_3dstate_pointer(cmd,
1529 GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_PS, pos);
Chia-I Wu257e75e2014-08-29 14:06:35 +08001530
1531 gen7_3dstate_pointer(cmd,
1532 GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_VS, 0);
1533 gen7_3dstate_pointer(cmd,
1534 GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_HS, 0);
1535 gen7_3dstate_pointer(cmd,
1536 GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_DS, 0);
1537 gen7_3dstate_pointer(cmd,
1538 GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_GS, 0);
1539
1540 gen7_3dstate_pointer(cmd,
1541 GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_VS, 0);
1542 gen7_3dstate_pointer(cmd,
1543 GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_HS, 0);
1544 gen7_3dstate_pointer(cmd,
1545 GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_DS, 0);
1546 gen7_3dstate_pointer(cmd,
1547 GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_GS, 0);
1548 gen7_3dstate_pointer(cmd,
1549 GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_PS, 0);
Chia-I Wu42a56202014-08-23 16:47:48 +08001550 } else {
1551 gen6_3DSTATE_BINDING_TABLE_POINTERS(cmd, 0, 0, pos);
Chia-I Wu257e75e2014-08-29 14:06:35 +08001552 gen6_3DSTATE_SAMPLER_STATE_POINTERS(cmd, 0, 0, 0);
Chia-I Wu42a56202014-08-23 16:47:48 +08001553 }
1554}
1555
Courtney Goeltzenleuchter3d72e8c2014-08-29 16:27:47 -06001556// TODO: These should probably be generated
1557/* DW2 */
1558# define GEN6_VS_SPF_MODE (1 << 31)
1559# define GEN6_VS_VECTOR_MASK_ENABLE (1 << 30)
1560# define GEN6_VS_SAMPLER_COUNT_SHIFT 27
1561# define GEN6_VS_BINDING_TABLE_ENTRY_COUNT_SHIFT 18
1562# define GEN6_VS_FLOATING_POINT_MODE_IEEE_754 (0 << 16)
1563# define GEN6_VS_FLOATING_POINT_MODE_ALT (1 << 16)
1564
1565static void gen6_3DSTATE_VS(struct intel_cmd *cmd)
1566{
1567 const uint8_t cmd_len = GEN6_3DSTATE_VS__SIZE;
1568 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_VS) | (cmd_len - 2);
1569 uint32_t dw2, dw4, dw5;
1570
1571 CMD_ASSERT(cmd, 6, 7.5);
1572
1573 /* From the BSpec, 3D Pipeline > Geometry > Vertex Shader > State,
1574 * 3DSTATE_VS, Dword 5.0 "VS Function Enable":
1575 *
1576 * [DevSNB] A pipeline flush must be programmed prior to a 3DSTATE_VS
1577 * command that causes the VS Function Enable to toggle. Pipeline
1578 * flush can be executed by sending a PIPE_CONTROL command with CS
1579 * stall bit set and a post sync operation.
1580 *
1581 * Although we don't disable the VS during normal drawing, BLORP sometimes
1582 * disables it. To be safe, do the flush here just in case.
1583 */
1584 cmd_wa_gen6_pre_depth_stall_write(cmd);
1585
1586 if (cmd->bind.vs.shader == NULL) {
1587 cmd_batch_reserve(cmd, cmd_len);
1588 cmd_batch_write(cmd, dw0);
1589 cmd_batch_write(cmd, 0);
1590 cmd_batch_write(cmd, 0);
1591 cmd_batch_write(cmd, 0);
1592 cmd_batch_write(cmd, 0);
1593 cmd_batch_write(cmd, 0);
1594 return;
1595 }
1596
1597 /*
1598 * Most of this is know at pipeline create EXCEPT the kernel address,
1599 * so that's why this is in cmd_pipeline vs. pipeline.
1600 */
1601 dw2 = (u_align(cmd->bind.vs.shader->sampler_count, 4) / 4) << GEN6_VS_SAMPLER_COUNT_SHIFT;
1602 dw4 = (1 << GEN6_VS_DW4_URB_GRF_START__SHIFT) |
1603 (cmd->bind.vs.shader->urb_read_length << GEN6_VS_DW4_URB_READ_LEN__SHIFT) |
1604 (0 << GEN6_VS_DW4_URB_READ_OFFSET__SHIFT);
1605
1606 dw5 = GEN6_VS_DW5_STATISTICS |
1607 GEN6_VS_DW5_VS_ENABLE;
1608 if (cmd_gen(cmd) == INTEL_GEN(7.5)) {
1609 dw5 |= ((cmd->dev->gpu->max_vs_threads-1) << GEN75_VS_DW5_MAX_THREADS__SHIFT);
1610 } else {
1611 dw5 |= ((cmd->dev->gpu->max_vs_threads-1) << GEN6_VS_DW5_MAX_THREADS__SHIFT);
1612 }
1613
1614 cmd_batch_reserve(cmd, cmd_len);
1615 cmd_batch_write(cmd, dw0);
1616 cmd_batch_write(cmd, cmd->bind.vs.kernel_pos);
1617 cmd_batch_write(cmd, dw2);
1618 cmd_batch_write(cmd, 0); /* scratch */
1619 cmd_batch_write(cmd, dw4);
1620 cmd_batch_write(cmd, dw5);
1621}
1622
Chia-I Wu52500102014-08-22 00:46:04 +08001623static void emit_bounded_states(struct intel_cmd *cmd)
1624{
1625 const struct intel_msaa_state *msaa = cmd->bind.state.msaa;
1626
1627 /* TODO more states */
1628
Chia-I Wu1744cca2014-08-22 11:10:17 +08001629 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
Chia-I Wu302742d2014-08-22 10:28:29 +08001630 gen7_cc_states(cmd);
Chia-I Wu1744cca2014-08-22 11:10:17 +08001631 gen7_viewport_states(cmd);
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001632
1633 gen7_pcb(cmd, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS,
1634 &cmd->bind.pipeline.graphics->vs);
1635 gen7_pcb(cmd, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_PS,
1636 &cmd->bind.pipeline.graphics->fs);
Chia-I Wu1f2fd292014-08-29 15:07:09 +08001637
Chia-I Wuc3f9c092014-08-30 14:29:29 +08001638 gen6_3DSTATE_CLIP(cmd);
Chia-I Wu8016a172014-08-29 18:31:32 +08001639 gen7_3DSTATE_SF(cmd);
1640 gen7_3DSTATE_SBE(cmd);
Chia-I Wu1f2fd292014-08-29 15:07:09 +08001641 gen7_3DSTATE_WM(cmd);
1642 gen7_3DSTATE_PS(cmd);
Chia-I Wu1744cca2014-08-22 11:10:17 +08001643 } else {
Chia-I Wu302742d2014-08-22 10:28:29 +08001644 gen6_cc_states(cmd);
Chia-I Wu1744cca2014-08-22 11:10:17 +08001645 gen6_viewport_states(cmd);
Chia-I Wu7fd5cac2014-08-27 13:19:29 +08001646
1647 gen6_pcb(cmd, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS,
1648 &cmd->bind.pipeline.graphics->vs);
1649 gen6_pcb(cmd, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_PS,
1650 &cmd->bind.pipeline.graphics->fs);
Chia-I Wu1f2fd292014-08-29 15:07:09 +08001651
Chia-I Wuc3f9c092014-08-30 14:29:29 +08001652 gen6_3DSTATE_CLIP(cmd);
Chia-I Wu8016a172014-08-29 18:31:32 +08001653 gen6_3DSTATE_SF(cmd);
Chia-I Wu1f2fd292014-08-29 15:07:09 +08001654 gen6_3DSTATE_WM(cmd);
Chia-I Wu1744cca2014-08-22 11:10:17 +08001655 }
Chia-I Wu302742d2014-08-22 10:28:29 +08001656
Chia-I Wu42a56202014-08-23 16:47:48 +08001657 emit_ps_resources(cmd, cmd->bind.pipeline.graphics->fs_rmap);
1658
Chia-I Wu8370b402014-08-29 12:28:37 +08001659 cmd_wa_gen6_pre_depth_stall_write(cmd);
1660 cmd_wa_gen6_pre_multisample_depth_flush(cmd);
Chia-I Wu9cb84ee2014-08-28 10:12:34 +08001661 /* 3DSTATE_MULTISAMPLE and 3DSTATE_SAMPLE_MASK */
Chia-I Wu52500102014-08-22 00:46:04 +08001662 cmd_batch_reserve(cmd, msaa->cmd_len);
1663 cmd_batch_write_n(cmd, msaa->cmd, msaa->cmd_len);
Courtney Goeltzenleuchter3d72e8c2014-08-29 16:27:47 -06001664
1665 gen6_3DSTATE_VS(cmd);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001666}
1667
1668static void emit_shader(struct intel_cmd *cmd,
Courtney Goeltzenleuchterba305812014-08-28 17:27:47 -06001669 const struct intel_pipe_shader *shader,
1670 struct intel_cmd_shader *pCmdShader)
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001671{
1672 uint32_t i;
1673 struct intel_cmd_shader *cmdShader;
1674
1675 for (i=0; i<cmd->bind.shaderCache.used; i++) {
Chia-I Wu338fe642014-08-28 10:43:04 +08001676 if (cmd->bind.shaderCache.shaderArray[i].shader == shader) {
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001677 /* shader is already part of pipeline */
1678 return;
1679 }
1680 }
1681
Chia-I Wu338fe642014-08-28 10:43:04 +08001682 if (cmd->bind.shaderCache.used == cmd->bind.shaderCache.count) {
1683 const XGL_UINT new_count = cmd->bind.shaderCache.count + 16;
1684
1685 cmdShader = cmd->bind.shaderCache.shaderArray;
1686
1687 cmd->bind.shaderCache.shaderArray =
1688 icd_alloc(sizeof(*cmdShader) * new_count,
1689 0, XGL_SYSTEM_ALLOC_INTERNAL);
1690 if (cmd->bind.shaderCache.shaderArray == NULL) {
1691 cmd->bind.shaderCache.shaderArray = cmdShader;
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001692 cmd->result = XGL_ERROR_OUT_OF_MEMORY;
1693 return;
1694 }
Chia-I Wu338fe642014-08-28 10:43:04 +08001695
1696 if (cmdShader) {
1697 memcpy(cmd->bind.shaderCache.shaderArray, cmdShader,
1698 sizeof(*cmdShader) * cmd->bind.shaderCache.used);
1699 icd_free(cmdShader);
1700 }
1701
1702 cmd->bind.shaderCache.count = new_count;
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001703 }
1704
Chia-I Wu338fe642014-08-28 10:43:04 +08001705 cmdShader = &cmd->bind.shaderCache.shaderArray[cmd->bind.shaderCache.used];
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001706 cmdShader->shader = shader;
1707 cmdShader->kernel_pos = cmd_kernel_copy(cmd, shader->pCode, shader->codeSize);
Courtney Goeltzenleuchterba305812014-08-28 17:27:47 -06001708 *pCmdShader = *cmdShader;
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001709 cmd->bind.shaderCache.used++;
1710 return;
1711}
1712
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001713static void cmd_bind_graphics_pipeline(struct intel_cmd *cmd,
Chia-I Wu338fe642014-08-28 10:43:04 +08001714 const struct intel_pipeline *pipeline)
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001715{
1716 cmd->bind.pipeline.graphics = pipeline;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001717
Chia-I Wu8370b402014-08-29 12:28:37 +08001718 if (pipeline->wa_flags & INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE)
1719 cmd_wa_gen6_pre_depth_stall_write(cmd);
1720 if (pipeline->wa_flags & INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL)
1721 cmd_wa_gen6_pre_command_scoreboard_stall(cmd);
1722 if (pipeline->wa_flags & INTEL_CMD_WA_GEN7_PRE_VS_DEPTH_STALL_WRITE)
1723 cmd_wa_gen7_pre_vs_depth_stall_write(cmd);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001724
1725 /* 3DSTATE_URB_VS and etc. */
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -06001726 assert(pipeline->cmd_len);
Chia-I Wub08727d2014-08-29 14:54:54 +08001727 cmd_batch_reserve(cmd, pipeline->cmd_len);
Courtney Goeltzenleuchterba305812014-08-28 17:27:47 -06001728 cmd_batch_write_n(cmd, pipeline->cmds, pipeline->cmd_len);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001729
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001730 if (pipeline->active_shaders & SHADER_VERTEX_FLAG) {
Courtney Goeltzenleuchterba305812014-08-28 17:27:47 -06001731 emit_shader(cmd, &pipeline->intel_vs, &cmd->bind.vs);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001732 }
1733 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
Courtney Goeltzenleuchterba305812014-08-28 17:27:47 -06001734 emit_shader(cmd, &pipeline->gs, &cmd->bind.gs);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001735 }
1736 if (pipeline->active_shaders & SHADER_FRAGMENT_FLAG) {
Courtney Goeltzenleuchterba305812014-08-28 17:27:47 -06001737 emit_shader(cmd, &pipeline->intel_fs, &cmd->bind.fs);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001738 }
1739 if (pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) {
Courtney Goeltzenleuchterba305812014-08-28 17:27:47 -06001740 emit_shader(cmd, &pipeline->tess_control, &cmd->bind.tess_control);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001741 }
1742 if (pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) {
Courtney Goeltzenleuchterba305812014-08-28 17:27:47 -06001743 emit_shader(cmd, &pipeline->tess_eval, &cmd->bind.tess_eval);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -06001744 }
Courtney Goeltzenleuchter68d9bef2014-08-28 17:35:03 -06001745
Chia-I Wud95aa2b2014-08-29 12:07:47 +08001746 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
1747 gen7_3DSTATE_GS(cmd);
1748 } else {
1749 gen6_3DSTATE_GS(cmd);
1750 }
Courtney Goeltzenleuchterf782a852014-08-28 17:44:53 -06001751
Chia-I Wu8370b402014-08-29 12:28:37 +08001752 if (pipeline->wa_flags & INTEL_CMD_WA_GEN7_POST_COMMAND_CS_STALL)
1753 cmd_wa_gen7_post_command_cs_stall(cmd);
1754 if (pipeline->wa_flags & INTEL_CMD_WA_GEN7_POST_COMMAND_DEPTH_STALL)
1755 cmd_wa_gen7_post_command_depth_stall(cmd);
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001756}
1757
1758static void cmd_bind_compute_pipeline(struct intel_cmd *cmd,
1759 const struct intel_pipeline *pipeline)
1760{
1761 cmd->bind.pipeline.compute = pipeline;
1762}
1763
1764static void cmd_bind_graphics_delta(struct intel_cmd *cmd,
1765 const struct intel_pipeline_delta *delta)
1766{
1767 cmd->bind.pipeline.graphics_delta = delta;
1768}
1769
1770static void cmd_bind_compute_delta(struct intel_cmd *cmd,
1771 const struct intel_pipeline_delta *delta)
1772{
1773 cmd->bind.pipeline.compute_delta = delta;
1774}
1775
1776static void cmd_bind_graphics_dset(struct intel_cmd *cmd,
1777 const struct intel_dset *dset,
1778 XGL_UINT slot_offset)
1779{
1780 cmd->bind.dset.graphics = dset;
1781 cmd->bind.dset.graphics_offset = slot_offset;
1782}
1783
1784static void cmd_bind_compute_dset(struct intel_cmd *cmd,
1785 const struct intel_dset *dset,
1786 XGL_UINT slot_offset)
1787{
1788 cmd->bind.dset.compute = dset;
1789 cmd->bind.dset.compute_offset = slot_offset;
1790}
1791
1792static void cmd_bind_graphics_dyn_view(struct intel_cmd *cmd,
1793 const XGL_MEMORY_VIEW_ATTACH_INFO *info)
1794{
1795 intel_mem_view_init(&cmd->bind.dyn_view.graphics, cmd->dev, info);
1796}
1797
1798static void cmd_bind_compute_dyn_view(struct intel_cmd *cmd,
1799 const XGL_MEMORY_VIEW_ATTACH_INFO *info)
1800{
1801 intel_mem_view_init(&cmd->bind.dyn_view.compute, cmd->dev, info);
1802}
1803
1804static void cmd_bind_index_data(struct intel_cmd *cmd,
1805 const struct intel_mem *mem,
1806 XGL_GPU_SIZE offset, XGL_INDEX_TYPE type)
1807{
1808 if (cmd_gen(cmd) >= INTEL_GEN(7.5)) {
1809 gen6_3DSTATE_INDEX_BUFFER(cmd, mem, offset, type, false);
1810 } else {
1811 cmd->bind.index.mem = mem;
1812 cmd->bind.index.offset = offset;
1813 cmd->bind.index.type = type;
1814 }
1815}
1816
1817static void cmd_bind_rt(struct intel_cmd *cmd,
1818 const XGL_COLOR_ATTACHMENT_BIND_INFO *attachments,
1819 XGL_UINT count)
1820{
Chia-I Wud88e02d2014-08-25 10:56:13 +08001821 XGL_UINT width = 0, height = 0;
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001822 XGL_UINT i;
1823
1824 for (i = 0; i < count; i++) {
1825 const XGL_COLOR_ATTACHMENT_BIND_INFO *att = &attachments[i];
1826 const struct intel_rt_view *rt = intel_rt_view(att->view);
Chia-I Wud88e02d2014-08-25 10:56:13 +08001827 const struct intel_layout *layout = &rt->img->layout;
1828
1829 if (i == 0) {
1830 width = layout->width0;
1831 height = layout->height0;
1832 } else {
1833 if (width > layout->width0)
1834 width = layout->width0;
1835 if (height > layout->height0)
1836 height = layout->height0;
1837 }
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001838
1839 cmd->bind.att.rt[i] = rt;
1840 }
1841
1842 cmd->bind.att.rt_count = count;
Chia-I Wud88e02d2014-08-25 10:56:13 +08001843
Chia-I Wu8370b402014-08-29 12:28:37 +08001844 cmd_wa_gen6_pre_depth_stall_write(cmd);
Chia-I Wud88e02d2014-08-25 10:56:13 +08001845 gen6_3DSTATE_DRAWING_RECTANGLE(cmd, width, height);
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001846}
1847
1848static void cmd_bind_ds(struct intel_cmd *cmd,
1849 const XGL_DEPTH_STENCIL_BIND_INFO *info)
1850{
1851 const struct intel_ds_view *ds;
1852
1853 if (info) {
1854 cmd->bind.att.ds = intel_ds_view(info->view);
1855 ds = cmd->bind.att.ds;
1856 } else {
1857 /* all zeros */
1858 static const struct intel_ds_view null_ds;
1859 ds = &null_ds;
1860 }
1861
Chia-I Wu8370b402014-08-29 12:28:37 +08001862 cmd_wa_gen6_pre_ds_flush(cmd);
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001863 gen6_3DSTATE_DEPTH_BUFFER(cmd, ds);
1864 gen6_3DSTATE_STENCIL_BUFFER(cmd, ds);
1865 gen6_3DSTATE_HIER_DEPTH_BUFFER(cmd, ds);
Chia-I Wuf8231032014-08-25 10:44:45 +08001866
1867 if (cmd_gen(cmd) >= INTEL_GEN(7))
1868 gen7_3DSTATE_CLEAR_PARAMS(cmd, 0);
1869 else
1870 gen6_3DSTATE_CLEAR_PARAMS(cmd, 0);
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001871}
1872
1873static void cmd_bind_viewport_state(struct intel_cmd *cmd,
1874 const struct intel_viewport_state *state)
1875{
1876 cmd->bind.state.viewport = state;
1877}
1878
1879static void cmd_bind_raster_state(struct intel_cmd *cmd,
1880 const struct intel_raster_state *state)
1881{
1882 cmd->bind.state.raster = state;
1883}
1884
1885static void cmd_bind_ds_state(struct intel_cmd *cmd,
1886 const struct intel_ds_state *state)
1887{
1888 cmd->bind.state.ds = state;
1889}
1890
1891static void cmd_bind_blend_state(struct intel_cmd *cmd,
1892 const struct intel_blend_state *state)
1893{
1894 cmd->bind.state.blend = state;
1895}
1896
1897static void cmd_bind_msaa_state(struct intel_cmd *cmd,
1898 const struct intel_msaa_state *state)
1899{
1900 cmd->bind.state.msaa = state;
1901}
1902
1903static void cmd_draw(struct intel_cmd *cmd,
1904 XGL_UINT vertex_start,
1905 XGL_UINT vertex_count,
1906 XGL_UINT instance_start,
1907 XGL_UINT instance_count,
1908 bool indexed,
1909 XGL_UINT vertex_base)
1910{
1911 const struct intel_pipeline *p = cmd->bind.pipeline.graphics;
1912
1913 emit_bounded_states(cmd);
1914
1915 if (indexed) {
1916 if (p->primitive_restart && !gen6_can_primitive_restart(cmd))
1917 cmd->result = XGL_ERROR_UNKNOWN;
1918
1919 if (cmd_gen(cmd) >= INTEL_GEN(7.5)) {
1920 gen75_3DSTATE_VF(cmd, p->primitive_restart,
1921 p->primitive_restart_index);
1922 } else {
1923 gen6_3DSTATE_INDEX_BUFFER(cmd, cmd->bind.index.mem,
1924 cmd->bind.index.offset, cmd->bind.index.type,
1925 p->primitive_restart);
1926 }
1927 } else {
1928 assert(!vertex_base);
1929 }
1930
1931 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
1932 gen7_3DPRIMITIVE(cmd, p->prim_type, indexed, vertex_count,
1933 vertex_start, instance_count, instance_start, vertex_base);
1934 } else {
1935 gen6_3DPRIMITIVE(cmd, p->prim_type, indexed, vertex_count,
1936 vertex_start, instance_count, instance_start, vertex_base);
1937 }
Chia-I Wu48c283d2014-08-25 23:13:46 +08001938
Chia-I Wu707a29e2014-08-27 12:51:47 +08001939 cmd->bind.draw_count++;
Chia-I Wu48c283d2014-08-25 23:13:46 +08001940 /* need to re-emit all workarounds */
1941 cmd->bind.wa_flags = 0;
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001942}
1943
Chia-I Wub2755562014-08-20 13:38:52 +08001944XGL_VOID XGLAPI intelCmdBindPipeline(
1945 XGL_CMD_BUFFER cmdBuffer,
1946 XGL_PIPELINE_BIND_POINT pipelineBindPoint,
1947 XGL_PIPELINE pipeline)
1948{
1949 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
1950
1951 switch (pipelineBindPoint) {
1952 case XGL_PIPELINE_BIND_POINT_COMPUTE:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001953 cmd_bind_compute_pipeline(cmd, intel_pipeline(pipeline));
Chia-I Wub2755562014-08-20 13:38:52 +08001954 break;
1955 case XGL_PIPELINE_BIND_POINT_GRAPHICS:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001956 cmd_bind_graphics_pipeline(cmd, intel_pipeline(pipeline));
Chia-I Wub2755562014-08-20 13:38:52 +08001957 break;
1958 default:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001959 cmd->result = XGL_ERROR_INVALID_VALUE;
Chia-I Wub2755562014-08-20 13:38:52 +08001960 break;
1961 }
1962}
1963
1964XGL_VOID XGLAPI intelCmdBindPipelineDelta(
1965 XGL_CMD_BUFFER cmdBuffer,
1966 XGL_PIPELINE_BIND_POINT pipelineBindPoint,
1967 XGL_PIPELINE_DELTA delta)
1968{
1969 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
1970
1971 switch (pipelineBindPoint) {
1972 case XGL_PIPELINE_BIND_POINT_COMPUTE:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001973 cmd_bind_compute_delta(cmd, delta);
Chia-I Wub2755562014-08-20 13:38:52 +08001974 break;
1975 case XGL_PIPELINE_BIND_POINT_GRAPHICS:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001976 cmd_bind_graphics_delta(cmd, delta);
Chia-I Wub2755562014-08-20 13:38:52 +08001977 break;
1978 default:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001979 cmd->result = XGL_ERROR_INVALID_VALUE;
Chia-I Wub2755562014-08-20 13:38:52 +08001980 break;
1981 }
1982}
1983
1984XGL_VOID XGLAPI intelCmdBindStateObject(
1985 XGL_CMD_BUFFER cmdBuffer,
1986 XGL_STATE_BIND_POINT stateBindPoint,
1987 XGL_STATE_OBJECT state)
1988{
1989 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
1990
1991 switch (stateBindPoint) {
1992 case XGL_STATE_BIND_VIEWPORT:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001993 cmd_bind_viewport_state(cmd,
1994 intel_viewport_state((XGL_VIEWPORT_STATE_OBJECT) state));
Chia-I Wub2755562014-08-20 13:38:52 +08001995 break;
1996 case XGL_STATE_BIND_RASTER:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08001997 cmd_bind_raster_state(cmd,
1998 intel_raster_state((XGL_RASTER_STATE_OBJECT) state));
Chia-I Wub2755562014-08-20 13:38:52 +08001999 break;
2000 case XGL_STATE_BIND_DEPTH_STENCIL:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002001 cmd_bind_ds_state(cmd,
2002 intel_ds_state((XGL_DEPTH_STENCIL_STATE_OBJECT) state));
Chia-I Wub2755562014-08-20 13:38:52 +08002003 break;
2004 case XGL_STATE_BIND_COLOR_BLEND:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002005 cmd_bind_blend_state(cmd,
2006 intel_blend_state((XGL_COLOR_BLEND_STATE_OBJECT) state));
Chia-I Wub2755562014-08-20 13:38:52 +08002007 break;
2008 case XGL_STATE_BIND_MSAA:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002009 cmd_bind_msaa_state(cmd,
2010 intel_msaa_state((XGL_MSAA_STATE_OBJECT) state));
Chia-I Wub2755562014-08-20 13:38:52 +08002011 break;
2012 default:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002013 cmd->result = XGL_ERROR_INVALID_VALUE;
Chia-I Wub2755562014-08-20 13:38:52 +08002014 break;
2015 }
2016}
2017
2018XGL_VOID XGLAPI intelCmdBindDescriptorSet(
2019 XGL_CMD_BUFFER cmdBuffer,
2020 XGL_PIPELINE_BIND_POINT pipelineBindPoint,
2021 XGL_UINT index,
2022 XGL_DESCRIPTOR_SET descriptorSet,
2023 XGL_UINT slotOffset)
2024{
2025 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
2026 struct intel_dset *dset = intel_dset(descriptorSet);
2027
2028 assert(!index);
2029
2030 switch (pipelineBindPoint) {
2031 case XGL_PIPELINE_BIND_POINT_COMPUTE:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002032 cmd_bind_compute_dset(cmd, dset, slotOffset);
Chia-I Wub2755562014-08-20 13:38:52 +08002033 break;
2034 case XGL_PIPELINE_BIND_POINT_GRAPHICS:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002035 cmd_bind_graphics_dset(cmd, dset, slotOffset);
Chia-I Wub2755562014-08-20 13:38:52 +08002036 break;
2037 default:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002038 cmd->result = XGL_ERROR_INVALID_VALUE;
Chia-I Wub2755562014-08-20 13:38:52 +08002039 break;
2040 }
2041}
2042
2043XGL_VOID XGLAPI intelCmdBindDynamicMemoryView(
2044 XGL_CMD_BUFFER cmdBuffer,
2045 XGL_PIPELINE_BIND_POINT pipelineBindPoint,
2046 const XGL_MEMORY_VIEW_ATTACH_INFO* pMemView)
2047{
2048 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
2049
2050 switch (pipelineBindPoint) {
2051 case XGL_PIPELINE_BIND_POINT_COMPUTE:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002052 cmd_bind_compute_dyn_view(cmd, pMemView);
Chia-I Wub2755562014-08-20 13:38:52 +08002053 break;
2054 case XGL_PIPELINE_BIND_POINT_GRAPHICS:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002055 cmd_bind_graphics_dyn_view(cmd, pMemView);
Chia-I Wub2755562014-08-20 13:38:52 +08002056 break;
2057 default:
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002058 cmd->result = XGL_ERROR_INVALID_VALUE;
Chia-I Wub2755562014-08-20 13:38:52 +08002059 break;
2060 }
2061}
2062
2063XGL_VOID XGLAPI intelCmdBindIndexData(
2064 XGL_CMD_BUFFER cmdBuffer,
2065 XGL_GPU_MEMORY mem_,
2066 XGL_GPU_SIZE offset,
2067 XGL_INDEX_TYPE indexType)
2068{
2069 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
2070 struct intel_mem *mem = intel_mem(mem_);
2071
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002072 cmd_bind_index_data(cmd, mem, offset, indexType);
Chia-I Wub2755562014-08-20 13:38:52 +08002073}
2074
2075XGL_VOID XGLAPI intelCmdBindAttachments(
2076 XGL_CMD_BUFFER cmdBuffer,
2077 XGL_UINT colorAttachmentCount,
2078 const XGL_COLOR_ATTACHMENT_BIND_INFO* pColorAttachments,
2079 const XGL_DEPTH_STENCIL_BIND_INFO* pDepthStencilAttachment)
2080{
2081 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
Chia-I Wub2755562014-08-20 13:38:52 +08002082
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002083 cmd_bind_rt(cmd, pColorAttachments, colorAttachmentCount);
2084 cmd_bind_ds(cmd, pDepthStencilAttachment);
Chia-I Wub2755562014-08-20 13:38:52 +08002085}
2086
2087XGL_VOID XGLAPI intelCmdDraw(
2088 XGL_CMD_BUFFER cmdBuffer,
2089 XGL_UINT firstVertex,
2090 XGL_UINT vertexCount,
2091 XGL_UINT firstInstance,
2092 XGL_UINT instanceCount)
2093{
Chia-I Wu59c097e2014-08-21 10:51:07 +08002094 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
Chia-I Wu59c097e2014-08-21 10:51:07 +08002095
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002096 cmd_draw(cmd, firstVertex, vertexCount,
2097 firstInstance, instanceCount, false, 0);
Chia-I Wub2755562014-08-20 13:38:52 +08002098}
2099
2100XGL_VOID XGLAPI intelCmdDrawIndexed(
2101 XGL_CMD_BUFFER cmdBuffer,
2102 XGL_UINT firstIndex,
2103 XGL_UINT indexCount,
2104 XGL_INT vertexOffset,
2105 XGL_UINT firstInstance,
2106 XGL_UINT instanceCount)
2107{
Chia-I Wu59c097e2014-08-21 10:51:07 +08002108 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
Chia-I Wu59c097e2014-08-21 10:51:07 +08002109
Chia-I Wu9f1722c2014-08-25 10:17:58 +08002110 cmd_draw(cmd, firstIndex, indexCount,
2111 firstInstance, instanceCount, true, vertexOffset);
Chia-I Wub2755562014-08-20 13:38:52 +08002112}
2113
2114XGL_VOID XGLAPI intelCmdDrawIndirect(
2115 XGL_CMD_BUFFER cmdBuffer,
2116 XGL_GPU_MEMORY mem,
2117 XGL_GPU_SIZE offset,
2118 XGL_UINT32 count,
2119 XGL_UINT32 stride)
2120{
Chia-I Wu59c097e2014-08-21 10:51:07 +08002121 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
2122
2123 cmd->result = XGL_ERROR_UNKNOWN;
Chia-I Wub2755562014-08-20 13:38:52 +08002124}
2125
2126XGL_VOID XGLAPI intelCmdDrawIndexedIndirect(
2127 XGL_CMD_BUFFER cmdBuffer,
2128 XGL_GPU_MEMORY mem,
2129 XGL_GPU_SIZE offset,
2130 XGL_UINT32 count,
2131 XGL_UINT32 stride)
2132{
Chia-I Wu59c097e2014-08-21 10:51:07 +08002133 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
2134
2135 cmd->result = XGL_ERROR_UNKNOWN;
Chia-I Wub2755562014-08-20 13:38:52 +08002136}
2137
2138XGL_VOID XGLAPI intelCmdDispatch(
2139 XGL_CMD_BUFFER cmdBuffer,
2140 XGL_UINT x,
2141 XGL_UINT y,
2142 XGL_UINT z)
2143{
Chia-I Wu59c097e2014-08-21 10:51:07 +08002144 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
2145
2146 cmd->result = XGL_ERROR_UNKNOWN;
Chia-I Wub2755562014-08-20 13:38:52 +08002147}
2148
2149XGL_VOID XGLAPI intelCmdDispatchIndirect(
2150 XGL_CMD_BUFFER cmdBuffer,
2151 XGL_GPU_MEMORY mem,
2152 XGL_GPU_SIZE offset)
2153{
Chia-I Wu59c097e2014-08-21 10:51:07 +08002154 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
2155
2156 cmd->result = XGL_ERROR_UNKNOWN;
Chia-I Wub2755562014-08-20 13:38:52 +08002157}