Merge commit 'origin/master' into i965g-restart
[mesa.git] / src / gallium / drivers / r300 / r300_state_inlines.h
1 /*
2 * Copyright 2009 Joakim Sindholt <opensource@zhasha.com>
3 * Corbin Simpson <MostAwesomeDude@gmail.com>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE. */
23
24 #ifndef R300_STATE_INLINES_H
25 #define R300_STATE_INLINES_H
26
27 #include "draw/draw_vertex.h"
28
29 #include "pipe/p_format.h"
30
31 #include "r300_reg.h"
32
33 /* Some maths. These should probably find their way to u_math, if needed. */
34
35 static INLINE int pack_float_16_6x(float f) {
36 return ((int)(f * 6.0) & 0xffff);
37 }
38
39 /* Blend state. */
40
41 static INLINE uint32_t r300_translate_blend_function(int blend_func)
42 {
43 switch (blend_func) {
44 case PIPE_BLEND_ADD:
45 return R300_COMB_FCN_ADD_CLAMP;
46 case PIPE_BLEND_SUBTRACT:
47 return R300_COMB_FCN_SUB_CLAMP;
48 case PIPE_BLEND_REVERSE_SUBTRACT:
49 return R300_COMB_FCN_RSUB_CLAMP;
50 case PIPE_BLEND_MIN:
51 return R300_COMB_FCN_MIN;
52 case PIPE_BLEND_MAX:
53 return R300_COMB_FCN_MAX;
54 default:
55 debug_printf("r300: Unknown blend function %d\n", blend_func);
56 assert(0);
57 break;
58 }
59 return 0;
60 }
61
62 /* XXX we can also offer the D3D versions of some of these... */
63 static INLINE uint32_t r300_translate_blend_factor(int blend_fact)
64 {
65 switch (blend_fact) {
66 case PIPE_BLENDFACTOR_ONE:
67 return R300_BLEND_GL_ONE;
68 case PIPE_BLENDFACTOR_SRC_COLOR:
69 return R300_BLEND_GL_SRC_COLOR;
70 case PIPE_BLENDFACTOR_SRC_ALPHA:
71 return R300_BLEND_GL_SRC_ALPHA;
72 case PIPE_BLENDFACTOR_DST_ALPHA:
73 return R300_BLEND_GL_DST_ALPHA;
74 case PIPE_BLENDFACTOR_DST_COLOR:
75 return R300_BLEND_GL_DST_COLOR;
76 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
77 return R300_BLEND_GL_SRC_ALPHA_SATURATE;
78 case PIPE_BLENDFACTOR_CONST_COLOR:
79 return R300_BLEND_GL_CONST_COLOR;
80 case PIPE_BLENDFACTOR_CONST_ALPHA:
81 return R300_BLEND_GL_CONST_ALPHA;
82 /* XXX WTF are these?
83 case PIPE_BLENDFACTOR_SRC1_COLOR:
84 case PIPE_BLENDFACTOR_SRC1_ALPHA: */
85 case PIPE_BLENDFACTOR_ZERO:
86 return R300_BLEND_GL_ZERO;
87 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
88 return R300_BLEND_GL_ONE_MINUS_SRC_COLOR;
89 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
90 return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA;
91 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
92 return R300_BLEND_GL_ONE_MINUS_DST_ALPHA;
93 case PIPE_BLENDFACTOR_INV_DST_COLOR:
94 return R300_BLEND_GL_ONE_MINUS_DST_COLOR;
95 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
96 return R300_BLEND_GL_ONE_MINUS_CONST_COLOR;
97 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
98 return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA;
99 /* XXX see above
100 case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
101 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: */
102 default:
103 debug_printf("r300: Unknown blend factor %d\n", blend_fact);
104 assert(0);
105 break;
106 }
107 return 0;
108 }
109
110 /* DSA state. */
111
112 static INLINE uint32_t r300_translate_depth_stencil_function(int zs_func)
113 {
114 switch (zs_func) {
115 case PIPE_FUNC_NEVER:
116 return R300_ZS_NEVER;
117 case PIPE_FUNC_LESS:
118 return R300_ZS_LESS;
119 case PIPE_FUNC_EQUAL:
120 return R300_ZS_EQUAL;
121 case PIPE_FUNC_LEQUAL:
122 return R300_ZS_LEQUAL;
123 case PIPE_FUNC_GREATER:
124 return R300_ZS_GREATER;
125 case PIPE_FUNC_NOTEQUAL:
126 return R300_ZS_NOTEQUAL;
127 case PIPE_FUNC_GEQUAL:
128 return R300_ZS_GEQUAL;
129 case PIPE_FUNC_ALWAYS:
130 return R300_ZS_ALWAYS;
131 default:
132 debug_printf("r300: Unknown depth/stencil function %d\n",
133 zs_func);
134 assert(0);
135 break;
136 }
137 return 0;
138 }
139
140 static INLINE uint32_t r300_translate_stencil_op(int s_op)
141 {
142 switch (s_op) {
143 case PIPE_STENCIL_OP_KEEP:
144 return R300_ZS_KEEP;
145 case PIPE_STENCIL_OP_ZERO:
146 return R300_ZS_ZERO;
147 case PIPE_STENCIL_OP_REPLACE:
148 return R300_ZS_REPLACE;
149 case PIPE_STENCIL_OP_INCR:
150 return R300_ZS_INCR;
151 case PIPE_STENCIL_OP_DECR:
152 return R300_ZS_DECR;
153 case PIPE_STENCIL_OP_INCR_WRAP:
154 return R300_ZS_INCR_WRAP;
155 case PIPE_STENCIL_OP_DECR_WRAP:
156 return R300_ZS_DECR_WRAP;
157 case PIPE_STENCIL_OP_INVERT:
158 return R300_ZS_INVERT;
159 default:
160 debug_printf("r300: Unknown stencil op %d", s_op);
161 assert(0);
162 break;
163 }
164 return 0;
165 }
166
167 static INLINE uint32_t r300_translate_alpha_function(int alpha_func)
168 {
169 switch (alpha_func) {
170 case PIPE_FUNC_NEVER:
171 return R300_FG_ALPHA_FUNC_NEVER;
172 case PIPE_FUNC_LESS:
173 return R300_FG_ALPHA_FUNC_LESS;
174 case PIPE_FUNC_EQUAL:
175 return R300_FG_ALPHA_FUNC_EQUAL;
176 case PIPE_FUNC_LEQUAL:
177 return R300_FG_ALPHA_FUNC_LE;
178 case PIPE_FUNC_GREATER:
179 return R300_FG_ALPHA_FUNC_GREATER;
180 case PIPE_FUNC_NOTEQUAL:
181 return R300_FG_ALPHA_FUNC_NOTEQUAL;
182 case PIPE_FUNC_GEQUAL:
183 return R300_FG_ALPHA_FUNC_GE;
184 case PIPE_FUNC_ALWAYS:
185 return R300_FG_ALPHA_FUNC_ALWAYS;
186 default:
187 debug_printf("r300: Unknown alpha function %d", alpha_func);
188 assert(0);
189 break;
190 }
191 return 0;
192 }
193
194 static INLINE uint32_t
195 r300_translate_polygon_mode_front(unsigned mode) {
196 switch (mode)
197 {
198 case PIPE_POLYGON_MODE_FILL:
199 return R300_GA_POLY_MODE_FRONT_PTYPE_TRI;
200 case PIPE_POLYGON_MODE_LINE:
201 return R300_GA_POLY_MODE_FRONT_PTYPE_LINE;
202 case PIPE_POLYGON_MODE_POINT:
203 return R300_GA_POLY_MODE_FRONT_PTYPE_POINT;
204
205 default:
206 debug_printf("r300: Bad polygon mode %i in %s\n", mode,
207 __FUNCTION__);
208 return R300_GA_POLY_MODE_FRONT_PTYPE_TRI;
209 }
210 }
211
212 static INLINE uint32_t
213 r300_translate_polygon_mode_back(unsigned mode) {
214 switch (mode)
215 {
216 case PIPE_POLYGON_MODE_FILL:
217 return R300_GA_POLY_MODE_BACK_PTYPE_TRI;
218 case PIPE_POLYGON_MODE_LINE:
219 return R300_GA_POLY_MODE_BACK_PTYPE_LINE;
220 case PIPE_POLYGON_MODE_POINT:
221 return R300_GA_POLY_MODE_BACK_PTYPE_POINT;
222
223 default:
224 debug_printf("r300: Bad polygon mode %i in %s\n", mode,
225 __FUNCTION__);
226 return R300_GA_POLY_MODE_BACK_PTYPE_TRI;
227 }
228 }
229
230 /* Texture sampler state. */
231
232 static INLINE uint32_t r300_translate_wrap(int wrap)
233 {
234 switch (wrap) {
235 case PIPE_TEX_WRAP_REPEAT:
236 return R300_TX_REPEAT;
237 case PIPE_TEX_WRAP_CLAMP:
238 return R300_TX_CLAMP;
239 case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
240 return R300_TX_CLAMP_TO_EDGE;
241 case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
242 return R300_TX_CLAMP_TO_BORDER;
243 case PIPE_TEX_WRAP_MIRROR_REPEAT:
244 return R300_TX_REPEAT | R300_TX_MIRRORED;
245 case PIPE_TEX_WRAP_MIRROR_CLAMP:
246 return R300_TX_CLAMP | R300_TX_MIRRORED;
247 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
248 return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
249 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
250 return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
251 default:
252 debug_printf("r300: Unknown texture wrap %d", wrap);
253 assert(0);
254 return 0;
255 }
256 }
257
258 static INLINE uint32_t r300_translate_tex_filters(int min, int mag, int mip)
259 {
260 uint32_t retval = 0;
261 switch (min) {
262 case PIPE_TEX_FILTER_NEAREST:
263 retval |= R300_TX_MIN_FILTER_NEAREST;
264 break;
265 case PIPE_TEX_FILTER_LINEAR:
266 retval |= R300_TX_MIN_FILTER_LINEAR;
267 break;
268 case PIPE_TEX_FILTER_ANISO:
269 retval |= R300_TX_MIN_FILTER_ANISO;
270 break;
271 default:
272 debug_printf("r300: Unknown texture filter %d\n", min);
273 assert(0);
274 break;
275 }
276 switch (mag) {
277 case PIPE_TEX_FILTER_NEAREST:
278 retval |= R300_TX_MAG_FILTER_NEAREST;
279 break;
280 case PIPE_TEX_FILTER_LINEAR:
281 retval |= R300_TX_MAG_FILTER_LINEAR;
282 break;
283 case PIPE_TEX_FILTER_ANISO:
284 retval |= R300_TX_MAG_FILTER_ANISO;
285 break;
286 default:
287 debug_printf("r300: Unknown texture filter %d\n", mag);
288 assert(0);
289 break;
290 }
291 switch (mip) {
292 case PIPE_TEX_MIPFILTER_NONE:
293 retval |= R300_TX_MIN_FILTER_MIP_NONE;
294 break;
295 case PIPE_TEX_MIPFILTER_NEAREST:
296 retval |= R300_TX_MIN_FILTER_MIP_NEAREST;
297 break;
298 case PIPE_TEX_MIPFILTER_LINEAR:
299 retval |= R300_TX_MIN_FILTER_MIP_LINEAR;
300 break;
301 default:
302 debug_printf("r300: Unknown texture filter %d\n", mip);
303 assert(0);
304 break;
305 }
306
307 return retval;
308 }
309
310 static INLINE uint32_t r300_anisotropy(float max_aniso)
311 {
312 if (max_aniso >= 16.0f) {
313 return R300_TX_MAX_ANISO_16_TO_1;
314 } else if (max_aniso >= 8.0f) {
315 return R300_TX_MAX_ANISO_8_TO_1;
316 } else if (max_aniso >= 4.0f) {
317 return R300_TX_MAX_ANISO_4_TO_1;
318 } else if (max_aniso >= 2.0f) {
319 return R300_TX_MAX_ANISO_2_TO_1;
320 } else {
321 return R300_TX_MAX_ANISO_1_TO_1;
322 }
323 }
324
325 /* Buffer formats. */
326
327 /* Colorbuffer formats. This is the unswizzled format of the RB3D block's
328 * output. For the swizzling of the targets, check the shader's format. */
329 static INLINE uint32_t r300_translate_colorformat(enum pipe_format format)
330 {
331 switch (format) {
332 /* 8-bit buffers */
333 case PIPE_FORMAT_I8_UNORM:
334 return R300_COLOR_FORMAT_I8;
335 /* 16-bit buffers */
336 case PIPE_FORMAT_R5G6B5_UNORM:
337 return R300_COLOR_FORMAT_RGB565;
338 case PIPE_FORMAT_A1R5G5B5_UNORM:
339 return R300_COLOR_FORMAT_ARGB1555;
340 case PIPE_FORMAT_A4R4G4B4_UNORM:
341 return R300_COLOR_FORMAT_ARGB4444;
342 /* 32-bit buffers */
343 case PIPE_FORMAT_A8R8G8B8_UNORM:
344 case PIPE_FORMAT_X8R8G8B8_UNORM:
345 case PIPE_FORMAT_R8G8B8A8_UNORM:
346 case PIPE_FORMAT_R8G8B8X8_UNORM:
347 return R300_COLOR_FORMAT_ARGB8888;
348 /* XXX Not in pipe_format
349 case PIPE_FORMAT_A32R32G32B32:
350 return R300_COLOR_FORMAT_ARGB32323232;
351 case PIPE_FORMAT_A16R16G16B16:
352 return R300_COLOR_FORMAT_ARGB16161616;
353 case PIPE_FORMAT_A10R10G10B10_UNORM:
354 return R500_COLOR_FORMAT_ARGB10101010;
355 case PIPE_FORMAT_A2R10G10B10_UNORM:
356 return R500_COLOR_FORMAT_ARGB2101010;
357 case PIPE_FORMAT_I10_UNORM:
358 return R500_COLOR_FORMAT_I10; */
359 default:
360 debug_printf("r300: Implementation error: "
361 "Got unsupported color format %s in %s\n",
362 pf_name(format), __FUNCTION__);
363 assert(0);
364 break;
365 }
366 return 0;
367 }
368
369 /* Depthbuffer and stencilbuffer. Thankfully, we only support two flavors. */
370 static INLINE uint32_t r300_translate_zsformat(enum pipe_format format)
371 {
372 switch (format) {
373 /* 16-bit depth, no stencil */
374 case PIPE_FORMAT_Z16_UNORM:
375 return R300_DEPTHFORMAT_16BIT_INT_Z;
376 /* 24-bit depth, ignored stencil */
377 case PIPE_FORMAT_Z24X8_UNORM:
378 /* 24-bit depth, 8-bit stencil */
379 case PIPE_FORMAT_Z24S8_UNORM:
380 return R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
381 default:
382 debug_printf("r300: Implementation error: "
383 "Got unsupported ZS format %s in %s\n",
384 pf_name(format), __FUNCTION__);
385 assert(0);
386 break;
387 }
388 return 0;
389 }
390
391 /* Shader output formats. This is essentially the swizzle from the shader
392 * to the RB3D block.
393 *
394 * Note that formats are stored from C3 to C0. */
395 static INLINE uint32_t r300_translate_out_fmt(enum pipe_format format)
396 {
397 switch (format) {
398 case PIPE_FORMAT_A8R8G8B8_UNORM:
399 case PIPE_FORMAT_X8R8G8B8_UNORM:
400 /* XXX */
401 case PIPE_FORMAT_Z24S8_UNORM:
402 return R300_US_OUT_FMT_C4_8 |
403 R300_C0_SEL_B | R300_C1_SEL_G |
404 R300_C2_SEL_R | R300_C3_SEL_A;
405 case PIPE_FORMAT_R8G8B8A8_UNORM:
406 case PIPE_FORMAT_R8G8B8X8_UNORM:
407 return R300_US_OUT_FMT_C4_8 |
408 R300_C0_SEL_A | R300_C1_SEL_B |
409 R300_C2_SEL_G | R300_C3_SEL_R;
410 default:
411 debug_printf("r300: Implementation error: "
412 "Got unsupported output format %s in %s\n",
413 pf_name(format), __FUNCTION__);
414 assert(0);
415 return R300_US_OUT_FMT_UNUSED;
416 }
417 return 0;
418 }
419
420 /* Non-CSO state. (For now.) */
421
422 static INLINE uint32_t r300_translate_gb_pipes(int pipe_count)
423 {
424 switch (pipe_count) {
425 case 1:
426 return R300_GB_TILE_PIPE_COUNT_RV300;
427 break;
428 case 2:
429 return R300_GB_TILE_PIPE_COUNT_R300;
430 break;
431 case 3:
432 return R300_GB_TILE_PIPE_COUNT_R420_3P;
433 break;
434 case 4:
435 return R300_GB_TILE_PIPE_COUNT_R420;
436 break;
437 }
438 return 0;
439 }
440
441 /* Utility function to count the number of components in RGBAZS formats.
442 * XXX should go to util or p_format.h */
443 static INLINE unsigned pf_component_count(enum pipe_format format) {
444 unsigned count = 0;
445
446 if (pf_layout(format) != PIPE_FORMAT_LAYOUT_RGBAZS) {
447 return count;
448 }
449
450 if (pf_size_x(format)) {
451 count++;
452 }
453 if (pf_size_y(format)) {
454 count++;
455 }
456 if (pf_size_z(format)) {
457 count++;
458 }
459 if (pf_size_w(format)) {
460 count++;
461 }
462
463 return count;
464 }
465
466 /* Translate pipe_formats into PSC vertex types. */
467 static INLINE uint16_t
468 r300_translate_vertex_data_type(enum pipe_format format) {
469 uint32_t result = 0;
470 unsigned components = pf_component_count(format);
471
472 if (pf_layout(format) != PIPE_FORMAT_LAYOUT_RGBAZS) {
473 debug_printf("r300: Bad format %s in %s:%d\n", pf_name(format),
474 __FUNCTION__, __LINE__);
475 assert(0);
476 }
477
478 switch (pf_type(format)) {
479 /* Half-floats, floats, doubles */
480 case PIPE_FORMAT_TYPE_FLOAT:
481 switch (pf_size_x(format)) {
482 case 4:
483 result = R300_DATA_TYPE_FLOAT_1 + (components - 1);
484 break;
485 default:
486 debug_printf("r300: Bad format %s in %s:%d\n",
487 pf_name(format), __FUNCTION__, __LINE__);
488 assert(0);
489 }
490 break;
491 /* Normalized unsigned ints */
492 case PIPE_FORMAT_TYPE_UNORM:
493 /* Normalized signed ints */
494 case PIPE_FORMAT_TYPE_SNORM:
495 /* Non-normalized unsigned ints */
496 case PIPE_FORMAT_TYPE_USCALED:
497 /* Non-normalized signed ints */
498 case PIPE_FORMAT_TYPE_SSCALED:
499 switch (pf_size_x(format)) {
500 case 1:
501 result = R300_DATA_TYPE_BYTE;
502 break;
503 case 2:
504 if (components > 2) {
505 result = R300_DATA_TYPE_SHORT_4;
506 } else {
507 result = R300_DATA_TYPE_SHORT_2;
508 }
509 break;
510 default:
511 debug_printf("r300: Bad format %s in %s:%d\n",
512 pf_name(format), __FUNCTION__, __LINE__);
513 debug_printf("r300: pf_size_x(format) == %d\n",
514 pf_size_x(format));
515 assert(0);
516 }
517 break;
518 default:
519 debug_printf("r300: Bad format %s in %s:%d\n",
520 pf_name(format), __FUNCTION__, __LINE__);
521 assert(0);
522 }
523
524 if (pf_type(format) == PIPE_FORMAT_TYPE_SSCALED) {
525 result |= R300_SIGNED;
526 } else if (pf_type(format) == PIPE_FORMAT_TYPE_UNORM) {
527 result |= R300_NORMALIZE;
528 } else if (pf_type(format) == PIPE_FORMAT_TYPE_SNORM) {
529 result |= (R300_SIGNED | R300_NORMALIZE);
530 }
531
532 return result;
533 }
534
535 static INLINE uint16_t
536 r300_translate_vertex_data_swizzle(enum pipe_format format) {
537
538 if (pf_layout(format) != PIPE_FORMAT_LAYOUT_RGBAZS) {
539 debug_printf("r300: Bad format %s in %s:%d\n",
540 pf_name(format), __FUNCTION__, __LINE__);
541 return 0;
542 }
543
544 return ((pf_swizzle_x(format) << R300_SWIZZLE_SELECT_X_SHIFT) |
545 (pf_swizzle_y(format) << R300_SWIZZLE_SELECT_Y_SHIFT) |
546 (pf_swizzle_z(format) << R300_SWIZZLE_SELECT_Z_SHIFT) |
547 (pf_swizzle_w(format) << R300_SWIZZLE_SELECT_W_SHIFT) |
548 (0xf << R300_WRITE_ENA_SHIFT));
549 }
550
551 #endif /* R300_STATE_INLINES_H */