mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 00:58:05 +02:00
r300g: fix blitting between 2D NPOT mipmaps
Even though MIP filtering is not supported, we can bind an arbitrary mipmap as the zero mipmap level. NPOT textures now follow GL_TEXTURE_BASE_LEVEL and GL_TEXTURE_MIN_LOD. This fixes piglit/fbo-copyteximage.
This commit is contained in:
parent
c0f0eb8668
commit
c5b8ba9368
4 changed files with 52 additions and 24 deletions
|
|
@ -1607,6 +1607,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
# define R300_TX_FORMAT_3D (1 << 25)
|
||||
# define R300_TX_FORMAT_CUBIC_MAP (2 << 25)
|
||||
# define R300_TX_FORMAT_TEX_COORD_TYPE_MASK (0x3 << 25)
|
||||
|
||||
/* alpha modes, convenience mostly */
|
||||
/* if you have alpha, pick constant appropriate to the
|
||||
|
|
|
|||
|
|
@ -592,6 +592,25 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
|
|||
texstate->filter1 = sampler->filter1;
|
||||
texstate->border_color = sampler->border_color;
|
||||
|
||||
/* determine min/max levels */
|
||||
max_level = MIN3(sampler->max_lod + view->base.first_level,
|
||||
tex->desc.b.b.last_level, view->base.last_level);
|
||||
min_level = MIN2(sampler->min_lod + view->base.first_level,
|
||||
max_level);
|
||||
|
||||
if (tex->desc.is_npot && min_level > 0) {
|
||||
/* Even though we do not implement mipmapping for NPOT
|
||||
* textures, we should at least honor the minimum level
|
||||
* which is allowed to be displayed. We do this by setting up
|
||||
* an i-th mipmap level as the zero level. */
|
||||
r300_texture_setup_format_state(r300->screen, &tex->desc,
|
||||
min_level,
|
||||
&texstate->format);
|
||||
texstate->format.tile_config |=
|
||||
tex->desc.offset_in_bytes[min_level] & 0xffffffe0;
|
||||
assert((tex->desc.offset_in_bytes[min_level] & 0x1f) == 0);
|
||||
}
|
||||
|
||||
/* Assign a texture cache region. */
|
||||
texstate->format.format1 |= view->texcache_region;
|
||||
|
||||
|
|
@ -654,12 +673,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
|
|||
texstate->filter0 |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE);
|
||||
}
|
||||
} else {
|
||||
/* determine min/max levels */
|
||||
/* the MAX_MIP level is the largest (finest) one */
|
||||
max_level = MIN3(sampler->max_lod + view->base.first_level,
|
||||
tex->desc.b.b.last_level, view->base.last_level);
|
||||
min_level = MIN2(sampler->min_lod + view->base.first_level,
|
||||
max_level);
|
||||
texstate->format.format0 |= R300_TX_NUM_LEVELS(max_level);
|
||||
texstate->filter0 |= R300_TX_MAX_MIP_LEVEL(min_level);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -541,48 +541,55 @@ boolean r300_is_sampler_format_supported(enum pipe_format format)
|
|||
return r300_translate_texformat(format, 0, TRUE) != ~0;
|
||||
}
|
||||
|
||||
static void r300_texture_setup_immutable_state(struct r300_screen* screen,
|
||||
struct r300_texture* tex)
|
||||
void r300_texture_setup_format_state(struct r300_screen *screen,
|
||||
struct r300_texture_desc *desc,
|
||||
unsigned level,
|
||||
struct r300_texture_format_state *out)
|
||||
{
|
||||
struct r300_texture_format_state* f = &tex->tx_format;
|
||||
struct pipe_resource *pt = &tex->desc.b.b;
|
||||
struct pipe_resource *pt = &desc->b.b;
|
||||
boolean is_r500 = screen->caps.is_r500;
|
||||
|
||||
/* Set sampler state. */
|
||||
f->format0 = R300_TX_WIDTH((pt->width0 - 1) & 0x7ff) |
|
||||
R300_TX_HEIGHT((pt->height0 - 1) & 0x7ff);
|
||||
/* 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;
|
||||
|
||||
if (tex->desc.uses_stride_addressing) {
|
||||
/* 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 */
|
||||
f->format0 |= R300_TX_PITCH_EN;
|
||||
f->format2 = (tex->desc.stride_in_pixels[0] - 1) & 0x1fff;
|
||||
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. */
|
||||
f->format0 |= R300_TX_DEPTH(util_logbase2(pt->depth0) & 0xf);
|
||||
out->format0 |=
|
||||
R300_TX_DEPTH(util_logbase2(u_minify(pt->depth0, level)) & 0xf);
|
||||
}
|
||||
|
||||
f->format1 = 0;
|
||||
if (pt->target == PIPE_TEXTURE_CUBE) {
|
||||
f->format1 |= R300_TX_FORMAT_CUBIC_MAP;
|
||||
out->format1 |= R300_TX_FORMAT_CUBIC_MAP;
|
||||
}
|
||||
if (pt->target == PIPE_TEXTURE_3D) {
|
||||
f->format1 |= R300_TX_FORMAT_3D;
|
||||
out->format1 |= R300_TX_FORMAT_3D;
|
||||
}
|
||||
|
||||
/* large textures on r500 */
|
||||
if (is_r500)
|
||||
{
|
||||
if (pt->width0 > 2048) {
|
||||
f->format2 |= R500_TXWIDTH_BIT11;
|
||||
out->format2 |= R500_TXWIDTH_BIT11;
|
||||
}
|
||||
if (pt->height0 > 2048) {
|
||||
f->format2 |= R500_TXHEIGHT_BIT11;
|
||||
out->format2 |= R500_TXHEIGHT_BIT11;
|
||||
}
|
||||
}
|
||||
|
||||
f->tile_config = R300_TXO_MACRO_TILE(tex->desc.macrotile[0]) |
|
||||
R300_TXO_MICRO_TILE(tex->desc.microtile);
|
||||
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_screen* screen,
|
||||
|
|
@ -716,7 +723,7 @@ r300_texture_create_object(struct r300_screen *rscreen,
|
|||
return NULL;
|
||||
}
|
||||
/* Initialize the hardware state. */
|
||||
r300_texture_setup_immutable_state(rscreen, tex);
|
||||
r300_texture_setup_format_state(rscreen, &tex->desc, 0, &tex->tx_format);
|
||||
r300_texture_setup_fb_state(rscreen, tex);
|
||||
|
||||
tex->desc.b.vtbl = &r300_texture_vtbl;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
struct pipe_screen;
|
||||
struct pipe_resource;
|
||||
struct winsys_handle;
|
||||
struct r300_texture_format_state;
|
||||
struct r300_texture_desc;
|
||||
struct r300_texture;
|
||||
struct r300_screen;
|
||||
|
||||
|
|
@ -51,6 +53,10 @@ boolean r300_is_zs_format_supported(enum pipe_format format);
|
|||
|
||||
boolean r300_is_sampler_format_supported(enum pipe_format format);
|
||||
|
||||
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*
|
||||
r300_texture_from_handle(struct pipe_screen* screen,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue