So that debugging is no longer a full-spam-or-nothing approach, you are now supposed to set the RADEON_DEBUG environment flag just like for classic Mesa. The available debug flags are different, however. Just running an OpenGL application with RADEON_DEBUG set to an arbitrary string will print out helpful information. Everything must be compiled with -DDEBUG for any of this to worktags/android-x86-1.6
@@ -9,6 +9,7 @@ C_SOURCES = \ | |||
r300_chipset.c \ | |||
r300_clear.c \ | |||
r300_context.c \ | |||
r300_debug.c \ | |||
r300_emit.c \ | |||
r300_flush.c \ | |||
r300_fs.c \ |
@@ -146,6 +146,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, | |||
r300->context.winsys = (struct pipe_winsys*)r300_winsys; | |||
r300->context.screen = r300_screen(screen); | |||
r300_init_debug(r300); | |||
r300->context.destroy = r300_destroy_context; | |||
r300->context.clear = r300_clear; |
@@ -275,6 +275,9 @@ struct r300_context { | |||
uint32_t dirty_state; | |||
/* Flag indicating whether or not the HW is dirty. */ | |||
uint32_t dirty_hw; | |||
/** Combination of DBG_xxx flags */ | |||
unsigned debug; | |||
}; | |||
/* Convenience cast wrapper. */ | |||
@@ -288,4 +291,40 @@ struct draw_stage* r300_draw_stage(struct r300_context* r300); | |||
void r300_init_state_functions(struct r300_context* r300); | |||
void r300_init_surface_functions(struct r300_context* r300); | |||
/* Debug functionality. */ | |||
/** | |||
* Debug flags to disable/enable certain groups of debugging outputs. | |||
* | |||
* \note These may be rather coarse, and the grouping may be impractical. | |||
* If you find, while debugging the driver, that a different grouping | |||
* of these flags would be beneficial, just feel free to change them | |||
* but make sure to update the documentation in r300_debug.c to reflect | |||
* those changes. | |||
*/ | |||
/*@{*/ | |||
#define DBG_HELP 0x0000001 | |||
#define DBG_FP 0x0000002 | |||
#define DBG_VP 0x0000004 | |||
#define DBG_CS 0x0000008 | |||
#define DBG_DRAW 0x0000010 | |||
/*@}*/ | |||
static INLINE boolean DBG_ON(struct r300_context * ctx, unsigned flags) | |||
{ | |||
return (ctx->debug & flags) ? true : false; | |||
} | |||
static INLINE void DBG(struct r300_context * ctx, unsigned flags, const char * fmt, ...) | |||
{ | |||
if (DBG_ON(ctx, flags)) { | |||
va_list va; | |||
va_start(va, fmt); | |||
debug_vprintf(fmt, va); | |||
va_end(va); | |||
} | |||
} | |||
void r300_init_debug(struct r300_context * ctx); | |||
#endif /* R300_CONTEXT_H */ |
@@ -49,7 +49,8 @@ | |||
(RADEON_CP_PACKET0 | ((count) << 16) | ((register) >> 2)) | |||
#define CS_LOCALS(context) \ | |||
struct r300_winsys* cs_winsys = context->winsys; \ | |||
struct r300_context* const cs_context_copy = (context); \ | |||
struct r300_winsys* cs_winsys = cs_context_copy->winsys; \ | |||
int cs_count = 0; | |||
#define CHECK_CS(size) \ | |||
@@ -58,7 +59,7 @@ | |||
#define BEGIN_CS(size) do { \ | |||
CHECK_CS(size); \ | |||
if (VERY_VERBOSE_CS) { \ | |||
debug_printf("r300: BEGIN_CS, count %d, in %s (%s:%d)\n", \ | |||
DBG(cs_context_copy, DBG_CS, "r300: BEGIN_CS, count %d, in %s (%s:%d)\n", \ | |||
size, __FUNCTION__, __FILE__, __LINE__); \ | |||
} \ | |||
cs_winsys->begin_cs(cs_winsys, (size), \ | |||
@@ -78,7 +79,7 @@ | |||
#define OUT_CS_REG(register, value) do { \ | |||
if (VERY_VERBOSE_REGISTERS) \ | |||
debug_printf("r300: writing 0x%08X to register 0x%04X\n", \ | |||
DBG(cs_context_copy, DBG_CS, "r300: writing 0x%08X to register 0x%04X\n", \ | |||
value, register); \ | |||
assert(register); \ | |||
OUT_CS(CP_PACKET0(register, 0)); \ | |||
@@ -89,14 +90,14 @@ | |||
* not the actual packet0 count! */ | |||
#define OUT_CS_REG_SEQ(register, count) do { \ | |||
if (VERY_VERBOSE_REGISTERS) \ | |||
debug_printf("r300: writing register sequence of %d to 0x%04X\n", \ | |||
DBG(cs_context_copy, DBG_CS, "r300: writing register sequence of %d to 0x%04X\n", \ | |||
count, register); \ | |||
assert(register); \ | |||
OUT_CS(CP_PACKET0(register, ((count) - 1))); \ | |||
} while (0) | |||
#define OUT_CS_RELOC(bo, offset, rd, wd, flags) do { \ | |||
debug_printf("r300: writing relocation for buffer %p, offset %d, " \ | |||
DBG(cs_context_copy, DBG_CS, "r300: writing relocation for buffer %p, offset %d, " \ | |||
"domains (%d, %d, %d)\n", \ | |||
bo, offset, rd, wd, flags); \ | |||
assert(bo); \ | |||
@@ -107,7 +108,7 @@ | |||
#define END_CS do { \ | |||
if (VERY_VERBOSE_CS) { \ | |||
debug_printf("r300: END_CS in %s (%s:%d)\n", __FUNCTION__, \ | |||
DBG(cs_context_copy, DBG_CS, "r300: END_CS in %s (%s:%d)\n", __FUNCTION__, \ | |||
__FILE__, __LINE__); \ | |||
} \ | |||
if (cs_count != 0) \ | |||
@@ -117,7 +118,7 @@ | |||
#define FLUSH_CS do { \ | |||
if (VERY_VERBOSE_CS) { \ | |||
debug_printf("r300: FLUSH_CS in %s (%s:%d)\n\n", __FUNCTION__, \ | |||
DBG(cs_context_copy, DBG_CS, "r300: FLUSH_CS in %s (%s:%d)\n\n", __FUNCTION__, \ | |||
__FILE__, __LINE__); \ | |||
} \ | |||
cs_winsys->flush_cs(cs_winsys); \ | |||
@@ -127,7 +128,7 @@ | |||
#define OUT_CS_ONE_REG(register, count) do { \ | |||
if (VERY_VERBOSE_REGISTERS) \ | |||
debug_printf("r300: writing data sequence of %d to 0x%04X\n", \ | |||
DBG(cs_context_copy, DBG_CS, "r300: writing data sequence of %d to 0x%04X\n", \ | |||
count, register); \ | |||
assert(register); \ | |||
OUT_CS(CP_PACKET0(register, ((count) - 1)) | RADEON_ONE_REG_WR); \ | |||
@@ -141,7 +142,7 @@ | |||
} while (0) | |||
#define OUT_CS_INDEX_RELOC(bo, offset, count, rd, wd, flags) do { \ | |||
debug_printf("r300: writing relocation for index buffer %p," \ | |||
DBG(cs_context_copy, DBG_CS, "r300: writing relocation for index buffer %p," \ | |||
"offset %d\n", bo, offset); \ | |||
assert(bo); \ | |||
OUT_CS(offset); \ |
@@ -0,0 +1,88 @@ | |||
/* | |||
* Copyright 2009 Nicolai Haehnle <nhaehnle@gmail.com> | |||
* | |||
* 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 | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR 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 "r300_context.h" | |||
#include <ctype.h> | |||
struct debug_option { | |||
const char * name; | |||
unsigned flag; | |||
const char * description; | |||
}; | |||
static struct debug_option debug_options[] = { | |||
{ "help", DBG_HELP, "Helpful meta-information about the driver" }, | |||
{ "fp", DBG_FP, "Fragment program handling" }, | |||
{ "vp", DBG_VP, "Vertex program handling" }, | |||
{ "cs", DBG_CS, "Command submissions" }, | |||
{ "draw", DBG_DRAW, "Draw and emit" }, | |||
{ "all", ~0, "Convenience option that enables all debug flags" }, | |||
/* must be last */ | |||
{ 0, 0, 0 } | |||
}; | |||
void r300_init_debug(struct r300_context * ctx) | |||
{ | |||
const char * options = debug_get_option("RADEON_DEBUG", 0); | |||
boolean printhint = false; | |||
if (options) { | |||
while(*options) { | |||
if (*options == ' ' || *options == ',') { | |||
options++; | |||
continue; | |||
} | |||
size_t length = strcspn(options, " ,"); | |||
struct debug_option * opt; | |||
for(opt = debug_options; opt->name; ++opt) { | |||
if (!strncmp(options, opt->name, length)) { | |||
ctx->debug |= opt->flag; | |||
break; | |||
} | |||
} | |||
if (!opt->name) { | |||
debug_printf("Unknown debug option: %s\n", options); | |||
printhint = true; | |||
} | |||
options += length; | |||
} | |||
if (!ctx->debug) | |||
printhint = true; | |||
} | |||
if (printhint || ctx->debug & DBG_HELP) { | |||
debug_printf("You can enable debug output by setting the RADEON_DEBUG environment variable\n" | |||
"to a comma-separated list of debug options. Available options are:\n"); | |||
for(struct debug_option * opt = debug_options; opt->name; ++opt) { | |||
debug_printf(" %s: %s\n", opt->name, opt->description); | |||
} | |||
} | |||
} |
@@ -490,7 +490,7 @@ void r300_emit_vertex_buffer(struct r300_context* r300) | |||
{ | |||
CS_LOCALS(r300); | |||
debug_printf("r300: Preparing vertex buffer %p for render, " | |||
DBG(r300, DBG_DRAW, "r300: Preparing vertex buffer %p for render, " | |||
"vertex size %d\n", r300->vbo, | |||
r300->vertex_info.vinfo.size); | |||
/* Set the pointer to our vertex buffer. The emitted values are this: |
@@ -96,7 +96,7 @@ void r300_translate_fragment_shader(struct r300_context* r300, | |||
memset(&compiler, 0, sizeof(compiler)); | |||
rc_init(&compiler.Base); | |||
compiler.Base.Debug = 1; | |||
compiler.Base.Debug = DBG_ON(r300, DBG_FP); | |||
compiler.code = &fs->code; | |||
compiler.is_r500 = r300_screen(r300->context.screen)->caps->is_r500; |
@@ -34,7 +34,7 @@ | |||
struct r300_render { | |||
/* Parent class */ | |||
struct vbuf_render base; | |||
/* Pipe context */ | |||
struct r300_context* r300; | |||
@@ -77,7 +77,7 @@ static boolean r300_render_allocate_vertices(struct vbuf_render* render, | |||
if (r300render->vbo && (size > r300render->vbo_alloc_size)) { | |||
pipe_buffer_reference(&r300render->vbo, NULL); | |||
} | |||
if (!r300render->vbo) { | |||
r300render->vbo = pipe_buffer_create(screen, | |||
64, | |||
@@ -184,7 +184,7 @@ static void r300_render_draw_arrays(struct vbuf_render* render, | |||
prepare_render(r300render, count); | |||
debug_printf("r300: Doing vbuf render, count %d\n", count); | |||
DBG(r300, DBG_DRAW, "r300: Doing vbuf render, count %d\n", count); | |||
BEGIN_CS(2); | |||
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0); |
@@ -195,13 +195,13 @@ static void r300_vertex_psc(struct r300_context* r300, | |||
* and not on attrib information. */ | |||
if (r300screen->caps->has_tcl) { | |||
attrib_count = r300->vs->info.num_inputs; | |||
debug_printf("r300: routing %d attribs in psc for vs\n", | |||
DBG(r300, DBG_DRAW, "r300: routing %d attribs in psc for vs\n", | |||
attrib_count); | |||
} else { | |||
attrib_count = vinfo->num_attribs; | |||
debug_printf("r300: attrib count: %d\n", attrib_count); | |||
DBG(r300, DBG_DRAW, "r300: attrib count: %d\n", attrib_count); | |||
for (i = 0; i < attrib_count; i++) { | |||
debug_printf("r300: attrib: offset %d, interp %d, size %d," | |||
DBG(r300, DBG_DRAW, "r300: attrib: offset %d, interp %d, size %d," | |||
" tab %d\n", vinfo->attrib[i].src_index, | |||
vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit, | |||
tab[i]); | |||
@@ -299,18 +299,18 @@ static void r300_update_fs_tab(struct r300_context* r300) | |||
} | |||
/* Now that we know where everything is... */ | |||
debug_printf("r300: fp input count: %d\n", info->num_inputs); | |||
DBG(r300, DBG_DRAW, "r300: fp input count: %d\n", info->num_inputs); | |||
for (i = 0; i < info->num_inputs; i++) { | |||
switch (tab[i]) { | |||
case INTERP_LINEAR: | |||
debug_printf("r300: attrib: " | |||
DBG(r300, DBG_DRAW, "r300: attrib: " | |||
"stack offset %d, color, tab %d\n", | |||
i, cols_emitted); | |||
tab[i] = cols_emitted; | |||
cols_emitted++; | |||
break; | |||
case INTERP_PERSPECTIVE: | |||
debug_printf("r300: attrib: " | |||
DBG(r300, DBG_DRAW, "r300: attrib: " | |||
"stack offset %d, texcoord, tab %d\n", | |||
i, cols + texs); | |||
tab[i] = cols + texs; |
@@ -116,7 +116,7 @@ void r300_translate_vertex_shader(struct r300_context* r300, | |||
/* Setup the compiler */ | |||
rc_init(&compiler.Base); | |||
compiler.Base.Debug = 1; | |||
compiler.Base.Debug = DBG_ON(r300, DBG_VP); | |||
compiler.code = &vs->code; | |||
compiler.UserData = vs; | |||