void r300_texture_setup_format_state(struct r300_screen *screen, struct r300_texture_desc *desc, unsigned level, struct r300_texture_format_state *out) { struct pipe_resource *pt = &desc->b.b; boolean is_r500 = screen->caps.is_r500; /* 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((u_minify(pt->width0, level) - 1) & 0x7ff) | R300_TX_HEIGHT((u_minify(pt->height0, level) - 1) & 0x7ff); if (desc->uses_stride_addressing) { /* rectangles love this */ out->format0 |= R300_TX_PITCH_EN; out->format2 = (desc->stride_in_pixels[level] - 1) & 0x1fff; } else { /* Power of two textures (3D, mipmaps, and no pitch), * also NPOT textures with a width being POT. */ out->format0 |= R300_TX_DEPTH(util_logbase2(u_minify(pt->depth0, level)) & 0xf); } 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) { if (pt->width0 > 2048) { out->format2 |= R500_TXWIDTH_BIT11; } if (pt->height0 > 2048) { out->format2 |= R500_TXHEIGHT_BIT11; } } out->tile_config = R300_TXO_MACRO_TILE(desc->macrotile[level]) | R300_TXO_MICRO_TILE(desc->microtile); }
/* 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; } out->us_format0 = R300_TX_WIDTH(us_width) | R300_TX_HEIGHT(us_height) | R300_TX_DEPTH(us_depth); } out->tile_config = R300_TXO_MACRO_TILE(desc->macrotile[level]) | R300_TXO_MICRO_TILE(desc->microtile); } static void r300_texture_setup_fb_state(struct r300_surface *surf) { struct r300_resource *tex = r300_resource(surf->base.texture); unsigned level = surf->base.u.tex.level; unsigned stride = r300_stride_to_width(surf->base.format, tex->tex.stride_in_bytes[level]); /* Set framebuffer state. */ if (util_format_is_depth_or_stencil(surf->base.format)) {
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_texture_state(struct r300_screen* screen, struct r300_texture* tex) { struct r300_texture_format_state* state = &tex->state; struct pipe_texture *pt = &tex->tex; unsigned i; boolean is_r500 = screen->caps->is_r500; /* Set sampler state. */ state->format0 = R300_TX_WIDTH((pt->width0 - 1) & 0x7ff) | R300_TX_HEIGHT((pt->height0 - 1) & 0x7ff); if (tex->is_npot) { /* rectangles love this */ state->format0 |= R300_TX_PITCH_EN; state->format2 = (tex->pitch[0] - 1) & 0x1fff; } else { /* power of two textures (3D, mipmaps, and no pitch) */ state->format0 |= R300_TX_DEPTH(util_logbase2(pt->depth0) & 0xf); } state->format1 = r300_translate_texformat(pt->format); if (pt->target == PIPE_TEXTURE_CUBE) { state->format1 |= R300_TX_FORMAT_CUBIC_MAP; } if (pt->target == PIPE_TEXTURE_3D) { state->format1 |= R300_TX_FORMAT_3D; } /* large textures on r500 */ if (is_r500) { if (pt->width0 > 2048) { state->format2 |= R500_TXWIDTH_BIT11; } if (pt->height0 > 2048) { state->format2 |= R500_TXHEIGHT_BIT11; } } SCREEN_DBG(screen, DBG_TEX, "r300: Set texture state (%dx%d, %d levels)\n", pt->width0, pt->height0, pt->last_level); /* Set framebuffer state. */ if (util_format_is_depth_or_stencil(tex->tex.format)) { for (i = 0; i <= tex->tex.last_level; i++) { tex->fb_state.depthpitch[i] = tex->pitch[i] | R300_DEPTHMACROTILE(tex->mip_macrotile[i]) | R300_DEPTHMICROTILE(tex->microtile); } tex->fb_state.zb_format = r300_translate_zsformat(tex->tex.format); } else { for (i = 0; i <= tex->tex.last_level; i++) { tex->fb_state.colorpitch[i] = tex->pitch[i] | r300_translate_colorformat(tex->tex.format) | R300_COLOR_TILE(tex->mip_macrotile[i]) | R300_COLOR_MICROTILE(tex->microtile); } tex->fb_state.us_out_fmt = r300_translate_out_fmt(tex->tex.format); } }