blob: 7646f0bdcf3a0dd47308905b189dfb090ff7b30a [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};
130struct intel_pipeline_shader *intel_pipeline_shader_create_meta(struct intel_dev *dev,
131 enum intel_dev_meta_shader id)
132{
133 struct intel_pipeline_shader *sh;
134 XGL_RESULT ret;
135
Chia-I Wuf9c81ef2015-02-22 13:49:15 +0800136 sh = intel_alloc(dev, sizeof(*sh), 0, XGL_SYSTEM_ALLOC_INTERNAL);
Chia-I Wu3f239832014-12-11 22:57:18 +0800137 if (!sh)
138 return NULL;
139 memset(sh, 0, sizeof(*sh));
140
141 ret = intel_pipeline_shader_compile_meta(sh, dev->gpu, id);
142 if (ret != XGL_SUCCESS) {
Chia-I Wuf9c81ef2015-02-22 13:49:15 +0800143 intel_free(dev, sh);
Chia-I Wu3f239832014-12-11 22:57:18 +0800144 return NULL;
145 }
146
147 switch (id) {
148 case INTEL_DEV_META_VS_FILL_MEM:
149 case INTEL_DEV_META_VS_COPY_MEM:
150 case INTEL_DEV_META_VS_COPY_MEM_UNALIGNED:
151 sh->max_threads = intel_gpu_get_max_threads(dev->gpu,
152 XGL_SHADER_STAGE_VERTEX);
153 break;
154 default:
155 sh->max_threads = intel_gpu_get_max_threads(dev->gpu,
156 XGL_SHADER_STAGE_FRAGMENT);
157 break;
158 }
159
160 return sh;
161}
162
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800163void intel_pipeline_shader_destroy(struct intel_dev *dev,
164 struct intel_pipeline_shader *sh)
Chia-I Wu3f239832014-12-11 22:57:18 +0800165{
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800166 intel_pipeline_shader_cleanup(sh, dev->gpu);
167 intel_free(dev, sh);
Chia-I Wu3f239832014-12-11 22:57:18 +0800168}
169
170static XGL_RESULT pipeline_build_shader(struct intel_pipeline *pipeline,
Chia-I Wuf8385062015-01-04 16:27:24 +0800171 const struct intel_desc_layout *layout,
172 const XGL_PIPELINE_SHADER *sh_info,
173 struct intel_pipeline_shader *sh)
Chia-I Wu3f239832014-12-11 22:57:18 +0800174{
175 XGL_RESULT ret;
176
Chia-I Wuf8385062015-01-04 16:27:24 +0800177 ret = intel_pipeline_shader_compile(sh,
178 pipeline->dev->gpu, layout, sh_info);
Chia-I Wu3f239832014-12-11 22:57:18 +0800179 if (ret != XGL_SUCCESS)
180 return ret;
181
182 sh->max_threads =
183 intel_gpu_get_max_threads(pipeline->dev->gpu, sh_info->stage);
184
185 /* 1KB aligned */
186 sh->scratch_offset = u_align(pipeline->scratch_size, 1024);
187 pipeline->scratch_size = sh->scratch_offset +
188 sh->per_thread_scratch_size * sh->max_threads;
189
190 pipeline->active_shaders |= 1 << sh_info->stage;
191
192 return XGL_SUCCESS;
193}
194
195static XGL_RESULT pipeline_build_shaders(struct intel_pipeline *pipeline,
196 const struct intel_pipeline_create_info *info)
197{
Chia-I Wuf8385062015-01-04 16:27:24 +0800198 const struct intel_desc_layout *layout =
199 intel_desc_layout(info->graphics.lastSetLayout);
Chia-I Wu3f239832014-12-11 22:57:18 +0800200 XGL_RESULT ret = XGL_SUCCESS;
201
Chia-I Wuf8385062015-01-04 16:27:24 +0800202 if (ret == XGL_SUCCESS && info->vs.shader) {
203 ret = pipeline_build_shader(pipeline, layout,
204 &info->vs, &pipeline->vs);
205 }
206 if (ret == XGL_SUCCESS && info->tcs.shader) {
207 ret = pipeline_build_shader(pipeline, layout,
208 &info->tcs,&pipeline->tcs);
209 }
210 if (ret == XGL_SUCCESS && info->tes.shader) {
211 ret = pipeline_build_shader(pipeline, layout,
212 &info->tes,&pipeline->tes);
213 }
214 if (ret == XGL_SUCCESS && info->gs.shader) {
215 ret = pipeline_build_shader(pipeline, layout,
216 &info->gs, &pipeline->gs);
217 }
218 if (ret == XGL_SUCCESS && info->fs.shader) {
219 ret = pipeline_build_shader(pipeline, layout,
220 &info->fs, &pipeline->fs);
221 }
Chia-I Wu3f239832014-12-11 22:57:18 +0800222
Chia-I Wuf8385062015-01-04 16:27:24 +0800223 if (ret == XGL_SUCCESS && info->compute.cs.shader) {
224 layout = intel_desc_layout(info->compute.lastSetLayout);
225 ret = pipeline_build_shader(pipeline, layout,
226 &info->compute.cs, &pipeline->cs);
227 }
Chia-I Wu3f239832014-12-11 22:57:18 +0800228
229 return ret;
230}
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600231static uint32_t *pipeline_cmd_ptr(struct intel_pipeline *pipeline, int cmd_len)
232{
233 uint32_t *ptr;
234
235 assert(pipeline->cmd_len + cmd_len < INTEL_PSO_CMD_ENTRIES);
236 ptr = &pipeline->cmds[pipeline->cmd_len];
237 pipeline->cmd_len += cmd_len;
238 return ptr;
239}
240
Chia-I Wube0a3d92014-09-02 13:20:59 +0800241static XGL_RESULT pipeline_build_ia(struct intel_pipeline *pipeline,
242 const struct intel_pipeline_create_info* info)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600243{
Chia-I Wube0a3d92014-09-02 13:20:59 +0800244 pipeline->topology = info->ia.topology;
245 pipeline->disable_vs_cache = info->ia.disableVertexReuse;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600246
Chia-I Wube0a3d92014-09-02 13:20:59 +0800247 switch (info->ia.topology) {
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600248 case XGL_TOPOLOGY_POINT_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600249 pipeline->prim_type = GEN6_3DPRIM_POINTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600250 break;
251 case XGL_TOPOLOGY_LINE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600252 pipeline->prim_type = GEN6_3DPRIM_LINELIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600253 break;
254 case XGL_TOPOLOGY_LINE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600255 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600256 break;
257 case XGL_TOPOLOGY_TRIANGLE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600258 pipeline->prim_type = GEN6_3DPRIM_TRILIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600259 break;
260 case XGL_TOPOLOGY_TRIANGLE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600261 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600262 break;
263 case XGL_TOPOLOGY_RECT_LIST:
264 /*
265 * TODO: Rect lists are special in XGL, do we need to do
266 * something special here?
267 * XGL Guide:
268 * The rectangle list is a special geometry primitive type
269 * that can be used for implementing post-processing techniques
270 * or efficient copy operations. There are some special limitations
271 * for rectangle primitives. They cannot be clipped, must
272 * be axis aligned and cannot have depth gradient.
273 * Failure to comply with these restrictions results in
274 * undefined rendering results.
275 */
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600276 pipeline->prim_type = GEN6_3DPRIM_RECTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600277 break;
278 case XGL_TOPOLOGY_QUAD_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600279 pipeline->prim_type = GEN6_3DPRIM_QUADLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600280 break;
281 case XGL_TOPOLOGY_QUAD_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600282 pipeline->prim_type = GEN6_3DPRIM_QUADSTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600283 break;
284 case XGL_TOPOLOGY_LINE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600285 pipeline->prim_type = GEN6_3DPRIM_LINELIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600286 break;
287 case XGL_TOPOLOGY_LINE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600288 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600289 break;
290 case XGL_TOPOLOGY_TRIANGLE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600291 pipeline->prim_type = GEN6_3DPRIM_TRILIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600292 break;
293 case XGL_TOPOLOGY_TRIANGLE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600294 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600295 break;
296 case XGL_TOPOLOGY_PATCH:
Chia-I Wube0a3d92014-09-02 13:20:59 +0800297 if (!info->tess.patchControlPoints ||
298 info->tess.patchControlPoints > 32)
299 return XGL_ERROR_BAD_PIPELINE_DATA;
300 pipeline->prim_type = GEN7_3DPRIM_PATCHLIST_1 +
301 info->tess.patchControlPoints - 1;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600302 break;
303 default:
304 return XGL_ERROR_BAD_PIPELINE_DATA;
305 }
306
Chia-I Wube0a3d92014-09-02 13:20:59 +0800307 if (info->ia.primitiveRestartEnable) {
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600308 pipeline->primitive_restart = true;
Chia-I Wube0a3d92014-09-02 13:20:59 +0800309 pipeline->primitive_restart_index = info->ia.primitiveRestartIndex;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600310 } else {
311 pipeline->primitive_restart = false;
312 }
313
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600314 return XGL_SUCCESS;
315}
316
Chia-I Wu3efef432014-08-28 15:00:16 +0800317static XGL_RESULT pipeline_rs_state(struct intel_pipeline *pipeline,
318 const XGL_PIPELINE_RS_STATE_CREATE_INFO* rs_state)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600319{
320 pipeline->depthClipEnable = rs_state->depthClipEnable;
321 pipeline->rasterizerDiscardEnable = rs_state->rasterizerDiscardEnable;
Tony Barbourfa6cac72015-01-16 14:27:35 -0700322
323 if (rs_state->provokingVertex == XGL_PROVOKING_VERTEX_FIRST) {
324 pipeline->provoking_vertex_tri = 0;
325 pipeline->provoking_vertex_trifan = 1;
326 pipeline->provoking_vertex_line = 0;
327 } else {
328 pipeline->provoking_vertex_tri = 2;
329 pipeline->provoking_vertex_trifan = 2;
330 pipeline->provoking_vertex_line = 1;
331 }
332
333 switch (rs_state->fillMode) {
334 case XGL_FILL_POINTS:
335 pipeline->cmd_sf_fill |= GEN7_SF_DW1_FRONTFACE_POINT |
336 GEN7_SF_DW1_BACKFACE_POINT;
337 break;
338 case XGL_FILL_WIREFRAME:
339 pipeline->cmd_sf_fill |= GEN7_SF_DW1_FRONTFACE_WIREFRAME |
340 GEN7_SF_DW1_BACKFACE_WIREFRAME;
341 break;
342 case XGL_FILL_SOLID:
343 default:
344 pipeline->cmd_sf_fill |= GEN7_SF_DW1_FRONTFACE_SOLID |
345 GEN7_SF_DW1_BACKFACE_SOLID;
346 break;
347 }
348
349 if (rs_state->frontFace == XGL_FRONT_FACE_CCW) {
350 pipeline->cmd_sf_fill |= GEN7_SF_DW1_FRONTWINDING_CCW;
351 pipeline->cmd_clip_cull |= GEN7_CLIP_DW1_FRONTWINDING_CCW;
352 }
353
354 switch (rs_state->cullMode) {
355 case XGL_CULL_NONE:
356 default:
357 pipeline->cmd_sf_cull |= GEN7_SF_DW2_CULLMODE_NONE;
358 pipeline->cmd_clip_cull |= GEN7_CLIP_DW1_CULLMODE_NONE;
359 break;
360 case XGL_CULL_FRONT:
361 pipeline->cmd_sf_cull |= GEN7_SF_DW2_CULLMODE_FRONT;
362 pipeline->cmd_clip_cull |= GEN7_CLIP_DW1_CULLMODE_FRONT;
363 break;
364 case XGL_CULL_BACK:
365 pipeline->cmd_sf_cull |= GEN7_SF_DW2_CULLMODE_BACK;
366 pipeline->cmd_clip_cull |= GEN7_CLIP_DW1_CULLMODE_BACK;
367 break;
368 case XGL_CULL_FRONT_AND_BACK:
369 pipeline->cmd_sf_cull |= GEN7_SF_DW2_CULLMODE_BOTH;
370 pipeline->cmd_clip_cull |= GEN7_CLIP_DW1_CULLMODE_BOTH;
371 break;
372 }
373
374 /* only GEN7+ needs cull mode in 3DSTATE_CLIP */
375 if (intel_gpu_gen(pipeline->dev->gpu) == INTEL_GEN(6))
376 pipeline->cmd_clip_cull = 0;
377
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600378 return XGL_SUCCESS;
379}
380
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600381static void pipeline_destroy(struct intel_obj *obj)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600382{
383 struct intel_pipeline *pipeline = intel_pipeline_from_obj(obj);
384
Chia-I Wu3f239832014-12-11 22:57:18 +0800385 if (pipeline->active_shaders & SHADER_VERTEX_FLAG) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800386 intel_pipeline_shader_cleanup(&pipeline->vs, pipeline->dev->gpu);
Chia-I Wu3f239832014-12-11 22:57:18 +0800387 }
388
389 if (pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800390 intel_pipeline_shader_cleanup(&pipeline->tcs, pipeline->dev->gpu);
Chia-I Wu3f239832014-12-11 22:57:18 +0800391 }
392
393 if (pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800394 intel_pipeline_shader_cleanup(&pipeline->tes, pipeline->dev->gpu);
Chia-I Wu3f239832014-12-11 22:57:18 +0800395 }
396
397 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800398 intel_pipeline_shader_cleanup(&pipeline->gs, pipeline->dev->gpu);
Chia-I Wu3f239832014-12-11 22:57:18 +0800399 }
400
401 if (pipeline->active_shaders & SHADER_FRAGMENT_FLAG) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800402 intel_pipeline_shader_cleanup(&pipeline->fs, pipeline->dev->gpu);
Chia-I Wu3f239832014-12-11 22:57:18 +0800403 }
404
405 if (pipeline->active_shaders & SHADER_COMPUTE_FLAG) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800406 intel_pipeline_shader_cleanup(&pipeline->cs, pipeline->dev->gpu);
Chia-I Wu3f239832014-12-11 22:57:18 +0800407 }
Chia-I Wued833872014-08-23 17:00:35 +0800408
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600409 intel_base_destroy(&pipeline->obj.base);
410}
411
Chia-I Wub1024732014-12-19 13:00:29 +0800412static XGL_RESULT pipeline_get_info(struct intel_base *base, int type,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600413 size_t *size, void *data)
Chia-I Wub1024732014-12-19 13:00:29 +0800414{
415 struct intel_pipeline *pipeline = intel_pipeline_from_base(base);
416 XGL_RESULT ret = XGL_SUCCESS;
417
418 switch (type) {
419 case XGL_INFO_TYPE_MEMORY_REQUIREMENTS:
420 {
421 XGL_MEMORY_REQUIREMENTS *mem_req = data;
422
423 *size = sizeof(XGL_MEMORY_REQUIREMENTS);
424 if (data) {
425 mem_req->size = pipeline->scratch_size;
426 mem_req->alignment = 1024;
Jon Ashburnd8031332015-01-22 10:52:13 -0700427 mem_req->memType = XGL_MEMORY_TYPE_OTHER;
Chia-I Wub1024732014-12-19 13:00:29 +0800428 }
429 }
430 break;
431 default:
432 ret = intel_base_get_info(base, type, size, data);
433 break;
434 }
435
436 return ret;
437}
438
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800439static XGL_RESULT pipeline_validate(struct intel_pipeline *pipeline)
Chia-I Wu3efef432014-08-28 15:00:16 +0800440{
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600441 /*
442 * Validate required elements
443 */
444 if (!(pipeline->active_shaders & SHADER_VERTEX_FLAG)) {
445 // TODO: Log debug message: Vertex Shader required.
Chia-I Wu3efef432014-08-28 15:00:16 +0800446 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600447 }
448
449 /*
450 * Tessalation control and evaluation have to both have a shader defined or
451 * neither should have a shader defined.
452 */
453 if (((pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) == 0) !=
454 ((pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) == 0) ) {
455 // TODO: Log debug message: Both Tess control and Tess eval are required to use tessalation
Chia-I Wu3efef432014-08-28 15:00:16 +0800456 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600457 }
458
459 if ((pipeline->active_shaders & SHADER_COMPUTE_FLAG) &&
460 (pipeline->active_shaders & (SHADER_VERTEX_FLAG | SHADER_TESS_CONTROL_FLAG |
461 SHADER_TESS_EVAL_FLAG | SHADER_GEOMETRY_FLAG |
462 SHADER_FRAGMENT_FLAG))) {
463 // TODO: Log debug message: Can only specify compute shader when doing compute
Chia-I Wu3efef432014-08-28 15:00:16 +0800464 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600465 }
466
467 /*
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600468 * XGL_TOPOLOGY_PATCH primitive topology is only valid for tessellation pipelines.
469 * Mismatching primitive topology and tessellation fails graphics pipeline creation.
470 */
471 if (pipeline->active_shaders & (SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG) &&
Chia-I Wube0a3d92014-09-02 13:20:59 +0800472 (pipeline->topology != XGL_TOPOLOGY_PATCH)) {
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600473 // TODO: Log debug message: Invalid topology used with tessalation shader.
Chia-I Wu3efef432014-08-28 15:00:16 +0800474 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600475 }
476
Chia-I Wube0a3d92014-09-02 13:20:59 +0800477 if ((pipeline->topology == XGL_TOPOLOGY_PATCH) &&
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600478 (pipeline->active_shaders & ~(SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG))) {
479 // TODO: Log debug message: Cannot use TOPOLOGY_PATCH on non-tessalation shader.
Chia-I Wu3efef432014-08-28 15:00:16 +0800480 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600481 }
482
Chia-I Wu3efef432014-08-28 15:00:16 +0800483 return XGL_SUCCESS;
484}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600485
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800486static void pipeline_build_urb_alloc_gen6(struct intel_pipeline *pipeline,
487 const struct intel_pipeline_create_info *info)
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800488{
Chia-I Wu509b3f22014-09-02 10:24:05 +0800489 const struct intel_gpu *gpu = pipeline->dev->gpu;
490 const int urb_size = ((gpu->gt == 2) ? 64 : 32) * 1024;
Chia-I Wua4d1b392014-10-10 13:57:29 +0800491 const struct intel_pipeline_shader *vs = &pipeline->vs;
492 const struct intel_pipeline_shader *gs = &pipeline->gs;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800493 int vs_entry_size, gs_entry_size;
494 int vs_size, gs_size;
495
Chia-I Wu509b3f22014-09-02 10:24:05 +0800496 INTEL_GPU_ASSERT(gpu, 6, 6);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800497
498 vs_entry_size = ((vs->in_count >= vs->out_count) ?
499 vs->in_count : vs->out_count);
500 gs_entry_size = (gs) ? gs->out_count : 0;
501
502 /* in bytes */
503 vs_entry_size *= sizeof(float) * 4;
504 gs_entry_size *= sizeof(float) * 4;
505
Chia-I Wua4d1b392014-10-10 13:57:29 +0800506 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800507 vs_size = urb_size / 2;
508 gs_size = vs_size;
509 } else {
510 vs_size = urb_size;
511 gs_size = 0;
512 }
513
514 /* 3DSTATE_URB */
515 {
516 const uint8_t cmd_len = 3;
517 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_URB) |
518 (cmd_len - 2);
519 int vs_alloc_size, gs_alloc_size;
520 int vs_entry_count, gs_entry_count;
521 uint32_t *dw;
522
523 /* in 1024-bit rows */
524 vs_alloc_size = (vs_entry_size + 128 - 1) / 128;
525 gs_alloc_size = (gs_entry_size + 128 - 1) / 128;
526
527 /* valid range is [1, 5] */
528 if (!vs_alloc_size)
529 vs_alloc_size = 1;
530 if (!gs_alloc_size)
531 gs_alloc_size = 1;
532 assert(vs_alloc_size <= 5 && gs_alloc_size <= 5);
533
534 /* valid range is [24, 256], multiples of 4 */
535 vs_entry_count = (vs_size / 128 / vs_alloc_size) & ~3;
536 if (vs_entry_count > 256)
537 vs_entry_count = 256;
538 assert(vs_entry_count >= 24);
539
540 /* valid range is [0, 256], multiples of 4 */
541 gs_entry_count = (gs_size / 128 / gs_alloc_size) & ~3;
542 if (gs_entry_count > 256)
543 gs_entry_count = 256;
544
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600545 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800546
547 dw[0] = dw0;
548 dw[1] = (vs_alloc_size - 1) << GEN6_URB_DW1_VS_ENTRY_SIZE__SHIFT |
549 vs_entry_count << GEN6_URB_DW1_VS_ENTRY_COUNT__SHIFT;
550 dw[2] = gs_entry_count << GEN6_URB_DW2_GS_ENTRY_COUNT__SHIFT |
551 (gs_alloc_size - 1) << GEN6_URB_DW2_GS_ENTRY_SIZE__SHIFT;
552 }
553}
554
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800555static void pipeline_build_urb_alloc_gen7(struct intel_pipeline *pipeline,
556 const struct intel_pipeline_create_info *info)
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800557{
Chia-I Wu509b3f22014-09-02 10:24:05 +0800558 const struct intel_gpu *gpu = pipeline->dev->gpu;
559 const int urb_size = ((gpu->gt == 3) ? 512 :
560 (gpu->gt == 2) ? 256 : 128) * 1024;
Cody Northrop306ec352014-10-06 15:11:45 -0600561 const struct intel_pipeline_shader *vs = &pipeline->vs;
562 const struct intel_pipeline_shader *gs = &pipeline->gs;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800563 /* some space is reserved for PCBs */
Chia-I Wu509b3f22014-09-02 10:24:05 +0800564 int urb_offset = ((gpu->gt == 3) ? 32 : 16) * 1024;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800565 int vs_entry_size, gs_entry_size;
566 int vs_size, gs_size;
567
Chia-I Wu509b3f22014-09-02 10:24:05 +0800568 INTEL_GPU_ASSERT(gpu, 7, 7.5);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800569
570 vs_entry_size = ((vs->in_count >= vs->out_count) ?
571 vs->in_count : vs->out_count);
572 gs_entry_size = (gs) ? gs->out_count : 0;
573
574 /* in bytes */
575 vs_entry_size *= sizeof(float) * 4;
576 gs_entry_size *= sizeof(float) * 4;
577
Chia-I Wua4d1b392014-10-10 13:57:29 +0800578 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800579 vs_size = (urb_size - urb_offset) / 2;
580 gs_size = vs_size;
581 } else {
582 vs_size = urb_size - urb_offset;
583 gs_size = 0;
584 }
585
586 /* 3DSTATE_URB_* */
587 {
588 const uint8_t cmd_len = 2;
589 int vs_alloc_size, gs_alloc_size;
590 int vs_entry_count, gs_entry_count;
591 uint32_t *dw;
592
593 /* in 512-bit rows */
594 vs_alloc_size = (vs_entry_size + 64 - 1) / 64;
595 gs_alloc_size = (gs_entry_size + 64 - 1) / 64;
596
597 if (!vs_alloc_size)
598 vs_alloc_size = 1;
599 if (!gs_alloc_size)
600 gs_alloc_size = 1;
601
602 /* avoid performance decrease due to banking */
603 if (vs_alloc_size == 5)
604 vs_alloc_size = 6;
605
606 /* in multiples of 8 */
607 vs_entry_count = (vs_size / 64 / vs_alloc_size) & ~7;
608 assert(vs_entry_count >= 32);
609
610 gs_entry_count = (gs_size / 64 / gs_alloc_size) & ~7;
611
Chia-I Wu509b3f22014-09-02 10:24:05 +0800612 if (intel_gpu_gen(gpu) >= INTEL_GEN(7.5)) {
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800613 const int max_vs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800614 (gpu->gt >= 2) ? 1664 : 640;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800615 const int max_gs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800616 (gpu->gt >= 2) ? 640 : 256;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800617 if (vs_entry_count >= max_vs_entry_count)
618 vs_entry_count = max_vs_entry_count;
619 if (gs_entry_count >= max_gs_entry_count)
620 gs_entry_count = max_gs_entry_count;
621 } else {
622 const int max_vs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800623 (gpu->gt == 2) ? 704 : 512;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800624 const int max_gs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800625 (gpu->gt == 2) ? 320 : 192;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800626 if (vs_entry_count >= max_vs_entry_count)
627 vs_entry_count = max_vs_entry_count;
628 if (gs_entry_count >= max_gs_entry_count)
629 gs_entry_count = max_gs_entry_count;
630 }
631
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600632 dw = pipeline_cmd_ptr(pipeline, cmd_len*4);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800633 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_VS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700634 dw[1] = (urb_offset / 8192) << GEN7_URB_DW1_OFFSET__SHIFT |
635 (vs_alloc_size - 1) << GEN7_URB_DW1_ENTRY_SIZE__SHIFT |
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800636 vs_entry_count;
637
638 dw += 2;
639 if (gs_size)
640 urb_offset += vs_size;
641 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_GS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700642 dw[1] = (urb_offset / 8192) << GEN7_URB_DW1_OFFSET__SHIFT |
643 (gs_alloc_size - 1) << GEN7_URB_DW1_ENTRY_SIZE__SHIFT |
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800644 gs_entry_count;
645
646 dw += 2;
647 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_HS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700648 dw[1] = (urb_offset / 8192) << GEN7_URB_DW1_OFFSET__SHIFT;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800649
650 dw += 2;
651 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_DS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700652 dw[1] = (urb_offset / 8192) << GEN7_URB_DW1_OFFSET__SHIFT;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800653 }
654}
655
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800656static void pipeline_build_push_const_alloc_gen7(struct intel_pipeline *pipeline,
657 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600658{
Chia-I Wu29193752015-02-11 11:04:05 -0700659 const struct intel_gpu *gpu = pipeline->dev->gpu;
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600660 const uint8_t cmd_len = 2;
661 uint32_t offset = 0;
662 uint32_t size = 8192;
663 uint32_t *dw;
664 int end;
665
Chia-I Wu509b3f22014-09-02 10:24:05 +0800666 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600667
668 /*
669 * From the Ivy Bridge PRM, volume 2 part 1, page 68:
670 *
671 * "(A table that says the maximum size of each constant buffer is
672 * 16KB")
673 *
674 * From the Ivy Bridge PRM, volume 2 part 1, page 115:
675 *
676 * "The sum of the Constant Buffer Offset and the Constant Buffer Size
677 * may not exceed the maximum value of the Constant Buffer Size."
678 *
679 * Thus, the valid range of buffer end is [0KB, 16KB].
680 */
681 end = (offset + size) / 1024;
682 if (end > 16) {
683 assert(!"invalid constant buffer end");
684 end = 16;
685 }
686
687 /* the valid range of buffer offset is [0KB, 15KB] */
688 offset = (offset + 1023) / 1024;
689 if (offset > 15) {
690 assert(!"invalid constant buffer offset");
691 offset = 15;
692 }
693
694 if (offset > end) {
695 assert(!size);
696 offset = end;
697 }
698
699 /* the valid range of buffer size is [0KB, 15KB] */
700 size = end - offset;
701 if (size > 15) {
702 assert(!"invalid constant buffer size");
703 size = 15;
704 }
705
Chia-I Wu29193752015-02-11 11:04:05 -0700706 if (gpu->gt == 3)
707 size *= 2;
708
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800709 dw = pipeline_cmd_ptr(pipeline, cmd_len * 5);
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600710 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_VS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700711 dw[1] = offset << GEN7_PCB_ALLOC_DW1_OFFSET__SHIFT |
712 size << GEN7_PCB_ALLOC_DW1_SIZE__SHIFT;
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600713
714 dw += 2;
715 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_PS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700716 dw[1] = size << GEN7_PCB_ALLOC_DW1_OFFSET__SHIFT |
717 size << GEN7_PCB_ALLOC_DW1_SIZE__SHIFT;
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600718
719 dw += 2;
720 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_HS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700721 dw[1] = 0 << GEN7_PCB_ALLOC_DW1_OFFSET__SHIFT |
722 0 << GEN7_PCB_ALLOC_DW1_SIZE__SHIFT;
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600723
724 dw += 2;
725 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_DS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700726 dw[1] = 0 << GEN7_PCB_ALLOC_DW1_OFFSET__SHIFT |
727 0 << GEN7_PCB_ALLOC_DW1_SIZE__SHIFT;
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600728
729 dw += 2;
730 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_GS) | (cmd_len - 2);
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700731 dw[1] = 0 << GEN7_PCB_ALLOC_DW1_OFFSET__SHIFT |
732 0 << GEN7_PCB_ALLOC_DW1_SIZE__SHIFT;
Chia-I Wu8370b402014-08-29 12:28:37 +0800733
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600734 // gen7_wa_pipe_control_cs_stall(p, true, true);
735 // looks equivalent to: gen6_wa_wm_multisample_flush - this does more
736 // than the documentation seems to imply
737}
738
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800739static void pipeline_build_vertex_elements(struct intel_pipeline *pipeline,
740 const struct intel_pipeline_create_info *info)
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800741{
Cody Northrop306ec352014-10-06 15:11:45 -0600742 const struct intel_pipeline_shader *vs = &pipeline->vs;
Chia-I Wu1d125092014-10-08 08:49:38 +0800743 uint8_t cmd_len;
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800744 uint32_t *dw;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600745 uint32_t i;
Chia-I Wu1d125092014-10-08 08:49:38 +0800746 int comps[4];
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800747
Chia-I Wu509b3f22014-09-02 10:24:05 +0800748 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800749
GregF8cd81832014-11-18 18:01:01 -0700750 cmd_len = 1 + 2 * u_popcountll(vs->inputs_read);
Chia-I Wu1d125092014-10-08 08:49:38 +0800751 if (vs->uses & (INTEL_SHADER_USE_VID | INTEL_SHADER_USE_IID))
752 cmd_len += 2;
753
754 if (cmd_len == 1)
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800755 return;
756
757 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Chia-I Wu1d125092014-10-08 08:49:38 +0800758
759 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_ELEMENTS) |
760 (cmd_len - 2);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800761 dw++;
762
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800763 /* VERTEX_ELEMENT_STATE */
Chia-I Wu1d125092014-10-08 08:49:38 +0800764 for (i = 0; i < info->vi.attributeCount; i++) {
GregF8cd81832014-11-18 18:01:01 -0700765 if (!(vs->inputs_read & (1L << i)))
GregF2dc40212014-10-31 17:31:47 -0600766 continue;
Chia-I Wu1d125092014-10-08 08:49:38 +0800767 const XGL_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION *attr =
768 &info->vi.pVertexAttributeDescriptions[i];
769 const int format =
770 intel_format_translate_color(pipeline->dev->gpu, attr->format);
771
772 comps[0] = GEN6_VFCOMP_STORE_0;
773 comps[1] = GEN6_VFCOMP_STORE_0;
774 comps[2] = GEN6_VFCOMP_STORE_0;
775 comps[3] = icd_format_is_int(attr->format) ?
776 GEN6_VFCOMP_STORE_1_INT : GEN6_VFCOMP_STORE_1_FP;
777
778 switch (icd_format_get_channel_count(attr->format)) {
779 case 4: comps[3] = GEN6_VFCOMP_STORE_SRC; /* fall through */
780 case 3: comps[2] = GEN6_VFCOMP_STORE_SRC; /* fall through */
781 case 2: comps[1] = GEN6_VFCOMP_STORE_SRC; /* fall through */
782 case 1: comps[0] = GEN6_VFCOMP_STORE_SRC; break;
783 default:
784 break;
785 }
786
787 assert(attr->offsetInBytes <= 2047);
788
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700789 dw[0] = attr->binding << GEN6_VE_DW0_VB_INDEX__SHIFT |
790 GEN6_VE_DW0_VALID |
791 format << GEN6_VE_DW0_FORMAT__SHIFT |
Chia-I Wu1d125092014-10-08 08:49:38 +0800792 attr->offsetInBytes;
793
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700794 dw[1] = comps[0] << GEN6_VE_DW1_COMP0__SHIFT |
795 comps[1] << GEN6_VE_DW1_COMP1__SHIFT |
796 comps[2] << GEN6_VE_DW1_COMP2__SHIFT |
797 comps[3] << GEN6_VE_DW1_COMP3__SHIFT;
Chia-I Wu1d125092014-10-08 08:49:38 +0800798
799 dw += 2;
800 }
GregF932fcf52014-10-29 17:02:11 -0600801
802 if (vs->uses & (INTEL_SHADER_USE_VID | INTEL_SHADER_USE_IID)) {
803 comps[0] = (vs->uses & INTEL_SHADER_USE_VID) ?
804 GEN6_VFCOMP_STORE_VID : GEN6_VFCOMP_STORE_0;
805 comps[1] = (vs->uses & INTEL_SHADER_USE_IID) ?
806 GEN6_VFCOMP_STORE_IID : GEN6_VFCOMP_NOSTORE;
807 comps[2] = GEN6_VFCOMP_NOSTORE;
808 comps[3] = GEN6_VFCOMP_NOSTORE;
809
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700810 dw[0] = GEN6_VE_DW0_VALID;
811 dw[1] = comps[0] << GEN6_VE_DW1_COMP0__SHIFT |
812 comps[1] << GEN6_VE_DW1_COMP1__SHIFT |
813 comps[2] << GEN6_VE_DW1_COMP2__SHIFT |
814 comps[3] << GEN6_VE_DW1_COMP3__SHIFT;
GregF932fcf52014-10-29 17:02:11 -0600815
816 dw += 2;
817 }
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800818}
819
GregF8cd81832014-11-18 18:01:01 -0700820static void pipeline_build_fragment_SBE(struct intel_pipeline *pipeline)
821{
822 const struct intel_pipeline_shader *fs = &pipeline->fs;
823 const struct intel_pipeline_shader *vs = &pipeline->vs;
824 uint8_t cmd_len;
825 uint32_t *body;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600826 uint32_t attr_skip, attr_count;
827 uint32_t vue_offset, vue_len;
828 uint32_t i;
GregF8cd81832014-11-18 18:01:01 -0700829
830 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
831
832 cmd_len = 14;
833
Chia-I Wuf85def42015-01-29 00:34:24 +0800834 if (intel_gpu_gen(pipeline->dev->gpu) >= INTEL_GEN(7))
835 body = pipeline_cmd_ptr(pipeline, cmd_len);
836 else
837 body = pipeline->cmd_3dstate_sbe;
GregF8cd81832014-11-18 18:01:01 -0700838
839 /* VS outputs VUE header and position additionally */
840 assert(vs->out_count >= fs->in_count + 2);
841 assert(!fs->reads_user_clip || vs->enable_user_clip);
842 attr_skip = vs->outputs_offset;
843 if (vs->enable_user_clip != fs->reads_user_clip) {
844 attr_skip += 2;
845 }
846 assert(vs->out_count >= attr_skip);
847 attr_count = vs->out_count - attr_skip;
848
849 // LUNARG TODO: We currently are only handling 16 attrs;
850 // ultimately, we need to handle 32
851 assert(fs->in_count <= 16);
852 assert(attr_count <= 16);
853
854 vue_offset = attr_skip / 2;
855 vue_len = (attr_count + 1) / 2;
856 if (!vue_len)
857 vue_len = 1;
858
859 body[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SBE) |
860 (cmd_len - 2);
861
862 // LUNARG TODO: If the attrs needed by the FS are exactly
863 // what is written by the VS, we don't need to enable
864 // swizzling, improving performance. Even if we swizzle,
865 // we can improve performance by reducing vue_len to
866 // just include the values needed by the FS:
867 // vue_len = ceiling((max_vs_out + 1)/2)
868
869 body[1] = GEN7_SBE_DW1_ATTR_SWIZZLE_ENABLE |
870 fs->in_count << GEN7_SBE_DW1_ATTR_COUNT__SHIFT |
871 vue_len << GEN7_SBE_DW1_URB_READ_LEN__SHIFT |
872 vue_offset << GEN7_SBE_DW1_URB_READ_OFFSET__SHIFT;
873
874 uint16_t vs_slot[fs->in_count];
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600875 int32_t fs_in = 0;
876 int32_t vs_out = - (vue_offset * 2 - vs->outputs_offset);
GregF8cd81832014-11-18 18:01:01 -0700877 for (i=0; i < 64; i++) {
Cody Northropd75c13e2015-01-02 14:07:20 -0700878 bool vsWrites = vs->outputs_written & (1L << i);
879 bool fsReads = fs->inputs_read & (1L << i);
880
881 if (fsReads) {
GregF8cd81832014-11-18 18:01:01 -0700882 assert(vs_out >= 0);
883 assert(fs_in < fs->in_count);
884 vs_slot[fs_in] = vs_out;
Cody Northropd75c13e2015-01-02 14:07:20 -0700885
886 if (!vsWrites) {
887 // If the vertex shader did not write this input, we cannot
888 // program the SBE to read it. Our choices are to allow it to
889 // read junk from a GRF, or get zero. We're choosing zero.
890 if (i >= fs->generic_input_start) {
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700891 vs_slot[fs_in] = GEN8_SBE_SWIZ_CONST_0000 |
892 GEN8_SBE_SWIZ_OVERRIDE_X |
893 GEN8_SBE_SWIZ_OVERRIDE_Y |
894 GEN8_SBE_SWIZ_OVERRIDE_Z |
895 GEN8_SBE_SWIZ_OVERRIDE_W;
Cody Northropd75c13e2015-01-02 14:07:20 -0700896 }
897 }
898
GregF8cd81832014-11-18 18:01:01 -0700899 fs_in += 1;
900 }
Cody Northropd75c13e2015-01-02 14:07:20 -0700901 if (vsWrites) {
GregF8cd81832014-11-18 18:01:01 -0700902 vs_out += 1;
903 }
904 }
905
906 for (i = 0; i < 8; i++) {
907 uint16_t hi, lo;
908
909 /* no attr swizzles */
910 if (i * 2 + 1 < fs->in_count) {
911 lo = vs_slot[i * 2];
912 hi = vs_slot[i * 2 + 1];
913 } else if (i * 2 < fs->in_count) {
914 lo = vs_slot[i * 2];
915 hi = 0;
916 } else {
917 hi = 0;
918 lo = 0;
919 }
920
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700921 body[2 + i] = hi << GEN8_SBE_SWIZ_HIGH__SHIFT | lo;
GregF8cd81832014-11-18 18:01:01 -0700922 }
923
924 body[10] = 0; /* point sprite enables */
925 body[11] = 0; /* constant interpolation enables */
926 body[12] = 0; /* WrapShortest enables */
927 body[13] = 0;
928}
929
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800930static void pipeline_build_gs(struct intel_pipeline *pipeline,
931 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600932{
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600933 // gen7_emit_3DSTATE_GS done by cmd_pipeline
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600934}
935
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800936static void pipeline_build_hs(struct intel_pipeline *pipeline,
937 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600938{
939 const uint8_t cmd_len = 7;
940 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
941 uint32_t *dw;
942
Chia-I Wu509b3f22014-09-02 10:24:05 +0800943 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600944
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800945 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600946 dw[0] = dw0;
947 dw[1] = 0;
948 dw[2] = 0;
949 dw[3] = 0;
950 dw[4] = 0;
951 dw[5] = 0;
952 dw[6] = 0;
953}
954
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800955static void pipeline_build_te(struct intel_pipeline *pipeline,
956 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600957{
958 const uint8_t cmd_len = 4;
959 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_TE) | (cmd_len - 2);
960 uint32_t *dw;
961
Chia-I Wu509b3f22014-09-02 10:24:05 +0800962 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600963
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800964 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600965 dw[0] = dw0;
966 dw[1] = 0;
967 dw[2] = 0;
968 dw[3] = 0;
969}
970
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800971static void pipeline_build_ds(struct intel_pipeline *pipeline,
972 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600973{
974 const uint8_t cmd_len = 6;
975 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
976 uint32_t *dw;
977
Chia-I Wu509b3f22014-09-02 10:24:05 +0800978 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600979
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800980 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600981 dw[0] = dw0;
982 dw[1] = 0;
983 dw[2] = 0;
984 dw[3] = 0;
985 dw[4] = 0;
986 dw[5] = 0;
987}
988
Tony Barbourfa6cac72015-01-16 14:27:35 -0700989static void pipeline_build_depth_stencil(struct intel_pipeline *pipeline,
990 const struct intel_pipeline_create_info *info)
991{
992 pipeline->cmd_depth_stencil = 0;
993
994 if (info->db.stencilTestEnable) {
995 pipeline->cmd_depth_stencil = 1 << 31 |
996 translate_compare_func(info->db.front.stencilFunc) << 28 |
997 translate_stencil_op(info->db.front.stencilFailOp) << 25 |
998 translate_stencil_op(info->db.front.stencilDepthFailOp) << 22 |
999 translate_stencil_op(info->db.front.stencilPassOp) << 19 |
1000 1 << 15 |
1001 translate_compare_func(info->db.back.stencilFunc) << 12 |
1002 translate_stencil_op(info->db.back.stencilFailOp) << 9 |
1003 translate_stencil_op(info->db.back.stencilDepthFailOp) << 6 |
1004 translate_stencil_op(info->db.back.stencilPassOp) << 3;
1005 }
1006
1007 pipeline->stencilTestEnable = info->db.stencilTestEnable;
1008
1009 /*
1010 * From the Sandy Bridge PRM, volume 2 part 1, page 360:
1011 *
1012 * "Enabling the Depth Test function without defining a Depth Buffer is
1013 * UNDEFINED."
1014 *
1015 * From the Sandy Bridge PRM, volume 2 part 1, page 375:
1016 *
1017 * "A Depth Buffer must be defined before enabling writes to it, or
1018 * operation is UNDEFINED."
1019 *
1020 * TODO We do not check these yet.
1021 */
1022 if (info->db.depthTestEnable) {
1023 pipeline->cmd_depth_test = GEN6_ZS_DW2_DEPTH_TEST_ENABLE |
1024 translate_compare_func(info->db.depthFunc) << 27;
1025 } else {
1026 pipeline->cmd_depth_test = GEN6_COMPAREFUNCTION_ALWAYS << 27;
1027 }
1028
1029 if (info->db.depthWriteEnable)
1030 pipeline->cmd_depth_test |= GEN6_ZS_DW2_DEPTH_WRITE_ENABLE;
1031}
1032
1033static void pipeline_init_sample_pattern(struct intel_pipeline *pipeline,
1034 uint8_t *samples)
1035{
1036 struct sample {
1037 int x, y;
1038 };
1039 static const struct sample default_pattern_2x[2] = {
1040 { -4, -4 },
1041 { 4, 4 },
1042 };
1043 static const struct sample default_pattern_4x[4] = {
1044 { -2, -6 },
1045 { 6, -2 },
1046 { -6, 2 },
1047 { 2, 6 },
1048 };
1049 static const struct sample default_pattern_8x[8] = {
1050 { 1, -3 },
1051 { -1, 3 },
1052 { 5, 1 },
1053 { -3, -5 },
1054 { -5, 5 },
1055 { -7, -1 },
1056 { 3, 7 },
1057 { 7, -7 },
1058 };
1059
1060 const struct sample *pattern;
1061 int i;
1062
1063 switch (pipeline->sample_count) {
1064 case 2:
1065 pattern = default_pattern_2x;
1066 break;
1067 case 4:
1068 pattern = default_pattern_4x;
1069 break;
1070 case 8:
1071 pattern = default_pattern_8x;
1072 break;
1073 default:
1074 memset(samples, 0, pipeline->sample_count);
1075 return;
1076 break;
1077 }
1078
1079 for (i = 0; i < pipeline->sample_count; i++)
1080 samples[i] = (pattern[i].x + 8) << 4 | (pattern[i].y + 8);
1081}
1082
1083static void pipeline_build_msaa(struct intel_pipeline *pipeline,
1084 const struct intel_pipeline_create_info *info)
1085{
1086 uint32_t cmd, cmd_len;
1087 uint32_t *dw;
1088
1089 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
1090
1091
1092 pipeline->sample_count = (info->ms.samples <= 1)?1:info->ms.samples;
1093
1094 /* 3DSTATE_MULTISAMPLE */
1095 cmd = GEN6_RENDER_CMD(3D, 3DSTATE_MULTISAMPLE);
1096 cmd_len = (intel_gpu_gen(pipeline->dev->gpu) >= INTEL_GEN(7)) ? 4 : 3;
1097 dw = pipeline_cmd_ptr(pipeline, cmd_len + 2);
1098 dw[0] = cmd | (cmd_len - 2);
1099 if (pipeline->sample_count <= 1)
1100 dw[1] = GEN6_MULTISAMPLE_DW1_NUMSAMPLES_1;
1101 else if (pipeline->sample_count <= 4 || intel_gpu_gen(pipeline->dev->gpu) == INTEL_GEN(6))
1102 dw[1] = GEN6_MULTISAMPLE_DW1_NUMSAMPLES_4;
1103 else
1104 dw[1] = GEN7_MULTISAMPLE_DW1_NUMSAMPLES_8;
1105
1106 pipeline_init_sample_pattern(pipeline, (uint8_t *) &dw[2]);
1107
1108 dw += cmd_len;
1109
1110 /* 3DSTATE_SAMPLE_MASK */
1111 cmd = GEN6_RENDER_CMD(3D, 3DSTATE_SAMPLE_MASK);
1112 cmd_len = 2;
1113
1114 dw[0] = cmd | (cmd_len - 2);
1115 dw[1] = info->ms.sampleMask & ((1 << pipeline->sample_count) - 1);
1116 pipeline->cmd_sample_mask = dw[1];
1117}
1118
1119static void pipeline_build_cb(struct intel_pipeline *pipeline,
1120 const struct intel_pipeline_create_info *info)
1121{
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001122 uint32_t i;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001123
1124 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
1125 STATIC_ASSERT(ARRAY_SIZE(pipeline->cmd_cb) >= INTEL_MAX_RENDER_TARGETS*2);
1126 assert(info->cb.attachmentCount <= INTEL_MAX_RENDER_TARGETS);
1127
1128 uint32_t *dw = pipeline->cmd_cb;
1129
1130 for (i = 0; i < info->cb.attachmentCount; i++) {
1131 const XGL_PIPELINE_CB_ATTACHMENT_STATE *att = &info->cb.pAttachments[i];
1132 uint32_t dw0, dw1;
1133
1134
1135 dw0 = 0;
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001136 dw1 = GEN6_RT_DW1_COLORCLAMP_RTFORMAT |
1137 GEN6_RT_DW1_PRE_BLEND_CLAMP |
1138 GEN6_RT_DW1_POST_BLEND_CLAMP;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001139
1140 if (att->blendEnable) {
1141 dw0 = 1 << 31 |
1142 translate_blend_func(att->blendFuncAlpha) << 26 |
1143 translate_blend(att->srcBlendAlpha) << 20 |
1144 translate_blend(att->destBlendAlpha) << 15 |
1145 translate_blend_func(att->blendFuncColor) << 11 |
1146 translate_blend(att->srcBlendColor) << 5 |
1147 translate_blend(att->destBlendColor);
1148
1149 if (att->blendFuncAlpha != att->blendFuncColor ||
1150 att->srcBlendAlpha != att->srcBlendColor ||
1151 att->destBlendAlpha != att->destBlendColor)
1152 dw0 |= 1 << 30;
Courtney Goeltzenleuchterdf13a4d2015-02-11 14:14:45 -07001153
1154 pipeline->dual_source_blend_enable = icd_pipeline_cb_att_needs_dual_source_blending(att);
Tony Barbourfa6cac72015-01-16 14:27:35 -07001155 }
1156
1157 if (info->cb.logicOp != XGL_LOGIC_OP_COPY) {
1158 int logicop;
1159
1160 switch (info->cb.logicOp) {
1161 case XGL_LOGIC_OP_CLEAR: logicop = GEN6_LOGICOP_CLEAR; break;
1162 case XGL_LOGIC_OP_AND: logicop = GEN6_LOGICOP_AND; break;
1163 case XGL_LOGIC_OP_AND_REVERSE: logicop = GEN6_LOGICOP_AND_REVERSE; break;
1164 case XGL_LOGIC_OP_AND_INVERTED: logicop = GEN6_LOGICOP_AND_INVERTED; break;
1165 case XGL_LOGIC_OP_NOOP: logicop = GEN6_LOGICOP_NOOP; break;
1166 case XGL_LOGIC_OP_XOR: logicop = GEN6_LOGICOP_XOR; break;
1167 case XGL_LOGIC_OP_OR: logicop = GEN6_LOGICOP_OR; break;
1168 case XGL_LOGIC_OP_NOR: logicop = GEN6_LOGICOP_NOR; break;
1169 case XGL_LOGIC_OP_EQUIV: logicop = GEN6_LOGICOP_EQUIV; break;
1170 case XGL_LOGIC_OP_INVERT: logicop = GEN6_LOGICOP_INVERT; break;
1171 case XGL_LOGIC_OP_OR_REVERSE: logicop = GEN6_LOGICOP_OR_REVERSE; break;
1172 case XGL_LOGIC_OP_COPY_INVERTED: logicop = GEN6_LOGICOP_COPY_INVERTED; break;
1173 case XGL_LOGIC_OP_OR_INVERTED: logicop = GEN6_LOGICOP_OR_INVERTED; break;
1174 case XGL_LOGIC_OP_NAND: logicop = GEN6_LOGICOP_NAND; break;
1175 case XGL_LOGIC_OP_SET: logicop = GEN6_LOGICOP_SET; break;
1176 default:
1177 assert(!"unknown logic op");
1178 logicop = GEN6_LOGICOP_CLEAR;
1179 break;
1180 }
1181
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001182 dw1 |= GEN6_RT_DW1_LOGICOP_ENABLE |
1183 logicop << GEN6_RT_DW1_LOGICOP_FUNC__SHIFT;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001184 }
1185
1186 if (!(att->channelWriteMask & 0x1))
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001187 dw1 |= GEN6_RT_DW1_WRITE_DISABLE_R;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001188 if (!(att->channelWriteMask & 0x2))
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001189 dw1 |= GEN6_RT_DW1_WRITE_DISABLE_G;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001190 if (!(att->channelWriteMask & 0x4))
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001191 dw1 |= GEN6_RT_DW1_WRITE_DISABLE_B;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001192 if (!(att->channelWriteMask & 0x8))
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001193 dw1 |= GEN6_RT_DW1_WRITE_DISABLE_A;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001194
1195 dw[2 * i] = dw0;
1196 dw[2 * i + 1] = dw1;
1197 }
1198
1199 for (i=info->cb.attachmentCount; i < INTEL_MAX_RENDER_TARGETS; i++)
1200 {
1201 dw[2 * i] = 0;
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001202 dw[2 * i + 1] = GEN6_RT_DW1_COLORCLAMP_RTFORMAT |
1203 GEN6_RT_DW1_PRE_BLEND_CLAMP |
1204 GEN6_RT_DW1_POST_BLEND_CLAMP |
1205 GEN6_RT_DW1_WRITE_DISABLE_R |
1206 GEN6_RT_DW1_WRITE_DISABLE_G |
1207 GEN6_RT_DW1_WRITE_DISABLE_B |
1208 GEN6_RT_DW1_WRITE_DISABLE_A;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001209 }
1210
1211}
1212
1213
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001214static XGL_RESULT pipeline_build_all(struct intel_pipeline *pipeline,
1215 const struct intel_pipeline_create_info *info)
Chia-I Wu3efef432014-08-28 15:00:16 +08001216{
1217 XGL_RESULT ret;
1218
Chia-I Wu98824592014-09-02 09:42:46 +08001219 ret = pipeline_build_shaders(pipeline, info);
1220 if (ret != XGL_SUCCESS)
1221 return ret;
1222
Chia-I Wu1d125092014-10-08 08:49:38 +08001223 if (info->vi.bindingCount > ARRAY_SIZE(pipeline->vb) ||
1224 info->vi.attributeCount > ARRAY_SIZE(pipeline->vb))
1225 return XGL_ERROR_BAD_PIPELINE_DATA;
1226
1227 pipeline->vb_count = info->vi.bindingCount;
1228 memcpy(pipeline->vb, info->vi.pVertexBindingDescriptions,
1229 sizeof(pipeline->vb[0]) * pipeline->vb_count);
1230
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001231 pipeline_build_vertex_elements(pipeline, info);
GregF8cd81832014-11-18 18:01:01 -07001232 pipeline_build_fragment_SBE(pipeline);
Tony Barbourfa6cac72015-01-16 14:27:35 -07001233 pipeline_build_msaa(pipeline, info);
Chia-I Wu5bdb0962015-01-24 12:49:28 +08001234 pipeline_build_depth_stencil(pipeline, info);
Chia-I Wu4d9ad912014-08-29 14:20:36 +08001235
Chia-I Wu509b3f22014-09-02 10:24:05 +08001236 if (intel_gpu_gen(pipeline->dev->gpu) >= INTEL_GEN(7)) {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001237 pipeline_build_urb_alloc_gen7(pipeline, info);
1238 pipeline_build_push_const_alloc_gen7(pipeline, info);
1239 pipeline_build_gs(pipeline, info);
1240 pipeline_build_hs(pipeline, info);
1241 pipeline_build_te(pipeline, info);
1242 pipeline_build_ds(pipeline, info);
Chia-I Wu8370b402014-08-29 12:28:37 +08001243
1244 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
1245 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL |
1246 INTEL_CMD_WA_GEN7_PRE_VS_DEPTH_STALL_WRITE |
1247 INTEL_CMD_WA_GEN7_POST_COMMAND_CS_STALL |
1248 INTEL_CMD_WA_GEN7_POST_COMMAND_DEPTH_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001249 } else {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001250 pipeline_build_urb_alloc_gen6(pipeline, info);
Chia-I Wu8370b402014-08-29 12:28:37 +08001251
1252 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
1253 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001254 }
1255
Chia-I Wube0a3d92014-09-02 13:20:59 +08001256 ret = pipeline_build_ia(pipeline, info);
Chia-I Wu3efef432014-08-28 15:00:16 +08001257
1258 if (ret == XGL_SUCCESS)
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001259 ret = pipeline_rs_state(pipeline, &info->rs);
Chia-I Wu3efef432014-08-28 15:00:16 +08001260
Chia-I Wu3efef432014-08-28 15:00:16 +08001261 if (ret == XGL_SUCCESS) {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001262 pipeline->db_format = info->db.format;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001263 pipeline_build_cb(pipeline, info);
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001264 pipeline->cb_state = info->cb;
1265 pipeline->tess_state = info->tess;
Chia-I Wu3efef432014-08-28 15:00:16 +08001266 }
1267
1268 return ret;
1269}
1270
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001271struct intel_pipeline_create_info_header {
1272 XGL_STRUCTURE_TYPE struct_type;
1273 const struct intel_pipeline_create_info_header *next;
1274};
1275
1276static XGL_RESULT pipeline_create_info_init(struct intel_pipeline_create_info *info,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001277 const struct intel_pipeline_create_info_header *header)
Chia-I Wu3efef432014-08-28 15:00:16 +08001278{
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001279 memset(info, 0, sizeof(*info));
Chia-I Wu3efef432014-08-28 15:00:16 +08001280
Tony Barbourfa6cac72015-01-16 14:27:35 -07001281
1282 /*
1283 * Do we need to set safe defaults in case the app doesn't provide all of
1284 * the necessary create infos?
1285 */
1286 info->ms.samples = 1;
1287 info->ms.sampleMask = 1;
1288
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001289 while (header) {
1290 const void *src = (const void *) header;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001291 size_t size;
Chia-I Wu3efef432014-08-28 15:00:16 +08001292 void *dst;
1293
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001294 switch (header->struct_type) {
Chia-I Wu3efef432014-08-28 15:00:16 +08001295 case XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001296 size = sizeof(info->graphics);
1297 dst = &info->graphics;
Chia-I Wu3efef432014-08-28 15:00:16 +08001298 break;
Chia-I Wu1d125092014-10-08 08:49:38 +08001299 case XGL_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO:
1300 size = sizeof(info->vi);
1301 dst = &info->vi;
1302 break;
Chia-I Wu3efef432014-08-28 15:00:16 +08001303 case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001304 size = sizeof(info->ia);
1305 dst = &info->ia;
Chia-I Wu3efef432014-08-28 15:00:16 +08001306 break;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001307 case XGL_STRUCTURE_TYPE_PIPELINE_DS_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001308 size = sizeof(info->db);
1309 dst = &info->db;
Chia-I Wu3efef432014-08-28 15:00:16 +08001310 break;
1311 case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001312 size = sizeof(info->cb);
1313 dst = &info->cb;
Chia-I Wu3efef432014-08-28 15:00:16 +08001314 break;
1315 case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001316 size = sizeof(info->rs);
1317 dst = &info->rs;
Chia-I Wu3efef432014-08-28 15:00:16 +08001318 break;
1319 case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001320 size = sizeof(info->tess);
1321 dst = &info->tess;
Chia-I Wu3efef432014-08-28 15:00:16 +08001322 break;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001323 case XGL_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO:
1324 size = sizeof(info->ms);
1325 dst = &info->ms;
1326 break;
1327 case XGL_STRUCTURE_TYPE_PIPELINE_VP_STATE_CREATE_INFO:
1328 size = sizeof(info->vp);
1329 dst = &info->vp;
1330 break;
Chia-I Wu3efef432014-08-28 15:00:16 +08001331 case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
1332 {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001333 const XGL_PIPELINE_SHADER *shader =
1334 (const XGL_PIPELINE_SHADER *) (header + 1);
Chia-I Wu3efef432014-08-28 15:00:16 +08001335
1336 src = (const void *) shader;
1337 size = sizeof(*shader);
1338
1339 switch (shader->stage) {
1340 case XGL_SHADER_STAGE_VERTEX:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001341 dst = &info->vs;
Chia-I Wu3efef432014-08-28 15:00:16 +08001342 break;
1343 case XGL_SHADER_STAGE_TESS_CONTROL:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001344 dst = &info->tcs;
Chia-I Wu3efef432014-08-28 15:00:16 +08001345 break;
1346 case XGL_SHADER_STAGE_TESS_EVALUATION:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001347 dst = &info->tes;
Chia-I Wu3efef432014-08-28 15:00:16 +08001348 break;
1349 case XGL_SHADER_STAGE_GEOMETRY:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001350 dst = &info->gs;
Chia-I Wu3efef432014-08-28 15:00:16 +08001351 break;
1352 case XGL_SHADER_STAGE_FRAGMENT:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001353 dst = &info->fs;
Chia-I Wu3efef432014-08-28 15:00:16 +08001354 break;
Chia-I Wu3efef432014-08-28 15:00:16 +08001355 default:
1356 return XGL_ERROR_BAD_PIPELINE_DATA;
1357 break;
1358 }
1359 }
1360 break;
1361 case XGL_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001362 size = sizeof(info->compute);
1363 dst = &info->compute;
Chia-I Wu3efef432014-08-28 15:00:16 +08001364 break;
1365 default:
1366 return XGL_ERROR_BAD_PIPELINE_DATA;
1367 break;
1368 }
1369
1370 memcpy(dst, src, size);
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001371 header = header->next;
Chia-I Wu3efef432014-08-28 15:00:16 +08001372 }
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001373
1374 return XGL_SUCCESS;
Chia-I Wu3efef432014-08-28 15:00:16 +08001375}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001376
Chia-I Wu3efef432014-08-28 15:00:16 +08001377static XGL_RESULT graphics_pipeline_create(struct intel_dev *dev,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001378 const XGL_GRAPHICS_PIPELINE_CREATE_INFO *info_,
Chia-I Wu3efef432014-08-28 15:00:16 +08001379 struct intel_pipeline **pipeline_ret)
1380{
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001381 struct intel_pipeline_create_info info;
Chia-I Wu3efef432014-08-28 15:00:16 +08001382 struct intel_pipeline *pipeline;
1383 XGL_RESULT ret;
1384
Chia-I Wu509b3f22014-09-02 10:24:05 +08001385 ret = pipeline_create_info_init(&info,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001386 (const struct intel_pipeline_create_info_header *) info_);
Chia-I Wu3efef432014-08-28 15:00:16 +08001387 if (ret != XGL_SUCCESS)
1388 return ret;
1389
Chia-I Wu545c2e12015-02-22 13:19:54 +08001390 pipeline = (struct intel_pipeline *) intel_base_create(&dev->base.handle,
1391 sizeof(*pipeline), dev->base.dbg,
1392 XGL_DBG_OBJECT_GRAPHICS_PIPELINE, info_, 0);
Chia-I Wu3efef432014-08-28 15:00:16 +08001393 if (!pipeline)
1394 return XGL_ERROR_OUT_OF_MEMORY;
1395
1396 pipeline->dev = dev;
Chia-I Wub1024732014-12-19 13:00:29 +08001397 pipeline->obj.base.get_info = pipeline_get_info;
Chia-I Wu3efef432014-08-28 15:00:16 +08001398 pipeline->obj.destroy = pipeline_destroy;
Chia-I Wu3efef432014-08-28 15:00:16 +08001399
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001400 ret = pipeline_build_all(pipeline, &info);
Chia-I Wu3efef432014-08-28 15:00:16 +08001401 if (ret == XGL_SUCCESS)
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001402 ret = pipeline_validate(pipeline);
Chia-I Wu3efef432014-08-28 15:00:16 +08001403 if (ret != XGL_SUCCESS) {
1404 pipeline_destroy(&pipeline->obj);
1405 return ret;
1406 }
1407
1408 *pipeline_ret = pipeline;
1409
1410 return XGL_SUCCESS;
1411}
1412
Chia-I Wu96177272015-01-03 15:27:41 +08001413ICD_EXPORT XGL_RESULT XGLAPI xglCreateGraphicsPipeline(
Chia-I Wu3efef432014-08-28 15:00:16 +08001414 XGL_DEVICE device,
1415 const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
1416 XGL_PIPELINE* pPipeline)
1417{
1418 struct intel_dev *dev = intel_dev(device);
1419
1420 return graphics_pipeline_create(dev, pCreateInfo,
1421 (struct intel_pipeline **) pPipeline);
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001422}
1423
Chia-I Wu96177272015-01-03 15:27:41 +08001424ICD_EXPORT XGL_RESULT XGLAPI xglCreateComputePipeline(
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001425 XGL_DEVICE device,
1426 const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo,
1427 XGL_PIPELINE* pPipeline)
1428{
1429 return XGL_ERROR_UNAVAILABLE;
1430}
1431
Chia-I Wu96177272015-01-03 15:27:41 +08001432ICD_EXPORT XGL_RESULT XGLAPI xglStorePipeline(
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001433 XGL_PIPELINE pipeline,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001434 size_t* pDataSize,
1435 void* pData)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001436{
1437 return XGL_ERROR_UNAVAILABLE;
1438}
1439
Chia-I Wu96177272015-01-03 15:27:41 +08001440ICD_EXPORT XGL_RESULT XGLAPI xglLoadPipeline(
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001441 XGL_DEVICE device,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001442 size_t dataSize,
1443 const void* pData,
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001444 XGL_PIPELINE* pPipeline)
1445{
1446 return XGL_ERROR_UNAVAILABLE;
1447}
1448
Chia-I Wu96177272015-01-03 15:27:41 +08001449ICD_EXPORT XGL_RESULT XGLAPI xglCreatePipelineDelta(
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001450 XGL_DEVICE device,
1451 XGL_PIPELINE p1,
1452 XGL_PIPELINE p2,
1453 XGL_PIPELINE_DELTA* delta)
1454{
1455 return XGL_ERROR_UNAVAILABLE;
1456}