diff options
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_build.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_dump.c | 35 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.c | 50 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.h | 8 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_parse.h | 1 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_ppc.c | 9 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_sse2.c | 8 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_ureg.c | 42 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_ureg.h | 27 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_rect.c | 8 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_rect.h | 4 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_tile.c | 4 |
12 files changed, 169 insertions, 29 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c index 010d501c60..e0cfc54420 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_build.c +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c @@ -482,6 +482,8 @@ tgsi_default_full_instruction( void ) full_instruction.FullSrcRegisters[i] = tgsi_default_full_src_register(); } + full_instruction.Flags = 0x0; + return full_instruction; } diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c index f36b1114a9..05b07a3a73 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c @@ -33,12 +33,19 @@ #include "tgsi_info.h" #include "tgsi_iterate.h" + +/** Number of spaces to indent for IF/LOOP/etc */ +static const int indent_spaces = 3; + + struct dump_ctx { struct tgsi_iterate_context iter; uint instno; + uint indentation; + void (*printf)(struct dump_ctx *ctx, const char *format, ...); }; @@ -328,6 +335,14 @@ tgsi_dump_immediate( iter_immediate( &ctx.iter, (struct tgsi_full_immediate *)imm ); } +static void +indent(struct dump_ctx *ctx) +{ + uint i; + for (i = 0; i < ctx->indentation; i++) + TXT(" "); +} + static boolean iter_instruction( struct tgsi_iterate_context *iter, @@ -341,6 +356,15 @@ iter_instruction( INSTID( instno ); TXT( ": " ); + + /* update indentation */ + if (inst->Instruction.Opcode == TGSI_OPCODE_ENDIF || + inst->Instruction.Opcode == TGSI_OPCODE_ENDFOR || + inst->Instruction.Opcode == TGSI_OPCODE_ENDLOOP) { + ctx->indentation -= indent_spaces; + } + indent(ctx); + TXT( tgsi_get_opcode_info( inst->Instruction.Opcode )->mnemonic ); switch (inst->Instruction.Saturate) { @@ -481,6 +505,14 @@ iter_instruction( break; } + /* update indentation */ + if (inst->Instruction.Opcode == TGSI_OPCODE_IF || + inst->Instruction.Opcode == TGSI_OPCODE_ELSE || + inst->Instruction.Opcode == TGSI_OPCODE_BGNFOR || + inst->Instruction.Opcode == TGSI_OPCODE_BGNLOOP) { + ctx->indentation += indent_spaces; + } + EOL(); return TRUE; @@ -495,6 +527,7 @@ tgsi_dump_instruction( ctx.instno = instno; ctx.printf = dump_ctx_printf; + ctx.indentation = 0; iter_instruction( &ctx.iter, (struct tgsi_full_instruction *)inst ); } @@ -527,6 +560,7 @@ tgsi_dump( ctx.instno = 0; ctx.printf = dump_ctx_printf; + ctx.indentation = 0; tgsi_iterate_shader( tokens, &ctx.iter ); } @@ -579,6 +613,7 @@ tgsi_dump_str( ctx.base.instno = 0; ctx.base.printf = &str_dump_ctx_printf; + ctx.base.indentation = 0; ctx.str = str; ctx.str[0] = 0; diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 951ecfd552..711e86d6ed 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -62,6 +62,9 @@ #define FAST_MATH 1 +/** for tgsi_full_instruction::Flags */ +#define SOA_DEPENDENCY_FLAG 0x1 + #define TILE_TOP_LEFT 0 #define TILE_TOP_RIGHT 1 #define TILE_BOTTOM_LEFT 2 @@ -182,7 +185,7 @@ print_temp(const struct tgsi_exec_machine *mach, uint index) * MOV t3, t2; * The second instruction will have the wrong value for t0 if executed as-is. */ -static boolean +boolean tgsi_check_soa_dependencies(const struct tgsi_full_instruction *inst) { uint i, chan; @@ -328,19 +331,24 @@ tgsi_exec_machine_bind_shader( * sizeof(struct tgsi_full_instruction)); maxInstructions += 10; } - memcpy(instructions + numInstructions, - &parse.FullToken.FullInstruction, - sizeof(instructions[0])); -#if 0 if (tgsi_check_soa_dependencies(&parse.FullToken.FullInstruction)) { - debug_printf("SOA dependency in instruction:\n"); - tgsi_dump_instruction(&parse.FullToken.FullInstruction, - numInstructions); + uint opcode = parse.FullToken.FullInstruction.Instruction.Opcode; + parse.FullToken.FullInstruction.Flags = SOA_DEPENDENCY_FLAG; + /* XXX we only handle SOA dependencies properly for MOV/SWZ + * at this time! + */ + if (opcode != TGSI_OPCODE_MOV && opcode != TGSI_OPCODE_SWZ) { + debug_printf("Warning: SOA dependency in instruction" + " is not handled:\n"); + tgsi_dump_instruction(&parse.FullToken.FullInstruction, + numInstructions); + } } -#else - (void) tgsi_check_soa_dependencies; -#endif + + memcpy(instructions + numInstructions, + &parse.FullToken.FullInstruction, + sizeof(instructions[0])); numInstructions++; break; @@ -2024,9 +2032,23 @@ exec_instruction( case TGSI_OPCODE_MOV: case TGSI_OPCODE_SWZ: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - STORE( &r[0], 0, chan_index ); + if (inst->Flags & SOA_DEPENDENCY_FLAG) { + /* Do all fetches into temp regs, then do all stores to avoid + * intermediate/accidental clobbering. This could be done all the + * time for MOV but for other instructions we'll need more temps... + */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[chan_index], 0, chan_index ); + } + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[chan_index], 0, chan_index ); + } + } + else { + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + STORE( &r[0], 0, chan_index ); + } } break; diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h index 8a9100f4c3..fd9ef6f35d 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -272,6 +272,14 @@ tgsi_exec_machine_run( struct tgsi_exec_machine *mach ); +void +tgsi_exec_machine_free_data(struct tgsi_exec_machine *mach); + + +boolean +tgsi_check_soa_dependencies(const struct tgsi_full_instruction *inst); + + static INLINE void tgsi_set_kill_mask(struct tgsi_exec_machine *mach, unsigned mask) { diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h index 1035bda1a8..a26ee5ba86 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_parse.h +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h @@ -87,6 +87,7 @@ struct tgsi_full_instruction struct tgsi_instruction_ext_texture InstructionExtTexture; struct tgsi_full_dst_register FullDstRegisters[TGSI_FULL_MAX_DST_REGISTERS]; struct tgsi_full_src_register FullSrcRegisters[TGSI_FULL_MAX_SRC_REGISTERS]; + uint Flags; /**< user-defined usage */ }; union tgsi_full_token diff --git a/src/gallium/auxiliary/tgsi/tgsi_ppc.c b/src/gallium/auxiliary/tgsi/tgsi_ppc.c index 2d6ad12ffb..4b1c7d4e01 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ppc.c +++ b/src/gallium/auxiliary/tgsi/tgsi_ppc.c @@ -1108,6 +1108,15 @@ static int emit_instruction(struct gen_context *gen, struct tgsi_full_instruction *inst) { + + /* we don't handle saturation/clamping yet */ + if (inst->Instruction.Saturate != TGSI_SAT_NONE) + return 0; + + /* need to use extra temps to fix SOA dependencies : */ + if (tgsi_check_soa_dependencies(inst)) + return FALSE; + switch (inst->Instruction.Opcode) { case TGSI_OPCODE_MOV: case TGSI_OPCODE_SWZ: diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c index cfec5cfc01..46f2387c15 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c @@ -1747,6 +1747,14 @@ emit_instruction( if (indirect_temp_reference(inst)) return FALSE; + /* we don't handle saturation/clamping yet */ + if (inst->Instruction.Saturate != TGSI_SAT_NONE) + return FALSE; + + /* need to use extra temps to fix SOA dependencies : */ + if (tgsi_check_soa_dependencies(inst)) + return FALSE; + switch (inst->Instruction.Opcode) { case TGSI_OPCODE_ARL: FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c index ba84a82b2b..7922931361 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c @@ -31,6 +31,7 @@ #include "tgsi/tgsi_ureg.h" #include "tgsi/tgsi_dump.h" #include "util/u_memory.h" +#include "util/u_math.h" union tgsi_any_token { struct tgsi_version version; @@ -103,6 +104,7 @@ struct ureg_program unsigned nr_constants; unsigned nr_samplers; + unsigned nr_instructions; struct ureg_tokens domain[2]; }; @@ -301,7 +303,7 @@ out: */ struct ureg_src ureg_DECL_constant(struct ureg_program *ureg ) { - return ureg_src_register( TGSI_FILE_TEMPORARY, ureg->nr_constants++ ); + return ureg_src_register( TGSI_FILE_CONSTANT, ureg->nr_constants++ ); } @@ -392,7 +394,7 @@ struct ureg_src ureg_DECL_immediate( struct ureg_program *ureg, unsigned nr ) { unsigned i; - unsigned swizzle; + unsigned swizzle = 0; /* Could do a first pass where we examine all existing immediates * without expanding. @@ -525,7 +527,9 @@ ureg_emit_insn(struct ureg_program *ureg, out[0].insn.NumSrcRegs = num_src; out[0].insn.Padding = 0; out[0].insn.Extended = 0; - + + ureg->nr_instructions++; + return ureg->domain[DOMAIN_INSN].count - 1; } @@ -544,6 +548,31 @@ ureg_emit_label(struct ureg_program *ureg, out[0].value = 0; out[0].insn_ext_label.Type = TGSI_INSTRUCTION_EXT_TYPE_LABEL; + + *label_token = ureg->domain[DOMAIN_INSN].count - 1; +} + +/* Will return a number which can be used in a label to point to the + * next instruction to be emitted. + */ +unsigned +ureg_get_instruction_number( struct ureg_program *ureg ) +{ + return ureg->nr_instructions; +} + +/* Patch a given label (expressed as a token number) to point to a + * given instruction (expressed as an instruction number). + */ +void +ureg_fixup_label(struct ureg_program *ureg, + unsigned label_token, + unsigned instruction_number ) +{ + union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, label_token ); + + assert(out->insn_ext_label.Type == TGSI_INSTRUCTION_EXT_TYPE_LABEL); + out->insn_ext_label.Label = instruction_number; } @@ -571,6 +600,7 @@ ureg_fixup_insn_size(struct ureg_program *ureg, { union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, insn ); + assert(out->insn.Type == TGSI_TOKEN_TYPE_INSTRUCTION); out->insn.NrTokens = ureg->domain[DOMAIN_INSN].count - insn - 1; } @@ -710,8 +740,7 @@ static void copy_instructions( struct ureg_program *ureg ) static void -fixup_header_size(struct ureg_program *ureg, - unsigned insn ) +fixup_header_size(struct ureg_program *ureg ) { union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_DECL, 1 ); @@ -739,12 +768,11 @@ emit_header( struct ureg_program *ureg ) void *ureg_create_shader( struct ureg_program *ureg ) { struct pipe_shader_state state; - unsigned insn; emit_header( ureg ); emit_decls( ureg ); copy_instructions( ureg ); - fixup_header_size( ureg, insn ); + fixup_header_size( ureg ); if (ureg->domain[0].tokens == error_tokens || ureg->domain[1].tokens == error_tokens) { diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h index 0a976fd63b..5a48bb7a35 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h @@ -175,6 +175,33 @@ ureg_DECL_immediate1f( struct ureg_program *ureg, } /*********************************************************************** + * Functions for patching up labels + */ + + +/* Will return a number which can be used in a label to point to the + * next instruction to be emitted. + */ +unsigned +ureg_get_instruction_number( struct ureg_program *ureg ); + + +/* Patch a given label (expressed as a token number) to point to a + * given instruction (expressed as an instruction number). + * + * Labels are obtained from instruction emitters, eg ureg_CAL(). + * Instruction numbers are obtained from ureg_get_instruction_number(), + * above. + */ +void +ureg_fixup_label(struct ureg_program *ureg, + unsigned label_token, + unsigned instruction_number ); + + + + +/*********************************************************************** * Internal instruction helpers, don't call these directly: */ diff --git a/src/gallium/auxiliary/util/u_rect.c b/src/gallium/auxiliary/util/u_rect.c index 74259d453b..9866b6fc8a 100644 --- a/src/gallium/auxiliary/util/u_rect.c +++ b/src/gallium/auxiliary/util/u_rect.c @@ -43,7 +43,7 @@ * src_pitch may be negative to do vertical flip of pixels from source. */ void -pipe_copy_rect(ubyte * dst, +util_copy_rect(ubyte * dst, const struct pipe_format_block *block, unsigned dst_stride, unsigned dst_x, @@ -91,7 +91,7 @@ pipe_copy_rect(ubyte * dst, } void -pipe_fill_rect(ubyte * dst, +util_fill_rect(ubyte * dst, const struct pipe_format_block *block, unsigned dst_stride, unsigned dst_x, @@ -204,7 +204,7 @@ util_surface_copy(struct pipe_context *pipe, if (src_map && dst_map) { /* If do_flip, invert src_y position and pass negative src stride */ - pipe_copy_rect(dst_map, + util_copy_rect(dst_map, &dst_trans->block, dst_trans->stride, 0, 0, @@ -263,7 +263,7 @@ util_surface_fill(struct pipe_context *pipe, case 1: case 2: case 4: - pipe_fill_rect(dst_map, &dst_trans->block, dst_trans->stride, + util_fill_rect(dst_map, &dst_trans->block, dst_trans->stride, 0, 0, width, height, value); break; case 8: diff --git a/src/gallium/auxiliary/util/u_rect.h b/src/gallium/auxiliary/util/u_rect.h index 59e842e16d..daa50834d3 100644 --- a/src/gallium/auxiliary/util/u_rect.h +++ b/src/gallium/auxiliary/util/u_rect.h @@ -42,13 +42,13 @@ struct pipe_surface; extern void -pipe_copy_rect(ubyte * dst, const struct pipe_format_block *block, +util_copy_rect(ubyte * dst, const struct pipe_format_block *block, unsigned dst_stride, unsigned dst_x, unsigned dst_y, unsigned width, unsigned height, const ubyte * src, int src_stride, unsigned src_x, int src_y); extern void -pipe_fill_rect(ubyte * dst, const struct pipe_format_block *block, +util_fill_rect(ubyte * dst, const struct pipe_format_block *block, unsigned dst_stride, unsigned dst_x, unsigned dst_y, unsigned width, unsigned height, uint32_t value); diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c index 422bc76003..9e76cfbb05 100644 --- a/src/gallium/auxiliary/util/u_tile.c +++ b/src/gallium/auxiliary/util/u_tile.c @@ -62,7 +62,7 @@ pipe_get_tile_raw(struct pipe_transfer *pt, if(!src) return; - pipe_copy_rect(dst, &pt->block, dst_stride, 0, 0, w, h, src, pt->stride, x, y); + util_copy_rect(dst, &pt->block, dst_stride, 0, 0, w, h, src, pt->stride, x, y); screen->transfer_unmap(screen, pt); } @@ -90,7 +90,7 @@ pipe_put_tile_raw(struct pipe_transfer *pt, if(!dst) return; - pipe_copy_rect(dst, &pt->block, pt->stride, x, y, w, h, src, src_stride, 0, 0); + util_copy_rect(dst, &pt->block, pt->stride, x, y, w, h, src, src_stride, 0, 0); screen->transfer_unmap(screen, pt); } |