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"
35
#include "brw_winsys.h"
37
/* Code to layout images in a mipmap tree for i965.
41
brw_tex_pitch_align (struct brw_texture *tex,
44
if (!tex->compressed) {
47
switch (tex->tiling) {
55
/* XXX: Untiled pitch alignment of 64 bytes for now to allow
56
* render-to-texture to work in all cases. This should
57
* probably be replaced at some point by some scheme to only
58
* do this when really necessary, for example standalone
59
* render target views.
65
pitch = align(pitch * tex->cpp, pitch_align);
74
brw_tex_alignment_unit(enum pipe_format pf,
78
case PIPE_FORMAT_DXT1_RGB:
79
case PIPE_FORMAT_DXT1_RGBA:
80
case PIPE_FORMAT_DXT3_RGBA:
81
case PIPE_FORMAT_DXT5_RGBA:
82
case PIPE_FORMAT_DXT1_SRGB:
83
case PIPE_FORMAT_DXT1_SRGBA:
84
case PIPE_FORMAT_DXT3_SRGBA:
85
case PIPE_FORMAT_DXT5_SRGBA:
99
brw_tex_set_level_info(struct brw_texture *tex,
103
GLuint w, GLuint h, GLuint d)
106
if (BRW_DEBUG & DEBUG_TEXTURE)
107
debug_printf("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
108
level, w, h, d, x, y, tex->level_offset[level]);
110
assert(tex->image_offset[level] == NULL);
111
assert(nr_images >= 1);
113
tex->level_offset[level] = (x + y * tex->pitch) * tex->cpp;
114
tex->nr_images[level] = nr_images;
116
tex->image_offset[level] = MALLOC(nr_images * sizeof(GLuint));
117
tex->image_offset[level][0] = 0;
122
brw_tex_set_image_offset(struct brw_texture *tex,
123
GLuint level, GLuint img,
127
assert((x == 0 && y == 0) || img != 0 || level != 0);
128
assert(img < tex->nr_images[level]);
130
if (BRW_DEBUG & DEBUG_TEXTURE)
131
debug_printf("%s level %d img %d pos %d,%d image_offset %x\n",
132
__FUNCTION__, level, img, x, y,
133
tex->image_offset[level][img]);
135
tex->image_offset[level][img] = (x + y * tex->pitch) * tex->cpp + offset;
140
static void brw_layout_2d( struct brw_texture *tex )
142
GLuint align_h = 2, align_w = 4;
146
GLuint width = tex->base.width0;
147
GLuint height = tex->base.height0;
149
tex->pitch = tex->base.width0;
150
brw_tex_alignment_unit(tex->base.format, &align_w, &align_h);
152
if (tex->compressed) {
153
tex->pitch = align(tex->base.width0, align_w);
156
/* May need to adjust pitch to accomodate the placement of
157
* the 2nd mipmap. This occurs when the alignment
158
* constraints of mipmap placement push the right edge of the
159
* 2nd mipmap out past the width of its parent.
161
if (tex->base.last_level > 0) {
164
if (tex->compressed) {
165
mip1_width = (align(u_minify(tex->base.width0, 1), align_w) +
166
align(u_minify(tex->base.width0, 2), align_w));
168
mip1_width = (align(u_minify(tex->base.width0, 1), align_w) +
169
u_minify(tex->base.width0, 2));
172
if (mip1_width > tex->pitch) {
173
tex->pitch = mip1_width;
177
/* Pitch must be a whole number of dwords, even though we
178
* express it in texels.
180
tex->pitch = brw_tex_pitch_align (tex, tex->pitch);
181
tex->total_height = 0;
183
for ( level = 0 ; level <= tex->base.last_level ; level++ ) {
186
brw_tex_set_level_info(tex, level, 1, x, y, width, height, 1);
189
img_height = MAX2(1, height/4);
191
img_height = align(height, align_h);
194
/* Because the images are packed better, the final offset
195
* might not be the maximal one:
197
tex->total_height = MAX2(tex->total_height, y + img_height);
199
/* Layout_below: step right after second mipmap.
202
x += align(width, align_w);
208
width = u_minify(width, 1);
209
height = u_minify(height, 1);
215
brw_layout_cubemap_idgng( struct brw_texture *tex )
217
GLuint align_h = 2, align_w = 4;
221
GLuint width = tex->base.width0;
222
GLuint height = tex->base.height0;
226
tex->pitch = tex->base.width0;
227
brw_tex_alignment_unit(tex->base.format, &align_w, &align_h);
228
y_pitch = align(height, align_h);
230
if (tex->compressed) {
231
tex->pitch = align(tex->base.width0, align_w);
234
if (tex->base.last_level != 0) {
237
if (tex->compressed) {
238
mip1_width = (align(u_minify(tex->base.width0, 1), align_w) +
239
align(u_minify(tex->base.width0, 2), align_w));
241
mip1_width = (align(u_minify(tex->base.width0, 1), align_w) +
242
u_minify(tex->base.width0, 2));
245
if (mip1_width > tex->pitch) {
246
tex->pitch = mip1_width;
250
tex->pitch = brw_tex_pitch_align(tex, tex->pitch);
252
if (tex->compressed) {
254
align(u_minify(y_pitch, 1), align_h) +
255
11 * align_h) / 4) * tex->pitch * tex->cpp;
257
tex->total_height = ((y_pitch +
258
align(u_minify(y_pitch, 1), align_h) +
259
11 * align_h) / 4) * 6;
262
align(u_minify(y_pitch, 1), align_h) +
263
11 * align_h) * tex->pitch * tex->cpp;
265
tex->total_height = (y_pitch +
266
align(u_minify(y_pitch, 1), align_h) +
270
for (level = 0; level <= tex->base.last_level; level++) {
272
GLuint nr_images = 6;
275
brw_tex_set_level_info(tex, level, nr_images, x, y, width, height, 1);
277
for (q = 0; q < nr_images; q++)
278
brw_tex_set_image_offset(tex, level, q, x, y, q * qpitch);
281
img_height = MAX2(1, height/4);
283
img_height = align(height, align_h);
286
x += align(width, align_w);
292
width = u_minify(width, 1);
293
height = u_minify(height, 1);
301
brw_layout_3d_cube( struct brw_texture *tex )
303
GLuint width = tex->base.width0;
304
GLuint height = tex->base.height0;
305
GLuint depth = tex->base.depth0;
306
GLuint pack_x_pitch, pack_x_nr;
312
tex->total_height = 0;
313
brw_tex_alignment_unit(tex->base.format, &align_w, &align_h);
315
if (tex->compressed) {
316
tex->pitch = align(width, align_w);
317
pack_y_pitch = (height + 3) / 4;
319
tex->pitch = brw_tex_pitch_align(tex, tex->base.width0);
320
pack_y_pitch = align(tex->base.height0, align_h);
323
pack_x_pitch = width;
326
for (level = 0 ; level <= tex->base.last_level ; level++) {
327
GLuint nr_images = tex->base.target == PIPE_TEXTURE_3D ? depth : 6;
332
brw_tex_set_level_info(tex, level, nr_images,
333
0, tex->total_height,
334
width, height, depth);
336
for (q = 0; q < nr_images;) {
337
for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) {
338
brw_tex_set_image_offset(tex, level, q, x, y, 0);
347
tex->total_height += y;
348
width = u_minify(width, 1);
349
height = u_minify(height, 1);
350
depth = u_minify(depth, 1);
352
if (tex->compressed) {
353
pack_y_pitch = (height + 3) / 4;
355
if (pack_x_pitch > align(width, align_w)) {
356
pack_x_pitch = align(width, align_w);
360
if (pack_x_pitch > 4) {
363
assert(pack_x_pitch * pack_x_nr <= tex->pitch);
366
if (pack_y_pitch > 2) {
368
pack_y_pitch = align(pack_y_pitch, align_h);
373
/* The 965's sampler lays cachelines out according to how accesses
374
* in the texture surfaces run, so they may be "vertical" through
375
* memory. As a result, the docs say in Surface Padding Requirements:
376
* Sampling Engine Surfaces that two extra rows of padding are required.
378
if (tex->base.target == PIPE_TEXTURE_CUBE)
379
tex->total_height += 2;
386
GLboolean brw_texture_layout(struct brw_screen *brw_screen,
387
struct brw_texture *tex )
389
switch (tex->base.target) {
390
case PIPE_TEXTURE_CUBE:
391
if (brw_screen->chipset.is_igdng)
392
brw_layout_cubemap_idgng( tex );
394
brw_layout_3d_cube( tex );
397
case PIPE_TEXTURE_3D:
398
brw_layout_3d_cube( tex );
402
brw_layout_2d( tex );
406
if (BRW_DEBUG & DEBUG_TEXTURE)
407
debug_printf("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
411
tex->pitch * tex->total_height * tex->cpp );