diff options
author | Dave Airlie <[email protected]> | 2009-04-09 10:14:35 +1000 |
---|---|---|
committer | Dave Airlie <[email protected]> | 2009-04-09 10:31:08 +1000 |
commit | d1a9b1f513109c975a5a7ed5a2d0c329b280afe4 (patch) | |
tree | 5c85af47b4f5af0661acf129e3ce3f59e43cbfd9 /src/gallium | |
parent | 90ffce497395d8c02fee2ea4ee4c025eede3d876 (diff) | |
parent | 8648c2685870174cf620ef15de70ef030a8d5a20 (diff) |
Merge remote branch 'origin/master' into radeon-rewrite
Conflicts:
src/mesa/drivers/dri/r200/r200_tex.c
src/mesa/drivers/dri/r300/r300_cmdbuf.c
src/mesa/drivers/dri/r300/r300_context.h
src/mesa/drivers/dri/r300/r300_swtcl.c
src/mesa/drivers/dri/r300/r300_tex.c
src/mesa/drivers/dri/r300/r300_texmem.c
src/mesa/drivers/dri/r300/r300_texstate.c
src/mesa/drivers/dri/radeon/radeon_tex.c
Diffstat (limited to 'src/gallium')
222 files changed, 6688 insertions, 1291 deletions
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index 5008086cf26..3133abe5dc7 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -286,7 +286,7 @@ aa_transform_inst(struct tgsi_transform_context *ctx, ctx->emit_instruction(ctx, &newInst); #endif - /* SGT t0.y, t0.xxxx, t0.wwww; # bool b = d > 1 (NOTE t0.w == 1) */ + /* SGT t0.y, t0.xxxx, tex.wwww; # bool b = d > 1 (NOTE tex.w == 1) */ newInst = tgsi_default_full_instruction(); newInst.Instruction.Opcode = TGSI_OPCODE_SGT; newInst.Instruction.NumDstRegs = 1; diff --git a/src/gallium/auxiliary/draw/draw_vertex.h b/src/gallium/auxiliary/draw/draw_vertex.h index c143cf23723..554f4ac3c18 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.h +++ b/src/gallium/auxiliary/draw/draw_vertex.h @@ -87,18 +87,17 @@ struct vertex_info } attrib[PIPE_MAX_SHADER_INPUTS]; }; -static INLINE int +static INLINE size_t draw_vinfo_size( const struct vertex_info *a ) { - return ((const char *)&a->attrib[a->num_attribs] - - (const char *)a); + return offsetof(const struct vertex_info, attrib[a->num_attribs]); } static INLINE int draw_vinfo_compare( const struct vertex_info *a, const struct vertex_info *b ) { - unsigned sizea = draw_vinfo_size( a ); + size_t sizea = draw_vinfo_size( a ); return memcmp( a, b, sizea ); } @@ -106,7 +105,7 @@ static INLINE void draw_vinfo_copy( struct vertex_info *dst, const struct vertex_info *src ) { - unsigned size = draw_vinfo_size( src ); + size_t size = draw_vinfo_size( src ); memcpy( dst, src, size ); } diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index b3200df8112..dbbc33fffa7 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -151,6 +151,7 @@ vs_exec_run_linear( struct draw_vertex_shader *shader, output[slot][1], output[slot][2], output[slot][3]); + assert(!util_is_inf_or_nan(output[slot][0])); } #endif diff --git a/src/gallium/auxiliary/indices/SConscript b/src/gallium/auxiliary/indices/SConscript index e5f7ee94845..712e215534f 100644 --- a/src/gallium/auxiliary/indices/SConscript +++ b/src/gallium/auxiliary/indices/SConscript @@ -1,17 +1,19 @@ Import('*') +from sys import executable as python_cmd + env.CodeGenerate( target = 'u_indices_gen.c', script = 'u_indices_gen.py', source = [], - command = 'python $SCRIPT > $TARGET' + command = python_cmd + ' $SCRIPT > $TARGET' ) env.CodeGenerate( target = 'u_unfilled_gen.c', script = 'u_unfilled_gen.py', source = [], - command = 'python $SCRIPT > $TARGET' + command = python_cmd + ' $SCRIPT > $TARGET' ) indices = env.ConvenienceLibrary( diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h index 2a1315922a8..92b6fd00564 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h @@ -158,7 +158,7 @@ pb_map(struct pb_buffer *buf, assert(buf); if(!buf) return NULL; - assert(p_atomic_read(&buf->base.reference.count) > 0); + assert(pipe_is_referenced(&buf->base.reference)); return buf->vtbl->map(buf, flags); } @@ -169,7 +169,7 @@ pb_unmap(struct pb_buffer *buf) assert(buf); if(!buf) return; - assert(p_atomic_read(&buf->base.reference.count) > 0); + assert(pipe_is_referenced(&buf->base.reference)); buf->vtbl->unmap(buf); } @@ -185,7 +185,7 @@ pb_get_base_buffer( struct pb_buffer *buf, offset = 0; return; } - assert(p_atomic_read(&buf->base.reference.count) > 0); + assert(pipe_is_referenced(&buf->base.reference)); assert(buf->vtbl->get_base_buffer); buf->vtbl->get_base_buffer(buf, base_buf, offset); assert(*base_buf); @@ -221,7 +221,7 @@ pb_destroy(struct pb_buffer *buf) assert(buf); if(!buf) return; - assert(p_atomic_read(&buf->base.reference.count) == 0); + assert(!pipe_is_referenced(&buf->base.reference)); buf->vtbl->destroy(buf); } diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index 1bdf7a0b2da..2cd0b8a8cdf 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -36,7 +36,7 @@ #include "pipe/p_config.h" -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) #include <unistd.h> #include <sched.h> #endif @@ -115,7 +115,7 @@ _fenced_buffer_add(struct fenced_buffer *fenced_buf) { struct fenced_buffer_list *fenced_list = fenced_buf->list; - assert(p_atomic_read(&fenced_buf->base.base.reference.count)); + assert(pipe_is_referenced(&fenced_buf->base.base.reference)); assert(fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE); assert(fenced_buf->fence); @@ -137,7 +137,7 @@ _fenced_buffer_destroy(struct fenced_buffer *fenced_buf) { struct fenced_buffer_list *fenced_list = fenced_buf->list; - assert(p_atomic_read(&fenced_buf->base.base.reference.count) == 0); + assert(!pipe_is_referenced(&fenced_buf->base.base.reference)); assert(!fenced_buf->fence); #ifdef DEBUG assert(fenced_buf->head.prev); @@ -181,7 +181,7 @@ _fenced_buffer_remove(struct fenced_buffer_list *fenced_list, * FIXME!!! */ - if(!p_atomic_read(&fenced_buf->base.base.reference.count)) + if(!pipe_is_referenced(&fenced_buf->base.base.reference)) _fenced_buffer_destroy(fenced_buf); } @@ -257,7 +257,7 @@ fenced_buffer_destroy(struct pb_buffer *buf) struct fenced_buffer_list *fenced_list = fenced_buf->list; pipe_mutex_lock(fenced_list->mutex); - assert(p_atomic_read(&fenced_buf->base.base.reference.count) == 0); + assert(!pipe_is_referenced(&fenced_buf->base.base.reference)); if (fenced_buf->fence) { struct pb_fence_ops *ops = fenced_list->ops; if(ops->fence_signalled(ops, fenced_buf->fence, 0) == 0) { @@ -573,7 +573,7 @@ fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list) /* Wait on outstanding fences */ while (fenced_list->numDelayed) { pipe_mutex_unlock(fenced_list->mutex); -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) sched_yield(); #endif _fenced_buffer_list_check_free(fenced_list, 1); diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c index 010a2ecc1fa..35358430b43 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c @@ -112,7 +112,7 @@ _pb_cache_buffer_destroy(struct pb_cache_buffer *buf) LIST_DEL(&buf->head); assert(mgr->numDelayed); --mgr->numDelayed; - assert(p_atomic_read(&buf->base.base.reference.count) == 0); + assert(!pipe_is_referenced(&buf->base.base.reference)); pb_reference(&buf->buffer, NULL); FREE(buf); } @@ -153,7 +153,7 @@ pb_cache_buffer_destroy(struct pb_buffer *_buf) struct pb_cache_manager *mgr = buf->mgr; pipe_mutex_lock(mgr->mutex); - assert(p_atomic_read(&buf->base.base.reference.count) == 0); + assert(!pipe_is_referenced(&buf->base.base.reference)); _pb_cache_buffer_list_check_free(mgr); @@ -310,7 +310,7 @@ pb_cache_manager_create_buffer(struct pb_manager *_mgr, return NULL; } - assert(p_atomic_read(&buf->buffer->base.reference.count) >= 1); + assert(pipe_is_referenced(&buf->buffer->base.reference)); assert(pb_check_alignment(desc->alignment, buf->buffer->base.alignment)); assert(pb_check_usage(desc->usage, buf->buffer->base.usage)); assert(buf->buffer->base.size >= size); diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c index 478682dbee9..f1a05be46e4 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c @@ -208,7 +208,7 @@ pb_debug_buffer_destroy(struct pb_buffer *_buf) { struct pb_debug_buffer *buf = pb_debug_buffer(_buf); - assert(p_atomic_read(&buf->base.base.reference.count) == 0); + assert(!pipe_is_referenced(&buf->base.base.reference)); pb_debug_buffer_check(buf); @@ -315,7 +315,7 @@ pb_debug_manager_create_buffer(struct pb_manager *_mgr, return NULL; } - assert(p_atomic_read(&buf->buffer->base.reference.count) >= 1); + assert(pipe_is_referenced(&buf->buffer->base.reference)); assert(pb_check_alignment(real_desc.alignment, buf->buffer->base.alignment)); assert(pb_check_usage(real_desc.usage, buf->buffer->base.usage)); assert(buf->buffer->base.size >= real_size); diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c index fb18dcc5dca..5a342fbf3b1 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c @@ -97,7 +97,7 @@ mm_buffer_destroy(struct pb_buffer *buf) struct mm_buffer *mm_buf = mm_buffer(buf); struct mm_pb_manager *mm = mm_buf->mgr; - assert(p_atomic_read(&mm_buf->base.base.reference.count) == 0); + assert(!pipe_is_referenced(&mm_buf->base.base.reference)); pipe_mutex_lock(mm->mutex); u_mmFreeMem(mm_buf->block); diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c index 75b95e132e8..07fd1a22d93 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c @@ -108,7 +108,7 @@ pool_buffer_destroy(struct pb_buffer *buf) struct pool_buffer *pool_buf = pool_buffer(buf); struct pool_pb_manager *pool = pool_buf->mgr; - assert(p_atomic_read(&pool_buf->base.base.reference.count) == 0); + assert(!pipe_is_referenced(&pool_buf->base.base.reference)); pipe_mutex_lock(pool->mutex); LIST_ADD(&pool_buf->head, &pool->free); @@ -216,7 +216,7 @@ pool_bufmgr_create_buffer(struct pb_manager *mgr, pipe_mutex_unlock(pool->mutex); pool_buf = LIST_ENTRY(struct pool_buffer, item, head); - assert(p_atomic_read(&pool_buf->base.base.reference.count) == 0); + assert(!pipe_is_referenced(&pool_buf->base.base.reference)); pipe_reference_init(&pool_buf->base.base.reference, 1); pool_buf->base.base.alignment = desc->alignment; pool_buf->base.base.usage = desc->usage; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c index a431fd5211e..724aaadb436 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c @@ -202,7 +202,7 @@ pb_slab_buffer_destroy(struct pb_buffer *_buf) pipe_mutex_lock(mgr->mutex); - assert(p_atomic_read(&buf->base.base.reference.count) == 0); + assert(!pipe_is_referenced(&buf->base.base.reference)); buf->mapCount = 0; diff --git a/src/gallium/auxiliary/rtasm/rtasm_execmem.c b/src/gallium/auxiliary/rtasm/rtasm_execmem.c index 1f0923b6831..01811d50114 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_execmem.c +++ b/src/gallium/auxiliary/rtasm/rtasm_execmem.c @@ -42,7 +42,7 @@ #endif -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) /* @@ -118,7 +118,7 @@ rtasm_exec_free(void *addr) } -#else /* PIPE_OS_LINUX || PIPE_OS_BSD */ +#else /* PIPE_OS_LINUX || PIPE_OS_BSD || PIPE_OS_SOLARIS */ /* * Just use regular memory. @@ -138,4 +138,4 @@ rtasm_exec_free(void *addr) } -#endif /* PIPE_OS_LINUX || PIPE_OS_BSD */ +#endif /* PIPE_OS_LINUX || PIPE_OS_BSD || PIPE_OS_SOLARIS */ diff --git a/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt b/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt index 5b21a2be0bd..a3f4947c734 100644 --- a/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt +++ b/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt @@ -262,7 +262,7 @@ TGSI Instruction Specification dst.w = round(src.w) -1.3.10 EXPBASE2 - Exponent Base 2 +1.3.10 EXPBASE2 - Exponential Base 2 dst.x = pow(2.0, src.x) dst.y = pow(2.0, src.x) @@ -382,9 +382,7 @@ TGSI Instruction Specification 1.5.7 KILP - Predicated Discard - if (cc.x || cc.y || cc.z || cc.w) - discard - endif + discard 1.5.8 LG2 - Logarithm Base 2 @@ -548,7 +546,7 @@ TGSI Instruction Specification 1.6.3 BRA - Branch - TBD + pc = target 1.6.4 CAL - Subroutine Call @@ -1038,3 +1036,74 @@ TGSI Instruction Specification Alias for ARR. + +2 Explanation of symbols used +============================== + + +2.1 Functions +-------------- + + + abs(x) Absolute value of x. + |x| + (x < 0.0) ? -x : x + + ceil(x) Ceiling of x. + + clamp(x,y,z) Clamp x between y and z. + (x < y) ? y : (x > z) ? z : x + + cos(x) Cosine of x. + + floor(x) Floor of x. + + lg2(x) Logarithm base 2 of x. + + max(x,y) Maximum of x and y. + (x > y) ? x : y + + min(x,y) Minimum of x and y. + (x < y) ? x : y + + partialx(x) Derivative of x relative to fragment's X. + + partialy(x) Derivative of x relative to fragment's Y. + + pop() Pop from stack. + + pow(x,y) Raise x to power of y. + + push(x) Push x on stack. + + round(x) Round x. + + sin(x) Sine of x. + + sqrt(x) Square root of x. + + trunc(x) Truncate x. + + +2.2 Keywords +------------- + + + discard Discard fragment. + + dst First destination register. + + dst0 First destination register. + + pc Program counter. + + src First source register. + + src0 First source register. + + src1 Second source register. + + src2 Third source register. + + target Label of target instruction. + diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index ba807e498f1..e8bd7cda3b1 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -123,6 +123,53 @@ #define UPDATE_EXEC_MASK(MACH) \ MACH->ExecMask = MACH->CondMask & MACH->LoopMask & MACH->ContMask & MACH->FuncMask + +static const union tgsi_exec_channel ZeroVec = + { { 0.0, 0.0, 0.0, 0.0 } }; + + +#ifdef DEBUG +static void +check_inf_or_nan(const union tgsi_exec_channel *chan) +{ + assert(!util_is_inf_or_nan(chan->f[0])); + assert(!util_is_inf_or_nan(chan->f[1])); + assert(!util_is_inf_or_nan(chan->f[2])); + assert(!util_is_inf_or_nan(chan->f[3])); +} +#endif + + +#ifdef DEBUG +static void +print_chan(const char *msg, const union tgsi_exec_channel *chan) +{ + debug_printf("%s = {%f, %f, %f, %f}\n", + msg, chan->f[0], chan->f[1], chan->f[2], chan->f[3]); +} +#endif + + +#ifdef DEBUG +static void +print_temp(const struct tgsi_exec_machine *mach, uint index) +{ + const struct tgsi_exec_vector *tmp = &mach->Temps[index]; + int i; + debug_printf("Temp[%u] =\n", index); + for (i = 0; i < 4; i++) { + debug_printf(" %c: { %f, %f, %f, %f }\n", + "XYZW"[i], + tmp->xyzw[i].f[0], + tmp->xyzw[i].f[1], + tmp->xyzw[i].f[2], + tmp->xyzw[i].f[3]); + } +} +#endif + + + /** * Initialize machine state by expanding tokens to full instructions, * allocating temporary storage, setting up constants, etc. @@ -278,6 +325,12 @@ tgsi_exec_machine_init( mach->Temps[TEMP_3_I].xyzw[TEMP_3_C].f[i] = 3.0f; mach->Temps[TEMP_HALF_I].xyzw[TEMP_HALF_C].f[i] = 0.5f; } + +#ifdef DEBUG + /* silence warnings */ + (void) print_chan; + (void) print_temp; +#endif } @@ -1281,6 +1334,10 @@ store_dest( union tgsi_exec_channel *dst; uint execmask = mach->ExecMask; +#ifdef DEBUG + check_inf_or_nan(chan); +#endif + switch (reg->DstRegister.File) { case TGSI_FILE_NULL: dst = &null; @@ -1643,7 +1700,7 @@ exec_tex(struct tgsi_exec_machine *mach, lodBias = 0.0; fetch_texel(mach->Samplers[unit], - &r[0], NULL, NULL, lodBias, /* S, T, P, BIAS */ + &r[0], &ZeroVec, &ZeroVec, lodBias, /* S, T, P, BIAS */ &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */ break; @@ -1847,7 +1904,7 @@ exec_instruction( switch (inst->Instruction.Opcode) { case TGSI_OPCODE_ARL: - /* TGSI_OPCODE_FLOOR */ + case TGSI_OPCODE_FLOOR: /* TGSI_OPCODE_FLR */ FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( &r[0], 0, chan_index ); diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h index 4ffd4efbffa..0b4b2a6fb6e 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -205,8 +205,8 @@ struct tgsi_exec_machine const float (*Consts)[4]; struct tgsi_exec_vector *Inputs; struct tgsi_exec_vector *Outputs; - const struct tgsi_token *Tokens; - unsigned Processor; + const struct tgsi_token *Tokens; /**< Declarations, instructions */ + unsigned Processor; /**< TGSI_PROCESSOR_x */ /* GEOMETRY processor only. */ unsigned *Primitives; diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c index 2b8a6f0fb19..37f2b66d1f6 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_info.c +++ b/src/gallium/auxiliary/tgsi/tgsi_info.c @@ -30,125 +30,125 @@ static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] = { - { 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, 0, 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, 1, 0, 0, "KIL" }, - { 0, 0, 0, 0, "END" }, - { 1, 1, 0, 0, "SWZ" } + { 1, 1, 0, 0, "ARL", NULL, NULL }, + { 1, 1, 0, 0, "MOV", NULL, NULL }, + { 1, 1, 0, 0, "LIT", NULL, NULL }, + { 1, 1, 0, 0, "RCP", "RECIP", NULL }, + { 1, 1, 0, 0, "RSQ", "RECIPSQRT", NULL }, + { 1, 1, 0, 0, "EXP", "EXPP", NULL }, + { 1, 1, 0, 0, "LOG", NULL, NULL }, + { 1, 2, 0, 0, "MUL", NULL, NULL }, + { 1, 2, 0, 0, "ADD", NULL, NULL }, + { 1, 2, 0, 0, "DP3", "DOT3", NULL }, + { 1, 2, 0, 0, "DP4", "DOT4", NULL }, + { 1, 2, 0, 0, "DST", NULL, NULL }, + { 1, 2, 0, 0, "MIN", NULL, NULL }, + { 1, 2, 0, 0, "MAX", NULL, NULL }, + { 1, 2, 0, 0, "SLT", "SETLT", NULL }, + { 1, 2, 0, 0, "SGE", "SETGE", NULL }, + { 1, 3, 0, 0, "MAD", "MADD", NULL }, + { 1, 2, 0, 0, "SUB", NULL, NULL }, + { 1, 3, 0, 0, "LRP", "LERP", NULL }, + { 1, 3, 0, 0, "CND", NULL, NULL }, + { 1, 3, 0, 0, "CND0", NULL, NULL }, + { 1, 3, 0, 0, "DP2A", "DP2ADD", "DOT2ADD" }, + { 1, 2, 0, 0, "INDEX", NULL, NULL }, + { 1, 1, 0, 0, "NEGATE", NULL, NULL }, + { 1, 1, 0, 0, "FRC", "FRAC", NULL }, + { 1, 3, 0, 0, "CLAMP", NULL, NULL }, + { 1, 1, 0, 0, "FLR", "FLOOR", NULL }, + { 1, 1, 0, 0, "ROUND", NULL, NULL }, + { 1, 1, 0, 0, "EX2", "EXPBASE2", NULL }, + { 1, 1, 0, 0, "LG2", "LOGBASE2", "LOGP" }, + { 1, 2, 0, 0, "POW", "POWER", NULL }, + { 1, 2, 0, 0, "XPD", "CRS", "CROSSPRODUCT" }, + { 1, 2, 0, 0, "M4X4", "MULTIPLYMATRIX", NULL }, + { 1, 1, 0, 0, "ABS", NULL, NULL }, + { 1, 1, 0, 0, "RCC", NULL, NULL }, + { 1, 2, 0, 0, "DPH", NULL, NULL }, + { 1, 1, 0, 0, "COS", NULL, NULL }, + { 1, 1, 0, 0, "DDX", "DSX", NULL }, + { 1, 1, 0, 0, "DDY", "DSY", NULL }, + { 0, 0, 0, 0, "KILP", NULL, NULL }, + { 1, 1, 0, 0, "PK2H", NULL, NULL }, + { 1, 1, 0, 0, "PK2US", NULL, NULL }, + { 1, 1, 0, 0, "PK4B", NULL, NULL }, + { 1, 1, 0, 0, "PK4UB", NULL, NULL }, + { 1, 2, 0, 0, "RFL", NULL, NULL }, + { 1, 2, 0, 0, "SEQ", NULL, NULL }, + { 1, 2, 0, 0, "SFL", NULL, NULL }, + { 1, 2, 0, 0, "SGT", NULL, NULL }, + { 1, 1, 0, 0, "SIN", NULL, NULL }, + { 1, 2, 0, 0, "SLE", NULL, NULL }, + { 1, 2, 0, 0, "SNE", NULL, NULL }, + { 1, 2, 0, 0, "STR", NULL, NULL }, + { 1, 2, 1, 0, "TEX", "TEXLD", NULL }, + { 1, 4, 1, 0, "TXD", "TEXLDD", NULL }, + { 1, 2, 1, 0, "TXP", NULL, NULL }, + { 1, 1, 0, 0, "UP2H", NULL, NULL }, + { 1, 1, 0, 0, "UP2US", NULL, NULL }, + { 1, 1, 0, 0, "UP4B", NULL, NULL }, + { 1, 1, 0, 0, "UP4UB", NULL, NULL }, + { 1, 3, 0, 0, "X2D", NULL, NULL }, + { 1, 1, 0, 0, "ARA", NULL, NULL }, + { 1, 1, 0, 0, "ARR", "MOVA", NULL }, + { 0, 1, 0, 0, "BRA", NULL, NULL }, + { 0, 0, 0, 1, "CAL", "CALL", NULL }, + { 0, 0, 0, 0, "RET", NULL, NULL }, + { 1, 1, 0, 0, "SGN", "SSG", NULL }, + { 1, 3, 0, 0, "CMP", NULL, NULL }, + { 1, 1, 0, 0, "SCS", "SINCOS", NULL }, + { 1, 2, 1, 0, "TXB", "TEXLDB", NULL }, + { 1, 1, 0, 0, "NRM", NULL, NULL }, + { 1, 2, 0, 0, "DIV", NULL, NULL }, + { 1, 2, 0, 0, "DP2", NULL, NULL }, + { 1, 2, 1, 0, "TXL", NULL, NULL }, + { 0, 0, 0, 0, "BRK", "BREAK", NULL }, + { 0, 1, 0, 1, "IF", NULL, NULL }, + { 0, 0, 0, 0, "LOOP", NULL, NULL }, + { 0, 1, 0, 0, "REP", NULL, NULL }, + { 0, 0, 0, 1, "ELSE", NULL, NULL }, + { 0, 0, 0, 0, "ENDIF", NULL, NULL }, + { 0, 0, 0, 0, "ENDLOOP", NULL, NULL }, + { 0, 0, 0, 0, "ENDREP", NULL, NULL }, + { 0, 1, 0, 0, "PUSHA", NULL, NULL }, + { 1, 0, 0, 0, "POPA", NULL, NULL }, + { 1, 1, 0, 0, "CEIL", NULL, NULL }, + { 1, 1, 0, 0, "I2F", NULL, NULL }, + { 1, 1, 0, 0, "NOT", NULL, NULL }, + { 1, 1, 0, 0, "INT", "TRUNC", NULL }, + { 1, 2, 0, 0, "SHL", NULL, NULL }, + { 1, 2, 0, 0, "SHR", NULL, NULL }, + { 1, 2, 0, 0, "AND", NULL, NULL }, + { 1, 2, 0, 0, "OR", NULL, NULL }, + { 1, 2, 0, 0, "MOD", NULL, NULL }, + { 1, 2, 0, 0, "XOR", NULL, NULL }, + { 1, 3, 0, 0, "SAD", NULL, NULL }, + { 1, 2, 1, 0, "TXF", NULL, NULL }, + { 1, 2, 1, 0, "TXQ", NULL, NULL }, + { 0, 0, 0, 0, "CONT", NULL, NULL }, + { 0, 0, 0, 0, "EMIT", NULL, NULL }, + { 0, 0, 0, 0, "ENDPRIM", NULL, NULL }, + { 0, 0, 0, 1, "BGNLOOP2", NULL, NULL }, + { 0, 0, 0, 0, "BGNSUB", NULL, NULL }, + { 0, 0, 0, 1, "ENDLOOP2", NULL, NULL }, + { 0, 0, 0, 0, "ENDSUB", NULL, NULL }, + { 1, 1, 0, 0, "NOISE1", NULL, NULL }, + { 1, 1, 0, 0, "NOISE2", NULL, NULL }, + { 1, 1, 0, 0, "NOISE3", NULL, NULL }, + { 1, 1, 0, 0, "NOISE4", NULL, NULL }, + { 0, 0, 0, 0, "NOP", NULL, NULL }, + { 1, 2, 0, 0, "M4X3", NULL, NULL }, + { 1, 2, 0, 0, "M3X4", NULL, NULL }, + { 1, 2, 0, 0, "M3X3", NULL, NULL }, + { 1, 2, 0, 0, "M3X2", NULL, NULL }, + { 1, 1, 0, 0, "NRM4", NULL, NULL }, + { 0, 1, 0, 0, "CALLNZ", NULL, NULL }, + { 0, 1, 0, 0, "IFC", NULL, NULL }, + { 0, 1, 0, 0, "BREAKC", NULL, NULL }, + { 0, 1, 0, 0, "KIL", "TEXKILL", NULL }, + { 0, 0, 0, 0, "END", NULL, NULL }, + { 1, 1, 0, 0, "SWZ", NULL, NULL } }; const struct tgsi_opcode_info * diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.h b/src/gallium/auxiliary/tgsi/tgsi_info.h index 7230bdaae33..077e25acd7f 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_info.h +++ b/src/gallium/auxiliary/tgsi/tgsi_info.h @@ -41,6 +41,8 @@ struct tgsi_opcode_info boolean is_tex; boolean is_branch; const char *mnemonic; + const char *alt_mnemonic1; + const char *alt_mnemonic2; }; const struct tgsi_opcode_info * diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c index 58fe07c11d1..a40fcab2126 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c @@ -358,9 +358,9 @@ parse_register_dst( /* 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> `]' + * <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `]' | + * <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `+' <uint> `]' | + * <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `-' <uint> `]' */ static boolean parse_register_src( @@ -368,11 +368,13 @@ parse_register_src( uint *file, int *index, uint *ind_file, - int *ind_index ) + int *ind_index, + uint *ind_comp) { const char *cur; uint uindex; + *ind_comp = TGSI_SWIZZLE_X; if (!parse_register_file_bracket( ctx, file )) return FALSE; eat_opt_white( &ctx->cur ); @@ -381,6 +383,32 @@ parse_register_src( if (!parse_register_dst( ctx, ind_file, ind_index )) return FALSE; eat_opt_white( &ctx->cur ); + + if (*ctx->cur == '.') { + ctx->cur++; + eat_opt_white(&ctx->cur); + + switch (uprcase(*ctx->cur)) { + case 'X': + *ind_comp = TGSI_SWIZZLE_X; + break; + case 'Y': + *ind_comp = TGSI_SWIZZLE_Y; + break; + case 'Z': + *ind_comp = TGSI_SWIZZLE_Z; + break; + case 'W': + *ind_comp = TGSI_SWIZZLE_W; + break; + default: + report_error(ctx, "Expected indirect register swizzle component `x', `y', `z' or `w'"); + return FALSE; + } + ctx->cur++; + eat_opt_white(&ctx->cur); + } + if (*ctx->cur == '+' || *ctx->cur == '-') { boolean negate; @@ -561,7 +589,9 @@ parse_src_operand( int index; uint ind_file; int ind_index; + uint ind_comp; uint swizzle[4]; + boolean parsed_ext_negate_paren = FALSE; boolean parsed_swizzle; boolean parsed_extswizzle; @@ -574,10 +604,17 @@ parse_src_operand( src->SrcRegisterExtMod.Negate = 1; eat_opt_white( &cur ); ctx->cur = cur; + parsed_ext_negate_paren = TRUE; + } + else if (*cur == '|') { + cur++; + src->SrcRegisterExtMod.Negate = 1; + src->SrcRegisterExtMod.Absolute = 1; + eat_opt_white(&cur); + ctx->cur = cur; } } - - if (*ctx->cur == '|') { + else if (*ctx->cur == '|') { ctx->cur++; eat_opt_white( &ctx->cur ); src->SrcRegisterExtMod.Absolute = 1; @@ -635,7 +672,7 @@ parse_src_operand( } } - if (!parse_register_src( ctx, &file, &index, &ind_file, &ind_index )) + if (!parse_register_src(ctx, &file, &index, &ind_file, &ind_index, &ind_comp)) return FALSE; src->SrcRegister.File = file; src->SrcRegister.Index = index; @@ -643,6 +680,10 @@ parse_src_operand( src->SrcRegister.Indirect = 1; src->SrcRegisterInd.File = ind_file; src->SrcRegisterInd.Index = ind_index; + src->SrcRegisterInd.SwizzleX = ind_comp; + src->SrcRegisterInd.SwizzleY = ind_comp; + src->SrcRegisterInd.SwizzleZ = ind_comp; + src->SrcRegisterInd.SwizzleW = ind_comp; } /* Parse optional swizzle. @@ -715,7 +756,7 @@ parse_src_operand( ctx->cur++; } - if (src->SrcRegisterExtMod.Negate) { + if (parsed_ext_negate_paren) { eat_opt_white( &ctx->cur ); if (*ctx->cur != ')') { report_error( ctx, "Expected `)'" ); @@ -741,6 +782,26 @@ static const char *texture_names[TGSI_TEXTURE_COUNT] = }; static boolean +match_inst_mnemonic(const char **pcur, + const struct tgsi_opcode_info *info) +{ + if (str_match_no_case(pcur, info->mnemonic)) { + return TRUE; + } + if (info->alt_mnemonic1) { + if (str_match_no_case(pcur, info->alt_mnemonic1)) { + return TRUE; + } + if (info->alt_mnemonic2) { + if (str_match_no_case(pcur, info->alt_mnemonic2)) { + return TRUE; + } + } + } + return FALSE; +} + +static boolean parse_instruction( struct translate_ctx *ctx, boolean has_label ) @@ -758,7 +819,7 @@ parse_instruction( const char *cur = ctx->cur; info = tgsi_get_opcode_info( i ); - if (str_match_no_case( &cur, info->mnemonic )) { + if (match_inst_mnemonic(&cur, info)) { if (str_match_no_case( &cur, "_SATNV" )) saturate = TGSI_SAT_MINUS_PLUS_ONE; else if (str_match_no_case( &cur, "_SAT" )) diff --git a/src/gallium/auxiliary/translate/translate.c b/src/gallium/auxiliary/translate/translate.c index 7678903f75c..a9b7253bf44 100644 --- a/src/gallium/auxiliary/translate/translate.c +++ b/src/gallium/auxiliary/translate/translate.c @@ -42,6 +42,8 @@ struct translate *translate_create( const struct translate_key *key ) translate = translate_sse2_create( key ); if (translate) return translate; +#else + (void)translate; #endif return translate_generic_create( key ); diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile index d68bdeadcc8..5035e9cc133 100644 --- a/src/gallium/auxiliary/util/Makefile +++ b/src/gallium/auxiliary/util/Makefile @@ -5,6 +5,8 @@ LIBNAME = util C_SOURCES = \ u_debug.c \ + u_debug_symbol.c \ + u_debug_stack.c \ u_blit.c \ u_cache.c \ u_draw_quad.c \ diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript index 0f15c632c3f..8317263bb8b 100644 --- a/src/gallium/auxiliary/util/SConscript +++ b/src/gallium/auxiliary/util/SConscript @@ -10,6 +10,7 @@ util = env.ConvenienceLibrary( 'u_debug_memory.c', 'u_debug_profile.c', 'u_debug_stack.c', + 'u_debug_symbol.c', 'u_draw_quad.c', 'u_gen_mipmap.c', 'u_handle_table.c', diff --git a/src/gallium/auxiliary/util/u_clear.h b/src/gallium/auxiliary/util/u_clear.h new file mode 100644 index 00000000000..7c16b32cf9f --- /dev/null +++ b/src/gallium/auxiliary/util/u_clear.h @@ -0,0 +1,60 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, 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. + * + **************************************************************************/ + +/* Authors: + * Michel Dänzer + */ + + +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "util/u_pack_color.h" + + +/** + * Clear the given buffers to the specified values. + * No masking, no scissor (clear entire buffer). + */ +static INLINE void +util_clear(struct pipe_context *pipe, + struct pipe_framebuffer_state *framebuffer, unsigned buffers, + const float *rgba, double depth, unsigned stencil) +{ + if (buffers & PIPE_CLEAR_COLOR) { + struct pipe_surface *ps = framebuffer->cbufs[0]; + unsigned color; + + util_pack_color(rgba, ps->format, &color); + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, color); + } + + if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { + struct pipe_surface *ps = framebuffer->zsbuf; + + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, + util_pack_z_stencil(ps->format, depth, stencil)); + } +} diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c index f96e27e09fd..96a2222f9b6 100644 --- a/src/gallium/auxiliary/util/u_debug.c +++ b/src/gallium/auxiliary/util/u_debug.c @@ -169,18 +169,18 @@ void debug_print_blob( const char *name, #endif -void _debug_break(void) +#ifndef debug_break +void debug_break(void) { -#if defined(PIPE_ARCH_X86) && defined(PIPE_CC_GCC) - __asm("int3"); -#elif defined(PIPE_ARCH_X86) && defined(PIPE_CC_MSVC) - _asm {int 3}; +#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) + DebugBreak(); #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) EngDebugBreak(); #else abort(); #endif } +#endif #ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY @@ -715,78 +715,85 @@ struct bmp_rgb_quad { uint8_t rgbAlpha; }; -void +void debug_dump_surface_bmp(const char *filename, struct pipe_surface *surface) { + struct pipe_transfer *transfer; + struct pipe_texture *texture = surface->texture; + struct pipe_screen *screen = texture->screen; + + transfer = screen->get_tex_transfer(screen, texture, surface->face, + surface->level, surface->zslice, + PIPE_TRANSFER_READ, 0, 0, surface->width, + surface->height); + + debug_dump_transfer_bmp(filename, transfer); + + screen->tex_transfer_destroy(transfer); +} + +void +debug_dump_transfer_bmp(const char *filename, + struct pipe_transfer *transfer) +{ #ifndef PIPE_SUBSYSTEM_WINDOWS_MINIPORT - struct pipe_texture *texture; - struct pipe_screen *screen; struct util_stream *stream; - struct pipe_transfer *transfer; struct bmp_file_header bmfh; struct bmp_info_header bmih; float *rgba; unsigned x, y; - if (!surface) + if (!transfer) goto error1; - rgba = MALLOC(surface->width*4*sizeof(float)); + rgba = MALLOC(transfer->width*transfer->height*4*sizeof(float)); if(!rgba) goto error1; - + bmfh.bfType = 0x4d42; - bmfh.bfSize = 14 + 40 + surface->height*surface->width*4; + bmfh.bfSize = 14 + 40 + transfer->height*transfer->width*4; bmfh.bfReserved1 = 0; bmfh.bfReserved2 = 0; bmfh.bfOffBits = 14 + 40; - + bmih.biSize = 40; - bmih.biWidth = surface->width; - bmih.biHeight = surface->height; + bmih.biWidth = transfer->width; + bmih.biHeight = transfer->height; bmih.biPlanes = 1; bmih.biBitCount = 32; bmih.biCompression = 0; - bmih.biSizeImage = surface->height*surface->width*4; + bmih.biSizeImage = transfer->height*transfer->width*4; bmih.biXPelsPerMeter = 0; bmih.biYPelsPerMeter = 0; bmih.biClrUsed = 0; bmih.biClrImportant = 0; - + stream = util_stream_create(filename, bmfh.bfSize); if(!stream) goto error2; - + util_stream_write(stream, &bmfh, 14); util_stream_write(stream, &bmih, 40); - texture = surface->texture; - screen = texture->screen; - - transfer = screen->get_tex_transfer(screen, texture, surface->face, - surface->level, surface->zslice, - PIPE_TRANSFER_READ, 0, 0, surface->width, - surface->height); + pipe_get_tile_rgba(transfer, 0, 0, + transfer->width, transfer->height, + rgba); - y = surface->height; + y = transfer->height; while(y--) { - pipe_get_tile_rgba(transfer, - 0, y, surface->width, 1, - rgba); - for(x = 0; x < surface->width; ++x) + float *ptr = rgba + (transfer->width * y * 4); + for(x = 0; x < transfer->width; ++x) { struct bmp_rgb_quad pixel; - pixel.rgbRed = float_to_ubyte(rgba[x*4 + 0]); - pixel.rgbGreen = float_to_ubyte(rgba[x*4 + 1]); - pixel.rgbBlue = float_to_ubyte(rgba[x*4 + 2]); - pixel.rgbAlpha = float_to_ubyte(rgba[x*4 + 3]); + pixel.rgbRed = float_to_ubyte(ptr[x*4 + 0]); + pixel.rgbGreen = float_to_ubyte(ptr[x*4 + 1]); + pixel.rgbBlue = float_to_ubyte(ptr[x*4 + 2]); + pixel.rgbAlpha = 255; util_stream_write(stream, &pixel, 4); - } + } } - screen->tex_transfer_destroy(transfer); - util_stream_close(stream); error2: FREE(rgba); diff --git a/src/gallium/auxiliary/util/u_debug.h b/src/gallium/auxiliary/util/u_debug.h index 7c829707b20..8d703e47fce 100644 --- a/src/gallium/auxiliary/util/u_debug.h +++ b/src/gallium/auxiliary/util/u_debug.h @@ -125,19 +125,16 @@ void debug_print_format(const char *msg, unsigned fmt ); #endif -void _debug_break(void); - - /** * Hard-coded breakpoint. */ #ifdef DEBUG -#if defined(PIPE_ARCH_X86) && defined(PIPE_CC_GCC) +#if (defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)) && defined(PIPE_CC_GCC) #define debug_break() __asm("int3") -#elif defined(PIPE_ARCH_X86) && defined(PIPE_CC_MSVC) -#define debug_break() do { _asm {int 3} } while(0) +#elif defined(PIPE_CC_MSVC) +#define debug_break() __debugbreak() #else -#define debug_break() _debug_break() +void debug_break(void); #endif #else /* !DEBUG */ #define debug_break() ((void)0) @@ -338,6 +335,7 @@ debug_profile_stop(void); #ifdef DEBUG struct pipe_surface; +struct pipe_transfer; void debug_dump_image(const char *prefix, unsigned format, unsigned cpp, unsigned width, unsigned height, @@ -347,6 +345,8 @@ void debug_dump_surface(const char *prefix, struct pipe_surface *surface); void debug_dump_surface_bmp(const char *filename, struct pipe_surface *surface); +void debug_dump_transfer_bmp(const char *filename, + struct pipe_transfer *transfer); #else #define debug_dump_image(prefix, format, cpp, width, height, stride, data) ((void)0) #define debug_dump_surface(prefix, surface) ((void)0) diff --git a/src/gallium/auxiliary/util/u_debug_stack.c b/src/gallium/auxiliary/util/u_debug_stack.c index 76068a65091..e9891fde8a3 100644 --- a/src/gallium/auxiliary/util/u_debug_stack.c +++ b/src/gallium/auxiliary/util/u_debug_stack.c @@ -33,6 +33,7 @@ */ #include "u_debug.h" +#include "u_debug_symbol.h" #include "u_debug_stack.h" @@ -49,7 +50,7 @@ debug_backtrace_capture(struct debug_stack_frame *backtrace, #if defined(PIPE_CC_GCC) frame_pointer = ((const void **)__builtin_frame_address(1)); -#elif defined(PIPE_CC_MSVC) +#elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86) __asm { mov frame_pointer, ebp } @@ -91,7 +92,7 @@ debug_backtrace_dump(const struct debug_stack_frame *backtrace, for(i = 0; i < nr_frames; ++i) { if(!backtrace[i].function) break; - debug_printf("\t%p\n", backtrace[i].function); + debug_symbol_print(backtrace[i].function); } } diff --git a/src/gallium/auxiliary/util/u_debug_symbol.c b/src/gallium/auxiliary/util/u_debug_symbol.c new file mode 100644 index 00000000000..811931f81b0 --- /dev/null +++ b/src/gallium/auxiliary/util/u_debug_symbol.c @@ -0,0 +1,250 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, 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 VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Symbol lookup. + * + * @author Jose Fonseca <[email protected]> + */ + +#include "pipe/p_compiler.h" + +#include "u_debug.h" +#include "u_debug_symbol.h" + +#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) && defined(PIPE_ARCH_X86) + +#include <windows.h> +#include <stddef.h> +#include <imagehlp.h> + +/* + * TODO: Cleanup code. + * TODO: Support x86_64 + */ + +static BOOL bSymInitialized = FALSE; + +static HMODULE hModule_Imagehlp = NULL; + +typedef BOOL (WINAPI *PFNSYMINITIALIZE)(HANDLE, LPSTR, BOOL); +static PFNSYMINITIALIZE pfnSymInitialize = NULL; + +static +BOOL WINAPI j_SymInitialize(HANDLE hProcess, PSTR UserSearchPath, BOOL fInvadeProcess) +{ + if( + (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) && + (pfnSymInitialize || (pfnSymInitialize = (PFNSYMINITIALIZE) GetProcAddress(hModule_Imagehlp, "SymInitialize"))) + ) + return pfnSymInitialize(hProcess, UserSearchPath, fInvadeProcess); + else + return FALSE; +} + +typedef BOOL (WINAPI *PFNSYMCLEANUP)(HANDLE); +static PFNSYMCLEANUP pfnSymCleanup = NULL; + +static +BOOL WINAPI j_SymCleanup(HANDLE hProcess) +{ + if( + (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) && + (pfnSymCleanup || (pfnSymCleanup = (PFNSYMCLEANUP) GetProcAddress(hModule_Imagehlp, "SymCleanup"))) + ) + return pfnSymCleanup(hProcess); + else + return FALSE; +} + +typedef DWORD (WINAPI *PFNSYMSETOPTIONS)(DWORD); +static PFNSYMSETOPTIONS pfnSymSetOptions = NULL; + +static +DWORD WINAPI j_SymSetOptions(DWORD SymOptions) +{ + if( + (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) && + (pfnSymSetOptions || (pfnSymSetOptions = (PFNSYMSETOPTIONS) GetProcAddress(hModule_Imagehlp, "SymSetOptions"))) + ) + return pfnSymSetOptions(SymOptions); + else + return FALSE; +} + +typedef BOOL (WINAPI *PFNSYMUNDNAME)(PIMAGEHLP_SYMBOL, PSTR, DWORD); +static PFNSYMUNDNAME pfnSymUnDName = NULL; + +static +BOOL WINAPI j_SymUnDName(PIMAGEHLP_SYMBOL Symbol, PSTR UnDecName, DWORD UnDecNameLength) +{ + if( + (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) && + (pfnSymUnDName || (pfnSymUnDName = (PFNSYMUNDNAME) GetProcAddress(hModule_Imagehlp, "SymUnDName"))) + ) + return pfnSymUnDName(Symbol, UnDecName, UnDecNameLength); + else + return FALSE; +} + +typedef PFUNCTION_TABLE_ACCESS_ROUTINE PFNSYMFUNCTIONTABLEACCESS; +static PFNSYMFUNCTIONTABLEACCESS pfnSymFunctionTableAccess = NULL; + +static +PVOID WINAPI j_SymFunctionTableAccess(HANDLE hProcess, DWORD AddrBase) +{ + if( + (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) && + (pfnSymFunctionTableAccess || (pfnSymFunctionTableAccess = (PFNSYMFUNCTIONTABLEACCESS) GetProcAddress(hModule_Imagehlp, "SymFunctionTableAccess"))) + ) + return pfnSymFunctionTableAccess(hProcess, AddrBase); + else + return NULL; +} + +typedef PGET_MODULE_BASE_ROUTINE PFNSYMGETMODULEBASE; +static PFNSYMGETMODULEBASE pfnSymGetModuleBase = NULL; + +static +DWORD WINAPI j_SymGetModuleBase(HANDLE hProcess, DWORD dwAddr) +{ + if( + (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) && + (pfnSymGetModuleBase || (pfnSymGetModuleBase = (PFNSYMGETMODULEBASE) GetProcAddress(hModule_Imagehlp, "SymGetModuleBase"))) + ) + return pfnSymGetModuleBase(hProcess, dwAddr); + else + return 0; +} + +typedef BOOL (WINAPI *PFNSTACKWALK)(DWORD, HANDLE, HANDLE, LPSTACKFRAME, LPVOID, PREAD_PROCESS_MEMORY_ROUTINE, PFUNCTION_TABLE_ACCESS_ROUTINE, PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE); +static PFNSTACKWALK pfnStackWalk = NULL; + +static +BOOL WINAPI j_StackWalk( + DWORD MachineType, + HANDLE hProcess, + HANDLE hThread, + LPSTACKFRAME StackFrame, + PVOID ContextRecord, + PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine, + PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, + PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, + PTRANSLATE_ADDRESS_ROUTINE TranslateAddress +) +{ + if( + (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) && + (pfnStackWalk || (pfnStackWalk = (PFNSTACKWALK) GetProcAddress(hModule_Imagehlp, "StackWalk"))) + ) + return pfnStackWalk( + MachineType, + hProcess, + hThread, + StackFrame, + ContextRecord, + ReadMemoryRoutine, + FunctionTableAccessRoutine, + GetModuleBaseRoutine, + TranslateAddress + ); + else + return FALSE; +} + +typedef BOOL (WINAPI *PFNSYMGETSYMFROMADDR)(HANDLE, DWORD, LPDWORD, PIMAGEHLP_SYMBOL); +static PFNSYMGETSYMFROMADDR pfnSymGetSymFromAddr = NULL; + +static +BOOL WINAPI j_SymGetSymFromAddr(HANDLE hProcess, DWORD Address, PDWORD Displacement, PIMAGEHLP_SYMBOL Symbol) +{ + if( + (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) && + (pfnSymGetSymFromAddr || (pfnSymGetSymFromAddr = (PFNSYMGETSYMFROMADDR) GetProcAddress(hModule_Imagehlp, "SymGetSymFromAddr"))) + ) + return pfnSymGetSymFromAddr(hProcess, Address, Displacement, Symbol); + else + return FALSE; +} + +typedef BOOL (WINAPI *PFNSYMGETLINEFROMADDR)(HANDLE, DWORD, LPDWORD, PIMAGEHLP_LINE); +static PFNSYMGETLINEFROMADDR pfnSymGetLineFromAddr = NULL; + +static +BOOL WINAPI j_SymGetLineFromAddr(HANDLE hProcess, DWORD dwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINE Line) +{ + if( + (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) && + (pfnSymGetLineFromAddr || (pfnSymGetLineFromAddr = (PFNSYMGETLINEFROMADDR) GetProcAddress(hModule_Imagehlp, "SymGetLineFromAddr"))) + ) + return pfnSymGetLineFromAddr(hProcess, dwAddr, pdwDisplacement, Line); + else + return FALSE; +} + + +static INLINE boolean +debug_symbol_print_imagehlp(const void *addr) +{ + HANDLE hProcess; + BYTE symbolBuffer[1024]; + PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL) symbolBuffer; + DWORD dwDisplacement = 0; // Displacement of the input address, relative to the start of the symbol + + hProcess = GetCurrentProcess(); + + pSymbol->SizeOfStruct = sizeof(symbolBuffer); + pSymbol->MaxNameLength = sizeof(symbolBuffer) - offsetof(IMAGEHLP_SYMBOL, Name); + + if(!bSymInitialized) { + j_SymSetOptions(/* SYMOPT_UNDNAME | */ SYMOPT_LOAD_LINES); + if(j_SymInitialize(hProcess, NULL, TRUE)) + bSymInitialized = TRUE; + } + + if(!j_SymGetSymFromAddr(hProcess, (DWORD)addr, &dwDisplacement, pSymbol)) + return FALSE; + + debug_printf("\t%s\n", pSymbol->Name); + + return TRUE; + +} +#endif + + +void +debug_symbol_print(const void *addr) +{ +#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) && defined(PIPE_ARCH_X86) + if(debug_symbol_print_imagehlp(addr)) + return; +#endif + + debug_printf("\t%p\n", addr); +} diff --git a/src/gallium/auxiliary/util/u_debug_symbol.h b/src/gallium/auxiliary/util/u_debug_symbol.h new file mode 100644 index 00000000000..021586987b6 --- /dev/null +++ b/src/gallium/auxiliary/util/u_debug_symbol.h @@ -0,0 +1,53 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, 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 VMWARE 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 U_DEBUG_SYMBOL_H_ +#define U_DEBUG_SYMBOL_H_ + + +/** + * @file + * Symbol lookup. + * + * @author Jose Fonseca <[email protected]> + */ + + +#ifdef __cplusplus +extern "C" { +#endif + + +void +debug_symbol_print(const void *addr); + + +#ifdef __cplusplus +} +#endif + +#endif /* U_DEBUG_SYMBOL_H_ */ diff --git a/src/gallium/auxiliary/util/u_double_list.h b/src/gallium/auxiliary/util/u_double_list.h index d108d92e52b..53bb1342ddc 100644 --- a/src/gallium/auxiliary/util/u_double_list.h +++ b/src/gallium/auxiliary/util/u_double_list.h @@ -95,5 +95,8 @@ struct list_head #define LIST_ENTRY(__type, __item, __field) \ ((__type *)(((char *)(__item)) - offsetof(__type, __field))) +#define LIST_IS_EMPTY(__list) \ + ((__list)->next == (__list)) + #endif /*_U_DOUBLE_LIST_H_*/ diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h index 1ecde7a9125..e5003af01d8 100644 --- a/src/gallium/auxiliary/util/u_math.h +++ b/src/gallium/auxiliary/util/u_math.h @@ -319,11 +319,33 @@ util_iround(float f) -#if defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86) +/** + * Test if x is NaN or +/- infinity. + */ +static INLINE boolean +util_is_inf_or_nan(float x) +{ + union fi tmp; + tmp.f = x; + return !(int)((unsigned int)((tmp.i & 0x7fffffff)-0x7f800000) >> 31); +} + + /** * Find first bit set in word. Least significant bit is 1. * Return 0 if no bits set. */ +#if defined(_MSC_VER) && _MSC_VER >= 1300 +static INLINE +unsigned long ffs( unsigned long u ) +{ + unsigned long i; + if(_BitScanForward(&i, u)) + return i + 1; + else + return 0; +} +#elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86) static INLINE unsigned ffs( unsigned u ) { @@ -339,9 +361,7 @@ unsigned ffs( unsigned u ) return i; } -#endif - -#ifdef __MINGW32__ +#elif defined(__MINGW32__) #define ffs __builtin_ffs #endif diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index e0e8aa8e9fe..eda883b3b92 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -434,12 +434,42 @@ util_pack_z(enum pipe_format format, double z) if (z == 1.0) return 0xffffff00; return ((uint) (z * 0xffffff)) << 8; + case PIPE_FORMAT_S8_UNORM: + /* this case can get it via util_pack_z_stencil() */ + return 0; default: debug_print_format("gallium: unhandled format in util_pack_z()", format); assert(0); return 0; } } + + +/** + * Pack Z and/or stencil values into a 32-bit value described by format. + * Note: it's assumed that z is in [0,1] and s in [0,255] + */ +static INLINE uint +util_pack_z_stencil(enum pipe_format format, double z, uint s) +{ + unsigned packed = util_pack_z(format, z); + + switch (format) { + case PIPE_FORMAT_S8Z24_UNORM: + packed |= s << 24; + break; + case PIPE_FORMAT_Z24S8_UNORM: + packed |= s; + break; + case PIPE_FORMAT_S8_UNORM: + packed |= s; + break; + default: + break; + } + + return packed; +} /** diff --git a/src/gallium/auxiliary/util/u_stream_stdc.c b/src/gallium/auxiliary/util/u_stream_stdc.c index 0ead45a7491..d8f648e5dd1 100644 --- a/src/gallium/auxiliary/util/u_stream_stdc.c +++ b/src/gallium/auxiliary/util/u_stream_stdc.c @@ -32,7 +32,7 @@ #include "pipe/p_config.h" -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_OS_SOLARIS) #include <stdio.h> diff --git a/src/gallium/auxiliary/util/u_string.h b/src/gallium/auxiliary/util/u_string.h index 08c89bbf770..cc7992d7391 100644 --- a/src/gallium/auxiliary/util/u_string.h +++ b/src/gallium/auxiliary/util/u_string.h @@ -130,7 +130,7 @@ static INLINE char * util_strstr(const char *haystack, const char *needle) { const char *p = haystack; - int len = strlen(needle); + size_t len = strlen(needle); for (; (p = util_strchr(p, *needle)) != 0; p++) { if (util_strncmp(p, needle, len) == 0) { diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c index d31ca9c029e..f0a5a339eb3 100644 --- a/src/gallium/auxiliary/util/u_tile.c +++ b/src/gallium/auxiliary/util/u_tile.c @@ -957,6 +957,7 @@ pipe_tile_raw_to_rgba(enum pipe_format format, s8z24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_Z24X8_UNORM: z24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_Z32_FLOAT: @@ -1069,6 +1070,7 @@ pipe_put_tile_rgba(struct pipe_transfer *pt, /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ break; case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_Z24X8_UNORM: /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ break; default: @@ -1198,6 +1200,20 @@ pipe_put_tile_z(struct pipe_transfer *pt, } } break; + case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_Z24X8_UNORM: + { + uint *pDest = (uint *) (map + y * pt->stride + x*4); + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + /* convert 32-bit Z to 24-bit Z (0 stencil) */ + pDest[j] = ptrc[j] << 8; + } + pDest += pt->stride/4; + ptrc += srcStride; + } + } + break; case PIPE_FORMAT_Z16_UNORM: { ushort *pDest = (ushort *) (map + y * pt->stride + x*2); diff --git a/src/gallium/auxiliary/util/u_time.c b/src/gallium/auxiliary/util/u_time.c index 357d9360c90..8afe4fccf7b 100644 --- a/src/gallium/auxiliary/util/u_time.c +++ b/src/gallium/auxiliary/util/u_time.c @@ -35,7 +35,7 @@ #include "pipe/p_config.h" -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) #include <sys/time.h> #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) #include <windows.h> @@ -77,7 +77,7 @@ util_time_get_frequency(void) void util_time_get(struct util_time *t) { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) gettimeofday(&t->tv, NULL); #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) LONGLONG temp; @@ -102,7 +102,7 @@ util_time_add(const struct util_time *t1, int64_t usecs, struct util_time *t2) { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) t2->tv.tv_sec = t1->tv.tv_sec + usecs / 1000000; t2->tv.tv_usec = t1->tv.tv_usec + usecs % 1000000; #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) @@ -124,7 +124,7 @@ int64_t util_time_diff(const struct util_time *t1, const struct util_time *t2) { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) return (t2->tv.tv_usec - t1->tv.tv_usec) + (t2->tv.tv_sec - t1->tv.tv_sec)*1000000; #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) @@ -144,7 +144,7 @@ util_time_micros( void ) util_time_get(&t1); -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) return t1.tv.tv_usec + t1.tv.tv_sec*1000000LL; #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) util_time_get_frequency(); @@ -166,7 +166,7 @@ static INLINE int util_time_compare(const struct util_time *t1, const struct util_time *t2) { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) if (t1->tv.tv_sec < t2->tv.tv_sec) return -1; else if(t1->tv.tv_sec > t2->tv.tv_sec) diff --git a/src/gallium/auxiliary/util/u_time.h b/src/gallium/auxiliary/util/u_time.h index 4346ce1fa45..6bca6077a2a 100644 --- a/src/gallium/auxiliary/util/u_time.h +++ b/src/gallium/auxiliary/util/u_time.h @@ -38,7 +38,7 @@ #include "pipe/p_config.h" -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) #include <time.h> /* timeval */ #include <unistd.h> /* usleep */ #endif @@ -58,7 +58,7 @@ extern "C" { */ struct util_time { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) struct timeval tv; #else int64_t counter; @@ -89,7 +89,7 @@ util_time_timeout(const struct util_time *start, const struct util_time *end, const struct util_time *curr); -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) #define util_time_sleep usleep #else void diff --git a/src/gallium/drivers/cell/ppu/cell_clear.c b/src/gallium/drivers/cell/ppu/cell_clear.c index edc06747ac1..79ad687ea94 100644 --- a/src/gallium/drivers/cell/ppu/cell_clear.c +++ b/src/gallium/drivers/cell/ppu/cell_clear.c @@ -46,53 +46,41 @@ /** - * Convert packed pixel from one format to another. - */ -static unsigned -convert_color(enum pipe_format srcFormat, unsigned srcColor, - enum pipe_format dstFormat) -{ - ubyte r, g, b, a; - unsigned dstColor; - - util_unpack_color_ub(srcFormat, &srcColor, &r, &g, &b, &a); - util_pack_color_ub(r, g, b, a, dstFormat, &dstColor); - - return dstColor; -} - - - -/** * Called via pipe->clear() */ void -cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +cell_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil) { struct cell_context *cell = cell_context(pipe); - uint surfIndex; if (cell->dirty) cell_update_derived(cell); - if (ps == cell->framebuffer.zsbuf) { - /* clear z/stencil buffer */ - surfIndex = 1; - } - else { - /* clear color buffer */ - surfIndex = 0; + if (buffers & PIPE_CLEAR_COLOR) { + uint surfIndex = 0; + uint clearValue; - if (ps->format != PIPE_FORMAT_A8R8G8B8_UNORM) { - clearValue = convert_color(PIPE_FORMAT_A8R8G8B8_UNORM, clearValue, - ps->format); - } + util_pack_color(rgba, cell->framebuffer.cbufs[0]->format, &clearValue); + + /* Build a CLEAR command and place it in the current batch buffer */ + STATIC_ASSERT(sizeof(struct cell_command_clear_surface) % 16 == 0); + struct cell_command_clear_surface *clr + = (struct cell_command_clear_surface *) + cell_batch_alloc16(cell, sizeof(*clr)); + clr->opcode[0] = CELL_CMD_CLEAR_SURFACE; + clr->surface = surfIndex; + clr->value = clearValue; } + if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { + uint surfIndex = 1; + uint clearValue; - /* Build a CLEAR command and place it in the current batch buffer */ - { + clearValue = util_pack_z_stencil(cell->framebuffer.zsbuf->format, + depth, stencil); + + /* Build a CLEAR command and place it in the current batch buffer */ STATIC_ASSERT(sizeof(struct cell_command_clear_surface) % 16 == 0); struct cell_command_clear_surface *clr = (struct cell_command_clear_surface *) @@ -101,17 +89,4 @@ cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps, clr->surface = surfIndex; clr->value = clearValue; } - - /* Technically, the surface's contents are now known and cleared, - * so we could set the status to PIPE_SURFACE_STATUS_CLEAR. But - * it turns out it's quite painful to recognize when any particular - * surface goes from PIPE_SURFACE_STATUS_CLEAR to - * PIPE_SURFACE_STATUS_DEFINED (i.e. with known contents), because - * the drawing commands could be operating on numerous draw buffers, - * which we'd have to iterate through to set all their stati... - * For now, we cheat a bit and set the surface's status to DEFINED - * right here. Later we should revisit this and set the status to - * CLEAR here, and find a better place to set the status to DEFINED. - */ - ps->status = PIPE_SURFACE_STATUS_DEFINED; } diff --git a/src/gallium/drivers/cell/ppu/cell_clear.h b/src/gallium/drivers/cell/ppu/cell_clear.h index ff47d43f4cd..08e091adfdb 100644 --- a/src/gallium/drivers/cell/ppu/cell_clear.h +++ b/src/gallium/drivers/cell/ppu/cell_clear.h @@ -31,13 +31,11 @@ struct pipe_context; -struct pipe_surface; extern void -cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); - +cell_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil); #endif /* CELL_CLEAR_H */ diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index ae82ded334a..808be589bd9 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -119,7 +119,7 @@ cell_create_context(struct pipe_screen *screen, cell->pipe.screen = screen; cell->pipe.destroy = cell_destroy_context; - cell->pipe.clear = cell_clear_surface; + cell->pipe.clear = cell_clear; cell->pipe.flush = cell_flush; #if 0 diff --git a/src/gallium/drivers/i915simple/i915_clear.c b/src/gallium/drivers/i915simple/i915_clear.c index 8a2d3ca43f1..90530f2826f 100644 --- a/src/gallium/drivers/i915simple/i915_clear.c +++ b/src/gallium/drivers/i915simple/i915_clear.c @@ -25,24 +25,24 @@ * **************************************************************************/ -/* Author: +/* Authors: * Brian Paul */ -#include "pipe/p_defines.h" +#include "util/u_clear.h" #include "i915_context.h" #include "i915_state.h" /** - * Clear the given surface to the specified value. + * Clear the given buffers to the specified values. * No masking, no scissor (clear entire buffer). */ void -i915_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +i915_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); - ps->status = PIPE_SURFACE_STATUS_DEFINED; + util_clear(pipe, &i915_context(pipe)->framebuffer, buffers, rgba, depth, + stencil); } diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 3cdabe45f9d..b6983ba86e7 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -314,8 +314,8 @@ void i915_emit_hardware_state(struct i915_context *i915 ); /*********************************************************************** * i915_clear.c: */ -void i915_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +void i915_clear( struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil); /*********************************************************************** diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 39aca9f8173..ca8e87af8d1 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -677,7 +677,6 @@ i915_get_tex_surface(struct pipe_screen *screen, ps->height = pt->height[level]; ps->offset = offset; ps->usage = flags; - ps->status = PIPE_SURFACE_STATUS_DEFINED; } return ps; } @@ -725,14 +724,6 @@ i915_init_texture_functions(struct i915_context *i915) static void i915_tex_surface_destroy(struct pipe_surface *surf) { - /* This really should not be possible, but it's actually - * happening quite a bit... Will fix. - */ - if (surf->status == PIPE_SURFACE_STATUS_CLEAR) { - debug_printf("XXX destroying a surface with pending clears...\n"); - assert(0); - } - pipe_texture_reference(&surf->texture, NULL); FREE(surf); } diff --git a/src/gallium/drivers/i965simple/brw_defines.h b/src/gallium/drivers/i965simple/brw_defines.h index 9379a397f63..715d2d2d011 100644 --- a/src/gallium/drivers/i965simple/brw_defines.h +++ b/src/gallium/drivers/i965simple/brw_defines.h @@ -289,6 +289,24 @@ #define BRW_RASTRULE_UPPER_LEFT 0 #define BRW_RASTRULE_UPPER_RIGHT 1 +/* These are listed as "Reserved, but not seen as useful" + * in Intel documentation (page 212, "Point Rasterization Rule", + * section 7.4 "SF Pipeline State Summary", of document + * "Intel® 965 Express Chipset Family and Intel® G35 Express + * Chipset Graphics Controller Programmer's Reference Manual, + * Volume 2: 3D/Media", Revision 1.0b as of January 2008, + * available at + * http://intellinuxgraphics.org/documentation.html + * at the time of this writing). + * + * These appear to be supported on at least some + * i965-family devices, and the BRW_RASTRULE_LOWER_RIGHT + * is useful when using OpenGL to render to a FBO + * (which has the pixel coordinate Y orientation inverted + * with respect to the normal OpenGL pixel coordinate system). + */ +#define BRW_RASTRULE_LOWER_LEFT 2 +#define BRW_RASTRULE_LOWER_RIGHT 3 #define BRW_RENDERTARGET_CLAMPRANGE_UNORM 0 #define BRW_RENDERTARGET_CLAMPRANGE_SNORM 1 diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index c921c0d38be..f44bd17451b 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -363,7 +363,6 @@ brw_get_tex_surface_screen(struct pipe_screen *screen, ps->nblocksy = pt->nblocksy[level]; ps->stride = tex->stride; ps->offset = offset; - ps->status = PIPE_SURFACE_STATUS_DEFINED; } return ps; } diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h index 97859110b5f..a54820e8512 100644 --- a/src/gallium/drivers/nouveau/nouveau_stateobj.h +++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h @@ -46,9 +46,12 @@ static INLINE void so_ref(struct nouveau_stateobj *ref, struct nouveau_stateobj **pso) { struct nouveau_stateobj *so = *pso; + int i; if (pipe_reference((struct pipe_reference**)pso, &ref->reference)) { free(so->push); + for (i = 0; i < so->cur_reloc; i++) + pipe_buffer_reference(&so->reloc[i].bo, NULL); free(so->reloc); free(so); } @@ -83,7 +86,8 @@ so_reloc(struct nouveau_stateobj *so, struct pipe_buffer *bo, { struct nouveau_stateobj_reloc *r = &so->reloc[so->cur_reloc++]; - r->bo = bo; + r->bo = NULL; + pipe_buffer_reference(&r->bo, bo); r->offset = so->cur - so->push; r->packet = so->cur_packet; r->data = data; diff --git a/src/gallium/drivers/nv04/nv04_miptree.c b/src/gallium/drivers/nv04/nv04_miptree.c index 85dc017fbc4..4da833c25e8 100644 --- a/src/gallium/drivers/nv04/nv04_miptree.c +++ b/src/gallium/drivers/nv04/nv04_miptree.c @@ -122,7 +122,6 @@ nv04_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ns->base.width = pt->width[level]; ns->base.height = pt->height[level]; ns->base.usage = flags; - ns->base.status = PIPE_SURFACE_STATUS_DEFINED; pipe_reference_init(&ns->base.reference, 1); ns->base.face = face; ns->base.level = level; diff --git a/src/gallium/drivers/nv10/nv10_clear.c b/src/gallium/drivers/nv10/nv10_clear.c index be7e09cf4b0..a39a2b5f525 100644 --- a/src/gallium/drivers/nv10/nv10_clear.c +++ b/src/gallium/drivers/nv10/nv10_clear.c @@ -1,12 +1,14 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" +#include "util/u_clear.h" #include "nv10_context.h" void -nv10_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +nv10_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); + util_clear(pipe, nv10_context(pipe)->framebuffer, buffers, rgba, depth, + stencil); } diff --git a/src/gallium/drivers/nv10/nv10_context.h b/src/gallium/drivers/nv10/nv10_context.h index f3b56de25a7..f1e003c9537 100644 --- a/src/gallium/drivers/nv10/nv10_context.h +++ b/src/gallium/drivers/nv10/nv10_context.h @@ -118,8 +118,9 @@ extern void nv10_init_surface_functions(struct nv10_context *nv10); extern void nv10_screen_init_miptree_functions(struct pipe_screen *pscreen); /* nv10_clear.c */ -extern void nv10_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +extern void nv10_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil); + /* nv10_draw.c */ extern struct draw_stage *nv10_draw_render_stage(struct nv10_context *nv10); diff --git a/src/gallium/drivers/nv10/nv10_miptree.c b/src/gallium/drivers/nv10/nv10_miptree.c index bb3a1c0f19e..34e3c2ebd77 100644 --- a/src/gallium/drivers/nv10/nv10_miptree.c +++ b/src/gallium/drivers/nv10/nv10_miptree.c @@ -136,7 +136,6 @@ nv10_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, ns->base.width = pt->width[level]; ns->base.height = pt->height[level]; ns->base.usage = flags; - ns->base.status = PIPE_SURFACE_STATUS_DEFINED; pipe_reference_init(&ns->base.reference, 1); ns->base.face = face; ns->base.level = level; diff --git a/src/gallium/drivers/nv20/nv20_clear.c b/src/gallium/drivers/nv20/nv20_clear.c index 29f4afd87c9..2b4490fa5e1 100644 --- a/src/gallium/drivers/nv20/nv20_clear.c +++ b/src/gallium/drivers/nv20/nv20_clear.c @@ -1,13 +1,14 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" +#include "util/u_clear.h" #include "nv20_context.h" void -nv20_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +nv20_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); - ps->status = PIPE_SURFACE_STATUS_CLEAR; + util_clear(pipe, nv20_context(pipe)->framebuffer, buffers, rgba, depth, + stencil); } diff --git a/src/gallium/drivers/nv20/nv20_context.h b/src/gallium/drivers/nv20/nv20_context.h index 8ad926db20a..fc932f1f90e 100644 --- a/src/gallium/drivers/nv20/nv20_context.h +++ b/src/gallium/drivers/nv20/nv20_context.h @@ -118,8 +118,8 @@ extern void nv20_init_surface_functions(struct nv20_context *nv20); extern void nv20_screen_init_miptree_functions(struct pipe_screen *pscreen); /* nv20_clear.c */ -extern void nv20_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +extern void nv20_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil); /* nv20_draw.c */ extern struct draw_stage *nv20_draw_render_stage(struct nv20_context *nv20); diff --git a/src/gallium/drivers/nv20/nv20_miptree.c b/src/gallium/drivers/nv20/nv20_miptree.c index b2f29aff8d2..185fbf53e0f 100644 --- a/src/gallium/drivers/nv20/nv20_miptree.c +++ b/src/gallium/drivers/nv20/nv20_miptree.c @@ -170,7 +170,6 @@ nv20_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, ns->base.width = pt->width[level]; ns->base.height = pt->height[level]; ns->base.usage = flags; - ns->base.status = PIPE_SURFACE_STATUS_DEFINED; pipe_reference_init(&ns->base.reference, 1); ns->base.face = face; ns->base.level = level; diff --git a/src/gallium/drivers/nv30/nv30_clear.c b/src/gallium/drivers/nv30/nv30_clear.c index 8c3ca204d58..c4ba9266647 100644 --- a/src/gallium/drivers/nv30/nv30_clear.c +++ b/src/gallium/drivers/nv30/nv30_clear.c @@ -1,13 +1,14 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" +#include "util/u_clear.h" #include "nv30_context.h" void -nv30_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +nv30_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); - ps->status = PIPE_SURFACE_STATUS_CLEAR; + util_clear(pipe, &nv30_context(pipe)->framebuffer, buffers, rgba, depth, + stencil); } diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index b9337697008..4229c0a0e14 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -206,7 +206,7 @@ extern boolean nv30_draw_elements(struct pipe_context *pipe, unsigned count); /* nv30_clear.c */ -extern void nv30_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +extern void nv30_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil); #endif diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c index d6dc621c9ee..7f8054de733 100644 --- a/src/gallium/drivers/nv30/nv30_miptree.c +++ b/src/gallium/drivers/nv30/nv30_miptree.c @@ -177,7 +177,6 @@ nv30_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ns->base.width = pt->width[level]; ns->base.height = pt->height[level]; ns->base.usage = flags; - ns->base.status = PIPE_SURFACE_STATUS_DEFINED; pipe_reference_init(&ns->base.reference, 1); ns->base.face = face; ns->base.level = level; diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index f77b08ff695..c18be20a327 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -21,14 +21,6 @@ static void nv30_state_do_validate(struct nv30_context *nv30, struct nv30_state_entry **states) { - const struct pipe_framebuffer_state *fb = &nv30->framebuffer; - unsigned i; - - for (i = 0; i < fb->nr_cbufs; i++) - fb->cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED; - if (fb->zsbuf) - fb->zsbuf->status = PIPE_SURFACE_STATUS_DEFINED; - while (*states) { struct nv30_state_entry *e = *states; diff --git a/src/gallium/drivers/nv40/nv40_clear.c b/src/gallium/drivers/nv40/nv40_clear.c index 59efd620e32..ddf13addf3b 100644 --- a/src/gallium/drivers/nv40/nv40_clear.c +++ b/src/gallium/drivers/nv40/nv40_clear.c @@ -1,13 +1,14 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" +#include "util/u_clear.h" #include "nv40_context.h" void -nv40_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +nv40_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); - ps->status = PIPE_SURFACE_STATUS_CLEAR; + util_clear(pipe, &nv40_context(pipe)->framebuffer, buffers, rgba, depth, + stencil); } diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index adcfbdd85a8..97bc83292d4 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -227,7 +227,7 @@ extern boolean nv40_draw_elements(struct pipe_context *pipe, unsigned count); /* nv40_clear.c */ -extern void nv40_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +extern void nv40_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil); #endif diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index abadca8c933..5a201ccf458 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -176,7 +176,6 @@ nv40_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ns->base.width = pt->width[level]; ns->base.height = pt->height[level]; ns->base.usage = flags; - ns->base.status = PIPE_SURFACE_STATUS_DEFINED; pipe_reference_init(&ns->base.reference, 1); ns->base.face = face; ns->base.level = level; diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index ce859def108..10aae298328 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -38,14 +38,6 @@ static void nv40_state_do_validate(struct nv40_context *nv40, struct nv40_state_entry **states) { - const struct pipe_framebuffer_state *fb = &nv40->framebuffer; - unsigned i; - - for (i = 0; i < fb->nr_cbufs; i++) - fb->cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED; - if (fb->zsbuf) - fb->zsbuf->status = PIPE_SURFACE_STATUS_DEFINED; - while (*states) { struct nv40_state_entry *e = *states; diff --git a/src/gallium/drivers/nv50/nv50_clear.c b/src/gallium/drivers/nv50/nv50_clear.c index f9bc3b53caa..db44a9da0e3 100644 --- a/src/gallium/drivers/nv50/nv50_clear.c +++ b/src/gallium/drivers/nv50/nv50_clear.c @@ -86,7 +86,5 @@ nv50_clear(struct pipe_context *pipe, struct pipe_surface *ps, pipe->set_framebuffer_state(pipe, &s_fb); pipe->set_scissor_state(pipe, &s_sc); nv50->dirty |= dirty; - - ps->status = PIPE_SURFACE_STATUS_CLEAR; } diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 313e435e7a5..7b67a754397 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -184,8 +184,8 @@ extern boolean nv50_draw_elements(struct pipe_context *pipe, extern void nv50_vbo_validate(struct nv50_context *nv50); /* nv50_clear.c */ -extern void nv50_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +extern void nv50_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil); /* nv50_program.c */ extern void nv50_vertprog_validate(struct nv50_context *nv50); diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index dc4688ccdc4..f79a7ca86c9 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -163,7 +163,6 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ps->width = pt->width[level]; ps->height = pt->height[level]; ps->usage = flags; - ps->status = PIPE_SURFACE_STATUS_DEFINED; pipe_reference_init(&ps->reference, 1); ps->face = face; ps->level = level; diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c index a2c56f99a89..35cebdbdc32 100644 --- a/src/gallium/drivers/nv50/nv50_query.c +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -41,7 +41,7 @@ nv50_query(struct pipe_query *pipe) static struct pipe_query * nv50_query_create(struct pipe_context *pipe, unsigned type) { - struct pipe_screen *screen = pipe->winsys; + struct pipe_screen *screen = pipe->screen; struct nv50_query *q = CALLOC_STRUCT(nv50_query); assert (q->type == PIPE_QUERY_OCCLUSION_COUNTER); diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 85098a78a25..c13d3de1cb9 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -178,17 +178,10 @@ nv50_state_emit(struct nv50_context *nv50) boolean nv50_state_validate(struct nv50_context *nv50) { - const struct pipe_framebuffer_state *fb = &nv50->framebuffer; struct nouveau_grobj *tesla = nv50->screen->tesla; struct nouveau_stateobj *so; unsigned i; - for (i = 0; i < fb->nr_cbufs; i++) - fb->cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED; - - if (fb->zsbuf) - fb->zsbuf->status = PIPE_SURFACE_STATUS_DEFINED; - if (nv50->dirty & NV50_NEW_FRAMEBUFFER) nv50_state_validate_fb(nv50); @@ -251,7 +244,7 @@ nv50_state_validate(struct nv50_context *nv50) } scissor_uptodate: - if (nv50->dirty & NV50_NEW_VIEWPORT) { + if (nv50->dirty & (NV50_NEW_VIEWPORT | NV50_NEW_RASTERIZER)) { unsigned bypass; if (!nv50->rasterizer->pipe.bypass_vs_clip_and_viewport) @@ -288,6 +281,7 @@ scissor_uptodate: so_ref(so, &nv50->state.viewport); so_ref(NULL, &so); + nv50->state.dirty |= NV50_NEW_VIEWPORT; } viewport_uptodate: diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index 0e4e1155325..e44f9b9dfc5 100644 --- a/src/gallium/drivers/r300/Makefile +++ b/src/gallium/drivers/r300/Makefile @@ -11,13 +11,14 @@ C_SOURCES = \ r300_emit.c \ r300_flush.c \ r300_query.c \ + r300_render.c \ r300_screen.c \ r300_state.c \ r300_state_derived.c \ r300_state_invariant.c \ r300_state_shader.c \ + r300_state_tcl.c \ r300_surface.c \ - r300_swtcl_emit.c \ r300_texture.c include ../../Makefile.template diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript index 18684c3e7f9..182ed2d459a 100644 --- a/src/gallium/drivers/r300/SConscript +++ b/src/gallium/drivers/r300/SConscript @@ -3,15 +3,25 @@ Import('*') env = env.Clone() r300 = env.ConvenienceLibrary( - target = 'r300', - source = [ - 'r300_blit.c', - 'r300_clear.c', - 'r300_context.c', - 'r300_screen.c', - 'r300_state.c', - 'r300_surface.c', - ]) + target = 'r300', + source = [ + 'r300_chipset.c', + 'r300_clear.c', + 'r300_context.c', + 'r300_debug.c', + 'r300_emit.c', + 'r300_flush.c', + 'r300_query.c', + 'r300_render.c', + 'r300_screen.c', + 'r300_state.c', + 'r300_state_derived.c', + 'r300_state_invariant.c', + 'r300_state_shader.c', + 'r300_state_tcl.c', + 'r300_surface.c', + 'r300_texture.c', + ]) Export('r300') diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c index e01a0546b22..9d95ad918c2 100644 --- a/src/gallium/drivers/r300/r300_chipset.c +++ b/src/gallium/drivers/r300/r300_chipset.c @@ -30,7 +30,7 @@ void r300_parse_chipset(struct r300_capabilities* caps) { /* Reasonable defaults */ - caps->has_tcl = getenv("RADEON_NO_TCL") ? TRUE : FALSE; + caps->has_tcl = getenv("RADEON_NO_TCL") ? FALSE : TRUE; caps->is_r500 = FALSE; caps->num_vert_fpus = 4; diff --git a/src/gallium/drivers/r300/r300_clear.c b/src/gallium/drivers/r300/r300_clear.c index fd28437aaa4..8b9cb819ae6 100644 --- a/src/gallium/drivers/r300/r300_clear.c +++ b/src/gallium/drivers/r300/r300_clear.c @@ -22,12 +22,14 @@ #include "r300_clear.h" -/* This gets its own file because Intel's is in its own file. - * I assume there's a good reason. */ +/* Clears currently bound buffers. */ void r300_clear(struct pipe_context* pipe, - struct pipe_surface* ps, - unsigned color) + unsigned buffers, + const float* rgba, + double depth, + unsigned stencil) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, color); - ps->status = PIPE_SURFACE_STATUS_DEFINED; -}
\ No newline at end of file + /* XXX we can and should do one clear if both color and zs are set */ + util_clear(pipe, &r300_context(pipe)->framebuffer_state, + buffers, rgba, depth, stencil); +} diff --git a/src/gallium/drivers/r300/r300_clear.h b/src/gallium/drivers/r300/r300_clear.h index e24a0690c9b..cd5900565e8 100644 --- a/src/gallium/drivers/r300/r300_clear.h +++ b/src/gallium/drivers/r300/r300_clear.h @@ -20,8 +20,17 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "pipe/p_context.h" +#ifndef R300_CLEAR_H +#define R300_CLEAR_H + +#include "util/u_clear.h" + +#include "r300_context.h" void r300_clear(struct pipe_context* pipe, - struct pipe_surface* ps, - unsigned color); + unsigned buffers, + const float* rgba, + double depth, + unsigned stencil); + +#endif /* R300_CLEAR_H */ diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index b8584702aad..31efe914171 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -125,7 +125,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300->context.draw_range_elements = r300_draw_range_elements; r300->draw = draw_create(); - draw_set_rasterize_stage(r300->draw, r300_draw_swtcl_stage(r300)); + draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300)); r300->blend_color_state = CALLOC_STRUCT(r300_blend_color_state); r300->rs_block = CALLOC_STRUCT(r300_rs_block); diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 0e5e471d116..fec2bad5461 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -169,10 +169,7 @@ struct r300_fragment_shader { int indirections; /* Indirection node offsets */ - int offset0; - int offset1; - int offset2; - int offset3; + int alu_offset[4]; /* Machine instructions */ struct { @@ -234,6 +231,29 @@ struct r300_vertex_format { int tab[16]; }; +struct r300_vertex_shader { + /* Parent class */ + struct pipe_shader_state state; + struct tgsi_shader_info info; + + /* Fallback shader, because Draw has issues */ + struct draw_vertex_shader* draw; + + /* Has this shader been translated yet? */ + boolean translated; + + /* Number of used instructions */ + int instruction_count; + + /* Machine instructions */ + struct { + uint32_t inst0; + uint32_t inst1; + uint32_t inst2; + uint32_t inst3; + } instructions[128]; /*< XXX magic number */ +}; + struct r300_context { /* Parent class */ struct pipe_context context; @@ -273,6 +293,8 @@ struct r300_context { int vertex_buffer_count; /* Vertex information. */ struct r300_vertex_format vertex_info; + /* Vertex shader. */ + struct r300_vertex_shader* vs; /* Viewport state. */ struct r300_viewport_state* viewport_state; /* Bitmask of dirty state objects. */ @@ -287,7 +309,7 @@ static struct r300_context* r300_context(struct pipe_context* context) { } /* Context initialization. */ -struct draw_stage* r300_draw_swtcl_stage(struct r300_context* r300); +struct draw_stage* r300_draw_stage(struct r300_context* r300); void r300_init_state_functions(struct r300_context* r300); void r300_init_surface_functions(struct r300_context* r300); diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h index 9913678d272..5d9799dd723 100644 --- a/src/gallium/drivers/r300/r300_cs.h +++ b/src/gallium/drivers/r300/r300_cs.h @@ -132,4 +132,14 @@ OUT_CS(CP_PACKET3(op, count)); \ } while (0) +#define OUT_CS_INDEX_RELOC(bo, offset, count, rd, wd, flags) do { \ + debug_printf("r300: writing relocation for index buffer %p," \ + "offset %d\n", bo, offset); \ + assert(bo); \ + OUT_CS(offset); \ + OUT_CS(count); \ + cs_winsys->write_cs_reloc(cs, bo, rd, wd, flags); \ + cs_count -= 2; \ +} while (0) + #endif /* R300_CS_H */ diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c index f657588c720..dd63136c9d6 100644 --- a/src/gallium/drivers/r300/r300_debug.c +++ b/src/gallium/drivers/r300/r300_debug.c @@ -22,6 +22,14 @@ #include "r300_debug.h" +static void r300_dump_fs(struct r300_fragment_shader* fs) +{ + int i; + + for (i = 0; i < fs->alu_instruction_count; i++) { + } +} + static char* r500_fs_swiz[] = { " R", " G", @@ -216,3 +224,15 @@ void r500_fs_dump(struct r500_fragment_shader* fs) } } } + +void r300_vs_dump(struct r300_vertex_shader* vs) +{ + int i; + + for (i = 0; i < vs->instruction_count; i++) { + debug_printf("inst0: 0x%x\n", vs->instructions[i].inst0); + debug_printf("inst1: 0x%x\n", vs->instructions[i].inst1); + debug_printf("inst2: 0x%x\n", vs->instructions[i].inst2); + debug_printf("inst3: 0x%x\n", vs->instructions[i].inst3); + } +} diff --git a/src/gallium/drivers/r300/r300_debug.h b/src/gallium/drivers/r300/r300_debug.h index de5d701ed9c..a1f873656dc 100644 --- a/src/gallium/drivers/r300/r300_debug.h +++ b/src/gallium/drivers/r300/r300_debug.h @@ -25,7 +25,10 @@ #include "r300_reg.h" #include "r300_state_shader.h" +#include "r300_state_tcl.h" void r500_fs_dump(struct r500_fragment_shader* fs); +void r300_vs_dump(struct r300_vertex_shader* vs); + #endif /* R300_DEBUG_H */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 9bfb89626cd..a3d83376b66 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -82,20 +82,20 @@ void r300_emit_dsa_state(struct r300_context* r300, void r300_emit_fragment_shader(struct r300_context* r300, struct r300_fragment_shader* fs) { - CS_LOCALS(r300); int i; + CS_LOCALS(r300); BEGIN_CS(22); - OUT_CS_REG(R300_US_CONFIG, MAX2(fs->indirections - 1, 0)); + OUT_CS_REG(R300_US_CONFIG, fs->indirections); OUT_CS_REG(R300_US_PIXSIZE, fs->shader.stack_size); /* XXX figure out exactly how big the sizes are on this reg */ - OUT_CS_REG(R300_US_CODE_OFFSET, 0x0); + OUT_CS_REG(R300_US_CODE_OFFSET, 0x40); /* XXX figure these ones out a bit better kthnx */ OUT_CS_REG(R300_US_CODE_ADDR_0, 0x0); OUT_CS_REG(R300_US_CODE_ADDR_1, 0x0); OUT_CS_REG(R300_US_CODE_ADDR_2, 0x0); - OUT_CS_REG(R300_US_CODE_ADDR_3, R300_RGBA_OUT); + OUT_CS_REG(R300_US_CODE_ADDR_3, 0x40 | R300_RGBA_OUT); for (i = 0; i < fs->alu_instruction_count; i++) { OUT_CS_REG(R300_US_ALU_RGB_INST_0 + (4 * i), @@ -114,10 +114,10 @@ void r300_emit_fragment_shader(struct r300_context* r300, void r500_emit_fragment_shader(struct r300_context* r300, struct r500_fragment_shader* fs) { - CS_LOCALS(r300); + int i; struct r300_constant_buffer* constants = &r300->shader_constants[PIPE_SHADER_FRAGMENT]; - int i; + CS_LOCALS(r300); BEGIN_CS(9 + (fs->instruction_count * 6) + (constants->count ? 3 : 0) + (constants->count * 4)); @@ -156,9 +156,9 @@ void r500_emit_fragment_shader(struct r300_context* r300, void r300_emit_fb_state(struct r300_context* r300, struct pipe_framebuffer_state* fb) { - CS_LOCALS(r300); - struct r300_texture* tex; int i; + struct r300_texture* tex; + CS_LOCALS(r300); BEGIN_CS((6 * fb->nr_cbufs) + (fb->zsbuf ? 6 : 0) + 4); for (i = 0; i < fb->nr_cbufs; i++) { @@ -217,9 +217,9 @@ void r300_emit_rs_state(struct r300_context* r300, struct r300_rs_state* rs) void r300_emit_rs_block_state(struct r300_context* r300, struct r300_rs_block* rs) { + int i; struct r300_screen* r300screen = r300_screen(r300->context.screen); CS_LOCALS(r300); - int i; BEGIN_CS(21); if (r300screen->caps->is_r500) { @@ -293,8 +293,8 @@ void r300_emit_texture(struct r300_context* r300, void r300_emit_vertex_format_state(struct r300_context* r300) { - CS_LOCALS(r300); int i; + CS_LOCALS(r300); BEGIN_CS(26); OUT_CS_REG(R300_VAP_VTX_SIZE, r300->vertex_info.vinfo.size); @@ -325,25 +325,80 @@ void r300_emit_vertex_format_state(struct r300_context* r300) END_CS; } +void r300_emit_vertex_shader(struct r300_context* r300, + struct r300_vertex_shader* vs) +{ + int i; + struct r300_screen* r300screen = r300_screen(r300->context.screen); + struct r300_constant_buffer* constants = + &r300->shader_constants[PIPE_SHADER_VERTEX]; + CS_LOCALS(r300); + + if (!r300screen->caps->has_tcl) { + debug_printf("r300: Implementation error: emit_vertex_shader called," + " but has_tcl is FALSE!\n"); + return; + } + + BEGIN_CS(13 + (vs->instruction_count * 4) + (constants->count * 4)); + + OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_0, R300_PVS_FIRST_INST(0) | + R300_PVS_LAST_INST(vs->instruction_count - 1)); + OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_1, vs->instruction_count - 1); + + /* XXX */ + OUT_CS_REG(R300_VAP_PVS_CONST_CNTL, 0x0); + + OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0); + OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, vs->instruction_count * 4); + for (i = 0; i < vs->instruction_count; i++) { + OUT_CS(vs->instructions[i].inst0); + OUT_CS(vs->instructions[i].inst1); + OUT_CS(vs->instructions[i].inst2); + OUT_CS(vs->instructions[i].inst3); + } + + if (constants->count) { + OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, + (r300screen->caps->is_r500 ? + R500_PVS_CONST_START : R300_PVS_CONST_START)); + OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, constants->count * 4); + for (i = 0; i < constants->count; i++) { + OUT_CS_32F(constants->constants[i][0]); + OUT_CS_32F(constants->constants[i][1]); + OUT_CS_32F(constants->constants[i][2]); + OUT_CS_32F(constants->constants[i][3]); + } + } + + OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(10) | + R300_PVS_NUM_CNTLRS(5) | + R300_PVS_NUM_FPUS(r300screen->caps->num_vert_fpus) | + R300_PVS_VF_MAX_VTX_NUM(12)); + OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0); + END_CS; + +} + void r300_emit_viewport_state(struct r300_context* r300, struct r300_viewport_state* viewport) { - return; CS_LOCALS(r300); - BEGIN_CS(7); - OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 7); + BEGIN_CS(9); + OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6); OUT_CS_32F(viewport->xscale); OUT_CS_32F(viewport->xoffset); OUT_CS_32F(viewport->yscale); OUT_CS_32F(viewport->yoffset); OUT_CS_32F(viewport->zscale); OUT_CS_32F(viewport->zoffset); - OUT_CS(viewport->vte_control); + + OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control); END_CS; } -static void r300_flush_textures(struct r300_context* r300) +void r300_flush_textures(struct r300_context* r300) { CS_LOCALS(r300); diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 0bc1f90e6ab..31dbc7ab853 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -64,9 +64,14 @@ void r300_emit_texture(struct r300_context* r300, void r300_emit_vertex_format_state(struct r300_context* r300); +void r300_emit_vertex_shader(struct r300_context* r300, + struct r300_vertex_shader* vs); + void r300_emit_viewport_state(struct r300_context* r300, struct r300_viewport_state* viewport); +void r300_flush_textures(struct r300_context* r300); + /* Emit all dirty state. */ void r300_emit_dirty_state(struct r300_context* r300); diff --git a/src/gallium/drivers/r300/r300_query.c b/src/gallium/drivers/r300/r300_query.c index 5f5f4c4dbd4..8fc61c2dec7 100644 --- a/src/gallium/drivers/r300/r300_query.c +++ b/src/gallium/drivers/r300/r300_query.c @@ -46,12 +46,12 @@ static void r300_destroy_query(struct pipe_context* pipe, static void r300_begin_query(struct pipe_context* pipe, struct pipe_query* query) { + uint32_t* map; struct r300_context* r300 = r300_context(pipe); struct r300_query* q = (struct r300_query*)query; CS_LOCALS(r300); - uint32_t* map = pipe_buffer_map(pipe->screen, q->buf, - PIPE_BUFFER_USAGE_CPU_WRITE); + map = pipe_buffer_map(pipe->screen, q->buf, PIPE_BUFFER_USAGE_CPU_WRITE); *map = ~0; pipe_buffer_unmap(pipe->screen, q->buf); @@ -79,6 +79,7 @@ static boolean r300_get_query_result(struct pipe_context* pipe, uint64_t* result) { struct r300_query* q = (struct r300_query*)query; + uint32_t* map; uint32_t temp; if (wait) { @@ -88,8 +89,7 @@ static boolean r300_get_query_result(struct pipe_context* pipe, pipe->flush(pipe, 0, NULL); } - uint32_t* map = pipe_buffer_map(pipe->screen, q->buf, - PIPE_BUFFER_USAGE_CPU_READ); + map = pipe_buffer_map(pipe->screen, q->buf, PIPE_BUFFER_USAGE_CPU_READ); temp = *map; pipe_buffer_unmap(pipe->screen, q->buf); diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h index 3fe45e13932..660816e1da1 100644 --- a/src/gallium/drivers/r300/r300_reg.h +++ b/src/gallium/drivers/r300/r300_reg.h @@ -73,6 +73,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_PVS_NUM_CNTLRS_SHIFT 4 # define R300_PVS_NUM_FPUS_SHIFT 8 # define R300_VF_MAX_VTX_NUM_SHIFT 18 +# define R300_PVS_NUM_SLOTS(x) ((x) << 0) +# define R300_PVS_NUM_CNTLRS(x) ((x) << 4) +# define R300_PVS_NUM_FPUS(x) ((x) << 8) +# define R300_PVS_VF_MAX_VTX_NUM(x) ((x) << 18) # define R300_GL_CLIP_SPACE_DEF (0 << 22) # define R300_DX_CLIP_SPACE_DEF (1 << 22) # define R500_TCL_STATE_OPTIMIZATION (1 << 23) @@ -506,6 +510,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_PVS_FIRST_INST_SHIFT 0 # define R300_PVS_XYZW_VALID_INST_SHIFT 10 # define R300_PVS_LAST_INST_SHIFT 20 +# define R300_PVS_FIRST_INST(x) ((x) << 0) +# define R300_PVS_LAST_INST(x) ((x) << 20) /* Addresses are relative the the vertex program parameters area. */ #define R300_VAP_PVS_CONST_CNTL 0x22D4 # define R300_PVS_CONST_BASE_OFFSET_SHIFT 0 @@ -1191,6 +1197,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_RS_INST_COUNT_MASK 0x0000000f # define R300_RS_TX_OFFSET_SHIFT 5 # define R300_RS_TX_OFFSET_MASK 0x000000e0 +# define R300_RS_TX_OFFSET(x) ((x) << 5) /* gap */ @@ -1434,6 +1441,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_TX_MAX_ANISO_8_TO_1 (3 << 21) # define R300_TX_MAX_ANISO_16_TO_1 (4 << 21) # define R300_TX_MAX_ANISO_MASK (7 << 21) +# define R300_TX_WRAP_S(x) ((x) << 0) +# define R300_TX_WRAP_T(x) ((x) << 3) #define R300_TX_FILTER1_0 0x4440 # define R300_CHROMA_KEY_MODE_DISABLE 0 diff --git a/src/gallium/drivers/r300/r300_swtcl_emit.c b/src/gallium/drivers/r300/r300_render.c index 83c25f496bf..b7ee8fb8a94 100644 --- a/src/gallium/drivers/r300/r300_swtcl_emit.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Corbin Simpson <[email protected]> + * Copyright 2009 Corbin Simpson <[email protected]> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -29,9 +29,9 @@ #include "r300_reg.h" #include "r300_state_derived.h" -/* r300_swtcl_emit: Vertex and index buffer primitive emission. No HW TCL. */ +/* r300_render: Vertex and index buffer primitive emission. */ -struct r300_swtcl_render { +struct r300_render { /* Parent class */ struct vbuf_render base; @@ -52,16 +52,16 @@ struct r300_swtcl_render { size_t vbo_max_used; }; -static INLINE struct r300_swtcl_render* -r300_swtcl_render(struct vbuf_render* render) +static INLINE struct r300_render* +r300_render(struct vbuf_render* render) { - return (struct r300_swtcl_render*)render; + return (struct r300_render*)render; } static const struct vertex_info* -r300_swtcl_render_get_vertex_info(struct vbuf_render* render) +r300_render_get_vertex_info(struct vbuf_render* render) { - struct r300_swtcl_render* r300render = r300_swtcl_render(render); + struct r300_render* r300render = r300_render(render); struct r300_context* r300 = r300render->r300; r300_update_derived_state(r300); @@ -69,11 +69,11 @@ r300_swtcl_render_get_vertex_info(struct vbuf_render* render) return &r300->vertex_info.vinfo; } -static boolean r300_swtcl_render_allocate_vertices(struct vbuf_render* render, +static boolean r300_render_allocate_vertices(struct vbuf_render* render, ushort vertex_size, ushort count) { - struct r300_swtcl_render* r300render = r300_swtcl_render(render); + struct r300_render* r300render = r300_render(render); struct r300_context* r300 = r300render->r300; struct pipe_screen* screen = r300->context.screen; size_t size = (size_t)vertex_size * (size_t)count; @@ -98,9 +98,9 @@ static boolean r300_swtcl_render_allocate_vertices(struct vbuf_render* render, } } -static void* r300_swtcl_render_map_vertices(struct vbuf_render* render) +static void* r300_render_map_vertices(struct vbuf_render* render) { - struct r300_swtcl_render* r300render = r300_swtcl_render(render); + struct r300_render* r300render = r300_render(render); struct pipe_screen* screen = r300render->r300->context.screen; r300render->vbo_map = pipe_buffer_map(screen, r300render->vbo, @@ -109,11 +109,11 @@ static void* r300_swtcl_render_map_vertices(struct vbuf_render* render) return (unsigned char*)r300render->vbo_map + r300render->vbo_offset; } -static void r300_swtcl_render_unmap_vertices(struct vbuf_render* render, +static void r300_render_unmap_vertices(struct vbuf_render* render, ushort min, ushort max) { - struct r300_swtcl_render* r300render = r300_swtcl_render(render); + struct r300_render* r300render = r300_render(render); struct pipe_screen* screen = r300render->r300->context.screen; r300render->vbo_max_used = MAX2(r300render->vbo_max_used, @@ -122,17 +122,17 @@ static void r300_swtcl_render_unmap_vertices(struct vbuf_render* render, pipe_buffer_unmap(screen, r300render->vbo); } -static void r300_swtcl_render_release_vertices(struct vbuf_render* render) +static void r300_render_release_vertices(struct vbuf_render* render) { - struct r300_swtcl_render* r300render = r300_swtcl_render(render); + struct r300_render* r300render = r300_render(render); pipe_buffer_reference(&r300render->vbo, NULL); } -static boolean r300_swtcl_render_set_primitive(struct vbuf_render* render, +static boolean r300_render_set_primitive(struct vbuf_render* render, unsigned prim) { - struct r300_swtcl_render* r300render = r300_swtcl_render(render); + struct r300_render* r300render = r300_render(render); r300render->prim = prim; switch (prim) { @@ -174,7 +174,7 @@ static boolean r300_swtcl_render_set_primitive(struct vbuf_render* render, return TRUE; } -static void prepare_render(struct r300_swtcl_render* render, unsigned count) +static void prepare_render(struct r300_render* render, unsigned count) { struct r300_context* r300 = render->r300; @@ -203,11 +203,11 @@ static void prepare_render(struct r300_swtcl_render* render, unsigned count) END_CS; } -static void r300_swtcl_render_draw_arrays(struct vbuf_render* render, +static void r300_render_draw_arrays(struct vbuf_render* render, unsigned start, unsigned count) { - struct r300_swtcl_render* r300render = r300_swtcl_render(render); + struct r300_render* r300render = r300_render(render); struct r300_context* r300 = r300render->r300; CS_LOCALS(r300); @@ -225,11 +225,11 @@ static void r300_swtcl_render_draw_arrays(struct vbuf_render* render, END_CS; } -static void r300_swtcl_render_draw(struct vbuf_render* render, +static void r300_render_draw(struct vbuf_render* render, const ushort* indices, uint count) { - struct r300_swtcl_render* r300render = r300_swtcl_render(render); + struct r300_render* r300render = r300_render(render); struct r300_context* r300 = r300render->r300; struct pipe_screen* screen = r300->context.screen; struct pipe_buffer* index_buffer; @@ -241,7 +241,7 @@ static void r300_swtcl_render_draw(struct vbuf_render* render, /* Send our indices into an index buffer. */ index_buffer = pipe_buffer_create(screen, 64, PIPE_BUFFER_USAGE_VERTEX, - count); + count * 2); if (!index_buffer) { return; } @@ -253,25 +253,24 @@ static void r300_swtcl_render_draw(struct vbuf_render* render, debug_printf("r300: Doing indexbuf render, count %d\n", count); - BEGIN_CS(5); + BEGIN_CS(6); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0); OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | - r300render->hwprim | R300_VAP_VF_CNTL__INDEX_SIZE_32bit); - + r300render->hwprim); OUT_CS_PKT3(R300_PACKET3_INDX_BUFFER, 2); OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2)); - OUT_CS_RELOC(index_buffer, 0, RADEON_GEM_DOMAIN_GTT, 0, 0); + OUT_CS_INDEX_RELOC(index_buffer, 0, count, RADEON_GEM_DOMAIN_GTT, 0, 0); END_CS; } -static void r300_swtcl_render_destroy(struct vbuf_render* render) +static void r300_render_destroy(struct vbuf_render* render) { FREE(render); } -static struct vbuf_render* r300_swtcl_render_create(struct r300_context* r300) +static struct vbuf_render* r300_render_create(struct r300_context* r300) { - struct r300_swtcl_render* r300render = CALLOC_STRUCT(r300_swtcl_render); + struct r300_render* r300render = CALLOC_STRUCT(r300_render); r300render->r300 = r300; @@ -279,25 +278,25 @@ static struct vbuf_render* r300_swtcl_render_create(struct r300_context* r300) r300render->base.max_vertex_buffer_bytes = 128 * 1024; r300render->base.max_indices = 16 * 1024; - r300render->base.get_vertex_info = r300_swtcl_render_get_vertex_info; - r300render->base.allocate_vertices = r300_swtcl_render_allocate_vertices; - r300render->base.map_vertices = r300_swtcl_render_map_vertices; - r300render->base.unmap_vertices = r300_swtcl_render_unmap_vertices; - r300render->base.set_primitive = r300_swtcl_render_set_primitive; - r300render->base.draw = r300_swtcl_render_draw; - r300render->base.draw_arrays = r300_swtcl_render_draw_arrays; - r300render->base.release_vertices = r300_swtcl_render_release_vertices; - r300render->base.destroy = r300_swtcl_render_destroy; + r300render->base.get_vertex_info = r300_render_get_vertex_info; + r300render->base.allocate_vertices = r300_render_allocate_vertices; + r300render->base.map_vertices = r300_render_map_vertices; + r300render->base.unmap_vertices = r300_render_unmap_vertices; + r300render->base.set_primitive = r300_render_set_primitive; + r300render->base.draw = r300_render_draw; + r300render->base.draw_arrays = r300_render_draw_arrays; + r300render->base.release_vertices = r300_render_release_vertices; + r300render->base.destroy = r300_render_destroy; return &r300render->base; } -struct draw_stage* r300_draw_swtcl_stage(struct r300_context* r300) +struct draw_stage* r300_draw_stage(struct r300_context* r300) { struct vbuf_render* render; struct draw_stage* stage; - render = r300_swtcl_render_create(r300); + render = r300_render_create(r300); if (!render) { return NULL; diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 2a026e7fcac..2a77fd17390 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -132,6 +132,7 @@ static void const struct pipe_constant_buffer* buffer) { struct r300_context* r300 = r300_context(pipe); + int i = r300->shader_constants[shader].user_count; /* This entire chunk of code seems ever-so-slightly baked. * It's as if I've got pipe_buffer* matryoshkas... */ @@ -149,6 +150,17 @@ static void } r300->dirty_state |= R300_NEW_CONSTANTS; + + /* If the number of constants have changed, invalidate the shader. */ + if (r300->shader_constants[shader].user_count != i) { + if (shader == PIPE_SHADER_FRAGMENT && r300->fs) { + r300->fs->translated = FALSE; + r300_translate_fragment_shader(r300, r300->fs); + } else if (shader == PIPE_SHADER_VERTEX && r300->vs) { + r300->vs->translated = FALSE; + r300_translate_vertex_shader(r300, r300->vs); + } + } } /* Create a new depth, stencil, and alpha state based on the CSO dsa state. @@ -293,11 +305,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) r300->fs = NULL; return; } else if (!fs->translated) { - if (r300_screen(r300->context.screen)->caps->is_r500) { - r500_translate_fragment_shader(r300, (struct r500_fragment_shader*)fs); - } else { - r300_translate_fragment_shader(r300, (struct r300_fragment_shader*)fs); - } + r300_translate_fragment_shader(r300, fs); } fs->translated = TRUE; @@ -330,9 +338,18 @@ static void* r300_create_rs_state(struct pipe_context* pipe, { struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state); - /* XXX this is part of HW TCL */ - /* XXX endian control */ - rs->vap_control_status = R300_VAP_TCL_BYPASS; + /* Copy rasterizer state for Draw. */ + rs->rs = *state; + + /* If bypassing TCL, or if no TCL engine is present, turn off the HW TCL. + * Else, enable HW TCL and force Draw's TCL off. */ + if (state->bypass_vs_clip_and_viewport || + !r300_screen(pipe->screen)->caps->has_tcl) { + rs->vap_control_status = R300_VAP_TCL_BYPASS; + } else { + rs->rs.bypass_vs_clip_and_viewport = TRUE; + rs->vap_control_status = 0; + } rs->point_size = pack_float_16_6x(state->point_size) | (pack_float_16_6x(state->point_size) << R300_POINTSIZE_X_SHIFT); @@ -395,8 +412,6 @@ static void* r300_create_rs_state(struct pipe_context* pipe, rs->color_control = R300_SHADE_MODEL_SMOOTH; } - rs->rs = *state; - return (void*)rs; } @@ -581,30 +596,68 @@ static void r300_set_vertex_elements(struct pipe_context* pipe, const struct pipe_vertex_element* elements) { struct r300_context* r300 = r300_context(pipe); - /* XXX Draw */ + draw_flush(r300->draw); draw_set_vertex_elements(r300->draw, count, elements); } static void* r300_create_vs_state(struct pipe_context* pipe, - const struct pipe_shader_state* state) + const struct pipe_shader_state* shader) { - struct r300_context* context = r300_context(pipe); - /* XXX handing this off to Draw for now */ - return draw_create_vertex_shader(context->draw, state); + struct r300_context* r300 = r300_context(pipe); + + if (r300_screen(pipe->screen)->caps->has_tcl) { + struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader); + /* Copy state directly into shader. */ + vs->state = *shader; + + tgsi_scan_shader(shader->tokens, &vs->info); + + /* Appease Draw. */ + vs->draw = draw_create_vertex_shader(r300->draw, shader); + + return (void*)vs; + } else { + return draw_create_vertex_shader(r300->draw, shader); + } } -static void r300_bind_vs_state(struct pipe_context* pipe, void* state) { - struct r300_context* context = r300_context(pipe); - /* XXX handing this off to Draw for now */ - draw_bind_vertex_shader(context->draw, (struct draw_vertex_shader*)state); +static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) +{ + struct r300_context* r300 = r300_context(pipe); + + if (r300_screen(pipe->screen)->caps->has_tcl) { + struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader; + + if (vs == NULL) { + r300->vs = NULL; + return; + } else if (!vs->translated) { + r300_translate_vertex_shader(r300, vs); + } + + draw_bind_vertex_shader(r300->draw, vs->draw); + r300->vs = vs; + r300->dirty_state |= R300_NEW_VERTEX_SHADER; + } else { + draw_bind_vertex_shader(r300->draw, + (struct draw_vertex_shader*)shader); + } } -static void r300_delete_vs_state(struct pipe_context* pipe, void* state) +static void r300_delete_vs_state(struct pipe_context* pipe, void* shader) { - struct r300_context* context = r300_context(pipe); - /* XXX handing this off to Draw for now */ - draw_delete_vertex_shader(context->draw, (struct draw_vertex_shader*)state); + struct r300_context* r300 = r300_context(pipe); + + if (r300_screen(pipe->screen)->caps->has_tcl) { + struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader; + + draw_delete_vertex_shader(r300->draw, vs->draw); + FREE(shader); + } else { + draw_delete_vertex_shader(r300->draw, + (struct draw_vertex_shader*)shader); + } } void r300_init_state_functions(struct r300_context* r300) diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index d761a0302f0..f1feafbcf91 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -30,9 +30,9 @@ * The vertex_info struct describes the post-TCL format of vertices. It is * required for Draw when doing SW TCL, and also for describing the * dreaded RS block on R300 chipsets. */ -/* XXX this function should be able to handle vert shaders as well as draw */ static void r300_update_vertex_layout(struct r300_context* r300) { + struct r300_screen* r300screen = r300_screen(r300->context.screen); struct r300_vertex_format vformat; struct vertex_info vinfo; boolean pos = FALSE, psize = FALSE, fog = FALSE; @@ -74,6 +74,13 @@ static void r300_update_vertex_layout(struct r300_context* r300) } } + if (r300screen->caps->has_tcl) { + for (i = 0; i < info->num_inputs; i++) { + /* XXX should probably do real lookup with vert shader */ + tab[i] = i; + } + } + /* Do the actual vertex_info setup. * * vertex_info has four uints of hardware-specific data in it. @@ -211,7 +218,6 @@ static void r300_update_rs_block(struct r300_context* r300) rs->ip[0] |= R500_RS_COL_FMT(R300_RS_COL_FMT_0001); } - /* Set up at least one texture pointer or RS will not be happy. */ if (tex_count == 0) { rs->ip[0] |= R500_RS_SEL_S(R500_RS_IP_PTR_K0) | @@ -220,15 +226,20 @@ static void r300_update_rs_block(struct r300_context* r300) R500_RS_SEL_Q(R500_RS_IP_PTR_K1); } + /* Rasterize at least one color, or bad things happen. */ + if ((col_count == 0) && (tex_count == 0)) { + col_count++; + } + for (i = 0; i < tex_count; i++) { - rs->inst[i] |= R500_RS_INST_TEX_ID(i) | R500_RS_INST_TEX_CN_WRITE | - R500_RS_INST_TEX_ADDR(fp_offset); + rs->inst[i] |= R500_RS_INST_TEX_ID(i) | + R500_RS_INST_TEX_CN_WRITE | R500_RS_INST_TEX_ADDR(fp_offset); fp_offset++; } for (i = 0; i < col_count; i++) { - rs->inst[i] |= R500_RS_INST_COL_ID(i) | R500_RS_INST_COL_CN_WRITE | - R500_RS_INST_COL_ADDR(fp_offset); + rs->inst[i] |= R500_RS_INST_COL_ID(i) | + R500_RS_INST_COL_CN_WRITE | R500_RS_INST_COL_ADDR(fp_offset); fp_offset++; } } else { @@ -268,15 +279,20 @@ static void r300_update_rs_block(struct r300_context* r300) R300_RS_SEL_Q(R300_RS_SEL_K1); } + /* Rasterize at least one color, or bad things happen. */ + if ((col_count == 0) && (tex_count == 0)) { + col_count++; + } + for (i = 0; i < tex_count; i++) { - rs->inst[i] |= R300_RS_INST_TEX_ID(i) | R300_RS_INST_TEX_CN_WRITE | - R300_RS_INST_TEX_ADDR(fp_offset); + rs->inst[i] |= R300_RS_INST_TEX_ID(i) | + R300_RS_INST_TEX_CN_WRITE | R300_RS_INST_TEX_ADDR(fp_offset); fp_offset++; } for (i = 0; i < col_count; i++) { - rs->inst[i] |= R300_RS_INST_COL_ID(i) | R300_RS_INST_COL_CN_WRITE | - R300_RS_INST_COL_ADDR(fp_offset); + rs->inst[i] |= R300_RS_INST_COL_ID(i) | + R300_RS_INST_COL_CN_WRITE | R300_RS_INST_COL_ADDR(fp_offset); fp_offset++; } } @@ -289,7 +305,8 @@ static void r300_update_rs_block(struct r300_context* r300) void r300_update_derived_state(struct r300_context* r300) { - if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER) { + if (r300->dirty_state & + (R300_NEW_FRAGMENT_SHADER | R300_NEW_VERTEX_SHADER)) { r300_update_vertex_layout(r300); } diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h index b80ff1c1aba..91b93fc367e 100644 --- a/src/gallium/drivers/r300/r300_state_inlines.h +++ b/src/gallium/drivers/r300/r300_state_inlines.h @@ -292,6 +292,7 @@ static INLINE uint32_t r300_translate_colorformat(enum pipe_format format) return R300_COLOR_FORMAT_ARGB4444; /* 32-bit buffers */ case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: return R300_COLOR_FORMAT_ARGB8888; /* XXX Not in pipe_format case PIPE_FORMAT_A32R32G32B32: @@ -337,6 +338,7 @@ static INLINE uint32_t r300_translate_out_fmt(enum pipe_format format) { switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: return R300_US_OUT_FMT_C4_8 | R300_C0_SEL_B | R300_C1_SEL_G | R300_C2_SEL_R | R300_C3_SEL_A; diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c index e1837b63801..8bd9b41bd74 100644 --- a/src/gallium/drivers/r300/r300_state_invariant.c +++ b/src/gallium/drivers/r300/r300_state_invariant.c @@ -86,7 +86,7 @@ void r300_emit_invariant_state(struct r300_context* r300) END_CS; /* XXX unsorted stuff from surface_fill */ - BEGIN_CS(91 + (caps->has_tcl ? 26 : 0)); + BEGIN_CS(79 + (caps->has_tcl ? 7 : 0)); /* Flush PVS. */ OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0); @@ -141,28 +141,11 @@ void r300_emit_invariant_state(struct r300_context* r300) OUT_CS_REG(R300_ZB_DEPTHCLEARVALUE, 0x00000000); OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0x00000000); OUT_CS_REG(R300_ZB_HIZ_PITCH, 0x00000000); - if (caps->has_tcl) { - OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, - (R300_DATA_TYPE_FLOAT_4 << R300_DATA_TYPE_0_SHIFT) | - ((R300_LAST_VEC | (1 << R300_DST_VEC_LOC_SHIFT) | - R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT)); - } else { - OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, - (R300_DATA_TYPE_FLOAT_4 << R300_DATA_TYPE_0_SHIFT) | - ((R300_LAST_VEC | (2 << R300_DST_VEC_LOC_SHIFT) | - R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT)); - } - OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0, - (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE0_SHIFT) | - (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE1_SHIFT)); OUT_CS_REG(R300_VAP_VTX_STATE_CNTL, 0x1); OUT_CS_REG(R300_VAP_VSM_VTX_ASSM, 0x405); OUT_CS_REG(R300_SE_VTE_CNTL, 0x0000043F); /* Vertex size. */ OUT_CS_REG(R300_VAP_VTX_SIZE, 0x8); - OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_0, 0x00000003); - OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_1, 0x00000000); - OUT_CS_REG(R300_TX_ENABLE, 0x0); /* XXX */ OUT_CS_REG(R300_SC_CLIP_RULE, 0xaaaa); @@ -173,33 +156,5 @@ void r300_emit_invariant_state(struct r300_context* r300) OUT_CS(R300_US_OUT_FMT_UNUSED); OUT_CS(R300_US_OUT_FMT_UNUSED); OUT_CS_REG(R300_US_W_FMT, R300_W_FMT_W0); - /* XXX these magic numbers should be explained when - * this becomes a cached state object */ - if (caps->has_tcl) { - OUT_CS_REG(R300_VAP_CNTL, 0xA | - (0x5 << R300_PVS_NUM_CNTLRS_SHIFT) | - (0xB << R300_VF_MAX_VTX_NUM_SHIFT) | - (caps->num_vert_fpus << R300_PVS_NUM_FPUS_SHIFT)); - OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_0, 0x00100000); - OUT_CS_REG(R300_VAP_PVS_CONST_CNTL, 0x00000000); - OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_1, 0x00000001); - /* XXX translate these back into normal instructions */ - OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x1); - OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0x0); - OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, 8); - OUT_CS(0x00F00203); - OUT_CS(0x00D10001); - OUT_CS(0x01248001); - OUT_CS(0x00000000); - OUT_CS(0x00F02203); - OUT_CS(0x00D10021); - OUT_CS(0x01248021); - OUT_CS(0x00000000); - } else { - OUT_CS_REG(R300_VAP_CNTL, 0xA | - (0x5 << R300_PVS_NUM_CNTLRS_SHIFT) | - (0x5 << R300_VF_MAX_VTX_NUM_SHIFT) | - (caps->num_vert_fpus << R300_PVS_NUM_FPUS_SHIFT)); - } END_CS; } diff --git a/src/gallium/drivers/r300/r300_state_invariant.h b/src/gallium/drivers/r300/r300_state_invariant.h index 8204bf9588b..5bea6779fe5 100644 --- a/src/gallium/drivers/r300/r300_state_invariant.h +++ b/src/gallium/drivers/r300/r300_state_invariant.h @@ -23,6 +23,7 @@ #ifndef R300_STATE_INVARIANT_H #define R300_STATE_INVARIANT_H +#include "r300_chipset.h" #include "r300_context.h" #include "r300_cs.h" #include "r300_reg.h" diff --git a/src/gallium/drivers/r300/r300_state_shader.c b/src/gallium/drivers/r300/r300_state_shader.c index 20b83bd15b1..1b02239ee76 100644 --- a/src/gallium/drivers/r300/r300_state_shader.c +++ b/src/gallium/drivers/r300/r300_state_shader.c @@ -171,6 +171,26 @@ static INLINE uint32_t r500_alpha_swiz(struct tgsi_full_src_register* reg) (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0); } +static INLINE uint32_t r300_rgb_op(unsigned op) +{ + switch (op) { + case TGSI_OPCODE_MOV: + return R300_ALU_OUTC_CMP; + default: + return 0; + } +} + +static INLINE uint32_t r300_alpha_op(unsigned op) +{ + switch (op) { + case TGSI_OPCODE_MOV: + return R300_ALU_OUTA_CMP; + default: + return 0; + } +} + static INLINE uint32_t r500_rgba_op(unsigned op) { switch (op) { @@ -249,6 +269,31 @@ static INLINE uint32_t r500_tex_op(unsigned op) } } +static INLINE void r300_emit_maths(struct r300_fragment_shader* fs, + struct r300_fs_asm* assembler, + struct tgsi_full_src_register* src, + struct tgsi_full_dst_register* dst, + unsigned op, + unsigned count) +{ + int i = fs->alu_instruction_count; + + fs->instructions[i].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | + R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | + R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | + r300_rgb_op(op); + fs->instructions[i].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | + R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ; + fs->instructions[i].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | + R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | + R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | + r300_alpha_op(op); + fs->instructions[i].alu_alpha_addr = R300_ALPHA_ADDR0(0) | + R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT; + + fs->alu_instruction_count++; +} + /* Setup an ALU operation. */ static INLINE void r500_emit_alu(struct r500_fragment_shader* fs, struct r300_fs_asm* assembler, @@ -367,11 +412,31 @@ static INLINE void r500_emit_tex(struct r500_fragment_shader* fs, } } +static void r300_fs_instruction(struct r300_fragment_shader* fs, + struct r300_fs_asm* assembler, + struct tgsi_full_instruction* inst) +{ + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_MOV: + /* src0 -> src1 and src2 forced to zero */ + inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0]; + inst->FullSrcRegisters[2] = r500_constant_zero; + r300_emit_maths(fs, assembler, inst->FullSrcRegisters, + &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); + break; + case TGSI_OPCODE_END: + break; + default: + debug_printf("r300: fs: Bad opcode %d\n", + inst->Instruction.Opcode); + break; + } +} + static void r500_fs_instruction(struct r500_fragment_shader* fs, struct r300_fs_asm* assembler, struct tgsi_full_instruction* inst) { - int i; /* Switch between opcodes. When possible, prefer using the official * AMD/ATI names for opcodes, please, as it facilitates using the * documentation. */ @@ -487,35 +552,26 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs, } } -static void r500_fs_finalize(struct r500_fragment_shader* fs, +static void r300_fs_finalize(struct r3xx_fragment_shader* fs, struct r300_fs_asm* assembler) { - fs->shader.stack_size = assembler->temp_count + assembler->temp_offset; + fs->stack_size = assembler->temp_count + assembler->temp_offset; +} +static void r500_fs_finalize(struct r500_fragment_shader* fs, + struct r300_fs_asm* assembler) +{ /* XXX should this just go with OPCODE_END? */ fs->instructions[fs->instruction_count - 1].inst0 |= R500_INST_LAST; } void r300_translate_fragment_shader(struct r300_context* r300, - struct r300_fragment_shader* fs) -{ - struct tgsi_parse_context parser; - - tgsi_parse_init(&parser, fs->shader.state.tokens); - - while (!tgsi_parse_end_of_tokens(&parser)) { - tgsi_parse_token(&parser); - } - - r300_copy_passthrough_shader(fs); -} - -void r500_translate_fragment_shader(struct r300_context* r300, - struct r500_fragment_shader* fs) + struct r3xx_fragment_shader* fs) { struct tgsi_parse_context parser; int i; + boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500; struct r300_constant_buffer* consts = &r300->shader_constants[PIPE_SHADER_FRAGMENT]; @@ -526,7 +582,12 @@ void r500_translate_fragment_shader(struct r300_context* r300, /* Setup starting offset for immediates. */ assembler->imm_offset = consts->user_count; - tgsi_parse_init(&parser, fs->shader.state.tokens); + /* Make sure we start at the beginning of the shader. */ + if (is_r500) { + ((struct r500_fragment_shader*)fs)->instruction_count = 0; + } + + tgsi_parse_init(&parser, fs->state.tokens); while (!tgsi_parse_end_of_tokens(&parser)) { tgsi_parse_token(&parser); @@ -553,25 +614,35 @@ void r500_translate_fragment_shader(struct r300_context* r300, assembler->imm_count++; break; case TGSI_TOKEN_TYPE_INSTRUCTION: - r500_fs_instruction(fs, assembler, - &parser.FullToken.FullInstruction); + if (is_r500) { + r500_fs_instruction((struct r500_fragment_shader*)fs, + assembler, &parser.FullToken.FullInstruction); + } else { + r300_fs_instruction((struct r300_fragment_shader*)fs, + assembler, &parser.FullToken.FullInstruction); + } break; } - } - debug_printf("r300: %d texs and %d colors, first free reg is %d\n", + debug_printf("r300: fs: %d texs and %d colors, first free reg is %d\n", assembler->tex_count, assembler->color_count, assembler->tex_count + assembler->color_count); consts->count = consts->user_count + assembler->imm_count; - debug_printf("r300: %d total constants, " + debug_printf("r300: fs: %d total constants, " "%d from user and %d from immediates\n", consts->count, consts->user_count, assembler->imm_count); - r500_fs_finalize(fs, assembler); + r300_fs_finalize(fs, assembler); + if (is_r500) { + r500_fs_finalize((struct r500_fragment_shader*)fs, assembler); + } - tgsi_dump(fs->shader.state.tokens); - r500_fs_dump(fs); + tgsi_dump(fs->state.tokens); + /* XXX finish r300 dumper too */ + if (is_r500) { + r500_fs_dump((struct r500_fragment_shader*)fs); + } tgsi_parse_free(&parser); FREE(assembler); diff --git a/src/gallium/drivers/r300/r300_state_shader.h b/src/gallium/drivers/r300/r300_state_shader.h index 06c0bb73789..185fdd90f0c 100644 --- a/src/gallium/drivers/r300/r300_state_shader.h +++ b/src/gallium/drivers/r300/r300_state_shader.h @@ -102,12 +102,9 @@ struct r300_fs_asm { }; void r300_translate_fragment_shader(struct r300_context* r300, - struct r300_fragment_shader* fs); + struct r3xx_fragment_shader* fs); -void r500_translate_fragment_shader(struct r300_context* r300, - struct r500_fragment_shader* fs); - -static const struct r300_fragment_shader r300_passthrough_fragment_shader = { +static struct r300_fragment_shader r300_passthrough_fragment_shader = { /* XXX This is the emission code. TODO: decode OUT_CS_REG(R300_US_CONFIG, 0); OUT_CS_REG(R300_US_CODE_OFFSET, 0x0); @@ -118,24 +115,24 @@ static const struct r300_fragment_shader r300_passthrough_fragment_shader = { */ .alu_instruction_count = 1, .tex_instruction_count = 0, - .indirections = 1, - .shader.stack_size = 2, + .indirections = 0, + .shader.stack_size = 1, .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | - R300_RGB_SWIZB(R300_ALU_ARGC_ONE) | + R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | - R300_ALU_OUTC_MAD, + R300_ALU_OUTC_CMP, .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | - R300_ALPHA_SWIZB(R300_ALU_ARGA_ONE) | + R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | - R300_ALU_OUTA_MAD, + R300_ALU_OUTA_CMP, .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) | R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, }; -static const struct r500_fragment_shader r500_passthrough_fragment_shader = { +static struct r500_fragment_shader r500_passthrough_fragment_shader = { .shader.stack_size = 0, .instruction_count = 1, .instructions[0].inst0 = R500_INST_TYPE_OUT | @@ -161,4 +158,73 @@ static const struct r500_fragment_shader r500_passthrough_fragment_shader = { R500_ALU_RGBA_A_SWIZ_0, }; +static struct r300_fragment_shader r300_texture_fragment_shader = { + /* XXX This is the emission code. TODO: decode + OUT_CS_REG(R300_US_CONFIG, 0); + OUT_CS_REG(R300_US_CODE_OFFSET, 0x0); + OUT_CS_REG(R300_US_CODE_ADDR_0, 0x0); + OUT_CS_REG(R300_US_CODE_ADDR_1, 0x0); + OUT_CS_REG(R300_US_CODE_ADDR_2, 0x0); + OUT_CS_REG(R300_US_CODE_ADDR_3, 0x400000); +*/ + .alu_instruction_count = 1, + .tex_instruction_count = 0, + .indirections = 0, + .shader.stack_size = 1, + + .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | + R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | + R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | + R300_ALU_OUTC_CMP, + .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | + R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, + .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | + R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | + R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | + R300_ALU_OUTA_CMP, + .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) | + R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, +}; + +static struct r500_fragment_shader r500_texture_fragment_shader = { + .shader.stack_size = 1, + .instruction_count = 2, + .instructions[0].inst0 = R500_INST_TYPE_TEX | + R500_INST_TEX_SEM_WAIT | + R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK | + R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, + .instructions[0].inst1 = R500_TEX_ID(0) | R500_TEX_INST_LD | + R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED, + .instructions[0].inst2 = R500_TEX_SRC_ADDR(0) | + R500_TEX_SRC_S_SWIZ_R | R500_TEX_SRC_T_SWIZ_G | + R500_TEX_SRC_R_SWIZ_B | R500_TEX_SRC_Q_SWIZ_A | + R500_TEX_DST_ADDR(0) | + R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G | + R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A, + .instructions[0].inst3 = 0x0, + .instructions[0].inst4 = 0x0, + .instructions[0].inst5 = 0x0, + .instructions[1].inst0 = R500_INST_TYPE_OUT | + R500_INST_TEX_SEM_WAIT | R500_INST_LAST | + R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK | + R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, + .instructions[1].inst1 = + R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST | + R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST, + .instructions[1].inst2 = + R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST | + R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST, + .instructions[1].inst3 = + R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R | + R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B | + R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R | + R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B, + .instructions[1].inst4 = + R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A, + .instructions[1].inst5 = + R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 | + R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 | + R500_ALU_RGBA_A_SWIZ_0, +}; + #endif /* R300_STATE_SHADER_H */ diff --git a/src/gallium/drivers/r300/r300_state_tcl.c b/src/gallium/drivers/r300/r300_state_tcl.c new file mode 100644 index 00000000000..47d6c6dfcdf --- /dev/null +++ b/src/gallium/drivers/r300/r300_state_tcl.c @@ -0,0 +1,285 @@ +/* + * Copyright 2009 Corbin Simpson <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "r300_state_tcl.h" + +static void r300_vs_declare(struct r300_vs_asm* assembler, + struct tgsi_full_declaration* decl) +{ + switch (decl->Declaration.File) { + case TGSI_FILE_INPUT: + break; + case TGSI_FILE_OUTPUT: + switch (decl->Semantic.SemanticName) { + case TGSI_SEMANTIC_POSITION: + assembler->tab[decl->DeclarationRange.First] = 0; + break; + case TGSI_SEMANTIC_COLOR: + assembler->tab[decl->DeclarationRange.First] = 2; + break; + case TGSI_SEMANTIC_GENERIC: + /* XXX multiple? */ + assembler->tab[decl->DeclarationRange.First] = 6; + break; + default: + debug_printf("r300: vs: Bad semantic declaration %d\n", + decl->Semantic.SemanticName); + break; + } + break; + case TGSI_FILE_CONSTANT: + break; + case TGSI_FILE_TEMPORARY: + assembler->temp_count++; + break; + default: + debug_printf("r300: vs: Bad file %d\n", decl->Declaration.File); + break; + } +} + +static INLINE unsigned r300_vs_src_type(struct r300_vs_asm* assembler, + struct tgsi_src_register* src) +{ + switch (src->File) { + case TGSI_FILE_NULL: + /* Probably a zero or one swizzle */ + return R300_PVS_SRC_REG_INPUT; + break; + case TGSI_FILE_INPUT: + return R300_PVS_SRC_REG_INPUT; + break; + case TGSI_FILE_TEMPORARY: + return R300_PVS_SRC_REG_TEMPORARY; + break; + case TGSI_FILE_CONSTANT: + return R300_PVS_SRC_REG_CONSTANT; + default: + debug_printf("r300: vs: Unimplemented src type %d\n", src->File); + break; + } + return 0; +} + +static INLINE unsigned r300_vs_dst_type(struct r300_vs_asm* assembler, + struct tgsi_dst_register* dst) +{ + switch (dst->File) { + case TGSI_FILE_TEMPORARY: + return R300_PVS_DST_REG_TEMPORARY; + break; + case TGSI_FILE_OUTPUT: + return R300_PVS_DST_REG_OUT; + break; + default: + debug_printf("r300: vs: Unimplemented dst type %d\n", dst->File); + break; + } + return 0; +} + +static INLINE unsigned r300_vs_dst(struct r300_vs_asm* assembler, + struct tgsi_dst_register* dst) +{ + switch (dst->File) { + case TGSI_FILE_TEMPORARY: + return dst->Index; + break; + case TGSI_FILE_OUTPUT: + return assembler->tab[dst->Index]; + break; + default: + debug_printf("r300: vs: Unimplemented dst %d\n", dst->File); + break; + } + return 0; +} + +static uint32_t r300_vs_op(unsigned op) +{ + switch (op) { + case TGSI_OPCODE_MUL: + return R300_VE_MULTIPLY; + case TGSI_OPCODE_ADD: + case TGSI_OPCODE_MOV: + case TGSI_OPCODE_SWZ: + return R300_VE_ADD; + case TGSI_OPCODE_MAD: + return R300_PVS_DST_MACRO_INST | R300_PVS_MACRO_OP_2CLK_MADD; + default: + break; + } + return 0; +} + +static uint32_t r300_vs_swiz(struct tgsi_full_src_register* reg) +{ + if (reg->SrcRegister.Extended) { + return reg->SrcRegisterExtSwz.ExtSwizzleX | + (reg->SrcRegisterExtSwz.ExtSwizzleY << 3) | + (reg->SrcRegisterExtSwz.ExtSwizzleZ << 6) | + (reg->SrcRegisterExtSwz.ExtSwizzleW << 9); + } else { + return reg->SrcRegister.SwizzleX | + (reg->SrcRegister.SwizzleY << 3) | + (reg->SrcRegister.SwizzleZ << 6) | + (reg->SrcRegister.SwizzleW << 9); + } +} + +static void r300_vs_emit_inst(struct r300_vertex_shader* vs, + struct r300_vs_asm* assembler, + struct tgsi_full_src_register* src, + struct tgsi_full_dst_register* dst, + unsigned op, + unsigned count) +{ + int i = vs->instruction_count; + vs->instructions[i].inst0 = R300_PVS_DST_OPCODE(r300_vs_op(op)) | + R300_PVS_DST_REG_TYPE(r300_vs_dst_type(assembler, &dst->DstRegister)) | + R300_PVS_DST_OFFSET(r300_vs_dst(assembler, &dst->DstRegister)) | + R300_PVS_DST_WE_XYZW; + switch (count) { + case 3: + vs->instructions[i].inst3 = + R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler, + &src[2].SrcRegister)) | + R300_PVS_SRC_OFFSET(src[2].SrcRegister.Index) | + R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[2])); + /* Fall through */ + case 2: + vs->instructions[i].inst2 = + R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler, + &src[1].SrcRegister)) | + R300_PVS_SRC_OFFSET(src[1].SrcRegister.Index) | + R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[1])); + /* Fall through */ + case 1: + vs->instructions[i].inst1 = + R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler, + &src[0].SrcRegister)) | + R300_PVS_SRC_OFFSET(src[0].SrcRegister.Index) | + R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[0])); + break; + } + vs->instruction_count++; +} + +static void r300_vs_instruction(struct r300_vertex_shader* vs, + struct r300_vs_asm* assembler, + struct tgsi_full_instruction* inst) +{ + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ADD: + case TGSI_OPCODE_MUL: + r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, + &inst->FullDstRegisters[0], inst->Instruction.Opcode, + 2); + break; + case TGSI_OPCODE_MOV: + case TGSI_OPCODE_SWZ: + inst->FullSrcRegisters[1] = r300_constant_zero; + r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, + &inst->FullDstRegisters[0], inst->Instruction.Opcode, + 2); + break; + case TGSI_OPCODE_MAD: + r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, + &inst->FullDstRegisters[0], inst->Instruction.Opcode, + 3); + break; + case TGSI_OPCODE_END: + break; + default: + debug_printf("r300: vs: Bad opcode %d\n", + inst->Instruction.Opcode); + break; + } +} + +void r300_translate_vertex_shader(struct r300_context* r300, + struct r300_vertex_shader* vs) +{ + struct tgsi_parse_context parser; + int i; + struct r300_constant_buffer* consts = + &r300->shader_constants[PIPE_SHADER_VERTEX]; + + struct r300_vs_asm* assembler = CALLOC_STRUCT(r300_vs_asm); + if (assembler == NULL) { + return; + } + /* Setup starting offset for immediates. */ + assembler->imm_offset = consts->user_count; + + tgsi_parse_init(&parser, vs->state.tokens); + + while (!tgsi_parse_end_of_tokens(&parser)) { + tgsi_parse_token(&parser); + + /* This is seriously the lamest way to create fragment programs ever. + * I blame TGSI. */ + switch (parser.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_DECLARATION: + /* Allocated registers sitting at the beginning + * of the program. */ + r300_vs_declare(assembler, &parser.FullToken.FullDeclaration); + break; + case TGSI_TOKEN_TYPE_IMMEDIATE: + debug_printf("r300: Emitting immediate to constant buffer, " + "position %d\n", + assembler->imm_offset + assembler->imm_count); + /* I am not amused by the length of these. */ + for (i = 0; i < 4; i++) { + consts->constants[assembler->imm_offset + + assembler->imm_count][i] = + parser.FullToken.FullImmediate.u.ImmediateFloat32[i] + .Float; + } + assembler->imm_count++; + break; + case TGSI_TOKEN_TYPE_INSTRUCTION: + r300_vs_instruction(vs, assembler, + &parser.FullToken.FullInstruction); + break; + } + } + + debug_printf("r300: vs: %d texs and %d colors, first free reg is %d\n", + assembler->tex_count, assembler->color_count, + assembler->tex_count + assembler->color_count); + + consts->count = consts->user_count + assembler->imm_count; + debug_printf("r300: vs: %d total constants, " + "%d from user and %d from immediates\n", consts->count, + consts->user_count, assembler->imm_count); + + debug_printf("r300: vs: tab: %d %d %d %d\n", assembler->tab[0], + assembler->tab[1], assembler->tab[2], assembler->tab[3]); + + tgsi_dump(vs->state.tokens); + /* XXX finish r300 vertex shader dumper */ + r300_vs_dump(vs); + + tgsi_parse_free(&parser); + FREE(assembler); +} diff --git a/src/gallium/drivers/r300/r300_state_tcl.h b/src/gallium/drivers/r300/r300_state_tcl.h new file mode 100644 index 00000000000..3d10e248e15 --- /dev/null +++ b/src/gallium/drivers/r300/r300_state_tcl.h @@ -0,0 +1,146 @@ +/* + * Copyright 2009 Corbin Simpson <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef R300_STATE_TCL_H +#define R300_STATE_TCL_H + +#include "tgsi/tgsi_parse.h" + +#include "r300_context.h" +#include "r300_debug.h" +#include "r300_reg.h" +#include "r300_screen.h" + +/* XXX get these to r300_reg */ +#define R300_PVS_DST_OPCODE(x) ((x) << 0) +# define R300_VE_MULTIPLY 2 +# define R300_VE_ADD 3 +#define R300_PVS_DST_MACRO_INST (1 << 7) +# define R300_PVS_MACRO_OP_2CLK_MADD 0 +#define R300_PVS_DST_REG_TYPE(x) ((x) << 8) +# define R300_PVS_DST_REG_TEMPORARY 0 +# define R300_PVS_DST_REG_A0 1 +# define R300_PVS_DST_REG_OUT 2 +# define R300_PVS_DST_REG_OUT_REPL_X 3 +# define R300_PVS_DST_REG_ALT_TEMPORARY 4 +# define R300_PVS_DST_REG_INPUT 5 +#define R300_PVS_DST_OFFSET(x) ((x) << 13) +#define R300_PVS_DST_WE(x) ((x) << 20) +#define R300_PVS_DST_WE_XYZW (0xf << 20) + +#define R300_PVS_SRC_REG_TYPE(x) ((x) << 0) +# define R300_PVS_SRC_REG_TEMPORARY 0 +# define R300_PVS_SRC_REG_INPUT 1 +# define R300_PVS_SRC_REG_CONSTANT 2 +# define R300_PVS_SRC_REG_ALT_TEMPORARY 3 +#define R300_PVS_SRC_OFFSET(x) ((x) << 5) +#define R300_PVS_SRC_SWIZZLE(x) ((x) << 13) +# define R300_PVS_SRC_SELECT_X 0 +# define R300_PVS_SRC_SELECT_Y 1 +# define R300_PVS_SRC_SELECT_Z 2 +# define R300_PVS_SRC_SELECT_W 3 +# define R300_PVS_SRC_SELECT_FORCE_0 4 +# define R300_PVS_SRC_SELECT_FORCE_1 5 +# define R300_PVS_SRC_SWIZZLE_XYZW \ + ((R300_PVS_SRC_SELECT_X | (R300_PVS_SRC_SELECT_Y << 3) | \ + (R300_PVS_SRC_SELECT_Z << 6) | (R300_PVS_SRC_SELECT_W << 9)) << 13) +# define R300_PVS_SRC_SWIZZLE_ZERO \ + ((R300_PVS_SRC_SELECT_FORCE_0 | (R300_PVS_SRC_SELECT_FORCE_0 << 3) | \ + (R300_PVS_SRC_SELECT_FORCE_0 << 6) | \ + (R300_PVS_SRC_SELECT_FORCE_0 << 9)) << 13) +# define R300_PVS_SRC_SWIZZLE_ONE \ + ((R300_PVS_SRC_SELECT_FORCE_1 | (R300_PVS_SRC_SELECT_FORCE_1 << 3) | \ + (R300_PVS_SRC_SELECT_FORCE_1 << 6) | \ + (R300_PVS_SRC_SELECT_FORCE_1 << 9)) << 13) + +static const struct tgsi_full_src_register r300_constant_zero = { + .SrcRegister.Extended = TRUE, + .SrcRegister.File = TGSI_FILE_NULL, + .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ZERO, + .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ZERO, + .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ZERO, + .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ZERO, +}; + +/* Temporary struct used to hold assembly state while putting together + * fragment programs. */ +struct r300_vs_asm { + /* Pipe context. */ + struct r300_context* r300; + /* Number of colors. */ + unsigned color_count; + /* Number of texcoords. */ + unsigned tex_count; + /* Number of requested temporary registers. */ + unsigned temp_count; + /* Offset for immediate constants. Neither R300 nor R500 can do four + * inline constants per source, so instead we copy immediates into the + * constant buffer. */ + unsigned imm_offset; + /* Number of immediate constants. */ + unsigned imm_count; + /* Offsets into vertex output memory. */ + unsigned tab[16]; +}; + +static struct r300_vertex_shader r300_passthrough_vertex_shader = { + /* XXX translate these back into normal instructions */ + .instruction_count = 2, + .instructions[0].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) | + R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) | + R300_PVS_DST_OFFSET(0) | R300_PVS_DST_WE_XYZW, + .instructions[0].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) | + R300_PVS_SRC_OFFSET(0) | R300_PVS_SRC_SWIZZLE_XYZW, + .instructions[0].inst2 = R300_PVS_SRC_SWIZZLE_ZERO, + .instructions[0].inst3 = 0x0, + .instructions[1].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) | + R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) | + R300_PVS_DST_OFFSET(2) | R300_PVS_DST_WE_XYZW, + .instructions[1].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) | + R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW, + .instructions[1].inst2 = R300_PVS_SRC_SWIZZLE_ZERO, + .instructions[1].inst3 = 0x0, +}; + +static struct r300_vertex_shader r300_texture_vertex_shader = { + /* XXX translate these back into normal instructions */ + .instruction_count = 2, + .instructions[0].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) | + R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) | + R300_PVS_DST_OFFSET(0) | R300_PVS_DST_WE_XYZW, + .instructions[0].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) | + R300_PVS_SRC_OFFSET(0) | R300_PVS_SRC_SWIZZLE_XYZW, + .instructions[0].inst2 = R300_PVS_SRC_SWIZZLE_ZERO, + .instructions[0].inst3 = 0x0, + .instructions[1].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) | + R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) | + R300_PVS_DST_OFFSET(6) | R300_PVS_DST_WE_XYZW, + .instructions[1].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) | + R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW, + .instructions[1].inst2 = R300_PVS_SRC_SWIZZLE_ZERO, + .instructions[1].inst3 = 0x0, +}; + +void r300_translate_vertex_shader(struct r300_context* r300, + struct r300_vertex_shader* vs); + +#endif /* R300_STATE_TCL_H */ diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c index db18975a10f..79bed032538 100644 --- a/src/gallium/drivers/r300/r300_surface.c +++ b/src/gallium/drivers/r300/r300_surface.c @@ -29,10 +29,10 @@ static void r300_surface_setup(struct pipe_context* pipe, unsigned w, unsigned h) { struct r300_context* r300 = r300_context(pipe); - CS_LOCALS(r300); struct r300_capabilities* caps = r300_screen(pipe->screen)->caps; struct r300_texture* tex = (struct r300_texture*)dest->texture; unsigned pixpitch = tex->stride / tex->tex.block.size; + CS_LOCALS(r300); r300_emit_blend_state(r300, &blend_clear_state); r300_emit_blend_color_state(r300, &blend_color_clear_state); @@ -80,14 +80,15 @@ static void r300_surface_fill(struct pipe_context* pipe, unsigned w, unsigned h, unsigned color) { + int i; + float r, g, b, a, depth; struct r300_context* r300 = r300_context(pipe); - CS_LOCALS(r300); struct r300_capabilities* caps = r300_screen(pipe->screen)->caps; struct r300_texture* tex = (struct r300_texture*)dest->texture; - int i; - float r, g, b, a, depth; unsigned pixpitch = tex->stride / tex->tex.block.size; + CS_LOCALS(r300); + a = (float)((color >> 24) & 0xff) / 255.0f; r = (float)((color >> 16) & 0xff) / 255.0f; g = (float)((color >> 8) & 0xff) / 255.0f; b = (float)((color >> 0) & 0xff) / 255.0f; @@ -96,7 +97,7 @@ static void r300_surface_fill(struct pipe_context* pipe, dest, x, y, w, h, pixpitch, color); /* Fallback? */ - if (tex->tex.format != PIPE_FORMAT_A8R8G8B8_UNORM) { + if (FALSE) { debug_printf("r300: Falling back on surface clear..."); util_surface_fill(pipe, dest, x, y, w, h, color); return; @@ -104,6 +105,19 @@ static void r300_surface_fill(struct pipe_context* pipe, r300_surface_setup(r300, dest, x, y, w, h); + /* Vertex shader setup */ + if (caps->has_tcl) { + r300_emit_vertex_shader(r300, &r300_passthrough_vertex_shader); + } else { + BEGIN_CS(4); + OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS); + OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(5) | + R300_PVS_NUM_CNTLRS(5) | + R300_PVS_NUM_FPUS(caps->num_vert_fpus) | + R300_PVS_VF_MAX_VTX_NUM(12)); + END_CS; + } + /* Fragment shader setup */ if (caps->is_r500) { r500_emit_fragment_shader(r300, &r500_passthrough_fragment_shader); @@ -113,7 +127,32 @@ static void r300_surface_fill(struct pipe_context* pipe, r300_emit_rs_block_state(r300, &r300_rs_block_clear_state); } - BEGIN_CS(21); + BEGIN_CS(31); + + /* VAP stream control, mapping from input memory to PVS/RS memory */ + if (caps->has_tcl) { + OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, + (R300_DATA_TYPE_FLOAT_4 << R300_DATA_TYPE_0_SHIFT) | + ((R300_LAST_VEC | (1 << R300_DST_VEC_LOC_SHIFT) | + R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT)); + } else { + OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, + (R300_DATA_TYPE_FLOAT_4 << R300_DATA_TYPE_0_SHIFT) | + ((R300_LAST_VEC | (2 << R300_DST_VEC_LOC_SHIFT) | + R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT)); + } + OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0, + (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE0_SHIFT) | + (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE1_SHIFT)); + + /* VAP format controls */ + OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_0, + R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT | + R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT); + OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_1, 0x0); + + /* Disable textures */ + OUT_CS_REG(R300_TX_ENABLE, 0x0); /* Viewport setup */ OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6); @@ -132,16 +171,17 @@ static void r300_surface_fill(struct pipe_context* pipe, /* Packet3 with our point vertex */ OUT_CS_PKT3(R200_3D_DRAW_IMMD_2, 8); OUT_CS(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING | - (1 << R300_PRIM_NUM_VERTICES_SHIFT)); + (1 << R300_PRIM_NUM_VERTICES_SHIFT)); + /* Position */ OUT_CS_32F(w / 2.0); OUT_CS_32F(h / 2.0); - /* XXX this should be the depth value to clear to */ OUT_CS_32F(1.0); OUT_CS_32F(1.0); + /* Color */ OUT_CS_32F(r); OUT_CS_32F(g); OUT_CS_32F(b); - OUT_CS_32F(1.0); + OUT_CS_32F(a); /* XXX figure out why this is 0xA and not 0x2 */ OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA); @@ -162,23 +202,100 @@ static void r300_surface_copy(struct pipe_context* pipe, unsigned w, unsigned h) { struct r300_context* r300 = r300_context(pipe); - CS_LOCALS(r300); + struct r300_capabilities* caps = r300_screen(pipe->screen)->caps; struct r300_texture* srctex = (struct r300_texture*)src->texture; struct r300_texture* desttex = (struct r300_texture*)dest->texture; - unsigned pixpitch = srctex->stride / srctex->tex.block.size; + CS_LOCALS(r300); + debug_printf("r300: Copying surface %p at (%d,%d) to %p at (%d, %d)," " dimensions %dx%d (pixel pitch %d)\n", src, srcx, srcy, dest, destx, desty, w, h, pixpitch); - /* if ((srctex == desttex) && + if ((srctex == desttex) && ((destx < srcx + w) || (srcx < destx + w)) && - ((desty < srcy + h) || (srcy < destx + h))) { */ - if (TRUE) { + ((desty < srcy + h) || (srcy < desty + h))) { debug_printf("r300: Falling back on surface_copy\n"); - return util_surface_copy(pipe, FALSE, dest, destx, desty, src, + util_surface_copy(pipe, FALSE, dest, destx, desty, src, srcx, srcy, w, h); } + + r300_emit_sampler(r300, &r300_sampler_copy_state, 0); + r300_emit_texture(r300, srctex, 0); + r300_flush_textures(r300); + + /* Vertex shader setup */ + if (caps->has_tcl) { + r300_emit_vertex_shader(r300, &r300_texture_vertex_shader); + } else { + BEGIN_CS(4); + OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS); + OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(5) | + R300_PVS_NUM_CNTLRS(5) | + R300_PVS_NUM_FPUS(caps->num_vert_fpus) | + R300_PVS_VF_MAX_VTX_NUM(12)); + END_CS; + } + + /* Fragment shader setup */ + if (caps->is_r500) { + r500_emit_fragment_shader(r300, &r500_texture_fragment_shader); + r300_emit_rs_block_state(r300, &r500_rs_block_copy_state); + } else { + r300_emit_fragment_shader(r300, &r300_texture_fragment_shader); + r300_emit_rs_block_state(r300, &r300_rs_block_copy_state); + } + + /* VAP stream control, mapping from input memory to PVS/RS memory */ + if (caps->has_tcl) { + OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, + (R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_0_SHIFT) | + ((R300_LAST_VEC | (1 << R300_DST_VEC_LOC_SHIFT) | + R300_DATA_TYPE_FLOAT_2) << R300_DATA_TYPE_1_SHIFT)); + } else { + OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, + (R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_0_SHIFT) | + ((R300_LAST_VEC | (6 << R300_DST_VEC_LOC_SHIFT) | + R300_DATA_TYPE_FLOAT_2) << R300_DATA_TYPE_1_SHIFT)); + } + OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0, + (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE0_SHIFT) | + (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE1_SHIFT)); + + /* VAP format controls */ + OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_0, + R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT); + /* Two components of texture 0 */ + OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_1, 0x2); + + /* Packet3 with our texcoords */ + OUT_CS_PKT3(R200_3D_DRAW_IMMD_2, 8); + OUT_CS(R300_PRIM_TYPE_QUADS | R300_PRIM_WALK_RING | + (4 << R300_PRIM_NUM_VERTICES_SHIFT)); + /* (x , y ) */ + OUT_CS_32F((float)destx); + OUT_CS_32F((float)desty); + OUT_CS_32F((float)srcx); + OUT_CS_32F((float)srcy); + /* (x , y + h) */ + OUT_CS_32F((float)destx); + OUT_CS_32F((float)(desty + h)); + OUT_CS_32F((float)srcx); + OUT_CS_32F((float)(srcy + h)); + /* (x + w, y + h) */ + OUT_CS_32F((float)(destx + w)); + OUT_CS_32F((float)(desty + h)); + OUT_CS_32F((float)(srcx + w)); + OUT_CS_32F((float)(srcy + h)); + /* (x + w, y ) */ + OUT_CS_32F((float)(destx + w)); + OUT_CS_32F((float)desty); + OUT_CS_32F((float)(srcx + w)); + OUT_CS_32F((float)srcy); + + OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA); + + r300->dirty_hw++; } void r300_init_surface_functions(struct r300_context* r300) diff --git a/src/gallium/drivers/r300/r300_surface.h b/src/gallium/drivers/r300/r300_surface.h index b75b3ab84cf..894def07aa8 100644 --- a/src/gallium/drivers/r300/r300_surface.h +++ b/src/gallium/drivers/r300/r300_surface.h @@ -32,22 +32,23 @@ #include "r300_cs.h" #include "r300_emit.h" #include "r300_state_shader.h" +#include "r300_state_tcl.h" #include "r300_state_inlines.h" -const struct r300_blend_state blend_clear_state = { +static struct r300_blend_state blend_clear_state = { .blend_control = 0x0, .alpha_blend_control = 0x0, .rop = 0x0, .dither = 0x0, }; -const struct r300_blend_color_state blend_color_clear_state = { +static struct r300_blend_color_state blend_color_clear_state = { .blend_color = 0x0, .blend_color_red_alpha = 0x0, .blend_color_green_blue = 0x0, }; -const struct r300_dsa_state dsa_clear_state = { +static struct r300_dsa_state dsa_clear_state = { .alpha_function = 0x0, .alpha_reference = 0x0, .z_buffer_control = 0x0, @@ -57,7 +58,7 @@ const struct r300_dsa_state dsa_clear_state = { .stencil_ref_bf = 0x0, }; -const struct r300_rs_state rs_clear_state = { +static struct r300_rs_state rs_clear_state = { .point_minmax = 0x36000006, .line_control = 0x00030006, .depth_scale_front = 0x0, @@ -71,7 +72,7 @@ const struct r300_rs_state rs_clear_state = { .color_control = R300_SHADE_MODEL_FLAT, }; -const struct r300_rs_block r300_rs_block_clear_state = { +static struct r300_rs_block r300_rs_block_clear_state = { .ip[0] = R500_RS_SEL_S(R300_RS_SEL_K0) | R500_RS_SEL_T(R300_RS_SEL_K0) | R500_RS_SEL_R(R300_RS_SEL_K0) | @@ -81,7 +82,7 @@ const struct r300_rs_block r300_rs_block_clear_state = { .inst_count = 0, }; -const struct r300_rs_block r500_rs_block_clear_state = { +static struct r300_rs_block r500_rs_block_clear_state = { .ip[0] = R500_RS_SEL_S(R500_RS_IP_PTR_K0) | R500_RS_SEL_T(R500_RS_IP_PTR_K0) | R500_RS_SEL_R(R500_RS_IP_PTR_K0) | @@ -91,4 +92,33 @@ const struct r300_rs_block r500_rs_block_clear_state = { .inst_count = 0, }; +/* The following state is used for surface_copy only. */ + +static struct r300_rs_block r300_rs_block_copy_state = { + .ip[0] = R500_RS_SEL_S(R300_RS_SEL_K0) | + R500_RS_SEL_T(R300_RS_SEL_K0) | + R500_RS_SEL_R(R300_RS_SEL_K0) | + R500_RS_SEL_Q(R300_RS_SEL_K1), + .inst[0] = R300_RS_INST_COL_CN_WRITE, + .count = R300_IT_COUNT(2) | R300_IC_COUNT(0) | R300_HIRES_EN, + .inst_count = R300_RS_TX_OFFSET(6), +}; + +static struct r300_rs_block r500_rs_block_copy_state = { + .ip[0] = R500_RS_SEL_S(0) | + R500_RS_SEL_T(1) | + R500_RS_SEL_R(R500_RS_IP_PTR_K0) | + R500_RS_SEL_Q(R500_RS_IP_PTR_K1), + .inst[0] = R500_RS_INST_TEX_CN_WRITE, + .count = R300_IT_COUNT(2) | R300_IC_COUNT(0) | R300_HIRES_EN, + .inst_count = R300_RS_TX_OFFSET(6), +}; + +static struct r300_sampler_state r300_sampler_copy_state = { + .filter0 = R300_TX_WRAP_S(R300_TX_CLAMP) | + R300_TX_WRAP_T(R300_TX_CLAMP) | + R300_TX_MAG_FILTER_NEAREST | + R300_TX_MIN_FILTER_NEAREST, +}; + #endif /* R300_SURFACE_H */ diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 6cdea3d2854..fe91f4e1844 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -147,7 +147,6 @@ static struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen, surface->height = texture->height[level]; surface->offset = offset; surface->usage = flags; - surface->status = PIPE_SURFACE_STATUS_DEFINED; } return surface; diff --git a/src/gallium/drivers/softpipe/sp_clear.c b/src/gallium/drivers/softpipe/sp_clear.c index ad108ec446d..fa59277438c 100644 --- a/src/gallium/drivers/softpipe/sp_clear.c +++ b/src/gallium/drivers/softpipe/sp_clear.c @@ -2,6 +2,7 @@ * * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. + * Copyright 2009 VMware, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -27,6 +28,7 @@ /* Author: * Brian Paul + * Michel Dänzer */ @@ -40,34 +42,15 @@ /** - * Convert packed pixel from one format to another. - */ -static unsigned -convert_color(enum pipe_format srcFormat, unsigned srcColor, - enum pipe_format dstFormat) -{ - ubyte r, g, b, a; - unsigned dstColor; - - util_unpack_color_ub(srcFormat, &srcColor, &r, &g, &b, &a); - util_pack_color_ub(r, g, b, a, dstFormat, &dstColor); - - return dstColor; -} - - - -/** - * Clear the given surface to the specified value. + * Clear the given buffers to the specified values. * No masking, no scissor (clear entire buffer). - * Note: when clearing a color buffer, the clearValue is always - * encoded as PIPE_FORMAT_A8R8G8B8_UNORM. */ void -softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +softpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil) { struct softpipe_context *softpipe = softpipe_context(pipe); + unsigned cv; uint i; if (softpipe->no_rast) @@ -77,31 +60,30 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, softpipe_update_derived(softpipe); /* not needed?? */ #endif - if (ps == sp_tile_cache_get_surface(softpipe->zsbuf_cache)) { - sp_tile_cache_clear(softpipe->zsbuf_cache, clearValue); - softpipe->framebuffer.zsbuf->status = PIPE_SURFACE_STATUS_CLEAR; -#if TILE_CLEAR_OPTIMIZATION - return; -#endif - } + if (buffers & PIPE_CLEAR_COLOR) { + for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) { + struct pipe_surface *ps = softpipe->framebuffer.cbufs[i]; - for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) { - if (ps == sp_tile_cache_get_surface(softpipe->cbuf_cache[i])) { - unsigned cv; - if (ps->format != PIPE_FORMAT_A8R8G8B8_UNORM) { - cv = convert_color(PIPE_FORMAT_A8R8G8B8_UNORM, clearValue, - ps->format); - } - else { - cv = clearValue; - } - sp_tile_cache_clear(softpipe->cbuf_cache[i], cv); - softpipe->framebuffer.cbufs[i]->status = PIPE_SURFACE_STATUS_CLEAR; + util_pack_color(rgba, ps->format, &cv); + sp_tile_cache_clear(softpipe->cbuf_cache[i], rgba, cv); + +#if !TILE_CLEAR_OPTIMIZATION + /* non-cached surface */ + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, cv); +#endif } } + if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { + static const float zero[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; + struct pipe_surface *ps = softpipe->framebuffer.zsbuf; + + cv = util_pack_z_stencil(ps->format, depth, stencil); + sp_tile_cache_clear(softpipe->zsbuf_cache, zero, cv); + #if !TILE_CLEAR_OPTIMIZATION - /* non-cached surface */ - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); + /* non-cached surface */ + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, cv); #endif + } } diff --git a/src/gallium/drivers/softpipe/sp_clear.h b/src/gallium/drivers/softpipe/sp_clear.h index a8ed1c4ecc4..2e450672f58 100644 --- a/src/gallium/drivers/softpipe/sp_clear.h +++ b/src/gallium/drivers/softpipe/sp_clear.h @@ -36,8 +36,8 @@ struct pipe_context; extern void -softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +softpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil); #endif /* SP_CLEAR_H */ diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c index 0c14d92864f..9ee86fe7878 100644 --- a/src/gallium/drivers/softpipe/sp_fs_exec.c +++ b/src/gallium/drivers/softpipe/sp_fs_exec.c @@ -25,22 +25,29 @@ * **************************************************************************/ +/** + * Execute fragment shader using the TGSI interpreter. + */ #include "sp_context.h" #include "sp_state.h" #include "sp_fs.h" #include "sp_quad.h" - #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "util/u_memory.h" #include "tgsi/tgsi_exec.h" #include "tgsi/tgsi_parse.h" + +/** + * Subclass of sp_fragment_shader + */ struct sp_exec_fragment_shader { struct sp_fragment_shader base; + /* No other members for now */ }; @@ -106,8 +113,6 @@ exec_prepare( const struct sp_fragment_shader *base, } - - /* TODO: hide the machine struct in here somewhere, remove from this * interface: */ @@ -116,7 +121,6 @@ exec_run( const struct sp_fragment_shader *base, struct tgsi_exec_machine *machine, struct quad_header *quad ) { - /* Compute X, Y, Z, W vals for this quad */ sp_setup_pos_vector(quad->posCoef, (float)quad->input.x0, (float)quad->input.y0, @@ -126,7 +130,6 @@ exec_run( const struct sp_fragment_shader *base, } - static void exec_delete( struct sp_fragment_shader *base ) { @@ -135,9 +138,6 @@ exec_delete( struct sp_fragment_shader *base ) } - - - struct sp_fragment_shader * softpipe_create_fs_exec(struct softpipe_context *softpipe, const struct pipe_shader_state *templ) @@ -160,4 +160,3 @@ softpipe_create_fs_exec(struct softpipe_context *softpipe, return &shader->base; } - diff --git a/src/gallium/drivers/softpipe/sp_fs_llvm.c b/src/gallium/drivers/softpipe/sp_fs_llvm.c index f33b3e32854..95c0d982d12 100644 --- a/src/gallium/drivers/softpipe/sp_fs_llvm.c +++ b/src/gallium/drivers/softpipe/sp_fs_llvm.c @@ -25,7 +25,9 @@ * **************************************************************************/ -/* Authors: +/** + * Execute fragment shader using LLVM code generation. + * Authors: * Zack Rusin */ @@ -33,7 +35,6 @@ #include "sp_state.h" #include "sp_fs.h" - #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "util/u_memory.h" @@ -41,11 +42,16 @@ #if 0 -struct sp_llvm_fragment_shader { +/** + * Subclass of sp_fragment_shader + */ +struct sp_llvm_fragment_shader +{ struct sp_fragment_shader base; struct gallivm_prog *llvm_prog; }; + static void shade_quad_llvm(struct quad_stage *qs, struct quad_header *quad) @@ -160,7 +166,7 @@ delete_llvm_fs( struct sp_fragment_shader *base ) struct sp_fragment_shader * softpipe_create_fs_llvm(struct softpipe_context *softpipe, - const struct pipe_shader_state *templ) + const struct pipe_shader_state *templ) { struct sp_llvm_fragment_shader *shader = NULL; diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index 366abe2ed49..31c3ca21c51 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -25,13 +25,15 @@ * **************************************************************************/ +/** + * Execute fragment shader using runtime SSE code generation. + */ #include "sp_context.h" #include "sp_state.h" #include "sp_fs.h" #include "sp_quad.h" - #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "util/u_memory.h" @@ -56,14 +58,25 @@ typedef void (PIPE_CDECL *codegen_function)( ); -struct sp_sse_fragment_shader { +/** + * Subclass of sp_fragment_shader + */ +struct sp_sse_fragment_shader +{ struct sp_fragment_shader base; - struct x86_function sse2_program; + struct x86_function sse2_program; codegen_function func; float immediates[TGSI_EXEC_NUM_IMMEDIATES][4]; }; +/** cast wrapper */ +static INLINE struct sp_sse_fragment_shader * +sp_sse_fragment_shader(const struct sp_fragment_shader *base) +{ + return (struct sp_sse_fragment_shader *) base; +} + static void fs_sse_prepare( const struct sp_fragment_shader *base, @@ -83,7 +96,7 @@ fs_sse_run( const struct sp_fragment_shader *base, struct tgsi_exec_machine *machine, struct quad_header *quad ) { - struct sp_sse_fragment_shader *shader = (struct sp_sse_fragment_shader *) base; + struct sp_sse_fragment_shader *shader = sp_sse_fragment_shader(base); /* Compute X, Y, Z, W vals for this quad -- place in temp[0] for now */ sp_setup_pos_vector(quad->posCoef, @@ -110,7 +123,7 @@ fs_sse_run( const struct sp_fragment_shader *base, static void fs_sse_delete( struct sp_fragment_shader *base ) { - struct sp_sse_fragment_shader *shader = (struct sp_sse_fragment_shader *) base; + struct sp_sse_fragment_shader *shader = sp_sse_fragment_shader(base); x86_release_func( &shader->sse2_program ); FREE(shader); @@ -156,7 +169,7 @@ softpipe_create_fs_sse(struct softpipe_context *softpipe, #else -/* Maybe put this varient in the header file. +/* Maybe put this variant in the header file. */ struct sp_fragment_shader * softpipe_create_fs_sse(struct softpipe_context *softpipe, diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index adca5df73d8..ca637a1d6a4 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -65,14 +65,11 @@ quad_shade_stage(struct quad_stage *qs) } - /** * Execute fragment shader for the four fragments in the quad. */ static void -shade_quad( - struct quad_stage *qs, - struct quad_header *quad ) +shade_quad(struct quad_stage *qs, struct quad_header *quad) { struct quad_shade_stage *qss = quad_shade_stage( qs ); struct softpipe_context *softpipe = qs->softpipe; @@ -85,9 +82,7 @@ shade_quad( machine->InterpCoefs = quad->coef; /* run shader */ - quad->inout.mask &= softpipe->fs->run( softpipe->fs, - &qss->machine, - quad ); + quad->inout.mask &= softpipe->fs->run( softpipe->fs, machine, quad ); /* store outputs */ z_written = FALSE; @@ -135,15 +130,17 @@ shade_quad( } /* shader may cull fragments */ - if( quad->inout.mask ) { + if (quad->inout.mask) { qs->next->run( qs->next, quad ); } } + /** * Per-primitive (or per-begin?) setup */ -static void shade_begin(struct quad_stage *qs) +static void +shade_begin(struct quad_stage *qs) { struct quad_shade_stage *qss = quad_shade_stage(qs); struct softpipe_context *softpipe = qs->softpipe; @@ -157,7 +154,8 @@ static void shade_begin(struct quad_stage *qs) } -static void shade_destroy(struct quad_stage *qs) +static void +shade_destroy(struct quad_stage *qs) { struct quad_shade_stage *qss = (struct quad_shade_stage *) qs; @@ -168,7 +166,8 @@ static void shade_destroy(struct quad_stage *qs) } -struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe ) +struct quad_stage * +sp_quad_shade_stage( struct softpipe_context *softpipe ) { struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage); diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 96cb09b9051..accc692b66f 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -252,16 +252,6 @@ static PIPE_THREAD_ROUTINE( quad_thread, param ) #endif -/** - * Test if x is NaN or +/- infinity. - */ -static INLINE boolean -is_inf_or_nan(float x) -{ - union fi tmp; - tmp.f = x; - return !(int)((unsigned int)((tmp.i & 0x7fffffff)-0x7f800000) >> 31); -} /** @@ -506,6 +496,9 @@ static void print_vertex(const struct setup_context *setup, for (i = 0; i < setup->quad.nr_attrs; i++) { debug_printf(" %d: %f %f %f %f\n", i, v[i][0], v[i][1], v[i][2], v[i][3]); + if (util_is_inf_or_nan(v[i][0])) { + debug_printf(" NaN!\n"); + } } } #endif @@ -595,7 +588,7 @@ static boolean setup_sort_vertices( struct setup_context *setup, debug_printf("%s one-over-area %f area %f det %f\n", __FUNCTION__, setup->oneoverarea, area, det ); */ - if (is_inf_or_nan(setup->oneoverarea)) + if (util_is_inf_or_nan(setup->oneoverarea)) return FALSE; } @@ -1065,7 +1058,7 @@ setup_line_coefficients(struct setup_context *setup, /* NOTE: this is not really area but something proportional to it */ area = setup->emaj.dx * setup->emaj.dx + setup->emaj.dy * setup->emaj.dy; - if (area == 0.0f || is_inf_or_nan(area)) + if (area == 0.0f || util_is_inf_or_nan(area)) return FALSE; setup->oneoverarea = 1.0f / area; @@ -1489,16 +1482,6 @@ void setup_prepare( struct setup_context *setup ) softpipe_update_derived(sp); } - /* Mark surfaces as defined now */ - for (i = 0; i < sp->framebuffer.nr_cbufs; i++){ - if (sp->framebuffer.cbufs[i]) { - sp->framebuffer.cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED; - } - } - if (sp->framebuffer.zsbuf) { - sp->framebuffer.zsbuf->status = PIPE_SURFACE_STATUS_DEFINED; - } - /* Note: nr_attrs is only used for debugging (vertex printing) */ setup->quad.nr_attrs = draw_num_vs_outputs(sp->draw); diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c index ef04843f172..b04c2a63ad6 100644 --- a/src/gallium/drivers/softpipe/sp_surface.c +++ b/src/gallium/drivers/softpipe/sp_surface.c @@ -27,6 +27,7 @@ #include "util/u_rect.h" #include "sp_context.h" +#include "sp_surface.h" static void diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 48b2c22af45..c0113c47adb 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -138,7 +138,6 @@ softpipe_texture_create(struct pipe_screen *screen, goto fail; } - assert(p_atomic_read(&spt->base.reference.count) == 1); return &spt->base; fail: @@ -328,7 +327,7 @@ static void * softpipe_transfer_map( struct pipe_screen *screen, struct pipe_transfer *transfer ) { - ubyte *map; + ubyte *map, *xfer_map; struct softpipe_texture *spt; unsigned flags = 0; @@ -358,9 +357,11 @@ softpipe_transfer_map( struct pipe_screen *screen, softpipe_screen(screen)->timestamp++; } - return map + softpipe_transfer(transfer)->offset + + xfer_map = map + softpipe_transfer(transfer)->offset + transfer->y / transfer->block.height * transfer->stride + transfer->x / transfer->block.width * transfer->block.size; + /*printf("map = %p xfer map = %p\n", map, xfer_map);*/ + return xfer_map; } diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 69292753f13..1f9b8f1f4fb 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -57,9 +57,9 @@ struct softpipe_tile_cache struct pipe_texture *texture; /**< if caching a texture */ struct softpipe_cached_tile entries[NUM_ENTRIES]; uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32]; - float clear_color[4]; - uint clear_val; - boolean depth_stencil; /** Is the surface a depth/stencil format? */ + float clear_color[4]; /**< for color bufs */ + uint clear_val; /**< for z+stencil, or packed color clear value */ + boolean depth_stencil; /**< Is the surface a depth/stencil format? */ struct pipe_transfer *tex_trans; void *tex_trans_map; @@ -599,40 +599,17 @@ sp_get_cached_tile_tex(struct softpipe_context *sp, * Save the color and set a 'clearflag' for each tile of the screen. */ void -sp_tile_cache_clear(struct softpipe_tile_cache *tc, uint clearValue) +sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float *rgba, + uint clearValue) { - uint r, g, b, a; uint pos; - tc->clear_val = clearValue; - - switch (tc->transfer->format) { - case PIPE_FORMAT_R8G8B8A8_UNORM: - r = (clearValue >> 24) & 0xff; - g = (clearValue >> 16) & 0xff; - b = (clearValue >> 8) & 0xff; - a = (clearValue ) & 0xff; - break; - case PIPE_FORMAT_A8R8G8B8_UNORM: - r = (clearValue >> 16) & 0xff; - g = (clearValue >> 8) & 0xff; - b = (clearValue ) & 0xff; - a = (clearValue >> 24) & 0xff; - break; - case PIPE_FORMAT_B8G8R8A8_UNORM: - r = (clearValue >> 8) & 0xff; - g = (clearValue >> 16) & 0xff; - b = (clearValue >> 24) & 0xff; - a = (clearValue ) & 0xff; - break; - default: - r = g = b = a = 0; - } + tc->clear_color[0] = rgba[0]; + tc->clear_color[1] = rgba[1]; + tc->clear_color[2] = rgba[2]; + tc->clear_color[3] = rgba[3]; - tc->clear_color[0] = r / 255.0f; - tc->clear_color[1] = g / 255.0f; - tc->clear_color[2] = b / 255.0f; - tc->clear_color[3] = a / 255.0f; + tc->clear_val = clearValue; #if TILE_CLEAR_OPTIMIZATION /* set flags to indicate all the tiles are cleared */ diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h index 9ac3fdda948..8f247d0e580 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tile_cache.h @@ -89,7 +89,8 @@ sp_flush_tile_cache(struct softpipe_context *softpipe, struct softpipe_tile_cache *tc); extern void -sp_tile_cache_clear(struct softpipe_tile_cache *tc, uint clearValue); +sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float *rgba, + uint clearValue); extern struct softpipe_cached_tile * sp_get_cached_tile(struct softpipe_context *softpipe, diff --git a/src/gallium/drivers/trace/README b/src/gallium/drivers/trace/README index f0e1cd596d3..73dce20372e 100644 --- a/src/gallium/drivers/trace/README +++ b/src/gallium/drivers/trace/README @@ -10,15 +10,14 @@ This directory contains a Gallium3D pipe driver which traces all incoming calls. To build, invoke scons on the top dir as - scons statetrackers=mesa drivers=softpipe,i965simple,trace winsys=xlib + scons dri=no statetrackers=mesa drivers=softpipe,i965simple,trace winsys=xlib = Usage = To use do - ln -s libGL.so build/linux-x86-debug/gallium/winsys/xlib/libGL.so.1 - export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/gallium/winsys/xlib + export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/lib ensure the right libGL.so is being picked by doing @@ -26,6 +25,7 @@ ensure the right libGL.so is being picked by doing and then try running + export XMESA_TRACE=y GALLIUM_TRACE=tri.trace progs/trivial/tri which should create a tri.trace file, which is an XML file. You can view copying diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index c8949729047..d8d5821a1d1 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -58,16 +58,14 @@ static INLINE struct pipe_texture * trace_texture_unwrap(struct trace_context *tr_ctx, struct pipe_texture *texture) { - struct trace_screen *tr_scr = trace_screen(tr_ctx->base.screen); struct trace_texture *tr_tex; if(!texture) return NULL; - tr_tex = trace_texture(tr_scr, texture); + tr_tex = trace_texture(texture); assert(tr_tex->texture); - assert(tr_tex->texture->screen == tr_scr->screen); return tr_tex->texture; } @@ -77,7 +75,6 @@ trace_surface_unwrap(struct trace_context *tr_ctx, struct pipe_surface *surface) { struct trace_screen *tr_scr = trace_screen(tr_ctx->base.screen); - struct trace_texture *tr_tex; struct trace_surface *tr_surf; if(!surface) @@ -87,8 +84,7 @@ trace_surface_unwrap(struct trace_context *tr_ctx, if(!surface->texture) return surface; - tr_tex = trace_texture(tr_scr, surface->texture); - tr_surf = trace_surface(tr_tex, surface); + tr_surf = trace_surface(surface); assert(tr_surf->surface); assert(tr_surf->surface->texture->screen == tr_scr->screen); @@ -973,21 +969,23 @@ trace_context_surface_fill(struct pipe_context *_pipe, static INLINE void trace_context_clear(struct pipe_context *_pipe, - struct pipe_surface *surface, - unsigned clearValue) + unsigned buffers, + const float *rgba, + double depth, + unsigned stencil) { struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; - surface = trace_surface_unwrap(tr_ctx, surface); - trace_dump_call_begin("pipe_context", "clear"); trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, surface); - trace_dump_arg(uint, clearValue); + trace_dump_arg(uint, buffers); + trace_dump_arg_array(float, rgba, 4); + trace_dump_arg(float, depth); + trace_dump_arg(uint, stencil); - pipe->clear(pipe, surface, clearValue);; + pipe->clear(pipe, buffers, rgba, depth, stencil); trace_dump_call_end(); } @@ -1037,9 +1035,9 @@ struct pipe_context * trace_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) { - struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_screen *tr_scr; struct trace_context *tr_ctx; - struct pipe_screen *screen = tr_scr->screen; + struct pipe_screen *screen; if(!pipe) goto error1; @@ -1047,6 +1045,9 @@ trace_context_create(struct pipe_screen *_screen, if(!trace_dump_enabled()) goto error1; + tr_scr = trace_screen(_screen); + screen = tr_scr->screen; + tr_ctx = CALLOC_STRUCT(trace_context); if(!tr_ctx) goto error1; diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c index 6837c94542d..2618883e70d 100644 --- a/src/gallium/drivers/trace/tr_dump.c +++ b/src/gallium/drivers/trace/tr_dump.c @@ -40,11 +40,12 @@ #include "pipe/p_config.h" -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) #include <stdlib.h> #endif #include "pipe/p_compiler.h" +#include "pipe/p_thread.h" #include "util/u_debug.h" #include "util/u_memory.h" #include "util/u_string.h" @@ -58,6 +59,8 @@ static struct util_stream *stream = NULL; static unsigned refcount = 0; +static pipe_mutex call_mutex; +static long unsigned call_no = 0; static INLINE void @@ -218,6 +221,8 @@ trace_dump_trace_close(void) util_stream_close(stream); stream = NULL; refcount = 0; + call_no = 0; + pipe_mutex_destroy(call_mutex); } } @@ -235,11 +240,13 @@ boolean trace_dump_trace_begin() if(!stream) return FALSE; + pipe_mutex_init(call_mutex); + trace_dump_writes("<?xml version='1.0' encoding='UTF-8'?>\n"); trace_dump_writes("<?xml-stylesheet type='text/xsl' href='trace.xsl'?>\n"); trace_dump_writes("<trace version='0.1'>\n"); -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) /* Linux applications rarely cleanup GL / Gallium resources so catch * application exit here */ atexit(trace_dump_trace_close); @@ -265,8 +272,16 @@ void trace_dump_trace_end(void) void trace_dump_call_begin(const char *klass, const char *method) { + pipe_mutex_lock(call_mutex); + ++call_no; trace_dump_indent(1); - trace_dump_tag_begin2("call", "class", klass, "method", method); + trace_dump_writes("<call no=\'"); + trace_dump_writef("%lu", call_no); + trace_dump_writes("\' class =\'"); + trace_dump_escape(klass); + trace_dump_writes("\' method=\'"); + trace_dump_escape(method); + trace_dump_writes("\'>"); trace_dump_newline(); } @@ -276,6 +291,7 @@ void trace_dump_call_end(void) trace_dump_tag_end("call"); trace_dump_newline(); util_stream_flush(stream); + pipe_mutex_unlock(call_mutex); } void trace_dump_arg_begin(const char *name) @@ -420,8 +436,7 @@ void trace_dump_buffer_ptr(struct pipe_buffer *_buffer) void trace_dump_texture_ptr(struct pipe_texture *_texture) { if (_texture) { - struct trace_screen *tr_scr = trace_screen(_texture->screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _texture); + struct trace_texture *tr_tex = trace_texture(_texture); trace_dump_ptr(tr_tex->texture); } else { trace_dump_null(); @@ -431,9 +446,7 @@ void trace_dump_texture_ptr(struct pipe_texture *_texture) void trace_dump_surface_ptr(struct pipe_surface *_surface) { if (_surface) { - struct trace_screen *tr_scr = trace_screen(_surface->texture->screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _surface->texture); - struct trace_surface *tr_surf = trace_surface(tr_tex, _surface); + struct trace_surface *tr_surf = trace_surface(_surface); trace_dump_ptr(tr_surf->surface); } else { trace_dump_null(); @@ -443,9 +456,7 @@ void trace_dump_surface_ptr(struct pipe_surface *_surface) void trace_dump_transfer_ptr(struct pipe_transfer *_transfer) { if (_transfer) { - struct trace_screen *tr_scr = trace_screen(_transfer->texture->screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _transfer->texture); - struct trace_transfer *tr_tran = trace_transfer(tr_tex, _transfer); + struct trace_transfer *tr_tran = trace_transfer(_transfer); trace_dump_ptr(tr_tran->transfer); } else { trace_dump_null(); diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index 954576d7217..67925053833 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -159,8 +159,7 @@ trace_screen_flush_frontbuffer(struct pipe_screen *_screen, void *context_private) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _surface->texture); - struct trace_surface *tr_surf = trace_surface(tr_tex, _surface); + struct trace_surface *tr_surf = trace_surface(_surface); struct pipe_screen *screen = tr_scr->screen; struct pipe_surface *surface = tr_surf->surface; @@ -242,7 +241,7 @@ static void trace_screen_texture_destroy(struct pipe_texture *_texture) { struct trace_screen *tr_scr = trace_screen(_texture->screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _texture); + struct trace_texture *tr_tex = trace_texture(_texture); struct pipe_screen *screen = tr_scr->screen; struct pipe_texture *texture = tr_tex->texture; @@ -255,7 +254,7 @@ trace_screen_texture_destroy(struct pipe_texture *_texture) trace_dump_call_end(); - trace_texture_destroy(tr_scr, _texture); + trace_texture_destroy(tr_tex); } @@ -272,7 +271,7 @@ trace_screen_get_tex_surface(struct pipe_screen *_screen, unsigned usage) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _texture); + struct trace_texture *tr_tex = trace_texture(_texture); struct pipe_screen *screen = tr_scr->screen; struct pipe_texture *texture = tr_tex->texture; struct pipe_surface *result = NULL; @@ -304,8 +303,7 @@ static void trace_screen_tex_surface_destroy(struct pipe_surface *_surface) { struct trace_screen *tr_scr = trace_screen(_surface->texture->screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _surface->texture); - struct trace_surface *tr_surf = trace_surface(tr_tex, _surface); + struct trace_surface *tr_surf = trace_surface(_surface); struct pipe_screen *screen = tr_scr->screen; struct pipe_surface *surface = tr_surf->surface; @@ -316,7 +314,7 @@ trace_screen_tex_surface_destroy(struct pipe_surface *_surface) trace_dump_call_end(); - trace_surface_destroy(tr_tex, _surface); + trace_surface_destroy(tr_surf); } @@ -334,7 +332,7 @@ trace_screen_get_tex_transfer(struct pipe_screen *_screen, unsigned x, unsigned y, unsigned w, unsigned h) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _texture); + struct trace_texture *tr_tex = trace_texture(_texture); struct pipe_screen *screen = tr_scr->screen; struct pipe_texture *texture = tr_tex->texture; struct pipe_transfer *result = NULL; @@ -372,10 +370,9 @@ static void trace_screen_tex_transfer_destroy(struct pipe_transfer *_transfer) { struct trace_screen *tr_scr = trace_screen(_transfer->texture->screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _transfer->texture); - struct trace_transfer *tr_tran = trace_transfer(tr_tex, _transfer); + struct trace_transfer *tr_trans = trace_transfer(_transfer); struct pipe_screen *screen = tr_scr->screen; - struct pipe_transfer *transfer = tr_tran->transfer; + struct pipe_transfer *transfer = tr_trans->transfer; trace_dump_call_begin("pipe_screen", "tex_transfer_destroy"); @@ -384,7 +381,7 @@ trace_screen_tex_transfer_destroy(struct pipe_transfer *_transfer) trace_dump_call_end(); - trace_transfer_destroy(tr_tex, _transfer); + trace_transfer_destroy(tr_trans); } @@ -393,8 +390,7 @@ trace_screen_transfer_map(struct pipe_screen *_screen, struct pipe_transfer *_transfer) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _transfer->texture); - struct trace_transfer *tr_trans = trace_transfer(tr_tex, _transfer); + struct trace_transfer *tr_trans = trace_transfer(_transfer); struct pipe_screen *screen = tr_scr->screen; struct pipe_transfer *transfer = tr_trans->transfer; void *map; @@ -416,8 +412,7 @@ trace_screen_transfer_unmap(struct pipe_screen *_screen, struct pipe_transfer *_transfer) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _transfer->texture); - struct trace_transfer *tr_trans = trace_transfer(tr_tex, _transfer); + struct trace_transfer *tr_trans = trace_transfer(_transfer); struct pipe_screen *screen = tr_scr->screen; struct pipe_transfer *transfer = tr_trans->transfer; @@ -706,7 +701,7 @@ trace_screen_buffer_unmap(struct pipe_screen *_screen, struct pipe_buffer *buffer = tr_buf->buffer; if (tr_buf->map && !tr_buf->range_flushed) - buffer_write(screen, buffer, tr_buf->map, 0, buffer->size); + buffer_write(screen, buffer, 0, tr_buf->map, buffer->size); tr_buf->map = NULL; tr_buf->range_flushed = FALSE; screen->buffer_unmap(screen, buffer); diff --git a/src/gallium/drivers/trace/tr_state.c b/src/gallium/drivers/trace/tr_state.c index f9fbe9aee79..a9570c1aebd 100644 --- a/src/gallium/drivers/trace/tr_state.c +++ b/src/gallium/drivers/trace/tr_state.c @@ -406,8 +406,6 @@ void trace_dump_surface(const struct pipe_surface *state) trace_dump_reference(&state->reference); trace_dump_member(format, state, format); - trace_dump_member(uint, state, status); - trace_dump_member(uint, state, clear_value); trace_dump_member(uint, state, width); trace_dump_member(uint, state, height); diff --git a/src/gallium/drivers/trace/tr_texture.c b/src/gallium/drivers/trace/tr_texture.c index 7b392f07286..f4e433792b1 100644 --- a/src/gallium/drivers/trace/tr_texture.c +++ b/src/gallium/drivers/trace/tr_texture.c @@ -62,10 +62,8 @@ error: void -trace_texture_destroy(struct trace_screen *tr_scr, - struct pipe_texture *texture) +trace_texture_destroy(struct trace_texture *tr_tex) { - struct trace_texture *tr_tex = trace_texture(tr_scr, texture); pipe_texture_reference(&tr_tex->texture, NULL); FREE(tr_tex); } @@ -102,10 +100,8 @@ error: void -trace_surface_destroy(struct trace_texture *tr_tex, - struct pipe_surface *surface) +trace_surface_destroy(struct trace_surface *tr_surf) { - struct trace_surface *tr_surf = trace_surface(tr_tex, surface); pipe_texture_reference(&tr_surf->base.texture, NULL); pipe_surface_reference(&tr_surf->surface, NULL); FREE(tr_surf); @@ -143,10 +139,8 @@ error: void -trace_transfer_destroy(struct trace_texture *tr_tex, - struct pipe_transfer *transfer) +trace_transfer_destroy(struct trace_transfer *tr_trans) { - struct trace_transfer *tr_trans = trace_transfer(tr_tex, transfer); struct pipe_screen *screen = tr_trans->transfer->texture->screen; pipe_texture_reference(&tr_trans->base.texture, NULL); screen->tex_transfer_destroy(tr_trans->transfer); diff --git a/src/gallium/drivers/trace/tr_texture.h b/src/gallium/drivers/trace/tr_texture.h index 9c21bc7d276..14dafd8b2c3 100644 --- a/src/gallium/drivers/trace/tr_texture.h +++ b/src/gallium/drivers/trace/tr_texture.h @@ -62,37 +62,31 @@ struct trace_transfer static INLINE struct trace_texture * -trace_texture(struct trace_screen *tr_scr, - struct pipe_texture *texture) +trace_texture(struct pipe_texture *texture) { if(!texture) return NULL; - assert(tr_scr); - assert(texture->screen == &tr_scr->base); + (void)trace_screen(texture->screen); return (struct trace_texture *)texture; } static INLINE struct trace_surface * -trace_surface(struct trace_texture *tr_tex, - struct pipe_surface *surface) +trace_surface(struct pipe_surface *surface) { if(!surface) return NULL; - assert(tr_tex); - assert(surface->texture == &tr_tex->base); + (void)trace_texture(surface->texture); return (struct trace_surface *)surface; } static INLINE struct trace_transfer * -trace_transfer(struct trace_texture *tr_tex, - struct pipe_transfer *transfer) +trace_transfer(struct pipe_transfer *transfer) { if(!transfer) return NULL; - assert(tr_tex); - assert(transfer->texture == &tr_tex->base); + (void)trace_texture(transfer->texture); return (struct trace_transfer *)transfer; } @@ -102,24 +96,21 @@ trace_texture_create(struct trace_screen *tr_scr, struct pipe_texture *texture); void -trace_texture_destroy(struct trace_screen *tr_scr, - struct pipe_texture *texture); +trace_texture_destroy(struct trace_texture *tr_tex); struct pipe_surface * trace_surface_create(struct trace_texture *tr_tex, struct pipe_surface *surface); void -trace_surface_destroy(struct trace_texture *tr_tex, - struct pipe_surface *surface); +trace_surface_destroy(struct trace_surface *tr_surf); struct pipe_transfer * trace_transfer_create(struct trace_texture *tr_tex, struct pipe_transfer *transfer); void -trace_transfer_destroy(struct trace_texture *tr_tex, - struct pipe_transfer *transfer); +trace_transfer_destroy(struct trace_transfer *tr_trans); #endif /* TR_TEXTURE_H_ */ diff --git a/src/gallium/drivers/trace/trace.xsl b/src/gallium/drivers/trace/trace.xsl index 9cd621e7ab9..7be95e0e753 100644 --- a/src/gallium/drivers/trace/trace.xsl +++ b/src/gallium/drivers/trace/trace.xsl @@ -68,6 +68,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. <xsl:template match="call"> <li> + <xsl:attribute name="value"> + <xsl:apply-templates select="@no"/> + </xsl:attribute> <span class="fun"> <xsl:value-of select="@class"/> <xsl:text>::</xsl:text> diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h index bc2a0a7ef3a..e6a67f8c2fd 100644 --- a/src/gallium/include/pipe/p_compiler.h +++ b/src/gallium/include/pipe/p_compiler.h @@ -124,11 +124,30 @@ typedef unsigned char boolean; # define INLINE inline # elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100) # define INLINE __inline +# elif defined(__SUNPRO_C) && defined(__C99FEATURES__) +# define INLINE inline +# elif (__STDC_VERSION__ >= 199901L) /* C99 */ +# define INLINE inline # else # define INLINE # endif #endif +/* The __FUNCTION__ gcc variable is generally only used for debugging. + * If we're not using gcc, define __FUNCTION__ as a cpp symbol here. + */ +#ifndef __FUNCTION__ +# if (!defined(__GNUC__) || (__GNUC__ < 2)) +# if (__STDC_VERSION__ >= 199901L) /* C99 */ || \ + (defined(__SUNPRO_C) && defined(__C99FEATURES__)) +# define __FUNCTION__ __func__ +# else +# define __FUNCTION__ "<unknown>" +# endif +# endif +#endif + + /* This should match linux gcc cdecl semantics everywhere, so that we * just codegen one calling convention on all platforms. diff --git a/src/gallium/include/pipe/p_config.h b/src/gallium/include/pipe/p_config.h index 7f7657031d8..63238ea46e9 100644 --- a/src/gallium/include/pipe/p_config.h +++ b/src/gallium/include/pipe/p_config.h @@ -77,11 +77,11 @@ * Processor architecture */ -#if defined(__i386__) /* gcc */ || defined(_M_IX86) /* msvc */ || defined(_X86_) || defined(__386__) || defined(i386) +#if defined(__i386__) /* gcc */ || defined(_M_IX86) /* msvc */ || defined(_X86_) || defined(__386__) || defined(i386) || defined(__i386) /* Sun cc */ #define PIPE_ARCH_X86 #endif -#if defined(__x86_64__) /* gcc */ || defined(_M_X64) /* msvc */ || defined(_M_AMD64) /* msvc */ +#if defined(__x86_64__) /* gcc */ || defined(_M_X64) /* msvc */ || defined(_M_AMD64) /* msvc */ || defined(__x86_64) /* Sun cc */ #define PIPE_ARCH_X86_64 #endif @@ -115,6 +115,10 @@ #define PIPE_OS_BSD #endif +#if defined(__sun) +#define PIPE_OS_SOLARIS +#endif + #if defined(_WIN32) || defined(WIN32) #define PIPE_OS_WINDOWS #endif @@ -126,9 +130,9 @@ * NOTE: There is no way to auto-detect most of these. */ -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) #define PIPE_SUBSYSTEM_DRI -#endif /* PIPE_OS_LINUX || PIPE_OS_BSD */ +#endif /* PIPE_OS_LINUX || PIPE_OS_BSD || PIPE_OS_SOLARIS */ #if defined(PIPE_OS_WINDOWS) #if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 2452bf3522b..29095dcdc3b 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -205,12 +205,20 @@ struct pipe_context { unsigned dstx, unsigned dsty, unsigned width, unsigned height, unsigned value); - - void (*clear)(struct pipe_context *pipe, - struct pipe_surface *ps, - unsigned clearValue); /*@}*/ + /** + * Clear the specified set of currently bound buffers to specified values. + * + * buffers is a bitfield of PIPE_CLEAR_* values. + * + * rgba is a pointer to an array of one float for each of r, g, b, a. + */ + void (*clear)(struct pipe_context *pipe, + unsigned buffers, + const float *rgba, + double depth, + unsigned stencil); /** Flush rendering (flags = bitmask of PIPE_FLUSH_x tokens) */ void (*flush)( struct pipe_context *pipe, diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 52d443970b0..81defa445bf 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -186,11 +186,12 @@ enum pipe_texture_target { /** - * Surface status + * Clear buffer bits */ -#define PIPE_SURFACE_STATUS_UNDEFINED 0 -#define PIPE_SURFACE_STATUS_DEFINED 1 -#define PIPE_SURFACE_STATUS_CLEAR 2 +/** All color buffers currently bound */ +#define PIPE_CLEAR_COLOR (1 << 0) +/** Depth/stencil combined */ +#define PIPE_CLEAR_DEPTHSTENCIL (1 << 1) /** diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index 3f65a604364..a279eefef9e 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -537,6 +537,13 @@ pf_get_nblocks(const struct pipe_format_block *block, unsigned width, unsigned h } static INLINE boolean +pf_is_depth_stencil( enum pipe_format format ) +{ + return (pf_get_component_bits( format, PIPE_FORMAT_COMP_Z ) + + pf_get_component_bits( format, PIPE_FORMAT_COMP_S )) != 0; +} + +static INLINE boolean pf_is_compressed( enum pipe_format format ) { return pf_layout(format) == PIPE_FORMAT_LAYOUT_DXT ? TRUE : FALSE; diff --git a/src/gallium/include/pipe/p_refcnt.h b/src/gallium/include/pipe/p_refcnt.h index 60844e40a57..1f89453e09a 100644 --- a/src/gallium/include/pipe/p_refcnt.h +++ b/src/gallium/include/pipe/p_refcnt.h @@ -51,6 +51,13 @@ pipe_reference_init(struct pipe_reference *reference, unsigned count) } +static INLINE bool +pipe_is_referenced(struct pipe_reference *reference) +{ + return p_atomic_read(&reference->count) != 0; +} + + /** * Set 'ptr' to point to 'reference' and update reference counting. * The old thing pointed to, if any, will be unreferenced first. @@ -65,12 +72,12 @@ pipe_reference(struct pipe_reference **ptr, struct pipe_reference *reference) /* bump the reference.count first */ if (reference) { - assert(p_atomic_read(&reference->count) != 0); + assert(pipe_is_referenced(reference)); p_atomic_inc(&reference->count); } if (*ptr) { - assert(p_atomic_read(&(*ptr)->count) != 0); + assert(pipe_is_referenced(*ptr)); if (p_atomic_dec_zero(&(*ptr)->count)) { destroy = TRUE; } @@ -81,6 +88,7 @@ pipe_reference(struct pipe_reference **ptr, struct pipe_reference *reference) return destroy; } + #ifdef __cplusplus } #endif diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 9c7baa3d92e..705ae68ec65 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -281,8 +281,6 @@ struct pipe_surface { struct pipe_reference reference; enum pipe_format format; /**< PIPE_FORMAT_x */ - unsigned status; /**< PIPE_SURFACE_STATUS_x */ - unsigned clear_value; /**< XXX may be temporary */ unsigned width; /**< logical width in pixels */ unsigned height; /**< logical height in pixels */ unsigned layout; /**< PIPE_SURFACE_LAYOUT_x */ diff --git a/src/gallium/include/pipe/p_thread.h b/src/gallium/include/pipe/p_thread.h index a9cd77541d4..de55e99ed49 100644 --- a/src/gallium/include/pipe/p_thread.h +++ b/src/gallium/include/pipe/p_thread.h @@ -38,7 +38,7 @@ #include "pipe/p_compiler.h" -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) #include <pthread.h> /* POSIX threads headers */ #include <stdio.h> /* for perror() */ @@ -210,7 +210,7 @@ typedef unsigned pipe_condvar; */ typedef struct { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) pthread_key_t key; #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) DWORD key; @@ -225,7 +225,7 @@ typedef struct { static INLINE void pipe_tsd_init(pipe_tsd *tsd) { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) { perror("pthread_key_create(): failed to allocate key for thread specific data"); exit(-1); @@ -242,7 +242,7 @@ pipe_tsd_get(pipe_tsd *tsd) if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) { pipe_tsd_init(tsd); } -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) return pthread_getspecific(tsd->key); #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) assert(0); @@ -259,7 +259,7 @@ pipe_tsd_set(pipe_tsd *tsd, void *value) if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) { pipe_tsd_init(tsd); } -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) if (pthread_setspecific(tsd->key, value) != 0) { perror("pthread_set_specific() failed"); exit(-1); diff --git a/src/gallium/state_trackers/egl/egl_surface.c b/src/gallium/state_trackers/egl/egl_surface.c index e6e80b985aa..489aa8d9af5 100644 --- a/src/gallium/state_trackers/egl/egl_surface.c +++ b/src/gallium/state_trackers/egl/egl_surface.c @@ -330,6 +330,13 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, if (ret) goto err_crtc; + + if (scrn->dpms) + drmModeConnectorSetProperty(dev->drmFD, + scrn->connectorID, + scrn->dpms->prop_id, + DRM_MODE_DPMS_ON); + surf->screen = scrn; scrn->surf = surf; @@ -399,8 +406,6 @@ drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) surf->user->pipe->flush(surf->user->pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE, NULL); /* TODO stuff here */ } - - st_notify_swapbuffers_complete(surf->stfb); } return EGL_TRUE; diff --git a/src/gallium/state_trackers/egl/egl_tracker.c b/src/gallium/state_trackers/egl/egl_tracker.c index a22ef381b96..abdf84544f3 100644 --- a/src/gallium/state_trackers/egl/egl_tracker.c +++ b/src/gallium/state_trackers/egl/egl_tracker.c @@ -66,10 +66,13 @@ drm_get_device_id(struct drm_device *device) { char path[512]; FILE *file; + char *ret; /* TODO get the real minor */ int minor = 0; + device->deviceID = 0; + snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor); file = fopen(path, "r"); if (!file) { @@ -77,7 +80,10 @@ drm_get_device_id(struct drm_device *device) return; } - fgets(path, sizeof( path ), file); + ret = fgets(path, sizeof( path ), file); + if (!ret) + return; + sscanf(path, "%x", &device->deviceID); fclose(file); } @@ -101,6 +107,25 @@ drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector) } } +static void +drm_find_dpms(struct drm_device *dev, struct drm_screen *screen) +{ + drmModeConnectorPtr c = screen->connector; + drmModePropertyPtr p; + int i; + + for (i = 0; i < c->count_props; i++) { + p = drmModeGetProperty(dev->drmFD, c->props[i]); + if (!strcmp(p->name, "DPMS")) + break; + + drmModeFreeProperty(p); + p = NULL; + } + + screen->dpms = p; +} + EGLBoolean drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) { @@ -154,6 +179,7 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) _eglInitScreen(&screen->base); _eglAddScreen(disp, &screen->base); drm_add_modes_from_connector(&screen->base, connector); + drm_find_dpms(dev, screen); dev->screens[num_screens++] = screen; } dev->count_screens = num_screens; @@ -200,6 +226,7 @@ drm_terminate(_EGLDriver *drv, EGLDisplay dpy) if (screen->shown) drm_takedown_shown_screen(drv, screen); + drmModeFreeProperty(screen->dpms); drmModeFreeConnector(screen->connector); _eglDestroyScreen(&screen->base); dev->screens[i] = NULL; diff --git a/src/gallium/state_trackers/egl/egl_tracker.h b/src/gallium/state_trackers/egl/egl_tracker.h index 908bab5f9bf..ce2717de639 100644 --- a/src/gallium/state_trackers/egl/egl_tracker.h +++ b/src/gallium/state_trackers/egl/egl_tracker.h @@ -114,6 +114,9 @@ struct drm_screen drmModeConnectorPtr connector; uint32_t connectorID; + /* dpms property */ + drmModePropertyPtr dpms; + /* Has this screen been shown */ int shown; diff --git a/src/gallium/state_trackers/g3dvl/vl_basic_csc.c b/src/gallium/state_trackers/g3dvl/vl_basic_csc.c index b61b49a2f8a..16d4f1e32c9 100644 --- a/src/gallium/state_trackers/g3dvl/vl_basic_csc.c +++ b/src/gallium/state_trackers/g3dvl/vl_basic_csc.c @@ -98,7 +98,8 @@ static int vlResizeFrameBuffer ); /* Clear to black, in case video doesn't fill the entire window */ - pipe->clear(pipe, basic_csc->framebuffer.cbufs[0], 0); + pipe->set_framebuffer_state(pipe, &basic_csc->framebuffer); + pipe->clear(pipe, PIPE_CLEAR_COLOR, 0, 0.0f, 0); return 0; } diff --git a/src/gallium/state_trackers/python/README b/src/gallium/state_trackers/python/README index 8f45fb6d1b7..e03d5468304 100644 --- a/src/gallium/state_trackers/python/README +++ b/src/gallium/state_trackers/python/README @@ -6,16 +6,27 @@ the python script perspective. To build you'll need: * Python (with development packages) * SCons -* SWIG -* Python Imaging Library with TK support (for the samples) +* SWIG, http://www.swig.org/download.html +* Python Imaging Library with TK support, http://www.pythonware.com/products/pil/, + for the samples + +On a debian-based distro you can simply do: + + aptitude install python-dev scons swig python-imaging python-imaging-tk + +On a Windows machine ensure the swig command is in your PATH. Invoke scons on the top dir as - scons statetrackers=python + scons debug=yes statetrackers=python drivers=softpipe,trace winsys=none + +To use it set PYTHONPATH appropriately, e.g, in Linux do: + + export PYTHONPATH=$PWD/build/linux-x86-debug/gallium/state_trackers/python -To use do +or (in Windows) - export PYTHONPATH=build/XXXX-XXXX-XXXX/gallium/state_trackers/python + set PYTHONPATH=%CD%\build\windows-x86-debug\gallium\state_trackers\python and then try running @@ -27,7 +38,6 @@ which should show a triangle. This is still work in progress: - errors are not handled properly and almost always result in crash - state atoms with array members are awkward to set -- there no efficient way to view images -- -Jose Fonseca <[email protected]> +Jose Fonseca <[email protected]> diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index 79e68de1df8..3f79cc1a3d7 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -37,13 +37,11 @@ %{ #include <stdio.h> -#include <Python.h> #include "pipe/p_screen.h" #include "pipe/p_context.h" #include "pipe/p_inlines.h" #include "pipe/p_shader_tokens.h" -#include "pipe/internal/p_winsys_screen.h" #include "cso_cache/cso_context.h" #include "util/u_draw_quad.h" #include "util/u_tile.h" @@ -58,7 +56,7 @@ %} %include "typemaps.i" - +%include "exception.i" %include "cstring.i" %include "carrays.i" @@ -71,8 +69,8 @@ %rename(Device) st_device; %rename(Context) st_context; %rename(Texture) pipe_texture; -%rename(Surface) pipe_surface; -%rename(Buffer) st_buffer; +%rename(Surface) st_surface; +%rename(Buffer) pipe_buffer; %rename(BlendColor) pipe_blend_color; %rename(Blend) pipe_blend_state; diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index 1fdbdf98b26..a40aa1e5187 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -116,15 +116,17 @@ struct st_context { } void set_constant_buffer(unsigned shader, unsigned index, - struct st_buffer *buffer ) + struct pipe_buffer *buffer ) { struct pipe_constant_buffer state; memset(&state, 0, sizeof(state)); - state.buffer = buffer ? buffer->buffer : NULL; + state.buffer = buffer; $self->pipe->set_constant_buffer($self->pipe, shader, index, &state); } - void set_framebuffer(const struct pipe_framebuffer_state *state ) { + void set_framebuffer(const struct pipe_framebuffer_state *state ) + { + memcpy(&$self->framebuffer, state, sizeof *state); cso_set_framebuffer($self->cso, state); } @@ -151,19 +153,19 @@ struct st_context { } void set_vertex_buffer(unsigned index, - unsigned pitch, + unsigned stride, unsigned max_index, unsigned buffer_offset, - struct st_buffer *buffer) + struct pipe_buffer *buffer) { unsigned i; struct pipe_vertex_buffer state; memset(&state, 0, sizeof(state)); - state.stride = pitch; + state.stride = stride; state.max_index = max_index; state.buffer_offset = buffer_offset; - state.buffer = buffer ? buffer->buffer : NULL; + state.buffer = buffer; memcpy(&$self->vertex_buffers[index], &state, sizeof(state)); @@ -198,22 +200,22 @@ struct st_context { $self->pipe->draw_arrays($self->pipe, mode, start, count); } - void draw_elements( struct st_buffer *indexBuffer, + void draw_elements( struct pipe_buffer *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count) { $self->pipe->draw_elements($self->pipe, - indexBuffer->buffer, + indexBuffer, indexSize, mode, start, count); } - void draw_range_elements( struct st_buffer *indexBuffer, + void draw_range_elements( struct pipe_buffer *indexBuffer, unsigned indexSize, unsigned minIndex, unsigned maxIndex, unsigned mode, unsigned start, unsigned count) { $self->pipe->draw_range_elements($self->pipe, - indexBuffer->buffer, + indexBuffer, indexSize, minIndex, maxIndex, mode, start, count); } @@ -256,32 +258,62 @@ error1: flush(unsigned flags = 0) { struct pipe_fence_handle *fence = NULL; $self->pipe->flush($self->pipe, flags | PIPE_FLUSH_RENDER_CACHE, &fence); - /* TODO: allow asynchronous operation */ - $self->pipe->winsys->fence_finish( $self->pipe->winsys, fence, 0 ); - $self->pipe->winsys->fence_reference( $self->pipe->winsys, &fence, NULL ); + if(fence) { + /* TODO: allow asynchronous operation */ + $self->pipe->screen->fence_finish( $self->pipe->screen, fence, 0 ); + $self->pipe->screen->fence_reference( $self->pipe->screen, &fence, NULL ); + } } /* * Surface functions */ - void surface_copy(struct pipe_surface *dest, + void surface_copy(struct st_surface *dst, unsigned destx, unsigned desty, - struct pipe_surface *src, + struct st_surface *src, unsigned srcx, unsigned srcy, - unsigned width, unsigned height) { - $self->pipe->surface_copy($self->pipe, dest, destx, desty, src, srcx, srcy, width, height); + unsigned width, unsigned height) + { + struct pipe_surface *_dst = NULL; + struct pipe_surface *_src = NULL; + + _dst = st_pipe_surface(dst, PIPE_BUFFER_USAGE_GPU_WRITE); + if(!_dst) + SWIG_exception(SWIG_ValueError, "couldn't acquire destination surface for writing"); + + _src = st_pipe_surface(src, PIPE_BUFFER_USAGE_GPU_READ); + if(!_src) + SWIG_exception(SWIG_ValueError, "couldn't acquire source surface for reading"); + + $self->pipe->surface_copy($self->pipe, _dst, destx, desty, _src, srcx, srcy, width, height); + + fail: + pipe_surface_reference(&_src, NULL); + pipe_surface_reference(&_dst, NULL); } - void surface_fill(struct pipe_surface *dst, + void surface_fill(struct st_surface *dst, unsigned x, unsigned y, unsigned width, unsigned height, - unsigned value) { - $self->pipe->surface_fill($self->pipe, dst, x, y, width, height, value); + unsigned value) + { + struct pipe_surface *_dst = NULL; + + _dst = st_pipe_surface(dst, PIPE_BUFFER_USAGE_GPU_WRITE); + if(!_dst) + SWIG_exception(SWIG_ValueError, "couldn't acquire destination surface for writing"); + + $self->pipe->surface_fill($self->pipe, _dst, x, y, width, height, value); + + fail: + pipe_surface_reference(&_dst, NULL); } - void surface_clear(struct pipe_surface *surface, unsigned value = 0) { - $self->pipe->clear($self->pipe, surface, value); + void clear(unsigned buffers, const float *rgba, double depth = 0.0f, + unsigned stencil = 0) + { + $self->pipe->clear($self->pipe, buffers, rgba, depth, stencil); } }; diff --git a/src/gallium/state_trackers/python/p_device.i b/src/gallium/state_trackers/python/p_device.i index 84fd2e4349b..f16fe5b0ff7 100644 --- a/src/gallium/state_trackers/python/p_device.i +++ b/src/gallium/state_trackers/python/p_device.i @@ -122,9 +122,9 @@ struct st_device { return $self->screen->texture_create($self->screen, &templat); } - struct st_buffer * + struct pipe_buffer * buffer_create(unsigned size, unsigned alignment = 0, unsigned usage = 0) { - return st_buffer_create($self, alignment, usage, size); + return pipe_buffer_create($self->screen, alignment, usage, size); } }; diff --git a/src/gallium/state_trackers/python/p_state.i b/src/gallium/state_trackers/python/p_state.i index 110b3d5da43..90f157e0ab0 100644 --- a/src/gallium/state_trackers/python/p_state.i +++ b/src/gallium/state_trackers/python/p_state.i @@ -59,13 +59,40 @@ } void - set_cbuf(unsigned index, struct pipe_surface *surface) { - pipe_surface_reference(&$self->cbufs[index], surface); + set_cbuf(unsigned index, struct st_surface *surface) + { + struct pipe_surface *_surface = NULL; + + if(index >= PIPE_MAX_COLOR_BUFS) + SWIG_exception(SWIG_ValueError, "index out of bounds"); + + if(surface) { + _surface = st_pipe_surface(surface, PIPE_BUFFER_USAGE_GPU_WRITE); + if(!_surface) + SWIG_exception(SWIG_ValueError, "couldn't acquire surface for writing"); + } + + pipe_surface_reference(&$self->cbufs[index], _surface); + + fail: + return; } void - set_zsbuf(struct pipe_surface *surface) { - pipe_surface_reference(&$self->zsbuf, surface); + set_zsbuf(struct st_surface *surface) + { + struct pipe_surface *_surface = NULL; + + if(surface) { + _surface = st_pipe_surface(surface, PIPE_BUFFER_USAGE_GPU_WRITE); + if(!_surface) + SWIG_exception(SWIG_ValueError, "couldn't acquire surface for writing"); + } + + pipe_surface_reference(&$self->zsbuf, _surface); + + fail: + return; } }; diff --git a/src/gallium/state_trackers/python/p_texture.i b/src/gallium/state_trackers/python/p_texture.i index 1e64fc8e41f..f41a95e6eb0 100644 --- a/src/gallium/state_trackers/python/p_texture.i +++ b/src/gallium/state_trackers/python/p_texture.i @@ -34,18 +34,19 @@ %nodefaultctor pipe_texture; -%nodefaultctor pipe_surface; -%nodefaultctor st_buffer; +%nodefaultctor st_surface; +%nodefaultctor pipe_buffer; %nodefaultdtor pipe_texture; -%nodefaultdtor pipe_surface; -%nodefaultdtor st_buffer; +%nodefaultdtor st_surface; +%nodefaultdtor pipe_buffer; %ignore pipe_texture::screen; -%ignore pipe_surface::winsys; -%immutable pipe_surface::texture; -%immutable pipe_surface::buffer; +%immutable st_surface::texture; +%immutable st_surface::face; +%immutable st_surface::level; +%immutable st_surface::zslice; %newobject pipe_texture::get_surface; @@ -78,54 +79,160 @@ } /** 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 ) + struct st_surface * + get_surface(unsigned face=0, unsigned level=0, unsigned zslice=0) { - struct pipe_screen *screen = $self->screen; - return screen->get_tex_surface(screen, $self, face, level, zslice, usage); + struct st_surface *surface; + + if(face >= ($self->target == PIPE_TEXTURE_CUBE ? 6U : 1U)) + SWIG_exception(SWIG_ValueError, "face out of bounds"); + if(level > $self->last_level) + SWIG_exception(SWIG_ValueError, "level out of bounds"); + if(zslice >= $self->depth[level]) + SWIG_exception(SWIG_ValueError, "zslice out of bounds"); + + surface = CALLOC_STRUCT(st_surface); + if(!surface) + return NULL; + + pipe_texture_reference(&surface->texture, $self); + surface->face = face; + surface->level = level; + surface->zslice = zslice; + + return surface; + + fail: + return NULL; } }; +struct st_surface +{ + %immutable; + + struct pipe_texture *texture; + unsigned face; + unsigned level; + unsigned zslice; + +}; -%extend pipe_surface { +%extend st_surface { + + %immutable; - ~pipe_surface() { - struct pipe_surface *ptr = $self; - pipe_surface_reference(&ptr, NULL); + unsigned format; + unsigned width; + unsigned height; + unsigned nblocksx; + unsigned nblocksy; + + ~st_surface() { + pipe_texture_reference(&$self->texture, NULL); + FREE($self); } - // gets mapped to pipe_surface_map automatically - void * map( unsigned flags ); + %cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1)); + void get_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, char **STRING, int *LENGTH) + { + struct pipe_texture *texture = $self->texture; + struct pipe_screen *screen = texture->screen; + struct pipe_transfer *transfer; + unsigned stride; - // gets mapped to pipe_surface_unmap automatically - void unmap( void ); + stride = pf_get_nblocksx(&texture->block, w) * texture->block.size; + *LENGTH = pf_get_nblocksy(&texture->block, h) * stride; + *STRING = (char *) malloc(*LENGTH); + if(!*STRING) + return; - void - get_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, char *raw, unsigned stride) { - pipe_get_tile_raw($self, x, y, w, h, raw, stride); + transfer = screen->get_tex_transfer(screen, + $self->texture, + $self->face, + $self->level, + $self->zslice, + PIPE_TRANSFER_READ, + x, y, w, h); + if(transfer) { + pipe_get_tile_raw(transfer, 0, 0, w, h, *STRING, stride); + screen->tex_transfer_destroy(transfer); + } } - void - put_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, const char *raw, unsigned stride) { - pipe_put_tile_raw($self, x, y, w, h, raw, stride); + %cstring_input_binary(const char *STRING, unsigned LENGTH); + void put_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, const char *STRING, unsigned LENGTH, unsigned stride = 0) + { + struct pipe_texture *texture = $self->texture; + struct pipe_screen *screen = texture->screen; + struct pipe_transfer *transfer; + + if(stride == 0) + stride = pf_get_nblocksx(&texture->block, w) * texture->block.size; + + if(LENGTH < pf_get_nblocksy(&texture->block, h) * stride) + SWIG_exception(SWIG_ValueError, "offset must be smaller than buffer size"); + + transfer = screen->get_tex_transfer(screen, + $self->texture, + $self->face, + $self->level, + $self->zslice, + PIPE_TRANSFER_WRITE, + x, y, w, h); + if(!transfer) + SWIG_exception(SWIG_MemoryError, "couldn't initiate transfer"); + + pipe_put_tile_raw(transfer, 0, 0, w, h, STRING, stride); + screen->tex_transfer_destroy(transfer); + + fail: + return; } void - get_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, float *rgba) { - pipe_get_tile_rgba($self, x, y, w, h, rgba); + get_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, float *rgba) + { + struct pipe_screen *screen = $self->texture->screen; + struct pipe_transfer *transfer; + transfer = screen->get_tex_transfer(screen, + $self->texture, + $self->face, + $self->level, + $self->zslice, + PIPE_TRANSFER_READ, + x, y, w, h); + if(transfer) { + pipe_get_tile_rgba(transfer, 0, 0, w, h, rgba); + screen->tex_transfer_destroy(transfer); + } } 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); + put_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *rgba) + { + struct pipe_screen *screen = $self->texture->screen; + struct pipe_transfer *transfer; + transfer = screen->get_tex_transfer(screen, + $self->texture, + $self->face, + $self->level, + $self->zslice, + PIPE_TRANSFER_WRITE, + x, y, w, h); + if(transfer) { + pipe_put_tile_rgba(transfer, 0, 0, w, h, rgba); + screen->tex_transfer_destroy(transfer); + } } %cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1)); void get_tile_rgba8(unsigned x, unsigned y, unsigned w, unsigned h, char **STRING, int *LENGTH) { - unsigned surface_usage; + struct pipe_screen *screen = $self->texture->screen; + struct pipe_transfer *transfer; float *rgba; unsigned char *rgba8; unsigned i, j, k; @@ -141,38 +248,67 @@ if(!*STRING) return; - rgba = malloc(w*4*sizeof(float)); + rgba = malloc(h*w*4*sizeof(float)); if(!rgba) return; rgba8 = (unsigned char *) *STRING; - /* XXX: force mappable surface */ - surface_usage = $self->usage; - $self->usage |= PIPE_BUFFER_USAGE_CPU_READ; - - for(j = 0; j < h; ++j) { - pipe_get_tile_rgba($self, - x, y + j, w, 1, - rgba); - for(i = 0; i < w; ++i) - for(k = 0; k <4; ++k) - rgba8[j*w*4 + i*4 + k] = float_to_ubyte(rgba[i*4 + k]); + transfer = screen->get_tex_transfer(screen, + $self->texture, + $self->face, + $self->level, + $self->zslice, + PIPE_TRANSFER_READ, + x, y, + w, h); + if(transfer) { + pipe_get_tile_rgba(transfer, 0, 0, w, h, rgba); + for(j = 0; j < h; ++j) { + for(i = 0; i < w; ++i) + for(k = 0; k <4; ++k) + rgba8[j*w*4 + i*4 + k] = float_to_ubyte(rgba[j*w*4 + i*4 + k]); + } + screen->tex_transfer_destroy(transfer); } - $self->usage = surface_usage; - free(rgba); } void - get_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, unsigned *z) { - pipe_get_tile_z($self, x, y, w, h, z); + get_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, unsigned *z) + { + struct pipe_screen *screen = $self->texture->screen; + struct pipe_transfer *transfer; + transfer = screen->get_tex_transfer(screen, + $self->texture, + $self->face, + $self->level, + $self->zslice, + PIPE_TRANSFER_READ, + x, y, w, h); + if(transfer) { + pipe_get_tile_z(transfer, 0, 0, w, h, z); + screen->tex_transfer_destroy(transfer); + } } void - put_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, const unsigned *z) { - pipe_put_tile_z($self, x, y, w, h, z); + put_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, const unsigned *z) + { + struct pipe_screen *screen = $self->texture->screen; + struct pipe_transfer *transfer; + transfer = screen->get_tex_transfer(screen, + $self->texture, + $self->face, + $self->level, + $self->zslice, + PIPE_TRANSFER_WRITE, + x, y, w, h); + if(transfer) { + pipe_put_tile_z(transfer, 0, 0, w, h, z); + screen->tex_transfer_destroy(transfer); + } } void @@ -183,6 +319,8 @@ unsigned compare_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *rgba, float tol = 0.0) { + struct pipe_screen *screen = $self->texture->screen; + struct pipe_transfer *transfer; float *rgba2; const float *p1; const float *p2; @@ -192,7 +330,20 @@ if(!rgba2) return ~0; - pipe_get_tile_rgba($self, x, y, w, h, rgba2); + transfer = screen->get_tex_transfer(screen, + $self->texture, + $self->face, + $self->level, + $self->zslice, + PIPE_TRANSFER_READ, + x, y, w, h); + if(!transfer) { + FREE(rgba2); + return ~0; + } + + pipe_get_tile_rgba(transfer, 0, 0, w, h, rgba2); + screen->tex_transfer_destroy(transfer); p1 = rgba; p2 = rgba2; @@ -214,63 +365,86 @@ }; -struct st_buffer { -}; +%{ + static enum pipe_format + st_surface_format_get(struct st_surface *surface) + { + return surface->texture->format; + } + + static unsigned + st_surface_width_get(struct st_surface *surface) + { + return surface->texture->width[surface->level]; + } + + static unsigned + st_surface_height_get(struct st_surface *surface) + { + return surface->texture->height[surface->level]; + } + + static unsigned + st_surface_nblocksx_get(struct st_surface *surface) + { + return surface->texture->nblocksx[surface->level]; + } + + static unsigned + st_surface_nblocksy_get(struct st_surface *surface) + { + return surface->texture->nblocksy[surface->level]; + } +%} + +/* Avoid naming conflict with p_inlines.h's pipe_buffer_read/write */ +%rename(read) read_; +%rename(write) write_; -%extend st_buffer { +%extend pipe_buffer { - ~st_buffer() { - st_buffer_destroy($self); + ~pipe_buffer() { + struct pipe_buffer *ptr = $self; + pipe_buffer_reference(&ptr, NULL); } unsigned __len__(void) { - assert(p_atomic_read(&$self->buffer->reference.count) > 0); - return $self->buffer->size; + assert(p_atomic_read(&$self->reference.count) > 0); + return $self->size; } %cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1)); - void read(char **STRING, int *LENGTH) + void read_(char **STRING, int *LENGTH) { - struct pipe_screen *screen = $self->st_dev->screen; - const char *map; + struct pipe_screen *screen = $self->screen; - assert(p_atomic_read(&$self->buffer->reference.count) > 0); + assert(p_atomic_read(&$self->reference.count) > 0); - *LENGTH = $self->buffer->size; - *STRING = (char *) malloc($self->buffer->size); + *LENGTH = $self->size; + *STRING = (char *) malloc($self->size); if(!*STRING) return; - map = pipe_buffer_map(screen, $self->buffer, PIPE_BUFFER_USAGE_CPU_READ); - if(map) { - memcpy(*STRING, map, $self->buffer->size); - pipe_buffer_unmap(screen, $self->buffer); - } + pipe_buffer_read(screen, $self, 0, $self->size, STRING); } %cstring_input_binary(const char *STRING, unsigned LENGTH); - void write(const char *STRING, unsigned LENGTH, unsigned offset = 0) + void write_(const char *STRING, unsigned LENGTH, unsigned offset = 0) { - struct pipe_screen *screen = $self->st_dev->screen; - char *map; + struct pipe_screen *screen = $self->screen; - assert(p_atomic_read(&$self->buffer->reference.count) > 0); + assert(p_atomic_read(&$self->reference.count) > 0); - if(offset > $self->buffer->size) { - PyErr_SetString(PyExc_ValueError, "offset must be smaller than buffer size"); - return; - } + if(offset > $self->size) + SWIG_exception(SWIG_ValueError, "offset must be smaller than buffer size"); - if(offset + LENGTH > $self->buffer->size) { - PyErr_SetString(PyExc_ValueError, "data length must fit inside the buffer"); - return; - } + if(offset + LENGTH > $self->size) + SWIG_exception(SWIG_ValueError, "data length must fit inside the buffer"); - map = pipe_buffer_map(screen, $self->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); - if(map) { - memcpy(map + offset, STRING, LENGTH); - pipe_buffer_unmap(screen, $self->buffer); - } + pipe_buffer_write(screen, $self, offset, LENGTH, STRING); + +fail: + return; } }; diff --git a/src/gallium/state_trackers/python/retrace/format.py b/src/gallium/state_trackers/python/retrace/format.py index 0bf6baf0b94..a4285bfe075 100755 --- a/src/gallium/state_trackers/python/retrace/format.py +++ b/src/gallium/state_trackers/python/retrace/format.py @@ -27,6 +27,9 @@ ########################################################################## +import sys + + class Formatter: '''Plain formatter''' @@ -91,10 +94,80 @@ class AnsiFormatter(Formatter): self._escape(self._normal) +class WindowsConsoleFormatter(Formatter): + '''Formatter for the Windows Console. See + http://code.activestate.com/recipes/496901/ for more information. + ''' + + STD_INPUT_HANDLE = -10 + STD_OUTPUT_HANDLE = -11 + STD_ERROR_HANDLE = -12 + + FOREGROUND_BLUE = 0x01 + FOREGROUND_GREEN = 0x02 + FOREGROUND_RED = 0x04 + FOREGROUND_INTENSITY = 0x08 + BACKGROUND_BLUE = 0x10 + BACKGROUND_GREEN = 0x20 + BACKGROUND_RED = 0x40 + BACKGROUND_INTENSITY = 0x80 + + _normal = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED + _bold = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY + _italic = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED + _red = FOREGROUND_RED | FOREGROUND_INTENSITY + _green = FOREGROUND_GREEN | FOREGROUND_INTENSITY + _blue = FOREGROUND_BLUE | FOREGROUND_INTENSITY + + def __init__(self, stream): + Formatter.__init__(self, stream) + + if stream is sys.stdin: + nStdHandle = self.STD_INPUT_HANDLE + elif stream is sys.stdout: + nStdHandle = self.STD_OUTPUT_HANDLE + elif stream is sys.stderr: + nStdHandle = self.STD_ERROR_HANDLE + else: + nStdHandle = None + + if nStdHandle: + import ctypes + self.handle = ctypes.windll.kernel32.GetStdHandle(nStdHandle) + else: + self.handle = None + + def _attribute(self, attr): + if self.handle: + import ctypes + ctypes.windll.kernel32.SetConsoleTextAttribute(self.handle, attr) + + def function(self, name): + self._attribute(self._bold) + Formatter.function(self, name) + self._attribute(self._normal) + + def variable(self, name): + self._attribute(self._italic) + Formatter.variable(self, name) + self._attribute(self._normal) + + def literal(self, value): + self._attribute(self._blue) + Formatter.literal(self, value) + self._attribute(self._normal) + + def address(self, value): + self._attribute(self._green) + Formatter.address(self, value) + self._attribute(self._normal) + def DefaultFormatter(stream): - if stream.isatty(): + if sys.platform in ('linux2', 'cygwin'): return AnsiFormatter(stream) + elif sys.platform in ('win32',): + return WindowsConsoleFormatter(stream) else: return Formatter(stream) diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py index e6999a2211e..5ea07724a50 100755 --- a/src/gallium/state_trackers/python/retrace/interpreter.py +++ b/src/gallium/state_trackers/python/retrace/interpreter.py @@ -54,14 +54,14 @@ def save_image(filename, surface): outimage = make_image(surface) outimage.save(filename, "PNG") -def show_image(surface): +def show_image(surface, title): outimage = make_image(surface) import Tkinter as tk from PIL import Image, ImageTk root = tk.Tk() - root.title('background image') + root.title(title) image1 = ImageTk.PhotoImage(outimage) w = image1.width() @@ -75,9 +75,6 @@ def show_image(surface): root.mainloop() -verbose = 1 - - class Struct: """C-like struct""" @@ -184,8 +181,12 @@ class Global(Object): def pipe_winsys_create(self): return Winsys(self.interpreter, gallium.Device()) - def pipe_screen_create(self, winsys): - return Screen(self.interpreter, winsys.real) + def pipe_screen_create(self, winsys=None): + if winsys is None: + real = gallium.Device() + else: + real = winsys.real + return Screen(self.interpreter, real) def pipe_context_create(self, screen): context = screen.real.context_create() @@ -237,6 +238,16 @@ class Winsys(Object): pass +class Transfer: + + def __init__(self, surface, x, y, w, h): + self.surface = surface + self.x = x + self.y = y + self.w = w + self.h = h + + class Screen(Object): def destroy(self): @@ -257,15 +268,15 @@ class Screen(Object): def is_format_supported(self, format, target, tex_usage, geom_flags): return self.real.is_format_supported(format, target, tex_usage, geom_flags) - def texture_create(self, template): + def texture_create(self, templat): return self.real.texture_create( - format = template.format, - width = template.width[0], - height = template.height[0], - depth = template.depth[0], - last_level = template.last_level, - target = template.target, - tex_usage = template.tex_usage, + format = templat.format, + width = templat.width[0], + height = templat.height[0], + depth = templat.depth[0], + last_level = templat.last_level, + target = templat.target, + tex_usage = templat.tex_usage, ) def texture_destroy(self, texture): @@ -275,7 +286,9 @@ class Screen(Object): pass def get_tex_surface(self, texture, face, level, zslice, usage): - return texture.get_surface(face, level, zslice, usage) + if texture is None: + return None + return texture.get_surface(face, level, zslice) def tex_surface_destroy(self, surface): self.interpreter.unregister_object(surface) @@ -284,9 +297,53 @@ class Screen(Object): pass def surface_write(self, surface, data, stride, size): + if surface is None: + return assert surface.nblocksy * stride == size surface.put_tile_raw(0, 0, surface.width, surface.height, data, stride) + def get_tex_transfer(self, texture, face, level, zslice, usage, x, y, w, h): + if texture is None: + return None + return Transfer(texture.get_surface(face, level, zslice), x, y, w, h) + + def tex_transfer_destroy(self, transfer): + self.interpreter.unregister_object(transfer) + + def transfer_write(self, transfer, stride, data, size): + if transfer is None: + return + transfer.surface.put_tile_raw(transfer.x, transfer.y, transfer.w, transfer.h, data, stride) + + def user_buffer_create(self, data, size): + # We don't really care to distinguish between user and regular buffers + buffer = self.real.buffer_create(size, + 4, + gallium.PIPE_BUFFER_USAGE_CPU_READ | + gallium.PIPE_BUFFER_USAGE_CPU_WRITE ) + assert size == len(data) + buffer.write(data) + return buffer + + def buffer_create(self, alignment, usage, size): + return self.real.buffer_create(size, alignment, usage) + + def buffer_destroy(self, buffer): + pass + + def buffer_write(self, buffer, data, size, offset=0): + assert size == len(data) + buffer.write(data) + + def fence_finish(self, fence, flags): + pass + + def fence_reference(self, dst, src): + pass + + def flush_frontbuffer(self, surface): + pass + class Context(Object): @@ -317,8 +374,8 @@ class Context(Object): def delete_sampler_state(self, state): pass - def bind_sampler_states(self, n, states): - for i in range(n): + def bind_sampler_states(self, num_states, states): + for i in range(num_states): self.real.set_sampler(i, states[i]) def create_rasterizer_state(self, state): @@ -375,7 +432,7 @@ class Context(Object): self.real.set_clip(_state) def dump_constant_buffer(self, buffer): - if verbose < 2: + if not self.interpreter.verbosity(2): return data = buffer.read() @@ -386,17 +443,17 @@ class Context(Object): sys.stdout.write('\tCONST[%2u] = {%10.4f, %10.4f, %10.4f, %10.4f}\n' % (index, x, y, z, w)) index += 1 - def set_constant_buffer(self, shader, index, state): - if state is not None: - self.real.set_constant_buffer(shader, index, state.buffer) + def set_constant_buffer(self, shader, index, buffer): + if buffer is not None: + self.real.set_constant_buffer(shader, index, buffer.buffer) - self.dump_constant_buffer(state.buffer) + self.dump_constant_buffer(buffer.buffer) def set_framebuffer_state(self, state): _state = gallium.Framebuffer() _state.width = state.width _state.height = state.height - _state.num_cbufs = state.num_cbufs + _state.nr_cbufs = state.nr_cbufs for i in range(len(state.cbufs)): _state.set_cbuf(i, state.cbufs[i]) _state.set_zsbuf(state.zsbuf) @@ -414,34 +471,34 @@ class Context(Object): def set_viewport_state(self, state): self.real.set_viewport(state) - def set_sampler_textures(self, n, textures): - for i in range(n): + def set_sampler_textures(self, num_textures, textures): + for i in range(num_textures): self.real.set_sampler_texture(i, textures[i]) - def set_vertex_buffers(self, n, vbufs): - self.vbufs = vbufs[0:n] - for i in range(n): - vbuf = vbufs[i] + def set_vertex_buffers(self, num_buffers, buffers): + self.vbufs = buffers[0:num_buffers] + for i in range(num_buffers): + vbuf = buffers[i] self.real.set_vertex_buffer( i, - pitch = vbuf.pitch, + stride = vbuf.stride, max_index = vbuf.max_index, buffer_offset = vbuf.buffer_offset, buffer = vbuf.buffer, ) - def set_vertex_elements(self, n, elements): - self.velems = elements[0:n] - for i in range(n): + def set_vertex_elements(self, num_elements, elements): + self.velems = elements[0:num_elements] + for i in range(num_elements): self.real.set_vertex_element(i, elements[i]) - self.real.set_vertex_elements(n) + self.real.set_vertex_elements(num_elements) def set_edgeflags(self, bitfield): # FIXME pass def dump_vertices(self, start, count): - if verbose < 2: + if not self.interpreter.verbosity(2): return for index in range(start, start + count): @@ -452,7 +509,7 @@ class Context(Object): for velem in self.velems: vbuf = self.vbufs[velem.vertex_buffer_index] - offset = vbuf.buffer_offset + velem.src_offset + vbuf.pitch*index + offset = vbuf.buffer_offset + velem.src_offset + vbuf.stride*index format = { gallium.PIPE_FORMAT_R32_FLOAT: 'f', gallium.PIPE_FORMAT_R32G32_FLOAT: '2f', @@ -468,7 +525,7 @@ class Context(Object): sys.stdout.write('\t},\n') def dump_indices(self, ibuf, isize, start, count): - if verbose < 2: + if not self.interpreter.verbosity(2): return format = { @@ -500,45 +557,51 @@ class Context(Object): self.dump_vertices(start, count) self.real.draw_arrays(mode, start, count) - - self.dirty = True + self._set_dirty() def draw_elements(self, indexBuffer, indexSize, mode, start, count): - if verbose >= 2: + if self.interpreter.verbosity(2): minindex, maxindex = self.dump_indices(indexBuffer, indexSize, start, count) self.dump_vertices(minindex, maxindex - minindex) self.real.draw_elements(indexBuffer, indexSize, mode, start, count) - - self.dirty = True + self._set_dirty() def draw_range_elements(self, indexBuffer, indexSize, minIndex, maxIndex, mode, start, count): - if verbose >= 2: + if self.interpreter.verbosity(2): minindex, maxindex = self.dump_indices(indexBuffer, indexSize, start, count) minindex = min(minindex, minIndex) maxindex = min(maxindex, maxIndex) self.dump_vertices(minindex, maxindex - minindex) self.real.draw_range_elements(indexBuffer, indexSize, minIndex, maxIndex, mode, start, count) - - self.dirty = True + self._set_dirty() + def _set_dirty(self): + if self.interpreter.options.step: + self._present() + else: + self.dirty = True + def flush(self, flags): self.real.flush(flags) if self.dirty: if flags & gallium.PIPE_FLUSH_FRAME: - self._update() + self._present() self.dirty = False return None - def clear(self, surface, value): - self.real.surface_clear(surface, value) + def clear(self, buffers, rgba, depth, stencil): + _rgba = gallium.FloatArray(4) + for i in range(4): + _rgba[i] = rgba[i] + self.real.clear(buffers, _rgba, depth, stencil) - def _update(self): + def _present(self): self.real.flush() if self.cbufs and self.cbufs[0]: - show_image(self.cbufs[0]) + self.interpreter.present(self.cbufs[0], "cbuf") class Interpreter(parser.TraceDumper): @@ -549,11 +612,13 @@ class Interpreter(parser.TraceDumper): ('pipe_screen', 'get_paramf'), )) - def __init__(self, stream): + def __init__(self, stream, options): parser.TraceDumper.__init__(self, stream) + self.options = options self.objects = {} self.result = None self.globl = Global(self, None) + self.call_no = None def register_object(self, address, object): self.objects[address] = object @@ -570,31 +635,70 @@ class Interpreter(parser.TraceDumper): self.interpret_call(call) def handle_call(self, call): + if self.options.stop and call.no >= self.options.stop: + sys.exit(0) if (call.klass, call.method) in self.ignore_calls: return - if verbose >= 1: + self.call_no = call.no + + if self.verbosity(1): parser.TraceDumper.handle_call(self, call) - args = [self.interpret_arg(arg) for name, arg in call.args] + args = [(str(name), self.interpret_arg(arg)) for name, arg in call.args] if call.klass: - obj = args[0] + name, obj = args[0] args = args[1:] else: obj = self.globl method = getattr(obj, call.method) - ret = method(*args) + ret = method(**dict(args)) if call.ret and isinstance(call.ret, model.Pointer): + if ret is None: + sys.stderr.write('warning: NULL returned\n') self.register_object(call.ret.address, ret) + self.call_no = None + def interpret_arg(self, node): translator = Translator(self) return translator.visit(node) + + def verbosity(self, level): + return self.options.verbosity >= level + + def present(self, surface, description): + if self.call_no < self.options.start: + return + + if self.options.images: + filename = '%s_%04u.png' % (description, self.call_no) + save_image(filename, surface) + else: + title = '%u. %s' % (self.call_no, description) + show_image(surface, title) +class Main(parser.Main): + + def get_optparser(self): + optparser = parser.Main.get_optparser(self) + optparser.add_option("-q", "--quiet", action="store_const", const=0, dest="verbosity", help="no messages") + optparser.add_option("-v", "--verbose", action="count", dest="verbosity", default=1, help="increase verbosity level") + optparser.add_option("-i", "--images", action="store_true", dest="images", default=False, help="save images instead of showing them") + optparser.add_option("-s", "--step", action="store_true", dest="step", default=False, help="step trhough every draw") + optparser.add_option("-f", "--from", action="store", type="int", dest="start", default=0, help="from call no") + optparser.add_option("-t", "--to", action="store", type="int", dest="stop", default=0, help="until call no") + return optparser + + def process_arg(self, stream, options): + parser = Interpreter(stream, options) + parser.parse() + + if __name__ == '__main__': - parser.main(Interpreter) + Main().main() diff --git a/src/gallium/state_trackers/python/retrace/model.py b/src/gallium/state_trackers/python/retrace/model.py index ae0f4327d76..d4a079fb1e5 100755 --- a/src/gallium/state_trackers/python/retrace/model.py +++ b/src/gallium/state_trackers/python/retrace/model.py @@ -101,7 +101,8 @@ class Pointer(Node): class Call: - def __init__(self, klass, method, args, ret): + def __init__(self, no, klass, method, args, ret): + self.no = no self.klass = klass self.method = method self.args = args @@ -187,6 +188,7 @@ class PrettyPrinter: self.formatter.address(node.address) def visit_call(self, node): + self.formatter.text('%s ' % node.no) if node.klass is not None: self.formatter.function(node.klass + '::' + node.method) else: diff --git a/src/gallium/state_trackers/python/retrace/parser.py b/src/gallium/state_trackers/python/retrace/parser.py index 5205f2d8dd5..b0f3e8a432f 100755 --- a/src/gallium/state_trackers/python/retrace/parser.py +++ b/src/gallium/state_trackers/python/retrace/parser.py @@ -30,6 +30,7 @@ import sys import xml.parsers.expat import binascii +import optparse from model import * @@ -189,6 +190,10 @@ class XmlParser: class TraceParser(XmlParser): + def __init__(self, fp): + XmlParser.__init__(self, fp) + self.last_call_no = 0 + def parse(self): self.element_start('trace') while self.token.type not in (ELEMENT_END, EOF): @@ -199,6 +204,13 @@ class TraceParser(XmlParser): def parse_call(self): attrs = self.element_start('call') + try: + no = int(attrs['no']) + except KeyError: + self.last_call_no += 1 + no = self.last_call_no + else: + self.last_call_no = no klass = attrs['class'] method = attrs['method'] args = [] @@ -216,7 +228,7 @@ class TraceParser(XmlParser): raise TokenMismatch("<arg ...> or <ret ...>", self.token) self.element_end('call') - return Call(klass, method, args, ret) + return Call(no, klass, method, args, ret) def parse_arg(self): attrs = self.element_start('arg') @@ -342,16 +354,39 @@ class TraceDumper(TraceParser): self.formatter.newline() -def main(ParserFactory): - for arg in sys.argv[1:]: - if arg.endswith('.gz'): - import gzip - stream = gzip.GzipFile(arg, 'rt') +class Main: + '''Common main class for all retrace command line utilities.''' + + def __init__(self): + pass + + def main(self): + optparser = self.get_optparser() + (options, args) = optparser.parse_args(sys.argv[1:]) + + if args: + for arg in args: + if arg.endswith('.gz'): + from gzip import GzipFile + stream = GzipFile(arg, 'rt') + elif arg.endswith('.bz2'): + from bz2 import BZ2File + stream = BZ2File(arg, 'rt') + else: + stream = open(arg, 'rt') + self.process_arg(stream, options) else: - stream = open(arg, 'rt') - parser = ParserFactory(stream) + self.process_arg(stream, options) + + def get_optparser(self): + optparser = optparse.OptionParser( + usage="\n\t%prog [options] [traces] ...") + return optparser + + def process_arg(self, stream, options): + parser = TraceDumper(stream) parser.parse() if __name__ == '__main__': - main(TraceDumper) + Main().main() diff --git a/src/gallium/state_trackers/python/samples/tri.py b/src/gallium/state_trackers/python/samples/tri.py index d3ccb6c2f46..4b9659861df 100644 --- a/src/gallium/state_trackers/python/samples/tri.py +++ b/src/gallium/state_trackers/python/samples/tri.py @@ -67,6 +67,8 @@ def test(dev): width = 255 height = 255 + minz = 0.0 + maxz = 1.0 # disabled blending/masking blend = Blend() @@ -77,31 +79,32 @@ def test(dev): blend.colormask = PIPE_MASK_RGBA ctx.set_blend(blend) - # no-op depth/stencil/alpha + # depth/stencil/alpha depth_stencil_alpha = DepthStencilAlpha() + depth_stencil_alpha.depth.enabled = 1 + depth_stencil_alpha.depth.writemask = 1 + depth_stencil_alpha.depth.func = PIPE_FUNC_LESS 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.scissor = 1 - #rasterizer.bypass_vs = 1 ctx.set_rasterizer(rasterizer) - # viewport (identity, we setup vertices in wincoords) + # viewport viewport = Viewport() scale = FloatArray(4) - scale[0] = 1.0 - scale[1] = 1.0 - scale[2] = 1.0 + scale[0] = width / 2.0 + scale[1] = -height / 2.0 + scale[2] = (maxz - minz) / 2.0 scale[3] = 1.0 viewport.scale = scale translate = FloatArray(4) - translate[0] = 0.0 - translate[1] = 0.0 - translate[2] = 0.0 + translate[0] = width / 2.0 + translate[1] = height / 2.0 + translate[2] = (maxz - minz) / 2.0 translate[3] = 0.0 viewport.translate = translate ctx.set_viewport(viewport) @@ -134,17 +137,25 @@ def test(dev): 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) + ).get_surface() + zbuf = dev.texture_create( + PIPE_FORMAT_Z32_UNORM, + width, height, + tex_usage=PIPE_TEXTURE_USAGE_DEPTH_STENCIL, + ).get_surface() fb = Framebuffer() fb.width = width fb.height = height - fb.num_cbufs = 1 - fb.set_cbuf(0, _cbuf) + fb.nr_cbufs = 1 + fb.set_cbuf(0, cbuf) + fb.set_zsbuf(zbuf) ctx.set_framebuffer(fb) - _cbuf.clear_value = 0x00000000 - ctx.surface_clear(_cbuf, _cbuf.clear_value) - del _cbuf + rgba = FloatArray(4); + rgba[0] = 0.0 + rgba[1] = 0.0 + rgba[2] = 0.0 + rgba[3] = 0.0 + ctx.clear(PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL, rgba, 1.0, 0xff) # vertex shader vs = Shader(''' @@ -173,25 +184,25 @@ def test(dev): nattrs = 2 verts = FloatArray(nverts * nattrs * 4) - verts[ 0] = 128.0 # x1 - verts[ 1] = 32.0 # y1 - verts[ 2] = 0.0 # z1 + verts[ 0] = 0.0 # x1 + verts[ 1] = 0.8 # y1 + verts[ 2] = 0.2 # 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[ 8] = -0.8 # x2 + verts[ 9] = -0.8 # y2 + verts[10] = 0.5 # 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[16] = 0.8 # x3 + verts[17] = -0.8 # y3 + verts[18] = 0.8 # z3 verts[19] = 1.0 # w3 verts[20] = 0.0 # r3 verts[21] = 0.0 # g3 @@ -205,8 +216,10 @@ def test(dev): ctx.flush() - show_image(cbuf.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ|PIPE_BUFFER_USAGE_CPU_WRITE)) - #save_image('tri.png', cbuf.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ|PIPE_BUFFER_USAGE_CPU_WRITE)) + show_image(cbuf) + #show_image(zbuf) + #save_image('cbuf.png', cbuf) + #save_image('zbuf.png', zbuf) diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c index 366d4eb19af..8246b378ce0 100644 --- a/src/gallium/state_trackers/python/st_device.c +++ b/src/gallium/state_trackers/python/st_device.c @@ -192,10 +192,16 @@ st_context_create(struct st_device *st_dev) memset(&rasterizer, 0, sizeof(rasterizer)); rasterizer.front_winding = PIPE_WINDING_CW; rasterizer.cull_mode = PIPE_WINDING_NONE; - rasterizer.bypass_vs_clip_and_viewport = 1; cso_set_rasterizer(st_ctx->cso, &rasterizer); } + /* clip */ + { + struct pipe_clip_state clip; + memset(&clip, 0, sizeof(clip)); + st_ctx->pipe->set_clip_state(st_ctx->pipe, &clip); + } + /* identity viewport */ { struct pipe_viewport_state viewport; @@ -291,37 +297,3 @@ st_context_create(struct st_device *st_dev) return st_ctx; } - - -void -st_buffer_destroy(struct st_buffer *st_buf) -{ - if(st_buf) { - pipe_buffer_reference(&st_buf->buffer, NULL); - FREE(st_buf); - } -} - - -struct st_buffer * -st_buffer_create(struct st_device *st_dev, - unsigned alignment, unsigned usage, unsigned size) -{ - struct pipe_screen *screen = st_dev->screen; - struct st_buffer *st_buf; - - st_buf = CALLOC_STRUCT(st_buffer); - if(!st_buf) - return NULL; - - st_buf->st_dev = st_dev; - - st_buf->buffer = pipe_buffer_create(screen, alignment, usage, size); - if(!st_buf->buffer) { - st_buffer_destroy(st_buf); - return NULL; - } - - return st_buf; -} - diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h index 0641aff149f..a246b6a1f25 100644 --- a/src/gallium/state_trackers/python/st_device.h +++ b/src/gallium/state_trackers/python/st_device.h @@ -38,10 +38,12 @@ struct pipe_context; struct st_winsys; -struct st_buffer { - struct st_device *st_dev; - - struct pipe_buffer *buffer; +struct st_surface +{ + struct pipe_texture *texture; + unsigned face; + unsigned level; + unsigned zslice; }; @@ -64,6 +66,8 @@ struct st_context { unsigned num_vertex_elements; struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS]; + + struct pipe_framebuffer_state framebuffer; }; @@ -78,12 +82,13 @@ struct st_device { }; -struct st_buffer * -st_buffer_create(struct st_device *st_dev, - unsigned alignment, unsigned usage, unsigned size); - -void -st_buffer_destroy(struct st_buffer *st_buf); +static INLINE struct pipe_surface * +st_pipe_surface(struct st_surface *surface, unsigned usage) +{ + struct pipe_texture *texture = surface->texture; + struct pipe_screen *screen = texture->screen; + return screen->get_tex_surface(screen, texture, surface->face, surface->level, surface->zslice, usage); +} struct st_context * st_context_create(struct st_device *st_dev); diff --git a/src/gallium/state_trackers/python/st_sample.c b/src/gallium/state_trackers/python/st_sample.c index c2ffe9fce1d..53a01891e12 100644 --- a/src/gallium/state_trackers/python/st_sample.c +++ b/src/gallium/state_trackers/python/st_sample.c @@ -34,6 +34,7 @@ #include "util/u_math.h" #include "util/u_memory.h" +#include "st_device.h" #include "st_sample.h" @@ -523,10 +524,13 @@ st_sample_pixel_block(enum pipe_format format, void -st_sample_surface(struct pipe_surface *surface, float *rgba) +st_sample_surface(struct st_surface *surface, float *rgba) { - struct pipe_screen *screen = surface->texture->screen; - uint rgba_stride = surface->width * 4; + struct pipe_texture *texture = surface->texture; + struct pipe_screen *screen = texture->screen; + unsigned width = texture->width[surface->level]; + unsigned height = texture->height[surface->level]; + uint rgba_stride = width * 4; struct pipe_transfer *transfer; void *raw; @@ -535,27 +539,27 @@ st_sample_surface(struct pipe_surface *surface, float *rgba) surface->face, surface->level, surface->zslice, - PIPE_TRANSFER_READ, + PIPE_TRANSFER_WRITE, 0, 0, - surface->width, - surface->height); + width, + height); if (!transfer) return; raw = screen->transfer_map(screen, transfer); if (raw) { - const struct pipe_format_block *block = &transfer->block; + const struct pipe_format_block *block = &texture->block; uint x, y; for (y = 0; y < transfer->nblocksy; ++y) { for (x = 0; x < transfer->nblocksx; ++x) { - st_sample_pixel_block(surface->format, + st_sample_pixel_block(texture->format, block, (uint8_t *) raw + y * transfer->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)); + MIN2(block->width, width - x*block->width), + MIN2(block->height, height - y*block->height)); } } diff --git a/src/gallium/state_trackers/python/st_sample.h b/src/gallium/state_trackers/python/st_sample.h index ff04a12613f..0a27083549f 100644 --- a/src/gallium/state_trackers/python/st_sample.h +++ b/src/gallium/state_trackers/python/st_sample.h @@ -41,7 +41,7 @@ st_sample_pixel_block(enum pipe_format format, unsigned w, unsigned h); void -st_sample_surface(struct pipe_surface *surface, float *rgba); +st_sample_surface(struct st_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 426f347d189..41cdeaa6fdc 100644 --- a/src/gallium/state_trackers/python/st_softpipe_winsys.c +++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c @@ -84,8 +84,7 @@ st_softpipe_buffer_unmap(struct pipe_winsys *winsys, static void -st_softpipe_buffer_destroy(struct pipe_winsys *winsys, - struct pipe_buffer *buf) +st_softpipe_buffer_destroy(struct pipe_buffer *buf) { struct st_softpipe_buffer *oldBuf = st_softpipe_buffer(buf); diff --git a/src/gallium/state_trackers/python/tests/.gitignore b/src/gallium/state_trackers/python/tests/.gitignore new file mode 100644 index 00000000000..0dbbaeea16b --- /dev/null +++ b/src/gallium/state_trackers/python/tests/.gitignore @@ -0,0 +1,3 @@ +*.txt +*.tsv +*.dot diff --git a/src/gallium/state_trackers/python/tests/base.py b/src/gallium/state_trackers/python/tests/base.py index 8477aa5fc9b..1fa7fe6f3b3 100644..100755 --- a/src/gallium/state_trackers/python/tests/base.py +++ b/src/gallium/state_trackers/python/tests/base.py @@ -1,6 +1,7 @@ #!/usr/bin/env python ########################################################################## # +# Copyright 2009 VMware, Inc. # Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. # All Rights Reserved. # @@ -19,7 +20,7 @@ # 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 +# IN NO EVENT SHALL VMWARE 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. @@ -33,6 +34,9 @@ Loosely inspired on Python's unittest module. """ +import os.path +import sys + from gallium import * @@ -115,17 +119,77 @@ class Test: self._run(result) result.summary() + def assert_rgba(self, surface, x, y, w, h, expected_rgba, pixel_tol=4.0/256, surface_tol=0.85): + total = h*w + different = surface.compare_tile_rgba(x, y, w, h, expected_rgba, tol=pixel_tol) + if different: + sys.stderr.write("%u out of %u pixels differ\n" % (different, total)) + + if float(total - different)/float(total) < surface_tol: + if 0: + rgba = FloatArray(h*w*4) + surface.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 + class TestCase(Test): + tags = () + def __init__(self, dev, **kargs): Test.__init__(self) self.dev = dev self.__dict__.update(kargs) def description(self): - raise NotImplementedError - + descriptions = [] + for tag in self.tags: + value = self.get(tag) + if value is not None and value != '': + descriptions.append(tag + '=' + str(value)) + return ' '.join(descriptions) + + def get(self, tag): + try: + method = getattr(self, '_get_' + tag) + except AttributeError: + return getattr(self, tag, None) + else: + return method() + + def _get_target(self): + return { + PIPE_TEXTURE_1D: "1d", + PIPE_TEXTURE_2D: "2d", + PIPE_TEXTURE_3D: "3d", + PIPE_TEXTURE_CUBE: "cube", + }[self.target] + + def _get_format(self): + name = formats[self.format] + if name.startswith('PIPE_FORMAT_'): + name = name[12:] + name = name.lower() + return name + + def _get_face(self): + if self.target == PIPE_TEXTURE_CUBE: + return { + 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: + return '' + def test(self): raise NotImplementedError @@ -167,27 +231,106 @@ class TestResult: self.passed = 0 self.skipped = 0 self.failed = 0 - self.failed_descriptions = [] + + self.names = ['result'] + self.types = ['pass skip fail'] + self.rows = [] def test_start(self, test): + sys.stdout.write("Running %s...\n" % test.description()) + sys.stdout.flush() self.tests += 1 - print "Running %s..." % test.description() def test_passed(self, test): + sys.stdout.write("PASS\n") + sys.stdout.flush() self.passed += 1 - print "PASS" + self.log_result(test, 'pass') def test_skipped(self, test): + sys.stdout.write("SKIP\n") + sys.stdout.flush() self.skipped += 1 - print "SKIP" + #self.log_result(test, 'skip') def test_failed(self, test): + sys.stdout.write("FAIL\n") + sys.stdout.flush() self.failed += 1 - self.failed_descriptions.append(test.description()) - print "FAIL" + self.log_result(test, 'fail') + + def log_result(self, test, result): + row = ['']*len(self.names) + + # add result + assert self.names[0] == 'result' + assert result in ('pass', 'skip', 'fail') + row[0] = result + + # add tags + for tag in test.tags: + value = test.get(tag) + + # infer type + if value is None: + continue + elif isinstance(value, (int, float)): + value = str(value) + type = 'c' # continous + elif isinstance(value, basestring): + type = 'd' # discrete + else: + assert False + value = str(value) + type = 'd' # discrete + + # insert value + try: + col = self.names.index(tag, 1) + except ValueError: + self.names.append(tag) + self.types.append(type) + row.append(value) + else: + row[col] = value + assert self.types[col] == type + + self.rows.append(row) 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 + sys.stdout.write("%u tests, %u passed, %u skipped, %u failed\n\n" % (self.tests, self.passed, self.skipped, self.failed)) + sys.stdout.flush() + + name, ext = os.path.splitext(os.path.basename(sys.argv[0])) + filename = name + '.tsv' + stream = file(filename, 'wt') + + # header + stream.write('\t'.join(self.names) + '\n') + stream.write('\t'.join(self.types) + '\n') + stream.write('class\n') + + # rows + for row in self.rows: + row += ['']*(len(self.names) - len(row)) + stream.write('\t'.join(row) + '\n') + + stream.close() + + # See http://www.ailab.si/orange/doc/ofb/c_otherclass.htm + try: + import orange + import orngTree + except ImportError: + sys.stderr.write('Install Orange from http://www.ailab.si/orange/ for a classification tree.\n') + return + + data = orange.ExampleTable(filename) + + tree = orngTree.TreeLearner(data, sameMajorityPruning=1, mForPruning=2) + + orngTree.printTxt(tree, maxDepth=4) + + file(name+'.txt', 'wt').write(orngTree.dumpTree(tree)) + + orngTree.printDot(tree, fileName=name+'.dot', nodeShape='ellipse', leafShape='box') diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-abs.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-abs.sh new file mode 100644 index 00000000000..7a0006bf660 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-abs.sh @@ -0,0 +1,13 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +DCL TEMP[0] + +IMM FLT32 { -0.5, -0.4, -0.6, 0.0 } + +ADD TEMP[0], IN[0], IMM[0] +ABS OUT[0], TEMP[0] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-add.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-add.sh new file mode 100644 index 00000000000..f7836c85ddb --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-add.sh @@ -0,0 +1,8 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +ADD OUT[0], IN[0], IN[0] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp3.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp3.sh new file mode 100644 index 00000000000..c89cd748a80 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp3.sh @@ -0,0 +1,8 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +DP3 OUT[0], IN[0], IN[0] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp4.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp4.sh new file mode 100644 index 00000000000..6517e3c4945 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp4.sh @@ -0,0 +1,8 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +DP4 OUT[0], IN[0].xyzx, IN[0].xyzx + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dst.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dst.sh new file mode 100644 index 00000000000..464880ba68f --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dst.sh @@ -0,0 +1,8 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +DST OUT[0], IN[0], IN[0] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-ex2.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-ex2.sh new file mode 100644 index 00000000000..2684076f1d6 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-ex2.sh @@ -0,0 +1,11 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +DCL TEMP[0] + +EX2 TEMP[0], IN[0].xxxx +MUL OUT[0], TEMP[0], IN[0] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-flr.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-flr.sh new file mode 100644 index 00000000000..ad11e28918a --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-flr.sh @@ -0,0 +1,15 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +DCL TEMP[0] + +IMM FLT32 { 2.5, 4.0, 2.0, 1.0 } +IMM FLT32 { 0.4, 0.25, 0.5, 1.0 } + +MUL TEMP[0], IN[0], IMM[0] +FLR TEMP[0], TEMP[0] +MUL OUT[0], TEMP[0], IMM[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-frc.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-frc.sh new file mode 100644 index 00000000000..4f3aa30d666 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-frc.sh @@ -0,0 +1,13 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +DCL TEMP[0] + +IMM FLT32 { 2.7, 3.1, 4.5, 1.0 } + +MUL TEMP[0], IN[0], IMM[0] +FRC OUT[0], TEMP[0] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lg2.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lg2.sh new file mode 100644 index 00000000000..54c7c644598 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lg2.sh @@ -0,0 +1,15 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +DCL TEMP[0] + +IMM FLT32 { 1.0, 0.0, 0.0, 0.0 } +IMM FLT32 { 0.5, 0.0, 0.0, 0.0 } + +ADD TEMP[0], IN[0], IMM[0] +LG2 TEMP[0].x, TEMP[0].xxxx +ADD OUT[0], TEMP[0], IMM[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lit.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lit.sh new file mode 100644 index 00000000000..0e78ef86b54 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lit.sh @@ -0,0 +1,8 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +LIT OUT[0], IN[0] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lrp.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lrp.sh new file mode 100644 index 00000000000..e9ee0f81478 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lrp.sh @@ -0,0 +1,11 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +DCL TEMP[0] + +ABS TEMP[0], IN[0] +LRP OUT[0], TEMP[0], IN[0].xxxx, IN[0].yyyy + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mad.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mad.sh new file mode 100644 index 00000000000..439acd5bbde --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mad.sh @@ -0,0 +1,11 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +IMM FLT32 { 0.5, 0.4, 0.6, 1.0 } +IMM FLT32 { 0.5, 0.4, 0.6, 0.0 } + +MAD OUT[0], IN[0], IMM[0], IMM[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-max.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-max.sh new file mode 100644 index 00000000000..ab21b245dd8 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-max.sh @@ -0,0 +1,10 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +IMM FLT32 { 0.4, 0.4, 0.4, 0.0 } + +MAX OUT[0], IN[0], IMM[0] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-min.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-min.sh new file mode 100644 index 00000000000..969ae73d98e --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-min.sh @@ -0,0 +1,10 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +IMM FLT32 { 0.6, 0.6, 0.6, 1.0 } + +MIN OUT[0], IN[0], IMM[0] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mov.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mov.sh new file mode 100644 index 00000000000..612975e0570 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mov.sh @@ -0,0 +1,8 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +MOV OUT[0], IN[0] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mul.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mul.sh new file mode 100644 index 00000000000..ed158b0fc69 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mul.sh @@ -0,0 +1,10 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +IMM FLT32 { 0.5, 0.6, 0.7, 1.0 } + +MUL OUT[0], IN[0], IMM[0] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rcp.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rcp.sh new file mode 100644 index 00000000000..cc9feef07e1 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rcp.sh @@ -0,0 +1,15 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +DCL TEMP[0] + +IMM FLT32 { 1.0, 0.0, 0.0, 0.0 } +IMM FLT32 { 1.5, 0.0, 0.0, 0.0 } + +ADD TEMP[0], IN[0], IMM[0] +RCP TEMP[0].x, TEMP[0].xxxx +SUB OUT[0], TEMP[0], IMM[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rsq.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rsq.sh new file mode 100644 index 00000000000..695621fdc97 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rsq.sh @@ -0,0 +1,15 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +DCL TEMP[0] + +IMM FLT32 { 1.0, 0.0, 0.0, 0.0 } +IMM FLT32 { 1.5, 0.0, 0.0, 0.0 } + +ADD TEMP[0], IN[0], IMM[0] +RSQ TEMP[0].x, TEMP[0].xxxx +SUB OUT[0], TEMP[0], IMM[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sge.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sge.sh new file mode 100644 index 00000000000..9505bc3c3e3 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sge.sh @@ -0,0 +1,13 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +DCL TEMP[0] + +IMM FLT32 { 0.6, 0.6, 0.6, 0.0 } + +SGE TEMP[0], IN[0], IMM[0] +MUL OUT[0], IN[0], TEMP[0] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh new file mode 100644 index 00000000000..f2a1521cbf0 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh @@ -0,0 +1,13 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +DCL TEMP[0] + +IMM FLT32 { 0.6, 0.6, 0.6, 0.0 } + +SLT TEMP[0], IN[0], IMM[0] +MUL OUT[0], IN[0], TEMP[0] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-abs.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-abs.sh new file mode 100644 index 00000000000..9cd4b682955 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-abs.sh @@ -0,0 +1,13 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +DCL TEMP[0] + +IMM FLT32 { -0.3, -0.5, -0.4, 0.0 } + +ADD TEMP[0], IN[0], IMM[0] +MOV OUT[0], |TEMP[0]| + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-absneg.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-absneg.sh new file mode 100644 index 00000000000..acd6aa750dd --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-absneg.sh @@ -0,0 +1,15 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +DCL TEMP[0] + +IMM FLT32 { -0.2, -0.3, -0.4, 0.0 } +IMM FLT32 { -1.0, -1.0, -1.0, -1.0 } + +ADD TEMP[0], IN[0], IMM[0] +MOV TEMP[0], -|TEMP[0]| +MUL OUT[0], TEMP[0], IMM[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-neg.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-neg.sh new file mode 100644 index 00000000000..ba1b61503b8 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-neg.sh @@ -0,0 +1,11 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +DCL TEMP[0] + +SUB TEMP[0], IN[0], IN[0].yzxw +MOV OUT[0], -TEMP[0] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-swz.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-swz.sh new file mode 100644 index 00000000000..192aa7bb26b --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-swz.sh @@ -0,0 +1,8 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +MOV OUT[0], IN[0].yxzw + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sub.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sub.sh new file mode 100644 index 00000000000..83441fa8207 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sub.sh @@ -0,0 +1,8 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +SUB OUT[0], IN[0], IN[0].yzxw + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-xpd.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-xpd.sh new file mode 100644 index 00000000000..d6f66c4927a --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-xpd.sh @@ -0,0 +1,8 @@ +FRAG1.1 + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +XPD OUT[0], IN[0], IN[0].yzxw + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py b/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py new file mode 100644 index 00000000000..d60fb38d1ae --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py @@ -0,0 +1,218 @@ +#!/usr/bin/env python +########################################################################## +# +# Copyright 2009 VMware, Inc. +# All Rights Reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, 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 VMWARE 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. +# +########################################################################## + + +from gallium import * + +def make_image(surface): + data = surface.get_tile_rgba8(0, 0, surface.width, surface.height) + + import Image + outimage = Image.fromstring('RGBA', (surface.width, surface.height), data, "raw", 'RGBA', 0, 1) + return outimage + +def save_image(filename, surface): + outimage = make_image(surface) + outimage.save(filename, "PNG") + +def test(dev, name): + ctx = dev.context_create() + + width = 320 + height = 320 + minz = 0.0 + maxz = 1.0 + + # 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) + + # depth/stencil/alpha + depth_stencil_alpha = DepthStencilAlpha() + depth_stencil_alpha.depth.enabled = 0 + depth_stencil_alpha.depth.writemask = 1 + depth_stencil_alpha.depth.func = PIPE_FUNC_LESS + ctx.set_depth_stencil_alpha(depth_stencil_alpha) + + # rasterizer + rasterizer = Rasterizer() + rasterizer.front_winding = PIPE_WINDING_CW + rasterizer.cull_mode = PIPE_WINDING_NONE + rasterizer.scissor = 1 + ctx.set_rasterizer(rasterizer) + + # viewport + viewport = Viewport() + scale = FloatArray(4) + scale[0] = width / 2.0 + scale[1] = -height / 2.0 + scale[2] = (maxz - minz) / 2.0 + scale[3] = 1.0 + viewport.scale = scale + translate = FloatArray(4) + translate[0] = width / 2.0 + translate[1] = height / 2.0 + translate[2] = (maxz - minz) / 2.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_NONE + sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST + sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST + sampler.normalized_coords = 1 + ctx.set_sampler(0, sampler) + + # 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, + ).get_surface() + fb = Framebuffer() + fb.width = width + fb.height = height + fb.nr_cbufs = 1 + fb.set_cbuf(0, cbuf) + ctx.set_framebuffer(fb) + rgba = FloatArray(4); + rgba[0] = 0.5 + rgba[1] = 0.5 + rgba[2] = 0.5 + rgba[3] = 0.5 + ctx.clear(PIPE_CLEAR_COLOR, rgba, 0.0, 0) + + # vertex shader + vs = Shader(''' + VERT1.1 + DCL IN[0], POSITION + DCL IN[1], COLOR + DCL OUT[0], POSITION + DCL OUT[1], COLOR + MOV OUT[0], IN[0] + MOV OUT[1], IN[1] + END + ''') + ctx.set_vertex_shader(vs) + + # fragment shader + fs = Shader(file('frag-' + name + '.sh', 'rt').read()) + ctx.set_fragment_shader(fs) + + xy = [ + -0.8, -0.8, + 0.8, -0.8, + 0.0, 0.8, + ] + color = [ + 1.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0, + ] + + nverts = 3 + nattrs = 2 + verts = FloatArray(nverts * nattrs * 4) + + for i in range(0, nverts): + verts[i * nattrs * 4 + 0] = xy[i * 2 + 0] # x + verts[i * nattrs * 4 + 1] = xy[i * 2 + 1] # y + verts[i * nattrs * 4 + 2] = 0.5 # z + verts[i * nattrs * 4 + 3] = 1.0 # w + verts[i * nattrs * 4 + 4] = color[i * 3 + 0] # r + verts[i * nattrs * 4 + 5] = color[i * 3 + 1] # g + verts[i * nattrs * 4 + 6] = color[i * 3 + 2] # b + verts[i * nattrs * 4 + 7] = 1.0 # a + + ctx.draw_vertices(PIPE_PRIM_TRIANGLES, + nverts, + nattrs, + verts) + + ctx.flush() + + save_image('frag-' + name + '.png', cbuf) + +def main(): + tests = [ + 'abs', + 'add', + 'dp3', + 'dp4', + 'dst', + 'ex2', + 'flr', + 'frc', + 'lg2', + 'lit', + 'lrp', + 'mad', + 'max', + 'min', + 'mov', + 'mul', + 'rcp', + 'rsq', + 'sge', + 'slt', + 'srcmod-abs', + 'srcmod-absneg', + 'srcmod-neg', + 'srcmod-swz', + 'sub', + 'xpd', + ] + + dev = Device() + for t in tests: + test(dev, t) + +if __name__ == '__main__': + main() diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-abs.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-abs.sh new file mode 100644 index 00000000000..f0d0d5de171 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-abs.sh @@ -0,0 +1,15 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR +DCL TEMP[0] + +IMM FLT32 { 0.2, 0.2, 0.0, 0.0 } + +ADD TEMP[0], IN[0], IMM[0] +ABS OUT[0], TEMP[0] +MOV OUT[1], IN[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-add.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-add.sh new file mode 100644 index 00000000000..936c851c9dc --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-add.sh @@ -0,0 +1,13 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +IMM FLT32 { 0.2, -0.1, 0.0, 0.0 } + +ADD OUT[0], IN[0], IMM[0] +MOV OUT[1], IN[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arl.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arl.sh new file mode 100644 index 00000000000..7638e96346e --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arl.sh @@ -0,0 +1,23 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +DCL TEMP[0] + +DCL ADDR[0] + +IMM FLT32 { 3.0, 1.0, 1.0, 1.0 } +IMM FLT32 { 1.0, 0.0, 0.0, 1.0 } +IMM FLT32 { 0.0, 1.0, 0.0, 1.0 } +IMM FLT32 { 0.0, 0.0, 1.0, 1.0 } +IMM FLT32 { 1.0, 1.0, 0.0, 1.0 } +IMM FLT32 { 0.0, 1.0, 1.0, 1.0 } + +MOV OUT[0], IN[0] +MUL TEMP[0], IN[0], IMM[0] +ARL ADDR[0].x, TEMP[0] +MOV OUT[1], IMM[ADDR[0].x + 3] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arr.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arr.sh new file mode 100644 index 00000000000..28ce6f9a0cf --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arr.sh @@ -0,0 +1,23 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +DCL TEMP[0] + +DCL ADDR[0] + +IMM FLT32 { 3.0, 1.0, 1.0, 1.0 } +IMM FLT32 { 1.0, 0.0, 0.0, 1.0 } +IMM FLT32 { 0.0, 1.0, 0.0, 1.0 } +IMM FLT32 { 0.0, 0.0, 1.0, 1.0 } +IMM FLT32 { 1.0, 1.0, 0.0, 1.0 } +IMM FLT32 { 0.0, 1.0, 1.0, 1.0 } + +MOV OUT[0], IN[0] +MUL TEMP[0], IN[0], IMM[0] +ARR ADDR[0].x, TEMP[0] +MOV OUT[1], IMM[ADDR[0].x + 3] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp3.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp3.sh new file mode 100644 index 00000000000..b57d68520fc --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp3.sh @@ -0,0 +1,16 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR +DCL TEMP[0] + +IMM FLT32 { 0.0, 0.0, 1.0, 1.0 } + +DP3 TEMP[0].xy, IN[0], IN[0] +MOV TEMP[0].zw, IMM[0] +MUL OUT[0], IN[0], TEMP[0] +MOV OUT[1], IN[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp4.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp4.sh new file mode 100644 index 00000000000..0eb31719c58 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp4.sh @@ -0,0 +1,16 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR +DCL TEMP[0] + +IMM FLT32 { 0.0, 0.0, 1.0, 1.0 } + +DP4 TEMP[0].xy, IN[0], IN[0] +MOV TEMP[0].zw, IMM[0] +MUL OUT[0], IN[0], TEMP[0] +MOV OUT[1], IN[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dst.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dst.sh new file mode 100644 index 00000000000..dc5e0eb92e5 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dst.sh @@ -0,0 +1,11 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +MOV OUT[0], IN[0] +DST OUT[1], IN[1], IN[0] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-ex2.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-ex2.sh new file mode 100644 index 00000000000..34057af4e66 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-ex2.sh @@ -0,0 +1,18 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +DCL TEMP[0..1] + +IMM FLT32 { 0.3, 0.3, 0.3, 1.0 } + +EX2 TEMP[0], IN[0] +EX2 TEMP[1], IN[1].yyyy +MUL TEMP[0], TEMP[0], IMM[0] +MOV OUT[0], IN[0] +MUL OUT[1], TEMP[0], TEMP[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-flr.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-flr.sh new file mode 100644 index 00000000000..44ad708119d --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-flr.sh @@ -0,0 +1,23 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +DCL TEMP[0] + +DCL ADDR[0] + +IMM FLT32 { 3.0, 1.0, 1.0, 1.0 } +IMM FLT32 { 1.0, 0.0, 0.0, 1.0 } +IMM FLT32 { 0.0, 1.0, 0.0, 1.0 } +IMM FLT32 { 0.0, 0.0, 1.0, 1.0 } +IMM FLT32 { 1.0, 1.0, 0.0, 1.0 } +IMM FLT32 { 0.0, 1.0, 1.0, 1.0 } + +MOV OUT[0], IN[0] +MUL TEMP[0], IN[0], IMM[0] +FLR ADDR[0].x, TEMP[0] +MOV OUT[1], IMM[ADDR[0].x + 3] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-frc.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-frc.sh new file mode 100644 index 00000000000..d179749de84 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-frc.sh @@ -0,0 +1,15 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +DCL TEMP[0] + +IMM FLT32 { 2.7, 3.1, 4.5, 1.0 } + +MUL TEMP[0], IN[0].xyxw, IMM[0] +MOV OUT[0], IN[0] +FRC OUT[1], TEMP[0] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lg2.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lg2.sh new file mode 100644 index 00000000000..f6e08d087c1 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lg2.sh @@ -0,0 +1,18 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +DCL TEMP[0] + +IMM FLT32 { 1.0, 0.0, 0.0, 0.0 } +IMM FLT32 { 0.5, 0.0, 0.0, 0.0 } + +ADD TEMP[0], IN[0], IMM[0] +LG2 TEMP[0].x, TEMP[0].xxxx +ADD OUT[0], TEMP[0], IMM[1] +MOV OUT[1], IN[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lit.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lit.sh new file mode 100644 index 00000000000..da98f30928e --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lit.sh @@ -0,0 +1,11 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +MOV OUT[0], IN[0] +LIT OUT[1], IN[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lrp.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lrp.sh new file mode 100644 index 00000000000..8c262580e23 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lrp.sh @@ -0,0 +1,14 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +DCL TEMP[0] + +ABS TEMP[0], IN[0] +MOV OUT[0], IN[0] +LRP OUT[1], TEMP[0], IN[1].xxxx, IN[1].yyyy + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mad.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mad.sh new file mode 100644 index 00000000000..eb07a3bd565 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mad.sh @@ -0,0 +1,14 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +IMM FLT32 { 0.5, 1.0, 1.0, 1.0 } +IMM FLT32 { 0.5, 0.0, 0.0, 0.0 } + +MAD OUT[0], IN[0], IMM[0], IMM[1] +MOV OUT[1], IN[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-max.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-max.sh new file mode 100644 index 00000000000..2d8b1fe3bfb --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-max.sh @@ -0,0 +1,13 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +IMM FLT32 { 0.5, 0.5, 0.5, 0.0 } + +MOV OUT[0], IN[0] +MAX OUT[1], IN[1], IMM[0] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-min.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-min.sh new file mode 100644 index 00000000000..84af0e29051 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-min.sh @@ -0,0 +1,13 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +IMM FLT32 { 0.5, 0.5, 0.5, 0.0 } + +MOV OUT[0], IN[0] +MIN OUT[1], IN[1], IMM[0] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mov.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mov.sh new file mode 100644 index 00000000000..bcdec07c204 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mov.sh @@ -0,0 +1,11 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +MOV OUT[0], IN[0] +MOV OUT[1], IN[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mul.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mul.sh new file mode 100644 index 00000000000..f3b57c30382 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mul.sh @@ -0,0 +1,13 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +IMM FLT32 { 0.6, 0.6, 1.0, 1.0 } + +MUL OUT[0], IN[0], IMM[0] +MOV OUT[1], IN[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rcp.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rcp.sh new file mode 100644 index 00000000000..78af589b5c0 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rcp.sh @@ -0,0 +1,18 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +DCL TEMP[0] + +IMM FLT32 { 1.0, 0.0, 0.0, 0.0 } +IMM FLT32 { 1.5, 0.0, 0.0, 0.0 } + +ADD TEMP[0], IN[0], IMM[0] +RCP TEMP[0].x, TEMP[0].xxxx +SUB OUT[0], TEMP[0], IMM[1] +MOV OUT[1], IN[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rsq.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rsq.sh new file mode 100644 index 00000000000..1675c7d5ff1 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rsq.sh @@ -0,0 +1,18 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +DCL TEMP[0] + +IMM FLT32 { 1.0, 0.0, 0.0, 0.0 } +IMM FLT32 { 1.5, 0.0, 0.0, 0.0 } + +ADD TEMP[0], IN[0], IMM[0] +RSQ TEMP[0].x, TEMP[0].xxxx +SUB OUT[0], TEMP[0], IMM[1] +MOV OUT[1], IN[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sge.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sge.sh new file mode 100644 index 00000000000..3d92cd5aaeb --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sge.sh @@ -0,0 +1,16 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +DCL TEMP[0] + +IMM FLT32 { -0.1, -0.1, 1.0, 0.0 } + +SGE TEMP[0], IN[0], IMM[0] +MOV OUT[0], IN[0] +MUL OUT[1], IN[1], TEMP[0] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-slt.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-slt.sh new file mode 100644 index 00000000000..85c60ff4ec8 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-slt.sh @@ -0,0 +1,16 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +DCL TEMP[0] + +IMM FLT32 { 0.6, 0.6, 0.0, 0.0 } + +SLT TEMP[0], IN[0], IMM[0] +MOV OUT[0], IN[0] +MUL OUT[1], IN[1], TEMP[0] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-abs.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-abs.sh new file mode 100644 index 00000000000..6db417a62e5 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-abs.sh @@ -0,0 +1,15 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR +DCL TEMP[0] + +IMM FLT32 { 0.1, 0.1, 0.0, 0.0 } + +ADD TEMP[0], IN[0], IMM[0] +MOV OUT[0], |TEMP[0]| +MOV OUT[1], IN[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-absneg.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-absneg.sh new file mode 100644 index 00000000000..fc832380520 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-absneg.sh @@ -0,0 +1,16 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR +DCL TEMP[0] + +IMM FLT32 { -0.2, -0.2, 0.0, 0.0 } + +ADD TEMP[0], IN[0], IMM[0] +MOV OUT[0].xy, -|TEMP[0]| +MOV OUT[0].zw, IN[0] +MOV OUT[1], IN[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-neg.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-neg.sh new file mode 100644 index 00000000000..ce4e90b5e10 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-neg.sh @@ -0,0 +1,12 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +MOV OUT[0].xy, -IN[0] +MOV OUT[0].zw, IN[0] +MOV OUT[1], IN[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-swz.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-swz.sh new file mode 100644 index 00000000000..c03de4c674e --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-swz.sh @@ -0,0 +1,11 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +MOV OUT[0], IN[0].yxzw +MOV OUT[1], IN[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sub.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sub.sh new file mode 100644 index 00000000000..a583b958284 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sub.sh @@ -0,0 +1,13 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +IMM FLT32 { 0.1, 0.1, 0.0, 0.0 } + +SUB OUT[0], IN[0], IMM[0] +MOV OUT[1], IN[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-xpd.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-xpd.sh new file mode 100644 index 00000000000..8def8943b03 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-xpd.sh @@ -0,0 +1,11 @@ +VERT1.1 + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR + +MOV OUT[0], IN[0] +XPD OUT[1], IN[0], IN[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py new file mode 100644 index 00000000000..472769f2592 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py @@ -0,0 +1,247 @@ +#!/usr/bin/env python +########################################################################## +# +# Copyright 2009 VMware, Inc. +# All Rights Reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, 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 VMWARE 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. +# +########################################################################## + + +from gallium import * + +def make_image(surface): + data = surface.get_tile_rgba8(0, 0, surface.width, surface.height) + + import Image + outimage = Image.fromstring('RGBA', (surface.width, surface.height), data, "raw", 'RGBA', 0, 1) + return outimage + +def save_image(filename, surface): + outimage = make_image(surface) + outimage.save(filename, "PNG") + +def test(dev, name): + ctx = dev.context_create() + + width = 320 + height = 320 + minz = 0.0 + maxz = 1.0 + + # 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) + + # depth/stencil/alpha + depth_stencil_alpha = DepthStencilAlpha() + depth_stencil_alpha.depth.enabled = 0 + depth_stencil_alpha.depth.writemask = 1 + depth_stencil_alpha.depth.func = PIPE_FUNC_LESS + ctx.set_depth_stencil_alpha(depth_stencil_alpha) + + # rasterizer + rasterizer = Rasterizer() + rasterizer.front_winding = PIPE_WINDING_CW + rasterizer.cull_mode = PIPE_WINDING_NONE + rasterizer.scissor = 1 + ctx.set_rasterizer(rasterizer) + + # viewport + viewport = Viewport() + scale = FloatArray(4) + scale[0] = width / 2.0 + scale[1] = -height / 2.0 + scale[2] = (maxz - minz) / 2.0 + scale[3] = 1.0 + viewport.scale = scale + translate = FloatArray(4) + translate[0] = width / 2.0 + translate[1] = height / 2.0 + translate[2] = (maxz - minz) / 2.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_NONE + sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST + sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST + sampler.normalized_coords = 1 + ctx.set_sampler(0, sampler) + + # 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, + ).get_surface() + fb = Framebuffer() + fb.width = width + fb.height = height + fb.nr_cbufs = 1 + fb.set_cbuf(0, cbuf) + ctx.set_framebuffer(fb) + rgba = FloatArray(4); + rgba[0] = 0.5 + rgba[1] = 0.5 + rgba[2] = 0.5 + rgba[3] = 0.5 + ctx.clear(PIPE_CLEAR_COLOR, rgba, 0.0, 0) + + # vertex shader + vs = Shader(file('vert-' + name + '.sh', 'rt').read()) + ctx.set_vertex_shader(vs) + + # fragment shader + fs = Shader(''' + FRAG1.1 + DCL IN[0], COLOR, LINEAR + DCL OUT[0], COLOR, CONSTANT + 0:MOV OUT[0], IN[0] + 1:END + ''') + ctx.set_fragment_shader(fs) + + xy = [ + 0.0, 0.8, + -0.2, 0.4, + 0.2, 0.4, + -0.4, 0.0, + 0.0, 0.0, + 0.4, 0.0, + -0.6, -0.4, + -0.2, -0.4, + 0.2, -0.4, + 0.6, -0.4, + -0.8, -0.8, + -0.4, -0.8, + 0.0, -0.8, + 0.4, -0.8, + 0.8, -0.8, + ] + color = [ + 1.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0, + ] + tri = [ + 1, 2, 0, + 3, 4, 1, + 4, 2, 1, + 4, 5, 2, + 6, 7, 3, + 7, 4, 3, + 7, 8, 4, + 8, 5, 4, + 8, 9, 5, + 10, 11, 6, + 11, 7, 6, + 11, 12, 7, + 12, 8, 7, + 12, 13, 8, + 13, 9, 8, + 13, 14, 9, + ] + + nverts = 16 * 3 + nattrs = 2 + verts = FloatArray(nverts * nattrs * 4) + + for i in range(0, nverts): + verts[i * nattrs * 4 + 0] = xy[tri[i] * 2 + 0] # x + verts[i * nattrs * 4 + 1] = xy[tri[i] * 2 + 1] # y + verts[i * nattrs * 4 + 2] = 0.5 # z + verts[i * nattrs * 4 + 3] = 1.0 # w + verts[i * nattrs * 4 + 4] = color[(i % 3) * 3 + 0] # r + verts[i * nattrs * 4 + 5] = color[(i % 3) * 3 + 1] # g + verts[i * nattrs * 4 + 6] = color[(i % 3) * 3 + 2] # b + verts[i * nattrs * 4 + 7] = 1.0 # a + + ctx.draw_vertices(PIPE_PRIM_TRIANGLES, + nverts, + nattrs, + verts) + + ctx.flush() + + save_image('vert-' + name + '.png', cbuf) + +def main(): + tests = [ + 'abs', + 'add', + 'arl', + 'arr', + 'dp3', + 'dp4', + 'dst', + 'ex2', + 'flr', + 'frc', + 'lg2', + 'lit', + 'lrp', + 'mad', + 'max', + 'min', + 'mov', + 'mul', + 'rcp', + 'rsq', + 'sge', + 'slt', + 'srcmod-abs', + 'srcmod-absneg', + 'srcmod-neg', + 'srcmod-swz', + 'sub', + 'xpd', + ] + + dev = Device() + for t in tests: + test(dev, t) + +if __name__ == '__main__': + main() diff --git a/src/gallium/state_trackers/python/tests/surface_copy.py b/src/gallium/state_trackers/python/tests/surface_copy.py new file mode 100755 index 00000000000..3ceecbbd3aa --- /dev/null +++ b/src/gallium/state_trackers/python/tests/surface_copy.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python +########################################################################## +# +# Copyright 2009 VMware, Inc. +# All Rights Reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, 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 VMWARE 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. +# +########################################################################## + + +from gallium import * +from base import * + + +def lods(*dims): + size = max(dims) + lods = 0 + while size: + lods += 1 + size >>= 1 + return lods + + +class TextureTest(TestCase): + + tags = ( + 'target', + 'format', + 'width', + 'height', + 'depth', + 'last_level', + 'face', + 'level', + '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 + + # textures + dst_texture = dev.texture_create( + target = target, + format = format, + width = width, + height = height, + depth = depth, + last_level = last_level, + tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET, + ) + if dst_texture is None: + raise TestSkip + + dst_surface = dst_texture.get_surface(face = face, level = level, zslice = zslice) + + src_texture = dev.texture_create( + target = target, + format = format, + width = dst_surface.width, + height = dst_surface.height, + depth = 1, + last_level = 0, + tex_usage = PIPE_TEXTURE_USAGE_SAMPLER, + ) + + src_surface = src_texture.get_surface() + + x = 0 + y = 0 + w = dst_surface.width + h = dst_surface.height + + stride = dst_surface.nblocksx * dst_texture.block.size + size = dst_surface.nblocksy * stride + src_raw = os.urandom(size) + + src_surface.put_tile_raw(0, 0, w, h, src_raw, stride) + + ctx = self.dev.context_create() + + ctx.surface_copy(dst_surface, 0, 0, + src_surface, 0, 0, w, h) + + ctx.flush() + + dst_raw = dst_surface.get_tile_raw(0, 0, w, h) + + if dst_raw != src_raw: + raise TestFailure + + + +def main(): + dev = Device() + suite = TestSuite() + + targets = [ + PIPE_TEXTURE_2D, + PIPE_TEXTURE_CUBE, + #PIPE_TEXTURE_3D, + ] + + formats = [ + PIPE_FORMAT_A8R8G8B8_UNORM, + PIPE_FORMAT_X8R8G8B8_UNORM, + PIPE_FORMAT_A8R8G8B8_SRGB, + PIPE_FORMAT_R5G6B5_UNORM, + PIPE_FORMAT_A1R5G5B5_UNORM, + PIPE_FORMAT_A4R4G4B4_UNORM, + PIPE_FORMAT_Z32_UNORM, + PIPE_FORMAT_Z24S8_UNORM, + PIPE_FORMAT_Z24X8_UNORM, + PIPE_FORMAT_Z16_UNORM, + PIPE_FORMAT_S8_UNORM, + PIPE_FORMAT_A8_UNORM, + PIPE_FORMAT_L8_UNORM, + PIPE_FORMAT_DXT1_RGB, + PIPE_FORMAT_DXT1_RGBA, + PIPE_FORMAT_DXT3_RGBA, + PIPE_FORMAT_DXT5_RGBA, + ] + + sizes = [64, 32, 16, 8, 4, 2, 1] + #sizes = [1020, 508, 252, 62, 30, 14, 6, 3] + #sizes = [64] + #sizes = [63] + + 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, + ] + + for target in targets: + for format in formats: + for size in sizes: + if target == PIPE_TEXTURE_3D: + depth = size + else: + depth = 1 + for face in faces: + if target != PIPE_TEXTURE_CUBE and face: + continue + 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() diff --git a/src/gallium/state_trackers/python/tests/texture_render.py b/src/gallium/state_trackers/python/tests/texture_render.py new file mode 100755 index 00000000000..0b76932b6ed --- /dev/null +++ b/src/gallium/state_trackers/python/tests/texture_render.py @@ -0,0 +1,320 @@ +#!/usr/bin/env python +########################################################################## +# +# Copyright 2009 VMware, Inc. +# All Rights Reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, 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 VMWARE 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. +# +########################################################################## + + +from gallium import * +from base import * + + +def lods(*dims): + size = max(dims) + lods = 0 + while size: + lods += 1 + size >>= 1 + return lods + + +class TextureTest(TestCase): + + tags = ( + 'target', + 'format', + 'width', + 'height', + 'depth', + 'last_level', + 'face', + 'level', + '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 + + # textures + dst_texture = dev.texture_create( + target = target, + format = format, + width = width, + height = height, + depth = depth, + last_level = last_level, + tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET, + ) + if dst_texture is None: + raise TestSkip + + dst_surface = dst_texture.get_surface(face = face, level = level, zslice = zslice) + + ref_texture = dev.texture_create( + target = target, + format = format, + width = dst_surface.width, + height = dst_surface.height, + depth = 1, + last_level = 0, + tex_usage = PIPE_TEXTURE_USAGE_SAMPLER, + ) + + ref_surface = ref_texture.get_surface() + + src_texture = dev.texture_create( + target = target, + format = PIPE_FORMAT_A8R8G8B8_UNORM, + width = dst_surface.width, + height = dst_surface.height, + depth = 1, + last_level = 0, + tex_usage = PIPE_TEXTURE_USAGE_SAMPLER, + ) + + src_surface = src_texture.get_surface() + + expected_rgba = FloatArray(height*width*4) + ref_surface.sample_rgba(expected_rgba) + + src_surface.put_tile_rgba(0, 0, src_surface.width, src_surface.height, expected_rgba) + + 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_vs_clip_and_viewport = 1 + ctx.set_rasterizer(rasterizer) + + # 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) + ctx.set_sampler_texture(0, src_texture) + + # framebuffer + cbuf_tex = dev.texture_create( + PIPE_FORMAT_A8R8G8B8_UNORM, + width, + height, + tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET, + ) + + fb = Framebuffer() + fb.width = dst_surface.width + fb.height = dst_surface.height + fb.nr_cbufs = 1 + fb.set_cbuf(0, dst_surface) + ctx.set_framebuffer(fb) + rgba = FloatArray(4); + rgba[0] = 0.0 + rgba[1] = 0.0 + rgba[2] = 0.0 + rgba[3] = 0.0 + ctx.clear(PIPE_CLEAR_COLOR, rgba, 0.0, 0) + 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 + 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], 2D + 1:END + ''') + #fs.dump() + ctx.set_fragment_shader(fs) + + nverts = 4 + nattrs = 2 + verts = FloatArray(nverts * nattrs * 4) + + x = 0 + y = 0 + w = dst_surface.width + h = dst_surface.height + + pos = [ + [x, y], + [x+w, y], + [x+w, y+h], + [x, y+h], + ] + + tex = [ + [0.0, 0.0], + [1.0, 0.0], + [1.0, 1.0], + [0.0, 1.0], + ] + + 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] = 0.0 + verts[j + 7] = 1.0 + + ctx.draw_vertices(PIPE_PRIM_TRIANGLE_FAN, + nverts, + nattrs, + verts) + + ctx.flush() + + self.assert_rgba(dst_surface, x, y, w, h, expected_rgba, 4.0/256, 0.85) + + + +def main(): + dev = Device() + suite = TestSuite() + + targets = [ + PIPE_TEXTURE_2D, + PIPE_TEXTURE_CUBE, + #PIPE_TEXTURE_3D, + ] + + formats = [ + PIPE_FORMAT_A8R8G8B8_UNORM, + PIPE_FORMAT_X8R8G8B8_UNORM, + #PIPE_FORMAT_A8R8G8B8_SRGB, + PIPE_FORMAT_R5G6B5_UNORM, + PIPE_FORMAT_A1R5G5B5_UNORM, + PIPE_FORMAT_A4R4G4B4_UNORM, + #PIPE_FORMAT_Z32_UNORM, + #PIPE_FORMAT_Z24S8_UNORM, + #PIPE_FORMAT_Z24X8_UNORM, + #PIPE_FORMAT_Z16_UNORM, + #PIPE_FORMAT_S8_UNORM, + PIPE_FORMAT_A8_UNORM, + PIPE_FORMAT_L8_UNORM, + #PIPE_FORMAT_DXT1_RGB, + #PIPE_FORMAT_DXT1_RGBA, + #PIPE_FORMAT_DXT3_RGBA, + #PIPE_FORMAT_DXT5_RGBA, + ] + + sizes = [64, 32, 16, 8, 4, 2, 1] + #sizes = [1020, 508, 252, 62, 30, 14, 6, 3] + #sizes = [64] + #sizes = [63] + + 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, + ] + + for target in targets: + for format in formats: + for size in sizes: + if target == PIPE_TEXTURE_3D: + depth = size + else: + depth = 1 + for face in faces: + if target != PIPE_TEXTURE_CUBE and face: + continue + 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() diff --git a/src/gallium/state_trackers/python/tests/texture.py b/src/gallium/state_trackers/python/tests/texture_sample.py index 880a61306c9..a382424667c 100644..100755 --- a/src/gallium/state_trackers/python/tests/texture.py +++ b/src/gallium/state_trackers/python/tests/texture_sample.py @@ -1,6 +1,7 @@ #!/usr/bin/env python ########################################################################## # +# Copyright 2009 VMware, Inc. # Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. # All Rights Reserved. # @@ -19,7 +20,7 @@ # 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 +# IN NO EVENT SHALL VMWARE 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. @@ -27,7 +28,6 @@ ########################################################################## -import sys from gallium import * from base import * @@ -101,31 +101,18 @@ def is_pot(n): 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, - ) - + tags = ( + 'target', + 'format', + 'width', + 'height', + 'depth', + 'last_level', + 'face', + 'level', + 'zslice', + ) + def test(self): dev = self.dev @@ -168,26 +155,9 @@ class TextureTest(TestCase): rasterizer = Rasterizer() rasterizer.front_winding = PIPE_WINDING_CW rasterizer.cull_mode = PIPE_WINDING_NONE - rasterizer.bypass_clipping = 1 - #rasterizer.bypass_vs = 1 + rasterizer.bypass_vs_clip_and_viewport = 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 @@ -214,7 +184,6 @@ class TextureTest(TestCase): 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, @@ -230,14 +199,19 @@ class TextureTest(TestCase): tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET, ) - cbuf = cbuf_tex.get_surface(usage = PIPE_BUFFER_USAGE_GPU_WRITE|PIPE_BUFFER_USAGE_GPU_READ) + cbuf = cbuf_tex.get_surface() fb = Framebuffer() fb.width = width fb.height = height - fb.num_cbufs = 1 + fb.nr_cbufs = 1 fb.set_cbuf(0, cbuf) ctx.set_framebuffer(fb) - ctx.surface_clear(cbuf, 0x00000000) + rgba = FloatArray(4); + rgba[0] = 0.5 + rgba[1] = 0.5 + rgba[2] = 0.5 + rgba[3] = 0.5 + ctx.clear(PIPE_CLEAR_COLOR, rgba, 0.0, 0) del fb # vertex shader @@ -307,26 +281,9 @@ class TextureTest(TestCase): ctx.flush() - cbuf = cbuf_tex.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ) + cbuf = cbuf_tex.get_surface() - 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 + self.assert_rgba(cbuf, x, y, w, h, expected_rgba, 4.0/256, 0.85) @@ -334,43 +291,57 @@ def main(): dev = Device() suite = TestSuite() - targets = [] - targets += [PIPE_TEXTURE_2D] - targets += [PIPE_TEXTURE_CUBE] - targets += [PIPE_TEXTURE_3D] + targets = [ + PIPE_TEXTURE_2D, + PIPE_TEXTURE_CUBE, + 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] + formats = [ + PIPE_FORMAT_A8R8G8B8_UNORM, + PIPE_FORMAT_X8R8G8B8_UNORM, + #PIPE_FORMAT_A8R8G8B8_SRGB, + PIPE_FORMAT_R5G6B5_UNORM, + PIPE_FORMAT_A1R5G5B5_UNORM, + PIPE_FORMAT_A4R4G4B4_UNORM, + #PIPE_FORMAT_Z32_UNORM, + #PIPE_FORMAT_Z24S8_UNORM, + #PIPE_FORMAT_Z24X8_UNORM, + #PIPE_FORMAT_Z16_UNORM, + #PIPE_FORMAT_S8_UNORM, + PIPE_FORMAT_A8_UNORM, + PIPE_FORMAT_L8_UNORM, + PIPE_FORMAT_YCBCR, + PIPE_FORMAT_DXT1_RGB, + #PIPE_FORMAT_DXT1_RGBA, + #PIPE_FORMAT_DXT3_RGBA, + #PIPE_FORMAT_DXT5_RGBA, + ] sizes = [64, 32, 16, 8, 4, 2, 1] #sizes = [1020, 508, 252, 62, 30, 14, 6, 3] #sizes = [64] #sizes = [63] + 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, + ] + 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: + if target != PIPE_TEXTURE_CUBE and face: + continue levels = lods(size) for last_level in range(levels): for level in range(0, last_level + 1): diff --git a/src/gallium/state_trackers/python/tests/texture_transfer.py b/src/gallium/state_trackers/python/tests/texture_transfer.py new file mode 100755 index 00000000000..e65b425adf4 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/texture_transfer.py @@ -0,0 +1,179 @@ +#!/usr/bin/env python +########################################################################## +# +# Copyright 2009 VMware, Inc. +# 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 VMWARE 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 os + +from gallium import * +from base import * + + +def lods(*dims): + size = max(dims) + lods = 0 + while size: + lods += 1 + size >>= 1 + return lods + + +class TextureTest(TestCase): + + tags = ( + 'target', + 'format', + 'width', + 'height', + 'depth', + 'last_level', + 'face', + 'level', + '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 = 0 + + texture = dev.texture_create( + target = target, + format = format, + width = width, + height = height, + depth = depth, + last_level = last_level, + tex_usage = tex_usage, + ) + if texture is None: + raise TestSkip + + surface = texture.get_surface(face, level, zslice) + + stride = surface.nblocksx * texture.block.size + size = surface.nblocksy * stride + + in_raw = os.urandom(size) + + surface.put_tile_raw(0, 0, surface.width, surface.height, in_raw, stride) + + out_raw = surface.get_tile_raw(0, 0, surface.width, surface.height) + + if in_raw != out_raw: + raise TestFailure + + +def main(): + dev = Device() + suite = TestSuite() + + targets = [ + PIPE_TEXTURE_2D, + PIPE_TEXTURE_CUBE, + PIPE_TEXTURE_3D, + ] + + formats = [ + PIPE_FORMAT_A8R8G8B8_UNORM, + PIPE_FORMAT_X8R8G8B8_UNORM, + PIPE_FORMAT_A8R8G8B8_SRGB, + PIPE_FORMAT_R5G6B5_UNORM, + PIPE_FORMAT_A1R5G5B5_UNORM, + PIPE_FORMAT_A4R4G4B4_UNORM, + PIPE_FORMAT_Z32_UNORM, + PIPE_FORMAT_Z24S8_UNORM, + PIPE_FORMAT_Z24X8_UNORM, + PIPE_FORMAT_Z16_UNORM, + PIPE_FORMAT_S8_UNORM, + PIPE_FORMAT_A8_UNORM, + PIPE_FORMAT_L8_UNORM, + PIPE_FORMAT_DXT1_RGB, + PIPE_FORMAT_DXT1_RGBA, + PIPE_FORMAT_DXT3_RGBA, + PIPE_FORMAT_DXT5_RGBA, + ] + + sizes = [64, 32, 16, 8, 4, 2, 1] + #sizes = [1020, 508, 252, 62, 30, 14, 6, 3] + #sizes = [64] + #sizes = [63] + + 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, + ] + + for target in targets: + for format in formats: + for size in sizes: + if target == PIPE_TEXTURE_3D: + depth = size + else: + depth = 1 + for face in faces: + if target != PIPE_TEXTURE_CUBE and face: + continue + 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() diff --git a/src/gallium/state_trackers/python/tests/tree.py b/src/gallium/state_trackers/python/tests/tree.py new file mode 100755 index 00000000000..0c1bcda4cf2 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/tree.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +# +# See also: +# http://www.ailab.si/orange/doc/ofb/c_otherclass.htm + +import os.path +import sys + +import orange +import orngTree + +for arg in sys.argv[1:]: + name, ext = os.path.splitext(arg) + + data = orange.ExampleTable(arg) + + tree = orngTree.TreeLearner(data, sameMajorityPruning=1, mForPruning=2) + + orngTree.printTxt(tree) + + file(name+'.txt', 'wt').write(orngTree.dumpTree(tree) + '\n') + + orngTree.printDot(tree, fileName=name+'.dot', nodeShape='ellipse', leafShape='box') diff --git a/src/gallium/state_trackers/wgl/shared/stw_context.c b/src/gallium/state_trackers/wgl/shared/stw_context.c index 89df8b0a2a0..f890225242a 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_context.c +++ b/src/gallium/state_trackers/wgl/shared/stw_context.c @@ -33,6 +33,12 @@ #include "pipe/p_context.h" #include "state_tracker/st_context.h" #include "state_tracker/st_public.h" + +#ifdef DEBUG +#include "trace/tr_screen.h" +#include "trace/tr_context.h" +#endif + #include "shared/stw_device.h" #include "shared/stw_winsys.h" #include "shared/stw_framebuffer.h" @@ -77,6 +83,7 @@ stw_create_layer_context( const struct pixelformat_info *pf = NULL; struct stw_context *ctx = NULL; GLvisual *visual = NULL; + struct pipe_screen *screen = NULL; struct pipe_context *pipe = NULL; UINT_PTR hglrc = 0; @@ -120,10 +127,24 @@ stw_create_layer_context( if (visual == NULL) goto fail; - pipe = stw_dev->stw_winsys->create_context( stw_dev->screen ); + screen = stw_dev->screen; + +#ifdef DEBUG + /* Unwrap screen */ + if(stw_dev->trace_running) + screen = trace_screen(screen)->screen; +#endif + + pipe = stw_dev->stw_winsys->create_context( screen ); if (pipe == NULL) goto fail; +#ifdef DEBUG + /* Wrap context */ + if(stw_dev->trace_running) + pipe = trace_context_create(stw_dev->screen, pipe); +#endif + assert(!pipe->priv); pipe->priv = hdc; @@ -317,10 +338,6 @@ stw_make_current( fb = framebuffer_create( hdc, visual, width, height ); if (fb == NULL) return FALSE; - - fb->dib_hDC = CreateCompatibleDC( hdc ); - fb->hbmDIB = NULL; - fb->pbPixels = NULL; } if (ctx && fb) { diff --git a/src/gallium/state_trackers/wgl/shared/stw_device.c b/src/gallium/state_trackers/wgl/shared/stw_device.c index 3c1eb1ad393..51936c2bdd6 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_device.c +++ b/src/gallium/state_trackers/wgl/shared/stw_device.c @@ -31,6 +31,11 @@ #include "util/u_debug.h" #include "pipe/p_screen.h" +#ifdef DEBUG +#include "trace/tr_screen.h" +#include "trace/tr_texture.h" +#endif + #include "shared/stw_device.h" #include "shared/stw_winsys.h" #include "shared/stw_pixelformat.h" @@ -52,13 +57,20 @@ struct stw_device *stw_dev = NULL; */ static void st_flush_frontbuffer(struct pipe_screen *screen, - struct pipe_surface *surf, + struct pipe_surface *surface, void *context_private ) { const struct stw_winsys *stw_winsys = stw_dev->stw_winsys; HDC hdc = (HDC)context_private; - stw_winsys->flush_frontbuffer(screen, surf, hdc); +#ifdef DEBUG + if(stw_dev->trace_running) { + screen = trace_screen(screen)->screen; + surface = trace_surface(surface)->surface; + } +#endif + + stw_winsys->flush_frontbuffer(screen, surface, hdc); } @@ -66,6 +78,7 @@ boolean st_init(const struct stw_winsys *stw_winsys) { static struct stw_device stw_dev_storage; + struct pipe_screen *screen; debug_printf("%s\n", __FUNCTION__); @@ -86,10 +99,17 @@ st_init(const struct stw_winsys *stw_winsys) _glthread_INIT_MUTEX(OneTimeLock); #endif - stw_dev->screen = stw_winsys->create_screen(); - if(!stw_dev->screen) + screen = stw_winsys->create_screen(); + if(!screen) goto error1; +#ifdef DEBUG + stw_dev->screen = trace_screen_create(screen); + stw_dev->trace_running = stw_dev->screen != screen ? TRUE : FALSE; +#else + stw_dev->screen = screen; +#endif + stw_dev->screen->flush_frontbuffer = st_flush_frontbuffer; pipe_mutex_init( stw_dev->mutex ); @@ -130,7 +150,7 @@ st_cleanup_thread(void) void st_cleanup(void) { - UINT_PTR i; + unsigned i; debug_printf("%s\n", __FUNCTION__); diff --git a/src/gallium/state_trackers/wgl/shared/stw_device.h b/src/gallium/state_trackers/wgl/shared/stw_device.h index 6a9cee0d028..703cb670816 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_device.h +++ b/src/gallium/state_trackers/wgl/shared/stw_device.h @@ -39,8 +39,13 @@ struct pipe_screen; struct stw_device { const struct stw_winsys *stw_winsys; + struct pipe_screen *screen; +#ifdef DEBUG + boolean trace_running; +#endif + pipe_mutex mutex; struct handle_table *ctx_table; diff --git a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c index 17c96c411f7..c96c4b8dfa8 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c +++ b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c @@ -32,6 +32,12 @@ #include "pipe/p_screen.h" #include "state_tracker/st_context.h" #include "state_tracker/st_public.h" + +#ifdef DEBUG +#include "trace/tr_screen.h" +#include "trace/tr_texture.h" +#endif + #include "stw_framebuffer.h" #include "stw_device.h" #include "stw_public.h" @@ -44,16 +50,6 @@ framebuffer_resize( GLuint width, GLuint height ) { - if (fb->hbmDIB == NULL || fb->stfb->Base.Width != width || fb->stfb->Base.Height != height) { - if (fb->hbmDIB) - DeleteObject( fb->hbmDIB ); - - fb->hbmDIB = CreateCompatibleBitmap( - fb->hDC, - width, - height ); - } - st_resize_framebuffer( fb->stfb, width, height ); } @@ -80,6 +76,14 @@ window_proc( } static INLINE boolean +stw_is_supported_color(enum pipe_format format) +{ + struct pipe_screen *screen = stw_dev->screen; + return screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, + PIPE_TEXTURE_USAGE_RENDER_TARGET, 0); +} + +static INLINE boolean stw_is_supported_depth_stencil(enum pipe_format format) { struct pipe_screen *screen = stw_dev->screen; @@ -99,13 +103,33 @@ framebuffer_create( struct stw_framebuffer *fb; enum pipe_format colorFormat, depthFormat, stencilFormat; - fb = CALLOC_STRUCT( stw_framebuffer ); - if (fb == NULL) - return NULL; - /* Determine PIPE_FORMATs for buffers. */ - colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; + + if(visual->alphaBits <= 0 && visual->redBits <= 5 && visual->blueBits <= 6 && visual->greenBits <= 5 && + stw_is_supported_color(PIPE_FORMAT_R5G6B5_UNORM)) { + colorFormat = PIPE_FORMAT_R5G6B5_UNORM; + } + else if(visual->alphaBits <= 0 && visual->redBits <= 8 && visual->blueBits <= 8 && visual->greenBits <= 8 && + stw_is_supported_color(PIPE_FORMAT_X8R8G8B8_UNORM)) { + colorFormat = PIPE_FORMAT_X8R8G8B8_UNORM; + } + else if(visual->alphaBits <= 1 && visual->redBits <= 5 && visual->blueBits <= 5 && visual->greenBits <= 5 && + stw_is_supported_color(PIPE_FORMAT_A1R5G5B5_UNORM)) { + colorFormat = PIPE_FORMAT_A1R5G5B5_UNORM; + } + else if(visual->alphaBits <= 4 && visual->redBits <= 4 && visual->blueBits <= 4 && visual->greenBits <= 4 && + stw_is_supported_color(PIPE_FORMAT_A4R4G4B4_UNORM)) { + colorFormat = PIPE_FORMAT_A4R4G4B4_UNORM; + } + else if(visual->alphaBits <= 8 && visual->redBits <= 8 && visual->blueBits <= 8 && visual->greenBits <= 8 && + stw_is_supported_color(PIPE_FORMAT_A8R8G8B8_UNORM)) { + colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; + } + else { + assert(0); + return NULL; + } if (visual->depthBits == 0) depthFormat = PIPE_FORMAT_NONE; @@ -151,6 +175,10 @@ framebuffer_create( stencilFormat = PIPE_FORMAT_NONE; } + fb = CALLOC_STRUCT( stw_framebuffer ); + if (fb == NULL) + return NULL; + fb->stfb = st_create_framebuffer( visual, colorFormat, @@ -167,10 +195,10 @@ framebuffer_create( */ fb->hWnd = WindowFromDC( hdc ); if (fb->hWnd != NULL) { - fb->WndProc = (WNDPROC) SetWindowLong( + fb->WndProc = (WNDPROC) SetWindowLongPtr( fb->hWnd, - GWL_WNDPROC, - (LONG) window_proc ); + GWLP_WNDPROC, + (LONG_PTR) window_proc ); } fb->next = fb_head; @@ -188,10 +216,10 @@ framebuffer_destroy( while (pfb != NULL) { if (pfb == fb) { if (fb->hWnd != NULL) { - SetWindowLong( + SetWindowLongPtr( fb->hWnd, - GWL_WNDPROC, - (LONG) fb->WndProc ); + GWLP_WNDPROC, + (LONG_PTR) fb->WndProc ); } *link = fb->next; @@ -224,7 +252,8 @@ stw_swap_buffers( HDC hdc ) { struct stw_framebuffer *fb; - struct pipe_surface *surf; + struct pipe_screen *screen; + struct pipe_surface *surface; fb = framebuffer_from_hdc( hdc ); if (fb == NULL) @@ -235,11 +264,20 @@ stw_swap_buffers( */ st_notify_swapbuffers( fb->stfb ); - st_get_framebuffer_surface( fb->stfb, ST_SURFACE_BACK_LEFT, &surf ); + screen = stw_dev->screen; + + if(!st_get_framebuffer_surface( fb->stfb, ST_SURFACE_BACK_LEFT, &surface )) + /* FIXME: this shouldn't happen, but does on glean */ + return FALSE; - stw_dev->stw_winsys->flush_frontbuffer(stw_dev->screen, - surf, - hdc ); +#ifdef DEBUG + if(stw_dev->trace_running) { + screen = trace_screen(screen)->screen; + surface = trace_surface(surface)->surface; + } +#endif + stw_dev->stw_winsys->flush_frontbuffer( screen, surface, hdc ); + return TRUE; } diff --git a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h index 2e16e421f2c..5abdf189970 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h +++ b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h @@ -36,12 +36,7 @@ struct stw_framebuffer { struct st_framebuffer *stfb; HDC hDC; - int pixelformat; BYTE cColorBits; - HDC dib_hDC; - HBITMAP hbmDIB; - HBITMAP hOldBitmap; - PBYTE pbPixels; HWND hWnd; WNDPROC WndProc; struct stw_framebuffer *next; diff --git a/src/gallium/winsys/drm/SConscript b/src/gallium/winsys/drm/SConscript index aef5210a32d..a9e9f2682a7 100644 --- a/src/gallium/winsys/drm/SConscript +++ b/src/gallium/winsys/drm/SConscript @@ -52,3 +52,8 @@ if env['dri']: SConscript([ 'intel/SConscript', ]) + + if 'radeon' in env['winsys']: + SConscript([ + 'radeon/SConscript', + ]) diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c index c4cbbc21248..0b45b1ff1f6 100644 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c +++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c @@ -199,7 +199,8 @@ dri_surface_from_handle(struct pipe_screen *screen, return NULL; memset(&templat, 0, sizeof(templat)); - templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET; + templat.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY | + NOUVEAU_TEXTURE_USAGE_LINEAR; templat.target = PIPE_TEXTURE_2D; templat.last_level = 0; templat.depth[0] = 1; diff --git a/src/gallium/winsys/drm/radeon/SConscript b/src/gallium/winsys/drm/radeon/SConscript index 2435211a327..8f99055b2f7 100644 --- a/src/gallium/winsys/drm/radeon/SConscript +++ b/src/gallium/winsys/drm/radeon/SConscript @@ -1,29 +1,7 @@ Import('*') -if 'mesa' in env['statetrackers']: - - env = drienv.Clone() - - DRIVER_SOURCES = [ - 'radeon_buffer.c', - 'radeon_context.c', - 'radeon_screen.c', - 'radeon_winsys_softpipe.c', - ] +SConscript(['core/SConscript',]) - sources = \ - COMMON_GALLIUM_SOURCES + \ - DRIVER_SOURCES - - drivers = [ - softpipe, - r300 - ] - - # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions - env.SharedLibrary( - target ='radeon_dri.so', - source = sources, - LIBS = drivers + mesa + auxiliaries + env['LIBS'], - ) +if 'mesa' in env['statetrackers']: + SConscript(['dri2/SConscript']) diff --git a/src/gallium/winsys/drm/radeon/core/SConscript b/src/gallium/winsys/drm/radeon/core/SConscript new file mode 100644 index 00000000000..578174e32ba --- /dev/null +++ b/src/gallium/winsys/drm/radeon/core/SConscript @@ -0,0 +1,17 @@ +Import('*') + +env = drienv.Clone() + +radeon_sources = [ + 'radeon_buffer.c', + 'radeon_drm.c', + 'radeon_r300.c', + 'radeon_winsys_softpipe.c', +] + +env.Append(CPPPATH = '#/src/gallium/drivers/r300') + +env.ConvenienceLibrary( + target ='radeonwinsys', + source = radeon_sources, +) diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c index 9dca510c815..611ee68da63 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c @@ -82,7 +82,8 @@ static struct pipe_buffer *radeon_buffer_user_create(struct pipe_winsys *ws, { struct radeon_pipe_buffer *radeon_buffer; - radeon_buffer = (struct radeon_pipe_buffer*)radeon_buffer_create(ws, 0, 0, bytes); + radeon_buffer = + (struct radeon_pipe_buffer*)radeon_buffer_create(ws, 0, 0, bytes); if (radeon_buffer == NULL) { return NULL; } @@ -94,7 +95,8 @@ static struct pipe_buffer *radeon_buffer_user_create(struct pipe_winsys *ws, static void radeon_buffer_del(struct pipe_buffer *buffer) { - struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer; + struct radeon_pipe_buffer *radeon_buffer = + (struct radeon_pipe_buffer*)buffer; radeon_bo_unref(radeon_buffer->bo); free(radeon_buffer); @@ -104,7 +106,8 @@ static void *radeon_buffer_map(struct pipe_winsys *ws, struct pipe_buffer *buffer, unsigned flags) { - struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer; + struct radeon_pipe_buffer *radeon_buffer = + (struct radeon_pipe_buffer*)buffer; int write = 0; if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) { @@ -120,9 +123,11 @@ static void *radeon_buffer_map(struct pipe_winsys *ws, return radeon_buffer->bo->ptr; } -static void radeon_buffer_unmap(struct pipe_winsys *ws, struct pipe_buffer *buffer) +static void radeon_buffer_unmap(struct pipe_winsys *ws, + struct pipe_buffer *buffer) { - struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer; + struct radeon_pipe_buffer *radeon_buffer = + (struct radeon_pipe_buffer*)buffer; radeon_bo_unmap(radeon_buffer->bo); } @@ -151,7 +156,7 @@ static void radeon_flush_frontbuffer(struct pipe_winsys *pipe_winsys, struct pipe_surface *pipe_surface, void *context_private) { - /* TODO: call dri2CopyRegion */ + /* XXX TODO: call dri2CopyRegion */ } struct radeon_winsys* radeon_pipe_winsys(int fd) diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h index 40ad0fc8d19..163422f2969 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h @@ -59,9 +59,10 @@ struct radeon_winsys { }; struct radeon_winsys* radeon_pipe_winsys(int fb); +#if 0 struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_context, uint32_t handle, enum pipe_format format, int w, int h, int pitch); - +#endif #endif diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c index c7b6813014f..293b6c2d389 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c @@ -39,7 +39,13 @@ static void radeon_r300_write_cs_reloc(struct radeon_cs* cs, static void radeon_r300_flush_cs(struct radeon_cs* cs) { - radeon_cs_emit(cs); + int retval = 0; + + retval = radeon_cs_emit(cs); + if (retval) { + debug_printf("radeon: Bad CS, dumping...\n"); + radeon_cs_print(cs, stderr); + } radeon_cs_erase(cs); } @@ -79,10 +85,15 @@ struct r300_winsys* radeon_create_r300_winsys(int fd, struct radeon_winsys* old_winsys) { struct r300_winsys* winsys = CALLOC_STRUCT(r300_winsys); + struct radeon_cs_manager* csm; + + if (winsys == NULL) { + return NULL; + } do_ioctls(winsys, fd); - struct radeon_cs_manager* csm = radeon_cs_manager_gem_ctor(fd); + csm = radeon_cs_manager_gem_ctor(fd); winsys->cs = radeon_cs_create(csm, 1024 * 64 / 4); diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c b/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c index 226e16674c8..33f9ac15ab1 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c @@ -39,16 +39,17 @@ struct radeon_softpipe_winsys { /** * Return list of surface formats supported by this driver. */ -static boolean radeon_is_format_supported(struct softpipe_winsys *sws, uint format) +static boolean radeon_is_format_supported(struct softpipe_winsys *sws, + uint format) { switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - return TRUE; - default: - break; - }; + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return TRUE; + default: + break; + } return FALSE; } diff --git a/src/gallium/winsys/drm/radeon/dri2/SConscript b/src/gallium/winsys/drm/radeon/dri2/SConscript new file mode 100644 index 00000000000..f2cdee97d92 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/dri2/SConscript @@ -0,0 +1,14 @@ +Import('*') + +env = drienv.Clone() + +drivers = [ + softpipe, + r300 +] + +env.SharedLibrary( + target ='radeon_dri.so', + source = COMMON_GALLIUM_SOURCES, + LIBS = drivers + mesa + auxiliaries + env['LIBS'], +) diff --git a/src/gallium/winsys/drm/radeon/python/README b/src/gallium/winsys/drm/radeon/python/README new file mode 100644 index 00000000000..d9e49bce67b --- /dev/null +++ b/src/gallium/winsys/drm/radeon/python/README @@ -0,0 +1,15 @@ +Python bindings for the radeon gallium driver. + + +See gallium/src/gallium/state_trackers/python/README for more information. + + +Build as: + + scons debug=1 statetrackers=python winsys=drm/radeon/python + +Run as: + + export PYTHONPATH=$PWD/build/linux-x86-debug/gallium/winsys/drm/radeon/python:$PWD/build/linux-x86-debug/gallium/state_trackers/python + + python src/gallium/state_trackers/python/samples/tri.py diff --git a/src/gallium/winsys/drm/radeon/python/SConscript b/src/gallium/winsys/drm/radeon/python/SConscript new file mode 100644 index 00000000000..3200fd8d1b0 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/python/SConscript @@ -0,0 +1,33 @@ +import os.path + +Import('*') + +if env['platform'] == 'linux': + + env = env.Clone() + + env.Tool('python') + + env.ParseConfig('pkg-config --cflags --libs libdrm') + + env.Prepend(CPPPATH = [ + '#src/gallium/state_trackers/python', + '../core', + ]) + + drivers = [ + softpipe, + radeon, + trace, + ] + + sources = [ + 'radeon_hardpipe_winsys.c', + 'xf86dri.c', + ] + + env.SharedLibrary( + target ='_gallium', + source = sources, + LIBS = [pyst] + drivers + auxiliaries + env['LIBS'], + ) diff --git a/src/gallium/winsys/drm/radeon/python/radeon_hardpipe_winsys.c b/src/gallium/winsys/drm/radeon/python/radeon_hardpipe_winsys.c new file mode 100644 index 00000000000..c3ec24aaf78 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/python/radeon_hardpipe_winsys.c @@ -0,0 +1,140 @@ + /************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, 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 VMWARE 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 <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include <X11/X.h> +#include <X11/Xlib.h> +#include <drm/drm.h> + +#include "pipe/p_screen.h" +#include "pipe/p_context.h" + +#include "st_winsys.h" + +#include "radeon_winsys.h" + +#include "xf86dri.h" + + +/* XXX: Force init_gallium symbol to be linked */ +extern void init_gallium(void); +void (*force_init_gallium_linkage)(void) = &init_gallium; + + +static struct pipe_screen * +radeon_hardpipe_screen_create(void) +{ + Display *dpy; + Window rootWin; + XWindowAttributes winAttr; + int isCapable; + int screen; + char *driverName; + char *curBusID; + unsigned magic; + int ddxDriverMajor; + int ddxDriverMinor; + int ddxDriverPatch; + drm_handle_t sAreaOffset; + int ret; + int drmFD; + drm_context_t hHWContext; + XID id; + + dpy = XOpenDisplay(":0"); + if (!dpy) { + fprintf(stderr, "Open Display Failed\n"); + return NULL; + } + + screen = DefaultScreen(dpy); + rootWin = RootWindow(dpy, screen); + XGetWindowAttributes(dpy, rootWin, &winAttr); + + ret = uniDRIQueryDirectRenderingCapable(dpy, screen, &isCapable); + if (!ret || !isCapable) { + fprintf(stderr, "No DRI on this display:sceen\n"); + goto error; + } + + if (!uniDRIOpenConnection(dpy, screen, &sAreaOffset, + &curBusID)) { + fprintf(stderr, "Could not open DRI connection.\n"); + goto error; + } + + if (!uniDRIGetClientDriverName(dpy, screen, &ddxDriverMajor, + &ddxDriverMinor, &ddxDriverPatch, + &driverName)) { + fprintf(stderr, "Could not get DRI driver name.\n"); + goto error; + } + + if ((drmFD = drmOpen(NULL, curBusID)) < 0) { + perror("DRM Device could not be opened"); + goto error; + } + + drmGetMagic(drmFD, &magic); + if (!uniDRIAuthConnection(dpy, screen, magic)) { + fprintf(stderr, "Could not get X server to authenticate us.\n"); + goto error; + } + + if (!uniDRICreateContext(dpy, screen, winAttr.visual, + &id, &hHWContext)) { + fprintf(stderr, "Could not create DRI context.\n"); + goto error; + } + + /* FIXME: create a radeon pipe_screen from drmFD and hHWContext */ + + return NULL; + +error: + return NULL; +} + + +static struct pipe_context * +radeon_hardpipe_context_create(struct pipe_screen *screen) +{ + /* FIXME: create a radon pipe_context from screen */ + + return NULL; +} + + +const struct st_winsys st_hardpipe_winsys = { + &radeon_hardpipe_screen_create, + &radeon_hardpipe_context_create, +}; + diff --git a/src/gallium/winsys/drm/radeon/python/xf86dri.c b/src/gallium/winsys/drm/radeon/python/xf86dri.c new file mode 100644 index 00000000000..1736f1e54f8 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/python/xf86dri.c @@ -0,0 +1,605 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, 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 PRECISION INSIGHT 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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <[email protected]> + * Jens Owen <[email protected]> + * Rickard E. (Rik) Faith <[email protected]> + * + */ + +/* THIS IS NOT AN X CONSORTIUM STANDARD */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define NEED_REPLIES +#include <X11/Xlibint.h> +#include <X11/extensions/Xext.h> +#include <X11/extensions/extutil.h> +#include "xf86dristr.h" + +static XExtensionInfo _xf86dri_info_data; +static XExtensionInfo *xf86dri_info = &_xf86dri_info_data; +static char xf86dri_extension_name[] = XF86DRINAME; + +#define uniDRICheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, xf86dri_extension_name, val) + +/***************************************************************************** + * * + * private utility routines * + * * + *****************************************************************************/ + +static int close_display(Display * dpy, XExtCodes * extCodes); +static /* const */ XExtensionHooks xf86dri_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + close_display, /* close_display */ + NULL, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + +static +XEXT_GENERATE_FIND_DISPLAY(find_display, xf86dri_info, + xf86dri_extension_name, &xf86dri_extension_hooks, + 0, NULL) + + static XEXT_GENERATE_CLOSE_DISPLAY(close_display, xf86dri_info) + +/***************************************************************************** + * * + * public XFree86-DRI Extension routines * + * * + *****************************************************************************/ +#if 0 +#include <stdio.h> +#define TRACE(msg) fprintf(stderr,"uniDRI%s\n", msg); +#else +#define TRACE(msg) +#endif + Bool uniDRIQueryExtension(dpy, event_basep, error_basep) + Display *dpy; + int *event_basep, *error_basep; +{ + XExtDisplayInfo *info = find_display(dpy); + + TRACE("QueryExtension..."); + if (XextHasExtension(info)) { + *event_basep = info->codes->first_event; + *error_basep = info->codes->first_error; + TRACE("QueryExtension... return True"); + return True; + } else { + TRACE("QueryExtension... return False"); + return False; + } +} + +Bool +uniDRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion) + Display *dpy; + int *majorVersion; + int *minorVersion; + int *patchVersion; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIQueryVersionReply rep; + xXF86DRIQueryVersionReq *req; + + TRACE("QueryVersion..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIQueryVersion, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIQueryVersion; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryVersion... return False"); + return False; + } + *majorVersion = rep.majorVersion; + *minorVersion = rep.minorVersion; + *patchVersion = rep.patchVersion; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryVersion... return True"); + return True; +} + +Bool +uniDRIQueryDirectRenderingCapable(dpy, screen, isCapable) + Display *dpy; + int screen; + Bool *isCapable; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIQueryDirectRenderingCapableReply rep; + xXF86DRIQueryDirectRenderingCapableReq *req; + + TRACE("QueryDirectRenderingCapable..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIQueryDirectRenderingCapable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIQueryDirectRenderingCapable; + req->screen = screen; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryDirectRenderingCapable... return False"); + return False; + } + *isCapable = rep.isCapable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryDirectRenderingCapable... return True"); + return True; +} + +Bool +uniDRIOpenConnection(dpy, screen, hSAREA, busIdString) + Display *dpy; + int screen; + drm_handle_t *hSAREA; + char **busIdString; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIOpenConnectionReply rep; + xXF86DRIOpenConnectionReq *req; + + TRACE("OpenConnection..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIOpenConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIOpenConnection; + req->screen = screen; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return False"); + return False; + } + + *hSAREA = rep.hSAREALow; +#ifdef LONG64 + if (sizeof(drm_handle_t) == 8) { + *hSAREA |= ((unsigned long)rep.hSAREAHigh) << 32; + } +#endif + if (rep.length) { + if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) { + _XEatData(dpy, ((rep.busIdStringLength + 3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return False"); + return False; + } + _XReadPad(dpy, *busIdString, rep.busIdStringLength); + } else { + *busIdString = NULL; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return True"); + return True; +} + +Bool +uniDRIAuthConnection(dpy, screen, magic) + Display *dpy; + int screen; + drm_magic_t magic; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIAuthConnectionReq *req; + xXF86DRIAuthConnectionReply rep; + + TRACE("AuthConnection..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIAuthConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIAuthConnection; + req->screen = screen; + req->magic = magic; + rep.authenticated = 0; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse) || !rep.authenticated) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("AuthConnection... return False"); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("AuthConnection... return True"); + return True; +} + +Bool +uniDRICloseConnection(dpy, screen) + Display *dpy; + int screen; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRICloseConnectionReq *req; + + TRACE("CloseConnection..."); + + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRICloseConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRICloseConnection; + req->screen = screen; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CloseConnection... return True"); + return True; +} + +Bool +uniDRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion, + ddxDriverMinorVersion, ddxDriverPatchVersion, + clientDriverName) + Display *dpy; + int screen; + int *ddxDriverMajorVersion; + int *ddxDriverMinorVersion; + int *ddxDriverPatchVersion; + char **clientDriverName; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIGetClientDriverNameReply rep; + xXF86DRIGetClientDriverNameReq *req; + + TRACE("GetClientDriverName..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIGetClientDriverName, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIGetClientDriverName; + req->screen = screen; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return False"); + return False; + } + + *ddxDriverMajorVersion = rep.ddxDriverMajorVersion; + *ddxDriverMinorVersion = rep.ddxDriverMinorVersion; + *ddxDriverPatchVersion = rep.ddxDriverPatchVersion; + + if (rep.length) { + if (!(*clientDriverName = + (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) { + _XEatData(dpy, ((rep.clientDriverNameLength + 3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return False"); + return False; + } + _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength); + } else { + *clientDriverName = NULL; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return True"); + return True; +} + +Bool +uniDRICreateContextWithConfig(dpy, screen, configID, context, hHWContext) + Display *dpy; + int screen; + int configID; + XID *context; + drm_context_t *hHWContext; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRICreateContextReply rep; + xXF86DRICreateContextReq *req; + + TRACE("CreateContext..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRICreateContext, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRICreateContext; + req->visual = configID; + req->screen = screen; + *context = XAllocID(dpy); + req->context = *context; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateContext... return False"); + return False; + } + *hHWContext = rep.hHWContext; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateContext... return True"); + return True; +} + +Bool +uniDRICreateContext(dpy, screen, visual, context, hHWContext) + Display *dpy; + int screen; + Visual *visual; + XID *context; + drm_context_t *hHWContext; +{ + return uniDRICreateContextWithConfig(dpy, screen, visual->visualid, + context, hHWContext); +} + +Bool +uniDRIDestroyContext(Display * ndpy, int screen, XID context) +{ + Display *const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIDestroyContextReq *req; + + TRACE("DestroyContext..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIDestroyContext, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIDestroyContext; + req->screen = screen; + req->context = context; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("DestroyContext... return True"); + return True; +} + +Bool +uniDRICreateDrawable(Display * ndpy, int screen, + Drawable drawable, drm_drawable_t * hHWDrawable) +{ + Display *const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display(dpy); + xXF86DRICreateDrawableReply rep; + xXF86DRICreateDrawableReq *req; + + TRACE("CreateDrawable..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRICreateDrawable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRICreateDrawable; + req->screen = screen; + req->drawable = drawable; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateDrawable... return False"); + return False; + } + *hHWDrawable = rep.hHWDrawable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateDrawable... return True"); + return True; +} + +Bool +uniDRIDestroyDrawable(Display * ndpy, int screen, Drawable drawable) +{ + Display *const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIDestroyDrawableReq *req; + + TRACE("DestroyDrawable..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIDestroyDrawable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIDestroyDrawable; + req->screen = screen; + req->drawable = drawable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("DestroyDrawable... return True"); + return True; +} + +Bool +uniDRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable, + unsigned int *index, unsigned int *stamp, + int *X, int *Y, int *W, int *H, + int *numClipRects, drm_clip_rect_t ** pClipRects, + int *backX, int *backY, + int *numBackClipRects, + drm_clip_rect_t ** pBackClipRects) +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIGetDrawableInfoReply rep; + xXF86DRIGetDrawableInfoReq *req; + int total_rects; + + TRACE("GetDrawableInfo..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIGetDrawableInfo, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIGetDrawableInfo; + req->screen = screen; + req->drawable = drawable; + + if (!_XReply(dpy, (xReply *) & rep, 1, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return False"); + return False; + } + *index = rep.drawableTableIndex; + *stamp = rep.drawableTableStamp; + *X = (int)rep.drawableX; + *Y = (int)rep.drawableY; + *W = (int)rep.drawableWidth; + *H = (int)rep.drawableHeight; + *numClipRects = rep.numClipRects; + total_rects = *numClipRects; + + *backX = rep.backX; + *backY = rep.backY; + *numBackClipRects = rep.numBackClipRects; + total_rects += *numBackClipRects; + +#if 0 + /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks + * backwards compatibility (Because of the >> 2 shift) but the fix + * enables multi-threaded apps to work. + */ + if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) - + SIZEOF(xGenericReply) + + total_rects * sizeof(drm_clip_rect_t)) + + 3) & ~3) >> 2)) { + _XEatData(dpy, rep.length); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return False"); + return False; + } +#endif + + if (*numClipRects) { + int len = sizeof(drm_clip_rect_t) * (*numClipRects); + + *pClipRects = (drm_clip_rect_t *) Xcalloc(len, 1); + if (*pClipRects) + _XRead(dpy, (char *)*pClipRects, len); + } else { + *pClipRects = NULL; + } + + if (*numBackClipRects) { + int len = sizeof(drm_clip_rect_t) * (*numBackClipRects); + + *pBackClipRects = (drm_clip_rect_t *) Xcalloc(len, 1); + if (*pBackClipRects) + _XRead(dpy, (char *)*pBackClipRects, len); + } else { + *pBackClipRects = NULL; + } + + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return True"); + return True; +} + +Bool +uniDRIGetDeviceInfo(dpy, screen, hFrameBuffer, + fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate) + Display *dpy; + int screen; + drm_handle_t *hFrameBuffer; + int *fbOrigin; + int *fbSize; + int *fbStride; + int *devPrivateSize; + void **pDevPrivate; +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86DRIGetDeviceInfoReply rep; + xXF86DRIGetDeviceInfoReq *req; + + TRACE("GetDeviceInfo..."); + uniDRICheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIGetDeviceInfo, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIGetDeviceInfo; + req->screen = screen; + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return False"); + return False; + } + + *hFrameBuffer = rep.hFrameBufferLow; +#ifdef LONG64 + if (sizeof(drm_handle_t) == 8) { + *hFrameBuffer |= ((unsigned long)rep.hFrameBufferHigh) << 32; + } +#endif + + *fbOrigin = rep.framebufferOrigin; + *fbSize = rep.framebufferSize; + *fbStride = rep.framebufferStride; + *devPrivateSize = rep.devPrivateSize; + + if (rep.length) { + if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) { + _XEatData(dpy, ((rep.devPrivateSize + 3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return False"); + return False; + } + _XRead(dpy, (char *)*pDevPrivate, rep.devPrivateSize); + } else { + *pDevPrivate = NULL; + } + + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return True"); + return True; +} diff --git a/src/gallium/winsys/drm/radeon/python/xf86dri.h b/src/gallium/winsys/drm/radeon/python/xf86dri.h new file mode 100644 index 00000000000..bf6de37d9dd --- /dev/null +++ b/src/gallium/winsys/drm/radeon/python/xf86dri.h @@ -0,0 +1,123 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, 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 PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/** + * \file xf86dri.h + * Protocol numbers and function prototypes for DRI X protocol. + * + * \author Kevin E. Martin <[email protected]> + * \author Jens Owen <[email protected]> + * \author Rickard E. (Rik) Faith <[email protected]> + */ + +#ifndef _XF86DRI_H_ +#define _XF86DRI_H_ + +#include <stdint.h> +#include <X11/Xfuncproto.h> +#include <drm/drm.h> + +#define X_XF86DRIQueryVersion 0 +#define X_XF86DRIQueryDirectRenderingCapable 1 +#define X_XF86DRIOpenConnection 2 +#define X_XF86DRICloseConnection 3 +#define X_XF86DRIGetClientDriverName 4 +#define X_XF86DRICreateContext 5 +#define X_XF86DRIDestroyContext 6 +#define X_XF86DRICreateDrawable 7 +#define X_XF86DRIDestroyDrawable 8 +#define X_XF86DRIGetDrawableInfo 9 +#define X_XF86DRIGetDeviceInfo 10 +#define X_XF86DRIAuthConnection 11 +#define X_XF86DRIOpenFullScreen 12 /* Deprecated */ +#define X_XF86DRICloseFullScreen 13 /* Deprecated */ + +#define XF86DRINumberEvents 0 + +#define XF86DRIClientNotLocal 0 +#define XF86DRIOperationNotSupported 1 +#define XF86DRINumberErrors (XF86DRIOperationNotSupported + 1) + +#ifndef _XF86DRI_SERVER_ + +_XFUNCPROTOBEGIN + Bool uniDRIQueryExtension(Display * dpy, int *event_base, + int *error_base); + +Bool uniDRIQueryVersion(Display * dpy, int *majorVersion, int *minorVersion, + int *patchVersion); + +Bool uniDRIQueryDirectRenderingCapable(Display * dpy, int screen, + Bool * isCapable); + +Bool uniDRIOpenConnection(Display * dpy, int screen, drm_handle_t * hSAREA, + char **busIDString); + +Bool uniDRIAuthConnection(Display * dpy, int screen, drm_magic_t magic); + +Bool uniDRICloseConnection(Display * dpy, int screen); + +Bool uniDRIGetClientDriverName(Display * dpy, int screen, + int *ddxDriverMajorVersion, + int *ddxDriverMinorVersion, + int *ddxDriverPatchVersion, + char **clientDriverName); + +Bool uniDRICreateContext(Display * dpy, int screen, Visual * visual, + XID * ptr_to_returned_context_id, + drm_context_t * hHWContext); + +Bool uniDRICreateContextWithConfig(Display * dpy, int screen, int configID, + XID * ptr_to_returned_context_id, + drm_context_t * hHWContext); + +extern Bool uniDRIDestroyContext(Display * dpy, int screen, XID context_id); + +extern Bool uniDRICreateDrawable(Display * dpy, int screen, + Drawable drawable, + drm_drawable_t * hHWDrawable); + +extern Bool uniDRIDestroyDrawable(Display * dpy, int screen, + Drawable drawable); + +Bool uniDRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable, + unsigned int *index, unsigned int *stamp, + int *X, int *Y, int *W, int *H, + int *numClipRects, drm_clip_rect_t ** pClipRects, + int *backX, int *backY, + int *numBackClipRects, + drm_clip_rect_t ** pBackClipRects); + +Bool uniDRIGetDeviceInfo(Display * dpy, int screen, + drm_handle_t * hFrameBuffer, int *fbOrigin, + int *fbSize, int *fbStride, int *devPrivateSize, + void **pDevPrivate); + +_XFUNCPROTOEND +#endif /* _XF86DRI_SERVER_ */ +#endif /* _XF86DRI_H_ */ diff --git a/src/gallium/winsys/drm/radeon/python/xf86dristr.h b/src/gallium/winsys/drm/radeon/python/xf86dristr.h new file mode 100644 index 00000000000..d8989963609 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/python/xf86dristr.h @@ -0,0 +1,389 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, 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 PRECISION INSIGHT 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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <[email protected]> + * Jens Owen <[email protected]> + * Rickard E. (Rik) Fiath <[email protected]> + * + */ + +#ifndef _XF86DRISTR_H_ +#define _XF86DRISTR_H_ + +#include "xf86dri.h" + +#define XF86DRINAME "XFree86-DRI" + +/* The DRI version number. This was originally set to be the same of the + * XFree86 version number. However, this version is really indepedent of + * the XFree86 version. + * + * Version History: + * 4.0.0: Original + * 4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02 + * 4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02 + */ +#define XF86DRI_MAJOR_VERSION 4 +#define XF86DRI_MINOR_VERSION 1 +#define XF86DRI_PATCH_VERSION 0 + +typedef struct _XF86DRIQueryVersion +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIQueryVersion */ + CARD16 length B16; +} xXF86DRIQueryVersionReq; + +#define sz_xXF86DRIQueryVersionReq 4 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 majorVersion B16; /* major version of DRI protocol */ + CARD16 minorVersion B16; /* minor version of DRI protocol */ + CARD32 patchVersion B32; /* patch version of DRI protocol */ + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIQueryVersionReply; + +#define sz_xXF86DRIQueryVersionReply 32 + +typedef struct _XF86DRIQueryDirectRenderingCapable +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* X_DRIQueryDirectRenderingCapable */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIQueryDirectRenderingCapableReq; + +#define sz_xXF86DRIQueryDirectRenderingCapableReq 8 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + BOOL isCapable; + BOOL pad2; + BOOL pad3; + BOOL pad4; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + CARD32 pad8 B32; + CARD32 pad9 B32; +} xXF86DRIQueryDirectRenderingCapableReply; + +#define sz_xXF86DRIQueryDirectRenderingCapableReply 32 + +typedef struct _XF86DRIOpenConnection +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIOpenConnection */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIOpenConnectionReq; + +#define sz_xXF86DRIOpenConnectionReq 8 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hSAREALow B32; + CARD32 hSAREAHigh B32; + CARD32 busIdStringLength B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + CARD32 pad8 B32; +} xXF86DRIOpenConnectionReply; + +#define sz_xXF86DRIOpenConnectionReply 32 + +typedef struct _XF86DRIAuthConnection +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseConnection */ + CARD16 length B16; + CARD32 screen B32; + CARD32 magic B32; +} xXF86DRIAuthConnectionReq; + +#define sz_xXF86DRIAuthConnectionReq 12 + +typedef struct +{ + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 authenticated B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIAuthConnectionReply; + +#define zx_xXF86DRIAuthConnectionReply 32 + +typedef struct _XF86DRICloseConnection +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseConnection */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRICloseConnectionReq; + +#define sz_xXF86DRICloseConnectionReq 8 + +typedef struct _XF86DRIGetClientDriverName +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetClientDriverName */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIGetClientDriverNameReq; + +#define sz_xXF86DRIGetClientDriverNameReq 8 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 ddxDriverMajorVersion B32; + CARD32 ddxDriverMinorVersion B32; + CARD32 ddxDriverPatchVersion B32; + CARD32 clientDriverNameLength B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIGetClientDriverNameReply; + +#define sz_xXF86DRIGetClientDriverNameReply 32 + +typedef struct _XF86DRICreateContext +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICreateContext */ + CARD16 length B16; + CARD32 screen B32; + CARD32 visual B32; + CARD32 context B32; +} xXF86DRICreateContextReq; + +#define sz_xXF86DRICreateContextReq 16 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hHWContext B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRICreateContextReply; + +#define sz_xXF86DRICreateContextReply 32 + +typedef struct _XF86DRIDestroyContext +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIDestroyContext */ + CARD16 length B16; + CARD32 screen B32; + CARD32 context B32; +} xXF86DRIDestroyContextReq; + +#define sz_xXF86DRIDestroyContextReq 12 + +typedef struct _XF86DRICreateDrawable +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICreateDrawable */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRICreateDrawableReq; + +#define sz_xXF86DRICreateDrawableReq 12 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hHWDrawable B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRICreateDrawableReply; + +#define sz_xXF86DRICreateDrawableReply 32 + +typedef struct _XF86DRIDestroyDrawable +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIDestroyDrawable */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRIDestroyDrawableReq; + +#define sz_xXF86DRIDestroyDrawableReq 12 + +typedef struct _XF86DRIGetDrawableInfo +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetDrawableInfo */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRIGetDrawableInfoReq; + +#define sz_xXF86DRIGetDrawableInfoReq 12 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 drawableTableIndex B32; + CARD32 drawableTableStamp B32; + INT16 drawableX B16; + INT16 drawableY B16; + INT16 drawableWidth B16; + INT16 drawableHeight B16; + CARD32 numClipRects B32; + INT16 backX B16; + INT16 backY B16; + CARD32 numBackClipRects B32; +} xXF86DRIGetDrawableInfoReply; + +#define sz_xXF86DRIGetDrawableInfoReply 36 + +typedef struct _XF86DRIGetDeviceInfo +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetDeviceInfo */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIGetDeviceInfoReq; + +#define sz_xXF86DRIGetDeviceInfoReq 8 + +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hFrameBufferLow B32; + CARD32 hFrameBufferHigh B32; + CARD32 framebufferOrigin B32; + CARD32 framebufferSize B32; + CARD32 framebufferStride B32; + CARD32 devPrivateSize B32; +} xXF86DRIGetDeviceInfoReply; + +#define sz_xXF86DRIGetDeviceInfoReply 32 + +typedef struct _XF86DRIOpenFullScreen +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIOpenFullScreen */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRIOpenFullScreenReq; + +#define sz_xXF86DRIOpenFullScreenReq 12 + +typedef struct +{ + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 isFullScreen B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIOpenFullScreenReply; + +#define sz_xXF86DRIOpenFullScreenReply 32 + +typedef struct _XF86DRICloseFullScreen +{ + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseFullScreen */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRICloseFullScreenReq; + +#define sz_xXF86DRICloseFullScreenReq 12 + +typedef struct +{ + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xXF86DRICloseFullScreenReply; + +#define sz_xXF86DRICloseFullScreenReply 32 + +#endif /* _XF86DRISTR_H_ */ diff --git a/src/gallium/winsys/gdi/SConscript b/src/gallium/winsys/gdi/SConscript index 72b5df8ca24..aabab95f3a8 100644 --- a/src/gallium/winsys/gdi/SConscript +++ b/src/gallium/winsys/gdi/SConscript @@ -21,12 +21,13 @@ if env['platform'] == 'windows': 'gdi_softpipe_winsys.c', ] - if env['toolchain'] == 'crossmingw': + if env['gcc']: sources += ['#src/gallium/state_trackers/wgl/opengl32.mingw.def'] else: sources += ['#src/gallium/state_trackers/wgl/opengl32.def'] drivers = [ + trace, softpipe, ] |