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_util.h" 34#include "hw/cmdstream.xml.h" 35#include "hw/common_3d.xml.h" 36#include "hw/state.xml.h" 37#include "hw/state_3d.xml.h" 38 39#include "util/format/u_format.h" 40#include "util/u_math.h" 41 42/* Returned when there is no match of pipe value to etna value */ 43#define ETNA_NO_MATCH (~0) 44 45static inline uint32_t 46translate_cull_face(unsigned cull_face, unsigned front_ccw) 47{ 48 switch (cull_face) { 49 case PIPE_FACE_NONE: 50 return VIVS_PA_CONFIG_CULL_FACE_MODE_OFF; 51 case PIPE_FACE_BACK: 52 return front_ccw ? VIVS_PA_CONFIG_CULL_FACE_MODE_CW 53 : VIVS_PA_CONFIG_CULL_FACE_MODE_CCW; 54 case PIPE_FACE_FRONT: 55 return front_ccw ? VIVS_PA_CONFIG_CULL_FACE_MODE_CCW 56 : VIVS_PA_CONFIG_CULL_FACE_MODE_CW; 57 default: 58 DBG("Unhandled cull face mode %i", cull_face); 59 return ETNA_NO_MATCH; 60 } 61} 62 63static inline uint32_t 64translate_polygon_mode(unsigned polygon_mode) 65{ 66 switch (polygon_mode) { 67 case PIPE_POLYGON_MODE_FILL: 68 return VIVS_PA_CONFIG_FILL_MODE_SOLID; 69 case PIPE_POLYGON_MODE_LINE: 70 return VIVS_PA_CONFIG_FILL_MODE_WIREFRAME; 71 case PIPE_POLYGON_MODE_POINT: 72 return VIVS_PA_CONFIG_FILL_MODE_POINT; 73 default: 74 DBG("Unhandled polygon mode %i", polygon_mode); 75 return ETNA_NO_MATCH; 76 } 77} 78 79static inline uint32_t 80translate_stencil_mode(bool enable_0, bool enable_1) 81{ 82 if (enable_0) { 83 return enable_1 ? VIVS_PE_STENCIL_CONFIG_MODE_TWO_SIDED 84 : VIVS_PE_STENCIL_CONFIG_MODE_ONE_SIDED; 85 } else { 86 return VIVS_PE_STENCIL_CONFIG_MODE_DISABLED; 87 } 88} 89 90static inline uint32_t 91translate_stencil_op(unsigned stencil_op) 92{ 93 switch (stencil_op) { 94 case PIPE_STENCIL_OP_KEEP: 95 return STENCIL_OP_KEEP; 96 case PIPE_STENCIL_OP_ZERO: 97 return STENCIL_OP_ZERO; 98 case PIPE_STENCIL_OP_REPLACE: 99 return STENCIL_OP_REPLACE; 100 case PIPE_STENCIL_OP_INCR: 101 return STENCIL_OP_INCR; 102 case PIPE_STENCIL_OP_DECR: 103 return STENCIL_OP_DECR; 104 case PIPE_STENCIL_OP_INCR_WRAP: 105 return STENCIL_OP_INCR_WRAP; 106 case PIPE_STENCIL_OP_DECR_WRAP: 107 return STENCIL_OP_DECR_WRAP; 108 case PIPE_STENCIL_OP_INVERT: 109 return STENCIL_OP_INVERT; 110 default: 111 DBG("Unhandled stencil op: %i", stencil_op); 112 return ETNA_NO_MATCH; 113 } 114} 115 116static inline uint32_t 117translate_blend_factor(unsigned blend_factor) 118{ 119 switch (blend_factor) { 120 case PIPE_BLENDFACTOR_ONE: 121 return BLEND_FUNC_ONE; 122 case PIPE_BLENDFACTOR_SRC_COLOR: 123 return BLEND_FUNC_SRC_COLOR; 124 case PIPE_BLENDFACTOR_SRC_ALPHA: 125 return BLEND_FUNC_SRC_ALPHA; 126 case PIPE_BLENDFACTOR_DST_ALPHA: 127 return BLEND_FUNC_DST_ALPHA; 128 case PIPE_BLENDFACTOR_DST_COLOR: 129 return BLEND_FUNC_DST_COLOR; 130 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: 131 return BLEND_FUNC_SRC_ALPHA_SATURATE; 132 case PIPE_BLENDFACTOR_CONST_COLOR: 133 return BLEND_FUNC_CONSTANT_COLOR; 134 case PIPE_BLENDFACTOR_CONST_ALPHA: 135 return BLEND_FUNC_CONSTANT_ALPHA; 136 case PIPE_BLENDFACTOR_ZERO: 137 return BLEND_FUNC_ZERO; 138 case PIPE_BLENDFACTOR_INV_SRC_COLOR: 139 return BLEND_FUNC_ONE_MINUS_SRC_COLOR; 140 case PIPE_BLENDFACTOR_INV_SRC_ALPHA: 141 return BLEND_FUNC_ONE_MINUS_SRC_ALPHA; 142 case PIPE_BLENDFACTOR_INV_DST_ALPHA: 143 return BLEND_FUNC_ONE_MINUS_DST_ALPHA; 144 case PIPE_BLENDFACTOR_INV_DST_COLOR: 145 return BLEND_FUNC_ONE_MINUS_DST_COLOR; 146 case PIPE_BLENDFACTOR_INV_CONST_COLOR: 147 return BLEND_FUNC_ONE_MINUS_CONSTANT_COLOR; 148 case PIPE_BLENDFACTOR_INV_CONST_ALPHA: 149 return BLEND_FUNC_ONE_MINUS_CONSTANT_ALPHA; 150 case PIPE_BLENDFACTOR_SRC1_COLOR: 151 case PIPE_BLENDFACTOR_SRC1_ALPHA: 152 case PIPE_BLENDFACTOR_INV_SRC1_COLOR: 153 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: 154 default: 155 DBG("Unhandled blend factor: %i", blend_factor); 156 return ETNA_NO_MATCH; 157 } 158} 159 160static inline uint32_t 161translate_texture_wrapmode(unsigned wrap) 162{ 163 switch (wrap) { 164 case PIPE_TEX_WRAP_REPEAT: 165 return TEXTURE_WRAPMODE_REPEAT; 166 case PIPE_TEX_WRAP_CLAMP: 167 return TEXTURE_WRAPMODE_CLAMP_TO_EDGE; 168 case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 169 return TEXTURE_WRAPMODE_CLAMP_TO_EDGE; 170 case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 171 return TEXTURE_WRAPMODE_CLAMP_TO_EDGE; /* XXX */ 172 case PIPE_TEX_WRAP_MIRROR_REPEAT: 173 return TEXTURE_WRAPMODE_MIRRORED_REPEAT; 174 case PIPE_TEX_WRAP_MIRROR_CLAMP: 175 return TEXTURE_WRAPMODE_MIRRORED_REPEAT; /* XXX */ 176 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 177 return TEXTURE_WRAPMODE_MIRRORED_REPEAT; /* XXX */ 178 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 179 return TEXTURE_WRAPMODE_MIRRORED_REPEAT; /* XXX */ 180 default: 181 DBG("Unhandled texture wrapmode: %i", wrap); 182 return ETNA_NO_MATCH; 183 } 184} 185 186static inline uint32_t 187translate_texture_mipfilter(unsigned filter) 188{ 189 switch (filter) { 190 case PIPE_TEX_MIPFILTER_NEAREST: 191 return TEXTURE_FILTER_NEAREST; 192 case PIPE_TEX_MIPFILTER_LINEAR: 193 return TEXTURE_FILTER_LINEAR; 194 case PIPE_TEX_MIPFILTER_NONE: 195 return TEXTURE_FILTER_NONE; 196 default: 197 DBG("Unhandled texture mipfilter: %i", filter); 198 return ETNA_NO_MATCH; 199 } 200} 201 202static inline uint32_t 203translate_texture_filter(unsigned filter) 204{ 205 switch (filter) { 206 case PIPE_TEX_FILTER_NEAREST: 207 return TEXTURE_FILTER_NEAREST; 208 case PIPE_TEX_FILTER_LINEAR: 209 return TEXTURE_FILTER_LINEAR; 210 default: 211 DBG("Unhandled texture filter: %i", filter); 212 return ETNA_NO_MATCH; 213 } 214} 215 216static inline int 217translate_rb_src_dst_swap(enum pipe_format src, enum pipe_format dst) 218{ 219 return translate_pe_format_rb_swap(src) ^ translate_pe_format_rb_swap(dst); 220} 221 222static inline uint32_t 223translate_depth_format(enum pipe_format fmt) 224{ 225 /* Note: Pipe format convention is LSB to MSB, VIVS is MSB to LSB */ 226 switch (fmt) { 227 case PIPE_FORMAT_Z16_UNORM: 228 return VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D16; 229 case PIPE_FORMAT_X8Z24_UNORM: 230 return VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D24S8; 231 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 232 return VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D24S8; 233 default: 234 return ETNA_NO_MATCH; 235 } 236} 237 238/* render target format for MSAA */ 239static inline uint32_t 240translate_ts_format(enum pipe_format fmt) 241{ 242 /* Note: Pipe format convention is LSB to MSB, VIVS is MSB to LSB */ 243 switch (fmt) { 244 case PIPE_FORMAT_B4G4R4X4_UNORM: 245 case PIPE_FORMAT_B4G4R4A4_UNORM: 246 return COMPRESSION_FORMAT_A4R4G4B4; 247 case PIPE_FORMAT_B5G5R5X1_UNORM: 248 return COMPRESSION_FORMAT_A1R5G5B5; 249 case PIPE_FORMAT_B5G5R5A1_UNORM: 250 return COMPRESSION_FORMAT_A1R5G5B5; 251 case PIPE_FORMAT_B5G6R5_UNORM: 252 return COMPRESSION_FORMAT_R5G6B5; 253 case PIPE_FORMAT_B8G8R8X8_UNORM: 254 case PIPE_FORMAT_B8G8R8X8_SRGB: 255 case PIPE_FORMAT_R8G8B8X8_UNORM: 256 return COMPRESSION_FORMAT_X8R8G8B8; 257 case PIPE_FORMAT_B8G8R8A8_UNORM: 258 case PIPE_FORMAT_B8G8R8A8_SRGB: 259 case PIPE_FORMAT_R8G8B8A8_UNORM: 260 return COMPRESSION_FORMAT_A8R8G8B8; 261 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 262 return COMPRESSION_FORMAT_D24S8; 263 case PIPE_FORMAT_X8Z24_UNORM: 264 return COMPRESSION_FORMAT_D24X8; 265 case PIPE_FORMAT_Z16_UNORM: 266 return COMPRESSION_FORMAT_D16; 267 /* MSAA with YUYV not supported */ 268 default: 269 return ETNA_NO_MATCH; 270 } 271} 272 273/* Return normalization flag for vertex element format */ 274static inline uint32_t 275translate_vertex_format_normalize(enum pipe_format fmt) 276{ 277 const struct util_format_description *desc = util_format_description(fmt); 278 if (!desc) 279 return VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF; 280 281 /* assumes that normalization of channel 0 holds for all channels; 282 * this holds for all vertex formats that we support */ 283 return desc->channel[0].normalized 284 ? VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_SIGN_EXTEND 285 : VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF; 286} 287 288static inline uint32_t 289translate_output_mode(enum pipe_format fmt, bool halti5) 290{ 291 const unsigned bits = 292 util_format_get_component_bits(fmt, UTIL_FORMAT_COLORSPACE_RGB, 0); 293 294 if (bits == 32) 295 return COLOR_OUTPUT_MODE_UIF32; 296 297 if (!util_format_is_pure_integer(fmt)) 298 return COLOR_OUTPUT_MODE_NORMAL; 299 300 /* generic integer output mode pre-halti5 (?) */ 301 if (bits == 10 || !halti5) 302 return COLOR_OUTPUT_MODE_A2B10G10R10UI; 303 304 if (util_format_is_pure_sint(fmt)) 305 return bits == 8 ? COLOR_OUTPUT_MODE_I8 : COLOR_OUTPUT_MODE_I16; 306 307 return bits == 8 ? COLOR_OUTPUT_MODE_U8 : COLOR_OUTPUT_MODE_U16; 308} 309 310static inline uint32_t 311translate_index_size(unsigned index_size) 312{ 313 switch (index_size) { 314 case 1: 315 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_CHAR; 316 case 2: 317 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_SHORT; 318 case 4: 319 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_INT; 320 default: 321 DBG("Unhandled index size %i", index_size); 322 return ETNA_NO_MATCH; 323 } 324} 325 326static inline uint32_t 327translate_draw_mode(unsigned mode) 328{ 329 switch (mode) { 330 case PIPE_PRIM_POINTS: 331 return PRIMITIVE_TYPE_POINTS; 332 case PIPE_PRIM_LINES: 333 return PRIMITIVE_TYPE_LINES; 334 case PIPE_PRIM_LINE_LOOP: 335 return PRIMITIVE_TYPE_LINE_LOOP; 336 case PIPE_PRIM_LINE_STRIP: 337 return PRIMITIVE_TYPE_LINE_STRIP; 338 case PIPE_PRIM_TRIANGLES: 339 return PRIMITIVE_TYPE_TRIANGLES; 340 case PIPE_PRIM_TRIANGLE_STRIP: 341 return PRIMITIVE_TYPE_TRIANGLE_STRIP; 342 case PIPE_PRIM_TRIANGLE_FAN: 343 return PRIMITIVE_TYPE_TRIANGLE_FAN; 344 case PIPE_PRIM_QUADS: 345 return PRIMITIVE_TYPE_QUADS; 346 default: 347 DBG("Unhandled draw mode primitive %i", mode); 348 return ETNA_NO_MATCH; 349 } 350} 351 352/* Get size multiple for size of texture/rendertarget with a certain layout 353 * This is affected by many different parameters: 354 * - A horizontal multiple of 16 is used when possible as resolve can be used 355 * at the cost of only a little bit extra memory usage. 356 * - If the surface is to be used with the resolve engine, set rs_align true. 357 * If set, a horizontal multiple of 16 will be used for tiled and linear, 358 * otherwise one of 16. However, such a surface will be incompatible 359 * with the samplers if the GPU does hot support the HALIGN feature. 360 * - If the surface is supertiled, horizontal and vertical multiple is always 64 361 * - If the surface is multi tiled or supertiled, make sure that the vertical size 362 * is a multiple of the number of pixel pipes as well. 363 * */ 364static inline void 365etna_layout_multiple(unsigned layout, unsigned pixel_pipes, bool rs_align, 366 unsigned *paddingX, unsigned *paddingY, unsigned *halign) 367{ 368 switch (layout) { 369 case ETNA_LAYOUT_LINEAR: 370 *paddingX = rs_align ? 16 : 4; 371 *paddingY = 1; 372 *halign = rs_align ? TEXTURE_HALIGN_SIXTEEN : TEXTURE_HALIGN_FOUR; 373 break; 374 case ETNA_LAYOUT_TILED: 375 *paddingX = rs_align ? 16 : 4; 376 *paddingY = 4; 377 *halign = rs_align ? TEXTURE_HALIGN_SIXTEEN : TEXTURE_HALIGN_FOUR; 378 break; 379 case ETNA_LAYOUT_SUPER_TILED: 380 *paddingX = 64; 381 *paddingY = 64; 382 *halign = TEXTURE_HALIGN_SUPER_TILED; 383 break; 384 case ETNA_LAYOUT_MULTI_TILED: 385 *paddingX = 16; 386 *paddingY = 4 * pixel_pipes; 387 *halign = TEXTURE_HALIGN_SPLIT_TILED; 388 break; 389 case ETNA_LAYOUT_MULTI_SUPERTILED: 390 *paddingX = 64; 391 *paddingY = 64 * pixel_pipes; 392 *halign = TEXTURE_HALIGN_SPLIT_SUPER_TILED; 393 break; 394 default: 395 DBG("Unhandled layout %i", layout); 396 } 397} 398 399static inline uint32_t 400translate_clear_depth_stencil(enum pipe_format format, float depth, 401 unsigned stencil) 402{ 403 uint32_t clear_value = 0; 404 405 // XXX util_pack_color 406 switch (format) { 407 case PIPE_FORMAT_Z16_UNORM: 408 clear_value = etna_cfloat_to_uintN(depth, 16); 409 clear_value |= clear_value << 16; 410 break; 411 case PIPE_FORMAT_X8Z24_UNORM: 412 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 413 clear_value = (etna_cfloat_to_uintN(depth, 24) << 8) | (stencil & 0xFF); 414 break; 415 default: 416 DBG("Unhandled pipe format for depth stencil clear: %i", format); 417 } 418 return clear_value; 419} 420 421/* Convert MSAA number of samples to x and y scaling factor. 422 * Return true if supported and false otherwise. */ 423static inline bool 424translate_samples_to_xyscale(int num_samples, int *xscale_out, int *yscale_out) 425{ 426 int xscale, yscale; 427 428 switch (num_samples) { 429 case 0: 430 case 1: 431 xscale = 1; 432 yscale = 1; 433 break; 434 case 2: 435 xscale = 2; 436 yscale = 1; 437 break; 438 case 4: 439 xscale = 2; 440 yscale = 2; 441 break; 442 default: 443 return false; 444 } 445 446 if (xscale_out) 447 *xscale_out = xscale; 448 if (yscale_out) 449 *yscale_out = yscale; 450 451 return true; 452} 453 454static inline uint32_t 455translate_texture_target(unsigned target) 456{ 457 switch (target) { 458 case PIPE_TEXTURE_1D: 459 return TEXTURE_TYPE_1D; 460 case PIPE_TEXTURE_2D: 461 case PIPE_TEXTURE_RECT: 462 case PIPE_TEXTURE_1D_ARRAY: 463 return TEXTURE_TYPE_2D; 464 case PIPE_TEXTURE_CUBE: 465 return TEXTURE_TYPE_CUBE_MAP; 466 case PIPE_TEXTURE_3D: 467 case PIPE_TEXTURE_2D_ARRAY: 468 return TEXTURE_TYPE_3D; 469 default: 470 DBG("Unhandled texture target: %i", target); 471 return ETNA_NO_MATCH; 472 } 473} 474 475static inline uint32_t 476translate_texture_compare(enum pipe_compare_func compare_func) 477{ 478 switch (compare_func) { 479 case PIPE_FUNC_NEVER: 480 return TEXTURE_COMPARE_FUNC_NEVER; 481 case PIPE_FUNC_LESS: 482 return TEXTURE_COMPARE_FUNC_LESS; 483 case PIPE_FUNC_EQUAL: 484 return TEXTURE_COMPARE_FUNC_EQUAL; 485 case PIPE_FUNC_LEQUAL: 486 return TEXTURE_COMPARE_FUNC_LEQUAL; 487 case PIPE_FUNC_GREATER: 488 return TEXTURE_COMPARE_FUNC_GREATER; 489 case PIPE_FUNC_NOTEQUAL: 490 return TEXTURE_COMPARE_FUNC_NOTEQUAL; 491 case PIPE_FUNC_GEQUAL: 492 return TEXTURE_COMPARE_FUNC_GEQUAL; 493 case PIPE_FUNC_ALWAYS: 494 return TEXTURE_COMPARE_FUNC_ALWAYS; 495 default: 496 unreachable("Invalid compare func"); 497 } 498} 499 500#endif 501