blob: db571f76487d3fbd6d75399a084e5bd93f6fbb72 [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
136 sh = icd_alloc(sizeof(*sh), 0, XGL_SYSTEM_ALLOC_INTERNAL);
137 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) {
143 icd_free(sh);
144 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
163void intel_pipeline_shader_destroy(struct intel_pipeline_shader *sh)
164{
165 intel_pipeline_shader_cleanup(sh);
166 icd_free(sh);
167}
168
169static XGL_RESULT pipeline_build_shader(struct intel_pipeline *pipeline,
Chia-I Wuf8385062015-01-04 16:27:24 +0800170 const struct intel_desc_layout *layout,
171 const XGL_PIPELINE_SHADER *sh_info,
172 struct intel_pipeline_shader *sh)
Chia-I Wu3f239832014-12-11 22:57:18 +0800173{
174 XGL_RESULT ret;
175
Chia-I Wuf8385062015-01-04 16:27:24 +0800176 ret = intel_pipeline_shader_compile(sh,
177 pipeline->dev->gpu, layout, sh_info);
Chia-I Wu3f239832014-12-11 22:57:18 +0800178 if (ret != XGL_SUCCESS)
179 return ret;
180
181 sh->max_threads =
182 intel_gpu_get_max_threads(pipeline->dev->gpu, sh_info->stage);
183
184 /* 1KB aligned */
185 sh->scratch_offset = u_align(pipeline->scratch_size, 1024);
186 pipeline->scratch_size = sh->scratch_offset +
187 sh->per_thread_scratch_size * sh->max_threads;
188
189 pipeline->active_shaders |= 1 << sh_info->stage;
190
191 return XGL_SUCCESS;
192}
193
194static XGL_RESULT pipeline_build_shaders(struct intel_pipeline *pipeline,
195 const struct intel_pipeline_create_info *info)
196{
Chia-I Wuf8385062015-01-04 16:27:24 +0800197 const struct intel_desc_layout *layout =
198 intel_desc_layout(info->graphics.lastSetLayout);
Chia-I Wu3f239832014-12-11 22:57:18 +0800199 XGL_RESULT ret = XGL_SUCCESS;
200
Chia-I Wuf8385062015-01-04 16:27:24 +0800201 if (ret == XGL_SUCCESS && info->vs.shader) {
202 ret = pipeline_build_shader(pipeline, layout,
203 &info->vs, &pipeline->vs);
204 }
205 if (ret == XGL_SUCCESS && info->tcs.shader) {
206 ret = pipeline_build_shader(pipeline, layout,
207 &info->tcs,&pipeline->tcs);
208 }
209 if (ret == XGL_SUCCESS && info->tes.shader) {
210 ret = pipeline_build_shader(pipeline, layout,
211 &info->tes,&pipeline->tes);
212 }
213 if (ret == XGL_SUCCESS && info->gs.shader) {
214 ret = pipeline_build_shader(pipeline, layout,
215 &info->gs, &pipeline->gs);
216 }
217 if (ret == XGL_SUCCESS && info->fs.shader) {
218 ret = pipeline_build_shader(pipeline, layout,
219 &info->fs, &pipeline->fs);
220 }
Chia-I Wu3f239832014-12-11 22:57:18 +0800221
Chia-I Wuf8385062015-01-04 16:27:24 +0800222 if (ret == XGL_SUCCESS && info->compute.cs.shader) {
223 layout = intel_desc_layout(info->compute.lastSetLayout);
224 ret = pipeline_build_shader(pipeline, layout,
225 &info->compute.cs, &pipeline->cs);
226 }
Chia-I Wu3f239832014-12-11 22:57:18 +0800227
228 return ret;
229}
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600230static uint32_t *pipeline_cmd_ptr(struct intel_pipeline *pipeline, int cmd_len)
231{
232 uint32_t *ptr;
233
234 assert(pipeline->cmd_len + cmd_len < INTEL_PSO_CMD_ENTRIES);
235 ptr = &pipeline->cmds[pipeline->cmd_len];
236 pipeline->cmd_len += cmd_len;
237 return ptr;
238}
239
Chia-I Wube0a3d92014-09-02 13:20:59 +0800240static XGL_RESULT pipeline_build_ia(struct intel_pipeline *pipeline,
241 const struct intel_pipeline_create_info* info)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600242{
Chia-I Wube0a3d92014-09-02 13:20:59 +0800243 pipeline->topology = info->ia.topology;
244 pipeline->disable_vs_cache = info->ia.disableVertexReuse;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600245
Chia-I Wube0a3d92014-09-02 13:20:59 +0800246 switch (info->ia.topology) {
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600247 case XGL_TOPOLOGY_POINT_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600248 pipeline->prim_type = GEN6_3DPRIM_POINTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600249 break;
250 case XGL_TOPOLOGY_LINE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600251 pipeline->prim_type = GEN6_3DPRIM_LINELIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600252 break;
253 case XGL_TOPOLOGY_LINE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600254 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600255 break;
256 case XGL_TOPOLOGY_TRIANGLE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600257 pipeline->prim_type = GEN6_3DPRIM_TRILIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600258 break;
259 case XGL_TOPOLOGY_TRIANGLE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600260 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600261 break;
262 case XGL_TOPOLOGY_RECT_LIST:
263 /*
264 * TODO: Rect lists are special in XGL, do we need to do
265 * something special here?
266 * XGL Guide:
267 * The rectangle list is a special geometry primitive type
268 * that can be used for implementing post-processing techniques
269 * or efficient copy operations. There are some special limitations
270 * for rectangle primitives. They cannot be clipped, must
271 * be axis aligned and cannot have depth gradient.
272 * Failure to comply with these restrictions results in
273 * undefined rendering results.
274 */
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600275 pipeline->prim_type = GEN6_3DPRIM_RECTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600276 break;
277 case XGL_TOPOLOGY_QUAD_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600278 pipeline->prim_type = GEN6_3DPRIM_QUADLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600279 break;
280 case XGL_TOPOLOGY_QUAD_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600281 pipeline->prim_type = GEN6_3DPRIM_QUADSTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600282 break;
283 case XGL_TOPOLOGY_LINE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600284 pipeline->prim_type = GEN6_3DPRIM_LINELIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600285 break;
286 case XGL_TOPOLOGY_LINE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600287 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600288 break;
289 case XGL_TOPOLOGY_TRIANGLE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600290 pipeline->prim_type = GEN6_3DPRIM_TRILIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600291 break;
292 case XGL_TOPOLOGY_TRIANGLE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600293 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600294 break;
295 case XGL_TOPOLOGY_PATCH:
Chia-I Wube0a3d92014-09-02 13:20:59 +0800296 if (!info->tess.patchControlPoints ||
297 info->tess.patchControlPoints > 32)
298 return XGL_ERROR_BAD_PIPELINE_DATA;
299 pipeline->prim_type = GEN7_3DPRIM_PATCHLIST_1 +
300 info->tess.patchControlPoints - 1;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600301 break;
302 default:
303 return XGL_ERROR_BAD_PIPELINE_DATA;
304 }
305
Chia-I Wube0a3d92014-09-02 13:20:59 +0800306 if (info->ia.primitiveRestartEnable) {
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600307 pipeline->primitive_restart = true;
Chia-I Wube0a3d92014-09-02 13:20:59 +0800308 pipeline->primitive_restart_index = info->ia.primitiveRestartIndex;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600309 } else {
310 pipeline->primitive_restart = false;
311 }
312
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600313 return XGL_SUCCESS;
314}
315
Chia-I Wu3efef432014-08-28 15:00:16 +0800316static XGL_RESULT pipeline_rs_state(struct intel_pipeline *pipeline,
317 const XGL_PIPELINE_RS_STATE_CREATE_INFO* rs_state)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600318{
319 pipeline->depthClipEnable = rs_state->depthClipEnable;
320 pipeline->rasterizerDiscardEnable = rs_state->rasterizerDiscardEnable;
Tony Barbourfa6cac72015-01-16 14:27:35 -0700321
322 if (rs_state->provokingVertex == XGL_PROVOKING_VERTEX_FIRST) {
323 pipeline->provoking_vertex_tri = 0;
324 pipeline->provoking_vertex_trifan = 1;
325 pipeline->provoking_vertex_line = 0;
326 } else {
327 pipeline->provoking_vertex_tri = 2;
328 pipeline->provoking_vertex_trifan = 2;
329 pipeline->provoking_vertex_line = 1;
330 }
331
332 switch (rs_state->fillMode) {
333 case XGL_FILL_POINTS:
334 pipeline->cmd_sf_fill |= GEN7_SF_DW1_FRONTFACE_POINT |
335 GEN7_SF_DW1_BACKFACE_POINT;
336 break;
337 case XGL_FILL_WIREFRAME:
338 pipeline->cmd_sf_fill |= GEN7_SF_DW1_FRONTFACE_WIREFRAME |
339 GEN7_SF_DW1_BACKFACE_WIREFRAME;
340 break;
341 case XGL_FILL_SOLID:
342 default:
343 pipeline->cmd_sf_fill |= GEN7_SF_DW1_FRONTFACE_SOLID |
344 GEN7_SF_DW1_BACKFACE_SOLID;
345 break;
346 }
347
348 if (rs_state->frontFace == XGL_FRONT_FACE_CCW) {
349 pipeline->cmd_sf_fill |= GEN7_SF_DW1_FRONTWINDING_CCW;
350 pipeline->cmd_clip_cull |= GEN7_CLIP_DW1_FRONTWINDING_CCW;
351 }
352
353 switch (rs_state->cullMode) {
354 case XGL_CULL_NONE:
355 default:
356 pipeline->cmd_sf_cull |= GEN7_SF_DW2_CULLMODE_NONE;
357 pipeline->cmd_clip_cull |= GEN7_CLIP_DW1_CULLMODE_NONE;
358 break;
359 case XGL_CULL_FRONT:
360 pipeline->cmd_sf_cull |= GEN7_SF_DW2_CULLMODE_FRONT;
361 pipeline->cmd_clip_cull |= GEN7_CLIP_DW1_CULLMODE_FRONT;
362 break;
363 case XGL_CULL_BACK:
364 pipeline->cmd_sf_cull |= GEN7_SF_DW2_CULLMODE_BACK;
365 pipeline->cmd_clip_cull |= GEN7_CLIP_DW1_CULLMODE_BACK;
366 break;
367 case XGL_CULL_FRONT_AND_BACK:
368 pipeline->cmd_sf_cull |= GEN7_SF_DW2_CULLMODE_BOTH;
369 pipeline->cmd_clip_cull |= GEN7_CLIP_DW1_CULLMODE_BOTH;
370 break;
371 }
372
373 /* only GEN7+ needs cull mode in 3DSTATE_CLIP */
374 if (intel_gpu_gen(pipeline->dev->gpu) == INTEL_GEN(6))
375 pipeline->cmd_clip_cull = 0;
376
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600377 return XGL_SUCCESS;
378}
379
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600380static void pipeline_destroy(struct intel_obj *obj)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600381{
382 struct intel_pipeline *pipeline = intel_pipeline_from_obj(obj);
383
Chia-I Wu3f239832014-12-11 22:57:18 +0800384 if (pipeline->active_shaders & SHADER_VERTEX_FLAG) {
385 intel_pipeline_shader_cleanup(&pipeline->vs);
386 }
387
388 if (pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) {
389 intel_pipeline_shader_cleanup(&pipeline->tcs);
390 }
391
392 if (pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) {
393 intel_pipeline_shader_cleanup(&pipeline->tes);
394 }
395
396 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
397 intel_pipeline_shader_cleanup(&pipeline->gs);
398 }
399
400 if (pipeline->active_shaders & SHADER_FRAGMENT_FLAG) {
401 intel_pipeline_shader_cleanup(&pipeline->fs);
402 }
403
404 if (pipeline->active_shaders & SHADER_COMPUTE_FLAG) {
405 intel_pipeline_shader_cleanup(&pipeline->cs);
406 }
Chia-I Wued833872014-08-23 17:00:35 +0800407
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600408 intel_base_destroy(&pipeline->obj.base);
409}
410
Chia-I Wub1024732014-12-19 13:00:29 +0800411static XGL_RESULT pipeline_get_info(struct intel_base *base, int type,
412 XGL_SIZE *size, XGL_VOID *data)
413{
414 struct intel_pipeline *pipeline = intel_pipeline_from_base(base);
415 XGL_RESULT ret = XGL_SUCCESS;
416
417 switch (type) {
418 case XGL_INFO_TYPE_MEMORY_REQUIREMENTS:
419 {
420 XGL_MEMORY_REQUIREMENTS *mem_req = data;
421
422 *size = sizeof(XGL_MEMORY_REQUIREMENTS);
423 if (data) {
424 mem_req->size = pipeline->scratch_size;
425 mem_req->alignment = 1024;
Jon Ashburnd8031332015-01-22 10:52:13 -0700426 mem_req->memType = XGL_MEMORY_TYPE_OTHER;
Chia-I Wub1024732014-12-19 13:00:29 +0800427 }
428 }
429 break;
430 default:
431 ret = intel_base_get_info(base, type, size, data);
432 break;
433 }
434
435 return ret;
436}
437
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800438static XGL_RESULT pipeline_validate(struct intel_pipeline *pipeline)
Chia-I Wu3efef432014-08-28 15:00:16 +0800439{
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600440 /*
441 * Validate required elements
442 */
443 if (!(pipeline->active_shaders & SHADER_VERTEX_FLAG)) {
444 // TODO: Log debug message: Vertex Shader required.
Chia-I Wu3efef432014-08-28 15:00:16 +0800445 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600446 }
447
448 /*
449 * Tessalation control and evaluation have to both have a shader defined or
450 * neither should have a shader defined.
451 */
452 if (((pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) == 0) !=
453 ((pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) == 0) ) {
454 // TODO: Log debug message: Both Tess control and Tess eval are required to use tessalation
Chia-I Wu3efef432014-08-28 15:00:16 +0800455 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600456 }
457
458 if ((pipeline->active_shaders & SHADER_COMPUTE_FLAG) &&
459 (pipeline->active_shaders & (SHADER_VERTEX_FLAG | SHADER_TESS_CONTROL_FLAG |
460 SHADER_TESS_EVAL_FLAG | SHADER_GEOMETRY_FLAG |
461 SHADER_FRAGMENT_FLAG))) {
462 // TODO: Log debug message: Can only specify compute shader when doing compute
Chia-I Wu3efef432014-08-28 15:00:16 +0800463 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600464 }
465
466 /*
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600467 * XGL_TOPOLOGY_PATCH primitive topology is only valid for tessellation pipelines.
468 * Mismatching primitive topology and tessellation fails graphics pipeline creation.
469 */
470 if (pipeline->active_shaders & (SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG) &&
Chia-I Wube0a3d92014-09-02 13:20:59 +0800471 (pipeline->topology != XGL_TOPOLOGY_PATCH)) {
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600472 // TODO: Log debug message: Invalid topology used with tessalation shader.
Chia-I Wu3efef432014-08-28 15:00:16 +0800473 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600474 }
475
Chia-I Wube0a3d92014-09-02 13:20:59 +0800476 if ((pipeline->topology == XGL_TOPOLOGY_PATCH) &&
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600477 (pipeline->active_shaders & ~(SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG))) {
478 // TODO: Log debug message: Cannot use TOPOLOGY_PATCH on non-tessalation shader.
Chia-I Wu3efef432014-08-28 15:00:16 +0800479 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600480 }
481
Chia-I Wu3efef432014-08-28 15:00:16 +0800482 return XGL_SUCCESS;
483}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600484
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800485static void pipeline_build_urb_alloc_gen6(struct intel_pipeline *pipeline,
486 const struct intel_pipeline_create_info *info)
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800487{
Chia-I Wu509b3f22014-09-02 10:24:05 +0800488 const struct intel_gpu *gpu = pipeline->dev->gpu;
489 const int urb_size = ((gpu->gt == 2) ? 64 : 32) * 1024;
Chia-I Wua4d1b392014-10-10 13:57:29 +0800490 const struct intel_pipeline_shader *vs = &pipeline->vs;
491 const struct intel_pipeline_shader *gs = &pipeline->gs;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800492 int vs_entry_size, gs_entry_size;
493 int vs_size, gs_size;
494
Chia-I Wu509b3f22014-09-02 10:24:05 +0800495 INTEL_GPU_ASSERT(gpu, 6, 6);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800496
497 vs_entry_size = ((vs->in_count >= vs->out_count) ?
498 vs->in_count : vs->out_count);
499 gs_entry_size = (gs) ? gs->out_count : 0;
500
501 /* in bytes */
502 vs_entry_size *= sizeof(float) * 4;
503 gs_entry_size *= sizeof(float) * 4;
504
Chia-I Wua4d1b392014-10-10 13:57:29 +0800505 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800506 vs_size = urb_size / 2;
507 gs_size = vs_size;
508 } else {
509 vs_size = urb_size;
510 gs_size = 0;
511 }
512
513 /* 3DSTATE_URB */
514 {
515 const uint8_t cmd_len = 3;
516 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_URB) |
517 (cmd_len - 2);
518 int vs_alloc_size, gs_alloc_size;
519 int vs_entry_count, gs_entry_count;
520 uint32_t *dw;
521
522 /* in 1024-bit rows */
523 vs_alloc_size = (vs_entry_size + 128 - 1) / 128;
524 gs_alloc_size = (gs_entry_size + 128 - 1) / 128;
525
526 /* valid range is [1, 5] */
527 if (!vs_alloc_size)
528 vs_alloc_size = 1;
529 if (!gs_alloc_size)
530 gs_alloc_size = 1;
531 assert(vs_alloc_size <= 5 && gs_alloc_size <= 5);
532
533 /* valid range is [24, 256], multiples of 4 */
534 vs_entry_count = (vs_size / 128 / vs_alloc_size) & ~3;
535 if (vs_entry_count > 256)
536 vs_entry_count = 256;
537 assert(vs_entry_count >= 24);
538
539 /* valid range is [0, 256], multiples of 4 */
540 gs_entry_count = (gs_size / 128 / gs_alloc_size) & ~3;
541 if (gs_entry_count > 256)
542 gs_entry_count = 256;
543
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600544 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800545
546 dw[0] = dw0;
547 dw[1] = (vs_alloc_size - 1) << GEN6_URB_DW1_VS_ENTRY_SIZE__SHIFT |
548 vs_entry_count << GEN6_URB_DW1_VS_ENTRY_COUNT__SHIFT;
549 dw[2] = gs_entry_count << GEN6_URB_DW2_GS_ENTRY_COUNT__SHIFT |
550 (gs_alloc_size - 1) << GEN6_URB_DW2_GS_ENTRY_SIZE__SHIFT;
551 }
552}
553
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800554static void pipeline_build_urb_alloc_gen7(struct intel_pipeline *pipeline,
555 const struct intel_pipeline_create_info *info)
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800556{
Chia-I Wu509b3f22014-09-02 10:24:05 +0800557 const struct intel_gpu *gpu = pipeline->dev->gpu;
558 const int urb_size = ((gpu->gt == 3) ? 512 :
559 (gpu->gt == 2) ? 256 : 128) * 1024;
Cody Northrop306ec352014-10-06 15:11:45 -0600560 const struct intel_pipeline_shader *vs = &pipeline->vs;
561 const struct intel_pipeline_shader *gs = &pipeline->gs;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800562 /* some space is reserved for PCBs */
Chia-I Wu509b3f22014-09-02 10:24:05 +0800563 int urb_offset = ((gpu->gt == 3) ? 32 : 16) * 1024;
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, 7, 7.5);
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 - urb_offset) / 2;
579 gs_size = vs_size;
580 } else {
581 vs_size = urb_size - urb_offset;
582 gs_size = 0;
583 }
584
585 /* 3DSTATE_URB_* */
586 {
587 const uint8_t cmd_len = 2;
588 int vs_alloc_size, gs_alloc_size;
589 int vs_entry_count, gs_entry_count;
590 uint32_t *dw;
591
592 /* in 512-bit rows */
593 vs_alloc_size = (vs_entry_size + 64 - 1) / 64;
594 gs_alloc_size = (gs_entry_size + 64 - 1) / 64;
595
596 if (!vs_alloc_size)
597 vs_alloc_size = 1;
598 if (!gs_alloc_size)
599 gs_alloc_size = 1;
600
601 /* avoid performance decrease due to banking */
602 if (vs_alloc_size == 5)
603 vs_alloc_size = 6;
604
605 /* in multiples of 8 */
606 vs_entry_count = (vs_size / 64 / vs_alloc_size) & ~7;
607 assert(vs_entry_count >= 32);
608
609 gs_entry_count = (gs_size / 64 / gs_alloc_size) & ~7;
610
Chia-I Wu509b3f22014-09-02 10:24:05 +0800611 if (intel_gpu_gen(gpu) >= INTEL_GEN(7.5)) {
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800612 const int max_vs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800613 (gpu->gt >= 2) ? 1664 : 640;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800614 const int max_gs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800615 (gpu->gt >= 2) ? 640 : 256;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800616 if (vs_entry_count >= max_vs_entry_count)
617 vs_entry_count = max_vs_entry_count;
618 if (gs_entry_count >= max_gs_entry_count)
619 gs_entry_count = max_gs_entry_count;
620 } else {
621 const int max_vs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800622 (gpu->gt == 2) ? 704 : 512;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800623 const int max_gs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800624 (gpu->gt == 2) ? 320 : 192;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800625 if (vs_entry_count >= max_vs_entry_count)
626 vs_entry_count = max_vs_entry_count;
627 if (gs_entry_count >= max_gs_entry_count)
628 gs_entry_count = max_gs_entry_count;
629 }
630
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600631 dw = pipeline_cmd_ptr(pipeline, cmd_len*4);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800632 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_VS) | (cmd_len - 2);
633 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT |
634 (vs_alloc_size - 1) << GEN7_URB_ANY_DW1_ENTRY_SIZE__SHIFT |
635 vs_entry_count;
636
637 dw += 2;
638 if (gs_size)
639 urb_offset += vs_size;
640 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_GS) | (cmd_len - 2);
641 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT |
642 (gs_alloc_size - 1) << GEN7_URB_ANY_DW1_ENTRY_SIZE__SHIFT |
643 gs_entry_count;
644
645 dw += 2;
646 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_HS) | (cmd_len - 2);
647 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT;
648
649 dw += 2;
650 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_DS) | (cmd_len - 2);
651 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT;
652 }
653}
654
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800655static void pipeline_build_push_const_alloc_gen7(struct intel_pipeline *pipeline,
656 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600657{
658 const uint8_t cmd_len = 2;
659 uint32_t offset = 0;
660 uint32_t size = 8192;
661 uint32_t *dw;
662 int end;
663
Chia-I Wu509b3f22014-09-02 10:24:05 +0800664 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600665
666 /*
667 * From the Ivy Bridge PRM, volume 2 part 1, page 68:
668 *
669 * "(A table that says the maximum size of each constant buffer is
670 * 16KB")
671 *
672 * From the Ivy Bridge PRM, volume 2 part 1, page 115:
673 *
674 * "The sum of the Constant Buffer Offset and the Constant Buffer Size
675 * may not exceed the maximum value of the Constant Buffer Size."
676 *
677 * Thus, the valid range of buffer end is [0KB, 16KB].
678 */
679 end = (offset + size) / 1024;
680 if (end > 16) {
681 assert(!"invalid constant buffer end");
682 end = 16;
683 }
684
685 /* the valid range of buffer offset is [0KB, 15KB] */
686 offset = (offset + 1023) / 1024;
687 if (offset > 15) {
688 assert(!"invalid constant buffer offset");
689 offset = 15;
690 }
691
692 if (offset > end) {
693 assert(!size);
694 offset = end;
695 }
696
697 /* the valid range of buffer size is [0KB, 15KB] */
698 size = end - offset;
699 if (size > 15) {
700 assert(!"invalid constant buffer size");
701 size = 15;
702 }
703
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800704 dw = pipeline_cmd_ptr(pipeline, cmd_len * 5);
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600705 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_VS) | (cmd_len - 2);
706 dw[1] = offset << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
707 size << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
708
709 dw += 2;
710 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_PS) | (cmd_len - 2);
711 dw[1] = size << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
712 size << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
713
714 dw += 2;
715 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_HS) | (cmd_len - 2);
716 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
717 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
718
719 dw += 2;
720 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_DS) | (cmd_len - 2);
721 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
722 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
723
724 dw += 2;
725 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_GS) | (cmd_len - 2);
726 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
727 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
Chia-I Wu8370b402014-08-29 12:28:37 +0800728
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600729 // gen7_wa_pipe_control_cs_stall(p, true, true);
730 // looks equivalent to: gen6_wa_wm_multisample_flush - this does more
731 // than the documentation seems to imply
732}
733
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800734static void pipeline_build_vertex_elements(struct intel_pipeline *pipeline,
735 const struct intel_pipeline_create_info *info)
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800736{
Cody Northrop306ec352014-10-06 15:11:45 -0600737 const struct intel_pipeline_shader *vs = &pipeline->vs;
Chia-I Wu1d125092014-10-08 08:49:38 +0800738 uint8_t cmd_len;
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800739 uint32_t *dw;
Chia-I Wu1d125092014-10-08 08:49:38 +0800740 XGL_UINT i;
741 int comps[4];
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800742
Chia-I Wu509b3f22014-09-02 10:24:05 +0800743 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800744
GregF8cd81832014-11-18 18:01:01 -0700745 cmd_len = 1 + 2 * u_popcountll(vs->inputs_read);
Chia-I Wu1d125092014-10-08 08:49:38 +0800746 if (vs->uses & (INTEL_SHADER_USE_VID | INTEL_SHADER_USE_IID))
747 cmd_len += 2;
748
749 if (cmd_len == 1)
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800750 return;
751
752 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Chia-I Wu1d125092014-10-08 08:49:38 +0800753
754 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_ELEMENTS) |
755 (cmd_len - 2);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800756 dw++;
757
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800758 /* VERTEX_ELEMENT_STATE */
Chia-I Wu1d125092014-10-08 08:49:38 +0800759 for (i = 0; i < info->vi.attributeCount; i++) {
GregF8cd81832014-11-18 18:01:01 -0700760 if (!(vs->inputs_read & (1L << i)))
GregF2dc40212014-10-31 17:31:47 -0600761 continue;
Chia-I Wu1d125092014-10-08 08:49:38 +0800762 const XGL_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION *attr =
763 &info->vi.pVertexAttributeDescriptions[i];
764 const int format =
765 intel_format_translate_color(pipeline->dev->gpu, attr->format);
766
767 comps[0] = GEN6_VFCOMP_STORE_0;
768 comps[1] = GEN6_VFCOMP_STORE_0;
769 comps[2] = GEN6_VFCOMP_STORE_0;
770 comps[3] = icd_format_is_int(attr->format) ?
771 GEN6_VFCOMP_STORE_1_INT : GEN6_VFCOMP_STORE_1_FP;
772
773 switch (icd_format_get_channel_count(attr->format)) {
774 case 4: comps[3] = GEN6_VFCOMP_STORE_SRC; /* fall through */
775 case 3: comps[2] = GEN6_VFCOMP_STORE_SRC; /* fall through */
776 case 2: comps[1] = GEN6_VFCOMP_STORE_SRC; /* fall through */
777 case 1: comps[0] = GEN6_VFCOMP_STORE_SRC; break;
778 default:
779 break;
780 }
781
782 assert(attr->offsetInBytes <= 2047);
783
784 dw[0] = attr->binding << GEN6_VE_STATE_DW0_VB_INDEX__SHIFT |
785 GEN6_VE_STATE_DW0_VALID |
786 format << GEN6_VE_STATE_DW0_FORMAT__SHIFT |
787 attr->offsetInBytes;
788
789 dw[1] = comps[0] << GEN6_VE_STATE_DW1_COMP0__SHIFT |
790 comps[1] << GEN6_VE_STATE_DW1_COMP1__SHIFT |
791 comps[2] << GEN6_VE_STATE_DW1_COMP2__SHIFT |
792 comps[3] << GEN6_VE_STATE_DW1_COMP3__SHIFT;
793
794 dw += 2;
795 }
GregF932fcf52014-10-29 17:02:11 -0600796
797 if (vs->uses & (INTEL_SHADER_USE_VID | INTEL_SHADER_USE_IID)) {
798 comps[0] = (vs->uses & INTEL_SHADER_USE_VID) ?
799 GEN6_VFCOMP_STORE_VID : GEN6_VFCOMP_STORE_0;
800 comps[1] = (vs->uses & INTEL_SHADER_USE_IID) ?
801 GEN6_VFCOMP_STORE_IID : GEN6_VFCOMP_NOSTORE;
802 comps[2] = GEN6_VFCOMP_NOSTORE;
803 comps[3] = GEN6_VFCOMP_NOSTORE;
804
805 dw[0] = GEN6_VE_STATE_DW0_VALID;
806 dw[1] = comps[0] << GEN6_VE_STATE_DW1_COMP0__SHIFT |
807 comps[1] << GEN6_VE_STATE_DW1_COMP1__SHIFT |
808 comps[2] << GEN6_VE_STATE_DW1_COMP2__SHIFT |
809 comps[3] << GEN6_VE_STATE_DW1_COMP3__SHIFT;
810
811 dw += 2;
812 }
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800813}
814
GregF8cd81832014-11-18 18:01:01 -0700815static void pipeline_build_fragment_SBE(struct intel_pipeline *pipeline)
816{
817 const struct intel_pipeline_shader *fs = &pipeline->fs;
818 const struct intel_pipeline_shader *vs = &pipeline->vs;
819 uint8_t cmd_len;
820 uint32_t *body;
821 XGL_UINT attr_skip, attr_count;
822 XGL_UINT vue_offset, vue_len;
823 XGL_UINT i;
824
825 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
826
827 cmd_len = 14;
828
829 body = pipeline_cmd_ptr(pipeline, cmd_len);
830 pipeline->cmd_sbe_body_offset = body - pipeline->cmds + 1;
831
832 /* VS outputs VUE header and position additionally */
833 assert(vs->out_count >= fs->in_count + 2);
834 assert(!fs->reads_user_clip || vs->enable_user_clip);
835 attr_skip = vs->outputs_offset;
836 if (vs->enable_user_clip != fs->reads_user_clip) {
837 attr_skip += 2;
838 }
839 assert(vs->out_count >= attr_skip);
840 attr_count = vs->out_count - attr_skip;
841
842 // LUNARG TODO: We currently are only handling 16 attrs;
843 // ultimately, we need to handle 32
844 assert(fs->in_count <= 16);
845 assert(attr_count <= 16);
846
847 vue_offset = attr_skip / 2;
848 vue_len = (attr_count + 1) / 2;
849 if (!vue_len)
850 vue_len = 1;
851
852 body[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SBE) |
853 (cmd_len - 2);
854
855 // LUNARG TODO: If the attrs needed by the FS are exactly
856 // what is written by the VS, we don't need to enable
857 // swizzling, improving performance. Even if we swizzle,
858 // we can improve performance by reducing vue_len to
859 // just include the values needed by the FS:
860 // vue_len = ceiling((max_vs_out + 1)/2)
861
862 body[1] = GEN7_SBE_DW1_ATTR_SWIZZLE_ENABLE |
863 fs->in_count << GEN7_SBE_DW1_ATTR_COUNT__SHIFT |
864 vue_len << GEN7_SBE_DW1_URB_READ_LEN__SHIFT |
865 vue_offset << GEN7_SBE_DW1_URB_READ_OFFSET__SHIFT;
866
867 uint16_t vs_slot[fs->in_count];
868 XGL_INT fs_in = 0;
869 XGL_INT vs_out = - (vue_offset * 2 - vs->outputs_offset);
870 for (i=0; i < 64; i++) {
Cody Northropd75c13e2015-01-02 14:07:20 -0700871 bool vsWrites = vs->outputs_written & (1L << i);
872 bool fsReads = fs->inputs_read & (1L << i);
873
874 if (fsReads) {
GregF8cd81832014-11-18 18:01:01 -0700875 assert(vs_out >= 0);
876 assert(fs_in < fs->in_count);
877 vs_slot[fs_in] = vs_out;
Cody Northropd75c13e2015-01-02 14:07:20 -0700878
879 if (!vsWrites) {
880 // If the vertex shader did not write this input, we cannot
881 // program the SBE to read it. Our choices are to allow it to
882 // read junk from a GRF, or get zero. We're choosing zero.
883 if (i >= fs->generic_input_start) {
884 vs_slot[fs_in] = GEN7_SBE_ATTR_CONST_0000 |
885 GEN7_SBE_ATTR_OVERRIDE_X |
886 GEN7_SBE_ATTR_OVERRIDE_Y |
887 GEN7_SBE_ATTR_OVERRIDE_Z |
888 GEN7_SBE_ATTR_OVERRIDE_W;
889 }
890 }
891
GregF8cd81832014-11-18 18:01:01 -0700892 fs_in += 1;
893 }
Cody Northropd75c13e2015-01-02 14:07:20 -0700894 if (vsWrites) {
GregF8cd81832014-11-18 18:01:01 -0700895 vs_out += 1;
896 }
897 }
898
899 for (i = 0; i < 8; i++) {
900 uint16_t hi, lo;
901
902 /* no attr swizzles */
903 if (i * 2 + 1 < fs->in_count) {
904 lo = vs_slot[i * 2];
905 hi = vs_slot[i * 2 + 1];
906 } else if (i * 2 < fs->in_count) {
907 lo = vs_slot[i * 2];
908 hi = 0;
909 } else {
910 hi = 0;
911 lo = 0;
912 }
913
914 body[2 + i] = hi << GEN7_SBE_ATTR_HIGH__SHIFT | lo;
915 }
916
917 body[10] = 0; /* point sprite enables */
918 body[11] = 0; /* constant interpolation enables */
919 body[12] = 0; /* WrapShortest enables */
920 body[13] = 0;
921}
922
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800923static void pipeline_build_gs(struct intel_pipeline *pipeline,
924 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600925{
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600926 // gen7_emit_3DSTATE_GS done by cmd_pipeline
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600927}
928
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800929static void pipeline_build_hs(struct intel_pipeline *pipeline,
930 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600931{
932 const uint8_t cmd_len = 7;
933 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
934 uint32_t *dw;
935
Chia-I Wu509b3f22014-09-02 10:24:05 +0800936 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600937
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800938 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600939 dw[0] = dw0;
940 dw[1] = 0;
941 dw[2] = 0;
942 dw[3] = 0;
943 dw[4] = 0;
944 dw[5] = 0;
945 dw[6] = 0;
946}
947
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800948static void pipeline_build_te(struct intel_pipeline *pipeline,
949 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600950{
951 const uint8_t cmd_len = 4;
952 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_TE) | (cmd_len - 2);
953 uint32_t *dw;
954
Chia-I Wu509b3f22014-09-02 10:24:05 +0800955 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600956
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800957 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600958 dw[0] = dw0;
959 dw[1] = 0;
960 dw[2] = 0;
961 dw[3] = 0;
962}
963
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800964static void pipeline_build_ds(struct intel_pipeline *pipeline,
965 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600966{
967 const uint8_t cmd_len = 6;
968 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
969 uint32_t *dw;
970
Chia-I Wu509b3f22014-09-02 10:24:05 +0800971 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600972
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800973 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600974 dw[0] = dw0;
975 dw[1] = 0;
976 dw[2] = 0;
977 dw[3] = 0;
978 dw[4] = 0;
979 dw[5] = 0;
980}
981
Tony Barbourfa6cac72015-01-16 14:27:35 -0700982static void pipeline_build_depth_stencil(struct intel_pipeline *pipeline,
983 const struct intel_pipeline_create_info *info)
984{
985 pipeline->cmd_depth_stencil = 0;
986
987 if (info->db.stencilTestEnable) {
988 pipeline->cmd_depth_stencil = 1 << 31 |
989 translate_compare_func(info->db.front.stencilFunc) << 28 |
990 translate_stencil_op(info->db.front.stencilFailOp) << 25 |
991 translate_stencil_op(info->db.front.stencilDepthFailOp) << 22 |
992 translate_stencil_op(info->db.front.stencilPassOp) << 19 |
993 1 << 15 |
994 translate_compare_func(info->db.back.stencilFunc) << 12 |
995 translate_stencil_op(info->db.back.stencilFailOp) << 9 |
996 translate_stencil_op(info->db.back.stencilDepthFailOp) << 6 |
997 translate_stencil_op(info->db.back.stencilPassOp) << 3;
998 }
999
1000 pipeline->stencilTestEnable = info->db.stencilTestEnable;
1001
1002 /*
1003 * From the Sandy Bridge PRM, volume 2 part 1, page 360:
1004 *
1005 * "Enabling the Depth Test function without defining a Depth Buffer is
1006 * UNDEFINED."
1007 *
1008 * From the Sandy Bridge PRM, volume 2 part 1, page 375:
1009 *
1010 * "A Depth Buffer must be defined before enabling writes to it, or
1011 * operation is UNDEFINED."
1012 *
1013 * TODO We do not check these yet.
1014 */
1015 if (info->db.depthTestEnable) {
1016 pipeline->cmd_depth_test = GEN6_ZS_DW2_DEPTH_TEST_ENABLE |
1017 translate_compare_func(info->db.depthFunc) << 27;
1018 } else {
1019 pipeline->cmd_depth_test = GEN6_COMPAREFUNCTION_ALWAYS << 27;
1020 }
1021
1022 if (info->db.depthWriteEnable)
1023 pipeline->cmd_depth_test |= GEN6_ZS_DW2_DEPTH_WRITE_ENABLE;
1024}
1025
1026static void pipeline_init_sample_pattern(struct intel_pipeline *pipeline,
1027 uint8_t *samples)
1028{
1029 struct sample {
1030 int x, y;
1031 };
1032 static const struct sample default_pattern_2x[2] = {
1033 { -4, -4 },
1034 { 4, 4 },
1035 };
1036 static const struct sample default_pattern_4x[4] = {
1037 { -2, -6 },
1038 { 6, -2 },
1039 { -6, 2 },
1040 { 2, 6 },
1041 };
1042 static const struct sample default_pattern_8x[8] = {
1043 { 1, -3 },
1044 { -1, 3 },
1045 { 5, 1 },
1046 { -3, -5 },
1047 { -5, 5 },
1048 { -7, -1 },
1049 { 3, 7 },
1050 { 7, -7 },
1051 };
1052
1053 const struct sample *pattern;
1054 int i;
1055
1056 switch (pipeline->sample_count) {
1057 case 2:
1058 pattern = default_pattern_2x;
1059 break;
1060 case 4:
1061 pattern = default_pattern_4x;
1062 break;
1063 case 8:
1064 pattern = default_pattern_8x;
1065 break;
1066 default:
1067 memset(samples, 0, pipeline->sample_count);
1068 return;
1069 break;
1070 }
1071
1072 for (i = 0; i < pipeline->sample_count; i++)
1073 samples[i] = (pattern[i].x + 8) << 4 | (pattern[i].y + 8);
1074}
1075
1076static void pipeline_build_msaa(struct intel_pipeline *pipeline,
1077 const struct intel_pipeline_create_info *info)
1078{
1079 uint32_t cmd, cmd_len;
1080 uint32_t *dw;
1081
1082 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
1083
1084
1085 pipeline->sample_count = (info->ms.samples <= 1)?1:info->ms.samples;
1086
1087 /* 3DSTATE_MULTISAMPLE */
1088 cmd = GEN6_RENDER_CMD(3D, 3DSTATE_MULTISAMPLE);
1089 cmd_len = (intel_gpu_gen(pipeline->dev->gpu) >= INTEL_GEN(7)) ? 4 : 3;
1090 dw = pipeline_cmd_ptr(pipeline, cmd_len + 2);
1091 dw[0] = cmd | (cmd_len - 2);
1092 if (pipeline->sample_count <= 1)
1093 dw[1] = GEN6_MULTISAMPLE_DW1_NUMSAMPLES_1;
1094 else if (pipeline->sample_count <= 4 || intel_gpu_gen(pipeline->dev->gpu) == INTEL_GEN(6))
1095 dw[1] = GEN6_MULTISAMPLE_DW1_NUMSAMPLES_4;
1096 else
1097 dw[1] = GEN7_MULTISAMPLE_DW1_NUMSAMPLES_8;
1098
1099 pipeline_init_sample_pattern(pipeline, (uint8_t *) &dw[2]);
1100
1101 dw += cmd_len;
1102
1103 /* 3DSTATE_SAMPLE_MASK */
1104 cmd = GEN6_RENDER_CMD(3D, 3DSTATE_SAMPLE_MASK);
1105 cmd_len = 2;
1106
1107 dw[0] = cmd | (cmd_len - 2);
1108 dw[1] = info->ms.sampleMask & ((1 << pipeline->sample_count) - 1);
1109 pipeline->cmd_sample_mask = dw[1];
1110}
1111
1112static void pipeline_build_cb(struct intel_pipeline *pipeline,
1113 const struct intel_pipeline_create_info *info)
1114{
1115 XGL_UINT i;
1116
1117 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
1118 STATIC_ASSERT(ARRAY_SIZE(pipeline->cmd_cb) >= INTEL_MAX_RENDER_TARGETS*2);
1119 assert(info->cb.attachmentCount <= INTEL_MAX_RENDER_TARGETS);
1120
1121 uint32_t *dw = pipeline->cmd_cb;
1122
1123 for (i = 0; i < info->cb.attachmentCount; i++) {
1124 const XGL_PIPELINE_CB_ATTACHMENT_STATE *att = &info->cb.pAttachments[i];
1125 uint32_t dw0, dw1;
1126
1127
1128 dw0 = 0;
1129 dw1 = GEN6_BLEND_DW1_COLORCLAMP_RTFORMAT |
1130 GEN6_BLEND_DW1_PRE_BLEND_CLAMP |
1131 GEN6_BLEND_DW1_POST_BLEND_CLAMP;
1132
1133 if (att->blendEnable) {
1134 dw0 = 1 << 31 |
1135 translate_blend_func(att->blendFuncAlpha) << 26 |
1136 translate_blend(att->srcBlendAlpha) << 20 |
1137 translate_blend(att->destBlendAlpha) << 15 |
1138 translate_blend_func(att->blendFuncColor) << 11 |
1139 translate_blend(att->srcBlendColor) << 5 |
1140 translate_blend(att->destBlendColor);
1141
1142 if (att->blendFuncAlpha != att->blendFuncColor ||
1143 att->srcBlendAlpha != att->srcBlendColor ||
1144 att->destBlendAlpha != att->destBlendColor)
1145 dw0 |= 1 << 30;
1146 }
1147
1148 if (info->cb.logicOp != XGL_LOGIC_OP_COPY) {
1149 int logicop;
1150
1151 switch (info->cb.logicOp) {
1152 case XGL_LOGIC_OP_CLEAR: logicop = GEN6_LOGICOP_CLEAR; break;
1153 case XGL_LOGIC_OP_AND: logicop = GEN6_LOGICOP_AND; break;
1154 case XGL_LOGIC_OP_AND_REVERSE: logicop = GEN6_LOGICOP_AND_REVERSE; break;
1155 case XGL_LOGIC_OP_AND_INVERTED: logicop = GEN6_LOGICOP_AND_INVERTED; break;
1156 case XGL_LOGIC_OP_NOOP: logicop = GEN6_LOGICOP_NOOP; break;
1157 case XGL_LOGIC_OP_XOR: logicop = GEN6_LOGICOP_XOR; break;
1158 case XGL_LOGIC_OP_OR: logicop = GEN6_LOGICOP_OR; break;
1159 case XGL_LOGIC_OP_NOR: logicop = GEN6_LOGICOP_NOR; break;
1160 case XGL_LOGIC_OP_EQUIV: logicop = GEN6_LOGICOP_EQUIV; break;
1161 case XGL_LOGIC_OP_INVERT: logicop = GEN6_LOGICOP_INVERT; break;
1162 case XGL_LOGIC_OP_OR_REVERSE: logicop = GEN6_LOGICOP_OR_REVERSE; break;
1163 case XGL_LOGIC_OP_COPY_INVERTED: logicop = GEN6_LOGICOP_COPY_INVERTED; break;
1164 case XGL_LOGIC_OP_OR_INVERTED: logicop = GEN6_LOGICOP_OR_INVERTED; break;
1165 case XGL_LOGIC_OP_NAND: logicop = GEN6_LOGICOP_NAND; break;
1166 case XGL_LOGIC_OP_SET: logicop = GEN6_LOGICOP_SET; break;
1167 default:
1168 assert(!"unknown logic op");
1169 logicop = GEN6_LOGICOP_CLEAR;
1170 break;
1171 }
1172
1173 dw1 |= GEN6_BLEND_DW1_LOGICOP_ENABLE |
1174 logicop << GEN6_BLEND_DW1_LOGICOP_FUNC__SHIFT;
1175 }
1176
1177 if (!(att->channelWriteMask & 0x1))
1178 dw1 |= GEN6_BLEND_DW1_WRITE_DISABLE_R;
1179 if (!(att->channelWriteMask & 0x2))
1180 dw1 |= GEN6_BLEND_DW1_WRITE_DISABLE_G;
1181 if (!(att->channelWriteMask & 0x4))
1182 dw1 |= GEN6_BLEND_DW1_WRITE_DISABLE_B;
1183 if (!(att->channelWriteMask & 0x8))
1184 dw1 |= GEN6_BLEND_DW1_WRITE_DISABLE_A;
1185
1186 dw[2 * i] = dw0;
1187 dw[2 * i + 1] = dw1;
1188 }
1189
1190 for (i=info->cb.attachmentCount; i < INTEL_MAX_RENDER_TARGETS; i++)
1191 {
1192 dw[2 * i] = 0;
1193 dw[2 * i + 1] = GEN6_BLEND_DW1_COLORCLAMP_RTFORMAT |
1194 GEN6_BLEND_DW1_PRE_BLEND_CLAMP |
1195 GEN6_BLEND_DW1_POST_BLEND_CLAMP |
1196 GEN6_BLEND_DW1_WRITE_DISABLE_R |
1197 GEN6_BLEND_DW1_WRITE_DISABLE_G |
1198 GEN6_BLEND_DW1_WRITE_DISABLE_B |
1199 GEN6_BLEND_DW1_WRITE_DISABLE_A;
1200 }
1201
1202}
1203
1204
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001205static XGL_RESULT pipeline_build_all(struct intel_pipeline *pipeline,
1206 const struct intel_pipeline_create_info *info)
Chia-I Wu3efef432014-08-28 15:00:16 +08001207{
1208 XGL_RESULT ret;
1209
Chia-I Wu98824592014-09-02 09:42:46 +08001210 ret = pipeline_build_shaders(pipeline, info);
1211 if (ret != XGL_SUCCESS)
1212 return ret;
1213
Chia-I Wu1d125092014-10-08 08:49:38 +08001214 if (info->vi.bindingCount > ARRAY_SIZE(pipeline->vb) ||
1215 info->vi.attributeCount > ARRAY_SIZE(pipeline->vb))
1216 return XGL_ERROR_BAD_PIPELINE_DATA;
1217
1218 pipeline->vb_count = info->vi.bindingCount;
1219 memcpy(pipeline->vb, info->vi.pVertexBindingDescriptions,
1220 sizeof(pipeline->vb[0]) * pipeline->vb_count);
1221
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001222 pipeline_build_vertex_elements(pipeline, info);
GregF8cd81832014-11-18 18:01:01 -07001223 pipeline_build_fragment_SBE(pipeline);
Tony Barbourfa6cac72015-01-16 14:27:35 -07001224 pipeline_build_msaa(pipeline, info);
Chia-I Wu5bdb0962015-01-24 12:49:28 +08001225 pipeline_build_depth_stencil(pipeline, info);
Chia-I Wu4d9ad912014-08-29 14:20:36 +08001226
Chia-I Wu509b3f22014-09-02 10:24:05 +08001227 if (intel_gpu_gen(pipeline->dev->gpu) >= INTEL_GEN(7)) {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001228 pipeline_build_urb_alloc_gen7(pipeline, info);
1229 pipeline_build_push_const_alloc_gen7(pipeline, info);
1230 pipeline_build_gs(pipeline, info);
1231 pipeline_build_hs(pipeline, info);
1232 pipeline_build_te(pipeline, info);
1233 pipeline_build_ds(pipeline, info);
Chia-I Wu8370b402014-08-29 12:28:37 +08001234
1235 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
1236 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL |
1237 INTEL_CMD_WA_GEN7_PRE_VS_DEPTH_STALL_WRITE |
1238 INTEL_CMD_WA_GEN7_POST_COMMAND_CS_STALL |
1239 INTEL_CMD_WA_GEN7_POST_COMMAND_DEPTH_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001240 } else {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001241 pipeline_build_urb_alloc_gen6(pipeline, info);
Chia-I Wu8370b402014-08-29 12:28:37 +08001242
1243 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
1244 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +08001245 }
1246
Chia-I Wube0a3d92014-09-02 13:20:59 +08001247 ret = pipeline_build_ia(pipeline, info);
Chia-I Wu3efef432014-08-28 15:00:16 +08001248
1249 if (ret == XGL_SUCCESS)
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001250 ret = pipeline_rs_state(pipeline, &info->rs);
Chia-I Wu3efef432014-08-28 15:00:16 +08001251
Chia-I Wu3efef432014-08-28 15:00:16 +08001252 if (ret == XGL_SUCCESS) {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001253 pipeline->db_format = info->db.format;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001254 pipeline_build_cb(pipeline, info);
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001255 pipeline->cb_state = info->cb;
1256 pipeline->tess_state = info->tess;
Chia-I Wu3efef432014-08-28 15:00:16 +08001257 }
1258
Tony Barbourfa6cac72015-01-16 14:27:35 -07001259 pipeline->scissor_enable = info->vp.scissorEnable;
1260
Chia-I Wu3efef432014-08-28 15:00:16 +08001261 return ret;
1262}
1263
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001264struct intel_pipeline_create_info_header {
1265 XGL_STRUCTURE_TYPE struct_type;
1266 const struct intel_pipeline_create_info_header *next;
1267};
1268
1269static XGL_RESULT pipeline_create_info_init(struct intel_pipeline_create_info *info,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001270 const struct intel_pipeline_create_info_header *header)
Chia-I Wu3efef432014-08-28 15:00:16 +08001271{
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001272 memset(info, 0, sizeof(*info));
Chia-I Wu3efef432014-08-28 15:00:16 +08001273
Tony Barbourfa6cac72015-01-16 14:27:35 -07001274
1275 /*
1276 * Do we need to set safe defaults in case the app doesn't provide all of
1277 * the necessary create infos?
1278 */
1279 info->ms.samples = 1;
1280 info->ms.sampleMask = 1;
1281
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001282 while (header) {
1283 const void *src = (const void *) header;
Chia-I Wu3efef432014-08-28 15:00:16 +08001284 XGL_SIZE size;
1285 void *dst;
1286
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001287 switch (header->struct_type) {
Chia-I Wu3efef432014-08-28 15:00:16 +08001288 case XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001289 size = sizeof(info->graphics);
1290 dst = &info->graphics;
Chia-I Wu3efef432014-08-28 15:00:16 +08001291 break;
Chia-I Wu1d125092014-10-08 08:49:38 +08001292 case XGL_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO:
1293 size = sizeof(info->vi);
1294 dst = &info->vi;
1295 break;
Chia-I Wu3efef432014-08-28 15:00:16 +08001296 case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001297 size = sizeof(info->ia);
1298 dst = &info->ia;
Chia-I Wu3efef432014-08-28 15:00:16 +08001299 break;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001300 case XGL_STRUCTURE_TYPE_PIPELINE_DS_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001301 size = sizeof(info->db);
1302 dst = &info->db;
Chia-I Wu3efef432014-08-28 15:00:16 +08001303 break;
1304 case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001305 size = sizeof(info->cb);
1306 dst = &info->cb;
Chia-I Wu3efef432014-08-28 15:00:16 +08001307 break;
1308 case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001309 size = sizeof(info->rs);
1310 dst = &info->rs;
Chia-I Wu3efef432014-08-28 15:00:16 +08001311 break;
1312 case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001313 size = sizeof(info->tess);
1314 dst = &info->tess;
Chia-I Wu3efef432014-08-28 15:00:16 +08001315 break;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001316 case XGL_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO:
1317 size = sizeof(info->ms);
1318 dst = &info->ms;
1319 break;
1320 case XGL_STRUCTURE_TYPE_PIPELINE_VP_STATE_CREATE_INFO:
1321 size = sizeof(info->vp);
1322 dst = &info->vp;
1323 break;
Chia-I Wu3efef432014-08-28 15:00:16 +08001324 case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
1325 {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001326 const XGL_PIPELINE_SHADER *shader =
1327 (const XGL_PIPELINE_SHADER *) (header + 1);
Chia-I Wu3efef432014-08-28 15:00:16 +08001328
1329 src = (const void *) shader;
1330 size = sizeof(*shader);
1331
1332 switch (shader->stage) {
1333 case XGL_SHADER_STAGE_VERTEX:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001334 dst = &info->vs;
Chia-I Wu3efef432014-08-28 15:00:16 +08001335 break;
1336 case XGL_SHADER_STAGE_TESS_CONTROL:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001337 dst = &info->tcs;
Chia-I Wu3efef432014-08-28 15:00:16 +08001338 break;
1339 case XGL_SHADER_STAGE_TESS_EVALUATION:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001340 dst = &info->tes;
Chia-I Wu3efef432014-08-28 15:00:16 +08001341 break;
1342 case XGL_SHADER_STAGE_GEOMETRY:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001343 dst = &info->gs;
Chia-I Wu3efef432014-08-28 15:00:16 +08001344 break;
1345 case XGL_SHADER_STAGE_FRAGMENT:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001346 dst = &info->fs;
Chia-I Wu3efef432014-08-28 15:00:16 +08001347 break;
Chia-I Wu3efef432014-08-28 15:00:16 +08001348 default:
1349 return XGL_ERROR_BAD_PIPELINE_DATA;
1350 break;
1351 }
1352 }
1353 break;
1354 case XGL_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001355 size = sizeof(info->compute);
1356 dst = &info->compute;
Chia-I Wu3efef432014-08-28 15:00:16 +08001357 break;
1358 default:
1359 return XGL_ERROR_BAD_PIPELINE_DATA;
1360 break;
1361 }
1362
1363 memcpy(dst, src, size);
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001364 header = header->next;
Chia-I Wu3efef432014-08-28 15:00:16 +08001365 }
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001366
1367 return XGL_SUCCESS;
Chia-I Wu3efef432014-08-28 15:00:16 +08001368}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001369
Chia-I Wu3efef432014-08-28 15:00:16 +08001370static XGL_RESULT graphics_pipeline_create(struct intel_dev *dev,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001371 const XGL_GRAPHICS_PIPELINE_CREATE_INFO *info_,
Chia-I Wu3efef432014-08-28 15:00:16 +08001372 struct intel_pipeline **pipeline_ret)
1373{
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001374 struct intel_pipeline_create_info info;
Chia-I Wu3efef432014-08-28 15:00:16 +08001375 struct intel_pipeline *pipeline;
1376 XGL_RESULT ret;
1377
Chia-I Wu509b3f22014-09-02 10:24:05 +08001378 ret = pipeline_create_info_init(&info,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001379 (const struct intel_pipeline_create_info_header *) info_);
Chia-I Wu3efef432014-08-28 15:00:16 +08001380 if (ret != XGL_SUCCESS)
1381 return ret;
1382
1383 pipeline = (struct intel_pipeline *)
1384 intel_base_create(dev, sizeof(*pipeline), dev->base.dbg,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001385 XGL_DBG_OBJECT_GRAPHICS_PIPELINE, info_, 0);
Chia-I Wu3efef432014-08-28 15:00:16 +08001386 if (!pipeline)
1387 return XGL_ERROR_OUT_OF_MEMORY;
1388
1389 pipeline->dev = dev;
Chia-I Wub1024732014-12-19 13:00:29 +08001390 pipeline->obj.base.get_info = pipeline_get_info;
Chia-I Wu3efef432014-08-28 15:00:16 +08001391 pipeline->obj.destroy = pipeline_destroy;
Chia-I Wu3efef432014-08-28 15:00:16 +08001392
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001393 ret = pipeline_build_all(pipeline, &info);
Chia-I Wu3efef432014-08-28 15:00:16 +08001394 if (ret == XGL_SUCCESS)
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001395 ret = pipeline_validate(pipeline);
Chia-I Wu3efef432014-08-28 15:00:16 +08001396 if (ret != XGL_SUCCESS) {
1397 pipeline_destroy(&pipeline->obj);
1398 return ret;
1399 }
1400
1401 *pipeline_ret = pipeline;
1402
1403 return XGL_SUCCESS;
1404}
1405
Chia-I Wu96177272015-01-03 15:27:41 +08001406ICD_EXPORT XGL_RESULT XGLAPI xglCreateGraphicsPipeline(
Chia-I Wu3efef432014-08-28 15:00:16 +08001407 XGL_DEVICE device,
1408 const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
1409 XGL_PIPELINE* pPipeline)
1410{
1411 struct intel_dev *dev = intel_dev(device);
1412
1413 return graphics_pipeline_create(dev, pCreateInfo,
1414 (struct intel_pipeline **) pPipeline);
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001415}
1416
Chia-I Wu96177272015-01-03 15:27:41 +08001417ICD_EXPORT XGL_RESULT XGLAPI xglCreateComputePipeline(
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001418 XGL_DEVICE device,
1419 const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo,
1420 XGL_PIPELINE* pPipeline)
1421{
1422 return XGL_ERROR_UNAVAILABLE;
1423}
1424
Chia-I Wu96177272015-01-03 15:27:41 +08001425ICD_EXPORT XGL_RESULT XGLAPI xglStorePipeline(
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001426 XGL_PIPELINE pipeline,
1427 XGL_SIZE* pDataSize,
1428 XGL_VOID* pData)
1429{
1430 return XGL_ERROR_UNAVAILABLE;
1431}
1432
Chia-I Wu96177272015-01-03 15:27:41 +08001433ICD_EXPORT XGL_RESULT XGLAPI xglLoadPipeline(
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001434 XGL_DEVICE device,
1435 XGL_SIZE dataSize,
1436 const XGL_VOID* pData,
1437 XGL_PIPELINE* pPipeline)
1438{
1439 return XGL_ERROR_UNAVAILABLE;
1440}
1441
Chia-I Wu96177272015-01-03 15:27:41 +08001442ICD_EXPORT XGL_RESULT XGLAPI xglCreatePipelineDelta(
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001443 XGL_DEVICE device,
1444 XGL_PIPELINE p1,
1445 XGL_PIPELINE p2,
1446 XGL_PIPELINE_DELTA* delta)
1447{
1448 return XGL_ERROR_UNAVAILABLE;
1449}