static void r300_setup_flags(struct r300_resource *tex) { tex->tex.uses_stride_addressing = !util_is_power_of_two(tex->b.b.width0) || (tex->tex.stride_in_bytes_override && r300_stride_to_width(tex->b.b.format, tex->tex.stride_in_bytes_override) != tex->b.b.width0); tex->tex.is_npot = tex->tex.uses_stride_addressing || !util_is_power_of_two(tex->b.b.height0) || !util_is_power_of_two(tex->b.b.depth0); }
static void r300_tex_print_info(struct r300_resource *tex, const char *func) { fprintf(stderr, "r300: %s: Macro: %s, Micro: %s, Pitch: %i, Dim: %ix%ix%i, " "LastLevel: %i, Size: %i, Format: %s, Samples: %i\n", func, tex->tex.macrotile[0] ? "YES" : " NO", tex->tex.microtile ? "YES" : " NO", r300_stride_to_width(tex->b.b.format, tex->tex.stride_in_bytes[0]), tex->b.b.width0, tex->b.b.height0, tex->b.b.depth0, tex->b.b.last_level, tex->tex.size_in_bytes, util_format_short_name(tex->b.b.format), tex->b.b.nr_samples); }
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; /* 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]); } }
void r300_texture_setup_format_state(struct r300_screen *screen, struct r300_resource *tex, enum pipe_format format, unsigned level, unsigned width0_override, unsigned height0_override, struct r300_texture_format_state *out) { struct pipe_resource *pt = &tex->b.b; struct r300_texture_desc *desc = &tex->tex; boolean is_r500 = screen->caps.is_r500; unsigned width, height, depth; unsigned txwidth, txheight, txdepth; width = u_minify(width0_override, level); height = u_minify(height0_override, level); depth = u_minify(desc->depth0, level); txwidth = (width - 1) & 0x7ff; txheight = (height - 1) & 0x7ff; txdepth = util_logbase2(depth) & 0xf; /* Mask out all the fields we change. */ out->format0 = 0; out->format1 &= ~R300_TX_FORMAT_TEX_COORD_TYPE_MASK; out->format2 &= R500_TXFORMAT_MSB; out->tile_config = 0; /* Set sampler state. */ out->format0 = R300_TX_WIDTH(txwidth) | R300_TX_HEIGHT(txheight) | R300_TX_DEPTH(txdepth); if (desc->uses_stride_addressing) { unsigned stride = r300_stride_to_width(format, desc->stride_in_bytes[level]); /* rectangles love this */ out->format0 |= R300_TX_PITCH_EN; out->format2 = (stride - 1) & 0x1fff; } if (pt->target == PIPE_TEXTURE_CUBE) { out->format1 |= R300_TX_FORMAT_CUBIC_MAP; } if (pt->target == PIPE_TEXTURE_3D) { out->format1 |= R300_TX_FORMAT_3D; } /* large textures on r500 */ if (is_r500) { unsigned us_width = txwidth; unsigned us_height = txheight; unsigned us_depth = txdepth; if (width > 2048) { out->format2 |= R500_TXWIDTH_BIT11; } if (height > 2048) { out->format2 |= R500_TXHEIGHT_BIT11; } /* The US_FORMAT register fixes an R500 TX addressing bug. * Don't ask why it must be set like this. I don't know it either. */ if (width > 2048) { us_width = (0x000007FF + us_width) >> 1; us_depth |= 0x0000000D; } if (height > 2048) { us_height = (0x000007FF + us_height) >> 1; us_depth |= 0x0000000E; }
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; } } } }