blob: cdf4ae725878c2c0e1d9f11edecbaf7ffff305a5 [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 Wu3efef432014-08-28 15:00:16 +080044static XGL_RESULT pipeline_ia_state(struct intel_pipeline *pipeline,
45 const XGL_PIPELINE_IA_STATE_CREATE_INFO* ia_state)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060046{
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -060047 pipeline->ia_state = *ia_state;
48
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060049 if (ia_state->provokingVertex == XGL_PROVOKING_VERTEX_FIRST) {
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060050 pipeline->provoking_vertex_tri = 0;
51 pipeline->provoking_vertex_trifan = 1;
52 pipeline->provoking_vertex_line = 0;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060053 } else {
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060054 pipeline->provoking_vertex_tri = 2;
55 pipeline->provoking_vertex_trifan = 2;
56 pipeline->provoking_vertex_line = 1;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060057 }
58
59 switch (ia_state->topology) {
60 case XGL_TOPOLOGY_POINT_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060061 pipeline->prim_type = GEN6_3DPRIM_POINTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060062 break;
63 case XGL_TOPOLOGY_LINE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060064 pipeline->prim_type = GEN6_3DPRIM_LINELIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060065 break;
66 case XGL_TOPOLOGY_LINE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060067 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060068 break;
69 case XGL_TOPOLOGY_TRIANGLE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060070 pipeline->prim_type = GEN6_3DPRIM_TRILIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060071 break;
72 case XGL_TOPOLOGY_TRIANGLE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060073 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060074 break;
75 case XGL_TOPOLOGY_RECT_LIST:
76 /*
77 * TODO: Rect lists are special in XGL, do we need to do
78 * something special here?
79 * XGL Guide:
80 * The rectangle list is a special geometry primitive type
81 * that can be used for implementing post-processing techniques
82 * or efficient copy operations. There are some special limitations
83 * for rectangle primitives. They cannot be clipped, must
84 * be axis aligned and cannot have depth gradient.
85 * Failure to comply with these restrictions results in
86 * undefined rendering results.
87 */
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060088 pipeline->prim_type = GEN6_3DPRIM_RECTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060089 break;
90 case XGL_TOPOLOGY_QUAD_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060091 pipeline->prim_type = GEN6_3DPRIM_QUADLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060092 break;
93 case XGL_TOPOLOGY_QUAD_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060094 pipeline->prim_type = GEN6_3DPRIM_QUADSTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060095 break;
96 case XGL_TOPOLOGY_LINE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060097 pipeline->prim_type = GEN6_3DPRIM_LINELIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060098 break;
99 case XGL_TOPOLOGY_LINE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600100 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600101 break;
102 case XGL_TOPOLOGY_TRIANGLE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600103 pipeline->prim_type = GEN6_3DPRIM_TRILIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600104 break;
105 case XGL_TOPOLOGY_TRIANGLE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -0600106 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600107 break;
108 case XGL_TOPOLOGY_PATCH:
109 // TODO: implement something here
110 break;
111 default:
112 return XGL_ERROR_BAD_PIPELINE_DATA;
113 }
114
115 if (ia_state->primitiveRestartEnable) {
116 pipeline->primitive_restart = true;
117 pipeline->primitive_restart_index = ia_state->primitiveRestartIndex;
118 } else {
119 pipeline->primitive_restart = false;
120 }
121
122 if (ia_state->disableVertexReuse) {
123 // TODO: What do we do to disable vertex reuse?
124 }
125
126 return XGL_SUCCESS;
127}
128
Chia-I Wu3efef432014-08-28 15:00:16 +0800129static XGL_RESULT pipeline_rs_state(struct intel_pipeline *pipeline,
130 const XGL_PIPELINE_RS_STATE_CREATE_INFO* rs_state)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600131{
132 pipeline->depthClipEnable = rs_state->depthClipEnable;
133 pipeline->rasterizerDiscardEnable = rs_state->rasterizerDiscardEnable;
134 pipeline->pointSize = rs_state->pointSize;
135 return XGL_SUCCESS;
136}
137
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600138static void pipeline_destroy(struct intel_obj *obj)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600139{
140 struct intel_pipeline *pipeline = intel_pipeline_from_obj(obj);
141
Chia-I Wu98824592014-09-02 09:42:46 +0800142 pipeline_tear_shaders(pipeline);
Chia-I Wued833872014-08-23 17:00:35 +0800143
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600144 intel_base_destroy(&pipeline->obj.base);
145}
146
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800147static XGL_RESULT pipeline_validate(struct intel_pipeline *pipeline)
Chia-I Wu3efef432014-08-28 15:00:16 +0800148{
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600149 /*
150 * Validate required elements
151 */
152 if (!(pipeline->active_shaders & SHADER_VERTEX_FLAG)) {
153 // TODO: Log debug message: Vertex Shader required.
Chia-I Wu3efef432014-08-28 15:00:16 +0800154 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600155 }
156
157 /*
158 * Tessalation control and evaluation have to both have a shader defined or
159 * neither should have a shader defined.
160 */
161 if (((pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) == 0) !=
162 ((pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) == 0) ) {
163 // TODO: Log debug message: Both Tess control and Tess eval are required to use tessalation
Chia-I Wu3efef432014-08-28 15:00:16 +0800164 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600165 }
166
167 if ((pipeline->active_shaders & SHADER_COMPUTE_FLAG) &&
168 (pipeline->active_shaders & (SHADER_VERTEX_FLAG | SHADER_TESS_CONTROL_FLAG |
169 SHADER_TESS_EVAL_FLAG | SHADER_GEOMETRY_FLAG |
170 SHADER_FRAGMENT_FLAG))) {
171 // TODO: Log debug message: Can only specify compute shader when doing compute
Chia-I Wu3efef432014-08-28 15:00:16 +0800172 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600173 }
174
175 /*
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600176 * XGL_TOPOLOGY_PATCH primitive topology is only valid for tessellation pipelines.
177 * Mismatching primitive topology and tessellation fails graphics pipeline creation.
178 */
179 if (pipeline->active_shaders & (SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG) &&
180 (pipeline->ia_state.topology != XGL_TOPOLOGY_PATCH)) {
181 // TODO: Log debug message: Invalid topology used with tessalation shader.
Chia-I Wu3efef432014-08-28 15:00:16 +0800182 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600183 }
184
185 if ((pipeline->ia_state.topology == XGL_TOPOLOGY_PATCH) &&
186 (pipeline->active_shaders & ~(SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG))) {
187 // TODO: Log debug message: Cannot use TOPOLOGY_PATCH on non-tessalation shader.
Chia-I Wu3efef432014-08-28 15:00:16 +0800188 return XGL_ERROR_BAD_PIPELINE_DATA;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600189 }
190
Chia-I Wu3efef432014-08-28 15:00:16 +0800191 return XGL_SUCCESS;
192}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600193
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800194static void pipeline_build_urb_alloc_gen6(struct intel_pipeline *pipeline,
195 const struct intel_pipeline_create_info *info)
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800196{
Chia-I Wu509b3f22014-09-02 10:24:05 +0800197 const struct intel_gpu *gpu = pipeline->dev->gpu;
198 const int urb_size = ((gpu->gt == 2) ? 64 : 32) * 1024;
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800199 const struct intel_shader *vs = intel_shader(info->vs.shader);
200 const struct intel_shader *gs = intel_shader(info->gs.shader);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800201 int vs_entry_size, gs_entry_size;
202 int vs_size, gs_size;
203
Chia-I Wu509b3f22014-09-02 10:24:05 +0800204 INTEL_GPU_ASSERT(gpu, 6, 6);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800205
206 vs_entry_size = ((vs->in_count >= vs->out_count) ?
207 vs->in_count : vs->out_count);
208 gs_entry_size = (gs) ? gs->out_count : 0;
209
210 /* in bytes */
211 vs_entry_size *= sizeof(float) * 4;
212 gs_entry_size *= sizeof(float) * 4;
213
214 if (gs) {
215 vs_size = urb_size / 2;
216 gs_size = vs_size;
217 } else {
218 vs_size = urb_size;
219 gs_size = 0;
220 }
221
222 /* 3DSTATE_URB */
223 {
224 const uint8_t cmd_len = 3;
225 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_URB) |
226 (cmd_len - 2);
227 int vs_alloc_size, gs_alloc_size;
228 int vs_entry_count, gs_entry_count;
229 uint32_t *dw;
230
231 /* in 1024-bit rows */
232 vs_alloc_size = (vs_entry_size + 128 - 1) / 128;
233 gs_alloc_size = (gs_entry_size + 128 - 1) / 128;
234
235 /* valid range is [1, 5] */
236 if (!vs_alloc_size)
237 vs_alloc_size = 1;
238 if (!gs_alloc_size)
239 gs_alloc_size = 1;
240 assert(vs_alloc_size <= 5 && gs_alloc_size <= 5);
241
242 /* valid range is [24, 256], multiples of 4 */
243 vs_entry_count = (vs_size / 128 / vs_alloc_size) & ~3;
244 if (vs_entry_count > 256)
245 vs_entry_count = 256;
246 assert(vs_entry_count >= 24);
247
248 /* valid range is [0, 256], multiples of 4 */
249 gs_entry_count = (gs_size / 128 / gs_alloc_size) & ~3;
250 if (gs_entry_count > 256)
251 gs_entry_count = 256;
252
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600253 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800254
255 dw[0] = dw0;
256 dw[1] = (vs_alloc_size - 1) << GEN6_URB_DW1_VS_ENTRY_SIZE__SHIFT |
257 vs_entry_count << GEN6_URB_DW1_VS_ENTRY_COUNT__SHIFT;
258 dw[2] = gs_entry_count << GEN6_URB_DW2_GS_ENTRY_COUNT__SHIFT |
259 (gs_alloc_size - 1) << GEN6_URB_DW2_GS_ENTRY_SIZE__SHIFT;
260 }
261}
262
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800263static void pipeline_build_urb_alloc_gen7(struct intel_pipeline *pipeline,
264 const struct intel_pipeline_create_info *info)
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800265{
Chia-I Wu509b3f22014-09-02 10:24:05 +0800266 const struct intel_gpu *gpu = pipeline->dev->gpu;
267 const int urb_size = ((gpu->gt == 3) ? 512 :
268 (gpu->gt == 2) ? 256 : 128) * 1024;
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800269 const struct intel_shader *vs = intel_shader(info->vs.shader);
270 const struct intel_shader *gs = intel_shader(info->gs.shader);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800271 /* some space is reserved for PCBs */
Chia-I Wu509b3f22014-09-02 10:24:05 +0800272 int urb_offset = ((gpu->gt == 3) ? 32 : 16) * 1024;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800273 int vs_entry_size, gs_entry_size;
274 int vs_size, gs_size;
275
Chia-I Wu509b3f22014-09-02 10:24:05 +0800276 INTEL_GPU_ASSERT(gpu, 7, 7.5);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800277
278 vs_entry_size = ((vs->in_count >= vs->out_count) ?
279 vs->in_count : vs->out_count);
280 gs_entry_size = (gs) ? gs->out_count : 0;
281
282 /* in bytes */
283 vs_entry_size *= sizeof(float) * 4;
284 gs_entry_size *= sizeof(float) * 4;
285
286 if (gs) {
287 vs_size = (urb_size - urb_offset) / 2;
288 gs_size = vs_size;
289 } else {
290 vs_size = urb_size - urb_offset;
291 gs_size = 0;
292 }
293
294 /* 3DSTATE_URB_* */
295 {
296 const uint8_t cmd_len = 2;
297 int vs_alloc_size, gs_alloc_size;
298 int vs_entry_count, gs_entry_count;
299 uint32_t *dw;
300
301 /* in 512-bit rows */
302 vs_alloc_size = (vs_entry_size + 64 - 1) / 64;
303 gs_alloc_size = (gs_entry_size + 64 - 1) / 64;
304
305 if (!vs_alloc_size)
306 vs_alloc_size = 1;
307 if (!gs_alloc_size)
308 gs_alloc_size = 1;
309
310 /* avoid performance decrease due to banking */
311 if (vs_alloc_size == 5)
312 vs_alloc_size = 6;
313
314 /* in multiples of 8 */
315 vs_entry_count = (vs_size / 64 / vs_alloc_size) & ~7;
316 assert(vs_entry_count >= 32);
317
318 gs_entry_count = (gs_size / 64 / gs_alloc_size) & ~7;
319
Chia-I Wu509b3f22014-09-02 10:24:05 +0800320 if (intel_gpu_gen(gpu) >= INTEL_GEN(7.5)) {
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800321 const int max_vs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800322 (gpu->gt >= 2) ? 1664 : 640;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800323 const int max_gs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800324 (gpu->gt >= 2) ? 640 : 256;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800325 if (vs_entry_count >= max_vs_entry_count)
326 vs_entry_count = max_vs_entry_count;
327 if (gs_entry_count >= max_gs_entry_count)
328 gs_entry_count = max_gs_entry_count;
329 } else {
330 const int max_vs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800331 (gpu->gt == 2) ? 704 : 512;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800332 const int max_gs_entry_count =
Chia-I Wu509b3f22014-09-02 10:24:05 +0800333 (gpu->gt == 2) ? 320 : 192;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800334 if (vs_entry_count >= max_vs_entry_count)
335 vs_entry_count = max_vs_entry_count;
336 if (gs_entry_count >= max_gs_entry_count)
337 gs_entry_count = max_gs_entry_count;
338 }
339
Courtney Goeltzenleuchter814cd292014-08-28 13:16:27 -0600340 dw = pipeline_cmd_ptr(pipeline, cmd_len*4);
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800341 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_VS) | (cmd_len - 2);
342 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT |
343 (vs_alloc_size - 1) << GEN7_URB_ANY_DW1_ENTRY_SIZE__SHIFT |
344 vs_entry_count;
345
346 dw += 2;
347 if (gs_size)
348 urb_offset += vs_size;
349 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_GS) | (cmd_len - 2);
350 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT |
351 (gs_alloc_size - 1) << GEN7_URB_ANY_DW1_ENTRY_SIZE__SHIFT |
352 gs_entry_count;
353
354 dw += 2;
355 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_HS) | (cmd_len - 2);
356 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT;
357
358 dw += 2;
359 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_DS) | (cmd_len - 2);
360 dw[1] = (urb_offset / 8192) << GEN7_URB_ANY_DW1_OFFSET__SHIFT;
361 }
362}
363
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800364static void pipeline_build_push_const_alloc_gen7(struct intel_pipeline *pipeline,
365 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600366{
367 const uint8_t cmd_len = 2;
368 uint32_t offset = 0;
369 uint32_t size = 8192;
370 uint32_t *dw;
371 int end;
372
Chia-I Wu509b3f22014-09-02 10:24:05 +0800373 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600374
375 /*
376 * From the Ivy Bridge PRM, volume 2 part 1, page 68:
377 *
378 * "(A table that says the maximum size of each constant buffer is
379 * 16KB")
380 *
381 * From the Ivy Bridge PRM, volume 2 part 1, page 115:
382 *
383 * "The sum of the Constant Buffer Offset and the Constant Buffer Size
384 * may not exceed the maximum value of the Constant Buffer Size."
385 *
386 * Thus, the valid range of buffer end is [0KB, 16KB].
387 */
388 end = (offset + size) / 1024;
389 if (end > 16) {
390 assert(!"invalid constant buffer end");
391 end = 16;
392 }
393
394 /* the valid range of buffer offset is [0KB, 15KB] */
395 offset = (offset + 1023) / 1024;
396 if (offset > 15) {
397 assert(!"invalid constant buffer offset");
398 offset = 15;
399 }
400
401 if (offset > end) {
402 assert(!size);
403 offset = end;
404 }
405
406 /* the valid range of buffer size is [0KB, 15KB] */
407 size = end - offset;
408 if (size > 15) {
409 assert(!"invalid constant buffer size");
410 size = 15;
411 }
412
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800413 dw = pipeline_cmd_ptr(pipeline, cmd_len * 5);
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600414 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_VS) | (cmd_len - 2);
415 dw[1] = offset << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
416 size << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
417
418 dw += 2;
419 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_PS) | (cmd_len - 2);
420 dw[1] = size << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
421 size << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
422
423 dw += 2;
424 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_HS) | (cmd_len - 2);
425 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
426 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
427
428 dw += 2;
429 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_DS) | (cmd_len - 2);
430 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
431 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
432
433 dw += 2;
434 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_GS) | (cmd_len - 2);
435 dw[1] = 0 << GEN7_PCB_ALLOC_ANY_DW1_OFFSET__SHIFT |
436 0 << GEN7_PCB_ALLOC_ANY_DW1_SIZE__SHIFT;
Chia-I Wu8370b402014-08-29 12:28:37 +0800437
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600438 // gen7_wa_pipe_control_cs_stall(p, true, true);
439 // looks equivalent to: gen6_wa_wm_multisample_flush - this does more
440 // than the documentation seems to imply
441}
442
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800443static void pipeline_build_vertex_elements(struct intel_pipeline *pipeline,
444 const struct intel_pipeline_create_info *info)
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800445{
446 const uint8_t cmd_len = 3;
447 const uint32_t dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_ELEMENTS) |
448 (cmd_len - 2);
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800449 const struct intel_shader *vs = intel_shader(info->vs.shader);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800450 int comps[4] = { GEN6_VFCOMP_NOSTORE, GEN6_VFCOMP_NOSTORE,
451 GEN6_VFCOMP_NOSTORE, GEN6_VFCOMP_NOSTORE };
452 uint32_t *dw;
453
Chia-I Wu509b3f22014-09-02 10:24:05 +0800454 INTEL_GPU_ASSERT(pipeline->dev->gpu, 6, 7.5);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800455
456 if (!(vs->uses & (INTEL_SHADER_USE_VID | INTEL_SHADER_USE_IID)))
457 return;
458
459 dw = pipeline_cmd_ptr(pipeline, cmd_len);
460 dw[0] = dw0;
461 dw++;
462
463 comps[0] = (vs->uses & INTEL_SHADER_USE_VID) ?
464 GEN6_VFCOMP_STORE_VID : GEN6_VFCOMP_STORE_0;
465 if (vs->uses & INTEL_SHADER_USE_IID)
466 comps[1] = GEN6_VFCOMP_STORE_IID;
467
468 /* VERTEX_ELEMENT_STATE */
469 dw[0] = GEN6_VE_STATE_DW0_VALID;
470 dw[1] = comps[0] << GEN6_VE_STATE_DW1_COMP0__SHIFT |
471 comps[1] << GEN6_VE_STATE_DW1_COMP1__SHIFT |
472 comps[2] << GEN6_VE_STATE_DW1_COMP2__SHIFT |
473 comps[3] << GEN6_VE_STATE_DW1_COMP3__SHIFT;
474}
475
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800476static void pipeline_build_gs(struct intel_pipeline *pipeline,
477 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600478{
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600479 // gen7_emit_3DSTATE_GS done by cmd_pipeline
Courtney Goeltzenleuchterb2867702014-08-28 17:44:05 -0600480}
481
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800482static void pipeline_build_hs(struct intel_pipeline *pipeline,
483 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600484{
485 const uint8_t cmd_len = 7;
486 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
487 uint32_t *dw;
488
Chia-I Wu509b3f22014-09-02 10:24:05 +0800489 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600490
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800491 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600492 dw[0] = dw0;
493 dw[1] = 0;
494 dw[2] = 0;
495 dw[3] = 0;
496 dw[4] = 0;
497 dw[5] = 0;
498 dw[6] = 0;
499}
500
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800501static void pipeline_build_te(struct intel_pipeline *pipeline,
502 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600503{
504 const uint8_t cmd_len = 4;
505 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_TE) | (cmd_len - 2);
506 uint32_t *dw;
507
Chia-I Wu509b3f22014-09-02 10:24:05 +0800508 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600509
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800510 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600511 dw[0] = dw0;
512 dw[1] = 0;
513 dw[2] = 0;
514 dw[3] = 0;
515}
516
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800517static void pipeline_build_ds(struct intel_pipeline *pipeline,
518 const struct intel_pipeline_create_info *info)
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600519{
520 const uint8_t cmd_len = 6;
521 const uint32_t dw0 = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
522 uint32_t *dw;
523
Chia-I Wu509b3f22014-09-02 10:24:05 +0800524 INTEL_GPU_ASSERT(pipeline->dev->gpu, 7, 7.5);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600525
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800526 dw = pipeline_cmd_ptr(pipeline, cmd_len);
Courtney Goeltzenleuchterdee81a62014-08-28 18:05:24 -0600527 dw[0] = dw0;
528 dw[1] = 0;
529 dw[2] = 0;
530 dw[3] = 0;
531 dw[4] = 0;
532 dw[5] = 0;
533}
534
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800535static XGL_RESULT pipeline_build_all(struct intel_pipeline *pipeline,
536 const struct intel_pipeline_create_info *info)
Chia-I Wu3efef432014-08-28 15:00:16 +0800537{
538 XGL_RESULT ret;
539
Chia-I Wu98824592014-09-02 09:42:46 +0800540 ret = pipeline_build_shaders(pipeline, info);
541 if (ret != XGL_SUCCESS)
542 return ret;
543
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800544 pipeline_build_vertex_elements(pipeline, info);
Chia-I Wu4d9ad912014-08-29 14:20:36 +0800545
Chia-I Wu509b3f22014-09-02 10:24:05 +0800546 if (intel_gpu_gen(pipeline->dev->gpu) >= INTEL_GEN(7)) {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800547 pipeline_build_urb_alloc_gen7(pipeline, info);
548 pipeline_build_push_const_alloc_gen7(pipeline, info);
549 pipeline_build_gs(pipeline, info);
550 pipeline_build_hs(pipeline, info);
551 pipeline_build_te(pipeline, info);
552 pipeline_build_ds(pipeline, info);
Chia-I Wu8370b402014-08-29 12:28:37 +0800553
554 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
555 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL |
556 INTEL_CMD_WA_GEN7_PRE_VS_DEPTH_STALL_WRITE |
557 INTEL_CMD_WA_GEN7_POST_COMMAND_CS_STALL |
558 INTEL_CMD_WA_GEN7_POST_COMMAND_DEPTH_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800559 } else {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800560 pipeline_build_urb_alloc_gen6(pipeline, info);
Chia-I Wu8370b402014-08-29 12:28:37 +0800561
562 pipeline->wa_flags = INTEL_CMD_WA_GEN6_PRE_DEPTH_STALL_WRITE |
563 INTEL_CMD_WA_GEN6_PRE_COMMAND_SCOREBOARD_STALL;
Chia-I Wubb2d8ca2014-08-28 23:15:48 +0800564 }
565
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800566 ret = pipeline_ia_state(pipeline, &info->ia);
Chia-I Wu3efef432014-08-28 15:00:16 +0800567
568 if (ret == XGL_SUCCESS)
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800569 ret = pipeline_rs_state(pipeline, &info->rs);
Chia-I Wu3efef432014-08-28 15:00:16 +0800570
Chia-I Wu3efef432014-08-28 15:00:16 +0800571 if (ret == XGL_SUCCESS) {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800572 pipeline->db_format = info->db.format;
573 pipeline->cb_state = info->cb;
574 pipeline->tess_state = info->tess;
Chia-I Wu3efef432014-08-28 15:00:16 +0800575 }
576
577 return ret;
578}
579
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800580struct intel_pipeline_create_info_header {
581 XGL_STRUCTURE_TYPE struct_type;
582 const struct intel_pipeline_create_info_header *next;
583};
584
585static XGL_RESULT pipeline_create_info_init(struct intel_pipeline_create_info *info,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800586 const struct intel_pipeline_create_info_header *header)
Chia-I Wu3efef432014-08-28 15:00:16 +0800587{
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800588 memset(info, 0, sizeof(*info));
Chia-I Wu3efef432014-08-28 15:00:16 +0800589
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800590 while (header) {
591 const void *src = (const void *) header;
Chia-I Wu3efef432014-08-28 15:00:16 +0800592 XGL_SIZE size;
593 void *dst;
594
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800595 switch (header->struct_type) {
Chia-I Wu3efef432014-08-28 15:00:16 +0800596 case XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800597 size = sizeof(info->graphics);
598 dst = &info->graphics;
Chia-I Wu3efef432014-08-28 15:00:16 +0800599 break;
600 case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800601 size = sizeof(info->ia);
602 dst = &info->ia;
Chia-I Wu3efef432014-08-28 15:00:16 +0800603 break;
604 case XGL_STRUCTURE_TYPE_PIPELINE_DB_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800605 size = sizeof(info->db);
606 dst = &info->db;
Chia-I Wu3efef432014-08-28 15:00:16 +0800607 break;
608 case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800609 size = sizeof(info->cb);
610 dst = &info->cb;
Chia-I Wu3efef432014-08-28 15:00:16 +0800611 break;
612 case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800613 size = sizeof(info->rs);
614 dst = &info->rs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800615 break;
616 case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800617 size = sizeof(info->tess);
618 dst = &info->tess;
Chia-I Wu3efef432014-08-28 15:00:16 +0800619 break;
620 case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
621 {
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800622 const XGL_PIPELINE_SHADER *shader =
623 (const XGL_PIPELINE_SHADER *) (header + 1);
Chia-I Wu3efef432014-08-28 15:00:16 +0800624
625 src = (const void *) shader;
626 size = sizeof(*shader);
627
628 switch (shader->stage) {
629 case XGL_SHADER_STAGE_VERTEX:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800630 dst = &info->vs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800631 break;
632 case XGL_SHADER_STAGE_TESS_CONTROL:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800633 dst = &info->tcs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800634 break;
635 case XGL_SHADER_STAGE_TESS_EVALUATION:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800636 dst = &info->tes;
Chia-I Wu3efef432014-08-28 15:00:16 +0800637 break;
638 case XGL_SHADER_STAGE_GEOMETRY:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800639 dst = &info->gs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800640 break;
641 case XGL_SHADER_STAGE_FRAGMENT:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800642 dst = &info->fs;
Chia-I Wu3efef432014-08-28 15:00:16 +0800643 break;
Chia-I Wu3efef432014-08-28 15:00:16 +0800644 default:
645 return XGL_ERROR_BAD_PIPELINE_DATA;
646 break;
647 }
648 }
649 break;
650 case XGL_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO:
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800651 size = sizeof(info->compute);
652 dst = &info->compute;
Chia-I Wu3efef432014-08-28 15:00:16 +0800653 break;
654 default:
655 return XGL_ERROR_BAD_PIPELINE_DATA;
656 break;
657 }
658
659 memcpy(dst, src, size);
660
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800661 header = header->next;
Chia-I Wu3efef432014-08-28 15:00:16 +0800662 }
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600663
664 return XGL_SUCCESS;
Chia-I Wu3efef432014-08-28 15:00:16 +0800665}
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600666
Chia-I Wu3efef432014-08-28 15:00:16 +0800667static XGL_RESULT graphics_pipeline_create(struct intel_dev *dev,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800668 const XGL_GRAPHICS_PIPELINE_CREATE_INFO *info_,
Chia-I Wu3efef432014-08-28 15:00:16 +0800669 struct intel_pipeline **pipeline_ret)
670{
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800671 struct intel_pipeline_create_info info;
Chia-I Wu3efef432014-08-28 15:00:16 +0800672 struct intel_pipeline *pipeline;
673 XGL_RESULT ret;
674
Chia-I Wu509b3f22014-09-02 10:24:05 +0800675 ret = pipeline_create_info_init(&info,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800676 (const struct intel_pipeline_create_info_header *) info_);
Chia-I Wu3efef432014-08-28 15:00:16 +0800677 if (ret != XGL_SUCCESS)
678 return ret;
679
680 pipeline = (struct intel_pipeline *)
681 intel_base_create(dev, sizeof(*pipeline), dev->base.dbg,
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800682 XGL_DBG_OBJECT_GRAPHICS_PIPELINE, info_, 0);
Chia-I Wu3efef432014-08-28 15:00:16 +0800683 if (!pipeline)
684 return XGL_ERROR_OUT_OF_MEMORY;
685
686 pipeline->dev = dev;
687 pipeline->obj.destroy = pipeline_destroy;
Chia-I Wu3efef432014-08-28 15:00:16 +0800688
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800689 ret = pipeline_build_all(pipeline, &info);
Chia-I Wu3efef432014-08-28 15:00:16 +0800690 if (ret == XGL_SUCCESS)
Chia-I Wuf90ff0c2014-09-02 09:32:46 +0800691 ret = pipeline_validate(pipeline);
Chia-I Wu3efef432014-08-28 15:00:16 +0800692 if (ret != XGL_SUCCESS) {
693 pipeline_destroy(&pipeline->obj);
694 return ret;
695 }
696
697 *pipeline_ret = pipeline;
698
699 return XGL_SUCCESS;
700}
701
702XGL_RESULT XGLAPI intelCreateGraphicsPipeline(
703 XGL_DEVICE device,
704 const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
705 XGL_PIPELINE* pPipeline)
706{
707 struct intel_dev *dev = intel_dev(device);
708
709 return graphics_pipeline_create(dev, pCreateInfo,
710 (struct intel_pipeline **) pPipeline);
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600711}
712
713XGL_RESULT XGLAPI intelCreateComputePipeline(
714 XGL_DEVICE device,
715 const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo,
716 XGL_PIPELINE* pPipeline)
717{
718 return XGL_ERROR_UNAVAILABLE;
719}
720
721XGL_RESULT XGLAPI intelStorePipeline(
722 XGL_PIPELINE pipeline,
723 XGL_SIZE* pDataSize,
724 XGL_VOID* pData)
725{
726 return XGL_ERROR_UNAVAILABLE;
727}
728
729XGL_RESULT XGLAPI intelLoadPipeline(
730 XGL_DEVICE device,
731 XGL_SIZE dataSize,
732 const XGL_VOID* pData,
733 XGL_PIPELINE* pPipeline)
734{
735 return XGL_ERROR_UNAVAILABLE;
736}
737
738XGL_RESULT XGLAPI intelCreatePipelineDelta(
739 XGL_DEVICE device,
740 XGL_PIPELINE p1,
741 XGL_PIPELINE p2,
742 XGL_PIPELINE_DELTA* delta)
743{
744 return XGL_ERROR_UNAVAILABLE;
745}