1 /* 2 * Copyright 2009 Joakim Sindholt <opensource (at) zhasha.com> 3 * Corbin Simpson <MostAwesomeDude (at) 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/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 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 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 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 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 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 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 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 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 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 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 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 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 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