r600g: EXT_texture_array support.
authorDave Airlie <airlied@redhat.com>
Thu, 17 Feb 2011 05:07:57 +0000 (15:07 +1000)
committerDave Airlie <airlied@redhat.com>
Thu, 24 Feb 2011 03:26:28 +0000 (13:26 +1000)
This adds EXT_texture_array support to r600g, it passes the piglit
array-texture test but I suspect may not be complete.

It currently requires a kernel patch to fix the CS checker to allow
these, so you need to use R600_ARRAY_TEXTURE=true for now
to enable them.

Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/drivers/r600/eg_state_inlines.h
src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/r600/r600_shader.c
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/r600/r600_state_inlines.h
src/gallium/drivers/r600/r600_texture.c

index f48b8a9..b5fcc71 100644 (file)
@@ -253,9 +253,13 @@ static inline unsigned r600_tex_dim(unsigned dim)
        default:
        case PIPE_TEXTURE_1D:
                return V_030000_SQ_TEX_DIM_1D;
+       case PIPE_TEXTURE_1D_ARRAY:
+               return V_030000_SQ_TEX_DIM_1D_ARRAY;
        case PIPE_TEXTURE_2D:
        case PIPE_TEXTURE_RECT:
                return V_030000_SQ_TEX_DIM_2D;
+       case PIPE_TEXTURE_2D_ARRAY:
+               return V_030000_SQ_TEX_DIM_2D_ARRAY;
        case PIPE_TEXTURE_3D:
                return V_030000_SQ_TEX_DIM_3D;
        case PIPE_TEXTURE_CUBE:
index 79b0d02..62d108f 100644 (file)
@@ -292,9 +292,12 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_PRIMITIVE_RESTART:
        case PIPE_CAP_INDEP_BLEND_FUNC: /* FIXME allow this */
        case PIPE_CAP_INSTANCED_DRAWING:
-       case PIPE_CAP_ARRAY_TEXTURES:
                return 0;
 
+       case PIPE_CAP_ARRAY_TEXTURES:
+               /* fix once the CS checker upstream is fixed */
+               return debug_get_bool_option("R600_ARRAY_TEXTURE", FALSE);
+
        /* Texturing. */
        case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
        case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
index acb3ef2..13ccc3f 100644 (file)
@@ -1850,6 +1850,12 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
                tex.coord_type_w = 1;
        }
 
+       if (inst->Texture.Texture == TGSI_TEXTURE_1D_ARRAY) {
+               tex.coord_type_z = 0;
+               tex.src_sel_z = 1;
+       } else if (inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY)
+               tex.coord_type_z = 0;
+
        if (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D || inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D)
                tex.src_sel_w = 2;
 
index a1f83ac..c365979 100644 (file)
@@ -402,6 +402,7 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c
        uint32_t word4 = 0, yuv_format = 0, pitch = 0;
        unsigned char swizzle[4], array_mode = 0, tile_type = 0;
        struct r600_bo *bo[2];
+       unsigned height, depth;
 
        if (resource == NULL)
                return NULL;
@@ -446,6 +447,15 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c
        array_mode = tmp->array_mode[0];
        tile_type = tmp->tile_type;
 
+       height = texture->height0;
+       depth = texture->depth0;
+       if (texture->target == PIPE_TEXTURE_1D_ARRAY) {
+               height = 1;
+               depth = texture->array_size;
+       } else if (texture->target == PIPE_TEXTURE_2D_ARRAY) {
+               depth = texture->array_size;
+       }
+
        /* FIXME properly handle first level != 0 */
        r600_pipe_state_add_reg(rstate, R_038000_RESOURCE0_WORD0,
                                S_038000_DIM(r600_tex_dim(texture->target)) |
@@ -454,8 +464,8 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c
                                S_038000_PITCH((pitch / 8) - 1) |
                                S_038000_TEX_WIDTH(texture->width0 - 1), 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate, R_038004_RESOURCE0_WORD1,
-                               S_038004_TEX_HEIGHT(texture->height0 - 1) |
-                               S_038004_TEX_DEPTH(texture->depth0 - 1) |
+                               S_038004_TEX_HEIGHT(height - 1) |
+                               S_038004_TEX_DEPTH(depth - 1) |
                                S_038004_DATA_FORMAT(format), 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate, R_038008_RESOURCE0_WORD2,
                                (tmp->offset[0] + r600_bo_offset(bo[0])) >> 8, 0xFFFFFFFF, bo[0]);
@@ -468,8 +478,8 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c
                                S_038010_BASE_LEVEL(state->u.tex.first_level), 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate, R_038014_RESOURCE0_WORD5,
                                S_038014_LAST_LEVEL(state->u.tex.last_level) |
-                               S_038014_BASE_ARRAY(0) |
-                               S_038014_LAST_ARRAY(0), 0xFFFFFFFF, NULL);
+                               S_038014_BASE_ARRAY(state->u.tex.first_layer) |
+                               S_038014_LAST_ARRAY(state->u.tex.last_layer), 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate, R_038018_RESOURCE0_WORD6,
                                S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_TEXTURE), 0xFFFFFFFF, NULL);
 
index 7d5c9e0..29e12f1 100644 (file)
@@ -253,9 +253,13 @@ static inline unsigned r600_tex_dim(unsigned dim)
        default:
        case PIPE_TEXTURE_1D:
                return V_038000_SQ_TEX_DIM_1D;
+       case PIPE_TEXTURE_1D_ARRAY:
+               return V_038000_SQ_TEX_DIM_1D_ARRAY;
        case PIPE_TEXTURE_2D:
        case PIPE_TEXTURE_RECT:
                return V_038000_SQ_TEX_DIM_2D;
+       case PIPE_TEXTURE_2D_ARRAY:
+               return V_038000_SQ_TEX_DIM_2D_ARRAY;
        case PIPE_TEXTURE_3D:
                return V_038000_SQ_TEX_DIM_3D;
        case PIPE_TEXTURE_CUBE:
index ce06d74..095558d 100644 (file)
@@ -79,10 +79,8 @@ unsigned r600_texture_get_offset(struct r600_resource_texture *rtex,
        switch (rtex->resource.b.b.b.target) {
        case PIPE_TEXTURE_3D:
        case PIPE_TEXTURE_CUBE:
-               return offset + layer * rtex->layer_size[level];
        default:
-               assert(layer == 0);
-               return offset;
+               return offset + layer * rtex->layer_size[level];
        }
 }
 
@@ -262,8 +260,11 @@ static void r600_setup_miptree(struct pipe_screen *screen,
                        else
                                size = layer_size * 6;
                }
-               else
+               else if (ptex->target == PIPE_TEXTURE_3D)
                        size = layer_size * u_minify(ptex->depth0, i);
+               else
+                       size = layer_size * ptex->array_size;
+
                /* align base image and start of miptree */
                if ((i == 0) || (i == 1))
                        offset = align(offset, r600_get_base_alignment(screen, ptex->format, array_mode));
@@ -507,6 +508,7 @@ int r600_texture_depth_flush(struct pipe_context *ctx,
        resource.width0 = texture->width0;
        resource.height0 = texture->height0;
        resource.depth0 = 1;
+       resource.array_size = 1;
        resource.last_level = texture->last_level;
        resource.nr_samples = 0;
        resource.usage = PIPE_USAGE_DYNAMIC;
@@ -642,6 +644,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
                return &trans->transfer;
        }
        trans->transfer.stride = rtex->pitch_in_bytes[level];
+       trans->transfer.layer_stride = rtex->layer_size[level];
        trans->offset = r600_texture_get_offset(rtex, level, box->z);
        return &trans->transfer;
 }