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 <marek.olsak@amd.com>
Reviewed-by: Edward O'Callaghan <eocallaghan@alterapraxis.com>
This commit is contained in:
Nicolai Hähnle 2016-01-26 10:29:50 -05:00
parent 4b02f16537
commit 7dd31b81fe
3 changed files with 25 additions and 5 deletions

View 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:

View 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);
return r600_create_surface_custom(pipe, tex, templ,
u_minify(tex->width0, level),
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, width, height);
}
static void r600_surface_destroy(struct pipe_context *pipe,

View 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: