blob: 881e103f69d251136480b92193ed3145d7c4ef08 [file] [log] [blame]
Chia-I Wua5714e82014-08-11 15:33:42 +08001/*
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
Chia-I Wu97702a62014-08-11 15:33:42 +080025#include <math.h>
26#include "genhw/genhw.h"
Chia-I Wua5714e82014-08-11 15:33:42 +080027#include "dev.h"
28#include "state.h"
29
Chia-I Wu97702a62014-08-11 15:33:42 +080030static int translate_compare_func(XGL_COMPARE_FUNC func)
31{
32 switch (func) {
33 case XGL_COMPARE_NEVER: return GEN6_COMPAREFUNCTION_NEVER;
34 case XGL_COMPARE_LESS: return GEN6_COMPAREFUNCTION_LESS;
35 case XGL_COMPARE_EQUAL: return GEN6_COMPAREFUNCTION_EQUAL;
36 case XGL_COMPARE_LESS_EQUAL: return GEN6_COMPAREFUNCTION_LEQUAL;
37 case XGL_COMPARE_GREATER: return GEN6_COMPAREFUNCTION_GREATER;
38 case XGL_COMPARE_NOT_EQUAL: return GEN6_COMPAREFUNCTION_NOTEQUAL;
39 case XGL_COMPARE_GREATER_EQUAL: return GEN6_COMPAREFUNCTION_GEQUAL;
40 case XGL_COMPARE_ALWAYS: return GEN6_COMPAREFUNCTION_ALWAYS;
41 default:
42 assert(!"unknown compare_func");
43 return GEN6_COMPAREFUNCTION_NEVER;
44 }
45}
46
47static int translate_stencil_op(XGL_STENCIL_OP op)
48{
49 switch (op) {
50 case XGL_STENCIL_OP_KEEP: return GEN6_STENCILOP_KEEP;
51 case XGL_STENCIL_OP_ZERO: return GEN6_STENCILOP_ZERO;
52 case XGL_STENCIL_OP_REPLACE: return GEN6_STENCILOP_REPLACE;
53 case XGL_STENCIL_OP_INC_CLAMP: return GEN6_STENCILOP_INCRSAT;
54 case XGL_STENCIL_OP_DEC_CLAMP: return GEN6_STENCILOP_DECRSAT;
55 case XGL_STENCIL_OP_INVERT: return GEN6_STENCILOP_INVERT;
56 case XGL_STENCIL_OP_INC_WRAP: return GEN6_STENCILOP_INCR;
57 case XGL_STENCIL_OP_DEC_WRAP: return GEN6_STENCILOP_DECR;
58 default:
59 assert(!"unknown stencil op");
60 return GEN6_STENCILOP_KEEP;
61 }
62}
63
64static int translate_blend_func(XGL_BLEND_FUNC func)
65{
66 switch (func) {
67 case XGL_BLEND_FUNC_ADD: return GEN6_BLENDFUNCTION_ADD;
68 case XGL_BLEND_FUNC_SUBTRACT: return GEN6_BLENDFUNCTION_SUBTRACT;
69 case XGL_BLEND_FUNC_REVERSE_SUBTRACT: return GEN6_BLENDFUNCTION_REVERSE_SUBTRACT;
70 case XGL_BLEND_FUNC_MIN: return GEN6_BLENDFUNCTION_MIN;
71 case XGL_BLEND_FUNC_MAX: return GEN6_BLENDFUNCTION_MAX;
72 default:
73 assert(!"unknown blend func");
74 return GEN6_BLENDFUNCTION_ADD;
75 };
76}
77
78static int translate_blend(XGL_BLEND blend)
79{
80 switch (blend) {
81 case XGL_BLEND_ZERO: return GEN6_BLENDFACTOR_ZERO;
82 case XGL_BLEND_ONE: return GEN6_BLENDFACTOR_ONE;
83 case XGL_BLEND_SRC_COLOR: return GEN6_BLENDFACTOR_SRC_COLOR;
84 case XGL_BLEND_ONE_MINUS_SRC_COLOR: return GEN6_BLENDFACTOR_INV_SRC_COLOR;
85 case XGL_BLEND_DEST_COLOR: return GEN6_BLENDFACTOR_DST_COLOR;
86 case XGL_BLEND_ONE_MINUS_DEST_COLOR: return GEN6_BLENDFACTOR_INV_DST_COLOR;
87 case XGL_BLEND_SRC_ALPHA: return GEN6_BLENDFACTOR_SRC_ALPHA;
88 case XGL_BLEND_ONE_MINUS_SRC_ALPHA: return GEN6_BLENDFACTOR_INV_SRC_ALPHA;
89 case XGL_BLEND_DEST_ALPHA: return GEN6_BLENDFACTOR_DST_ALPHA;
90 case XGL_BLEND_ONE_MINUS_DEST_ALPHA: return GEN6_BLENDFACTOR_INV_DST_ALPHA;
91 case XGL_BLEND_CONSTANT_COLOR: return GEN6_BLENDFACTOR_CONST_COLOR;
92 case XGL_BLEND_ONE_MINUS_CONSTANT_COLOR: return GEN6_BLENDFACTOR_INV_CONST_COLOR;
93 case XGL_BLEND_CONSTANT_ALPHA: return GEN6_BLENDFACTOR_CONST_ALPHA;
94 case XGL_BLEND_ONE_MINUS_CONSTANT_ALPHA: return GEN6_BLENDFACTOR_INV_CONST_ALPHA;
95 case XGL_BLEND_SRC_ALPHA_SATURATE: return GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE;
96 case XGL_BLEND_SRC1_COLOR: return GEN6_BLENDFACTOR_SRC1_COLOR;
97 case XGL_BLEND_ONE_MINUS_SRC1_COLOR: return GEN6_BLENDFACTOR_INV_SRC1_COLOR;
98 case XGL_BLEND_SRC1_ALPHA: return GEN6_BLENDFACTOR_SRC1_ALPHA;
99 case XGL_BLEND_ONE_MINUS_SRC1_ALPHA: return GEN6_BLENDFACTOR_INV_SRC1_ALPHA;
100 default:
101 assert(!"unknown blend factor");
102 return GEN6_BLENDFACTOR_ONE;
103 };
104}
105
106static void
107raster_state_init(struct intel_raster_state *state,
108 const struct intel_gpu *gpu,
109 const XGL_RASTER_STATE_CREATE_INFO *info)
110{
111 switch (info->fillMode) {
112 case XFL_FILL_POINTS:
113 state->cmd_sf_fill |= GEN7_SF_DW1_FRONTFACE_POINT |
114 GEN7_SF_DW1_BACKFACE_POINT;
115 break;
116 case XGL_FILL_WIREFRAME:
117 state->cmd_sf_fill |= GEN7_SF_DW1_FRONTFACE_WIREFRAME |
118 GEN7_SF_DW1_BACKFACE_WIREFRAME;
119 break;
120 case XGL_FILL_SOLID:
121 default:
122 state->cmd_sf_fill |= GEN7_SF_DW1_FRONTFACE_SOLID |
123 GEN7_SF_DW1_BACKFACE_SOLID;
124 break;
125 }
126
127 if (info->frontFace == XGL_FRONT_FACE_CCW) {
128 state->cmd_sf_fill |= GEN7_SF_DW1_FRONTWINDING_CCW;
129 state->cmd_clip_cull |= GEN7_CLIP_DW1_FRONTWINDING_CCW;
130 }
131
132 switch (info->cullMode) {
133 case XGL_CULL_NONE:
134 default:
135 state->cmd_sf_cull |= GEN7_SF_DW2_CULLMODE_NONE;
136 state->cmd_clip_cull |= GEN7_CLIP_DW1_CULLMODE_NONE;
137 break;
138 case XGL_CULL_FRONT:
139 state->cmd_sf_cull |= GEN7_SF_DW2_CULLMODE_FRONT;
140 state->cmd_clip_cull |= GEN7_CLIP_DW1_CULLMODE_FRONT;
141 break;
142 case XGL_CULL_BACK:
143 state->cmd_sf_cull |= GEN7_SF_DW2_CULLMODE_BACK;
144 state->cmd_clip_cull |= GEN7_CLIP_DW1_CULLMODE_BACK;
145 break;
146 case XGL_CULL_FRONT_AND_BACK:
147 state->cmd_sf_cull |= GEN7_SF_DW2_CULLMODE_BOTH;
148 state->cmd_clip_cull |= GEN7_CLIP_DW1_CULLMODE_BOTH;
149 break;
150 }
151
152 /* only GEN7+ needs cull mode in 3DSTATE_CLIP */
153 if (intel_gpu_gen(gpu) == INTEL_GEN(6))
154 state->cmd_clip_cull = 0;
155
156 /* XXX scale info->depthBias back into NDC */
157 state->cmd_depth_offset_const = u_fui((float) info->depthBias * 2.0f);
158 state->cmd_depth_offset_clamp = u_fui(info->depthBiasClamp);
159 state->cmd_depth_offset_scale = u_fui(info->slopeScaledDepthBias);
160}
161
162static void
163viewport_get_guardband(const struct intel_gpu *gpu,
164 int center_x, int center_y,
165 int *min_gbx, int *max_gbx,
166 int *min_gby, int *max_gby)
167{
168 /*
169 * From the Sandy Bridge PRM, volume 2 part 1, page 234:
170 *
171 * "Per-Device Guardband Extents
172 *
173 * - Supported X,Y ScreenSpace "Guardband" Extent: [-16K,16K-1]
174 * - Maximum Post-Clamp Delta (X or Y): 16K"
175 *
176 * "In addition, in order to be correctly rendered, objects must have a
177 * screenspace bounding box not exceeding 8K in the X or Y direction.
178 * This additional restriction must also be comprehended by software,
179 * i.e., enforced by use of clipping."
180 *
181 * From the Ivy Bridge PRM, volume 2 part 1, page 248:
182 *
183 * "Per-Device Guardband Extents
184 *
185 * - Supported X,Y ScreenSpace "Guardband" Extent: [-32K,32K-1]
186 * - Maximum Post-Clamp Delta (X or Y): N/A"
187 *
188 * "In addition, in order to be correctly rendered, objects must have a
189 * screenspace bounding box not exceeding 8K in the X or Y direction.
190 * This additional restriction must also be comprehended by software,
191 * i.e., enforced by use of clipping."
192 *
193 * Combined, the bounding box of any object can not exceed 8K in both
194 * width and height.
195 *
196 * Below we set the guardband as a squre of length 8K, centered at where
197 * the viewport is. This makes sure all objects passing the GB test are
198 * valid to the renderer, and those failing the XY clipping have a
199 * better chance of passing the GB test.
200 */
201 const int max_extent = (intel_gpu_gen(gpu) >= INTEL_GEN(7)) ? 32768 : 16384;
202 const int half_len = 8192 / 2;
203
204 /* make sure the guardband is within the valid range */
205 if (center_x - half_len < -max_extent)
206 center_x = -max_extent + half_len;
207 else if (center_x + half_len > max_extent - 1)
208 center_x = max_extent - half_len;
209
210 if (center_y - half_len < -max_extent)
211 center_y = -max_extent + half_len;
212 else if (center_y + half_len > max_extent - 1)
213 center_y = max_extent - half_len;
214
215 *min_gbx = (float) (center_x - half_len);
216 *max_gbx = (float) (center_x + half_len);
217 *min_gby = (float) (center_y - half_len);
218 *max_gby = (float) (center_y + half_len);
219}
220
221static XGL_RESULT
Chia-I Wu7b566a42014-08-22 10:58:57 +0800222viewport_state_alloc_cmd(struct intel_viewport_state *state,
223 const struct intel_gpu *gpu,
224 const XGL_VIEWPORT_STATE_CREATE_INFO *info)
225{
226 INTEL_GPU_ASSERT(gpu, 6, 7.5);
227
Chia-I Wu7d841502014-08-30 14:29:15 +0800228 state->viewport_count = info->viewportCount;
Chia-I Wu7b566a42014-08-22 10:58:57 +0800229 state->scissor_enable = info->scissorEnable;
230
231 if (intel_gpu_gen(gpu) >= INTEL_GEN(7)) {
232 state->cmd_align = GEN7_ALIGNMENT_SF_CLIP_VIEWPORT;
233 state->cmd_len = 16 * info->viewportCount;
234
235 state->cmd_clip_offset = 8;
236 } else {
237 state->cmd_align = GEN6_ALIGNMENT_SF_VIEWPORT;
238 state->cmd_len = 8 * info->viewportCount;
239
240 state->cmd_clip_offset =
241 u_align(state->cmd_len, GEN6_ALIGNMENT_CLIP_VIEWPORT);
242 state->cmd_len = state->cmd_clip_offset + 4 * info->viewportCount;
243 }
244
245 state->cmd_cc_offset =
246 u_align(state->cmd_len, GEN6_ALIGNMENT_CC_VIEWPORT);
247 state->cmd_len = state->cmd_cc_offset + 2 * info->viewportCount;
248
249 if (state->scissor_enable) {
250 state->cmd_scissor_rect_offset =
251 u_align(state->cmd_len, GEN6_ALIGNMENT_SCISSOR_RECT);
252 state->cmd_len = state->cmd_scissor_rect_offset +
253 2 * info->viewportCount;
254 }
255
256 state->cmd = icd_alloc(sizeof(uint32_t) * state->cmd_len,
257 0, XGL_SYSTEM_ALLOC_INTERNAL);
258 if (!state->cmd)
259 return XGL_ERROR_OUT_OF_MEMORY;
260
261 return XGL_SUCCESS;
262}
263
264static XGL_RESULT
Chia-I Wu97702a62014-08-11 15:33:42 +0800265viewport_state_init(struct intel_viewport_state *state,
266 const struct intel_gpu *gpu,
267 const XGL_VIEWPORT_STATE_CREATE_INFO *info)
268{
269 const XGL_UINT sf_stride = (intel_gpu_gen(gpu) >= INTEL_GEN(7)) ? 16 : 8;
270 const XGL_UINT clip_stride = (intel_gpu_gen(gpu) >= INTEL_GEN(7)) ? 16 : 4;
271 uint32_t *sf_viewport, *clip_viewport, *cc_viewport, *scissor_rect;
272 XGL_UINT i;
Chia-I Wu7b566a42014-08-22 10:58:57 +0800273 XGL_RESULT ret;
Chia-I Wu97702a62014-08-11 15:33:42 +0800274
275 INTEL_GPU_ASSERT(gpu, 6, 7.5);
276
Chia-I Wu7b566a42014-08-22 10:58:57 +0800277 ret = viewport_state_alloc_cmd(state, gpu, info);
278 if (ret != XGL_SUCCESS)
279 return ret;
Chia-I Wu97702a62014-08-11 15:33:42 +0800280
281 sf_viewport = state->cmd;
Chia-I Wu7b566a42014-08-22 10:58:57 +0800282 clip_viewport = state->cmd + state->cmd_clip_offset;
283 cc_viewport = state->cmd + state->cmd_cc_offset;
284 scissor_rect = state->cmd + state->cmd_scissor_rect_offset;
Chia-I Wu97702a62014-08-11 15:33:42 +0800285
286 for (i = 0; i < info->viewportCount; i++) {
287 const XGL_VIEWPORT *viewport = &info->viewports[i];
288 const XGL_RECT *scissor = &info->scissors[i];
289 uint32_t *dw = NULL;
290 float translate[3], scale[3];
291 int min_gbx, max_gbx, min_gby, max_gby;
292
293 scale[0] = viewport->width / 2.0f;
294 scale[1] = viewport->height / 2.0f;
295 scale[2] = (viewport->maxDepth - viewport->minDepth) / 2.0;
296 translate[0] = viewport->originX + scale[0];
297 translate[1] = viewport->originY + scale[1];
298 translate[2] = (viewport->minDepth + viewport->maxDepth) / 2.0f;
299
300 viewport_get_guardband(gpu, (int) translate[0], (int) translate[1],
301 &min_gbx, &max_gbx, &min_gby, &max_gby);
302
303 /* SF_VIEWPORT */
304 dw = sf_viewport;
305 dw[0] = u_fui(scale[0]);
306 dw[1] = u_fui(scale[1]);
307 dw[2] = u_fui(scale[2]);
308 dw[3] = u_fui(translate[0]);
309 dw[4] = u_fui(translate[1]);
310 dw[5] = u_fui(translate[2]);
311 dw[6] = 0;
312 dw[7] = 0;
313 sf_viewport += sf_stride;
314
315 /* CLIP_VIEWPORT */
316 dw = clip_viewport;
317 dw[0] = ((float) min_gbx - translate[0]) / fabsf(scale[0]);
318 dw[1] = ((float) max_gbx - translate[0]) / fabsf(scale[0]);
319 dw[2] = ((float) min_gby - translate[1]) / fabsf(scale[1]);
320 dw[3] = ((float) max_gby - translate[1]) / fabsf(scale[1]);
321 clip_viewport += clip_stride;
322
323 /* CC_VIEWPORT */
324 dw = cc_viewport;
325 dw[0] = u_fui(viewport->minDepth);
326 dw[1] = u_fui(viewport->maxDepth);
327 cc_viewport += 2;
328
329 /* SCISSOR_RECT */
Chia-I Wu7b566a42014-08-22 10:58:57 +0800330 if (state->scissor_enable) {
331 int16_t max_x, max_y;
332
333 max_x = (scissor->offset.x + scissor->extent.width - 1) & 0xffff;
334 max_y = (scissor->offset.y + scissor->extent.height - 1) & 0xffff;
335
336 dw = scissor_rect;
337 if (scissor->extent.width && scissor->extent.height) {
338 dw[0] = (scissor->offset.y & 0xffff) << 16 |
339 (scissor->offset.x & 0xffff);
340 dw[1] = max_y << 16 | max_x;
341 } else {
342 dw[0] = 1 << 16 | 1;
343 dw[1] = 0;
344 }
345 scissor_rect += 2;
Chia-I Wu97702a62014-08-11 15:33:42 +0800346 }
Chia-I Wu97702a62014-08-11 15:33:42 +0800347 }
348
349 return XGL_SUCCESS;
350}
351
352static void
353msaa_state_init(struct intel_msaa_state *state,
354 const struct intel_gpu *gpu,
355 const XGL_MSAA_STATE_CREATE_INFO *info)
356{
357 /* taken from Mesa */
358 static const uint32_t brw_multisample_positions_1x_2x = 0x0088cc44;
359 static const uint32_t brw_multisample_positions_4x = 0xae2ae662;
360 static const uint32_t brw_multisample_positions_8x[] = { 0xdbb39d79, 0x3ff55117 };
361 uint32_t cmd, cmd_len;
362 uint32_t *dw = state->cmd;
363
364 INTEL_GPU_ASSERT(gpu, 6, 7.5);
365 STATIC_ASSERT(ARRAY_SIZE(state->cmd) >= 6);
366
Chia-I Wu0b171262014-08-29 15:03:28 +0800367 state->sample_count = info->samples;
368 if (!state->sample_count)
369 state->sample_count = 1;
370
Chia-I Wu97702a62014-08-11 15:33:42 +0800371 /* 3DSTATE_MULTISAMPLE */
Chia-I Wu426072d2014-08-26 14:31:55 +0800372 cmd = GEN6_RENDER_CMD(3D, 3DSTATE_MULTISAMPLE);
Chia-I Wu97702a62014-08-11 15:33:42 +0800373 cmd_len = (intel_gpu_gen(gpu) >= INTEL_GEN(7)) ? 4 : 3;
374
375 dw[0] = cmd | (cmd_len - 2);
376 if (info->samples <= 1) {
377 dw[1] = GEN6_MULTISAMPLE_DW1_NUMSAMPLES_1;
378 dw[2] = brw_multisample_positions_1x_2x;
379 } else if (info->samples <= 4 || intel_gpu_gen(gpu) == INTEL_GEN(6)) {
380 dw[1] = GEN6_MULTISAMPLE_DW1_NUMSAMPLES_4;
381 dw[2] = brw_multisample_positions_4x;
382 } else {
383 dw[1] = GEN7_MULTISAMPLE_DW1_NUMSAMPLES_8;
384 dw[2] = brw_multisample_positions_8x[0];
385 dw[3] = brw_multisample_positions_8x[1];
386 }
387
388 dw += cmd_len;
389
Chia-I Wuf3c59252014-08-22 09:26:22 +0800390 state->cmd_len = cmd_len + 2;
391
Chia-I Wu97702a62014-08-11 15:33:42 +0800392 /* 3DSTATE_SAMPLE_MASK */
Chia-I Wu426072d2014-08-26 14:31:55 +0800393 cmd = GEN6_RENDER_CMD(3D, 3DSTATE_SAMPLE_MASK);
Chia-I Wu97702a62014-08-11 15:33:42 +0800394 cmd_len = 2;
395
396 dw[0] = cmd | (cmd_len - 2);
397 dw[1] = info->sampleMask & ((1 << info->samples) - 1);
398}
399
400static void
401blend_state_init(struct intel_blend_state *state,
402 const struct intel_gpu *gpu,
403 const XGL_COLOR_BLEND_STATE_CREATE_INFO *info)
404{
405 XGL_UINT i;
406
407 INTEL_GPU_ASSERT(gpu, 6, 7.5);
408
409 for (i = 0; i < ARRAY_SIZE(info->attachment); i++) {
410 const XGL_COLOR_ATTACHMENT_BLEND_STATE *att = &info->attachment[i];
411 uint32_t *dw = &state->cmd[2 * i];
412
413 if (att->blendEnable) {
414 dw[0] = 1 << 31 |
415 translate_blend_func(att->blendFuncAlpha) << 26 |
416 translate_blend(att->srcBlendAlpha) << 20 |
417 translate_blend(att->destBlendAlpha) << 15 |
418 translate_blend_func(att->blendFuncColor) << 11 |
419 translate_blend(att->srcBlendColor) << 5 |
420 translate_blend(att->destBlendColor);
421
422 if (att->blendFuncAlpha != att->blendFuncColor ||
423 att->srcBlendAlpha != att->srcBlendColor ||
424 att->destBlendAlpha != att->destBlendColor)
425 dw[0] |= 1 << 30;
426 }
427
428 dw[1] = GEN6_BLEND_DW1_COLORCLAMP_RTFORMAT |
429 0x3;
430 }
431
432 memcpy(state->cmd_blend_color, info->blendConst, sizeof(info->blendConst));
433}
434
435static XGL_RESULT
436ds_state_init(struct intel_ds_state *state,
437 const struct intel_gpu *gpu,
438 const XGL_DEPTH_STENCIL_STATE_CREATE_INFO *info)
439{
440 uint32_t *dw = state->cmd;
441
442 INTEL_GPU_ASSERT(gpu, 6, 7.5);
443
444 STATIC_ASSERT(ARRAY_SIZE(state->cmd) >= 3);
445
446 if (info->depthBoundsEnable)
447 return XGL_ERROR_UNKNOWN;
448
449 /*
450 * From the Sandy Bridge PRM, volume 2 part 1, page 359:
451 *
452 * "If the Depth Buffer is either undefined or does not have a surface
453 * format of D32_FLOAT_S8X24_UINT or D24_UNORM_S8_UINT and separate
454 * stencil buffer is disabled, Stencil Test Enable must be DISABLED"
455 *
456 * From the Sandy Bridge PRM, volume 2 part 1, page 370:
457 *
458 * "This field (Stencil Test Enable) cannot be enabled if
459 * Surface Format in 3DSTATE_DEPTH_BUFFER is set to D16_UNORM."
460 *
461 * TODO We do not check these yet.
462 */
463 if (info->stencilTestEnable) {
464 dw[0] = 1 << 31 |
465 translate_compare_func(info->front.stencilFunc) << 28 |
466 translate_stencil_op(info->front.stencilFailOp) << 25 |
467 translate_stencil_op(info->front.stencilDepthFailOp) << 22 |
468 translate_stencil_op(info->front.stencilPassOp) << 19 |
469 1 << 15 |
470 translate_compare_func(info->back.stencilFunc) << 12 |
471 translate_stencil_op(info->back.stencilFailOp) << 9 |
472 translate_stencil_op(info->back.stencilDepthFailOp) << 6 |
473 translate_stencil_op(info->back.stencilPassOp) << 3;
474
475 if (info->stencilWriteMask)
476 dw[0] |= 1 << 18;
477
478 dw[1] = (info->stencilReadMask & 0xff) << 24 |
479 (info->stencilWriteMask & 0xff) << 16;
480
481 state->cmd_stencil_ref = (info->front.stencilRef & 0xff) << 24 |
482 (info->back.stencilRef & 0xff) << 16;
483 }
484
485 /*
486 * From the Sandy Bridge PRM, volume 2 part 1, page 360:
487 *
488 * "Enabling the Depth Test function without defining a Depth Buffer is
489 * UNDEFINED."
490 *
491 * From the Sandy Bridge PRM, volume 2 part 1, page 375:
492 *
493 * "A Depth Buffer must be defined before enabling writes to it, or
494 * operation is UNDEFINED."
495 *
496 * TODO We do not check these yet.
497 */
498 if (info->depthTestEnable) {
499 dw[2] = 1 << 31 |
500 translate_compare_func(info->depthFunc) << 27 |
501 (bool) info->depthWriteEnable << 26;
502 } else {
503 dw[2] = GEN6_COMPAREFUNCTION_ALWAYS << 27;
504 }
505
506 return XGL_SUCCESS;
507}
508
Chia-I Wua5714e82014-08-11 15:33:42 +0800509static void viewport_state_destroy(struct intel_obj *obj)
510{
511 struct intel_viewport_state *state = intel_viewport_state_from_obj(obj);
512
513 intel_viewport_state_destroy(state);
514}
515
516XGL_RESULT intel_viewport_state_create(struct intel_dev *dev,
517 const XGL_VIEWPORT_STATE_CREATE_INFO *info,
518 struct intel_viewport_state **state_ret)
519{
520 struct intel_viewport_state *state;
Chia-I Wu97702a62014-08-11 15:33:42 +0800521 XGL_RESULT ret;
Chia-I Wua5714e82014-08-11 15:33:42 +0800522
523 state = (struct intel_viewport_state *) intel_base_create(dev,
524 sizeof(*state), dev->base.dbg, XGL_DBG_OBJECT_VIEWPORT_STATE,
525 info, 0);
526 if (!state)
527 return XGL_ERROR_OUT_OF_MEMORY;
528
529 state->obj.destroy = viewport_state_destroy;
530
Chia-I Wu97702a62014-08-11 15:33:42 +0800531 ret = viewport_state_init(state, dev->gpu, info);
532 if (ret != XGL_SUCCESS) {
533 intel_viewport_state_destroy(state);
534 return ret;
535 }
Chia-I Wua5714e82014-08-11 15:33:42 +0800536
537 *state_ret = state;
538
539 return XGL_SUCCESS;
540}
541
542void intel_viewport_state_destroy(struct intel_viewport_state *state)
543{
Chia-I Wu97702a62014-08-11 15:33:42 +0800544 icd_free(state->cmd);
Chia-I Wua5714e82014-08-11 15:33:42 +0800545 intel_base_destroy(&state->obj.base);
546}
547
548static void raster_state_destroy(struct intel_obj *obj)
549{
550 struct intel_raster_state *state = intel_raster_state_from_obj(obj);
551
552 intel_raster_state_destroy(state);
553}
554
555XGL_RESULT intel_raster_state_create(struct intel_dev *dev,
556 const XGL_RASTER_STATE_CREATE_INFO *info,
557 struct intel_raster_state **state_ret)
558{
559 struct intel_raster_state *state;
560
561 state = (struct intel_raster_state *) intel_base_create(dev,
562 sizeof(*state), dev->base.dbg, XGL_DBG_OBJECT_RASTER_STATE,
563 info, 0);
564 if (!state)
565 return XGL_ERROR_OUT_OF_MEMORY;
566
567 state->obj.destroy = raster_state_destroy;
568
Chia-I Wu97702a62014-08-11 15:33:42 +0800569 raster_state_init(state, dev->gpu, info);
Chia-I Wua5714e82014-08-11 15:33:42 +0800570
571 *state_ret = state;
572
573 return XGL_SUCCESS;
574}
575
576void intel_raster_state_destroy(struct intel_raster_state *state)
577{
578 intel_base_destroy(&state->obj.base);
579}
580
581static void msaa_state_destroy(struct intel_obj *obj)
582{
583 struct intel_msaa_state *state = intel_msaa_state_from_obj(obj);
584
585 intel_msaa_state_destroy(state);
586}
587
588XGL_RESULT intel_msaa_state_create(struct intel_dev *dev,
589 const XGL_MSAA_STATE_CREATE_INFO *info,
590 struct intel_msaa_state **state_ret)
591{
592 struct intel_msaa_state *state;
593
594 state = (struct intel_msaa_state *) intel_base_create(dev,
595 sizeof(*state), dev->base.dbg, XGL_DBG_OBJECT_MSAA_STATE,
596 info, 0);
597 if (!state)
598 return XGL_ERROR_OUT_OF_MEMORY;
599
600 state->obj.destroy = msaa_state_destroy;
601
Chia-I Wu97702a62014-08-11 15:33:42 +0800602 msaa_state_init(state, dev->gpu, info);
Chia-I Wua5714e82014-08-11 15:33:42 +0800603
604 *state_ret = state;
605
606 return XGL_SUCCESS;
607}
608
609void intel_msaa_state_destroy(struct intel_msaa_state *state)
610{
611 intel_base_destroy(&state->obj.base);
612}
613
614static void blend_state_destroy(struct intel_obj *obj)
615{
616 struct intel_blend_state *state = intel_blend_state_from_obj(obj);
617
618 intel_blend_state_destroy(state);
619}
620
621XGL_RESULT intel_blend_state_create(struct intel_dev *dev,
622 const XGL_COLOR_BLEND_STATE_CREATE_INFO *info,
623 struct intel_blend_state **state_ret)
624{
625 struct intel_blend_state *state;
626
627 state = (struct intel_blend_state *) intel_base_create(dev,
Courtney Goeltzenleuchter985ad492014-08-27 14:04:17 -0600628 sizeof(*state), dev->base.dbg, XGL_DBG_OBJECT_COLOR_BLEND_STATE,
Chia-I Wua5714e82014-08-11 15:33:42 +0800629 info, 0);
630 if (!state)
631 return XGL_ERROR_OUT_OF_MEMORY;
632
633 state->obj.destroy = blend_state_destroy;
634
Chia-I Wu97702a62014-08-11 15:33:42 +0800635 blend_state_init(state, dev->gpu, info);
Chia-I Wua5714e82014-08-11 15:33:42 +0800636
637 *state_ret = state;
638
639 return XGL_SUCCESS;
640}
641
642void intel_blend_state_destroy(struct intel_blend_state *state)
643{
644 intel_base_destroy(&state->obj.base);
645}
646
647static void ds_state_destroy(struct intel_obj *obj)
648{
649 struct intel_ds_state *state = intel_ds_state_from_obj(obj);
650
651 intel_ds_state_destroy(state);
652}
653
654XGL_RESULT intel_ds_state_create(struct intel_dev *dev,
655 const XGL_DEPTH_STENCIL_STATE_CREATE_INFO *info,
656 struct intel_ds_state **state_ret)
657{
658 struct intel_ds_state *state;
Chia-I Wu97702a62014-08-11 15:33:42 +0800659 XGL_RESULT ret;
Chia-I Wua5714e82014-08-11 15:33:42 +0800660
661 state = (struct intel_ds_state *) intel_base_create(dev,
Courtney Goeltzenleuchtere7dc05f2014-08-22 16:26:07 -0600662 sizeof(*state), dev->base.dbg, XGL_DBG_OBJECT_DEPTH_STENCIL_STATE,
Chia-I Wua5714e82014-08-11 15:33:42 +0800663 info, 0);
664 if (!state)
665 return XGL_ERROR_OUT_OF_MEMORY;
666
667 state->obj.destroy = ds_state_destroy;
668
Chia-I Wu97702a62014-08-11 15:33:42 +0800669 ret = ds_state_init(state, dev->gpu, info);
670 if (ret != XGL_SUCCESS) {
671 intel_ds_state_destroy(state);
672 return ret;
673 }
Chia-I Wua5714e82014-08-11 15:33:42 +0800674
675 *state_ret = state;
676
677 return XGL_SUCCESS;
678}
679
680void intel_ds_state_destroy(struct intel_ds_state *state)
681{
682 intel_base_destroy(&state->obj.base);
683}
684
685XGL_RESULT XGLAPI intelCreateViewportState(
686 XGL_DEVICE device,
687 const XGL_VIEWPORT_STATE_CREATE_INFO* pCreateInfo,
688 XGL_VIEWPORT_STATE_OBJECT* pState)
689{
690 struct intel_dev *dev = intel_dev(device);
691
692 return intel_viewport_state_create(dev, pCreateInfo,
693 (struct intel_viewport_state **) pState);
694}
695
696XGL_RESULT XGLAPI intelCreateRasterState(
697 XGL_DEVICE device,
698 const XGL_RASTER_STATE_CREATE_INFO* pCreateInfo,
699 XGL_RASTER_STATE_OBJECT* pState)
700{
701 struct intel_dev *dev = intel_dev(device);
702
703 return intel_raster_state_create(dev, pCreateInfo,
704 (struct intel_raster_state **) pState);
705}
706
707XGL_RESULT XGLAPI intelCreateMsaaState(
708 XGL_DEVICE device,
709 const XGL_MSAA_STATE_CREATE_INFO* pCreateInfo,
710 XGL_MSAA_STATE_OBJECT* pState)
711{
712 struct intel_dev *dev = intel_dev(device);
713
714 return intel_msaa_state_create(dev, pCreateInfo,
715 (struct intel_msaa_state **) pState);
716}
717
718XGL_RESULT XGLAPI intelCreateColorBlendState(
719 XGL_DEVICE device,
720 const XGL_COLOR_BLEND_STATE_CREATE_INFO* pCreateInfo,
721 XGL_COLOR_BLEND_STATE_OBJECT* pState)
722{
723 struct intel_dev *dev = intel_dev(device);
724
725 return intel_blend_state_create(dev, pCreateInfo,
726 (struct intel_blend_state **) pState);
727}
728
729XGL_RESULT XGLAPI intelCreateDepthStencilState(
730 XGL_DEVICE device,
731 const XGL_DEPTH_STENCIL_STATE_CREATE_INFO* pCreateInfo,
732 XGL_DEPTH_STENCIL_STATE_OBJECT* pState)
733{
734 struct intel_dev *dev = intel_dev(device);
735
736 return intel_ds_state_create(dev, pCreateInfo,
737 (struct intel_ds_state **) pState);
738}