blob: 35337a5e72629017481c3f56f3aa943e5c4b1c70 [file] [log] [blame]
Chia-I Wu4bc47012014-08-14 13:03:25 +08001/*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
26 */
27
Chia-I Wu8a8d8b62014-08-14 13:26:26 +080028#ifndef LAYOUT_H
29#define LAYOUT_H
Chia-I Wu4bc47012014-08-14 13:03:25 +080030
Chia-I Wu8a8d8b62014-08-14 13:26:26 +080031#include "kmd/winsys.h"
32#include "intel.h"
Chia-I Wu4bc47012014-08-14 13:03:25 +080033
Chia-I Wu8a8d8b62014-08-14 13:26:26 +080034#define INTEL_IMG_MAX_LEVELS 16
Chia-I Wu4bc47012014-08-14 13:03:25 +080035
Chia-I Wu8a8d8b62014-08-14 13:26:26 +080036enum intel_layout_aux_type {
37 INTEL_LAYOUT_AUX_NONE,
38 INTEL_LAYOUT_AUX_HIZ,
39 INTEL_LAYOUT_AUX_MCS,
Chia-I Wu4bc47012014-08-14 13:03:25 +080040};
41
42/**
43 * Texture layout.
44 */
Chia-I Wu8a8d8b62014-08-14 13:26:26 +080045struct intel_layout {
46 enum intel_layout_aux_type aux_type;
47 XGL_FORMAT format;
Chia-I Wu4bc47012014-08-14 13:03:25 +080048 bool separate_stencil;
49
50 /*
51 * width, height, and size of pixel blocks, for conversion between 2D
52 * coordinates and memory offsets
53 */
54 unsigned block_width;
55 unsigned block_height;
56 unsigned block_size;
57
58 /* arrangements of samples and array layers */
59 bool interleaved_samples;
60 bool full_layers;
61 bool is_2d;
62
63 /* bitmask of valid tiling modes */
64 unsigned valid_tilings;
65 enum intel_tiling_mode tiling;
66
67 /* mipmap alignments */
68 unsigned align_i;
69 unsigned align_j;
70
71 struct {
72 /* physical position of a mipmap */
73 unsigned x;
74 unsigned y;
75
76 /*
77 * Physical size of a mipmap slice. For 3D textures, there may be
78 * multiple slices.
79 */
80 unsigned slice_width;
81 unsigned slice_height;
Chia-I Wu8a8d8b62014-08-14 13:26:26 +080082 } levels[INTEL_IMG_MAX_LEVELS];
Chia-I Wu4bc47012014-08-14 13:03:25 +080083
84 /* physical height of array layers, cube faces, or sample layers */
85 unsigned layer_height;
86
87 /* distance in bytes between two pixel block rows */
88 unsigned bo_stride;
89 /* number of pixel block rows */
90 unsigned bo_height;
91
92 unsigned aux_stride;
93 unsigned aux_height;
94};
95
Chia-I Wu8a8d8b62014-08-14 13:26:26 +080096void intel_layout_init(struct intel_layout *layout,
97 const struct intel_dev *dev,
98 const XGL_IMAGE_CREATE_INFO *info);
Chia-I Wu4bc47012014-08-14 13:03:25 +080099
100bool
Chia-I Wu8a8d8b62014-08-14 13:26:26 +0800101intel_layout_update_for_imported_bo(struct intel_layout *layout,
102 enum intel_tiling_mode tiling,
103 unsigned bo_stride);
Chia-I Wu4bc47012014-08-14 13:03:25 +0800104
105/**
106 * Convert from pixel position to memory position.
107 */
108static inline void
Chia-I Wu8a8d8b62014-08-14 13:26:26 +0800109intel_layout_pos_to_mem(const struct intel_layout *layout,
110 unsigned x, unsigned y,
111 unsigned *mem_x, unsigned *mem_y)
Chia-I Wu4bc47012014-08-14 13:03:25 +0800112{
113 assert(x % layout->block_width == 0);
114 assert(y % layout->block_height == 0);
115
116 *mem_x = x / layout->block_width * layout->block_size;
117 *mem_y = y / layout->block_height;
118}
119
120/**
121 * Convert from memory position to memory offset.
122 */
123static inline unsigned
Chia-I Wu8a8d8b62014-08-14 13:26:26 +0800124intel_layout_mem_to_off(const struct intel_layout *layout,
125 unsigned mem_x, unsigned mem_y)
Chia-I Wu4bc47012014-08-14 13:03:25 +0800126{
127 return mem_y * layout->bo_stride + mem_x;
128}
129
130/**
131 * Return the stride, in bytes, between slices within a level.
132 */
133static inline unsigned
Chia-I Wu8a8d8b62014-08-14 13:26:26 +0800134intel_layout_get_slice_stride(const struct intel_layout *layout,
135 unsigned level)
Chia-I Wu4bc47012014-08-14 13:03:25 +0800136{
137 unsigned y;
138
139 if (layout->is_2d) {
140 y = layout->layer_height;
141 } else if (level == 0) {
142 y = layout->levels[0].slice_height;
143 } else {
144 assert(!"no single slice stride for 3D texture with level > 0");
145 y = 0;
146 }
147
148 assert(y % layout->block_height == 0);
149
150 return (y / layout->block_height) * layout->bo_stride;
151}
152
153/**
154 * Return the physical size, in bytes, of a slice in a level.
155 */
156static inline unsigned
Chia-I Wu8a8d8b62014-08-14 13:26:26 +0800157intel_layout_get_slice_size(const struct intel_layout *layout, unsigned level)
Chia-I Wu4bc47012014-08-14 13:03:25 +0800158{
159 const unsigned w = layout->levels[level].slice_width;
160 const unsigned h = layout->levels[level].slice_height;
161
162 assert(w % layout->block_width == 0);
163 assert(h % layout->block_height == 0);
164
165 return (w / layout->block_width * layout->block_size) *
166 (h / layout->block_height);
167}
168
169/**
170 * Return the pixel position of a slice.
171 */
172static inline void
Chia-I Wu8a8d8b62014-08-14 13:26:26 +0800173intel_layout_get_slice_pos(const struct intel_layout *layout,
174 unsigned level, unsigned slice,
175 unsigned *x, unsigned *y)
Chia-I Wu4bc47012014-08-14 13:03:25 +0800176{
177 if (layout->is_2d) {
178 *x = layout->levels[level].x;
179 *y = layout->levels[level].y + layout->layer_height * slice;
180 } else {
181 const unsigned sx = slice & ((1 << level) - 1);
182 const unsigned sy = slice >> level;
183
184 *x = layout->levels[level].x + layout->levels[level].slice_width * sx;
185 *y = layout->levels[level].y + layout->levels[level].slice_height * sy;
186
187 /* should not overlap with the next level */
Chia-I Wu8a8d8b62014-08-14 13:26:26 +0800188 if (level + 1 < ARRAY_SIZE(layout->levels) &&
189 layout->levels[level + 1].y) {
Chia-I Wu4bc47012014-08-14 13:03:25 +0800190 assert(*y + layout->levels[level].slice_height <=
191 layout->levels[level + 1].y);
192 }
193 }
194
195 /* should not exceed the bo size */
196 assert(*y + layout->levels[level].slice_height <=
197 layout->bo_height * layout->block_height);
198}
199
Chia-I Wu8a8d8b62014-08-14 13:26:26 +0800200#endif /* LAYOUT_H */