diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gallium/drivers/r300/r300_context.h | 8 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_emit.c | 16 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_texture.c | 35 | 
3 files changed, 42 insertions, 17 deletions
| diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 4d73567bbe..cee0734d21 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -181,6 +181,9 @@ struct r300_texture {      /* Offsets into the buffer. */      unsigned offset[PIPE_MAX_TEXTURE_LEVELS]; +    /* A pitch for each mip-level */ +    unsigned pitch[PIPE_MAX_TEXTURE_LEVELS]; +      /* Size of one zslice or face based on the texture target */      unsigned layer_size[PIPE_MAX_TEXTURE_LEVELS]; @@ -197,6 +200,11 @@ struct r300_texture {      /* Total size of this texture, in bytes. */      unsigned size; +    /* Whether this texture has non-power-of-two dimensions. +     * It can be either a regular texture or a rectangle one. +     */ +    boolean is_npot; +      /* Pipe buffer backing this texture. */      struct pipe_buffer* buffer; diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 3b0b41e486..be38fbc619 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -285,21 +285,22 @@ void r300_emit_fb_state(struct r300_context* r300,                          struct pipe_framebuffer_state* fb)  {      struct r300_texture* tex; -    unsigned pixpitch; +    struct pipe_surface* surf;      int i;      CS_LOCALS(r300);      BEGIN_CS((10 * fb->nr_cbufs) + (fb->zsbuf ? 10 : 0) + 4);      for (i = 0; i < fb->nr_cbufs; i++) { -        tex = (struct r300_texture*)fb->cbufs[i]->texture; +        surf = fb->cbufs[i]; +        tex = (struct r300_texture*)surf->texture;          assert(tex && tex->buffer && "cbuf is marked, but NULL!"); -        pixpitch = r300_texture_get_stride(tex, 0) / tex->tex.block.size; +        /* XXX I still need to figure out how to set the mipmap level here */          OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1);          OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);          OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1); -        OUT_CS_RELOC(tex->buffer, pixpitch | +        OUT_CS_RELOC(tex->buffer, tex->pitch[surf->level] |                       r300_translate_colorformat(tex->tex.format), 0,                       RADEON_GEM_DOMAIN_VRAM, 0); @@ -308,9 +309,9 @@ void r300_emit_fb_state(struct r300_context* r300,      }      if (fb->zsbuf) { -        tex = (struct r300_texture*)fb->zsbuf->texture; +        surf = fb->zsbuf; +        tex = (struct r300_texture*)surf->texture;          assert(tex && tex->buffer && "zsbuf is marked, but NULL!"); -        pixpitch = r300_texture_get_stride(tex, 0) / tex->tex.block.size;          OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1);          OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); @@ -318,7 +319,8 @@ void r300_emit_fb_state(struct r300_context* r300,          OUT_CS_REG(R300_ZB_FORMAT, r300_translate_zsformat(tex->tex.format));          OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); -        OUT_CS_RELOC(tex->buffer, pixpitch, 0, RADEON_GEM_DOMAIN_VRAM, 0); +        OUT_CS_RELOC(tex->buffer, tex->pitch[surf->level], 0, +                     RADEON_GEM_DOMAIN_VRAM, 0);      }      OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 3e90fea6c8..7199918a84 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -33,21 +33,15 @@ static void r300_setup_texture_state(struct r300_texture* tex, boolean is_r500)  {      struct r300_texture_state* state = &tex->state;      struct pipe_texture *pt = &tex->tex; -    unsigned stride;      state->format0 = R300_TX_WIDTH((pt->width[0] - 1) & 0x7ff) |                       R300_TX_HEIGHT((pt->height[0] - 1) & 0x7ff); -    if (!util_is_power_of_two(pt->width[0]) || -        !util_is_power_of_two(pt->height[0])) { - +    if (tex->is_npot) {          /* rectangles love this */          state->format0 |= R300_TX_PITCH_EN; - -        stride = r300_texture_get_stride(tex, 0) / pt->block.size; -        state->format2 = (stride - 1) & 0x1fff; -    } -    else { +        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->depth[0]) & 0xf) |                            R300_TX_NUM_LEVELS(pt->last_level & 0xf); @@ -143,6 +137,12 @@ static void r300_setup_miptree(struct r300_texture* tex)          tex->size = tex->offset[i] + size;          tex->layer_size[i] = layer_size; +        if (tex->is_npot) { +            tex->pitch[i] = stride / base->block.size; +        } else { +            tex->pitch[i] = base->width[i]; +        } +          debug_printf("r300: Texture miptree: Level %d "                  "(%dx%dx%d px, pitch %d bytes)\n",                  i, base->width[i], base->height[i], base->depth[i], @@ -150,6 +150,12 @@ static void r300_setup_miptree(struct r300_texture* tex)      }  } +static void r300_setup_flags(struct r300_texture* tex) +{ +    tex->is_npot = !util_is_power_of_two(tex->tex.width[0]) || +                   !util_is_power_of_two(tex->tex.height[0]); +} +  /* Create a new texture. */  static struct pipe_texture*      r300_texture_create(struct pipe_screen* screen, @@ -165,8 +171,8 @@ static struct pipe_texture*      pipe_reference_init(&tex->tex.reference, 1);      tex->tex.screen = screen; +    r300_setup_flags(tex);      r300_setup_miptree(tex); -      r300_setup_texture_state(tex, r300_screen(screen)->caps->is_r500);      tex->buffer = screen->buffer_create(screen, 1024, @@ -234,6 +240,13 @@ static struct pipe_texture*  {      struct r300_texture* tex; +    /* Support only 2D textures without mipmaps */ +    if (base->target != PIPE_TEXTURE_2D || +        base->depth[0] != 1 || +        base->last_level != 0) { +        return NULL; +    } +      tex = CALLOC_STRUCT(r300_texture);      if (!tex) {          return NULL; @@ -244,7 +257,9 @@ static struct pipe_texture*      tex->tex.screen = screen;      tex->stride_override = *stride; +    tex->pitch[0] = *stride / base->block.size; +    r300_setup_flags(tex);      r300_setup_texture_state(tex, r300_screen(screen)->caps->is_r500);      pipe_buffer_reference(&tex->buffer, buffer); | 
