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