1 /* 2 * Copyright (c) 2012-2013 Etnaviv Project 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sub license, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the 12 * next paragraph) shall be included in all copies or substantial portions 13 * of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 /* inlined translation functions between gallium and vivante */ 24 #ifndef H_TRANSLATE 25 #define H_TRANSLATE 26 27 #include "pipe/p_defines.h" 28 #include "pipe/p_format.h" 29 #include "pipe/p_state.h" 30 31 #include "etnaviv_debug.h" 32 #include "etnaviv_format.h" 33 #include "etnaviv_tiling.h" 34 #include "etnaviv_util.h" 35 #include "hw/cmdstream.xml.h" 36 #include "hw/common_3d.xml.h" 37 #include "hw/state.xml.h" 38 #include "hw/state_3d.xml.h" 39 40 #include "util/u_format.h" 41 #include "util/u_math.h" 42 43 #include <stdio.h> 44 45 /* Returned when there is no match of pipe value to etna value */ 46 #define ETNA_NO_MATCH (~0) 47 48 static inline uint32_t 49 translate_cull_face(unsigned cull_face, unsigned front_ccw) 50 { 51 switch (cull_face) { 52 case PIPE_FACE_NONE: 53 return VIVS_PA_CONFIG_CULL_FACE_MODE_OFF; 54 case PIPE_FACE_BACK: 55 return front_ccw ? VIVS_PA_CONFIG_CULL_FACE_MODE_CW 56 : VIVS_PA_CONFIG_CULL_FACE_MODE_CCW; 57 case PIPE_FACE_FRONT: 58 return front_ccw ? VIVS_PA_CONFIG_CULL_FACE_MODE_CCW 59 : VIVS_PA_CONFIG_CULL_FACE_MODE_CW; 60 default: 61 DBG("Unhandled cull face mode %i", cull_face); 62 return ETNA_NO_MATCH; 63 } 64 } 65 66 static inline uint32_t 67 translate_polygon_mode(unsigned polygon_mode) 68 { 69 switch (polygon_mode) { 70 case PIPE_POLYGON_MODE_FILL: 71 return VIVS_PA_CONFIG_FILL_MODE_SOLID; 72 case PIPE_POLYGON_MODE_LINE: 73 return VIVS_PA_CONFIG_FILL_MODE_WIREFRAME; 74 case PIPE_POLYGON_MODE_POINT: 75 return VIVS_PA_CONFIG_FILL_MODE_POINT; 76 default: 77 DBG("Unhandled polygon mode %i", polygon_mode); 78 return ETNA_NO_MATCH; 79 } 80 } 81 82 static inline uint32_t 83 translate_stencil_mode(bool enable_0, bool enable_1) 84 { 85 if (enable_0) { 86 return enable_1 ? VIVS_PE_STENCIL_CONFIG_MODE_TWO_SIDED 87 : VIVS_PE_STENCIL_CONFIG_MODE_ONE_SIDED; 88 } else { 89 return VIVS_PE_STENCIL_CONFIG_MODE_DISABLED; 90 } 91 } 92 93 static inline uint32_t 94 translate_stencil_op(unsigned stencil_op) 95 { 96 switch (stencil_op) { 97 case PIPE_STENCIL_OP_KEEP: 98 return STENCIL_OP_KEEP; 99 case PIPE_STENCIL_OP_ZERO: 100 return STENCIL_OP_ZERO; 101 case PIPE_STENCIL_OP_REPLACE: 102 return STENCIL_OP_REPLACE; 103 case PIPE_STENCIL_OP_INCR: 104 return STENCIL_OP_INCR; 105 case PIPE_STENCIL_OP_DECR: 106 return STENCIL_OP_DECR; 107 case PIPE_STENCIL_OP_INCR_WRAP: 108 return STENCIL_OP_INCR_WRAP; 109 case PIPE_STENCIL_OP_DECR_WRAP: 110 return STENCIL_OP_DECR_WRAP; 111 case PIPE_STENCIL_OP_INVERT: 112 return STENCIL_OP_INVERT; 113 default: 114 DBG("Unhandled stencil op: %i", stencil_op); 115 return ETNA_NO_MATCH; 116 } 117 } 118 119 static inline uint32_t 120 translate_blend(unsigned blend) 121 { 122 switch (blend) { 123 case PIPE_BLEND_ADD: 124 return BLEND_EQ_ADD; 125 case PIPE_BLEND_SUBTRACT: 126 return BLEND_EQ_SUBTRACT; 127 case PIPE_BLEND_REVERSE_SUBTRACT: 128 return BLEND_EQ_REVERSE_SUBTRACT; 129 case PIPE_BLEND_MIN: 130 return BLEND_EQ_MIN; 131 case PIPE_BLEND_MAX: 132 return BLEND_EQ_MAX; 133 default: 134 DBG("Unhandled blend: %i", blend); 135 return ETNA_NO_MATCH; 136 } 137 } 138 139 static inline uint32_t 140 translate_blend_factor(unsigned blend_factor) 141 { 142 switch (blend_factor) { 143 case PIPE_BLENDFACTOR_ONE: 144 return BLEND_FUNC_ONE; 145 case PIPE_BLENDFACTOR_SRC_COLOR: 146 return BLEND_FUNC_SRC_COLOR; 147 case PIPE_BLENDFACTOR_SRC_ALPHA: 148 return BLEND_FUNC_SRC_ALPHA; 149 case PIPE_BLENDFACTOR_DST_ALPHA: 150 return BLEND_FUNC_DST_ALPHA; 151 case PIPE_BLENDFACTOR_DST_COLOR: 152 return BLEND_FUNC_DST_COLOR; 153 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: 154 return BLEND_FUNC_SRC_ALPHA_SATURATE; 155 case PIPE_BLENDFACTOR_CONST_COLOR: 156 return BLEND_FUNC_CONSTANT_COLOR; 157 case PIPE_BLENDFACTOR_CONST_ALPHA: 158 return BLEND_FUNC_CONSTANT_ALPHA; 159 case PIPE_BLENDFACTOR_ZERO: 160 return BLEND_FUNC_ZERO; 161 case PIPE_BLENDFACTOR_INV_SRC_COLOR: 162 return BLEND_FUNC_ONE_MINUS_SRC_COLOR; 163 case PIPE_BLENDFACTOR_INV_SRC_ALPHA: 164 return BLEND_FUNC_ONE_MINUS_SRC_ALPHA; 165 case PIPE_BLENDFACTOR_INV_DST_ALPHA: 166 return BLEND_FUNC_ONE_MINUS_DST_ALPHA; 167 case PIPE_BLENDFACTOR_INV_DST_COLOR: 168 return BLEND_FUNC_ONE_MINUS_DST_COLOR; 169 case PIPE_BLENDFACTOR_INV_CONST_COLOR: 170 return BLEND_FUNC_ONE_MINUS_CONSTANT_COLOR; 171 case PIPE_BLENDFACTOR_INV_CONST_ALPHA: 172 return BLEND_FUNC_ONE_MINUS_CONSTANT_ALPHA; 173 case PIPE_BLENDFACTOR_SRC1_COLOR: 174 case PIPE_BLENDFACTOR_SRC1_ALPHA: 175 case PIPE_BLENDFACTOR_INV_SRC1_COLOR: 176 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: 177 default: 178 DBG("Unhandled blend factor: %i", blend_factor); 179 return ETNA_NO_MATCH; 180 } 181 } 182 183 static inline uint32_t 184 translate_texture_wrapmode(unsigned wrap) 185 { 186 switch (wrap) { 187 case PIPE_TEX_WRAP_REPEAT: 188 return TEXTURE_WRAPMODE_REPEAT; 189 case PIPE_TEX_WRAP_CLAMP: 190 return TEXTURE_WRAPMODE_CLAMP_TO_EDGE; 191 case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 192 return TEXTURE_WRAPMODE_CLAMP_TO_EDGE; 193 case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 194 return TEXTURE_WRAPMODE_CLAMP_TO_EDGE; /* XXX */ 195 case PIPE_TEX_WRAP_MIRROR_REPEAT: 196 return TEXTURE_WRAPMODE_MIRRORED_REPEAT; 197 case PIPE_TEX_WRAP_MIRROR_CLAMP: 198 return TEXTURE_WRAPMODE_MIRRORED_REPEAT; /* XXX */ 199 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 200 return TEXTURE_WRAPMODE_MIRRORED_REPEAT; /* XXX */ 201 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 202 return TEXTURE_WRAPMODE_MIRRORED_REPEAT; /* XXX */ 203 default: 204 DBG("Unhandled texture wrapmode: %i", wrap); 205 return ETNA_NO_MATCH; 206 } 207 } 208 209 static inline uint32_t 210 translate_texture_mipfilter(unsigned filter) 211 { 212 switch (filter) { 213 case PIPE_TEX_MIPFILTER_NEAREST: 214 return TEXTURE_FILTER_NEAREST; 215 case PIPE_TEX_MIPFILTER_LINEAR: 216 return TEXTURE_FILTER_LINEAR; 217 case PIPE_TEX_MIPFILTER_NONE: 218 return TEXTURE_FILTER_NONE; 219 default: 220 DBG("Unhandled texture mipfilter: %i", filter); 221 return ETNA_NO_MATCH; 222 } 223 } 224 225 static inline uint32_t 226 translate_texture_filter(unsigned filter) 227 { 228 switch (filter) { 229 case PIPE_TEX_FILTER_NEAREST: 230 return TEXTURE_FILTER_NEAREST; 231 case PIPE_TEX_FILTER_LINEAR: 232 return TEXTURE_FILTER_LINEAR; 233 /* What about anisotropic? */ 234 default: 235 DBG("Unhandled texture filter: %i", filter); 236 return ETNA_NO_MATCH; 237 } 238 } 239 240 /* return a RS "compatible" format for use when copying */ 241 static inline enum pipe_format 242 etna_compatible_rs_format(enum pipe_format fmt) 243 { 244 /* YUYV and UYVY are blocksize 4, but 2 bytes per pixel */ 245 if (fmt == PIPE_FORMAT_YUYV || fmt == PIPE_FORMAT_UYVY) 246 return PIPE_FORMAT_B4G4R4A4_UNORM; 247 248 switch (util_format_get_blocksize(fmt)) { 249 case 2: 250 return PIPE_FORMAT_B4G4R4A4_UNORM; 251 case 4: 252 return PIPE_FORMAT_B8G8R8A8_UNORM; 253 default: 254 return fmt; 255 } 256 } 257 258 static inline int 259 translate_rb_src_dst_swap(enum pipe_format src, enum pipe_format dst) 260 { 261 return translate_rs_format_rb_swap(src) ^ translate_rs_format_rb_swap(dst); 262 } 263 264 static inline uint32_t 265 translate_depth_format(enum pipe_format fmt) 266 { 267 /* Note: Pipe format convention is LSB to MSB, VIVS is MSB to LSB */ 268 switch (fmt) { 269 case PIPE_FORMAT_Z16_UNORM: 270 return VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D16; 271 case PIPE_FORMAT_X8Z24_UNORM: 272 return VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D24S8; 273 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 274 return VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D24S8; 275 default: 276 return ETNA_NO_MATCH; 277 } 278 } 279 280 /* render target format for MSAA */ 281 static inline uint32_t 282 translate_msaa_format(enum pipe_format fmt) 283 { 284 /* Note: Pipe format convention is LSB to MSB, VIVS is MSB to LSB */ 285 switch (fmt) { 286 case PIPE_FORMAT_B4G4R4X4_UNORM: 287 return COLOR_COMPRESSION_FORMAT_A4R4G4B4; 288 case PIPE_FORMAT_B4G4R4A4_UNORM: 289 return COLOR_COMPRESSION_FORMAT_A4R4G4B4; 290 case PIPE_FORMAT_B5G5R5X1_UNORM: 291 return COLOR_COMPRESSION_FORMAT_A1R5G5B5; 292 case PIPE_FORMAT_B5G5R5A1_UNORM: 293 return COLOR_COMPRESSION_FORMAT_A1R5G5B5; 294 case PIPE_FORMAT_B5G6R5_UNORM: 295 return COLOR_COMPRESSION_FORMAT_R5G6B5; 296 case PIPE_FORMAT_B8G8R8X8_UNORM: 297 return COLOR_COMPRESSION_FORMAT_X8R8G8B8; 298 case PIPE_FORMAT_B8G8R8A8_UNORM: 299 return COLOR_COMPRESSION_FORMAT_A8R8G8B8; 300 /* MSAA with YUYV not supported */ 301 default: 302 return ETNA_NO_MATCH; 303 } 304 } 305 306 /* Return normalization flag for vertex element format */ 307 static inline uint32_t 308 translate_vertex_format_normalize(enum pipe_format fmt) 309 { 310 const struct util_format_description *desc = util_format_description(fmt); 311 if (!desc) 312 return VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF; 313 314 /* assumes that normalization of channel 0 holds for all channels; 315 * this holds for all vertex formats that we support */ 316 return desc->channel[0].normalized 317 ? VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_ON 318 : VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF; 319 } 320 321 static inline uint32_t 322 translate_index_size(unsigned index_size) 323 { 324 switch (index_size) { 325 case 1: 326 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_CHAR; 327 case 2: 328 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_SHORT; 329 case 4: 330 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_INT; 331 default: 332 DBG("Unhandled index size %i", index_size); 333 return ETNA_NO_MATCH; 334 } 335 } 336 337 static inline uint32_t 338 translate_draw_mode(unsigned mode) 339 { 340 switch (mode) { 341 case PIPE_PRIM_POINTS: 342 return PRIMITIVE_TYPE_POINTS; 343 case PIPE_PRIM_LINES: 344 return PRIMITIVE_TYPE_LINES; 345 case PIPE_PRIM_LINE_LOOP: 346 return PRIMITIVE_TYPE_LINE_LOOP; 347 case PIPE_PRIM_LINE_STRIP: 348 return PRIMITIVE_TYPE_LINE_STRIP; 349 case PIPE_PRIM_TRIANGLES: 350 return PRIMITIVE_TYPE_TRIANGLES; 351 case PIPE_PRIM_TRIANGLE_STRIP: 352 return PRIMITIVE_TYPE_TRIANGLE_STRIP; 353 case PIPE_PRIM_TRIANGLE_FAN: 354 return PRIMITIVE_TYPE_TRIANGLE_FAN; 355 case PIPE_PRIM_QUADS: 356 return PRIMITIVE_TYPE_QUADS; 357 default: 358 DBG("Unhandled draw mode primitive %i", mode); 359 return ETNA_NO_MATCH; 360 } 361 } 362 363 /* Get size multiple for size of texture/rendertarget with a certain layout 364 * This is affected by many different parameters: 365 * - A horizontal multiple of 16 is used when possible as resolve can be used 366 * at the cost of only a little bit extra memory usage. 367 * - If the surface is to be used with the resolve engine, set rs_align true. 368 * If set, a horizontal multiple of 16 will be used for tiled and linear, 369 * otherwise one of 16. However, such a surface will be incompatible 370 * with the samplers if the GPU does hot support the HALIGN feature. 371 * - If the surface is supertiled, horizontal and vertical multiple is always 64 372 * - If the surface is multi tiled or supertiled, make sure that the vertical size 373 * is a multiple of the number of pixel pipes as well. 374 * */ 375 static inline void 376 etna_layout_multiple(unsigned layout, unsigned pixel_pipes, bool rs_align, 377 unsigned *paddingX, unsigned *paddingY, unsigned *halign) 378 { 379 switch (layout) { 380 case ETNA_LAYOUT_LINEAR: 381 *paddingX = rs_align ? 16 : 4; 382 *paddingY = 1; 383 *halign = rs_align ? TEXTURE_HALIGN_SIXTEEN : TEXTURE_HALIGN_FOUR; 384 break; 385 case ETNA_LAYOUT_TILED: 386 *paddingX = rs_align ? 16 : 4; 387 *paddingY = 4; 388 *halign = rs_align ? TEXTURE_HALIGN_SIXTEEN : TEXTURE_HALIGN_FOUR; 389 break; 390 case ETNA_LAYOUT_SUPER_TILED: 391 *paddingX = 64; 392 *paddingY = 64; 393 *halign = TEXTURE_HALIGN_SUPER_TILED; 394 break; 395 case ETNA_LAYOUT_MULTI_TILED: 396 *paddingX = 16; 397 *paddingY = 4 * pixel_pipes; 398 *halign = TEXTURE_HALIGN_SPLIT_TILED; 399 break; 400 case ETNA_LAYOUT_MULTI_SUPERTILED: 401 *paddingX = 64; 402 *paddingY = 64 * pixel_pipes; 403 *halign = TEXTURE_HALIGN_SPLIT_SUPER_TILED; 404 break; 405 default: 406 DBG("Unhandled layout %i", layout); 407 } 408 } 409 410 static inline void etna_adjust_rs_align(unsigned num_pixelpipes, 411 unsigned *paddingX, unsigned *paddingY) 412 { 413 unsigned alignX = ETNA_RS_WIDTH_MASK + 1; 414 unsigned alignY = (ETNA_RS_HEIGHT_MASK + 1) * num_pixelpipes; 415 416 if (paddingX) 417 *paddingX = align(*paddingX, alignX); 418 if (paddingY) 419 *paddingY = align(*paddingY, alignY); 420 } 421 422 static inline uint32_t 423 translate_clear_depth_stencil(enum pipe_format format, float depth, 424 unsigned stencil) 425 { 426 uint32_t clear_value = 0; 427 428 // XXX util_pack_color 429 switch (format) { 430 case PIPE_FORMAT_Z16_UNORM: 431 clear_value = etna_cfloat_to_uintN(depth, 16); 432 clear_value |= clear_value << 16; 433 break; 434 case PIPE_FORMAT_X8Z24_UNORM: 435 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 436 clear_value = (etna_cfloat_to_uintN(depth, 24) << 8) | (stencil & 0xFF); 437 break; 438 default: 439 DBG("Unhandled pipe format for depth stencil clear: %i", format); 440 } 441 return clear_value; 442 } 443 444 /* Convert MSAA number of samples to x and y scaling factor and 445 * VIVS_GL_MULTI_SAMPLE_CONFIG value. 446 * Return true if supported and false otherwise. */ 447 static inline bool 448 translate_samples_to_xyscale(int num_samples, int *xscale_out, int *yscale_out, 449 uint32_t *config_out) 450 { 451 int xscale, yscale; 452 uint32_t config; 453 454 switch (num_samples) { 455 case 0: 456 case 1: 457 xscale = 1; 458 yscale = 1; 459 config = VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_NONE; 460 break; 461 case 2: 462 xscale = 2; 463 yscale = 1; 464 config = VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_2X; 465 break; 466 case 4: 467 xscale = 2; 468 yscale = 2; 469 config = VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_4X; 470 break; 471 default: 472 return false; 473 } 474 475 if (xscale_out) 476 *xscale_out = xscale; 477 if (yscale_out) 478 *yscale_out = yscale; 479 if (config_out) 480 *config_out = config; 481 482 return true; 483 } 484 485 #endif 486