summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Olšák <marek.olsak@amd.com>2014-08-07 21:14:31 +0200
committerCarl Worth <cworth@cworth.org>2014-08-11 14:36:24 -0700
commit629df2fbddc2938116497ec664ab622b0de1a61f (patch)
tree7a2d6fbd2c5580b0ba4f3371ec269a9820ab116a
parent22ec7df0d7687eb7db72ac2a004b21d4cb35ec7b (diff)
radeonsi: fix CMASK and HTILE allocation on Tahiti
Tahiti has 12 tile pipes, but P8 pipe config. It looks like there is no way to get the pipe config except for reading GB_TILE_MODE. The TILING_CONFIG ioctl doesn't return more than 8 pipes, so we can't use that for Hawaii. This fixes a regression caused by fcb6c0d2b8cb36c3d1b7cbbf3437aeb65a808682 (cherry picked from 9b046474c95f15338d4c748df9b62871bba6f36f as part of Mesa 10.2.5) on Tahiti. v2: add an assertion and print an error on failure Cc: mesa-stable@lists.freedesktop.org Reviewed-by: Michel Dänzer <michel.daenzer@amd.com> (cherry picked from commit 955505f6ff1c8bba7eb142200d3bd065eb4d2297)
-rw-r--r--src/gallium/drivers/radeon/r600_texture.c4
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.c55
2 files changed, 56 insertions, 3 deletions
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index 0e5956836bb..9a46c53f3f7 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -389,7 +389,7 @@ static void si_texture_get_cmask_info(struct r600_common_screen *rscreen,
struct r600_cmask_info *out)
{
unsigned pipe_interleave_bytes = rscreen->tiling_info.group_bytes;
- unsigned num_pipes = rscreen->info.r600_num_tile_pipes;
+ unsigned num_pipes = rscreen->tiling_info.num_channels;
unsigned cl_width, cl_height;
switch (num_pipes) {
@@ -487,7 +487,7 @@ static unsigned si_texture_htile_alloc_size(struct r600_common_screen *rscreen,
{
unsigned cl_width, cl_height, width, height;
unsigned slice_elements, slice_bytes, pipe_interleave_bytes, base_align;
- unsigned num_pipes = rscreen->info.r600_num_tile_pipes;
+ unsigned num_pipes = rscreen->tiling_info.num_channels;
/* HTILE is broken with 1D tiling on old kernels and CIK. */
if (rtex->surface.level[0].mode == RADEON_SURF_MODE_1D &&
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
index 8c12bf7cffd..ca8cea3e519 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -23,6 +23,7 @@
#include "si_pipe.h"
#include "si_public.h"
+#include "sid.h"
#include "radeon/radeon_uvd.h"
#include "util/u_blitter.h"
@@ -384,6 +385,57 @@ static void si_destroy_screen(struct pipe_screen* pscreen)
r600_destroy_common_screen(&sscreen->b);
}
+#define SI_TILE_MODE_COLOR_2D_8BPP 14
+
+/* Initialize pipe config. This is especially important for GPUs
+ * with 16 pipes and more where it's initialized incorrectly by
+ * the TILING_CONFIG ioctl. */
+static bool si_initialize_pipe_config(struct si_screen *sscreen)
+{
+ unsigned mode2d;
+
+ /* This is okay, because there can be no 2D tiling without
+ * the tile mode array, so we won't need the pipe config.
+ * Return "success".
+ */
+ if (!sscreen->b.info.si_tile_mode_array_valid)
+ return true;
+
+ /* The same index is used for the 2D mode on CIK too. */
+ mode2d = sscreen->b.info.si_tile_mode_array[SI_TILE_MODE_COLOR_2D_8BPP];
+
+ switch (G_009910_PIPE_CONFIG(mode2d)) {
+ case V_02803C_ADDR_SURF_P2:
+ sscreen->b.tiling_info.num_channels = 2;
+ break;
+ case V_02803C_X_ADDR_SURF_P4_8X16:
+ case V_02803C_X_ADDR_SURF_P4_16X16:
+ case V_02803C_X_ADDR_SURF_P4_16X32:
+ case V_02803C_X_ADDR_SURF_P4_32X32:
+ sscreen->b.tiling_info.num_channels = 4;
+ break;
+ case V_02803C_X_ADDR_SURF_P8_16X16_8X16:
+ case V_02803C_X_ADDR_SURF_P8_16X32_8X16:
+ case V_02803C_X_ADDR_SURF_P8_32X32_8X16:
+ case V_02803C_X_ADDR_SURF_P8_16X32_16X16:
+ case V_02803C_X_ADDR_SURF_P8_32X32_16X16:
+ case V_02803C_X_ADDR_SURF_P8_32X32_16X32:
+ case V_02803C_X_ADDR_SURF_P8_32X64_32X32:
+ sscreen->b.tiling_info.num_channels = 8;
+ break;
+ case V_02803C_X_ADDR_SURF_P16_32X32_8X16:
+ case V_02803C_X_ADDR_SURF_P16_32X32_16X16:
+ sscreen->b.tiling_info.num_channels = 16;
+ break;
+ default:
+ assert(0);
+ fprintf(stderr, "radeonsi: Unknown pipe config %i.\n",
+ G_009910_PIPE_CONFIG(mode2d));
+ return false;
+ }
+ return true;
+}
+
struct pipe_screen *radeonsi_screen_create(struct radeon_winsys *ws)
{
struct si_screen *sscreen = CALLOC_STRUCT(si_screen);
@@ -399,7 +451,8 @@ struct pipe_screen *radeonsi_screen_create(struct radeon_winsys *ws)
sscreen->b.b.is_format_supported = si_is_format_supported;
sscreen->b.b.resource_create = r600_resource_create_common;
- if (!r600_common_screen_init(&sscreen->b, ws)) {
+ if (!r600_common_screen_init(&sscreen->b, ws) ||
+ !si_initialize_pipe_config(sscreen)) {
FREE(sscreen);
return NULL;
}