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