2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4 develop this 3D driver.
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
14 The above copyright notice and this permission notice (including the
15 next paragraph) shall be included in all copies or substantial
16 portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **********************************************************************/
28 #include "pipe/p_format.h"
30 #include "util/u_math.h"
31 #include "util/u_memory.h"
33 #include "brw_screen.h"
34 #include "brw_debug.h"
36 /* Code to layout images in a mipmap tree for i965.
40 brw_tex_pitch_align (struct brw_texture
*tex
,
43 if (!tex
->compressed
) {
46 switch (tex
->tiling
) {
54 /* XXX: Untiled pitch alignment of 64 bytes for now to allow
55 * render-to-texture to work in all cases. This should
56 * probably be replaced at some point by some scheme to only
57 * do this when really necessary, for example standalone
58 * render target views.
64 pitch
= align(pitch
* tex
->cpp
, pitch_align
);
73 brw_tex_alignment_unit(enum pipe_format pf
,
77 case PIPE_FORMAT_DXT1_RGB
:
78 case PIPE_FORMAT_DXT1_RGBA
:
79 case PIPE_FORMAT_DXT3_RGBA
:
80 case PIPE_FORMAT_DXT5_RGBA
:
81 case PIPE_FORMAT_DXT1_SRGB
:
82 case PIPE_FORMAT_DXT1_SRGBA
:
83 case PIPE_FORMAT_DXT3_SRGBA
:
84 case PIPE_FORMAT_DXT5_SRGBA
:
98 brw_tex_set_level_info(struct brw_texture
*tex
,
102 GLuint w
, GLuint h
, GLuint d
)
104 assert(tex
->base
.width
[level
] == w
);
105 assert(tex
->base
.height
[level
] == h
);
106 assert(tex
->base
.depth
[level
] == d
);
107 assert(tex
->image_offset
[level
] == NULL
);
108 assert(nr_images
>= 1);
110 if (BRW_DEBUG
& DEBUG_TEXTURE
)
111 debug_printf("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__
,
112 level
, w
, h
, d
, x
, y
, tex
->level_offset
[level
]);
115 tex
->level_offset
[level
] = (x
+ y
* tex
->pitch
) * tex
->cpp
;
116 tex
->nr_images
[level
] = nr_images
;
118 tex
->image_offset
[level
] = MALLOC(nr_images
* sizeof(GLuint
));
119 tex
->image_offset
[level
][0] = 0;
124 brw_tex_set_image_offset(struct brw_texture
*tex
,
125 GLuint level
, GLuint img
,
129 assert((x
== 0 && y
== 0) || img
!= 0 || level
!= 0);
130 assert(img
< tex
->nr_images
[level
]);
132 if (BRW_DEBUG
& DEBUG_TEXTURE
)
133 debug_printf("%s level %d img %d pos %d,%d image_offset %x\n",
134 __FUNCTION__
, level
, img
, x
, y
,
135 tex
->image_offset
[level
][img
]);
137 tex
->image_offset
[level
][img
] = (x
+ y
* tex
->pitch
) * tex
->cpp
+ offset
;
142 static void brw_layout_2d( struct brw_texture
*tex
)
144 GLuint align_h
= 2, align_w
= 4;
148 GLuint width
= tex
->base
.width
[0];
149 GLuint height
= tex
->base
.height
[0];
151 tex
->pitch
= tex
->base
.width
[0];
152 brw_tex_alignment_unit(tex
->base
.format
, &align_w
, &align_h
);
154 if (tex
->compressed
) {
155 tex
->pitch
= align(tex
->base
.width
[0], align_w
);
158 /* May need to adjust pitch to accomodate the placement of
159 * the 2nd mipmap. This occurs when the alignment
160 * constraints of mipmap placement push the right edge of the
161 * 2nd mipmap out past the width of its parent.
163 if (tex
->base
.last_level
> 0) {
166 if (tex
->compressed
) {
167 mip1_width
= align(minify(tex
->base
.width
[0]), align_w
)
168 + align(minify(minify(tex
->base
.width
[0])), align_w
);
170 mip1_width
= align(minify(tex
->base
.width
[0]), align_w
)
171 + minify(minify(tex
->base
.width
[0]));
174 if (mip1_width
> tex
->pitch
) {
175 tex
->pitch
= mip1_width
;
179 /* Pitch must be a whole number of dwords, even though we
180 * express it in texels.
182 tex
->pitch
= brw_tex_pitch_align (tex
, tex
->pitch
);
183 tex
->total_height
= 0;
185 for ( level
= 0 ; level
<= tex
->base
.last_level
; level
++ ) {
188 brw_tex_set_level_info(tex
, level
, 1, x
, y
, width
, height
, 1);
191 img_height
= MAX2(1, height
/4);
193 img_height
= align(height
, align_h
);
196 /* Because the images are packed better, the final offset
197 * might not be the maximal one:
199 tex
->total_height
= MAX2(tex
->total_height
, y
+ img_height
);
201 /* Layout_below: step right after second mipmap.
204 x
+= align(width
, align_w
);
210 width
= minify(width
);
211 height
= minify(height
);
217 brw_layout_cubemap_idgng( struct brw_texture
*tex
)
219 GLuint align_h
= 2, align_w
= 4;
223 GLuint width
= tex
->base
.width
[0];
224 GLuint height
= tex
->base
.height
[0];
228 tex
->pitch
= tex
->base
.width
[0];
229 brw_tex_alignment_unit(tex
->base
.format
, &align_w
, &align_h
);
230 y_pitch
= align(height
, align_h
);
232 if (tex
->compressed
) {
233 tex
->pitch
= align(tex
->base
.width
[0], align_w
);
236 if (tex
->base
.last_level
!= 0) {
239 if (tex
->compressed
) {
240 mip1_width
= (align(minify(tex
->base
.width
[0]), align_w
) +
241 align(minify(minify(tex
->base
.width
[0])), align_w
));
243 mip1_width
= (align(minify(tex
->base
.width
[0]), align_w
) +
244 minify(minify(tex
->base
.width
[0])));
247 if (mip1_width
> tex
->pitch
) {
248 tex
->pitch
= mip1_width
;
252 tex
->pitch
= brw_tex_pitch_align(tex
, tex
->pitch
);
254 if (tex
->compressed
) {
256 align(minify(y_pitch
), align_h
) +
257 11 * align_h
) / 4) * tex
->pitch
* tex
->cpp
;
259 tex
->total_height
= ((y_pitch
+
260 align(minify(y_pitch
), align_h
) +
261 11 * align_h
) / 4) * 6;
264 align(minify(y_pitch
), align_h
) +
265 11 * align_h
) * tex
->pitch
* tex
->cpp
;
267 tex
->total_height
= (y_pitch
+
268 align(minify(y_pitch
), align_h
) +
272 for (level
= 0; level
<= tex
->base
.last_level
; level
++) {
274 GLuint nr_images
= 6;
277 brw_tex_set_level_info(tex
, level
, nr_images
, x
, y
, width
, height
, 1);
279 for (q
= 0; q
< nr_images
; q
++)
280 brw_tex_set_image_offset(tex
, level
, q
, x
, y
, q
* qpitch
);
283 img_height
= MAX2(1, height
/4);
285 img_height
= align(height
, align_h
);
288 x
+= align(width
, align_w
);
294 width
= minify(width
);
295 height
= minify(height
);
303 brw_layout_3d_cube( struct brw_texture
*tex
)
305 GLuint width
= tex
->base
.width
[0];
306 GLuint height
= tex
->base
.height
[0];
307 GLuint depth
= tex
->base
.depth
[0];
308 GLuint pack_x_pitch
, pack_x_nr
;
314 tex
->total_height
= 0;
315 brw_tex_alignment_unit(tex
->base
.format
, &align_w
, &align_h
);
317 if (tex
->compressed
) {
318 tex
->pitch
= align(width
, align_w
);
319 pack_y_pitch
= (height
+ 3) / 4;
321 tex
->pitch
= brw_tex_pitch_align(tex
, tex
->base
.width
[0]);
322 pack_y_pitch
= align(tex
->base
.height
[0], align_h
);
325 pack_x_pitch
= width
;
328 for (level
= 0 ; level
<= tex
->base
.last_level
; level
++) {
329 GLuint nr_images
= tex
->base
.target
== PIPE_TEXTURE_3D
? depth
: 6;
334 brw_tex_set_level_info(tex
, level
, nr_images
,
335 0, tex
->total_height
,
336 width
, height
, depth
);
338 for (q
= 0; q
< nr_images
;) {
339 for (j
= 0; j
< pack_x_nr
&& q
< nr_images
; j
++, q
++) {
340 brw_tex_set_image_offset(tex
, level
, q
, x
, y
, 0);
349 tex
->total_height
+= y
;
350 width
= minify(width
);
351 height
= minify(height
);
352 depth
= minify(depth
);
354 if (tex
->compressed
) {
355 pack_y_pitch
= (height
+ 3) / 4;
357 if (pack_x_pitch
> align(width
, align_w
)) {
358 pack_x_pitch
= align(width
, align_w
);
362 if (pack_x_pitch
> 4) {
365 assert(pack_x_pitch
* pack_x_nr
<= tex
->pitch
);
368 if (pack_y_pitch
> 2) {
370 pack_y_pitch
= align(pack_y_pitch
, align_h
);
375 /* The 965's sampler lays cachelines out according to how accesses
376 * in the texture surfaces run, so they may be "vertical" through
377 * memory. As a result, the docs say in Surface Padding Requirements:
378 * Sampling Engine Surfaces that two extra rows of padding are required.
380 if (tex
->base
.target
== PIPE_TEXTURE_CUBE
)
381 tex
->total_height
+= 2;
388 GLboolean
brw_texture_layout(struct brw_screen
*brw_screen
,
389 struct brw_texture
*tex
)
391 switch (tex
->base
.target
) {
392 case PIPE_TEXTURE_CUBE
:
393 if (brw_screen
->chipset
.is_igdng
)
394 brw_layout_cubemap_idgng( tex
);
396 brw_layout_3d_cube( tex
);
399 case PIPE_TEXTURE_3D
:
400 brw_layout_3d_cube( tex
);
404 brw_layout_2d( tex
);
408 if (BRW_DEBUG
& DEBUG_TEXTURE
)
409 debug_printf("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__
,
413 tex
->pitch
* tex
->total_height
* tex
->cpp
);