blob: 90454f0f71a2a4e8b380cc5eb655f758233942ae [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.
23 */
24
Chia-I Wu8370b402014-08-29 12:28:37 +080025#include "genhw/genhw.h"
26
27#include "cmd.h"
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -060028#include "shader.h"
Chia-I Wued833872014-08-23 17:00:35 +080029#include "pipeline_priv.h"
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060030
Chia-I Wu3efef432014-08-28 15:00:16 +080031struct intel_pipeline_builder {
32 const struct intel_gpu *gpu;
33
34 XGL_GRAPHICS_PIPELINE_CREATE_INFO graphics;
35 XGL_PIPELINE_IA_STATE_CREATE_INFO ia;
36 XGL_PIPELINE_DB_STATE_CREATE_INFO db;
37 XGL_PIPELINE_CB_STATE cb;
38 XGL_PIPELINE_RS_STATE_CREATE_INFO rs;
39 XGL_PIPELINE_TESS_STATE_CREATE_INFO tess;
40 XGL_PIPELINE_SHADER vs;
41 XGL_PIPELINE_SHADER tcs;
42 XGL_PIPELINE_SHADER tes;
43 XGL_PIPELINE_SHADER gs;
44 XGL_PIPELINE_SHADER fs;
45
46 XGL_COMPUTE_PIPELINE_CREATE_INFO compute;
47 XGL_PIPELINE_SHADER cs;
48};
49
50struct intel_pipeline_builder_create_info {
51 XGL_STRUCTURE_TYPE struct_type;
52 XGL_VOID *next;
53};
54
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -060055static uint32_t *pipeline_cmd_ptr(struct intel_pipeline *pipeline, int cmd_len)
56{
57 uint32_t *ptr;
58
59 assert(pipeline->cmd_len + cmd_len < INTEL_PSO_CMD_ENTRIES);
60 ptr = &pipeline->cmds[pipeline->cmd_len];
61 pipeline->cmd_len += cmd_len;
62 return ptr;
63}
64
Chia-I Wu3efef432014-08-28 15:00:16 +080065static XGL_RESULT pipeline_ia_state(struct intel_pipeline *pipeline,
66 const XGL_PIPELINE_IA_STATE_CREATE_INFO* ia_state)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060067{
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -060068 pipeline->ia_state = *ia_state;
69
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060070 if (ia_state->provokingVertex == XGL_PROVOKING_VERTEX_FIRST) {
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060071 pipeline->provoking_vertex_tri = 0;
72 pipeline->provoking_vertex_trifan = 1;
73 pipeline->provoking_vertex_line = 0;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060074 } else {
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060075 pipeline->provoking_vertex_tri = 2;
76 pipeline->provoking_vertex_trifan = 2;
77 pipeline->provoking_vertex_line = 1;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060078 }
79
80 switch (ia_state->topology) {
81 case XGL_TOPOLOGY_POINT_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060082 pipeline->prim_type = GEN6_3DPRIM_POINTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060083 break;
84 case XGL_TOPOLOGY_LINE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060085 pipeline->prim_type = GEN6_3DPRIM_LINELIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060086 break;
87 case XGL_TOPOLOGY_LINE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060088 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060089 break;
90 case XGL_TOPOLOGY_TRIANGLE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060091 pipeline->prim_type = GEN6_3DPRIM_TRILIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060092 break;
93 case XGL_TOPOLOGY_TRIANGLE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060094 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060095 break;
96 case XGL_TOPOLOGY_RECT_LIST:
97 /*
98 * TODO: Rect lists are special in XGL, do we need to do
99 * something special here?
100 * XGL Guide:
101 * The rectangle list is a special geometry primitive type
102 * that can be used for implementing post-processing techniques
103 * or efficient copy operations. There are some special limitations
104 * for rectangle primitives. They cannot be clipped, must
105 * be axis aligned and cannot have depth gradient.
106 * Failure to comply with these restrictions results in
107 * undefined rendering results.
108 */
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600109 pipeline->prim_type = GEN6_3DPRIM_RECTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600110 break;
111 case XGL_TOPOLOGY_QUAD_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600112 pipeline->prim_type = GEN6_3DPRIM_QUADLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600113 break;
114 case XGL_TOPOLOGY_QUAD_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600115 pipeline->prim_type = GEN6_3DPRIM_QUADSTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600116 break;
117 case XGL_TOPOLOGY_LINE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600118 pipeline->prim_type = GEN6_3DPRIM_LINELIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600119 break;
120 case XGL_TOPOLOGY_LINE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600121 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600122 break;
123 case XGL_TOPOLOGY_TRIANGLE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600124 pipeline->prim_type = GEN6_3DPRIM_TRILIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600125 break;
126 case XGL_TOPOLOGY_TRIANGLE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600127 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600128 break;
129 case XGL_TOPOLOGY_PATCH:
130 // TODO: implement something here
131 break;
132 default:
133 return XGL_ERROR_BAD_PIPELINE_DATA;
134 }
135
136 if (ia_state->primitiveRestartEnable) {
137 pipeline->primitive_restart = true;
138 pipeline->primitive_restart_index = ia_state->primitiveRestartIndex;
139 } else {
140 pipeline->primitive_restart = false;
141 }
142
143 if (ia_state->disableVertexReuse) {
144 // TODO: What do we do to disable vertex reuse?
145 }
146
147 return XGL_SUCCESS;
148}
149
Chia-I Wu3efef432014-08-28 15:00:16 +0800150static XGL_RESULT pipeline_rs_state(struct intel_pipeline *pipeline,
151 const XGL_PIPELINE_RS_STATE_CREATE_INFO* rs_state)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600152{
153 pipeline->depthClipEnable = rs_state->depthClipEnable;
154 pipeline->rasterizerDiscardEnable = rs_state->rasterizerDiscardEnable;
155 pipeline->pointSize = rs_state->pointSize;
156 return XGL_SUCCESS;
157}
158
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600159static void pipeline_destroy(struct intel_obj *obj)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600160{
161 struct intel_pipeline *pipeline = intel_pipeline_from_obj(obj);
162
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -0600163 if (pipeline->active_shaders & SHADER_VERTEX_FLAG) {
Chia-I Wu282d3bc2014-08-28 15:36:44 +0800164 icd_free(pipeline->intel_vs.pCode);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -0600165 }
166 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
Chia-I Wu282d3bc2014-08-28 15:36:44 +0800167 icd_free(pipeline->gs.pCode);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -0600168 }
169 if (pipeline->active_shaders & SHADER_FRAGMENT_FLAG) {
Chia-I Wu282d3bc2014-08-28 15:36:44 +0800170 icd_free(pipeline->intel_fs.pCode);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -0600171 }
172 if (pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) {
Chia-I Wu282d3bc2014-08-28 15:36:44 +0800173 icd_free(pipeline->tess_control.pCode);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -0600174 }
175 if (pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) {
Chia-I Wu282d3bc2014-08-28 15:36:44 +0800176 icd_free(pipeline->tess_eval.pCode);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -0600177 }
178
Chia-I Wued833872014-08-23 17:00:35 +0800179 if (pipeline->vs_rmap)
180 intel_rmap_destroy(pipeline->vs_rmap);
181 if (pipeline->fs_rmap)
182 intel_rmap_destroy(pipeline->fs_rmap);
183
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600184 intel_base_destroy(&pipeline->obj.base);
185}
186
Courtney Goeltzenleuchterc4ef6142014-08-29 16:25:30 -0600187static void intel_pipe_shader_init(struct intel_shader *sh,
188 struct intel_pipe_shader *pipe_sh)
189{
190 pipe_sh->in_count = sh->in_count;
191 pipe_sh->out_count = sh->out_count;
192 pipe_sh->sampler_count = sh->sampler_count;
193 pipe_sh->surface_count = sh->surface_count;
194 pipe_sh->barycentric_interps = sh->barycentric_interps;
195 pipe_sh->urb_read_length = sh->urb_read_length;
196 pipe_sh->urb_grf_start = sh->urb_grf_start;
197 pipe_sh->uses = sh->uses;
198}
199
Chia-I Wu3efef432014-08-28 15:00:16 +0800200static XGL_RESULT pipeline_shader(struct intel_pipeline *pipeline,
201 const XGL_PIPELINE_SHADER *info)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600202{
Chia-I Wu3efef432014-08-28 15:00:16 +0800203 struct intel_shader *sh = intel_shader(info->shader);
204 void *kernel;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600205
Chia-I Wu3efef432014-08-28 15:00:16 +0800206 // TODO: process shader object and include in pipeline
207 // For now that processing is simply a copy so that the app
208 // can destroy the original shader object after pipeline creation.
209 kernel = icd_alloc(sh->ir->size, 0, XGL_SYSTEM_ALLOC_INTERNAL_SHADER);
210 if (!kernel)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600211 return XGL_ERROR_OUT_OF_MEMORY;
Chia-I Wu3efef432014-08-28 15:00:16 +0800212
Courtney Goeltzenleuchterc4ef6142014-08-29 16:25:30 -0600213 // TODO: This should be a compile step
214 memcpy(kernel, sh->ir->kernel, sh->ir->size);
215
Chia-I Wu3efef432014-08-28 15:00:16 +0800216 switch (info->stage) {
217 case XGL_SHADER_STAGE_VERTEX:
218 /*
219 * TODO: What should we do here?
220 * shader_state (XGL_PIPELINE_SHADER) contains links
221 * to application memory in the pLinkConstBufferInfo and
222 * it's pBufferData pointers. Do we need to bring all that
223 * into the driver or is it okay to rely on those references
224 * holding good data. In OpenGL we'd make a driver copy. Not
225 * as clear for XGL.
226 * For now, use the app pointers.
227 */
228 pipeline->vs = *info;
Courtney Goeltzenleuchterc4ef6142014-08-29 16:25:30 -0600229
230 /*
231 * Grab what we need from the intel_shader object as that
232 * could go away after the pipeline is created.
233 */
234 intel_pipe_shader_init(sh, &pipeline->intel_vs);
Chia-I Wu3efef432014-08-28 15:00:16 +0800235 pipeline->intel_vs.pCode = kernel;
236 pipeline->intel_vs.codeSize = sh->ir->size;
237 pipeline->active_shaders |= SHADER_VERTEX_FLAG;
238 pipeline->vs_rmap = intel_rmap_create(pipeline->dev,
239 &info->descriptorSetMapping[0],
240 &info->dynamicMemoryViewMapping, 0);
241 if (!pipeline->vs_rmap) {
242 icd_free(kernel);
243 return XGL_ERROR_OUT_OF_MEMORY;
244 }
245 break;
246 case XGL_SHADER_STAGE_GEOMETRY:
Courtney Goeltzenleuchterc4ef6142014-08-29 16:25:30 -0600247 intel_pipe_shader_init(sh, &pipeline->gs);
Chia-I Wu3efef432014-08-28 15:00:16 +0800248 pipeline->gs.pCode = kernel;
249 pipeline->gs.codeSize = sh->ir->size;
250 pipeline->active_shaders |= SHADER_GEOMETRY_FLAG;
251 break;
252 case XGL_SHADER_STAGE_FRAGMENT:
253 pipeline->fs = *info;
Courtney Goeltzenleuchterc4ef6142014-08-29 16:25:30 -0600254 intel_pipe_shader_init(sh, &pipeline->intel_fs);
Chia-I Wu3efef432014-08-28 15:00:16 +0800255 pipeline->intel_fs.pCode = kernel;
256 pipeline->intel_fs.codeSize = sh->ir->size;
257 pipeline->active_shaders |= SHADER_FRAGMENT_FLAG;
258 /* assuming one RT; need to parse the shader */
259 pipeline->fs_rmap = intel_rmap_create(pipeline->dev,
260 &info->descriptorSetMapping[0],
261 &info->dynamicMemoryViewMapping, 1);
262 if (!pipeline->fs_rmap) {
263 icd_free(kernel);
264 return XGL_ERROR_OUT_OF_MEMORY;
265 }
266 break;
267 case XGL_SHADER_STAGE_TESS_CONTROL:
Courtney Goeltzenleuchterc4ef6142014-08-29 16:25:30 -0600268 intel_pipe_shader_init(sh, &pipeline->tess_control);
Chia-I Wu3efef432014-08-28 15:00:16 +0800269 pipeline->tess_control.pCode = kernel;
270 pipeline->tess_control.codeSize = sh->ir->size;
271 pipeline->active_shaders |= SHADER_TESS_CONTROL_FLAG;
272 break;
273 case XGL_SHADER_STAGE_TESS_EVALUATION:
Courtney Goeltzenleuchterc4ef6142014-08-29 16:25:30 -0600274 intel_pipe_shader_init(sh, &pipeline->tess_eval);
Chia-I Wu3efef432014-08-28 15:00:16 +0800275 pipeline->tess_eval.pCode = kernel;
276 pipeline->tess_eval.codeSize = sh->ir->size;
277 pipeline->active_shaders |= SHADER_TESS_EVAL_FLAG;
278 break;
279 case XGL_SHADER_STAGE_COMPUTE:
Courtney Goeltzenleuchterc4ef6142014-08-29 16:25:30 -0600280 intel_pipe_shader_init(sh, &pipeline->compute);
Chia-I Wu3efef432014-08-28 15:00:16 +0800281 pipeline->compute.pCode = kernel;
282 pipeline->compute.codeSize = sh->ir->size;
283 pipeline->active_shaders |= SHADER_COMPUTE_FLAG;
284 break;
285 default:
286 assert(!"unknown shader stage");
287 break;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600288 }
289
Chia-I Wu3efef432014-08-28 15:00:16 +0800290 return XGL_SUCCESS;
291}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600292
Chia-I Wu3efef432014-08-28 15:00:16 +0800293static XGL_RESULT builder_validate(const struct intel_pipeline_builder *builder,
294 const struct intel_pipeline *pipeline)
295{
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600296 /*
297 * Validate required elements
298 */
299 if (!(pipeline->active_shaders & SHADER_VERTEX_FLAG)) {
300 // TODO: Log debug message: Vertex Shader required.
Chia-I Wu3efef432014-08-28 15:00:16 +0800301 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600302 }
303
304 /*
305 * Tessalation control and evaluation have to both have a shader defined or
306 * neither should have a shader defined.
307 */
308 if (((pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) == 0) !=
309 ((pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) == 0) ) {
310 // TODO: Log debug message: Both Tess control and Tess eval are required to use tessalation
Chia-I Wu3efef432014-08-28 15:00:16 +0800311 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600312 }
313
314 if ((pipeline->active_shaders & SHADER_COMPUTE_FLAG) &&
315 (pipeline->active_shaders & (SHADER_VERTEX_FLAG | SHADER_TESS_CONTROL_FLAG |
316 SHADER_TESS_EVAL_FLAG | SHADER_GEOMETRY_FLAG |
317 SHADER_FRAGMENT_FLAG))) {
318 // TODO: Log debug message: Can only specify compute shader when doing compute
Chia-I Wu3efef432014-08-28 15:00:16 +0800319 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600320 }
321
322 /*
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600323 * XGL_TOPOLOGY_PATCH primitive topology is only valid for tessellation pipelines.
324 * Mismatching primitive topology and tessellation fails graphics pipeline creation.
325 */
326 if (pipeline->active_shaders & (SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG) &&
327 (pipeline->ia_state.topology != XGL_TOPOLOGY_PATCH)) {
328 // TODO: Log debug message: Invalid topology used with tessalation shader.
Chia-I Wu3efef432014-08-28 15:00:16 +0800329 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600330 }
331
332 if ((pipeline->ia_state.topology == XGL_TOPOLOGY_PATCH) &&
333 (pipeline->active_shaders & ~(SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG))) {
334 // TODO: Log debug message: Cannot use TOPOLOGY_PATCH on non-tessalation shader.
Chia-I Wu3efef432014-08-28 15:00:16 +0800335 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600336 }
337
Chia-I Wu3efef432014-08-28 15:00:16 +0800338 return XGL_SUCCESS;
339}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600340
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800341static void builder_build_urb_alloc_gen6(struct intel_pipeline_builder *builder,
342 struct intel_pipeline *pipeline)
343{
344 const int urb_size = ((builder->gpu->gt == 2) ? 64 : 32) * 1024;
345 const struct intel_shader *vs = intel_shader(builder->vs.shader);
346 const struct intel_shader *gs = intel_shader(builder->gs.shader);
347 int vs_entry_size, gs_entry_size;
348 int vs_size, gs_size;
349
350 INTEL_GPU_ASSERT(builder->gpu, 6, 6);
351
352 vs_entry_size = ((vs->in_count >= vs->out_count) ?
353 vs->in_count : vs->out_count);
354 gs_entry_size = (gs) ? gs->out_count : 0;
355
356 /* in bytes */
357 vs_entry_size *= sizeof(float) * 4;
358 gs_entry_size *= sizeof(float) * 4;
359
360 if (gs) {
361 vs_size = urb_size / 2;
362 gs_size = vs_size;
363 } else {
364 vs_size = urb_size;
365 gs_size = 0;
366 }
367
368 /* 3DSTATE_URB */
369 {
370 const uint8_t cmd_len = 3;
371 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_URB) |
372 (cmd_len - 2);
373 int vs_alloc_size, gs_alloc_size;
374 int vs_entry_count, gs_entry_count;
375 uint32_t *dw;
376
377 /* in 1024-bit rows */
378 vs_alloc_size = (vs_entry_size + 128 - 1) / 128;
379 gs_alloc_size = (gs_entry_size + 128 - 1) / 128;
380
381 /* valid range is [1, 5] */
382 if (!vs_alloc_size)
383 vs_alloc_size = 1;
384 if (!gs_alloc_size)
385 gs_alloc_size = 1;
386 assert(vs_alloc_size <= 5 && gs_alloc_size <= 5);
387
388 /* valid range is [24, 256], multiples of 4 */
389 vs_entry_count = (vs_size / 128 / vs_alloc_size) & ~3;
390 if (vs_entry_count > 256)
391 vs_entry_count = 256;
392 assert(vs_entry_count >= 24);
393
394 /* valid range is [0, 256], multiples of 4 */
395 gs_entry_count = (gs_size / 128 / gs_alloc_size) & ~3;
396 if (gs_entry_count > 256)
397 gs_entry_count = 256;
398
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600399 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800400
401 dw[0] = dw0;
402 dw[1] = (vs_alloc_size - 1) << GEN6_URB_DW1_VS_ENTRY_SIZE__SHIFT |
403 vs_entry_count << GEN6_URB_DW1_VS_ENTRY_COUNT__SHIFT;
404 dw[2] = gs_entry_count << GEN6_URB_DW2_GS_ENTRY_COUNT__SHIFT |
405 (gs_alloc_size - 1) << GEN6_URB_DW2_GS_ENTRY_SIZE__SHIFT;
406 }
407}
408
409static void builder_build_urb_alloc_gen7(struct intel_pipeline_builder *builder,
410 struct intel_pipeline *pipeline)
411{
412 const int urb_size = ((builder->gpu->gt == 3) ? 512 :
413 (builder->gpu->gt == 2) ? 256 : 128) * 1024;
414 const struct intel_shader *vs = intel_shader(builder->vs.shader);
415 const struct intel_shader *gs = intel_shader(builder->gs.shader);
416 /* some space is reserved for PCBs */
417 int urb_offset = ((builder->gpu->gt == 3) ? 32 : 16) * 1024;
418 int vs_entry_size, gs_entry_size;
419 int vs_size, gs_size;
420
421 INTEL_GPU_ASSERT(builder->gpu, 7, 7.5);
422
423 vs_entry_size = ((vs->in_count >= vs->out_count) ?
424 vs->in_count : vs->out_count);
425 gs_entry_size = (gs) ? gs->out_count : 0;
426
427 /* in bytes */
428 vs_entry_size *= sizeof(float) * 4;
429 gs_entry_size *= sizeof(float) * 4;
430
431 if (gs) {
432 vs_size = (urb_size - urb_offset) / 2;
433 gs_size = vs_size;
434 } else {
435 vs_size = urb_size - urb_offset;
436 gs_size = 0;
437 }
438
439 /* 3DSTATE_URB_* */
440 {
441 const uint8_t cmd_len = 2;
442 int vs_alloc_size, gs_alloc_size;
443 int vs_entry_count, gs_entry_count;
444 uint32_t *dw;
445
446 /* in 512-bit rows */
447 vs_alloc_size = (vs_entry_size + 64 - 1) / 64;
448 gs_alloc_size = (gs_entry_size + 64 - 1) / 64;
449
450 if (!vs_alloc_size)
451 vs_alloc_size = 1;
452 if (!gs_alloc_size)
453 gs_alloc_size = 1;
454
455 /* avoid performance decrease due to banking */
456 if (vs_alloc_size == 5)
457 vs_alloc_size = 6;
458
459 /* in multiples of 8 */
460 vs_entry_count = (vs_size / 64 / vs_alloc_size) & ~7;
461 assert(vs_entry_count >= 32);
462
463 gs_entry_count = (gs_size / 64 / gs_alloc_size) & ~7;
464
465 if (intel_gpu_gen(builder->gpu) >= INTEL_GEN(7.5)) {
466 const int max_vs_entry_count =
Chia-I Wuc137a152014-08-31 12:26:39 +0800467 (builder->gpu->gt >= 2) ? 1664 : 640;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800468 const int max_gs_entry_count =
469 (builder->gpu->gt >= 2) ? 640 : 256;
470 if (vs_entry_count >= max_vs_entry_count)
471 vs_entry_count = max_vs_entry_count;
472 if (gs_entry_count >= max_gs_entry_count)
473 gs_entry_count = max_gs_entry_count;
474 } else {
475 const int max_vs_entry_count =
476 (builder->gpu->gt == 2) ? 704 : 512;
477 const int max_gs_entry_count =
478 (builder->gpu->gt == 2) ? 320 : 192;
479 if (vs_entry_count >= max_vs_entry_count)
480 vs_entry_count = max_vs_entry_count;
481 if (gs_entry_count >= max_gs_entry_count)
482 gs_entry_count = max_gs_entry_count;
483 }
484
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600485 dw = pipeline_cmd_ptr(pipeline, cmd_len*4);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800486 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_VS) | (cmd_len - 2);
487 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT |
488 (vs_alloc_size - 1) << GEN7_URB_ANY_DW1_ENTRY_SIZE__SHIFT |
489 vs_entry_count;
490
491 dw += 2;
492 if (gs_size)
493 urb_offset += vs_size;
494 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_GS) | (cmd_len - 2);
495 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT |
496 (gs_alloc_size - 1) << GEN7_URB_ANY_DW1_ENTRY_SIZE__SHIFT |
497 gs_entry_count;
498
499 dw += 2;
500 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_HS) | (cmd_len - 2);
501 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT;
502
503 dw += 2;
504 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_DS) | (cmd_len - 2);
505 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT;
506 }
507}
508
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600509static void builder_build_push_const_alloc_gen7(struct intel_pipeline_builder *builder,
510 struct intel_pipeline *p)
511{
512 const uint8_t cmd_len = 2;
513 uint32_t offset = 0;
514 uint32_t size = 8192;
515 uint32_t *dw;
516 int end;
517
Chia-I Wu480d33b2014-08-29 10:26:14 +0800518 INTEL_GPU_ASSERT(builder->gpu, 7, 7.5);
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600519
520 /*
521 * From the Ivy Bridge PRM, volume 2 part 1, page 68:
522 *
523 * "(A table that says the maximum size of each constant buffer is
524 * 16KB")
525 *
526 * From the Ivy Bridge PRM, volume 2 part 1, page 115:
527 *
528 * "The sum of the Constant Buffer Offset and the Constant Buffer Size
529 * may not exceed the maximum value of the Constant Buffer Size."
530 *
531 * Thus, the valid range of buffer end is [0KB, 16KB].
532 */
533 end = (offset + size) / 1024;
534 if (end > 16) {
535 assert(!"invalid constant buffer end");
536 end = 16;
537 }
538
539 /* the valid range of buffer offset is [0KB, 15KB] */
540 offset = (offset + 1023) / 1024;
541 if (offset > 15) {
542 assert(!"invalid constant buffer offset");
543 offset = 15;
544 }
545
546 if (offset > end) {
547 assert(!size);
548 offset = end;
549 }
550
551 /* the valid range of buffer size is [0KB, 15KB] */
552 size = end - offset;
553 if (size > 15) {
554 assert(!"invalid constant buffer size");
555 size = 15;
556 }
557
558 dw = pipeline_cmd_ptr(p, cmd_len * 5);
559 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_VS) | (cmd_len - 2);
560 dw[1] = offset << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
561 size << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
562
563 dw += 2;
564 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_PS) | (cmd_len - 2);
565 dw[1] = size << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
566 size << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
567
568 dw += 2;
569 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_HS) | (cmd_len - 2);
570 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
571 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
572
573 dw += 2;
574 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_DS) | (cmd_len - 2);
575 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
576 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
577
578 dw += 2;
579 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_GS) | (cmd_len - 2);
580 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
581 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
Chia-I Wu8370b402014-08-29 12:28:37 +0800582
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600583 // gen7_wa_pipe_control_cs_stall(p, true, true);
584 // looks equivalent to: gen6_wa_wm_multisample_flush - this does more
585 // than the documentation seems to imply
586}
587
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800588static void builder_build_vertex_elements(struct intel_pipeline_builder *builder,
589 struct intel_pipeline *pipeline)
590{
591 const uint8_t cmd_len = 3;
592 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_ELEMENTS) |
593 (cmd_len - 2);
594 const struct intel_shader *vs = intel_shader(builder->vs.shader);
595 int comps[4] = { GEN6_VFCOMP_NOSTORE, GEN6_VFCOMP_NOSTORE,
596 GEN6_VFCOMP_NOSTORE, GEN6_VFCOMP_NOSTORE };
597 uint32_t *dw;
598
599 INTEL_GPU_ASSERT(builder->gpu, 6, 7.5);
600
601 if (!(vs->uses & (INTEL_SHADER_USE_VID | INTEL_SHADER_USE_IID)))
602 return;
603
604 dw = pipeline_cmd_ptr(pipeline, cmd_len);
605 dw[0] = dw0;
606 dw++;
607
608 comps[0] = (vs->uses & INTEL_SHADER_USE_VID) ?
609 GEN6_VFCOMP_STORE_VID : GEN6_VFCOMP_STORE_0;
610 if (vs->uses & INTEL_SHADER_USE_IID)
611 comps[1] = GEN6_VFCOMP_STORE_IID;
612
613 /* VERTEX_ELEMENT_STATE */
614 dw[0] = GEN6_VE_STATE_DW0_VALID;
615 dw[1] = comps[0] << GEN6_VE_STATE_DW1_COMP0__SHIFT |
616 comps[1] << GEN6_VE_STATE_DW1_COMP1__SHIFT |
617 comps[2] << GEN6_VE_STATE_DW1_COMP2__SHIFT |
618 comps[3] << GEN6_VE_STATE_DW1_COMP3__SHIFT;
619}
620
621
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600622static void gen7_pipeline_gs(struct intel_pipeline_builder *builder,
623 struct intel_pipeline *pipeline)
624{
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600625 // gen7_emit_3DSTATE_GS done by cmd_pipeline
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600626}
627
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600628static void
629gen7_emit_3DSTATE_HS(struct intel_pipeline_builder *builder,
630 struct intel_pipeline *p)
631{
632 const uint8_t cmd_len = 7;
633 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
634 uint32_t *dw;
635
Chia-I Wu480d33b2014-08-29 10:26:14 +0800636 INTEL_GPU_ASSERT(builder->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600637
638 dw = pipeline_cmd_ptr(p, cmd_len);
639 dw[0] = dw0;
640 dw[1] = 0;
641 dw[2] = 0;
642 dw[3] = 0;
643 dw[4] = 0;
644 dw[5] = 0;
645 dw[6] = 0;
646}
647
648static void gen7_pipeline_hs(struct intel_pipeline_builder *builder,
649 struct intel_pipeline *pipeline)
650{
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600651 gen7_emit_3DSTATE_HS(builder, pipeline);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600652}
653
654static void gen7_pipeline_te(struct intel_pipeline_builder *builder,
655 struct intel_pipeline *p)
656{
657 const uint8_t cmd_len = 4;
658 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_TE) | (cmd_len - 2);
659 uint32_t *dw;
660
Chia-I Wu480d33b2014-08-29 10:26:14 +0800661 INTEL_GPU_ASSERT(builder->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600662
663 dw = pipeline_cmd_ptr(p, cmd_len);
664 dw[0] = dw0;
665 dw[1] = 0;
666 dw[2] = 0;
667 dw[3] = 0;
668}
669
670static void gen7_pipeline_ds(struct intel_pipeline_builder *builder,
671 struct intel_pipeline *p)
672{
673 const uint8_t cmd_len = 6;
674 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
675 uint32_t *dw;
676
Chia-I Wu480d33b2014-08-29 10:26:14 +0800677 INTEL_GPU_ASSERT(builder->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600678
679 dw = pipeline_cmd_ptr(p, cmd_len);
680 dw[0] = dw0;
681 dw[1] = 0;
682 dw[2] = 0;
683 dw[3] = 0;
684 dw[4] = 0;
685 dw[5] = 0;
686}
687
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800688static XGL_RESULT builder_build_all(struct intel_pipeline_builder *builder,
689 struct intel_pipeline *pipeline)
Chia-I Wu3efef432014-08-28 15:00:16 +0800690{
691 XGL_RESULT ret;
692
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800693 builder_build_vertex_elements(builder, pipeline);
694
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800695 if (intel_gpu_gen(builder->gpu) >= INTEL_GEN(7)) {
696 builder_build_urb_alloc_gen7(builder, pipeline);
Courtney Goeltzenleuchter68d9bef2014-08-28 17:35:03 -0600697 builder_build_push_const_alloc_gen7(builder, pipeline);
698 gen7_pipeline_gs(builder, pipeline);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600699 gen7_pipeline_hs(builder, pipeline);
700 gen7_pipeline_te(builder, pipeline);
701 gen7_pipeline_ds(builder, pipeline);
Chia-I Wu8370b402014-08-29 12:28:37 +0800702
703 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
704 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL |
705 INTEL_CMD_WA_GEN7_PRE_VS_DEPTH_STALL_WRITE |
706 INTEL_CMD_WA_GEN7_POST_COMMAND_CS_STALL |
707 INTEL_CMD_WA_GEN7_POST_COMMAND_DEPTH_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800708 } else {
709 builder_build_urb_alloc_gen6(builder, pipeline);
Chia-I Wu8370b402014-08-29 12:28:37 +0800710
711 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
712 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800713 }
714
Chia-I Wu3efef432014-08-28 15:00:16 +0800715 ret = pipeline_ia_state(pipeline, &builder->ia);
716
717 if (ret == XGL_SUCCESS)
718 ret = pipeline_rs_state(pipeline, &builder->rs);
719
720 if (ret == XGL_SUCCESS && builder->vs.shader)
721 ret = pipeline_shader(pipeline, &builder->vs);
722 if (ret == XGL_SUCCESS && builder->tcs.shader)
723 ret = pipeline_shader(pipeline, &builder->tcs);
724 if (ret == XGL_SUCCESS && builder->tes.shader)
725 ret = pipeline_shader(pipeline, &builder->tes);
726 if (ret == XGL_SUCCESS && builder->gs.shader)
727 ret = pipeline_shader(pipeline, &builder->gs);
728 if (ret == XGL_SUCCESS && builder->fs.shader)
729 ret = pipeline_shader(pipeline, &builder->fs);
730
731 if (ret == XGL_SUCCESS) {
732 pipeline->db_format = builder->db.format;
733 pipeline->cb_state = builder->cb;
734 pipeline->tess_state = builder->tess;
735 }
736
737 return ret;
738}
739
740static XGL_RESULT builder_init(struct intel_pipeline_builder *builder,
741 const struct intel_gpu *gpu,
742 const struct intel_pipeline_builder_create_info *info)
743{
744 memset(builder, 0, sizeof(*builder));
745
746 builder->gpu = gpu;
747
748 while (info) {
749 const void *src = (const void *) info;
750 XGL_SIZE size;
751 void *dst;
752
753 switch (info->struct_type) {
754 case XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO:
755 size = sizeof(builder->graphics);
756 dst = &builder->graphics;
757 break;
758 case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
759 size = sizeof(builder->ia);
760 dst = &builder->ia;
761 break;
762 case XGL_STRUCTURE_TYPE_PIPELINE_DB_STATE_CREATE_INFO:
763 size = sizeof(builder->db);
764 dst = &builder->db;
765 break;
766 case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
767 size = sizeof(builder->cb);
768 dst = &builder->cb;
769 break;
770 case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
771 size = sizeof(builder->rs);
772 dst = &builder->rs;
773 break;
774 case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
775 size = sizeof(builder->tess);
776 dst = &builder->tess;
777 break;
778 case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
779 {
780 const XGL_PIPELINE_SHADER *shader = (const XGL_PIPELINE_SHADER *) (info + 1);
781
782 src = (const void *) shader;
783 size = sizeof(*shader);
784
785 switch (shader->stage) {
786 case XGL_SHADER_STAGE_VERTEX:
787 dst = &builder->vs;
788 break;
789 case XGL_SHADER_STAGE_TESS_CONTROL:
790 dst = &builder->tcs;
791 break;
792 case XGL_SHADER_STAGE_TESS_EVALUATION:
793 dst = &builder->tes;
794 break;
795 case XGL_SHADER_STAGE_GEOMETRY:
796 dst = &builder->gs;
797 break;
798 case XGL_SHADER_STAGE_FRAGMENT:
799 dst = &builder->fs;
800 break;
801 case XGL_SHADER_STAGE_COMPUTE:
802 dst = &builder->cs;
803 break;
804 default:
805 return XGL_ERROR_BAD_PIPELINE_DATA;
806 break;
807 }
808 }
809 break;
810 case XGL_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO:
811 size = sizeof(builder->compute);
812 dst = &builder->compute;
813 break;
814 default:
815 return XGL_ERROR_BAD_PIPELINE_DATA;
816 break;
817 }
818
819 memcpy(dst, src, size);
820
821 info = info->next;
822 }
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600823
824 return XGL_SUCCESS;
Chia-I Wu3efef432014-08-28 15:00:16 +0800825}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600826
Chia-I Wu3efef432014-08-28 15:00:16 +0800827static XGL_RESULT graphics_pipeline_create(struct intel_dev *dev,
828 const XGL_GRAPHICS_PIPELINE_CREATE_INFO *info,
829 struct intel_pipeline **pipeline_ret)
830{
831 struct intel_pipeline_builder builder;
832 struct intel_pipeline *pipeline;
833 XGL_RESULT ret;
834
835 ret = builder_init(&builder, dev->gpu,
836 (const struct intel_pipeline_builder_create_info *) info);
837 if (ret != XGL_SUCCESS)
838 return ret;
839
840 pipeline = (struct intel_pipeline *)
841 intel_base_create(dev, sizeof(*pipeline), dev->base.dbg,
842 XGL_DBG_OBJECT_GRAPHICS_PIPELINE, info, 0);
843 if (!pipeline)
844 return XGL_ERROR_OUT_OF_MEMORY;
845
846 pipeline->dev = dev;
847 pipeline->obj.destroy = pipeline_destroy;
Chia-I Wu3efef432014-08-28 15:00:16 +0800848
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800849 ret = builder_build_all(&builder, pipeline);
Chia-I Wu3efef432014-08-28 15:00:16 +0800850 if (ret == XGL_SUCCESS)
851 ret = builder_validate(&builder, pipeline);
852 if (ret != XGL_SUCCESS) {
853 pipeline_destroy(&pipeline->obj);
854 return ret;
855 }
856
857 *pipeline_ret = pipeline;
858
859 return XGL_SUCCESS;
860}
861
862XGL_RESULT XGLAPI intelCreateGraphicsPipeline(
863 XGL_DEVICE device,
864 const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
865 XGL_PIPELINE* pPipeline)
866{
867 struct intel_dev *dev = intel_dev(device);
868
869 return graphics_pipeline_create(dev, pCreateInfo,
870 (struct intel_pipeline **) pPipeline);
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600871}
872
873XGL_RESULT XGLAPI intelCreateComputePipeline(
874 XGL_DEVICE device,
875 const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo,
876 XGL_PIPELINE* pPipeline)
877{
878 return XGL_ERROR_UNAVAILABLE;
879}
880
881XGL_RESULT XGLAPI intelStorePipeline(
882 XGL_PIPELINE pipeline,
883 XGL_SIZE* pDataSize,
884 XGL_VOID* pData)
885{
886 return XGL_ERROR_UNAVAILABLE;
887}
888
889XGL_RESULT XGLAPI intelLoadPipeline(
890 XGL_DEVICE device,
891 XGL_SIZE dataSize,
892 const XGL_VOID* pData,
893 XGL_PIPELINE* pPipeline)
894{
895 return XGL_ERROR_UNAVAILABLE;
896}
897
898XGL_RESULT XGLAPI intelCreatePipelineDelta(
899 XGL_DEVICE device,
900 XGL_PIPELINE p1,
901 XGL_PIPELINE p2,
902 XGL_PIPELINE_DELTA* delta)
903{
904 return XGL_ERROR_UNAVAILABLE;
905}