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