blob: ba27d3798d0291e7315943e9ddec1f0161275a62 [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"
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -060026#include "pipeline.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
127 intel_base_destroy(&pipeline->obj.base);
128}
129
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600130static XGL_RESULT pipeline_get_info(struct intel_base *base, int type,
131 XGL_SIZE *size, XGL_VOID *data)
132{
133 struct intel_pipeline *pipeline = intel_pipeline_from_base(base);
134 XGL_RESULT ret = XGL_SUCCESS;
135
136 switch (type) {
137 case XGL_INFO_TYPE_MEMORY_REQUIREMENTS:
138 {
139 XGL_MEMORY_REQUIREMENTS *mem_req = data;
140
141 mem_req->size = pipeline->total_size;
142 // Programs must be aligned to 64bytes.
143 mem_req->alignment = 64;
144 mem_req->heapCount = 1;
145 mem_req->heaps[0] = 0;
146
147 *size = sizeof(*mem_req);
148 }
149 break;
150 default:
151 ret = intel_base_get_info(base, type, size, data);
152 break;
153 }
154
155 return ret;
156}
157
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600158XGL_RESULT XGLAPI intelCreateGraphicsPipeline(
159 XGL_DEVICE device,
160 const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
161 XGL_PIPELINE* pPipeline)
162{
163 union {
164 const void *ptr;
165 const struct {
166 XGL_STRUCTURE_TYPE struct_type;
167 XGL_VOID *next;
168 } *header;
169 const XGL_GRAPHICS_PIPELINE_CREATE_INFO* graphics_pipeline;
170 const XGL_PIPELINE_IA_STATE_CREATE_INFO* ia_state;
171 const XGL_PIPELINE_DB_STATE_CREATE_INFO* db_state;
172 const XGL_PIPELINE_CB_STATE* cb_state;
173 const XGL_PIPELINE_RS_STATE_CREATE_INFO* rs_state;
174 const XGL_PIPELINE_TESS_STATE_CREATE_INFO* tess_state;
175 const XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* shader_state;
176 } info = { .ptr = pCreateInfo };
177 struct intel_dev *dev = intel_dev(device);
178 struct intel_pipeline *pipeline;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600179 struct intel_shader *shader;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600180 XGL_RESULT result;
181
182 pipeline = (struct intel_pipeline *) intel_base_create(dev, sizeof(*pipeline),
183 dev->base.dbg, XGL_DBG_OBJECT_GRAPHICS_PIPELINE, pCreateInfo, 0);
184 if (!pipeline) {
185 return XGL_ERROR_OUT_OF_MEMORY;
186 }
187
188 pipeline->dev = dev;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600189 pipeline->obj.destroy = pipeline_destroy;
190 pipeline->obj.base.get_info = pipeline_get_info;
191 pipeline->total_size = 0;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600192
193 do {
194 result = XGL_SUCCESS;
195
196 switch (info.header->struct_type) {
197 case XGL_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO:
198 // TODO: Should not see Compute Pipeline structs processing CreateGraphicsPipeline
199 return XGL_ERROR_BAD_PIPELINE_DATA;
200
201 case XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO:
202 if (info.graphics_pipeline->flags & XGL_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT) {
203 // TODO: process disable optimization.
204 }
205 break;
206
207 case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600208 result = pipeline_ia_state(dev, pipeline, info.ia_state);
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600209 break;
210
211 case XGL_STRUCTURE_TYPE_PIPELINE_DB_STATE_CREATE_INFO:
212 pipeline->db_format = info.db_state->format;
213 break;
214
215 case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
216 pipeline->cb_state = *info.cb_state;
217 break;
218
219 case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600220 result = pipeline_rs_state(dev, pipeline, info.rs_state);
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600221 break;
222
223 case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
224 pipeline->tess_state = *info.tess_state;
225 break;
226
227 case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600228 shader = intel_shader(info.shader_state->shader.shader);
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600229 switch (info.shader_state->shader.stage) {
230 case XGL_SHADER_STAGE_VERTEX:
231 pipeline->vs = info.shader_state->shader;
232 pipeline->active_shaders |= SHADER_VERTEX_FLAG;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600233 pipeline->total_size += shader->codeSize;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600234 break;
235 case XGL_SHADER_STAGE_GEOMETRY:
236 pipeline->gs = info.shader_state->shader;
237 pipeline->active_shaders |= SHADER_GEOMETRY_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_FRAGMENT:
241 pipeline->fs = info.shader_state->shader;
242 pipeline->active_shaders |= SHADER_FRAGMENT_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_TESS_CONTROL:
246 pipeline->tess_control = info.shader_state->shader;
247 pipeline->active_shaders |= SHADER_TESS_CONTROL_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_EVALUATION:
251 pipeline->tess_eval = info.shader_state->shader;
252 pipeline->active_shaders |= SHADER_TESS_EVAL_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_COMPUTE:
256 pipeline->compute = info.shader_state->shader;
257 pipeline->active_shaders |= SHADER_COMPUTE_FLAG;
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600258 pipeline->total_size += shader->codeSize;
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600259 break;
260 default:
261 // TODO: Log debug message
262 result = XGL_ERROR_BAD_PIPELINE_DATA;
263 goto error_exit;
264 }
265 break;
266
267 default:
268 // TODO: Log debug message
269 result = XGL_ERROR_BAD_PIPELINE_DATA;
270 goto error_exit;
271 }
272
273 if (result != XGL_SUCCESS) {
274 // TODO: What needs to happen if pipeline build fails?
275 goto error_exit;
276 }
277 info.ptr = info.header->next;
278 } while (info.ptr != NULL);
279
280 /*
281 * Validate required elements
282 */
283 if (!(pipeline->active_shaders & SHADER_VERTEX_FLAG)) {
284 // TODO: Log debug message: Vertex Shader required.
285 result = XGL_ERROR_BAD_PIPELINE_DATA;
286 goto error_exit;
287 }
288
289 /*
290 * Tessalation control and evaluation have to both have a shader defined or
291 * neither should have a shader defined.
292 */
293 if (((pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) == 0) !=
294 ((pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) == 0) ) {
295 // TODO: Log debug message: Both Tess control and Tess eval are required to use tessalation
296 result = XGL_ERROR_BAD_PIPELINE_DATA;
297 goto error_exit;
298 }
299
300 if ((pipeline->active_shaders & SHADER_COMPUTE_FLAG) &&
301 (pipeline->active_shaders & (SHADER_VERTEX_FLAG | SHADER_TESS_CONTROL_FLAG |
302 SHADER_TESS_EVAL_FLAG | SHADER_GEOMETRY_FLAG |
303 SHADER_FRAGMENT_FLAG))) {
304 // TODO: Log debug message: Can only specify compute shader when doing compute
305 result = XGL_ERROR_BAD_PIPELINE_DATA;
306 goto error_exit;
307 }
308
309 /*
Courtney Goeltzenleuchter42509992014-08-21 17:33:46 -0600310 * XGL_TOPOLOGY_PATCH primitive topology is only valid for tessellation pipelines.
311 * Mismatching primitive topology and tessellation fails graphics pipeline creation.
312 */
313 if (pipeline->active_shaders & (SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG) &&
314 (pipeline->ia_state.topology != XGL_TOPOLOGY_PATCH)) {
315 // TODO: Log debug message: Invalid topology used with tessalation shader.
316 result = XGL_ERROR_BAD_PIPELINE_DATA;
317 goto error_exit;
318 }
319
320 if ((pipeline->ia_state.topology == XGL_TOPOLOGY_PATCH) &&
321 (pipeline->active_shaders & ~(SHADER_TESS_CONTROL_FLAG | SHADER_TESS_EVAL_FLAG))) {
322 // TODO: Log debug message: Cannot use TOPOLOGY_PATCH on non-tessalation shader.
323 result = XGL_ERROR_BAD_PIPELINE_DATA;
324 goto error_exit;
325 }
326
327 /*
Courtney Goeltzenleuchter05a60542014-08-15 14:54:34 -0600328 * Now compile everything into a pipeline object ready for the HW.
329 */
330
331 *pPipeline = pipeline;
332
333 return XGL_SUCCESS;
334
335error_exit:
336 intel_base_destroy(&pipeline->obj.base);
337 return result;
338}
339
340XGL_RESULT XGLAPI intelCreateComputePipeline(
341 XGL_DEVICE device,
342 const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo,
343 XGL_PIPELINE* pPipeline)
344{
345 return XGL_ERROR_UNAVAILABLE;
346}
347
348XGL_RESULT XGLAPI intelStorePipeline(
349 XGL_PIPELINE pipeline,
350 XGL_SIZE* pDataSize,
351 XGL_VOID* pData)
352{
353 return XGL_ERROR_UNAVAILABLE;
354}
355
356XGL_RESULT XGLAPI intelLoadPipeline(
357 XGL_DEVICE device,
358 XGL_SIZE dataSize,
359 const XGL_VOID* pData,
360 XGL_PIPELINE* pPipeline)
361{
362 return XGL_ERROR_UNAVAILABLE;
363}
364
365XGL_RESULT XGLAPI intelCreatePipelineDelta(
366 XGL_DEVICE device,
367 XGL_PIPELINE p1,
368 XGL_PIPELINE p2,
369 XGL_PIPELINE_DELTA* delta)
370{
371 return XGL_ERROR_UNAVAILABLE;
372}