2 * Mesa 3-D graphics library
4 * Copyright (C) 2014 LunarG, Inc.
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:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
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.
25 * Chia-I Wu <olv@lunarg.com>
31 #include "genhw/genhw.h"
32 #include "intel_winsys.h"
37 enum ilo_image_aux_type
{
43 enum ilo_image_walk_type
{
45 * LODs of each array layer are first packed together in MIPLAYOUT_BELOW.
46 * Array layers are then stacked together vertically.
48 * This can be used for mipmapped 2D textures.
53 * Array layers of each LOD are first stacked together vertically and
54 * tightly. LODs are then packed together in MIPLAYOUT_BELOW with each LOD
55 * starting at page boundaries.
57 * This is usually used for non-mipmapped 2D textures, as multiple LODs are
58 * not supported natively.
63 * 3D slices of each LOD are first packed together horizontally and tightly
64 * with wrapping. LODs are then stacked together vertically and tightly.
66 * This is used for 3D textures.
72 * When the walk type is ILO_IMAGE_WALK_LAYER, there is only a slice in each
73 * LOD and this is used to describe LODs in the first array layer. Otherwise,
74 * there can be multiple slices in each LOD and this is used to describe the
75 * first slice in each LOD.
77 struct ilo_image_lod
{
78 /* physical position in pixels */
82 /* physical size of a slice in pixels */
84 unsigned slice_height
;
91 enum pipe_texture_target target
;
93 /* size, format, etc for programming hardware states */
99 unsigned sample_count
;
100 enum pipe_format format
;
101 bool separate_stencil
;
104 * width, height, and size of pixel blocks for conversion between pixel
105 * positions and memory offsets
107 unsigned block_width
;
108 unsigned block_height
;
111 enum ilo_image_walk_type walk
;
112 bool interleaved_samples
;
114 enum gen_surface_tiling tiling
;
116 /* physical LOD slice alignments */
120 struct ilo_image_lod lods
[PIPE_MAX_TEXTURE_LEVELS
];
122 /* physical layer height for ILO_IMAGE_WALK_LAYER */
123 unsigned walk_layer_height
;
125 /* distance in bytes between two pixel block rows */
127 /* number of pixel block rows */
133 enum ilo_image_aux_type type
;
135 /* bitmask of levels that can use aux */
138 /* LOD offsets for ILO_IMAGE_WALK_LOD */
139 unsigned walk_lod_offsets
[PIPE_MAX_TEXTURE_LEVELS
];
141 unsigned walk_layer_height
;
145 /* managed by users */
149 /* managed by users */
153 struct pipe_resource
;
156 ilo_image_init(struct ilo_image
*img
,
157 const struct ilo_dev
*dev
,
158 const struct pipe_resource
*templ
);
161 ilo_image_init_for_imported(struct ilo_image
*img
,
162 const struct ilo_dev
*dev
,
163 const struct pipe_resource
*templ
,
164 enum gen_surface_tiling tiling
,
168 ilo_image_can_enable_aux(const struct ilo_image
*img
, unsigned level
)
170 return (img
->aux
.bo
&& (img
->aux
.enables
& (1 << level
)));
174 * Convert from pixel position to 2D memory offset.
177 ilo_image_pos_to_mem(const struct ilo_image
*img
,
178 unsigned pos_x
, unsigned pos_y
,
179 unsigned *mem_x
, unsigned *mem_y
)
181 assert(pos_x
% img
->block_width
== 0);
182 assert(pos_y
% img
->block_height
== 0);
184 *mem_x
= pos_x
/ img
->block_width
* img
->block_size
;
185 *mem_y
= pos_y
/ img
->block_height
;
189 * Convert from 2D memory offset to linear offset.
191 static inline unsigned
192 ilo_image_mem_to_linear(const struct ilo_image
*img
,
193 unsigned mem_x
, unsigned mem_y
)
195 return mem_y
* img
->bo_stride
+ mem_x
;
199 * Convert from 2D memory offset to raw offset.
201 static inline unsigned
202 ilo_image_mem_to_raw(const struct ilo_image
*img
,
203 unsigned mem_x
, unsigned mem_y
)
205 unsigned tile_w
, tile_h
;
207 switch (img
->tiling
) {
208 case GEN6_TILING_NONE
:
225 assert(!"unknown tiling");
231 assert(mem_x
% tile_w
== 0);
232 assert(mem_y
% tile_h
== 0);
234 return mem_y
* img
->bo_stride
+ mem_x
* tile_h
;
238 * Return the stride, in bytes, between slices within a level.
240 static inline unsigned
241 ilo_image_get_slice_stride(const struct ilo_image
*img
, unsigned level
)
246 case ILO_IMAGE_WALK_LAYER
:
247 h
= img
->walk_layer_height
;
249 case ILO_IMAGE_WALK_LOD
:
250 h
= img
->lods
[level
].slice_height
;
252 case ILO_IMAGE_WALK_3D
:
254 h
= img
->lods
[0].slice_height
;
259 assert(!"no single stride to walk across slices");
264 assert(h
% img
->block_height
== 0);
266 return (h
/ img
->block_height
) * img
->bo_stride
;
270 * Return the physical size, in bytes, of a slice in a level.
272 static inline unsigned
273 ilo_image_get_slice_size(const struct ilo_image
*img
, unsigned level
)
275 const unsigned w
= img
->lods
[level
].slice_width
;
276 const unsigned h
= img
->lods
[level
].slice_height
;
278 assert(w
% img
->block_width
== 0);
279 assert(h
% img
->block_height
== 0);
281 return (w
/ img
->block_width
* img
->block_size
) *
282 (h
/ img
->block_height
);
286 * Return the pixel position of a slice.
289 ilo_image_get_slice_pos(const struct ilo_image
*img
,
290 unsigned level
, unsigned slice
,
291 unsigned *x
, unsigned *y
)
294 case ILO_IMAGE_WALK_LAYER
:
295 *x
= img
->lods
[level
].x
;
296 *y
= img
->lods
[level
].y
+ img
->walk_layer_height
* slice
;
298 case ILO_IMAGE_WALK_LOD
:
299 *x
= img
->lods
[level
].x
;
300 *y
= img
->lods
[level
].y
+ img
->lods
[level
].slice_height
* slice
;
302 case ILO_IMAGE_WALK_3D
:
304 /* slices are packed horizontally with wrapping */
305 const unsigned sx
= slice
& ((1 << level
) - 1);
306 const unsigned sy
= slice
>> level
;
308 assert(slice
< u_minify(img
->depth0
, level
));
310 *x
= img
->lods
[level
].x
+ img
->lods
[level
].slice_width
* sx
;
311 *y
= img
->lods
[level
].y
+ img
->lods
[level
].slice_height
* sy
;
315 assert(!"unknown img walk type");
321 /* should not exceed the bo size */
322 assert(*y
+ img
->lods
[level
].slice_height
<=
323 img
->bo_height
* img
->block_height
);
326 #endif /* ILO_IMAGE_H */