blob: 1d434d31923455fc2e05b9fd179fb7d38a05da96 [file] [log] [blame]
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001/*
2 * XGL
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
Chia-I Wu44e42362014-09-02 08:32:09 +080023 *
24 * Authors:
25 * Courtney Goeltzenleuchter <courtney@lunarg.com>
26 * Chia-I Wu <olv@lunarg.com>
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060027 */
28
Chia-I Wu8370b402014-08-29 12:28:37 +080029#include "genhw/genhw.h"
Chia-I Wu8370b402014-08-29 12:28:37 +080030#include "cmd.h"
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -060031#include "shader.h"
Chia-I Wued833872014-08-23 17:00:35 +080032#include "pipeline_priv.h"
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060033
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -060034static uint32_t *pipeline_cmd_ptr(struct intel_pipeline *pipeline, int cmd_len)
35{
36 uint32_t *ptr;
37
38 assert(pipeline->cmd_len + cmd_len < INTEL_PSO_CMD_ENTRIES);
39 ptr = &pipeline->cmds[pipeline->cmd_len];
40 pipeline->cmd_len += cmd_len;
41 return ptr;
42}
43
Chia-I Wube0a3d92014-09-02 13:20:59 +080044static XGL_RESULT pipeline_build_ia(struct intel_pipeline *pipeline,
45 const struct intel_pipeline_create_info* info)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060046{
Chia-I Wube0a3d92014-09-02 13:20:59 +080047 pipeline->topology = info->ia.topology;
48 pipeline->disable_vs_cache = info->ia.disableVertexReuse;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -060049
Chia-I Wube0a3d92014-09-02 13:20:59 +080050 if (info->ia.provokingVertex == XGL_PROVOKING_VERTEX_FIRST) {
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060051 pipeline->provoking_vertex_tri = 0;
52 pipeline->provoking_vertex_trifan = 1;
53 pipeline->provoking_vertex_line = 0;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060054 } else {
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060055 pipeline->provoking_vertex_tri = 2;
56 pipeline->provoking_vertex_trifan = 2;
57 pipeline->provoking_vertex_line = 1;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060058 }
59
Chia-I Wube0a3d92014-09-02 13:20:59 +080060 switch (info->ia.topology) {
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060061 case XGL_TOPOLOGY_POINT_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060062 pipeline->prim_type = GEN6_3DPRIM_POINTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060063 break;
64 case XGL_TOPOLOGY_LINE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060065 pipeline->prim_type = GEN6_3DPRIM_LINELIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060066 break;
67 case XGL_TOPOLOGY_LINE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060068 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060069 break;
70 case XGL_TOPOLOGY_TRIANGLE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060071 pipeline->prim_type = GEN6_3DPRIM_TRILIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060072 break;
73 case XGL_TOPOLOGY_TRIANGLE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060074 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060075 break;
76 case XGL_TOPOLOGY_RECT_LIST:
77 /*
78 * TODO: Rect lists are special in XGL, do we need to do
79 * something special here?
80 * XGL Guide:
81 * The rectangle list is a special geometry primitive type
82 * that can be used for implementing post-processing techniques
83 * or efficient copy operations. There are some special limitations
84 * for rectangle primitives. They cannot be clipped, must
85 * be axis aligned and cannot have depth gradient.
86 * Failure to comply with these restrictions results in
87 * undefined rendering results.
88 */
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060089 pipeline->prim_type = GEN6_3DPRIM_RECTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060090 break;
91 case XGL_TOPOLOGY_QUAD_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060092 pipeline->prim_type = GEN6_3DPRIM_QUADLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060093 break;
94 case XGL_TOPOLOGY_QUAD_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060095 pipeline->prim_type = GEN6_3DPRIM_QUADSTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060096 break;
97 case XGL_TOPOLOGY_LINE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060098 pipeline->prim_type = GEN6_3DPRIM_LINELIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060099 break;
100 case XGL_TOPOLOGY_LINE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600101 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600102 break;
103 case XGL_TOPOLOGY_TRIANGLE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600104 pipeline->prim_type = GEN6_3DPRIM_TRILIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600105 break;
106 case XGL_TOPOLOGY_TRIANGLE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600107 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600108 break;
109 case XGL_TOPOLOGY_PATCH:
Chia-I Wube0a3d92014-09-02 13:20:59 +0800110 if (!info->tess.patchControlPoints ||
111 info->tess.patchControlPoints > 32)
112 return XGL_ERROR_BAD_PIPELINE_DATA;
113 pipeline->prim_type = GEN7_3DPRIM_PATCHLIST_1 +
114 info->tess.patchControlPoints - 1;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600115 break;
116 default:
117 return XGL_ERROR_BAD_PIPELINE_DATA;
118 }
119
Chia-I Wube0a3d92014-09-02 13:20:59 +0800120 if (info->ia.primitiveRestartEnable) {
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600121 pipeline->primitive_restart = true;
Chia-I Wube0a3d92014-09-02 13:20:59 +0800122 pipeline->primitive_restart_index = info->ia.primitiveRestartIndex;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600123 } else {
124 pipeline->primitive_restart = false;
125 }
126
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600127 return XGL_SUCCESS;
128}
129
Chia-I Wu3efef432014-08-28 15:00:16 +0800130static XGL_RESULT pipeline_rs_state(struct intel_pipeline *pipeline,
131 const XGL_PIPELINE_RS_STATE_CREATE_INFO* rs_state)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600132{
133 pipeline->depthClipEnable = rs_state->depthClipEnable;
134 pipeline->rasterizerDiscardEnable = rs_state->rasterizerDiscardEnable;
135 pipeline->pointSize = rs_state->pointSize;
136 return XGL_SUCCESS;
137}
138
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600139static void pipeline_destroy(struct intel_obj *obj)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600140{
141 struct intel_pipeline *pipeline = intel_pipeline_from_obj(obj);
142
Chia-I Wu98824592014-09-02 09:42:46 +0800143 pipeline_tear_shaders(pipeline);
Chia-I Wued833872014-08-23 17:00:35 +0800144
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600145 intel_base_destroy(&pipeline->obj.base);
146}
147
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800148static XGL_RESULT pipeline_validate(struct intel_pipeline *pipeline)
Chia-I Wu3efef432014-08-28 15:00:16 +0800149{
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600150 /*
151 * Validate required elements
152 */
153 if (!(pipeline->active_shaders & SHADER_VERTEX_FLAG)) {
154 // TODO: Log debug message: Vertex Shader required.
Chia-I Wu3efef432014-08-28 15:00:16 +0800155 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600156 }
157
158 /*
159 * Tessalation control and evaluation have to both have a shader defined or
160 * neither should have a shader defined.
161 */
162 if (((pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) == 0) !=
163 ((pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) == 0) ) {
164 // TODO: Log debug message: Both Tess control and Tess eval are required to use tessalation
Chia-I Wu3efef432014-08-28 15:00:16 +0800165 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600166 }
167
168 if ((pipeline->active_shaders & SHADER_COMPUTE_FLAG) &&
169 (pipeline->active_shaders & (SHADER_VERTEX_FLAG | SHADER_TESS_CONTROL_FLAG |
170 SHADER_TESS_EVAL_FLAG | SHADER_GEOMETRY_FLAG |
171 SHADER_FRAGMENT_FLAG))) {
172 // TODO: Log debug message: Can only specify compute shader when doing compute
Chia-I Wu3efef432014-08-28 15:00:16 +0800173 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600174 }
175
176 /*
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600177 * XGL_TOPOLOGY_PATCH primitive topology is only valid for tessellation pipelines.
178 * Mismatching primitive topology and tessellation fails graphics pipeline creation.
179 */
180 if (pipeline->active_shaders & (SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG) &&
Chia-I Wube0a3d92014-09-02 13:20:59 +0800181 (pipeline->topology != XGL_TOPOLOGY_PATCH)) {
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600182 // TODO: Log debug message: Invalid topology used with tessalation shader.
Chia-I Wu3efef432014-08-28 15:00:16 +0800183 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600184 }
185
Chia-I Wube0a3d92014-09-02 13:20:59 +0800186 if ((pipeline->topology == XGL_TOPOLOGY_PATCH) &&
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600187 (pipeline->active_shaders & ~(SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG))) {
188 // TODO: Log debug message: Cannot use TOPOLOGY_PATCH on non-tessalation shader.
Chia-I Wu3efef432014-08-28 15:00:16 +0800189 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600190 }
191
Chia-I Wu3efef432014-08-28 15:00:16 +0800192 return XGL_SUCCESS;
193}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600194
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800195static void pipeline_build_urb_alloc_gen6(struct intel_pipeline *pipeline,
196 const struct intel_pipeline_create_info *info)
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800197{
Chia-I Wu509b3f22014-09-02 10:24:05 +0800198 const struct intel_gpu *gpu = pipeline->dev->gpu;
199 const int urb_size = ((gpu->gt == 2) ? 64 : 32) * 1024;
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800200 const struct intel_shader *vs = intel_shader(info->vs.shader);
201 const struct intel_shader *gs = intel_shader(info->gs.shader);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800202 int vs_entry_size, gs_entry_size;
203 int vs_size, gs_size;
204
Chia-I Wu509b3f22014-09-02 10:24:05 +0800205 INTEL_GPU_ASSERT(gpu, 6, 6);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800206
207 vs_entry_size = ((vs->in_count >= vs->out_count) ?
208 vs->in_count : vs->out_count);
209 gs_entry_size = (gs) ? gs->out_count : 0;
210
211 /* in bytes */
212 vs_entry_size *= sizeof(float) * 4;
213 gs_entry_size *= sizeof(float) * 4;
214
215 if (gs) {
216 vs_size = urb_size / 2;
217 gs_size = vs_size;
218 } else {
219 vs_size = urb_size;
220 gs_size = 0;
221 }
222
223 /* 3DSTATE_URB */
224 {
225 const uint8_t cmd_len = 3;
226 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_URB) |
227 (cmd_len - 2);
228 int vs_alloc_size, gs_alloc_size;
229 int vs_entry_count, gs_entry_count;
230 uint32_t *dw;
231
232 /* in 1024-bit rows */
233 vs_alloc_size = (vs_entry_size + 128 - 1) / 128;
234 gs_alloc_size = (gs_entry_size + 128 - 1) / 128;
235
236 /* valid range is [1, 5] */
237 if (!vs_alloc_size)
238 vs_alloc_size = 1;
239 if (!gs_alloc_size)
240 gs_alloc_size = 1;
241 assert(vs_alloc_size <= 5 && gs_alloc_size <= 5);
242
243 /* valid range is [24, 256], multiples of 4 */
244 vs_entry_count = (vs_size / 128 / vs_alloc_size) & ~3;
245 if (vs_entry_count > 256)
246 vs_entry_count = 256;
247 assert(vs_entry_count >= 24);
248
249 /* valid range is [0, 256], multiples of 4 */
250 gs_entry_count = (gs_size / 128 / gs_alloc_size) & ~3;
251 if (gs_entry_count > 256)
252 gs_entry_count = 256;
253
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600254 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800255
256 dw[0] = dw0;
257 dw[1] = (vs_alloc_size - 1) << GEN6_URB_DW1_VS_ENTRY_SIZE__SHIFT |
258 vs_entry_count << GEN6_URB_DW1_VS_ENTRY_COUNT__SHIFT;
259 dw[2] = gs_entry_count << GEN6_URB_DW2_GS_ENTRY_COUNT__SHIFT |
260 (gs_alloc_size - 1) << GEN6_URB_DW2_GS_ENTRY_SIZE__SHIFT;
261 }
262}
263
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800264static void pipeline_build_urb_alloc_gen7(struct intel_pipeline *pipeline,
265 const struct intel_pipeline_create_info *info)
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800266{
Chia-I Wu509b3f22014-09-02 10:24:05 +0800267 const struct intel_gpu *gpu = pipeline->dev->gpu;
268 const int urb_size = ((gpu->gt == 3) ? 512 :
269 (gpu->gt == 2) ? 256 : 128) * 1024;
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800270 const struct intel_shader *vs = intel_shader(info->vs.shader);
271 const struct intel_shader *gs = intel_shader(info->gs.shader);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800272 /* some space is reserved for PCBs */
Chia-I Wu509b3f22014-09-02 10:24:05 +0800273 int urb_offset = ((gpu->gt == 3) ? 32 : 16) * 1024;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800274 int vs_entry_size, gs_entry_size;
275 int vs_size, gs_size;
276
Chia-I Wu509b3f22014-09-02 10:24:05 +0800277 INTEL_GPU_ASSERT(gpu, 7, 7.5);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800278
279 vs_entry_size = ((vs->in_count >= vs->out_count) ?
280 vs->in_count : vs->out_count);
281 gs_entry_size = (gs) ? gs->out_count : 0;
282
283 /* in bytes */
284 vs_entry_size *= sizeof(float) * 4;
285 gs_entry_size *= sizeof(float) * 4;
286
287 if (gs) {
288 vs_size = (urb_size - urb_offset) / 2;
289 gs_size = vs_size;
290 } else {
291 vs_size = urb_size - urb_offset;
292 gs_size = 0;
293 }
294
295 /* 3DSTATE_URB_* */
296 {
297 const uint8_t cmd_len = 2;
298 int vs_alloc_size, gs_alloc_size;
299 int vs_entry_count, gs_entry_count;
300 uint32_t *dw;
301
302 /* in 512-bit rows */
303 vs_alloc_size = (vs_entry_size + 64 - 1) / 64;
304 gs_alloc_size = (gs_entry_size + 64 - 1) / 64;
305
306 if (!vs_alloc_size)
307 vs_alloc_size = 1;
308 if (!gs_alloc_size)
309 gs_alloc_size = 1;
310
311 /* avoid performance decrease due to banking */
312 if (vs_alloc_size == 5)
313 vs_alloc_size = 6;
314
315 /* in multiples of 8 */
316 vs_entry_count = (vs_size / 64 / vs_alloc_size) & ~7;
317 assert(vs_entry_count >= 32);
318
319 gs_entry_count = (gs_size / 64 / gs_alloc_size) & ~7;
320
Chia-I Wu509b3f22014-09-02 10:24:05 +0800321 if (intel_gpu_gen(gpu) >= INTEL_GEN(7.5)) {
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800322 const int max_vs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800323 (gpu->gt >= 2) ? 1664 : 640;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800324 const int max_gs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800325 (gpu->gt >= 2) ? 640 : 256;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800326 if (vs_entry_count >= max_vs_entry_count)
327 vs_entry_count = max_vs_entry_count;
328 if (gs_entry_count >= max_gs_entry_count)
329 gs_entry_count = max_gs_entry_count;
330 } else {
331 const int max_vs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800332 (gpu->gt == 2) ? 704 : 512;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800333 const int max_gs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800334 (gpu->gt == 2) ? 320 : 192;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800335 if (vs_entry_count >= max_vs_entry_count)
336 vs_entry_count = max_vs_entry_count;
337 if (gs_entry_count >= max_gs_entry_count)
338 gs_entry_count = max_gs_entry_count;
339 }
340
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600341 dw = pipeline_cmd_ptr(pipeline, cmd_len*4);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800342 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_VS) | (cmd_len - 2);
343 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT |
344 (vs_alloc_size - 1) << GEN7_URB_ANY_DW1_ENTRY_SIZE__SHIFT |
345 vs_entry_count;
346
347 dw += 2;
348 if (gs_size)
349 urb_offset += vs_size;
350 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_GS) | (cmd_len - 2);
351 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT |
352 (gs_alloc_size - 1) << GEN7_URB_ANY_DW1_ENTRY_SIZE__SHIFT |
353 gs_entry_count;
354
355 dw += 2;
356 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_HS) | (cmd_len - 2);
357 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT;
358
359 dw += 2;
360 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_DS) | (cmd_len - 2);
361 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT;
362 }
363}
364
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800365static void pipeline_build_push_const_alloc_gen7(struct intel_pipeline *pipeline,
366 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600367{
368 const uint8_t cmd_len = 2;
369 uint32_t offset = 0;
370 uint32_t size = 8192;
371 uint32_t *dw;
372 int end;
373
Chia-I Wu509b3f22014-09-02 10:24:05 +0800374 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600375
376 /*
377 * From the Ivy Bridge PRM, volume 2 part 1, page 68:
378 *
379 * "(A table that says the maximum size of each constant buffer is
380 * 16KB")
381 *
382 * From the Ivy Bridge PRM, volume 2 part 1, page 115:
383 *
384 * "The sum of the Constant Buffer Offset and the Constant Buffer Size
385 * may not exceed the maximum value of the Constant Buffer Size."
386 *
387 * Thus, the valid range of buffer end is [0KB, 16KB].
388 */
389 end = (offset + size) / 1024;
390 if (end > 16) {
391 assert(!"invalid constant buffer end");
392 end = 16;
393 }
394
395 /* the valid range of buffer offset is [0KB, 15KB] */
396 offset = (offset + 1023) / 1024;
397 if (offset > 15) {
398 assert(!"invalid constant buffer offset");
399 offset = 15;
400 }
401
402 if (offset > end) {
403 assert(!size);
404 offset = end;
405 }
406
407 /* the valid range of buffer size is [0KB, 15KB] */
408 size = end - offset;
409 if (size > 15) {
410 assert(!"invalid constant buffer size");
411 size = 15;
412 }
413
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800414 dw = pipeline_cmd_ptr(pipeline, cmd_len * 5);
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600415 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_VS) | (cmd_len - 2);
416 dw[1] = offset << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
417 size << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
418
419 dw += 2;
420 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_PS) | (cmd_len - 2);
421 dw[1] = size << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
422 size << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
423
424 dw += 2;
425 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_HS) | (cmd_len - 2);
426 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
427 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
428
429 dw += 2;
430 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_DS) | (cmd_len - 2);
431 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
432 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
433
434 dw += 2;
435 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_GS) | (cmd_len - 2);
436 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
437 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
Chia-I Wu8370b402014-08-29 12:28:37 +0800438
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600439 // gen7_wa_pipe_control_cs_stall(p, true, true);
440 // looks equivalent to: gen6_wa_wm_multisample_flush - this does more
441 // than the documentation seems to imply
442}
443
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800444static void pipeline_build_vertex_elements(struct intel_pipeline *pipeline,
445 const struct intel_pipeline_create_info *info)
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800446{
447 const uint8_t cmd_len = 3;
448 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_ELEMENTS) |
449 (cmd_len - 2);
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800450 const struct intel_shader *vs = intel_shader(info->vs.shader);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800451 int comps[4] = { GEN6_VFCOMP_NOSTORE, GEN6_VFCOMP_NOSTORE,
452 GEN6_VFCOMP_NOSTORE, GEN6_VFCOMP_NOSTORE };
453 uint32_t *dw;
454
Chia-I Wu509b3f22014-09-02 10:24:05 +0800455 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800456
457 if (!(vs->uses & (INTEL_SHADER_USE_VID | INTEL_SHADER_USE_IID)))
458 return;
459
460 dw = pipeline_cmd_ptr(pipeline, cmd_len);
461 dw[0] = dw0;
462 dw++;
463
464 comps[0] = (vs->uses & INTEL_SHADER_USE_VID) ?
465 GEN6_VFCOMP_STORE_VID : GEN6_VFCOMP_STORE_0;
466 if (vs->uses & INTEL_SHADER_USE_IID)
467 comps[1] = GEN6_VFCOMP_STORE_IID;
468
469 /* VERTEX_ELEMENT_STATE */
470 dw[0] = GEN6_VE_STATE_DW0_VALID;
471 dw[1] = comps[0] << GEN6_VE_STATE_DW1_COMP0__SHIFT |
472 comps[1] << GEN6_VE_STATE_DW1_COMP1__SHIFT |
473 comps[2] << GEN6_VE_STATE_DW1_COMP2__SHIFT |
474 comps[3] << GEN6_VE_STATE_DW1_COMP3__SHIFT;
475}
476
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800477static void pipeline_build_gs(struct intel_pipeline *pipeline,
478 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600479{
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600480 // gen7_emit_3DSTATE_GS done by cmd_pipeline
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600481}
482
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800483static void pipeline_build_hs(struct intel_pipeline *pipeline,
484 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600485{
486 const uint8_t cmd_len = 7;
487 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
488 uint32_t *dw;
489
Chia-I Wu509b3f22014-09-02 10:24:05 +0800490 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600491
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800492 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600493 dw[0] = dw0;
494 dw[1] = 0;
495 dw[2] = 0;
496 dw[3] = 0;
497 dw[4] = 0;
498 dw[5] = 0;
499 dw[6] = 0;
500}
501
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800502static void pipeline_build_te(struct intel_pipeline *pipeline,
503 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600504{
505 const uint8_t cmd_len = 4;
506 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_TE) | (cmd_len - 2);
507 uint32_t *dw;
508
Chia-I Wu509b3f22014-09-02 10:24:05 +0800509 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600510
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800511 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600512 dw[0] = dw0;
513 dw[1] = 0;
514 dw[2] = 0;
515 dw[3] = 0;
516}
517
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800518static void pipeline_build_ds(struct intel_pipeline *pipeline,
519 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600520{
521 const uint8_t cmd_len = 6;
522 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
523 uint32_t *dw;
524
Chia-I Wu509b3f22014-09-02 10:24:05 +0800525 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600526
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800527 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600528 dw[0] = dw0;
529 dw[1] = 0;
530 dw[2] = 0;
531 dw[3] = 0;
532 dw[4] = 0;
533 dw[5] = 0;
534}
535
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800536static XGL_RESULT pipeline_build_all(struct intel_pipeline *pipeline,
537 const struct intel_pipeline_create_info *info)
Chia-I Wu3efef432014-08-28 15:00:16 +0800538{
539 XGL_RESULT ret;
540
Chia-I Wu98824592014-09-02 09:42:46 +0800541 ret = pipeline_build_shaders(pipeline, info);
542 if (ret != XGL_SUCCESS)
543 return ret;
544
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800545 pipeline_build_vertex_elements(pipeline, info);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800546
Chia-I Wu509b3f22014-09-02 10:24:05 +0800547 if (intel_gpu_gen(pipeline->dev->gpu) >= INTEL_GEN(7)) {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800548 pipeline_build_urb_alloc_gen7(pipeline, info);
549 pipeline_build_push_const_alloc_gen7(pipeline, info);
550 pipeline_build_gs(pipeline, info);
551 pipeline_build_hs(pipeline, info);
552 pipeline_build_te(pipeline, info);
553 pipeline_build_ds(pipeline, info);
Chia-I Wu8370b402014-08-29 12:28:37 +0800554
555 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
556 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL |
557 INTEL_CMD_WA_GEN7_PRE_VS_DEPTH_STALL_WRITE |
558 INTEL_CMD_WA_GEN7_POST_COMMAND_CS_STALL |
559 INTEL_CMD_WA_GEN7_POST_COMMAND_DEPTH_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800560 } else {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800561 pipeline_build_urb_alloc_gen6(pipeline, info);
Chia-I Wu8370b402014-08-29 12:28:37 +0800562
563 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
564 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800565 }
566
Chia-I Wube0a3d92014-09-02 13:20:59 +0800567 ret = pipeline_build_ia(pipeline, info);
Chia-I Wu3efef432014-08-28 15:00:16 +0800568
569 if (ret == XGL_SUCCESS)
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800570 ret = pipeline_rs_state(pipeline, &info->rs);
Chia-I Wu3efef432014-08-28 15:00:16 +0800571
Chia-I Wu3efef432014-08-28 15:00:16 +0800572 if (ret == XGL_SUCCESS) {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800573 pipeline->db_format = info->db.format;
574 pipeline->cb_state = info->cb;
575 pipeline->tess_state = info->tess;
Chia-I Wu3efef432014-08-28 15:00:16 +0800576 }
577
578 return ret;
579}
580
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800581struct intel_pipeline_create_info_header {
582 XGL_STRUCTURE_TYPE struct_type;
583 const struct intel_pipeline_create_info_header *next;
584};
585
586static XGL_RESULT pipeline_create_info_init(struct intel_pipeline_create_info *info,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800587 const struct intel_pipeline_create_info_header *header)
Chia-I Wu3efef432014-08-28 15:00:16 +0800588{
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800589 memset(info, 0, sizeof(*info));
Chia-I Wu3efef432014-08-28 15:00:16 +0800590
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800591 while (header) {
592 const void *src = (const void *) header;
Chia-I Wu3efef432014-08-28 15:00:16 +0800593 XGL_SIZE size;
594 void *dst;
595
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800596 switch (header->struct_type) {
Chia-I Wu3efef432014-08-28 15:00:16 +0800597 case XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800598 size = sizeof(info->graphics);
599 dst = &info->graphics;
Chia-I Wu3efef432014-08-28 15:00:16 +0800600 break;
601 case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800602 size = sizeof(info->ia);
603 dst = &info->ia;
Chia-I Wu3efef432014-08-28 15:00:16 +0800604 break;
605 case XGL_STRUCTURE_TYPE_PIPELINE_DB_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800606 size = sizeof(info->db);
607 dst = &info->db;
Chia-I Wu3efef432014-08-28 15:00:16 +0800608 break;
609 case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800610 size = sizeof(info->cb);
611 dst = &info->cb;
Chia-I Wu3efef432014-08-28 15:00:16 +0800612 break;
613 case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800614 size = sizeof(info->rs);
615 dst = &info->rs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800616 break;
617 case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800618 size = sizeof(info->tess);
619 dst = &info->tess;
Chia-I Wu3efef432014-08-28 15:00:16 +0800620 break;
621 case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
622 {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800623 const XGL_PIPELINE_SHADER *shader =
624 (const XGL_PIPELINE_SHADER *) (header + 1);
Chia-I Wu3efef432014-08-28 15:00:16 +0800625
626 src = (const void *) shader;
627 size = sizeof(*shader);
628
629 switch (shader->stage) {
630 case XGL_SHADER_STAGE_VERTEX:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800631 dst = &info->vs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800632 break;
633 case XGL_SHADER_STAGE_TESS_CONTROL:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800634 dst = &info->tcs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800635 break;
636 case XGL_SHADER_STAGE_TESS_EVALUATION:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800637 dst = &info->tes;
Chia-I Wu3efef432014-08-28 15:00:16 +0800638 break;
639 case XGL_SHADER_STAGE_GEOMETRY:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800640 dst = &info->gs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800641 break;
642 case XGL_SHADER_STAGE_FRAGMENT:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800643 dst = &info->fs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800644 break;
Chia-I Wu3efef432014-08-28 15:00:16 +0800645 default:
646 return XGL_ERROR_BAD_PIPELINE_DATA;
647 break;
648 }
649 }
650 break;
651 case XGL_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800652 size = sizeof(info->compute);
653 dst = &info->compute;
Chia-I Wu3efef432014-08-28 15:00:16 +0800654 break;
655 default:
656 return XGL_ERROR_BAD_PIPELINE_DATA;
657 break;
658 }
659
660 memcpy(dst, src, size);
661
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800662 header = header->next;
Chia-I Wu3efef432014-08-28 15:00:16 +0800663 }
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600664
665 return XGL_SUCCESS;
Chia-I Wu3efef432014-08-28 15:00:16 +0800666}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600667
Chia-I Wu3efef432014-08-28 15:00:16 +0800668static XGL_RESULT graphics_pipeline_create(struct intel_dev *dev,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800669 const XGL_GRAPHICS_PIPELINE_CREATE_INFO *info_,
Chia-I Wu3efef432014-08-28 15:00:16 +0800670 struct intel_pipeline **pipeline_ret)
671{
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800672 struct intel_pipeline_create_info info;
Chia-I Wu3efef432014-08-28 15:00:16 +0800673 struct intel_pipeline *pipeline;
674 XGL_RESULT ret;
675
Chia-I Wu509b3f22014-09-02 10:24:05 +0800676 ret = pipeline_create_info_init(&info,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800677 (const struct intel_pipeline_create_info_header *) info_);
Chia-I Wu3efef432014-08-28 15:00:16 +0800678 if (ret != XGL_SUCCESS)
679 return ret;
680
681 pipeline = (struct intel_pipeline *)
682 intel_base_create(dev, sizeof(*pipeline), dev->base.dbg,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800683 XGL_DBG_OBJECT_GRAPHICS_PIPELINE, info_, 0);
Chia-I Wu3efef432014-08-28 15:00:16 +0800684 if (!pipeline)
685 return XGL_ERROR_OUT_OF_MEMORY;
686
687 pipeline->dev = dev;
688 pipeline->obj.destroy = pipeline_destroy;
Chia-I Wu3efef432014-08-28 15:00:16 +0800689
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800690 ret = pipeline_build_all(pipeline, &info);
Chia-I Wu3efef432014-08-28 15:00:16 +0800691 if (ret == XGL_SUCCESS)
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800692 ret = pipeline_validate(pipeline);
Chia-I Wu3efef432014-08-28 15:00:16 +0800693 if (ret != XGL_SUCCESS) {
694 pipeline_destroy(&pipeline->obj);
695 return ret;
696 }
697
698 *pipeline_ret = pipeline;
699
700 return XGL_SUCCESS;
701}
702
703XGL_RESULT XGLAPI intelCreateGraphicsPipeline(
704 XGL_DEVICE device,
705 const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
706 XGL_PIPELINE* pPipeline)
707{
708 struct intel_dev *dev = intel_dev(device);
709
710 return graphics_pipeline_create(dev, pCreateInfo,
711 (struct intel_pipeline **) pPipeline);
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600712}
713
714XGL_RESULT XGLAPI intelCreateComputePipeline(
715 XGL_DEVICE device,
716 const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo,
717 XGL_PIPELINE* pPipeline)
718{
719 return XGL_ERROR_UNAVAILABLE;
720}
721
722XGL_RESULT XGLAPI intelStorePipeline(
723 XGL_PIPELINE pipeline,
724 XGL_SIZE* pDataSize,
725 XGL_VOID* pData)
726{
727 return XGL_ERROR_UNAVAILABLE;
728}
729
730XGL_RESULT XGLAPI intelLoadPipeline(
731 XGL_DEVICE device,
732 XGL_SIZE dataSize,
733 const XGL_VOID* pData,
734 XGL_PIPELINE* pPipeline)
735{
736 return XGL_ERROR_UNAVAILABLE;
737}
738
739XGL_RESULT XGLAPI intelCreatePipelineDelta(
740 XGL_DEVICE device,
741 XGL_PIPELINE p1,
742 XGL_PIPELINE p2,
743 XGL_PIPELINE_DELTA* delta)
744{
745 return XGL_ERROR_UNAVAILABLE;
746}