blob: 964618130e59f284ede655afae33548dccda9ba9 [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"
30
31#include "cmd.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
Chia-I Wu3efef432014-08-28 15:00:16 +080035struct intel_pipeline_builder {
36 const struct intel_gpu *gpu;
37
38 XGL_GRAPHICS_PIPELINE_CREATE_INFO graphics;
39 XGL_PIPELINE_IA_STATE_CREATE_INFO ia;
40 XGL_PIPELINE_DB_STATE_CREATE_INFO db;
41 XGL_PIPELINE_CB_STATE cb;
42 XGL_PIPELINE_RS_STATE_CREATE_INFO rs;
43 XGL_PIPELINE_TESS_STATE_CREATE_INFO tess;
44 XGL_PIPELINE_SHADER vs;
45 XGL_PIPELINE_SHADER tcs;
46 XGL_PIPELINE_SHADER tes;
47 XGL_PIPELINE_SHADER gs;
48 XGL_PIPELINE_SHADER fs;
49
50 XGL_COMPUTE_PIPELINE_CREATE_INFO compute;
51 XGL_PIPELINE_SHADER cs;
52};
53
54struct intel_pipeline_builder_create_info {
55 XGL_STRUCTURE_TYPE struct_type;
56 XGL_VOID *next;
57};
58
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -060059static uint32_t *pipeline_cmd_ptr(struct intel_pipeline *pipeline, int cmd_len)
60{
61 uint32_t *ptr;
62
63 assert(pipeline->cmd_len + cmd_len < INTEL_PSO_CMD_ENTRIES);
64 ptr = &pipeline->cmds[pipeline->cmd_len];
65 pipeline->cmd_len += cmd_len;
66 return ptr;
67}
68
Chia-I Wu3efef432014-08-28 15:00:16 +080069static XGL_RESULT pipeline_ia_state(struct intel_pipeline *pipeline,
70 const XGL_PIPELINE_IA_STATE_CREATE_INFO* ia_state)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060071{
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -060072 pipeline->ia_state = *ia_state;
73
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060074 if (ia_state->provokingVertex == XGL_PROVOKING_VERTEX_FIRST) {
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060075 pipeline->provoking_vertex_tri = 0;
76 pipeline->provoking_vertex_trifan = 1;
77 pipeline->provoking_vertex_line = 0;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060078 } else {
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060079 pipeline->provoking_vertex_tri = 2;
80 pipeline->provoking_vertex_trifan = 2;
81 pipeline->provoking_vertex_line = 1;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060082 }
83
84 switch (ia_state->topology) {
85 case XGL_TOPOLOGY_POINT_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060086 pipeline->prim_type = GEN6_3DPRIM_POINTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060087 break;
88 case XGL_TOPOLOGY_LINE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060089 pipeline->prim_type = GEN6_3DPRIM_LINELIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060090 break;
91 case XGL_TOPOLOGY_LINE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060092 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060093 break;
94 case XGL_TOPOLOGY_TRIANGLE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060095 pipeline->prim_type = GEN6_3DPRIM_TRILIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060096 break;
97 case XGL_TOPOLOGY_TRIANGLE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060098 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060099 break;
100 case XGL_TOPOLOGY_RECT_LIST:
101 /*
102 * TODO: Rect lists are special in XGL, do we need to do
103 * something special here?
104 * XGL Guide:
105 * The rectangle list is a special geometry primitive type
106 * that can be used for implementing post-processing techniques
107 * or efficient copy operations. There are some special limitations
108 * for rectangle primitives. They cannot be clipped, must
109 * be axis aligned and cannot have depth gradient.
110 * Failure to comply with these restrictions results in
111 * undefined rendering results.
112 */
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600113 pipeline->prim_type = GEN6_3DPRIM_RECTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600114 break;
115 case XGL_TOPOLOGY_QUAD_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600116 pipeline->prim_type = GEN6_3DPRIM_QUADLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600117 break;
118 case XGL_TOPOLOGY_QUAD_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600119 pipeline->prim_type = GEN6_3DPRIM_QUADSTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600120 break;
121 case XGL_TOPOLOGY_LINE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600122 pipeline->prim_type = GEN6_3DPRIM_LINELIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600123 break;
124 case XGL_TOPOLOGY_LINE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600125 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600126 break;
127 case XGL_TOPOLOGY_TRIANGLE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600128 pipeline->prim_type = GEN6_3DPRIM_TRILIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600129 break;
130 case XGL_TOPOLOGY_TRIANGLE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600131 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600132 break;
133 case XGL_TOPOLOGY_PATCH:
134 // TODO: implement something here
135 break;
136 default:
137 return XGL_ERROR_BAD_PIPELINE_DATA;
138 }
139
140 if (ia_state->primitiveRestartEnable) {
141 pipeline->primitive_restart = true;
142 pipeline->primitive_restart_index = ia_state->primitiveRestartIndex;
143 } else {
144 pipeline->primitive_restart = false;
145 }
146
147 if (ia_state->disableVertexReuse) {
148 // TODO: What do we do to disable vertex reuse?
149 }
150
151 return XGL_SUCCESS;
152}
153
Chia-I Wu3efef432014-08-28 15:00:16 +0800154static XGL_RESULT pipeline_rs_state(struct intel_pipeline *pipeline,
155 const XGL_PIPELINE_RS_STATE_CREATE_INFO* rs_state)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600156{
157 pipeline->depthClipEnable = rs_state->depthClipEnable;
158 pipeline->rasterizerDiscardEnable = rs_state->rasterizerDiscardEnable;
159 pipeline->pointSize = rs_state->pointSize;
160 return XGL_SUCCESS;
161}
162
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600163static void pipeline_destroy(struct intel_obj *obj)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600164{
165 struct intel_pipeline *pipeline = intel_pipeline_from_obj(obj);
166
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -0600167 if (pipeline->active_shaders & SHADER_VERTEX_FLAG) {
Chia-I Wu282d3bc2014-08-28 15:36:44 +0800168 icd_free(pipeline->intel_vs.pCode);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -0600169 }
170 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
Chia-I Wu282d3bc2014-08-28 15:36:44 +0800171 icd_free(pipeline->gs.pCode);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -0600172 }
173 if (pipeline->active_shaders & SHADER_FRAGMENT_FLAG) {
Chia-I Wu282d3bc2014-08-28 15:36:44 +0800174 icd_free(pipeline->intel_fs.pCode);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -0600175 }
176 if (pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) {
Chia-I Wu282d3bc2014-08-28 15:36:44 +0800177 icd_free(pipeline->tess_control.pCode);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -0600178 }
179 if (pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) {
Chia-I Wu282d3bc2014-08-28 15:36:44 +0800180 icd_free(pipeline->tess_eval.pCode);
Courtney Goeltzenleuchterd85c1d62014-08-27 14:04:53 -0600181 }
182
Chia-I Wued833872014-08-23 17:00:35 +0800183 if (pipeline->vs_rmap)
184 intel_rmap_destroy(pipeline->vs_rmap);
185 if (pipeline->fs_rmap)
186 intel_rmap_destroy(pipeline->fs_rmap);
187
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600188 intel_base_destroy(&pipeline->obj.base);
189}
190
Courtney Goeltzenleuchterc4ef6142014-08-29 16:25:30 -0600191static void intel_pipe_shader_init(struct intel_shader *sh,
192 struct intel_pipe_shader *pipe_sh)
193{
194 pipe_sh->in_count = sh->in_count;
195 pipe_sh->out_count = sh->out_count;
196 pipe_sh->sampler_count = sh->sampler_count;
197 pipe_sh->surface_count = sh->surface_count;
198 pipe_sh->barycentric_interps = sh->barycentric_interps;
199 pipe_sh->urb_read_length = sh->urb_read_length;
200 pipe_sh->urb_grf_start = sh->urb_grf_start;
201 pipe_sh->uses = sh->uses;
202}
203
Chia-I Wu3efef432014-08-28 15:00:16 +0800204static XGL_RESULT pipeline_shader(struct intel_pipeline *pipeline,
205 const XGL_PIPELINE_SHADER *info)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600206{
Chia-I Wu3efef432014-08-28 15:00:16 +0800207 struct intel_shader *sh = intel_shader(info->shader);
208 void *kernel;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600209
Chia-I Wu3efef432014-08-28 15:00:16 +0800210 // TODO: process shader object and include in pipeline
211 // For now that processing is simply a copy so that the app
212 // can destroy the original shader object after pipeline creation.
213 kernel = icd_alloc(sh->ir->size, 0, XGL_SYSTEM_ALLOC_INTERNAL_SHADER);
214 if (!kernel)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600215 return XGL_ERROR_OUT_OF_MEMORY;
Chia-I Wu3efef432014-08-28 15:00:16 +0800216
Courtney Goeltzenleuchterc4ef6142014-08-29 16:25:30 -0600217 // TODO: This should be a compile step
218 memcpy(kernel, sh->ir->kernel, sh->ir->size);
219
Chia-I Wu3efef432014-08-28 15:00:16 +0800220 switch (info->stage) {
221 case XGL_SHADER_STAGE_VERTEX:
222 /*
223 * TODO: What should we do here?
224 * shader_state (XGL_PIPELINE_SHADER) contains links
225 * to application memory in the pLinkConstBufferInfo and
226 * it's pBufferData pointers. Do we need to bring all that
227 * into the driver or is it okay to rely on those references
228 * holding good data. In OpenGL we'd make a driver copy. Not
229 * as clear for XGL.
230 * For now, use the app pointers.
231 */
232 pipeline->vs = *info;
Courtney Goeltzenleuchterc4ef6142014-08-29 16:25:30 -0600233
234 /*
235 * Grab what we need from the intel_shader object as that
236 * could go away after the pipeline is created.
237 */
238 intel_pipe_shader_init(sh, &pipeline->intel_vs);
Chia-I Wu3efef432014-08-28 15:00:16 +0800239 pipeline->intel_vs.pCode = kernel;
240 pipeline->intel_vs.codeSize = sh->ir->size;
241 pipeline->active_shaders |= SHADER_VERTEX_FLAG;
242 pipeline->vs_rmap = intel_rmap_create(pipeline->dev,
243 &info->descriptorSetMapping[0],
244 &info->dynamicMemoryViewMapping, 0);
245 if (!pipeline->vs_rmap) {
246 icd_free(kernel);
247 return XGL_ERROR_OUT_OF_MEMORY;
248 }
249 break;
250 case XGL_SHADER_STAGE_GEOMETRY:
Courtney Goeltzenleuchterc4ef6142014-08-29 16:25:30 -0600251 intel_pipe_shader_init(sh, &pipeline->gs);
Chia-I Wu3efef432014-08-28 15:00:16 +0800252 pipeline->gs.pCode = kernel;
253 pipeline->gs.codeSize = sh->ir->size;
254 pipeline->active_shaders |= SHADER_GEOMETRY_FLAG;
255 break;
256 case XGL_SHADER_STAGE_FRAGMENT:
257 pipeline->fs = *info;
Courtney Goeltzenleuchterc4ef6142014-08-29 16:25:30 -0600258 intel_pipe_shader_init(sh, &pipeline->intel_fs);
Chia-I Wu3efef432014-08-28 15:00:16 +0800259 pipeline->intel_fs.pCode = kernel;
260 pipeline->intel_fs.codeSize = sh->ir->size;
261 pipeline->active_shaders |= SHADER_FRAGMENT_FLAG;
262 /* assuming one RT; need to parse the shader */
263 pipeline->fs_rmap = intel_rmap_create(pipeline->dev,
264 &info->descriptorSetMapping[0],
265 &info->dynamicMemoryViewMapping, 1);
266 if (!pipeline->fs_rmap) {
267 icd_free(kernel);
268 return XGL_ERROR_OUT_OF_MEMORY;
269 }
270 break;
271 case XGL_SHADER_STAGE_TESS_CONTROL:
Courtney Goeltzenleuchterc4ef6142014-08-29 16:25:30 -0600272 intel_pipe_shader_init(sh, &pipeline->tess_control);
Chia-I Wu3efef432014-08-28 15:00:16 +0800273 pipeline->tess_control.pCode = kernel;
274 pipeline->tess_control.codeSize = sh->ir->size;
275 pipeline->active_shaders |= SHADER_TESS_CONTROL_FLAG;
276 break;
277 case XGL_SHADER_STAGE_TESS_EVALUATION:
Courtney Goeltzenleuchterc4ef6142014-08-29 16:25:30 -0600278 intel_pipe_shader_init(sh, &pipeline->tess_eval);
Chia-I Wu3efef432014-08-28 15:00:16 +0800279 pipeline->tess_eval.pCode = kernel;
280 pipeline->tess_eval.codeSize = sh->ir->size;
281 pipeline->active_shaders |= SHADER_TESS_EVAL_FLAG;
282 break;
283 case XGL_SHADER_STAGE_COMPUTE:
Courtney Goeltzenleuchterc4ef6142014-08-29 16:25:30 -0600284 intel_pipe_shader_init(sh, &pipeline->compute);
Chia-I Wu3efef432014-08-28 15:00:16 +0800285 pipeline->compute.pCode = kernel;
286 pipeline->compute.codeSize = sh->ir->size;
287 pipeline->active_shaders |= SHADER_COMPUTE_FLAG;
288 break;
289 default:
290 assert(!"unknown shader stage");
291 break;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600292 }
293
Chia-I Wu3efef432014-08-28 15:00:16 +0800294 return XGL_SUCCESS;
295}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600296
Chia-I Wu3efef432014-08-28 15:00:16 +0800297static XGL_RESULT builder_validate(const struct intel_pipeline_builder *builder,
298 const struct intel_pipeline *pipeline)
299{
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600300 /*
301 * Validate required elements
302 */
303 if (!(pipeline->active_shaders & SHADER_VERTEX_FLAG)) {
304 // TODO: Log debug message: Vertex Shader required.
Chia-I Wu3efef432014-08-28 15:00:16 +0800305 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600306 }
307
308 /*
309 * Tessalation control and evaluation have to both have a shader defined or
310 * neither should have a shader defined.
311 */
312 if (((pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) == 0) !=
313 ((pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) == 0) ) {
314 // TODO: Log debug message: Both Tess control and Tess eval are required to use tessalation
Chia-I Wu3efef432014-08-28 15:00:16 +0800315 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600316 }
317
318 if ((pipeline->active_shaders & SHADER_COMPUTE_FLAG) &&
319 (pipeline->active_shaders & (SHADER_VERTEX_FLAG | SHADER_TESS_CONTROL_FLAG |
320 SHADER_TESS_EVAL_FLAG | SHADER_GEOMETRY_FLAG |
321 SHADER_FRAGMENT_FLAG))) {
322 // TODO: Log debug message: Can only specify compute shader when doing compute
Chia-I Wu3efef432014-08-28 15:00:16 +0800323 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600324 }
325
326 /*
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600327 * XGL_TOPOLOGY_PATCH primitive topology is only valid for tessellation pipelines.
328 * Mismatching primitive topology and tessellation fails graphics pipeline creation.
329 */
330 if (pipeline->active_shaders & (SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG) &&
331 (pipeline->ia_state.topology != XGL_TOPOLOGY_PATCH)) {
332 // TODO: Log debug message: Invalid topology used with tessalation shader.
Chia-I Wu3efef432014-08-28 15:00:16 +0800333 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600334 }
335
336 if ((pipeline->ia_state.topology == XGL_TOPOLOGY_PATCH) &&
337 (pipeline->active_shaders & ~(SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG))) {
338 // TODO: Log debug message: Cannot use TOPOLOGY_PATCH on non-tessalation shader.
Chia-I Wu3efef432014-08-28 15:00:16 +0800339 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600340 }
341
Chia-I Wu3efef432014-08-28 15:00:16 +0800342 return XGL_SUCCESS;
343}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600344
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800345static void builder_build_urb_alloc_gen6(struct intel_pipeline_builder *builder,
346 struct intel_pipeline *pipeline)
347{
348 const int urb_size = ((builder->gpu->gt == 2) ? 64 : 32) * 1024;
349 const struct intel_shader *vs = intel_shader(builder->vs.shader);
350 const struct intel_shader *gs = intel_shader(builder->gs.shader);
351 int vs_entry_size, gs_entry_size;
352 int vs_size, gs_size;
353
354 INTEL_GPU_ASSERT(builder->gpu, 6, 6);
355
356 vs_entry_size = ((vs->in_count >= vs->out_count) ?
357 vs->in_count : vs->out_count);
358 gs_entry_size = (gs) ? gs->out_count : 0;
359
360 /* in bytes */
361 vs_entry_size *= sizeof(float) * 4;
362 gs_entry_size *= sizeof(float) * 4;
363
364 if (gs) {
365 vs_size = urb_size / 2;
366 gs_size = vs_size;
367 } else {
368 vs_size = urb_size;
369 gs_size = 0;
370 }
371
372 /* 3DSTATE_URB */
373 {
374 const uint8_t cmd_len = 3;
375 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_URB) |
376 (cmd_len - 2);
377 int vs_alloc_size, gs_alloc_size;
378 int vs_entry_count, gs_entry_count;
379 uint32_t *dw;
380
381 /* in 1024-bit rows */
382 vs_alloc_size = (vs_entry_size + 128 - 1) / 128;
383 gs_alloc_size = (gs_entry_size + 128 - 1) / 128;
384
385 /* valid range is [1, 5] */
386 if (!vs_alloc_size)
387 vs_alloc_size = 1;
388 if (!gs_alloc_size)
389 gs_alloc_size = 1;
390 assert(vs_alloc_size <= 5 && gs_alloc_size <= 5);
391
392 /* valid range is [24, 256], multiples of 4 */
393 vs_entry_count = (vs_size / 128 / vs_alloc_size) & ~3;
394 if (vs_entry_count > 256)
395 vs_entry_count = 256;
396 assert(vs_entry_count >= 24);
397
398 /* valid range is [0, 256], multiples of 4 */
399 gs_entry_count = (gs_size / 128 / gs_alloc_size) & ~3;
400 if (gs_entry_count > 256)
401 gs_entry_count = 256;
402
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600403 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800404
405 dw[0] = dw0;
406 dw[1] = (vs_alloc_size - 1) << GEN6_URB_DW1_VS_ENTRY_SIZE__SHIFT |
407 vs_entry_count << GEN6_URB_DW1_VS_ENTRY_COUNT__SHIFT;
408 dw[2] = gs_entry_count << GEN6_URB_DW2_GS_ENTRY_COUNT__SHIFT |
409 (gs_alloc_size - 1) << GEN6_URB_DW2_GS_ENTRY_SIZE__SHIFT;
410 }
411}
412
413static void builder_build_urb_alloc_gen7(struct intel_pipeline_builder *builder,
414 struct intel_pipeline *pipeline)
415{
416 const int urb_size = ((builder->gpu->gt == 3) ? 512 :
417 (builder->gpu->gt == 2) ? 256 : 128) * 1024;
418 const struct intel_shader *vs = intel_shader(builder->vs.shader);
419 const struct intel_shader *gs = intel_shader(builder->gs.shader);
420 /* some space is reserved for PCBs */
421 int urb_offset = ((builder->gpu->gt == 3) ? 32 : 16) * 1024;
422 int vs_entry_size, gs_entry_size;
423 int vs_size, gs_size;
424
425 INTEL_GPU_ASSERT(builder->gpu, 7, 7.5);
426
427 vs_entry_size = ((vs->in_count >= vs->out_count) ?
428 vs->in_count : vs->out_count);
429 gs_entry_size = (gs) ? gs->out_count : 0;
430
431 /* in bytes */
432 vs_entry_size *= sizeof(float) * 4;
433 gs_entry_size *= sizeof(float) * 4;
434
435 if (gs) {
436 vs_size = (urb_size - urb_offset) / 2;
437 gs_size = vs_size;
438 } else {
439 vs_size = urb_size - urb_offset;
440 gs_size = 0;
441 }
442
443 /* 3DSTATE_URB_* */
444 {
445 const uint8_t cmd_len = 2;
446 int vs_alloc_size, gs_alloc_size;
447 int vs_entry_count, gs_entry_count;
448 uint32_t *dw;
449
450 /* in 512-bit rows */
451 vs_alloc_size = (vs_entry_size + 64 - 1) / 64;
452 gs_alloc_size = (gs_entry_size + 64 - 1) / 64;
453
454 if (!vs_alloc_size)
455 vs_alloc_size = 1;
456 if (!gs_alloc_size)
457 gs_alloc_size = 1;
458
459 /* avoid performance decrease due to banking */
460 if (vs_alloc_size == 5)
461 vs_alloc_size = 6;
462
463 /* in multiples of 8 */
464 vs_entry_count = (vs_size / 64 / vs_alloc_size) & ~7;
465 assert(vs_entry_count >= 32);
466
467 gs_entry_count = (gs_size / 64 / gs_alloc_size) & ~7;
468
469 if (intel_gpu_gen(builder->gpu) >= INTEL_GEN(7.5)) {
470 const int max_vs_entry_count =
Chia-I Wuc137a152014-08-31 12:26:39 +0800471 (builder->gpu->gt >= 2) ? 1664 : 640;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800472 const int max_gs_entry_count =
473 (builder->gpu->gt >= 2) ? 640 : 256;
474 if (vs_entry_count >= max_vs_entry_count)
475 vs_entry_count = max_vs_entry_count;
476 if (gs_entry_count >= max_gs_entry_count)
477 gs_entry_count = max_gs_entry_count;
478 } else {
479 const int max_vs_entry_count =
480 (builder->gpu->gt == 2) ? 704 : 512;
481 const int max_gs_entry_count =
482 (builder->gpu->gt == 2) ? 320 : 192;
483 if (vs_entry_count >= max_vs_entry_count)
484 vs_entry_count = max_vs_entry_count;
485 if (gs_entry_count >= max_gs_entry_count)
486 gs_entry_count = max_gs_entry_count;
487 }
488
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600489 dw = pipeline_cmd_ptr(pipeline, cmd_len*4);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800490 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_VS) | (cmd_len - 2);
491 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT |
492 (vs_alloc_size - 1) << GEN7_URB_ANY_DW1_ENTRY_SIZE__SHIFT |
493 vs_entry_count;
494
495 dw += 2;
496 if (gs_size)
497 urb_offset += vs_size;
498 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_GS) | (cmd_len - 2);
499 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT |
500 (gs_alloc_size - 1) << GEN7_URB_ANY_DW1_ENTRY_SIZE__SHIFT |
501 gs_entry_count;
502
503 dw += 2;
504 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_HS) | (cmd_len - 2);
505 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT;
506
507 dw += 2;
508 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_DS) | (cmd_len - 2);
509 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT;
510 }
511}
512
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600513static void builder_build_push_const_alloc_gen7(struct intel_pipeline_builder *builder,
514 struct intel_pipeline *p)
515{
516 const uint8_t cmd_len = 2;
517 uint32_t offset = 0;
518 uint32_t size = 8192;
519 uint32_t *dw;
520 int end;
521
Chia-I Wu480d33b2014-08-29 10:26:14 +0800522 INTEL_GPU_ASSERT(builder->gpu, 7, 7.5);
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600523
524 /*
525 * From the Ivy Bridge PRM, volume 2 part 1, page 68:
526 *
527 * "(A table that says the maximum size of each constant buffer is
528 * 16KB")
529 *
530 * From the Ivy Bridge PRM, volume 2 part 1, page 115:
531 *
532 * "The sum of the Constant Buffer Offset and the Constant Buffer Size
533 * may not exceed the maximum value of the Constant Buffer Size."
534 *
535 * Thus, the valid range of buffer end is [0KB, 16KB].
536 */
537 end = (offset + size) / 1024;
538 if (end > 16) {
539 assert(!"invalid constant buffer end");
540 end = 16;
541 }
542
543 /* the valid range of buffer offset is [0KB, 15KB] */
544 offset = (offset + 1023) / 1024;
545 if (offset > 15) {
546 assert(!"invalid constant buffer offset");
547 offset = 15;
548 }
549
550 if (offset > end) {
551 assert(!size);
552 offset = end;
553 }
554
555 /* the valid range of buffer size is [0KB, 15KB] */
556 size = end - offset;
557 if (size > 15) {
558 assert(!"invalid constant buffer size");
559 size = 15;
560 }
561
562 dw = pipeline_cmd_ptr(p, cmd_len * 5);
563 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_VS) | (cmd_len - 2);
564 dw[1] = offset << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
565 size << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
566
567 dw += 2;
568 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_PS) | (cmd_len - 2);
569 dw[1] = size << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
570 size << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
571
572 dw += 2;
573 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_HS) | (cmd_len - 2);
574 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
575 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
576
577 dw += 2;
578 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_DS) | (cmd_len - 2);
579 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
580 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
581
582 dw += 2;
583 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_GS) | (cmd_len - 2);
584 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
585 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
Chia-I Wu8370b402014-08-29 12:28:37 +0800586
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600587 // gen7_wa_pipe_control_cs_stall(p, true, true);
588 // looks equivalent to: gen6_wa_wm_multisample_flush - this does more
589 // than the documentation seems to imply
590}
591
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800592static void builder_build_vertex_elements(struct intel_pipeline_builder *builder,
593 struct intel_pipeline *pipeline)
594{
595 const uint8_t cmd_len = 3;
596 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_ELEMENTS) |
597 (cmd_len - 2);
598 const struct intel_shader *vs = intel_shader(builder->vs.shader);
599 int comps[4] = { GEN6_VFCOMP_NOSTORE, GEN6_VFCOMP_NOSTORE,
600 GEN6_VFCOMP_NOSTORE, GEN6_VFCOMP_NOSTORE };
601 uint32_t *dw;
602
603 INTEL_GPU_ASSERT(builder->gpu, 6, 7.5);
604
605 if (!(vs->uses & (INTEL_SHADER_USE_VID | INTEL_SHADER_USE_IID)))
606 return;
607
608 dw = pipeline_cmd_ptr(pipeline, cmd_len);
609 dw[0] = dw0;
610 dw++;
611
612 comps[0] = (vs->uses & INTEL_SHADER_USE_VID) ?
613 GEN6_VFCOMP_STORE_VID : GEN6_VFCOMP_STORE_0;
614 if (vs->uses & INTEL_SHADER_USE_IID)
615 comps[1] = GEN6_VFCOMP_STORE_IID;
616
617 /* VERTEX_ELEMENT_STATE */
618 dw[0] = GEN6_VE_STATE_DW0_VALID;
619 dw[1] = comps[0] << GEN6_VE_STATE_DW1_COMP0__SHIFT |
620 comps[1] << GEN6_VE_STATE_DW1_COMP1__SHIFT |
621 comps[2] << GEN6_VE_STATE_DW1_COMP2__SHIFT |
622 comps[3] << GEN6_VE_STATE_DW1_COMP3__SHIFT;
623}
624
625
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600626static void gen7_pipeline_gs(struct intel_pipeline_builder *builder,
627 struct intel_pipeline *pipeline)
628{
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600629 // gen7_emit_3DSTATE_GS done by cmd_pipeline
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600630}
631
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600632static void
633gen7_emit_3DSTATE_HS(struct intel_pipeline_builder *builder,
634 struct intel_pipeline *p)
635{
636 const uint8_t cmd_len = 7;
637 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
638 uint32_t *dw;
639
Chia-I Wu480d33b2014-08-29 10:26:14 +0800640 INTEL_GPU_ASSERT(builder->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600641
642 dw = pipeline_cmd_ptr(p, cmd_len);
643 dw[0] = dw0;
644 dw[1] = 0;
645 dw[2] = 0;
646 dw[3] = 0;
647 dw[4] = 0;
648 dw[5] = 0;
649 dw[6] = 0;
650}
651
652static void gen7_pipeline_hs(struct intel_pipeline_builder *builder,
653 struct intel_pipeline *pipeline)
654{
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600655 gen7_emit_3DSTATE_HS(builder, pipeline);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600656}
657
658static void gen7_pipeline_te(struct intel_pipeline_builder *builder,
659 struct intel_pipeline *p)
660{
661 const uint8_t cmd_len = 4;
662 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_TE) | (cmd_len - 2);
663 uint32_t *dw;
664
Chia-I Wu480d33b2014-08-29 10:26:14 +0800665 INTEL_GPU_ASSERT(builder->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600666
667 dw = pipeline_cmd_ptr(p, cmd_len);
668 dw[0] = dw0;
669 dw[1] = 0;
670 dw[2] = 0;
671 dw[3] = 0;
672}
673
674static void gen7_pipeline_ds(struct intel_pipeline_builder *builder,
675 struct intel_pipeline *p)
676{
677 const uint8_t cmd_len = 6;
678 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
679 uint32_t *dw;
680
Chia-I Wu480d33b2014-08-29 10:26:14 +0800681 INTEL_GPU_ASSERT(builder->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600682
683 dw = pipeline_cmd_ptr(p, cmd_len);
684 dw[0] = dw0;
685 dw[1] = 0;
686 dw[2] = 0;
687 dw[3] = 0;
688 dw[4] = 0;
689 dw[5] = 0;
690}
691
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800692static XGL_RESULT builder_build_all(struct intel_pipeline_builder *builder,
693 struct intel_pipeline *pipeline)
Chia-I Wu3efef432014-08-28 15:00:16 +0800694{
695 XGL_RESULT ret;
696
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800697 builder_build_vertex_elements(builder, pipeline);
698
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800699 if (intel_gpu_gen(builder->gpu) >= INTEL_GEN(7)) {
700 builder_build_urb_alloc_gen7(builder, pipeline);
Courtney Goeltzenleuchter68d9bef2014-08-28 17:35:03 -0600701 builder_build_push_const_alloc_gen7(builder, pipeline);
702 gen7_pipeline_gs(builder, pipeline);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600703 gen7_pipeline_hs(builder, pipeline);
704 gen7_pipeline_te(builder, pipeline);
705 gen7_pipeline_ds(builder, pipeline);
Chia-I Wu8370b402014-08-29 12:28:37 +0800706
707 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
708 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL |
709 INTEL_CMD_WA_GEN7_PRE_VS_DEPTH_STALL_WRITE |
710 INTEL_CMD_WA_GEN7_POST_COMMAND_CS_STALL |
711 INTEL_CMD_WA_GEN7_POST_COMMAND_DEPTH_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800712 } else {
713 builder_build_urb_alloc_gen6(builder, pipeline);
Chia-I Wu8370b402014-08-29 12:28:37 +0800714
715 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
716 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800717 }
718
Chia-I Wu3efef432014-08-28 15:00:16 +0800719 ret = pipeline_ia_state(pipeline, &builder->ia);
720
721 if (ret == XGL_SUCCESS)
722 ret = pipeline_rs_state(pipeline, &builder->rs);
723
724 if (ret == XGL_SUCCESS && builder->vs.shader)
725 ret = pipeline_shader(pipeline, &builder->vs);
726 if (ret == XGL_SUCCESS && builder->tcs.shader)
727 ret = pipeline_shader(pipeline, &builder->tcs);
728 if (ret == XGL_SUCCESS && builder->tes.shader)
729 ret = pipeline_shader(pipeline, &builder->tes);
730 if (ret == XGL_SUCCESS && builder->gs.shader)
731 ret = pipeline_shader(pipeline, &builder->gs);
732 if (ret == XGL_SUCCESS && builder->fs.shader)
733 ret = pipeline_shader(pipeline, &builder->fs);
734
735 if (ret == XGL_SUCCESS) {
736 pipeline->db_format = builder->db.format;
737 pipeline->cb_state = builder->cb;
738 pipeline->tess_state = builder->tess;
739 }
740
741 return ret;
742}
743
744static XGL_RESULT builder_init(struct intel_pipeline_builder *builder,
745 const struct intel_gpu *gpu,
746 const struct intel_pipeline_builder_create_info *info)
747{
748 memset(builder, 0, sizeof(*builder));
749
750 builder->gpu = gpu;
751
752 while (info) {
753 const void *src = (const void *) info;
754 XGL_SIZE size;
755 void *dst;
756
757 switch (info->struct_type) {
758 case XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO:
759 size = sizeof(builder->graphics);
760 dst = &builder->graphics;
761 break;
762 case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
763 size = sizeof(builder->ia);
764 dst = &builder->ia;
765 break;
766 case XGL_STRUCTURE_TYPE_PIPELINE_DB_STATE_CREATE_INFO:
767 size = sizeof(builder->db);
768 dst = &builder->db;
769 break;
770 case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
771 size = sizeof(builder->cb);
772 dst = &builder->cb;
773 break;
774 case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
775 size = sizeof(builder->rs);
776 dst = &builder->rs;
777 break;
778 case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
779 size = sizeof(builder->tess);
780 dst = &builder->tess;
781 break;
782 case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
783 {
784 const XGL_PIPELINE_SHADER *shader = (const XGL_PIPELINE_SHADER *) (info + 1);
785
786 src = (const void *) shader;
787 size = sizeof(*shader);
788
789 switch (shader->stage) {
790 case XGL_SHADER_STAGE_VERTEX:
791 dst = &builder->vs;
792 break;
793 case XGL_SHADER_STAGE_TESS_CONTROL:
794 dst = &builder->tcs;
795 break;
796 case XGL_SHADER_STAGE_TESS_EVALUATION:
797 dst = &builder->tes;
798 break;
799 case XGL_SHADER_STAGE_GEOMETRY:
800 dst = &builder->gs;
801 break;
802 case XGL_SHADER_STAGE_FRAGMENT:
803 dst = &builder->fs;
804 break;
805 case XGL_SHADER_STAGE_COMPUTE:
806 dst = &builder->cs;
807 break;
808 default:
809 return XGL_ERROR_BAD_PIPELINE_DATA;
810 break;
811 }
812 }
813 break;
814 case XGL_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO:
815 size = sizeof(builder->compute);
816 dst = &builder->compute;
817 break;
818 default:
819 return XGL_ERROR_BAD_PIPELINE_DATA;
820 break;
821 }
822
823 memcpy(dst, src, size);
824
825 info = info->next;
826 }
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600827
828 return XGL_SUCCESS;
Chia-I Wu3efef432014-08-28 15:00:16 +0800829}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600830
Chia-I Wu3efef432014-08-28 15:00:16 +0800831static XGL_RESULT graphics_pipeline_create(struct intel_dev *dev,
832 const XGL_GRAPHICS_PIPELINE_CREATE_INFO *info,
833 struct intel_pipeline **pipeline_ret)
834{
835 struct intel_pipeline_builder builder;
836 struct intel_pipeline *pipeline;
837 XGL_RESULT ret;
838
839 ret = builder_init(&builder, dev->gpu,
840 (const struct intel_pipeline_builder_create_info *) info);
841 if (ret != XGL_SUCCESS)
842 return ret;
843
844 pipeline = (struct intel_pipeline *)
845 intel_base_create(dev, sizeof(*pipeline), dev->base.dbg,
846 XGL_DBG_OBJECT_GRAPHICS_PIPELINE, info, 0);
847 if (!pipeline)
848 return XGL_ERROR_OUT_OF_MEMORY;
849
850 pipeline->dev = dev;
851 pipeline->obj.destroy = pipeline_destroy;
Chia-I Wu3efef432014-08-28 15:00:16 +0800852
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800853 ret = builder_build_all(&builder, pipeline);
Chia-I Wu3efef432014-08-28 15:00:16 +0800854 if (ret == XGL_SUCCESS)
855 ret = builder_validate(&builder, pipeline);
856 if (ret != XGL_SUCCESS) {
857 pipeline_destroy(&pipeline->obj);
858 return ret;
859 }
860
861 *pipeline_ret = pipeline;
862
863 return XGL_SUCCESS;
864}
865
866XGL_RESULT XGLAPI intelCreateGraphicsPipeline(
867 XGL_DEVICE device,
868 const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
869 XGL_PIPELINE* pPipeline)
870{
871 struct intel_dev *dev = intel_dev(device);
872
873 return graphics_pipeline_create(dev, pCreateInfo,
874 (struct intel_pipeline **) pPipeline);
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600875}
876
877XGL_RESULT XGLAPI intelCreateComputePipeline(
878 XGL_DEVICE device,
879 const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo,
880 XGL_PIPELINE* pPipeline)
881{
882 return XGL_ERROR_UNAVAILABLE;
883}
884
885XGL_RESULT XGLAPI intelStorePipeline(
886 XGL_PIPELINE pipeline,
887 XGL_SIZE* pDataSize,
888 XGL_VOID* pData)
889{
890 return XGL_ERROR_UNAVAILABLE;
891}
892
893XGL_RESULT XGLAPI intelLoadPipeline(
894 XGL_DEVICE device,
895 XGL_SIZE dataSize,
896 const XGL_VOID* pData,
897 XGL_PIPELINE* pPipeline)
898{
899 return XGL_ERROR_UNAVAILABLE;
900}
901
902XGL_RESULT XGLAPI intelCreatePipelineDelta(
903 XGL_DEVICE device,
904 XGL_PIPELINE p1,
905 XGL_PIPELINE p2,
906 XGL_PIPELINE_DELTA* delta)
907{
908 return XGL_ERROR_UNAVAILABLE;
909}