blob: c022e26f84eb43a4989997c31adca19ecc58fd1b [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) {
Jeremy Hayes4c329eb2015-01-14 14:58:37 -0700115 case XGL_FILL_POINTS:
Chia-I Wu97702a62014-08-11 15:33:42 +0800116 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];
Chia-I Wua6c4f152014-12-02 04:19:58 +0800450 uint32_t *dw = &state->cmd_blend[i];
Chia-I Wu97702a62014-08-11 15:33:42 +0800451
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 }
Chia-I Wu97702a62014-08-11 15:33:42 +0800466 }
467
468 memcpy(state->cmd_blend_color, info->blendConst, sizeof(info->blendConst));
469}
470
471static XGL_RESULT
472ds_state_init(struct intel_ds_state *state,
473 const struct intel_gpu *gpu,
474 const XGL_DEPTH_STENCIL_STATE_CREATE_INFO *info)
475{
476 uint32_t *dw = state->cmd;
477
478 INTEL_GPU_ASSERT(gpu, 6, 7.5);
479
480 STATIC_ASSERT(ARRAY_SIZE(state->cmd) >= 3);
481
482 if (info->depthBoundsEnable)
483 return XGL_ERROR_UNKNOWN;
484
485 /*
486 * From the Sandy Bridge PRM, volume 2 part 1, page 359:
487 *
488 * "If the Depth Buffer is either undefined or does not have a surface
489 * format of D32_FLOAT_S8X24_UINT or D24_UNORM_S8_UINT and separate
490 * stencil buffer is disabled, Stencil Test Enable must be DISABLED"
491 *
492 * From the Sandy Bridge PRM, volume 2 part 1, page 370:
493 *
494 * "This field (Stencil Test Enable) cannot be enabled if
495 * Surface Format in 3DSTATE_DEPTH_BUFFER is set to D16_UNORM."
496 *
497 * TODO We do not check these yet.
498 */
499 if (info->stencilTestEnable) {
500 dw[0] = 1 << 31 |
501 translate_compare_func(info->front.stencilFunc) << 28 |
502 translate_stencil_op(info->front.stencilFailOp) << 25 |
503 translate_stencil_op(info->front.stencilDepthFailOp) << 22 |
504 translate_stencil_op(info->front.stencilPassOp) << 19 |
505 1 << 15 |
506 translate_compare_func(info->back.stencilFunc) << 12 |
507 translate_stencil_op(info->back.stencilFailOp) << 9 |
508 translate_stencil_op(info->back.stencilDepthFailOp) << 6 |
509 translate_stencil_op(info->back.stencilPassOp) << 3;
510
511 if (info->stencilWriteMask)
512 dw[0] |= 1 << 18;
513
Mike Stroyan0fa44e22015-01-14 17:39:35 -0700514 /* same read and write masks for both front and back faces */
Chia-I Wu97702a62014-08-11 15:33:42 +0800515 dw[1] = (info->stencilReadMask & 0xff) << 24 |
Mike Stroyan0fa44e22015-01-14 17:39:35 -0700516 (info->stencilWriteMask & 0xff) << 16 |
517 (info->stencilReadMask & 0xff) << 8 |
518 (info->stencilWriteMask & 0xff);
Chia-I Wu97702a62014-08-11 15:33:42 +0800519
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) {
Chia-I Wud37703c2014-10-24 12:31:29 +0800538 dw[2] = GEN6_ZS_DW2_DEPTH_TEST_ENABLE |
539 translate_compare_func(info->depthFunc) << 27;
Chia-I Wu97702a62014-08-11 15:33:42 +0800540 } else {
541 dw[2] = GEN6_COMPAREFUNCTION_ALWAYS << 27;
542 }
543
Chia-I Wud37703c2014-10-24 12:31:29 +0800544 if (info->depthWriteEnable)
545 dw[2] |= GEN6_ZS_DW2_DEPTH_WRITE_ENABLE;
546
Chia-I Wu97702a62014-08-11 15:33:42 +0800547 return XGL_SUCCESS;
548}
549
Chia-I Wua5714e82014-08-11 15:33:42 +0800550static void viewport_state_destroy(struct intel_obj *obj)
551{
552 struct intel_viewport_state *state = intel_viewport_state_from_obj(obj);
553
554 intel_viewport_state_destroy(state);
555}
556
557XGL_RESULT intel_viewport_state_create(struct intel_dev *dev,
558 const XGL_VIEWPORT_STATE_CREATE_INFO *info,
559 struct intel_viewport_state **state_ret)
560{
561 struct intel_viewport_state *state;
Chia-I Wu97702a62014-08-11 15:33:42 +0800562 XGL_RESULT ret;
Chia-I Wua5714e82014-08-11 15:33:42 +0800563
564 state = (struct intel_viewport_state *) intel_base_create(dev,
565 sizeof(*state), dev->base.dbg, XGL_DBG_OBJECT_VIEWPORT_STATE,
566 info, 0);
567 if (!state)
568 return XGL_ERROR_OUT_OF_MEMORY;
569
570 state->obj.destroy = viewport_state_destroy;
571
Chia-I Wu97702a62014-08-11 15:33:42 +0800572 ret = viewport_state_init(state, dev->gpu, info);
573 if (ret != XGL_SUCCESS) {
574 intel_viewport_state_destroy(state);
575 return ret;
576 }
Chia-I Wua5714e82014-08-11 15:33:42 +0800577
578 *state_ret = state;
579
580 return XGL_SUCCESS;
581}
582
583void intel_viewport_state_destroy(struct intel_viewport_state *state)
584{
Chia-I Wu97702a62014-08-11 15:33:42 +0800585 icd_free(state->cmd);
Chia-I Wua5714e82014-08-11 15:33:42 +0800586 intel_base_destroy(&state->obj.base);
587}
588
589static void raster_state_destroy(struct intel_obj *obj)
590{
591 struct intel_raster_state *state = intel_raster_state_from_obj(obj);
592
593 intel_raster_state_destroy(state);
594}
595
596XGL_RESULT intel_raster_state_create(struct intel_dev *dev,
597 const XGL_RASTER_STATE_CREATE_INFO *info,
598 struct intel_raster_state **state_ret)
599{
600 struct intel_raster_state *state;
601
602 state = (struct intel_raster_state *) intel_base_create(dev,
603 sizeof(*state), dev->base.dbg, XGL_DBG_OBJECT_RASTER_STATE,
604 info, 0);
605 if (!state)
606 return XGL_ERROR_OUT_OF_MEMORY;
607
608 state->obj.destroy = raster_state_destroy;
609
Chia-I Wu97702a62014-08-11 15:33:42 +0800610 raster_state_init(state, dev->gpu, info);
Chia-I Wua5714e82014-08-11 15:33:42 +0800611
612 *state_ret = state;
613
614 return XGL_SUCCESS;
615}
616
617void intel_raster_state_destroy(struct intel_raster_state *state)
618{
619 intel_base_destroy(&state->obj.base);
620}
621
622static void msaa_state_destroy(struct intel_obj *obj)
623{
624 struct intel_msaa_state *state = intel_msaa_state_from_obj(obj);
625
626 intel_msaa_state_destroy(state);
627}
628
629XGL_RESULT intel_msaa_state_create(struct intel_dev *dev,
630 const XGL_MSAA_STATE_CREATE_INFO *info,
631 struct intel_msaa_state **state_ret)
632{
633 struct intel_msaa_state *state;
634
635 state = (struct intel_msaa_state *) intel_base_create(dev,
636 sizeof(*state), dev->base.dbg, XGL_DBG_OBJECT_MSAA_STATE,
637 info, 0);
638 if (!state)
639 return XGL_ERROR_OUT_OF_MEMORY;
640
641 state->obj.destroy = msaa_state_destroy;
642
Chia-I Wu97702a62014-08-11 15:33:42 +0800643 msaa_state_init(state, dev->gpu, info);
Chia-I Wua5714e82014-08-11 15:33:42 +0800644
645 *state_ret = state;
646
647 return XGL_SUCCESS;
648}
649
650void intel_msaa_state_destroy(struct intel_msaa_state *state)
651{
652 intel_base_destroy(&state->obj.base);
653}
654
655static void blend_state_destroy(struct intel_obj *obj)
656{
657 struct intel_blend_state *state = intel_blend_state_from_obj(obj);
658
659 intel_blend_state_destroy(state);
660}
661
662XGL_RESULT intel_blend_state_create(struct intel_dev *dev,
663 const XGL_COLOR_BLEND_STATE_CREATE_INFO *info,
664 struct intel_blend_state **state_ret)
665{
666 struct intel_blend_state *state;
667
668 state = (struct intel_blend_state *) intel_base_create(dev,
Courtney Goeltzenleuchter985ad492014-08-27 14:04:17 -0600669 sizeof(*state), dev->base.dbg, XGL_DBG_OBJECT_COLOR_BLEND_STATE,
Chia-I Wua5714e82014-08-11 15:33:42 +0800670 info, 0);
671 if (!state)
672 return XGL_ERROR_OUT_OF_MEMORY;
673
674 state->obj.destroy = blend_state_destroy;
675
Chia-I Wu97702a62014-08-11 15:33:42 +0800676 blend_state_init(state, dev->gpu, info);
Chia-I Wua5714e82014-08-11 15:33:42 +0800677
678 *state_ret = state;
679
680 return XGL_SUCCESS;
681}
682
683void intel_blend_state_destroy(struct intel_blend_state *state)
684{
685 intel_base_destroy(&state->obj.base);
686}
687
688static void ds_state_destroy(struct intel_obj *obj)
689{
690 struct intel_ds_state *state = intel_ds_state_from_obj(obj);
691
692 intel_ds_state_destroy(state);
693}
694
695XGL_RESULT intel_ds_state_create(struct intel_dev *dev,
696 const XGL_DEPTH_STENCIL_STATE_CREATE_INFO *info,
697 struct intel_ds_state **state_ret)
698{
699 struct intel_ds_state *state;
Chia-I Wu97702a62014-08-11 15:33:42 +0800700 XGL_RESULT ret;
Chia-I Wua5714e82014-08-11 15:33:42 +0800701
702 state = (struct intel_ds_state *) intel_base_create(dev,
Courtney Goeltzenleuchtere7dc05f2014-08-22 16:26:07 -0600703 sizeof(*state), dev->base.dbg, XGL_DBG_OBJECT_DEPTH_STENCIL_STATE,
Chia-I Wua5714e82014-08-11 15:33:42 +0800704 info, 0);
705 if (!state)
706 return XGL_ERROR_OUT_OF_MEMORY;
707
708 state->obj.destroy = ds_state_destroy;
709
Chia-I Wu97702a62014-08-11 15:33:42 +0800710 ret = ds_state_init(state, dev->gpu, info);
711 if (ret != XGL_SUCCESS) {
712 intel_ds_state_destroy(state);
713 return ret;
714 }
Chia-I Wua5714e82014-08-11 15:33:42 +0800715
716 *state_ret = state;
717
718 return XGL_SUCCESS;
719}
720
721void intel_ds_state_destroy(struct intel_ds_state *state)
722{
723 intel_base_destroy(&state->obj.base);
724}
725
Chia-I Wu96177272015-01-03 15:27:41 +0800726ICD_EXPORT XGL_RESULT XGLAPI xglCreateViewportState(
Chia-I Wua5714e82014-08-11 15:33:42 +0800727 XGL_DEVICE device,
728 const XGL_VIEWPORT_STATE_CREATE_INFO* pCreateInfo,
729 XGL_VIEWPORT_STATE_OBJECT* pState)
730{
731 struct intel_dev *dev = intel_dev(device);
732
733 return intel_viewport_state_create(dev, pCreateInfo,
734 (struct intel_viewport_state **) pState);
735}
736
Chia-I Wu96177272015-01-03 15:27:41 +0800737ICD_EXPORT XGL_RESULT XGLAPI xglCreateRasterState(
Chia-I Wua5714e82014-08-11 15:33:42 +0800738 XGL_DEVICE device,
739 const XGL_RASTER_STATE_CREATE_INFO* pCreateInfo,
740 XGL_RASTER_STATE_OBJECT* pState)
741{
742 struct intel_dev *dev = intel_dev(device);
743
744 return intel_raster_state_create(dev, pCreateInfo,
745 (struct intel_raster_state **) pState);
746}
747
Chia-I Wu96177272015-01-03 15:27:41 +0800748ICD_EXPORT XGL_RESULT XGLAPI xglCreateMsaaState(
Chia-I Wua5714e82014-08-11 15:33:42 +0800749 XGL_DEVICE device,
750 const XGL_MSAA_STATE_CREATE_INFO* pCreateInfo,
751 XGL_MSAA_STATE_OBJECT* pState)
752{
753 struct intel_dev *dev = intel_dev(device);
754
755 return intel_msaa_state_create(dev, pCreateInfo,
756 (struct intel_msaa_state **) pState);
757}
758
Chia-I Wu96177272015-01-03 15:27:41 +0800759ICD_EXPORT XGL_RESULT XGLAPI xglCreateColorBlendState(
Chia-I Wua5714e82014-08-11 15:33:42 +0800760 XGL_DEVICE device,
761 const XGL_COLOR_BLEND_STATE_CREATE_INFO* pCreateInfo,
762 XGL_COLOR_BLEND_STATE_OBJECT* pState)
763{
764 struct intel_dev *dev = intel_dev(device);
765
766 return intel_blend_state_create(dev, pCreateInfo,
767 (struct intel_blend_state **) pState);
768}
769
Chia-I Wu96177272015-01-03 15:27:41 +0800770ICD_EXPORT XGL_RESULT XGLAPI xglCreateDepthStencilState(
Chia-I Wua5714e82014-08-11 15:33:42 +0800771 XGL_DEVICE device,
772 const XGL_DEPTH_STENCIL_STATE_CREATE_INFO* pCreateInfo,
773 XGL_DEPTH_STENCIL_STATE_OBJECT* pState)
774{
775 struct intel_dev *dev = intel_dev(device);
776
777 return intel_ds_state_create(dev, pCreateInfo,
778 (struct intel_ds_state **) pState);
779}