From patchwork Thu Jan 17 18:08:49 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Michel_D=C3=A4nzer?= X-Patchwork-Id: 1997631 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork2.kernel.org (Postfix) with ESMTP id C1F82DFB77 for ; Thu, 17 Jan 2013 18:11:54 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8D93BE6CB9 for ; Thu, 17 Jan 2013 10:11:54 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail.gna.ch (darkcity.gna.ch [195.226.6.51]) by gabe.freedesktop.org (Postfix) with ESMTP id D1ADDE6C8C for ; Thu, 17 Jan 2013 10:09:01 -0800 (PST) Received: from localhost (localhost [127.0.0.1]) by darkcity.gna.ch (Postfix) with ESMTP id 3FC045E0A1A for ; Thu, 17 Jan 2013 19:06:47 +0100 (CET) X-Virus-Scanned: amavisd-new at gna.ch Received: from mail.gna.ch ([127.0.0.1]) by localhost (darkcity.gna.ch [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id r3M8cEqRtpa2 for ; Thu, 17 Jan 2013 19:06:36 +0100 (CET) Received: from ruby.local (77-56-77-139.dclient.hispeed.ch [77.56.77.139]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by darkcity.gna.ch (Postfix) with ESMTPSA id AC19A5E0901 for ; Thu, 17 Jan 2013 19:06:36 +0100 (CET) Received: from daenzer by ruby.local with local (Exim 4.80) (envelope-from ) id 1TvttR-0003Oi-LX for dri-devel@lists.freedesktop.org; Thu, 17 Jan 2013 19:08:49 +0100 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= To: dri-devel@lists.freedesktop.org Subject: [PATCH libdrm] radeon: Fix 1D tiling layout on SI. Date: Thu, 17 Jan 2013 19:08:49 +0100 Message-Id: <1358446129-13029-1-git-send-email-michel@daenzer.net> X-Mailer: git-send-email 1.7.10.4 MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org From: Michel Dänzer Very similar to Evergreen, but slightly different rules for tile / slice alignment. Fortunately, these map quite naturally onto the previous fixes for linear aligned layout on SI. 2D tiling still needs more work here and possibly in the kernel. Signed-off-by: Michel Dänzer --- radeon/radeon_surface.c | 111 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 88 insertions(+), 23 deletions(-) diff --git a/radeon/radeon_surface.c b/radeon/radeon_surface.c index eb587d2..8e93873 100644 --- a/radeon/radeon_surface.c +++ b/radeon/radeon_surface.c @@ -1000,25 +1000,28 @@ static int eg_surface_best(struct radeon_surface_manager *surf_man, * Southern Islands family */ -static void si_surf_minify_linear_aligned(struct radeon_surface *surf, - unsigned level, - uint32_t xalign, uint32_t yalign, uint32_t zalign, uint32_t slice_align, - unsigned offset) +static void si_surf_minify(struct radeon_surface *surf, + struct radeon_surface_level *surflevel, + unsigned bpe, unsigned level, + uint32_t xalign, uint32_t yalign, uint32_t zalign, uint32_t slice_align, + unsigned offset) { - surf->level[level].npix_x = mip_minify(surf->npix_x, level); - surf->level[level].npix_y = mip_minify(surf->npix_y, level); - surf->level[level].npix_z = mip_minify(surf->npix_z, level); + surflevel->npix_x = mip_minify(surf->npix_x, level); + surflevel->npix_y = mip_minify(surf->npix_y, level); + surflevel->npix_z = mip_minify(surf->npix_z, level); if (level == 0 && surf->last_level > 0) { - surf->level[level].nblk_x = (next_power_of_two(surf->level[level].npix_x) + surf->blk_w - 1) / surf->blk_w; - surf->level[level].nblk_y = (next_power_of_two(surf->level[level].npix_y) + surf->blk_h - 1) / surf->blk_h; - surf->level[level].nblk_z = (next_power_of_two(surf->level[level].npix_z) + surf->blk_d - 1) / surf->blk_d; + surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w; + surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h; + surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d; } else { - surf->level[level].nblk_x = (surf->level[level].npix_x + surf->blk_w - 1) / surf->blk_w; - surf->level[level].nblk_y = (surf->level[level].npix_y + surf->blk_h - 1) / surf->blk_h; - surf->level[level].nblk_z = (surf->level[level].npix_z + surf->blk_d - 1) / surf->blk_d; + surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w; + surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h; + surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d; } + surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign); + /* XXX: Texture sampling uses unexpectedly large pitches in some cases, * these are just guesses for the rules behind those */ @@ -1027,17 +1030,16 @@ static void si_surf_minify_linear_aligned(struct radeon_surface *surf, xalign = MAX2(xalign, slice_align / surf->bpe); else /* Small rows evenly distributed across slice */ - xalign = MAX2(xalign, slice_align / surf->bpe / surf->level[level].npix_y); + xalign = MAX2(xalign, slice_align / surf->bpe / surflevel->nblk_y); - surf->level[level].nblk_x = ALIGN(surf->level[level].nblk_x, xalign); - surf->level[level].nblk_y = ALIGN(surf->level[level].nblk_y, yalign); - surf->level[level].nblk_z = ALIGN(surf->level[level].nblk_z, zalign); + surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign); + surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign); - surf->level[level].offset = offset; - surf->level[level].pitch_bytes = surf->level[level].nblk_x * surf->bpe * surf->nsamples; - surf->level[level].slice_size = ALIGN(surf->level[level].pitch_bytes * surf->level[level].nblk_y, slice_align); + surflevel->offset = offset; + surflevel->pitch_bytes = surflevel->nblk_x * surf->bpe * surf->nsamples; + surflevel->slice_size = ALIGN(surflevel->pitch_bytes * surflevel->nblk_y, slice_align); - surf->bo_size = offset + surf->level[level].slice_size * surf->level[level].nblk_z * surf->array_size; + surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size; } static int si_surface_init_linear_aligned(struct radeon_surface_manager *surf_man, @@ -1059,7 +1061,48 @@ static int si_surface_init_linear_aligned(struct radeon_surface_manager *surf_ma /* build mipmap tree */ for (i = start_level; i <= surf->last_level; i++) { surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED; - si_surf_minify_linear_aligned(surf, i, xalign, yalign, zalign, slice_align, offset); + si_surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, + zalign, slice_align, offset); + /* level0 and first mipmap need to have alignment */ + offset = surf->bo_size; + if ((i == 0)) { + offset = ALIGN(offset, surf->bo_alignment); + } + } + return 0; +} + +static int si_surface_init_1d(struct radeon_surface_manager *surf_man, + struct radeon_surface *surf, + struct radeon_surface_level *level, + unsigned bpe, + uint64_t offset, unsigned start_level) +{ + uint32_t xalign, yalign, zalign, slice_align; + unsigned i; + + /* compute alignment */ + xalign = 8; + yalign = 8; + zalign = 1; + slice_align = surf_man->hw_info.group_bytes; + if (surf->flags & RADEON_SURF_SCANOUT) { + xalign = MAX2((bpe == 1) ? 64 : 32, xalign); + } + + if (!start_level) { + unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes); + surf->bo_alignment = MAX2(surf->bo_alignment, alignment); + + if (offset) { + offset = ALIGN(offset, alignment); + } + } + + /* build mipmap tree */ + for (i = start_level; i <= surf->last_level; i++) { + level[i].mode = RADEON_SURF_MODE_1D; + si_surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, slice_align, offset); /* level0 and first mipmap need to have alignment */ offset = surf->bo_size; if ((i == 0)) { @@ -1069,6 +1112,28 @@ static int si_surface_init_linear_aligned(struct radeon_surface_manager *surf_ma return 0; } +static int si_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man, + struct radeon_surface *surf) +{ + unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER; + int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags; + /* Old libdrm headers didn't have stencil_level in it. This prevents crashes. */ + struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL]; + struct radeon_surface_level *stencil_level = + (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp; + + r = si_surface_init_1d(surf_man, surf, surf->level, surf->bpe, 0, 0); + if (r) + return r; + + if (is_depth_stencil) { + r = si_surface_init_1d(surf_man, surf, stencil_level, 1, + surf->bo_size, 0); + surf->stencil_offset = stencil_level[0].offset; + } + return r; +} + static int si_surface_init(struct radeon_surface_manager *surf_man, struct radeon_surface *surf) { @@ -1115,7 +1180,7 @@ static int si_surface_init(struct radeon_surface_manager *surf_man, r = si_surface_init_linear_aligned(surf_man, surf, 0, 0); break; case RADEON_SURF_MODE_1D: - r = eg_surface_init_1d_miptrees(surf_man, surf); + r = si_surface_init_1d_miptrees(surf_man, surf); break; case RADEON_SURF_MODE_2D: r = eg_surface_init_2d_miptrees(surf_man, surf);