radeonsi/gfx9: fix most things wrong with shader images
authorMarek Olšák <marek.olsak@amd.com>
Sun, 23 Apr 2017 21:06:38 +0000 (23:06 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 26 Apr 2017 11:08:05 +0000 (13:08 +0200)
There are 2 major hw changes:
- The address must always point to the address of level 0. GFX9 tiling
  modes don't allow binding to a non-0 level.
- 3D must always be bound as 3D, because 2D and 3D use entirely different
  tiling modes, and the texture target determines which set of modes is
  used.

Cc: 17.1 <mesa-stable@lists.freedesktop.org>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeonsi/si_descriptors.c
src/gallium/drivers/radeonsi/si_state.c

index 971aa43..bd73fcc 100644 (file)
@@ -765,7 +765,7 @@ static void si_set_shader_image(struct si_context *ctx,
                static const unsigned char swizzle[4] = { 0, 1, 2, 3 };
                struct r600_texture *tex = (struct r600_texture *)res;
                unsigned level = view->u.tex.level;
-               unsigned width, height, depth;
+               unsigned width, height, depth, hw_level;
                bool uses_dcc = vi_dcc_enabled(tex, level);
 
                assert(!tex->is_depth);
@@ -794,20 +794,31 @@ static void si_set_shader_image(struct si_context *ctx,
                    p_atomic_read(&tex->framebuffers_bound))
                        ctx->need_check_render_feedback = true;
 
-               /* Always force the base level to the selected level.
-                *
-                * This is required for 3D textures, where otherwise
-                * selecting a single slice for non-layered bindings
-                * fails. It doesn't hurt the other targets.
-                */
-               width = u_minify(res->b.b.width0, level);
-               height = u_minify(res->b.b.height0, level);
-               depth = u_minify(res->b.b.depth0, level);
+               if (ctx->b.chip_class >= GFX9) {
+                       /* Always set the base address. The swizzle modes don't
+                        * allow setting mipmap level offsets as the base.
+                        */
+                       width = res->b.b.width0;
+                       height = res->b.b.height0;
+                       depth = res->b.b.depth0;
+                       hw_level = level;
+               } else {
+                       /* Always force the base level to the selected level.
+                        *
+                        * This is required for 3D textures, where otherwise
+                        * selecting a single slice for non-layered bindings
+                        * fails. It doesn't hurt the other targets.
+                        */
+                       width = u_minify(res->b.b.width0, level);
+                       height = u_minify(res->b.b.height0, level);
+                       depth = u_minify(res->b.b.depth0, level);
+                       hw_level = 0;
+               }
 
                si_make_texture_descriptor(screen, tex,
                                           false, res->b.b.target,
                                           view->format, swizzle,
-                                          0, 0,
+                                          hw_level, hw_level,
                                           view->u.tex.first_layer,
                                           view->u.tex.last_layer,
                                           width, height, depth,
index 8a8705f..ec99326 100644 (file)
@@ -3189,7 +3189,8 @@ si_make_texture_descriptor(struct si_screen *screen,
        if (!sampler &&
            (res->target == PIPE_TEXTURE_CUBE ||
             res->target == PIPE_TEXTURE_CUBE_ARRAY ||
-            res->target == PIPE_TEXTURE_3D)) {
+            (screen->b.chip_class <= VI &&
+             res->target == PIPE_TEXTURE_3D))) {
                /* For the purpose of shader images, treat cube maps and 3D
                 * textures as 2D arrays. For 3D textures, the address
                 * calculations for mipmaps are different, so we rely on the