From 3594bf233d16ceb21e97fcdfb57ea45cb0c5e41b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 3 Mar 2010 16:12:22 -0500 Subject: [PATCH] radeon/r200/r300/r600: add check_blit vtbl function Check if the native blit formats are supported, if not, attempt to use an alternate format. Skip 3, >4 bpp as per comments from mcencora on irc. Signed-off-by: Alex Deucher --- src/mesa/drivers/dri/r200/r200_blit.c | 4 +- src/mesa/drivers/dri/r200/r200_blit.h | 2 + src/mesa/drivers/dri/r200/r200_context.c | 1 + src/mesa/drivers/dri/r300/r300_blit.c | 4 +- src/mesa/drivers/dri/r300/r300_blit.h | 4 +- src/mesa/drivers/dri/r300/r300_context.c | 3 +- src/mesa/drivers/dri/r600/r600_blit.c | 4 +- src/mesa/drivers/dri/r600/r600_blit.h | 33 ++++++++++++++ src/mesa/drivers/dri/r600/r600_context.c | 1 + src/mesa/drivers/dri/radeon/radeon_blit.c | 4 +- src/mesa/drivers/dri/radeon/radeon_blit.h | 2 + .../dri/radeon/radeon_common_context.h | 1 + src/mesa/drivers/dri/radeon/radeon_context.c | 1 + src/mesa/drivers/dri/radeon/radeon_tex_copy.c | 44 ++++++++++++++++--- 14 files changed, 93 insertions(+), 15 deletions(-) diff --git a/src/mesa/drivers/dri/r200/r200_blit.c b/src/mesa/drivers/dri/r200/r200_blit.c index 56b08a21bd5..b56327dad5f 100644 --- a/src/mesa/drivers/dri/r200/r200_blit.c +++ b/src/mesa/drivers/dri/r200/r200_blit.c @@ -38,7 +38,7 @@ static inline uint32_t cmdpacket0(struct radeon_screen *rscrn, } /* common formats supported as both textures and render targets */ -static unsigned is_blit_supported(gl_format mesa_format) +unsigned r200_check_blit(gl_format mesa_format) { /* XXX others? BE/LE? */ switch (mesa_format) { @@ -337,7 +337,7 @@ unsigned r200_blit(GLcontext *ctx, { struct r200_context *r200 = R200_CONTEXT(ctx); - if (!is_blit_supported(dst_mesaformat)) + if (!r200_check_blit(dst_mesaformat)) return GL_FALSE; /* Make sure that colorbuffer has even width - hw limitation */ diff --git a/src/mesa/drivers/dri/r200/r200_blit.h b/src/mesa/drivers/dri/r200/r200_blit.h index 38487266ae1..53206f0b471 100644 --- a/src/mesa/drivers/dri/r200/r200_blit.h +++ b/src/mesa/drivers/dri/r200/r200_blit.h @@ -30,6 +30,8 @@ void r200_blit_init(struct r200_context *r200); +unsigned r200_check_blit(gl_format mesa_format); + unsigned r200_blit(GLcontext *ctx, struct radeon_bo *src_bo, intptr_t src_offset, diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index 6ecd46ecd9e..dad2580e08b 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -264,6 +264,7 @@ static void r200_init_vtbl(radeonContextPtr radeon) radeon->vtbl.fallback = r200Fallback; radeon->vtbl.update_scissor = r200_vtbl_update_scissor; radeon->vtbl.emit_query_finish = r200_emit_query_finish; + radeon->vtbl.check_blit = r200_check_blit; radeon->vtbl.blit = r200_blit; } diff --git a/src/mesa/drivers/dri/r300/r300_blit.c b/src/mesa/drivers/dri/r300/r300_blit.c index 35fd06734f8..9637a9b7ad9 100644 --- a/src/mesa/drivers/dri/r300/r300_blit.c +++ b/src/mesa/drivers/dri/r300/r300_blit.c @@ -498,7 +498,7 @@ static void emit_cb_setup(struct r300_context *r300, END_BATCH(); } -static unsigned is_blit_supported(gl_format dst_format) +unsigned r300_check_blit(gl_format dst_format) { switch (dst_format) { case MESA_FORMAT_RGB565: @@ -566,7 +566,7 @@ unsigned r300_blit(GLcontext *ctx, { r300ContextPtr r300 = R300_CONTEXT(ctx); - if (!is_blit_supported(dst_mesaformat)) + if (!r300_check_blit(dst_mesaformat)) return 0; /* Make sure that colorbuffer has even width - hw limitation */ diff --git a/src/mesa/drivers/dri/r300/r300_blit.h b/src/mesa/drivers/dri/r300/r300_blit.h index 735acaddd70..39b157a57b8 100644 --- a/src/mesa/drivers/dri/r300/r300_blit.h +++ b/src/mesa/drivers/dri/r300/r300_blit.h @@ -30,6 +30,8 @@ void r300_blit_init(struct r300_context *r300); +unsigned r300_check_blit(gl_format mesa_format); + unsigned r300_blit(GLcontext *ctx, struct radeon_bo *src_bo, intptr_t src_offset, @@ -51,4 +53,4 @@ unsigned r300_blit(GLcontext *ctx, unsigned reg_height, unsigned flip_y); -#endif // R300_BLIT_H \ No newline at end of file +#endif // R300_BLIT_H diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index fe2ed22dc24..df4cc11da42 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -320,7 +320,8 @@ static void r300_init_vtbl(radeonContextPtr radeon) } else radeon->vtbl.emit_query_finish = r300_emit_query_finish; - radeon->vtbl.blit = r300_blit; + radeon->vtbl.check_blit = r300_check_blit; + radeon->vtbl.blit = r300_blit; } static void r300InitConstValues(GLcontext *ctx, radeonScreenPtr screen) diff --git a/src/mesa/drivers/dri/r600/r600_blit.c b/src/mesa/drivers/dri/r600/r600_blit.c index 8eafd42e8fb..9d17463cae1 100644 --- a/src/mesa/drivers/dri/r600/r600_blit.c +++ b/src/mesa/drivers/dri/r600/r600_blit.c @@ -33,7 +33,7 @@ #include "r600_cmdbuf.h" /* common formats supported as both textures and render targets */ -static unsigned is_blit_supported(gl_format mesa_format) +unsigned r600_check_blit(gl_format mesa_format) { switch (mesa_format) { case MESA_FORMAT_RGBA8888: @@ -1582,7 +1582,7 @@ unsigned r600_blit(GLcontext *ctx, context_t *context = R700_CONTEXT(ctx); int id = 0; - if (!is_blit_supported(dst_mesaformat)) + if (!r600_check_blit(dst_mesaformat)) return GL_FALSE; if (src_bo == dst_bo) { diff --git a/src/mesa/drivers/dri/r600/r600_blit.h b/src/mesa/drivers/dri/r600/r600_blit.h index f280e23489e..d56b21ba9b5 100644 --- a/src/mesa/drivers/dri/r600/r600_blit.h +++ b/src/mesa/drivers/dri/r600/r600_blit.h @@ -1,3 +1,35 @@ +/* + * Copyright (C) 2009 Advanced Micro Devices, Inc. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef R600_BLIT_H +#define R600_BLIT_H + +unsigned r600_check_blit(gl_format mesa_format); + unsigned r600_blit(GLcontext *ctx, struct radeon_bo *src_bo, intptr_t src_offset, @@ -19,3 +51,4 @@ unsigned r600_blit(GLcontext *ctx, unsigned h, unsigned flip_y); +#endif // R600_BLIT_H diff --git a/src/mesa/drivers/dri/r600/r600_context.c b/src/mesa/drivers/dri/r600/r600_context.c index 1a4b014d9f5..3d6802e735b 100644 --- a/src/mesa/drivers/dri/r600/r600_context.c +++ b/src/mesa/drivers/dri/r600/r600_context.c @@ -236,6 +236,7 @@ static void r600_init_vtbl(radeonContextPtr radeon) radeon->vtbl.pre_emit_atoms = r600_vtbl_pre_emit_atoms; radeon->vtbl.fallback = r600_fallback; radeon->vtbl.emit_query_finish = r600_emit_query_finish; + radeon->vtbl.check_blit = r600_check_blit; radeon->vtbl.blit = r600_blit; } diff --git a/src/mesa/drivers/dri/radeon/radeon_blit.c b/src/mesa/drivers/dri/radeon/radeon_blit.c index 34b9af40636..e188a122d53 100644 --- a/src/mesa/drivers/dri/radeon/radeon_blit.c +++ b/src/mesa/drivers/dri/radeon/radeon_blit.c @@ -38,7 +38,7 @@ static inline uint32_t cmdpacket0(struct radeon_screen *rscrn, } /* common formats supported as both textures and render targets */ -static unsigned is_blit_supported(gl_format mesa_format) +unsigned r100_check_blit(gl_format mesa_format) { /* XXX others? BE/LE? */ switch (mesa_format) { @@ -333,7 +333,7 @@ unsigned r100_blit(GLcontext *ctx, { struct r100_context *r100 = R100_CONTEXT(ctx); - if (!is_blit_supported(dst_mesaformat)) + if (!r100_check_blit(dst_mesaformat)) return GL_FALSE; /* Make sure that colorbuffer has even width - hw limitation */ diff --git a/src/mesa/drivers/dri/radeon/radeon_blit.h b/src/mesa/drivers/dri/radeon/radeon_blit.h index d36366ff791..d7d0b5554a6 100644 --- a/src/mesa/drivers/dri/radeon/radeon_blit.h +++ b/src/mesa/drivers/dri/radeon/radeon_blit.h @@ -30,6 +30,8 @@ void r100_blit_init(struct r100_context *r100); +unsigned r100_check_blit(gl_format mesa_format); + unsigned r100_blit(GLcontext *ctx, struct radeon_bo *src_bo, intptr_t src_offset, diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h index e397ee8c226..d1a24e265f2 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -518,6 +518,7 @@ struct radeon_context { void (*free_context)(GLcontext *ctx); void (*emit_query_finish)(radeonContextPtr radeon); void (*update_scissor)(GLcontext *ctx); + unsigned (*check_blit)(gl_format mesa_format); unsigned (*blit)(GLcontext *ctx, struct radeon_bo *src_bo, intptr_t src_offset, diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index 4625af14ad8..878a453bd53 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -198,6 +198,7 @@ static void r100_init_vtbl(radeonContextPtr radeon) radeon->vtbl.fallback = radeonFallback; radeon->vtbl.free_context = r100_vtbl_free_context; radeon->vtbl.emit_query_finish = r100_emit_query_finish; + radeon->vtbl.check_blit = r100_check_blit; radeon->vtbl.blit = r100_blit; } diff --git a/src/mesa/drivers/dri/radeon/radeon_tex_copy.c b/src/mesa/drivers/dri/radeon/radeon_tex_copy.c index 18cf182e547..89fe9915a70 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tex_copy.c +++ b/src/mesa/drivers/dri/radeon/radeon_tex_copy.c @@ -46,6 +46,12 @@ do_copy_texsubimage(GLcontext *ctx, { radeonContextPtr radeon = RADEON_CONTEXT(ctx); struct radeon_renderbuffer *rrb; + unsigned src_bpp; + unsigned dst_bpp; + gl_format src_mesaformat; + gl_format dst_mesaformat; + unsigned src_width; + unsigned dst_width; if (_mesa_get_format_bits(timg->base.TexFormat, GL_DEPTH_BITS) > 0) { rrb = radeon_get_depthbuffer(radeon); @@ -76,12 +82,40 @@ do_copy_texsubimage(GLcontext *ctx, } + src_mesaformat = rrb->base.Format; + dst_mesaformat = timg->base.TexFormat; + src_width = rrb->base.Width; + dst_width = timg->base.Width; + src_bpp = _mesa_get_format_bytes(src_mesaformat); + dst_bpp = _mesa_get_format_bytes(dst_mesaformat); + if (!radeon->vtbl.check_blit(dst_mesaformat)) { + if (src_bpp != dst_bpp) + return GL_FALSE; + + switch (dst_bpp) { + case 2: + src_mesaformat = MESA_FORMAT_RGB565; + dst_mesaformat = MESA_FORMAT_RGB565; + break; + case 4: + src_mesaformat = MESA_FORMAT_ARGB8888; + dst_mesaformat = MESA_FORMAT_ARGB8888; + break; + case 1: + src_mesaformat = MESA_FORMAT_A8; + dst_mesaformat = MESA_FORMAT_A8; + break; + default: + return GL_FALSE; + } + } + /* blit from src buffer to texture */ - return radeon->vtbl.blit(ctx, rrb->bo, src_offset, rrb->base.Format, rrb->pitch/rrb->cpp, - rrb->base.Width, rrb->base.Height, x, y, - timg->mt->bo, dst_offset, timg->base.TexFormat, - timg->mt->levels[level].rowstride / _mesa_get_format_bytes(timg->base.TexFormat), - timg->base.Width, timg->base.Height, + return radeon->vtbl.blit(ctx, rrb->bo, src_offset, src_mesaformat, rrb->pitch/rrb->cpp, + src_width, rrb->base.Height, x, y, + timg->mt->bo, dst_offset, dst_mesaformat, + timg->mt->levels[level].rowstride / dst_bpp, + dst_width, timg->base.Height, dstx, dsty, width, height, 1); } -- 2.30.2