diff options
Diffstat (limited to 'src/gallium')
40 files changed, 4046 insertions, 131 deletions
diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index f599bee07e7..ce41418a0f9 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -142,12 +142,13 @@ _fenced_buffer_destroy(struct fenced_buffer *fenced_buf) static INLINE void -_fenced_buffer_remove(struct fenced_buffer *fenced_buf) +_fenced_buffer_remove(struct fenced_buffer_list *fenced_list, + struct fenced_buffer *fenced_buf) { - struct fenced_buffer_list *fenced_list = fenced_buf->list; struct pipe_winsys *winsys = fenced_list->winsys; assert(fenced_buf->fence); + assert(fenced_buf->list == fenced_list); winsys->fence_reference(winsys, &fenced_buf->fence, NULL); fenced_buf->flags &= ~PIPE_BUFFER_USAGE_GPU_READ_WRITE; @@ -184,7 +185,8 @@ _fenced_buffer_finish(struct fenced_buffer *fenced_buf) return PIPE_ERROR; } /* Remove from the fenced list */ - _fenced_buffer_remove(fenced_buf); /* TODO: remove consequents */ + /* TODO: remove consequents */ + _fenced_buffer_remove(fenced_list, fenced_buf); } fenced_buf->flags &= ~PIPE_BUFFER_USAGE_GPU_READ_WRITE; @@ -223,7 +225,7 @@ _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, assert(winsys->fence_signalled(winsys, fenced_buf->fence, 0) == 0); } - _fenced_buffer_remove(fenced_buf); + _fenced_buffer_remove(fenced_list, fenced_buf); curr = next; next = curr->next; @@ -248,7 +250,7 @@ fenced_buffer_destroy(struct pb_buffer *buf) do { fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head); assert(winsys->fence_signalled(winsys, fenced_buf->fence, 0) == 0); - _fenced_buffer_remove(fenced_buf); + _fenced_buffer_remove(fenced_list, fenced_buf); curr = prev; prev = curr->prev; } while (curr != &fenced_list->delayed); @@ -395,7 +397,7 @@ buffer_fence(struct pb_buffer *buf, _glthread_LOCK_MUTEX(fenced_list->mutex); if (fenced_buf->fence) - _fenced_buffer_remove(fenced_buf); + _fenced_buffer_remove(fenced_list, fenced_buf); if (fence) { winsys->fence_reference(winsys, &fenced_buf->fence, fence); fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE; diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c index 0eedb1c91e3..29bb530b4dd 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c @@ -26,6 +26,7 @@ **************************************************************************/ #include "pipe/p_debug.h" +#include "util/u_string.h" #include "tgsi_dump.h" #include "tgsi_iterate.h" @@ -34,28 +35,31 @@ struct dump_ctx struct tgsi_iterate_context iter; uint instno; + + struct util_strbuf *sbuf; }; static void dump_enum( + struct util_strbuf *sbuf, uint e, const char **enums, uint enum_count ) { if (e >= enum_count) - debug_printf( "%u", e ); + util_strbuf_printf( sbuf, "%u", e ); else - debug_printf( "%s", enums[e] ); + util_strbuf_printf( sbuf, "%s", enums[e] ); } -#define EOL() debug_printf( "\n" ) -#define TXT(S) debug_printf( "%s", S ) -#define CHR(C) debug_printf( "%c", C ) -#define UIX(I) debug_printf( "0x%x", I ) -#define UID(I) debug_printf( "%u", I ) -#define SID(I) debug_printf( "%d", I ) -#define FLT(F) debug_printf( "%10.4f", F ) -#define ENM(E,ENUMS) dump_enum( E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) +#define EOL() util_strbuf_printf( sbuf, "\n" ) +#define TXT(S) util_strbuf_printf( sbuf, "%s", S ) +#define CHR(C) util_strbuf_printf( sbuf, "%c", C ) +#define UIX(I) util_strbuf_printf( sbuf, "0x%x", I ) +#define UID(I) util_strbuf_printf( sbuf, "%u", I ) +#define SID(I) util_strbuf_printf( sbuf, "%d", I ) +#define FLT(F) util_strbuf_printf( sbuf, "%10.4f", F ) +#define ENM(E,ENUMS) dump_enum( sbuf, E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) static const char *processor_type_names[] = { @@ -266,6 +270,7 @@ static const char *modulate_names[TGSI_MODULATE_COUNT] = static void _dump_register( + struct util_strbuf *sbuf, uint file, int first, int last ) @@ -282,6 +287,7 @@ _dump_register( static void _dump_register_ind( + struct util_strbuf *sbuf, uint file, int index, uint ind_file, @@ -303,6 +309,7 @@ _dump_register_ind( static void _dump_writemask( + struct util_strbuf *sbuf, uint writemask ) { if (writemask != TGSI_WRITEMASK_XYZW) { @@ -318,17 +325,23 @@ _dump_writemask( } } -void -tgsi_dump_declaration( - const struct tgsi_full_declaration *decl ) +static boolean +iter_declaration( + struct tgsi_iterate_context *iter, + struct tgsi_full_declaration *decl ) { + struct dump_ctx *ctx = (struct dump_ctx *) iter; + struct util_strbuf *sbuf = ctx->sbuf; + TXT( "DCL " ); _dump_register( + sbuf, decl->Declaration.File, decl->DeclarationRange.First, decl->DeclarationRange.Last ); _dump_writemask( + sbuf, decl->Declaration.UsageMask ); if (decl->Declaration.Semantic) { @@ -346,21 +359,35 @@ tgsi_dump_declaration( ENM( decl->Declaration.Interpolate, interpolate_names ); EOL(); -} -static boolean -iter_declaration( - struct tgsi_iterate_context *iter, - struct tgsi_full_declaration *decl ) -{ - tgsi_dump_declaration( decl ); return TRUE; } void -tgsi_dump_immediate( - const struct tgsi_full_immediate *imm ) +tgsi_dump_declaration( + const struct tgsi_full_declaration *decl ) { + static char str[1024]; + struct util_strbuf sbuf; + struct dump_ctx ctx; + + util_strbuf_init(&sbuf, str, sizeof(str)); + + ctx.sbuf = &sbuf; + + iter_declaration( &ctx.iter, (struct tgsi_full_declaration *)decl ); + + debug_printf("%s", str); +} + +static boolean +iter_immediate( + struct tgsi_iterate_context *iter, + struct tgsi_full_immediate *imm ) +{ + struct dump_ctx *ctx = (struct dump_ctx *) iter; + struct util_strbuf *sbuf = ctx->sbuf; + uint i; TXT( "IMM " ); @@ -382,22 +409,36 @@ tgsi_dump_immediate( TXT( " }" ); EOL(); -} -static boolean -iter_immediate( - struct tgsi_iterate_context *iter, - struct tgsi_full_immediate *imm ) -{ - tgsi_dump_immediate( imm ); return TRUE; } void -tgsi_dump_instruction( - const struct tgsi_full_instruction *inst, - uint instno ) +tgsi_dump_immediate( + const struct tgsi_full_immediate *imm ) { + static char str[1024]; + struct util_strbuf sbuf; + struct dump_ctx ctx; + + util_strbuf_init(&sbuf, str, sizeof(str)); + + ctx.sbuf = &sbuf; + + iter_immediate( &ctx.iter, (struct tgsi_full_immediate *)imm ); + + debug_printf("%s", str); +} + +static boolean +iter_instruction( + struct tgsi_iterate_context *iter, + struct tgsi_full_instruction *inst ) +{ + struct dump_ctx *ctx = (struct dump_ctx *) iter; + struct util_strbuf *sbuf = ctx->sbuf; + uint instno = ctx->instno++; + uint i; boolean first_reg = TRUE; @@ -426,11 +467,12 @@ tgsi_dump_instruction( CHR( ' ' ); _dump_register( + sbuf, dst->DstRegister.File, dst->DstRegister.Index, dst->DstRegister.Index ); ENM( dst->DstRegisterExtModulate.Modulate, modulate_names ); - _dump_writemask( dst->DstRegister.WriteMask ); + _dump_writemask( sbuf, dst->DstRegister.WriteMask ); first_reg = FALSE; } @@ -457,6 +499,7 @@ tgsi_dump_instruction( if (src->SrcRegister.Indirect) { _dump_register_ind( + sbuf, src->SrcRegister.File, src->SrcRegister.Index, src->SrcRegisterInd.File, @@ -464,6 +507,7 @@ tgsi_dump_instruction( } else { _dump_register( + sbuf, src->SrcRegister.File, src->SrcRegister.Index, src->SrcRegister.Index ); @@ -529,38 +573,55 @@ tgsi_dump_instruction( } EOL(); + + return TRUE; } -static boolean -iter_instruction( - struct tgsi_iterate_context *iter, - struct tgsi_full_instruction *inst ) +void +tgsi_dump_instruction( + const struct tgsi_full_instruction *inst, + uint instno ) { - struct dump_ctx *ctx = (struct dump_ctx *) iter; + static char str[1024]; + struct util_strbuf sbuf; + struct dump_ctx ctx; - tgsi_dump_instruction( inst, ctx->instno++ ); - return TRUE; + util_strbuf_init(&sbuf, str, sizeof(str)); + + ctx.instno = instno; + ctx.sbuf = &sbuf; + + iter_instruction( &ctx.iter, (struct tgsi_full_instruction *)inst ); + + debug_printf("%s", str); } static boolean prolog( - struct tgsi_iterate_context *ctx ) + struct tgsi_iterate_context *iter ) { - ENM( ctx->processor.Processor, processor_type_names ); - UID( ctx->version.MajorVersion ); + struct dump_ctx *ctx = (struct dump_ctx *) iter; + struct util_strbuf *sbuf = ctx->sbuf; + ENM( iter->processor.Processor, processor_type_names ); + UID( iter->version.MajorVersion ); CHR( '.' ); - UID( ctx->version.MinorVersion ); + UID( iter->version.MinorVersion ); EOL(); return TRUE; } void -tgsi_dump( +tgsi_dump_str( const struct tgsi_token *tokens, - uint flags ) + uint flags, + char *str, + size_t size) { + struct util_strbuf sbuf; struct dump_ctx ctx; + util_strbuf_init(&sbuf, str, size); + /* sanity checks */ assert( strcmp( opcode_names[TGSI_OPCODE_CONT], "CONT" ) == 0 ); assert( strcmp( opcode_names[TGSI_OPCODE_END], "END" ) == 0 ); @@ -572,6 +633,19 @@ tgsi_dump( ctx.iter.epilog = NULL; ctx.instno = 0; + ctx.sbuf = &sbuf; tgsi_iterate_shader( tokens, &ctx.iter ); } + +void +tgsi_dump( + const struct tgsi_token *tokens, + uint flags ) +{ + static char str[4096]; + + tgsi_dump_str(tokens, flags, str, sizeof(str)); + + debug_printf("%s", str); +} diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.h b/src/gallium/auxiliary/tgsi/tgsi_dump.h index 51c230b5db4..ad1e647ec90 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.h +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.h @@ -35,6 +35,13 @@ extern "C" { #endif void +tgsi_dump_str( + const struct tgsi_token *tokens, + uint flags, + char *str, + size_t size); + +void tgsi_dump( const struct tgsi_token *tokens, uint flags ); diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index cdc7e66361d..082b0e9fb56 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -50,12 +50,12 @@ #endif - - #include "pipe/p_compiler.h" #include "pipe/p_util.h" #include "pipe/p_debug.h" #include "pipe/p_format.h" +#include "pipe/p_state.h" +#include "pipe/p_inlines.h" #include "util/u_string.h" @@ -335,7 +335,7 @@ const char * debug_dump_enum(const struct debug_named_value *names, unsigned long value) { - static char rest[256]; + static char rest[64]; while(names->name) { if(names->value == value) @@ -498,10 +498,9 @@ void debug_print_format(const char *msg, unsigned fmt ) } #endif -char *pf_sprint_name( char *str, enum pipe_format format ) +const char *pf_name( enum pipe_format format ) { - strcpy( str, debug_dump_enum(pipe_format_names, format) ); - return str; + return debug_dump_enum(pipe_format_names, format); } @@ -509,7 +508,7 @@ char *pf_sprint_name( char *str, enum pipe_format format ) void debug_dump_image(const char *prefix, unsigned format, unsigned cpp, unsigned width, unsigned height, - unsigned pitch, + unsigned stride, const void *data) { #ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY @@ -530,7 +529,7 @@ void debug_dump_image(const char *prefix, for(i = 0; i < sizeof(filename); ++i) wfilename[i] = (WCHAR)filename[i]; - pMap = (unsigned char *)EngMapFile(wfilename, sizeof(header) + cpp*width*height, &iFile); + pMap = (unsigned char *)EngMapFile(wfilename, sizeof(header) + height*width*cpp, &iFile); if(!pMap) return; @@ -542,11 +541,44 @@ void debug_dump_image(const char *prefix, pMap += sizeof(header); for(i = 0; i < height; ++i) { - memcpy(pMap, (unsigned char *)data + cpp*pitch*i, cpp*width); + memcpy(pMap, (unsigned char *)data + stride*i, cpp*width); pMap += cpp*width; } EngUnmapFile(iFile); #endif } + +void debug_dump_surface(const char *prefix, + struct pipe_surface *surface) +{ + unsigned surface_usage; + void *data; + + if (!surface) + goto error1; + + /* XXX: force mappable surface */ + surface_usage = surface->usage; + surface->usage |= PIPE_BUFFER_USAGE_CPU_READ; + + data = pipe_surface_map(surface, + PIPE_BUFFER_USAGE_CPU_READ); + if(!data) + goto error2; + + debug_dump_image(prefix, + surface->format, + surface->block.size, + surface->nblocksx, + surface->nblocksy, + surface->stride, + data); + + pipe_surface_unmap(surface); +error2: + surface->usage = surface_usage; +error1: + ; +} #endif diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index 2b6db43bee6..e366039a27c 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -51,12 +51,12 @@ pipe_get_tile_raw(struct pipe_surface *ps, { const void *src; - if (pipe_clip_tile(x, y, &w, &h, ps)) - return; - if (dst_stride == 0) dst_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size; + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + src = pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_READ); assert(src); if(!src) @@ -79,12 +79,12 @@ pipe_put_tile_raw(struct pipe_surface *ps, { void *dst; - if (pipe_clip_tile(x, y, &w, &h, ps)) - return; - if (src_stride == 0) src_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size; + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + dst = pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_WRITE); assert(dst); if(!dst) @@ -109,7 +109,7 @@ pipe_put_tile_raw(struct pipe_surface *ps, /*** PIPE_FORMAT_A8R8G8B8_UNORM ***/ static void -a8r8g8b8_get_tile_rgba(unsigned *src, +a8r8g8b8_get_tile_rgba(const unsigned *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -156,7 +156,7 @@ a8r8g8b8_put_tile_rgba(unsigned *dst, /*** PIPE_FORMAT_A8R8G8B8_UNORM ***/ static void -x8r8g8b8_get_tile_rgba(unsigned *src, +x8r8g8b8_get_tile_rgba(const unsigned *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -202,7 +202,7 @@ x8r8g8b8_put_tile_rgba(unsigned *dst, /*** PIPE_FORMAT_B8G8R8A8_UNORM ***/ static void -b8g8r8a8_get_tile_rgba(unsigned *src, +b8g8r8a8_get_tile_rgba(const unsigned *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -249,7 +249,7 @@ b8g8r8a8_put_tile_rgba(unsigned *dst, /*** PIPE_FORMAT_A1R5G5B5_UNORM ***/ static void -a1r5g5b5_get_tile_rgba(ushort *src, +a1r5g5b5_get_tile_rgba(const ushort *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -270,10 +270,37 @@ a1r5g5b5_get_tile_rgba(ushort *src, } +static void +a1r5g5b5_put_tile_rgba(ushort *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r, g, b, a; + UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); + UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]); + UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]); + UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); + r = r >> 3; /* 5 bits */ + g = g >> 3; /* 5 bits */ + b = b >> 3; /* 5 bits */ + a = a >> 7; /* 1 bit */ + *dst++ = (a << 15) | (r << 10) | (g << 5) | b; + } + p += src_stride; + } +} + + /*** PIPE_FORMAT_A4R4G4B4_UNORM ***/ static void -a4r4g4b4_get_tile_rgba(ushort *src, +a4r4g4b4_get_tile_rgba(const ushort *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -324,7 +351,7 @@ a4r4g4b4_put_tile_rgba(ushort *dst, /*** PIPE_FORMAT_R5G6B5_UNORM ***/ static void -r5g6b5_get_tile_rgba(ushort *src, +r5g6b5_get_tile_rgba(const ushort *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -373,7 +400,7 @@ r5g6b5_put_tile_rgba(ushort *dst, * Return each Z value as four floats in [0,1]. */ static void -z16_get_tile_rgba(ushort *src, +z16_get_tile_rgba(const ushort *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -399,7 +426,7 @@ z16_get_tile_rgba(ushort *src, /*** PIPE_FORMAT_L8_UNORM ***/ static void -l8_get_tile_rgba(ubyte *src, +l8_get_tile_rgba(const ubyte *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -419,10 +446,31 @@ l8_get_tile_rgba(ubyte *src, } +static void +l8_put_tile_rgba(ubyte *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r; + UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); + *dst++ = r; + } + p += src_stride; + } +} + + + /*** PIPE_FORMAT_A8_UNORM ***/ static void -a8_get_tile_rgba(ubyte *src, +a8_get_tile_rgba(const ubyte *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -441,10 +489,32 @@ a8_get_tile_rgba(ubyte *src, } } + +static void +a8_put_tile_rgba(ubyte *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned a; + UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); + *dst++ = a; + } + p += src_stride; + } +} + + + /*** PIPE_FORMAT_R16_SNORM ***/ static void -r16_get_tile_rgba(short *src, +r16_get_tile_rgba(const short *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -485,7 +555,7 @@ r16_put_tile_rgba(short *dst, /*** PIPE_FORMAT_R16G16B16A16_SNORM ***/ static void -r16g16b16a16_get_tile_rgba(short *src, +r16g16b16a16_get_tile_rgba(const short *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -530,7 +600,7 @@ r16g16b16a16_put_tile_rgba(short *dst, /*** PIPE_FORMAT_I8_UNORM ***/ static void -i8_get_tile_rgba(ubyte *src, +i8_get_tile_rgba(const ubyte *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -550,13 +620,33 @@ i8_get_tile_rgba(ubyte *src, } +static void +i8_put_tile_rgba(ubyte *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r; + UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); + *dst++ = r; + } + p += src_stride; + } +} + + /*** PIPE_FORMAT_A8L8_UNORM ***/ static void -a8_l8_get_tile_rgba(ushort *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) +a8l8_get_tile_rgba(const ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) { unsigned i, j; @@ -574,6 +664,27 @@ a8_l8_get_tile_rgba(ushort *src, } +static void +a8l8_put_tile_rgba(ushort *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r, a; + UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); + UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); + *dst++ = (a << 8) | r; + } + p += src_stride; + } +} + + /*** PIPE_FORMAT_Z32_UNORM ***/ @@ -582,7 +693,7 @@ a8_l8_get_tile_rgba(ushort *src, * Return each Z value as four floats in [0,1]. */ static void -z32_get_tile_rgba(unsigned *src, +z32_get_tile_rgba(const unsigned *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -609,7 +720,7 @@ z32_get_tile_rgba(unsigned *src, * Return Z component as four float in [0,1]. Stencil part ignored. */ static void -s8z24_get_tile_rgba(unsigned *src, +s8z24_get_tile_rgba(const unsigned *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -636,7 +747,7 @@ s8z24_get_tile_rgba(unsigned *src, * Return Z component as four float in [0,1]. Stencil part ignored. */ static void -z24s8_get_tile_rgba(unsigned *src, +z24s8_get_tile_rgba(const unsigned *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -663,7 +774,7 @@ z24s8_get_tile_rgba(unsigned *src, * Convert YCbCr (or YCrCb) to RGBA. */ static void -ycbcr_get_tile_rgba(ushort *src, +ycbcr_get_tile_rgba(const ushort *src, unsigned w, unsigned h, float *p, unsigned dst_stride, @@ -780,7 +891,7 @@ pipe_tile_raw_to_rgba(enum pipe_format format, i8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_A8L8_UNORM: - a8_l8_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); + a8l8_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_R16_SNORM: r16_get_tile_rgba((short *) src, w, h, dst, dst_stride); @@ -867,7 +978,7 @@ pipe_put_tile_rgba(struct pipe_surface *ps, b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); break; case PIPE_FORMAT_A1R5G5B5_UNORM: - /*a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ + a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); break; case PIPE_FORMAT_R5G6B5_UNORM: r5g6b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); @@ -879,19 +990,19 @@ pipe_put_tile_rgba(struct pipe_surface *ps, a4r4g4b4_put_tile_rgba((ushort *) packed, w, h, p, src_stride); break; case PIPE_FORMAT_L8_UNORM: - /*l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/ + l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); break; case PIPE_FORMAT_A8_UNORM: - /*a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/ + a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); break; case PIPE_FORMAT_I8_UNORM: - /*i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/ + i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); break; case PIPE_FORMAT_A8L8_UNORM: - /*a8_l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ + a8l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride); break; case PIPE_FORMAT_R16_SNORM: - /*r16_put_tile_rgba((short *) packed, w, h, p, src_stride);*/ + r16_put_tile_rgba((short *) packed, w, h, p, src_stride); break; case PIPE_FORMAT_R16G16B16A16_SNORM: r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride); diff --git a/src/gallium/auxiliary/util/u_string.h b/src/gallium/auxiliary/util/u_string.h index 73c88d87b4c..abc3232b492 100644 --- a/src/gallium/auxiliary/util/u_string.h +++ b/src/gallium/auxiliary/util/u_string.h @@ -176,6 +176,43 @@ util_memmove(void *dest, const void *src, size_t n) #endif +/** + * Printable string buffer + */ +struct util_strbuf +{ + char *str; + char *ptr; + size_t left; +}; + + +static INLINE void +util_strbuf_init(struct util_strbuf *sbuf, char *str, size_t size) +{ + sbuf->str = str; + sbuf->str[0] = 0; + sbuf->ptr = sbuf->str; + sbuf->left = size; +} + + +static INLINE void +util_strbuf_printf(struct util_strbuf *sbuf, const char *format, ...) +{ + if(sbuf->left > 1) { + size_t written; + va_list ap; + va_start(ap, format); + written = util_vsnprintf(sbuf->ptr, sbuf->left, format, ap); + va_end(ap); + sbuf->ptr += written; + sbuf->left -= written; + } +} + + + #ifdef __cplusplus } #endif diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index cf9b68b695f..2bf441a0c5f 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.c +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -132,6 +132,11 @@ cell_is_format_supported( struct pipe_screen *screen, static void cell_destroy_screen( struct pipe_screen *screen ) { + struct pipe_winsys *winsys = screen->winsys; + + if(winsys->destroy) + winsys->destroy(winsys); + FREE(screen); } diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index 4c01b8d5b17..e3d19017b5d 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -44,6 +44,9 @@ static void i915_destroy( struct pipe_context *pipe ) struct i915_context *i915 = i915_context( pipe ); draw_destroy( i915->draw ); + + if(i915->winsys) + i915->winsys->destroy(i915->winsys); FREE( i915 ); } diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c index 4b1b8af7da8..0afa17bed85 100644 --- a/src/gallium/drivers/i915simple/i915_screen.c +++ b/src/gallium/drivers/i915simple/i915_screen.c @@ -193,6 +193,11 @@ i915_is_format_supported( struct pipe_screen *screen, static void i915_destroy_screen( struct pipe_screen *screen ) { + struct pipe_winsys *winsys = screen->winsys; + + if(winsys->destroy) + winsys->destroy(winsys); + FREE(screen); } diff --git a/src/gallium/drivers/i915simple/i915_winsys.h b/src/gallium/drivers/i915simple/i915_winsys.h index 9afaa16a62c..81904c2a742 100644 --- a/src/gallium/drivers/i915simple/i915_winsys.h +++ b/src/gallium/drivers/i915simple/i915_winsys.h @@ -75,6 +75,8 @@ struct pipe_screen; */ struct i915_winsys { + void (*destroy)( struct i915_winsys *sws ); + /** * Get the current batch buffer from the winsys. */ diff --git a/src/gallium/drivers/i965simple/brw_context.c b/src/gallium/drivers/i965simple/brw_context.c index a276cc0535d..8326f7b9c40 100644 --- a/src/gallium/drivers/i965simple/brw_context.c +++ b/src/gallium/drivers/i965simple/brw_context.c @@ -52,6 +52,9 @@ static void brw_destroy(struct pipe_context *pipe) { struct brw_context *brw = brw_context(pipe); + if(brw->winsys->destroy) + brw->winsys->destroy(brw->winsys); + FREE(brw); } diff --git a/src/gallium/drivers/i965simple/brw_context.h b/src/gallium/drivers/i965simple/brw_context.h index f00eb34f92b..3079485180b 100644 --- a/src/gallium/drivers/i965simple/brw_context.h +++ b/src/gallium/drivers/i965simple/brw_context.h @@ -188,7 +188,7 @@ extern int BRW_DEBUG; } while(0) #define PRINT(...) do { \ - debug_printf(brw->pipe.winsys, __VA_ARGS__); \ + debug_printf(__VA_ARGS__); \ } while(0) struct brw_state_flags { diff --git a/src/gallium/drivers/i965simple/brw_screen.c b/src/gallium/drivers/i965simple/brw_screen.c index 6d8f24d1c49..fadfbf94ab3 100644 --- a/src/gallium/drivers/i965simple/brw_screen.c +++ b/src/gallium/drivers/i965simple/brw_screen.c @@ -206,6 +206,11 @@ brw_is_format_supported( struct pipe_screen *screen, static void brw_destroy_screen( struct pipe_screen *screen ) { + struct pipe_winsys *winsys = screen->winsys; + + if(winsys->destroy) + winsys->destroy(winsys); + FREE(screen); } diff --git a/src/gallium/drivers/i965simple/brw_winsys.h b/src/gallium/drivers/i965simple/brw_winsys.h index b67bd737502..ec1e400418f 100644 --- a/src/gallium/drivers/i965simple/brw_winsys.h +++ b/src/gallium/drivers/i965simple/brw_winsys.h @@ -112,6 +112,8 @@ enum brw_cache_id { */ struct brw_winsys { + void (*destroy)(struct brw_winsys *); + /** * Reserve space on batch buffer. * diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index 33888abcc5e..0c82692c6ee 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -104,6 +104,8 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) } } break; + case PIPE_FORMAT_X8Z24_UNORM: + /* fall-through */ case PIPE_FORMAT_S8Z24_UNORM: { float scale = (float) ((1 << 24) - 1); @@ -119,6 +121,8 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) } } break; + case PIPE_FORMAT_Z24X8_UNORM: + /* fall-through */ case PIPE_FORMAT_Z24S8_UNORM: { float scale = (float) ((1 << 24) - 1); @@ -209,6 +213,9 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) tile->data.depth16[y][x] = (ushort) bzzzz[j]; } break; + case PIPE_FORMAT_X8Z24_UNORM: + /* fall-through */ + /* (yes, this falls through to a different case than above) */ case PIPE_FORMAT_Z32_UNORM: for (j = 0; j < QUAD_SIZE; j++) { int x = quad->x0 % TILE_SIZE + (j & 1); @@ -234,6 +241,13 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) tile->data.depth32[y][x] = z24s8; } break; + case PIPE_FORMAT_Z24X8_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->x0 % TILE_SIZE + (j & 1); + int y = quad->y0 % TILE_SIZE + (j >> 1); + tile->data.depth32[y][x] = bzzzz[j] << 8; + } + break; default: assert(0); } diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index ceb5616b5d0..f6b3d7ac24f 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -139,6 +139,11 @@ softpipe_is_format_supported( struct pipe_screen *screen, static void softpipe_destroy_screen( struct pipe_screen *screen ) { + struct pipe_winsys *winsys = screen->winsys; + + if(winsys->destroy) + winsys->destroy(winsys); + FREE(screen); } diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 4321ca46f42..b48eec730b2 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -284,9 +284,9 @@ static void print_vertex(const struct setup_context *setup, const float (*v)[4]) { int i; - debug_printf("Vertex: (%p)\n", v); + debug_printf(" Vertex: (%p)\n", v); for (i = 0; i < setup->quad.nr_attrs; i++) { - debug_printf(" %d: %f %f %f %f\n", i, + debug_printf(" %d: %f %f %f %f\n", i, v[i][0], v[i][1], v[i][2], v[i][3]); } } diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index ed150527e2d..01f4d0ca811 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -601,9 +601,9 @@ get_texel(struct tgsi_sampler *sampler, unsigned face, unsigned level, int x, int y, int z, float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j) { - if (x < 0 || x >= sampler->texture->width[level] || - y < 0 || y >= sampler->texture->height[level] || - z < 0 || z >= sampler->texture->depth[level]) { + if (x < 0 || x >= (int) sampler->texture->width[level] || + y < 0 || y >= (int) sampler->texture->height[level] || + z < 0 || z >= (int) sampler->texture->depth[level]) { rgba[0][j] = sampler->state->border_color[0]; rgba[1][j] = sampler->state->border_color[1]; rgba[2][j] = sampler->state->border_color[2]; @@ -619,6 +619,12 @@ get_texel(struct tgsi_sampler *sampler, rgba[1][j] = tile->data.color[ty][tx][1]; rgba[2][j] = tile->data.color[ty][tx][2]; rgba[3][j] = tile->data.color[ty][tx][3]; + if (0) + { + debug_printf("Get texel %f %f %f %f from %s\n", + rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j], + pf_name(sampler->texture->format)); + } } } diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 5d10234945f..57c12ffe335 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -170,7 +170,9 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, PIPE_BUFFER_USAGE_CPU_WRITE); tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM || + ps->format == PIPE_FORMAT_X8Z24_UNORM || ps->format == PIPE_FORMAT_Z24S8_UNORM || + ps->format == PIPE_FORMAT_Z24X8_UNORM || ps->format == PIPE_FORMAT_Z16_UNORM || ps->format == PIPE_FORMAT_Z32_UNORM || ps->format == PIPE_FORMAT_S8_UNORM); diff --git a/src/gallium/drivers/trace/README b/src/gallium/drivers/trace/README new file mode 100644 index 00000000000..81da610bd5e --- /dev/null +++ b/src/gallium/drivers/trace/README @@ -0,0 +1,37 @@ +This directory contains a Gallium3D pipe driver which traces all incoming calls. + +To build, invoke scons on the top dir as + + scons statetrackers=mesa drivers=softpipe,i915simple,trace winsys=xlib + +To use do + + ln -s libGL.so build/linux-x86-debug/gallium/winsys/xlib/libGL.so.1 + export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/gallium/winsys/xlib + export GALLIUM_TRACE=y + +ensure the right libGL.so is being picked by doing + + ldd `which glxingo` + +and then try running + + glxinfo + +which should create a gallium.*.trace file, which is an XML file. You can view +copying trace.xsl and trace.css to the same directory, and opening with a +XSLT capable browser like Firefox or Internet Explorer. It often happens that +the trace file was not properly terminated, and a + + </trace> + +closing tag is missing from the file end. Add it before try to open or +further transform it by doing + + echo '</trace>' >> gallium.??.trace + + +This is still work in progress. + +-- +Jose Fonseca <[email protected]> diff --git a/src/gallium/drivers/trace/SConscript b/src/gallium/drivers/trace/SConscript new file mode 100644 index 00000000000..35507e21e4c --- /dev/null +++ b/src/gallium/drivers/trace/SConscript @@ -0,0 +1,16 @@ +Import('*') + +env = env.Clone() + +trace = env.ConvenienceLibrary( + target = 'trace', + source = [ + 'tr_context.c', + 'tr_dump.c', + 'tr_screen.c', + 'tr_state.c', + 'tr_stream.c', + 'tr_winsys.c', + ]) + +Export('trace')
\ No newline at end of file diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c new file mode 100644 index 00000000000..47a217ec7c7 --- /dev/null +++ b/src/gallium/drivers/trace/tr_context.c @@ -0,0 +1,1064 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, 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 TUNGSTEN GRAPHICS 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 "pipe/p_util.h" + +#include "tr_stream.h" +#include "tr_dump.h" +#include "tr_state.h" +#include "tr_winsys.h" +#include "tr_screen.h" +#include "tr_context.h" + + +static INLINE void +trace_context_set_edgeflags(struct pipe_context *_pipe, + const unsigned *bitfield) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_edgeflags"); + + trace_dump_arg(stream, ptr, pipe); + /* FIXME: we don't know how big this array is */ + trace_dump_arg(stream, ptr, bitfield); + + pipe->set_edgeflags(pipe, bitfield);; + + trace_dump_call_end(stream); +} + + +static INLINE boolean +trace_context_draw_arrays(struct pipe_context *_pipe, + unsigned mode, unsigned start, unsigned count) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + boolean result; + + trace_dump_call_begin(stream, "pipe_context", "draw_arrays"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, uint, mode); + trace_dump_arg(stream, uint, start); + trace_dump_arg(stream, uint, count); + + result = pipe->draw_arrays(pipe, mode, start, count);; + + trace_dump_ret(stream, bool, result); + + trace_dump_call_end(stream); + + return result; +} + + +static INLINE boolean +trace_context_draw_elements(struct pipe_context *_pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + boolean result; + + trace_dump_call_begin(stream, "pipe_context", "draw_elements"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, indexBuffer); + trace_dump_arg(stream, uint, indexSize); + trace_dump_arg(stream, uint, mode); + trace_dump_arg(stream, uint, start); + trace_dump_arg(stream, uint, count); + + result = pipe->draw_elements(pipe, indexBuffer, indexSize, mode, start, count);; + + trace_dump_ret(stream, bool, result); + + trace_dump_call_end(stream); + + return result; +} + + +static INLINE boolean +trace_context_draw_range_elements(struct pipe_context *_pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned minIndex, + unsigned maxIndex, + unsigned mode, + unsigned start, + unsigned count) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + boolean result; + + trace_dump_call_begin(stream, "pipe_context", "draw_range_elements"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, indexBuffer); + trace_dump_arg(stream, uint, indexSize); + trace_dump_arg(stream, uint, minIndex); + trace_dump_arg(stream, uint, maxIndex); + trace_dump_arg(stream, uint, mode); + trace_dump_arg(stream, uint, start); + trace_dump_arg(stream, uint, count); + + result = pipe->draw_range_elements(pipe, + indexBuffer, + indexSize, minIndex, maxIndex, + mode, start, count); + + trace_dump_ret(stream, bool, result); + + trace_dump_call_end(stream); + + return result; +} + + +static INLINE struct pipe_query * +trace_context_create_query(struct pipe_context *_pipe, + unsigned query_type) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + struct pipe_query *result; + + trace_dump_call_begin(stream, "pipe_context", "create_query"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, uint, query_type); + + result = pipe->create_query(pipe, query_type);; + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static INLINE void +trace_context_destroy_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "destroy_query"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, query); + + pipe->destroy_query(pipe, query);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_begin_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "begin_query"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, query); + + pipe->begin_query(pipe, query);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_end_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "end_query"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, query); + + pipe->end_query(pipe, query); + + trace_dump_call_end(stream); +} + + +static INLINE boolean +trace_context_get_query_result(struct pipe_context *_pipe, + struct pipe_query *query, + boolean wait, + uint64 *presult) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + uint64 result; + boolean _result; + + trace_dump_call_begin(stream, "pipe_context", "get_query_result"); + + trace_dump_arg(stream, ptr, pipe); + + _result = pipe->get_query_result(pipe, query, wait, presult);; + result = *presult; + + trace_dump_arg(stream, uint, result); + trace_dump_ret(stream, bool, _result); + + trace_dump_call_end(stream); + + return _result; +} + + +static INLINE void * +trace_context_create_blend_state(struct pipe_context *_pipe, + const struct pipe_blend_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + void * result; + + trace_dump_call_begin(stream, "pipe_context", "create_blend_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, blend_state, state); + + result = pipe->create_blend_state(pipe, state);; + + trace_dump_call_end(stream); + + return result; +} + + +static INLINE void +trace_context_bind_blend_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "bind_blend_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->bind_blend_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_delete_blend_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "delete_blend_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->delete_blend_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void * +trace_context_create_sampler_state(struct pipe_context *_pipe, + const struct pipe_sampler_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + void * result; + + trace_dump_call_begin(stream, "pipe_context", "create_sampler_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + result = pipe->create_sampler_state(pipe, state);; + + trace_dump_ret(stream, sampler_state, result); + + trace_dump_call_end(stream); + + return result; +} + + +static INLINE void +trace_context_bind_sampler_states(struct pipe_context *_pipe, + unsigned num_states, void **states) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "bind_sampler_states"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, uint, num_states); + trace_dump_arg_array(stream, ptr, states, num_states); + + pipe->bind_sampler_states(pipe, num_states, states);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_delete_sampler_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "delete_sampler_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->delete_sampler_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void * +trace_context_create_rasterizer_state(struct pipe_context *_pipe, + const struct pipe_rasterizer_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + void * result; + + trace_dump_call_begin(stream, "pipe_context", "create_rasterizer_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, rasterizer_state, state); + + result = pipe->create_rasterizer_state(pipe, state);; + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static INLINE void +trace_context_bind_rasterizer_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "bind_rasterizer_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->bind_rasterizer_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_delete_rasterizer_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "delete_rasterizer_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->delete_rasterizer_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void * +trace_context_create_depth_stencil_alpha_state(struct pipe_context *_pipe, + const struct pipe_depth_stencil_alpha_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + void * result; + + trace_dump_call_begin(stream, "pipe_context", "create_depth_stencil_alpha_state"); + + result = pipe->create_depth_stencil_alpha_state(pipe, state);; + + trace_dump_ret(stream, ptr, result); + trace_dump_arg(stream, depth_stencil_alpha_state, state); + + trace_dump_call_end(stream); + + return result; +} + + +static INLINE void +trace_context_bind_depth_stencil_alpha_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "bind_depth_stencil_alpha_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->bind_depth_stencil_alpha_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_delete_depth_stencil_alpha_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "delete_depth_stencil_alpha_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->delete_depth_stencil_alpha_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void * +trace_context_create_fs_state(struct pipe_context *_pipe, + const struct pipe_shader_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + void * result; + + trace_dump_call_begin(stream, "pipe_context", "create_fs_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, shader_state, state); + + result = pipe->create_fs_state(pipe, state);; + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static INLINE void +trace_context_bind_fs_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "bind_fs_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->bind_fs_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_delete_fs_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "delete_fs_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->delete_fs_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void * +trace_context_create_vs_state(struct pipe_context *_pipe, + const struct pipe_shader_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + void * result; + + trace_dump_call_begin(stream, "pipe_context", "create_vs_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, shader_state, state); + + result = pipe->create_vs_state(pipe, state);; + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static INLINE void +trace_context_bind_vs_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "bind_vs_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->bind_vs_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_delete_vs_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "delete_vs_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->delete_vs_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_set_blend_color(struct pipe_context *_pipe, + const struct pipe_blend_color *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_blend_color"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, blend_color, state); + + pipe->set_blend_color(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_set_clip_state(struct pipe_context *_pipe, + const struct pipe_clip_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_clip_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, clip_state, state); + + pipe->set_clip_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_set_constant_buffer(struct pipe_context *_pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buffer) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_constant_buffer"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, uint, shader); + trace_dump_arg(stream, uint, index); + trace_dump_arg(stream, constant_buffer, buffer); + + pipe->set_constant_buffer(pipe, shader, index, buffer);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_set_framebuffer_state(struct pipe_context *_pipe, + const struct pipe_framebuffer_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_framebuffer_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, framebuffer_state, state); + + pipe->set_framebuffer_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_set_polygon_stipple(struct pipe_context *_pipe, + const struct pipe_poly_stipple *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_polygon_stipple"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, poly_stipple, state); + + pipe->set_polygon_stipple(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_set_scissor_state(struct pipe_context *_pipe, + const struct pipe_scissor_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_scissor_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, scissor_state, state); + + pipe->set_scissor_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_set_viewport_state(struct pipe_context *_pipe, + const struct pipe_viewport_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_viewport_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, viewport_state, state); + + pipe->set_viewport_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_set_sampler_textures(struct pipe_context *_pipe, + unsigned num_textures, + struct pipe_texture **textures) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_sampler_textures"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, uint, num_textures); + trace_dump_arg_array(stream, ptr, textures, num_textures); + + pipe->set_sampler_textures(pipe, num_textures, textures);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_set_vertex_buffers(struct pipe_context *_pipe, + unsigned num_buffers, + const struct pipe_vertex_buffer *buffers) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_vertex_buffers"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, uint, num_buffers); + + trace_dump_arg_begin(stream, "buffers"); + trace_dump_struct_array(stream, vertex_buffer, buffers, num_buffers); + trace_dump_arg_end(stream); + + pipe->set_vertex_buffers(pipe, num_buffers, buffers);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_set_vertex_elements(struct pipe_context *_pipe, + unsigned num_elements, + const struct pipe_vertex_element *elements) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_vertex_elements"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, uint, num_elements); + trace_dump_arg(stream, ptr, elements); + + trace_dump_arg_begin(stream, "elements"); + trace_dump_struct_array(stream, vertex_element, elements, num_elements); + trace_dump_arg_end(stream); + + pipe->set_vertex_elements(pipe, num_elements, elements);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_surface_copy(struct pipe_context *_pipe, + boolean do_flip, + struct pipe_surface *dest, + unsigned destx, unsigned desty, + struct pipe_surface *src, + unsigned srcx, unsigned srcy, + unsigned width, unsigned height) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "surface_copy"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, bool, do_flip); + trace_dump_arg(stream, ptr, dest); + trace_dump_arg(stream, uint, destx); + trace_dump_arg(stream, uint, desty); + trace_dump_arg(stream, ptr, src); + trace_dump_arg(stream, uint, srcx); + trace_dump_arg(stream, uint, srcy); + trace_dump_arg(stream, uint, width); + trace_dump_arg(stream, uint, height); + + pipe->surface_copy(pipe, do_flip, + dest, destx, desty, + src, srcx, srcy, width, height); + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_surface_fill(struct pipe_context *_pipe, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, + unsigned value) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "surface_fill"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, dst); + trace_dump_arg(stream, uint, dstx); + trace_dump_arg(stream, uint, dsty); + trace_dump_arg(stream, uint, width); + trace_dump_arg(stream, uint, height); + + pipe->surface_fill(pipe, dst, dstx, dsty, width, height, value);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_clear(struct pipe_context *_pipe, + struct pipe_surface *surface, + unsigned clearValue) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "clear"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, surface); + trace_dump_arg(stream, uint, clearValue); + + pipe->clear(pipe, surface, clearValue);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_flush(struct pipe_context *_pipe, + unsigned flags, + struct pipe_fence_handle **fence) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "flush"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, uint, flags); + trace_dump_arg(stream, ptr, fence); + + pipe->flush(pipe, flags, fence);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_destroy(struct pipe_context *_pipe) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "destroy"); + + trace_dump_arg(stream, ptr, pipe); + + pipe->destroy(pipe); + + trace_dump_call_end(stream); + + FREE(tr_ctx); +} + + +struct pipe_context * +trace_context_create(struct pipe_context *pipe) +{ + struct trace_context *tr_ctx; + + if(!debug_get_bool_option("GALLIUM_TRACE", FALSE)) + return pipe; + + tr_ctx = CALLOC_STRUCT(trace_context); + if(!tr_ctx) + return NULL; + + tr_ctx->base.winsys = pipe->winsys; + tr_ctx->base.screen = pipe->screen; + tr_ctx->base.destroy = trace_context_destroy; + tr_ctx->base.set_edgeflags = trace_context_set_edgeflags; + tr_ctx->base.draw_arrays = trace_context_draw_arrays; + tr_ctx->base.draw_elements = trace_context_draw_elements; + tr_ctx->base.draw_range_elements = trace_context_draw_range_elements; + tr_ctx->base.create_query = trace_context_create_query; + tr_ctx->base.destroy_query = trace_context_destroy_query; + tr_ctx->base.begin_query = trace_context_begin_query; + tr_ctx->base.end_query = trace_context_end_query; + tr_ctx->base.get_query_result = trace_context_get_query_result; + tr_ctx->base.create_blend_state = trace_context_create_blend_state; + tr_ctx->base.bind_blend_state = trace_context_bind_blend_state; + tr_ctx->base.delete_blend_state = trace_context_delete_blend_state; + tr_ctx->base.create_sampler_state = trace_context_create_sampler_state; + tr_ctx->base.bind_sampler_states = trace_context_bind_sampler_states; + tr_ctx->base.delete_sampler_state = trace_context_delete_sampler_state; + tr_ctx->base.create_rasterizer_state = trace_context_create_rasterizer_state; + tr_ctx->base.bind_rasterizer_state = trace_context_bind_rasterizer_state; + tr_ctx->base.delete_rasterizer_state = trace_context_delete_rasterizer_state; + tr_ctx->base.create_depth_stencil_alpha_state = trace_context_create_depth_stencil_alpha_state; + tr_ctx->base.bind_depth_stencil_alpha_state = trace_context_bind_depth_stencil_alpha_state; + tr_ctx->base.delete_depth_stencil_alpha_state = trace_context_delete_depth_stencil_alpha_state; + tr_ctx->base.create_fs_state = trace_context_create_fs_state; + tr_ctx->base.bind_fs_state = trace_context_bind_fs_state; + tr_ctx->base.delete_fs_state = trace_context_delete_fs_state; + tr_ctx->base.create_vs_state = trace_context_create_vs_state; + tr_ctx->base.bind_vs_state = trace_context_bind_vs_state; + tr_ctx->base.delete_vs_state = trace_context_delete_vs_state; + tr_ctx->base.set_blend_color = trace_context_set_blend_color; + tr_ctx->base.set_clip_state = trace_context_set_clip_state; + tr_ctx->base.set_constant_buffer = trace_context_set_constant_buffer; + tr_ctx->base.set_framebuffer_state = trace_context_set_framebuffer_state; + tr_ctx->base.set_polygon_stipple = trace_context_set_polygon_stipple; + tr_ctx->base.set_scissor_state = trace_context_set_scissor_state; + tr_ctx->base.set_viewport_state = trace_context_set_viewport_state; + tr_ctx->base.set_sampler_textures = trace_context_set_sampler_textures; + tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers; + tr_ctx->base.set_vertex_elements = trace_context_set_vertex_elements; + tr_ctx->base.surface_copy = trace_context_surface_copy; + tr_ctx->base.surface_fill = trace_context_surface_fill; + tr_ctx->base.clear = trace_context_clear; + tr_ctx->base.flush = trace_context_flush; + + tr_ctx->pipe = pipe; + + /* We don't want to trace the internal pipe calls */ + pipe->winsys = trace_winsys(pipe->winsys)->winsys; + pipe->screen = trace_screen(pipe->screen)->screen; + + return &tr_ctx->base; +} diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h new file mode 100644 index 00000000000..80fb5980d6a --- /dev/null +++ b/src/gallium/drivers/trace/tr_context.h @@ -0,0 +1,58 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, 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 TUNGSTEN GRAPHICS 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 TR_CONTEXT_H_ +#define TR_CONTEXT_H_ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_context.h" + + +struct trace_context +{ + struct pipe_context base; + + struct pipe_context *pipe; +}; + + +static INLINE struct trace_context * +trace_context(struct pipe_context *pipe) +{ + assert(pipe); + return (struct trace_context *)pipe; +} + + + +struct pipe_context * +trace_context_create(struct pipe_context *pipe); + + +#endif /* TR_CONTEXT_H_ */ diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c new file mode 100644 index 00000000000..f545de30f4f --- /dev/null +++ b/src/gallium/drivers/trace/tr_dump.c @@ -0,0 +1,364 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, 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 TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + + +/** + * @file + * Trace dumping functions. + * + * For now we just use standard XML for dumping the trace calls, as this is + * simple to write, parse, and visually inspect, but the actual representation + * is abstracted out of this file, so that we can switch to a binary + * representation if/when it becomes justified. + * + * @author Jose Fonseca <[email protected]> + */ + + +#include "pipe/p_compiler.h" +#include "util/u_string.h" + +#include "tr_stream.h" +#include "tr_dump.h" + + +static INLINE void +trace_dump_write(struct trace_stream *stream, const char *s) +{ + trace_stream_write(stream, s, strlen(s)); +} + + +static INLINE void +trace_dump_writef(struct trace_stream *stream, const char *format, ...) +{ + char buf[1024]; + va_list ap; + va_start(ap, format); + util_vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + trace_dump_write(stream, buf); +} + + +static INLINE void +trace_dump_escape(struct trace_stream *stream, const char *str) +{ + const unsigned char *p = (const unsigned char *)str; + unsigned char c; + while((c = *p++) != 0) { + if(c == '<') + trace_dump_write(stream, "<"); + else if(c == '>') + trace_dump_write(stream, ">"); + else if(c == '&') + trace_dump_write(stream, "&"); + else if(c == '\'') + trace_dump_write(stream, "'"); + else if(c == '\"') + trace_dump_write(stream, """); + else if(c >= 0x20 && c <= 0x7e) + trace_dump_writef(stream, "%c", c); + else + trace_dump_writef(stream, "&#%u;", c); + } +} + + +static INLINE void +trace_dump_indent(struct trace_stream *stream, unsigned level) +{ + unsigned i; + for(i = 0; i < level; ++i) + trace_dump_write(stream, "\t"); +} + + +static INLINE void +trace_dump_newline(struct trace_stream *stream) +{ + trace_dump_write(stream, "\n"); +} + + +static INLINE void +trace_dump_tag(struct trace_stream *stream, + const char *name) +{ + trace_dump_write(stream, "<"); + trace_dump_write(stream, name); + trace_dump_write(stream, "/>"); +} + + +static INLINE void +trace_dump_tag_begin(struct trace_stream *stream, + const char *name) +{ + trace_dump_write(stream, "<"); + trace_dump_write(stream, name); + trace_dump_write(stream, ">"); +} + +static INLINE void +trace_dump_tag_begin1(struct trace_stream *stream, + const char *name, + const char *attr1, const char *value1) +{ + trace_dump_write(stream, "<"); + trace_dump_write(stream, name); + trace_dump_write(stream, " "); + trace_dump_write(stream, attr1); + trace_dump_write(stream, "='"); + trace_dump_escape(stream, value1); + trace_dump_write(stream, "'>"); +} + + +static INLINE void +trace_dump_tag_begin2(struct trace_stream *stream, + const char *name, + const char *attr1, const char *value1, + const char *attr2, const char *value2) +{ + trace_dump_write(stream, "<"); + trace_dump_write(stream, name); + trace_dump_write(stream, " "); + trace_dump_write(stream, attr1); + trace_dump_write(stream, "=\'"); + trace_dump_escape(stream, value1); + trace_dump_write(stream, "\' "); + trace_dump_write(stream, attr2); + trace_dump_write(stream, "=\'"); + trace_dump_escape(stream, value2); + trace_dump_write(stream, "\'>"); +} + + +static INLINE void +trace_dump_tag_begin3(struct trace_stream *stream, + const char *name, + const char *attr1, const char *value1, + const char *attr2, const char *value2, + const char *attr3, const char *value3) +{ + trace_dump_write(stream, "<"); + trace_dump_write(stream, name); + trace_dump_write(stream, " "); + trace_dump_write(stream, attr1); + trace_dump_write(stream, "=\'"); + trace_dump_escape(stream, value1); + trace_dump_write(stream, "\' "); + trace_dump_write(stream, attr2); + trace_dump_write(stream, "=\'"); + trace_dump_escape(stream, value2); + trace_dump_write(stream, "\' "); + trace_dump_write(stream, attr3); + trace_dump_write(stream, "=\'"); + trace_dump_escape(stream, value3); + trace_dump_write(stream, "\'>"); +} + + +static INLINE void +trace_dump_tag_end(struct trace_stream *stream, + const char *name) +{ + trace_dump_write(stream, "</"); + trace_dump_write(stream, name); + trace_dump_write(stream, ">"); +} + + +void trace_dump_trace_begin(struct trace_stream *stream, + unsigned version) +{ + trace_dump_write(stream, "<?xml version='1.0' encoding='UTF-8'?>\n"); + trace_dump_write(stream, "<?xml-stylesheet type='text/xsl' href='trace.xsl'?>\n"); + trace_dump_writef(stream, "<trace version='%u'>\n", version); +} + + +void trace_dump_trace_end(struct trace_stream *stream) +{ + trace_dump_write(stream, "</trace>\n"); +} + +void trace_dump_call_begin(struct trace_stream *stream, + const char *klass, const char *method) +{ + trace_dump_indent(stream, 1); + trace_dump_tag_begin2(stream, "call", "class", klass, "method", method); + trace_dump_newline(stream); +} + +void trace_dump_call_end(struct trace_stream *stream) +{ + trace_dump_indent(stream, 1); + trace_dump_tag_end(stream, "call"); + trace_dump_newline(stream); +} + +void trace_dump_arg_begin(struct trace_stream *stream, + const char *name) +{ + trace_dump_indent(stream, 2); + trace_dump_tag_begin1(stream, "arg", "name", name); +} + +void trace_dump_arg_end(struct trace_stream *stream) +{ + trace_dump_tag_end(stream, "arg"); + trace_dump_newline(stream); +} + +void trace_dump_ret_begin(struct trace_stream *stream) +{ + trace_dump_indent(stream, 2); + trace_dump_tag_begin(stream, "ret"); +} + +void trace_dump_ret_end(struct trace_stream *stream) +{ + trace_dump_tag_end(stream, "ret"); + trace_dump_newline(stream); +} + +void trace_dump_bool(struct trace_stream *stream, + int value) +{ + trace_dump_writef(stream, "<bool>%c</bool>", value ? '1' : '0'); +} + +void trace_dump_int(struct trace_stream *stream, + long int value) +{ + trace_dump_writef(stream, "<int>%li</int>", value); +} + +void trace_dump_uint(struct trace_stream *stream, + long unsigned value) +{ + trace_dump_writef(stream, "<uint>%lu</uint>", value); +} + +void trace_dump_float(struct trace_stream *stream, + double value) +{ + trace_dump_writef(stream, "<float>%g</float>", value); +} + +void trace_dump_bytes(struct trace_stream *stream, + const void *data, + long unsigned size) +{ + static char hex_table[] = "0123456789ABCDE"; + const uint8_t *p = data; + long unsigned i; + trace_dump_write(stream, "<bytes>"); + for(i = 0; i < size; ++i) { + uint8_t byte = *p++; + char str[3]; + str[0] = hex_table[byte >> 4]; + str[1] = hex_table[byte & 0xf]; + str[2] = 0; + trace_dump_write(stream, str); + } + trace_dump_write(stream, "</bytes>"); +} + +void trace_dump_string(struct trace_stream *stream, + const char *str) +{ + trace_dump_write(stream, "<string>"); + trace_dump_escape(stream, str); + trace_dump_write(stream, "</string>"); +} + +void trace_dump_enum(struct trace_stream *stream, + const char *value) +{ + trace_dump_write(stream, "<enum>"); + trace_dump_escape(stream, value); + trace_dump_write(stream, "</enum>"); +} + +void trace_dump_array_begin(struct trace_stream *stream) +{ + trace_dump_write(stream, "<array>"); +} + +void trace_dump_array_end(struct trace_stream *stream) +{ + trace_dump_write(stream, "</array>"); +} + +void trace_dump_elem_begin(struct trace_stream *stream) +{ + trace_dump_write(stream, "<elem>"); +} + +void trace_dump_elem_end(struct trace_stream *stream) +{ + trace_dump_write(stream, "</elem>"); +} + +void trace_dump_struct_begin(struct trace_stream *stream, + const char *name) +{ + trace_dump_writef(stream, "<struct name='%s'>", name); +} + +void trace_dump_struct_end(struct trace_stream *stream) +{ + trace_dump_write(stream, "</struct>"); +} + +void trace_dump_member_begin(struct trace_stream *stream, + const char *name) +{ + trace_dump_writef(stream, "<member name='%s'>", name); +} + +void trace_dump_member_end(struct trace_stream *stream) +{ + trace_dump_write(stream, "</member>"); +} + +void trace_dump_null(struct trace_stream *stream) +{ + trace_dump_write(stream, "<null/>"); +} + +void trace_dump_ptr(struct trace_stream *stream, + const void *value) +{ + if(value) + trace_dump_writef(stream, "<ptr>%p</ptr>", value); + else + trace_dump_null(stream); +} diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h new file mode 100644 index 00000000000..b2367c3288a --- /dev/null +++ b/src/gallium/drivers/trace/tr_dump.h @@ -0,0 +1,134 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation streams (the + * "Software"), to deal in the Software without restriction, including + * without limitation 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 TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + +/** + * @file + * Trace data dumping primitives. + */ + +#ifndef TR_DUMP_H +#define TR_DUMP_H + + +#include "pipe/p_util.h" + + +struct trace_stream; + + +void trace_dump_trace_begin(struct trace_stream *stream, unsigned version); +void trace_dump_trace_end(struct trace_stream *stream); +void trace_dump_call_begin(struct trace_stream *stream, const char *klass, const char *method); +void trace_dump_call_end(struct trace_stream *stream); +void trace_dump_arg_begin(struct trace_stream *stream, const char *name); +void trace_dump_arg_end(struct trace_stream *stream); +void trace_dump_ret_begin(struct trace_stream *stream); +void trace_dump_ret_end(struct trace_stream *stream); +void trace_dump_bool(struct trace_stream *stream, int value); +void trace_dump_int(struct trace_stream *stream, long int value); +void trace_dump_uint(struct trace_stream *stream, long unsigned value); +void trace_dump_float(struct trace_stream *stream, double value); +void trace_dump_bytes(struct trace_stream *stream, const void *data, long unsigned size); +void trace_dump_string(struct trace_stream *stream, const char *str); +void trace_dump_enum(struct trace_stream *stream, const char *value); +void trace_dump_array_begin(struct trace_stream *stream); +void trace_dump_array_end(struct trace_stream *stream); +void trace_dump_elem_begin(struct trace_stream *stream); +void trace_dump_elem_end(struct trace_stream *stream); +void trace_dump_struct_begin(struct trace_stream *stream, const char *name); +void trace_dump_struct_end(struct trace_stream *stream); +void trace_dump_member_begin(struct trace_stream *stream, const char *name); +void trace_dump_member_end(struct trace_stream *stream); +void trace_dump_null(struct trace_stream *stream); +void trace_dump_ptr(struct trace_stream *stream, const void *value); + + +/* + * Code saving macros. + */ + +#define trace_dump_arg(_stream, _type, _arg) \ + do { \ + trace_dump_arg_begin(_stream, #_arg); \ + trace_dump_##_type(_stream, _arg); \ + trace_dump_arg_end(_stream); \ + } while(0) + +#define trace_dump_ret(_stream, _type, _arg) \ + do { \ + trace_dump_ret_begin(_stream); \ + trace_dump_##_type(_stream, _arg); \ + trace_dump_ret_end(_stream); \ + } while(0) + +#define trace_dump_array(_stream, _type, _obj, _size) \ + do { \ + unsigned long idx; \ + trace_dump_array_begin(_stream); \ + for(idx = 0; idx < (_size); ++idx) { \ + trace_dump_elem_begin(_stream); \ + trace_dump_##_type(_stream, (_obj)[idx]); \ + trace_dump_elem_end(_stream); \ + } \ + trace_dump_array_end(_stream); \ + } while(0) + +#define trace_dump_struct_array(_stream, _type, _obj, _size) \ + do { \ + unsigned long idx; \ + trace_dump_array_begin(_stream); \ + for(idx = 0; idx < (_size); ++idx) { \ + trace_dump_elem_begin(_stream); \ + trace_dump_##_type(_stream, &(_obj)[idx]); \ + trace_dump_elem_end(_stream); \ + } \ + trace_dump_array_end(_stream); \ + } while(0) + +#define trace_dump_member(_stream, _type, _obj, _member) \ + do { \ + trace_dump_member_begin(_stream, #_member); \ + trace_dump_##_type(_stream, (_obj)->_member); \ + trace_dump_member_end(_stream); \ + } while(0) + +#define trace_dump_arg_array(_stream, _type, _arg, _size) \ + do { \ + trace_dump_arg_begin(_stream, #_arg); \ + trace_dump_array(_stream, _type, _arg, _size); \ + trace_dump_arg_end(_stream); \ + } while(0) + +#define trace_dump_member_array(_stream, _type, _obj, _member) \ + do { \ + trace_dump_member_begin(_stream, #_member); \ + trace_dump_array(_stream, _type, (_obj)->_member, sizeof((_obj)->_member)/sizeof((_obj)->_member[0])); \ + trace_dump_member_end(_stream); \ + } while(0) + + +#endif /* TR_DUMP_H */ diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c new file mode 100644 index 00000000000..de885abae2c --- /dev/null +++ b/src/gallium/drivers/trace/tr_screen.c @@ -0,0 +1,383 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, 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 TUNGSTEN GRAPHICS 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 "pipe/p_util.h" + +#include "tr_stream.h" +#include "tr_dump.h" +#include "tr_state.h" +#include "tr_winsys.h" +#include "tr_screen.h" + + +static const char * +trace_screen_get_name(struct pipe_screen *_screen) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + const char *result; + + trace_dump_call_begin(stream, "pipe_screen", "get_name"); + + trace_dump_arg(stream, ptr, screen); + + result = screen->get_name(screen); + + trace_dump_ret(stream, string, result); + + trace_dump_call_end(stream); + + return result; +} + + +static const char * +trace_screen_get_vendor(struct pipe_screen *_screen) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + const char *result; + + trace_dump_call_begin(stream, "pipe_screen", "get_vendor"); + + trace_dump_arg(stream, ptr, screen); + + result = screen->get_vendor(screen); + + trace_dump_ret(stream, string, result); + + trace_dump_call_end(stream); + + return result; +} + + +static int +trace_screen_get_param(struct pipe_screen *_screen, + int param) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + int result; + + trace_dump_call_begin(stream, "pipe_screen", "get_param"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, int, param); + + result = screen->get_param(screen, param); + + trace_dump_ret(stream, int, result); + + trace_dump_call_end(stream); + + return result; +} + + +static float +trace_screen_get_paramf(struct pipe_screen *_screen, + int param) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + float result; + + trace_dump_call_begin(stream, "pipe_screen", "get_paramf"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, int, param); + + result = screen->get_paramf(screen, param); + + trace_dump_ret(stream, float, result); + + trace_dump_call_end(stream); + + return result; +} + + +static boolean +trace_screen_is_format_supported(struct pipe_screen *_screen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + boolean result; + + trace_dump_call_begin(stream, "pipe_screen", "is_format_supported"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, format, format); + trace_dump_arg(stream, int, target); + trace_dump_arg(stream, uint, tex_usage); + trace_dump_arg(stream, uint, geom_flags); + + result = screen->is_format_supported(screen, format, target, tex_usage, geom_flags); + + trace_dump_ret(stream, bool, result); + + trace_dump_call_end(stream); + + return result; +} + + +static struct pipe_texture * +trace_screen_texture_create(struct pipe_screen *_screen, + const struct pipe_texture *templat) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + struct pipe_texture *result; + + trace_dump_call_begin(stream, "pipe_screen", "texture_create"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, template, templat); + + result = screen->texture_create(screen, templat); + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static struct pipe_texture * +trace_screen_texture_blanket(struct pipe_screen *_screen, + const struct pipe_texture *templat, + const unsigned *ppitch, + struct pipe_buffer *buffer) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + unsigned pitch = *ppitch; + struct pipe_texture *result; + + trace_dump_call_begin(stream, "pipe_screen", "texture_blanket"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, template, templat); + trace_dump_arg(stream, uint, pitch); + trace_dump_arg(stream, ptr, buffer); + + result = screen->texture_blanket(screen, templat, ppitch, buffer); + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static void +trace_screen_texture_release(struct pipe_screen *_screen, + struct pipe_texture **ptexture) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + struct pipe_texture *texture = *ptexture; + + trace_dump_call_begin(stream, "pipe_screen", "texture_release"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, ptr, texture); + + screen->texture_release(screen, ptexture); + + trace_dump_call_end(stream); +} + +static struct pipe_surface * +trace_screen_get_tex_surface(struct pipe_screen *_screen, + struct pipe_texture *texture, + unsigned face, unsigned level, + unsigned zslice, + unsigned usage) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + struct pipe_surface *result; + + trace_dump_call_begin(stream, "pipe_screen", "get_tex_surface"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, ptr, texture); + trace_dump_arg(stream, uint, face); + trace_dump_arg(stream, uint, level); + trace_dump_arg(stream, uint, zslice); + trace_dump_arg(stream, uint, usage); + + result = screen->get_tex_surface(screen, texture, face, level, zslice, usage); + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static void +trace_screen_tex_surface_release(struct pipe_screen *_screen, + struct pipe_surface **psurface) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + struct pipe_surface *surface = *psurface; + + trace_dump_call_begin(stream, "pipe_screen", "tex_surface_release"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, ptr, surface); + + screen->tex_surface_release(screen, psurface); + + trace_dump_call_end(stream); +} + + +static void * +trace_screen_surface_map(struct pipe_screen *_screen, + struct pipe_surface *surface, + unsigned flags) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + struct pipe_surface *result; + + trace_dump_call_begin(stream, "pipe_screen", "surface_map"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, ptr, surface); + trace_dump_arg(stream, uint, flags); + + result = screen->surface_map(screen, surface, flags); + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static void +trace_screen_surface_unmap(struct pipe_screen *_screen, + struct pipe_surface *surface) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + + trace_dump_call_begin(stream, "pipe_screen", "surface_unmap"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, ptr, surface); + + screen->surface_unmap(screen, surface); + + trace_dump_call_end(stream); +} + + +static void +trace_screen_destroy(struct pipe_screen *_screen) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + + trace_dump_call_begin(stream, "pipe_screen", "destroy"); + + trace_dump_arg(stream, ptr, screen); + + screen->destroy(screen); + + trace_dump_call_end(stream); + + FREE(tr_scr); +} + + +struct pipe_screen * +trace_screen_create(struct pipe_screen *screen) +{ + struct trace_screen *tr_scr; + + if(!debug_get_bool_option("GALLIUM_TRACE", FALSE)) + return screen; + + tr_scr = CALLOC_STRUCT(trace_screen); + if(!tr_scr) + return NULL; + + tr_scr->base.winsys = screen->winsys; + tr_scr->base.destroy = trace_screen_destroy; + tr_scr->base.get_name = trace_screen_get_name; + tr_scr->base.get_vendor = trace_screen_get_vendor; + tr_scr->base.get_param = trace_screen_get_param; + tr_scr->base.get_paramf = trace_screen_get_paramf; + tr_scr->base.is_format_supported = trace_screen_is_format_supported; + tr_scr->base.texture_create = trace_screen_texture_create; + tr_scr->base.texture_blanket = trace_screen_texture_blanket; + tr_scr->base.texture_release = trace_screen_texture_release; + tr_scr->base.get_tex_surface = trace_screen_get_tex_surface; + tr_scr->base.tex_surface_release = trace_screen_tex_surface_release; + tr_scr->base.surface_map = trace_screen_surface_map; + tr_scr->base.surface_unmap = trace_screen_surface_unmap; + + tr_scr->screen = screen; + + tr_scr->stream = trace_winsys(screen->winsys)->stream; + if(!tr_scr->stream) + return NULL; + + /* We don't want to trace the internal pipe calls */ + screen->winsys = trace_winsys(screen->winsys)->winsys; + + return &tr_scr->base; +} diff --git a/src/gallium/drivers/trace/tr_screen.h b/src/gallium/drivers/trace/tr_screen.h new file mode 100644 index 00000000000..40b844778fe --- /dev/null +++ b/src/gallium/drivers/trace/tr_screen.h @@ -0,0 +1,63 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, 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 TUNGSTEN GRAPHICS 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 TR_SCREEN_H_ +#define TR_SCREEN_H_ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_screen.h" + + +struct trace_stream; + + +struct trace_screen +{ + struct pipe_screen base; + + struct pipe_screen *screen; + + struct trace_stream *stream; +}; + + +static INLINE struct trace_screen * +trace_screen(struct pipe_screen *screen) +{ + assert(screen); + return (struct trace_screen *)screen; +} + + + +struct pipe_screen * +trace_screen_create(struct pipe_screen *screen); + + +#endif /* TR_SCREEN_H_ */ diff --git a/src/gallium/drivers/trace/tr_state.c b/src/gallium/drivers/trace/tr_state.c new file mode 100644 index 00000000000..9ffe77146d9 --- /dev/null +++ b/src/gallium/drivers/trace/tr_state.c @@ -0,0 +1,488 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, 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 TUNGSTEN GRAPHICS 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 "pipe/p_compiler.h" +#include "tgsi/tgsi_dump.h" + +#include "tr_dump.h" +#include "tr_state.h" + + +void trace_dump_format(struct trace_stream *stream, + enum pipe_format format) +{ + trace_dump_enum(stream, pf_name(format) ); +} + + +void trace_dump_block(struct trace_stream *stream, + const struct pipe_format_block *block) +{ + trace_dump_struct_begin(stream, "pipe_format_block"); + trace_dump_member(stream, uint, block, size); + trace_dump_member(stream, uint, block, width); + trace_dump_member(stream, uint, block, height); + trace_dump_struct_end(stream); +} + + +void trace_dump_template(struct trace_stream *stream, + const struct pipe_texture *templat) +{ + assert(templat); + if(!templat) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_texture"); + + trace_dump_member(stream, int, templat, target); + trace_dump_member(stream, format, templat, format); + + trace_dump_member_begin(stream, "width"); + trace_dump_array(stream, uint, templat->width, 1); + trace_dump_member_end(stream); + + trace_dump_member_begin(stream, "height"); + trace_dump_array(stream, uint, templat->height, 1); + trace_dump_member_end(stream); + + trace_dump_member_begin(stream, "block"); + trace_dump_block(stream, &templat->block); + trace_dump_member_end(stream); + + trace_dump_member(stream, uint, templat, last_level); + trace_dump_member(stream, uint, templat, tex_usage); + + trace_dump_struct_end(stream); +} + + +void trace_dump_rasterizer_state(struct trace_stream *stream, + const struct pipe_rasterizer_state *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_rasterizer_state"); + + trace_dump_member(stream, bool, state, flatshade); + trace_dump_member(stream, bool, state, light_twoside); + trace_dump_member(stream, uint, state, front_winding); + trace_dump_member(stream, uint, state, cull_mode); + trace_dump_member(stream, uint, state, fill_cw); + trace_dump_member(stream, uint, state, fill_ccw); + trace_dump_member(stream, bool, state, offset_cw); + trace_dump_member(stream, bool, state, offset_ccw); + trace_dump_member(stream, bool, state, scissor); + trace_dump_member(stream, bool, state, poly_smooth); + trace_dump_member(stream, bool, state, poly_stipple_enable); + trace_dump_member(stream, bool, state, point_smooth); + trace_dump_member(stream, bool, state, point_sprite); + trace_dump_member(stream, bool, state, point_size_per_vertex); + trace_dump_member(stream, bool, state, multisample); + trace_dump_member(stream, bool, state, line_smooth); + trace_dump_member(stream, bool, state, line_stipple_enable); + trace_dump_member(stream, uint, state, line_stipple_factor); + trace_dump_member(stream, uint, state, line_stipple_pattern); + trace_dump_member(stream, bool, state, line_last_pixel); + trace_dump_member(stream, bool, state, bypass_clipping); + trace_dump_member(stream, bool, state, bypass_vs); + trace_dump_member(stream, bool, state, origin_lower_left); + trace_dump_member(stream, bool, state, flatshade_first); + trace_dump_member(stream, bool, state, gl_rasterization_rules); + + trace_dump_member(stream, float, state, line_width); + trace_dump_member(stream, float, state, point_size); + trace_dump_member(stream, float, state, point_size_min); + trace_dump_member(stream, float, state, point_size_max); + trace_dump_member(stream, float, state, offset_units); + trace_dump_member(stream, float, state, offset_scale); + + trace_dump_member_array(stream, uint, state, sprite_coord_mode); + + trace_dump_struct_end(stream); +} + + +void trace_dump_poly_stipple(struct trace_stream *stream, + const struct pipe_poly_stipple *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_poly_stipple"); + + trace_dump_member_begin(stream, "stipple"); + trace_dump_bytes(stream, + state->stipple, + sizeof(state->stipple)); + trace_dump_member_end(stream); + + trace_dump_struct_end(stream); +} + + +void trace_dump_viewport_state(struct trace_stream *stream, + const struct pipe_viewport_state *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_viewport_state"); + + trace_dump_member_array(stream, float, state, scale); + trace_dump_member_array(stream, float, state, translate); + + trace_dump_struct_end(stream); +} + + +void trace_dump_scissor_state(struct trace_stream *stream, + const struct pipe_scissor_state *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_scissor_state"); + + trace_dump_member(stream, uint, state, minx); + trace_dump_member(stream, uint, state, miny); + trace_dump_member(stream, uint, state, maxx); + trace_dump_member(stream, uint, state, maxy); + + trace_dump_struct_end(stream); +} + + +void trace_dump_clip_state(struct trace_stream *stream, + const struct pipe_clip_state *state) +{ + unsigned i; + + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_scissor_state"); + + trace_dump_member_begin(stream, "ucp"); + trace_dump_array_begin(stream); + for(i = 0; i < PIPE_MAX_CLIP_PLANES; ++i) + trace_dump_array(stream, float, state->ucp[i], 4); + trace_dump_array_end(stream); + trace_dump_member_end(stream); + + trace_dump_member(stream, uint, state, nr); + + trace_dump_struct_end(stream); +} + + +void trace_dump_constant_buffer(struct trace_stream *stream, + const struct pipe_constant_buffer *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_constant_buffer"); + + trace_dump_member(stream, ptr, state, buffer); + trace_dump_member(stream, uint, state, size); + + trace_dump_struct_end(stream); +} + + +void trace_dump_shader_state(struct trace_stream *stream, + const struct pipe_shader_state *state) +{ + static char str[8192]; + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + tgsi_dump_str(state->tokens, 0, str, sizeof(str)); + + trace_dump_struct_begin(stream, "pipe_shader_state"); + + trace_dump_member_begin(stream, "tokens"); + trace_dump_string(stream, str); + trace_dump_member_end(stream); + + trace_dump_struct_end(stream); +} + + +void trace_dump_depth_stencil_alpha_state(struct trace_stream *stream, + const struct pipe_depth_stencil_alpha_state *state) +{ + unsigned i; + + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_depth_stencil_alpha_state"); + + trace_dump_member_begin(stream, "depth"); + trace_dump_struct_begin(stream, ""); + trace_dump_member(stream, bool, &state->depth, enabled); + trace_dump_member(stream, bool, &state->depth, writemask); + trace_dump_member(stream, uint, &state->depth, func); + trace_dump_member(stream, bool, &state->depth, occlusion_count); + trace_dump_struct_end(stream); + trace_dump_member_end(stream); + + trace_dump_member_begin(stream, "stencil"); + trace_dump_array_begin(stream); + for(i = 0; i < Elements(state->stencil); ++i) { + trace_dump_elem_begin(stream); + trace_dump_struct_begin(stream, ""); + trace_dump_member(stream, bool, &state->stencil[i], enabled); + trace_dump_member(stream, uint, &state->stencil[i], func); + trace_dump_member(stream, uint, &state->stencil[i], fail_op); + trace_dump_member(stream, uint, &state->stencil[i], zpass_op); + trace_dump_member(stream, uint, &state->stencil[i], zfail_op); + trace_dump_member(stream, uint, &state->stencil[i], ref_value); + trace_dump_member(stream, uint, &state->stencil[i], value_mask); + trace_dump_member(stream, uint, &state->stencil[i], write_mask); + trace_dump_struct_end(stream); + trace_dump_elem_end(stream); + } + trace_dump_array_end(stream); + trace_dump_member_end(stream); + + trace_dump_member_begin(stream, "alpha"); + trace_dump_struct_begin(stream, ""); + trace_dump_member(stream, bool, &state->alpha, enabled); + trace_dump_member(stream, uint, &state->alpha, func); + trace_dump_member(stream, float, &state->alpha, ref); + trace_dump_struct_end(stream); + trace_dump_member_end(stream); + + trace_dump_struct_end(stream); +} + + +void trace_dump_blend_state(struct trace_stream *stream, + const struct pipe_blend_state *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_blend_state"); + + trace_dump_member(stream, bool, state, blend_enable); + + trace_dump_member(stream, uint, state, rgb_func); + trace_dump_member(stream, uint, state, rgb_src_factor); + trace_dump_member(stream, uint, state, rgb_dst_factor); + + trace_dump_member(stream, uint, state, alpha_func); + trace_dump_member(stream, uint, state, alpha_src_factor); + trace_dump_member(stream, uint, state, alpha_dst_factor); + + trace_dump_member(stream, bool, state, logicop_enable); + trace_dump_member(stream, uint, state, logicop_func); + + trace_dump_member(stream, uint, state, colormask); + trace_dump_member(stream, bool, state, dither); + + trace_dump_struct_end(stream); +} + + +void trace_dump_blend_color(struct trace_stream *stream, + const struct pipe_blend_color *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_blend_color"); + + trace_dump_member_array(stream, float, state, color); + + trace_dump_struct_end(stream); +} + + +void trace_dump_framebuffer_state(struct trace_stream *stream, + const struct pipe_framebuffer_state *state) +{ + trace_dump_struct_begin(stream, "pipe_framebuffer_state"); + + trace_dump_member(stream, uint, state, width); + trace_dump_member(stream, uint, state, height); + trace_dump_member(stream, uint, state, num_cbufs); + trace_dump_member_array(stream, ptr, state, cbufs); + trace_dump_member(stream, ptr, state, zsbuf); + + trace_dump_struct_end(stream); +} + + +void trace_dump_sampler_state(struct trace_stream *stream, + const struct pipe_sampler_state *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_sampler_state"); + + trace_dump_member(stream, uint, state, wrap_s); + trace_dump_member(stream, uint, state, wrap_t); + trace_dump_member(stream, uint, state, wrap_r); + trace_dump_member(stream, uint, state, min_img_filter); + trace_dump_member(stream, uint, state, min_mip_filter); + trace_dump_member(stream, uint, state, mag_img_filter); + trace_dump_member(stream, bool, state, compare_mode); + trace_dump_member(stream, uint, state, compare_func); + trace_dump_member(stream, bool, state, normalized_coords); + trace_dump_member(stream, uint, state, prefilter); + trace_dump_member(stream, float, state, shadow_ambient); + trace_dump_member(stream, float, state, lod_bias); + trace_dump_member(stream, float, state, min_lod); + trace_dump_member(stream, float, state, max_lod); + trace_dump_member_array(stream, float, state, border_color); + trace_dump_member(stream, float, state, max_anisotropy); + + trace_dump_struct_end(stream); +} + + +void trace_dump_surface(struct trace_stream *stream, + const struct pipe_surface *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_surface"); + + trace_dump_member(stream, ptr, state, buffer); + trace_dump_member(stream, format, state, format); + trace_dump_member(stream, uint, state, status); + trace_dump_member(stream, uint, state, clear_value); + trace_dump_member(stream, uint, state, width); + trace_dump_member(stream, uint, state, height); + + trace_dump_member_begin(stream, "block"); + trace_dump_block(stream, &state->block); + trace_dump_member_end(stream); + + trace_dump_member(stream, uint, state, nblocksx); + trace_dump_member(stream, uint, state, nblocksy); + trace_dump_member(stream, uint, state, stride); + trace_dump_member(stream, uint, state, layout); + trace_dump_member(stream, uint, state, offset); + trace_dump_member(stream, uint, state, refcount); + trace_dump_member(stream, uint, state, usage); + + trace_dump_member(stream, ptr, state, texture); + trace_dump_member(stream, uint, state, face); + trace_dump_member(stream, uint, state, level); + trace_dump_member(stream, uint, state, zslice); + + trace_dump_struct_end(stream); +} + + +void trace_dump_vertex_buffer(struct trace_stream *stream, + const struct pipe_vertex_buffer *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_vertex_buffer"); + + trace_dump_member(stream, uint, state, pitch); + trace_dump_member(stream, uint, state, max_index); + trace_dump_member(stream, uint, state, buffer_offset); + trace_dump_member(stream, ptr, state, buffer); + + trace_dump_struct_end(stream); +} + + +void trace_dump_vertex_element(struct trace_stream *stream, + const struct pipe_vertex_element *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_vertex_element"); + + trace_dump_member(stream, uint, state, src_offset); + + trace_dump_member(stream, uint, state, vertex_buffer_index); + trace_dump_member(stream, uint, state, nr_components); + + trace_dump_member(stream, format, state, src_format); + + trace_dump_struct_end(stream); +} diff --git a/src/gallium/drivers/trace/tr_state.h b/src/gallium/drivers/trace/tr_state.h new file mode 100644 index 00000000000..c1df63db6af --- /dev/null +++ b/src/gallium/drivers/trace/tr_state.h @@ -0,0 +1,95 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation streams (the + * "Software"), to deal in the Software without restriction, including + * without limitation 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 TUNGSTEN GRAPHICS 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 TR_STATE_H +#define TR_STATE_H + +#include "pipe/p_format.h" +#include "pipe/p_state.h" +#include "pipe/p_shader_tokens.h" + + +void trace_dump_format(struct trace_stream *stream, + enum pipe_format format); + +void trace_dump_block(struct trace_stream *stream, + const struct pipe_format_block *block); + +void trace_dump_template(struct trace_stream *stream, + const struct pipe_texture *templat); + + +void trace_dump_rasterizer_state(struct trace_stream *stream, + const struct pipe_rasterizer_state *state); + +void trace_dump_poly_stipple(struct trace_stream *stream, + const struct pipe_poly_stipple *state); + +void trace_dump_viewport_state(struct trace_stream *stream, + const struct pipe_viewport_state *state); + +void trace_dump_scissor_state(struct trace_stream *stream, + const struct pipe_scissor_state *state); + +void trace_dump_clip_state(struct trace_stream *stream, + const struct pipe_clip_state *state); + +void trace_dump_constant_buffer(struct trace_stream *stream, + const struct pipe_constant_buffer *state); + +void trace_dump_token(struct trace_stream *stream, + const struct tgsi_token *token); + +void trace_dump_shader_state(struct trace_stream *stream, + const struct pipe_shader_state *state); + +void trace_dump_depth_stencil_alpha_state(struct trace_stream *stream, + const struct pipe_depth_stencil_alpha_state *state); + +void trace_dump_blend_state(struct trace_stream *stream, + const struct pipe_blend_state *state); + +void trace_dump_blend_color(struct trace_stream *stream, + const struct pipe_blend_color *state); + +void trace_dump_framebuffer_state(struct trace_stream *stream, + const struct pipe_framebuffer_state *state); + +void trace_dump_sampler_state(struct trace_stream *stream, + const struct pipe_sampler_state *state); + +void trace_dump_surface(struct trace_stream *stream, + const struct pipe_surface *state); + +void trace_dump_vertex_buffer(struct trace_stream *stream, + const struct pipe_vertex_buffer *state); + +void trace_dump_vertex_element(struct trace_stream *stream, + const struct pipe_vertex_element *state); + + +#endif /* TR_STATE_H */ diff --git a/src/gallium/drivers/trace/tr_stream.c b/src/gallium/drivers/trace/tr_stream.c new file mode 100644 index 00000000000..14cc257e154 --- /dev/null +++ b/src/gallium/drivers/trace/tr_stream.c @@ -0,0 +1,100 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, 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 TUNGSTEN GRAPHICS 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 "pipe/p_config.h" + +#if defined(PIPE_OS_LINUX) +#include <stdio.h> +#else +#error Unsupported platform +#endif + +#include "pipe/p_util.h" + +#include "tr_stream.h" + + +struct trace_stream +{ +#if defined(PIPE_OS_LINUX) + FILE *file; +#endif +}; + + +struct trace_stream * +trace_stream_create(const char *name, const char *ext) +{ + struct trace_stream *stream; + static unsigned file_no = 0; + char filename[1024]; + + stream = CALLOC_STRUCT(trace_stream); + if(!stream) + goto error1; + + snprintf(filename, sizeof(filename), "%s.%u.%s", name, file_no, ext); + +#if defined(PIPE_OS_LINUX) + stream->file = fopen(filename, "w"); + if(!stream->file) + goto error2; +#endif + + return stream; + +error2: + FREE(stream); +error1: + return NULL; +} + + +boolean +trace_stream_write(struct trace_stream *stream, const void *data, size_t size) +{ + if(!stream) + return FALSE; + +#if defined(PIPE_OS_LINUX) + return fwrite(data, size, 1, stream->file) == size ? TRUE : FALSE; +#endif +} + + +void +trace_stream_close(struct trace_stream *stream) +{ + if(!stream) + return; + +#if defined(PIPE_OS_LINUX) + fclose(stream->file); +#endif + + FREE(stream); +} diff --git a/src/gallium/drivers/trace/tr_stream.h b/src/gallium/drivers/trace/tr_stream.h new file mode 100644 index 00000000000..d50fed26917 --- /dev/null +++ b/src/gallium/drivers/trace/tr_stream.h @@ -0,0 +1,52 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation streams (the + * "Software"), to deal in the Software without restriction, including + * without limitation 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 TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + +/** + * @file + * Cross-platform sequential access stream abstraction. + */ + +#ifndef TR_STREAM_H +#define TR_STREAM_H + + +#include "pipe/p_compiler.h" + +struct trace_stream; + + +struct trace_stream * +trace_stream_create(const char *name, const char *ext); + +boolean +trace_stream_write(struct trace_stream *stream, const void *data, size_t size); + +void +trace_stream_close(struct trace_stream *stream); + + +#endif /* TR_STREAM_H */ diff --git a/src/gallium/drivers/trace/tr_winsys.c b/src/gallium/drivers/trace/tr_winsys.c new file mode 100644 index 00000000000..964da5677b2 --- /dev/null +++ b/src/gallium/drivers/trace/tr_winsys.c @@ -0,0 +1,462 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, 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 TUNGSTEN GRAPHICS 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 "pipe/p_util.h" +#include "util/u_hash_table.h" + +#include "tr_stream.h" +#include "tr_dump.h" +#include "tr_state.h" +#include "tr_winsys.h" + + +static unsigned trace_buffer_hash(void *buffer) +{ + return (unsigned)(uintptr_t)buffer; +} + + +static int trace_buffer_compare(void *buffer1, void *buffer2) +{ + return (char *)buffer2 - (char *)buffer1; +} + + +static const char * +trace_winsys_get_name(struct pipe_winsys *_winsys) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + const char *result; + + trace_dump_call_begin(stream, "pipe_winsys", "get_name"); + + trace_dump_arg(stream, ptr, winsys); + + result = winsys->get_name(winsys); + + trace_dump_ret(stream, string, result); + + trace_dump_call_end(stream); + + return result; +} + + +static void +trace_winsys_flush_frontbuffer(struct pipe_winsys *_winsys, + struct pipe_surface *surface, + void *context_private) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + + trace_dump_call_begin(stream, "pipe_winsys", "flush_frontbuffer"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, surface); + trace_dump_arg(stream, ptr, context_private); + + winsys->flush_frontbuffer(winsys, surface, context_private); + + trace_dump_call_end(stream); +} + + +static struct pipe_surface * +trace_winsys_surface_alloc(struct pipe_winsys *_winsys) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + struct pipe_surface *result; + + trace_dump_call_begin(stream, "pipe_winsys", "surface_alloc"); + + trace_dump_arg(stream, ptr, winsys); + + result = winsys->surface_alloc(winsys); + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static int +trace_winsys_surface_alloc_storage(struct pipe_winsys *_winsys, + struct pipe_surface *surface, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + int result; + + trace_dump_call_begin(stream, "pipe_winsys", "surface_alloc_storage"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, surface); + trace_dump_arg(stream, uint, width); + trace_dump_arg(stream, uint, height); + trace_dump_arg(stream, format, format); + trace_dump_arg(stream, uint, flags); + trace_dump_arg(stream, uint, tex_usage); + + result = winsys->surface_alloc_storage(winsys, + surface, + width, height, + format, + flags, + tex_usage); + + trace_dump_ret(stream, int, result); + + trace_dump_call_end(stream); + + return result; +} + + +static void +trace_winsys_surface_release(struct pipe_winsys *_winsys, + struct pipe_surface **psurface) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + struct pipe_surface *surface = *psurface; + + trace_dump_call_begin(stream, "pipe_winsys", "surface_release"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, surface); + + winsys->surface_release(winsys, psurface); + + trace_dump_call_end(stream); +} + + +static struct pipe_buffer * +trace_winsys_buffer_create(struct pipe_winsys *_winsys, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + struct pipe_buffer *result; + + trace_dump_call_begin(stream, "pipe_winsys", "buffer_create"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, uint, alignment); + trace_dump_arg(stream, uint, usage); + trace_dump_arg(stream, uint, size); + + result = winsys->buffer_create(winsys, alignment, usage, size); + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static struct pipe_buffer * +trace_winsys_user_buffer_create(struct pipe_winsys *_winsys, + void *ptr, + unsigned bytes) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + struct pipe_buffer *result; + + trace_dump_call_begin(stream, "pipe_winsys", "user_buffer_create"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, ptr); + trace_dump_arg(stream, uint, bytes); + + result = winsys->user_buffer_create(winsys, ptr, bytes); + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static void * +trace_winsys_buffer_map(struct pipe_winsys *_winsys, + struct pipe_buffer *buffer, + unsigned usage) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + void *result; + + trace_dump_call_begin(stream, "pipe_winsys", "buffer_map"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, buffer); + trace_dump_arg(stream, uint, usage); + + result = winsys->buffer_map(winsys, buffer, usage); + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + if(result) { + if(usage & PIPE_BUFFER_USAGE_CPU_WRITE) { + assert(!hash_table_get(tr_ws->buffer_maps, buffer)); + hash_table_set(tr_ws->buffer_maps, buffer, result); + } + } + + return result; +} + + +static void +trace_winsys_buffer_unmap(struct pipe_winsys *_winsys, + struct pipe_buffer *buffer) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + const void *map; + + map = hash_table_get(tr_ws->buffer_maps, buffer); + if(map) { + trace_dump_call_begin(stream, "", "memcpy"); + + trace_dump_arg_begin(stream, "dst"); + trace_dump_ptr(stream, map); + trace_dump_arg_end(stream); + + trace_dump_arg_begin(stream, "src"); + trace_dump_bytes(stream, map, buffer->size); + trace_dump_arg_end(stream); + + trace_dump_arg_begin(stream, "size"); + trace_dump_uint(stream, buffer->size); + trace_dump_arg_end(stream); + + trace_dump_call_end(stream); + + winsys->buffer_unmap(winsys, buffer); + + hash_table_remove(tr_ws->buffer_maps, buffer); + } + + trace_dump_call_begin(stream, "pipe_winsys", "buffer_unmap"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, buffer); + + winsys->buffer_unmap(winsys, buffer); + + trace_dump_call_end(stream); +} + + +static void +trace_winsys_buffer_destroy(struct pipe_winsys *_winsys, + struct pipe_buffer *buffer) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + + trace_dump_call_begin(stream, "pipe_winsys", "buffer_destroy"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, buffer); + + winsys->buffer_destroy(winsys, buffer); + + trace_dump_call_end(stream); +} + + +static void +trace_winsys_fence_reference(struct pipe_winsys *_winsys, + struct pipe_fence_handle **pdst, + struct pipe_fence_handle *src) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + struct pipe_fence_handle *dst = *pdst; + + trace_dump_call_begin(stream, "pipe_winsys", "fence_reference"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, dst); + trace_dump_arg(stream, ptr, src); + + winsys->fence_reference(winsys, pdst, src); + + trace_dump_call_end(stream); +} + + +static int +trace_winsys_fence_signalled(struct pipe_winsys *_winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + int result; + + trace_dump_call_begin(stream, "pipe_winsys", "fence_signalled"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, fence); + trace_dump_arg(stream, uint, flag); + + result = winsys->fence_signalled(winsys, fence, flag); + + trace_dump_ret(stream, int, result); + + trace_dump_call_end(stream); + + return result; +} + + +static int +trace_winsys_fence_finish(struct pipe_winsys *_winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + int result; + + trace_dump_call_begin(stream, "pipe_winsys", "fence_finish"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, fence); + trace_dump_arg(stream, uint, flag); + + result = winsys->fence_finish(winsys, fence, flag); + + trace_dump_ret(stream, int, result); + + trace_dump_call_end(stream); + + return result; +} + + +static void +trace_winsys_destroy(struct pipe_winsys *_winsys) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + + trace_dump_call_begin(stream, "pipe_winsys", "destroy"); + + trace_dump_arg(stream, ptr, winsys); + + winsys->destroy(winsys); + + trace_dump_call_end(stream); + + trace_dump_trace_end(stream); + + hash_table_destroy(tr_ws->buffer_maps); + + trace_stream_close(tr_ws->stream); + + FREE(tr_ws); +} + + +struct pipe_winsys * +trace_winsys_create(struct pipe_winsys *winsys) +{ + struct trace_winsys *tr_ws; + + if(!debug_get_bool_option("GALLIUM_TRACE", FALSE)) + return winsys; + + tr_ws = CALLOC_STRUCT(trace_winsys); + if(!tr_ws) + return NULL; + + tr_ws->base.destroy = trace_winsys_destroy; + tr_ws->base.get_name = trace_winsys_get_name; + tr_ws->base.flush_frontbuffer = trace_winsys_flush_frontbuffer; + tr_ws->base.surface_alloc = trace_winsys_surface_alloc; + tr_ws->base.surface_alloc_storage = trace_winsys_surface_alloc_storage; + tr_ws->base.surface_release = trace_winsys_surface_release; + tr_ws->base.buffer_create = trace_winsys_buffer_create; + tr_ws->base.user_buffer_create = trace_winsys_user_buffer_create; + tr_ws->base.buffer_map = trace_winsys_buffer_map; + tr_ws->base.buffer_unmap = trace_winsys_buffer_unmap; + tr_ws->base.buffer_destroy = trace_winsys_buffer_destroy; + tr_ws->base.fence_reference = trace_winsys_fence_reference; + tr_ws->base.fence_signalled = trace_winsys_fence_signalled; + tr_ws->base.fence_finish = trace_winsys_fence_finish; + + tr_ws->winsys = winsys; + + tr_ws->stream = trace_stream_create("gallium", "trace"); + if(!tr_ws->stream) + return NULL; + + tr_ws->buffer_maps = hash_table_create(trace_buffer_hash, + trace_buffer_compare); + if(!tr_ws->buffer_maps) + return NULL; + + + trace_dump_trace_begin(tr_ws->stream, 0); + + return &tr_ws->base; +} diff --git a/src/gallium/drivers/trace/tr_winsys.h b/src/gallium/drivers/trace/tr_winsys.h new file mode 100644 index 00000000000..a3576da867e --- /dev/null +++ b/src/gallium/drivers/trace/tr_winsys.h @@ -0,0 +1,66 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, 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 TUNGSTEN GRAPHICS 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 TR_WINSYS_H_ +#define TR_WINSYS_H_ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_winsys.h" + + +struct hash_table; +struct trace_stream; + + +struct trace_winsys +{ + struct pipe_winsys base; + + struct pipe_winsys *winsys; + + struct trace_stream *stream; + + struct hash_table *buffer_maps; +}; + + +static INLINE struct trace_winsys * +trace_winsys(struct pipe_winsys *winsys) +{ + assert(winsys); + return (struct trace_winsys *)winsys; +} + + + +struct pipe_winsys * +trace_winsys_create(struct pipe_winsys *winsys); + + +#endif /* TR_WINSYS_H_ */ diff --git a/src/gallium/drivers/trace/trace.xsl b/src/gallium/drivers/trace/trace.xsl new file mode 100644 index 00000000000..9cd621e7ab9 --- /dev/null +++ b/src/gallium/drivers/trace/trace.xsl @@ -0,0 +1,185 @@ +<?xml version="1.0"?> + +<!-- + +Copyright 2008 Tungsten Graphics, Inc. + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU Lesser General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +!--> + +<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + + <xsl:output method="html" /> + + <xsl:strip-space elements="*" /> + + <xsl:template match="/trace"> + <html> + <head> + <title>Gallium Trace</title> + </head> + <style> + body { + font-family: verdana, sans-serif; + font-size: 11px; + font-weight: normal; + text-align : left; + } + + .fun { + font-weight: bold; + } + + .var { + font-style: italic; + } + + .typ { + display: none; + } + + .lit { + color: #0000ff; + } + + .ptr { + color: #008000; + } + </style> + <body> + <ol class="calls"> + <xsl:apply-templates/> + </ol> + </body> + </html> + </xsl:template> + + <xsl:template match="call"> + <li> + <span class="fun"> + <xsl:value-of select="@class"/> + <xsl:text>::</xsl:text> + <xsl:value-of select="@method"/> + </span> + <xsl:text>(</xsl:text> + <xsl:apply-templates select="arg"/> + <xsl:text>)</xsl:text> + <xsl:apply-templates select="ret"/> + </li> + </xsl:template> + + <xsl:template match="arg|member"> + <xsl:apply-templates select="@name"/> + <xsl:text> = </xsl:text> + <xsl:apply-templates /> + <xsl:if test="position() != last()"> + <xsl:text>, </xsl:text> + </xsl:if> + </xsl:template> + + <xsl:template match="ret"> + <xsl:text> = </xsl:text> + <xsl:apply-templates /> + </xsl:template> + + <xsl:template match="bool|int|uint|float|enum"> + <span class="lit"> + <xsl:value-of select="text()"/> + </span> + </xsl:template> + + <xsl:template match="bytes"> + <span class="lit"> + <xsl:text>...</xsl:text> + </span> + </xsl:template> + + <xsl:template match="string"> + <span class="lit"> + <xsl:text>"</xsl:text> + <xsl:call-template name="break"> + <xsl:with-param name="text" select="text()"/> + </xsl:call-template> + <xsl:text>"</xsl:text> + </span> + </xsl:template> + + <xsl:template match="array|struct"> + <xsl:text>{</xsl:text> + <xsl:apply-templates /> + <xsl:text>}</xsl:text> + </xsl:template> + + <xsl:template match="elem"> + <xsl:apply-templates /> + <xsl:if test="position() != last()"> + <xsl:text>, </xsl:text> + </xsl:if> + </xsl:template> + + <xsl:template match="null"> + <span class="ptr"> + <xsl:text>NULL</xsl:text> + </span> + </xsl:template> + + <xsl:template match="ptr"> + <span class="ptr"> + <xsl:value-of select="text()"/> + </span> + </xsl:template> + + <xsl:template match="@name"> + <span class="var"> + <xsl:value-of select="."/> + </span> + </xsl:template> + + <xsl:template name="break"> + <xsl:param name="text" select="."/> + <xsl:choose> + <xsl:when test="contains($text, '
')"> + <xsl:value-of select="substring-before($text, '
')"/> + <br/> + <xsl:call-template name="break"> + <xsl:with-param name="text" select="substring-after($text, '
')"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$text"/> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <xsl:template name="replace"> + <xsl:param name="text"/> + <xsl:param name="from"/> + <xsl:param name="to"/> + <xsl:choose> + <xsl:when test="contains($text,$from)"> + <xsl:value-of select="concat(substring-before($text,$from),$to)"/> + <xsl:call-template name="replace"> + <xsl:with-param name="text" select="substring-after($text,$from)"/> + <xsl:with-param name="from" select="$from"/> + <xsl:with-param name="to" select="$to"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$text"/> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + +</xsl:transform> diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index a5816c3cbb7..6478ae2f08e 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -332,13 +332,17 @@ debug_profile_stop(void); #ifdef DEBUG +struct pipe_surface; void debug_dump_image(const char *prefix, unsigned format, unsigned cpp, unsigned width, unsigned height, - unsigned pitch, + unsigned stride, const void *data); +void debug_dump_surface(const char *prefix, + struct pipe_surface *surface); #else -#define debug_dump_image(prefix, format, cpp, width, height, pitch, data) ((void)0) +#define debug_dump_image(prefix, format, cpp, width, height, stride, data) ((void)0) +#define debug_dump_surface(prefix, surface) ((void)0) #endif diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index 947c4455835..d9aa5792a44 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -28,11 +28,11 @@ #ifndef PIPE_FORMAT_H #define PIPE_FORMAT_H -#include "util/u_string.h" - #include "p_compiler.h" #include "p_debug.h" +#include "util/u_string.h" + #ifdef __cplusplus extern "C" { #endif @@ -379,7 +379,7 @@ enum pipe_format { /** * Builds pipe format name from format token. */ -extern char *pf_sprint_name( char *str, enum pipe_format format ); +extern const char *pf_name( enum pipe_format format ); /** * Return bits for a particular component. diff --git a/src/gallium/include/pipe/p_winsys.h b/src/gallium/include/pipe/p_winsys.h index 7ebc2851928..5d18291dc6c 100644 --- a/src/gallium/include/pipe/p_winsys.h +++ b/src/gallium/include/pipe/p_winsys.h @@ -62,6 +62,8 @@ struct pipe_surface; */ struct pipe_winsys { + void (*destroy)( struct pipe_winsys *ws ); + /** Returns name of this winsys interface */ const char *(*get_name)( struct pipe_winsys *ws ); diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript index 14a85ae0f2b..8650f595a72 100644 --- a/src/gallium/winsys/xlib/SConscript +++ b/src/gallium/winsys/xlib/SConscript @@ -9,31 +9,35 @@ if env['platform'] == 'linux' \ and 'i965simple' in env['drivers'] \ and not env['dri']: - env = env.Clone() + env = env.Clone() - env.Append(CPPPATH = [ - '#/src/mesa', - '#/src/mesa/main', - ]) + env.Append(CPPPATH = [ + '#/src/mesa', + '#/src/mesa/main', + ]) - sources = [ - 'glxapi.c', - 'fakeglx.c', - 'xfonts.c', - 'xm_api.c', - 'xm_winsys.c', - 'xm_winsys_aub.c', - 'brw_aub.c', - ] - - drivers = [ - softpipe, - i965simple - ] + sources = [ + 'glxapi.c', + 'fakeglx.c', + 'xfonts.c', + 'xm_api.c', + 'xm_winsys.c', + 'xm_winsys_aub.c', + 'brw_aub.c', + ] + + drivers = [ + softpipe, + i965simple, + ] + + if 'trace' in env['drivers']: + env.Append(CPPDEFINES = 'GALLIUM_TRACE') + drivers += [trace] - # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions - env.SharedLibrary( - target ='GL', - source = sources, - LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], - ) + # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions + env.SharedLibrary( + target ='GL', + source = sources, + LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], + ) diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index 8a32c54349b..4e5441a13d2 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -363,7 +363,12 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type, stencilFormat = PIPE_FORMAT_S8_UNORM; } else { + /* no stencil */ stencilFormat = PIPE_FORMAT_NONE; + if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) { + /* use 24-bit Z, undefined stencil channel */ + depthFormat = PIPE_FORMAT_X8Z24_UNORM; + } } diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 9225ee510df..6071a5ad5e4 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -54,6 +54,12 @@ #define TILE_SIZE 32 /* avoid compilation errors */ #endif +#ifdef GALLIUM_TRACE +#include "trace/tr_winsys.h" +#include "trace/tr_screen.h" +#include "trace/tr_context.h" +#endif + #include "xm_winsys_aub.h" @@ -645,7 +651,11 @@ xmesa_get_pipe_winsys(struct xmesa_visual *xm_vis) ws->base.get_name = xm_get_name; } - return &ws->base; +#ifdef GALLIUM_TRACE + return trace_winsys_create(&ws->base); +#else + return &ws->base; +#endif } @@ -674,7 +684,15 @@ xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) { struct pipe_screen *screen = softpipe_create_screen(pws); +#ifdef GALLIUM_TRACE + screen = trace_screen_create(screen); +#endif + pipe = softpipe_create(screen, pws, NULL); + +#ifdef GALLIUM_TRACE + pipe = trace_context_create(pipe); +#endif } if (pipe) |