radeonsi: fix CMASK and HTILE allocation on Tahiti
authorMarek Olšák <marek.olsak@amd.com>
Thu, 7 Aug 2014 19:14:31 +0000 (21:14 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Sat, 9 Aug 2014 21:41:16 +0000 (23:41 +0200)
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 9b046474c95f15338d4c748df9b62871bba6f36f
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>
src/gallium/drivers/radeon/r600_texture.c
src/gallium/drivers/radeonsi/si_pipe.c

index 6c846241cb0856c9610f81485773cb2a3ae72f28..d07c9a0c500fb5ea6fd08526dd81d7af3d0df24a 100644 (file)
@@ -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) {
@@ -486,7 +486,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 &&
index 635b37d81c620b081a07cf262dc52712f716bf87..85b57f4b3bd3c22fc071854e737ecbea6fc761b1 100644 (file)
@@ -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"
@@ -397,6 +398,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);
@@ -412,7 +464,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;
        }