r300g: accelerate blitting for all formats by faking the texture format

This commit is contained in:
Marek Olšák 2010-02-14 04:57:03 +01:00
parent 2523172a5e
commit f22ddd8e47
3 changed files with 85 additions and 7 deletions

View file

@ -22,6 +22,9 @@
#include "r300_blit.h"
#include "r300_context.h"
#include "r300_texture.h"
#include "util/u_format.h"
static void r300_blitter_save_states(struct r300_context* r300)
{
@ -86,13 +89,13 @@ void r300_clear(struct pipe_context* pipe,
buffers, rgba, depth, stencil);
}
/* Copy a block of pixels from one surface to another. */
void r300_surface_copy(struct pipe_context* pipe,
struct pipe_surface* dst,
unsigned dstx, unsigned dsty,
struct pipe_surface* src,
unsigned srcx, unsigned srcy,
unsigned width, unsigned height)
/* Copy a block of pixels from one surface to another using HW. */
static void r300_hw_copy(struct pipe_context* pipe,
struct pipe_surface* dst,
unsigned dstx, unsigned dsty,
struct pipe_surface* src,
unsigned srcx, unsigned srcy,
unsigned width, unsigned height)
{
struct r300_context* r300 = r300_context(pipe);
@ -114,6 +117,63 @@ void r300_surface_copy(struct pipe_context* pipe,
dst, dstx, dsty, src, srcx, srcy, width, height, TRUE);
}
/* Copy a block of pixels from one surface to another. */
void r300_surface_copy(struct pipe_context* pipe,
struct pipe_surface* dst,
unsigned dstx, unsigned dsty,
struct pipe_surface* src,
unsigned srcx, unsigned srcy,
unsigned width, unsigned height)
{
enum pipe_format old_format = dst->texture->format;
enum pipe_format new_format = old_format;
assert(dst->texture->format == src->texture->format);
if (!pipe->screen->is_format_supported(pipe->screen,
old_format, src->texture->target,
PIPE_TEXTURE_USAGE_RENDER_TARGET |
PIPE_TEXTURE_USAGE_SAMPLER, 0)) {
switch (util_format_get_blocksize(old_format)) {
case 1:
new_format = PIPE_FORMAT_I8_UNORM;
break;
case 2:
new_format = PIPE_FORMAT_A4R4G4B4_UNORM;
break;
case 4:
new_format = PIPE_FORMAT_A8R8G8B8_UNORM;
break;
default:
debug_printf("r300: surface_copy: Unhandled format: %s. Falling back to software.\n"
"r300: surface_copy: Software fallback doesn't work for tiled textures.\n",
util_format_name(old_format));
}
}
if (old_format != new_format) {
dst->format = new_format;
src->format = new_format;
r300_texture_reinterpret_format(pipe->screen,
dst->texture, new_format);
r300_texture_reinterpret_format(pipe->screen,
src->texture, new_format);
}
r300_hw_copy(pipe, dst, dstx, dsty, src, srcx, srcy, width, height);
if (old_format != new_format) {
dst->format = old_format;
src->format = old_format;
r300_texture_reinterpret_format(pipe->screen,
dst->texture, old_format);
r300_texture_reinterpret_format(pipe->screen,
src->texture, old_format);
}
}
/* Fill a region of a surface with a constant value. */
void r300_surface_fill(struct pipe_context* pipe,
struct pipe_surface* dst,

View file

@ -85,6 +85,20 @@ static void r300_setup_texture_state(struct r300_screen* screen, struct r300_tex
pt->width0, pt->height0, pt->last_level);
}
void r300_texture_reinterpret_format(struct pipe_screen *screen,
struct pipe_texture *tex,
enum pipe_format new_format)
{
struct r300_screen *r300screen = r300_screen(screen);
SCREEN_DBG(r300screen, DBG_TEX, "r300: Reinterpreting format: %s -> %s\n",
util_format_name(tex->format), util_format_name(new_format));
tex->format = new_format;
r300_setup_texture_state(r300_screen(screen), (struct r300_texture*)tex);
}
unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level,
unsigned zslice, unsigned face)
{

View file

@ -38,6 +38,10 @@ unsigned r300_texture_get_stride(struct r300_screen* screen,
unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level,
unsigned zslice, unsigned face);
void r300_texture_reinterpret_format(struct pipe_screen *screen,
struct pipe_texture *tex,
enum pipe_format new_format);
/* Translate a pipe_format into a useful texture format for sampling.
*
* R300_EASY_TX_FORMAT swizzles the texture.