blob: cc04221cd63b378f16e63277f65b733c4448e3c5 [file] [log] [blame]
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001/*
2 * XGL
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
Chia-I Wu44e42362014-09-02 08:32:09 +080023 *
24 * Authors:
25 * Courtney Goeltzenleuchter <courtney@lunarg.com>
26 * Chia-I Wu <olv@lunarg.com>
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060027 */
28
Chia-I Wu8370b402014-08-29 12:28:37 +080029#include "genhw/genhw.h"
Chia-I Wu3f239832014-12-11 22:57:18 +080030#include "compiler/pipeline/pipeline_compiler_interface.h"
Chia-I Wu8370b402014-08-29 12:28:37 +080031#include "cmd.h"
Chia-I Wu1d125092014-10-08 08:49:38 +080032#include "format.h"
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -060033#include "shader.h"
Chia-I Wu3f239832014-12-11 22:57:18 +080034#include "pipeline.h"
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060035
Chia-I Wu3f239832014-12-11 22:57:18 +080036struct intel_pipeline_create_info {
37 XGL_GRAPHICS_PIPELINE_CREATE_INFO graphics;
38 XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO vi;
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};
52struct intel_pipeline_shader *intel_pipeline_shader_create_meta(struct intel_dev *dev,
53 enum intel_dev_meta_shader id)
54{
55 struct intel_pipeline_shader *sh;
56 XGL_RESULT ret;
57
58 sh = icd_alloc(sizeof(*sh), 0, XGL_SYSTEM_ALLOC_INTERNAL);
59 if (!sh)
60 return NULL;
61 memset(sh, 0, sizeof(*sh));
62
63 ret = intel_pipeline_shader_compile_meta(sh, dev->gpu, id);
64 if (ret != XGL_SUCCESS) {
65 icd_free(sh);
66 return NULL;
67 }
68
69 switch (id) {
70 case INTEL_DEV_META_VS_FILL_MEM:
71 case INTEL_DEV_META_VS_COPY_MEM:
72 case INTEL_DEV_META_VS_COPY_MEM_UNALIGNED:
73 sh->max_threads = intel_gpu_get_max_threads(dev->gpu,
74 XGL_SHADER_STAGE_VERTEX);
75 break;
76 default:
77 sh->max_threads = intel_gpu_get_max_threads(dev->gpu,
78 XGL_SHADER_STAGE_FRAGMENT);
79 break;
80 }
81
82 return sh;
83}
84
85void intel_pipeline_shader_destroy(struct intel_pipeline_shader *sh)
86{
87 intel_pipeline_shader_cleanup(sh);
88 icd_free(sh);
89}
90
91static XGL_RESULT pipeline_build_shader(struct intel_pipeline *pipeline,
92 struct intel_pipeline_shader *sh,
93 const XGL_PIPELINE_SHADER *sh_info)
94{
95 XGL_RESULT ret;
96
97 ret = intel_pipeline_shader_compile(sh, pipeline->dev->gpu, sh_info);
98 if (ret != XGL_SUCCESS)
99 return ret;
100
101 sh->max_threads =
102 intel_gpu_get_max_threads(pipeline->dev->gpu, sh_info->stage);
103
104 /* 1KB aligned */
105 sh->scratch_offset = u_align(pipeline->scratch_size, 1024);
106 pipeline->scratch_size = sh->scratch_offset +
107 sh->per_thread_scratch_size * sh->max_threads;
108
109 pipeline->active_shaders |= 1 << sh_info->stage;
110
111 return XGL_SUCCESS;
112}
113
114static XGL_RESULT pipeline_build_shaders(struct intel_pipeline *pipeline,
115 const struct intel_pipeline_create_info *info)
116{
117 XGL_RESULT ret = XGL_SUCCESS;
118
119 if (ret == XGL_SUCCESS && info->vs.shader)
120 ret = pipeline_build_shader(pipeline, &pipeline->vs, &info->vs);
121 if (ret == XGL_SUCCESS && info->tcs.shader)
122 ret = pipeline_build_shader(pipeline, &pipeline->tcs, &info->tcs);
123 if (ret == XGL_SUCCESS && info->tes.shader)
124 ret = pipeline_build_shader(pipeline, &pipeline->tes, &info->tes);
125 if (ret == XGL_SUCCESS && info->gs.shader)
126 ret = pipeline_build_shader(pipeline, &pipeline->gs, &info->gs);
127 if (ret == XGL_SUCCESS && info->fs.shader)
128 ret = pipeline_build_shader(pipeline, &pipeline->fs, &info->fs);
129
130 if (ret == XGL_SUCCESS && info->compute.cs.shader)
131 ret = pipeline_build_shader(pipeline, &pipeline->cs, &info->compute.cs);
132
133 return ret;
134}
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600135static uint32_t *pipeline_cmd_ptr(struct intel_pipeline *pipeline, int cmd_len)
136{
137 uint32_t *ptr;
138
139 assert(pipeline->cmd_len + cmd_len < INTEL_PSO_CMD_ENTRIES);
140 ptr = &pipeline->cmds[pipeline->cmd_len];
141 pipeline->cmd_len += cmd_len;
142 return ptr;
143}
144
Chia-I Wube0a3d92014-09-02 13:20:59 +0800145static XGL_RESULT pipeline_build_ia(struct intel_pipeline *pipeline,
146 const struct intel_pipeline_create_info* info)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600147{
Chia-I Wube0a3d92014-09-02 13:20:59 +0800148 pipeline->topology = info->ia.topology;
149 pipeline->disable_vs_cache = info->ia.disableVertexReuse;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600150
Chia-I Wube0a3d92014-09-02 13:20:59 +0800151 if (info->ia.provokingVertex == XGL_PROVOKING_VERTEX_FIRST) {
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600152 pipeline->provoking_vertex_tri = 0;
153 pipeline->provoking_vertex_trifan = 1;
154 pipeline->provoking_vertex_line = 0;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600155 } else {
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600156 pipeline->provoking_vertex_tri = 2;
157 pipeline->provoking_vertex_trifan = 2;
158 pipeline->provoking_vertex_line = 1;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600159 }
160
Chia-I Wube0a3d92014-09-02 13:20:59 +0800161 switch (info->ia.topology) {
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600162 case XGL_TOPOLOGY_POINT_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600163 pipeline->prim_type = GEN6_3DPRIM_POINTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600164 break;
165 case XGL_TOPOLOGY_LINE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600166 pipeline->prim_type = GEN6_3DPRIM_LINELIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600167 break;
168 case XGL_TOPOLOGY_LINE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600169 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600170 break;
171 case XGL_TOPOLOGY_TRIANGLE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600172 pipeline->prim_type = GEN6_3DPRIM_TRILIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600173 break;
174 case XGL_TOPOLOGY_TRIANGLE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600175 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600176 break;
177 case XGL_TOPOLOGY_RECT_LIST:
178 /*
179 * TODO: Rect lists are special in XGL, do we need to do
180 * something special here?
181 * XGL Guide:
182 * The rectangle list is a special geometry primitive type
183 * that can be used for implementing post-processing techniques
184 * or efficient copy operations. There are some special limitations
185 * for rectangle primitives. They cannot be clipped, must
186 * be axis aligned and cannot have depth gradient.
187 * Failure to comply with these restrictions results in
188 * undefined rendering results.
189 */
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600190 pipeline->prim_type = GEN6_3DPRIM_RECTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600191 break;
192 case XGL_TOPOLOGY_QUAD_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600193 pipeline->prim_type = GEN6_3DPRIM_QUADLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600194 break;
195 case XGL_TOPOLOGY_QUAD_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600196 pipeline->prim_type = GEN6_3DPRIM_QUADSTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600197 break;
198 case XGL_TOPOLOGY_LINE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600199 pipeline->prim_type = GEN6_3DPRIM_LINELIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600200 break;
201 case XGL_TOPOLOGY_LINE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600202 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600203 break;
204 case XGL_TOPOLOGY_TRIANGLE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600205 pipeline->prim_type = GEN6_3DPRIM_TRILIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600206 break;
207 case XGL_TOPOLOGY_TRIANGLE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600208 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600209 break;
210 case XGL_TOPOLOGY_PATCH:
Chia-I Wube0a3d92014-09-02 13:20:59 +0800211 if (!info->tess.patchControlPoints ||
212 info->tess.patchControlPoints > 32)
213 return XGL_ERROR_BAD_PIPELINE_DATA;
214 pipeline->prim_type = GEN7_3DPRIM_PATCHLIST_1 +
215 info->tess.patchControlPoints - 1;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600216 break;
217 default:
218 return XGL_ERROR_BAD_PIPELINE_DATA;
219 }
220
Chia-I Wube0a3d92014-09-02 13:20:59 +0800221 if (info->ia.primitiveRestartEnable) {
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600222 pipeline->primitive_restart = true;
Chia-I Wube0a3d92014-09-02 13:20:59 +0800223 pipeline->primitive_restart_index = info->ia.primitiveRestartIndex;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600224 } else {
225 pipeline->primitive_restart = false;
226 }
227
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600228 return XGL_SUCCESS;
229}
230
Chia-I Wu3efef432014-08-28 15:00:16 +0800231static XGL_RESULT pipeline_rs_state(struct intel_pipeline *pipeline,
232 const XGL_PIPELINE_RS_STATE_CREATE_INFO* rs_state)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600233{
234 pipeline->depthClipEnable = rs_state->depthClipEnable;
235 pipeline->rasterizerDiscardEnable = rs_state->rasterizerDiscardEnable;
236 pipeline->pointSize = rs_state->pointSize;
237 return XGL_SUCCESS;
238}
239
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600240static void pipeline_destroy(struct intel_obj *obj)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600241{
242 struct intel_pipeline *pipeline = intel_pipeline_from_obj(obj);
243
Chia-I Wu3f239832014-12-11 22:57:18 +0800244 if (pipeline->active_shaders & SHADER_VERTEX_FLAG) {
245 intel_pipeline_shader_cleanup(&pipeline->vs);
246 }
247
248 if (pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) {
249 intel_pipeline_shader_cleanup(&pipeline->tcs);
250 }
251
252 if (pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) {
253 intel_pipeline_shader_cleanup(&pipeline->tes);
254 }
255
256 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
257 intel_pipeline_shader_cleanup(&pipeline->gs);
258 }
259
260 if (pipeline->active_shaders & SHADER_FRAGMENT_FLAG) {
261 intel_pipeline_shader_cleanup(&pipeline->fs);
262 }
263
264 if (pipeline->active_shaders & SHADER_COMPUTE_FLAG) {
265 intel_pipeline_shader_cleanup(&pipeline->cs);
266 }
Chia-I Wued833872014-08-23 17:00:35 +0800267
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600268 intel_base_destroy(&pipeline->obj.base);
269}
270
Chia-I Wub1024732014-12-19 13:00:29 +0800271static XGL_RESULT pipeline_get_info(struct intel_base *base, int type,
272 XGL_SIZE *size, XGL_VOID *data)
273{
274 struct intel_pipeline *pipeline = intel_pipeline_from_base(base);
275 XGL_RESULT ret = XGL_SUCCESS;
276
277 switch (type) {
278 case XGL_INFO_TYPE_MEMORY_REQUIREMENTS:
279 {
280 XGL_MEMORY_REQUIREMENTS *mem_req = data;
281
282 *size = sizeof(XGL_MEMORY_REQUIREMENTS);
283 if (data) {
284 mem_req->size = pipeline->scratch_size;
285 mem_req->alignment = 1024;
286 mem_req->heapCount = 1;
287 mem_req->heaps[0] = 0;
288 }
289 }
290 break;
291 default:
292 ret = intel_base_get_info(base, type, size, data);
293 break;
294 }
295
296 return ret;
297}
298
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800299static XGL_RESULT pipeline_validate(struct intel_pipeline *pipeline)
Chia-I Wu3efef432014-08-28 15:00:16 +0800300{
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600301 /*
302 * Validate required elements
303 */
304 if (!(pipeline->active_shaders & SHADER_VERTEX_FLAG)) {
305 // TODO: Log debug message: Vertex Shader required.
Chia-I Wu3efef432014-08-28 15:00:16 +0800306 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600307 }
308
309 /*
310 * Tessalation control and evaluation have to both have a shader defined or
311 * neither should have a shader defined.
312 */
313 if (((pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) == 0) !=
314 ((pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) == 0) ) {
315 // TODO: Log debug message: Both Tess control and Tess eval are required to use tessalation
Chia-I Wu3efef432014-08-28 15:00:16 +0800316 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600317 }
318
319 if ((pipeline->active_shaders & SHADER_COMPUTE_FLAG) &&
320 (pipeline->active_shaders & (SHADER_VERTEX_FLAG | SHADER_TESS_CONTROL_FLAG |
321 SHADER_TESS_EVAL_FLAG | SHADER_GEOMETRY_FLAG |
322 SHADER_FRAGMENT_FLAG))) {
323 // TODO: Log debug message: Can only specify compute shader when doing compute
Chia-I Wu3efef432014-08-28 15:00:16 +0800324 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600325 }
326
327 /*
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600328 * XGL_TOPOLOGY_PATCH primitive topology is only valid for tessellation pipelines.
329 * Mismatching primitive topology and tessellation fails graphics pipeline creation.
330 */
331 if (pipeline->active_shaders & (SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG) &&
Chia-I Wube0a3d92014-09-02 13:20:59 +0800332 (pipeline->topology != XGL_TOPOLOGY_PATCH)) {
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600333 // TODO: Log debug message: Invalid topology used with tessalation shader.
Chia-I Wu3efef432014-08-28 15:00:16 +0800334 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600335 }
336
Chia-I Wube0a3d92014-09-02 13:20:59 +0800337 if ((pipeline->topology == XGL_TOPOLOGY_PATCH) &&
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600338 (pipeline->active_shaders & ~(SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG))) {
339 // TODO: Log debug message: Cannot use TOPOLOGY_PATCH on non-tessalation shader.
Chia-I Wu3efef432014-08-28 15:00:16 +0800340 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600341 }
342
Chia-I Wu3efef432014-08-28 15:00:16 +0800343 return XGL_SUCCESS;
344}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600345
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800346static void pipeline_build_urb_alloc_gen6(struct intel_pipeline *pipeline,
347 const struct intel_pipeline_create_info *info)
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800348{
Chia-I Wu509b3f22014-09-02 10:24:05 +0800349 const struct intel_gpu *gpu = pipeline->dev->gpu;
350 const int urb_size = ((gpu->gt == 2) ? 64 : 32) * 1024;
Chia-I Wua4d1b392014-10-10 13:57:29 +0800351 const struct intel_pipeline_shader *vs = &pipeline->vs;
352 const struct intel_pipeline_shader *gs = &pipeline->gs;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800353 int vs_entry_size, gs_entry_size;
354 int vs_size, gs_size;
355
Chia-I Wu509b3f22014-09-02 10:24:05 +0800356 INTEL_GPU_ASSERT(gpu, 6, 6);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800357
358 vs_entry_size = ((vs->in_count >= vs->out_count) ?
359 vs->in_count : vs->out_count);
360 gs_entry_size = (gs) ? gs->out_count : 0;
361
362 /* in bytes */
363 vs_entry_size *= sizeof(float) * 4;
364 gs_entry_size *= sizeof(float) * 4;
365
Chia-I Wua4d1b392014-10-10 13:57:29 +0800366 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800367 vs_size = urb_size / 2;
368 gs_size = vs_size;
369 } else {
370 vs_size = urb_size;
371 gs_size = 0;
372 }
373
374 /* 3DSTATE_URB */
375 {
376 const uint8_t cmd_len = 3;
377 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_URB) |
378 (cmd_len - 2);
379 int vs_alloc_size, gs_alloc_size;
380 int vs_entry_count, gs_entry_count;
381 uint32_t *dw;
382
383 /* in 1024-bit rows */
384 vs_alloc_size = (vs_entry_size + 128 - 1) / 128;
385 gs_alloc_size = (gs_entry_size + 128 - 1) / 128;
386
387 /* valid range is [1, 5] */
388 if (!vs_alloc_size)
389 vs_alloc_size = 1;
390 if (!gs_alloc_size)
391 gs_alloc_size = 1;
392 assert(vs_alloc_size <= 5 && gs_alloc_size <= 5);
393
394 /* valid range is [24, 256], multiples of 4 */
395 vs_entry_count = (vs_size / 128 / vs_alloc_size) & ~3;
396 if (vs_entry_count > 256)
397 vs_entry_count = 256;
398 assert(vs_entry_count >= 24);
399
400 /* valid range is [0, 256], multiples of 4 */
401 gs_entry_count = (gs_size / 128 / gs_alloc_size) & ~3;
402 if (gs_entry_count > 256)
403 gs_entry_count = 256;
404
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600405 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800406
407 dw[0] = dw0;
408 dw[1] = (vs_alloc_size - 1) << GEN6_URB_DW1_VS_ENTRY_SIZE__SHIFT |
409 vs_entry_count << GEN6_URB_DW1_VS_ENTRY_COUNT__SHIFT;
410 dw[2] = gs_entry_count << GEN6_URB_DW2_GS_ENTRY_COUNT__SHIFT |
411 (gs_alloc_size - 1) << GEN6_URB_DW2_GS_ENTRY_SIZE__SHIFT;
412 }
413}
414
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800415static void pipeline_build_urb_alloc_gen7(struct intel_pipeline *pipeline,
416 const struct intel_pipeline_create_info *info)
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800417{
Chia-I Wu509b3f22014-09-02 10:24:05 +0800418 const struct intel_gpu *gpu = pipeline->dev->gpu;
419 const int urb_size = ((gpu->gt == 3) ? 512 :
420 (gpu->gt == 2) ? 256 : 128) * 1024;
Cody Northrop306ec352014-10-06 15:11:45 -0600421 const struct intel_pipeline_shader *vs = &pipeline->vs;
422 const struct intel_pipeline_shader *gs = &pipeline->gs;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800423 /* some space is reserved for PCBs */
Chia-I Wu509b3f22014-09-02 10:24:05 +0800424 int urb_offset = ((gpu->gt == 3) ? 32 : 16) * 1024;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800425 int vs_entry_size, gs_entry_size;
426 int vs_size, gs_size;
427
Chia-I Wu509b3f22014-09-02 10:24:05 +0800428 INTEL_GPU_ASSERT(gpu, 7, 7.5);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800429
430 vs_entry_size = ((vs->in_count >= vs->out_count) ?
431 vs->in_count : vs->out_count);
432 gs_entry_size = (gs) ? gs->out_count : 0;
433
434 /* in bytes */
435 vs_entry_size *= sizeof(float) * 4;
436 gs_entry_size *= sizeof(float) * 4;
437
Chia-I Wua4d1b392014-10-10 13:57:29 +0800438 if (pipeline->active_shaders & SHADER_GEOMETRY_FLAG) {
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800439 vs_size = (urb_size - urb_offset) / 2;
440 gs_size = vs_size;
441 } else {
442 vs_size = urb_size - urb_offset;
443 gs_size = 0;
444 }
445
446 /* 3DSTATE_URB_* */
447 {
448 const uint8_t cmd_len = 2;
449 int vs_alloc_size, gs_alloc_size;
450 int vs_entry_count, gs_entry_count;
451 uint32_t *dw;
452
453 /* in 512-bit rows */
454 vs_alloc_size = (vs_entry_size + 64 - 1) / 64;
455 gs_alloc_size = (gs_entry_size + 64 - 1) / 64;
456
457 if (!vs_alloc_size)
458 vs_alloc_size = 1;
459 if (!gs_alloc_size)
460 gs_alloc_size = 1;
461
462 /* avoid performance decrease due to banking */
463 if (vs_alloc_size == 5)
464 vs_alloc_size = 6;
465
466 /* in multiples of 8 */
467 vs_entry_count = (vs_size / 64 / vs_alloc_size) & ~7;
468 assert(vs_entry_count >= 32);
469
470 gs_entry_count = (gs_size / 64 / gs_alloc_size) & ~7;
471
Chia-I Wu509b3f22014-09-02 10:24:05 +0800472 if (intel_gpu_gen(gpu) >= INTEL_GEN(7.5)) {
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800473 const int max_vs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800474 (gpu->gt >= 2) ? 1664 : 640;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800475 const int max_gs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800476 (gpu->gt >= 2) ? 640 : 256;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800477 if (vs_entry_count >= max_vs_entry_count)
478 vs_entry_count = max_vs_entry_count;
479 if (gs_entry_count >= max_gs_entry_count)
480 gs_entry_count = max_gs_entry_count;
481 } else {
482 const int max_vs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800483 (gpu->gt == 2) ? 704 : 512;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800484 const int max_gs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800485 (gpu->gt == 2) ? 320 : 192;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800486 if (vs_entry_count >= max_vs_entry_count)
487 vs_entry_count = max_vs_entry_count;
488 if (gs_entry_count >= max_gs_entry_count)
489 gs_entry_count = max_gs_entry_count;
490 }
491
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600492 dw = pipeline_cmd_ptr(pipeline, cmd_len*4);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800493 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_VS) | (cmd_len - 2);
494 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT |
495 (vs_alloc_size - 1) << GEN7_URB_ANY_DW1_ENTRY_SIZE__SHIFT |
496 vs_entry_count;
497
498 dw += 2;
499 if (gs_size)
500 urb_offset += vs_size;
501 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_GS) | (cmd_len - 2);
502 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT |
503 (gs_alloc_size - 1) << GEN7_URB_ANY_DW1_ENTRY_SIZE__SHIFT |
504 gs_entry_count;
505
506 dw += 2;
507 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_HS) | (cmd_len - 2);
508 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT;
509
510 dw += 2;
511 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_DS) | (cmd_len - 2);
512 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT;
513 }
514}
515
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800516static void pipeline_build_push_const_alloc_gen7(struct intel_pipeline *pipeline,
517 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600518{
519 const uint8_t cmd_len = 2;
520 uint32_t offset = 0;
521 uint32_t size = 8192;
522 uint32_t *dw;
523 int end;
524
Chia-I Wu509b3f22014-09-02 10:24:05 +0800525 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600526
527 /*
528 * From the Ivy Bridge PRM, volume 2 part 1, page 68:
529 *
530 * "(A table that says the maximum size of each constant buffer is
531 * 16KB")
532 *
533 * From the Ivy Bridge PRM, volume 2 part 1, page 115:
534 *
535 * "The sum of the Constant Buffer Offset and the Constant Buffer Size
536 * may not exceed the maximum value of the Constant Buffer Size."
537 *
538 * Thus, the valid range of buffer end is [0KB, 16KB].
539 */
540 end = (offset + size) / 1024;
541 if (end > 16) {
542 assert(!"invalid constant buffer end");
543 end = 16;
544 }
545
546 /* the valid range of buffer offset is [0KB, 15KB] */
547 offset = (offset + 1023) / 1024;
548 if (offset > 15) {
549 assert(!"invalid constant buffer offset");
550 offset = 15;
551 }
552
553 if (offset > end) {
554 assert(!size);
555 offset = end;
556 }
557
558 /* the valid range of buffer size is [0KB, 15KB] */
559 size = end - offset;
560 if (size > 15) {
561 assert(!"invalid constant buffer size");
562 size = 15;
563 }
564
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800565 dw = pipeline_cmd_ptr(pipeline, cmd_len * 5);
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600566 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_VS) | (cmd_len - 2);
567 dw[1] = offset << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
568 size << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
569
570 dw += 2;
571 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_PS) | (cmd_len - 2);
572 dw[1] = size << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
573 size << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
574
575 dw += 2;
576 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_HS) | (cmd_len - 2);
577 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
578 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
579
580 dw += 2;
581 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_DS) | (cmd_len - 2);
582 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
583 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
584
585 dw += 2;
586 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_GS) | (cmd_len - 2);
587 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
588 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
Chia-I Wu8370b402014-08-29 12:28:37 +0800589
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600590 // gen7_wa_pipe_control_cs_stall(p, true, true);
591 // looks equivalent to: gen6_wa_wm_multisample_flush - this does more
592 // than the documentation seems to imply
593}
594
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800595static void pipeline_build_vertex_elements(struct intel_pipeline *pipeline,
596 const struct intel_pipeline_create_info *info)
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800597{
Cody Northrop306ec352014-10-06 15:11:45 -0600598 const struct intel_pipeline_shader *vs = &pipeline->vs;
Chia-I Wu1d125092014-10-08 08:49:38 +0800599 uint8_t cmd_len;
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800600 uint32_t *dw;
Chia-I Wu1d125092014-10-08 08:49:38 +0800601 XGL_UINT i;
602 int comps[4];
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800603
Chia-I Wu509b3f22014-09-02 10:24:05 +0800604 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800605
GregF8cd81832014-11-18 18:01:01 -0700606 cmd_len = 1 + 2 * u_popcountll(vs->inputs_read);
Chia-I Wu1d125092014-10-08 08:49:38 +0800607 if (vs->uses & (INTEL_SHADER_USE_VID | INTEL_SHADER_USE_IID))
608 cmd_len += 2;
609
610 if (cmd_len == 1)
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800611 return;
612
613 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Chia-I Wu1d125092014-10-08 08:49:38 +0800614
615 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_ELEMENTS) |
616 (cmd_len - 2);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800617 dw++;
618
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800619 /* VERTEX_ELEMENT_STATE */
Chia-I Wu1d125092014-10-08 08:49:38 +0800620 for (i = 0; i < info->vi.attributeCount; i++) {
GregF8cd81832014-11-18 18:01:01 -0700621 if (!(vs->inputs_read & (1L << i)))
GregF2dc40212014-10-31 17:31:47 -0600622 continue;
Chia-I Wu1d125092014-10-08 08:49:38 +0800623 const XGL_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION *attr =
624 &info->vi.pVertexAttributeDescriptions[i];
625 const int format =
626 intel_format_translate_color(pipeline->dev->gpu, attr->format);
627
628 comps[0] = GEN6_VFCOMP_STORE_0;
629 comps[1] = GEN6_VFCOMP_STORE_0;
630 comps[2] = GEN6_VFCOMP_STORE_0;
631 comps[3] = icd_format_is_int(attr->format) ?
632 GEN6_VFCOMP_STORE_1_INT : GEN6_VFCOMP_STORE_1_FP;
633
634 switch (icd_format_get_channel_count(attr->format)) {
635 case 4: comps[3] = GEN6_VFCOMP_STORE_SRC; /* fall through */
636 case 3: comps[2] = GEN6_VFCOMP_STORE_SRC; /* fall through */
637 case 2: comps[1] = GEN6_VFCOMP_STORE_SRC; /* fall through */
638 case 1: comps[0] = GEN6_VFCOMP_STORE_SRC; break;
639 default:
640 break;
641 }
642
643 assert(attr->offsetInBytes <= 2047);
644
645 dw[0] = attr->binding << GEN6_VE_STATE_DW0_VB_INDEX__SHIFT |
646 GEN6_VE_STATE_DW0_VALID |
647 format << GEN6_VE_STATE_DW0_FORMAT__SHIFT |
648 attr->offsetInBytes;
649
650 dw[1] = comps[0] << GEN6_VE_STATE_DW1_COMP0__SHIFT |
651 comps[1] << GEN6_VE_STATE_DW1_COMP1__SHIFT |
652 comps[2] << GEN6_VE_STATE_DW1_COMP2__SHIFT |
653 comps[3] << GEN6_VE_STATE_DW1_COMP3__SHIFT;
654
655 dw += 2;
656 }
GregF932fcf52014-10-29 17:02:11 -0600657
658 if (vs->uses & (INTEL_SHADER_USE_VID | INTEL_SHADER_USE_IID)) {
659 comps[0] = (vs->uses & INTEL_SHADER_USE_VID) ?
660 GEN6_VFCOMP_STORE_VID : GEN6_VFCOMP_STORE_0;
661 comps[1] = (vs->uses & INTEL_SHADER_USE_IID) ?
662 GEN6_VFCOMP_STORE_IID : GEN6_VFCOMP_NOSTORE;
663 comps[2] = GEN6_VFCOMP_NOSTORE;
664 comps[3] = GEN6_VFCOMP_NOSTORE;
665
666 dw[0] = GEN6_VE_STATE_DW0_VALID;
667 dw[1] = comps[0] << GEN6_VE_STATE_DW1_COMP0__SHIFT |
668 comps[1] << GEN6_VE_STATE_DW1_COMP1__SHIFT |
669 comps[2] << GEN6_VE_STATE_DW1_COMP2__SHIFT |
670 comps[3] << GEN6_VE_STATE_DW1_COMP3__SHIFT;
671
672 dw += 2;
673 }
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800674}
675
GregF8cd81832014-11-18 18:01:01 -0700676static void pipeline_build_fragment_SBE(struct intel_pipeline *pipeline)
677{
678 const struct intel_pipeline_shader *fs = &pipeline->fs;
679 const struct intel_pipeline_shader *vs = &pipeline->vs;
680 uint8_t cmd_len;
681 uint32_t *body;
682 XGL_UINT attr_skip, attr_count;
683 XGL_UINT vue_offset, vue_len;
684 XGL_UINT i;
685
686 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
687
688 cmd_len = 14;
689
690 body = pipeline_cmd_ptr(pipeline, cmd_len);
691 pipeline->cmd_sbe_body_offset = body - pipeline->cmds + 1;
692
693 /* VS outputs VUE header and position additionally */
694 assert(vs->out_count >= fs->in_count + 2);
695 assert(!fs->reads_user_clip || vs->enable_user_clip);
696 attr_skip = vs->outputs_offset;
697 if (vs->enable_user_clip != fs->reads_user_clip) {
698 attr_skip += 2;
699 }
700 assert(vs->out_count >= attr_skip);
701 attr_count = vs->out_count - attr_skip;
702
703 // LUNARG TODO: We currently are only handling 16 attrs;
704 // ultimately, we need to handle 32
705 assert(fs->in_count <= 16);
706 assert(attr_count <= 16);
707
708 vue_offset = attr_skip / 2;
709 vue_len = (attr_count + 1) / 2;
710 if (!vue_len)
711 vue_len = 1;
712
713 body[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SBE) |
714 (cmd_len - 2);
715
716 // LUNARG TODO: If the attrs needed by the FS are exactly
717 // what is written by the VS, we don't need to enable
718 // swizzling, improving performance. Even if we swizzle,
719 // we can improve performance by reducing vue_len to
720 // just include the values needed by the FS:
721 // vue_len = ceiling((max_vs_out + 1)/2)
722
723 body[1] = GEN7_SBE_DW1_ATTR_SWIZZLE_ENABLE |
724 fs->in_count << GEN7_SBE_DW1_ATTR_COUNT__SHIFT |
725 vue_len << GEN7_SBE_DW1_URB_READ_LEN__SHIFT |
726 vue_offset << GEN7_SBE_DW1_URB_READ_OFFSET__SHIFT;
727
728 uint16_t vs_slot[fs->in_count];
729 XGL_INT fs_in = 0;
730 XGL_INT vs_out = - (vue_offset * 2 - vs->outputs_offset);
731 for (i=0; i < 64; i++) {
Cody Northropd75c13e2015-01-02 14:07:20 -0700732 bool vsWrites = vs->outputs_written & (1L << i);
733 bool fsReads = fs->inputs_read & (1L << i);
734
735 if (fsReads) {
GregF8cd81832014-11-18 18:01:01 -0700736 assert(vs_out >= 0);
737 assert(fs_in < fs->in_count);
738 vs_slot[fs_in] = vs_out;
Cody Northropd75c13e2015-01-02 14:07:20 -0700739
740 if (!vsWrites) {
741 // If the vertex shader did not write this input, we cannot
742 // program the SBE to read it. Our choices are to allow it to
743 // read junk from a GRF, or get zero. We're choosing zero.
744 if (i >= fs->generic_input_start) {
745 vs_slot[fs_in] = GEN7_SBE_ATTR_CONST_0000 |
746 GEN7_SBE_ATTR_OVERRIDE_X |
747 GEN7_SBE_ATTR_OVERRIDE_Y |
748 GEN7_SBE_ATTR_OVERRIDE_Z |
749 GEN7_SBE_ATTR_OVERRIDE_W;
750 }
751 }
752
GregF8cd81832014-11-18 18:01:01 -0700753 fs_in += 1;
754 }
Cody Northropd75c13e2015-01-02 14:07:20 -0700755 if (vsWrites) {
GregF8cd81832014-11-18 18:01:01 -0700756 vs_out += 1;
757 }
758 }
759
760 for (i = 0; i < 8; i++) {
761 uint16_t hi, lo;
762
763 /* no attr swizzles */
764 if (i * 2 + 1 < fs->in_count) {
765 lo = vs_slot[i * 2];
766 hi = vs_slot[i * 2 + 1];
767 } else if (i * 2 < fs->in_count) {
768 lo = vs_slot[i * 2];
769 hi = 0;
770 } else {
771 hi = 0;
772 lo = 0;
773 }
774
775 body[2 + i] = hi << GEN7_SBE_ATTR_HIGH__SHIFT | lo;
776 }
777
778 body[10] = 0; /* point sprite enables */
779 body[11] = 0; /* constant interpolation enables */
780 body[12] = 0; /* WrapShortest enables */
781 body[13] = 0;
782}
783
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800784static void pipeline_build_gs(struct intel_pipeline *pipeline,
785 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600786{
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600787 // gen7_emit_3DSTATE_GS done by cmd_pipeline
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600788}
789
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800790static void pipeline_build_hs(struct intel_pipeline *pipeline,
791 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600792{
793 const uint8_t cmd_len = 7;
794 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
795 uint32_t *dw;
796
Chia-I Wu509b3f22014-09-02 10:24:05 +0800797 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600798
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800799 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600800 dw[0] = dw0;
801 dw[1] = 0;
802 dw[2] = 0;
803 dw[3] = 0;
804 dw[4] = 0;
805 dw[5] = 0;
806 dw[6] = 0;
807}
808
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800809static void pipeline_build_te(struct intel_pipeline *pipeline,
810 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600811{
812 const uint8_t cmd_len = 4;
813 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_TE) | (cmd_len - 2);
814 uint32_t *dw;
815
Chia-I Wu509b3f22014-09-02 10:24:05 +0800816 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600817
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800818 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600819 dw[0] = dw0;
820 dw[1] = 0;
821 dw[2] = 0;
822 dw[3] = 0;
823}
824
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800825static void pipeline_build_ds(struct intel_pipeline *pipeline,
826 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600827{
828 const uint8_t cmd_len = 6;
829 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
830 uint32_t *dw;
831
Chia-I Wu509b3f22014-09-02 10:24:05 +0800832 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600833
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800834 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600835 dw[0] = dw0;
836 dw[1] = 0;
837 dw[2] = 0;
838 dw[3] = 0;
839 dw[4] = 0;
840 dw[5] = 0;
841}
842
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800843static XGL_RESULT pipeline_build_all(struct intel_pipeline *pipeline,
844 const struct intel_pipeline_create_info *info)
Chia-I Wu3efef432014-08-28 15:00:16 +0800845{
846 XGL_RESULT ret;
847
Chia-I Wu98824592014-09-02 09:42:46 +0800848 ret = pipeline_build_shaders(pipeline, info);
849 if (ret != XGL_SUCCESS)
850 return ret;
851
Chia-I Wu1d125092014-10-08 08:49:38 +0800852 if (info->vi.bindingCount > ARRAY_SIZE(pipeline->vb) ||
853 info->vi.attributeCount > ARRAY_SIZE(pipeline->vb))
854 return XGL_ERROR_BAD_PIPELINE_DATA;
855
856 pipeline->vb_count = info->vi.bindingCount;
857 memcpy(pipeline->vb, info->vi.pVertexBindingDescriptions,
858 sizeof(pipeline->vb[0]) * pipeline->vb_count);
859
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800860 pipeline_build_vertex_elements(pipeline, info);
GregF8cd81832014-11-18 18:01:01 -0700861 pipeline_build_fragment_SBE(pipeline);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800862
Chia-I Wu509b3f22014-09-02 10:24:05 +0800863 if (intel_gpu_gen(pipeline->dev->gpu) >= INTEL_GEN(7)) {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800864 pipeline_build_urb_alloc_gen7(pipeline, info);
865 pipeline_build_push_const_alloc_gen7(pipeline, info);
866 pipeline_build_gs(pipeline, info);
867 pipeline_build_hs(pipeline, info);
868 pipeline_build_te(pipeline, info);
869 pipeline_build_ds(pipeline, info);
Chia-I Wu8370b402014-08-29 12:28:37 +0800870
871 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
872 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL |
873 INTEL_CMD_WA_GEN7_PRE_VS_DEPTH_STALL_WRITE |
874 INTEL_CMD_WA_GEN7_POST_COMMAND_CS_STALL |
875 INTEL_CMD_WA_GEN7_POST_COMMAND_DEPTH_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800876 } else {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800877 pipeline_build_urb_alloc_gen6(pipeline, info);
Chia-I Wu8370b402014-08-29 12:28:37 +0800878
879 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
880 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800881 }
882
Chia-I Wube0a3d92014-09-02 13:20:59 +0800883 ret = pipeline_build_ia(pipeline, info);
Chia-I Wu3efef432014-08-28 15:00:16 +0800884
885 if (ret == XGL_SUCCESS)
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800886 ret = pipeline_rs_state(pipeline, &info->rs);
Chia-I Wu3efef432014-08-28 15:00:16 +0800887
Chia-I Wu3efef432014-08-28 15:00:16 +0800888 if (ret == XGL_SUCCESS) {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800889 pipeline->db_format = info->db.format;
890 pipeline->cb_state = info->cb;
891 pipeline->tess_state = info->tess;
Chia-I Wu3efef432014-08-28 15:00:16 +0800892 }
893
894 return ret;
895}
896
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800897struct intel_pipeline_create_info_header {
898 XGL_STRUCTURE_TYPE struct_type;
899 const struct intel_pipeline_create_info_header *next;
900};
901
902static XGL_RESULT pipeline_create_info_init(struct intel_pipeline_create_info *info,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800903 const struct intel_pipeline_create_info_header *header)
Chia-I Wu3efef432014-08-28 15:00:16 +0800904{
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800905 memset(info, 0, sizeof(*info));
Chia-I Wu3efef432014-08-28 15:00:16 +0800906
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800907 while (header) {
908 const void *src = (const void *) header;
Chia-I Wu3efef432014-08-28 15:00:16 +0800909 XGL_SIZE size;
910 void *dst;
911
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800912 switch (header->struct_type) {
Chia-I Wu3efef432014-08-28 15:00:16 +0800913 case XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800914 size = sizeof(info->graphics);
915 dst = &info->graphics;
Chia-I Wu3efef432014-08-28 15:00:16 +0800916 break;
Chia-I Wu1d125092014-10-08 08:49:38 +0800917 case XGL_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO:
918 size = sizeof(info->vi);
919 dst = &info->vi;
920 break;
Chia-I Wu3efef432014-08-28 15:00:16 +0800921 case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800922 size = sizeof(info->ia);
923 dst = &info->ia;
Chia-I Wu3efef432014-08-28 15:00:16 +0800924 break;
925 case XGL_STRUCTURE_TYPE_PIPELINE_DB_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800926 size = sizeof(info->db);
927 dst = &info->db;
Chia-I Wu3efef432014-08-28 15:00:16 +0800928 break;
929 case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800930 size = sizeof(info->cb);
931 dst = &info->cb;
Chia-I Wu3efef432014-08-28 15:00:16 +0800932 break;
933 case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800934 size = sizeof(info->rs);
935 dst = &info->rs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800936 break;
937 case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800938 size = sizeof(info->tess);
939 dst = &info->tess;
Chia-I Wu3efef432014-08-28 15:00:16 +0800940 break;
941 case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
942 {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800943 const XGL_PIPELINE_SHADER *shader =
944 (const XGL_PIPELINE_SHADER *) (header + 1);
Chia-I Wu3efef432014-08-28 15:00:16 +0800945
946 src = (const void *) shader;
947 size = sizeof(*shader);
948
949 switch (shader->stage) {
950 case XGL_SHADER_STAGE_VERTEX:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800951 dst = &info->vs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800952 break;
953 case XGL_SHADER_STAGE_TESS_CONTROL:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800954 dst = &info->tcs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800955 break;
956 case XGL_SHADER_STAGE_TESS_EVALUATION:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800957 dst = &info->tes;
Chia-I Wu3efef432014-08-28 15:00:16 +0800958 break;
959 case XGL_SHADER_STAGE_GEOMETRY:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800960 dst = &info->gs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800961 break;
962 case XGL_SHADER_STAGE_FRAGMENT:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800963 dst = &info->fs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800964 break;
Chia-I Wu3efef432014-08-28 15:00:16 +0800965 default:
966 return XGL_ERROR_BAD_PIPELINE_DATA;
967 break;
968 }
969 }
970 break;
971 case XGL_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800972 size = sizeof(info->compute);
973 dst = &info->compute;
Chia-I Wu3efef432014-08-28 15:00:16 +0800974 break;
975 default:
976 return XGL_ERROR_BAD_PIPELINE_DATA;
977 break;
978 }
979
980 memcpy(dst, src, size);
981
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800982 header = header->next;
Chia-I Wu3efef432014-08-28 15:00:16 +0800983 }
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600984
985 return XGL_SUCCESS;
Chia-I Wu3efef432014-08-28 15:00:16 +0800986}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600987
Chia-I Wu3efef432014-08-28 15:00:16 +0800988static XGL_RESULT graphics_pipeline_create(struct intel_dev *dev,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800989 const XGL_GRAPHICS_PIPELINE_CREATE_INFO *info_,
Chia-I Wu3efef432014-08-28 15:00:16 +0800990 struct intel_pipeline **pipeline_ret)
991{
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800992 struct intel_pipeline_create_info info;
Chia-I Wu3efef432014-08-28 15:00:16 +0800993 struct intel_pipeline *pipeline;
994 XGL_RESULT ret;
995
Chia-I Wu509b3f22014-09-02 10:24:05 +0800996 ret = pipeline_create_info_init(&info,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800997 (const struct intel_pipeline_create_info_header *) info_);
Chia-I Wu3efef432014-08-28 15:00:16 +0800998 if (ret != XGL_SUCCESS)
999 return ret;
1000
1001 pipeline = (struct intel_pipeline *)
1002 intel_base_create(dev, sizeof(*pipeline), dev->base.dbg,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001003 XGL_DBG_OBJECT_GRAPHICS_PIPELINE, info_, 0);
Chia-I Wu3efef432014-08-28 15:00:16 +08001004 if (!pipeline)
1005 return XGL_ERROR_OUT_OF_MEMORY;
1006
1007 pipeline->dev = dev;
Chia-I Wub1024732014-12-19 13:00:29 +08001008 pipeline->obj.base.get_info = pipeline_get_info;
Chia-I Wu3efef432014-08-28 15:00:16 +08001009 pipeline->obj.destroy = pipeline_destroy;
Chia-I Wu3efef432014-08-28 15:00:16 +08001010
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001011 ret = pipeline_build_all(pipeline, &info);
Chia-I Wu3efef432014-08-28 15:00:16 +08001012 if (ret == XGL_SUCCESS)
Chia-I Wuf90ff0c2014-09-02 09:32:46 +08001013 ret = pipeline_validate(pipeline);
Chia-I Wu3efef432014-08-28 15:00:16 +08001014 if (ret != XGL_SUCCESS) {
1015 pipeline_destroy(&pipeline->obj);
1016 return ret;
1017 }
1018
1019 *pipeline_ret = pipeline;
1020
1021 return XGL_SUCCESS;
1022}
1023
Chia-I Wu96177272015-01-03 15:27:41 +08001024ICD_EXPORT XGL_RESULT XGLAPI xglCreateGraphicsPipeline(
Chia-I Wu3efef432014-08-28 15:00:16 +08001025 XGL_DEVICE device,
1026 const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
1027 XGL_PIPELINE* pPipeline)
1028{
1029 struct intel_dev *dev = intel_dev(device);
1030
1031 return graphics_pipeline_create(dev, pCreateInfo,
1032 (struct intel_pipeline **) pPipeline);
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001033}
1034
Chia-I Wu96177272015-01-03 15:27:41 +08001035ICD_EXPORT XGL_RESULT XGLAPI xglCreateComputePipeline(
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001036 XGL_DEVICE device,
1037 const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo,
1038 XGL_PIPELINE* pPipeline)
1039{
1040 return XGL_ERROR_UNAVAILABLE;
1041}
1042
Chia-I Wu96177272015-01-03 15:27:41 +08001043ICD_EXPORT XGL_RESULT XGLAPI xglStorePipeline(
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001044 XGL_PIPELINE pipeline,
1045 XGL_SIZE* pDataSize,
1046 XGL_VOID* pData)
1047{
1048 return XGL_ERROR_UNAVAILABLE;
1049}
1050
Chia-I Wu96177272015-01-03 15:27:41 +08001051ICD_EXPORT XGL_RESULT XGLAPI xglLoadPipeline(
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001052 XGL_DEVICE device,
1053 XGL_SIZE dataSize,
1054 const XGL_VOID* pData,
1055 XGL_PIPELINE* pPipeline)
1056{
1057 return XGL_ERROR_UNAVAILABLE;
1058}
1059
Chia-I Wu96177272015-01-03 15:27:41 +08001060ICD_EXPORT XGL_RESULT XGLAPI xglCreatePipelineDelta(
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001061 XGL_DEVICE device,
1062 XGL_PIPELINE p1,
1063 XGL_PIPELINE p2,
1064 XGL_PIPELINE_DELTA* delta)
1065{
1066 return XGL_ERROR_UNAVAILABLE;
1067}