+static int r600_init_surface(struct radeon_surface *surface,
+ const struct pipe_resource *ptex,
+ unsigned array_mode)
+{
+ surface->npix_x = ptex->width0;
+ surface->npix_y = ptex->height0;
+ surface->npix_z = ptex->depth0;
+ surface->blk_w = util_format_get_blockwidth(ptex->format);
+ surface->blk_h = util_format_get_blockheight(ptex->format);
+ surface->blk_d = 1;
+ surface->array_size = 1;
+ surface->last_level = ptex->last_level;
+ surface->bpe = util_format_get_blocksize(ptex->format);
+ /* align byte per element on dword */
+ if (surface->bpe == 3) {
+ surface->bpe = 4;
+ }
+ surface->nsamples = 1;
+ surface->flags = 0;
+ switch (array_mode) {
+ case V_038000_ARRAY_1D_TILED_THIN1:
+ surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
+ break;
+ case V_038000_ARRAY_2D_TILED_THIN1:
+ surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
+ break;
+ case V_038000_ARRAY_LINEAR_ALIGNED:
+ surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
+ break;
+ case V_038000_ARRAY_LINEAR_GENERAL:
+ default:
+ surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE);
+ break;
+ }
+ switch (ptex->target) {
+ case PIPE_TEXTURE_1D:
+ surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE);
+ break;
+ case PIPE_TEXTURE_RECT:
+ case PIPE_TEXTURE_2D:
+ surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
+ break;
+ case PIPE_TEXTURE_3D:
+ surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE);
+ break;
+ case PIPE_TEXTURE_1D_ARRAY:
+ surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE);
+ surface->array_size = ptex->array_size;
+ break;
+ case PIPE_TEXTURE_2D_ARRAY:
+ surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE);
+ surface->array_size = ptex->array_size;
+ break;
+ case PIPE_TEXTURE_CUBE:
+ surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_CUBEMAP, TYPE);
+ break;
+ case PIPE_BUFFER:
+ default:
+ return -EINVAL;
+ }
+ if (ptex->bind & PIPE_BIND_SCANOUT) {
+ surface->flags |= RADEON_SURF_SCANOUT;
+ }
+ if (util_format_is_depth_and_stencil(ptex->format)) {
+ surface->flags |= RADEON_SURF_ZBUFFER;
+ surface->flags |= RADEON_SURF_SBUFFER;
+ }
+
+ return 0;
+}
+
+static int r600_setup_surface(struct pipe_screen *screen,
+ struct r600_resource_texture *rtex,
+ unsigned array_mode,
+ unsigned pitch_in_bytes_override)
+{
+ struct pipe_resource *ptex = &rtex->resource.b.b.b;
+ struct r600_screen *rscreen = (struct r600_screen*)screen;
+ unsigned i;
+ int r;
+
+ if (util_format_is_depth_or_stencil(rtex->real_format)) {
+ rtex->surface.flags |= RADEON_SURF_ZBUFFER;
+ rtex->surface.flags |= RADEON_SURF_SBUFFER;
+ }
+
+ r = rscreen->ws->surface_init(rscreen->ws, &rtex->surface);
+ if (r) {
+ return r;
+ }
+ rtex->size = rtex->surface.bo_size;
+ if (pitch_in_bytes_override && pitch_in_bytes_override != rtex->surface.level[0].pitch_bytes) {
+ /* old ddx on evergreen over estimate alignment for 1d, only 1 level
+ * for those
+ */
+ rtex->surface.level[0].nblk_x = pitch_in_bytes_override / rtex->surface.bpe;
+ rtex->surface.level[0].pitch_bytes = pitch_in_bytes_override;
+ rtex->surface.level[0].slice_size = pitch_in_bytes_override * rtex->surface.level[0].nblk_y;
+ if (rtex->surface.flags & RADEON_SURF_SBUFFER) {
+ rtex->surface.stencil_offset = rtex->surface.level[0].slice_size;
+ }
+ }
+ for (i = 0; i <= ptex->last_level; i++) {
+ rtex->offset[i] = rtex->surface.level[i].offset;
+ rtex->layer_size[i] = rtex->surface.level[i].slice_size;
+ rtex->pitch_in_bytes[i] = rtex->surface.level[i].pitch_bytes;
+ switch (rtex->surface.level[i].mode) {
+ case RADEON_SURF_MODE_LINEAR_ALIGNED:
+ rtex->array_mode[i] = V_038000_ARRAY_LINEAR_ALIGNED;
+ break;
+ case RADEON_SURF_MODE_1D:
+ rtex->array_mode[i] = V_038000_ARRAY_1D_TILED_THIN1;
+ break;
+ case RADEON_SURF_MODE_2D:
+ rtex->array_mode[i] = V_038000_ARRAY_2D_TILED_THIN1;
+ break;
+ default:
+ case RADEON_SURF_MODE_LINEAR:
+ rtex->array_mode[i] = 0;
+ break;
+ }
+ }
+ return 0;
+}
+