blob: 0a9997ec4b02bb6ea1922974cdce69b4b86d5574 [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 Wu8370b402014-08-29 12:28:37 +080030#include "cmd.h"
Chia-I Wu1d125092014-10-08 08:49:38 +080031#include "format.h"
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -060032#include "shader.h"
Chia-I Wued833872014-08-23 17:00:35 +080033#include "pipeline_priv.h"
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060034
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -060035static uint32_t *pipeline_cmd_ptr(struct intel_pipeline *pipeline, int cmd_len)
36{
37 uint32_t *ptr;
38
39 assert(pipeline->cmd_len + cmd_len < INTEL_PSO_CMD_ENTRIES);
40 ptr = &pipeline->cmds[pipeline->cmd_len];
41 pipeline->cmd_len += cmd_len;
42 return ptr;
43}
44
Chia-I Wube0a3d92014-09-02 13:20:59 +080045static XGL_RESULT pipeline_build_ia(struct intel_pipeline *pipeline,
46 const struct intel_pipeline_create_info* info)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060047{
Chia-I Wube0a3d92014-09-02 13:20:59 +080048 pipeline->topology = info->ia.topology;
49 pipeline->disable_vs_cache = info->ia.disableVertexReuse;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -060050
Chia-I Wube0a3d92014-09-02 13:20:59 +080051 if (info->ia.provokingVertex == XGL_PROVOKING_VERTEX_FIRST) {
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060052 pipeline->provoking_vertex_tri = 0;
53 pipeline->provoking_vertex_trifan = 1;
54 pipeline->provoking_vertex_line = 0;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060055 } else {
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060056 pipeline->provoking_vertex_tri = 2;
57 pipeline->provoking_vertex_trifan = 2;
58 pipeline->provoking_vertex_line = 1;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060059 }
60
Chia-I Wube0a3d92014-09-02 13:20:59 +080061 switch (info->ia.topology) {
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060062 case XGL_TOPOLOGY_POINT_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060063 pipeline->prim_type = GEN6_3DPRIM_POINTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060064 break;
65 case XGL_TOPOLOGY_LINE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060066 pipeline->prim_type = GEN6_3DPRIM_LINELIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060067 break;
68 case XGL_TOPOLOGY_LINE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060069 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060070 break;
71 case XGL_TOPOLOGY_TRIANGLE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060072 pipeline->prim_type = GEN6_3DPRIM_TRILIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060073 break;
74 case XGL_TOPOLOGY_TRIANGLE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060075 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060076 break;
77 case XGL_TOPOLOGY_RECT_LIST:
78 /*
79 * TODO: Rect lists are special in XGL, do we need to do
80 * something special here?
81 * XGL Guide:
82 * The rectangle list is a special geometry primitive type
83 * that can be used for implementing post-processing techniques
84 * or efficient copy operations. There are some special limitations
85 * for rectangle primitives. They cannot be clipped, must
86 * be axis aligned and cannot have depth gradient.
87 * Failure to comply with these restrictions results in
88 * undefined rendering results.
89 */
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060090 pipeline->prim_type = GEN6_3DPRIM_RECTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060091 break;
92 case XGL_TOPOLOGY_QUAD_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060093 pipeline->prim_type = GEN6_3DPRIM_QUADLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060094 break;
95 case XGL_TOPOLOGY_QUAD_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060096 pipeline->prim_type = GEN6_3DPRIM_QUADSTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060097 break;
98 case XGL_TOPOLOGY_LINE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060099 pipeline->prim_type = GEN6_3DPRIM_LINELIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600100 break;
101 case XGL_TOPOLOGY_LINE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600102 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600103 break;
104 case XGL_TOPOLOGY_TRIANGLE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600105 pipeline->prim_type = GEN6_3DPRIM_TRILIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600106 break;
107 case XGL_TOPOLOGY_TRIANGLE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600108 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600109 break;
110 case XGL_TOPOLOGY_PATCH:
Chia-I Wube0a3d92014-09-02 13:20:59 +0800111 if (!info->tess.patchControlPoints ||
112 info->tess.patchControlPoints > 32)
113 return XGL_ERROR_BAD_PIPELINE_DATA;
114 pipeline->prim_type = GEN7_3DPRIM_PATCHLIST_1 +
115 info->tess.patchControlPoints - 1;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600116 break;
117 default:
118 return XGL_ERROR_BAD_PIPELINE_DATA;
119 }
120
Chia-I Wube0a3d92014-09-02 13:20:59 +0800121 if (info->ia.primitiveRestartEnable) {
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600122 pipeline->primitive_restart = true;
Chia-I Wube0a3d92014-09-02 13:20:59 +0800123 pipeline->primitive_restart_index = info->ia.primitiveRestartIndex;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600124 } else {
125 pipeline->primitive_restart = false;
126 }
127
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600128 return XGL_SUCCESS;
129}
130
Chia-I Wu3efef432014-08-28 15:00:16 +0800131static XGL_RESULT pipeline_rs_state(struct intel_pipeline *pipeline,
132 const XGL_PIPELINE_RS_STATE_CREATE_INFO* rs_state)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600133{
134 pipeline->depthClipEnable = rs_state->depthClipEnable;
135 pipeline->rasterizerDiscardEnable = rs_state->rasterizerDiscardEnable;
136 pipeline->pointSize = rs_state->pointSize;
137 return XGL_SUCCESS;
138}
139
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600140static void pipeline_destroy(struct intel_obj *obj)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600141{
142 struct intel_pipeline *pipeline = intel_pipeline_from_obj(obj);
143
Chia-I Wu98824592014-09-02 09:42:46 +0800144 pipeline_tear_shaders(pipeline);
Chia-I Wued833872014-08-23 17:00:35 +0800145
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600146 intel_base_destroy(&pipeline->obj.base);
147}
148
Chia-I Wub1024732014-12-19 13:00:29 +0800149static XGL_RESULT pipeline_get_info(struct intel_base *base, int type,
150 XGL_SIZE *size, XGL_VOID *data)
151{
152 struct intel_pipeline *pipeline = intel_pipeline_from_base(base);
153 XGL_RESULT ret = XGL_SUCCESS;
154
155 switch (type) {
156 case XGL_INFO_TYPE_MEMORY_REQUIREMENTS:
157 {
158 XGL_MEMORY_REQUIREMENTS *mem_req = data;
159
160 *size = sizeof(XGL_MEMORY_REQUIREMENTS);
161 if (data) {
162 mem_req->size = pipeline->scratch_size;
163 mem_req->alignment = 1024;
164 mem_req->heapCount = 1;
165 mem_req->heaps[0] = 0;
166 }
167 }
168 break;
169 default:
170 ret = intel_base_get_info(base, type, size, data);
171 break;
172 }
173
174 return ret;
175}
176
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800177static XGL_RESULT pipeline_validate(struct intel_pipeline *pipeline)
Chia-I Wu3efef432014-08-28 15:00:16 +0800178{
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600179 /*
180 * Validate required elements
181 */
182 if (!(pipeline->active_shaders & SHADER_VERTEX_FLAG)) {
183 // TODO: Log debug message: Vertex Shader required.
Chia-I Wu3efef432014-08-28 15:00:16 +0800184 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600185 }
186
187 /*
188 * Tessalation control and evaluation have to both have a shader defined or
189 * neither should have a shader defined.
190 */
191 if (((pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) == 0) !=
192 ((pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) == 0) ) {
193 // TODO: Log debug message: Both Tess control and Tess eval are required to use tessalation
Chia-I Wu3efef432014-08-28 15:00:16 +0800194 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600195 }
196
197 if ((pipeline->active_shaders & SHADER_COMPUTE_FLAG) &&
198 (pipeline->active_shaders & (SHADER_VERTEX_FLAG | SHADER_TESS_CONTROL_FLAG |
199 SHADER_TESS_EVAL_FLAG | SHADER_GEOMETRY_FLAG |
200 SHADER_FRAGMENT_FLAG))) {
201 // TODO: Log debug message: Can only specify compute shader when doing compute
Chia-I Wu3efef432014-08-28 15:00:16 +0800202 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600203 }
204
205 /*
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600206 * XGL_TOPOLOGY_PATCH primitive topology is only valid for tessellation pipelines.
207 * Mismatching primitive topology and tessellation fails graphics pipeline creation.
208 */
209 if (pipeline->active_shaders & (SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG) &&
Chia-I Wube0a3d92014-09-02 13:20:59 +0800210 (pipeline->topology != XGL_TOPOLOGY_PATCH)) {
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600211 // TODO: Log debug message: Invalid topology used with tessalation shader.
Chia-I Wu3efef432014-08-28 15:00:16 +0800212 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600213 }
214
Chia-I Wube0a3d92014-09-02 13:20:59 +0800215 if ((pipeline->topology == XGL_TOPOLOGY_PATCH) &&
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600216 (pipeline->active_shaders & ~(SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG))) {
217 // TODO: Log debug message: Cannot use TOPOLOGY_PATCH on non-tessalation shader.
Chia-I Wu3efef432014-08-28 15:00:16 +0800218 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600219 }
220
Chia-I Wu3efef432014-08-28 15:00:16 +0800221 return XGL_SUCCESS;
222}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600223
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800224static void pipeline_build_urb_alloc_gen6(struct intel_pipeline *pipeline,
225 const struct intel_pipeline_create_info *info)
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800226{
Chia-I Wu509b3f22014-09-02 10:24:05 +0800227 const struct intel_gpu *gpu = pipeline->dev->gpu;
228 const int urb_size = ((gpu->gt == 2) ? 64 : 32) * 1024;
Chia-I Wua4d1b392014-10-10 13:57:29 +0800229 const struct intel_pipeline_shader *vs = &pipeline->vs;
230 const struct intel_pipeline_shader *gs = &pipeline->gs;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800231 int vs_entry_size, gs_entry_size;
232 int vs_size, gs_size;
233
Chia-I Wu509b3f22014-09-02 10:24:05 +0800234 INTEL_GPU_ASSERT(gpu, 6, 6);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800235
236 vs_entry_size = ((vs->in_count >= vs->out_count) ?
237 vs->in_count : vs->out_count);
238 gs_entry_size = (gs) ? gs->out_count : 0;
239
240 /* in bytes */
241 vs_entry_size *= sizeof(float) * 4;
242 gs_entry_size *= sizeof(float) * 4;
243
Chia-I Wua4d1b392014-10-10 13:57:29 +0800244 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800245 vs_size = urb_size / 2;
246 gs_size = vs_size;
247 } else {
248 vs_size = urb_size;
249 gs_size = 0;
250 }
251
252 /* 3DSTATE_URB */
253 {
254 const uint8_t cmd_len = 3;
255 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_URB) |
256 (cmd_len - 2);
257 int vs_alloc_size, gs_alloc_size;
258 int vs_entry_count, gs_entry_count;
259 uint32_t *dw;
260
261 /* in 1024-bit rows */
262 vs_alloc_size = (vs_entry_size + 128 - 1) / 128;
263 gs_alloc_size = (gs_entry_size + 128 - 1) / 128;
264
265 /* valid range is [1, 5] */
266 if (!vs_alloc_size)
267 vs_alloc_size = 1;
268 if (!gs_alloc_size)
269 gs_alloc_size = 1;
270 assert(vs_alloc_size <= 5 && gs_alloc_size <= 5);
271
272 /* valid range is [24, 256], multiples of 4 */
273 vs_entry_count = (vs_size / 128 / vs_alloc_size) & ~3;
274 if (vs_entry_count > 256)
275 vs_entry_count = 256;
276 assert(vs_entry_count >= 24);
277
278 /* valid range is [0, 256], multiples of 4 */
279 gs_entry_count = (gs_size / 128 / gs_alloc_size) & ~3;
280 if (gs_entry_count > 256)
281 gs_entry_count = 256;
282
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600283 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800284
285 dw[0] = dw0;
286 dw[1] = (vs_alloc_size - 1) << GEN6_URB_DW1_VS_ENTRY_SIZE__SHIFT |
287 vs_entry_count << GEN6_URB_DW1_VS_ENTRY_COUNT__SHIFT;
288 dw[2] = gs_entry_count << GEN6_URB_DW2_GS_ENTRY_COUNT__SHIFT |
289 (gs_alloc_size - 1) << GEN6_URB_DW2_GS_ENTRY_SIZE__SHIFT;
290 }
291}
292
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800293static void pipeline_build_urb_alloc_gen7(struct intel_pipeline *pipeline,
294 const struct intel_pipeline_create_info *info)
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800295{
Chia-I Wu509b3f22014-09-02 10:24:05 +0800296 const struct intel_gpu *gpu = pipeline->dev->gpu;
297 const int urb_size = ((gpu->gt == 3) ? 512 :
298 (gpu->gt == 2) ? 256 : 128) * 1024;
Cody Northrop306ec352014-10-06 15:11:45 -0600299 const struct intel_pipeline_shader *vs = &pipeline->vs;
300 const struct intel_pipeline_shader *gs = &pipeline->gs;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800301 /* some space is reserved for PCBs */
Chia-I Wu509b3f22014-09-02 10:24:05 +0800302 int urb_offset = ((gpu->gt == 3) ? 32 : 16) * 1024;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800303 int vs_entry_size, gs_entry_size;
304 int vs_size, gs_size;
305
Chia-I Wu509b3f22014-09-02 10:24:05 +0800306 INTEL_GPU_ASSERT(gpu, 7, 7.5);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800307
308 vs_entry_size = ((vs->in_count >= vs->out_count) ?
309 vs->in_count : vs->out_count);
310 gs_entry_size = (gs) ? gs->out_count : 0;
311
312 /* in bytes */
313 vs_entry_size *= sizeof(float) * 4;
314 gs_entry_size *= sizeof(float) * 4;
315
Chia-I Wua4d1b392014-10-10 13:57:29 +0800316 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800317 vs_size = (urb_size - urb_offset) / 2;
318 gs_size = vs_size;
319 } else {
320 vs_size = urb_size - urb_offset;
321 gs_size = 0;
322 }
323
324 /* 3DSTATE_URB_* */
325 {
326 const uint8_t cmd_len = 2;
327 int vs_alloc_size, gs_alloc_size;
328 int vs_entry_count, gs_entry_count;
329 uint32_t *dw;
330
331 /* in 512-bit rows */
332 vs_alloc_size = (vs_entry_size + 64 - 1) / 64;
333 gs_alloc_size = (gs_entry_size + 64 - 1) / 64;
334
335 if (!vs_alloc_size)
336 vs_alloc_size = 1;
337 if (!gs_alloc_size)
338 gs_alloc_size = 1;
339
340 /* avoid performance decrease due to banking */
341 if (vs_alloc_size == 5)
342 vs_alloc_size = 6;
343
344 /* in multiples of 8 */
345 vs_entry_count = (vs_size / 64 / vs_alloc_size) & ~7;
346 assert(vs_entry_count >= 32);
347
348 gs_entry_count = (gs_size / 64 / gs_alloc_size) & ~7;
349
Chia-I Wu509b3f22014-09-02 10:24:05 +0800350 if (intel_gpu_gen(gpu) >= INTEL_GEN(7.5)) {
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800351 const int max_vs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800352 (gpu->gt >= 2) ? 1664 : 640;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800353 const int max_gs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800354 (gpu->gt >= 2) ? 640 : 256;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800355 if (vs_entry_count >= max_vs_entry_count)
356 vs_entry_count = max_vs_entry_count;
357 if (gs_entry_count >= max_gs_entry_count)
358 gs_entry_count = max_gs_entry_count;
359 } else {
360 const int max_vs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800361 (gpu->gt == 2) ? 704 : 512;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800362 const int max_gs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800363 (gpu->gt == 2) ? 320 : 192;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800364 if (vs_entry_count >= max_vs_entry_count)
365 vs_entry_count = max_vs_entry_count;
366 if (gs_entry_count >= max_gs_entry_count)
367 gs_entry_count = max_gs_entry_count;
368 }
369
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600370 dw = pipeline_cmd_ptr(pipeline, cmd_len*4);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800371 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_VS) | (cmd_len - 2);
372 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT |
373 (vs_alloc_size - 1) << GEN7_URB_ANY_DW1_ENTRY_SIZE__SHIFT |
374 vs_entry_count;
375
376 dw += 2;
377 if (gs_size)
378 urb_offset += vs_size;
379 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_GS) | (cmd_len - 2);
380 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT |
381 (gs_alloc_size - 1) << GEN7_URB_ANY_DW1_ENTRY_SIZE__SHIFT |
382 gs_entry_count;
383
384 dw += 2;
385 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_HS) | (cmd_len - 2);
386 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT;
387
388 dw += 2;
389 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_DS) | (cmd_len - 2);
390 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT;
391 }
392}
393
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800394static void pipeline_build_push_const_alloc_gen7(struct intel_pipeline *pipeline,
395 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600396{
397 const uint8_t cmd_len = 2;
398 uint32_t offset = 0;
399 uint32_t size = 8192;
400 uint32_t *dw;
401 int end;
402
Chia-I Wu509b3f22014-09-02 10:24:05 +0800403 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600404
405 /*
406 * From the Ivy Bridge PRM, volume 2 part 1, page 68:
407 *
408 * "(A table that says the maximum size of each constant buffer is
409 * 16KB")
410 *
411 * From the Ivy Bridge PRM, volume 2 part 1, page 115:
412 *
413 * "The sum of the Constant Buffer Offset and the Constant Buffer Size
414 * may not exceed the maximum value of the Constant Buffer Size."
415 *
416 * Thus, the valid range of buffer end is [0KB, 16KB].
417 */
418 end = (offset + size) / 1024;
419 if (end > 16) {
420 assert(!"invalid constant buffer end");
421 end = 16;
422 }
423
424 /* the valid range of buffer offset is [0KB, 15KB] */
425 offset = (offset + 1023) / 1024;
426 if (offset > 15) {
427 assert(!"invalid constant buffer offset");
428 offset = 15;
429 }
430
431 if (offset > end) {
432 assert(!size);
433 offset = end;
434 }
435
436 /* the valid range of buffer size is [0KB, 15KB] */
437 size = end - offset;
438 if (size > 15) {
439 assert(!"invalid constant buffer size");
440 size = 15;
441 }
442
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800443 dw = pipeline_cmd_ptr(pipeline, cmd_len * 5);
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600444 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_VS) | (cmd_len - 2);
445 dw[1] = offset << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
446 size << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
447
448 dw += 2;
449 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_PS) | (cmd_len - 2);
450 dw[1] = size << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
451 size << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
452
453 dw += 2;
454 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_HS) | (cmd_len - 2);
455 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
456 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
457
458 dw += 2;
459 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_DS) | (cmd_len - 2);
460 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
461 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
462
463 dw += 2;
464 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_GS) | (cmd_len - 2);
465 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
466 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
Chia-I Wu8370b402014-08-29 12:28:37 +0800467
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600468 // gen7_wa_pipe_control_cs_stall(p, true, true);
469 // looks equivalent to: gen6_wa_wm_multisample_flush - this does more
470 // than the documentation seems to imply
471}
472
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800473static void pipeline_build_vertex_elements(struct intel_pipeline *pipeline,
474 const struct intel_pipeline_create_info *info)
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800475{
Cody Northrop306ec352014-10-06 15:11:45 -0600476 const struct intel_pipeline_shader *vs = &pipeline->vs;
Chia-I Wu1d125092014-10-08 08:49:38 +0800477 uint8_t cmd_len;
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800478 uint32_t *dw;
Chia-I Wu1d125092014-10-08 08:49:38 +0800479 XGL_UINT i;
480 int comps[4];
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800481
Chia-I Wu509b3f22014-09-02 10:24:05 +0800482 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800483
GregF8cd81832014-11-18 18:01:01 -0700484 cmd_len = 1 + 2 * u_popcountll(vs->inputs_read);
Chia-I Wu1d125092014-10-08 08:49:38 +0800485 if (vs->uses & (INTEL_SHADER_USE_VID | INTEL_SHADER_USE_IID))
486 cmd_len += 2;
487
488 if (cmd_len == 1)
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800489 return;
490
491 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Chia-I Wu1d125092014-10-08 08:49:38 +0800492
493 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_ELEMENTS) |
494 (cmd_len - 2);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800495 dw++;
496
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800497 /* VERTEX_ELEMENT_STATE */
Chia-I Wu1d125092014-10-08 08:49:38 +0800498 for (i = 0; i < info->vi.attributeCount; i++) {
GregF8cd81832014-11-18 18:01:01 -0700499 if (!(vs->inputs_read & (1L << i)))
GregF2dc40212014-10-31 17:31:47 -0600500 continue;
Chia-I Wu1d125092014-10-08 08:49:38 +0800501 const XGL_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION *attr =
502 &info->vi.pVertexAttributeDescriptions[i];
503 const int format =
504 intel_format_translate_color(pipeline->dev->gpu, attr->format);
505
506 comps[0] = GEN6_VFCOMP_STORE_0;
507 comps[1] = GEN6_VFCOMP_STORE_0;
508 comps[2] = GEN6_VFCOMP_STORE_0;
509 comps[3] = icd_format_is_int(attr->format) ?
510 GEN6_VFCOMP_STORE_1_INT : GEN6_VFCOMP_STORE_1_FP;
511
512 switch (icd_format_get_channel_count(attr->format)) {
513 case 4: comps[3] = GEN6_VFCOMP_STORE_SRC; /* fall through */
514 case 3: comps[2] = GEN6_VFCOMP_STORE_SRC; /* fall through */
515 case 2: comps[1] = GEN6_VFCOMP_STORE_SRC; /* fall through */
516 case 1: comps[0] = GEN6_VFCOMP_STORE_SRC; break;
517 default:
518 break;
519 }
520
521 assert(attr->offsetInBytes <= 2047);
522
523 dw[0] = attr->binding << GEN6_VE_STATE_DW0_VB_INDEX__SHIFT |
524 GEN6_VE_STATE_DW0_VALID |
525 format << GEN6_VE_STATE_DW0_FORMAT__SHIFT |
526 attr->offsetInBytes;
527
528 dw[1] = comps[0] << GEN6_VE_STATE_DW1_COMP0__SHIFT |
529 comps[1] << GEN6_VE_STATE_DW1_COMP1__SHIFT |
530 comps[2] << GEN6_VE_STATE_DW1_COMP2__SHIFT |
531 comps[3] << GEN6_VE_STATE_DW1_COMP3__SHIFT;
532
533 dw += 2;
534 }
GregF932fcf52014-10-29 17:02:11 -0600535
536 if (vs->uses & (INTEL_SHADER_USE_VID | INTEL_SHADER_USE_IID)) {
537 comps[0] = (vs->uses & INTEL_SHADER_USE_VID) ?
538 GEN6_VFCOMP_STORE_VID : GEN6_VFCOMP_STORE_0;
539 comps[1] = (vs->uses & INTEL_SHADER_USE_IID) ?
540 GEN6_VFCOMP_STORE_IID : GEN6_VFCOMP_NOSTORE;
541 comps[2] = GEN6_VFCOMP_NOSTORE;
542 comps[3] = GEN6_VFCOMP_NOSTORE;
543
544 dw[0] = GEN6_VE_STATE_DW0_VALID;
545 dw[1] = comps[0] << GEN6_VE_STATE_DW1_COMP0__SHIFT |
546 comps[1] << GEN6_VE_STATE_DW1_COMP1__SHIFT |
547 comps[2] << GEN6_VE_STATE_DW1_COMP2__SHIFT |
548 comps[3] << GEN6_VE_STATE_DW1_COMP3__SHIFT;
549
550 dw += 2;
551 }
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800552}
553
GregF8cd81832014-11-18 18:01:01 -0700554static void pipeline_build_fragment_SBE(struct intel_pipeline *pipeline)
555{
556 const struct intel_pipeline_shader *fs = &pipeline->fs;
557 const struct intel_pipeline_shader *vs = &pipeline->vs;
558 uint8_t cmd_len;
559 uint32_t *body;
560 XGL_UINT attr_skip, attr_count;
561 XGL_UINT vue_offset, vue_len;
562 XGL_UINT i;
563
564 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
565
566 cmd_len = 14;
567
568 body = pipeline_cmd_ptr(pipeline, cmd_len);
569 pipeline->cmd_sbe_body_offset = body - pipeline->cmds + 1;
570
571 /* VS outputs VUE header and position additionally */
572 assert(vs->out_count >= fs->in_count + 2);
573 assert(!fs->reads_user_clip || vs->enable_user_clip);
574 attr_skip = vs->outputs_offset;
575 if (vs->enable_user_clip != fs->reads_user_clip) {
576 attr_skip += 2;
577 }
578 assert(vs->out_count >= attr_skip);
579 attr_count = vs->out_count - attr_skip;
580
581 // LUNARG TODO: We currently are only handling 16 attrs;
582 // ultimately, we need to handle 32
583 assert(fs->in_count <= 16);
584 assert(attr_count <= 16);
585
586 vue_offset = attr_skip / 2;
587 vue_len = (attr_count + 1) / 2;
588 if (!vue_len)
589 vue_len = 1;
590
591 body[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SBE) |
592 (cmd_len - 2);
593
594 // LUNARG TODO: If the attrs needed by the FS are exactly
595 // what is written by the VS, we don't need to enable
596 // swizzling, improving performance. Even if we swizzle,
597 // we can improve performance by reducing vue_len to
598 // just include the values needed by the FS:
599 // vue_len = ceiling((max_vs_out + 1)/2)
600
601 body[1] = GEN7_SBE_DW1_ATTR_SWIZZLE_ENABLE |
602 fs->in_count << GEN7_SBE_DW1_ATTR_COUNT__SHIFT |
603 vue_len << GEN7_SBE_DW1_URB_READ_LEN__SHIFT |
604 vue_offset << GEN7_SBE_DW1_URB_READ_OFFSET__SHIFT;
605
606 uint16_t vs_slot[fs->in_count];
607 XGL_INT fs_in = 0;
608 XGL_INT vs_out = - (vue_offset * 2 - vs->outputs_offset);
609 for (i=0; i < 64; i++) {
Cody Northropd75c13e2015-01-02 14:07:20 -0700610 bool vsWrites = vs->outputs_written & (1L << i);
611 bool fsReads = fs->inputs_read & (1L << i);
612
613 if (fsReads) {
GregF8cd81832014-11-18 18:01:01 -0700614 assert(vs_out >= 0);
615 assert(fs_in < fs->in_count);
616 vs_slot[fs_in] = vs_out;
Cody Northropd75c13e2015-01-02 14:07:20 -0700617
618 if (!vsWrites) {
619 // If the vertex shader did not write this input, we cannot
620 // program the SBE to read it. Our choices are to allow it to
621 // read junk from a GRF, or get zero. We're choosing zero.
622 if (i >= fs->generic_input_start) {
623 vs_slot[fs_in] = GEN7_SBE_ATTR_CONST_0000 |
624 GEN7_SBE_ATTR_OVERRIDE_X |
625 GEN7_SBE_ATTR_OVERRIDE_Y |
626 GEN7_SBE_ATTR_OVERRIDE_Z |
627 GEN7_SBE_ATTR_OVERRIDE_W;
628 }
629 }
630
GregF8cd81832014-11-18 18:01:01 -0700631 fs_in += 1;
632 }
Cody Northropd75c13e2015-01-02 14:07:20 -0700633 if (vsWrites) {
GregF8cd81832014-11-18 18:01:01 -0700634 vs_out += 1;
635 }
636 }
637
638 for (i = 0; i < 8; i++) {
639 uint16_t hi, lo;
640
641 /* no attr swizzles */
642 if (i * 2 + 1 < fs->in_count) {
643 lo = vs_slot[i * 2];
644 hi = vs_slot[i * 2 + 1];
645 } else if (i * 2 < fs->in_count) {
646 lo = vs_slot[i * 2];
647 hi = 0;
648 } else {
649 hi = 0;
650 lo = 0;
651 }
652
653 body[2 + i] = hi << GEN7_SBE_ATTR_HIGH__SHIFT | lo;
654 }
655
656 body[10] = 0; /* point sprite enables */
657 body[11] = 0; /* constant interpolation enables */
658 body[12] = 0; /* WrapShortest enables */
659 body[13] = 0;
660}
661
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800662static void pipeline_build_gs(struct intel_pipeline *pipeline,
663 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600664{
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600665 // gen7_emit_3DSTATE_GS done by cmd_pipeline
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600666}
667
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800668static void pipeline_build_hs(struct intel_pipeline *pipeline,
669 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600670{
671 const uint8_t cmd_len = 7;
672 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
673 uint32_t *dw;
674
Chia-I Wu509b3f22014-09-02 10:24:05 +0800675 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600676
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800677 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600678 dw[0] = dw0;
679 dw[1] = 0;
680 dw[2] = 0;
681 dw[3] = 0;
682 dw[4] = 0;
683 dw[5] = 0;
684 dw[6] = 0;
685}
686
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800687static void pipeline_build_te(struct intel_pipeline *pipeline,
688 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600689{
690 const uint8_t cmd_len = 4;
691 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_TE) | (cmd_len - 2);
692 uint32_t *dw;
693
Chia-I Wu509b3f22014-09-02 10:24:05 +0800694 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600695
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800696 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600697 dw[0] = dw0;
698 dw[1] = 0;
699 dw[2] = 0;
700 dw[3] = 0;
701}
702
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800703static void pipeline_build_ds(struct intel_pipeline *pipeline,
704 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600705{
706 const uint8_t cmd_len = 6;
707 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
708 uint32_t *dw;
709
Chia-I Wu509b3f22014-09-02 10:24:05 +0800710 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600711
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800712 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600713 dw[0] = dw0;
714 dw[1] = 0;
715 dw[2] = 0;
716 dw[3] = 0;
717 dw[4] = 0;
718 dw[5] = 0;
719}
720
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800721static XGL_RESULT pipeline_build_all(struct intel_pipeline *pipeline,
722 const struct intel_pipeline_create_info *info)
Chia-I Wu3efef432014-08-28 15:00:16 +0800723{
724 XGL_RESULT ret;
725
Chia-I Wu98824592014-09-02 09:42:46 +0800726 ret = pipeline_build_shaders(pipeline, info);
727 if (ret != XGL_SUCCESS)
728 return ret;
729
Chia-I Wu1d125092014-10-08 08:49:38 +0800730 if (info->vi.bindingCount > ARRAY_SIZE(pipeline->vb) ||
731 info->vi.attributeCount > ARRAY_SIZE(pipeline->vb))
732 return XGL_ERROR_BAD_PIPELINE_DATA;
733
734 pipeline->vb_count = info->vi.bindingCount;
735 memcpy(pipeline->vb, info->vi.pVertexBindingDescriptions,
736 sizeof(pipeline->vb[0]) * pipeline->vb_count);
737
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800738 pipeline_build_vertex_elements(pipeline, info);
GregF8cd81832014-11-18 18:01:01 -0700739 pipeline_build_fragment_SBE(pipeline);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800740
Chia-I Wu509b3f22014-09-02 10:24:05 +0800741 if (intel_gpu_gen(pipeline->dev->gpu) >= INTEL_GEN(7)) {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800742 pipeline_build_urb_alloc_gen7(pipeline, info);
743 pipeline_build_push_const_alloc_gen7(pipeline, info);
744 pipeline_build_gs(pipeline, info);
745 pipeline_build_hs(pipeline, info);
746 pipeline_build_te(pipeline, info);
747 pipeline_build_ds(pipeline, info);
Chia-I Wu8370b402014-08-29 12:28:37 +0800748
749 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
750 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL |
751 INTEL_CMD_WA_GEN7_PRE_VS_DEPTH_STALL_WRITE |
752 INTEL_CMD_WA_GEN7_POST_COMMAND_CS_STALL |
753 INTEL_CMD_WA_GEN7_POST_COMMAND_DEPTH_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800754 } else {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800755 pipeline_build_urb_alloc_gen6(pipeline, info);
Chia-I Wu8370b402014-08-29 12:28:37 +0800756
757 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
758 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800759 }
760
Chia-I Wube0a3d92014-09-02 13:20:59 +0800761 ret = pipeline_build_ia(pipeline, info);
Chia-I Wu3efef432014-08-28 15:00:16 +0800762
763 if (ret == XGL_SUCCESS)
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800764 ret = pipeline_rs_state(pipeline, &info->rs);
Chia-I Wu3efef432014-08-28 15:00:16 +0800765
Chia-I Wu3efef432014-08-28 15:00:16 +0800766 if (ret == XGL_SUCCESS) {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800767 pipeline->db_format = info->db.format;
768 pipeline->cb_state = info->cb;
769 pipeline->tess_state = info->tess;
Chia-I Wu3efef432014-08-28 15:00:16 +0800770 }
771
772 return ret;
773}
774
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800775struct intel_pipeline_create_info_header {
776 XGL_STRUCTURE_TYPE struct_type;
777 const struct intel_pipeline_create_info_header *next;
778};
779
780static XGL_RESULT pipeline_create_info_init(struct intel_pipeline_create_info *info,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800781 const struct intel_pipeline_create_info_header *header)
Chia-I Wu3efef432014-08-28 15:00:16 +0800782{
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800783 memset(info, 0, sizeof(*info));
Chia-I Wu3efef432014-08-28 15:00:16 +0800784
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800785 while (header) {
786 const void *src = (const void *) header;
Chia-I Wu3efef432014-08-28 15:00:16 +0800787 XGL_SIZE size;
788 void *dst;
789
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800790 switch (header->struct_type) {
Chia-I Wu3efef432014-08-28 15:00:16 +0800791 case XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800792 size = sizeof(info->graphics);
793 dst = &info->graphics;
Chia-I Wu3efef432014-08-28 15:00:16 +0800794 break;
Chia-I Wu1d125092014-10-08 08:49:38 +0800795 case XGL_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO:
796 size = sizeof(info->vi);
797 dst = &info->vi;
798 break;
Chia-I Wu3efef432014-08-28 15:00:16 +0800799 case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800800 size = sizeof(info->ia);
801 dst = &info->ia;
Chia-I Wu3efef432014-08-28 15:00:16 +0800802 break;
803 case XGL_STRUCTURE_TYPE_PIPELINE_DB_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800804 size = sizeof(info->db);
805 dst = &info->db;
Chia-I Wu3efef432014-08-28 15:00:16 +0800806 break;
807 case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800808 size = sizeof(info->cb);
809 dst = &info->cb;
Chia-I Wu3efef432014-08-28 15:00:16 +0800810 break;
811 case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800812 size = sizeof(info->rs);
813 dst = &info->rs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800814 break;
815 case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800816 size = sizeof(info->tess);
817 dst = &info->tess;
Chia-I Wu3efef432014-08-28 15:00:16 +0800818 break;
819 case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
820 {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800821 const XGL_PIPELINE_SHADER *shader =
822 (const XGL_PIPELINE_SHADER *) (header + 1);
Chia-I Wu3efef432014-08-28 15:00:16 +0800823
824 src = (const void *) shader;
825 size = sizeof(*shader);
826
827 switch (shader->stage) {
828 case XGL_SHADER_STAGE_VERTEX:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800829 dst = &info->vs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800830 break;
831 case XGL_SHADER_STAGE_TESS_CONTROL:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800832 dst = &info->tcs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800833 break;
834 case XGL_SHADER_STAGE_TESS_EVALUATION:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800835 dst = &info->tes;
Chia-I Wu3efef432014-08-28 15:00:16 +0800836 break;
837 case XGL_SHADER_STAGE_GEOMETRY:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800838 dst = &info->gs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800839 break;
840 case XGL_SHADER_STAGE_FRAGMENT:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800841 dst = &info->fs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800842 break;
Chia-I Wu3efef432014-08-28 15:00:16 +0800843 default:
844 return XGL_ERROR_BAD_PIPELINE_DATA;
845 break;
846 }
847 }
848 break;
849 case XGL_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800850 size = sizeof(info->compute);
851 dst = &info->compute;
Chia-I Wu3efef432014-08-28 15:00:16 +0800852 break;
853 default:
854 return XGL_ERROR_BAD_PIPELINE_DATA;
855 break;
856 }
857
858 memcpy(dst, src, size);
859
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800860 header = header->next;
Chia-I Wu3efef432014-08-28 15:00:16 +0800861 }
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600862
863 return XGL_SUCCESS;
Chia-I Wu3efef432014-08-28 15:00:16 +0800864}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600865
Chia-I Wu3efef432014-08-28 15:00:16 +0800866static XGL_RESULT graphics_pipeline_create(struct intel_dev *dev,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800867 const XGL_GRAPHICS_PIPELINE_CREATE_INFO *info_,
Chia-I Wu3efef432014-08-28 15:00:16 +0800868 struct intel_pipeline **pipeline_ret)
869{
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800870 struct intel_pipeline_create_info info;
Chia-I Wu3efef432014-08-28 15:00:16 +0800871 struct intel_pipeline *pipeline;
872 XGL_RESULT ret;
873
Chia-I Wu509b3f22014-09-02 10:24:05 +0800874 ret = pipeline_create_info_init(&info,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800875 (const struct intel_pipeline_create_info_header *) info_);
Chia-I Wu3efef432014-08-28 15:00:16 +0800876 if (ret != XGL_SUCCESS)
877 return ret;
878
879 pipeline = (struct intel_pipeline *)
880 intel_base_create(dev, sizeof(*pipeline), dev->base.dbg,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800881 XGL_DBG_OBJECT_GRAPHICS_PIPELINE, info_, 0);
Chia-I Wu3efef432014-08-28 15:00:16 +0800882 if (!pipeline)
883 return XGL_ERROR_OUT_OF_MEMORY;
884
885 pipeline->dev = dev;
Chia-I Wub1024732014-12-19 13:00:29 +0800886 pipeline->obj.base.get_info = pipeline_get_info;
Chia-I Wu3efef432014-08-28 15:00:16 +0800887 pipeline->obj.destroy = pipeline_destroy;
Chia-I Wu3efef432014-08-28 15:00:16 +0800888
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800889 ret = pipeline_build_all(pipeline, &info);
Chia-I Wu3efef432014-08-28 15:00:16 +0800890 if (ret == XGL_SUCCESS)
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800891 ret = pipeline_validate(pipeline);
Chia-I Wu3efef432014-08-28 15:00:16 +0800892 if (ret != XGL_SUCCESS) {
893 pipeline_destroy(&pipeline->obj);
894 return ret;
895 }
896
897 *pipeline_ret = pipeline;
898
899 return XGL_SUCCESS;
900}
901
Chia-I Wu96177272015-01-03 15:27:41 +0800902ICD_EXPORT XGL_RESULT XGLAPI xglCreateGraphicsPipeline(
Chia-I Wu3efef432014-08-28 15:00:16 +0800903 XGL_DEVICE device,
904 const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
905 XGL_PIPELINE* pPipeline)
906{
907 struct intel_dev *dev = intel_dev(device);
908
909 return graphics_pipeline_create(dev, pCreateInfo,
910 (struct intel_pipeline **) pPipeline);
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600911}
912
Chia-I Wu96177272015-01-03 15:27:41 +0800913ICD_EXPORT XGL_RESULT XGLAPI xglCreateComputePipeline(
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600914 XGL_DEVICE device,
915 const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo,
916 XGL_PIPELINE* pPipeline)
917{
918 return XGL_ERROR_UNAVAILABLE;
919}
920
Chia-I Wu96177272015-01-03 15:27:41 +0800921ICD_EXPORT XGL_RESULT XGLAPI xglStorePipeline(
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600922 XGL_PIPELINE pipeline,
923 XGL_SIZE* pDataSize,
924 XGL_VOID* pData)
925{
926 return XGL_ERROR_UNAVAILABLE;
927}
928
Chia-I Wu96177272015-01-03 15:27:41 +0800929ICD_EXPORT XGL_RESULT XGLAPI xglLoadPipeline(
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600930 XGL_DEVICE device,
931 XGL_SIZE dataSize,
932 const XGL_VOID* pData,
933 XGL_PIPELINE* pPipeline)
934{
935 return XGL_ERROR_UNAVAILABLE;
936}
937
Chia-I Wu96177272015-01-03 15:27:41 +0800938ICD_EXPORT XGL_RESULT XGLAPI xglCreatePipelineDelta(
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600939 XGL_DEVICE device,
940 XGL_PIPELINE p1,
941 XGL_PIPELINE p2,
942 XGL_PIPELINE_DELTA* delta)
943{
944 return XGL_ERROR_UNAVAILABLE;
945}