diff options
Diffstat (limited to 'src/gallium/drivers/r600')
| -rw-r--r-- | src/gallium/drivers/r600/r600_blit.c | 60 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_pipe.c | 2 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_texture.c | 13 | 
3 files changed, 75 insertions, 0 deletions
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index fbade99fc5..6687d09e0f 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -219,6 +219,47 @@ static void r600_hw_copy_region(struct pipe_context *ctx,  	r600_blitter_end(ctx);  } +struct texture_orig_info { +	unsigned format; +	unsigned width0; +	unsigned height0; +}; + +static void r600_s3tc_to_blittable(struct pipe_resource *tex, +				   unsigned level, +				   struct texture_orig_info *orig) +{ +	unsigned pixsize = util_format_get_blocksize(tex->format); +	int new_format; +	int new_height, new_width; + +	orig->format = tex->format; +	orig->width0 = tex->width0; +	orig->height0 = tex->height0; + +	if (pixsize == 8) +		new_format = PIPE_FORMAT_R16G16B16A16_UNORM; /* 64-bit block */ +	else +		new_format = PIPE_FORMAT_R32G32B32A32_UNORM; /* 128-bit block */ + +	new_width = util_format_get_nblocksx(tex->format, orig->width0); +	new_height = util_format_get_nblocksy(tex->format, orig->height0); + +	tex->width0 = new_width; +	tex->height0 = new_height; +	tex->format = new_format; + +} + +static void r600_reset_blittable_to_s3tc(struct pipe_resource *tex, +					 unsigned level, +					 struct texture_orig_info *orig) +{ +	tex->format = orig->format; +	tex->width0 = orig->width0; +	tex->height0 = orig->height0; +} +  static void r600_resource_copy_region(struct pipe_context *ctx,  				      struct pipe_resource *dst,  				      unsigned dst_level, @@ -228,13 +269,32 @@ static void r600_resource_copy_region(struct pipe_context *ctx,  				      const struct pipe_box *src_box)  {  	struct r600_resource_texture *rsrc = (struct r600_resource_texture*)src; +	struct texture_orig_info orig_info[2]; +	boolean restore_orig[2];  	if (rsrc->depth && !rsrc->is_flushing_texture)  		r600_texture_depth_flush(ctx, src, FALSE); +	restore_orig[0] = restore_orig[1] = FALSE; + +	if (util_format_is_s3tc(src->format)) { +		r600_s3tc_to_blittable(src, src_level, &orig_info[0]); +		restore_orig[0] = TRUE; +	} + +	if (util_format_is_s3tc(dst->format)) { +		r600_s3tc_to_blittable(dst, dst_level, &orig_info[1]); +		restore_orig[1] = TRUE; +	} +  	r600_hw_copy_region(ctx, dst, dst_level, dstx, dsty, dstz,  			    src, src_level, src_box); +	if (restore_orig[0]) +		r600_reset_blittable_to_s3tc(src, src_level, &orig_info[0]); + +	if (restore_orig[1]) +		r600_reset_blittable_to_s3tc(dst, dst_level, &orig_info[1]);  }  void r600_init_blit_functions(struct r600_pipe_context *rctx) diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index f9e8e76d24..9d6c9bd542 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -30,6 +30,7 @@  #include <tgsi/tgsi_util.h>  #include <util/u_blitter.h>  #include <util/u_double_list.h> +#include <util/u_format_s3tc.h>  #include <util/u_transfer.h>  #include <util/u_surface.h>  #include <util/u_pack_color.h> @@ -502,6 +503,7 @@ struct pipe_screen *r600_screen_create(struct radeon *radeon)  	r600_init_screen_resource_functions(&rscreen->screen);  	rscreen->tiling_info = r600_get_tiling_info(radeon); +	util_format_s3tc_init();  	util_slab_create(&rscreen->pool_buffers,  			 sizeof(struct r600_resource_buffer), 64, diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index db39383e30..dd14143c2c 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -27,6 +27,7 @@  #include <errno.h>  #include <pipe/p_screen.h>  #include <util/u_format.h> +#include <util/u_format_s3tc.h>  #include <util/u_math.h>  #include <util/u_inlines.h>  #include <util/u_memory.h> @@ -289,6 +290,10 @@ static boolean permit_hardware_blit(struct pipe_screen *screen,  	else  		bind = PIPE_BIND_RENDER_TARGET; +	/* hackaround for S3TC */ +	if (util_format_is_s3tc(res->format)) +		return TRUE; +	      	if (!screen->is_format_supported(screen,  				res->format,  				res->target, @@ -417,6 +422,10 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen,  		}  	} +	if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) && +	    util_format_is_s3tc(templ->format)) +		array_mode = V_038000_ARRAY_1D_TILED_THIN1; +  	return (struct pipe_resource *)r600_texture_create_object(screen, templ, array_mode,  								  0, 0, NULL); @@ -869,6 +878,10 @@ uint32_t r600_translate_texformat(enum pipe_format format,  		if (!r600_enable_s3tc)  			goto out_unknown; +		if (!util_format_s3tc_enabled) { +			goto out_unknown; +		} +  		switch (format) {  		case PIPE_FORMAT_DXT1_RGB:  		case PIPE_FORMAT_DXT1_RGBA:  | 
