From 5c94779585e24e8bd1bd41707521584af4251de3 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 23 Apr 2017 23:06:38 +0200 Subject: radeonsi/gfx9: fix most things wrong with shader images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Nicolai Hähnle --- src/gallium/drivers/radeonsi/si_descriptors.c | 33 ++++++++++++++++++--------- src/gallium/drivers/radeonsi/si_state.c | 3 ++- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index 971aa43c436..bd73fcc3f9f 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -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, diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 8a8705f153d..ec99326dda4 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -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 -- cgit v1.2.3