summaryrefslogtreecommitdiff
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c49
-rw-r--r--src/gallium/auxiliary/tgsi/Makefile1
-rw-r--r--src/gallium/auxiliary/tgsi/SConscript3
-rw-r--r--src/gallium/auxiliary/tgsi/exec/tgsi_exec.c3
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_dump.c1086
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_dump.h16
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c845
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_dump_c.h49
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_iterate.c85
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_iterate.h76
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_sanity.c341
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_sanity.h49
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_text.c530
-rw-r--r--src/gallium/auxiliary/util/p_debug.c32
-rw-r--r--src/gallium/auxiliary/util/p_debug_prof.c269
-rw-r--r--src/gallium/auxiliary/util/p_tile.c119
-rw-r--r--src/gallium/auxiliary/util/p_tile.h7
-rw-r--r--src/gallium/auxiliary/util/u_blit.c12
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c3
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.c24
-rw-r--r--src/gallium/drivers/i915simple/i915_screen.c18
-rw-r--r--src/gallium/drivers/i965simple/brw_screen.c5
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c21
-rw-r--r--src/gallium/drivers/softpipe/sp_setup.c5
-rw-r--r--src/gallium/include/pipe/p_defines.h13
-rw-r--r--src/gallium/include/pipe/p_format.h29
-rw-r--r--src/gallium/include/pipe/p_screen.h9
-rw-r--r--src/gallium/include/pipe/p_state.h6
-rw-r--r--src/gallium/state_trackers/python/SConscript30
-rw-r--r--src/gallium/state_trackers/python/gallium.i218
-rw-r--r--src/gallium/state_trackers/python/samples/tri.py (renamed from src/gallium/state_trackers/python/samples/simple.py)152
-rw-r--r--src/gallium/state_trackers/python/st_device.c143
-rw-r--r--src/gallium/state_trackers/python/st_device.h4
-rw-r--r--src/gallium/state_trackers/python/st_hardpipe_winsys.c78
-rw-r--r--src/gallium/state_trackers/python/st_sample.c548
-rw-r--r--src/gallium/state_trackers/python/st_sample.h47
-rw-r--r--src/gallium/state_trackers/python/st_softpipe_winsys.c2
-rw-r--r--src/gallium/state_trackers/python/st_winsys.h4
-rw-r--r--src/gallium/state_trackers/python/tests/base.py193
-rw-r--r--src/gallium/state_trackers/python/tests/texture.py397
40 files changed, 4087 insertions, 1434 deletions
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c
index affa6aa85c..d02e3500ff 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c
@@ -109,7 +109,7 @@ static const uint8_t random_pattern[32] = {
static INLINE void
fill_random_pattern(uint8_t *dst, size_t size)
{
- unsigned i = 0;
+ size_t i = 0;
while(size--) {
*dst++ = random_pattern[i++];
i &= sizeof(random_pattern) - 1;
@@ -118,15 +118,21 @@ fill_random_pattern(uint8_t *dst, size_t size)
static INLINE boolean
-check_random_pattern(const uint8_t *dst, size_t size)
+check_random_pattern(const uint8_t *dst, size_t size,
+ size_t *min_ofs, size_t *max_ofs)
{
- unsigned i = 0;
- while(size--) {
- if(*dst++ != random_pattern[i++])
- return FALSE;
- i &= sizeof(random_pattern) - 1;
+ boolean result = TRUE;
+ size_t i;
+ *min_ofs = size;
+ *max_ofs = 0;
+ for(i = 0; i < size; ++i) {
+ if(*dst++ != random_pattern[i % sizeof(random_pattern)]) {
+ *min_ofs = MIN2(*min_ofs, i);
+ *max_ofs = MIN2(*max_ofs, i);
+ result = FALSE;
+ }
}
- return TRUE;
+ return result;
}
@@ -141,15 +147,28 @@ pb_debug_buffer_destroy(struct pb_buffer *_buf)
map = pb_map(buf->buffer, PIPE_BUFFER_USAGE_CPU_READ);
assert(map);
if(map) {
- if(!check_random_pattern(map, buf->underflow_size)) {
- debug_error("buffer underflow detected\n");
- debug_assert(0);
+ boolean underflow, overflow;
+ size_t min_ofs, max_ofs;
+
+ underflow = !check_random_pattern(map, buf->underflow_size,
+ &min_ofs, &max_ofs);
+ if(underflow) {
+ debug_printf("buffer underflow (%u of %u bytes) detected\n",
+ buf->underflow_size - min_ofs,
+ buf->underflow_size);
}
- if(!check_random_pattern(map + buf->underflow_size + buf->base.base.size,
- buf->overflow_size)) {
- debug_error("buffer overflow detected\n");
- debug_assert(0);
+
+ overflow = !check_random_pattern(map + buf->underflow_size + buf->base.base.size,
+ buf->overflow_size,
+ &min_ofs, &max_ofs);
+ if(overflow) {
+ debug_printf("buffer overflow (%u of %u bytes) detected\n",
+ max_ofs,
+ buf->overflow_size);
}
+
+ debug_assert(!underflow && !overflow);
+
pb_unmap(buf->buffer);
}
diff --git a/src/gallium/auxiliary/tgsi/Makefile b/src/gallium/auxiliary/tgsi/Makefile
index 5555639b70..9c4b967651 100644
--- a/src/gallium/auxiliary/tgsi/Makefile
+++ b/src/gallium/auxiliary/tgsi/Makefile
@@ -6,6 +6,7 @@ LIBNAME = tgsi
C_SOURCES = \
exec/tgsi_exec.c \
exec/tgsi_sse2.c \
+ util/tgsi_iterate.c \
util/tgsi_build.c \
util/tgsi_dump.c \
util/tgsi_parse.c \
diff --git a/src/gallium/auxiliary/tgsi/SConscript b/src/gallium/auxiliary/tgsi/SConscript
index b62c8efe02..3bbfa1be54 100644
--- a/src/gallium/auxiliary/tgsi/SConscript
+++ b/src/gallium/auxiliary/tgsi/SConscript
@@ -7,7 +7,10 @@ tgsi = env.ConvenienceLibrary(
'exec/tgsi_sse2.c',
'util/tgsi_build.c',
'util/tgsi_dump.c',
+ 'util/tgsi_dump_c.c',
+ 'util/tgsi_iterate.c',
'util/tgsi_parse.c',
+ 'util/tgsi_sanity.c',
'util/tgsi_scan.c',
'util/tgsi_text.c',
'util/tgsi_transform.c',
diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c
index 46949661af..001a4c4b15 100644
--- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c
@@ -2400,7 +2400,8 @@ exec_instruction(
/* Restore ContMask, but don't pop */
assert(mach->ContStackTop > 0);
mach->ContMask = mach->ContStack[mach->ContStackTop - 1];
- if (mach->LoopMask) {
+ UPDATE_EXEC_MASK(mach);
+ if (mach->ExecMask) {
/* repeat loop: jump to instruction just past BGNLOOP */
*pc = inst->InstructionExtLabel.Label + 1;
}
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c
index 0cf4454f25..94180f7e50 100644
--- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c
@@ -1,6 +1,6 @@
/**************************************************************************
*
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -26,25 +26,26 @@
**************************************************************************/
#include "pipe/p_debug.h"
-#include "pipe/p_util.h"
-#include "pipe/p_shader_tokens.h"
-#include "util/u_string.h"
#include "tgsi_dump.h"
-#include "tgsi_parse.h"
-#include "tgsi_build.h"
+#include "tgsi_iterate.h"
+
+struct dump_ctx
+{
+ struct tgsi_iterate_context iter;
+
+ uint instno;
+};
static void
dump_enum(
- const unsigned e,
- const char **enums,
- const unsigned enums_count )
+ uint e,
+ const char **enums,
+ uint enum_count )
{
- if (e >= enums_count) {
+ if (e >= enum_count)
debug_printf( "%u", e );
- }
- else {
+ else
debug_printf( "%s", enums[e] );
- }
}
#define EOL() debug_printf( "\n" )
@@ -56,40 +57,14 @@ dump_enum(
#define FLT(F) debug_printf( "%10.4f", F )
#define ENM(E,ENUMS) dump_enum( E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) )
-static const char *TGSI_PROCESSOR_TYPES[] =
-{
- "PROCESSOR_FRAGMENT",
- "PROCESSOR_VERTEX",
- "PROCESSOR_GEOMETRY"
-};
-
-static const char *TGSI_PROCESSOR_TYPES_SHORT[] =
+static const char *processor_type_names[] =
{
"FRAG",
"VERT",
"GEOM"
};
-static const char *TGSI_TOKEN_TYPES[] =
-{
- "TOKEN_TYPE_DECLARATION",
- "TOKEN_TYPE_IMMEDIATE",
- "TOKEN_TYPE_INSTRUCTION"
-};
-
-static const char *TGSI_FILES[] =
-{
- "FILE_NULL",
- "FILE_CONSTANT",
- "FILE_INPUT",
- "FILE_OUTPUT",
- "FILE_TEMPORARY",
- "FILE_SAMPLER",
- "FILE_ADDRESS",
- "FILE_IMMEDIATE"
-};
-
-static const char *TGSI_FILES_SHORT[] =
+static const char *file_names[] =
{
"NULL",
"CONST",
@@ -101,39 +76,14 @@ static const char *TGSI_FILES_SHORT[] =
"IMM"
};
-static const char *TGSI_DECLARES[] =
-{
- "DECLARE_RANGE",
- "DECLARE_MASK"
-};
-
-static const char *TGSI_INTERPOLATES[] =
-{
- "INTERPOLATE_CONSTANT",
- "INTERPOLATE_LINEAR",
- "INTERPOLATE_PERSPECTIVE",
- "INTERPOLATE_ATTRIB"
-};
-
-static const char *TGSI_INTERPOLATES_SHORT[] =
+static const char *interpolate_names[] =
{
"CONSTANT",
"LINEAR",
"PERSPECTIVE"
};
-static const char *TGSI_SEMANTICS[] =
-{
- "SEMANTIC_POSITION",
- "SEMANTIC_COLOR",
- "SEMANTIC_BCOLOR",
- "SEMANTIC_FOG",
- "SEMANTIC_PSIZE",
- "SEMANTIC_GENERIC",
- "SEMANTIC_NORMAL"
-};
-
-static const char *TGSI_SEMANTICS_SHORT[] =
+static const char *semantic_names[] =
{
"POSITION",
"COLOR",
@@ -144,139 +94,12 @@ static const char *TGSI_SEMANTICS_SHORT[] =
"NORMAL"
};
-static const char *TGSI_IMMS[] =
-{
- "IMM_FLOAT32"
-};
-
-static const char *TGSI_IMMS_SHORT[] =
+static const char *immediate_type_names[] =
{
"FLT32"
};
-static const char *TGSI_OPCODES[TGSI_OPCODE_LAST] =
-{
- "OPCODE_ARL",
- "OPCODE_MOV",
- "OPCODE_LIT",
- "OPCODE_RCP",
- "OPCODE_RSQ",
- "OPCODE_EXP",
- "OPCODE_LOG",
- "OPCODE_MUL",
- "OPCODE_ADD",
- "OPCODE_DP3",
- "OPCODE_DP4",
- "OPCODE_DST",
- "OPCODE_MIN",
- "OPCODE_MAX",
- "OPCODE_SLT",
- "OPCODE_SGE",
- "OPCODE_MAD",
- "OPCODE_SUB",
- "OPCODE_LERP",
- "OPCODE_CND",
- "OPCODE_CND0",
- "OPCODE_DOT2ADD",
- "OPCODE_INDEX",
- "OPCODE_NEGATE",
- "OPCODE_FRAC",
- "OPCODE_CLAMP",
- "OPCODE_FLOOR",
- "OPCODE_ROUND",
- "OPCODE_EXPBASE2",
- "OPCODE_LOGBASE2",
- "OPCODE_POWER",
- "OPCODE_CROSSPRODUCT",
- "OPCODE_MULTIPLYMATRIX",
- "OPCODE_ABS",
- "OPCODE_RCC",
- "OPCODE_DPH",
- "OPCODE_COS",
- "OPCODE_DDX",
- "OPCODE_DDY",
- "OPCODE_KILP",
- "OPCODE_PK2H",
- "OPCODE_PK2US",
- "OPCODE_PK4B",
- "OPCODE_PK4UB",
- "OPCODE_RFL",
- "OPCODE_SEQ",
- "OPCODE_SFL",
- "OPCODE_SGT",
- "OPCODE_SIN",
- "OPCODE_SLE",
- "OPCODE_SNE",
- "OPCODE_STR",
- "OPCODE_TEX",
- "OPCODE_TXD",
- "OPCODE_TXP",
- "OPCODE_UP2H",
- "OPCODE_UP2US",
- "OPCODE_UP4B",
- "OPCODE_UP4UB",
- "OPCODE_X2D",
- "OPCODE_ARA",
- "OPCODE_ARR",
- "OPCODE_BRA",
- "OPCODE_CAL",
- "OPCODE_RET",
- "OPCODE_SSG",
- "OPCODE_CMP",
- "OPCODE_SCS",
- "OPCODE_TXB",
- "OPCODE_NRM",
- "OPCODE_DIV",
- "OPCODE_DP2",
- "OPCODE_TXL",
- "OPCODE_BRK",
- "OPCODE_IF",
- "OPCODE_LOOP",
- "OPCODE_REP",
- "OPCODE_ELSE",
- "OPCODE_ENDIF",
- "OPCODE_ENDLOOP",
- "OPCODE_ENDREP",
- "OPCODE_PUSHA",
- "OPCODE_POPA",
- "OPCODE_CEIL",
- "OPCODE_I2F",
- "OPCODE_NOT",
- "OPCODE_TRUNC",
- "OPCODE_SHL",
- "OPCODE_SHR",
- "OPCODE_AND",
- "OPCODE_OR",
- "OPCODE_MOD",
- "OPCODE_XOR",
- "OPCODE_SAD",
- "OPCODE_TXF",
- "OPCODE_TXQ",
- "OPCODE_CONT",
- "OPCODE_EMIT",
- "OPCODE_ENDPRIM",
- "OPCODE_BGNLOOP2",
- "OPCODE_BGNSUB",
- "OPCODE_ENDLOOP2",
- "OPCODE_ENDSUB",
- "OPCODE_NOISE1",
- "OPCODE_NOISE2",
- "OPCODE_NOISE3",
- "OPCODE_NOISE4",
- "OPCODE_NOP",
- "OPCODE_M4X3",
- "OPCODE_M3X4",
- "OPCODE_M3X3",
- "OPCODE_M3X2",
- "OPCODE_NRM4",
- "OPCODE_CALLNZ",
- "OPCODE_IFC",
- "OPCODE_BREAKC",
- "OPCODE_KIL",
- "OPCODE_END"
-};
-
-static const char *TGSI_OPCODES_SHORT[TGSI_OPCODE_LAST] =
+static const char *opcode_names[TGSI_OPCODE_LAST] =
{
"ARL",
"MOV",
@@ -399,50 +222,7 @@ static const char *TGSI_OPCODES_SHORT[TGSI_OPCODE_LAST] =
"SWZ"
};
-static const char *TGSI_SATS[] =
-{
- "SAT_NONE",
- "SAT_ZERO_ONE",
- "SAT_MINUS_PLUS_ONE"
-};
-
-static const char *TGSI_INSTRUCTION_EXTS[] =
-{
- "INSTRUCTION_EXT_TYPE_NV",
- "INSTRUCTION_EXT_TYPE_LABEL",
- "INSTRUCTION_EXT_TYPE_TEXTURE"
-};
-
-static const char *TGSI_PRECISIONS[] =
-{
- "PRECISION_DEFAULT",
- "TGSI_PRECISION_FLOAT32",
- "TGSI_PRECISION_FLOAT16",
- "TGSI_PRECISION_FIXED12"
-};
-
-static const char *TGSI_CCS[] =
-{
- "CC_GT",
- "CC_EQ",
- "CC_LT",
- "CC_UN",
- "CC_GE",
- "CC_LE",
- "CC_NE",
- "CC_TR",
- "CC_FL"
-};
-
-static const char *TGSI_SWIZZLES[] =
-{
- "SWIZZLE_X",
- "SWIZZLE_Y",
- "SWIZZLE_Z",
- "SWIZZLE_W"
-};
-
-static const char *TGSI_SWIZZLES_SHORT[] =
+static const char *swizzle_names[] =
{
"x",
"y",
@@ -450,20 +230,7 @@ static const char *TGSI_SWIZZLES_SHORT[] =
"w"
};
-static const char *TGSI_TEXTURES[] =
-{
- "TEXTURE_UNKNOWN",
- "TEXTURE_1D",
- "TEXTURE_2D",
- "TEXTURE_3D",
- "TEXTURE_CUBE",
- "TEXTURE_RECT",
- "TEXTURE_SHADOW1D",
- "TEXTURE_SHADOW2D",
- "TEXTURE_SHADOWRECT"
-};
-
-static const char *TGSI_TEXTURES_SHORT[] =
+static const char *texture_names[] =
{
"UNKNOWN",
"1D",
@@ -476,23 +243,7 @@ static const char *TGSI_TEXTURES_SHORT[] =
"SHADOWRECT"
};
-static const char *TGSI_SRC_REGISTER_EXTS[] =
-{
- "SRC_REGISTER_EXT_TYPE_SWZ",
- "SRC_REGISTER_EXT_TYPE_MOD"
-};
-
-static const char *TGSI_EXTSWIZZLES[] =
-{
- "EXTSWIZZLE_X",
- "EXTSWIZZLE_Y",
- "EXTSWIZZLE_Z",
- "EXTSWIZZLE_W",
- "EXTSWIZZLE_ZERO",
- "EXTSWIZZLE_ONE"
-};
-
-static const char *TGSI_EXTSWIZZLES_SHORT[] =
+static const char *extswizzle_names[] =
{
"x",
"y",
@@ -502,44 +253,7 @@ static const char *TGSI_EXTSWIZZLES_SHORT[] =
"1"
};
-static const char *TGSI_WRITEMASKS[] =
-{
- "0",
- "WRITEMASK_X",
- "WRITEMASK_Y",
- "WRITEMASK_XY",
- "WRITEMASK_Z",
- "WRITEMASK_XZ",
- "WRITEMASK_YZ",
- "WRITEMASK_XYZ",
- "WRITEMASK_W",
- "WRITEMASK_XW",
- "WRITEMASK_YW",
- "WRITEMASK_XYW",
- "WRITEMASK_ZW",
- "WRITEMASK_XZW",
- "WRITEMASK_YZW",
- "WRITEMASK_XYZW"
-};
-
-static const char *TGSI_DST_REGISTER_EXTS[] =
-{
- "DST_REGISTER_EXT_TYPE_CONDCODE",
- "DST_REGISTER_EXT_TYPE_MODULATE"
-};
-
-static const char *TGSI_MODULATES[] =
-{
- "MODULATE_1X",
- "MODULATE_2X",
- "MODULATE_4X",
- "MODULATE_8X",
- "MODULATE_HALF",
- "MODULATE_QUARTER",
- "MODULATE_EIGHTH"
-};
-
-static const char *TGSI_MODULATES_SHORT[TGSI_MODULATE_COUNT] =
+static const char *modulate_names[TGSI_MODULATE_COUNT] =
{
"",
"_2X",
@@ -550,40 +264,86 @@ static const char *TGSI_MODULATES_SHORT[TGSI_MODULATE_COUNT] =
"_D8"
};
-void
-tgsi_dump_declaration(
- const struct tgsi_full_declaration *decl )
+static void
+_dump_register_prefix(
+ uint file,
+ uint first,
+ uint last )
{
- TXT( "\nDCL " );
- ENM( decl->Declaration.File, TGSI_FILES_SHORT );
+
+
+}
+static void
+_dump_register(
+ uint file,
+ int first,
+ int last )
+{
+ ENM( file, file_names );
CHR( '[' );
- UID( decl->DeclarationRange.First );
- if (decl->DeclarationRange.First != decl->DeclarationRange.Last) {
+ SID( first );
+ if (first != last) {
TXT( ".." );
- UID( decl->DeclarationRange.Last );
+ SID( last );
}
CHR( ']' );
+}
+
+static void
+_dump_register_ind(
+ uint file,
+ int index,
+ uint ind_file,
+ int ind_index )
+{
+ ENM( file, file_names );
+ CHR( '[' );
+ ENM( ind_file, file_names );
+ CHR( '[' );
+ SID( ind_index );
+ CHR( ']' );
+ if (index != 0) {
+ if (index > 0)
+ CHR( '+' );
+ SID( index );
+ }
+ CHR( ']' );
+}
- if( decl->Declaration.UsageMask != TGSI_WRITEMASK_XYZW ) {
+static void
+_dump_writemask(
+ uint writemask )
+{
+ if (writemask != TGSI_WRITEMASK_XYZW) {
CHR( '.' );
- if( decl->Declaration.UsageMask & TGSI_WRITEMASK_X ) {
+ if (writemask & TGSI_WRITEMASK_X)
CHR( 'x' );
- }
- if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Y ) {
+ if (writemask & TGSI_WRITEMASK_Y)
CHR( 'y' );
- }
- if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Z ) {
+ if (writemask & TGSI_WRITEMASK_Z)
CHR( 'z' );
- }
- if( decl->Declaration.UsageMask & TGSI_WRITEMASK_W ) {
+ if (writemask & TGSI_WRITEMASK_W)
CHR( 'w' );
- }
}
+}
+
+void
+tgsi_dump_declaration(
+ const struct tgsi_full_declaration *decl )
+{
+ TXT( "\nDCL " );
+
+ _dump_register(
+ decl->Declaration.File,
+ decl->DeclarationRange.First,
+ decl->DeclarationRange.Last );
+ _dump_writemask(
+ decl->Declaration.UsageMask );
if (decl->Declaration.Semantic) {
TXT( ", " );
- ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS_SHORT );
+ ENM( decl->Semantic.SemanticName, semantic_names );
if (decl->Semantic.SemanticIndex != 0 ||
decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC) {
CHR( '[' );
@@ -593,134 +353,66 @@ tgsi_dump_declaration(
}
TXT( ", " );
- ENM( decl->Declaration.Interpolate, TGSI_INTERPOLATES_SHORT );
+ ENM( decl->Declaration.Interpolate, interpolate_names );
}
-static void
-dump_declaration_verbose(
- struct tgsi_full_declaration *decl,
- unsigned ignored,
- unsigned deflt,
- struct tgsi_full_declaration *fd )
+static boolean
+iter_declaration(
+ struct tgsi_iterate_context *iter,
+ struct tgsi_full_declaration *decl )
{
- TXT( "\nFile : " );
- ENM( decl->Declaration.File, TGSI_FILES );
- if( deflt || fd->Declaration.UsageMask != decl->Declaration.UsageMask ) {
- TXT( "\nUsageMask : " );
- if( decl->Declaration.UsageMask & TGSI_WRITEMASK_X ) {
- CHR( 'X' );
- }
- if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Y ) {
- CHR( 'Y' );
- }
- if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Z ) {
- CHR( 'Z' );
- }
- if( decl->Declaration.UsageMask & TGSI_WRITEMASK_W ) {
- CHR( 'W' );
- }
- }
- if( deflt || fd->Declaration.Interpolate != decl->Declaration.Interpolate ) {
- TXT( "\nInterpolate: " );
- ENM( decl->Declaration.Interpolate, TGSI_INTERPOLATES );
- }
- if( deflt || fd->Declaration.Semantic != decl->Declaration.Semantic ) {
- TXT( "\nSemantic : " );
- UID( decl->Declaration.Semantic );
- }
- if( ignored ) {
- TXT( "\nPadding : " );
- UIX( decl->Declaration.Padding );
- }
-
- EOL();
- TXT( "\nFirst: " );
- UID( decl->DeclarationRange.First );
- TXT( "\nLast : " );
- UID( decl->DeclarationRange.Last );
-
- if( decl->Declaration.Semantic ) {
- EOL();
- TXT( "\nSemanticName : " );
- ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS );
- TXT( "\nSemanticIndex: " );
- UID( decl->Semantic.SemanticIndex );
- if( ignored ) {
- TXT( "\nPadding : " );
- UIX( decl->Semantic.Padding );
- }
- }
+ tgsi_dump_declaration( decl );
+ return TRUE;
}
void
tgsi_dump_immediate(
const struct tgsi_full_immediate *imm )
{
- unsigned i;
+ uint i;
TXT( "\nIMM " );
- ENM( imm->Immediate.DataType, TGSI_IMMS_SHORT );
+ ENM( imm->Immediate.DataType, immediate_type_names );
TXT( " { " );
- for( i = 0; i < imm->Immediate.Size - 1; i++ ) {
- switch( imm->Immediate.DataType ) {
+ for (i = 0; i < imm->Immediate.Size - 1; i++) {
+ switch (imm->Immediate.DataType) {
case TGSI_IMM_FLOAT32:
FLT( imm->u.ImmediateFloat32[i].Float );
break;
-
default:
assert( 0 );
}
- if( i < imm->Immediate.Size - 2 ) {
+ if (i < imm->Immediate.Size - 2)
TXT( ", " );
- }
}
TXT( " }" );
}
-static void
-dump_immediate_verbose(
- struct tgsi_full_immediate *imm,
- unsigned ignored )
+static boolean
+iter_immediate(
+ struct tgsi_iterate_context *iter,
+ struct tgsi_full_immediate *imm )
{
- unsigned i;
-
- TXT( "\nDataType : " );
- ENM( imm->Immediate.DataType, TGSI_IMMS );
- if( ignored ) {
- TXT( "\nPadding : " );
- UIX( imm->Immediate.Padding );
- }
-
- for( i = 0; i < imm->Immediate.Size - 1; i++ ) {
- EOL();
- switch( imm->Immediate.DataType ) {
- case TGSI_IMM_FLOAT32:
- TXT( "\nFloat: " );
- FLT( imm->u.ImmediateFloat32[i].Float );
- break;
-
- default:
- assert( 0 );
- }
- }
+ tgsi_dump_immediate( imm );
+ return TRUE;
}
void
tgsi_dump_instruction(
- const struct tgsi_full_instruction *inst,
- unsigned instno )
+ const struct tgsi_full_instruction *inst,
+ uint instno )
{
- unsigned i;
- boolean first_reg = TRUE;
+ uint i;
+ boolean first_reg = TRUE;
EOL();
UID( instno );
CHR( ':' );
- ENM( inst->Instruction.Opcode, TGSI_OPCODES_SHORT );
+ ENM( inst->Instruction.Opcode, opcode_names );
- switch( inst->Instruction.Saturate ) {
+ switch (inst->Instruction.Saturate) {
case TGSI_SAT_NONE:
break;
case TGSI_SAT_ZERO_ONE:
@@ -733,47 +425,28 @@ tgsi_dump_instruction(
assert( 0 );
}
- for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) {
+ for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
const struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
- if( !first_reg ) {
+ if (!first_reg)
CHR( ',' );
- }
CHR( ' ' );
- ENM( dst->DstRegister.File, TGSI_FILES_SHORT );
-
- CHR( '[' );
- SID( dst->DstRegister.Index );
- CHR( ']' );
-
- ENM( dst->DstRegisterExtModulate.Modulate, TGSI_MODULATES_SHORT );
-
- if( dst->DstRegister.WriteMask != TGSI_WRITEMASK_XYZW ) {
- CHR( '.' );
- if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_X ) {
- CHR( 'x' );
- }
- if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_Y ) {
- CHR( 'y' );
- }
- if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_Z ) {
- CHR( 'z' );
- }
- if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_W ) {
- CHR( 'w' );
- }
- }
+ _dump_register(
+ dst->DstRegister.File,
+ dst->DstRegister.Index,
+ dst->DstRegister.Index );
+ ENM( dst->DstRegisterExtModulate.Modulate, modulate_names );
+ _dump_writemask( dst->DstRegister.WriteMask );
first_reg = FALSE;
}
- for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) {
+ for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
const struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i];
- if( !first_reg ) {
+ if (!first_reg)
CHR( ',' );
- }
CHR( ' ' );
if (src->SrcRegisterExtMod.Negate)
@@ -789,40 +462,39 @@ tgsi_dump_instruction(
if (src->SrcRegister.Negate)
CHR( '-' );
- ENM( src->SrcRegister.File, TGSI_FILES_SHORT );
-
- CHR( '[' );
if (src->SrcRegister.Indirect) {
- TXT( "ADDR[0]" );
- if (src->SrcRegister.Index != 0) {
- if (src->SrcRegister.Index > 0)
- CHR( '+' );
- SID( src->SrcRegister.Index );
- }
+ _dump_register_ind(
+ src->SrcRegister.File,
+ src->SrcRegister.Index,
+ src->SrcRegisterInd.File,
+ src->SrcRegisterInd.Index );
+ }
+ else {
+ _dump_register(
+ src->SrcRegister.File,
+ src->SrcRegister.Index,
+ src->SrcRegister.Index );
}
- else
- SID( src->SrcRegister.Index );
- CHR( ']' );
if (src->SrcRegister.SwizzleX != TGSI_SWIZZLE_X ||
src->SrcRegister.SwizzleY != TGSI_SWIZZLE_Y ||
src->SrcRegister.SwizzleZ != TGSI_SWIZZLE_Z ||
src->SrcRegister.SwizzleW != TGSI_SWIZZLE_W) {
CHR( '.' );
- ENM( src->SrcRegister.SwizzleX, TGSI_SWIZZLES_SHORT );
- ENM( src->SrcRegister.SwizzleY, TGSI_SWIZZLES_SHORT );
- ENM( src->SrcRegister.SwizzleZ, TGSI_SWIZZLES_SHORT );
- ENM( src->SrcRegister.SwizzleW, TGSI_SWIZZLES_SHORT );
+ ENM( src->SrcRegister.SwizzleX, swizzle_names );
+ ENM( src->SrcRegister.SwizzleY, swizzle_names );
+ ENM( src->SrcRegister.SwizzleZ, swizzle_names );
+ ENM( src->SrcRegister.SwizzleW, swizzle_names );
}
if (src->SrcRegisterExtSwz.ExtSwizzleX != TGSI_EXTSWIZZLE_X ||
src->SrcRegisterExtSwz.ExtSwizzleY != TGSI_EXTSWIZZLE_Y ||
src->SrcRegisterExtSwz.ExtSwizzleZ != TGSI_EXTSWIZZLE_Z ||
src->SrcRegisterExtSwz.ExtSwizzleW != TGSI_EXTSWIZZLE_W) {
CHR( '.' );
- ENM( src->SrcRegisterExtSwz.ExtSwizzleX, TGSI_EXTSWIZZLES_SHORT );
- ENM( src->SrcRegisterExtSwz.ExtSwizzleY, TGSI_EXTSWIZZLES_SHORT );
- ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, TGSI_EXTSWIZZLES_SHORT );
- ENM( src->SrcRegisterExtSwz.ExtSwizzleW, TGSI_EXTSWIZZLES_SHORT );
+ ENM( src->SrcRegisterExtSwz.ExtSwizzleX, extswizzle_names );
+ ENM( src->SrcRegisterExtSwz.ExtSwizzleY, extswizzle_names );
+ ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, extswizzle_names );
+ ENM( src->SrcRegisterExtSwz.ExtSwizzleW, extswizzle_names );
}
if (src->SrcRegisterExtMod.Complement)
@@ -841,10 +513,10 @@ tgsi_dump_instruction(
if (inst->InstructionExtTexture.Texture != TGSI_TEXTURE_UNKNOWN) {
TXT( ", " );
- ENM( inst->InstructionExtTexture.Texture, TGSI_TEXTURES_SHORT );
+ ENM( inst->InstructionExtTexture.Texture, texture_names );
}
- switch( inst->Instruction.Opcode ) {
+ switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_IF:
case TGSI_OPCODE_ELSE:
case TGSI_OPCODE_BGNLOOP2:
@@ -856,461 +528,47 @@ tgsi_dump_instruction(
}
}
-static void
-dump_instruction_verbose(
- struct tgsi_full_instruction *inst,
- unsigned ignored,
- unsigned deflt,
- struct tgsi_full_instruction *fi )
+static boolean
+iter_instruction(
+ struct tgsi_iterate_context *iter,
+ struct tgsi_full_instruction *inst )
{
- unsigned i;
-
- TXT( "\nOpcode : " );
- ENM( inst->Instruction.Opcode, TGSI_OPCODES );
- if( deflt || fi->Instruction.Saturate != inst->Instruction.Saturate ) {
- TXT( "\nSaturate : " );
- ENM( inst->Instruction.Saturate, TGSI_SATS );
- }
- if( deflt || fi->Instruction.NumDstRegs != inst->Instruction.NumDstRegs ) {
- TXT( "\nNumDstRegs : " );
- UID( inst->Instruction.NumDstRegs );
- }
- if( deflt || fi->Instruction.NumSrcRegs != inst->Instruction.NumSrcRegs ) {
- TXT( "\nNumSrcRegs : " );
- UID( inst->Instruction.NumSrcRegs );
- }
- if( ignored ) {
- TXT( "\nPadding : " );
- UIX( inst->Instruction.Padding );
- }
-
- if( deflt || tgsi_compare_instruction_ext_nv( inst->InstructionExtNv, fi->InstructionExtNv ) ) {
- EOL();
- TXT( "\nType : " );
- ENM( inst->InstructionExtNv.Type, TGSI_INSTRUCTION_EXTS );
- if( deflt || fi->InstructionExtNv.Precision != inst->InstructionExtNv.Precision ) {
- TXT( "\nPrecision : " );
- ENM( inst->InstructionExtNv.Precision, TGSI_PRECISIONS );
- }
- if( deflt || fi->InstructionExtNv.CondDstIndex != inst->InstructionExtNv.CondDstIndex ) {
- TXT( "\nCondDstIndex : " );
- UID( inst->InstructionExtNv.CondDstIndex );
- }
- if( deflt || fi->InstructionExtNv.CondFlowIndex != inst->InstructionExtNv.CondFlowIndex ) {
- TXT( "\nCondFlowIndex : " );
- UID( inst->InstructionExtNv.CondFlowIndex );
- }
- if( deflt || fi->InstructionExtNv.CondMask != inst->InstructionExtNv.CondMask ) {
- TXT( "\nCondMask : " );
- ENM( inst->InstructionExtNv.CondMask, TGSI_CCS );
- }
- if( deflt || fi->InstructionExtNv.CondSwizzleX != inst->InstructionExtNv.CondSwizzleX ) {
- TXT( "\nCondSwizzleX : " );
- ENM( inst->InstructionExtNv.CondSwizzleX, TGSI_SWIZZLES );
- }
- if( deflt || fi->InstructionExtNv.CondSwizzleY != inst->InstructionExtNv.CondSwizzleY ) {
- TXT( "\nCondSwizzleY : " );
- ENM( inst->InstructionExtNv.CondSwizzleY, TGSI_SWIZZLES );
- }
- if( deflt || fi->InstructionExtNv.CondSwizzleZ != inst->InstructionExtNv.CondSwizzleZ ) {
- TXT( "\nCondSwizzleZ : " );
- ENM( inst->InstructionExtNv.CondSwizzleZ, TGSI_SWIZZLES );
- }
- if( deflt || fi->InstructionExtNv.CondSwizzleW != inst->InstructionExtNv.CondSwizzleW ) {
- TXT( "\nCondSwizzleW : " );
- ENM( inst->InstructionExtNv.CondSwizzleW, TGSI_SWIZZLES );
- }
- if( deflt || fi->InstructionExtNv.CondDstUpdate != inst->InstructionExtNv.CondDstUpdate ) {
- TXT( "\nCondDstUpdate : " );
- UID( inst->InstructionExtNv.CondDstUpdate );
- }
- if( deflt || fi->InstructionExtNv.CondFlowEnable != inst->InstructionExtNv.CondFlowEnable ) {
- TXT( "\nCondFlowEnable: " );
- UID( inst->InstructionExtNv.CondFlowEnable );
- }
- if( ignored ) {
- TXT( "\nPadding : " );
- UIX( inst->InstructionExtNv.Padding );
- if( deflt || fi->InstructionExtNv.Extended != inst->InstructionExtNv.Extended ) {
- TXT( "\nExtended : " );
- UID( inst->InstructionExtNv.Extended );
- }
- }
- }
-
- if( deflt || tgsi_compare_instruction_ext_label( inst->InstructionExtLabel, fi->InstructionExtLabel ) ) {
- EOL();
- TXT( "\nType : " );
- ENM( inst->InstructionExtLabel.Type, TGSI_INSTRUCTION_EXTS );
- if( deflt || fi->InstructionExtLabel.Label != inst->InstructionExtLabel.Label ) {
- TXT( "\nLabel : " );
- UID( inst->InstructionExtLabel.Label );
- }
- if( ignored ) {
- TXT( "\nPadding : " );
- UIX( inst->InstructionExtLabel.Padding );
- if( deflt || fi->InstructionExtLabel.Extended != inst->InstructionExtLabel.Extended ) {
- TXT( "\nExtended: " );
- UID( inst->InstructionExtLabel.Extended );
- }
- }
- }
-
- if( deflt || tgsi_compare_instruction_ext_texture( inst->InstructionExtTexture, fi->InstructionExtTexture ) ) {
- EOL();
- TXT( "\nType : " );
- ENM( inst->InstructionExtTexture.Type, TGSI_INSTRUCTION_EXTS );
- if( deflt || fi->InstructionExtTexture.Texture != inst->InstructionExtTexture.Texture ) {
- TXT( "\nTexture : " );
- ENM( inst->InstructionExtTexture.Texture, TGSI_TEXTURES );
- }
- if( ignored ) {
- TXT( "\nPadding : " );
- UIX( inst->InstructionExtTexture.Padding );
- if( deflt || fi->InstructionExtTexture.Extended != inst->InstructionExtTexture.Extended ) {
- TXT( "\nExtended: " );
- UID( inst->InstructionExtTexture.Extended );
- }
- }
- }
-
- for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) {
- struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
- struct tgsi_full_dst_register *fd = &fi->FullDstRegisters[i];
-
- EOL();
- TXT( "\nFile : " );
- ENM( dst->DstRegister.File, TGSI_FILES );
- if( deflt || fd->DstRegister.WriteMask != dst->DstRegister.WriteMask ) {
- TXT( "\nWriteMask: " );
- ENM( dst->DstRegister.WriteMask, TGSI_WRITEMASKS );
- }
- if( ignored ) {
- if( deflt || fd->DstRegister.Indirect != dst->DstRegister.Indirect ) {
- TXT( "\nIndirect : " );
- UID( dst->DstRegister.Indirect );
- }
- if( deflt || fd->DstRegister.Dimension != dst->DstRegister.Dimension ) {
- TXT( "\nDimension: " );
- UID( dst->DstRegister.Dimension );
- }
- }
- if( deflt || fd->DstRegister.Index != dst->DstRegister.Index ) {
- TXT( "\nIndex : " );
- SID( dst->DstRegister.Index );
- }
- if( ignored ) {
- TXT( "\nPadding : " );
- UIX( dst->DstRegister.Padding );
- if( deflt || fd->DstRegister.Extended != dst->DstRegister.Extended ) {
- TXT( "\nExtended : " );
- UID( dst->DstRegister.Extended );
- }
- }
-
- if( deflt || tgsi_compare_dst_register_ext_concode( dst->DstRegisterExtConcode, fd->DstRegisterExtConcode ) ) {
- EOL();
- TXT( "\nType : " );
- ENM( dst->DstRegisterExtConcode.Type, TGSI_DST_REGISTER_EXTS );
- if( deflt || fd->DstRegisterExtConcode.CondMask != dst->DstRegisterExtConcode.CondMask ) {
- TXT( "\nCondMask : " );
- ENM( dst->DstRegisterExtConcode.CondMask, TGSI_CCS );
- }
- if( deflt || fd->DstRegisterExtConcode.CondSwizzleX != dst->DstRegisterExtConcode.CondSwizzleX ) {
- TXT( "\nCondSwizzleX: " );
- ENM( dst->DstRegisterExtConcode.CondSwizzleX, TGSI_SWIZZLES );
- }
- if( deflt || fd->DstRegisterExtConcode.CondSwizzleY != dst->DstRegisterExtConcode.CondSwizzleY ) {
- TXT( "\nCondSwizzleY: " );
- ENM( dst->DstRegisterExtConcode.CondSwizzleY, TGSI_SWIZZLES );
- }
- if( deflt || fd->DstRegisterExtConcode.CondSwizzleZ != dst->DstRegisterExtConcode.CondSwizzleZ ) {
- TXT( "\nCondSwizzleZ: " );
- ENM( dst->DstRegisterExtConcode.CondSwizzleZ, TGSI_SWIZZLES );
- }
- if( deflt || fd->DstRegisterExtConcode.CondSwizzleW != dst->DstRegisterExtConcode.CondSwizzleW ) {
- TXT( "\nCondSwizzleW: " );
- ENM( dst->DstRegisterExtConcode.CondSwizzleW, TGSI_SWIZZLES );
- }
- if( deflt || fd->DstRegisterExtConcode.CondSrcIndex != dst->DstRegisterExtConcode.CondSrcIndex ) {
- TXT( "\nCondSrcIndex: " );
- UID( dst->DstRegisterExtConcode.CondSrcIndex );
- }
- if( ignored ) {
- TXT( "\nPadding : " );
- UIX( dst->DstRegisterExtConcode.Padding );
- if( deflt || fd->DstRegisterExtConcode.Extended != dst->DstRegisterExtConcode.Extended ) {
- TXT( "\nExtended : " );
- UID( dst->DstRegisterExtConcode.Extended );
- }
- }
- }
-
- if( deflt || tgsi_compare_dst_register_ext_modulate( dst->DstRegisterExtModulate, fd->DstRegisterExtModulate ) ) {
- EOL();
- TXT( "\nType : " );
- ENM( dst->DstRegisterExtModulate.Type, TGSI_DST_REGISTER_EXTS );
- if( deflt || fd->DstRegisterExtModulate.Modulate != dst->DstRegisterExtModulate.Modulate ) {
- TXT( "\nModulate: " );
- ENM( dst->DstRegisterExtModulate.Modulate, TGSI_MODULATES );
- }
- if( ignored ) {
- TXT( "\nPadding : " );
- UIX( dst->DstRegisterExtModulate.Padding );
- if( deflt || fd->DstRegisterExtModulate.Extended != dst->DstRegisterExtModulate.Extended ) {
- TXT( "\nExtended: " );
- UID( dst->DstRegisterExtModulate.Extended );
- }
- }
- }
- }
+ struct dump_ctx *ctx = (struct dump_ctx *) iter;
- for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) {
- struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i];
- struct tgsi_full_src_register *fs = &fi->FullSrcRegisters[i];
-
- EOL();
- TXT( "\nFile : ");
- ENM( src->SrcRegister.File, TGSI_FILES );
- if( deflt || fs->SrcRegister.SwizzleX != src->SrcRegister.SwizzleX ) {
- TXT( "\nSwizzleX : " );
- ENM( src->SrcRegister.SwizzleX, TGSI_SWIZZLES );
- }
- if( deflt || fs->SrcRegister.SwizzleY != src->SrcRegister.SwizzleY ) {
- TXT( "\nSwizzleY : " );
- ENM( src->SrcRegister.SwizzleY, TGSI_SWIZZLES );
- }
- if( deflt || fs->SrcRegister.SwizzleZ != src->SrcRegister.SwizzleZ ) {
- TXT( "\nSwizzleZ : " );
- ENM( src->SrcRegister.SwizzleZ, TGSI_SWIZZLES );
- }
- if( deflt || fs->SrcRegister.SwizzleW != src->SrcRegister.SwizzleW ) {
- TXT( "\nSwizzleW : " );
- ENM( src->SrcRegister.SwizzleW, TGSI_SWIZZLES );
- }
- if( deflt || fs->SrcRegister.Negate != src->SrcRegister.Negate ) {
- TXT( "\nNegate : " );
- UID( src->SrcRegister.Negate );
- }
- if( ignored ) {
- if( deflt || fs->SrcRegister.Indirect != src->SrcRegister.Indirect ) {
- TXT( "\nIndirect : " );
- UID( src->SrcRegister.Indirect );
- }
- if( deflt || fs->SrcRegister.Dimension != src->SrcRegister.Dimension ) {
- TXT( "\nDimension: " );
- UID( src->SrcRegister.Dimension );
- }
- }
- if( deflt || fs->SrcRegister.Index != src->SrcRegister.Index ) {
- TXT( "\nIndex : " );
- SID( src->SrcRegister.Index );
- }
- if( ignored ) {
- if( deflt || fs->SrcRegister.Extended != src->SrcRegister.Extended ) {
- TXT( "\nExtended : " );
- UID( src->SrcRegister.Extended );
- }
- }
-
- if( deflt || tgsi_compare_src_register_ext_swz( src->SrcRegisterExtSwz, fs->SrcRegisterExtSwz ) ) {
- EOL();
- TXT( "\nType : " );
- ENM( src->SrcRegisterExtSwz.Type, TGSI_SRC_REGISTER_EXTS );
- if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleX != src->SrcRegisterExtSwz.ExtSwizzleX ) {
- TXT( "\nExtSwizzleX: " );
- ENM( src->SrcRegisterExtSwz.ExtSwizzleX, TGSI_EXTSWIZZLES );
- }
- if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleY != src->SrcRegisterExtSwz.ExtSwizzleY ) {
- TXT( "\nExtSwizzleY: " );
- ENM( src->SrcRegisterExtSwz.ExtSwizzleY, TGSI_EXTSWIZZLES );
- }
- if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleZ != src->SrcRegisterExtSwz.ExtSwizzleZ ) {
- TXT( "\nExtSwizzleZ: " );
- ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, TGSI_EXTSWIZZLES );
- }
- if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleW != src->SrcRegisterExtSwz.ExtSwizzleW ) {
- TXT( "\nExtSwizzleW: " );
- ENM( src->SrcRegisterExtSwz.ExtSwizzleW, TGSI_EXTSWIZZLES );
- }
- if( deflt || fs->SrcRegisterExtSwz.NegateX != src->SrcRegisterExtSwz.NegateX ) {
- TXT( "\nNegateX : " );
- UID( src->SrcRegisterExtSwz.NegateX );
- }
- if( deflt || fs->SrcRegisterExtSwz.NegateY != src->SrcRegisterExtSwz.NegateY ) {
- TXT( "\nNegateY : " );
- UID( src->SrcRegisterExtSwz.NegateY );
- }
- if( deflt || fs->SrcRegisterExtSwz.NegateZ != src->SrcRegisterExtSwz.NegateZ ) {
- TXT( "\nNegateZ : " );
- UID( src->SrcRegisterExtSwz.NegateZ );
- }
- if( deflt || fs->SrcRegisterExtSwz.NegateW != src->SrcRegisterExtSwz.NegateW ) {
- TXT( "\nNegateW : " );
- UID( src->SrcRegisterExtSwz.NegateW );
- }
- if( ignored ) {
- TXT( "\nPadding : " );
- UIX( src->SrcRegisterExtSwz.Padding );
- if( deflt || fs->SrcRegisterExtSwz.Extended != src->SrcRegisterExtSwz.Extended ) {
- TXT( "\nExtended : " );
- UID( src->SrcRegisterExtSwz.Extended );
- }
- }
- }
+ tgsi_dump_instruction( inst, ctx->instno++ );
+ return TRUE;
+}
- if( deflt || tgsi_compare_src_register_ext_mod( src->SrcRegisterExtMod, fs->SrcRegisterExtMod ) ) {
- EOL();
- TXT( "\nType : " );
- ENM( src->SrcRegisterExtMod.Type, TGSI_SRC_REGISTER_EXTS );
- if( deflt || fs->SrcRegisterExtMod.Complement != src->SrcRegisterExtMod.Complement ) {
- TXT( "\nComplement: " );
- UID( src->SrcRegisterExtMod.Complement );
- }
- if( deflt || fs->SrcRegisterExtMod.Bias != src->SrcRegisterExtMod.Bias ) {
- TXT( "\nBias : " );
- UID( src->SrcRegisterExtMod.Bias );
- }
- if( deflt || fs->SrcRegisterExtMod.Scale2X != src->SrcRegisterExtMod.Scale2X ) {
- TXT( "\nScale2X : " );
- UID( src->SrcRegisterExtMod.Scale2X );
- }
- if( deflt || fs->SrcRegisterExtMod.Absolute != src->SrcRegisterExtMod.Absolute ) {
- TXT( "\nAbsolute : " );
- UID( src->SrcRegisterExtMod.Absolute );
- }
- if( deflt || fs->SrcRegisterExtMod.Negate != src->SrcRegisterExtMod.Negate ) {
- TXT( "\nNegate : " );
- UID( src->SrcRegisterExtMod.Negate );
- }
- if( ignored ) {
- TXT( "\nPadding : " );
- UIX( src->SrcRegisterExtMod.Padding );
- if( deflt || fs->SrcRegisterExtMod.Extended != src->SrcRegisterExtMod.Extended ) {
- TXT( "\nExtended : " );
- UID( src->SrcRegisterExtMod.Extended );
- }
- }
- }
- }
+static boolean
+prolog(
+ struct tgsi_iterate_context *ctx )
+{
+ EOL();
+ ENM( ctx->processor.Processor, processor_type_names );
+ UID( ctx->version.MajorVersion );
+ CHR( '.' );
+ UID( ctx->version.MinorVersion );
+ return TRUE;
}
void
tgsi_dump(
const struct tgsi_token *tokens,
- unsigned flags )
+ uint flags )
{
- struct tgsi_parse_context parse;
- struct tgsi_full_instruction fi;
- struct tgsi_full_declaration fd;
- unsigned verbose = flags & TGSI_DUMP_VERBOSE;
- unsigned ignored = !(flags & TGSI_DUMP_NO_IGNORED);
- unsigned deflt = !(flags & TGSI_DUMP_NO_DEFAULT);
- unsigned instno = 0;
+ struct dump_ctx ctx;
/* sanity checks */
- assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_CONT], "OPCODE_CONT") == 0);
- assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_END], "OPCODE_END") == 0);
- assert(strcmp(TGSI_OPCODES_SHORT[TGSI_OPCODE_END], "END") == 0);
-
- tgsi_parse_init( &parse, tokens );
+ assert( strcmp( opcode_names[TGSI_OPCODE_CONT], "CONT" ) == 0 );
+ assert( strcmp( opcode_names[TGSI_OPCODE_END], "END" ) == 0 );
- TXT( "tgsi-dump begin -----------------" );
-
- EOL();
- ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES_SHORT );
- UID( parse.FullVersion.Version.MajorVersion );
- CHR( '.' );
- UID( parse.FullVersion.Version.MinorVersion );
-
- if( verbose ) {
- TXT( "\nMajorVersion: " );
- UID( parse.FullVersion.Version.MajorVersion );
- TXT( "\nMinorVersion: " );
- UID( parse.FullVersion.Version.MinorVersion );
- EOL();
-
- TXT( "\nHeaderSize: " );
- UID( parse.FullHeader.Header.HeaderSize );
- TXT( "\nBodySize : " );
- UID( parse.FullHeader.Header.BodySize );
- TXT( "\nProcessor : " );
- ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES );
- EOL();
- }
-
- fi = tgsi_default_full_instruction();
- fd = tgsi_default_full_declaration();
-
- while( !tgsi_parse_end_of_tokens( &parse ) ) {
- tgsi_parse_token( &parse );
-
- switch( parse.FullToken.Token.Type ) {
- case TGSI_TOKEN_TYPE_DECLARATION:
- tgsi_dump_declaration(
- &parse.FullToken.FullDeclaration );
- break;
-
- case TGSI_TOKEN_TYPE_IMMEDIATE:
- tgsi_dump_immediate(
- &parse.FullToken.FullImmediate );
- break;
-
- case TGSI_TOKEN_TYPE_INSTRUCTION:
- tgsi_dump_instruction(
- &parse.FullToken.FullInstruction,
- instno );
- instno++;
- break;
-
- default:
- assert( 0 );
- }
-
- if( verbose ) {
- TXT( "\nType : " );
- ENM( parse.FullToken.Token.Type, TGSI_TOKEN_TYPES );
- if( ignored ) {
- TXT( "\nSize : " );
- UID( parse.FullToken.Token.Size );
- if( deflt || parse.FullToken.Token.Extended ) {
- TXT( "\nExtended : " );
- UID( parse.FullToken.Token.Extended );
- }
- }
-
- switch( parse.FullToken.Token.Type ) {
- case TGSI_TOKEN_TYPE_DECLARATION:
- dump_declaration_verbose(
- &parse.FullToken.FullDeclaration,
- ignored,
- deflt,
- &fd );
- break;
-
- case TGSI_TOKEN_TYPE_IMMEDIATE:
- dump_immediate_verbose(
- &parse.FullToken.FullImmediate,
- ignored );
- break;
-
- case TGSI_TOKEN_TYPE_INSTRUCTION:
- dump_instruction_verbose(
- &parse.FullToken.FullInstruction,
- ignored,
- deflt,
- &fi );
- break;
-
- default:
- assert( 0 );
- }
-
- EOL();
- }
- }
+ ctx.iter.prolog = prolog;
+ ctx.iter.iterate_instruction = iter_instruction;
+ ctx.iter.iterate_declaration = iter_declaration;
+ ctx.iter.iterate_immediate = iter_immediate;
+ ctx.iter.epilog = NULL;
- TXT( "\ntgsi-dump end -------------------\n" );
+ ctx.instno = 0;
- tgsi_parse_free( &parse );
+ tgsi_iterate_shader( tokens, &ctx.iter );
}
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h
index ba7692b511..51c230b5db 100644
--- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h
@@ -1,6 +1,6 @@
/**************************************************************************
*
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -28,18 +28,16 @@
#ifndef TGSI_DUMP_H
#define TGSI_DUMP_H
+#include "pipe/p_shader_tokens.h"
+
#if defined __cplusplus
extern "C" {
#endif
-#define TGSI_DUMP_VERBOSE 1
-#define TGSI_DUMP_NO_IGNORED 2
-#define TGSI_DUMP_NO_DEFAULT 4
-
void
tgsi_dump(
const struct tgsi_token *tokens,
- unsigned flags );
+ uint flags );
struct tgsi_full_immediate;
struct tgsi_full_instruction;
@@ -51,12 +49,12 @@ tgsi_dump_immediate(
void
tgsi_dump_instruction(
- const struct tgsi_full_instruction *inst,
- unsigned instno );
+ const struct tgsi_full_instruction *inst,
+ uint instno );
void
tgsi_dump_declaration(
- const struct tgsi_full_declaration *decl );
+ const struct tgsi_full_declaration *decl );
#if defined __cplusplus
}
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c
new file mode 100644
index 0000000000..eabd74bd6d
--- /dev/null
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c
@@ -0,0 +1,845 @@
+/**************************************************************************
+ *
+ * Copyright 2007-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_debug.h"
+#include "pipe/p_util.h"
+#include "util/u_string.h"
+#include "tgsi_dump_c.h"
+#include "tgsi_parse.h"
+#include "tgsi_build.h"
+
+static void
+dump_enum(
+ const unsigned e,
+ const char **enums,
+ const unsigned enums_count )
+{
+ if (e >= enums_count) {
+ debug_printf( "%u", e );
+ }
+ else {
+ debug_printf( "%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 ) )
+
+static const char *TGSI_PROCESSOR_TYPES[] =
+{
+ "PROCESSOR_FRAGMENT",
+ "PROCESSOR_VERTEX",
+ "PROCESSOR_GEOMETRY"
+};
+
+static const char *TGSI_TOKEN_TYPES[] =
+{
+ "TOKEN_TYPE_DECLARATION",
+ "TOKEN_TYPE_IMMEDIATE",
+ "TOKEN_TYPE_INSTRUCTION"
+};
+
+static const char *TGSI_FILES[] =
+{
+ "FILE_NULL",
+ "FILE_CONSTANT",
+ "FILE_INPUT",
+ "FILE_OUTPUT",
+ "FILE_TEMPORARY",
+ "FILE_SAMPLER",
+ "FILE_ADDRESS",
+ "FILE_IMMEDIATE"
+};
+
+static const char *TGSI_INTERPOLATES[] =
+{
+ "INTERPOLATE_CONSTANT",
+ "INTERPOLATE_LINEAR",
+ "INTERPOLATE_PERSPECTIVE"
+};
+
+static const char *TGSI_SEMANTICS[] =
+{
+ "SEMANTIC_POSITION",
+ "SEMANTIC_COLOR",
+ "SEMANTIC_BCOLOR",
+ "SEMANTIC_FOG",
+ "SEMANTIC_PSIZE",
+ "SEMANTIC_GENERIC",
+ "SEMANTIC_NORMAL"
+};
+
+static const char *TGSI_IMMS[] =
+{
+ "IMM_FLOAT32"
+};
+
+static const char *TGSI_OPCODES[TGSI_OPCODE_LAST] =
+{
+ "OPCODE_ARL",
+ "OPCODE_MOV",
+ "OPCODE_LIT",
+ "OPCODE_RCP",
+ "OPCODE_RSQ",
+ "OPCODE_EXP",
+ "OPCODE_LOG",
+ "OPCODE_MUL",
+ "OPCODE_ADD",
+ "OPCODE_DP3",
+ "OPCODE_DP4",
+ "OPCODE_DST",
+ "OPCODE_MIN",
+ "OPCODE_MAX",
+ "OPCODE_SLT",
+ "OPCODE_SGE",
+ "OPCODE_MAD",
+ "OPCODE_SUB",
+ "OPCODE_LERP",
+ "OPCODE_CND",
+ "OPCODE_CND0",
+ "OPCODE_DOT2ADD",
+ "OPCODE_INDEX",
+ "OPCODE_NEGATE",
+ "OPCODE_FRAC",
+ "OPCODE_CLAMP",
+ "OPCODE_FLOOR",
+ "OPCODE_ROUND",
+ "OPCODE_EXPBASE2",
+ "OPCODE_LOGBASE2",
+ "OPCODE_POWER",
+ "OPCODE_CROSSPRODUCT",
+ "OPCODE_MULTIPLYMATRIX",
+ "OPCODE_ABS",
+ "OPCODE_RCC",
+ "OPCODE_DPH",
+ "OPCODE_COS",
+ "OPCODE_DDX",
+ "OPCODE_DDY",
+ "OPCODE_KILP",
+ "OPCODE_PK2H",
+ "OPCODE_PK2US",
+ "OPCODE_PK4B",
+ "OPCODE_PK4UB",
+ "OPCODE_RFL",
+ "OPCODE_SEQ",
+ "OPCODE_SFL",
+ "OPCODE_SGT",
+ "OPCODE_SIN",
+ "OPCODE_SLE",
+ "OPCODE_SNE",
+ "OPCODE_STR",
+ "OPCODE_TEX",
+ "OPCODE_TXD",
+ "OPCODE_TXP",
+ "OPCODE_UP2H",
+ "OPCODE_UP2US",
+ "OPCODE_UP4B",
+ "OPCODE_UP4UB",
+ "OPCODE_X2D",
+ "OPCODE_ARA",
+ "OPCODE_ARR",
+ "OPCODE_BRA",
+ "OPCODE_CAL",
+ "OPCODE_RET",
+ "OPCODE_SSG",
+ "OPCODE_CMP",
+ "OPCODE_SCS",
+ "OPCODE_TXB",
+ "OPCODE_NRM",
+ "OPCODE_DIV",
+ "OPCODE_DP2",
+ "OPCODE_TXL",
+ "OPCODE_BRK",
+ "OPCODE_IF",
+ "OPCODE_LOOP",
+ "OPCODE_REP",
+ "OPCODE_ELSE",
+ "OPCODE_ENDIF",
+ "OPCODE_ENDLOOP",
+ "OPCODE_ENDREP",
+ "OPCODE_PUSHA",
+ "OPCODE_POPA",
+ "OPCODE_CEIL",
+ "OPCODE_I2F",
+ "OPCODE_NOT",
+ "OPCODE_TRUNC",
+ "OPCODE_SHL",
+ "OPCODE_SHR",
+ "OPCODE_AND",
+ "OPCODE_OR",
+ "OPCODE_MOD",
+ "OPCODE_XOR",
+ "OPCODE_SAD",
+ "OPCODE_TXF",
+ "OPCODE_TXQ",
+ "OPCODE_CONT",
+ "OPCODE_EMIT",
+ "OPCODE_ENDPRIM",
+ "OPCODE_BGNLOOP2",
+ "OPCODE_BGNSUB",
+ "OPCODE_ENDLOOP2",
+ "OPCODE_ENDSUB",
+ "OPCODE_NOISE1",
+ "OPCODE_NOISE2",
+ "OPCODE_NOISE3",
+ "OPCODE_NOISE4",
+ "OPCODE_NOP",
+ "OPCODE_M4X3",
+ "OPCODE_M3X4",
+ "OPCODE_M3X3",
+ "OPCODE_M3X2",
+ "OPCODE_NRM4",
+ "OPCODE_CALLNZ",
+ "OPCODE_IFC",
+ "OPCODE_BREAKC",
+ "OPCODE_KIL",
+ "OPCODE_END"
+};
+
+static const char *TGSI_SATS[] =
+{
+ "SAT_NONE",
+ "SAT_ZERO_ONE",
+ "SAT_MINUS_PLUS_ONE"
+};
+
+static const char *TGSI_INSTRUCTION_EXTS[] =
+{
+ "INSTRUCTION_EXT_TYPE_NV",
+ "INSTRUCTION_EXT_TYPE_LABEL",
+ "INSTRUCTION_EXT_TYPE_TEXTURE"
+};
+
+static const char *TGSI_PRECISIONS[] =
+{
+ "PRECISION_DEFAULT",
+ "PRECISION_FLOAT32",
+ "PRECISION_FLOAT16",
+ "PRECISION_FIXED12"
+};
+
+static const char *TGSI_CCS[] =
+{
+ "CC_GT",
+ "CC_EQ",
+ "CC_LT",
+ "CC_UN",
+ "CC_GE",
+ "CC_LE",
+ "CC_NE",
+ "CC_TR",
+ "CC_FL"
+};
+
+static const char *TGSI_SWIZZLES[] =
+{
+ "SWIZZLE_X",
+ "SWIZZLE_Y",
+ "SWIZZLE_Z",
+ "SWIZZLE_W"
+};
+
+static const char *TGSI_TEXTURES[] =
+{
+ "TEXTURE_UNKNOWN",
+ "TEXTURE_1D",
+ "TEXTURE_2D",
+ "TEXTURE_3D",
+ "TEXTURE_CUBE",
+ "TEXTURE_RECT",
+ "TEXTURE_SHADOW1D",
+ "TEXTURE_SHADOW2D",
+ "TEXTURE_SHADOWRECT"
+};
+
+static const char *TGSI_SRC_REGISTER_EXTS[] =
+{
+ "SRC_REGISTER_EXT_TYPE_SWZ",
+ "SRC_REGISTER_EXT_TYPE_MOD"
+};
+
+static const char *TGSI_EXTSWIZZLES[] =
+{
+ "EXTSWIZZLE_X",
+ "EXTSWIZZLE_Y",
+ "EXTSWIZZLE_Z",
+ "EXTSWIZZLE_W",
+ "EXTSWIZZLE_ZERO",
+ "EXTSWIZZLE_ONE"
+};
+
+static const char *TGSI_WRITEMASKS[] =
+{
+ "0",
+ "WRITEMASK_X",
+ "WRITEMASK_Y",
+ "WRITEMASK_XY",
+ "WRITEMASK_Z",
+ "WRITEMASK_XZ",
+ "WRITEMASK_YZ",
+ "WRITEMASK_XYZ",
+ "WRITEMASK_W",
+ "WRITEMASK_XW",
+ "WRITEMASK_YW",
+ "WRITEMASK_XYW",
+ "WRITEMASK_ZW",
+ "WRITEMASK_XZW",
+ "WRITEMASK_YZW",
+ "WRITEMASK_XYZW"
+};
+
+static const char *TGSI_DST_REGISTER_EXTS[] =
+{
+ "DST_REGISTER_EXT_TYPE_CONDCODE",
+ "DST_REGISTER_EXT_TYPE_MODULATE"
+};
+
+static const char *TGSI_MODULATES[] =
+{
+ "MODULATE_1X",
+ "MODULATE_2X",
+ "MODULATE_4X",
+ "MODULATE_8X",
+ "MODULATE_HALF",
+ "MODULATE_QUARTER",
+ "MODULATE_EIGHTH"
+};
+
+static void
+dump_declaration_verbose(
+ struct tgsi_full_declaration *decl,
+ unsigned ignored,
+ unsigned deflt,
+ struct tgsi_full_declaration *fd )
+{
+ TXT( "\nFile : " );
+ ENM( decl->Declaration.File, TGSI_FILES );
+ if( deflt || fd->Declaration.UsageMask != decl->Declaration.UsageMask ) {
+ TXT( "\nUsageMask : " );
+ if( decl->Declaration.UsageMask & TGSI_WRITEMASK_X ) {
+ CHR( 'X' );
+ }
+ if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Y ) {
+ CHR( 'Y' );
+ }
+ if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Z ) {
+ CHR( 'Z' );
+ }
+ if( decl->Declaration.UsageMask & TGSI_WRITEMASK_W ) {
+ CHR( 'W' );
+ }
+ }
+ if( deflt || fd->Declaration.Interpolate != decl->Declaration.Interpolate ) {
+ TXT( "\nInterpolate: " );
+ ENM( decl->Declaration.Interpolate, TGSI_INTERPOLATES );
+ }
+ if( deflt || fd->Declaration.Semantic != decl->Declaration.Semantic ) {
+ TXT( "\nSemantic : " );
+ UID( decl->Declaration.Semantic );
+ }
+ if( ignored ) {
+ TXT( "\nPadding : " );
+ UIX( decl->Declaration.Padding );
+ }
+
+ EOL();
+ TXT( "\nFirst: " );
+ UID( decl->DeclarationRange.First );
+ TXT( "\nLast : " );
+ UID( decl->DeclarationRange.Last );
+
+ if( decl->Declaration.Semantic ) {
+ EOL();
+ TXT( "\nSemanticName : " );
+ ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS );
+ TXT( "\nSemanticIndex: " );
+ UID( decl->Semantic.SemanticIndex );
+ if( ignored ) {
+ TXT( "\nPadding : " );
+ UIX( decl->Semantic.Padding );
+ }
+ }
+}
+
+static void
+dump_immediate_verbose(
+ struct tgsi_full_immediate *imm,
+ unsigned ignored )
+{
+ unsigned i;
+
+ TXT( "\nDataType : " );
+ ENM( imm->Immediate.DataType, TGSI_IMMS );
+ if( ignored ) {
+ TXT( "\nPadding : " );
+ UIX( imm->Immediate.Padding );
+ }
+
+ for( i = 0; i < imm->Immediate.Size - 1; i++ ) {
+ EOL();
+ switch( imm->Immediate.DataType ) {
+ case TGSI_IMM_FLOAT32:
+ TXT( "\nFloat: " );
+ FLT( imm->u.ImmediateFloat32[i].Float );
+ break;
+
+ default:
+ assert( 0 );
+ }
+ }
+}
+
+static void
+dump_instruction_verbose(
+ struct tgsi_full_instruction *inst,
+ unsigned ignored,
+ unsigned deflt,
+ struct tgsi_full_instruction *fi )
+{
+ unsigned i;
+
+ TXT( "\nOpcode : " );
+ ENM( inst->Instruction.Opcode, TGSI_OPCODES );
+ if( deflt || fi->Instruction.Saturate != inst->Instruction.Saturate ) {
+ TXT( "\nSaturate : " );
+ ENM( inst->Instruction.Saturate, TGSI_SATS );
+ }
+ if( deflt || fi->Instruction.NumDstRegs != inst->Instruction.NumDstRegs ) {
+ TXT( "\nNumDstRegs : " );
+ UID( inst->Instruction.NumDstRegs );
+ }
+ if( deflt || fi->Instruction.NumSrcRegs != inst->Instruction.NumSrcRegs ) {
+ TXT( "\nNumSrcRegs : " );
+ UID( inst->Instruction.NumSrcRegs );
+ }
+ if( ignored ) {
+ TXT( "\nPadding : " );
+ UIX( inst->Instruction.Padding );
+ }
+
+ if( deflt || tgsi_compare_instruction_ext_nv( inst->InstructionExtNv, fi->InstructionExtNv ) ) {
+ EOL();
+ TXT( "\nType : " );
+ ENM( inst->InstructionExtNv.Type, TGSI_INSTRUCTION_EXTS );
+ if( deflt || fi->InstructionExtNv.Precision != inst->InstructionExtNv.Precision ) {
+ TXT( "\nPrecision : " );
+ ENM( inst->InstructionExtNv.Precision, TGSI_PRECISIONS );
+ }
+ if( deflt || fi->InstructionExtNv.CondDstIndex != inst->InstructionExtNv.CondDstIndex ) {
+ TXT( "\nCondDstIndex : " );
+ UID( inst->InstructionExtNv.CondDstIndex );
+ }
+ if( deflt || fi->InstructionExtNv.CondFlowIndex != inst->InstructionExtNv.CondFlowIndex ) {
+ TXT( "\nCondFlowIndex : " );
+ UID( inst->InstructionExtNv.CondFlowIndex );
+ }
+ if( deflt || fi->InstructionExtNv.CondMask != inst->InstructionExtNv.CondMask ) {
+ TXT( "\nCondMask : " );
+ ENM( inst->InstructionExtNv.CondMask, TGSI_CCS );
+ }
+ if( deflt || fi->InstructionExtNv.CondSwizzleX != inst->InstructionExtNv.CondSwizzleX ) {
+ TXT( "\nCondSwizzleX : " );
+ ENM( inst->InstructionExtNv.CondSwizzleX, TGSI_SWIZZLES );
+ }
+ if( deflt || fi->InstructionExtNv.CondSwizzleY != inst->InstructionExtNv.CondSwizzleY ) {
+ TXT( "\nCondSwizzleY : " );
+ ENM( inst->InstructionExtNv.CondSwizzleY, TGSI_SWIZZLES );
+ }
+ if( deflt || fi->InstructionExtNv.CondSwizzleZ != inst->InstructionExtNv.CondSwizzleZ ) {
+ TXT( "\nCondSwizzleZ : " );
+ ENM( inst->InstructionExtNv.CondSwizzleZ, TGSI_SWIZZLES );
+ }
+ if( deflt || fi->InstructionExtNv.CondSwizzleW != inst->InstructionExtNv.CondSwizzleW ) {
+ TXT( "\nCondSwizzleW : " );
+ ENM( inst->InstructionExtNv.CondSwizzleW, TGSI_SWIZZLES );
+ }
+ if( deflt || fi->InstructionExtNv.CondDstUpdate != inst->InstructionExtNv.CondDstUpdate ) {
+ TXT( "\nCondDstUpdate : " );
+ UID( inst->InstructionExtNv.CondDstUpdate );
+ }
+ if( deflt || fi->InstructionExtNv.CondFlowEnable != inst->InstructionExtNv.CondFlowEnable ) {
+ TXT( "\nCondFlowEnable: " );
+ UID( inst->InstructionExtNv.CondFlowEnable );
+ }
+ if( ignored ) {
+ TXT( "\nPadding : " );
+ UIX( inst->InstructionExtNv.Padding );
+ if( deflt || fi->InstructionExtNv.Extended != inst->InstructionExtNv.Extended ) {
+ TXT( "\nExtended : " );
+ UID( inst->InstructionExtNv.Extended );
+ }
+ }
+ }
+
+ if( deflt || tgsi_compare_instruction_ext_label( inst->InstructionExtLabel, fi->InstructionExtLabel ) ) {
+ EOL();
+ TXT( "\nType : " );
+ ENM( inst->InstructionExtLabel.Type, TGSI_INSTRUCTION_EXTS );
+ if( deflt || fi->InstructionExtLabel.Label != inst->InstructionExtLabel.Label ) {
+ TXT( "\nLabel : " );
+ UID( inst->InstructionExtLabel.Label );
+ }
+ if( ignored ) {
+ TXT( "\nPadding : " );
+ UIX( inst->InstructionExtLabel.Padding );
+ if( deflt || fi->InstructionExtLabel.Extended != inst->InstructionExtLabel.Extended ) {
+ TXT( "\nExtended: " );
+ UID( inst->InstructionExtLabel.Extended );
+ }
+ }
+ }
+
+ if( deflt || tgsi_compare_instruction_ext_texture( inst->InstructionExtTexture, fi->InstructionExtTexture ) ) {
+ EOL();
+ TXT( "\nType : " );
+ ENM( inst->InstructionExtTexture.Type, TGSI_INSTRUCTION_EXTS );
+ if( deflt || fi->InstructionExtTexture.Texture != inst->InstructionExtTexture.Texture ) {
+ TXT( "\nTexture : " );
+ ENM( inst->InstructionExtTexture.Texture, TGSI_TEXTURES );
+ }
+ if( ignored ) {
+ TXT( "\nPadding : " );
+ UIX( inst->InstructionExtTexture.Padding );
+ if( deflt || fi->InstructionExtTexture.Extended != inst->InstructionExtTexture.Extended ) {
+ TXT( "\nExtended: " );
+ UID( inst->InstructionExtTexture.Extended );
+ }
+ }
+ }
+
+ for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) {
+ struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
+ struct tgsi_full_dst_register *fd = &fi->FullDstRegisters[i];
+
+ EOL();
+ TXT( "\nFile : " );
+ ENM( dst->DstRegister.File, TGSI_FILES );
+ if( deflt || fd->DstRegister.WriteMask != dst->DstRegister.WriteMask ) {
+ TXT( "\nWriteMask: " );
+ ENM( dst->DstRegister.WriteMask, TGSI_WRITEMASKS );
+ }
+ if( ignored ) {
+ if( deflt || fd->DstRegister.Indirect != dst->DstRegister.Indirect ) {
+ TXT( "\nIndirect : " );
+ UID( dst->DstRegister.Indirect );
+ }
+ if( deflt || fd->DstRegister.Dimension != dst->DstRegister.Dimension ) {
+ TXT( "\nDimension: " );
+ UID( dst->DstRegister.Dimension );
+ }
+ }
+ if( deflt || fd->DstRegister.Index != dst->DstRegister.Index ) {
+ TXT( "\nIndex : " );
+ SID( dst->DstRegister.Index );
+ }
+ if( ignored ) {
+ TXT( "\nPadding : " );
+ UIX( dst->DstRegister.Padding );
+ if( deflt || fd->DstRegister.Extended != dst->DstRegister.Extended ) {
+ TXT( "\nExtended : " );
+ UID( dst->DstRegister.Extended );
+ }
+ }
+
+ if( deflt || tgsi_compare_dst_register_ext_concode( dst->DstRegisterExtConcode, fd->DstRegisterExtConcode ) ) {
+ EOL();
+ TXT( "\nType : " );
+ ENM( dst->DstRegisterExtConcode.Type, TGSI_DST_REGISTER_EXTS );
+ if( deflt || fd->DstRegisterExtConcode.CondMask != dst->DstRegisterExtConcode.CondMask ) {
+ TXT( "\nCondMask : " );
+ ENM( dst->DstRegisterExtConcode.CondMask, TGSI_CCS );
+ }
+ if( deflt || fd->DstRegisterExtConcode.CondSwizzleX != dst->DstRegisterExtConcode.CondSwizzleX ) {
+ TXT( "\nCondSwizzleX: " );
+ ENM( dst->DstRegisterExtConcode.CondSwizzleX, TGSI_SWIZZLES );
+ }
+ if( deflt || fd->DstRegisterExtConcode.CondSwizzleY != dst->DstRegisterExtConcode.CondSwizzleY ) {
+ TXT( "\nCondSwizzleY: " );
+ ENM( dst->DstRegisterExtConcode.CondSwizzleY, TGSI_SWIZZLES );
+ }
+ if( deflt || fd->DstRegisterExtConcode.CondSwizzleZ != dst->DstRegisterExtConcode.CondSwizzleZ ) {
+ TXT( "\nCondSwizzleZ: " );
+ ENM( dst->DstRegisterExtConcode.CondSwizzleZ, TGSI_SWIZZLES );
+ }
+ if( deflt || fd->DstRegisterExtConcode.CondSwizzleW != dst->DstRegisterExtConcode.CondSwizzleW ) {
+ TXT( "\nCondSwizzleW: " );
+ ENM( dst->DstRegisterExtConcode.CondSwizzleW, TGSI_SWIZZLES );
+ }
+ if( deflt || fd->DstRegisterExtConcode.CondSrcIndex != dst->DstRegisterExtConcode.CondSrcIndex ) {
+ TXT( "\nCondSrcIndex: " );
+ UID( dst->DstRegisterExtConcode.CondSrcIndex );
+ }
+ if( ignored ) {
+ TXT( "\nPadding : " );
+ UIX( dst->DstRegisterExtConcode.Padding );
+ if( deflt || fd->DstRegisterExtConcode.Extended != dst->DstRegisterExtConcode.Extended ) {
+ TXT( "\nExtended : " );
+ UID( dst->DstRegisterExtConcode.Extended );
+ }
+ }
+ }
+
+ if( deflt || tgsi_compare_dst_register_ext_modulate( dst->DstRegisterExtModulate, fd->DstRegisterExtModulate ) ) {
+ EOL();
+ TXT( "\nType : " );
+ ENM( dst->DstRegisterExtModulate.Type, TGSI_DST_REGISTER_EXTS );
+ if( deflt || fd->DstRegisterExtModulate.Modulate != dst->DstRegisterExtModulate.Modulate ) {
+ TXT( "\nModulate: " );
+ ENM( dst->DstRegisterExtModulate.Modulate, TGSI_MODULATES );
+ }
+ if( ignored ) {
+ TXT( "\nPadding : " );
+ UIX( dst->DstRegisterExtModulate.Padding );
+ if( deflt || fd->DstRegisterExtModulate.Extended != dst->DstRegisterExtModulate.Extended ) {
+ TXT( "\nExtended: " );
+ UID( dst->DstRegisterExtModulate.Extended );
+ }
+ }
+ }
+ }
+
+ for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) {
+ struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i];
+ struct tgsi_full_src_register *fs = &fi->FullSrcRegisters[i];
+
+ EOL();
+ TXT( "\nFile : ");
+ ENM( src->SrcRegister.File, TGSI_FILES );
+ if( deflt || fs->SrcRegister.SwizzleX != src->SrcRegister.SwizzleX ) {
+ TXT( "\nSwizzleX : " );
+ ENM( src->SrcRegister.SwizzleX, TGSI_SWIZZLES );
+ }
+ if( deflt || fs->SrcRegister.SwizzleY != src->SrcRegister.SwizzleY ) {
+ TXT( "\nSwizzleY : " );
+ ENM( src->SrcRegister.SwizzleY, TGSI_SWIZZLES );
+ }
+ if( deflt || fs->SrcRegister.SwizzleZ != src->SrcRegister.SwizzleZ ) {
+ TXT( "\nSwizzleZ : " );
+ ENM( src->SrcRegister.SwizzleZ, TGSI_SWIZZLES );
+ }
+ if( deflt || fs->SrcRegister.SwizzleW != src->SrcRegister.SwizzleW ) {
+ TXT( "\nSwizzleW : " );
+ ENM( src->SrcRegister.SwizzleW, TGSI_SWIZZLES );
+ }
+ if( deflt || fs->SrcRegister.Negate != src->SrcRegister.Negate ) {
+ TXT( "\nNegate : " );
+ UID( src->SrcRegister.Negate );
+ }
+ if( ignored ) {
+ if( deflt || fs->SrcRegister.Indirect != src->SrcRegister.Indirect ) {
+ TXT( "\nIndirect : " );
+ UID( src->SrcRegister.Indirect );
+ }
+ if( deflt || fs->SrcRegister.Dimension != src->SrcRegister.Dimension ) {
+ TXT( "\nDimension: " );
+ UID( src->SrcRegister.Dimension );
+ }
+ }
+ if( deflt || fs->SrcRegister.Index != src->SrcRegister.Index ) {
+ TXT( "\nIndex : " );
+ SID( src->SrcRegister.Index );
+ }
+ if( ignored ) {
+ if( deflt || fs->SrcRegister.Extended != src->SrcRegister.Extended ) {
+ TXT( "\nExtended : " );
+ UID( src->SrcRegister.Extended );
+ }
+ }
+
+ if( deflt || tgsi_compare_src_register_ext_swz( src->SrcRegisterExtSwz, fs->SrcRegisterExtSwz ) ) {
+ EOL();
+ TXT( "\nType : " );
+ ENM( src->SrcRegisterExtSwz.Type, TGSI_SRC_REGISTER_EXTS );
+ if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleX != src->SrcRegisterExtSwz.ExtSwizzleX ) {
+ TXT( "\nExtSwizzleX: " );
+ ENM( src->SrcRegisterExtSwz.ExtSwizzleX, TGSI_EXTSWIZZLES );
+ }
+ if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleY != src->SrcRegisterExtSwz.ExtSwizzleY ) {
+ TXT( "\nExtSwizzleY: " );
+ ENM( src->SrcRegisterExtSwz.ExtSwizzleY, TGSI_EXTSWIZZLES );
+ }
+ if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleZ != src->SrcRegisterExtSwz.ExtSwizzleZ ) {
+ TXT( "\nExtSwizzleZ: " );
+ ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, TGSI_EXTSWIZZLES );
+ }
+ if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleW != src->SrcRegisterExtSwz.ExtSwizzleW ) {
+ TXT( "\nExtSwizzleW: " );
+ ENM( src->SrcRegisterExtSwz.ExtSwizzleW, TGSI_EXTSWIZZLES );
+ }
+ if( deflt || fs->SrcRegisterExtSwz.NegateX != src->SrcRegisterExtSwz.NegateX ) {
+ TXT( "\nNegateX : " );
+ UID( src->SrcRegisterExtSwz.NegateX );
+ }
+ if( deflt || fs->SrcRegisterExtSwz.NegateY != src->SrcRegisterExtSwz.NegateY ) {
+ TXT( "\nNegateY : " );
+ UID( src->SrcRegisterExtSwz.NegateY );
+ }
+ if( deflt || fs->SrcRegisterExtSwz.NegateZ != src->SrcRegisterExtSwz.NegateZ ) {
+ TXT( "\nNegateZ : " );
+ UID( src->SrcRegisterExtSwz.NegateZ );
+ }
+ if( deflt || fs->SrcRegisterExtSwz.NegateW != src->SrcRegisterExtSwz.NegateW ) {
+ TXT( "\nNegateW : " );
+ UID( src->SrcRegisterExtSwz.NegateW );
+ }
+ if( ignored ) {
+ TXT( "\nPadding : " );
+ UIX( src->SrcRegisterExtSwz.Padding );
+ if( deflt || fs->SrcRegisterExtSwz.Extended != src->SrcRegisterExtSwz.Extended ) {
+ TXT( "\nExtended : " );
+ UID( src->SrcRegisterExtSwz.Extended );
+ }
+ }
+ }
+
+ if( deflt || tgsi_compare_src_register_ext_mod( src->SrcRegisterExtMod, fs->SrcRegisterExtMod ) ) {
+ EOL();
+ TXT( "\nType : " );
+ ENM( src->SrcRegisterExtMod.Type, TGSI_SRC_REGISTER_EXTS );
+ if( deflt || fs->SrcRegisterExtMod.Complement != src->SrcRegisterExtMod.Complement ) {
+ TXT( "\nComplement: " );
+ UID( src->SrcRegisterExtMod.Complement );
+ }
+ if( deflt || fs->SrcRegisterExtMod.Bias != src->SrcRegisterExtMod.Bias ) {
+ TXT( "\nBias : " );
+ UID( src->SrcRegisterExtMod.Bias );
+ }
+ if( deflt || fs->SrcRegisterExtMod.Scale2X != src->SrcRegisterExtMod.Scale2X ) {
+ TXT( "\nScale2X : " );
+ UID( src->SrcRegisterExtMod.Scale2X );
+ }
+ if( deflt || fs->SrcRegisterExtMod.Absolute != src->SrcRegisterExtMod.Absolute ) {
+ TXT( "\nAbsolute : " );
+ UID( src->SrcRegisterExtMod.Absolute );
+ }
+ if( deflt || fs->SrcRegisterExtMod.Negate != src->SrcRegisterExtMod.Negate ) {
+ TXT( "\nNegate : " );
+ UID( src->SrcRegisterExtMod.Negate );
+ }
+ if( ignored ) {
+ TXT( "\nPadding : " );
+ UIX( src->SrcRegisterExtMod.Padding );
+ if( deflt || fs->SrcRegisterExtMod.Extended != src->SrcRegisterExtMod.Extended ) {
+ TXT( "\nExtended : " );
+ UID( src->SrcRegisterExtMod.Extended );
+ }
+ }
+ }
+ }
+}
+
+void
+tgsi_dump_c(
+ const struct tgsi_token *tokens,
+ uint flags )
+{
+ struct tgsi_parse_context parse;
+ struct tgsi_full_instruction fi;
+ struct tgsi_full_declaration fd;
+ uint ignored = flags & TGSI_DUMP_C_IGNORED;
+ uint deflt = flags & TGSI_DUMP_C_DEFAULT;
+ uint instno = 0;
+
+ /* sanity checks */
+ assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_CONT], "OPCODE_CONT") == 0);
+ assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_END], "OPCODE_END") == 0);
+
+ tgsi_parse_init( &parse, tokens );
+
+ TXT( "tgsi-dump begin -----------------" );
+
+ TXT( "\nMajorVersion: " );
+ UID( parse.FullVersion.Version.MajorVersion );
+ TXT( "\nMinorVersion: " );
+ UID( parse.FullVersion.Version.MinorVersion );
+ EOL();
+
+ TXT( "\nHeaderSize: " );
+ UID( parse.FullHeader.Header.HeaderSize );
+ TXT( "\nBodySize : " );
+ UID( parse.FullHeader.Header.BodySize );
+ TXT( "\nProcessor : " );
+ ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES );
+ EOL();
+
+ fi = tgsi_default_full_instruction();
+ fd = tgsi_default_full_declaration();
+
+ while( !tgsi_parse_end_of_tokens( &parse ) ) {
+ tgsi_parse_token( &parse );
+
+ TXT( "\nType : " );
+ ENM( parse.FullToken.Token.Type, TGSI_TOKEN_TYPES );
+ if( ignored ) {
+ TXT( "\nSize : " );
+ UID( parse.FullToken.Token.Size );
+ if( deflt || parse.FullToken.Token.Extended ) {
+ TXT( "\nExtended : " );
+ UID( parse.FullToken.Token.Extended );
+ }
+ }
+
+ switch( parse.FullToken.Token.Type ) {
+ case TGSI_TOKEN_TYPE_DECLARATION:
+ dump_declaration_verbose(
+ &parse.FullToken.FullDeclaration,
+ ignored,
+ deflt,
+ &fd );
+ break;
+
+ case TGSI_TOKEN_TYPE_IMMEDIATE:
+ dump_immediate_verbose(
+ &parse.FullToken.FullImmediate,
+ ignored );
+ break;
+
+ case TGSI_TOKEN_TYPE_INSTRUCTION:
+ dump_instruction_verbose(
+ &parse.FullToken.FullInstruction,
+ ignored,
+ deflt,
+ &fi );
+ break;
+
+ default:
+ assert( 0 );
+ }
+
+ EOL();
+ }
+
+ TXT( "\ntgsi-dump end -------------------\n" );
+
+ tgsi_parse_free( &parse );
+}
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.h b/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.h
new file mode 100644
index 0000000000..d91cd35b3b
--- /dev/null
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.h
@@ -0,0 +1,49 @@
+/**************************************************************************
+ *
+ * Copyright 2007-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 TGSI_DUMP_C_H
+#define TGSI_DUMP_C_H
+
+#include "pipe/p_shader_tokens.h"
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+#define TGSI_DUMP_C_IGNORED 1
+#define TGSI_DUMP_C_DEFAULT 2
+
+void
+tgsi_dump_c(
+ const struct tgsi_token *tokens,
+ uint flags );
+
+#if defined __cplusplus
+}
+#endif
+
+#endif /* TGSI_DUMP_C_H */
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_iterate.c b/src/gallium/auxiliary/tgsi/util/tgsi_iterate.c
new file mode 100644
index 0000000000..5371a88b96
--- /dev/null
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_iterate.c
@@ -0,0 +1,85 @@
+/**************************************************************************
+ *
+ * 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_debug.h"
+#include "tgsi_iterate.h"
+
+boolean
+tgsi_iterate_shader(
+ const struct tgsi_token *tokens,
+ struct tgsi_iterate_context *ctx )
+{
+ struct tgsi_parse_context parse;
+
+ if (tgsi_parse_init( &parse, tokens ) != TGSI_PARSE_OK)
+ return FALSE;
+
+ ctx->processor = parse.FullHeader.Processor;
+ ctx->version = parse.FullVersion.Version;
+
+ if (ctx->prolog)
+ if (!ctx->prolog( ctx ))
+ goto fail;
+
+ while (!tgsi_parse_end_of_tokens( &parse )) {
+ tgsi_parse_token( &parse );
+
+ switch (parse.FullToken.Token.Type) {
+ case TGSI_TOKEN_TYPE_INSTRUCTION:
+ if (ctx->iterate_instruction)
+ if (!ctx->iterate_instruction( ctx, &parse.FullToken.FullInstruction ))
+ goto fail;
+ break;
+
+ case TGSI_TOKEN_TYPE_DECLARATION:
+ if (ctx->iterate_declaration)
+ if (!ctx->iterate_declaration( ctx, &parse.FullToken.FullDeclaration ))
+ goto fail;
+ break;
+
+ case TGSI_TOKEN_TYPE_IMMEDIATE:
+ if (ctx->iterate_immediate)
+ if (!ctx->iterate_immediate( ctx, &parse.FullToken.FullImmediate ))
+ goto fail;
+ break;
+
+ default:
+ assert( 0 );
+ }
+ }
+
+ if (ctx->epilog)
+ if (!ctx->epilog( ctx ))
+ goto fail;
+
+ tgsi_parse_free( &parse );
+ return TRUE;
+
+fail:
+ tgsi_parse_free( &parse );
+ return FALSE;
+}
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_iterate.h b/src/gallium/auxiliary/tgsi/util/tgsi_iterate.h
new file mode 100644
index 0000000000..f5bebf89b8
--- /dev/null
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_iterate.h
@@ -0,0 +1,76 @@
+/**************************************************************************
+ *
+ * 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 TGSI_ITERATE_H
+#define TGSI_ITERATE_H
+
+#include "pipe/p_shader_tokens.h"
+#include "tgsi/util/tgsi_parse.h"
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+struct tgsi_iterate_context
+{
+ boolean
+ (* prolog)(
+ struct tgsi_iterate_context *ctx );
+
+ boolean
+ (* iterate_instruction)(
+ struct tgsi_iterate_context *ctx,
+ struct tgsi_full_instruction *inst );
+
+ boolean
+ (* iterate_declaration)(
+ struct tgsi_iterate_context *ctx,
+ struct tgsi_full_declaration *decl );
+
+ boolean
+ (* iterate_immediate)(
+ struct tgsi_iterate_context *ctx,
+ struct tgsi_full_immediate *imm );
+
+ boolean
+ (* epilog)(
+ struct tgsi_iterate_context *ctx );
+
+ struct tgsi_processor processor;
+ struct tgsi_version version;
+};
+
+boolean
+tgsi_iterate_shader(
+ const struct tgsi_token *tokens,
+ struct tgsi_iterate_context *ctx );
+
+#if defined __cplusplus
+}
+#endif
+
+#endif /* TGSI_ITERATE_H */
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c
new file mode 100644
index 0000000000..9673f061ce
--- /dev/null
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c
@@ -0,0 +1,341 @@
+/**************************************************************************
+ *
+ * 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_debug.h"
+#include "tgsi_sanity.h"
+#include "tgsi_iterate.h"
+
+#define MAX_REGISTERS 256
+
+typedef uint reg_flag;
+
+#define BITS_IN_REG_FLAG (sizeof( reg_flag ) * 8)
+
+struct sanity_check_ctx
+{
+ struct tgsi_iterate_context iter;
+
+ reg_flag regs_decl[TGSI_FILE_COUNT][MAX_REGISTERS / BITS_IN_REG_FLAG];
+ reg_flag regs_used[TGSI_FILE_COUNT][MAX_REGISTERS / BITS_IN_REG_FLAG];
+ boolean regs_ind_used[TGSI_FILE_COUNT];
+ uint num_imms;
+ uint num_instructions;
+ uint index_of_END;
+
+ uint errors;
+ uint warnings;
+};
+
+static void
+report_error(
+ struct sanity_check_ctx *ctx,
+ const char *format,
+ ... )
+{
+ va_list args;
+
+ debug_printf( "Error : " );
+ va_start( args, format );
+ _debug_vprintf( format, args );
+ va_end( args );
+ debug_printf( "\n" );
+ ctx->errors++;
+}
+
+static void
+report_warning(
+ struct sanity_check_ctx *ctx,
+ const char *format,
+ ... )
+{
+ va_list args;
+
+ debug_printf( "Warning: " );
+ va_start( args, format );
+ _debug_vprintf( format, args );
+ va_end( args );
+ debug_printf( "\n" );
+ ctx->warnings++;
+}
+
+static boolean
+check_file_name(
+ struct sanity_check_ctx *ctx,
+ uint file )
+{
+ if (file <= TGSI_FILE_NULL || file >= TGSI_FILE_COUNT) {
+ report_error( ctx, "Invalid register file name" );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static boolean
+is_register_declared(
+ struct sanity_check_ctx *ctx,
+ uint file,
+ int index )
+{
+ assert( index >= 0 && index < MAX_REGISTERS );
+
+ return (ctx->regs_decl[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE;
+}
+
+static boolean
+is_any_register_declared(
+ struct sanity_check_ctx *ctx,
+ uint file )
+{
+ uint i;
+
+ for (i = 0; i < MAX_REGISTERS / BITS_IN_REG_FLAG; i++)
+ if (ctx->regs_decl[file][i])
+ return TRUE;
+ return FALSE;
+}
+
+static boolean
+is_register_used(
+ struct sanity_check_ctx *ctx,
+ uint file,
+ int index )
+{
+ assert( index < MAX_REGISTERS );
+
+ return (ctx->regs_used[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE;
+}
+
+static const char *file_names[] =
+{
+ "NULL",
+ "CONST",
+ "IN",
+ "OUT",
+ "TEMP",
+ "SAMP",
+ "ADDR",
+ "IMM"
+};
+
+static boolean
+check_register_usage(
+ struct sanity_check_ctx *ctx,
+ uint file,
+ int index,
+ const char *name,
+ boolean indirect_access )
+{
+ if (!check_file_name( ctx, file ))
+ return FALSE;
+ if (indirect_access) {
+ if (!is_any_register_declared( ctx, file ))
+ report_error( ctx, "%s: Undeclared %s register", file_names[file], name );
+ ctx->regs_ind_used[file] = TRUE;
+ }
+ else {
+ if (!is_register_declared( ctx, file, index ))
+ report_error( ctx, "%s[%d]: Undeclared %s register", file_names[file], index, name );
+ ctx->regs_used[file][index / BITS_IN_REG_FLAG] |= (1 << (index % BITS_IN_REG_FLAG));
+ }
+ return TRUE;
+}
+
+static boolean
+iter_instruction(
+ struct tgsi_iterate_context *iter,
+ struct tgsi_full_instruction *inst )
+{
+ struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
+ uint i;
+
+ /* There must be no other instructions after END.
+ */
+ if (ctx->index_of_END != ~0) {
+ report_error( ctx, "Unexpected instruction after END" );
+ }
+ else if (inst->Instruction.Opcode == TGSI_OPCODE_END) {
+ ctx->index_of_END = ctx->num_instructions;
+ }
+
+ /* Check destination and source registers' validity.
+ * Mark the registers as used.
+ */
+ for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
+ check_register_usage(
+ ctx,
+ inst->FullDstRegisters[i].DstRegister.File,
+ inst->FullDstRegisters[i].DstRegister.Index,
+ "destination",
+ FALSE );
+ }
+ for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
+ check_register_usage(
+ ctx,
+ inst->FullSrcRegisters[i].SrcRegister.File,
+ inst->FullSrcRegisters[i].SrcRegister.Index,
+ "source",
+ inst->FullSrcRegisters[i].SrcRegister.Indirect );
+ if (inst->FullSrcRegisters[i].SrcRegister.Indirect) {
+ uint file;
+ int index;
+
+ file = inst->FullSrcRegisters[i].SrcRegisterInd.File;
+ index = inst->FullSrcRegisters[i].SrcRegisterInd.Index;
+ check_register_usage(
+ ctx,
+ file,
+ index,
+ "indirect",
+ FALSE );
+ if (file != TGSI_FILE_ADDRESS || index != 0)
+ report_warning( ctx, "Indirect register not ADDR[0]" );
+ }
+ }
+
+ ctx->num_instructions++;
+
+ return TRUE;
+}
+
+static boolean
+iter_declaration(
+ struct tgsi_iterate_context *iter,
+ struct tgsi_full_declaration *decl )
+{
+ struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
+ uint file;
+ uint i;
+
+ /* No declarations allowed after the first instruction.
+ */
+ if (ctx->num_instructions > 0)
+ report_error( ctx, "Instruction expected but declaration found" );
+
+ /* Check registers' validity.
+ * Mark the registers as declared.
+ */
+ file = decl->Declaration.File;
+ if (!check_file_name( ctx, file ))
+ return TRUE;
+ for (i = decl->DeclarationRange.First; i <= decl->DeclarationRange.Last; i++) {
+ if (is_register_declared( ctx, file, i ))
+ report_error( ctx, "The same register declared twice" );
+ ctx->regs_decl[file][i / BITS_IN_REG_FLAG] |= (1 << (i % BITS_IN_REG_FLAG));
+ }
+
+ return TRUE;
+}
+
+static boolean
+iter_immediate(
+ struct tgsi_iterate_context *iter,
+ struct tgsi_full_immediate *imm )
+{
+ struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
+
+ assert( ctx->num_imms < MAX_REGISTERS );
+
+ /* No immediates allowed after the first instruction.
+ */
+ if (ctx->num_instructions > 0)
+ report_error( ctx, "Instruction expected but immediate found" );
+
+ /* Mark the register as declared.
+ */
+ ctx->regs_decl[TGSI_FILE_IMMEDIATE][ctx->num_imms / BITS_IN_REG_FLAG] |= (1 << (ctx->num_imms % BITS_IN_REG_FLAG));
+ ctx->num_imms++;
+
+ /* Check data type validity.
+ */
+ if (imm->Immediate.DataType != TGSI_IMM_FLOAT32) {
+ report_error( ctx, "Invalid immediate data type" );
+ return TRUE;
+ }
+
+ return TRUE;
+}
+
+static boolean
+epilog(
+ struct tgsi_iterate_context *iter )
+{
+ struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
+ uint file;
+
+ /* There must be an END instruction at the end.
+ */
+ if (ctx->index_of_END == ~0 || ctx->index_of_END != ctx->num_instructions - 1) {
+ report_error( ctx, "Expected END at end of instruction sequence" );
+ }
+
+ /* Check if all declared registers were used.
+ */
+ for (file = TGSI_FILE_NULL; file < TGSI_FILE_COUNT; file++) {
+ uint i;
+
+ for (i = 0; i < MAX_REGISTERS; i++) {
+ if (is_register_declared( ctx, file, i ) && !is_register_used( ctx, file, i ) && !ctx->regs_ind_used[file]) {
+ report_warning( ctx, "Register never used" );
+ }
+ }
+ }
+
+ /* Print totals, if any.
+ */
+ if (ctx->errors || ctx->warnings)
+ debug_printf( "\n%u errors, %u warnings", ctx->errors, ctx->warnings );
+
+ return TRUE;
+}
+
+boolean
+tgsi_sanity_check(
+ struct tgsi_token *tokens )
+{
+ struct sanity_check_ctx ctx;
+
+ ctx.iter.prolog = NULL;
+ ctx.iter.iterate_instruction = iter_instruction;
+ ctx.iter.iterate_declaration = iter_declaration;
+ ctx.iter.iterate_immediate = iter_immediate;
+ ctx.iter.epilog = epilog;
+
+ memset( ctx.regs_decl, 0, sizeof( ctx.regs_decl ) );
+ memset( ctx.regs_used, 0, sizeof( ctx.regs_used ) );
+ memset( ctx.regs_ind_used, 0, sizeof( ctx.regs_ind_used ) );
+ ctx.num_imms = 0;
+ ctx.num_instructions = 0;
+ ctx.index_of_END = ~0;
+
+ ctx.errors = 0;
+ ctx.warnings = 0;
+
+ if (!tgsi_iterate_shader( tokens, &ctx.iter ))
+ return FALSE;
+
+ return ctx.errors == 0;
+}
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.h b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.h
new file mode 100644
index 0000000000..ca45e94c7a
--- /dev/null
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.h
@@ -0,0 +1,49 @@
+/**************************************************************************
+ *
+ * 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 TGSI_SANITY_H
+#define TGSI_SANITY_H
+
+#include "pipe/p_shader_tokens.h"
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/* Check the given token stream for errors and common mistakes.
+ * Diagnostic messages are printed out to the debug output.
+ * Returns TRUE if there are no errors, even though there could be some warnings.
+ */
+boolean
+tgsi_sanity_check(
+ struct tgsi_token *tokens );
+
+#if defined __cplusplus
+}
+#endif
+
+#endif /* TGSI_SANITY_H */
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.c b/src/gallium/auxiliary/tgsi/util/tgsi_text.c
index 1b283feb4c..35cb3055bb 100644
--- a/src/gallium/auxiliary/tgsi/util/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.c
@@ -29,6 +29,7 @@
#include "tgsi_text.h"
#include "tgsi_build.h"
#include "tgsi_parse.h"
+#include "tgsi_sanity.h"
#include "tgsi_util.h"
static boolean is_alpha_underscore( const char *cur )
@@ -225,24 +226,21 @@ static const char *file_names[TGSI_FILE_COUNT] =
};
static boolean
-parse_file(
- struct translate_ctx *ctx,
- uint *file )
+parse_file( const char **pcur, uint *file )
{
uint i;
for (i = 0; i < TGSI_FILE_COUNT; i++) {
- const char *cur = ctx->cur;
+ const char *cur = *pcur;
if (str_match_no_case( &cur, file_names[i] )) {
if (!is_digit_alpha_underscore( cur )) {
- ctx->cur = cur;
+ *pcur = cur;
*file = i;
return TRUE;
}
}
}
- report_error( ctx, "Unknown register file" );
return FALSE;
}
@@ -289,72 +287,153 @@ parse_opt_writemask(
return TRUE;
}
-/* Parse register part common for decls and operands.
- * <register_prefix> ::= <file> `[' <index>
+/* <register_file_bracket> ::= <file> `['
*/
static boolean
-parse_register_prefix(
+parse_register_file_bracket(
struct translate_ctx *ctx,
- uint *file,
- uint *index )
+ uint *file )
{
- if (!parse_file( ctx, file ))
+ if (!parse_file( &ctx->cur, file )) {
+ report_error( ctx, "Unknown register file" );
return FALSE;
+ }
eat_opt_white( &ctx->cur );
if (*ctx->cur != '[') {
report_error( ctx, "Expected `['" );
return FALSE;
}
ctx->cur++;
+ return TRUE;
+}
+
+/* <register_file_bracket_index> ::= <register_file_bracket> <uint>
+ */
+static boolean
+parse_register_file_bracket_index(
+ struct translate_ctx *ctx,
+ uint *file,
+ int *index )
+{
+ uint uindex;
+
+ if (!parse_register_file_bracket( ctx, file ))
+ return FALSE;
eat_opt_white( &ctx->cur );
- if (!parse_uint( &ctx->cur, index )) {
- report_error( ctx, "Expected literal integer" );
+ if (!parse_uint( &ctx->cur, &uindex )) {
+ report_error( ctx, "Expected literal unsigned integer" );
+ return FALSE;
+ }
+ *index = (int) uindex;
+ return TRUE;
+}
+
+/* Parse destination register operand.
+ * <register_dst> ::= <register_file_bracket_index> `]'
+ */
+static boolean
+parse_register_dst(
+ struct translate_ctx *ctx,
+ uint *file,
+ int *index )
+{
+ if (!parse_register_file_bracket_index( ctx, file, index ))
+ return FALSE;
+ eat_opt_white( &ctx->cur );
+ if (*ctx->cur != ']') {
+ report_error( ctx, "Expected `]'" );
return FALSE;
}
+ ctx->cur++;
return TRUE;
}
-/* Parse register operand.
- * <register> ::= <register_prefix> `]'
+/* Parse source register operand.
+ * <register_src> ::= <register_file_bracket_index> `]' |
+ * <register_file_bracket> <register_dst> `]' |
+ * <register_file_bracket> <register_dst> `+' <uint> `]' |
+ * <register_file_bracket> <register_dst> `-' <uint> `]'
*/
static boolean
-parse_register(
+parse_register_src(
struct translate_ctx *ctx,
uint *file,
- uint *index )
+ int *index,
+ uint *ind_file,
+ int *ind_index )
{
- if (!parse_register_prefix( ctx, file, index ))
+ const char *cur;
+ uint uindex;
+
+ if (!parse_register_file_bracket( ctx, file ))
return FALSE;
eat_opt_white( &ctx->cur );
+ cur = ctx->cur;
+ if (parse_file( &cur, ind_file )) {
+ if (!parse_register_dst( ctx, ind_file, ind_index ))
+ return FALSE;
+ eat_opt_white( &ctx->cur );
+ if (*ctx->cur == '+' || *ctx->cur == '-') {
+ boolean negate;
+
+ negate = *ctx->cur == '-';
+ ctx->cur++;
+ eat_opt_white( &ctx->cur );
+ if (!parse_uint( &ctx->cur, &uindex )) {
+ report_error( ctx, "Expected literal unsigned integer" );
+ return FALSE;
+ }
+ if (negate)
+ *index = -(int) uindex;
+ else
+ *index = (int) uindex;
+ }
+ else {
+ *index = 0;
+ }
+ }
+ else {
+ if (!parse_uint( &ctx->cur, &uindex )) {
+ report_error( ctx, "Expected literal unsigned integer" );
+ return FALSE;
+ }
+ *index = (int) uindex;
+ *ind_file = TGSI_FILE_NULL;
+ *ind_index = 0;
+ }
+ eat_opt_white( &ctx->cur );
if (*ctx->cur != ']') {
report_error( ctx, "Expected `]'" );
return FALSE;
}
ctx->cur++;
- /* TODO: Modulate suffix */
return TRUE;
}
/* Parse register declaration.
- * <register> ::= <register_prefix> `]' | <register_prefix> `..' <index> `]'
+ * <register_dcl> ::= <register_file_bracket_index> `]' |
+ * <register_file_bracket_index> `..' <index> `]'
*/
static boolean
parse_register_dcl(
struct translate_ctx *ctx,
uint *file,
- uint *first,
- uint *last )
+ int *first,
+ int *last )
{
- if (!parse_register_prefix( ctx, file, first ))
+ if (!parse_register_file_bracket_index( ctx, file, first ))
return FALSE;
eat_opt_white( &ctx->cur );
if (ctx->cur[0] == '.' && ctx->cur[1] == '.') {
+ uint uindex;
+
ctx->cur += 2;
eat_opt_white( &ctx->cur );
- if (!parse_uint( &ctx->cur, last )) {
+ if (!parse_uint( &ctx->cur, &uindex )) {
report_error( ctx, "Expected literal integer" );
return FALSE;
}
+ *last = (int) uindex;
eat_opt_white( &ctx->cur );
}
else {
@@ -385,11 +464,11 @@ parse_dst_operand(
struct tgsi_full_dst_register *dst )
{
uint file;
- uint index;
+ int index;
uint writemask;
const char *cur;
- if (!parse_register( ctx, &file, &index ))
+ if (!parse_register_dst( ctx, &file, &index ))
return FALSE;
cur = ctx->cur;
@@ -418,6 +497,52 @@ parse_dst_operand(
}
static boolean
+parse_optional_swizzle(
+ struct translate_ctx *ctx,
+ uint swizzle[4],
+ boolean *parsed_swizzle,
+ boolean *parsed_extswizzle )
+{
+ const char *cur = ctx->cur;
+
+ *parsed_swizzle = FALSE;
+ *parsed_extswizzle = FALSE;
+
+ eat_opt_white( &cur );
+ if (*cur == '.') {
+ uint i;
+
+ cur++;
+ eat_opt_white( &cur );
+ for (i = 0; i < 4; i++) {
+ if (toupper( *cur ) == 'X')
+ swizzle[i] = TGSI_SWIZZLE_X;
+ else if (toupper( *cur ) == 'Y')
+ swizzle[i] = TGSI_SWIZZLE_Y;
+ else if (toupper( *cur ) == 'Z')
+ swizzle[i] = TGSI_SWIZZLE_Z;
+ else if (toupper( *cur ) == 'W')
+ swizzle[i] = TGSI_SWIZZLE_W;
+ else {
+ if (*cur == '0')
+ swizzle[i] = TGSI_EXTSWIZZLE_ZERO;
+ else if (*cur == '1')
+ swizzle[i] = TGSI_EXTSWIZZLE_ONE;
+ else {
+ report_error( ctx, "Expected register swizzle component `x', `y', `z', `w', `0' or `1'" );
+ return FALSE;
+ }
+ *parsed_extswizzle = TRUE;
+ }
+ cur++;
+ }
+ *parsed_swizzle = TRUE;
+ ctx->cur = cur;
+ }
+ return TRUE;
+}
+
+static boolean
parse_src_operand(
struct translate_ctx *ctx,
struct tgsi_full_src_register *src )
@@ -425,7 +550,12 @@ parse_src_operand(
const char *cur;
float value;
uint file;
- uint index;
+ int index;
+ uint ind_file;
+ int ind_index;
+ uint swizzle[4];
+ boolean parsed_swizzle;
+ boolean parsed_extswizzle;
if (*ctx->cur == '-') {
cur = ctx->cur;
@@ -497,40 +627,33 @@ parse_src_operand(
}
}
- if (!parse_register( ctx, &file, &index ))
+ if (!parse_register_src( ctx, &file, &index, &ind_file, &ind_index ))
return FALSE;
src->SrcRegister.File = file;
src->SrcRegister.Index = index;
+ if (ind_file != TGSI_FILE_NULL) {
+ src->SrcRegister.Indirect = 1;
+ src->SrcRegisterInd.File = ind_file;
+ src->SrcRegisterInd.Index = ind_index;
+ }
- /* Parse optional swizzle
+ /* Parse optional swizzle.
*/
- cur = ctx->cur;
- eat_opt_white( &cur );
- if (*cur == '.') {
- uint i;
-
- cur++;
- eat_opt_white( &cur );
- for (i = 0; i < 4; i++) {
- uint swizzle;
-
- if (toupper( *cur ) == 'X')
- swizzle = TGSI_SWIZZLE_X;
- else if (toupper( *cur ) == 'Y')
- swizzle = TGSI_SWIZZLE_Y;
- else if (toupper( *cur ) == 'Z')
- swizzle = TGSI_SWIZZLE_Z;
- else if (toupper( *cur ) == 'W')
- swizzle = TGSI_SWIZZLE_W;
- else {
- report_error( ctx, "Expected register swizzle component either `x', `y', `z' or `w'" );
- return FALSE;
- }
- cur++;
- tgsi_util_set_src_register_swizzle( &src->SrcRegister, swizzle, i );
+ if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle, &parsed_extswizzle )) {
+ if (parsed_extswizzle) {
+ assert( parsed_swizzle );
+
+ src->SrcRegisterExtSwz.ExtSwizzleX = swizzle[0];
+ src->SrcRegisterExtSwz.ExtSwizzleY = swizzle[1];
+ src->SrcRegisterExtSwz.ExtSwizzleZ = swizzle[2];
+ src->SrcRegisterExtSwz.ExtSwizzleW = swizzle[3];
+ }
+ else if (parsed_swizzle) {
+ src->SrcRegister.SwizzleX = swizzle[0];
+ src->SrcRegister.SwizzleY = swizzle[1];
+ src->SrcRegister.SwizzleZ = swizzle[2];
+ src->SrcRegister.SwizzleW = swizzle[3];
}
-
- ctx->cur = cur;
}
if (src->SrcRegisterExtMod.Complement) {
@@ -601,130 +724,131 @@ struct opcode_info
uint num_dst;
uint num_src;
uint is_tex;
+ uint is_branch;
const char *mnemonic;
};
static const struct opcode_info opcode_info[TGSI_OPCODE_LAST] =
{
- { 1, 1, 0, "ARL" },
- { 1, 1, 0, "MOV" },
- { 1, 1, 0, "LIT" },
- { 1, 1, 0, "RCP" },
- { 1, 1, 0, "RSQ" },
- { 1, 1, 0, "EXP" },
- { 1, 1, 0, "LOG" },
- { 1, 2, 0, "MUL" },
- { 1, 2, 0, "ADD" },
- { 1, 2, 0, "DP3" },
- { 1, 2, 0, "DP4" },
- { 1, 2, 0, "DST" },
- { 1, 2, 0, "MIN" },
- { 1, 2, 0, "MAX" },
- { 1, 2, 0, "SLT" },
- { 1, 2, 0, "SGE" },
- { 1, 3, 0, "MAD" },
- { 1, 2, 0, "SUB" },
- { 1, 3, 0, "LERP" },
- { 1, 3, 0, "CND" },
- { 1, 3, 0, "CND0" },
- { 1, 3, 0, "DOT2ADD" },
- { 1, 2, 0, "INDEX" },
- { 1, 1, 0, "NEGATE" },
- { 1, 1, 0, "FRAC" },
- { 1, 3, 0, "CLAMP" },
- { 1, 1, 0, "FLOOR" },
- { 1, 1, 0, "ROUND" },
- { 1, 1, 0, "EXPBASE2" },
- { 1, 1, 0, "LOGBASE2" },
- { 1, 2, 0, "POWER" },
- { 1, 2, 0, "CROSSPRODUCT" },
- { 1, 2, 0, "MULTIPLYMATRIX" },
- { 1, 1, 0, "ABS" },
- { 1, 1, 0, "RCC" },
- { 1, 2, 0, "DPH" },
- { 1, 1, 0, "COS" },
- { 1, 1, 0, "DDX" },
- { 1, 1, 0, "DDY" },
- { 0, 1, 0, "KILP" },
- { 1, 1, 0, "PK2H" },
- { 1, 1, 0, "PK2US" },
- { 1, 1, 0, "PK4B" },
- { 1, 1, 0, "PK4UB" },
- { 1, 2, 0, "RFL" },
- { 1, 2, 0, "SEQ" },
- { 1, 2, 0, "SFL" },
- { 1, 2, 0, "SGT" },
- { 1, 1, 0, "SIN" },
- { 1, 2, 0, "SLE" },
- { 1, 2, 0, "SNE" },
- { 1, 2, 0, "STR" },
- { 1, 2, 1, "TEX" },
- { 1, 4, 1, "TXD" },
- { 1, 2, 1, "TXP" },
- { 1, 1, 0, "UP2H" },
- { 1, 1, 0, "UP2US" },
- { 1, 1, 0, "UP4B" },
- { 1, 1, 0, "UP4UB" },
- { 1, 3, 0, "X2D" },
- { 1, 1, 0, "ARA" },
- { 1, 1, 0, "ARR" },
- { 0, 1, 0, "BRA" },
- { 0, 0, 0, "CAL" },
- { 0, 0, 0, "RET" },
- { 1, 1, 0, "SSG" },
- { 1, 3, 0, "CMP" },
- { 1, 1, 0, "SCS" },
- { 1, 2, 1, "TXB" },
- { 1, 1, 0, "NRM" },
- { 1, 2, 0, "DIV" },
- { 1, 2, 0, "DP2" },
- { 1, 2, 1, "TXL" },
- { 0, 0, 0, "BRK" },
- { 0, 1, 0, "IF" },
- { 0, 0, 0, "LOOP" },
- { 0, 1, 0, "REP" },
- { 0, 0, 0, "ELSE" },
- { 0, 0, 0, "ENDIF" },
- { 0, 0, 0, "ENDLOOP" },
- { 0, 0, 0, "ENDREP" },
- { 0, 1, 0, "PUSHA" },
- { 1, 0, 0, "POPA" },
- { 1, 1, 0, "CEIL" },
- { 1, 1, 0, "I2F" },
- { 1, 1, 0, "NOT" },
- { 1, 1, 0, "TRUNC" },
- { 1, 2, 0, "SHL" },
- { 1, 2, 0, "SHR" },
- { 1, 2, 0, "AND" },
- { 1, 2, 0, "OR" },
- { 1, 2, 0, "MOD" },
- { 1, 2, 0, "XOR" },
- { 1, 3, 0, "SAD" },
- { 1, 2, 1, "TXF" },
- { 1, 2, 1, "TXQ" },
- { 0, 0, 0, "CONT" },
- { 0, 0, 0, "EMIT" },
- { 0, 0, 0, "ENDPRIM" },
- { 0, 0, 0, "BGNLOOP2" },
- { 0, 0, 0, "BGNSUB" },
- { 0, 0, 0, "ENDLOOP2" },
- { 0, 0, 0, "ENDSUB" },
- { 1, 1, 0, "NOISE1" },
- { 1, 1, 0, "NOISE2" },
- { 1, 1, 0, "NOISE3" },
- { 1, 1, 0, "NOISE4" },
- { 0, 0, 0, "NOP" },
- { 1, 2, 0, "M4X3" },
- { 1, 2, 0, "M3X4" },
- { 1, 2, 0, "M3X3" },
- { 1, 2, 0, "M3X2" },
- { 1, 1, 0, "NRM4" },
- { 0, 1, 0, "CALLNZ" },
- { 0, 1, 0, "IFC" },
- { 0, 1, 0, "BREAKC" },
- { 0, 0, 0, "KIL" },
- { 0, 0, 0, "END" },
- { 1, 1, 0, "SWZ" }
+ { 1, 1, 0, 0, "ARL" },
+ { 1, 1, 0, 0, "MOV" },
+ { 1, 1, 0, 0, "LIT" },
+ { 1, 1, 0, 0, "RCP" },
+ { 1, 1, 0, 0, "RSQ" },
+ { 1, 1, 0, 0, "EXP" },
+ { 1, 1, 0, 0, "LOG" },
+ { 1, 2, 0, 0, "MUL" },
+ { 1, 2, 0, 0, "ADD" },
+ { 1, 2, 0, 0, "DP3" },
+ { 1, 2, 0, 0, "DP4" },
+ { 1, 2, 0, 0, "DST" },
+ { 1, 2, 0, 0, "MIN" },
+ { 1, 2, 0, 0, "MAX" },
+ { 1, 2, 0, 0, "SLT" },
+ { 1, 2, 0, 0, "SGE" },
+ { 1, 3, 0, 0, "MAD" },
+ { 1, 2, 0, 0, "SUB" },
+ { 1, 3, 0, 0, "LERP" },
+ { 1, 3, 0, 0, "CND" },
+ { 1, 3, 0, 0, "CND0" },
+ { 1, 3, 0, 0, "DOT2ADD" },
+ { 1, 2, 0, 0, "INDEX" },
+ { 1, 1, 0, 0, "NEGATE" },
+ { 1, 1, 0, 0, "FRAC" },
+ { 1, 3, 0, 0, "CLAMP" },
+ { 1, 1, 0, 0, "FLOOR" },
+ { 1, 1, 0, 0, "ROUND" },
+ { 1, 1, 0, 0, "EXPBASE2" },
+ { 1, 1, 0, 0, "LOGBASE2" },
+ { 1, 2, 0, 0, "POWER" },
+ { 1, 2, 0, 0, "CROSSPRODUCT" },
+ { 1, 2, 0, 0, "MULTIPLYMATRIX" },
+ { 1, 1, 0, 0, "ABS" },
+ { 1, 1, 0, 0, "RCC" },
+ { 1, 2, 0, 0, "DPH" },
+ { 1, 1, 0, 0, "COS" },
+ { 1, 1, 0, 0, "DDX" },
+ { 1, 1, 0, 0, "DDY" },
+ { 0, 1, 0, 0, "KILP" },
+ { 1, 1, 0, 0, "PK2H" },
+ { 1, 1, 0, 0, "PK2US" },
+ { 1, 1, 0, 0, "PK4B" },
+ { 1, 1, 0, 0, "PK4UB" },
+ { 1, 2, 0, 0, "RFL" },
+ { 1, 2, 0, 0, "SEQ" },
+ { 1, 2, 0, 0, "SFL" },
+ { 1, 2, 0, 0, "SGT" },
+ { 1, 1, 0, 0, "SIN" },
+ { 1, 2, 0, 0, "SLE" },
+ { 1, 2, 0, 0, "SNE" },
+ { 1, 2, 0, 0, "STR" },
+ { 1, 2, 1, 0, "TEX" },
+ { 1, 4, 1, 0, "TXD" },
+ { 1, 2, 1, 0, "TXP" },
+ { 1, 1, 0, 0, "UP2H" },
+ { 1, 1, 0, 0, "UP2US" },
+ { 1, 1, 0, 0, "UP4B" },
+ { 1, 1, 0, 0, "UP4UB" },
+ { 1, 3, 0, 0, "X2D" },
+ { 1, 1, 0, 0, "ARA" },
+ { 1, 1, 0, 0, "ARR" },
+ { 0, 1, 0, 0, "BRA" },
+ { 0, 0, 0, 1, "CAL" },
+ { 0, 0, 0, 0, "RET" },
+ { 1, 1, 0, 0, "SSG" },
+ { 1, 3, 0, 0, "CMP" },
+ { 1, 1, 0, 0, "SCS" },
+ { 1, 2, 1, 0, "TXB" },
+ { 1, 1, 0, 0, "NRM" },
+ { 1, 2, 0, 0, "DIV" },
+ { 1, 2, 0, 0, "DP2" },
+ { 1, 2, 1, 0, "TXL" },
+ { 0, 0, 0, 0, "BRK" },
+ { 0, 1, 0, 1, "IF" },
+ { 0, 0, 0, 0, "LOOP" },
+ { 0, 1, 0, 0, "REP" },
+ { 0, 0, 0, 1, "ELSE" },
+ { 0, 0, 0, 0, "ENDIF" },
+ { 0, 0, 0, 0, "ENDLOOP" },
+ { 0, 0, 0, 0, "ENDREP" },
+ { 0, 1, 0, 0, "PUSHA" },
+ { 1, 0, 0, 0, "POPA" },
+ { 1, 1, 0, 0, "CEIL" },
+ { 1, 1, 0, 0, "I2F" },
+ { 1, 1, 0, 0, "NOT" },
+ { 1, 1, 0, 0, "TRUNC" },
+ { 1, 2, 0, 0, "SHL" },
+ { 1, 2, 0, 0, "SHR" },
+ { 1, 2, 0, 0, "AND" },
+ { 1, 2, 0, 0, "OR" },
+ { 1, 2, 0, 0, "MOD" },
+ { 1, 2, 0, 0, "XOR" },
+ { 1, 3, 0, 0, "SAD" },
+ { 1, 2, 1, 0, "TXF" },
+ { 1, 2, 1, 0, "TXQ" },
+ { 0, 0, 0, 0, "CONT" },
+ { 0, 0, 0, 0, "EMIT" },
+ { 0, 0, 0, 0, "ENDPRIM" },
+ { 0, 0, 0, 1, "BGNLOOP2" },
+ { 0, 0, 0, 0, "BGNSUB" },
+ { 0, 0, 0, 1, "ENDLOOP2" },
+ { 0, 0, 0, 0, "ENDSUB" },
+ { 1, 1, 0, 0, "NOISE1" },
+ { 1, 1, 0, 0, "NOISE2" },
+ { 1, 1, 0, 0, "NOISE3" },
+ { 1, 1, 0, 0, "NOISE4" },
+ { 0, 0, 0, 0, "NOP" },
+ { 1, 2, 0, 0, "M4X3" },
+ { 1, 2, 0, 0, "M3X4" },
+ { 1, 2, 0, 0, "M3X3" },
+ { 1, 2, 0, 0, "M3X2" },
+ { 1, 1, 0, 0, "NRM4" },
+ { 0, 1, 0, 0, "CALLNZ" },
+ { 0, 1, 0, 0, "IFC" },
+ { 0, 1, 0, 0, "BREAKC" },
+ { 0, 0, 0, 0, "KIL" },
+ { 0, 0, 0, 0, "END" },
+ { 1, 1, 0, 0, "SWZ" }
};
static const char *texture_names[TGSI_TEXTURE_COUNT] =
@@ -740,7 +864,10 @@ static const char *texture_names[TGSI_TEXTURE_COUNT] =
"SHADOWRECT"
};
-static boolean parse_instruction( struct translate_ctx *ctx )
+static boolean
+parse_instruction(
+ struct translate_ctx *ctx,
+ boolean has_label )
{
uint i;
uint saturate = TGSI_SAT_NONE;
@@ -754,23 +881,32 @@ static boolean parse_instruction( struct translate_ctx *ctx )
for (i = 0; i < TGSI_OPCODE_LAST; i++) {
const char *cur = ctx->cur;
- if (str_match_no_case( &cur, opcode_info[i].mnemonic )) {
+ info = &opcode_info[i];
+ if (str_match_no_case( &cur, info->mnemonic )) {
if (str_match_no_case( &cur, "_SATNV" ))
saturate = TGSI_SAT_MINUS_PLUS_ONE;
else if (str_match_no_case( &cur, "_SAT" ))
saturate = TGSI_SAT_ZERO_ONE;
- if (*cur == '\0' || eat_white( &cur )) {
+ if (info->num_dst + info->num_src + info->is_tex == 0) {
+ if (!is_digit_alpha_underscore( cur )) {
+ ctx->cur = cur;
+ break;
+ }
+ }
+ else if (*cur == '\0' || eat_white( &cur )) {
ctx->cur = cur;
break;
}
}
}
if (i == TGSI_OPCODE_LAST) {
- report_error( ctx, "Unknown opcode" );
+ if (has_label)
+ report_error( ctx, "Unknown opcode" );
+ else
+ report_error( ctx, "Expected `DCL', `IMM' or a label" );
return FALSE;
}
- info = &opcode_info[i];
inst = tgsi_default_full_instruction();
inst.Instruction.Opcode = i;
@@ -817,6 +953,23 @@ static boolean parse_instruction( struct translate_ctx *ctx )
}
}
+ if (info->is_branch) {
+ uint target;
+
+ eat_opt_white( &ctx->cur );
+ if (*ctx->cur != ':') {
+ report_error( ctx, "Expected `:'" );
+ return FALSE;
+ }
+ ctx->cur++;
+ eat_opt_white( &ctx->cur );
+ if (!parse_uint( &ctx->cur, &target )) {
+ report_error( ctx, "Expected a label" );
+ return FALSE;
+ }
+ inst.InstructionExtLabel.Label = target;
+ }
+
advance = tgsi_build_full_instruction(
&inst,
ctx->tokens_cur,
@@ -851,8 +1004,8 @@ static boolean parse_declaration( struct translate_ctx *ctx )
{
struct tgsi_full_declaration decl;
uint file;
- uint first;
- uint last;
+ int first;
+ int last;
uint writemask;
const char *cur;
uint advance;
@@ -1024,8 +1177,11 @@ static boolean translate( struct translate_ctx *ctx )
return FALSE;
}
+ if (*ctx->cur == '\0')
+ break;
+
if (parse_label( ctx, &label_val )) {
- if (!parse_instruction( ctx ))
+ if (!parse_instruction( ctx, TRUE ))
return FALSE;
}
else if (str_match_no_case( &ctx->cur, "DCL" )) {
@@ -1036,8 +1192,7 @@ static boolean translate( struct translate_ctx *ctx )
if (!parse_immediate( ctx ))
return FALSE;
}
- else {
- report_error( ctx, "Expected `DCL', `IMM' or a label" );
+ else if (!parse_instruction( ctx, FALSE )) {
return FALSE;
}
}
@@ -1059,5 +1214,8 @@ tgsi_text_translate(
ctx.tokens_cur = tokens;
ctx.tokens_end = tokens + num_tokens;
- return translate( &ctx );
+ if (!translate( &ctx ))
+ return FALSE;
+
+ return tgsi_sanity_check( tokens );
}
diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c
index 7b28900a25..b0240ad737 100644
--- a/src/gallium/auxiliary/util/p_debug.c
+++ b/src/gallium/auxiliary/util/p_debug.c
@@ -174,20 +174,19 @@ copy(char *dst, const char *start, const char *end, size_t n)
#endif
-const char *
-debug_get_option(const char *name, const char *dfault)
+static INLINE const char *
+_debug_get_option(const char *name)
{
- const char *result;
#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
/* EngMapFile creates the file if it does not exists, so it must either be
* disabled on release versions (or put in a less conspicuous place). */
#ifdef DEBUG
+ const char *result = NULL;
ULONG_PTR iFile = 0;
const void *pMap = NULL;
const char *sol, *eol, *sep;
static char output[1024];
- result = dfault;
pMap = EngMapFile(L"\\??\\c:\\gallium.cfg", 0, &iFile);
if(pMap) {
sol = (const char *)pMap;
@@ -208,18 +207,27 @@ debug_get_option(const char *name, const char *dfault)
}
EngUnmapFile(iFile);
}
+ return result;
#else
- result = dfault;
+ return NULL;
#endif
#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE)
/* TODO: implement */
- result = dfault;
+ return NULL;
#else
- result = getenv(name);
- if(!result)
- result = dfault;
+ return getenv(name);
#endif
+}
+const char *
+debug_get_option(const char *name, const char *dfault)
+{
+ const char *result;
+
+ result = _debug_get_option(name);
+ if(!result)
+ result = dfault;
+
debug_printf("%s: %s = %s\n", __FUNCTION__, name, result ? result : "(null)");
return result;
@@ -228,7 +236,7 @@ debug_get_option(const char *name, const char *dfault)
boolean
debug_get_bool_option(const char *name, boolean dfault)
{
- const char *str = debug_get_option(name, NULL);
+ const char *str = _debug_get_option(name);
boolean result;
if(str == NULL)
@@ -258,7 +266,7 @@ debug_get_num_option(const char *name, long dfault)
long result;
const char *str;
- str = debug_get_option(name, NULL);
+ str = _debug_get_option(name);
if(!str)
result = dfault;
else {
@@ -294,7 +302,7 @@ debug_get_flags_option(const char *name,
unsigned long result;
const char *str;
- str = debug_get_option(name, NULL);
+ str = _debug_get_option(name);
if(!str)
result = dfault;
else {
diff --git a/src/gallium/auxiliary/util/p_debug_prof.c b/src/gallium/auxiliary/util/p_debug_prof.c
index 958f99c327..5f9772ef91 100644
--- a/src/gallium/auxiliary/util/p_debug_prof.c
+++ b/src/gallium/auxiliary/util/p_debug_prof.c
@@ -46,15 +46,86 @@
#include "util/u_string.h"
-#define PROFILE_FILE_SIZE 4*1024*1024
+#define PROFILE_TABLE_SIZE (1024*1024)
#define FILE_NAME_SIZE 256
-static WCHAR wFileName[FILE_NAME_SIZE];
+struct debug_profile_entry
+{
+ uintptr_t caller;
+ uintptr_t callee;
+ uint64_t samples;
+};
+
+static unsigned long enabled = 0;
+
+static WCHAR wFileName[FILE_NAME_SIZE] = L"\\??\\c:\\00000000.prof";
static ULONG_PTR iFile = 0;
-static void *pMap = NULL;
-static void *pMapEnd = NULL;
+
+static struct debug_profile_entry *table = NULL;
+static unsigned long free_table_entries = 0;
+static unsigned long max_table_entries = 0;
+
+uint64_t start_stamp = 0;
+uint64_t end_stamp = 0;
+
+
+static void
+debug_profile_entry(uintptr_t caller, uintptr_t callee, uint64_t samples)
+{
+ unsigned hash = ( caller + callee ) & PROFILE_TABLE_SIZE - 1;
+
+ while(1) {
+ if(table[hash].caller == 0 && table[hash].callee == 0) {
+ table[hash].caller = caller;
+ table[hash].callee = callee;
+ table[hash].samples = samples;
+ --free_table_entries;
+ break;
+ }
+ else if(table[hash].caller == caller && table[hash].callee == callee) {
+ table[hash].samples += samples;
+ break;
+ }
+ else {
+ ++hash;
+ }
+ }
+}
+
+
+static uintptr_t caller_stack[1024];
+static unsigned last_caller = 0;
+
+
+static int64_t delta(void) {
+ int64_t result = end_stamp - start_stamp;
+ if(result > UINT64_C(0xffffffff))
+ result = 0;
+ return result;
+}
+
+
+static void __cdecl
+debug_profile_enter(uintptr_t callee)
+{
+ uintptr_t caller = last_caller ? caller_stack[last_caller - 1] : 0;
+
+ if (caller)
+ debug_profile_entry(caller, 0, delta());
+ debug_profile_entry(caller, callee, 1);
+ caller_stack[last_caller++] = callee;
+}
+static void __cdecl
+debug_profile_exit(uintptr_t callee)
+{
+ debug_profile_entry(callee, 0, delta());
+ if(last_caller)
+ --last_caller;
+}
+
+
/**
* Called at the start of every method or function.
*
@@ -63,27 +134,49 @@ static void *pMapEnd = NULL;
void __declspec(naked) __cdecl
_penter(void) {
_asm {
- push ebx
- mov ebx, [pMap]
- test ebx, ebx
- jz done
- cmp ebx, [pMapEnd]
- je done
push eax
+ mov eax, [enabled]
+ test eax, eax
+ jz skip
+
push edx
- mov eax, [esp+12]
- and eax, 0xfffffffe
- mov [ebx], eax
- add ebx, 4
+
rdtsc
- mov [ebx], eax
- add ebx, 4
- mov [pMap], ebx
+ mov dword ptr [end_stamp], eax
+ mov dword ptr [end_stamp+4], edx
+
+ xor eax, eax
+ mov [enabled], eax
+
+ mov eax, [esp+8]
+
+ push ebx
+ push ecx
+ push ebp
+ push edi
+ push esi
+
+ push eax
+ call debug_profile_enter
+ add esp, 4
+
+ pop esi
+ pop edi
+ pop ebp
+ pop ecx
+ pop ebx
+
+ mov eax, 1
+ mov [enabled], eax
+
+ rdtsc
+ mov dword ptr [start_stamp], eax
+ mov dword ptr [start_stamp+4], edx
+
pop edx
+skip:
pop eax
-done:
- pop ebx
- ret
+ ret
}
}
@@ -96,46 +189,60 @@ done:
void __declspec(naked) __cdecl
_pexit(void) {
_asm {
- push ebx
- mov ebx, [pMap]
- test ebx, ebx
- jz done
- cmp ebx, [pMapEnd]
- je done
push eax
+ mov eax, [enabled]
+ test eax, eax
+ jz skip
+
push edx
- mov eax, [esp+12]
- or eax, 0x00000001
- mov [ebx], eax
- add ebx, 4
+
rdtsc
- mov [ebx], eax
- add ebx, 4
- mov [pMap], ebx
- pop edx
- pop eax
-done:
+ mov dword ptr [end_stamp], eax
+ mov dword ptr [end_stamp+4], edx
+
+ xor eax, eax
+ mov [enabled], eax
+
+ mov eax, [esp+8]
+
+ push ebx
+ push ecx
+ push ebp
+ push edi
+ push esi
+
+ push eax
+ call debug_profile_exit
+ add esp, 4
+
+ pop esi
+ pop edi
+ pop ebp
+ pop ecx
pop ebx
- ret
- }
-}
+ mov eax, 1
+ mov [enabled], eax
-void __declspec(naked)
-__debug_profile_reference1(void) {
- _asm {
- call _penter
- call _pexit
+ rdtsc
+ mov dword ptr [start_stamp], eax
+ mov dword ptr [start_stamp+4], edx
+
+ pop edx
+skip:
+ pop eax
ret
}
}
+/**
+ * Reference function for calibration.
+ */
void __declspec(naked)
-__debug_profile_reference2(void) {
+__debug_profile_reference(void) {
_asm {
call _penter
- call __debug_profile_reference1
call _pexit
ret
}
@@ -145,31 +252,69 @@ __debug_profile_reference2(void) {
void
debug_profile_start(void)
{
- static unsigned no = 0;
- char filename[FILE_NAME_SIZE];
- unsigned i;
+ WCHAR *p;
- util_snprintf(filename, sizeof(filename), "\\??\\c:\\%03u.prof", ++no);
- for(i = 0; i < FILE_NAME_SIZE; ++i)
- wFileName[i] = (WCHAR)filename[i];
-
- pMap = EngMapFile(wFileName, PROFILE_FILE_SIZE, &iFile);
- if(pMap) {
- pMapEnd = (unsigned char*)pMap + PROFILE_FILE_SIZE;
- /* reference functions for calibration purposes */
- __debug_profile_reference2();
+ // increment starting from the less significant digit
+ p = &wFileName[14];
+ while(1) {
+ if(*p == '9') {
+ *p-- = '0';
+ }
+ else {
+ *p += 1;
+ break;
+ }
+ }
+
+ table = EngMapFile(wFileName,
+ PROFILE_TABLE_SIZE*sizeof(struct debug_profile_entry),
+ &iFile);
+ if(table) {
+ unsigned i;
+
+ free_table_entries = max_table_entries = PROFILE_TABLE_SIZE;
+ memset(table, 0, PROFILE_TABLE_SIZE*sizeof(struct debug_profile_entry));
+
+ table[0].caller = (uintptr_t)&__debug_profile_reference;
+ table[0].callee = 0;
+ table[0].samples = 0;
+ --free_table_entries;
+
+ _asm {
+ push edx
+ push eax
+
+ rdtsc
+ mov dword ptr [start_stamp], eax
+ mov dword ptr [start_stamp+4], edx
+
+ pop edx
+ pop eax
+ }
+
+ last_caller = 0;
+
+ enabled = 1;
+
+ for(i = 0; i < 8; ++i) {
+ _asm {
+ call __debug_profile_reference
+ }
+ }
}
}
+
void
debug_profile_stop(void)
{
- if(iFile) {
+ enabled = 0;
+
+ if(iFile)
EngUnmapFile(iFile);
- /* TODO: truncate file */
- }
iFile = 0;
- pMapEnd = pMap = NULL;
+ table = NULL;
+ free_table_entries = max_table_entries = 0;
}
#endif /* PROFILE */
diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c
index 1a1a2d96cc..1bf0d72733 100644
--- a/src/gallium/auxiliary/util/p_tile.c
+++ b/src/gallium/auxiliary/util/p_tile.c
@@ -346,7 +346,7 @@ r5g6b5_get_tile_rgba(ushort *src,
static void
-r5g5b5_put_tile_rgba(ushort *dst,
+r5g6b5_put_tile_rgba(ushort *dst,
unsigned w, unsigned h,
const float *p,
unsigned src_stride)
@@ -632,13 +632,10 @@ ycbcr_get_tile_rgba(ushort *src,
const float scale = 1.0f / 255.0f;
unsigned i, j;
- /* we're assuming we're being asked for an even number of texels */
- assert((w & 1) == 0);
-
for (i = 0; i < h; i++) {
float *pRow = p;
/* do two texels at a time */
- for (j = 0; j < w; j += 2, src += 2) {
+ for (j = 0; j < (w & ~1); j += 2, src += 2) {
const ushort t0 = src[0];
const ushort t1 = src[1];
const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */
@@ -676,87 +673,125 @@ ycbcr_get_tile_rgba(ushort *src,
pRow += 4;
}
+ /* do the last texel */
+ if (w & 1) {
+ const ushort t0 = src[0];
+ const ushort t1 = src[1];
+ const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */
+ ubyte cb, cr;
+ float r, g, b;
+
+ if (rev) {
+ cb = t1 & 0xff; /* chroma U */
+ cr = t0 & 0xff; /* chroma V */
+ }
+ else {
+ cb = t0 & 0xff; /* chroma U */
+ cr = t1 & 0xff; /* chroma V */
+ }
+
+ /* even pixel: y0,cr,cb */
+ r = 1.164f * (y0-16) + 1.596f * (cr-128);
+ g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
+ b = 1.164f * (y0-16) + 2.018f * (cb-128);
+ pRow[0] = r * scale;
+ pRow[1] = g * scale;
+ pRow[2] = b * scale;
+ pRow[3] = 1.0f;
+ pRow += 4;
+ }
p += dst_stride;
}
}
void
-pipe_get_tile_rgba(struct pipe_surface *ps,
- uint x, uint y, uint w, uint h,
- float *p)
+pipe_tile_raw_to_rgba(enum pipe_format format,
+ void *src,
+ uint w, uint h,
+ float *dst, unsigned dst_stride)
{
- unsigned dst_stride = w * 4;
- void *packed;
-
- if (pipe_clip_tile(x, y, &w, &h, ps))
- return;
-
- packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size);
-
- if (!packed)
- return;
-
- pipe_get_tile_raw(ps, x, y, w, h, packed, 0);
-
- switch (ps->format) {
+ switch (format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
- a8r8g8b8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
+ a8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_X8R8G8B8_UNORM:
- x8r8g8b8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
+ x8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_B8G8R8A8_UNORM:
- b8g8r8a8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
+ b8g8r8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_A1R5G5B5_UNORM:
- a1r5g5b5_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
+ a1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_A4R4G4B4_UNORM:
- a4r4g4b4_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
+ a4r4g4b4_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_R5G6B5_UNORM:
- r5g6b5_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
+ r5g6b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_L8_UNORM:
- l8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride);
+ l8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_A8_UNORM:
- a8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride);
+ a8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_I8_UNORM:
- i8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride);
+ i8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_A8L8_UNORM:
- a8_l8_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
+ a8_l8_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_R16G16B16A16_SNORM:
- r16g16b16a16_get_tile_rgba((short *) packed, w, h, p, dst_stride);
+ r16g16b16a16_get_tile_rgba((short *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_Z16_UNORM:
- z16_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
+ z16_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_Z32_UNORM:
- z32_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
+ z32_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_S8Z24_UNORM:
case PIPE_FORMAT_X8Z24_UNORM:
- s8z24_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
+ s8z24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_Z24S8_UNORM:
- z24s8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
+ z24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_YCBCR:
- assert((x & 1) == 0);
- ycbcr_get_tile_rgba((ushort *) packed, w, h, p, dst_stride, FALSE);
+ ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, FALSE);
break;
case PIPE_FORMAT_YCBCR_REV:
- assert((x & 1) == 0);
- ycbcr_get_tile_rgba((ushort *) packed, w, h, p, dst_stride, TRUE);
+ ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, TRUE);
break;
default:
assert(0);
}
+}
+
+
+void
+pipe_get_tile_rgba(struct pipe_surface *ps,
+ uint x, uint y, uint w, uint h,
+ float *p)
+{
+ unsigned dst_stride = w * 4;
+ void *packed;
+
+ if (pipe_clip_tile(x, y, &w, &h, ps))
+ return;
+
+ packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size);
+
+ if (!packed)
+ return;
+
+ if(ps->format == PIPE_FORMAT_YCBCR || ps->format == PIPE_FORMAT_YCBCR_REV)
+ assert((x & 1) == 0);
+
+ pipe_get_tile_raw(ps, x, y, w, h, packed, 0);
+
+ pipe_tile_raw_to_rgba(ps->format, packed, w, h, p, dst_stride);
FREE(packed);
}
@@ -792,7 +827,7 @@ pipe_put_tile_rgba(struct pipe_surface *ps,
/*a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
break;
case PIPE_FORMAT_R5G6B5_UNORM:
- r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
+ r5g6b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
break;
case PIPE_FORMAT_R8G8B8A8_UNORM:
assert(0);
diff --git a/src/gallium/auxiliary/util/p_tile.h b/src/gallium/auxiliary/util/p_tile.h
index adfec8bcee..a8ac805308 100644
--- a/src/gallium/auxiliary/util/p_tile.h
+++ b/src/gallium/auxiliary/util/p_tile.h
@@ -87,6 +87,13 @@ pipe_put_tile_z(struct pipe_surface *ps,
uint x, uint y, uint w, uint h,
const uint *z);
+void
+pipe_tile_raw_to_rgba(enum pipe_format format,
+ void *src,
+ uint w, uint h,
+ float *dst, unsigned dst_stride);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index 3dc9fdd11e..ae087df4cf 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -307,8 +307,10 @@ util_blit_pixels(struct blit_state *ctx,
dstY1 = tmp;
}
- assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE));
- assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE));
+ assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_SAMPLER, 0));
+ assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_SAMPLER, 0));
if(dst->format == src->format && (dstX1 - dstX0) == srcW && (dstY1 - dstY0) == srcH) {
/* FIXME: this will most surely fail for overlapping rectangles */
@@ -319,7 +321,8 @@ util_blit_pixels(struct blit_state *ctx,
return;
}
- assert(screen->is_format_supported(screen, dst->format, PIPE_SURFACE));
+ assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_RENDER_TARGET, 0));
/*
* XXX for now we're always creating a temporary texture.
@@ -449,7 +452,8 @@ util_blit_pixels_tex(struct blit_state *ctx,
t0 = srcY0 / (float)tex->height[0];
t1 = srcY1 / (float)tex->height[0];
- assert(screen->is_format_supported(screen, dst->format, PIPE_SURFACE));
+ assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_RENDER_TARGET, 0));
/* save state (restored below) */
cso_save_blend(ctx->cso);
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index 5313a8008a..4999822068 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -858,7 +858,8 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
uint zslice = 0;
/* check if we can render in the texture's format */
- if (!screen->is_format_supported(screen, pt->format, PIPE_SURFACE)) {
+ if (!screen->is_format_supported(screen, pt->format, PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) {
fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel);
return;
}
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c
index 5198b51441..cf9b68b695 100644
--- a/src/gallium/drivers/cell/ppu/cell_screen.c
+++ b/src/gallium/drivers/cell/ppu/cell_screen.c
@@ -115,23 +115,17 @@ cell_get_paramf(struct pipe_screen *screen, int param)
static boolean
cell_is_format_supported( struct pipe_screen *screen,
- enum pipe_format format, uint type )
+ enum pipe_format format,
+ enum pipe_texture_target target,
+ unsigned tex_usage,
+ unsigned geom_flags )
{
- switch (type) {
- case PIPE_TEXTURE:
- /* cell supports most texture formats, XXX for now anyway */
- if (format == PIPE_FORMAT_DXT5_RGBA ||
- format == PIPE_FORMAT_R8G8B8A8_SRGB)
- return FALSE;
- else
- return TRUE;
- case PIPE_SURFACE:
- /* cell supports all (off-screen) surface formats, XXX for now */
- return TRUE;
- default:
- assert(0);
+ /* cell supports most formats, XXX for now anyway */
+ if (format == PIPE_FORMAT_DXT5_RGBA ||
+ format == PIPE_FORMAT_R8G8B8A8_SRGB)
return FALSE;
- }
+ else
+ return TRUE;
}
diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c
index ba8f183bdf..4b1b8af7da 100644
--- a/src/gallium/drivers/i915simple/i915_screen.c
+++ b/src/gallium/drivers/i915simple/i915_screen.c
@@ -148,7 +148,10 @@ i915_get_paramf(struct pipe_screen *screen, int param)
static boolean
i915_is_format_supported( struct pipe_screen *screen,
- enum pipe_format format, uint type )
+ enum pipe_format format,
+ enum pipe_texture_target target,
+ unsigned tex_usage,
+ unsigned geom_flags )
{
static const enum pipe_format tex_supported[] = {
PIPE_FORMAT_R8G8B8A8_UNORM,
@@ -173,17 +176,10 @@ i915_is_format_supported( struct pipe_screen *screen,
const enum pipe_format *list;
uint i;
- switch (type) {
- case PIPE_TEXTURE:
- list = tex_supported;
- break;
- case PIPE_SURFACE:
+ if(tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET)
list = surface_supported;
- break;
- default:
- assert(0);
- return FALSE;
- }
+ else
+ list = tex_supported;
for (i = 0; list[i] != PIPE_FORMAT_NONE; i++) {
if (list[i] == format)
diff --git a/src/gallium/drivers/i965simple/brw_screen.c b/src/gallium/drivers/i965simple/brw_screen.c
index b700f7e4f5..6d8f24d1c4 100644
--- a/src/gallium/drivers/i965simple/brw_screen.c
+++ b/src/gallium/drivers/i965simple/brw_screen.c
@@ -136,7 +136,10 @@ brw_get_paramf(struct pipe_screen *screen, int param)
static boolean
brw_is_format_supported( struct pipe_screen *screen,
- enum pipe_format format, uint type )
+ enum pipe_format format,
+ enum pipe_texture_target target,
+ unsigned tex_usage,
+ unsigned geom_flags )
{
#if 0
/* XXX: This is broken -- rewrite if still needed. */
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index e9926bf41f..3f9d4b0ed3 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -115,18 +115,19 @@ softpipe_get_paramf(struct pipe_screen *screen, int param)
*/
static boolean
softpipe_is_format_supported( struct pipe_screen *screen,
- enum pipe_format format, uint type )
+ enum pipe_format format,
+ enum pipe_texture_target target,
+ unsigned tex_usage,
+ unsigned geom_flags )
{
- switch (type) {
- case PIPE_TEXTURE:
- /* softpipe supports all texture formats */
- return TRUE;
- case PIPE_SURFACE:
- /* softpipe supports all (off-screen) surface formats */
- return TRUE;
- default:
- assert(0);
+ switch(format) {
+ case PIPE_FORMAT_DXT1_RGB:
+ case PIPE_FORMAT_DXT1_RGBA:
+ case PIPE_FORMAT_DXT3_RGBA:
+ case PIPE_FORMAT_DXT5_RGBA:
return FALSE;
+ default:
+ return TRUE;
}
}
diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c
index e99df9d018..4321ca46f4 100644
--- a/src/gallium/drivers/softpipe/sp_setup.c
+++ b/src/gallium/drivers/softpipe/sp_setup.c
@@ -941,6 +941,11 @@ setup_line(struct setup_context *setup,
print_vertex(setup, v1);
#endif
+ assert(v0[0][0] < 1.0e9);
+ assert(v0[0][1] < 1.0e9);
+ assert(v1[0][0] < 1.0e9);
+ assert(v1[0][1] < 1.0e9);
+
if (setup->softpipe->no_rast)
return;
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index f8fadf31b6..b1d100ef53 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -166,11 +166,14 @@ enum pipe_texture_target {
#define PIPE_TEX_FACE_NEG_Z 5
#define PIPE_TEX_FACE_MAX 6
-/**
- * Surfaces, textures, etc. (others may be added)
- */
-#define PIPE_TEXTURE 1
-#define PIPE_SURFACE 2 /**< user-created surfaces */
+#define PIPE_TEXTURE_USAGE_RENDER_TARGET 0x1
+#define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* ie a backbuffer */
+#define PIPE_TEXTURE_USAGE_PRIMARY 0x4 /* ie a frontbuffer */
+#define PIPE_TEXTURE_USAGE_DEPTH_STENCIL 0x8
+#define PIPE_TEXTURE_USAGE_SAMPLER 0x10
+
+#define PIPE_TEXTURE_GEOM_NON_SQUARE 0x1
+#define PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO 0x2
/**
diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h
index a2c6155d01..947c445583 100644
--- a/src/gallium/include/pipe/p_format.h
+++ b/src/gallium/include/pipe/p_format.h
@@ -519,27 +519,16 @@ pf_get_nblocks(const struct pipe_format_block *block, unsigned width, unsigned h
return pf_get_nblocksx(block, width)*pf_get_nblocksy(block, height);
}
-static INLINE void
-pipe_rect_to_blocks(const struct pipe_format_block *block,
- unsigned *width, unsigned *height,
- unsigned *src_x, unsigned *src_y,
- unsigned *dst_x, unsigned *dst_y)
+static INLINE boolean
+pf_is_compressed( enum pipe_format format )
{
- assert(block->size > 0);
- assert(block->width > 0);
- assert(block->height > 0);
- if(width)
- *width = pf_get_nblocksx(block, *width);
- if(height)
- *height = pf_get_nblocksy(block, *height);
- if(src_x)
- *src_x /= block->width;
- if(src_y)
- *src_y /= block->height;
- if(dst_x)
- *dst_x /= block->width;
- if(dst_y)
- *dst_y /= block->height;
+ return pf_layout(format) == PIPE_FORMAT_LAYOUT_DXT ? TRUE : FALSE;
+}
+
+static INLINE boolean
+pf_is_ycbcr( enum pipe_format format )
+{
+ return pf_layout(format) == PIPE_FORMAT_LAYOUT_YCBCR ? TRUE : FALSE;
}
#ifdef __cplusplus
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index cc8430dae1..b15affef7a 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -77,11 +77,14 @@ struct pipe_screen {
/**
* Check if the given pipe_format is supported as a texture or
* drawing surface.
- * \param type one of PIPE_TEXTURE, PIPE_SURFACE
+ * \param tex_usage bitmask of PIPE_TEXTURE_USAGE_*
+ * \param flags bitmask of PIPE_TEXTURE_GEOM_*
*/
boolean (*is_format_supported)( struct pipe_screen *,
- enum pipe_format format,
- uint type );
+ enum pipe_format format,
+ enum pipe_texture_target target,
+ unsigned tex_usage,
+ unsigned geom_flags );
/**
* Create a new texture object, using the given template info.
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 5546796936..2401305eb7 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -287,12 +287,6 @@ struct pipe_surface
};
-#define PIPE_TEXTURE_USAGE_RENDER_TARGET 0x1
-#define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* ie a backbuffer */
-#define PIPE_TEXTURE_USAGE_PRIMARY 0x4 /* ie a frontbuffer */
-#define PIPE_TEXTURE_USAGE_DEPTH_STENCIL 0x8
-#define PIPE_TEXTURE_USAGE_SAMPLER 0x10
-
/**
* Texture object.
*/
diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript
index 57a3fb2075..973d96d55a 100644
--- a/src/gallium/state_trackers/python/SConscript
+++ b/src/gallium/state_trackers/python/SConscript
@@ -1,24 +1,34 @@
+import sys
+import os.path
+
Import('*')
if 'python' in env['statetrackers']:
env = env.Clone()
- env.Append(CPPPATH = '.')
+ env.Tool('python')
env.Tool('swig')
env.Append(SWIGPATH = ['#src/gallium/include', '#src/gallium/include/pipe'])
env.Append(SWIGFLAGS = ['-python', '-keyword'])
- env.ParseConfig('python-config --cflags --ldflags --libs')
-
- env.SharedLibrary(
- target = '_gallium',
- source = [
- 'gallium.i',
+ env.Append(CPPPATH = '.')
+
+ pyst = env.ConvenienceLibrary(
+ target = 'pyst',
+ source = [
+ 'gallium.i',
'st_device.c',
+ 'st_sample.c',
'st_softpipe_winsys.c',
- ],
- SHLIBPREFIX = '',
- LIBS = softpipe + auxiliaries + env['LIBS'],
+ ],
+ )
+
+ env.SharedLibrary(
+ target = '_gallium',
+ source = [
+ 'st_hardpipe_winsys.c',
+ ],
+ LIBS = [pyst, softpipe] + auxiliaries + env['LIBS'],
)
diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i
index d6594f3a87..8d8b762ea5 100644
--- a/src/gallium/state_trackers/python/gallium.i
+++ b/src/gallium/state_trackers/python/gallium.i
@@ -44,15 +44,19 @@
#include "pipe/p_inlines.h"
#include "pipe/p_util.h"
#include "pipe/p_shader_tokens.h"
+#include "cso_cache/cso_context.h"
#include "util/u_draw_quad.h"
#include "util/p_tile.h"
-#include "cso_cache/cso_context.h"
+#include "tgsi/util/tgsi_text.h"
+#include "tgsi/util/tgsi_dump.h"
#include "st_device.h"
+#include "st_sample.h"
%}
%include "carrays.i"
+%array_class(unsigned char, ByteArray);
%array_class(int, IntArray);
%array_class(float, FloatArray);
@@ -63,6 +67,7 @@
%rename(Surface) pipe_surface;
%rename(Buffer) pipe_buffer;
+
%rename(BlendColor) pipe_blend_color;
%rename(Blend) pipe_blend_state;
%rename(Clip) pipe_clip_state;
@@ -79,15 +84,30 @@
%rename(VertexElement) pipe_vertex_element;
%rename(Viewport) pipe_viewport_state;
+%nodefaultctor st_device;
+%nodefaultctor st_context;
+%nodefaultctor pipe_texture;
+%nodefaultctor pipe_surface;
+%nodefaultctor pipe_buffer;
+
+%nodefaultdtor st_device;
+%nodefaultdtor st_context;
+%nodefaultdtor pipe_texture;
+%nodefaultdtor pipe_surface;
+%nodefaultdtor pipe_buffer;
+
+%ignore pipe_texture::screen;
+
+%ignore pipe_surface::winsys;
+%immutable pipe_surface::texture;
+%immutable pipe_surface::buffer;
+
%include "p_format.i";
%include "pipe/p_defines.h";
%include "pipe/p_state.h";
%include "pipe/p_shader_tokens.h";
-%nodefaultctor;
-%nodefaultdtor;
-
struct st_device {
};
@@ -95,9 +115,13 @@ struct st_context {
};
+%newobject st_device::texture_create;
+%newobject st_device::context_create;
+%newobject st_device::buffer_create;
+
%extend st_device {
- st_device(int hardware = 0) {
+ st_device(int hardware = 1) {
return st_device_create(hardware ? TRUE : FALSE);
}
@@ -134,8 +158,15 @@ struct st_context {
* drawing surface.
* \param type one of PIPE_TEXTURE, PIPE_SURFACE
*/
- int is_format_supported( enum pipe_format format, unsigned type ) {
- return $self->screen->is_format_supported( $self->screen, format, type);
+ int is_format_supported( enum pipe_format format,
+ enum pipe_texture_target target,
+ unsigned tex_usage,
+ unsigned geom_flags ) {
+ return $self->screen->is_format_supported( $self->screen,
+ format,
+ target,
+ tex_usage,
+ geom_flags );
}
struct st_context *
@@ -151,7 +182,7 @@ struct st_context {
unsigned depth = 1,
unsigned last_level = 0,
enum pipe_texture_target target = PIPE_TEXTURE_2D,
- unsigned usage = 0
+ unsigned tex_usage = 0
) {
struct pipe_texture templat;
memset(&templat, 0, sizeof(templat));
@@ -162,7 +193,7 @@ struct st_context {
templat.depth[0] = depth;
templat.last_level = last_level;
templat.target = target;
- templat.tex_usage = usage;
+ templat.tex_usage = tex_usage;
return $self->screen->texture_create($self->screen, &templat);
}
@@ -201,29 +232,32 @@ struct st_context {
cso_set_depth_stencil_alpha($self->cso, state);
}
-
- void * create_fs( const struct pipe_shader_state *state ) {
- return $self->pipe->create_fs_state($self->pipe, state);
- }
-
- void bind_fs( void *state_obj ) {
- $self->pipe->bind_fs_state($self->pipe, state_obj);
- }
-
- void delete_fs( void *state_obj ) {
- $self->pipe->delete_fs_state($self->pipe, state_obj);
- }
+ void set_fragment_shader( const struct pipe_shader_state *state ) {
+ void *fs;
+
+ fs = $self->pipe->create_fs_state($self->pipe, state);
+ if(!fs)
+ return;
+
+ if(cso_set_fragment_shader_handle($self->cso, fs) != PIPE_OK)
+ return;
- void * create_vs( const struct pipe_shader_state *state ) {
- return $self->pipe->create_vs_state($self->pipe, state);
+ cso_delete_fragment_shader($self->cso, $self->fs);
+ $self->fs = fs;
}
-
- void bind_vs( void *state_obj ) {
- $self->pipe->bind_vs_state($self->pipe, state_obj);
- }
-
- void delete_vs( void *state_obj ) {
- $self->pipe->delete_vs_state($self->pipe, state_obj);
+
+ void set_vertex_shader( const struct pipe_shader_state *state ) {
+ void *vs;
+
+ vs = $self->pipe->create_vs_state($self->pipe, state);
+ if(!vs)
+ return;
+
+ if(cso_set_vertex_shader_handle($self->cso, vs) != PIPE_OK)
+ return;
+
+ cso_delete_vertex_shader($self->cso, $self->vs);
+ $self->vs = vs;
}
/*
@@ -261,6 +295,8 @@ struct st_context {
void set_sampler_texture(unsigned index,
struct pipe_texture *texture) {
+ if(!texture)
+ texture = $self->default_texture;
pipe_texture_reference(&$self->sampler_textures[index], texture);
$self->pipe->set_sampler_textures($self->pipe,
PIPE_MAX_SAMPLERS,
@@ -327,10 +363,6 @@ error1:
;
}
- void draw_quad(float x0, float y0, float x1, float y1, float z = 0.0f) {
- util_draw_texquad($self->pipe, x0, y0, x1, y1, z);
- }
-
void
flush(void) {
struct pipe_fence_handle *fence = NULL;
@@ -360,13 +392,15 @@ error1:
$self->pipe->surface_fill($self->pipe, dst, x, y, width, height, value);
}
- void clear(struct pipe_surface *surface, unsigned value) {
+ void surface_clear(struct pipe_surface *surface, unsigned value = 0) {
$self->pipe->clear($self->pipe, surface, value);
}
};
+%newobject pipe_texture::get_surface;
+
%extend pipe_texture {
~pipe_texture() {
@@ -374,6 +408,26 @@ error1:
pipe_texture_reference(&ptr, NULL);
}
+ unsigned get_width(unsigned level=0) {
+ return $self->width[level];
+ }
+
+ unsigned get_height(unsigned level=0) {
+ return $self->height[level];
+ }
+
+ unsigned get_depth(unsigned level=0) {
+ return $self->depth[level];
+ }
+
+ unsigned get_nblocksx(unsigned level=0) {
+ return $self->nblocksx[level];
+ }
+
+ unsigned get_nblocksy(unsigned level=0) {
+ return $self->nblocksy[level];
+ }
+
/** Get a surface which is a "view" into a texture */
struct pipe_surface *
get_surface(unsigned face=0, unsigned level=0, unsigned zslice=0, unsigned usage=0 )
@@ -399,13 +453,23 @@ error1:
void unmap( void );
void
- get_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, float *p) {
- pipe_get_tile_rgba($self, x, y, w, h, p);
+ get_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, unsigned char *raw, unsigned stride) {
+ pipe_get_tile_raw($self, x, y, w, h, raw, stride);
+ }
+
+ void
+ put_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, const unsigned char *raw, unsigned stride) {
+ pipe_put_tile_raw($self, x, y, w, h, raw, stride);
}
void
- put_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *p) {
- pipe_put_tile_rgba($self, x, y, w, h, p);
+ get_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, float *rgba) {
+ pipe_get_tile_rgba($self, x, y, w, h, rgba);
+ }
+
+ void
+ put_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *rgba) {
+ pipe_put_tile_rgba($self, x, y, w, h, rgba);
}
void
@@ -418,6 +482,43 @@ error1:
pipe_put_tile_z($self, x, y, w, h, z);
}
+ void
+ sample_rgba(float *rgba) {
+ st_sample_surface($self, rgba);
+ }
+
+ unsigned
+ compare_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *rgba, float tol = 0.0)
+ {
+ float *rgba2;
+ const float *p1;
+ const float *p2;
+ unsigned i, j, n;
+
+ rgba2 = MALLOC(h*w*4*sizeof(float));
+ if(!rgba2)
+ return ~0;
+
+ pipe_get_tile_rgba($self, x, y, w, h, rgba2);
+
+ p1 = rgba;
+ p2 = rgba2;
+ n = 0;
+ for(i = h*w; i; --i) {
+ unsigned differs = 0;
+ for(j = 4; j; --j) {
+ float delta = *p2++ - *p1++;
+ if (delta < -tol || delta > tol)
+ differs = 1;
+ }
+ n += differs;
+ }
+
+ FREE(rgba2);
+
+ return n;
+ }
+
};
@@ -446,3 +547,42 @@ error1:
}
};
+
+
+%extend pipe_shader_state {
+
+ pipe_shader_state(const char *text, unsigned num_tokens = 1024) {
+ struct tgsi_token *tokens;
+ struct pipe_shader_state *shader;
+
+ tokens = MALLOC(num_tokens * sizeof(struct tgsi_token));
+ if(!tokens)
+ goto error1;
+
+ if(tgsi_text_translate(text, tokens, num_tokens ) != TRUE)
+ goto error2;
+
+ shader = CALLOC_STRUCT(pipe_shader_state);
+ if(!shader)
+ goto error3;
+
+ shader->tokens = tokens;
+
+ return shader;
+
+error3:
+error2:
+ FREE(tokens);
+error1:
+ return NULL;
+ }
+
+ ~pipe_shader_state() {
+ FREE((void*)$self->tokens);
+ FREE($self);
+ }
+
+ void dump(unsigned flags = 0) {
+ tgsi_dump($self->tokens, flags);
+ }
+} \ No newline at end of file
diff --git a/src/gallium/state_trackers/python/samples/simple.py b/src/gallium/state_trackers/python/samples/tri.py
index 77e182b644..1271c67627 100644
--- a/src/gallium/state_trackers/python/samples/simple.py
+++ b/src/gallium/state_trackers/python/samples/tri.py
@@ -30,7 +30,7 @@
from gallium import *
-def save_image(filename, surface):
+def make_image(surface):
pixels = FloatArray(surface.height*surface.width*4)
surface.get_tile_rgba(0, 0, surface.width, surface.height, pixels)
@@ -45,14 +45,38 @@ def save_image(filename, surface):
offset = (y*surface.width + x)*4
r, g, b, a = [int(pixels[offset + ch]*255) for ch in range(4)]
outpixels[x, y] = r, g, b
+ return outimage
+
+def save_image(filename, surface):
+ outimage = make_image(surface)
outimage.save(filename, "PNG")
+def show_image(surface):
+ outimage = make_image(surface)
+
+ import Tkinter as tk
+ from PIL import Image, ImageTk
+ root = tk.Tk()
+
+ root.title('background image')
+
+ image1 = ImageTk.PhotoImage(outimage)
+ w = image1.width()
+ h = image1.height()
+ x = 100
+ y = 100
+ root.geometry("%dx%d+%d+%d" % (w, h, x, y))
+ panel1 = tk.Label(root, image=image1)
+ panel1.pack(side='top', fill='both', expand='yes')
+ panel1.image = image1
+ root.mainloop()
+
def test(dev):
ctx = dev.context_create()
- width = 256
- height = 256
+ width = 255
+ height = 255
# disabled blending/masking
blend = Blend()
@@ -72,6 +96,7 @@ def test(dev):
rasterizer.front_winding = PIPE_WINDING_CW
rasterizer.cull_mode = PIPE_WINDING_NONE
rasterizer.bypass_clipping = 1
+ rasterizer.scissor = 1
#rasterizer.bypass_vs = 1
ctx.set_rasterizer(rasterizer)
@@ -102,55 +127,102 @@ def test(dev):
sampler.normalized_coords = 1
ctx.set_sampler(0, sampler)
- # texture
- texture = dev.texture_create(PIPE_FORMAT_A8R8G8B8_UNORM, width, height, usage=PIPE_TEXTURE_USAGE_RENDER_TARGET)
- ctx.set_sampler_texture(0, texture)
-
- # drawing dest
- surface = texture.get_surface(usage = PIPE_BUFFER_USAGE_GPU_WRITE)
+ # scissor
+ scissor = Scissor()
+ scissor.minx = 0
+ scissor.miny = 0
+ scissor.maxx = width
+ scissor.maxy = height
+ ctx.set_scissor(scissor)
+
+ clip = Clip()
+ clip.nr = 0
+ ctx.set_clip(clip)
+
+ # framebuffer
+ cbuf = dev.texture_create(
+ PIPE_FORMAT_X8R8G8B8_UNORM,
+ width, height,
+ tex_usage=PIPE_TEXTURE_USAGE_DISPLAY_TARGET,
+ )
+ _cbuf = cbuf.get_surface(usage = PIPE_BUFFER_USAGE_GPU_READ|PIPE_BUFFER_USAGE_GPU_WRITE)
fb = Framebuffer()
- fb.width = surface.width
- fb.height = surface.height
+ fb.width = width
+ fb.height = height
fb.num_cbufs = 1
- fb.set_cbuf(0, surface)
+ fb.set_cbuf(0, _cbuf)
ctx.set_framebuffer(fb)
-
+ _cbuf.clear_value = 0x00000000
+ ctx.surface_clear(_cbuf, _cbuf.clear_value)
+ del _cbuf
+
# vertex shader
- # vs = Shader()
- #ctx.set_vertex_shader(vs)
+ vs = Shader('''
+ VERT1.1
+ DCL IN[0], POSITION, CONSTANT
+ DCL IN[1], COLOR, CONSTANT
+ DCL OUT[0], POSITION, CONSTANT
+ DCL OUT[1], COLOR, CONSTANT
+ 0:MOV OUT[0], IN[0]
+ 1:MOV OUT[1], IN[1]
+ 2:END
+ ''')
+ #vs.dump()
+ ctx.set_vertex_shader(vs)
# fragment shader
- #fs = Shader()
- #ctx.set_fragment_shader(fs)
-
- if 0:
- nverts = 4
- nattrs = 1
- vertices = FloatArray(n_verts * nattrs * 4)
-
- # init vertex data that doesn't change
- for i in range(nverts):
- for j in range(nattrs):
- vertices[(i*nattrs +j)*4 + 0] = 0.0
- vertices[(i*nattrs +j)*4 + 1] = 0.0
- vertices[(i*nattrs +j)*4 + 2] = 0.0
- vertices[(i*nattrs +j)*4 + 3] = 0.0
-
- ctx.draw_vertices(PIPE_PRIM_TRIANGLE_FAN,
- 4, # verts
- 2, # attribs/vert
- vertices)
- else:
- ctx.draw_quad(32.0, 32.0, 224.0, 224.0)
+ fs = Shader('''
+ FRAG1.1
+ DCL IN[0], COLOR, LINEAR
+ DCL OUT[0], COLOR, CONSTANT
+ 0:MOV OUT[0], IN[0]
+ 1:END
+ ''')
+ #fs.dump()
+ ctx.set_fragment_shader(fs)
+
+ nverts = 3
+ nattrs = 2
+ verts = FloatArray(nverts * nattrs * 4)
+
+ verts[ 0] = 128.0 # x1
+ verts[ 1] = 32.0 # y1
+ verts[ 2] = 0.0 # z1
+ verts[ 3] = 1.0 # w1
+ verts[ 4] = 1.0 # r1
+ verts[ 5] = 0.0 # g1
+ verts[ 6] = 0.0 # b1
+ verts[ 7] = 1.0 # a1
+ verts[ 8] = 32.0 # x2
+ verts[ 9] = 224.0 # y2
+ verts[10] = 0.0 # z2
+ verts[11] = 1.0 # w2
+ verts[12] = 0.0 # r2
+ verts[13] = 1.0 # g2
+ verts[14] = 0.0 # b2
+ verts[15] = 1.0 # a2
+ verts[16] = 224.0 # x3
+ verts[17] = 224.0 # y3
+ verts[18] = 0.0 # z3
+ verts[19] = 1.0 # w3
+ verts[20] = 0.0 # r3
+ verts[21] = 0.0 # g3
+ verts[22] = 1.0 # b3
+ verts[23] = 1.0 # a3
+
+ ctx.draw_vertices(PIPE_PRIM_TRIANGLES,
+ nverts,
+ nattrs,
+ verts)
ctx.flush()
-
- save_image("simple.png", surface)
+
+ show_image(cbuf.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ|PIPE_BUFFER_USAGE_CPU_WRITE))
def main():
- dev = Device(0)
+ dev = Device()
test(dev)
diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c
index 430a7af176..2e53a83eea 100644
--- a/src/gallium/state_trackers/python/st_device.c
+++ b/src/gallium/state_trackers/python/st_device.c
@@ -70,6 +70,7 @@ st_device_create_from_st_winsys(const struct st_winsys *st_ws)
if(!st_dev)
return NULL;
+ st_dev->refcount = 1;
st_dev->st_ws = st_ws;
st_dev->screen = st_ws->screen_create();
@@ -82,12 +83,10 @@ st_device_create_from_st_winsys(const struct st_winsys *st_ws)
struct st_device *
st_device_create(boolean hardware) {
-#if 0
if(hardware)
- return st_device_create_from_st_winsys(&st_hardware_winsys);
+ return st_device_create_from_st_winsys(&st_hardpipe_winsys);
else
-#endif
- return st_device_create_from_st_winsys(&st_software_winsys);
+ return st_device_create_from_st_winsys(&st_softpipe_winsys);
}
@@ -99,25 +98,20 @@ st_context_destroy(struct st_context *st_ctx)
if(st_ctx) {
struct st_device *st_dev = st_ctx->st_dev;
- if(st_ctx->vs) {
- st_ctx->pipe->bind_vs_state(st_ctx->pipe, NULL);
- st_ctx->pipe->delete_vs_state(st_ctx->pipe, st_ctx->vs);
- }
-
- if(st_ctx->fs) {
- st_ctx->pipe->bind_fs_state(st_ctx->pipe, NULL);
- st_ctx->pipe->delete_fs_state(st_ctx->pipe, st_ctx->fs);
- }
-
- if(st_ctx->cso)
+ if(st_ctx->cso) {
+ cso_delete_vertex_shader(st_ctx->cso, st_ctx->vs);
+ cso_delete_fragment_shader(st_ctx->cso, st_ctx->fs);
+
cso_destroy_context(st_ctx->cso);
+ }
if(st_ctx->pipe)
st_ctx->st_dev->st_ws->context_destroy(st_ctx->pipe);
for(i = 0; i < PIPE_MAX_SAMPLERS; ++i)
pipe_texture_reference(&st_ctx->sampler_textures[i], NULL);
-
+ pipe_texture_reference(&st_ctx->default_texture, NULL);
+
FREE(st_ctx);
if(!--st_dev->refcount)
@@ -146,8 +140,111 @@ st_context_create(struct st_device *st_dev)
if(!st_ctx->cso)
st_context_destroy(st_ctx);
+ /* disabled blending/masking */
+ {
+ struct pipe_blend_state blend;
+ memset(&blend, 0, sizeof(blend));
+ blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.colormask = PIPE_MASK_RGBA;
+ cso_set_blend(st_ctx->cso, &blend);
+ }
+
+ /* no-op depth/stencil/alpha */
+ {
+ struct pipe_depth_stencil_alpha_state depthstencil;
+ memset(&depthstencil, 0, sizeof(depthstencil));
+ cso_set_depth_stencil_alpha(st_ctx->cso, &depthstencil);
+ }
+
+ /* rasterizer */
+ {
+ struct pipe_rasterizer_state rasterizer;
+ memset(&rasterizer, 0, sizeof(rasterizer));
+ rasterizer.front_winding = PIPE_WINDING_CW;
+ rasterizer.cull_mode = PIPE_WINDING_NONE;
+ rasterizer.bypass_clipping = 1;
+ /*rasterizer.bypass_vs = 1;*/
+ cso_set_rasterizer(st_ctx->cso, &rasterizer);
+ }
+
+ /* identity viewport */
+ {
+ struct pipe_viewport_state viewport;
+ viewport.scale[0] = 1.0;
+ viewport.scale[1] = 1.0;
+ viewport.scale[2] = 1.0;
+ viewport.scale[3] = 1.0;
+ viewport.translate[0] = 0.0;
+ viewport.translate[1] = 0.0;
+ viewport.translate[2] = 0.0;
+ viewport.translate[3] = 0.0;
+ cso_set_viewport(st_ctx->cso, &viewport);
+ }
+
+ /* samplers */
+ {
+ struct pipe_sampler_state sampler;
+ unsigned i;
+ memset(&sampler, 0, sizeof(sampler));
+ sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
+ sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
+ sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
+ sampler.normalized_coords = 1;
+ for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
+ cso_single_sampler(st_ctx->cso, i, &sampler);
+ cso_single_sampler_done(st_ctx->cso);
+ }
+
+ /* default textures */
+ {
+ struct pipe_screen *screen = st_dev->screen;
+ struct pipe_texture templat;
+ struct pipe_surface *surface;
+ unsigned i;
+
+ memset( &templat, 0, sizeof( templat ) );
+ templat.target = PIPE_TEXTURE_2D;
+ templat.format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ templat.block.size = 4;
+ templat.block.width = 1;
+ templat.block.height = 1;
+ templat.width[0] = 1;
+ templat.height[0] = 1;
+ templat.depth[0] = 1;
+ templat.last_level = 0;
+
+ st_ctx->default_texture = screen->texture_create( screen, &templat );
+ if(st_ctx->default_texture) {
+ surface = screen->get_tex_surface( screen,
+ st_ctx->default_texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE );
+ if(surface) {
+ uint32_t *map;
+ map = (uint32_t *) pipe_surface_map(surface, PIPE_BUFFER_USAGE_CPU_WRITE );
+ if(map) {
+ *map = 0x00000000;
+ pipe_surface_unmap( surface );
+ }
+ pipe_surface_reference(&surface, NULL);
+ }
+ }
+
+ for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
+ pipe_texture_reference(&st_ctx->sampler_textures[i], st_ctx->default_texture);
+
+ cso_set_sampler_textures(st_ctx->cso, PIPE_MAX_SAMPLERS, st_ctx->sampler_textures);
+ }
+
/* vertex shader */
{
+ struct pipe_shader_state vert_shader;
+
const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
TGSI_SEMANTIC_GENERIC };
const uint semantic_indexes[] = { 0, 0 };
@@ -155,15 +252,17 @@ st_context_create(struct st_device *st_dev)
2,
semantic_names,
semantic_indexes,
- &st_ctx->vert_shader);
+ &vert_shader);
+ cso_set_vertex_shader_handle(st_ctx->cso, st_ctx->vs);
}
/* fragment shader */
- st_ctx->fs = util_make_fragment_passthrough_shader(st_ctx->pipe,
- &st_ctx->frag_shader);
-
- st_ctx->pipe->bind_fs_state(st_ctx->pipe, st_ctx->fs);
- st_ctx->pipe->bind_vs_state(st_ctx->pipe, st_ctx->vs);
+ {
+ struct pipe_shader_state frag_shader;
+ st_ctx->fs = util_make_fragment_passthrough_shader(st_ctx->pipe,
+ &frag_shader);
+ cso_set_fragment_shader_handle(st_ctx->cso, st_ctx->fs);
+ }
return st_ctx;
}
diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h
index 46db20acd7..2d95c2da73 100644
--- a/src/gallium/state_trackers/python/st_device.h
+++ b/src/gallium/state_trackers/python/st_device.h
@@ -45,12 +45,10 @@ struct st_context {
struct cso_context *cso;
- struct pipe_shader_state vert_shader;
- struct pipe_shader_state frag_shader;
-
void *vs;
void *fs;
+ struct pipe_texture *default_texture;
struct pipe_texture *sampler_textures[PIPE_MAX_SAMPLERS];
struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS];
diff --git a/src/gallium/state_trackers/python/st_hardpipe_winsys.c b/src/gallium/state_trackers/python/st_hardpipe_winsys.c
new file mode 100644
index 0000000000..1e04998232
--- /dev/null
+++ b/src/gallium/state_trackers/python/st_hardpipe_winsys.c
@@ -0,0 +1,78 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * 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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Stub for hardware pipe driver support.
+ */
+
+
+#include "pipe/p_compiler.h"
+
+#include "st_winsys.h"
+
+
+/* XXX: Force init_gallium symbol to be linked */
+extern void init_gallium(void);
+void (*force_init_gallium_linkage)(void) = &init_gallium;
+
+
+static void
+st_hardpipe_screen_destroy(struct pipe_screen *screen)
+{
+ st_softpipe_winsys.screen_destroy(screen);
+}
+
+
+static struct pipe_screen *
+st_hardpipe_screen_create(void)
+{
+ return st_softpipe_winsys.screen_create();
+}
+
+
+static void
+st_hardpipe_context_destroy(struct pipe_context *pipe)
+{
+ st_softpipe_winsys.context_destroy(pipe);
+}
+
+
+static struct pipe_context *
+st_hardpipe_context_create(struct pipe_screen *screen)
+{
+ return st_softpipe_winsys.context_create(screen);
+}
+
+
+const struct st_winsys st_hardpipe_winsys = {
+ &st_hardpipe_screen_create,
+ &st_hardpipe_screen_destroy,
+ &st_hardpipe_context_create,
+ &st_hardpipe_context_destroy
+};
diff --git a/src/gallium/state_trackers/python/st_sample.c b/src/gallium/state_trackers/python/st_sample.c
new file mode 100644
index 0000000000..b47c7be293
--- /dev/null
+++ b/src/gallium/state_trackers/python/st_sample.c
@@ -0,0 +1,548 @@
+/**************************************************************************
+ *
+ * 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 "pipe/p_format.h"
+#include "pipe/p_state.h"
+#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
+#include "util/p_tile.h"
+
+#include "st_sample.h"
+
+
+/**
+ * Use our own pseudo random generator to ensure consistent runs among
+ * multiple runs and platforms.
+ *
+ * @sa http://en.wikipedia.org/wiki/Linear_congruential_generator
+ */
+static uint32_t st_random(void) {
+ static uint64_t seed = UINT64_C(0xbb9a063afb0a739d);
+
+ seed = UINT64_C(134775813) * seed + UINT64_C(1);
+
+ return (uint16_t)(seed >> 32);
+}
+
+
+/**
+ * We don't want to include the patent-encumbered DXT code here, so instead
+ * we store several uncompressed/compressed data pairs for hardware testing
+ * purposes.
+ */
+struct dxt_data
+{
+ uint8_t rgba[16*4];
+ uint8_t raw[16];
+};
+
+
+static const struct dxt_data
+dxt1_rgb_data[] = {
+ {
+ {
+ 0x99, 0xb0, 0x8e, 0xff,
+ 0x5d, 0x62, 0x89, 0xff,
+ 0x99, 0xb0, 0x8e, 0xff,
+ 0x99, 0xb0, 0x8e, 0xff,
+ 0xd6, 0xff, 0x94, 0xff,
+ 0x5d, 0x62, 0x89, 0xff,
+ 0x99, 0xb0, 0x8e, 0xff,
+ 0xd6, 0xff, 0x94, 0xff,
+ 0x5d, 0x62, 0x89, 0xff,
+ 0x5d, 0x62, 0x89, 0xff,
+ 0x99, 0xb0, 0x8e, 0xff,
+ 0x21, 0x14, 0x84, 0xff,
+ 0x5d, 0x62, 0x89, 0xff,
+ 0x21, 0x14, 0x84, 0xff,
+ 0x21, 0x14, 0x84, 0xff,
+ 0x99, 0xb0, 0x8e, 0xff
+ },
+ {0xf2, 0xd7, 0xb0, 0x20, 0xae, 0x2c, 0x6f, 0x97}
+ },
+ {
+ {
+ 0xb5, 0xcf, 0x9c, 0xff,
+ 0x83, 0x8c, 0x8b, 0xff,
+ 0x21, 0x08, 0x6b, 0xff,
+ 0x83, 0x8c, 0x8b, 0xff,
+ 0x52, 0x4a, 0x7b, 0xff,
+ 0x83, 0x8c, 0x8b, 0xff,
+ 0x83, 0x8c, 0x8b, 0xff,
+ 0xb5, 0xcf, 0x9c, 0xff,
+ 0x21, 0x08, 0x6b, 0xff,
+ 0xb5, 0xcf, 0x9c, 0xff,
+ 0x83, 0x8c, 0x8b, 0xff,
+ 0x52, 0x4a, 0x7b, 0xff,
+ 0xb5, 0xcf, 0x9c, 0xff,
+ 0x83, 0x8c, 0x8b, 0xff,
+ 0x52, 0x4a, 0x7b, 0xff,
+ 0x83, 0x8c, 0x8b, 0xff
+ },
+ {0x73, 0xb6, 0x4d, 0x20, 0x98, 0x2b, 0xe1, 0xb8}
+ },
+ {
+ {
+ 0x00, 0x2c, 0xff, 0xff,
+ 0x94, 0x8d, 0x7b, 0xff,
+ 0x4a, 0x5c, 0xbd, 0xff,
+ 0x4a, 0x5c, 0xbd, 0xff,
+ 0x4a, 0x5c, 0xbd, 0xff,
+ 0x94, 0x8d, 0x7b, 0xff,
+ 0x94, 0x8d, 0x7b, 0xff,
+ 0x94, 0x8d, 0x7b, 0xff,
+ 0xde, 0xbe, 0x39, 0xff,
+ 0x94, 0x8d, 0x7b, 0xff,
+ 0xde, 0xbe, 0x39, 0xff,
+ 0xde, 0xbe, 0x39, 0xff,
+ 0xde, 0xbe, 0x39, 0xff,
+ 0xde, 0xbe, 0x39, 0xff,
+ 0xde, 0xbe, 0x39, 0xff,
+ 0x94, 0x8d, 0x7b, 0xff
+ },
+ {0xe7, 0xdd, 0x7f, 0x01, 0xf9, 0xab, 0x08, 0x80}
+ },
+ {
+ {
+ 0x6b, 0x24, 0x21, 0xff,
+ 0x7b, 0x4f, 0x5d, 0xff,
+ 0x7b, 0x4f, 0x5d, 0xff,
+ 0x8b, 0x7a, 0x99, 0xff,
+ 0x7b, 0x4f, 0x5d, 0xff,
+ 0x7b, 0x4f, 0x5d, 0xff,
+ 0x6b, 0x24, 0x21, 0xff,
+ 0x8b, 0x7a, 0x99, 0xff,
+ 0x9c, 0xa6, 0xd6, 0xff,
+ 0x6b, 0x24, 0x21, 0xff,
+ 0x7b, 0x4f, 0x5d, 0xff,
+ 0x8b, 0x7a, 0x99, 0xff,
+ 0x6b, 0x24, 0x21, 0xff,
+ 0x8b, 0x7a, 0x99, 0xff,
+ 0x7b, 0x4f, 0x5d, 0xff,
+ 0x9c, 0xa6, 0xd6, 0xff
+ },
+ {0x3a, 0x9d, 0x24, 0x69, 0xbd, 0x9f, 0xb4, 0x39}
+ }
+};
+
+
+static const struct dxt_data
+dxt1_rgba_data[] = {
+ {
+ {
+ 0x00, 0x00, 0x00, 0x00,
+ 0x4e, 0xaa, 0x90, 0xff,
+ 0x4e, 0xaa, 0x90, 0xff,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x4e, 0xaa, 0x90, 0xff,
+ 0x29, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x4e, 0xaa, 0x90, 0xff,
+ 0x73, 0x55, 0x21, 0xff,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x4e, 0xaa, 0x90, 0xff,
+ 0x4e, 0xaa, 0x90, 0xff,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x4e, 0xaa, 0x90, 0xff
+ },
+ {0xff, 0x2f, 0xa4, 0x72, 0xeb, 0xb2, 0xbd, 0xbe}
+ },
+ {
+ {
+ 0xb5, 0xe3, 0x63, 0xff,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x6b, 0x24, 0x84, 0xff,
+ 0xb5, 0xe3, 0x63, 0xff,
+ 0x00, 0x00, 0x00, 0x00,
+ 0xb5, 0xe3, 0x63, 0xff,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x6b, 0x24, 0x84, 0xff,
+ 0x6b, 0x24, 0x84, 0xff,
+ 0x00, 0x00, 0x00, 0x00,
+ 0xb5, 0xe3, 0x63, 0xff,
+ 0x90, 0x83, 0x73, 0xff,
+ 0xb5, 0xe3, 0x63, 0xff
+ },
+ {0x30, 0x69, 0x0c, 0xb7, 0x4d, 0xf7, 0x0f, 0x67}
+ },
+ {
+ {
+ 0x00, 0x00, 0x00, 0x00,
+ 0xc6, 0x86, 0x8c, 0xff,
+ 0xc6, 0x86, 0x8c, 0xff,
+ 0x21, 0x65, 0x42, 0xff,
+ 0x21, 0x65, 0x42, 0xff,
+ 0x21, 0x65, 0x42, 0xff,
+ 0x21, 0x65, 0x42, 0xff,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x21, 0x65, 0x42, 0xff,
+ 0xc6, 0x86, 0x8c, 0xff,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0xc6, 0x86, 0x8c, 0xff
+ },
+ {0x28, 0x23, 0x31, 0xc4, 0x17, 0xc0, 0xd3, 0x7f}
+ },
+ {
+ {
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0xc6, 0xe3, 0x9c, 0xff,
+ 0x7b, 0x1c, 0x52, 0xff,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x7b, 0x1c, 0x52, 0xff,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x7b, 0x1c, 0x52, 0xff,
+ 0xa0, 0x7f, 0x77, 0xff,
+ 0xc6, 0xe3, 0x9c, 0xff,
+ 0x00, 0x00, 0x00, 0x00,
+ 0xa0, 0x7f, 0x77, 0xff
+ },
+ {0xea, 0x78, 0x13, 0xc7, 0x7f, 0xfc, 0x33, 0xb6}
+ },
+};
+
+
+static const struct dxt_data
+dxt3_rgba_data[] = {
+ {
+ {
+ 0x6d, 0xc6, 0x96, 0x77,
+ 0x6d, 0xc6, 0x96, 0xee,
+ 0x6d, 0xc6, 0x96, 0xaa,
+ 0x8c, 0xff, 0xb5, 0x44,
+ 0x6d, 0xc6, 0x96, 0xff,
+ 0x6d, 0xc6, 0x96, 0x88,
+ 0x31, 0x55, 0x5a, 0x66,
+ 0x6d, 0xc6, 0x96, 0x99,
+ 0x31, 0x55, 0x5a, 0xbb,
+ 0x31, 0x55, 0x5a, 0x55,
+ 0x31, 0x55, 0x5a, 0x11,
+ 0x6d, 0xc6, 0x96, 0xcc,
+ 0x6d, 0xc6, 0x96, 0xcc,
+ 0x6d, 0xc6, 0x96, 0x11,
+ 0x31, 0x55, 0x5a, 0x44,
+ 0x31, 0x55, 0x5a, 0x88
+ },
+ {0xe7, 0x4a, 0x8f, 0x96, 0x5b, 0xc1, 0x1c, 0x84, 0xf6, 0x8f, 0xab, 0x32, 0x2a, 0x9a, 0x95, 0x5a}
+ },
+ {
+ {
+ 0xad, 0xeb, 0x73, 0x99,
+ 0x97, 0xaa, 0x86, 0x66,
+ 0x6b, 0x28, 0xad, 0x99,
+ 0xad, 0xeb, 0x73, 0x99,
+ 0x6b, 0x28, 0xad, 0x22,
+ 0xad, 0xeb, 0x73, 0xff,
+ 0x97, 0xaa, 0x86, 0x55,
+ 0x6b, 0x28, 0xad, 0x55,
+ 0x6b, 0x28, 0xad, 0x44,
+ 0xad, 0xeb, 0x73, 0x33,
+ 0x6b, 0x28, 0xad, 0xee,
+ 0x6b, 0x28, 0xad, 0x99,
+ 0x97, 0xaa, 0x86, 0x66,
+ 0xad, 0xeb, 0x73, 0xbb,
+ 0x97, 0xaa, 0x86, 0x99,
+ 0xad, 0xeb, 0x73, 0xbb
+ },
+ {0x69, 0x99, 0xf2, 0x55, 0x34, 0x9e, 0xb6, 0xb9, 0x4e, 0xaf, 0x55, 0x69, 0x18, 0x61, 0x51, 0x22}
+ },
+ {
+ {
+ 0x63, 0xd7, 0xd6, 0x00,
+ 0x57, 0x62, 0x5d, 0xdd,
+ 0x57, 0x62, 0x5d, 0xcc,
+ 0x57, 0x62, 0x5d, 0xbb,
+ 0x52, 0x28, 0x21, 0xaa,
+ 0x57, 0x62, 0x5d, 0xcc,
+ 0x57, 0x62, 0x5d, 0xcc,
+ 0x57, 0x62, 0x5d, 0x66,
+ 0x57, 0x62, 0x5d, 0x22,
+ 0x57, 0x62, 0x5d, 0xdd,
+ 0x63, 0xd7, 0xd6, 0xee,
+ 0x57, 0x62, 0x5d, 0x33,
+ 0x63, 0xd7, 0xd6, 0x55,
+ 0x52, 0x28, 0x21, 0x55,
+ 0x57, 0x62, 0x5d, 0x11,
+ 0x5d, 0x9c, 0x99, 0xee
+ },
+ {0xd0, 0xbc, 0xca, 0x6c, 0xd2, 0x3e, 0x55, 0xe1, 0xba, 0x66, 0x44, 0x51, 0xfc, 0xfd, 0xcf, 0xb4}
+ },
+ {
+ {
+ 0x94, 0x6f, 0x60, 0x22,
+ 0x94, 0x6f, 0x60, 0x22,
+ 0xc5, 0xab, 0x76, 0x11,
+ 0xc5, 0xab, 0x76, 0xee,
+ 0x63, 0x34, 0x4a, 0xdd,
+ 0x63, 0x34, 0x4a, 0x33,
+ 0x94, 0x6f, 0x60, 0x77,
+ 0xf7, 0xe7, 0x8c, 0x00,
+ 0x94, 0x6f, 0x60, 0x33,
+ 0x63, 0x34, 0x4a, 0xaa,
+ 0x94, 0x6f, 0x60, 0x77,
+ 0x63, 0x34, 0x4a, 0xcc,
+ 0x94, 0x6f, 0x60, 0xaa,
+ 0xf7, 0xe7, 0x8c, 0x99,
+ 0x63, 0x34, 0x4a, 0x44,
+ 0xc5, 0xab, 0x76, 0xaa
+ },
+ {0x22, 0xe1, 0x3d, 0x07, 0xa3, 0xc7, 0x9a, 0xa4, 0x31, 0xf7, 0xa9, 0x61, 0xaf, 0x35, 0x77, 0x93}
+ },
+};
+
+
+static const struct dxt_data
+dxt5_rgba_data[] = {
+ {
+ {
+ 0x6d, 0xc6, 0x96, 0x74,
+ 0x6d, 0xc6, 0x96, 0xf8,
+ 0x6d, 0xc6, 0x96, 0xb6,
+ 0x8c, 0xff, 0xb5, 0x53,
+ 0x6d, 0xc6, 0x96, 0xf8,
+ 0x6d, 0xc6, 0x96, 0x95,
+ 0x31, 0x55, 0x5a, 0x53,
+ 0x6d, 0xc6, 0x96, 0x95,
+ 0x31, 0x55, 0x5a, 0xb6,
+ 0x31, 0x55, 0x5a, 0x53,
+ 0x31, 0x55, 0x5a, 0x11,
+ 0x6d, 0xc6, 0x96, 0xd7,
+ 0x6d, 0xc6, 0x96, 0xb6,
+ 0x6d, 0xc6, 0x96, 0x11,
+ 0x31, 0x55, 0x5a, 0x32,
+ 0x31, 0x55, 0x5a, 0x95
+ },
+ {0xf8, 0x11, 0xc5, 0x0c, 0x9a, 0x73, 0xb4, 0x9c, 0xf6, 0x8f, 0xab, 0x32, 0x2a, 0x9a, 0x95, 0x5a}
+ },
+ {
+ {
+ 0xad, 0xeb, 0x73, 0xa1,
+ 0x97, 0xaa, 0x86, 0x65,
+ 0x6b, 0x28, 0xad, 0xa1,
+ 0xad, 0xeb, 0x73, 0xa1,
+ 0x6b, 0x28, 0xad, 0x2a,
+ 0xad, 0xeb, 0x73, 0xfb,
+ 0x97, 0xaa, 0x86, 0x47,
+ 0x6b, 0x28, 0xad, 0x65,
+ 0x6b, 0x28, 0xad, 0x47,
+ 0xad, 0xeb, 0x73, 0x47,
+ 0x6b, 0x28, 0xad, 0xdd,
+ 0x6b, 0x28, 0xad, 0xa1,
+ 0x97, 0xaa, 0x86, 0x65,
+ 0xad, 0xeb, 0x73, 0xbf,
+ 0x97, 0xaa, 0x86, 0xa1,
+ 0xad, 0xeb, 0x73, 0xbf
+ },
+ {0xfb, 0x2a, 0x34, 0x19, 0xdc, 0xbf, 0xe8, 0x71, 0x4e, 0xaf, 0x55, 0x69, 0x18, 0x61, 0x51, 0x22}
+ },
+ {
+ {
+ 0x63, 0xd7, 0xd6, 0x00,
+ 0x57, 0x62, 0x5d, 0xf5,
+ 0x57, 0x62, 0x5d, 0xd2,
+ 0x57, 0x62, 0x5d, 0xaf,
+ 0x52, 0x28, 0x21, 0xaf,
+ 0x57, 0x62, 0x5d, 0xd2,
+ 0x57, 0x62, 0x5d, 0xd2,
+ 0x57, 0x62, 0x5d, 0x69,
+ 0x57, 0x62, 0x5d, 0x23,
+ 0x57, 0x62, 0x5d, 0xd2,
+ 0x63, 0xd7, 0xd6, 0xf5,
+ 0x57, 0x62, 0x5d, 0x46,
+ 0x63, 0xd7, 0xd6, 0x46,
+ 0x52, 0x28, 0x21, 0x69,
+ 0x57, 0x62, 0x5d, 0x23,
+ 0x5d, 0x9c, 0x99, 0xf5
+ },
+ {0xf5, 0x00, 0x81, 0x36, 0xa9, 0x17, 0xec, 0x1e, 0xba, 0x66, 0x44, 0x51, 0xfc, 0xfd, 0xcf, 0xb4}
+ },
+ {
+ {
+ 0x94, 0x6f, 0x60, 0x25,
+ 0x94, 0x6f, 0x60, 0x25,
+ 0xc5, 0xab, 0x76, 0x05,
+ 0xc5, 0xab, 0x76, 0xe8,
+ 0x63, 0x34, 0x4a, 0xe8,
+ 0x63, 0x34, 0x4a, 0x25,
+ 0x94, 0x6f, 0x60, 0x86,
+ 0xf7, 0xe7, 0x8c, 0x05,
+ 0x94, 0x6f, 0x60, 0x25,
+ 0x63, 0x34, 0x4a, 0xa7,
+ 0x94, 0x6f, 0x60, 0x66,
+ 0x63, 0x34, 0x4a, 0xc7,
+ 0x94, 0x6f, 0x60, 0xa7,
+ 0xf7, 0xe7, 0x8c, 0xa7,
+ 0x63, 0x34, 0x4a, 0x45,
+ 0xc5, 0xab, 0x76, 0xa7
+ },
+ {0xe8, 0x05, 0x7f, 0x80, 0x33, 0x5f, 0xb5, 0x79, 0x31, 0xf7, 0xa9, 0x61, 0xaf, 0x35, 0x77, 0x93}
+ },
+};
+
+
+static INLINE void
+st_sample_dxt_pixel_block(enum pipe_format format,
+ const struct pipe_format_block *block,
+ uint8_t *raw,
+ float *rgba, unsigned rgba_stride,
+ unsigned w, unsigned h)
+{
+ const struct dxt_data *data;
+ unsigned n;
+ unsigned i;
+ unsigned x, y, ch;
+
+ switch(format) {
+ case PIPE_FORMAT_DXT1_RGB:
+ data = dxt1_rgb_data;
+ n = sizeof(dxt1_rgb_data)/sizeof(dxt1_rgb_data[0]);
+ break;
+ case PIPE_FORMAT_DXT1_RGBA:
+ data = dxt1_rgba_data;
+ n = sizeof(dxt1_rgba_data)/sizeof(dxt1_rgba_data[0]);
+ break;
+ case PIPE_FORMAT_DXT3_RGBA:
+ data = dxt3_rgba_data;
+ n = sizeof(dxt3_rgba_data)/sizeof(dxt3_rgba_data[0]);
+ break;
+ case PIPE_FORMAT_DXT5_RGBA:
+ data = dxt5_rgba_data;
+ n = sizeof(dxt5_rgba_data)/sizeof(dxt5_rgba_data[0]);
+ break;
+ default:
+ assert(0);
+ }
+
+ i = st_random() % n;
+
+ for(y = 0; y < h; ++y)
+ for(x = 0; x < w; ++x)
+ for(ch = 0; ch < 4; ++ch)
+ rgba[y*rgba_stride + x*4 + ch] = (float)(data[i].rgba[y*4*4 + x*4 + ch])/255.0f;
+
+ memcpy(raw, data[i].raw, block->size);
+}
+
+
+static INLINE void
+st_sample_generic_pixel_block(enum pipe_format format,
+ const struct pipe_format_block *block,
+ uint8_t *raw,
+ float *rgba, unsigned rgba_stride,
+ unsigned w, unsigned h)
+{
+ unsigned i;
+ unsigned x, y, ch;
+
+ for(i = 0; i < block->size; ++i)
+ raw[i] = (uint8_t)st_random();
+
+
+ pipe_tile_raw_to_rgba(format,
+ raw,
+ w, h,
+ rgba, rgba_stride);
+
+ if(format == PIPE_FORMAT_YCBCR || format == PIPE_FORMAT_YCBCR_REV) {
+ for(y = 0; y < h; ++y) {
+ for(x = 0; x < w; ++x) {
+ for(ch = 0; ch < 4; ++ch) {
+ unsigned offset = y*rgba_stride + x*4 + ch;
+ rgba[offset] = CLAMP(rgba[offset], 0.0f, 1.0f);
+ }
+ }
+ }
+ }
+}
+
+
+/**
+ * Randomly sample pixels.
+ */
+void
+st_sample_pixel_block(enum pipe_format format,
+ const struct pipe_format_block *block,
+ void *raw,
+ float *rgba, unsigned rgba_stride,
+ unsigned w, unsigned h)
+{
+ switch(format) {
+ case PIPE_FORMAT_DXT1_RGB:
+ case PIPE_FORMAT_DXT1_RGBA:
+ case PIPE_FORMAT_DXT3_RGBA:
+ case PIPE_FORMAT_DXT5_RGBA:
+ st_sample_dxt_pixel_block(format, block, raw, rgba, rgba_stride, w, h);
+ break;
+
+ default:
+ st_sample_generic_pixel_block(format, block, raw, rgba, rgba_stride, w, h);
+ break;
+ }
+}
+
+
+void
+st_sample_surface(struct pipe_surface *surface, float *rgba)
+{
+ const struct pipe_format_block *block = &surface->block;
+ unsigned rgba_stride = surface->width*4;
+ void *raw;
+ unsigned x, y;
+
+ raw = pipe_surface_map(surface, PIPE_BUFFER_USAGE_CPU_READ);
+ if(!raw)
+ return;
+
+ for (y = 0; y < surface->nblocksy; ++y) {
+ for(x = 0; x < surface->nblocksx; ++x) {
+ st_sample_pixel_block(surface->format,
+ block,
+ (uint8_t*)raw + y*surface->stride + x*block->size,
+ rgba + y*block->height*rgba_stride + x*block->width*4,
+ rgba_stride,
+ MIN2(block->width, surface->width - x*block->width),
+ MIN2(block->height, surface->height - y*block->height));
+ }
+ }
+
+ pipe_surface_unmap(surface);
+}
diff --git a/src/gallium/state_trackers/python/st_sample.h b/src/gallium/state_trackers/python/st_sample.h
new file mode 100644
index 0000000000..ff04a12613
--- /dev/null
+++ b/src/gallium/state_trackers/python/st_sample.h
@@ -0,0 +1,47 @@
+/**************************************************************************
+ *
+ * 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 ST_SAMPLE_H_
+#define ST_SAMPLE_H_
+
+
+#include "pipe/p_format.h"
+
+
+void
+st_sample_pixel_block(enum pipe_format format,
+ const struct pipe_format_block *block,
+ void *raw,
+ float *rgba, unsigned rgba_stride,
+ unsigned w, unsigned h);
+
+void
+st_sample_surface(struct pipe_surface *surface, float *rgba);
+
+
+#endif /* ST_SAMPLE_H_ */
diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c
index 964d60de1d..1fda70ca00 100644
--- a/src/gallium/state_trackers/python/st_softpipe_winsys.c
+++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c
@@ -313,7 +313,7 @@ st_softpipe_context_create(struct pipe_screen *screen)
}
-const struct st_winsys st_software_winsys = {
+const struct st_winsys st_softpipe_winsys = {
&st_softpipe_screen_create,
&st_softpipe_screen_destroy,
&st_softpipe_context_create,
diff --git a/src/gallium/state_trackers/python/st_winsys.h b/src/gallium/state_trackers/python/st_winsys.h
index 992fc9ab4b..43db8b6bff 100644
--- a/src/gallium/state_trackers/python/st_winsys.h
+++ b/src/gallium/state_trackers/python/st_winsys.h
@@ -50,9 +50,9 @@ struct st_winsys
};
-extern const struct st_winsys st_software_winsys;
+extern const struct st_winsys st_softpipe_winsys;
-extern const struct st_winsys st_hardware_winsys;
+extern const struct st_winsys st_hardpipe_winsys;
#endif /* ST_WINSYS_H_ */
diff --git a/src/gallium/state_trackers/python/tests/base.py b/src/gallium/state_trackers/python/tests/base.py
new file mode 100644
index 0000000000..8477aa5fc9
--- /dev/null
+++ b/src/gallium/state_trackers/python/tests/base.py
@@ -0,0 +1,193 @@
+#!/usr/bin/env python
+##########################################################################
+#
+# 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.
+#
+##########################################################################
+
+
+"""Base classes for tests.
+
+Loosely inspired on Python's unittest module.
+"""
+
+
+from gallium import *
+
+
+# Enumerate all pixel formats
+formats = {}
+for name, value in globals().items():
+ if name.startswith("PIPE_FORMAT_") and isinstance(value, int):
+ formats[value] = name
+
+
+def make_image(width, height, rgba):
+ import Image
+ outimage = Image.new(
+ mode='RGB',
+ size=(width, height),
+ color=(0,0,0))
+ outpixels = outimage.load()
+ for y in range(0, height):
+ for x in range(0, width):
+ offset = (y*width + x)*4
+ r, g, b, a = [int(min(max(rgba[offset + ch], 0.0), 1.0)*255) for ch in range(4)]
+ outpixels[x, y] = r, g, b
+ return outimage
+
+def save_image(width, height, rgba, filename):
+ outimage = make_image(width, height, rgba)
+ outimage.save(filename, "PNG")
+
+def show_image(width, height, **rgbas):
+ import Tkinter as tk
+ from PIL import Image, ImageTk
+
+ root = tk.Tk()
+
+ x = 64
+ y = 64
+
+ labels = rgbas.keys()
+ labels.sort()
+ for i in range(len(labels)):
+ label = labels[i]
+ outimage = make_image(width, height, rgbas[label])
+
+ if i:
+ window = tk.Toplevel(root)
+ else:
+ window = root
+ window.title(label)
+ image1 = ImageTk.PhotoImage(outimage)
+ w = image1.width()
+ h = image1.height()
+ window.geometry("%dx%d+%d+%d" % (w, h, x, y))
+ panel1 = tk.Label(window, image=image1)
+ panel1.pack(side='top', fill='both', expand='yes')
+ panel1.image = image1
+ x += w + 2
+
+ root.mainloop()
+
+
+class TestFailure(Exception):
+
+ pass
+
+class TestSkip(Exception):
+
+ pass
+
+
+class Test:
+
+ def __init__(self):
+ pass
+
+ def _run(self, result):
+ raise NotImplementedError
+
+ def run(self):
+ result = TestResult()
+ self._run(result)
+ result.summary()
+
+
+class TestCase(Test):
+
+ def __init__(self, dev, **kargs):
+ Test.__init__(self)
+ self.dev = dev
+ self.__dict__.update(kargs)
+
+ def description(self):
+ raise NotImplementedError
+
+ def test(self):
+ raise NotImplementedError
+
+ def _run(self, result):
+ result.test_start(self)
+ try:
+ self.test()
+ except KeyboardInterrupt:
+ raise
+ except TestSkip:
+ result.test_skipped(self)
+ except TestFailure:
+ result.test_failed(self)
+ else:
+ result.test_passed(self)
+
+
+class TestSuite(Test):
+
+ def __init__(self, tests = None):
+ Test.__init__(self)
+ if tests is None:
+ self.tests = []
+ else:
+ self.tests = tests
+
+ def add_test(self, test):
+ self.tests.append(test)
+
+ def _run(self, result):
+ for test in self.tests:
+ test._run(result)
+
+
+class TestResult:
+
+ def __init__(self):
+ self.tests = 0
+ self.passed = 0
+ self.skipped = 0
+ self.failed = 0
+ self.failed_descriptions = []
+
+ def test_start(self, test):
+ self.tests += 1
+ print "Running %s..." % test.description()
+
+ def test_passed(self, test):
+ self.passed += 1
+ print "PASS"
+
+ def test_skipped(self, test):
+ self.skipped += 1
+ print "SKIP"
+
+ def test_failed(self, test):
+ self.failed += 1
+ self.failed_descriptions.append(test.description())
+ print "FAIL"
+
+ def summary(self):
+ print "%u tests, %u passed, %u skipped, %u failed" % (self.tests, self.passed, self.skipped, self.failed)
+ for description in self.failed_descriptions:
+ print " %s" % description
+ \ No newline at end of file
diff --git a/src/gallium/state_trackers/python/tests/texture.py b/src/gallium/state_trackers/python/tests/texture.py
new file mode 100644
index 0000000000..880a61306c
--- /dev/null
+++ b/src/gallium/state_trackers/python/tests/texture.py
@@ -0,0 +1,397 @@
+#!/usr/bin/env python
+##########################################################################
+#
+# 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.
+#
+##########################################################################
+
+
+import sys
+from gallium import *
+from base import *
+
+
+def lods(*dims):
+ size = max(dims)
+ lods = 0
+ while size:
+ lods += 1
+ size >>= 1
+ return lods
+
+
+def minify(dims, level = 1):
+ return [max(dim>>level, 1) for dim in dims]
+
+
+def tex_coords(texture, face, level, zslice):
+ st = [
+ [0.0, 0.0],
+ [1.0, 0.0],
+ [1.0, 1.0],
+ [0.0, 1.0],
+ ]
+
+ if texture.target == PIPE_TEXTURE_2D:
+ return [[s, t, 0.0] for s, t in st]
+ elif texture.target == PIPE_TEXTURE_3D:
+ depth = texture.get_depth(level)
+ if depth > 1:
+ r = float(zslice)/float(depth - 1)
+ else:
+ r = 0.0
+ return [[s, t, r] for s, t in st]
+ elif texture.target == PIPE_TEXTURE_CUBE:
+ result = []
+ for s, t in st:
+ # See http://developer.nvidia.com/object/cube_map_ogl_tutorial.html
+ sc = 2.0*s - 1.0
+ tc = 2.0*t - 1.0
+ if face == PIPE_TEX_FACE_POS_X:
+ rx = 1.0
+ ry = -tc
+ rz = -sc
+ if face == PIPE_TEX_FACE_NEG_X:
+ rx = -1.0
+ ry = -tc
+ rz = sc
+ if face == PIPE_TEX_FACE_POS_Y:
+ rx = sc
+ ry = 1.0
+ rz = tc
+ if face == PIPE_TEX_FACE_NEG_Y:
+ rx = sc
+ ry = -1.0
+ rz = -tc
+ if face == PIPE_TEX_FACE_POS_Z:
+ rx = sc
+ ry = -tc
+ rz = 1.0
+ if face == PIPE_TEX_FACE_NEG_Z:
+ rx = -sc
+ ry = -tc
+ rz = -1.0
+ result.append([rx, ry, rz])
+ return result
+
+def is_pot(n):
+ return n & (n - 1) == 0
+
+
+class TextureTest(TestCase):
+
+ def description(self):
+ target = {
+ PIPE_TEXTURE_1D: "1d",
+ PIPE_TEXTURE_2D: "2d",
+ PIPE_TEXTURE_3D: "3d",
+ PIPE_TEXTURE_CUBE: "cube",
+ }[self.target]
+ format = formats[self.format]
+ if self.target == PIPE_TEXTURE_CUBE:
+ face = {
+ PIPE_TEX_FACE_POS_X: "+x",
+ PIPE_TEX_FACE_NEG_X: "-x",
+ PIPE_TEX_FACE_POS_Y: "+y",
+ PIPE_TEX_FACE_NEG_Y: "-y",
+ PIPE_TEX_FACE_POS_Z: "+z",
+ PIPE_TEX_FACE_NEG_Z: "-z",
+ }[self.face]
+ else:
+ face = ""
+ return "%s %s %ux%ux%u last_level=%u face=%s level=%u zslice=%u" % (
+ target, format,
+ self.width, self.height, self.depth, self.last_level,
+ face, self.level, self.zslice,
+ )
+
+ def test(self):
+ dev = self.dev
+
+ target = self.target
+ format = self.format
+ width = self.width
+ height = self.height
+ depth = self.depth
+ last_level = self.last_level
+ face = self.face
+ level = self.level
+ zslice = self.zslice
+
+ tex_usage = PIPE_TEXTURE_USAGE_SAMPLER
+ geom_flags = 0
+ if width != height:
+ geom_flags |= PIPE_TEXTURE_GEOM_NON_SQUARE
+ if not is_pot(width) or not is_pot(height) or not is_pot(depth):
+ geom_flags |= PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO
+
+ if not dev.is_format_supported(format, target, tex_usage, geom_flags):
+ raise TestSkip
+
+ ctx = self.dev.context_create()
+
+ # disabled blending/masking
+ blend = Blend()
+ blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.colormask = PIPE_MASK_RGBA
+ ctx.set_blend(blend)
+
+ # no-op depth/stencil/alpha
+ depth_stencil_alpha = DepthStencilAlpha()
+ ctx.set_depth_stencil_alpha(depth_stencil_alpha)
+
+ # rasterizer
+ rasterizer = Rasterizer()
+ rasterizer.front_winding = PIPE_WINDING_CW
+ rasterizer.cull_mode = PIPE_WINDING_NONE
+ rasterizer.bypass_clipping = 1
+ #rasterizer.bypass_vs = 1
+ ctx.set_rasterizer(rasterizer)
+
+ # viewport (identity, we setup vertices in wincoords)
+ viewport = Viewport()
+ scale = FloatArray(4)
+ scale[0] = 1.0
+ scale[1] = 1.0
+ scale[2] = 1.0
+ scale[3] = 1.0
+ viewport.scale = scale
+ translate = FloatArray(4)
+ translate[0] = 0.0
+ translate[1] = 0.0
+ translate[2] = 0.0
+ translate[3] = 0.0
+ viewport.translate = translate
+ ctx.set_viewport(viewport)
+
+ # samplers
+ sampler = Sampler()
+ sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE
+ sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE
+ sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE
+ sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST
+ sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST
+ sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST
+ sampler.normalized_coords = 1
+ sampler.min_lod = 0
+ sampler.max_lod = PIPE_MAX_TEXTURE_LEVELS - 1
+ ctx.set_sampler(0, sampler)
+
+ # texture
+ texture = dev.texture_create(
+ target = target,
+ format = format,
+ width = width,
+ height = height,
+ depth = depth,
+ last_level = last_level,
+ tex_usage = tex_usage,
+ )
+
+ expected_rgba = FloatArray(height*width*4)
+ texture.get_surface(
+ usage = PIPE_BUFFER_USAGE_CPU_READ|PIPE_BUFFER_USAGE_CPU_WRITE,
+ face = face,
+ level = level,
+ zslice = zslice,
+ ).sample_rgba(expected_rgba)
+
+ ctx.set_sampler_texture(0, texture)
+
+ # framebuffer
+ cbuf_tex = dev.texture_create(
+ PIPE_FORMAT_A8R8G8B8_UNORM,
+ width,
+ height,
+ tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET,
+ )
+
+ cbuf = cbuf_tex.get_surface(usage = PIPE_BUFFER_USAGE_GPU_WRITE|PIPE_BUFFER_USAGE_GPU_READ)
+ fb = Framebuffer()
+ fb.width = width
+ fb.height = height
+ fb.num_cbufs = 1
+ fb.set_cbuf(0, cbuf)
+ ctx.set_framebuffer(fb)
+ ctx.surface_clear(cbuf, 0x00000000)
+ del fb
+
+ # vertex shader
+ vs = Shader('''
+ VERT1.1
+ DCL IN[0], POSITION, CONSTANT
+ DCL IN[1], GENERIC, CONSTANT
+ DCL OUT[0], POSITION, CONSTANT
+ DCL OUT[1], GENERIC, CONSTANT
+ 0:MOV OUT[0], IN[0]
+ 1:MOV OUT[1], IN[1]
+ 2:END
+ ''')
+ #vs.dump()
+ ctx.set_vertex_shader(vs)
+
+ # fragment shader
+ op = {
+ PIPE_TEXTURE_1D: "1D",
+ PIPE_TEXTURE_2D: "2D",
+ PIPE_TEXTURE_3D: "3D",
+ PIPE_TEXTURE_CUBE: "CUBE",
+ }[target]
+ fs = Shader('''
+ FRAG1.1
+ DCL IN[0], GENERIC[0], LINEAR
+ DCL OUT[0], COLOR, CONSTANT
+ DCL SAMP[0], CONSTANT
+ 0:TEX OUT[0], IN[0], SAMP[0], %s
+ 1:END
+ ''' % op)
+ #fs.dump()
+ ctx.set_fragment_shader(fs)
+
+ nverts = 4
+ nattrs = 2
+ verts = FloatArray(nverts * nattrs * 4)
+
+ x = 0
+ y = 0
+ w, h = minify((width, height), level)
+
+ pos = [
+ [x, y],
+ [x+w, y],
+ [x+w, y+h],
+ [x, y+h],
+ ]
+
+ tex = tex_coords(texture, face, level, zslice)
+
+ for i in range(0, 4):
+ j = 8*i
+ verts[j + 0] = pos[i][0] # x
+ verts[j + 1] = pos[i][1] # y
+ verts[j + 2] = 0.0 # z
+ verts[j + 3] = 1.0 # w
+ verts[j + 4] = tex[i][0] # s
+ verts[j + 5] = tex[i][1] # r
+ verts[j + 6] = tex[i][2] # q
+ verts[j + 7] = 1.0
+
+ ctx.draw_vertices(PIPE_PRIM_TRIANGLE_FAN,
+ nverts,
+ nattrs,
+ verts)
+
+ ctx.flush()
+
+ cbuf = cbuf_tex.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ)
+
+ total = h*w
+ different = cbuf.compare_tile_rgba(x, y, w, h, expected_rgba, tol=4.0/256)
+ if different:
+ sys.stderr.write("%u out of %u pixels differ\n" % (different, total))
+
+ if float(total - different)/float(total) < 0.85:
+
+ if 0:
+ rgba = FloatArray(h*w*4)
+ cbuf.get_tile_rgba(x, y, w, h, rgba)
+ show_image(w, h, Result=rgba, Expected=expected_rgba)
+ save_image(w, h, rgba, "result.png")
+ save_image(w, h, expected_rgba, "expected.png")
+ #sys.exit(0)
+
+ raise TestFailure
+
+ del ctx
+
+
+
+def main():
+ dev = Device()
+ suite = TestSuite()
+
+ targets = []
+ targets += [PIPE_TEXTURE_2D]
+ targets += [PIPE_TEXTURE_CUBE]
+ targets += [PIPE_TEXTURE_3D]
+
+ formats = []
+ formats += [PIPE_FORMAT_A8R8G8B8_UNORM]
+ formats += [PIPE_FORMAT_R5G6B5_UNORM]
+ formats += [PIPE_FORMAT_L8_UNORM]
+ formats += [PIPE_FORMAT_YCBCR]
+ formats += [PIPE_FORMAT_DXT1_RGB]
+
+ sizes = [64, 32, 16, 8, 4, 2, 1]
+ #sizes = [1020, 508, 252, 62, 30, 14, 6, 3]
+ #sizes = [64]
+ #sizes = [63]
+
+ for target in targets:
+ for format in formats:
+ for size in sizes:
+ if target == PIPE_TEXTURE_CUBE:
+ faces = [
+ PIPE_TEX_FACE_POS_X,
+ PIPE_TEX_FACE_NEG_X,
+ PIPE_TEX_FACE_POS_Y,
+ PIPE_TEX_FACE_NEG_Y,
+ PIPE_TEX_FACE_POS_Z,
+ PIPE_TEX_FACE_NEG_Z,
+ ]
+ #faces = [PIPE_TEX_FACE_NEG_X]
+ else:
+ faces = [0]
+ if target == PIPE_TEXTURE_3D:
+ depth = size
+ else:
+ depth = 1
+ for face in faces:
+ levels = lods(size)
+ for last_level in range(levels):
+ for level in range(0, last_level + 1):
+ zslice = 0
+ while zslice < depth >> level:
+ test = TextureTest(
+ dev = dev,
+ target = target,
+ format = format,
+ width = size,
+ height = size,
+ depth = depth,
+ last_level = last_level,
+ face = face,
+ level = level,
+ zslice = zslice,
+ )
+ suite.add_test(test)
+ zslice = (zslice + 1)*2 - 1
+ suite.run()
+
+
+if __name__ == '__main__':
+ main()