radeon/r200/r300/r600: add check_blit vtbl function
authorAlex Deucher <alexdeucher@gmail.com>
Wed, 3 Mar 2010 21:12:22 +0000 (16:12 -0500)
committerAlex Deucher <alexdeucher@gmail.com>
Wed, 3 Mar 2010 21:14:17 +0000 (16:14 -0500)
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 <alexdeucher@gmail.com>
14 files changed:
src/mesa/drivers/dri/r200/r200_blit.c
src/mesa/drivers/dri/r200/r200_blit.h
src/mesa/drivers/dri/r200/r200_context.c
src/mesa/drivers/dri/r300/r300_blit.c
src/mesa/drivers/dri/r300/r300_blit.h
src/mesa/drivers/dri/r300/r300_context.c
src/mesa/drivers/dri/r600/r600_blit.c
src/mesa/drivers/dri/r600/r600_blit.h
src/mesa/drivers/dri/r600/r600_context.c
src/mesa/drivers/dri/radeon/radeon_blit.c
src/mesa/drivers/dri/radeon/radeon_blit.h
src/mesa/drivers/dri/radeon/radeon_common_context.h
src/mesa/drivers/dri/radeon/radeon_context.c
src/mesa/drivers/dri/radeon/radeon_tex_copy.c

index 56b08a21bd5c200e2c166bdbeb6b6b767c374944..b56327dad5f68ef7ae231147646c3ae8df4e3098 100644 (file)
@@ -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 */
index 38487266ae1ff08cd535f1e8aa6f0e5c8a0801c5..53206f0b47178e381e46ab0f3b6c1459cc7f060c 100644 (file)
@@ -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,
index 6ecd46ecd9e4a75dbed1561cd03cb49b0b827f3e..dad2580e08b28b58d4be876873e8666c62f6c18c 100644 (file)
@@ -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;
 }
 
index 35fd06734f89793da4020594701d473413afb5ec..9637a9b7ad9244466f84ad78d0df67c502aa6d70 100644 (file)
@@ -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 */
index 735acaddd703f7f445d133e3457fc919781d110d..39b157a57b8a9a012e7d62b8a1a6d1195fb2d778 100644 (file)
@@ -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
index fe2ed22dc2419e324293f6f9fc63779c7ea57b2b..df4cc11da42ece32124d13baaa358919afde4904 100644 (file)
@@ -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)
index 8eafd42e8fb2fc9e84ccaf52717c5f3620ee50f5..9d17463cae152a66b7673132e3e14f9578d49ca7 100644 (file)
@@ -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) {
index f280e23489e014608be682bc672811d79e97212c..d56b21ba9b57a1467daded9b20a492b96587efe8 100644 (file)
@@ -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
index 1a4b014d9f5a6fc68c52e3a7943e31488be8267d..3d6802e735b4b61853a84f4eabdbc8fcd0862b56 100644 (file)
@@ -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;
 }
 
index 34b9af406361a6afa9bd999a3e8dbee8f8f667ee..e188a122d5350d0822d8b15e0069a53c3a89194c 100644 (file)
@@ -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 */
index d36366ff791b17c5d4085f9221c6d13b1f6a3def..d7d0b5554a66efd48b3e454fd51b10c450f9260e 100644 (file)
@@ -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,
index e397ee8c22677f942f999b7a76523086424724a6..d1a24e265f2e14ba1561fe211ea9df3186c073eb 100644 (file)
@@ -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,
index 4625af14ad8352de32d61f7c2d9d16e01b99288f..878a453bd539cd9b84abc97fadadb5bc80ebeb43 100644 (file)
@@ -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;
 }
 
index 18cf182e547b6f8dfec1a37ab4a7163ec276318b..89fe9915a700c20bb8493844cf58cd12a6fc6fce 100644 (file)
@@ -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);
 }