*/
#include "intel_mipmap_tree.h"
-#include "intel_tex_layout.h"
-#include "intel_context.h"
+#include "brw_context.h"
#include "main/macros.h"
#define FILE_DEBUG_FLAG DEBUG_MIPTREE
+static unsigned int
+intel_horizontal_texture_alignment_unit(struct brw_context *brw,
+ gl_format format)
+{
+ /**
+ * From the "Alignment Unit Size" section of various specs, namely:
+ * - Gen3 Spec: "Memory Data Formats" Volume, Section 1.20.1.4
+ * - i965 and G45 PRMs: Volume 1, Section 6.17.3.4.
+ * - Ironlake and Sandybridge PRMs: Volume 1, Part 1, Section 7.18.3.4
+ * - BSpec (for Ivybridge and slight variations in separate stencil)
+ *
+ * +----------------------------------------------------------------------+
+ * | | alignment unit width ("i") |
+ * | Surface Property |-----------------------------|
+ * | | 915 | 965 | ILK | SNB | IVB |
+ * +----------------------------------------------------------------------+
+ * | YUV 4:2:2 format | 8 | 4 | 4 | 4 | 4 |
+ * | BC1-5 compressed format (DXTn/S3TC) | 4 | 4 | 4 | 4 | 4 |
+ * | FXT1 compressed format | 8 | 8 | 8 | 8 | 8 |
+ * | Depth Buffer (16-bit) | 4 | 4 | 4 | 4 | 8 |
+ * | Depth Buffer (other) | 4 | 4 | 4 | 4 | 4 |
+ * | Separate Stencil Buffer | N/A | N/A | 8 | 8 | 8 |
+ * | All Others | 4 | 4 | 4 | 4 | 4 |
+ * +----------------------------------------------------------------------+
+ *
+ * On IVB+, non-special cases can be overridden by setting the SURFACE_STATE
+ * "Surface Horizontal Alignment" field to HALIGN_4 or HALIGN_8.
+ */
+ if (_mesa_is_format_compressed(format)) {
+ /* The hardware alignment requirements for compressed textures
+ * happen to match the block boundaries.
+ */
+ unsigned int i, j;
+ _mesa_get_format_block_size(format, &i, &j);
+ return i;
+ }
+
+ if (format == MESA_FORMAT_S8)
+ return 8;
+
+ if (brw->gen >= 7 && format == MESA_FORMAT_Z16)
+ return 8;
+
+ return 4;
+}
+
+static unsigned int
+intel_vertical_texture_alignment_unit(struct brw_context *brw,
+ gl_format format)
+{
+ /**
+ * From the "Alignment Unit Size" section of various specs, namely:
+ * - Gen3 Spec: "Memory Data Formats" Volume, Section 1.20.1.4
+ * - i965 and G45 PRMs: Volume 1, Section 6.17.3.4.
+ * - Ironlake and Sandybridge PRMs: Volume 1, Part 1, Section 7.18.3.4
+ * - BSpec (for Ivybridge and slight variations in separate stencil)
+ *
+ * +----------------------------------------------------------------------+
+ * | | alignment unit height ("j") |
+ * | Surface Property |-----------------------------|
+ * | | 915 | 965 | ILK | SNB | IVB |
+ * +----------------------------------------------------------------------+
+ * | BC1-5 compressed format (DXTn/S3TC) | 4 | 4 | 4 | 4 | 4 |
+ * | FXT1 compressed format | 4 | 4 | 4 | 4 | 4 |
+ * | Depth Buffer | 2 | 2 | 2 | 4 | 4 |
+ * | Separate Stencil Buffer | N/A | N/A | N/A | 4 | 8 |
+ * | Multisampled (4x or 8x) render target | N/A | N/A | N/A | 4 | 4 |
+ * | All Others | 2 | 2 | 2 | 2 | 2 |
+ * +----------------------------------------------------------------------+
+ *
+ * On SNB+, non-special cases can be overridden by setting the SURFACE_STATE
+ * "Surface Vertical Alignment" field to VALIGN_2 or VALIGN_4.
+ *
+ * We currently don't support multisampling.
+ */
+ if (_mesa_is_format_compressed(format))
+ return 4;
+
+ if (format == MESA_FORMAT_S8)
+ return brw->gen >= 7 ? 8 : 4;
+
+ GLenum base_format = _mesa_get_format_base_format(format);
+
+ if (brw->gen >= 6 &&
+ (base_format == GL_DEPTH_COMPONENT ||
+ base_format == GL_DEPTH_STENCIL)) {
+ return 4;
+ }
+
+ return 2;
+}
+
static void
brw_miptree_layout_2d(struct intel_mipmap_tree *mt)
{
- unsigned level;
unsigned x = 0;
unsigned y = 0;
unsigned width = mt->physical_width0;
mt->total_height = 0;
- for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
+ for (unsigned level = mt->first_level; level <= mt->last_level; level++) {
unsigned img_height;
intel_miptree_set_level_info(mt, level, x, y, width,
}
static void
-brw_miptree_layout_texture_array(struct intel_context *intel,
+brw_miptree_layout_texture_array(struct brw_context *brw,
struct intel_mipmap_tree *mt)
{
- unsigned level;
unsigned qpitch = 0;
- int h0, h1, q;
+ int h0, h1;
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);
+ qpitch = (h0 + h1 + (brw->gen >= 7 ? 12 : 11) * mt->align_h);
if (mt->compressed)
qpitch /= 4;
brw_miptree_layout_2d(mt);
- for (level = mt->first_level; level <= mt->last_level; level++) {
- for (q = 0; q < mt->physical_depth0; q++) {
+ for (unsigned level = mt->first_level; level <= mt->last_level; level++) {
+ for (int q = 0; q < mt->physical_depth0; q++) {
intel_miptree_set_image_offset(mt, level, q, 0, q * qpitch);
}
}
}
static void
-brw_miptree_layout_texture_3d(struct intel_context *intel,
+brw_miptree_layout_texture_3d(struct brw_context *brw,
struct intel_mipmap_tree *mt)
{
unsigned width = mt->physical_width0;
unsigned depth = mt->physical_depth0;
unsigned pack_x_pitch, pack_x_nr;
unsigned pack_y_pitch;
- unsigned level;
mt->total_height = 0;
pack_x_pitch = width;
pack_x_nr = 1;
- for (level = mt->first_level ; level <= mt->last_level ; level++) {
+ for (unsigned level = mt->first_level; level <= mt->last_level; level++) {
int x = 0;
int y = 0;
- int q, j;
intel_miptree_set_level_info(mt, level,
0, mt->total_height,
width, height, depth);
- for (q = 0; q < depth; /* empty */) {
- for (j = 0; j < pack_x_nr && q < depth; j++, q++) {
+ for (int q = 0; q < depth; /* empty */) {
+ for (int j = 0; j < pack_x_nr && q < depth; j++, q++) {
intel_miptree_set_image_offset(mt, level, q, x, y);
x += pack_x_pitch;
}
}
void
-brw_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree *mt)
+brw_miptree_layout(struct brw_context *brw, struct intel_mipmap_tree *mt)
{
+ mt->align_w = intel_horizontal_texture_alignment_unit(brw, mt->format);
+ mt->align_h = intel_vertical_texture_alignment_unit(brw, mt->format);
+
switch (mt->target) {
case GL_TEXTURE_CUBE_MAP:
- if (intel->gen == 4) {
+ if (brw->gen == 4) {
/* Gen4 stores cube maps as 3D textures. */
assert(mt->physical_depth0 == 6);
- brw_miptree_layout_texture_3d(intel, mt);
+ brw_miptree_layout_texture_3d(brw, mt);
} else {
/* All other hardware stores cube maps as 2D arrays. */
- brw_miptree_layout_texture_array(intel, mt);
+ brw_miptree_layout_texture_array(brw, mt);
}
break;
case GL_TEXTURE_3D:
- brw_miptree_layout_texture_3d(intel, mt);
+ brw_miptree_layout_texture_3d(brw, mt);
break;
case GL_TEXTURE_1D_ARRAY:
case GL_TEXTURE_2D_ARRAY:
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
case GL_TEXTURE_CUBE_MAP_ARRAY:
- brw_miptree_layout_texture_array(intel, mt);
+ brw_miptree_layout_texture_array(brw, mt);
break;
default:
switch (mt->msaa_layout) {
case INTEL_MSAA_LAYOUT_UMS:
case INTEL_MSAA_LAYOUT_CMS:
- brw_miptree_layout_texture_array(intel, mt);
+ brw_miptree_layout_texture_array(brw, mt);
break;
case INTEL_MSAA_LAYOUT_NONE:
case INTEL_MSAA_LAYOUT_IMS: