• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "pipe/p_format.h"
29 #include "util/format/u_format.h"
30 #include "r300_reg.h"
31 #include <stdio.h>
32 
33 /* Some maths. These should probably find their way to u_math, if needed. */
34 
pack_float_16_6x(float f)35 static inline int pack_float_16_6x(float f) {
36     return ((int)(f * 6.0) & 0xffff);
37 }
38 
39 /* Blend state. */
40 
r300_translate_blend_function(int blend_func,boolean clamp)41 static inline uint32_t r300_translate_blend_function(int blend_func,
42                                                      boolean clamp)
43 {
44     switch (blend_func) {
45     case PIPE_BLEND_ADD:
46         return clamp ? R300_COMB_FCN_ADD_CLAMP : R300_COMB_FCN_ADD_NOCLAMP;
47     case PIPE_BLEND_SUBTRACT:
48         return clamp ? R300_COMB_FCN_SUB_CLAMP : R300_COMB_FCN_SUB_NOCLAMP;
49     case PIPE_BLEND_REVERSE_SUBTRACT:
50         return clamp ? R300_COMB_FCN_RSUB_CLAMP : R300_COMB_FCN_RSUB_NOCLAMP;
51     case PIPE_BLEND_MIN:
52         return R300_COMB_FCN_MIN;
53     case PIPE_BLEND_MAX:
54         return R300_COMB_FCN_MAX;
55     default:
56         fprintf(stderr, "r300: Unknown blend function %d\n", blend_func);
57         assert(0);
58         break;
59     }
60     return 0;
61 }
62 
r300_translate_blend_factor(int blend_fact)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         case PIPE_BLENDFACTOR_ZERO:
83             return R300_BLEND_GL_ZERO;
84         case PIPE_BLENDFACTOR_INV_SRC_COLOR:
85             return R300_BLEND_GL_ONE_MINUS_SRC_COLOR;
86         case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
87             return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA;
88         case PIPE_BLENDFACTOR_INV_DST_ALPHA:
89             return R300_BLEND_GL_ONE_MINUS_DST_ALPHA;
90         case PIPE_BLENDFACTOR_INV_DST_COLOR:
91             return R300_BLEND_GL_ONE_MINUS_DST_COLOR;
92         case PIPE_BLENDFACTOR_INV_CONST_COLOR:
93             return R300_BLEND_GL_ONE_MINUS_CONST_COLOR;
94         case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
95             return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA;
96 
97         case PIPE_BLENDFACTOR_SRC1_COLOR:
98         case PIPE_BLENDFACTOR_SRC1_ALPHA:
99         case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
100         case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
101             fprintf(stderr, "r300: Implementation error: "
102                 "Bad blend factor %d not supported!\n", blend_fact);
103             assert(0);
104             break;
105 
106         default:
107             fprintf(stderr, "r300: Unknown blend factor %d\n", blend_fact);
108             assert(0);
109             break;
110     }
111     return 0;
112 }
113 
114 /* DSA state. */
115 
r300_translate_depth_stencil_function(int zs_func)116 static inline uint32_t r300_translate_depth_stencil_function(int zs_func)
117 {
118     switch (zs_func) {
119         case PIPE_FUNC_NEVER:
120             return R300_ZS_NEVER;
121         case PIPE_FUNC_LESS:
122             return R300_ZS_LESS;
123         case PIPE_FUNC_EQUAL:
124             return R300_ZS_EQUAL;
125         case PIPE_FUNC_LEQUAL:
126             return R300_ZS_LEQUAL;
127         case PIPE_FUNC_GREATER:
128             return R300_ZS_GREATER;
129         case PIPE_FUNC_NOTEQUAL:
130             return R300_ZS_NOTEQUAL;
131         case PIPE_FUNC_GEQUAL:
132             return R300_ZS_GEQUAL;
133         case PIPE_FUNC_ALWAYS:
134             return R300_ZS_ALWAYS;
135         default:
136             fprintf(stderr, "r300: Unknown depth/stencil function %d\n",
137                 zs_func);
138             assert(0);
139             break;
140     }
141     return 0;
142 }
143 
r300_translate_stencil_op(int s_op)144 static inline uint32_t r300_translate_stencil_op(int s_op)
145 {
146     switch (s_op) {
147         case PIPE_STENCIL_OP_KEEP:
148             return R300_ZS_KEEP;
149         case PIPE_STENCIL_OP_ZERO:
150             return R300_ZS_ZERO;
151         case PIPE_STENCIL_OP_REPLACE:
152             return R300_ZS_REPLACE;
153         case PIPE_STENCIL_OP_INCR:
154             return R300_ZS_INCR;
155         case PIPE_STENCIL_OP_DECR:
156             return R300_ZS_DECR;
157         case PIPE_STENCIL_OP_INCR_WRAP:
158             return R300_ZS_INCR_WRAP;
159         case PIPE_STENCIL_OP_DECR_WRAP:
160             return R300_ZS_DECR_WRAP;
161         case PIPE_STENCIL_OP_INVERT:
162             return R300_ZS_INVERT;
163         default:
164             fprintf(stderr, "r300: Unknown stencil op %d", s_op);
165             assert(0);
166             break;
167     }
168     return 0;
169 }
170 
r300_translate_alpha_function(int alpha_func)171 static inline uint32_t r300_translate_alpha_function(int alpha_func)
172 {
173     switch (alpha_func) {
174         case PIPE_FUNC_NEVER:
175             return R300_FG_ALPHA_FUNC_NEVER;
176         case PIPE_FUNC_LESS:
177             return R300_FG_ALPHA_FUNC_LESS;
178         case PIPE_FUNC_EQUAL:
179             return R300_FG_ALPHA_FUNC_EQUAL;
180         case PIPE_FUNC_LEQUAL:
181             return R300_FG_ALPHA_FUNC_LE;
182         case PIPE_FUNC_GREATER:
183             return R300_FG_ALPHA_FUNC_GREATER;
184         case PIPE_FUNC_NOTEQUAL:
185             return R300_FG_ALPHA_FUNC_NOTEQUAL;
186         case PIPE_FUNC_GEQUAL:
187             return R300_FG_ALPHA_FUNC_GE;
188         case PIPE_FUNC_ALWAYS:
189             return R300_FG_ALPHA_FUNC_ALWAYS;
190         default:
191             fprintf(stderr, "r300: Unknown alpha function %d", alpha_func);
192             assert(0);
193             break;
194     }
195     return 0;
196 }
197 
198 static inline uint32_t
r300_translate_polygon_mode_front(unsigned mode)199 r300_translate_polygon_mode_front(unsigned mode) {
200     switch (mode)
201     {
202         case PIPE_POLYGON_MODE_FILL:
203             return R300_GA_POLY_MODE_FRONT_PTYPE_TRI;
204         case PIPE_POLYGON_MODE_LINE:
205             return R300_GA_POLY_MODE_FRONT_PTYPE_LINE;
206         case PIPE_POLYGON_MODE_POINT:
207             return R300_GA_POLY_MODE_FRONT_PTYPE_POINT;
208 
209         default:
210             fprintf(stderr, "r300: Bad polygon mode %i in %s\n", mode,
211                 __FUNCTION__);
212             return R300_GA_POLY_MODE_FRONT_PTYPE_TRI;
213     }
214 }
215 
216 static inline uint32_t
r300_translate_polygon_mode_back(unsigned mode)217 r300_translate_polygon_mode_back(unsigned mode) {
218     switch (mode)
219     {
220         case PIPE_POLYGON_MODE_FILL:
221             return R300_GA_POLY_MODE_BACK_PTYPE_TRI;
222         case PIPE_POLYGON_MODE_LINE:
223             return R300_GA_POLY_MODE_BACK_PTYPE_LINE;
224         case PIPE_POLYGON_MODE_POINT:
225             return R300_GA_POLY_MODE_BACK_PTYPE_POINT;
226 
227         default:
228             fprintf(stderr, "r300: Bad polygon mode %i in %s\n", mode,
229                 __FUNCTION__);
230             return R300_GA_POLY_MODE_BACK_PTYPE_TRI;
231     }
232 }
233 
234 /* Texture sampler state. */
235 
r300_translate_wrap(int wrap)236 static inline uint32_t r300_translate_wrap(int wrap)
237 {
238     switch (wrap) {
239         case PIPE_TEX_WRAP_REPEAT:
240             return R300_TX_REPEAT;
241         case PIPE_TEX_WRAP_CLAMP:
242             return R300_TX_CLAMP;
243         case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
244             return R300_TX_CLAMP_TO_EDGE;
245         case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
246             return R300_TX_CLAMP_TO_BORDER;
247         case PIPE_TEX_WRAP_MIRROR_REPEAT:
248             return R300_TX_REPEAT | R300_TX_MIRRORED;
249         case PIPE_TEX_WRAP_MIRROR_CLAMP:
250             return R300_TX_CLAMP | R300_TX_MIRRORED;
251         case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
252             return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
253         case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
254             return R300_TX_CLAMP_TO_BORDER | R300_TX_MIRRORED;
255         default:
256             fprintf(stderr, "r300: Unknown texture wrap %d", wrap);
257             assert(0);
258             return 0;
259     }
260 }
261 
r300_translate_tex_filters(int min,int mag,int mip,boolean is_anisotropic)262 static inline uint32_t r300_translate_tex_filters(int min, int mag, int mip,
263                                                   boolean is_anisotropic)
264 {
265     uint32_t retval = 0;
266 
267     switch (min) {
268     case PIPE_TEX_FILTER_NEAREST:
269         retval |= R300_TX_MIN_FILTER_NEAREST;
270         break;
271     case PIPE_TEX_FILTER_LINEAR:
272         retval |= is_anisotropic ? R300_TX_MIN_FILTER_ANISO :
273                                    R300_TX_MIN_FILTER_LINEAR;
274         break;
275     default:
276         fprintf(stderr, "r300: Unknown texture filter %d\n", min);
277         assert(0);
278     }
279 
280     switch (mag) {
281     case PIPE_TEX_FILTER_NEAREST:
282         retval |= R300_TX_MAG_FILTER_NEAREST;
283         break;
284     case PIPE_TEX_FILTER_LINEAR:
285         retval |= is_anisotropic ? R300_TX_MAG_FILTER_ANISO :
286                                    R300_TX_MAG_FILTER_LINEAR;
287         break;
288     default:
289         fprintf(stderr, "r300: Unknown texture filter %d\n", mag);
290         assert(0);
291     }
292 
293     switch (mip) {
294     case PIPE_TEX_MIPFILTER_NONE:
295         retval |= R300_TX_MIN_FILTER_MIP_NONE;
296         break;
297     case PIPE_TEX_MIPFILTER_NEAREST:
298         retval |= R300_TX_MIN_FILTER_MIP_NEAREST;
299         break;
300     case PIPE_TEX_MIPFILTER_LINEAR:
301         retval |= R300_TX_MIN_FILTER_MIP_LINEAR;
302         break;
303     default:
304         fprintf(stderr, "r300: Unknown texture filter %d\n", mip);
305         assert(0);
306     }
307 
308     return retval;
309 }
310 
r300_anisotropy(unsigned max_aniso)311 static inline uint32_t r300_anisotropy(unsigned max_aniso)
312 {
313     if (max_aniso >= 16) {
314         return R300_TX_MAX_ANISO_16_TO_1;
315     } else if (max_aniso >= 8) {
316         return R300_TX_MAX_ANISO_8_TO_1;
317     } else if (max_aniso >= 4) {
318         return R300_TX_MAX_ANISO_4_TO_1;
319     } else if (max_aniso >= 2) {
320         return R300_TX_MAX_ANISO_2_TO_1;
321     } else {
322         return R300_TX_MAX_ANISO_1_TO_1;
323     }
324 }
325 
r500_anisotropy(unsigned max_aniso)326 static inline uint32_t r500_anisotropy(unsigned max_aniso)
327 {
328     if (!max_aniso) {
329         return 0;
330     }
331     max_aniso -= 1;
332 
333     // Map the range [0, 15] to [0, 63].
334     return R500_TX_MAX_ANISO(MIN2((unsigned)(max_aniso*4.2001), 63)) |
335            R500_TX_ANISO_HIGH_QUALITY;
336 }
337 
338 /* Translate pipe_formats into PSC vertex types. */
339 static inline uint16_t
r300_translate_vertex_data_type(enum pipe_format format)340 r300_translate_vertex_data_type(enum pipe_format format) {
341     uint32_t result = 0;
342     const struct util_format_description *desc;
343     unsigned i;
344 
345     if (!format)
346         format = PIPE_FORMAT_R32_FLOAT;
347 
348     desc = util_format_description(format);
349 
350     if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
351         return R300_INVALID_FORMAT;
352     }
353 
354     /* Find the first non-VOID channel. */
355     for (i = 0; i < 4; i++) {
356         if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
357             break;
358         }
359     }
360 
361     switch (desc->channel[i].type) {
362         /* Half-floats, floats, doubles */
363         case UTIL_FORMAT_TYPE_FLOAT:
364             switch (desc->channel[i].size) {
365                 case 16:
366                     /* Supported only on RV350 and later. */
367                     if (desc->nr_channels > 2) {
368                         result = R300_DATA_TYPE_FLT16_4;
369                     } else {
370                         result = R300_DATA_TYPE_FLT16_2;
371                     }
372                     break;
373                 case 32:
374                     result = R300_DATA_TYPE_FLOAT_1 + (desc->nr_channels - 1);
375                     break;
376                 default:
377                     return R300_INVALID_FORMAT;
378             }
379             break;
380         /* Unsigned ints */
381         case UTIL_FORMAT_TYPE_UNSIGNED:
382         /* Signed ints */
383         case UTIL_FORMAT_TYPE_SIGNED:
384             switch (desc->channel[i].size) {
385                 case 8:
386                     result = R300_DATA_TYPE_BYTE;
387                     break;
388                 case 16:
389                     if (desc->nr_channels > 2) {
390                         result = R300_DATA_TYPE_SHORT_4;
391                     } else {
392                         result = R300_DATA_TYPE_SHORT_2;
393                     }
394                     break;
395                 default:
396                     return R300_INVALID_FORMAT;
397             }
398             break;
399         default:
400             return R300_INVALID_FORMAT;
401     }
402 
403     if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
404         result |= R300_SIGNED;
405     }
406     if (desc->channel[i].normalized) {
407         result |= R300_NORMALIZE;
408     }
409 
410     return result;
411 }
412 
413 static inline uint16_t
r300_translate_vertex_data_swizzle(enum pipe_format format)414 r300_translate_vertex_data_swizzle(enum pipe_format format) {
415     const struct util_format_description *desc;
416     unsigned i, swizzle = 0;
417 
418     if (!format)
419         return (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_X_SHIFT) |
420                (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Y_SHIFT) |
421                (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_SHIFT) |
422                (R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_SHIFT);
423 
424     desc = util_format_description(format);
425 
426     if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
427         fprintf(stderr, "r300: Bad format %s in %s:%d\n",
428             util_format_short_name(format), __FUNCTION__, __LINE__);
429         return 0;
430     }
431 
432     for (i = 0; i < desc->nr_channels; i++) {
433         swizzle |=
434             MIN2(desc->swizzle[i], R300_SWIZZLE_SELECT_FP_ONE) << (3*i);
435     }
436     /* Set (0,0,0,1) in unused components. */
437     for (; i < 3; i++) {
438         swizzle |= R300_SWIZZLE_SELECT_FP_ZERO << (3*i);
439     }
440     for (; i < 4; i++) {
441         swizzle |= R300_SWIZZLE_SELECT_FP_ONE << (3*i);
442     }
443 
444     return swizzle | (0xf << R300_WRITE_ENA_SHIFT);
445 }
446 
447 #endif /* R300_STATE_INLINES_H */
448