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