diff options
author | Marek Olšák <[email protected]> | 2017-04-23 23:06:38 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2017-04-26 13:08:05 +0200 |
commit | 5c94779585e24e8bd1bd41707521584af4251de3 (patch) | |
tree | 9621243bbffa25474b7c39a6439cf616e93f6962 | |
parent | 65e0c3fba74ee98cacadbba4bd005b930609b65e (diff) |
radeonsi/gfx9: fix most things wrong with shader images
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 <[email protected]>
Reviewed-by: Nicolai Hähnle <[email protected]>
-rw-r--r-- | src/gallium/drivers/radeonsi/si_descriptors.c | 33 | ||||
-rw-r--r-- | 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 |