#define FILE_DEBUG_FLAG DEBUG_MIPTREE
-GLboolean brw_miptree_layout(struct intel_context *intel,
- struct intel_mipmap_tree *mt,
- uint32_t tiling)
+static void
+brw_miptree_layout_texture_array(struct intel_context *intel,
+ struct intel_mipmap_tree *mt)
{
- /* XXX: these vary depending on image format: */
- /* GLint align_w = 4; */
+ GLuint level;
+ GLuint qpitch = 0;
+ int h0, h1, q;
+
+ h0 = ALIGN(mt->physical_height0, mt->align_h);
+ h1 = ALIGN(minify(mt->physical_height0, 1), mt->align_h);
+ if (mt->array_spacing_lod0)
+ qpitch = h0;
+ else
+ qpitch = (h0 + h1 + (intel->gen >= 7 ? 12 : 11) * mt->align_h);
+ if (mt->compressed)
+ qpitch /= 4;
+
+ i945_miptree_layout_2d(mt);
+
+ for (level = mt->first_level; level <= mt->last_level; level++) {
+ for (q = 0; q < mt->physical_depth0; q++) {
+ intel_miptree_set_image_offset(mt, level, q, 0, q * qpitch);
+ }
+ }
+ mt->total_height = qpitch * mt->physical_depth0;
+}
+void
+brw_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree *mt)
+{
switch (mt->target) {
+ case GL_TEXTURE_CUBE_MAP_ARRAY:
+ brw_miptree_layout_texture_array(intel, mt);
+ break;
+
case GL_TEXTURE_CUBE_MAP:
- if (intel->gen == 5) {
- GLuint align_h = 2, align_w = 4;
- GLuint level;
- GLuint x = 0;
- GLuint y = 0;
- GLuint width = mt->width0;
- GLuint height = mt->height0;
- GLuint qpitch = 0;
- GLuint y_pitch = 0;
-
- mt->total_width = mt->width0;
- intel_get_texture_alignment_unit(mt->internal_format, &align_w, &align_h);
- y_pitch = ALIGN(height, align_h);
-
- if (mt->compressed) {
- mt->total_width = ALIGN(mt->width0, align_w);
- }
-
- if (mt->first_level != mt->last_level) {
- GLuint mip1_width;
-
- if (mt->compressed) {
- mip1_width = ALIGN(minify(mt->width0), align_w)
- + ALIGN(minify(minify(mt->width0)), align_w);
- } else {
- mip1_width = ALIGN(minify(mt->width0), align_w)
- + minify(minify(mt->width0));
- }
-
- if (mip1_width > mt->total_width) {
- mt->total_width = mip1_width;
- }
- }
-
- if (mt->compressed) {
- qpitch = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) / 4;
- mt->total_height = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) / 4 * 6;
- } else {
- qpitch = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h);
- mt->total_height = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) * 6;
- }
-
- for (level = mt->first_level; level <= mt->last_level; level++) {
- GLuint img_height;
- GLuint nr_images = 6;
- GLuint q = 0;
-
- intel_miptree_set_level_info(mt, level, nr_images, x, y, width,
- height, 1);
-
- for (q = 0; q < nr_images; q++)
- intel_miptree_set_image_offset(mt, level, q,
- x, y + q * qpitch);
-
- if (mt->compressed)
- img_height = MAX2(1, height/4);
- else
- img_height = ALIGN(height, align_h);
-
- if (level == mt->first_level + 1) {
- x += ALIGN(width, align_w);
- }
- else {
- y += img_height;
- }
-
- width = minify(width);
- height = minify(height);
- }
-
- break;
+ if (intel->gen >= 5) {
+ /* On Ironlake, cube maps are finally represented as just a series of
+ * MIPLAYOUT_BELOW 2D textures (like 2D texture arrays), separated by a
+ * pitch of qpitch rows, where qpitch is defined by the equation given
+ * in Volume 1 of the BSpec.
+ */
+ brw_miptree_layout_texture_array(intel, mt);
+ break;
}
+ assert(mt->physical_depth0 == 6);
+ /* FALLTHROUGH */
case GL_TEXTURE_3D: {
- GLuint width = mt->width0;
- GLuint height = mt->height0;
- GLuint depth = mt->depth0;
+ GLuint width = mt->physical_width0;
+ GLuint height = mt->physical_height0;
+ GLuint depth = mt->physical_depth0;
GLuint pack_x_pitch, pack_x_nr;
GLuint pack_y_pitch;
GLuint level;
- GLuint align_h = 2;
- GLuint align_w = 4;
mt->total_height = 0;
- intel_get_texture_alignment_unit(mt->internal_format, &align_w, &align_h);
if (mt->compressed) {
- mt->total_width = ALIGN(width, align_w);
+ mt->total_width = ALIGN(width, mt->align_w);
pack_y_pitch = (height + 3) / 4;
} else {
- mt->total_width = mt->width0;
- pack_y_pitch = ALIGN(mt->height0, align_h);
+ mt->total_width = mt->physical_width0;
+ pack_y_pitch = ALIGN(mt->physical_height0, mt->align_h);
}
pack_x_pitch = width;
pack_x_nr = 1;
for (level = mt->first_level ; level <= mt->last_level ; level++) {
- GLuint nr_images = mt->target == GL_TEXTURE_3D ? depth : 6;
GLint x = 0;
GLint y = 0;
GLint q, j;
- intel_miptree_set_level_info(mt, level, nr_images,
+ intel_miptree_set_level_info(mt, level,
0, mt->total_height,
width, height, depth);
- for (q = 0; q < nr_images;) {
- for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) {
+ for (q = 0; q < depth; /* empty */) {
+ for (j = 0; j < pack_x_nr && q < depth; j++, q++) {
intel_miptree_set_image_offset(mt, level, q, x, y);
x += pack_x_pitch;
}
+ if (x > mt->total_width)
+ mt->total_width = x;
x = 0;
y += pack_y_pitch;
mt->total_height += y;
- width = minify(width);
- height = minify(height);
- depth = minify(depth);
+ width = minify(width, 1);
+ height = minify(height, 1);
+ if (mt->target == GL_TEXTURE_3D)
+ depth = minify(depth, 1);
if (mt->compressed) {
pack_y_pitch = (height + 3) / 4;
- if (pack_x_pitch > ALIGN(width, align_w)) {
- pack_x_pitch = ALIGN(width, align_w);
+ if (pack_x_pitch > ALIGN(width, mt->align_w)) {
+ pack_x_pitch = ALIGN(width, mt->align_w);
pack_x_nr <<= 1;
}
} else {
+ pack_x_nr <<= 1;
if (pack_x_pitch > 4) {
pack_x_pitch >>= 1;
- pack_x_nr <<= 1;
- assert(pack_x_pitch * pack_x_nr <= mt->total_width);
}
if (pack_y_pitch > 2) {
pack_y_pitch >>= 1;
- pack_y_pitch = ALIGN(pack_y_pitch, align_h);
+ pack_y_pitch = ALIGN(pack_y_pitch, mt->align_h);
}
}
* in the texture surfaces run, so they may be "vertical" through
* memory. As a result, the docs say in Surface Padding Requirements:
* Sampling Engine Surfaces that two extra rows of padding are required.
- * We don't know of similar requirements for pre-965, but given that
- * those docs are silent on padding requirements in general, let's play
- * it safe.
*/
if (mt->target == GL_TEXTURE_CUBE_MAP)
mt->total_height += 2;
break;
}
+ case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_1D_ARRAY:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ brw_miptree_layout_texture_array(intel, mt);
+ break;
+
default:
- i945_miptree_layout_2d(intel, mt, tiling);
+ switch (mt->msaa_layout) {
+ case INTEL_MSAA_LAYOUT_UMS:
+ case INTEL_MSAA_LAYOUT_CMS:
+ brw_miptree_layout_texture_array(intel, mt);
+ break;
+ case INTEL_MSAA_LAYOUT_NONE:
+ case INTEL_MSAA_LAYOUT_IMS:
+ i945_miptree_layout_2d(mt);
+ break;
+ }
break;
}
DBG("%s: %dx%dx%d\n", __FUNCTION__,
mt->total_width, mt->total_height, mt->cpp);
-
- return GL_TRUE;
}