summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri
diff options
context:
space:
mode:
authorKeith Whitwell <keithw@vmware.com>2010-03-10 08:29:27 +0000
committerKeith Whitwell <keithw@vmware.com>2010-03-10 08:29:27 +0000
commit155fbcb0ed85c6452cbedd2317f201100fe698ab (patch)
tree15e8a2662b1341bd07cebb9cd3624bc4ed42d020 /src/mesa/drivers/dri
parent9a8342ebcd83a2022b3c9b9539c5b15ac56d6440 (diff)
parenteeaa0861bfc98a06ceec269801271b7453c4fcbd (diff)
Merge commit 'origin/master' into gallium-sw-api-2
Diffstat (limited to 'src/mesa/drivers/dri')
-rw-r--r--src/mesa/drivers/dri/i965/brw_disasm.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_program.c14
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_emit.c6
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_glsl.c144
-rw-r--r--src/mesa/drivers/dri/r200/Makefile1
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.c1
l---------src/mesa/drivers/dri/r200/radeon_pixel_read.c1
-rw-r--r--src/mesa/drivers/dri/r300/Makefile3
-rw-r--r--src/mesa/drivers/dri/r300/r300_cmdbuf.c35
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.c6
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.c75
-rw-r--r--src/mesa/drivers/dri/r300/r300_tex.c39
-rw-r--r--src/mesa/drivers/dri/r300/r300_tex.h3
l---------src/mesa/drivers/dri/r300/radeon_pixel_read.c1
-rw-r--r--src/mesa/drivers/dri/r600/Makefile3
-rw-r--r--src/mesa/drivers/dri/r600/r600_context.c1
l---------src/mesa/drivers/dri/r600/radeon_pixel_read.c1
-rw-r--r--src/mesa/drivers/dri/radeon/Makefile1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common.h6
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common_context.h1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.c1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_fbo.c126
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c3
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_pixel_read.c188
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texture.c16
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texture.h2
26 files changed, 472 insertions, 210 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_disasm.c b/src/mesa/drivers/dri/i965/brw_disasm.c
index a8f6b993ac..54699cf8d3 100644
--- a/src/mesa/drivers/dri/i965/brw_disasm.c
+++ b/src/mesa/drivers/dri/i965/brw_disasm.c
@@ -74,9 +74,9 @@ struct {
[BRW_OPCODE_JMPI] = { .name = "jmpi", .nsrc = 1, .ndst = 0 },
[BRW_OPCODE_IF] = { .name = "if", .nsrc = 2, .ndst = 0 },
[BRW_OPCODE_IFF] = { .name = "iff", .nsrc = 1, .ndst = 01 },
- [BRW_OPCODE_WHILE] = { .name = "while", .nsrc = 1, .ndst = 0 },
+ [BRW_OPCODE_WHILE] = { .name = "while", .nsrc = 2, .ndst = 0 },
[BRW_OPCODE_ELSE] = { .name = "else", .nsrc = 2, .ndst = 0 },
- [BRW_OPCODE_BREAK] = { .name = "break", .nsrc = 1, .ndst = 0 },
+ [BRW_OPCODE_BREAK] = { .name = "break", .nsrc = 2, .ndst = 0 },
[BRW_OPCODE_CONTINUE] = { .name = "cont", .nsrc = 1, .ndst = 0 },
[BRW_OPCODE_HALT] = { .name = "halt", .nsrc = 1, .ndst = 0 },
[BRW_OPCODE_MSAVE] = { .name = "msave", .nsrc = 1, .ndst = 1 },
diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c
index c78f7b38ae..1fd957b3ad 100644
--- a/src/mesa/drivers/dri/i965/brw_program.c
+++ b/src/mesa/drivers/dri/i965/brw_program.c
@@ -95,9 +95,17 @@ static void brwDeleteProgram( GLcontext *ctx,
struct gl_program *prog )
{
if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
- struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog;
- struct brw_fragment_program *brw_fprog = brw_fragment_program(fprog);
- dri_bo_unreference(brw_fprog->const_buffer);
+ struct gl_fragment_program *fp = (struct gl_fragment_program *) prog;
+ struct brw_fragment_program *brw_fp = brw_fragment_program(fp);
+
+ dri_bo_unreference(brw_fp->const_buffer);
+ }
+
+ if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
+ struct gl_vertex_program *vp = (struct gl_vertex_program *) prog;
+ struct brw_vertex_program *brw_vp = brw_vertex_program(vp);
+
+ dri_bo_unreference(brw_vp->const_buffer);
}
_mesa_delete_program( ctx, prog );
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index a7c4b58972..a48804a660 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -1717,11 +1717,13 @@ void brw_vs_emit(struct brw_vs_compile *c )
/* patch all the BREAK/CONT instructions from last BEGINLOOP */
while (inst0 > loop_inst[loop_depth]) {
inst0--;
- if (inst0->header.opcode == BRW_OPCODE_BREAK) {
+ if (inst0->header.opcode == BRW_OPCODE_BREAK &&
+ inst0->bits3.if_else.jump_count == 0) {
inst0->bits3.if_else.jump_count = br * (inst1 - inst0 + 1);
inst0->bits3.if_else.pop_count = 0;
}
- else if (inst0->header.opcode == BRW_OPCODE_CONTINUE) {
+ else if (inst0->header.opcode == BRW_OPCODE_CONTINUE &&
+ inst0->bits3.if_else.jump_count == 0) {
inst0->bits3.if_else.jump_count = br * (inst1 - inst0);
inst0->bits3.if_else.pop_count = 0;
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 562608e2ec..ea3c2405af 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -614,112 +614,6 @@ static void invoke_subroutine( struct brw_wm_compile *c,
}
}
-/* Workaround for using brw_wm_emit.c's emit functions, which expect
- * destination regs to be uniquely written. Moves arguments out to
- * temporaries as necessary for instructions which use their destination as
- * a temporary.
- */
-static void
-unalias3(struct brw_wm_compile *c,
- void (*func)(struct brw_compile *c,
- const struct brw_reg *dst,
- GLuint mask,
- const struct brw_reg *arg0,
- const struct brw_reg *arg1,
- const struct brw_reg *arg2),
- const struct brw_reg *dst,
- GLuint mask,
- const struct brw_reg *arg0,
- const struct brw_reg *arg1,
- const struct brw_reg *arg2)
-{
- struct brw_compile *p = &c->func;
- struct brw_reg tmp_arg0[4], tmp_arg1[4], tmp_arg2[4];
- int i, j;
- int mark = mark_tmps(c);
-
- for (j = 0; j < 4; j++) {
- tmp_arg0[j] = arg0[j];
- tmp_arg1[j] = arg1[j];
- tmp_arg2[j] = arg2[j];
- }
-
- for (i = 0; i < 4; i++) {
- if (mask & (1<<i)) {
- for (j = 0; j < 4; j++) {
- if (arg0[j].file == dst[i].file &&
- dst[i].nr == arg0[j].nr) {
- tmp_arg0[j] = alloc_tmp(c);
- brw_MOV(p, tmp_arg0[j], arg0[j]);
- }
- if (arg1[j].file == dst[i].file &&
- dst[i].nr == arg1[j].nr) {
- tmp_arg1[j] = alloc_tmp(c);
- brw_MOV(p, tmp_arg1[j], arg1[j]);
- }
- if (arg2[j].file == dst[i].file &&
- dst[i].nr == arg2[j].nr) {
- tmp_arg2[j] = alloc_tmp(c);
- brw_MOV(p, tmp_arg2[j], arg2[j]);
- }
- }
- }
- }
-
- func(p, dst, mask, tmp_arg0, tmp_arg1, tmp_arg2);
-
- release_tmps(c, mark);
-}
-
-/* Workaround for using brw_wm_emit.c's emit functions, which expect
- * destination regs to be uniquely written. Moves arguments out to
- * temporaries as necessary for instructions which use their destination as
- * a temporary.
- */
-static void
-unalias2(struct brw_wm_compile *c,
- void (*func)(struct brw_compile *c,
- const struct brw_reg *dst,
- GLuint mask,
- const struct brw_reg *arg0,
- const struct brw_reg *arg1),
- const struct brw_reg *dst,
- GLuint mask,
- const struct brw_reg *arg0,
- const struct brw_reg *arg1)
-{
- struct brw_compile *p = &c->func;
- struct brw_reg tmp_arg0[4], tmp_arg1[4];
- int i, j;
- int mark = mark_tmps(c);
-
- for (j = 0; j < 4; j++) {
- tmp_arg0[j] = arg0[j];
- tmp_arg1[j] = arg1[j];
- }
-
- for (i = 0; i < 4; i++) {
- if (mask & (1<<i)) {
- for (j = 0; j < 4; j++) {
- if (arg0[j].file == dst[i].file &&
- dst[i].nr == arg0[j].nr) {
- tmp_arg0[j] = alloc_tmp(c);
- brw_MOV(p, tmp_arg0[j], arg0[j]);
- }
- if (arg1[j].file == dst[i].file &&
- dst[i].nr == arg1[j].nr) {
- tmp_arg1[j] = alloc_tmp(c);
- brw_MOV(p, tmp_arg1[j], arg1[j]);
- }
- }
- }
- }
-
- func(p, dst, mask, tmp_arg0, tmp_arg1);
-
- release_tmps(c, mark);
-}
-
static void emit_arl(struct brw_wm_compile *c,
const struct prog_instruction *inst)
{
@@ -1813,14 +1707,29 @@ static void
get_argument_regs(struct brw_wm_compile *c,
const struct prog_instruction *inst,
int index,
+ struct brw_reg *dst,
struct brw_reg *regs,
int mask)
{
- int i;
+ struct brw_compile *p = &c->func;
+ int i, j;
for (i = 0; i < 4; i++) {
- if (mask & (1 << i))
+ if (mask & (1 << i)) {
regs[i] = get_src_reg(c, inst, index, i);
+
+ /* Unalias destination registers from our sources. */
+ if (regs[i].file == BRW_GENERAL_REGISTER_FILE) {
+ for (j = 0; j < 4; j++) {
+ if (memcmp(&regs[i], &dst[j], sizeof(regs[0])) == 0) {
+ struct brw_reg tmp = alloc_tmp(c);
+ brw_MOV(p, tmp, regs[i]);
+ regs[i] = tmp;
+ break;
+ }
+ }
+ }
+ }
}
}
@@ -1845,6 +1754,7 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
int dst_flags;
struct brw_reg args[3][4], dst[4];
int j;
+ int mark = mark_tmps( c );
c->cur_inst = i;
@@ -1866,7 +1776,7 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
}
}
for (j = 0; j < brw_wm_nr_args(inst->Opcode); j++)
- get_argument_regs(c, inst, j, args[j], WRITEMASK_XYZW);
+ get_argument_regs(c, inst, j, dst, args[j], WRITEMASK_XYZW);
dst_flags = inst->DstReg.WriteMask;
if (inst->SaturateMode == SATURATE_ZERO_ONE)
@@ -1920,8 +1830,7 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
emit_alu1(p, brw_RNDD, dst, dst_flags, args[0]);
break;
case OPCODE_LRP:
- unalias3(c, emit_lrp,
- dst, dst_flags, args[0], args[1], args[2]);
+ emit_lrp(p, dst, dst_flags, args[0], args[1], args[2]);
break;
case OPCODE_TRUNC:
emit_alu1(p, brw_RNDZ, dst, dst_flags, args[0]);
@@ -1961,10 +1870,10 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
emit_math1(c, BRW_MATH_FUNCTION_LOG, dst, dst_flags, args[0]);
break;
case OPCODE_MIN:
- unalias2(c, emit_min, dst, dst_flags, args[0], args[1]);
+ emit_min(p, dst, dst_flags, args[0], args[1]);
break;
case OPCODE_MAX:
- unalias2(c, emit_max, dst, dst_flags, args[0], args[1]);
+ emit_max(p, dst, dst_flags, args[0], args[1]);
break;
case OPCODE_DDX:
case OPCODE_DDY:
@@ -2103,11 +2012,13 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
/* patch all the BREAK/CONT instructions from last BGNLOOP */
while (inst0 > loop_inst[loop_depth]) {
inst0--;
- if (inst0->header.opcode == BRW_OPCODE_BREAK) {
+ if (inst0->header.opcode == BRW_OPCODE_BREAK &&
+ inst0->bits3.if_else.jump_count == 0) {
inst0->bits3.if_else.jump_count = br * (inst1 - inst0 + 1);
inst0->bits3.if_else.pop_count = 0;
}
- else if (inst0->header.opcode == BRW_OPCODE_CONTINUE) {
+ else if (inst0->header.opcode == BRW_OPCODE_CONTINUE &&
+ inst0->bits3.if_else.jump_count == 0) {
inst0->bits3.if_else.jump_count = br * (inst1 - inst0);
inst0->bits3.if_else.pop_count = 0;
}
@@ -2119,6 +2030,9 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
inst->Opcode);
}
+ /* Release temporaries containing any unaliased source regs. */
+ release_tmps( c, mark );
+
if (inst->CondUpdate)
brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
else
diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile
index 3f87100570..9ea81fd505 100644
--- a/src/mesa/drivers/dri/r200/Makefile
+++ b/src/mesa/drivers/dri/r200/Makefile
@@ -21,6 +21,7 @@ RADEON_COMMON_SOURCES = \
radeon_fbo.c \
radeon_lock.c \
radeon_mipmap_tree.c \
+ radeon_pixel_read.c \
radeon_queryobj.c \
radeon_span.c \
radeon_texture.c \
diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c
index dad2580e08..4f1a56658c 100644
--- a/src/mesa/drivers/dri/r200/r200_context.c
+++ b/src/mesa/drivers/dri/r200/r200_context.c
@@ -266,6 +266,7 @@ static void r200_init_vtbl(radeonContextPtr radeon)
radeon->vtbl.emit_query_finish = r200_emit_query_finish;
radeon->vtbl.check_blit = r200_check_blit;
radeon->vtbl.blit = r200_blit;
+ radeon->vtbl.is_format_renderable = radeonIsFormatRenderable;
}
diff --git a/src/mesa/drivers/dri/r200/radeon_pixel_read.c b/src/mesa/drivers/dri/r200/radeon_pixel_read.c
new file mode 120000
index 0000000000..3b03803126
--- /dev/null
+++ b/src/mesa/drivers/dri/r200/radeon_pixel_read.c
@@ -0,0 +1 @@
+../radeon/radeon_pixel_read.c \ No newline at end of file
diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile
index 4257a32b89..2245998c95 100644
--- a/src/mesa/drivers/dri/r300/Makefile
+++ b/src/mesa/drivers/dri/r300/Makefile
@@ -31,8 +31,9 @@ RADEON_COMMON_SOURCES = \
radeon_fbo.c \
radeon_lock.c \
radeon_mipmap_tree.c \
- radeon_span.c \
+ radeon_pixel_read.c \
radeon_queryobj.c \
+ radeon_span.c \
radeon_texture.c \
radeon_tex_copy.c \
radeon_tex_getimage.c \
diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
index 6cfa5686f4..e2dbb1dbf4 100644
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
@@ -332,36 +332,37 @@ void r300_emit_cb_setup(struct r300_context *r300,
assert(offset % 32 == 0);
switch (format) {
- case MESA_FORMAT_RGB565:
- assert(_mesa_little_endian());
- cbpitch |= R300_COLOR_FORMAT_RGB565;
+ case MESA_FORMAT_SL8:
+ case MESA_FORMAT_A8:
+ case MESA_FORMAT_L8:
+ case MESA_FORMAT_I8:
+ cbpitch |= R300_COLOR_FORMAT_I8;
break;
+ case MESA_FORMAT_RGB565:
case MESA_FORMAT_RGB565_REV:
- assert(!_mesa_little_endian());
cbpitch |= R300_COLOR_FORMAT_RGB565;
break;
case MESA_FORMAT_ARGB4444:
- assert(_mesa_little_endian());
- cbpitch |= R300_COLOR_FORMAT_ARGB4444;
- break;
case MESA_FORMAT_ARGB4444_REV:
- assert(!_mesa_little_endian());
cbpitch |= R300_COLOR_FORMAT_ARGB4444;
break;
+ case MESA_FORMAT_RGBA5551:
case MESA_FORMAT_ARGB1555:
- assert(_mesa_little_endian());
- cbpitch |= R300_COLOR_FORMAT_ARGB1555;
- break;
case MESA_FORMAT_ARGB1555_REV:
- assert(!_mesa_little_endian());
cbpitch |= R300_COLOR_FORMAT_ARGB1555;
break;
+ case MESA_FORMAT_RGBA8888:
+ case MESA_FORMAT_RGBA8888_REV:
+ case MESA_FORMAT_XRGB8888:
+ case MESA_FORMAT_ARGB8888:
+ case MESA_FORMAT_XRGB8888_REV:
+ case MESA_FORMAT_ARGB8888_REV:
+ case MESA_FORMAT_SRGBA8:
+ case MESA_FORMAT_SARGB8:
+ cbpitch |= R300_COLOR_FORMAT_ARGB8888;
+ break;
default:
- if (cpp == 4) {
- cbpitch |= R300_COLOR_FORMAT_ARGB8888;
- } else {
- _mesa_problem(r300->radeon.glCtx, "unexpected format in emit_cb_offset()");;
- }
+ _mesa_problem(r300->radeon.glCtx, "unexpected format in emit_cb_offset()");
break;
}
diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
index ff35cd5275..364e0ba6b6 100644
--- a/src/mesa/drivers/dri/r300/r300_context.c
+++ b/src/mesa/drivers/dri/r300/r300_context.c
@@ -321,6 +321,12 @@ static void r300_init_vtbl(radeonContextPtr radeon)
radeon->vtbl.check_blit = r300_check_blit;
radeon->vtbl.blit = r300_blit;
+
+ if (radeon->radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
+ radeon->vtbl.is_format_renderable = r500IsFormatRenderable;
+ } else {
+ radeon->vtbl.is_format_renderable = r300IsFormatRenderable;
+ }
}
static void r300InitConstValues(GLcontext *ctx, radeonScreenPtr screen)
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index 5979dedac4..8748941241 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -46,6 +46,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "main/simple_list.h"
#include "main/api_arrayelt.h"
+#include "drivers/common/meta.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "shader/prog_parameter.h"
@@ -2237,6 +2238,68 @@ void r300UpdateShaderStates(r300ContextPtr rmesa)
}
}
+#define EASY_US_OUT_FMT(comps, c0, c1, c2, c3) \
+ (R500_OUT_FMT_##comps | R500_C0_SEL_##c0 | R500_C1_SEL_##c1 | \
+ R500_C2_SEL_##c2 | R500_C3_SEL_##c3)
+static void r300SetupUsOutputFormat(GLcontext *ctx)
+{
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+ uint32_t hw_format;
+ struct radeon_renderbuffer *rrb = radeon_get_colorbuffer(&rmesa->radeon);
+
+ if (!rrb) {
+ return;
+ }
+
+ switch (rrb->base.Format)
+ {
+ case MESA_FORMAT_RGBA5551:
+ case MESA_FORMAT_RGBA8888:
+ hw_format = EASY_US_OUT_FMT(C4_8, A, B, G, R);
+ break;
+ case MESA_FORMAT_RGB565_REV:
+ case MESA_FORMAT_RGBA8888_REV:
+ hw_format = EASY_US_OUT_FMT(C4_8, R, G, B, A);
+ break;
+ case MESA_FORMAT_RGB565:
+ case MESA_FORMAT_ARGB4444:
+ case MESA_FORMAT_ARGB1555:
+ case MESA_FORMAT_XRGB8888:
+ case MESA_FORMAT_ARGB8888:
+ hw_format = EASY_US_OUT_FMT(C4_8, B, G, R, A);
+ break;
+ case MESA_FORMAT_ARGB4444_REV:
+ case MESA_FORMAT_ARGB1555_REV:
+ case MESA_FORMAT_XRGB8888_REV:
+ case MESA_FORMAT_ARGB8888_REV:
+ hw_format = EASY_US_OUT_FMT(C4_8, A, R, G, B);
+ break;
+ case MESA_FORMAT_SRGBA8:
+ hw_format = EASY_US_OUT_FMT(C4_10_GAMMA, A, B, G, R);
+ break;
+ case MESA_FORMAT_SARGB8:
+ hw_format = EASY_US_OUT_FMT(C4_10_GAMMA, B, G, R, A);
+ break;
+ case MESA_FORMAT_SL8:
+ hw_format = EASY_US_OUT_FMT(C4_10_GAMMA, A, A, R, A);
+ break;
+ case MESA_FORMAT_A8:
+ hw_format = EASY_US_OUT_FMT(C4_8, A, A, A, A);
+ break;
+ case MESA_FORMAT_L8:
+ case MESA_FORMAT_I8:
+ hw_format = EASY_US_OUT_FMT(C4_8, A, A, R, A);
+ break;
+ default:
+ assert(!"Unsupported format");
+ break;
+ }
+
+ R300_STATECHANGE(rmesa, us_out_fmt);
+ rmesa->hw.us_out_fmt.cmd[1] = hw_format;
+}
+#undef EASY_US_OUT_FMT
+
/**
* Called by Mesa after an internal state update.
*/
@@ -2266,6 +2329,10 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
r300->hw.shade2.cmd[1] &= ~R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST;
}
+ if (new_state & _NEW_BUFFERS) {
+ r300SetupUsOutputFormat(ctx);
+ }
+
r300->radeon.NewGLState |= new_state;
}
@@ -2326,8 +2393,12 @@ void r300InitStateFuncs(struct dd_function_table *functions)
functions->ClipPlane = r300ClipPlane;
functions->Scissor = radeonScissor;
- functions->DrawBuffer = radeonDrawBuffer;
- functions->ReadBuffer = radeonReadBuffer;
+ functions->DrawBuffer = radeonDrawBuffer;
+ functions->ReadBuffer = radeonReadBuffer;
+
+ functions->CopyPixels = _mesa_meta_CopyPixels;
+ functions->DrawPixels = _mesa_meta_DrawPixels;
+ functions->ReadPixels = radeonReadPixels;
}
void r300InitShaderFunctions(r300ContextPtr r300)
diff --git a/src/mesa/drivers/dri/r300/r300_tex.c b/src/mesa/drivers/dri/r300/r300_tex.c
index 8dd8507395..baef206bc2 100644
--- a/src/mesa/drivers/dri/r300/r300_tex.c
+++ b/src/mesa/drivers/dri/r300/r300_tex.c
@@ -308,6 +308,45 @@ static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx,
return &t->base;
}
+unsigned r300IsFormatRenderable(gl_format mesa_format)
+{
+ switch (mesa_format)
+ {
+ case MESA_FORMAT_RGB565:
+ case MESA_FORMAT_RGBA5551:
+ case MESA_FORMAT_RGBA8888:
+ case MESA_FORMAT_RGB565_REV:
+ case MESA_FORMAT_RGBA8888_REV:
+ case MESA_FORMAT_ARGB4444:
+ case MESA_FORMAT_ARGB1555:
+ case MESA_FORMAT_XRGB8888:
+ case MESA_FORMAT_ARGB8888:
+ case MESA_FORMAT_ARGB4444_REV:
+ case MESA_FORMAT_ARGB1555_REV:
+ case MESA_FORMAT_XRGB8888_REV:
+ case MESA_FORMAT_ARGB8888_REV:
+ case MESA_FORMAT_SRGBA8:
+ case MESA_FORMAT_SARGB8:
+ case MESA_FORMAT_SL8:
+ case MESA_FORMAT_A8:
+ case MESA_FORMAT_L8:
+ case MESA_FORMAT_I8:
+ case MESA_FORMAT_Z16:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+unsigned r500IsFormatRenderable(gl_format mesa_format)
+{
+ if (mesa_format == MESA_FORMAT_S8_Z24) {
+ return 1;
+ } else {
+ return r300IsFormatRenderable(mesa_format);
+ }
+}
+
void r300InitTextureFuncs(radeonContextPtr radeon, struct dd_function_table *functions)
{
/* Note: we only plug in the functions we implement in the driver
diff --git a/src/mesa/drivers/dri/r300/r300_tex.h b/src/mesa/drivers/dri/r300/r300_tex.h
index 9694e703b8..aca44cd766 100644
--- a/src/mesa/drivers/dri/r300/r300_tex.h
+++ b/src/mesa/drivers/dri/r300/r300_tex.h
@@ -53,4 +53,7 @@ extern void r300InitTextureFuncs(radeonContextPtr radeon, struct dd_function_tab
int32_t r300TranslateTexFormat(gl_format mesaFormat);
+unsigned r300IsFormatRenderable(gl_format mesaFormat);
+unsigned r500IsFormatRenderable(gl_format mesaFormat);
+
#endif /* __r300_TEX_H__ */
diff --git a/src/mesa/drivers/dri/r300/radeon_pixel_read.c b/src/mesa/drivers/dri/r300/radeon_pixel_read.c
new file mode 120000
index 0000000000..3b03803126
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/radeon_pixel_read.c
@@ -0,0 +1 @@
+../radeon/radeon_pixel_read.c \ No newline at end of file
diff --git a/src/mesa/drivers/dri/r600/Makefile b/src/mesa/drivers/dri/r600/Makefile
index f76859d11e..17915621ee 100644
--- a/src/mesa/drivers/dri/r600/Makefile
+++ b/src/mesa/drivers/dri/r600/Makefile
@@ -31,9 +31,10 @@ RADEON_COMMON_SOURCES = \
radeon_fbo.c \
radeon_lock.c \
radeon_mipmap_tree.c \
+ radeon_pixel_read.c \
+ radeon_queryobj.c \
radeon_span.c \
radeon_texture.c \
- radeon_queryobj.c \
radeon_tex_copy.c \
radeon_tex_getimage.c \
radeon_tile.c
diff --git a/src/mesa/drivers/dri/r600/r600_context.c b/src/mesa/drivers/dri/r600/r600_context.c
index 134e97e7c3..76d5027649 100644
--- a/src/mesa/drivers/dri/r600/r600_context.c
+++ b/src/mesa/drivers/dri/r600/r600_context.c
@@ -239,6 +239,7 @@ static void r600_init_vtbl(radeonContextPtr radeon)
radeon->vtbl.emit_query_finish = r600_emit_query_finish;
radeon->vtbl.check_blit = r600_check_blit;
radeon->vtbl.blit = r600_blit;
+ radeon->vtbl.is_format_renderable = radeonIsFormatRenderable;
}
static void r600InitConstValues(GLcontext *ctx, radeonScreenPtr screen)
diff --git a/src/mesa/drivers/dri/r600/radeon_pixel_read.c b/src/mesa/drivers/dri/r600/radeon_pixel_read.c
new file mode 120000
index 0000000000..3b03803126
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/radeon_pixel_read.c
@@ -0,0 +1 @@
+../radeon/radeon_pixel_read.c \ No newline at end of file
diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile
index 6904ebbee3..19df62742e 100644
--- a/src/mesa/drivers/dri/radeon/Makefile
+++ b/src/mesa/drivers/dri/radeon/Makefile
@@ -22,6 +22,7 @@ RADEON_COMMON_SOURCES = \
radeon_fbo.c \
radeon_lock.c \
radeon_mipmap_tree.c \
+ radeon_pixel_read.c \
radeon_queryobj.c \
radeon_span.c \
radeon_texture.c \
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h
index cd01c9984e..35b3f08fff 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.h
+++ b/src/mesa/drivers/dri/radeon/radeon_common.h
@@ -44,6 +44,12 @@ radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb,
struct radeon_renderbuffer *
radeon_create_renderbuffer(gl_format format, __DRIdrawable *driDrawPriv);
+void
+radeonReadPixels(GLcontext * ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *pack, GLvoid * pixels);
+
void radeon_check_front_buffer_rendering(GLcontext *ctx);
static inline struct radeon_renderbuffer *radeon_renderbuffer(struct gl_renderbuffer *rb)
{
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h
index d1a24e265f..5156c5d0d0 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.h
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h
@@ -539,6 +539,7 @@ struct radeon_context {
unsigned reg_width,
unsigned reg_height,
unsigned flip_y);
+ unsigned (*is_format_renderable)(gl_format mesa_format);
} vtbl;
};
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c
index 878a453bd5..56aba16e9e 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_context.c
@@ -200,6 +200,7 @@ static void r100_init_vtbl(radeonContextPtr radeon)
radeon->vtbl.emit_query_finish = r100_emit_query_finish;
radeon->vtbl.check_blit = r100_check_blit;
radeon->vtbl.blit = r100_blit;
+ radeon->vtbl.is_format_renderable = radeonIsFormatRenderable;
}
/* Create the device specific context.
diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c
index 46664a1755..6398605835 100644
--- a/src/mesa/drivers/dri/radeon/radeon_fbo.c
+++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c
@@ -409,82 +409,51 @@ radeon_framebuffer_renderbuffer(GLcontext * ctx,
radeon_draw_buffer(ctx, fb);
}
-
-/* TODO: According to EXT_fbo spec internal format of texture image
- * once set during glTexImage call, should be preserved when
- * attaching image to renderbuffer. When HW doesn't support
- * rendering to format of attached image, set framebuffer
- * completeness accordingly in radeon_validate_framebuffer (issue #79).
- */
static GLboolean
radeon_update_wrapper(GLcontext *ctx, struct radeon_renderbuffer *rrb,
struct gl_texture_image *texImage)
{
- int retry = 0;
- gl_format texFormat;
-
radeon_print(RADEON_TEXTURE, RADEON_TRACE,
- "%s(%p, rrb %p, texImage %p) \n",
- __func__, ctx, rrb, texImage);
-
-restart:
- if (texImage->TexFormat == _dri_texformat_argb8888) {
- rrb->base.DataType = GL_UNSIGNED_BYTE;
- DBG("Render to RGBA8 texture OK\n");
+ "%s(%p, rrb %p, texImage %p, texFormat %s) \n",
+ __func__, ctx, rrb, texImage, _mesa_get_format_name(texImage->TexFormat));
+
+ switch (texImage->TexFormat) {
+ case MESA_FORMAT_RGBA8888:
+ case MESA_FORMAT_RGBA8888_REV:
+ case MESA_FORMAT_ARGB8888:
+ case MESA_FORMAT_ARGB8888_REV:
+ case MESA_FORMAT_XRGB8888:
+ case MESA_FORMAT_XRGB8888_REV:
+ case MESA_FORMAT_RGB565:
+ case MESA_FORMAT_RGB565_REV:
+ case MESA_FORMAT_RGBA5551:
+ case MESA_FORMAT_ARGB1555:
+ case MESA_FORMAT_ARGB1555_REV:
+ case MESA_FORMAT_ARGB4444:
+ case MESA_FORMAT_ARGB4444_REV:
+ rrb->base.DataType = GL_UNSIGNED_BYTE;
+ break;
+ case MESA_FORMAT_Z16:
+ rrb->base.DataType = GL_UNSIGNED_SHORT;
+ break;
+ case MESA_FORMAT_X8_Z24:
+ rrb->base.DataType = GL_UNSIGNED_INT;
+ break;
+ case MESA_FORMAT_S8_Z24:
+ rrb->base.DataType = GL_UNSIGNED_INT_24_8_EXT;
+ break;
}
- else if (texImage->TexFormat == _dri_texformat_rgb565) {
- rrb->base.DataType = GL_UNSIGNED_BYTE;
- DBG("Render to RGB5 texture OK\n");
- }
- else if (texImage->TexFormat == _dri_texformat_argb1555) {
- rrb->base.DataType = GL_UNSIGNED_BYTE;
- DBG("Render to ARGB1555 texture OK\n");
- }
- else if (texImage->TexFormat == _dri_texformat_argb4444) {
- rrb->base.DataType = GL_UNSIGNED_BYTE;
- DBG("Render to ARGB4444 texture OK\n");
- }
- else if (texImage->TexFormat == MESA_FORMAT_Z16) {
- rrb->base.DataType = GL_UNSIGNED_SHORT;
- DBG("Render to DEPTH16 texture OK\n");
- }
- else if (texImage->TexFormat == MESA_FORMAT_S8_Z24) {
- rrb->base.DataType = GL_UNSIGNED_INT_24_8_EXT;
- DBG("Render to DEPTH_STENCIL texture OK\n");
- }
- else {
- /* try redoing the FBO */
- if (retry == 1) {
- DBG("Render to texture BAD FORMAT %d\n",
- texImage->TexFormat);
- return GL_FALSE;
- }
- /* XXX why is the tex format being set here?
- * I think this can be removed.
- */
- texImage->TexFormat = radeonChooseTextureFormat(ctx, texImage->InternalFormat, 0,
- _mesa_get_format_datatype(texImage->TexFormat),
- 1);
-
- retry++;
- goto restart;
- }
-
- texFormat = texImage->TexFormat;
-
- rrb->base.Format = texFormat;
-
- rrb->cpp = _mesa_get_format_bytes(texFormat);
+
+ rrb->cpp = _mesa_get_format_bytes(texImage->TexFormat);
rrb->pitch = texImage->Width * rrb->cpp;
+ rrb->base.Format = texImage->TexFormat;
rrb->base.InternalFormat = texImage->InternalFormat;
- rrb->base._BaseFormat = _mesa_base_fbo_format(ctx, rrb->base.InternalFormat);
-
+ rrb->base._BaseFormat = _mesa_base_fbo_format(ctx, rrb->base.InternalFormat);
rrb->base.Width = texImage->Width;
rrb->base.Height = texImage->Height;
-
rrb->base.Delete = radeon_delete_renderbuffer;
rrb->base.AllocStorage = radeon_nop_alloc_storage;
-
+
return GL_TRUE;
}
@@ -607,6 +576,35 @@ radeon_finish_render_texture(GLcontext * ctx,
static void
radeon_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
{
+ radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+ gl_format mesa_format;
+ int i;
+
+ for (i = -2; i < (GLint) ctx->Const.MaxColorAttachments; i++) {
+ struct gl_renderbuffer_attachment *att;
+ if (i == -2) {
+ att = &fb->Attachment[BUFFER_DEPTH];
+ } else if (i == -1) {
+ att = &fb->Attachment[BUFFER_STENCIL];
+ } else {
+ att = &fb->Attachment[BUFFER_COLOR0 + i];
+ }
+
+ if (att->Type == GL_TEXTURE) {
+ mesa_format = att->Texture->Image[att->CubeMapFace][att->TextureLevel]->TexFormat;
+ } else {
+ /* All renderbuffer formats are renderable, but not sampable */
+ continue;
+ }
+
+ if (!radeon->vtbl.is_format_renderable(mesa_format)){
+ fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
+ radeon_print(RADEON_TEXTURE, RADEON_TRACE,
+ "%s: HW doesn't support format %s as output format of attachment %d\n",
+ __FUNCTION__, _mesa_get_format_name(mesa_format), i);
+ return;
+ }
+ }
}
void radeon_fbo_init(struct radeon_context *radeon)
diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
index c6cc417dd6..78c5f5dd57 100644
--- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
+++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
@@ -468,12 +468,9 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt,
radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel];
- /* TODO: bring back these assertions once the FBOs are fixed */
-#if 0
assert(image->mtlevel == level);
assert(srclvl->size == dstlvl->size);
assert(srclvl->rowstride == dstlvl->rowstride);
-#endif
radeon_bo_map(image->mt->bo, GL_FALSE);
diff --git a/src/mesa/drivers/dri/radeon/radeon_pixel_read.c b/src/mesa/drivers/dri/radeon/radeon_pixel_read.c
new file mode 100644
index 0000000000..27841938e6
--- /dev/null
+++ b/src/mesa/drivers/dri/radeon/radeon_pixel_read.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2010 Maciej Cencora <m.cencora@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#include "stdint.h"
+#include "main/bufferobj.h"
+#include "main/enums.h"
+#include "main/image.h"
+#include "main/state.h"
+#include "swrast/swrast.h"
+
+#include "radeon_common_context.h"
+#include "radeon_debug.h"
+#include "radeon_mipmap_tree.h"
+
+static gl_format gl_format_and_type_to_mesa_format(GLenum format, GLenum type)
+{
+ switch (format)
+ {
+ case GL_RGB:
+ switch (type) {
+ case GL_UNSIGNED_SHORT_5_6_5:
+ return MESA_FORMAT_RGB565;
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ return MESA_FORMAT_RGB565_REV;
+ }
+ break;
+ case GL_RGBA:
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ return MESA_FORMAT_RGBA8888_REV;
+ case GL_FLOAT:
+ return MESA_FORMAT_RGBA_FLOAT32;
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ return MESA_FORMAT_ARGB4444;
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+ return MESA_FORMAT_ARGB4444;
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ return MESA_FORMAT_RGBA5551;
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ return MESA_FORMAT_ARGB1555_REV;
+ case GL_UNSIGNED_INT_8_8_8_8:
+ return MESA_FORMAT_ARGB8888;
+ case GL_UNSIGNED_INT_8_8_8_8_REV:
+ return MESA_FORMAT_ARGB8888_REV;
+ }
+ break;
+ }
+
+ return MESA_FORMAT_NONE;
+}
+
+static GLboolean
+do_blit_readpixels(GLcontext * ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *pack, GLvoid * pixels)
+{
+ radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+ const struct radeon_renderbuffer *rrb = radeon_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
+ const gl_format dst_format = gl_format_and_type_to_mesa_format(format, type);
+ unsigned dst_rowstride, dst_imagesize, aligned_rowstride, flip_y;
+ struct radeon_bo *dst_buffer;
+ GLint dst_x = 0, dst_y = 0;
+
+ /* It's not worth if number of pixels to copy is really small */
+ if (width * height < 100) {
+ return GL_FALSE;
+ }
+
+ if (dst_format == MESA_FORMAT_NONE ||
+ !radeon->vtbl.check_blit(dst_format) || !radeon->vtbl.blit) {
+ return GL_FALSE;
+ }
+
+ if (ctx->_ImageTransferState) {
+ return GL_FALSE;
+ }
+
+ if (pack->SwapBytes || pack->LsbFirst) {
+ return GL_FALSE;
+ }
+
+ if (pack->RowLength > 0) {
+ dst_rowstride = pack->RowLength;
+ } else {
+ dst_rowstride = width;
+ }
+
+ if (!_mesa_clip_copytexsubimage(ctx, &dst_x, &dst_y, &x, &y, &width, &height)) {
+ return GL_TRUE;
+ }
+ assert(x >= 0 && y >= 0);
+
+ aligned_rowstride = get_texture_image_row_stride(radeon, dst_format, dst_rowstride, 0);
+ dst_imagesize = get_texture_image_size(dst_format,
+ aligned_rowstride,
+ height, 1, 0);
+ dst_buffer = radeon_bo_open(radeon->radeonScreen->bom, 0, dst_imagesize, 1024, RADEON_GEM_DOMAIN_GTT, 0);
+
+ /* Disable source Y flipping for FBOs */
+ flip_y = (ctx->ReadBuffer->Name == 0);
+ if (pack->Invert) {
+ y = rrb->base.Height - height - y;
+ flip_y = !flip_y;
+ }
+
+ if (radeon->vtbl.blit(ctx,
+ rrb->bo,
+ rrb->draw_offset,
+ rrb->base.Format,
+ rrb->pitch / rrb->cpp,
+ rrb->base.Width,
+ rrb->base.Height,
+ x,
+ y,
+ dst_buffer,
+ 0, /* dst_offset */
+ dst_format,
+ aligned_rowstride / _mesa_get_format_bytes(dst_format),
+ width,
+ height,
+ 0, /* dst_x */
+ 0, /* dst_y */
+ width,
+ height,
+ flip_y))
+ {
+ radeon_bo_map(dst_buffer, 0);
+ dst_rowstride *= _mesa_get_format_bytes(dst_format);
+ copy_rows(pixels, dst_rowstride, dst_buffer->ptr,
+ aligned_rowstride, height, dst_rowstride);
+ radeon_bo_unmap(dst_buffer);
+ radeon_bo_unref(dst_buffer);
+ return GL_TRUE;
+ } else {
+ radeon_bo_unref(dst_buffer);
+ return GL_FALSE;
+ }
+}
+
+void
+radeonReadPixels(GLcontext * ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *pack, GLvoid * pixels)
+{
+ if (do_blit_readpixels(ctx, x, y, width, height, format, type, pack, pixels))
+ return;
+
+ /* Update Mesa state before calling down into _swrast_ReadPixels, as
+ * the spans code requires the computed buffer states to be up to date,
+ * but _swrast_ReadPixels only updates Mesa state after setting up
+ * the spans code.
+ */
+
+ radeon_print(RADEON_FALLBACKS, RADEON_NORMAL,
+ "Falling back to sw for ReadPixels (format %s, type %s)\n",
+ _mesa_lookup_enum_by_nr(format), _mesa_lookup_enum_by_nr(type));
+
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
+
+ _swrast_ReadPixels(ctx, x, y, width, height, format, type, pack, pixels);
+}
diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c
index 3ccc711253..2b655fbd95 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texture.c
+++ b/src/mesa/drivers/dri/radeon/radeon_texture.c
@@ -1006,3 +1006,19 @@ void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0,
format, type, pixels, packing, texObj, texImage, 0);
}
+
+unsigned radeonIsFormatRenderable(gl_format mesa_format)
+{
+ if (mesa_format == _dri_texformat_argb8888 || mesa_format == _dri_texformat_rgb565 ||
+ mesa_format == _dri_texformat_argb1555 || mesa_format == _dri_texformat_argb4444)
+ return 1;
+
+ switch (mesa_format)
+ {
+ case MESA_FORMAT_Z16:
+ case MESA_FORMAT_S8_Z24:
+ return 1;
+ default:
+ return 0;
+ }
+}
diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.h b/src/mesa/drivers/dri/radeon/radeon_texture.h
index f09dd65214..4ce639ea34 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texture.h
+++ b/src/mesa/drivers/dri/radeon/radeon_texture.h
@@ -135,4 +135,6 @@ void radeonCopyTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
GLint x, GLint y,
GLsizei width, GLsizei height);
+unsigned radeonIsFormatRenderable(gl_format mesa_format);
+
#endif