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 /* 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 */ 440