gallium/radeon: support PIPE_CAP_SURFACE_REINTERPRET_BLOCKS
authorNicolai Hähnle <nicolai.haehnle@amd.com>
Tue, 26 Jan 2016 15:29:50 +0000 (10:29 -0500)
committerNicolai Hähnle <nicolai.haehnle@amd.com>
Wed, 3 Feb 2016 13:10:37 +0000 (14:10 +0100)
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 <marek.olsak@amd.com>
Reviewed-by: Edward O'Callaghan <eocallaghan@alterapraxis.com>
src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/radeon/r600_texture.c
src/gallium/drivers/radeonsi/si_pipe.c

index 27313c5..c6127d7 100644 (file)
@@ -285,6 +285,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_TGSI_TXQS:
        case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
        case PIPE_CAP_INVALIDATE_BUFFER:
+       case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
                return 1;
 
        case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
@@ -367,7 +368,6 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
        case PIPE_CAP_GENERATE_MIPMAP:
        case PIPE_CAP_STRING_MARKER:
-       case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
                return 0;
 
        case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
index 109b860..09318e0 100644 (file)
@@ -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,
index 5145983..cb584f5 100644 (file)
@@ -308,6 +308,7 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
        case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
        case PIPE_CAP_INVALIDATE_BUFFER:
+       case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
                return 1;
 
        case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
@@ -357,7 +358,6 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
        case PIPE_CAP_GENERATE_MIPMAP:
        case PIPE_CAP_STRING_MARKER:
-       case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
                return 0;
 
        case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS: