+ for (i = 0; i <= tex->b.b.b.last_level; i++)
+ tex->tex.cbzb_allowed[i] = first_level_valid && tex->tex.macrotile[i];
+}
+
+static unsigned r300_pixels_to_dwords(unsigned stride,
+ unsigned height,
+ unsigned xblock, unsigned yblock)
+{
+ return (util_align_npot(stride, xblock) * align(height, yblock)) / (xblock * yblock);
+}
+
+static void r300_setup_hyperz_properties(struct r300_screen *screen,
+ struct r300_resource *tex)
+{
+ /* The tile size of 1 DWORD in ZMASK RAM is:
+ *
+ * GPU Pipes 4x4 mode 8x8 mode
+ * ------------------------------------------
+ * R580 4P/1Z 32x32 64x64
+ * RV570 3P/1Z 48x16 96x32
+ * RV530 1P/2Z 32x16 64x32
+ * 1P/1Z 16x16 32x32
+ */
+ static unsigned zmask_blocks_x_per_dw[4] = {4, 8, 12, 8};
+ static unsigned zmask_blocks_y_per_dw[4] = {4, 4, 4, 8};
+
+ /* In HIZ RAM, one dword is always 8x8 pixels (each byte is 4x4 pixels),
+ * but the blocks have very weird ordering.
+ *
+ * With 2 pipes and an image of size 8xY, where Y >= 1,
+ * clearing 4 dwords clears blocks like this:
+ *
+ * 01012323
+ *
+ * where numbers correspond to dword indices. The blocks are interleaved
+ * in the X direction, so the alignment must be 4x1 blocks (32x8 pixels).
+ *
+ * With 4 pipes and an image of size 8xY, where Y >= 4,
+ * clearing 8 dwords clears blocks like this:
+ * 01012323
+ * 45456767
+ * 01012323
+ * 45456767
+ * where numbers correspond to dword indices. The blocks are interleaved
+ * in both directions, so the alignment must be 4x4 blocks (32x32 pixels)
+ */
+ static unsigned hiz_align_x[4] = {8, 32, 48, 32};
+ static unsigned hiz_align_y[4] = {8, 8, 8, 32};
+
+ if (util_format_is_depth_or_stencil(tex->b.b.b.format) &&
+ util_format_get_blocksizebits(tex->b.b.b.format) == 32 &&
+ tex->tex.microtile) {
+ unsigned i, pipes;
+
+ if (screen->caps.family == CHIP_FAMILY_RV530) {
+ pipes = screen->info.r300_num_z_pipes;
+ } else {
+ pipes = screen->info.r300_num_gb_pipes;
+ }
+
+ for (i = 0; i <= tex->b.b.b.last_level; i++) {
+ unsigned zcomp_numdw, zcompsize, hiz_numdw, stride, height;
+
+ stride = align(tex->tex.stride_in_pixels[i], 16);
+ height = u_minify(tex->b.b.b.height0, i);
+
+ /* The 8x8 compression mode needs macrotiling. */
+ zcompsize = screen->caps.z_compress == R300_ZCOMP_8X8 &&
+ tex->tex.macrotile[i] &&
+ tex->b.b.b.nr_samples <= 1 ? 8 : 4;
+
+ /* Get the ZMASK buffer size in dwords. */
+ zcomp_numdw = r300_pixels_to_dwords(stride, height,
+ zmask_blocks_x_per_dw[pipes-1] * zcompsize,
+ zmask_blocks_y_per_dw[pipes-1] * zcompsize);
+
+ /* Check whether we have enough ZMASK memory. */
+ if (util_format_get_blocksizebits(tex->b.b.b.format) == 32 &&
+ zcomp_numdw <= screen->caps.zmask_ram * pipes) {
+ tex->tex.zmask_dwords[i] = zcomp_numdw;
+ tex->tex.zcomp8x8[i] = zcompsize == 8;
+
+ tex->tex.zmask_stride_in_pixels[i] =
+ util_align_npot(stride, zmask_blocks_x_per_dw[pipes-1] * zcompsize);
+ } else {
+ tex->tex.zmask_dwords[i] = 0;
+ tex->tex.zcomp8x8[i] = FALSE;
+ tex->tex.zmask_stride_in_pixels[i] = 0;
+ }
+
+ /* Now setup HIZ. */
+ stride = util_align_npot(stride, hiz_align_x[pipes-1]);
+ height = align(height, hiz_align_y[pipes-1]);
+
+ /* Get the HIZ buffer size in dwords. */
+ hiz_numdw = (stride * height) / (8*8 * pipes);
+
+ /* Check whether we have enough HIZ memory. */
+ if (hiz_numdw <= screen->caps.hiz_ram * pipes) {
+ tex->tex.hiz_dwords[i] = hiz_numdw;
+ tex->tex.hiz_stride_in_pixels[i] = stride;
+ } else {
+ tex->tex.hiz_dwords[i] = 0;
+ tex->tex.hiz_stride_in_pixels[i] = 0;
+ }
+ }
+ }