summaryrefslogtreecommitdiffstats
path: root/src/intel/isl/isl.h
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2016-09-08 22:18:47 -0700
committerJason Ekstrand <[email protected]>2016-09-12 19:44:05 -0700
commitd038adca0eae173be0d2082f9b6d7e6d7c8aadf1 (patch)
tree0bc9dfe91cb9c40bf14e0eb2513725f719456eab /src/intel/isl/isl.h
parent883086500b130e4667108a52bca9f37defcd7564 (diff)
intel/isl: Add support for RGB formats in X and Y-tiled memory
Normally, using a non-linear tiling format helps improve cache locality by ensuring that neighboring pixels are usually close-by in memory. For RGB formats, this still sort-of holds, but it can also lead to rather terrible memory access patterns where a single RGB pixel value crosses a tile boundary and gets split into two pieces in different 4K pages. It also makes for some rather awkward calculations because your tile size is no longer an even multiple of surface element size. For these reasons, we chose to simply never create tiled RGB images in the Vulkan driver. The GL driver, however, is not so kind so we need to support it somehow. I briefly toyed with a couple of different schemes but this is the best one I could come up with. The fundamental problem is that a tile no longer contains an integer number of surface elements. I briefly considered a couple other options but found them wanting: 1) Using floats for the logical tile size. This leads to potential rounding error problems. 2) When presented with a RGB format, just make the tile 3-times as wide. This isn't so nice because now our tiles are no longer power-of-two size. Also, it can force the row_pitch to be larger than needed which, while not strictly a problem for ISL, causes incompatibility problems with the way the GL driver chooses surface pitches. The chosen method requires that you pay attention and not just assume that your tile_info is in the units you think it is. However, it's nice because it provides a nice "these are the units" declaration in isl_tile_info itself. Previously, the tile_info wasn't usable as a stand-alone structure because you had to also know the format. It also forces figuring out how to deal with inconsistencies between tiling and format back to the caller which is good because the two different consumers of isl_tile_info really want to deal with it differently: Computation of the surface size wants the fewest number of horizontal tiles possible while get_intratile_offset is far more concerned with things aligning nicely. Signed-off-by: Jason Ekstrand <[email protected]> Acked-by: Chad Versace <[email protected]>
Diffstat (limited to 'src/intel/isl/isl.h')
-rw-r--r--src/intel/isl/isl.h21
1 files changed, 20 insertions, 1 deletions
diff --git a/src/intel/isl/isl.h b/src/intel/isl/isl.h
index 3604fadb27e..d2f0e168495 100644
--- a/src/intel/isl/isl.h
+++ b/src/intel/isl/isl.h
@@ -728,7 +728,26 @@ struct isl_format_layout {
struct isl_tile_info {
enum isl_tiling tiling;
- /** The logical size of the tile in units of surface elements
+ /* The size (in bits per block) of a single surface element
+ *
+ * For surfaces with power-of-two formats, this is the same as
+ * isl_format_layout::bpb. For non-power-of-two formats it may be smaller.
+ * The logical_extent_el field is in terms of elements of this size.
+ *
+ * For example, consider ISL_FORMAT_R32G32B32_FLOAT for which
+ * isl_format_layout::bpb is 96 (a non-power-of-two). In this case, none
+ * of the tiling formats can actually hold an integer number of 96-bit
+ * surface elements so isl_tiling_get_info returns an isl_tile_info for a
+ * 32-bit element size. It is the responsibility of the caller to
+ * recognize that 32 != 96 ad adjust accordingly. For instance, to compute
+ * the width of a surface in tiles, you would do:
+ *
+ * width_tl = DIV_ROUND_UP(width_el * (format_bpb / tile_info.format_bpb),
+ * tile_info.logical_extent_el.width);
+ */
+ uint32_t format_bpb;
+
+ /** The logical size of the tile in units of format_bpb size elements
*
* This field determines how a given surface is cut up into tiles. It is
* used to compute the size of a surface in tiles and can be used to