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/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(unsigned blend) 118{ 119 switch (blend) { 120 case PIPE_BLEND_ADD: 121 return BLEND_EQ_ADD; 122 case PIPE_BLEND_SUBTRACT: 123 return BLEND_EQ_SUBTRACT; 124 case PIPE_BLEND_REVERSE_SUBTRACT: 125 return BLEND_EQ_REVERSE_SUBTRACT; 126 case PIPE_BLEND_MIN: 127 return BLEND_EQ_MIN; 128 case PIPE_BLEND_MAX: 129 return BLEND_EQ_MAX; 130 default: 131 DBG("Unhandled blend: %i", blend); 132 return ETNA_NO_MATCH; 133 } 134} 135 136static inline uint32_t 137translate_blend_factor(unsigned blend_factor) 138{ 139 switch (blend_factor) { 140 case PIPE_BLENDFACTOR_ONE: 141 return BLEND_FUNC_ONE; 142 case PIPE_BLENDFACTOR_SRC_COLOR: 143 return BLEND_FUNC_SRC_COLOR; 144 case PIPE_BLENDFACTOR_SRC_ALPHA: 145 return BLEND_FUNC_SRC_ALPHA; 146 case PIPE_BLENDFACTOR_DST_ALPHA: 147 return BLEND_FUNC_DST_ALPHA; 148 case PIPE_BLENDFACTOR_DST_COLOR: 149 return BLEND_FUNC_DST_COLOR; 150 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: 151 return BLEND_FUNC_SRC_ALPHA_SATURATE; 152 case PIPE_BLENDFACTOR_CONST_COLOR: 153 return BLEND_FUNC_CONSTANT_COLOR; 154 case PIPE_BLENDFACTOR_CONST_ALPHA: 155 return BLEND_FUNC_CONSTANT_ALPHA; 156 case PIPE_BLENDFACTOR_ZERO: 157 return BLEND_FUNC_ZERO; 158 case PIPE_BLENDFACTOR_INV_SRC_COLOR: 159 return BLEND_FUNC_ONE_MINUS_SRC_COLOR; 160 case PIPE_BLENDFACTOR_INV_SRC_ALPHA: 161 return BLEND_FUNC_ONE_MINUS_SRC_ALPHA; 162 case PIPE_BLENDFACTOR_INV_DST_ALPHA: 163 return BLEND_FUNC_ONE_MINUS_DST_ALPHA; 164 case PIPE_BLENDFACTOR_INV_DST_COLOR: 165 return BLEND_FUNC_ONE_MINUS_DST_COLOR; 166 case PIPE_BLENDFACTOR_INV_CONST_COLOR: 167 return BLEND_FUNC_ONE_MINUS_CONSTANT_COLOR; 168 case PIPE_BLENDFACTOR_INV_CONST_ALPHA: 169 return BLEND_FUNC_ONE_MINUS_CONSTANT_ALPHA; 170 case PIPE_BLENDFACTOR_SRC1_COLOR: 171 case PIPE_BLENDFACTOR_SRC1_ALPHA: 172 case PIPE_BLENDFACTOR_INV_SRC1_COLOR: 173 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: 174 default: 175 DBG("Unhandled blend factor: %i", blend_factor); 176 return ETNA_NO_MATCH; 177 } 178} 179 180static inline uint32_t 181translate_texture_wrapmode(unsigned wrap) 182{ 183 switch (wrap) { 184 case PIPE_TEX_WRAP_REPEAT: 185 return TEXTURE_WRAPMODE_REPEAT; 186 case PIPE_TEX_WRAP_CLAMP: 187 return TEXTURE_WRAPMODE_CLAMP_TO_EDGE; 188 case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 189 return TEXTURE_WRAPMODE_CLAMP_TO_EDGE; 190 case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 191 return TEXTURE_WRAPMODE_CLAMP_TO_EDGE; /* XXX */ 192 case PIPE_TEX_WRAP_MIRROR_REPEAT: 193 return TEXTURE_WRAPMODE_MIRRORED_REPEAT; 194 case PIPE_TEX_WRAP_MIRROR_CLAMP: 195 return TEXTURE_WRAPMODE_MIRRORED_REPEAT; /* XXX */ 196 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 197 return TEXTURE_WRAPMODE_MIRRORED_REPEAT; /* XXX */ 198 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 199 return TEXTURE_WRAPMODE_MIRRORED_REPEAT; /* XXX */ 200 default: 201 DBG("Unhandled texture wrapmode: %i", wrap); 202 return ETNA_NO_MATCH; 203 } 204} 205 206static inline uint32_t 207translate_texture_mipfilter(unsigned filter) 208{ 209 switch (filter) { 210 case PIPE_TEX_MIPFILTER_NEAREST: 211 return TEXTURE_FILTER_NEAREST; 212 case PIPE_TEX_MIPFILTER_LINEAR: 213 return TEXTURE_FILTER_LINEAR; 214 case PIPE_TEX_MIPFILTER_NONE: 215 return TEXTURE_FILTER_NONE; 216 default: 217 DBG("Unhandled texture mipfilter: %i", filter); 218 return ETNA_NO_MATCH; 219 } 220} 221 222static inline uint32_t 223translate_texture_filter(unsigned filter) 224{ 225 switch (filter) { 226 case PIPE_TEX_FILTER_NEAREST: 227 return TEXTURE_FILTER_NEAREST; 228 case PIPE_TEX_FILTER_LINEAR: 229 return TEXTURE_FILTER_LINEAR; 230 /* What about anisotropic? */ 231 default: 232 DBG("Unhandled texture filter: %i", filter); 233 return ETNA_NO_MATCH; 234 } 235} 236 237/* return a RS "compatible" format for use when copying */ 238static inline enum pipe_format 239etna_compatible_rs_format(enum pipe_format fmt) 240{ 241 /* YUYV and UYVY are blocksize 4, but 2 bytes per pixel */ 242 if (fmt == PIPE_FORMAT_YUYV || fmt == PIPE_FORMAT_UYVY) 243 return PIPE_FORMAT_B4G4R4A4_UNORM; 244 245 switch (util_format_get_blocksize(fmt)) { 246 case 2: 247 return PIPE_FORMAT_B4G4R4A4_UNORM; 248 case 4: 249 return PIPE_FORMAT_B8G8R8A8_UNORM; 250 default: 251 return fmt; 252 } 253} 254 255static inline int 256translate_rb_src_dst_swap(enum pipe_format src, enum pipe_format dst) 257{ 258 return translate_rs_format_rb_swap(src) ^ translate_rs_format_rb_swap(dst); 259} 260 261static inline uint32_t 262translate_depth_format(enum pipe_format fmt) 263{ 264 /* Note: Pipe format convention is LSB to MSB, VIVS is MSB to LSB */ 265 switch (fmt) { 266 case PIPE_FORMAT_Z16_UNORM: 267 return VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D16; 268 case PIPE_FORMAT_X8Z24_UNORM: 269 return VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D24S8; 270 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 271 return VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D24S8; 272 default: 273 return ETNA_NO_MATCH; 274 } 275} 276 277/* render target format for MSAA */ 278static inline uint32_t 279translate_msaa_format(enum pipe_format fmt) 280{ 281 /* Note: Pipe format convention is LSB to MSB, VIVS is MSB to LSB */ 282 switch (fmt) { 283 case PIPE_FORMAT_B4G4R4X4_UNORM: 284 return COLOR_COMPRESSION_FORMAT_A4R4G4B4; 285 case PIPE_FORMAT_B4G4R4A4_UNORM: 286 return COLOR_COMPRESSION_FORMAT_A4R4G4B4; 287 case PIPE_FORMAT_B5G5R5X1_UNORM: 288 return COLOR_COMPRESSION_FORMAT_A1R5G5B5; 289 case PIPE_FORMAT_B5G5R5A1_UNORM: 290 return COLOR_COMPRESSION_FORMAT_A1R5G5B5; 291 case PIPE_FORMAT_B5G6R5_UNORM: 292 return COLOR_COMPRESSION_FORMAT_R5G6B5; 293 case PIPE_FORMAT_B8G8R8X8_UNORM: 294 return COLOR_COMPRESSION_FORMAT_X8R8G8B8; 295 case PIPE_FORMAT_B8G8R8A8_UNORM: 296 return COLOR_COMPRESSION_FORMAT_A8R8G8B8; 297 /* MSAA with YUYV not supported */ 298 default: 299 return ETNA_NO_MATCH; 300 } 301} 302 303/* Return normalization flag for vertex element format */ 304static inline uint32_t 305translate_vertex_format_normalize(enum pipe_format fmt) 306{ 307 const struct util_format_description *desc = util_format_description(fmt); 308 if (!desc) 309 return VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF; 310 311 /* assumes that normalization of channel 0 holds for all channels; 312 * this holds for all vertex formats that we support */ 313 return desc->channel[0].normalized 314 ? VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_ON 315 : VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF; 316} 317 318static inline uint32_t 319translate_index_size(unsigned index_size) 320{ 321 switch (index_size) { 322 case 1: 323 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_CHAR; 324 case 2: 325 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_SHORT; 326 case 4: 327 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_INT; 328 default: 329 DBG("Unhandled index size %i", index_size); 330 return ETNA_NO_MATCH; 331 } 332} 333 334static inline uint32_t 335translate_draw_mode(unsigned mode) 336{ 337 switch (mode) { 338 case PIPE_PRIM_POINTS: 339 return PRIMITIVE_TYPE_POINTS; 340 case PIPE_PRIM_LINES: 341 return PRIMITIVE_TYPE_LINES; 342 case PIPE_PRIM_LINE_LOOP: 343 return PRIMITIVE_TYPE_LINE_LOOP; 344 case PIPE_PRIM_LINE_STRIP: 345 return PRIMITIVE_TYPE_LINE_STRIP; 346 case PIPE_PRIM_TRIANGLES: 347 return PRIMITIVE_TYPE_TRIANGLES; 348 case PIPE_PRIM_TRIANGLE_STRIP: 349 return PRIMITIVE_TYPE_TRIANGLE_STRIP; 350 case PIPE_PRIM_TRIANGLE_FAN: 351 return PRIMITIVE_TYPE_TRIANGLE_FAN; 352 case PIPE_PRIM_QUADS: 353 return PRIMITIVE_TYPE_QUADS; 354 default: 355 DBG("Unhandled draw mode primitive %i", mode); 356 return ETNA_NO_MATCH; 357 } 358} 359 360/* Get size multiple for size of texture/rendertarget with a certain layout 361 * This is affected by many different parameters: 362 * - A horizontal multiple of 16 is used when possible as resolve can be used 363 * at the cost of only a little bit extra memory usage. 364 * - If the surface is to be used with the resolve engine, set rs_align true. 365 * If set, a horizontal multiple of 16 will be used for tiled and linear, 366 * otherwise one of 16. However, such a surface will be incompatible 367 * with the samplers if the GPU does hot support the HALIGN feature. 368 * - If the surface is supertiled, horizontal and vertical multiple is always 64 369 * - If the surface is multi tiled or supertiled, make sure that the vertical size 370 * is a multiple of the number of pixel pipes as well. 371 * */ 372static inline void 373etna_layout_multiple(unsigned layout, unsigned pixel_pipes, bool rs_align, 374 unsigned *paddingX, unsigned *paddingY, unsigned *halign) 375{ 376 switch (layout) { 377 case ETNA_LAYOUT_LINEAR: 378 *paddingX = rs_align ? 16 : 4; 379 *paddingY = 1; 380 *halign = rs_align ? TEXTURE_HALIGN_SIXTEEN : TEXTURE_HALIGN_FOUR; 381 break; 382 case ETNA_LAYOUT_TILED: 383 *paddingX = rs_align ? 16 : 4; 384 *paddingY = 4; 385 *halign = rs_align ? TEXTURE_HALIGN_SIXTEEN : TEXTURE_HALIGN_FOUR; 386 break; 387 case ETNA_LAYOUT_SUPER_TILED: 388 *paddingX = 64; 389 *paddingY = 64; 390 *halign = TEXTURE_HALIGN_SUPER_TILED; 391 break; 392 case ETNA_LAYOUT_MULTI_TILED: 393 *paddingX = 16; 394 *paddingY = 4 * pixel_pipes; 395 *halign = TEXTURE_HALIGN_SPLIT_TILED; 396 break; 397 case ETNA_LAYOUT_MULTI_SUPERTILED: 398 *paddingX = 64; 399 *paddingY = 64 * pixel_pipes; 400 *halign = TEXTURE_HALIGN_SPLIT_SUPER_TILED; 401 break; 402 default: 403 DBG("Unhandled layout %i", layout); 404 } 405} 406 407static inline void etna_adjust_rs_align(unsigned num_pixelpipes, 408 unsigned *paddingX, unsigned *paddingY) 409{ 410 unsigned alignX = ETNA_RS_WIDTH_MASK + 1; 411 unsigned alignY = (ETNA_RS_HEIGHT_MASK + 1) * num_pixelpipes; 412 413 if (paddingX) 414 *paddingX = align(*paddingX, alignX); 415 if (paddingY) 416 *paddingY = align(*paddingY, alignY); 417} 418 419static inline uint32_t 420translate_clear_depth_stencil(enum pipe_format format, float depth, 421 unsigned stencil) 422{ 423 uint32_t clear_value = 0; 424 425 // XXX util_pack_color 426 switch (format) { 427 case PIPE_FORMAT_Z16_UNORM: 428 clear_value = etna_cfloat_to_uintN(depth, 16); 429 clear_value |= clear_value << 16; 430 break; 431 case PIPE_FORMAT_X8Z24_UNORM: 432 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 433 clear_value = (etna_cfloat_to_uintN(depth, 24) << 8) | (stencil & 0xFF); 434 break; 435 default: 436 DBG("Unhandled pipe format for depth stencil clear: %i", format); 437 } 438 return clear_value; 439} 440 441/* Convert MSAA number of samples to x and y scaling factor and 442 * VIVS_GL_MULTI_SAMPLE_CONFIG value. 443 * Return true if supported and false otherwise. */ 444static inline bool 445translate_samples_to_xyscale(int num_samples, int *xscale_out, int *yscale_out, 446 uint32_t *config_out) 447{ 448 int xscale, yscale; 449 uint32_t config; 450 451 switch (num_samples) { 452 case 0: 453 case 1: 454 xscale = 1; 455 yscale = 1; 456 config = VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_NONE; 457 break; 458 case 2: 459 xscale = 2; 460 yscale = 1; 461 config = VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_2X; 462 break; 463 case 4: 464 xscale = 2; 465 yscale = 2; 466 config = VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_4X; 467 break; 468 default: 469 return false; 470 } 471 472 if (xscale_out) 473 *xscale_out = xscale; 474 if (yscale_out) 475 *yscale_out = yscale; 476 if (config_out) 477 *config_out = config; 478 479 return true; 480} 481 482#endif 483