summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/radeon/r600_texture.c
diff options
context:
space:
mode:
authorNicolai Hähnle <[email protected]>2016-01-26 10:29:50 -0500
committerNicolai Hähnle <[email protected]>2016-02-03 14:10:37 +0100
commit7dd31b81fee7fe40bd09cf3fbc324fcc32782479 (patch)
tree6c709b737fb8a9f786cf8650c4eef329d5cf4094 /src/gallium/drivers/radeon/r600_texture.c
parent4b02f165375ccff65e117651a9a75920a1b4e502 (diff)
gallium/radeon: support PIPE_CAP_SURFACE_REINTERPRET_BLOCKS
This is already used internally in si_resource_copy_region for compressed textures, so the only real change here is the adjusted surface size computation. Reviewed-by: Marek Olšák <[email protected]> Reviewed-by: Edward O'Callaghan <[email protected]>
Diffstat (limited to 'src/gallium/drivers/radeon/r600_texture.c')
-rw-r--r--src/gallium/drivers/radeon/r600_texture.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index 109b8605f9a..09318e0f8d4 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -1212,10 +1212,30 @@ static struct pipe_surface *r600_create_surface(struct pipe_context *pipe,
const struct pipe_surface *templ)
{
unsigned level = templ->u.tex.level;
+ unsigned width = u_minify(tex->width0, level);
+ unsigned height = u_minify(tex->height0, level);
+
+ if (templ->format != tex->format) {
+ const struct util_format_description *tex_desc
+ = util_format_description(tex->format);
+ const struct util_format_description *templ_desc
+ = util_format_description(templ->format);
+
+ assert(tex_desc->block.bits == templ_desc->block.bits);
+
+ /* Adjust size of surface if and only if the block width or
+ * height is changed. */
+ if (tex_desc->block.width != templ_desc->block.width ||
+ tex_desc->block.height != templ_desc->block.height) {
+ unsigned nblks_x = util_format_get_nblocksx(tex->format, width);
+ unsigned nblks_y = util_format_get_nblocksy(tex->format, height);
+
+ width = nblks_x * templ_desc->block.width;
+ height = nblks_y * templ_desc->block.height;
+ }
+ }
- return r600_create_surface_custom(pipe, tex, templ,
- u_minify(tex->width0, level),
- u_minify(tex->height0, level));
+ return r600_create_surface_custom(pipe, tex, templ, width, height);
}
static void r600_surface_destroy(struct pipe_context *pipe,