+ for (i = 0; i <= tex->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.format) &&
+ util_format_get_blocksizebits(tex->b.b.format) == 32 &&
+ tex->tex.microtile) {
+ unsigned i, pipes;
+
+ if (screen->caps.family == CHIP_RV530) {
+ pipes = screen->info.r300_num_z_pipes;
+ } else {
+ pipes = screen->info.r300_num_gb_pipes;
+ }
+
+ for (i = 0; i <= tex->b.b.last_level; i++) {
+ unsigned zcomp_numdw, zcompsize, hiz_numdw, stride, height;
+
+ stride = r300_stride_to_width(tex->b.b.format,
+ tex->tex.stride_in_bytes[i]);
+ stride = align(stride, 16);
+ height = u_minify(tex->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.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.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;
+ }
+ }
+ }
+}
+
+static void r300_setup_cmask_properties(struct r300_screen *screen,
+ struct r300_resource *tex)
+{
+ static unsigned cmask_align_x[4] = {16, 32, 48, 32};
+ static unsigned cmask_align_y[4] = {16, 16, 16, 32};
+ unsigned pipes, stride, cmask_num_dw, cmask_max_size;
+
+ if (!screen->caps.has_cmask) {
+ return;
+ }
+
+ /* We need an AA colorbuffer, no mipmaps. */
+ if (tex->b.b.nr_samples <= 1 ||
+ tex->b.b.last_level > 0 ||
+ util_format_is_depth_or_stencil(tex->b.b.format)) {
+ return;
+ }
+
+ /* FP16 AA needs R500 and a fairly new DRM. */
+ if ((tex->b.b.format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
+ tex->b.b.format == PIPE_FORMAT_R16G16B16X16_FLOAT) &&
+ (!screen->caps.is_r500 || screen->info.drm_minor < 29)) {
+ return;
+ }
+
+ if (SCREEN_DBG_ON(screen, DBG_NO_CMASK)) {
+ return;
+ }
+
+ /* CMASK is part of raster pipes. The number of Z pipes doesn't matter. */
+ pipes = screen->info.r300_num_gb_pipes;
+
+ /* The single-pipe cards have 5120 dwords of CMASK RAM,
+ * the other cards have 4096 dwords of CMASK RAM per pipe. */
+ cmask_max_size = pipes == 1 ? 5120 : pipes * 4096;
+
+ stride = r300_stride_to_width(tex->b.b.format,
+ tex->tex.stride_in_bytes[0]);
+ stride = align(stride, 16);
+
+ /* Get the CMASK size in dwords. */
+ cmask_num_dw = r300_pixels_to_dwords(stride, tex->b.b.height0,
+ cmask_align_x[pipes-1],
+ cmask_align_y[pipes-1]);
+
+ /* Check the CMASK size against the CMASK memory limit. */
+ if (cmask_num_dw <= cmask_max_size) {
+ tex->tex.cmask_dwords = cmask_num_dw;
+ tex->tex.cmask_stride_in_pixels =
+ util_align_npot(stride, cmask_align_x[pipes-1]);
+ }