.. | .. |
---|
131 | 131 | SVGA3DBLOCKDESC_BC3 = 1 << 26, |
---|
132 | 132 | SVGA3DBLOCKDESC_BC4 = 1 << 27, |
---|
133 | 133 | SVGA3DBLOCKDESC_BC5 = 1 << 28, |
---|
| 134 | + SVGA3DBLOCKDESC_BC6H = 1 << 29, |
---|
| 135 | + SVGA3DBLOCKDESC_BC7 = 1 << 30, |
---|
134 | 136 | |
---|
135 | 137 | SVGA3DBLOCKDESC_A_UINT = SVGA3DBLOCKDESC_ALPHA | |
---|
136 | 138 | SVGA3DBLOCKDESC_UINT | |
---|
.. | .. |
---|
290 | 292 | SVGA3DBLOCKDESC_COMP_UNORM, |
---|
291 | 293 | SVGA3DBLOCKDESC_BC5_COMP_SNORM = SVGA3DBLOCKDESC_BC5 | |
---|
292 | 294 | SVGA3DBLOCKDESC_COMP_SNORM, |
---|
| 295 | + SVGA3DBLOCKDESC_BC6H_COMP_TYPELESS = SVGA3DBLOCKDESC_BC6H | |
---|
| 296 | + SVGA3DBLOCKDESC_COMP_TYPELESS, |
---|
| 297 | + SVGA3DBLOCKDESC_BC6H_COMP_UF16 = SVGA3DBLOCKDESC_BC6H | |
---|
| 298 | + SVGA3DBLOCKDESC_COMPRESSED, |
---|
| 299 | + SVGA3DBLOCKDESC_BC6H_COMP_SF16 = SVGA3DBLOCKDESC_BC6H | |
---|
| 300 | + SVGA3DBLOCKDESC_COMPRESSED, |
---|
| 301 | + SVGA3DBLOCKDESC_BC7_COMP_TYPELESS = SVGA3DBLOCKDESC_BC7 | |
---|
| 302 | + SVGA3DBLOCKDESC_COMP_TYPELESS, |
---|
| 303 | + SVGA3DBLOCKDESC_BC7_COMP_UNORM = SVGA3DBLOCKDESC_BC7 | |
---|
| 304 | + SVGA3DBLOCKDESC_COMP_UNORM, |
---|
| 305 | + SVGA3DBLOCKDESC_BC7_COMP_UNORM_SRGB = SVGA3DBLOCKDESC_BC7_COMP_UNORM | |
---|
| 306 | + SVGA3DBLOCKDESC_SRGB, |
---|
293 | 307 | |
---|
294 | 308 | SVGA3DBLOCKDESC_NV12 = SVGA3DBLOCKDESC_YUV_VIDEO | |
---|
295 | 309 | SVGA3DBLOCKDESC_PLANAR_YUV | |
---|
.. | .. |
---|
494 | 508 | {{8}, {8}, {8}, {0}}, |
---|
495 | 509 | {{16}, {8}, {0}, {0}}}, |
---|
496 | 510 | |
---|
497 | | - {SVGA3D_FORMAT_DEAD1, SVGA3DBLOCKDESC_UVL, |
---|
| 511 | + {SVGA3D_FORMAT_DEAD1, SVGA3DBLOCKDESC_NONE, |
---|
498 | 512 | {1, 1, 1}, 3, 3, |
---|
499 | 513 | {{8}, {8}, {8}, {0}}, |
---|
500 | 514 | {{16}, {8}, {0}, {0}}}, |
---|
.. | .. |
---|
604 | 618 | {{0}, {0}, {48}, {0}}, |
---|
605 | 619 | {{0}, {0}, {0}, {0}}}, |
---|
606 | 620 | |
---|
607 | | - {SVGA3D_AYUV, SVGA3DBLOCKDESC_AYUV, |
---|
| 621 | + {SVGA3D_FORMAT_DEAD2, SVGA3DBLOCKDESC_NONE, |
---|
608 | 622 | {1, 1, 1}, 4, 4, |
---|
609 | 623 | {{8}, {8}, {8}, {8}}, |
---|
610 | 624 | {{0}, {8}, {16}, {24}}}, |
---|
.. | .. |
---|
1103 | 1117 | {4, 4, 1}, 16, 16, |
---|
1104 | 1118 | {{0}, {0}, {128}, {0}}, |
---|
1105 | 1119 | {{0}, {0}, {0}, {0}}}, |
---|
| 1120 | + |
---|
| 1121 | + {SVGA3D_B4G4R4A4_UNORM, SVGA3DBLOCKDESC_RGBA_UNORM, |
---|
| 1122 | + {1, 1, 1}, 2, 2, |
---|
| 1123 | + {{4}, {4}, {4}, {4}}, |
---|
| 1124 | + {{0}, {4}, {8}, {12}}}, |
---|
| 1125 | + |
---|
| 1126 | + {SVGA3D_BC6H_TYPELESS, SVGA3DBLOCKDESC_BC6H_COMP_TYPELESS, |
---|
| 1127 | + {4, 4, 1}, 16, 16, |
---|
| 1128 | + {{0}, {0}, {128}, {0}}, |
---|
| 1129 | + {{0}, {0}, {0}, {0}}}, |
---|
| 1130 | + |
---|
| 1131 | + {SVGA3D_BC6H_UF16, SVGA3DBLOCKDESC_BC6H_COMP_UF16, |
---|
| 1132 | + {4, 4, 1}, 16, 16, |
---|
| 1133 | + {{0}, {0}, {128}, {0}}, |
---|
| 1134 | + {{0}, {0}, {0}, {0}}}, |
---|
| 1135 | + |
---|
| 1136 | + {SVGA3D_BC6H_SF16, SVGA3DBLOCKDESC_BC6H_COMP_SF16, |
---|
| 1137 | + {4, 4, 1}, 16, 16, |
---|
| 1138 | + {{0}, {0}, {128}, {0}}, |
---|
| 1139 | + {{0}, {0}, {0}, {0}}}, |
---|
| 1140 | + |
---|
| 1141 | + {SVGA3D_BC7_TYPELESS, SVGA3DBLOCKDESC_BC7_COMP_TYPELESS, |
---|
| 1142 | + {4, 4, 1}, 16, 16, |
---|
| 1143 | + {{0}, {0}, {128}, {0}}, |
---|
| 1144 | + {{0}, {0}, {0}, {0}}}, |
---|
| 1145 | + |
---|
| 1146 | + {SVGA3D_BC7_UNORM, SVGA3DBLOCKDESC_BC7_COMP_UNORM, |
---|
| 1147 | + {4, 4, 1}, 16, 16, |
---|
| 1148 | + {{0}, {0}, {128}, {0}}, |
---|
| 1149 | + {{0}, {0}, {0}, {0}}}, |
---|
| 1150 | + |
---|
| 1151 | + {SVGA3D_BC7_UNORM_SRGB, SVGA3DBLOCKDESC_BC7_COMP_UNORM_SRGB, |
---|
| 1152 | + {4, 4, 1}, 16, 16, |
---|
| 1153 | + {{0}, {0}, {128}, {0}}, |
---|
| 1154 | + {{0}, {0}, {0}, {0}}}, |
---|
| 1155 | + |
---|
| 1156 | + {SVGA3D_AYUV, SVGA3DBLOCKDESC_AYUV, |
---|
| 1157 | + {1, 1, 1}, 4, 4, |
---|
| 1158 | + {{8}, {8}, {8}, {8}}, |
---|
| 1159 | + {{0}, {8}, {16}, {24}}}, |
---|
1106 | 1160 | }; |
---|
1107 | 1161 | |
---|
1108 | 1162 | static inline u32 clamped_umul32(u32 a, u32 b) |
---|
.. | .. |
---|
1280 | 1334 | return offset; |
---|
1281 | 1335 | } |
---|
1282 | 1336 | |
---|
1283 | | - |
---|
1284 | 1337 | static inline u32 |
---|
1285 | 1338 | svga3dsurface_get_image_offset(SVGA3dSurfaceFormat format, |
---|
1286 | 1339 | surf_size_struct baseLevelSize, |
---|
.. | .. |
---|
1375 | 1428 | return svga3dsurface_is_dx_screen_target_format(format); |
---|
1376 | 1429 | } |
---|
1377 | 1430 | |
---|
| 1431 | +/** |
---|
| 1432 | + * struct svga3dsurface_mip - Mimpmap level information |
---|
| 1433 | + * @bytes: Bytes required in the backing store of this mipmap level. |
---|
| 1434 | + * @img_stride: Byte stride per image. |
---|
| 1435 | + * @row_stride: Byte stride per block row. |
---|
| 1436 | + * @size: The size of the mipmap. |
---|
| 1437 | + */ |
---|
| 1438 | +struct svga3dsurface_mip { |
---|
| 1439 | + size_t bytes; |
---|
| 1440 | + size_t img_stride; |
---|
| 1441 | + size_t row_stride; |
---|
| 1442 | + struct drm_vmw_size size; |
---|
| 1443 | + |
---|
| 1444 | +}; |
---|
| 1445 | + |
---|
| 1446 | +/** |
---|
| 1447 | + * struct svga3dsurface_cache - Cached surface information |
---|
| 1448 | + * @desc: Pointer to the surface descriptor |
---|
| 1449 | + * @mip: Array of mipmap level information. Valid size is @num_mip_levels. |
---|
| 1450 | + * @mip_chain_bytes: Bytes required in the backing store for the whole chain |
---|
| 1451 | + * of mip levels. |
---|
| 1452 | + * @sheet_bytes: Bytes required in the backing store for a sheet |
---|
| 1453 | + * representing a single sample. |
---|
| 1454 | + * @num_mip_levels: Valid size of the @mip array. Number of mipmap levels in |
---|
| 1455 | + * a chain. |
---|
| 1456 | + * @num_layers: Number of slices in an array texture or number of faces in |
---|
| 1457 | + * a cubemap texture. |
---|
| 1458 | + */ |
---|
| 1459 | +struct svga3dsurface_cache { |
---|
| 1460 | + const struct svga3d_surface_desc *desc; |
---|
| 1461 | + struct svga3dsurface_mip mip[DRM_VMW_MAX_MIP_LEVELS]; |
---|
| 1462 | + size_t mip_chain_bytes; |
---|
| 1463 | + size_t sheet_bytes; |
---|
| 1464 | + u32 num_mip_levels; |
---|
| 1465 | + u32 num_layers; |
---|
| 1466 | +}; |
---|
| 1467 | + |
---|
| 1468 | +/** |
---|
| 1469 | + * struct svga3dsurface_loc - Surface location |
---|
| 1470 | + * @sheet: The multisample sheet. |
---|
| 1471 | + * @sub_resource: Surface subresource. Defined as layer * num_mip_levels + |
---|
| 1472 | + * mip_level. |
---|
| 1473 | + * @x: X coordinate. |
---|
| 1474 | + * @y: Y coordinate. |
---|
| 1475 | + * @z: Z coordinate. |
---|
| 1476 | + */ |
---|
| 1477 | +struct svga3dsurface_loc { |
---|
| 1478 | + u32 sheet; |
---|
| 1479 | + u32 sub_resource; |
---|
| 1480 | + u32 x, y, z; |
---|
| 1481 | +}; |
---|
| 1482 | + |
---|
| 1483 | +/** |
---|
| 1484 | + * svga3dsurface_subres - Compute the subresource from layer and mipmap. |
---|
| 1485 | + * @cache: Surface layout data. |
---|
| 1486 | + * @mip_level: The mipmap level. |
---|
| 1487 | + * @layer: The surface layer (face or array slice). |
---|
| 1488 | + * |
---|
| 1489 | + * Return: The subresource. |
---|
| 1490 | + */ |
---|
| 1491 | +static inline u32 svga3dsurface_subres(const struct svga3dsurface_cache *cache, |
---|
| 1492 | + u32 mip_level, u32 layer) |
---|
| 1493 | +{ |
---|
| 1494 | + return cache->num_mip_levels * layer + mip_level; |
---|
| 1495 | +} |
---|
| 1496 | + |
---|
| 1497 | +/** |
---|
| 1498 | + * svga3dsurface_setup_cache - Build a surface cache entry |
---|
| 1499 | + * @size: The surface base level dimensions. |
---|
| 1500 | + * @format: The surface format. |
---|
| 1501 | + * @num_mip_levels: Number of mipmap levels. |
---|
| 1502 | + * @num_layers: Number of layers. |
---|
| 1503 | + * @cache: Pointer to a struct svga3dsurface_cach object to be filled in. |
---|
| 1504 | + * |
---|
| 1505 | + * Return: Zero on success, -EINVAL on invalid surface layout. |
---|
| 1506 | + */ |
---|
| 1507 | +static inline int svga3dsurface_setup_cache(const struct drm_vmw_size *size, |
---|
| 1508 | + SVGA3dSurfaceFormat format, |
---|
| 1509 | + u32 num_mip_levels, |
---|
| 1510 | + u32 num_layers, |
---|
| 1511 | + u32 num_samples, |
---|
| 1512 | + struct svga3dsurface_cache *cache) |
---|
| 1513 | +{ |
---|
| 1514 | + const struct svga3d_surface_desc *desc; |
---|
| 1515 | + u32 i; |
---|
| 1516 | + |
---|
| 1517 | + memset(cache, 0, sizeof(*cache)); |
---|
| 1518 | + cache->desc = desc = svga3dsurface_get_desc(format); |
---|
| 1519 | + cache->num_mip_levels = num_mip_levels; |
---|
| 1520 | + cache->num_layers = num_layers; |
---|
| 1521 | + for (i = 0; i < cache->num_mip_levels; i++) { |
---|
| 1522 | + struct svga3dsurface_mip *mip = &cache->mip[i]; |
---|
| 1523 | + |
---|
| 1524 | + mip->size = svga3dsurface_get_mip_size(*size, i); |
---|
| 1525 | + mip->bytes = svga3dsurface_get_image_buffer_size |
---|
| 1526 | + (desc, &mip->size, 0); |
---|
| 1527 | + mip->row_stride = |
---|
| 1528 | + __KERNEL_DIV_ROUND_UP(mip->size.width, |
---|
| 1529 | + desc->block_size.width) * |
---|
| 1530 | + desc->bytes_per_block * num_samples; |
---|
| 1531 | + if (!mip->row_stride) |
---|
| 1532 | + goto invalid_dim; |
---|
| 1533 | + |
---|
| 1534 | + mip->img_stride = |
---|
| 1535 | + __KERNEL_DIV_ROUND_UP(mip->size.height, |
---|
| 1536 | + desc->block_size.height) * |
---|
| 1537 | + mip->row_stride; |
---|
| 1538 | + if (!mip->img_stride) |
---|
| 1539 | + goto invalid_dim; |
---|
| 1540 | + |
---|
| 1541 | + cache->mip_chain_bytes += mip->bytes; |
---|
| 1542 | + } |
---|
| 1543 | + cache->sheet_bytes = cache->mip_chain_bytes * num_layers; |
---|
| 1544 | + if (!cache->sheet_bytes) |
---|
| 1545 | + goto invalid_dim; |
---|
| 1546 | + |
---|
| 1547 | + return 0; |
---|
| 1548 | + |
---|
| 1549 | +invalid_dim: |
---|
| 1550 | + VMW_DEBUG_USER("Invalid surface layout for dirty tracking.\n"); |
---|
| 1551 | + return -EINVAL; |
---|
| 1552 | +} |
---|
| 1553 | + |
---|
| 1554 | +/** |
---|
| 1555 | + * svga3dsurface_get_loc - Get a surface location from an offset into the |
---|
| 1556 | + * backing store |
---|
| 1557 | + * @cache: Surface layout data. |
---|
| 1558 | + * @loc: Pointer to a struct svga3dsurface_loc to be filled in. |
---|
| 1559 | + * @offset: Offset into the surface backing store. |
---|
| 1560 | + */ |
---|
| 1561 | +static inline void |
---|
| 1562 | +svga3dsurface_get_loc(const struct svga3dsurface_cache *cache, |
---|
| 1563 | + struct svga3dsurface_loc *loc, |
---|
| 1564 | + size_t offset) |
---|
| 1565 | +{ |
---|
| 1566 | + const struct svga3dsurface_mip *mip = &cache->mip[0]; |
---|
| 1567 | + const struct svga3d_surface_desc *desc = cache->desc; |
---|
| 1568 | + u32 layer; |
---|
| 1569 | + int i; |
---|
| 1570 | + |
---|
| 1571 | + loc->sheet = offset / cache->sheet_bytes; |
---|
| 1572 | + offset -= loc->sheet * cache->sheet_bytes; |
---|
| 1573 | + |
---|
| 1574 | + layer = offset / cache->mip_chain_bytes; |
---|
| 1575 | + offset -= layer * cache->mip_chain_bytes; |
---|
| 1576 | + for (i = 0; i < cache->num_mip_levels; ++i, ++mip) { |
---|
| 1577 | + if (mip->bytes > offset) |
---|
| 1578 | + break; |
---|
| 1579 | + offset -= mip->bytes; |
---|
| 1580 | + } |
---|
| 1581 | + |
---|
| 1582 | + loc->sub_resource = svga3dsurface_subres(cache, i, layer); |
---|
| 1583 | + loc->z = offset / mip->img_stride; |
---|
| 1584 | + offset -= loc->z * mip->img_stride; |
---|
| 1585 | + loc->z *= desc->block_size.depth; |
---|
| 1586 | + loc->y = offset / mip->row_stride; |
---|
| 1587 | + offset -= loc->y * mip->row_stride; |
---|
| 1588 | + loc->y *= desc->block_size.height; |
---|
| 1589 | + loc->x = offset / desc->bytes_per_block; |
---|
| 1590 | + loc->x *= desc->block_size.width; |
---|
| 1591 | +} |
---|
| 1592 | + |
---|
| 1593 | +/** |
---|
| 1594 | + * svga3dsurface_inc_loc - Clamp increment a surface location with one block |
---|
| 1595 | + * size |
---|
| 1596 | + * in each dimension. |
---|
| 1597 | + * @loc: Pointer to a struct svga3dsurface_loc to be incremented. |
---|
| 1598 | + * |
---|
| 1599 | + * When computing the size of a range as size = end - start, the range does not |
---|
| 1600 | + * include the end element. However a location representing the last byte |
---|
| 1601 | + * of a touched region in the backing store *is* included in the range. |
---|
| 1602 | + * This function modifies such a location to match the end definition |
---|
| 1603 | + * given as start + size which is the one used in a SVGA3dBox. |
---|
| 1604 | + */ |
---|
| 1605 | +static inline void |
---|
| 1606 | +svga3dsurface_inc_loc(const struct svga3dsurface_cache *cache, |
---|
| 1607 | + struct svga3dsurface_loc *loc) |
---|
| 1608 | +{ |
---|
| 1609 | + const struct svga3d_surface_desc *desc = cache->desc; |
---|
| 1610 | + u32 mip = loc->sub_resource % cache->num_mip_levels; |
---|
| 1611 | + const struct drm_vmw_size *size = &cache->mip[mip].size; |
---|
| 1612 | + |
---|
| 1613 | + loc->sub_resource++; |
---|
| 1614 | + loc->x += desc->block_size.width; |
---|
| 1615 | + if (loc->x > size->width) |
---|
| 1616 | + loc->x = size->width; |
---|
| 1617 | + loc->y += desc->block_size.height; |
---|
| 1618 | + if (loc->y > size->height) |
---|
| 1619 | + loc->y = size->height; |
---|
| 1620 | + loc->z += desc->block_size.depth; |
---|
| 1621 | + if (loc->z > size->depth) |
---|
| 1622 | + loc->z = size->depth; |
---|
| 1623 | +} |
---|
| 1624 | + |
---|
| 1625 | +/** |
---|
| 1626 | + * svga3dsurface_min_loc - The start location in a subresource |
---|
| 1627 | + * @cache: Surface layout data. |
---|
| 1628 | + * @sub_resource: The subresource. |
---|
| 1629 | + * @loc: Pointer to a struct svga3dsurface_loc to be filled in. |
---|
| 1630 | + */ |
---|
| 1631 | +static inline void |
---|
| 1632 | +svga3dsurface_min_loc(const struct svga3dsurface_cache *cache, |
---|
| 1633 | + u32 sub_resource, |
---|
| 1634 | + struct svga3dsurface_loc *loc) |
---|
| 1635 | +{ |
---|
| 1636 | + loc->sheet = 0; |
---|
| 1637 | + loc->sub_resource = sub_resource; |
---|
| 1638 | + loc->x = loc->y = loc->z = 0; |
---|
| 1639 | +} |
---|
| 1640 | + |
---|
| 1641 | +/** |
---|
| 1642 | + * svga3dsurface_min_loc - The end location in a subresource |
---|
| 1643 | + * @cache: Surface layout data. |
---|
| 1644 | + * @sub_resource: The subresource. |
---|
| 1645 | + * @loc: Pointer to a struct svga3dsurface_loc to be filled in. |
---|
| 1646 | + * |
---|
| 1647 | + * Following the end definition given in svga3dsurface_inc_loc(), |
---|
| 1648 | + * Compute the end location of a surface subresource. |
---|
| 1649 | + */ |
---|
| 1650 | +static inline void |
---|
| 1651 | +svga3dsurface_max_loc(const struct svga3dsurface_cache *cache, |
---|
| 1652 | + u32 sub_resource, |
---|
| 1653 | + struct svga3dsurface_loc *loc) |
---|
| 1654 | +{ |
---|
| 1655 | + const struct drm_vmw_size *size; |
---|
| 1656 | + u32 mip; |
---|
| 1657 | + |
---|
| 1658 | + loc->sheet = 0; |
---|
| 1659 | + loc->sub_resource = sub_resource + 1; |
---|
| 1660 | + mip = sub_resource % cache->num_mip_levels; |
---|
| 1661 | + size = &cache->mip[mip].size; |
---|
| 1662 | + loc->x = size->width; |
---|
| 1663 | + loc->y = size->height; |
---|
| 1664 | + loc->z = size->depth; |
---|
| 1665 | +} |
---|
| 1666 | + |
---|
1378 | 1667 | #endif /* _SVGA3D_SURFACEDEFS_H_ */ |
---|