blob: 9356ded404eb0391869424cd4dbe690f5a9ef620 [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 Wuf90ff0c2014-09-02 09:32:46 +0800149static XGL_RESULT pipeline_validate(struct intel_pipeline *pipeline)
Chia-I Wu3efef432014-08-28 15:00:16 +0800150{
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600151 /*
152 * Validate required elements
153 */
154 if (!(pipeline->active_shaders & SHADER_VERTEX_FLAG)) {
155 // TODO: Log debug message: Vertex Shader required.
Chia-I Wu3efef432014-08-28 15:00:16 +0800156 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600157 }
158
159 /*
160 * Tessalation control and evaluation have to both have a shader defined or
161 * neither should have a shader defined.
162 */
163 if (((pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) == 0) !=
164 ((pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) == 0) ) {
165 // TODO: Log debug message: Both Tess control and Tess eval are required to use tessalation
Chia-I Wu3efef432014-08-28 15:00:16 +0800166 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600167 }
168
169 if ((pipeline->active_shaders & SHADER_COMPUTE_FLAG) &&
170 (pipeline->active_shaders & (SHADER_VERTEX_FLAG | SHADER_TESS_CONTROL_FLAG |
171 SHADER_TESS_EVAL_FLAG | SHADER_GEOMETRY_FLAG |
172 SHADER_FRAGMENT_FLAG))) {
173 // TODO: Log debug message: Can only specify compute shader when doing compute
Chia-I Wu3efef432014-08-28 15:00:16 +0800174 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600175 }
176
177 /*
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600178 * XGL_TOPOLOGY_PATCH primitive topology is only valid for tessellation pipelines.
179 * Mismatching primitive topology and tessellation fails graphics pipeline creation.
180 */
181 if (pipeline->active_shaders & (SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG) &&
Chia-I Wube0a3d92014-09-02 13:20:59 +0800182 (pipeline->topology != XGL_TOPOLOGY_PATCH)) {
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600183 // TODO: Log debug message: Invalid topology used with tessalation shader.
Chia-I Wu3efef432014-08-28 15:00:16 +0800184 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600185 }
186
Chia-I Wube0a3d92014-09-02 13:20:59 +0800187 if ((pipeline->topology == XGL_TOPOLOGY_PATCH) &&
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600188 (pipeline->active_shaders & ~(SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG))) {
189 // TODO: Log debug message: Cannot use TOPOLOGY_PATCH on non-tessalation shader.
Chia-I Wu3efef432014-08-28 15:00:16 +0800190 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600191 }
192
Chia-I Wu3efef432014-08-28 15:00:16 +0800193 return XGL_SUCCESS;
194}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600195
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800196static void pipeline_build_urb_alloc_gen6(struct intel_pipeline *pipeline,
197 const struct intel_pipeline_create_info *info)
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800198{
Chia-I Wu509b3f22014-09-02 10:24:05 +0800199 const struct intel_gpu *gpu = pipeline->dev->gpu;
200 const int urb_size = ((gpu->gt == 2) ? 64 : 32) * 1024;
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800201 const struct intel_shader *vs = intel_shader(info->vs.shader);
202 const struct intel_shader *gs = intel_shader(info->gs.shader);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800203 int vs_entry_size, gs_entry_size;
204 int vs_size, gs_size;
205
Chia-I Wu509b3f22014-09-02 10:24:05 +0800206 INTEL_GPU_ASSERT(gpu, 6, 6);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800207
208 vs_entry_size = ((vs->in_count >= vs->out_count) ?
209 vs->in_count : vs->out_count);
210 gs_entry_size = (gs) ? gs->out_count : 0;
211
212 /* in bytes */
213 vs_entry_size *= sizeof(float) * 4;
214 gs_entry_size *= sizeof(float) * 4;
215
216 if (gs) {
217 vs_size = urb_size / 2;
218 gs_size = vs_size;
219 } else {
220 vs_size = urb_size;
221 gs_size = 0;
222 }
223
224 /* 3DSTATE_URB */
225 {
226 const uint8_t cmd_len = 3;
227 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_URB) |
228 (cmd_len - 2);
229 int vs_alloc_size, gs_alloc_size;
230 int vs_entry_count, gs_entry_count;
231 uint32_t *dw;
232
233 /* in 1024-bit rows */
234 vs_alloc_size = (vs_entry_size + 128 - 1) / 128;
235 gs_alloc_size = (gs_entry_size + 128 - 1) / 128;
236
237 /* valid range is [1, 5] */
238 if (!vs_alloc_size)
239 vs_alloc_size = 1;
240 if (!gs_alloc_size)
241 gs_alloc_size = 1;
242 assert(vs_alloc_size <= 5 && gs_alloc_size <= 5);
243
244 /* valid range is [24, 256], multiples of 4 */
245 vs_entry_count = (vs_size / 128 / vs_alloc_size) & ~3;
246 if (vs_entry_count > 256)
247 vs_entry_count = 256;
248 assert(vs_entry_count >= 24);
249
250 /* valid range is [0, 256], multiples of 4 */
251 gs_entry_count = (gs_size / 128 / gs_alloc_size) & ~3;
252 if (gs_entry_count > 256)
253 gs_entry_count = 256;
254
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600255 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800256
257 dw[0] = dw0;
258 dw[1] = (vs_alloc_size - 1) << GEN6_URB_DW1_VS_ENTRY_SIZE__SHIFT |
259 vs_entry_count << GEN6_URB_DW1_VS_ENTRY_COUNT__SHIFT;
260 dw[2] = gs_entry_count << GEN6_URB_DW2_GS_ENTRY_COUNT__SHIFT |
261 (gs_alloc_size - 1) << GEN6_URB_DW2_GS_ENTRY_SIZE__SHIFT;
262 }
263}
264
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800265static void pipeline_build_urb_alloc_gen7(struct intel_pipeline *pipeline,
266 const struct intel_pipeline_create_info *info)
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800267{
Chia-I Wu509b3f22014-09-02 10:24:05 +0800268 const struct intel_gpu *gpu = pipeline->dev->gpu;
269 const int urb_size = ((gpu->gt == 3) ? 512 :
270 (gpu->gt == 2) ? 256 : 128) * 1024;
Cody Northrop306ec352014-10-06 15:11:45 -0600271 const struct intel_pipeline_shader *vs = &pipeline->vs;
272 const struct intel_pipeline_shader *gs = &pipeline->gs;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800273 /* some space is reserved for PCBs */
Chia-I Wu509b3f22014-09-02 10:24:05 +0800274 int urb_offset = ((gpu->gt == 3) ? 32 : 16) * 1024;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800275 int vs_entry_size, gs_entry_size;
276 int vs_size, gs_size;
277
Chia-I Wu509b3f22014-09-02 10:24:05 +0800278 INTEL_GPU_ASSERT(gpu, 7, 7.5);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800279
280 vs_entry_size = ((vs->in_count >= vs->out_count) ?
281 vs->in_count : vs->out_count);
282 gs_entry_size = (gs) ? gs->out_count : 0;
283
284 /* in bytes */
285 vs_entry_size *= sizeof(float) * 4;
286 gs_entry_size *= sizeof(float) * 4;
287
288 if (gs) {
289 vs_size = (urb_size - urb_offset) / 2;
290 gs_size = vs_size;
291 } else {
292 vs_size = urb_size - urb_offset;
293 gs_size = 0;
294 }
295
296 /* 3DSTATE_URB_* */
297 {
298 const uint8_t cmd_len = 2;
299 int vs_alloc_size, gs_alloc_size;
300 int vs_entry_count, gs_entry_count;
301 uint32_t *dw;
302
303 /* in 512-bit rows */
304 vs_alloc_size = (vs_entry_size + 64 - 1) / 64;
305 gs_alloc_size = (gs_entry_size + 64 - 1) / 64;
306
307 if (!vs_alloc_size)
308 vs_alloc_size = 1;
309 if (!gs_alloc_size)
310 gs_alloc_size = 1;
311
312 /* avoid performance decrease due to banking */
313 if (vs_alloc_size == 5)
314 vs_alloc_size = 6;
315
316 /* in multiples of 8 */
317 vs_entry_count = (vs_size / 64 / vs_alloc_size) & ~7;
318 assert(vs_entry_count >= 32);
319
320 gs_entry_count = (gs_size / 64 / gs_alloc_size) & ~7;
321
Chia-I Wu509b3f22014-09-02 10:24:05 +0800322 if (intel_gpu_gen(gpu) >= INTEL_GEN(7.5)) {
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800323 const int max_vs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800324 (gpu->gt >= 2) ? 1664 : 640;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800325 const int max_gs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800326 (gpu->gt >= 2) ? 640 : 256;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800327 if (vs_entry_count >= max_vs_entry_count)
328 vs_entry_count = max_vs_entry_count;
329 if (gs_entry_count >= max_gs_entry_count)
330 gs_entry_count = max_gs_entry_count;
331 } else {
332 const int max_vs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800333 (gpu->gt == 2) ? 704 : 512;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800334 const int max_gs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800335 (gpu->gt == 2) ? 320 : 192;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800336 if (vs_entry_count >= max_vs_entry_count)
337 vs_entry_count = max_vs_entry_count;
338 if (gs_entry_count >= max_gs_entry_count)
339 gs_entry_count = max_gs_entry_count;
340 }
341
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600342 dw = pipeline_cmd_ptr(pipeline, cmd_len*4);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800343 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_VS) | (cmd_len - 2);
344 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT |
345 (vs_alloc_size - 1) << GEN7_URB_ANY_DW1_ENTRY_SIZE__SHIFT |
346 vs_entry_count;
347
348 dw += 2;
349 if (gs_size)
350 urb_offset += vs_size;
351 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_GS) | (cmd_len - 2);
352 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT |
353 (gs_alloc_size - 1) << GEN7_URB_ANY_DW1_ENTRY_SIZE__SHIFT |
354 gs_entry_count;
355
356 dw += 2;
357 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_HS) | (cmd_len - 2);
358 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT;
359
360 dw += 2;
361 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_DS) | (cmd_len - 2);
362 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT;
363 }
364}
365
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800366static void pipeline_build_push_const_alloc_gen7(struct intel_pipeline *pipeline,
367 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600368{
369 const uint8_t cmd_len = 2;
370 uint32_t offset = 0;
371 uint32_t size = 8192;
372 uint32_t *dw;
373 int end;
374
Chia-I Wu509b3f22014-09-02 10:24:05 +0800375 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600376
377 /*
378 * From the Ivy Bridge PRM, volume 2 part 1, page 68:
379 *
380 * "(A table that says the maximum size of each constant buffer is
381 * 16KB")
382 *
383 * From the Ivy Bridge PRM, volume 2 part 1, page 115:
384 *
385 * "The sum of the Constant Buffer Offset and the Constant Buffer Size
386 * may not exceed the maximum value of the Constant Buffer Size."
387 *
388 * Thus, the valid range of buffer end is [0KB, 16KB].
389 */
390 end = (offset + size) / 1024;
391 if (end > 16) {
392 assert(!"invalid constant buffer end");
393 end = 16;
394 }
395
396 /* the valid range of buffer offset is [0KB, 15KB] */
397 offset = (offset + 1023) / 1024;
398 if (offset > 15) {
399 assert(!"invalid constant buffer offset");
400 offset = 15;
401 }
402
403 if (offset > end) {
404 assert(!size);
405 offset = end;
406 }
407
408 /* the valid range of buffer size is [0KB, 15KB] */
409 size = end - offset;
410 if (size > 15) {
411 assert(!"invalid constant buffer size");
412 size = 15;
413 }
414
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800415 dw = pipeline_cmd_ptr(pipeline, cmd_len * 5);
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600416 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_VS) | (cmd_len - 2);
417 dw[1] = offset << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
418 size << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
419
420 dw += 2;
421 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_PS) | (cmd_len - 2);
422 dw[1] = size << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
423 size << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
424
425 dw += 2;
426 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_HS) | (cmd_len - 2);
427 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
428 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
429
430 dw += 2;
431 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_DS) | (cmd_len - 2);
432 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
433 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
434
435 dw += 2;
436 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_GS) | (cmd_len - 2);
437 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
438 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
Chia-I Wu8370b402014-08-29 12:28:37 +0800439
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600440 // gen7_wa_pipe_control_cs_stall(p, true, true);
441 // looks equivalent to: gen6_wa_wm_multisample_flush - this does more
442 // than the documentation seems to imply
443}
444
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800445static void pipeline_build_vertex_elements(struct intel_pipeline *pipeline,
446 const struct intel_pipeline_create_info *info)
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800447{
Cody Northrop306ec352014-10-06 15:11:45 -0600448 const struct intel_pipeline_shader *vs = &pipeline->vs;
Chia-I Wu1d125092014-10-08 08:49:38 +0800449 uint8_t cmd_len;
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800450 uint32_t *dw;
Chia-I Wu1d125092014-10-08 08:49:38 +0800451 XGL_UINT i;
452 int comps[4];
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800453
Chia-I Wu509b3f22014-09-02 10:24:05 +0800454 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800455
Chia-I Wu1d125092014-10-08 08:49:38 +0800456 cmd_len = 1 + 2 * info->vi.attributeCount;
457 if (vs->uses & (INTEL_SHADER_USE_VID | INTEL_SHADER_USE_IID))
458 cmd_len += 2;
459
460 if (cmd_len == 1)
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800461 return;
462
463 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Chia-I Wu1d125092014-10-08 08:49:38 +0800464
465 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_ELEMENTS) |
466 (cmd_len - 2);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800467 dw++;
468
Chia-I Wu1d125092014-10-08 08:49:38 +0800469 if (vs->uses & (INTEL_SHADER_USE_VID | INTEL_SHADER_USE_IID)) {
470 comps[0] = (vs->uses & INTEL_SHADER_USE_VID) ?
471 GEN6_VFCOMP_STORE_VID : GEN6_VFCOMP_STORE_0;
472 comps[1] = (vs->uses & INTEL_SHADER_USE_IID) ?
473 GEN6_VFCOMP_STORE_IID : GEN6_VFCOMP_NOSTORE;
474 comps[2] = GEN6_VFCOMP_NOSTORE;
475 comps[3] = GEN6_VFCOMP_NOSTORE;
476
477 dw[0] = GEN6_VE_STATE_DW0_VALID;
478 dw[1] = comps[0] << GEN6_VE_STATE_DW1_COMP0__SHIFT |
479 comps[1] << GEN6_VE_STATE_DW1_COMP1__SHIFT |
480 comps[2] << GEN6_VE_STATE_DW1_COMP2__SHIFT |
481 comps[3] << GEN6_VE_STATE_DW1_COMP3__SHIFT;
482
483 dw += 2;
484 }
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800485
486 /* VERTEX_ELEMENT_STATE */
Chia-I Wu1d125092014-10-08 08:49:38 +0800487 for (i = 0; i < info->vi.attributeCount; i++) {
488 const XGL_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION *attr =
489 &info->vi.pVertexAttributeDescriptions[i];
490 const int format =
491 intel_format_translate_color(pipeline->dev->gpu, attr->format);
492
493 comps[0] = GEN6_VFCOMP_STORE_0;
494 comps[1] = GEN6_VFCOMP_STORE_0;
495 comps[2] = GEN6_VFCOMP_STORE_0;
496 comps[3] = icd_format_is_int(attr->format) ?
497 GEN6_VFCOMP_STORE_1_INT : GEN6_VFCOMP_STORE_1_FP;
498
499 switch (icd_format_get_channel_count(attr->format)) {
500 case 4: comps[3] = GEN6_VFCOMP_STORE_SRC; /* fall through */
501 case 3: comps[2] = GEN6_VFCOMP_STORE_SRC; /* fall through */
502 case 2: comps[1] = GEN6_VFCOMP_STORE_SRC; /* fall through */
503 case 1: comps[0] = GEN6_VFCOMP_STORE_SRC; break;
504 default:
505 break;
506 }
507
508 assert(attr->offsetInBytes <= 2047);
509
510 dw[0] = attr->binding << GEN6_VE_STATE_DW0_VB_INDEX__SHIFT |
511 GEN6_VE_STATE_DW0_VALID |
512 format << GEN6_VE_STATE_DW0_FORMAT__SHIFT |
513 attr->offsetInBytes;
514
515 dw[1] = comps[0] << GEN6_VE_STATE_DW1_COMP0__SHIFT |
516 comps[1] << GEN6_VE_STATE_DW1_COMP1__SHIFT |
517 comps[2] << GEN6_VE_STATE_DW1_COMP2__SHIFT |
518 comps[3] << GEN6_VE_STATE_DW1_COMP3__SHIFT;
519
520 dw += 2;
521 }
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800522}
523
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800524static void pipeline_build_gs(struct intel_pipeline *pipeline,
525 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600526{
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600527 // gen7_emit_3DSTATE_GS done by cmd_pipeline
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600528}
529
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800530static void pipeline_build_hs(struct intel_pipeline *pipeline,
531 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600532{
533 const uint8_t cmd_len = 7;
534 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
535 uint32_t *dw;
536
Chia-I Wu509b3f22014-09-02 10:24:05 +0800537 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600538
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800539 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600540 dw[0] = dw0;
541 dw[1] = 0;
542 dw[2] = 0;
543 dw[3] = 0;
544 dw[4] = 0;
545 dw[5] = 0;
546 dw[6] = 0;
547}
548
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800549static void pipeline_build_te(struct intel_pipeline *pipeline,
550 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600551{
552 const uint8_t cmd_len = 4;
553 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_TE) | (cmd_len - 2);
554 uint32_t *dw;
555
Chia-I Wu509b3f22014-09-02 10:24:05 +0800556 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600557
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800558 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600559 dw[0] = dw0;
560 dw[1] = 0;
561 dw[2] = 0;
562 dw[3] = 0;
563}
564
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800565static void pipeline_build_ds(struct intel_pipeline *pipeline,
566 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600567{
568 const uint8_t cmd_len = 6;
569 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
570 uint32_t *dw;
571
Chia-I Wu509b3f22014-09-02 10:24:05 +0800572 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600573
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800574 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600575 dw[0] = dw0;
576 dw[1] = 0;
577 dw[2] = 0;
578 dw[3] = 0;
579 dw[4] = 0;
580 dw[5] = 0;
581}
582
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800583static XGL_RESULT pipeline_build_all(struct intel_pipeline *pipeline,
584 const struct intel_pipeline_create_info *info)
Chia-I Wu3efef432014-08-28 15:00:16 +0800585{
586 XGL_RESULT ret;
587
Chia-I Wu98824592014-09-02 09:42:46 +0800588 ret = pipeline_build_shaders(pipeline, info);
589 if (ret != XGL_SUCCESS)
590 return ret;
591
Chia-I Wu1d125092014-10-08 08:49:38 +0800592 if (info->vi.bindingCount > ARRAY_SIZE(pipeline->vb) ||
593 info->vi.attributeCount > ARRAY_SIZE(pipeline->vb))
594 return XGL_ERROR_BAD_PIPELINE_DATA;
595
596 pipeline->vb_count = info->vi.bindingCount;
597 memcpy(pipeline->vb, info->vi.pVertexBindingDescriptions,
598 sizeof(pipeline->vb[0]) * pipeline->vb_count);
599
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800600 pipeline_build_vertex_elements(pipeline, info);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800601
Chia-I Wu509b3f22014-09-02 10:24:05 +0800602 if (intel_gpu_gen(pipeline->dev->gpu) >= INTEL_GEN(7)) {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800603 pipeline_build_urb_alloc_gen7(pipeline, info);
604 pipeline_build_push_const_alloc_gen7(pipeline, info);
605 pipeline_build_gs(pipeline, info);
606 pipeline_build_hs(pipeline, info);
607 pipeline_build_te(pipeline, info);
608 pipeline_build_ds(pipeline, info);
Chia-I Wu8370b402014-08-29 12:28:37 +0800609
610 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
611 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL |
612 INTEL_CMD_WA_GEN7_PRE_VS_DEPTH_STALL_WRITE |
613 INTEL_CMD_WA_GEN7_POST_COMMAND_CS_STALL |
614 INTEL_CMD_WA_GEN7_POST_COMMAND_DEPTH_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800615 } else {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800616 pipeline_build_urb_alloc_gen6(pipeline, info);
Chia-I Wu8370b402014-08-29 12:28:37 +0800617
618 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
619 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800620 }
621
Chia-I Wube0a3d92014-09-02 13:20:59 +0800622 ret = pipeline_build_ia(pipeline, info);
Chia-I Wu3efef432014-08-28 15:00:16 +0800623
624 if (ret == XGL_SUCCESS)
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800625 ret = pipeline_rs_state(pipeline, &info->rs);
Chia-I Wu3efef432014-08-28 15:00:16 +0800626
Chia-I Wu3efef432014-08-28 15:00:16 +0800627 if (ret == XGL_SUCCESS) {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800628 pipeline->db_format = info->db.format;
629 pipeline->cb_state = info->cb;
630 pipeline->tess_state = info->tess;
Chia-I Wu3efef432014-08-28 15:00:16 +0800631 }
632
633 return ret;
634}
635
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800636struct intel_pipeline_create_info_header {
637 XGL_STRUCTURE_TYPE struct_type;
638 const struct intel_pipeline_create_info_header *next;
639};
640
641static XGL_RESULT pipeline_create_info_init(struct intel_pipeline_create_info *info,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800642 const struct intel_pipeline_create_info_header *header)
Chia-I Wu3efef432014-08-28 15:00:16 +0800643{
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800644 memset(info, 0, sizeof(*info));
Chia-I Wu3efef432014-08-28 15:00:16 +0800645
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800646 while (header) {
647 const void *src = (const void *) header;
Chia-I Wu3efef432014-08-28 15:00:16 +0800648 XGL_SIZE size;
649 void *dst;
650
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800651 switch (header->struct_type) {
Chia-I Wu3efef432014-08-28 15:00:16 +0800652 case XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800653 size = sizeof(info->graphics);
654 dst = &info->graphics;
Chia-I Wu3efef432014-08-28 15:00:16 +0800655 break;
Chia-I Wu1d125092014-10-08 08:49:38 +0800656 case XGL_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO:
657 size = sizeof(info->vi);
658 dst = &info->vi;
659 break;
Chia-I Wu3efef432014-08-28 15:00:16 +0800660 case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800661 size = sizeof(info->ia);
662 dst = &info->ia;
Chia-I Wu3efef432014-08-28 15:00:16 +0800663 break;
664 case XGL_STRUCTURE_TYPE_PIPELINE_DB_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800665 size = sizeof(info->db);
666 dst = &info->db;
Chia-I Wu3efef432014-08-28 15:00:16 +0800667 break;
668 case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800669 size = sizeof(info->cb);
670 dst = &info->cb;
Chia-I Wu3efef432014-08-28 15:00:16 +0800671 break;
672 case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800673 size = sizeof(info->rs);
674 dst = &info->rs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800675 break;
676 case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800677 size = sizeof(info->tess);
678 dst = &info->tess;
Chia-I Wu3efef432014-08-28 15:00:16 +0800679 break;
680 case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
681 {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800682 const XGL_PIPELINE_SHADER *shader =
683 (const XGL_PIPELINE_SHADER *) (header + 1);
Chia-I Wu3efef432014-08-28 15:00:16 +0800684
685 src = (const void *) shader;
686 size = sizeof(*shader);
687
688 switch (shader->stage) {
689 case XGL_SHADER_STAGE_VERTEX:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800690 dst = &info->vs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800691 break;
692 case XGL_SHADER_STAGE_TESS_CONTROL:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800693 dst = &info->tcs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800694 break;
695 case XGL_SHADER_STAGE_TESS_EVALUATION:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800696 dst = &info->tes;
Chia-I Wu3efef432014-08-28 15:00:16 +0800697 break;
698 case XGL_SHADER_STAGE_GEOMETRY:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800699 dst = &info->gs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800700 break;
701 case XGL_SHADER_STAGE_FRAGMENT:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800702 dst = &info->fs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800703 break;
Chia-I Wu3efef432014-08-28 15:00:16 +0800704 default:
705 return XGL_ERROR_BAD_PIPELINE_DATA;
706 break;
707 }
708 }
709 break;
710 case XGL_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800711 size = sizeof(info->compute);
712 dst = &info->compute;
Chia-I Wu3efef432014-08-28 15:00:16 +0800713 break;
714 default:
715 return XGL_ERROR_BAD_PIPELINE_DATA;
716 break;
717 }
718
719 memcpy(dst, src, size);
720
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800721 header = header->next;
Chia-I Wu3efef432014-08-28 15:00:16 +0800722 }
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600723
724 return XGL_SUCCESS;
Chia-I Wu3efef432014-08-28 15:00:16 +0800725}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600726
Chia-I Wu3efef432014-08-28 15:00:16 +0800727static XGL_RESULT graphics_pipeline_create(struct intel_dev *dev,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800728 const XGL_GRAPHICS_PIPELINE_CREATE_INFO *info_,
Chia-I Wu3efef432014-08-28 15:00:16 +0800729 struct intel_pipeline **pipeline_ret)
730{
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800731 struct intel_pipeline_create_info info;
Chia-I Wu3efef432014-08-28 15:00:16 +0800732 struct intel_pipeline *pipeline;
733 XGL_RESULT ret;
734
Chia-I Wu509b3f22014-09-02 10:24:05 +0800735 ret = pipeline_create_info_init(&info,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800736 (const struct intel_pipeline_create_info_header *) info_);
Chia-I Wu3efef432014-08-28 15:00:16 +0800737 if (ret != XGL_SUCCESS)
738 return ret;
739
740 pipeline = (struct intel_pipeline *)
741 intel_base_create(dev, sizeof(*pipeline), dev->base.dbg,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800742 XGL_DBG_OBJECT_GRAPHICS_PIPELINE, info_, 0);
Chia-I Wu3efef432014-08-28 15:00:16 +0800743 if (!pipeline)
744 return XGL_ERROR_OUT_OF_MEMORY;
745
746 pipeline->dev = dev;
747 pipeline->obj.destroy = pipeline_destroy;
Chia-I Wu3efef432014-08-28 15:00:16 +0800748
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800749 ret = pipeline_build_all(pipeline, &info);
Chia-I Wu3efef432014-08-28 15:00:16 +0800750 if (ret == XGL_SUCCESS)
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800751 ret = pipeline_validate(pipeline);
Chia-I Wu3efef432014-08-28 15:00:16 +0800752 if (ret != XGL_SUCCESS) {
753 pipeline_destroy(&pipeline->obj);
754 return ret;
755 }
756
757 *pipeline_ret = pipeline;
758
759 return XGL_SUCCESS;
760}
761
762XGL_RESULT XGLAPI intelCreateGraphicsPipeline(
763 XGL_DEVICE device,
764 const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
765 XGL_PIPELINE* pPipeline)
766{
767 struct intel_dev *dev = intel_dev(device);
768
769 return graphics_pipeline_create(dev, pCreateInfo,
770 (struct intel_pipeline **) pPipeline);
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600771}
772
773XGL_RESULT XGLAPI intelCreateComputePipeline(
774 XGL_DEVICE device,
775 const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo,
776 XGL_PIPELINE* pPipeline)
777{
778 return XGL_ERROR_UNAVAILABLE;
779}
780
781XGL_RESULT XGLAPI intelStorePipeline(
782 XGL_PIPELINE pipeline,
783 XGL_SIZE* pDataSize,
784 XGL_VOID* pData)
785{
786 return XGL_ERROR_UNAVAILABLE;
787}
788
789XGL_RESULT XGLAPI intelLoadPipeline(
790 XGL_DEVICE device,
791 XGL_SIZE dataSize,
792 const XGL_VOID* pData,
793 XGL_PIPELINE* pPipeline)
794{
795 return XGL_ERROR_UNAVAILABLE;
796}
797
798XGL_RESULT XGLAPI intelCreatePipelineDelta(
799 XGL_DEVICE device,
800 XGL_PIPELINE p1,
801 XGL_PIPELINE p2,
802 XGL_PIPELINE_DELTA* delta)
803{
804 return XGL_ERROR_UNAVAILABLE;
805}