blob: f8c8f6eeb79e9d3a7898ac7a28a28e030564bc5a [file] [log] [blame]
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001/*
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 * Courtney Goeltzenleuchter <courtney@lunarg.com>
26 * Chia-I Wu <olv@lunarg.com>
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060027 */
28
Chia-I Wu8370b402014-08-29 12:28:37 +080029#include "genhw/genhw.h"
Chia-I Wu3f239832014-12-11 22:57:18 +080030#include "compiler/pipeline/pipeline_compiler_interface.h"
Chia-I Wu8370b402014-08-29 12:28:37 +080031#include "cmd.h"
Chia-I Wu1d125092014-10-08 08:49:38 +080032#include "format.h"
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -060033#include "shader.h"
Chia-I Wu3f239832014-12-11 22:57:18 +080034#include "pipeline.h"
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060035
Tony Barbourfa6cac72015-01-16 14:27:35 -070036static int translate_blend_func(XGL_BLEND_FUNC func)
37{
38 switch (func) {
39 case XGL_BLEND_FUNC_ADD: return GEN6_BLENDFUNCTION_ADD;
40 case XGL_BLEND_FUNC_SUBTRACT: return GEN6_BLENDFUNCTION_SUBTRACT;
41 case XGL_BLEND_FUNC_REVERSE_SUBTRACT: return GEN6_BLENDFUNCTION_REVERSE_SUBTRACT;
42 case XGL_BLEND_FUNC_MIN: return GEN6_BLENDFUNCTION_MIN;
43 case XGL_BLEND_FUNC_MAX: return GEN6_BLENDFUNCTION_MAX;
44 default:
45 assert(!"unknown blend func");
46 return GEN6_BLENDFUNCTION_ADD;
47 };
48}
49
50static int translate_blend(XGL_BLEND blend)
51{
52 switch (blend) {
53 case XGL_BLEND_ZERO: return GEN6_BLENDFACTOR_ZERO;
54 case XGL_BLEND_ONE: return GEN6_BLENDFACTOR_ONE;
55 case XGL_BLEND_SRC_COLOR: return GEN6_BLENDFACTOR_SRC_COLOR;
56 case XGL_BLEND_ONE_MINUS_SRC_COLOR: return GEN6_BLENDFACTOR_INV_SRC_COLOR;
57 case XGL_BLEND_DEST_COLOR: return GEN6_BLENDFACTOR_DST_COLOR;
58 case XGL_BLEND_ONE_MINUS_DEST_COLOR: return GEN6_BLENDFACTOR_INV_DST_COLOR;
59 case XGL_BLEND_SRC_ALPHA: return GEN6_BLENDFACTOR_SRC_ALPHA;
60 case XGL_BLEND_ONE_MINUS_SRC_ALPHA: return GEN6_BLENDFACTOR_INV_SRC_ALPHA;
61 case XGL_BLEND_DEST_ALPHA: return GEN6_BLENDFACTOR_DST_ALPHA;
62 case XGL_BLEND_ONE_MINUS_DEST_ALPHA: return GEN6_BLENDFACTOR_INV_DST_ALPHA;
63 case XGL_BLEND_CONSTANT_COLOR: return GEN6_BLENDFACTOR_CONST_COLOR;
64 case XGL_BLEND_ONE_MINUS_CONSTANT_COLOR: return GEN6_BLENDFACTOR_INV_CONST_COLOR;
65 case XGL_BLEND_CONSTANT_ALPHA: return GEN6_BLENDFACTOR_CONST_ALPHA;
66 case XGL_BLEND_ONE_MINUS_CONSTANT_ALPHA: return GEN6_BLENDFACTOR_INV_CONST_ALPHA;
67 case XGL_BLEND_SRC_ALPHA_SATURATE: return GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE;
68 case XGL_BLEND_SRC1_COLOR: return GEN6_BLENDFACTOR_SRC1_COLOR;
69 case XGL_BLEND_ONE_MINUS_SRC1_COLOR: return GEN6_BLENDFACTOR_INV_SRC1_COLOR;
70 case XGL_BLEND_SRC1_ALPHA: return GEN6_BLENDFACTOR_SRC1_ALPHA;
71 case XGL_BLEND_ONE_MINUS_SRC1_ALPHA: return GEN6_BLENDFACTOR_INV_SRC1_ALPHA;
72 default:
73 assert(!"unknown blend factor");
74 return GEN6_BLENDFACTOR_ONE;
75 };
76}
77
78static int translate_compare_func(XGL_COMPARE_FUNC func)
79{
80 switch (func) {
81 case XGL_COMPARE_NEVER: return GEN6_COMPAREFUNCTION_NEVER;
82 case XGL_COMPARE_LESS: return GEN6_COMPAREFUNCTION_LESS;
83 case XGL_COMPARE_EQUAL: return GEN6_COMPAREFUNCTION_EQUAL;
84 case XGL_COMPARE_LESS_EQUAL: return GEN6_COMPAREFUNCTION_LEQUAL;
85 case XGL_COMPARE_GREATER: return GEN6_COMPAREFUNCTION_GREATER;
86 case XGL_COMPARE_NOT_EQUAL: return GEN6_COMPAREFUNCTION_NOTEQUAL;
87 case XGL_COMPARE_GREATER_EQUAL: return GEN6_COMPAREFUNCTION_GEQUAL;
88 case XGL_COMPARE_ALWAYS: return GEN6_COMPAREFUNCTION_ALWAYS;
89 default:
90 assert(!"unknown compare_func");
91 return GEN6_COMPAREFUNCTION_NEVER;
92 }
93}
94
95static int translate_stencil_op(XGL_STENCIL_OP op)
96{
97 switch (op) {
98 case XGL_STENCIL_OP_KEEP: return GEN6_STENCILOP_KEEP;
99 case XGL_STENCIL_OP_ZERO: return GEN6_STENCILOP_ZERO;
100 case XGL_STENCIL_OP_REPLACE: return GEN6_STENCILOP_REPLACE;
101 case XGL_STENCIL_OP_INC_CLAMP: return GEN6_STENCILOP_INCRSAT;
102 case XGL_STENCIL_OP_DEC_CLAMP: return GEN6_STENCILOP_DECRSAT;
103 case XGL_STENCIL_OP_INVERT: return GEN6_STENCILOP_INVERT;
104 case XGL_STENCIL_OP_INC_WRAP: return GEN6_STENCILOP_INCR;
105 case XGL_STENCIL_OP_DEC_WRAP: return GEN6_STENCILOP_DECR;
106 default:
107 assert(!"unknown stencil op");
108 return GEN6_STENCILOP_KEEP;
109 }
110}
111
Chia-I Wu3f239832014-12-11 22:57:18 +0800112struct intel_pipeline_create_info {
113 XGL_GRAPHICS_PIPELINE_CREATE_INFO graphics;
114 XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO vi;
115 XGL_PIPELINE_IA_STATE_CREATE_INFO ia;
Tony Barbourfa6cac72015-01-16 14:27:35 -0700116 XGL_PIPELINE_DS_STATE_CREATE_INFO db;
117 XGL_PIPELINE_CB_STATE_CREATE_INFO cb;
Chia-I Wu3f239832014-12-11 22:57:18 +0800118 XGL_PIPELINE_RS_STATE_CREATE_INFO rs;
119 XGL_PIPELINE_TESS_STATE_CREATE_INFO tess;
Tony Barbourfa6cac72015-01-16 14:27:35 -0700120 XGL_PIPELINE_MS_STATE_CREATE_INFO ms;
121 XGL_PIPELINE_VP_STATE_CREATE_INFO vp;
Chia-I Wu3f239832014-12-11 22:57:18 +0800122 XGL_PIPELINE_SHADER vs;
123 XGL_PIPELINE_SHADER tcs;
124 XGL_PIPELINE_SHADER tes;
125 XGL_PIPELINE_SHADER gs;
126 XGL_PIPELINE_SHADER fs;
127
128 XGL_COMPUTE_PIPELINE_CREATE_INFO compute;
129};
Chia-I Wu38d1ddf2015-03-02 10:51:39 -0700130
131/* in S1.3 */
132struct intel_pipeline_sample_position {
133 int8_t x, y;
134};
135
136static uint8_t pack_sample_position(const struct intel_dev *dev,
137 const struct intel_pipeline_sample_position *pos)
138{
139 return (pos->x + 8) << 4 | (pos->y + 8);
140}
141
142void intel_pipeline_init_default_sample_patterns(const struct intel_dev *dev,
143 uint8_t *pat_1x, uint8_t *pat_2x,
144 uint8_t *pat_4x, uint8_t *pat_8x,
145 uint8_t *pat_16x)
146{
147 static const struct intel_pipeline_sample_position default_1x[1] = {
148 { 0, 0 },
149 };
150 static const struct intel_pipeline_sample_position default_2x[2] = {
151 { -4, -4 },
152 { 4, 4 },
153 };
154 static const struct intel_pipeline_sample_position default_4x[4] = {
155 { -2, -6 },
156 { 6, -2 },
157 { -6, 2 },
158 { 2, 6 },
159 };
160 static const struct intel_pipeline_sample_position default_8x[8] = {
161 { -1, 1 },
162 { 1, 5 },
163 { 3, -5 },
164 { 5, 3 },
165 { -7, -1 },
166 { -3, -7 },
167 { 7, -3 },
168 { -5, 7 },
169 };
170 static const struct intel_pipeline_sample_position default_16x[16] = {
171 { 0, 2 },
172 { 3, 0 },
173 { -3, -2 },
174 { -2, -4 },
175 { 4, 3 },
176 { 5, 1 },
177 { 6, -1 },
178 { 2, -6 },
179 { -4, 5 },
180 { -5, -5 },
181 { -1, -7 },
182 { 7, -3 },
183 { -7, 4 },
184 { 1, -8 },
185 { -6, 6 },
186 { -8, 7 },
187 };
188 int i;
189
190 pat_1x[0] = pack_sample_position(dev, default_1x);
191 for (i = 0; i < 2; i++)
192 pat_2x[i] = pack_sample_position(dev, &default_2x[i]);
193 for (i = 0; i < 4; i++)
194 pat_4x[i] = pack_sample_position(dev, &default_4x[i]);
195 for (i = 0; i < 8; i++)
196 pat_8x[i] = pack_sample_position(dev, &default_8x[i]);
197 for (i = 0; i < 16; i++)
198 pat_16x[i] = pack_sample_position(dev, &default_16x[i]);
199}
200
Chia-I Wu3f239832014-12-11 22:57:18 +0800201struct intel_pipeline_shader *intel_pipeline_shader_create_meta(struct intel_dev *dev,
202 enum intel_dev_meta_shader id)
203{
204 struct intel_pipeline_shader *sh;
205 XGL_RESULT ret;
206
Chia-I Wuf9c81ef2015-02-22 13:49:15 +0800207 sh = intel_alloc(dev, sizeof(*sh), 0, XGL_SYSTEM_ALLOC_INTERNAL);
Chia-I Wu3f239832014-12-11 22:57:18 +0800208 if (!sh)
209 return NULL;
210 memset(sh, 0, sizeof(*sh));
211
212 ret = intel_pipeline_shader_compile_meta(sh, dev->gpu, id);
213 if (ret != XGL_SUCCESS) {
Chia-I Wuf9c81ef2015-02-22 13:49:15 +0800214 intel_free(dev, sh);
Chia-I Wu3f239832014-12-11 22:57:18 +0800215 return NULL;
216 }
217
218 switch (id) {
219 case INTEL_DEV_META_VS_FILL_MEM:
220 case INTEL_DEV_META_VS_COPY_MEM:
221 case INTEL_DEV_META_VS_COPY_MEM_UNALIGNED:
222 sh->max_threads = intel_gpu_get_max_threads(dev->gpu,
223 XGL_SHADER_STAGE_VERTEX);
224 break;
225 default:
226 sh->max_threads = intel_gpu_get_max_threads(dev->gpu,
227 XGL_SHADER_STAGE_FRAGMENT);
228 break;
229 }
230
231 return sh;
232}
233
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800234void intel_pipeline_shader_destroy(struct intel_dev *dev,
235 struct intel_pipeline_shader *sh)
Chia-I Wu3f239832014-12-11 22:57:18 +0800236{
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800237 intel_pipeline_shader_cleanup(sh, dev->gpu);
238 intel_free(dev, sh);
Chia-I Wu3f239832014-12-11 22:57:18 +0800239}
240
241static XGL_RESULT pipeline_build_shader(struct intel_pipeline *pipeline,
Chia-I Wuf8385062015-01-04 16:27:24 +0800242 const struct intel_desc_layout *layout,
243 const XGL_PIPELINE_SHADER *sh_info,
244 struct intel_pipeline_shader *sh)
Chia-I Wu3f239832014-12-11 22:57:18 +0800245{
246 XGL_RESULT ret;
247
Chia-I Wuf8385062015-01-04 16:27:24 +0800248 ret = intel_pipeline_shader_compile(sh,
249 pipeline->dev->gpu, layout, sh_info);
Chia-I Wu3f239832014-12-11 22:57:18 +0800250 if (ret != XGL_SUCCESS)
251 return ret;
252
253 sh->max_threads =
254 intel_gpu_get_max_threads(pipeline->dev->gpu, sh_info->stage);
255
256 /* 1KB aligned */
257 sh->scratch_offset = u_align(pipeline->scratch_size, 1024);
258 pipeline->scratch_size = sh->scratch_offset +
259 sh->per_thread_scratch_size * sh->max_threads;
260
261 pipeline->active_shaders |= 1 << sh_info->stage;
262
263 return XGL_SUCCESS;
264}
265
266static XGL_RESULT pipeline_build_shaders(struct intel_pipeline *pipeline,
267 const struct intel_pipeline_create_info *info)
268{
Chia-I Wuf8385062015-01-04 16:27:24 +0800269 const struct intel_desc_layout *layout =
270 intel_desc_layout(info->graphics.lastSetLayout);
Chia-I Wu3f239832014-12-11 22:57:18 +0800271 XGL_RESULT ret = XGL_SUCCESS;
272
Chia-I Wuf8385062015-01-04 16:27:24 +0800273 if (ret == XGL_SUCCESS && info->vs.shader) {
274 ret = pipeline_build_shader(pipeline, layout,
275 &info->vs, &pipeline->vs);
276 }
277 if (ret == XGL_SUCCESS && info->tcs.shader) {
278 ret = pipeline_build_shader(pipeline, layout,
279 &info->tcs,&pipeline->tcs);
280 }
281 if (ret == XGL_SUCCESS && info->tes.shader) {
282 ret = pipeline_build_shader(pipeline, layout,
283 &info->tes,&pipeline->tes);
284 }
285 if (ret == XGL_SUCCESS && info->gs.shader) {
286 ret = pipeline_build_shader(pipeline, layout,
287 &info->gs, &pipeline->gs);
288 }
289 if (ret == XGL_SUCCESS && info->fs.shader) {
290 ret = pipeline_build_shader(pipeline, layout,
291 &info->fs, &pipeline->fs);
292 }
Chia-I Wu3f239832014-12-11 22:57:18 +0800293
Chia-I Wuf8385062015-01-04 16:27:24 +0800294 if (ret == XGL_SUCCESS && info->compute.cs.shader) {
295 layout = intel_desc_layout(info->compute.lastSetLayout);
296 ret = pipeline_build_shader(pipeline, layout,
297 &info->compute.cs, &pipeline->cs);
298 }
Chia-I Wu3f239832014-12-11 22:57:18 +0800299
300 return ret;
301}
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600302static uint32_t *pipeline_cmd_ptr(struct intel_pipeline *pipeline, int cmd_len)
303{
304 uint32_t *ptr;
305
306 assert(pipeline->cmd_len + cmd_len < INTEL_PSO_CMD_ENTRIES);
307 ptr = &pipeline->cmds[pipeline->cmd_len];
308 pipeline->cmd_len += cmd_len;
309 return ptr;
310}
311
Chia-I Wube0a3d92014-09-02 13:20:59 +0800312static XGL_RESULT pipeline_build_ia(struct intel_pipeline *pipeline,
313 const struct intel_pipeline_create_info* info)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600314{
Chia-I Wube0a3d92014-09-02 13:20:59 +0800315 pipeline->topology = info->ia.topology;
316 pipeline->disable_vs_cache = info->ia.disableVertexReuse;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600317
Chia-I Wube0a3d92014-09-02 13:20:59 +0800318 switch (info->ia.topology) {
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600319 case XGL_TOPOLOGY_POINT_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600320 pipeline->prim_type = GEN6_3DPRIM_POINTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600321 break;
322 case XGL_TOPOLOGY_LINE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600323 pipeline->prim_type = GEN6_3DPRIM_LINELIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600324 break;
325 case XGL_TOPOLOGY_LINE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600326 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600327 break;
328 case XGL_TOPOLOGY_TRIANGLE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600329 pipeline->prim_type = GEN6_3DPRIM_TRILIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600330 break;
331 case XGL_TOPOLOGY_TRIANGLE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600332 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600333 break;
334 case XGL_TOPOLOGY_RECT_LIST:
335 /*
336 * TODO: Rect lists are special in XGL, do we need to do
337 * something special here?
338 * XGL Guide:
339 * The rectangle list is a special geometry primitive type
340 * that can be used for implementing post-processing techniques
341 * or efficient copy operations. There are some special limitations
342 * for rectangle primitives. They cannot be clipped, must
343 * be axis aligned and cannot have depth gradient.
344 * Failure to comply with these restrictions results in
345 * undefined rendering results.
346 */
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600347 pipeline->prim_type = GEN6_3DPRIM_RECTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600348 break;
349 case XGL_TOPOLOGY_QUAD_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600350 pipeline->prim_type = GEN6_3DPRIM_QUADLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600351 break;
352 case XGL_TOPOLOGY_QUAD_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600353 pipeline->prim_type = GEN6_3DPRIM_QUADSTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600354 break;
355 case XGL_TOPOLOGY_LINE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600356 pipeline->prim_type = GEN6_3DPRIM_LINELIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600357 break;
358 case XGL_TOPOLOGY_LINE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600359 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600360 break;
361 case XGL_TOPOLOGY_TRIANGLE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600362 pipeline->prim_type = GEN6_3DPRIM_TRILIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600363 break;
364 case XGL_TOPOLOGY_TRIANGLE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600365 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600366 break;
367 case XGL_TOPOLOGY_PATCH:
Chia-I Wube0a3d92014-09-02 13:20:59 +0800368 if (!info->tess.patchControlPoints ||
369 info->tess.patchControlPoints > 32)
370 return XGL_ERROR_BAD_PIPELINE_DATA;
371 pipeline->prim_type = GEN7_3DPRIM_PATCHLIST_1 +
372 info->tess.patchControlPoints - 1;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600373 break;
374 default:
375 return XGL_ERROR_BAD_PIPELINE_DATA;
376 }
377
Chia-I Wube0a3d92014-09-02 13:20:59 +0800378 if (info->ia.primitiveRestartEnable) {
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600379 pipeline->primitive_restart = true;
Chia-I Wube0a3d92014-09-02 13:20:59 +0800380 pipeline->primitive_restart_index = info->ia.primitiveRestartIndex;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600381 } else {
382 pipeline->primitive_restart = false;
383 }
384
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600385 return XGL_SUCCESS;
386}
387
Chia-I Wu3efef432014-08-28 15:00:16 +0800388static XGL_RESULT pipeline_rs_state(struct intel_pipeline *pipeline,
389 const XGL_PIPELINE_RS_STATE_CREATE_INFO* rs_state)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600390{
391 pipeline->depthClipEnable = rs_state->depthClipEnable;
392 pipeline->rasterizerDiscardEnable = rs_state->rasterizerDiscardEnable;
Tony Barbourfa6cac72015-01-16 14:27:35 -0700393
394 if (rs_state->provokingVertex == XGL_PROVOKING_VERTEX_FIRST) {
395 pipeline->provoking_vertex_tri = 0;
396 pipeline->provoking_vertex_trifan = 1;
397 pipeline->provoking_vertex_line = 0;
398 } else {
399 pipeline->provoking_vertex_tri = 2;
400 pipeline->provoking_vertex_trifan = 2;
401 pipeline->provoking_vertex_line = 1;
402 }
403
404 switch (rs_state->fillMode) {
405 case XGL_FILL_POINTS:
406 pipeline->cmd_sf_fill |= GEN7_SF_DW1_FRONTFACE_POINT |
407 GEN7_SF_DW1_BACKFACE_POINT;
408 break;
409 case XGL_FILL_WIREFRAME:
410 pipeline->cmd_sf_fill |= GEN7_SF_DW1_FRONTFACE_WIREFRAME |
411 GEN7_SF_DW1_BACKFACE_WIREFRAME;
412 break;
413 case XGL_FILL_SOLID:
414 default:
415 pipeline->cmd_sf_fill |= GEN7_SF_DW1_FRONTFACE_SOLID |
416 GEN7_SF_DW1_BACKFACE_SOLID;
417 break;
418 }
419
420 if (rs_state->frontFace == XGL_FRONT_FACE_CCW) {
421 pipeline->cmd_sf_fill |= GEN7_SF_DW1_FRONTWINDING_CCW;
422 pipeline->cmd_clip_cull |= GEN7_CLIP_DW1_FRONTWINDING_CCW;
423 }
424
425 switch (rs_state->cullMode) {
426 case XGL_CULL_NONE:
427 default:
428 pipeline->cmd_sf_cull |= GEN7_SF_DW2_CULLMODE_NONE;
429 pipeline->cmd_clip_cull |= GEN7_CLIP_DW1_CULLMODE_NONE;
430 break;
431 case XGL_CULL_FRONT:
432 pipeline->cmd_sf_cull |= GEN7_SF_DW2_CULLMODE_FRONT;
433 pipeline->cmd_clip_cull |= GEN7_CLIP_DW1_CULLMODE_FRONT;
434 break;
435 case XGL_CULL_BACK:
436 pipeline->cmd_sf_cull |= GEN7_SF_DW2_CULLMODE_BACK;
437 pipeline->cmd_clip_cull |= GEN7_CLIP_DW1_CULLMODE_BACK;
438 break;
439 case XGL_CULL_FRONT_AND_BACK:
440 pipeline->cmd_sf_cull |= GEN7_SF_DW2_CULLMODE_BOTH;
441 pipeline->cmd_clip_cull |= GEN7_CLIP_DW1_CULLMODE_BOTH;
442 break;
443 }
444
445 /* only GEN7+ needs cull mode in 3DSTATE_CLIP */
446 if (intel_gpu_gen(pipeline->dev->gpu) == INTEL_GEN(6))
447 pipeline->cmd_clip_cull = 0;
448
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600449 return XGL_SUCCESS;
450}
451
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600452static void pipeline_destroy(struct intel_obj *obj)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600453{
454 struct intel_pipeline *pipeline = intel_pipeline_from_obj(obj);
455
Chia-I Wu3f239832014-12-11 22:57:18 +0800456 if (pipeline->active_shaders & SHADER_VERTEX_FLAG) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800457 intel_pipeline_shader_cleanup(&pipeline->vs, pipeline->dev->gpu);
Chia-I Wu3f239832014-12-11 22:57:18 +0800458 }
459
460 if (pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800461 intel_pipeline_shader_cleanup(&pipeline->tcs, pipeline->dev->gpu);
Chia-I Wu3f239832014-12-11 22:57:18 +0800462 }
463
464 if (pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800465 intel_pipeline_shader_cleanup(&pipeline->tes, pipeline->dev->gpu);
Chia-I Wu3f239832014-12-11 22:57:18 +0800466 }
467
468 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800469 intel_pipeline_shader_cleanup(&pipeline->gs, pipeline->dev->gpu);
Chia-I Wu3f239832014-12-11 22:57:18 +0800470 }
471
472 if (pipeline->active_shaders & SHADER_FRAGMENT_FLAG) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800473 intel_pipeline_shader_cleanup(&pipeline->fs, pipeline->dev->gpu);
Chia-I Wu3f239832014-12-11 22:57:18 +0800474 }
475
476 if (pipeline->active_shaders & SHADER_COMPUTE_FLAG) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800477 intel_pipeline_shader_cleanup(&pipeline->cs, pipeline->dev->gpu);
Chia-I Wu3f239832014-12-11 22:57:18 +0800478 }
Chia-I Wued833872014-08-23 17:00:35 +0800479
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600480 intel_base_destroy(&pipeline->obj.base);
481}
482
Chia-I Wub1024732014-12-19 13:00:29 +0800483static XGL_RESULT pipeline_get_info(struct intel_base *base, int type,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600484 size_t *size, void *data)
Chia-I Wub1024732014-12-19 13:00:29 +0800485{
486 struct intel_pipeline *pipeline = intel_pipeline_from_base(base);
487 XGL_RESULT ret = XGL_SUCCESS;
488
489 switch (type) {
490 case XGL_INFO_TYPE_MEMORY_REQUIREMENTS:
491 {
492 XGL_MEMORY_REQUIREMENTS *mem_req = data;
493
494 *size = sizeof(XGL_MEMORY_REQUIREMENTS);
495 if (data) {
496 mem_req->size = pipeline->scratch_size;
497 mem_req->alignment = 1024;
Jon Ashburnd8031332015-01-22 10:52:13 -0700498 mem_req->memType = XGL_MEMORY_TYPE_OTHER;
Chia-I Wub1024732014-12-19 13:00:29 +0800499 }
500 }
501 break;
502 default:
503 ret = intel_base_get_info(base, type, size, data);
504 break;
505 }
506
507 return ret;
508}
509
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800510static XGL_RESULT pipeline_validate(struct intel_pipeline *pipeline)
Chia-I Wu3efef432014-08-28 15:00:16 +0800511{
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600512 /*
513 * Validate required elements
514 */
515 if (!(pipeline->active_shaders & SHADER_VERTEX_FLAG)) {
516 // TODO: Log debug message: Vertex Shader required.
Chia-I Wu3efef432014-08-28 15:00:16 +0800517 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600518 }
519
520 /*
521 * Tessalation control and evaluation have to both have a shader defined or
522 * neither should have a shader defined.
523 */
524 if (((pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) == 0) !=
525 ((pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) == 0) ) {
526 // TODO: Log debug message: Both Tess control and Tess eval are required to use tessalation
Chia-I Wu3efef432014-08-28 15:00:16 +0800527 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600528 }
529
530 if ((pipeline->active_shaders & SHADER_COMPUTE_FLAG) &&
531 (pipeline->active_shaders & (SHADER_VERTEX_FLAG | SHADER_TESS_CONTROL_FLAG |
532 SHADER_TESS_EVAL_FLAG | SHADER_GEOMETRY_FLAG |
533 SHADER_FRAGMENT_FLAG))) {
534 // TODO: Log debug message: Can only specify compute shader when doing compute
Chia-I Wu3efef432014-08-28 15:00:16 +0800535 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600536 }
537
538 /*
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600539 * XGL_TOPOLOGY_PATCH primitive topology is only valid for tessellation pipelines.
540 * Mismatching primitive topology and tessellation fails graphics pipeline creation.
541 */
542 if (pipeline->active_shaders & (SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG) &&
Chia-I Wube0a3d92014-09-02 13:20:59 +0800543 (pipeline->topology != XGL_TOPOLOGY_PATCH)) {
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600544 // TODO: Log debug message: Invalid topology used with tessalation shader.
Chia-I Wu3efef432014-08-28 15:00:16 +0800545 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600546 }
547
Chia-I Wube0a3d92014-09-02 13:20:59 +0800548 if ((pipeline->topology == XGL_TOPOLOGY_PATCH) &&
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600549 (pipeline->active_shaders & ~(SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG))) {
550 // TODO: Log debug message: Cannot use TOPOLOGY_PATCH on non-tessalation shader.
Chia-I Wu3efef432014-08-28 15:00:16 +0800551 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600552 }
553
Chia-I Wu3efef432014-08-28 15:00:16 +0800554 return XGL_SUCCESS;
555}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600556
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800557static void pipeline_build_urb_alloc_gen6(struct intel_pipeline *pipeline,
558 const struct intel_pipeline_create_info *info)
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800559{
Chia-I Wu509b3f22014-09-02 10:24:05 +0800560 const struct intel_gpu *gpu = pipeline->dev->gpu;
561 const int urb_size = ((gpu->gt == 2) ? 64 : 32) * 1024;
Chia-I Wua4d1b392014-10-10 13:57:29 +0800562 const struct intel_pipeline_shader *vs = &pipeline->vs;
563 const struct intel_pipeline_shader *gs = &pipeline->gs;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800564 int vs_entry_size, gs_entry_size;
565 int vs_size, gs_size;
566
Chia-I Wu509b3f22014-09-02 10:24:05 +0800567 INTEL_GPU_ASSERT(gpu, 6, 6);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800568
569 vs_entry_size = ((vs->in_count >= vs->out_count) ?
570 vs->in_count : vs->out_count);
571 gs_entry_size = (gs) ? gs->out_count : 0;
572
573 /* in bytes */
574 vs_entry_size *= sizeof(float) * 4;
575 gs_entry_size *= sizeof(float) * 4;
576
Chia-I Wua4d1b392014-10-10 13:57:29 +0800577 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800578 vs_size = urb_size / 2;
579 gs_size = vs_size;
580 } else {
581 vs_size = urb_size;
582 gs_size = 0;
583 }
584
585 /* 3DSTATE_URB */
586 {
587 const uint8_t cmd_len = 3;
588 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_URB) |
589 (cmd_len - 2);
590 int vs_alloc_size, gs_alloc_size;
591 int vs_entry_count, gs_entry_count;
592 uint32_t *dw;
593
594 /* in 1024-bit rows */
595 vs_alloc_size = (vs_entry_size + 128 - 1) / 128;
596 gs_alloc_size = (gs_entry_size + 128 - 1) / 128;
597
598 /* valid range is [1, 5] */
599 if (!vs_alloc_size)
600 vs_alloc_size = 1;
601 if (!gs_alloc_size)
602 gs_alloc_size = 1;
603 assert(vs_alloc_size <= 5 && gs_alloc_size <= 5);
604
605 /* valid range is [24, 256], multiples of 4 */
606 vs_entry_count = (vs_size / 128 / vs_alloc_size) & ~3;
607 if (vs_entry_count > 256)
608 vs_entry_count = 256;
609 assert(vs_entry_count >= 24);
610
611 /* valid range is [0, 256], multiples of 4 */
612 gs_entry_count = (gs_size / 128 / gs_alloc_size) & ~3;
613 if (gs_entry_count > 256)
614 gs_entry_count = 256;
615
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600616 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800617
618 dw[0] = dw0;
619 dw[1] = (vs_alloc_size - 1) << GEN6_URB_DW1_VS_ENTRY_SIZE__SHIFT |
620 vs_entry_count << GEN6_URB_DW1_VS_ENTRY_COUNT__SHIFT;
621 dw[2] = gs_entry_count << GEN6_URB_DW2_GS_ENTRY_COUNT__SHIFT |
622 (gs_alloc_size - 1) << GEN6_URB_DW2_GS_ENTRY_SIZE__SHIFT;
623 }
624}
625
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800626static void pipeline_build_urb_alloc_gen7(struct intel_pipeline *pipeline,
627 const struct intel_pipeline_create_info *info)
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800628{
Chia-I Wu509b3f22014-09-02 10:24:05 +0800629 const struct intel_gpu *gpu = pipeline->dev->gpu;
630 const int urb_size = ((gpu->gt == 3) ? 512 :
631 (gpu->gt == 2) ? 256 : 128) * 1024;
Cody Northrop306ec352014-10-06 15:11:45 -0600632 const struct intel_pipeline_shader *vs = &pipeline->vs;
633 const struct intel_pipeline_shader *gs = &pipeline->gs;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800634 /* some space is reserved for PCBs */
Chia-I Wu509b3f22014-09-02 10:24:05 +0800635 int urb_offset = ((gpu->gt == 3) ? 32 : 16) * 1024;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800636 int vs_entry_size, gs_entry_size;
637 int vs_size, gs_size;
638
Chia-I Wu509b3f22014-09-02 10:24:05 +0800639 INTEL_GPU_ASSERT(gpu, 7, 7.5);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800640
641 vs_entry_size = ((vs->in_count >= vs->out_count) ?
642 vs->in_count : vs->out_count);
643 gs_entry_size = (gs) ? gs->out_count : 0;
644
645 /* in bytes */
646 vs_entry_size *= sizeof(float) * 4;
647 gs_entry_size *= sizeof(float) * 4;
648
Chia-I Wua4d1b392014-10-10 13:57:29 +0800649 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800650 vs_size = (urb_size - urb_offset) / 2;
651 gs_size = vs_size;
652 } else {
653 vs_size = urb_size - urb_offset;
654 gs_size = 0;
655 }
656
657 /* 3DSTATE_URB_* */
658 {
659 const uint8_t cmd_len = 2;
660 int vs_alloc_size, gs_alloc_size;
661 int vs_entry_count, gs_entry_count;
662 uint32_t *dw;
663
664 /* in 512-bit rows */
665 vs_alloc_size = (vs_entry_size + 64 - 1) / 64;
666 gs_alloc_size = (gs_entry_size + 64 - 1) / 64;
667
668 if (!vs_alloc_size)
669 vs_alloc_size = 1;
670 if (!gs_alloc_size)
671 gs_alloc_size = 1;
672
673 /* avoid performance decrease due to banking */
674 if (vs_alloc_size == 5)
675 vs_alloc_size = 6;
676
677 /* in multiples of 8 */
678 vs_entry_count = (vs_size / 64 / vs_alloc_size) & ~7;
679 assert(vs_entry_count >= 32);
680
681 gs_entry_count = (gs_size / 64 / gs_alloc_size) & ~7;
682
Chia-I Wu509b3f22014-09-02 10:24:05 +0800683 if (intel_gpu_gen(gpu) >= INTEL_GEN(7.5)) {
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800684 const int max_vs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800685 (gpu->gt >= 2) ? 1664 : 640;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800686 const int max_gs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800687 (gpu->gt >= 2) ? 640 : 256;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800688 if (vs_entry_count >= max_vs_entry_count)
689 vs_entry_count = max_vs_entry_count;
690 if (gs_entry_count >= max_gs_entry_count)
691 gs_entry_count = max_gs_entry_count;
692 } else {
693 const int max_vs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800694 (gpu->gt == 2) ? 704 : 512;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800695 const int max_gs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800696 (gpu->gt == 2) ? 320 : 192;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800697 if (vs_entry_count >= max_vs_entry_count)
698 vs_entry_count = max_vs_entry_count;
699 if (gs_entry_count >= max_gs_entry_count)
700 gs_entry_count = max_gs_entry_count;
701 }
702
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600703 dw = pipeline_cmd_ptr(pipeline, cmd_len*4);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800704 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_VS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700705 dw[1] = (urb_offset / 8192) << GEN7_URB_DW1_OFFSET__SHIFT |
706 (vs_alloc_size - 1) << GEN7_URB_DW1_ENTRY_SIZE__SHIFT |
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800707 vs_entry_count;
708
709 dw += 2;
710 if (gs_size)
711 urb_offset += vs_size;
712 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_GS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700713 dw[1] = (urb_offset / 8192) << GEN7_URB_DW1_OFFSET__SHIFT |
714 (gs_alloc_size - 1) << GEN7_URB_DW1_ENTRY_SIZE__SHIFT |
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800715 gs_entry_count;
716
717 dw += 2;
718 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_HS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700719 dw[1] = (urb_offset / 8192) << GEN7_URB_DW1_OFFSET__SHIFT;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800720
721 dw += 2;
722 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_DS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700723 dw[1] = (urb_offset / 8192) << GEN7_URB_DW1_OFFSET__SHIFT;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800724 }
725}
726
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800727static void pipeline_build_push_const_alloc_gen7(struct intel_pipeline *pipeline,
728 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600729{
Chia-I Wu29193752015-02-11 11:04:05 -0700730 const struct intel_gpu *gpu = pipeline->dev->gpu;
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600731 const uint8_t cmd_len = 2;
732 uint32_t offset = 0;
733 uint32_t size = 8192;
734 uint32_t *dw;
735 int end;
736
Chia-I Wu509b3f22014-09-02 10:24:05 +0800737 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600738
739 /*
740 * From the Ivy Bridge PRM, volume 2 part 1, page 68:
741 *
742 * "(A table that says the maximum size of each constant buffer is
743 * 16KB")
744 *
745 * From the Ivy Bridge PRM, volume 2 part 1, page 115:
746 *
747 * "The sum of the Constant Buffer Offset and the Constant Buffer Size
748 * may not exceed the maximum value of the Constant Buffer Size."
749 *
750 * Thus, the valid range of buffer end is [0KB, 16KB].
751 */
752 end = (offset + size) / 1024;
753 if (end > 16) {
754 assert(!"invalid constant buffer end");
755 end = 16;
756 }
757
758 /* the valid range of buffer offset is [0KB, 15KB] */
759 offset = (offset + 1023) / 1024;
760 if (offset > 15) {
761 assert(!"invalid constant buffer offset");
762 offset = 15;
763 }
764
765 if (offset > end) {
766 assert(!size);
767 offset = end;
768 }
769
770 /* the valid range of buffer size is [0KB, 15KB] */
771 size = end - offset;
772 if (size > 15) {
773 assert(!"invalid constant buffer size");
774 size = 15;
775 }
776
Chia-I Wu29193752015-02-11 11:04:05 -0700777 if (gpu->gt == 3)
778 size *= 2;
779
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800780 dw = pipeline_cmd_ptr(pipeline, cmd_len * 5);
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600781 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_VS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700782 dw[1] = offset << GEN7_PCB_ALLOC_DW1_OFFSET__SHIFT |
783 size << GEN7_PCB_ALLOC_DW1_SIZE__SHIFT;
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600784
785 dw += 2;
786 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_PS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700787 dw[1] = size << GEN7_PCB_ALLOC_DW1_OFFSET__SHIFT |
788 size << GEN7_PCB_ALLOC_DW1_SIZE__SHIFT;
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600789
790 dw += 2;
791 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_HS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700792 dw[1] = 0 << GEN7_PCB_ALLOC_DW1_OFFSET__SHIFT |
793 0 << GEN7_PCB_ALLOC_DW1_SIZE__SHIFT;
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600794
795 dw += 2;
796 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_DS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700797 dw[1] = 0 << GEN7_PCB_ALLOC_DW1_OFFSET__SHIFT |
798 0 << GEN7_PCB_ALLOC_DW1_SIZE__SHIFT;
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600799
800 dw += 2;
801 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_GS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700802 dw[1] = 0 << GEN7_PCB_ALLOC_DW1_OFFSET__SHIFT |
803 0 << GEN7_PCB_ALLOC_DW1_SIZE__SHIFT;
Chia-I Wu8370b402014-08-29 12:28:37 +0800804
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600805 // gen7_wa_pipe_control_cs_stall(p, true, true);
806 // looks equivalent to: gen6_wa_wm_multisample_flush - this does more
807 // than the documentation seems to imply
808}
809
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800810static void pipeline_build_vertex_elements(struct intel_pipeline *pipeline,
811 const struct intel_pipeline_create_info *info)
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800812{
Cody Northrop306ec352014-10-06 15:11:45 -0600813 const struct intel_pipeline_shader *vs = &pipeline->vs;
Chia-I Wu1d125092014-10-08 08:49:38 +0800814 uint8_t cmd_len;
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800815 uint32_t *dw;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600816 uint32_t i;
Chia-I Wu1d125092014-10-08 08:49:38 +0800817 int comps[4];
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800818
Chia-I Wu509b3f22014-09-02 10:24:05 +0800819 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800820
GregF8cd81832014-11-18 18:01:01 -0700821 cmd_len = 1 + 2 * u_popcountll(vs->inputs_read);
Chia-I Wu1d125092014-10-08 08:49:38 +0800822 if (vs->uses & (INTEL_SHADER_USE_VID | INTEL_SHADER_USE_IID))
823 cmd_len += 2;
824
825 if (cmd_len == 1)
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800826 return;
827
828 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Chia-I Wu1d125092014-10-08 08:49:38 +0800829
830 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_ELEMENTS) |
831 (cmd_len - 2);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800832 dw++;
833
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800834 /* VERTEX_ELEMENT_STATE */
Chia-I Wu1d125092014-10-08 08:49:38 +0800835 for (i = 0; i < info->vi.attributeCount; i++) {
GregF8cd81832014-11-18 18:01:01 -0700836 if (!(vs->inputs_read & (1L << i)))
GregF2dc40212014-10-31 17:31:47 -0600837 continue;
Chia-I Wu1d125092014-10-08 08:49:38 +0800838 const XGL_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION *attr =
839 &info->vi.pVertexAttributeDescriptions[i];
840 const int format =
841 intel_format_translate_color(pipeline->dev->gpu, attr->format);
842
843 comps[0] = GEN6_VFCOMP_STORE_0;
844 comps[1] = GEN6_VFCOMP_STORE_0;
845 comps[2] = GEN6_VFCOMP_STORE_0;
846 comps[3] = icd_format_is_int(attr->format) ?
847 GEN6_VFCOMP_STORE_1_INT : GEN6_VFCOMP_STORE_1_FP;
848
849 switch (icd_format_get_channel_count(attr->format)) {
850 case 4: comps[3] = GEN6_VFCOMP_STORE_SRC; /* fall through */
851 case 3: comps[2] = GEN6_VFCOMP_STORE_SRC; /* fall through */
852 case 2: comps[1] = GEN6_VFCOMP_STORE_SRC; /* fall through */
853 case 1: comps[0] = GEN6_VFCOMP_STORE_SRC; break;
854 default:
855 break;
856 }
857
858 assert(attr->offsetInBytes <= 2047);
859
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700860 dw[0] = attr->binding << GEN6_VE_DW0_VB_INDEX__SHIFT |
861 GEN6_VE_DW0_VALID |
862 format << GEN6_VE_DW0_FORMAT__SHIFT |
Chia-I Wu1d125092014-10-08 08:49:38 +0800863 attr->offsetInBytes;
864
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700865 dw[1] = comps[0] << GEN6_VE_DW1_COMP0__SHIFT |
866 comps[1] << GEN6_VE_DW1_COMP1__SHIFT |
867 comps[2] << GEN6_VE_DW1_COMP2__SHIFT |
868 comps[3] << GEN6_VE_DW1_COMP3__SHIFT;
Chia-I Wu1d125092014-10-08 08:49:38 +0800869
870 dw += 2;
871 }
GregF932fcf52014-10-29 17:02:11 -0600872
873 if (vs->uses & (INTEL_SHADER_USE_VID | INTEL_SHADER_USE_IID)) {
874 comps[0] = (vs->uses & INTEL_SHADER_USE_VID) ?
875 GEN6_VFCOMP_STORE_VID : GEN6_VFCOMP_STORE_0;
876 comps[1] = (vs->uses & INTEL_SHADER_USE_IID) ?
877 GEN6_VFCOMP_STORE_IID : GEN6_VFCOMP_NOSTORE;
878 comps[2] = GEN6_VFCOMP_NOSTORE;
879 comps[3] = GEN6_VFCOMP_NOSTORE;
880
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700881 dw[0] = GEN6_VE_DW0_VALID;
882 dw[1] = comps[0] << GEN6_VE_DW1_COMP0__SHIFT |
883 comps[1] << GEN6_VE_DW1_COMP1__SHIFT |
884 comps[2] << GEN6_VE_DW1_COMP2__SHIFT |
885 comps[3] << GEN6_VE_DW1_COMP3__SHIFT;
GregF932fcf52014-10-29 17:02:11 -0600886
887 dw += 2;
888 }
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800889}
890
GregF8cd81832014-11-18 18:01:01 -0700891static void pipeline_build_fragment_SBE(struct intel_pipeline *pipeline)
892{
893 const struct intel_pipeline_shader *fs = &pipeline->fs;
894 const struct intel_pipeline_shader *vs = &pipeline->vs;
895 uint8_t cmd_len;
896 uint32_t *body;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600897 uint32_t attr_skip, attr_count;
898 uint32_t vue_offset, vue_len;
899 uint32_t i;
GregF8cd81832014-11-18 18:01:01 -0700900
901 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
902
903 cmd_len = 14;
904
Chia-I Wuf85def42015-01-29 00:34:24 +0800905 if (intel_gpu_gen(pipeline->dev->gpu) >= INTEL_GEN(7))
906 body = pipeline_cmd_ptr(pipeline, cmd_len);
907 else
908 body = pipeline->cmd_3dstate_sbe;
GregF8cd81832014-11-18 18:01:01 -0700909
910 /* VS outputs VUE header and position additionally */
911 assert(vs->out_count >= fs->in_count + 2);
912 assert(!fs->reads_user_clip || vs->enable_user_clip);
913 attr_skip = vs->outputs_offset;
914 if (vs->enable_user_clip != fs->reads_user_clip) {
915 attr_skip += 2;
916 }
917 assert(vs->out_count >= attr_skip);
918 attr_count = vs->out_count - attr_skip;
919
920 // LUNARG TODO: We currently are only handling 16 attrs;
921 // ultimately, we need to handle 32
922 assert(fs->in_count <= 16);
923 assert(attr_count <= 16);
924
925 vue_offset = attr_skip / 2;
926 vue_len = (attr_count + 1) / 2;
927 if (!vue_len)
928 vue_len = 1;
929
930 body[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SBE) |
931 (cmd_len - 2);
932
933 // LUNARG TODO: If the attrs needed by the FS are exactly
934 // what is written by the VS, we don't need to enable
935 // swizzling, improving performance. Even if we swizzle,
936 // we can improve performance by reducing vue_len to
937 // just include the values needed by the FS:
938 // vue_len = ceiling((max_vs_out + 1)/2)
939
940 body[1] = GEN7_SBE_DW1_ATTR_SWIZZLE_ENABLE |
941 fs->in_count << GEN7_SBE_DW1_ATTR_COUNT__SHIFT |
942 vue_len << GEN7_SBE_DW1_URB_READ_LEN__SHIFT |
943 vue_offset << GEN7_SBE_DW1_URB_READ_OFFSET__SHIFT;
944
945 uint16_t vs_slot[fs->in_count];
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600946 int32_t fs_in = 0;
947 int32_t vs_out = - (vue_offset * 2 - vs->outputs_offset);
GregF8cd81832014-11-18 18:01:01 -0700948 for (i=0; i < 64; i++) {
Cody Northropd75c13e2015-01-02 14:07:20 -0700949 bool vsWrites = vs->outputs_written & (1L << i);
950 bool fsReads = fs->inputs_read & (1L << i);
951
952 if (fsReads) {
GregF8cd81832014-11-18 18:01:01 -0700953 assert(vs_out >= 0);
954 assert(fs_in < fs->in_count);
955 vs_slot[fs_in] = vs_out;
Cody Northropd75c13e2015-01-02 14:07:20 -0700956
957 if (!vsWrites) {
958 // If the vertex shader did not write this input, we cannot
959 // program the SBE to read it. Our choices are to allow it to
960 // read junk from a GRF, or get zero. We're choosing zero.
961 if (i >= fs->generic_input_start) {
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700962 vs_slot[fs_in] = GEN8_SBE_SWIZ_CONST_0000 |
963 GEN8_SBE_SWIZ_OVERRIDE_X |
964 GEN8_SBE_SWIZ_OVERRIDE_Y |
965 GEN8_SBE_SWIZ_OVERRIDE_Z |
966 GEN8_SBE_SWIZ_OVERRIDE_W;
Cody Northropd75c13e2015-01-02 14:07:20 -0700967 }
968 }
969
GregF8cd81832014-11-18 18:01:01 -0700970 fs_in += 1;
971 }
Cody Northropd75c13e2015-01-02 14:07:20 -0700972 if (vsWrites) {
GregF8cd81832014-11-18 18:01:01 -0700973 vs_out += 1;
974 }
975 }
976
977 for (i = 0; i < 8; i++) {
978 uint16_t hi, lo;
979
980 /* no attr swizzles */
981 if (i * 2 + 1 < fs->in_count) {
982 lo = vs_slot[i * 2];
983 hi = vs_slot[i * 2 + 1];
984 } else if (i * 2 < fs->in_count) {
985 lo = vs_slot[i * 2];
986 hi = 0;
987 } else {
988 hi = 0;
989 lo = 0;
990 }
991
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700992 body[2 + i] = hi << GEN8_SBE_SWIZ_HIGH__SHIFT | lo;
GregF8cd81832014-11-18 18:01:01 -0700993 }
994
995 body[10] = 0; /* point sprite enables */
996 body[11] = 0; /* constant interpolation enables */
997 body[12] = 0; /* WrapShortest enables */
998 body[13] = 0;
999}
1000
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001001static void pipeline_build_gs(struct intel_pipeline *pipeline,
1002 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -06001003{
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -06001004 // gen7_emit_3DSTATE_GS done by cmd_pipeline
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -06001005}
1006
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001007static void pipeline_build_hs(struct intel_pipeline *pipeline,
1008 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -06001009{
1010 const uint8_t cmd_len = 7;
1011 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
1012 uint32_t *dw;
1013
Chia-I Wu509b3f22014-09-02 10:24:05 +08001014 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -06001015
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001016 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -06001017 dw[0] = dw0;
1018 dw[1] = 0;
1019 dw[2] = 0;
1020 dw[3] = 0;
1021 dw[4] = 0;
1022 dw[5] = 0;
1023 dw[6] = 0;
1024}
1025
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001026static void pipeline_build_te(struct intel_pipeline *pipeline,
1027 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -06001028{
1029 const uint8_t cmd_len = 4;
1030 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_TE) | (cmd_len - 2);
1031 uint32_t *dw;
1032
Chia-I Wu509b3f22014-09-02 10:24:05 +08001033 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -06001034
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001035 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -06001036 dw[0] = dw0;
1037 dw[1] = 0;
1038 dw[2] = 0;
1039 dw[3] = 0;
1040}
1041
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001042static void pipeline_build_ds(struct intel_pipeline *pipeline,
1043 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -06001044{
1045 const uint8_t cmd_len = 6;
1046 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
1047 uint32_t *dw;
1048
Chia-I Wu509b3f22014-09-02 10:24:05 +08001049 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -06001050
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001051 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -06001052 dw[0] = dw0;
1053 dw[1] = 0;
1054 dw[2] = 0;
1055 dw[3] = 0;
1056 dw[4] = 0;
1057 dw[5] = 0;
1058}
1059
Tony Barbourfa6cac72015-01-16 14:27:35 -07001060static void pipeline_build_depth_stencil(struct intel_pipeline *pipeline,
1061 const struct intel_pipeline_create_info *info)
1062{
1063 pipeline->cmd_depth_stencil = 0;
1064
1065 if (info->db.stencilTestEnable) {
1066 pipeline->cmd_depth_stencil = 1 << 31 |
1067 translate_compare_func(info->db.front.stencilFunc) << 28 |
1068 translate_stencil_op(info->db.front.stencilFailOp) << 25 |
1069 translate_stencil_op(info->db.front.stencilDepthFailOp) << 22 |
1070 translate_stencil_op(info->db.front.stencilPassOp) << 19 |
1071 1 << 15 |
1072 translate_compare_func(info->db.back.stencilFunc) << 12 |
1073 translate_stencil_op(info->db.back.stencilFailOp) << 9 |
1074 translate_stencil_op(info->db.back.stencilDepthFailOp) << 6 |
1075 translate_stencil_op(info->db.back.stencilPassOp) << 3;
1076 }
1077
1078 pipeline->stencilTestEnable = info->db.stencilTestEnable;
1079
1080 /*
1081 * From the Sandy Bridge PRM, volume 2 part 1, page 360:
1082 *
1083 * "Enabling the Depth Test function without defining a Depth Buffer is
1084 * UNDEFINED."
1085 *
1086 * From the Sandy Bridge PRM, volume 2 part 1, page 375:
1087 *
1088 * "A Depth Buffer must be defined before enabling writes to it, or
1089 * operation is UNDEFINED."
1090 *
1091 * TODO We do not check these yet.
1092 */
1093 if (info->db.depthTestEnable) {
1094 pipeline->cmd_depth_test = GEN6_ZS_DW2_DEPTH_TEST_ENABLE |
1095 translate_compare_func(info->db.depthFunc) << 27;
1096 } else {
1097 pipeline->cmd_depth_test = GEN6_COMPAREFUNCTION_ALWAYS << 27;
1098 }
1099
1100 if (info->db.depthWriteEnable)
1101 pipeline->cmd_depth_test |= GEN6_ZS_DW2_DEPTH_WRITE_ENABLE;
1102}
1103
Tony Barbourfa6cac72015-01-16 14:27:35 -07001104static void pipeline_build_msaa(struct intel_pipeline *pipeline,
1105 const struct intel_pipeline_create_info *info)
1106{
1107 uint32_t cmd, cmd_len;
1108 uint32_t *dw;
1109
1110 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
1111
Chia-I Wu8ada4242015-03-02 11:19:33 -07001112 pipeline->sample_count = (info->ms.samples <= 1) ? 1 : info->ms.samples;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001113
1114 /* 3DSTATE_SAMPLE_MASK */
1115 cmd = GEN6_RENDER_CMD(3D, 3DSTATE_SAMPLE_MASK);
1116 cmd_len = 2;
1117
Chia-I Wu8ada4242015-03-02 11:19:33 -07001118 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Tony Barbourfa6cac72015-01-16 14:27:35 -07001119 dw[0] = cmd | (cmd_len - 2);
1120 dw[1] = info->ms.sampleMask & ((1 << pipeline->sample_count) - 1);
1121 pipeline->cmd_sample_mask = dw[1];
1122}
1123
1124static void pipeline_build_cb(struct intel_pipeline *pipeline,
1125 const struct intel_pipeline_create_info *info)
1126{
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001127 uint32_t i;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001128
1129 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
1130 STATIC_ASSERT(ARRAY_SIZE(pipeline->cmd_cb) >= INTEL_MAX_RENDER_TARGETS*2);
1131 assert(info->cb.attachmentCount <= INTEL_MAX_RENDER_TARGETS);
1132
1133 uint32_t *dw = pipeline->cmd_cb;
1134
1135 for (i = 0; i < info->cb.attachmentCount; i++) {
1136 const XGL_PIPELINE_CB_ATTACHMENT_STATE *att = &info->cb.pAttachments[i];
1137 uint32_t dw0, dw1;
1138
1139
1140 dw0 = 0;
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001141 dw1 = GEN6_RT_DW1_COLORCLAMP_RTFORMAT |
1142 GEN6_RT_DW1_PRE_BLEND_CLAMP |
1143 GEN6_RT_DW1_POST_BLEND_CLAMP;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001144
1145 if (att->blendEnable) {
1146 dw0 = 1 << 31 |
1147 translate_blend_func(att->blendFuncAlpha) << 26 |
1148 translate_blend(att->srcBlendAlpha) << 20 |
1149 translate_blend(att->destBlendAlpha) << 15 |
1150 translate_blend_func(att->blendFuncColor) << 11 |
1151 translate_blend(att->srcBlendColor) << 5 |
1152 translate_blend(att->destBlendColor);
1153
1154 if (att->blendFuncAlpha != att->blendFuncColor ||
1155 att->srcBlendAlpha != att->srcBlendColor ||
1156 att->destBlendAlpha != att->destBlendColor)
1157 dw0 |= 1 << 30;
Courtney Goeltzenleuchterdf13a4d2015-02-11 14:14:45 -07001158
1159 pipeline->dual_source_blend_enable = icd_pipeline_cb_att_needs_dual_source_blending(att);
Tony Barbourfa6cac72015-01-16 14:27:35 -07001160 }
1161
1162 if (info->cb.logicOp != XGL_LOGIC_OP_COPY) {
1163 int logicop;
1164
1165 switch (info->cb.logicOp) {
1166 case XGL_LOGIC_OP_CLEAR: logicop = GEN6_LOGICOP_CLEAR; break;
1167 case XGL_LOGIC_OP_AND: logicop = GEN6_LOGICOP_AND; break;
1168 case XGL_LOGIC_OP_AND_REVERSE: logicop = GEN6_LOGICOP_AND_REVERSE; break;
1169 case XGL_LOGIC_OP_AND_INVERTED: logicop = GEN6_LOGICOP_AND_INVERTED; break;
1170 case XGL_LOGIC_OP_NOOP: logicop = GEN6_LOGICOP_NOOP; break;
1171 case XGL_LOGIC_OP_XOR: logicop = GEN6_LOGICOP_XOR; break;
1172 case XGL_LOGIC_OP_OR: logicop = GEN6_LOGICOP_OR; break;
1173 case XGL_LOGIC_OP_NOR: logicop = GEN6_LOGICOP_NOR; break;
1174 case XGL_LOGIC_OP_EQUIV: logicop = GEN6_LOGICOP_EQUIV; break;
1175 case XGL_LOGIC_OP_INVERT: logicop = GEN6_LOGICOP_INVERT; break;
1176 case XGL_LOGIC_OP_OR_REVERSE: logicop = GEN6_LOGICOP_OR_REVERSE; break;
1177 case XGL_LOGIC_OP_COPY_INVERTED: logicop = GEN6_LOGICOP_COPY_INVERTED; break;
1178 case XGL_LOGIC_OP_OR_INVERTED: logicop = GEN6_LOGICOP_OR_INVERTED; break;
1179 case XGL_LOGIC_OP_NAND: logicop = GEN6_LOGICOP_NAND; break;
1180 case XGL_LOGIC_OP_SET: logicop = GEN6_LOGICOP_SET; break;
1181 default:
1182 assert(!"unknown logic op");
1183 logicop = GEN6_LOGICOP_CLEAR;
1184 break;
1185 }
1186
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001187 dw1 |= GEN6_RT_DW1_LOGICOP_ENABLE |
1188 logicop << GEN6_RT_DW1_LOGICOP_FUNC__SHIFT;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001189 }
1190
1191 if (!(att->channelWriteMask & 0x1))
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001192 dw1 |= GEN6_RT_DW1_WRITE_DISABLE_R;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001193 if (!(att->channelWriteMask & 0x2))
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001194 dw1 |= GEN6_RT_DW1_WRITE_DISABLE_G;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001195 if (!(att->channelWriteMask & 0x4))
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001196 dw1 |= GEN6_RT_DW1_WRITE_DISABLE_B;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001197 if (!(att->channelWriteMask & 0x8))
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001198 dw1 |= GEN6_RT_DW1_WRITE_DISABLE_A;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001199
1200 dw[2 * i] = dw0;
1201 dw[2 * i + 1] = dw1;
1202 }
1203
1204 for (i=info->cb.attachmentCount; i < INTEL_MAX_RENDER_TARGETS; i++)
1205 {
1206 dw[2 * i] = 0;
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001207 dw[2 * i + 1] = GEN6_RT_DW1_COLORCLAMP_RTFORMAT |
1208 GEN6_RT_DW1_PRE_BLEND_CLAMP |
1209 GEN6_RT_DW1_POST_BLEND_CLAMP |
1210 GEN6_RT_DW1_WRITE_DISABLE_R |
1211 GEN6_RT_DW1_WRITE_DISABLE_G |
1212 GEN6_RT_DW1_WRITE_DISABLE_B |
1213 GEN6_RT_DW1_WRITE_DISABLE_A;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001214 }
1215
1216}
1217
1218
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001219static XGL_RESULT pipeline_build_all(struct intel_pipeline *pipeline,
1220 const struct intel_pipeline_create_info *info)
Chia-I Wu3efef432014-08-28 15:00:16 +08001221{
1222 XGL_RESULT ret;
1223
Chia-I Wu98824592014-09-02 09:42:46 +08001224 ret = pipeline_build_shaders(pipeline, info);
1225 if (ret != XGL_SUCCESS)
1226 return ret;
1227
Chia-I Wu1d125092014-10-08 08:49:38 +08001228 if (info->vi.bindingCount > ARRAY_SIZE(pipeline->vb) ||
1229 info->vi.attributeCount > ARRAY_SIZE(pipeline->vb))
1230 return XGL_ERROR_BAD_PIPELINE_DATA;
1231
1232 pipeline->vb_count = info->vi.bindingCount;
1233 memcpy(pipeline->vb, info->vi.pVertexBindingDescriptions,
1234 sizeof(pipeline->vb[0]) * pipeline->vb_count);
1235
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001236 pipeline_build_vertex_elements(pipeline, info);
GregF8cd81832014-11-18 18:01:01 -07001237 pipeline_build_fragment_SBE(pipeline);
Tony Barbourfa6cac72015-01-16 14:27:35 -07001238 pipeline_build_msaa(pipeline, info);
Chia-I Wu5bdb0962015-01-24 12:49:28 +08001239 pipeline_build_depth_stencil(pipeline, info);
Chia-I Wu4d9ad912014-08-29 14:20:36 +08001240
Chia-I Wu509b3f22014-09-02 10:24:05 +08001241 if (intel_gpu_gen(pipeline->dev->gpu) >= INTEL_GEN(7)) {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001242 pipeline_build_urb_alloc_gen7(pipeline, info);
1243 pipeline_build_push_const_alloc_gen7(pipeline, info);
1244 pipeline_build_gs(pipeline, info);
1245 pipeline_build_hs(pipeline, info);
1246 pipeline_build_te(pipeline, info);
1247 pipeline_build_ds(pipeline, info);
Chia-I Wu8370b402014-08-29 12:28:37 +08001248
1249 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
1250 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL |
1251 INTEL_CMD_WA_GEN7_PRE_VS_DEPTH_STALL_WRITE |
1252 INTEL_CMD_WA_GEN7_POST_COMMAND_CS_STALL |
1253 INTEL_CMD_WA_GEN7_POST_COMMAND_DEPTH_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001254 } else {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001255 pipeline_build_urb_alloc_gen6(pipeline, info);
Chia-I Wu8370b402014-08-29 12:28:37 +08001256
1257 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
1258 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001259 }
1260
Chia-I Wube0a3d92014-09-02 13:20:59 +08001261 ret = pipeline_build_ia(pipeline, info);
Chia-I Wu3efef432014-08-28 15:00:16 +08001262
1263 if (ret == XGL_SUCCESS)
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001264 ret = pipeline_rs_state(pipeline, &info->rs);
Chia-I Wu3efef432014-08-28 15:00:16 +08001265
Chia-I Wu3efef432014-08-28 15:00:16 +08001266 if (ret == XGL_SUCCESS) {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001267 pipeline->db_format = info->db.format;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001268 pipeline_build_cb(pipeline, info);
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001269 pipeline->cb_state = info->cb;
1270 pipeline->tess_state = info->tess;
Chia-I Wu3efef432014-08-28 15:00:16 +08001271 }
1272
1273 return ret;
1274}
1275
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001276struct intel_pipeline_create_info_header {
1277 XGL_STRUCTURE_TYPE struct_type;
1278 const struct intel_pipeline_create_info_header *next;
1279};
1280
1281static XGL_RESULT pipeline_create_info_init(struct intel_pipeline_create_info *info,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001282 const struct intel_pipeline_create_info_header *header)
Chia-I Wu3efef432014-08-28 15:00:16 +08001283{
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001284 memset(info, 0, sizeof(*info));
Chia-I Wu3efef432014-08-28 15:00:16 +08001285
Tony Barbourfa6cac72015-01-16 14:27:35 -07001286
1287 /*
1288 * Do we need to set safe defaults in case the app doesn't provide all of
1289 * the necessary create infos?
1290 */
1291 info->ms.samples = 1;
1292 info->ms.sampleMask = 1;
1293
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001294 while (header) {
1295 const void *src = (const void *) header;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001296 size_t size;
Chia-I Wu3efef432014-08-28 15:00:16 +08001297 void *dst;
1298
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001299 switch (header->struct_type) {
Chia-I Wu3efef432014-08-28 15:00:16 +08001300 case XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001301 size = sizeof(info->graphics);
1302 dst = &info->graphics;
Chia-I Wu3efef432014-08-28 15:00:16 +08001303 break;
Chia-I Wu1d125092014-10-08 08:49:38 +08001304 case XGL_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO:
1305 size = sizeof(info->vi);
1306 dst = &info->vi;
1307 break;
Chia-I Wu3efef432014-08-28 15:00:16 +08001308 case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001309 size = sizeof(info->ia);
1310 dst = &info->ia;
Chia-I Wu3efef432014-08-28 15:00:16 +08001311 break;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001312 case XGL_STRUCTURE_TYPE_PIPELINE_DS_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001313 size = sizeof(info->db);
1314 dst = &info->db;
Chia-I Wu3efef432014-08-28 15:00:16 +08001315 break;
1316 case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001317 size = sizeof(info->cb);
1318 dst = &info->cb;
Chia-I Wu3efef432014-08-28 15:00:16 +08001319 break;
1320 case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001321 size = sizeof(info->rs);
1322 dst = &info->rs;
Chia-I Wu3efef432014-08-28 15:00:16 +08001323 break;
1324 case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001325 size = sizeof(info->tess);
1326 dst = &info->tess;
Chia-I Wu3efef432014-08-28 15:00:16 +08001327 break;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001328 case XGL_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO:
1329 size = sizeof(info->ms);
1330 dst = &info->ms;
1331 break;
1332 case XGL_STRUCTURE_TYPE_PIPELINE_VP_STATE_CREATE_INFO:
1333 size = sizeof(info->vp);
1334 dst = &info->vp;
1335 break;
Chia-I Wu3efef432014-08-28 15:00:16 +08001336 case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
1337 {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001338 const XGL_PIPELINE_SHADER *shader =
1339 (const XGL_PIPELINE_SHADER *) (header + 1);
Chia-I Wu3efef432014-08-28 15:00:16 +08001340
1341 src = (const void *) shader;
1342 size = sizeof(*shader);
1343
1344 switch (shader->stage) {
1345 case XGL_SHADER_STAGE_VERTEX:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001346 dst = &info->vs;
Chia-I Wu3efef432014-08-28 15:00:16 +08001347 break;
1348 case XGL_SHADER_STAGE_TESS_CONTROL:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001349 dst = &info->tcs;
Chia-I Wu3efef432014-08-28 15:00:16 +08001350 break;
1351 case XGL_SHADER_STAGE_TESS_EVALUATION:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001352 dst = &info->tes;
Chia-I Wu3efef432014-08-28 15:00:16 +08001353 break;
1354 case XGL_SHADER_STAGE_GEOMETRY:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001355 dst = &info->gs;
Chia-I Wu3efef432014-08-28 15:00:16 +08001356 break;
1357 case XGL_SHADER_STAGE_FRAGMENT:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001358 dst = &info->fs;
Chia-I Wu3efef432014-08-28 15:00:16 +08001359 break;
Chia-I Wu3efef432014-08-28 15:00:16 +08001360 default:
1361 return XGL_ERROR_BAD_PIPELINE_DATA;
1362 break;
1363 }
1364 }
1365 break;
1366 case XGL_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001367 size = sizeof(info->compute);
1368 dst = &info->compute;
Chia-I Wu3efef432014-08-28 15:00:16 +08001369 break;
1370 default:
1371 return XGL_ERROR_BAD_PIPELINE_DATA;
1372 break;
1373 }
1374
1375 memcpy(dst, src, size);
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001376 header = header->next;
Chia-I Wu3efef432014-08-28 15:00:16 +08001377 }
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001378
1379 return XGL_SUCCESS;
Chia-I Wu3efef432014-08-28 15:00:16 +08001380}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001381
Chia-I Wu3efef432014-08-28 15:00:16 +08001382static XGL_RESULT graphics_pipeline_create(struct intel_dev *dev,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001383 const XGL_GRAPHICS_PIPELINE_CREATE_INFO *info_,
Chia-I Wu3efef432014-08-28 15:00:16 +08001384 struct intel_pipeline **pipeline_ret)
1385{
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001386 struct intel_pipeline_create_info info;
Chia-I Wu3efef432014-08-28 15:00:16 +08001387 struct intel_pipeline *pipeline;
1388 XGL_RESULT ret;
1389
Chia-I Wu509b3f22014-09-02 10:24:05 +08001390 ret = pipeline_create_info_init(&info,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001391 (const struct intel_pipeline_create_info_header *) info_);
Chia-I Wu3efef432014-08-28 15:00:16 +08001392 if (ret != XGL_SUCCESS)
1393 return ret;
1394
Chia-I Wu545c2e12015-02-22 13:19:54 +08001395 pipeline = (struct intel_pipeline *) intel_base_create(&dev->base.handle,
1396 sizeof(*pipeline), dev->base.dbg,
1397 XGL_DBG_OBJECT_GRAPHICS_PIPELINE, info_, 0);
Chia-I Wu3efef432014-08-28 15:00:16 +08001398 if (!pipeline)
1399 return XGL_ERROR_OUT_OF_MEMORY;
1400
1401 pipeline->dev = dev;
Chia-I Wub1024732014-12-19 13:00:29 +08001402 pipeline->obj.base.get_info = pipeline_get_info;
Chia-I Wu3efef432014-08-28 15:00:16 +08001403 pipeline->obj.destroy = pipeline_destroy;
Chia-I Wu3efef432014-08-28 15:00:16 +08001404
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001405 ret = pipeline_build_all(pipeline, &info);
Chia-I Wu3efef432014-08-28 15:00:16 +08001406 if (ret == XGL_SUCCESS)
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001407 ret = pipeline_validate(pipeline);
Chia-I Wu3efef432014-08-28 15:00:16 +08001408 if (ret != XGL_SUCCESS) {
1409 pipeline_destroy(&pipeline->obj);
1410 return ret;
1411 }
1412
1413 *pipeline_ret = pipeline;
1414
1415 return XGL_SUCCESS;
1416}
1417
Chia-I Wu96177272015-01-03 15:27:41 +08001418ICD_EXPORT XGL_RESULT XGLAPI xglCreateGraphicsPipeline(
Chia-I Wu3efef432014-08-28 15:00:16 +08001419 XGL_DEVICE device,
1420 const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
1421 XGL_PIPELINE* pPipeline)
1422{
1423 struct intel_dev *dev = intel_dev(device);
1424
1425 return graphics_pipeline_create(dev, pCreateInfo,
1426 (struct intel_pipeline **) pPipeline);
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001427}
1428
Chia-I Wu96177272015-01-03 15:27:41 +08001429ICD_EXPORT XGL_RESULT XGLAPI xglCreateComputePipeline(
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001430 XGL_DEVICE device,
1431 const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo,
1432 XGL_PIPELINE* pPipeline)
1433{
1434 return XGL_ERROR_UNAVAILABLE;
1435}
1436
Chia-I Wu96177272015-01-03 15:27:41 +08001437ICD_EXPORT XGL_RESULT XGLAPI xglStorePipeline(
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001438 XGL_PIPELINE pipeline,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001439 size_t* pDataSize,
1440 void* pData)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001441{
1442 return XGL_ERROR_UNAVAILABLE;
1443}
1444
Chia-I Wu96177272015-01-03 15:27:41 +08001445ICD_EXPORT XGL_RESULT XGLAPI xglLoadPipeline(
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001446 XGL_DEVICE device,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001447 size_t dataSize,
1448 const void* pData,
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001449 XGL_PIPELINE* pPipeline)
1450{
1451 return XGL_ERROR_UNAVAILABLE;
1452}
1453
Chia-I Wu96177272015-01-03 15:27:41 +08001454ICD_EXPORT XGL_RESULT XGLAPI xglCreatePipelineDelta(
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001455 XGL_DEVICE device,
1456 XGL_PIPELINE p1,
1457 XGL_PIPELINE p2,
1458 XGL_PIPELINE_DELTA* delta)
1459{
1460 return XGL_ERROR_UNAVAILABLE;
1461}