blob: ad72d71c8989437efab5e3abcf194eab349b4bea [file] [log] [blame]
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -06001/*
2 * XGL
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -060025#include "shader.h"
Chia-I Wued833872014-08-23 17:00:35 +080026#include "pipeline_priv.h"
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060027#include "genhw/gen_render_3d.xml.h"
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060028
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -060029static XGL_RESULT pipeline_ia_state(struct intel_dev *dev, struct intel_pipeline *pipeline,
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060030 const XGL_PIPELINE_IA_STATE_CREATE_INFO* ia_state)
31{
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -060032 pipeline->ia_state = *ia_state;
33
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060034 if (ia_state->provokingVertex == XGL_PROVOKING_VERTEX_FIRST) {
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060035 pipeline->provoking_vertex_tri = 0;
36 pipeline->provoking_vertex_trifan = 1;
37 pipeline->provoking_vertex_line = 0;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060038 } else {
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060039 pipeline->provoking_vertex_tri = 2;
40 pipeline->provoking_vertex_trifan = 2;
41 pipeline->provoking_vertex_line = 1;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060042 }
43
44 switch (ia_state->topology) {
45 case XGL_TOPOLOGY_POINT_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060046 pipeline->prim_type = GEN6_3DPRIM_POINTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060047 break;
48 case XGL_TOPOLOGY_LINE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060049 pipeline->prim_type = GEN6_3DPRIM_LINELIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060050 break;
51 case XGL_TOPOLOGY_LINE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060052 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060053 break;
54 case XGL_TOPOLOGY_TRIANGLE_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060055 pipeline->prim_type = GEN6_3DPRIM_TRILIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060056 break;
57 case XGL_TOPOLOGY_TRIANGLE_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060058 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060059 break;
60 case XGL_TOPOLOGY_RECT_LIST:
61 /*
62 * TODO: Rect lists are special in XGL, do we need to do
63 * something special here?
64 * XGL Guide:
65 * The rectangle list is a special geometry primitive type
66 * that can be used for implementing post-processing techniques
67 * or efficient copy operations. There are some special limitations
68 * for rectangle primitives. They cannot be clipped, must
69 * be axis aligned and cannot have depth gradient.
70 * Failure to comply with these restrictions results in
71 * undefined rendering results.
72 */
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060073 pipeline->prim_type = GEN6_3DPRIM_RECTLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060074 break;
75 case XGL_TOPOLOGY_QUAD_LIST:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060076 pipeline->prim_type = GEN6_3DPRIM_QUADLIST;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060077 break;
78 case XGL_TOPOLOGY_QUAD_STRIP:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060079 pipeline->prim_type = GEN6_3DPRIM_QUADSTRIP;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060080 break;
81 case XGL_TOPOLOGY_LINE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060082 pipeline->prim_type = GEN6_3DPRIM_LINELIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060083 break;
84 case XGL_TOPOLOGY_LINE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060085 pipeline->prim_type = GEN6_3DPRIM_LINESTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060086 break;
87 case XGL_TOPOLOGY_TRIANGLE_LIST_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060088 pipeline->prim_type = GEN6_3DPRIM_TRILIST_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060089 break;
90 case XGL_TOPOLOGY_TRIANGLE_STRIP_ADJ:
Courtney Goeltzenleuchter8a3de592014-08-22 09:09:46 -060091 pipeline->prim_type = GEN6_3DPRIM_TRISTRIP_ADJ;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060092 break;
93 case XGL_TOPOLOGY_PATCH:
94 // TODO: implement something here
95 break;
96 default:
97 return XGL_ERROR_BAD_PIPELINE_DATA;
98 }
99
100 if (ia_state->primitiveRestartEnable) {
101 pipeline->primitive_restart = true;
102 pipeline->primitive_restart_index = ia_state->primitiveRestartIndex;
103 } else {
104 pipeline->primitive_restart = false;
105 }
106
107 if (ia_state->disableVertexReuse) {
108 // TODO: What do we do to disable vertex reuse?
109 }
110
111 return XGL_SUCCESS;
112}
113
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600114static XGL_RESULT pipeline_rs_state(struct intel_dev *dev, struct intel_pipeline *pipeline,
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600115 const XGL_PIPELINE_RS_STATE_CREATE_INFO* rs_state)
116{
117 pipeline->depthClipEnable = rs_state->depthClipEnable;
118 pipeline->rasterizerDiscardEnable = rs_state->rasterizerDiscardEnable;
119 pipeline->pointSize = rs_state->pointSize;
120 return XGL_SUCCESS;
121}
122
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600123static void pipeline_destroy(struct intel_obj *obj)
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600124{
125 struct intel_pipeline *pipeline = intel_pipeline_from_obj(obj);
126
Chia-I Wued833872014-08-23 17:00:35 +0800127 if (pipeline->vs_rmap)
128 intel_rmap_destroy(pipeline->vs_rmap);
129 if (pipeline->fs_rmap)
130 intel_rmap_destroy(pipeline->fs_rmap);
131
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600132 intel_base_destroy(&pipeline->obj.base);
133}
134
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600135static XGL_RESULT pipeline_get_info(struct intel_base *base, int type,
136 XGL_SIZE *size, XGL_VOID *data)
137{
138 struct intel_pipeline *pipeline = intel_pipeline_from_base(base);
139 XGL_RESULT ret = XGL_SUCCESS;
140
141 switch (type) {
142 case XGL_INFO_TYPE_MEMORY_REQUIREMENTS:
143 {
144 XGL_MEMORY_REQUIREMENTS *mem_req = data;
145
146 mem_req->size = pipeline->total_size;
147 // Programs must be aligned to 64bytes.
148 mem_req->alignment = 64;
149 mem_req->heapCount = 1;
150 mem_req->heaps[0] = 0;
151
152 *size = sizeof(*mem_req);
153 }
154 break;
155 default:
156 ret = intel_base_get_info(base, type, size, data);
157 break;
158 }
159
160 return ret;
161}
162
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600163XGL_RESULT XGLAPI intelCreateGraphicsPipeline(
164 XGL_DEVICE device,
165 const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
166 XGL_PIPELINE* pPipeline)
167{
168 union {
169 const void *ptr;
170 const struct {
171 XGL_STRUCTURE_TYPE struct_type;
172 XGL_VOID *next;
173 } *header;
174 const XGL_GRAPHICS_PIPELINE_CREATE_INFO* graphics_pipeline;
175 const XGL_PIPELINE_IA_STATE_CREATE_INFO* ia_state;
176 const XGL_PIPELINE_DB_STATE_CREATE_INFO* db_state;
177 const XGL_PIPELINE_CB_STATE* cb_state;
178 const XGL_PIPELINE_RS_STATE_CREATE_INFO* rs_state;
179 const XGL_PIPELINE_TESS_STATE_CREATE_INFO* tess_state;
180 const XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* shader_state;
181 } info = { .ptr = pCreateInfo };
182 struct intel_dev *dev = intel_dev(device);
183 struct intel_pipeline *pipeline;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600184 struct intel_shader *shader;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600185 XGL_RESULT result;
186
187 pipeline = (struct intel_pipeline *) intel_base_create(dev, sizeof(*pipeline),
188 dev->base.dbg, XGL_DBG_OBJECT_GRAPHICS_PIPELINE, pCreateInfo, 0);
189 if (!pipeline) {
190 return XGL_ERROR_OUT_OF_MEMORY;
191 }
192
193 pipeline->dev = dev;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600194 pipeline->obj.destroy = pipeline_destroy;
195 pipeline->obj.base.get_info = pipeline_get_info;
196 pipeline->total_size = 0;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600197
198 do {
199 result = XGL_SUCCESS;
200
201 switch (info.header->struct_type) {
202 case XGL_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO:
203 // TODO: Should not see Compute Pipeline structs processing CreateGraphicsPipeline
204 return XGL_ERROR_BAD_PIPELINE_DATA;
205
206 case XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO:
207 if (info.graphics_pipeline->flags & XGL_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT) {
208 // TODO: process disable optimization.
209 }
210 break;
211
212 case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600213 result = pipeline_ia_state(dev, pipeline, info.ia_state);
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600214 break;
215
216 case XGL_STRUCTURE_TYPE_PIPELINE_DB_STATE_CREATE_INFO:
217 pipeline->db_format = info.db_state->format;
218 break;
219
220 case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
221 pipeline->cb_state = *info.cb_state;
222 break;
223
224 case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600225 result = pipeline_rs_state(dev, pipeline, info.rs_state);
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600226 break;
227
228 case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
229 pipeline->tess_state = *info.tess_state;
230 break;
231
232 case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600233 shader = intel_shader(info.shader_state->shader.shader);
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600234 switch (info.shader_state->shader.stage) {
235 case XGL_SHADER_STAGE_VERTEX:
236 pipeline->vs = info.shader_state->shader;
237 pipeline->active_shaders |= SHADER_VERTEX_FLAG;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600238 pipeline->total_size += shader->codeSize;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600239 break;
240 case XGL_SHADER_STAGE_GEOMETRY:
241 pipeline->gs = info.shader_state->shader;
242 pipeline->active_shaders |= SHADER_GEOMETRY_FLAG;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600243 pipeline->total_size += shader->codeSize;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600244 break;
245 case XGL_SHADER_STAGE_FRAGMENT:
246 pipeline->fs = info.shader_state->shader;
247 pipeline->active_shaders |= SHADER_FRAGMENT_FLAG;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600248 pipeline->total_size += shader->codeSize;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600249 break;
250 case XGL_SHADER_STAGE_TESS_CONTROL:
251 pipeline->tess_control = info.shader_state->shader;
252 pipeline->active_shaders |= SHADER_TESS_CONTROL_FLAG;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600253 pipeline->total_size += shader->codeSize;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600254 break;
255 case XGL_SHADER_STAGE_TESS_EVALUATION:
256 pipeline->tess_eval = info.shader_state->shader;
257 pipeline->active_shaders |= SHADER_TESS_EVAL_FLAG;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600258 pipeline->total_size += shader->codeSize;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600259 break;
260 case XGL_SHADER_STAGE_COMPUTE:
261 pipeline->compute = info.shader_state->shader;
262 pipeline->active_shaders |= SHADER_COMPUTE_FLAG;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600263 pipeline->total_size += shader->codeSize;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600264 break;
265 default:
266 // TODO: Log debug message
267 result = XGL_ERROR_BAD_PIPELINE_DATA;
268 goto error_exit;
269 }
270 break;
271
272 default:
273 // TODO: Log debug message
274 result = XGL_ERROR_BAD_PIPELINE_DATA;
275 goto error_exit;
276 }
277
278 if (result != XGL_SUCCESS) {
279 // TODO: What needs to happen if pipeline build fails?
280 goto error_exit;
281 }
282 info.ptr = info.header->next;
283 } while (info.ptr != NULL);
284
285 /*
286 * Validate required elements
287 */
288 if (!(pipeline->active_shaders & SHADER_VERTEX_FLAG)) {
289 // TODO: Log debug message: Vertex Shader required.
290 result = XGL_ERROR_BAD_PIPELINE_DATA;
291 goto error_exit;
292 }
293
Chia-I Wued833872014-08-23 17:00:35 +0800294 if (pipeline->active_shaders & SHADER_VERTEX_FLAG) {
295 pipeline->vs_rmap = intel_rmap_create(dev,
296 &pipeline->vs.descriptorSetMapping[0],
297 &pipeline->vs.dynamicMemoryViewMapping, 0);
298 if (!pipeline->vs_rmap) {
299 result = XGL_ERROR_OUT_OF_MEMORY;
300 goto error_exit;
301 }
302 }
303
304 if (pipeline->active_shaders & SHADER_FRAGMENT_FLAG) {
305 /* assuming one RT; need to parse the shader */
306 pipeline->fs_rmap = intel_rmap_create(dev,
307 &pipeline->fs.descriptorSetMapping[0],
308 &pipeline->fs.dynamicMemoryViewMapping, 1);
309 if (!pipeline->fs_rmap) {
310 result = XGL_ERROR_OUT_OF_MEMORY;
311 goto error_exit;
312 }
313 }
314
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600315 /*
316 * Tessalation control and evaluation have to both have a shader defined or
317 * neither should have a shader defined.
318 */
319 if (((pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) == 0) !=
320 ((pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) == 0) ) {
321 // TODO: Log debug message: Both Tess control and Tess eval are required to use tessalation
322 result = XGL_ERROR_BAD_PIPELINE_DATA;
323 goto error_exit;
324 }
325
326 if ((pipeline->active_shaders & SHADER_COMPUTE_FLAG) &&
327 (pipeline->active_shaders & (SHADER_VERTEX_FLAG | SHADER_TESS_CONTROL_FLAG |
328 SHADER_TESS_EVAL_FLAG | SHADER_GEOMETRY_FLAG |
329 SHADER_FRAGMENT_FLAG))) {
330 // TODO: Log debug message: Can only specify compute shader when doing compute
331 result = XGL_ERROR_BAD_PIPELINE_DATA;
332 goto error_exit;
333 }
334
335 /*
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600336 * XGL_TOPOLOGY_PATCH primitive topology is only valid for tessellation pipelines.
337 * Mismatching primitive topology and tessellation fails graphics pipeline creation.
338 */
339 if (pipeline->active_shaders & (SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG) &&
340 (pipeline->ia_state.topology != XGL_TOPOLOGY_PATCH)) {
341 // TODO: Log debug message: Invalid topology used with tessalation shader.
342 result = XGL_ERROR_BAD_PIPELINE_DATA;
343 goto error_exit;
344 }
345
346 if ((pipeline->ia_state.topology == XGL_TOPOLOGY_PATCH) &&
347 (pipeline->active_shaders & ~(SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG))) {
348 // TODO: Log debug message: Cannot use TOPOLOGY_PATCH on non-tessalation shader.
349 result = XGL_ERROR_BAD_PIPELINE_DATA;
350 goto error_exit;
351 }
352
353 /*
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600354 * Now compile everything into a pipeline object ready for the HW.
355 */
356
357 *pPipeline = pipeline;
358
359 return XGL_SUCCESS;
360
361error_exit:
Chia-I Wued833872014-08-23 17:00:35 +0800362 if (pipeline->vs_rmap)
363 intel_rmap_destroy(pipeline->vs_rmap);
364 if (pipeline->fs_rmap)
365 intel_rmap_destroy(pipeline->fs_rmap);
366
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600367 intel_base_destroy(&pipeline->obj.base);
368 return result;
369}
370
371XGL_RESULT XGLAPI intelCreateComputePipeline(
372 XGL_DEVICE device,
373 const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo,
374 XGL_PIPELINE* pPipeline)
375{
376 return XGL_ERROR_UNAVAILABLE;
377}
378
379XGL_RESULT XGLAPI intelStorePipeline(
380 XGL_PIPELINE pipeline,
381 XGL_SIZE* pDataSize,
382 XGL_VOID* pData)
383{
384 return XGL_ERROR_UNAVAILABLE;
385}
386
387XGL_RESULT XGLAPI intelLoadPipeline(
388 XGL_DEVICE device,
389 XGL_SIZE dataSize,
390 const XGL_VOID* pData,
391 XGL_PIPELINE* pPipeline)
392{
393 return XGL_ERROR_UNAVAILABLE;
394}
395
396XGL_RESULT XGLAPI intelCreatePipelineDelta(
397 XGL_DEVICE device,
398 XGL_PIPELINE p1,
399 XGL_PIPELINE p2,
400 XGL_PIPELINE_DELTA* delta)
401{
402 return XGL_ERROR_UNAVAILABLE;
403}