blob: 20c68c3beff2d1a3d7d8fe572f271525a1f437ee [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];
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
514 dw[1] = (info->stencilReadMask & 0xff) << 24 |
515 (info->stencilWriteMask & 0xff) << 16;
516
517 state->cmd_stencil_ref = (info->front.stencilRef & 0xff) << 24 |
518 (info->back.stencilRef & 0xff) << 16;
519 }
520
521 /*
522 * From the Sandy Bridge PRM, volume 2 part 1, page 360:
523 *
524 * "Enabling the Depth Test function without defining a Depth Buffer is
525 * UNDEFINED."
526 *
527 * From the Sandy Bridge PRM, volume 2 part 1, page 375:
528 *
529 * "A Depth Buffer must be defined before enabling writes to it, or
530 * operation is UNDEFINED."
531 *
532 * TODO We do not check these yet.
533 */
534 if (info->depthTestEnable) {
Chia-I Wud37703c2014-10-24 12:31:29 +0800535 dw[2] = GEN6_ZS_DW2_DEPTH_TEST_ENABLE |
536 translate_compare_func(info->depthFunc) << 27;
Chia-I Wu97702a62014-08-11 15:33:42 +0800537 } else {
538 dw[2] = GEN6_COMPAREFUNCTION_ALWAYS << 27;
539 }
540
Chia-I Wud37703c2014-10-24 12:31:29 +0800541 if (info->depthWriteEnable)
542 dw[2] |= GEN6_ZS_DW2_DEPTH_WRITE_ENABLE;
543
Chia-I Wu97702a62014-08-11 15:33:42 +0800544 return XGL_SUCCESS;
545}
546
Chia-I Wua5714e82014-08-11 15:33:42 +0800547static void viewport_state_destroy(struct intel_obj *obj)
548{
549 struct intel_viewport_state *state = intel_viewport_state_from_obj(obj);
550
551 intel_viewport_state_destroy(state);
552}
553
554XGL_RESULT intel_viewport_state_create(struct intel_dev *dev,
555 const XGL_VIEWPORT_STATE_CREATE_INFO *info,
556 struct intel_viewport_state **state_ret)
557{
558 struct intel_viewport_state *state;
Chia-I Wu97702a62014-08-11 15:33:42 +0800559 XGL_RESULT ret;
Chia-I Wua5714e82014-08-11 15:33:42 +0800560
561 state = (struct intel_viewport_state *) intel_base_create(dev,
562 sizeof(*state), dev->base.dbg, XGL_DBG_OBJECT_VIEWPORT_STATE,
563 info, 0);
564 if (!state)
565 return XGL_ERROR_OUT_OF_MEMORY;
566
567 state->obj.destroy = viewport_state_destroy;
568
Chia-I Wu97702a62014-08-11 15:33:42 +0800569 ret = viewport_state_init(state, dev->gpu, info);
570 if (ret != XGL_SUCCESS) {
571 intel_viewport_state_destroy(state);
572 return ret;
573 }
Chia-I Wua5714e82014-08-11 15:33:42 +0800574
575 *state_ret = state;
576
577 return XGL_SUCCESS;
578}
579
580void intel_viewport_state_destroy(struct intel_viewport_state *state)
581{
Chia-I Wu97702a62014-08-11 15:33:42 +0800582 icd_free(state->cmd);
Chia-I Wua5714e82014-08-11 15:33:42 +0800583 intel_base_destroy(&state->obj.base);
584}
585
586static void raster_state_destroy(struct intel_obj *obj)
587{
588 struct intel_raster_state *state = intel_raster_state_from_obj(obj);
589
590 intel_raster_state_destroy(state);
591}
592
593XGL_RESULT intel_raster_state_create(struct intel_dev *dev,
594 const XGL_RASTER_STATE_CREATE_INFO *info,
595 struct intel_raster_state **state_ret)
596{
597 struct intel_raster_state *state;
598
599 state = (struct intel_raster_state *) intel_base_create(dev,
600 sizeof(*state), dev->base.dbg, XGL_DBG_OBJECT_RASTER_STATE,
601 info, 0);
602 if (!state)
603 return XGL_ERROR_OUT_OF_MEMORY;
604
605 state->obj.destroy = raster_state_destroy;
606
Chia-I Wu97702a62014-08-11 15:33:42 +0800607 raster_state_init(state, dev->gpu, info);
Chia-I Wua5714e82014-08-11 15:33:42 +0800608
609 *state_ret = state;
610
611 return XGL_SUCCESS;
612}
613
614void intel_raster_state_destroy(struct intel_raster_state *state)
615{
616 intel_base_destroy(&state->obj.base);
617}
618
619static void msaa_state_destroy(struct intel_obj *obj)
620{
621 struct intel_msaa_state *state = intel_msaa_state_from_obj(obj);
622
623 intel_msaa_state_destroy(state);
624}
625
626XGL_RESULT intel_msaa_state_create(struct intel_dev *dev,
627 const XGL_MSAA_STATE_CREATE_INFO *info,
628 struct intel_msaa_state **state_ret)
629{
630 struct intel_msaa_state *state;
631
632 state = (struct intel_msaa_state *) intel_base_create(dev,
633 sizeof(*state), dev->base.dbg, XGL_DBG_OBJECT_MSAA_STATE,
634 info, 0);
635 if (!state)
636 return XGL_ERROR_OUT_OF_MEMORY;
637
638 state->obj.destroy = msaa_state_destroy;
639
Chia-I Wu97702a62014-08-11 15:33:42 +0800640 msaa_state_init(state, dev->gpu, info);
Chia-I Wua5714e82014-08-11 15:33:42 +0800641
642 *state_ret = state;
643
644 return XGL_SUCCESS;
645}
646
647void intel_msaa_state_destroy(struct intel_msaa_state *state)
648{
649 intel_base_destroy(&state->obj.base);
650}
651
652static void blend_state_destroy(struct intel_obj *obj)
653{
654 struct intel_blend_state *state = intel_blend_state_from_obj(obj);
655
656 intel_blend_state_destroy(state);
657}
658
659XGL_RESULT intel_blend_state_create(struct intel_dev *dev,
660 const XGL_COLOR_BLEND_STATE_CREATE_INFO *info,
661 struct intel_blend_state **state_ret)
662{
663 struct intel_blend_state *state;
664
665 state = (struct intel_blend_state *) intel_base_create(dev,
Courtney Goeltzenleuchter985ad492014-08-27 14:04:17 -0600666 sizeof(*state), dev->base.dbg, XGL_DBG_OBJECT_COLOR_BLEND_STATE,
Chia-I Wua5714e82014-08-11 15:33:42 +0800667 info, 0);
668 if (!state)
669 return XGL_ERROR_OUT_OF_MEMORY;
670
671 state->obj.destroy = blend_state_destroy;
672
Chia-I Wu97702a62014-08-11 15:33:42 +0800673 blend_state_init(state, dev->gpu, info);
Chia-I Wua5714e82014-08-11 15:33:42 +0800674
675 *state_ret = state;
676
677 return XGL_SUCCESS;
678}
679
680void intel_blend_state_destroy(struct intel_blend_state *state)
681{
682 intel_base_destroy(&state->obj.base);
683}
684
685static void ds_state_destroy(struct intel_obj *obj)
686{
687 struct intel_ds_state *state = intel_ds_state_from_obj(obj);
688
689 intel_ds_state_destroy(state);
690}
691
692XGL_RESULT intel_ds_state_create(struct intel_dev *dev,
693 const XGL_DEPTH_STENCIL_STATE_CREATE_INFO *info,
694 struct intel_ds_state **state_ret)
695{
696 struct intel_ds_state *state;
Chia-I Wu97702a62014-08-11 15:33:42 +0800697 XGL_RESULT ret;
Chia-I Wua5714e82014-08-11 15:33:42 +0800698
699 state = (struct intel_ds_state *) intel_base_create(dev,
Courtney Goeltzenleuchtere7dc05f2014-08-22 16:26:07 -0600700 sizeof(*state), dev->base.dbg, XGL_DBG_OBJECT_DEPTH_STENCIL_STATE,
Chia-I Wua5714e82014-08-11 15:33:42 +0800701 info, 0);
702 if (!state)
703 return XGL_ERROR_OUT_OF_MEMORY;
704
705 state->obj.destroy = ds_state_destroy;
706
Chia-I Wu97702a62014-08-11 15:33:42 +0800707 ret = ds_state_init(state, dev->gpu, info);
708 if (ret != XGL_SUCCESS) {
709 intel_ds_state_destroy(state);
710 return ret;
711 }
Chia-I Wua5714e82014-08-11 15:33:42 +0800712
713 *state_ret = state;
714
715 return XGL_SUCCESS;
716}
717
718void intel_ds_state_destroy(struct intel_ds_state *state)
719{
720 intel_base_destroy(&state->obj.base);
721}
722
Chia-I Wu96177272015-01-03 15:27:41 +0800723ICD_EXPORT XGL_RESULT XGLAPI xglCreateViewportState(
Chia-I Wua5714e82014-08-11 15:33:42 +0800724 XGL_DEVICE device,
725 const XGL_VIEWPORT_STATE_CREATE_INFO* pCreateInfo,
726 XGL_VIEWPORT_STATE_OBJECT* pState)
727{
728 struct intel_dev *dev = intel_dev(device);
729
730 return intel_viewport_state_create(dev, pCreateInfo,
731 (struct intel_viewport_state **) pState);
732}
733
Chia-I Wu96177272015-01-03 15:27:41 +0800734ICD_EXPORT XGL_RESULT XGLAPI xglCreateRasterState(
Chia-I Wua5714e82014-08-11 15:33:42 +0800735 XGL_DEVICE device,
736 const XGL_RASTER_STATE_CREATE_INFO* pCreateInfo,
737 XGL_RASTER_STATE_OBJECT* pState)
738{
739 struct intel_dev *dev = intel_dev(device);
740
741 return intel_raster_state_create(dev, pCreateInfo,
742 (struct intel_raster_state **) pState);
743}
744
Chia-I Wu96177272015-01-03 15:27:41 +0800745ICD_EXPORT XGL_RESULT XGLAPI xglCreateMsaaState(
Chia-I Wua5714e82014-08-11 15:33:42 +0800746 XGL_DEVICE device,
747 const XGL_MSAA_STATE_CREATE_INFO* pCreateInfo,
748 XGL_MSAA_STATE_OBJECT* pState)
749{
750 struct intel_dev *dev = intel_dev(device);
751
752 return intel_msaa_state_create(dev, pCreateInfo,
753 (struct intel_msaa_state **) pState);
754}
755
Chia-I Wu96177272015-01-03 15:27:41 +0800756ICD_EXPORT XGL_RESULT XGLAPI xglCreateColorBlendState(
Chia-I Wua5714e82014-08-11 15:33:42 +0800757 XGL_DEVICE device,
758 const XGL_COLOR_BLEND_STATE_CREATE_INFO* pCreateInfo,
759 XGL_COLOR_BLEND_STATE_OBJECT* pState)
760{
761 struct intel_dev *dev = intel_dev(device);
762
763 return intel_blend_state_create(dev, pCreateInfo,
764 (struct intel_blend_state **) pState);
765}
766
Chia-I Wu96177272015-01-03 15:27:41 +0800767ICD_EXPORT XGL_RESULT XGLAPI xglCreateDepthStencilState(
Chia-I Wua5714e82014-08-11 15:33:42 +0800768 XGL_DEVICE device,
769 const XGL_DEPTH_STENCIL_STATE_CREATE_INFO* pCreateInfo,
770 XGL_DEPTH_STENCIL_STATE_OBJECT* pState)
771{
772 struct intel_dev *dev = intel_dev(device);
773
774 return intel_ds_state_create(dev, pCreateInfo,
775 (struct intel_ds_state **) pState);
776}