blob: ca6155776f7153bbcc85ae3e6d4a464c88b25454 [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
25#include "pipeline.h"
26#include "brw_defines.h"
27
28static XGL_RESULT intelPipelineIAState(struct intel_dev *dev, struct intel_pipeline *pipeline,
29 const XGL_PIPELINE_IA_STATE_CREATE_INFO* ia_state)
30{
31 if (ia_state->provokingVertex == XGL_PROVOKING_VERTEX_FIRST) {
32 pipeline->provoking_vertex_tri = BRW_PROVOKING_VERTEX_0;
33 pipeline->provoking_vertex_trifan = BRW_PROVOKING_VERTEX_1;
34 pipeline->provoking_vertex_line = BRW_PROVOKING_VERTEX_0;
35 } else {
36 pipeline->provoking_vertex_tri = BRW_PROVOKING_VERTEX_2;
37 pipeline->provoking_vertex_trifan = BRW_PROVOKING_VERTEX_2;
38 pipeline->provoking_vertex_line = BRW_PROVOKING_VERTEX_1;
39 }
40
41 switch (ia_state->topology) {
42 case XGL_TOPOLOGY_POINT_LIST:
43 pipeline->prim_type = _3DPRIM_POINTLIST;
44 break;
45 case XGL_TOPOLOGY_LINE_LIST:
46 pipeline->prim_type = _3DPRIM_LINELIST;
47 break;
48 case XGL_TOPOLOGY_LINE_STRIP:
49 pipeline->prim_type = _3DPRIM_LINESTRIP;
50 break;
51 case XGL_TOPOLOGY_TRIANGLE_LIST:
52 pipeline->prim_type = _3DPRIM_TRILIST;
53 break;
54 case XGL_TOPOLOGY_TRIANGLE_STRIP:
55 pipeline->prim_type = _3DPRIM_TRISTRIP;
56 break;
57 case XGL_TOPOLOGY_RECT_LIST:
58 /*
59 * TODO: Rect lists are special in XGL, do we need to do
60 * something special here?
61 * XGL Guide:
62 * The rectangle list is a special geometry primitive type
63 * that can be used for implementing post-processing techniques
64 * or efficient copy operations. There are some special limitations
65 * for rectangle primitives. They cannot be clipped, must
66 * be axis aligned and cannot have depth gradient.
67 * Failure to comply with these restrictions results in
68 * undefined rendering results.
69 */
70 pipeline->prim_type = _3DPRIM_RECTLIST;
71 break;
72 case XGL_TOPOLOGY_QUAD_LIST:
73 pipeline->prim_type = _3DPRIM_QUADLIST;
74 break;
75 case XGL_TOPOLOGY_QUAD_STRIP:
76 pipeline->prim_type = _3DPRIM_QUADSTRIP;
77 break;
78 case XGL_TOPOLOGY_LINE_LIST_ADJ:
79 // TODO: implement
80 break;
81 case XGL_TOPOLOGY_LINE_STRIP_ADJ:
82 // TODO: implement
83 break;
84 case XGL_TOPOLOGY_TRIANGLE_LIST_ADJ:
85 // TODO: implement
86 break;
87 case XGL_TOPOLOGY_TRIANGLE_STRIP_ADJ:
88 // TODO: implement
89 break;
90 case XGL_TOPOLOGY_PATCH:
91 // TODO: implement something here
92 break;
93 default:
94 return XGL_ERROR_BAD_PIPELINE_DATA;
95 }
96
97 if (ia_state->primitiveRestartEnable) {
98 pipeline->primitive_restart = true;
99 pipeline->primitive_restart_index = ia_state->primitiveRestartIndex;
100 } else {
101 pipeline->primitive_restart = false;
102 }
103
104 if (ia_state->disableVertexReuse) {
105 // TODO: What do we do to disable vertex reuse?
106 }
107
108 return XGL_SUCCESS;
109}
110
111static XGL_RESULT intelPipelineRSState(struct intel_dev *dev, struct intel_pipeline *pipeline,
112 const XGL_PIPELINE_RS_STATE_CREATE_INFO* rs_state)
113{
114 pipeline->depthClipEnable = rs_state->depthClipEnable;
115 pipeline->rasterizerDiscardEnable = rs_state->rasterizerDiscardEnable;
116 pipeline->pointSize = rs_state->pointSize;
117 return XGL_SUCCESS;
118}
119
120static void intelPipelineDestroy(struct intel_obj *obj)
121{
122 struct intel_pipeline *pipeline = intel_pipeline_from_obj(obj);
123
124 intel_base_destroy(&pipeline->obj.base);
125}
126
127XGL_RESULT XGLAPI intelCreateGraphicsPipeline(
128 XGL_DEVICE device,
129 const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
130 XGL_PIPELINE* pPipeline)
131{
132 union {
133 const void *ptr;
134 const struct {
135 XGL_STRUCTURE_TYPE struct_type;
136 XGL_VOID *next;
137 } *header;
138 const XGL_GRAPHICS_PIPELINE_CREATE_INFO* graphics_pipeline;
139 const XGL_PIPELINE_IA_STATE_CREATE_INFO* ia_state;
140 const XGL_PIPELINE_DB_STATE_CREATE_INFO* db_state;
141 const XGL_PIPELINE_CB_STATE* cb_state;
142 const XGL_PIPELINE_RS_STATE_CREATE_INFO* rs_state;
143 const XGL_PIPELINE_TESS_STATE_CREATE_INFO* tess_state;
144 const XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* shader_state;
145 } info = { .ptr = pCreateInfo };
146 struct intel_dev *dev = intel_dev(device);
147 struct intel_pipeline *pipeline;
148 XGL_RESULT result;
149
150 pipeline = (struct intel_pipeline *) intel_base_create(dev, sizeof(*pipeline),
151 dev->base.dbg, XGL_DBG_OBJECT_GRAPHICS_PIPELINE, pCreateInfo, 0);
152 if (!pipeline) {
153 return XGL_ERROR_OUT_OF_MEMORY;
154 }
155
156 pipeline->dev = dev;
157 pipeline->obj.destroy = intelPipelineDestroy;
158
159 do {
160 result = XGL_SUCCESS;
161
162 switch (info.header->struct_type) {
163 case XGL_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO:
164 // TODO: Should not see Compute Pipeline structs processing CreateGraphicsPipeline
165 return XGL_ERROR_BAD_PIPELINE_DATA;
166
167 case XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO:
168 if (info.graphics_pipeline->flags & XGL_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT) {
169 // TODO: process disable optimization.
170 }
171 break;
172
173 case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
174 result = intelPipelineIAState(dev, pipeline, info.ia_state);
175 break;
176
177 case XGL_STRUCTURE_TYPE_PIPELINE_DB_STATE_CREATE_INFO:
178 pipeline->db_format = info.db_state->format;
179 break;
180
181 case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
182 pipeline->cb_state = *info.cb_state;
183 break;
184
185 case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
186 result = intelPipelineRSState(dev, pipeline, info.rs_state);
187 break;
188
189 case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
190 pipeline->tess_state = *info.tess_state;
191 break;
192
193 case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
194 switch (info.shader_state->shader.stage) {
195 case XGL_SHADER_STAGE_VERTEX:
196 pipeline->vs = info.shader_state->shader;
197 pipeline->active_shaders |= SHADER_VERTEX_FLAG;
198 break;
199 case XGL_SHADER_STAGE_GEOMETRY:
200 pipeline->gs = info.shader_state->shader;
201 pipeline->active_shaders |= SHADER_GEOMETRY_FLAG;
202 break;
203 case XGL_SHADER_STAGE_FRAGMENT:
204 pipeline->fs = info.shader_state->shader;
205 pipeline->active_shaders |= SHADER_FRAGMENT_FLAG;
206 break;
207 case XGL_SHADER_STAGE_TESS_CONTROL:
208 pipeline->tess_control = info.shader_state->shader;
209 pipeline->active_shaders |= SHADER_TESS_CONTROL_FLAG;
210 break;
211 case XGL_SHADER_STAGE_TESS_EVALUATION:
212 pipeline->tess_eval = info.shader_state->shader;
213 pipeline->active_shaders |= SHADER_TESS_EVAL_FLAG;
214 break;
215 case XGL_SHADER_STAGE_COMPUTE:
216 pipeline->compute = info.shader_state->shader;
217 pipeline->active_shaders |= SHADER_COMPUTE_FLAG;
218 break;
219 default:
220 // TODO: Log debug message
221 result = XGL_ERROR_BAD_PIPELINE_DATA;
222 goto error_exit;
223 }
224 break;
225
226 default:
227 // TODO: Log debug message
228 result = XGL_ERROR_BAD_PIPELINE_DATA;
229 goto error_exit;
230 }
231
232 if (result != XGL_SUCCESS) {
233 // TODO: What needs to happen if pipeline build fails?
234 goto error_exit;
235 }
236 info.ptr = info.header->next;
237 } while (info.ptr != NULL);
238
239 /*
240 * Validate required elements
241 */
242 if (!(pipeline->active_shaders & SHADER_VERTEX_FLAG)) {
243 // TODO: Log debug message: Vertex Shader required.
244 result = XGL_ERROR_BAD_PIPELINE_DATA;
245 goto error_exit;
246 }
247
248 /*
249 * Tessalation control and evaluation have to both have a shader defined or
250 * neither should have a shader defined.
251 */
252 if (((pipeline->active_shaders & SHADER_TESS_CONTROL_FLAG) == 0) !=
253 ((pipeline->active_shaders & SHADER_TESS_EVAL_FLAG) == 0) ) {
254 // TODO: Log debug message: Both Tess control and Tess eval are required to use tessalation
255 result = XGL_ERROR_BAD_PIPELINE_DATA;
256 goto error_exit;
257 }
258
259 if ((pipeline->active_shaders & SHADER_COMPUTE_FLAG) &&
260 (pipeline->active_shaders & (SHADER_VERTEX_FLAG | SHADER_TESS_CONTROL_FLAG |
261 SHADER_TESS_EVAL_FLAG | SHADER_GEOMETRY_FLAG |
262 SHADER_FRAGMENT_FLAG))) {
263 // TODO: Log debug message: Can only specify compute shader when doing compute
264 result = XGL_ERROR_BAD_PIPELINE_DATA;
265 goto error_exit;
266 }
267
268 /*
269 * Now compile everything into a pipeline object ready for the HW.
270 */
271
272 *pPipeline = pipeline;
273
274 return XGL_SUCCESS;
275
276error_exit:
277 intel_base_destroy(&pipeline->obj.base);
278 return result;
279}
280
281XGL_RESULT XGLAPI intelCreateComputePipeline(
282 XGL_DEVICE device,
283 const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo,
284 XGL_PIPELINE* pPipeline)
285{
286 return XGL_ERROR_UNAVAILABLE;
287}
288
289XGL_RESULT XGLAPI intelStorePipeline(
290 XGL_PIPELINE pipeline,
291 XGL_SIZE* pDataSize,
292 XGL_VOID* pData)
293{
294 return XGL_ERROR_UNAVAILABLE;
295}
296
297XGL_RESULT XGLAPI intelLoadPipeline(
298 XGL_DEVICE device,
299 XGL_SIZE dataSize,
300 const XGL_VOID* pData,
301 XGL_PIPELINE* pPipeline)
302{
303 return XGL_ERROR_UNAVAILABLE;
304}
305
306XGL_RESULT XGLAPI intelCreatePipelineDelta(
307 XGL_DEVICE device,
308 XGL_PIPELINE p1,
309 XGL_PIPELINE p2,
310 XGL_PIPELINE_DELTA* delta)
311{
312 return XGL_ERROR_UNAVAILABLE;
313}