diff options
author | Brian <brian.paul@tungstengraphics.com> | 2007-08-21 20:13:31 -0600 |
---|---|---|
committer | Brian <brian.paul@tungstengraphics.com> | 2007-08-21 20:18:58 -0600 |
commit | 0d9bcdbeb11ad1ce7e5257f652ccf9ebf1aa59a7 (patch) | |
tree | 1870f28e4635270a9be238cec0ab4f61f8611c62 /src/mesa/pipe | |
parent | d70d41eefc1045bd2f8ddf2cb701d7789c671012 (diff) |
Fragment shader translation seems to basically work now. More testing needed.
Diffstat (limited to 'src/mesa/pipe')
-rw-r--r-- | src/mesa/pipe/i915simple/Makefile | 1 | ||||
-rw-r--r-- | src/mesa/pipe/i915simple/i915_context.h | 7 | ||||
-rw-r--r-- | src/mesa/pipe/i915simple/i915_fpc.c | 146 | ||||
-rw-r--r-- | src/mesa/pipe/i915simple/i915_fpc.h | 105 | ||||
-rw-r--r-- | src/mesa/pipe/i915simple/i915_fpc_translate.c | 297 | ||||
-rw-r--r-- | src/mesa/pipe/i915simple/i915_state.c | 2 | ||||
-rw-r--r-- | src/mesa/pipe/i915simple/i915_state_derived.c | 5 | ||||
-rw-r--r-- | src/mesa/pipe/i915simple/i915_state_emit.c | 43 |
8 files changed, 284 insertions, 322 deletions
diff --git a/src/mesa/pipe/i915simple/Makefile b/src/mesa/pipe/i915simple/Makefile index fc825c7302..2353d0df01 100644 --- a/src/mesa/pipe/i915simple/Makefile +++ b/src/mesa/pipe/i915simple/Makefile @@ -22,7 +22,6 @@ DRIVER_SOURCES = \ i915_strings.c \ i915_prim_emit.c \ i915_tex_layout.c \ - i915_fpc.c \ i915_fpc_debug.c \ i915_fpc_emit.c \ i915_fpc_translate.c \ diff --git a/src/mesa/pipe/i915simple/i915_context.h b/src/mesa/pipe/i915simple/i915_context.h index a3927bf8b8..bc00d61d4b 100644 --- a/src/mesa/pipe/i915simple/i915_context.h +++ b/src/mesa/pipe/i915simple/i915_context.h @@ -84,6 +84,11 @@ struct i915_state { unsigned immediate[I915_MAX_IMMEDIATE]; unsigned dynamic[I915_MAX_DYNAMIC]; + + uint *program; + uint program_len; + uint *constants; + uint num_constants; unsigned id; /* track lost context events */ }; @@ -115,6 +120,8 @@ struct i915_context struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; + struct pipe_constant_buffer temp_constants; /*XXX temporary*/ + unsigned dirty; unsigned *batch_start; diff --git a/src/mesa/pipe/i915simple/i915_fpc.c b/src/mesa/pipe/i915simple/i915_fpc.c index fd0bbbc482..3bf2231589 100644 --- a/src/mesa/pipe/i915simple/i915_fpc.c +++ b/src/mesa/pipe/i915simple/i915_fpc.c @@ -35,149 +35,3 @@ #include "i915_fpc.h" - - -void -i915_program_error(struct i915_fp_compile *p, const char *msg) -{ - fprintf(stderr, "i915_program_error: %s", msg); - p->fp->error = 1; -} - - -static struct i915_fp_compile * -i915_init_compile(struct i915_context *i915, struct i915_fragment_program *fp) -{ - struct i915_fp_compile *p = CALLOC_STRUCT(i915_fp_compile); - - p->fp = fp; -#if 0 - p->env_param = NULL; /*i915->intel.ctx.FragmentProgram.Parameters;*/ -#endif - p->constants = i915->fs.constants; - p->nr_tex_indirect = 1; /* correct? */ - p->nr_tex_insn = 0; - p->nr_alu_insn = 0; - p->nr_decl_insn = 0; - - memset(p->constant_flags, 0, sizeof(p->constant_flags)); - - p->csr = p->program; - p->decl = p->declarations; - p->decl_s = 0; - p->decl_t = 0; - p->temp_flag = 0xffff000; - p->utemp_flag = ~0x7; - -#if 0 - p->fp->translated = 0; - p->fp->error = 0; - p->fp->nr_constants = 0; -#endif - p->fp->wpos_tex = -1; - p->fp->nr_params = 0; - - *(p->decl++) = _3DSTATE_PIXEL_SHADER_PROGRAM; - - return p; -} - -/* Copy compile results to the fragment program struct and destroy the - * compilation context. - */ -static void -i915_fini_compile(struct i915_fp_compile *p) -{ - uint program_size = p->csr - p->program; - uint decl_size = p->decl - p->declarations; - - if (p->nr_tex_indirect > I915_MAX_TEX_INDIRECT) - i915_program_error(p, "Exceeded max nr indirect texture lookups"); - - if (p->nr_tex_insn > I915_MAX_TEX_INSN) - i915_program_error(p, "Exceeded max TEX instructions"); - - if (p->nr_alu_insn > I915_MAX_ALU_INSN) - i915_program_error(p, "Exceeded max ALU instructions"); - - if (p->nr_decl_insn > I915_MAX_DECL_INSN) - i915_program_error(p, "Exceeded max DECL instructions"); - - if (p->fp->error) { - p->fp->NumNativeInstructions = 0; - p->fp->NumNativeAluInstructions = 0; - p->fp->NumNativeTexInstructions = 0; - p->fp->NumNativeTexIndirections = 0; - return; - } - else { - p->fp->NumNativeInstructions = (p->nr_alu_insn + - p->nr_tex_insn + - p->nr_decl_insn); - p->fp->NumNativeAluInstructions = p->nr_alu_insn; - p->fp->NumNativeTexInstructions = p->nr_tex_insn; - p->fp->NumNativeTexIndirections = p->nr_tex_indirect; - } - - p->declarations[0] |= program_size + decl_size - 2; - - /* Copy compilation results to fragment program struct: - */ - memcpy(p->fp->program, - p->declarations, - decl_size * sizeof(uint)); - - memcpy(p->fp->program + decl_size, - p->program, - program_size * sizeof(uint)); - - p->fp->program_size = program_size + decl_size; - - /* Release the compilation struct: - */ - free(p); -} - - -/** - * Find an unused texture coordinate slot to use for fragment WPOS. - * Update p->fp->wpos_tex with the result (-1 if no used texcoord slot is found). - */ -static void -find_wpos_space(struct i915_fp_compile *p) -{ - const uint inputs = p->shader->inputs_read; - uint i; - - p->fp->wpos_tex = -1; - - if (inputs & FRAG_BIT_WPOS) { - for (i = 0; i < I915_TEX_UNITS; i++) { - if ((inputs & (FRAG_BIT_TEX0 << i)) == 0) { - p->fp->wpos_tex = i; - return; - } - } - - i915_program_error(p, "No free texcoord for wpos value"); - } -} - - - -void i915_compile_fragment_program( struct i915_context *i915, - struct i915_fragment_program *fp ) -{ - struct i915_fp_compile *p = i915_init_compile(i915, fp); - struct tgsi_token *tokens = i915->fs.tokens; - - find_wpos_space(p); - - i915_translate_program(p, tokens); - i915_fixup_depth_write(p); - - i915_fini_compile(p); -#if 0 - fp->translated = 1; -#endif -} diff --git a/src/mesa/pipe/i915simple/i915_fpc.h b/src/mesa/pipe/i915simple/i915_fpc.h index 0a8bffcd9a..1acb69e8ed 100644 --- a/src/mesa/pipe/i915simple/i915_fpc.h +++ b/src/mesa/pipe/i915simple/i915_fpc.h @@ -90,71 +90,10 @@ enum -#if 1 /*XXX temp */ -/* Hardware version of a parsed fragment program. "Derived" from the - * mesa fragment_program struct. - */ -struct i915_fragment_program -{ -#if 0 - struct gl_fragment_program Base; -#else - uint NumNativeInstructions; - uint NumNativeAluInstructions; - uint NumNativeTexInstructions; - uint NumNativeTexIndirections; -#endif - - boolean error; /**< Set if i915_program_error() is called */ -#if 0 - uint id; /**< String id */ - boolean translated; -#endif - - /* Decls + instructions: - */ - uint program[I915_PROGRAM_SIZE]; - uint program_size; - -#if 0 - /* Constant buffer: - */ - float constant[I915_MAX_CONSTANT][4]; - uint nr_constants; -#endif - - /* Some of which are parameters: - */ - struct - { - uint reg; /* Hardware constant idx */ - const float *values; /* Pointer to tracked values */ - } param[I915_MAX_CONSTANT]; - uint nr_params; - -#if 0 - uint param_state; -#endif - uint wpos_tex; -}; -#endif - - -/*********************************************************************** - * Public interface for the compiler - */ - -void i915_compile_fragment_program( struct i915_context *i915, - struct i915_fragment_program *fp ); - - -/*********************************************************************** - * Private details of the compiler +/** + * Program translation state */ - struct i915_fp_compile { - struct i915_fragment_program *fp; - struct pipe_shader_state *shader; uint declarations[I915_PROGRAM_SIZE]; @@ -186,9 +125,12 @@ struct i915_fp_compile { uint nr_alu_insn; uint nr_decl_insn; -#if 0 - float (*env_param)[4]; -#endif + boolean error; /**< Set if i915_program_error() is called */ + uint wpos_tex; + uint NumNativeInstructions; + uint NumNativeAluInstructions; + uint NumNativeTexInstructions; + uint NumNativeTexIndirections; }; @@ -268,6 +210,14 @@ negate(int reg, int x, int y, int z, int w) } + +/*********************************************************************** + * Public interface for the compiler + */ +extern void i915_translate_fragment_program( struct i915_context *i915 ); + + + extern uint i915_get_temp(struct i915_fp_compile *p); extern uint i915_get_utemp(struct i915_fp_compile *p); extern void i915_release_utemps(struct i915_fp_compile *p); @@ -302,38 +252,21 @@ extern uint i915_emit_const4f(struct i915_fp_compile *p, float c2, float c3); -#if 0 -extern uint i915_emit_param4fv(struct i915_fp_compile *p, - const float * values); -#endif - - - -/*====================================================================== - * i915_fpc_debug.c - */ -extern void i915_program_error(struct i915_fp_compile *p, - const char *msg); - - /*====================================================================== * i915_fpc_debug.c */ extern void i915_disassemble_program(const uint * program, uint sz); -#if 0 -extern void i915_print_mesa_instructions( const struct prog_instruction *insn, - uint nr ); -#endif /*====================================================================== * i915_fpc_translate.c */ -void i915_fixup_depth_write(struct i915_fp_compile *p); extern void -i915_translate_program(struct i915_fp_compile *p, const struct tgsi_token *token); +i915_program_error(struct i915_fp_compile *p, const char *msg); +extern void +i915_translate_fragment_program(struct i915_context *i915); #endif diff --git a/src/mesa/pipe/i915simple/i915_fpc_translate.c b/src/mesa/pipe/i915simple/i915_fpc_translate.c index db6b92ad7f..cf6a142075 100644 --- a/src/mesa/pipe/i915simple/i915_fpc_translate.c +++ b/src/mesa/pipe/i915simple/i915_fpc_translate.c @@ -32,6 +32,34 @@ #include "pipe/tgsi/core/tgsi_token.h" #include "pipe/tgsi/core/tgsi_parse.h" +/** + * Simple pass-through fragment shader to use when we don't have + * a real shader (or it fails to compile for some reason). + */ +static unsigned passthrough[] = +{ + _3DSTATE_PIXEL_SHADER_PROGRAM | ((2*3)-1), + + /* declare input color: + */ + (D0_DCL | + (REG_TYPE_T << D0_TYPE_SHIFT) | + (T_DIFFUSE << D0_NR_SHIFT) | + D0_CHANNEL_ALL), + 0, + 0, + + /* move to output color: + */ + (A0_MOV | + (REG_TYPE_OC << A0_DEST_TYPE_SHIFT) | + A0_DEST_CHANNEL_ALL | + (REG_TYPE_T << A0_SRC0_TYPE_SHIFT) | + (T_DIFFUSE << A0_SRC0_NR_SHIFT)), + 0x01230000, /* .xyzw */ + 0 +}; + /* 1, -1/3!, 1/5!, -1/7! */ static const float sin_constants[4] = { 1.0, @@ -48,6 +76,30 @@ static const float cos_constants[4] = { 1.0, }; + +static void +i915_use_passthrough_shader(struct i915_context *i915) +{ + fprintf(stderr, "**** Using i915 pass-through fragment shader\n"); + + i915->current.program = (uint *) malloc(sizeof(passthrough)); + memcpy(i915->current.program, passthrough, sizeof(passthrough)); + i915->current.program_len = Elements(passthrough); + + i915->current.constants = NULL; + i915->current.num_constants = 0; +} + + +void +i915_program_error(struct i915_fp_compile *p, const char *msg) +{ + fprintf(stderr, "i915_program_error: %s\n", msg); + p->error = 1; +} + + + /** * Construct a ureg for the given source register. Will emit * constants, apply swizzling and negation as needed. @@ -59,7 +111,7 @@ src_vector(struct i915_fp_compile *p, const uint index = source->SrcRegister.Index; uint src; - switch (source->SrcRegisterInd.File) { + switch (source->SrcRegister.File) { case TGSI_FILE_TEMPORARY: if (source->SrcRegister.Index >= I915_MAX_TEMPORARY) { i915_program_error(p, "Exceeded max temporary reg"); @@ -79,7 +131,7 @@ src_vector(struct i915_fp_compile *p, */ switch (index) { case FRAG_ATTRIB_WPOS: - src = i915_emit_decl(p, REG_TYPE_T, p->fp->wpos_tex, D0_CHANNEL_ALL); + src = i915_emit_decl(p, REG_TYPE_T, p->wpos_tex, D0_CHANNEL_ALL); break; case FRAG_ATTRIB_COL0: src = i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL); @@ -111,27 +163,9 @@ src_vector(struct i915_fp_compile *p, } break; - /* Various parameters and env values. All emitted to - * hardware as program constants. - */ -#if 0 - case PROGRAM_LOCAL_PARAM: - src = i915_emit_param4fv(p, program->Base.LocalParams[index]); - break; - case PROGRAM_ENV_PARAM: - src = i915_emit_param4fv(p, p->env_param[index]); - break; - case PROGRAM_CONSTANT: - case PROGRAM_STATE_VAR: - case PROGRAM_NAMED_PARAM: - src = i915_emit_param4fv( - p, program->Base.Parameters->ParameterValues[index]); - break; -#else case TGSI_FILE_CONSTANT: src = UREG(REG_TYPE_CONST, index); break; -#endif default: i915_program_error(p, "Bad source->File"); @@ -151,26 +185,14 @@ src_vector(struct i915_fp_compile *p, assert(!source->SrcRegisterExtSwz.NegateW); assert(!source->SrcRegisterExtMod.Absolute); assert(!source->SrcRegisterExtMod.Negate); -#if 0 - if (source->SrcRegister.Negate) - negate all - - if (extended source swiz per component) - src = negate(src, - source->SrcRegisterExtSwz.NegateX, - source->SrcRegisterExtSwz.NegateY, - source->SrcRegisterExtSwz.NegateZ, - source->SrcRegisterExtSwz.NegateW); - if (mod.abs) - absolute value - - if (mod.negate) - another negate; -#endif + return src; } +/** + * Construct a ureg for a destination register. + */ static uint get_result_vector(struct i915_fp_compile *p, const struct tgsi_full_dst_register *dest) @@ -178,9 +200,9 @@ get_result_vector(struct i915_fp_compile *p, switch (dest->DstRegister.File) { case TGSI_FILE_OUTPUT: switch (dest->DstRegister.Index) { - case FRAG_RESULT_COLR: + case 1: /*COLOR*/ /*FRAG_RESULT_COLR:*/ return UREG(REG_TYPE_OC, 0); - case FRAG_RESULT_DEPR: + case 0: /*DEPTH*/ /*FRAG_RESULT_DEPR:*/ return UREG(REG_TYPE_OD, 0); default: i915_program_error(p, "Bad inst->DstReg.Index"); @@ -296,12 +318,15 @@ emit_simple_arith(struct i915_fp_compile *p, } -#define EMIT_1ARG_ARITH( OP ) emit_simple_arith(p, inst, OP, 1) -#define EMIT_2ARG_ARITH( OP ) emit_simple_arith(p, inst, OP, 2) -#define EMIT_3ARG_ARITH( OP ) emit_simple_arith(p, inst, OP, 3) - - - +/* + * Translate TGSI instruction to i915 instruction. + * + * Possible concerns: + * + * SIN, COS -- could use another taylor step? + * LIT -- results seem a little different to sw mesa + * LOG -- different to mesa on negative numbers, but this is conformant. + */ static void i915_translate_instruction(struct i915_fp_compile *p, const struct tgsi_full_instruction *inst) @@ -321,7 +346,7 @@ i915_translate_instruction(struct i915_fp_compile *p, break; case TGSI_OPCODE_ADD: - EMIT_2ARG_ARITH(A0_ADD); + emit_simple_arith(p, inst, A0_ADD, 2); break; case TGSI_OPCODE_CMP: @@ -385,11 +410,11 @@ i915_translate_instruction(struct i915_fp_compile *p, break; case TGSI_OPCODE_DP3: - EMIT_2ARG_ARITH(A0_DP3); + emit_simple_arith(p, inst, A0_DP3, 2); break; case TGSI_OPCODE_DP4: - EMIT_2ARG_ARITH(A0_DP4); + emit_simple_arith(p, inst, A0_DP4, 2); break; case TGSI_OPCODE_DPH: @@ -431,11 +456,11 @@ i915_translate_instruction(struct i915_fp_compile *p, break; case TGSI_OPCODE_FLR: - EMIT_1ARG_ARITH(A0_FLR); + emit_simple_arith(p, inst, A0_FLR, 1); break; case TGSI_OPCODE_FRC: - EMIT_1ARG_ARITH(A0_FRC); + emit_simple_arith(p, inst, A0_FRC, 1); break; case TGSI_OPCODE_KIL: @@ -512,11 +537,11 @@ i915_translate_instruction(struct i915_fp_compile *p, break; case TGSI_OPCODE_MAD: - EMIT_3ARG_ARITH(A0_MAD); + emit_simple_arith(p, inst, A0_MAD, 3); break; case TGSI_OPCODE_MAX: - EMIT_2ARG_ARITH(A0_MAX); + emit_simple_arith(p, inst, A0_MAX, 2); break; case TGSI_OPCODE_MIN: @@ -539,11 +564,11 @@ i915_translate_instruction(struct i915_fp_compile *p, case TGSI_OPCODE_MOV: /* aka TGSI_OPCODE_SWZ */ - EMIT_1ARG_ARITH(A0_MOV); + emit_simple_arith(p, inst, A0_MOV, 1); break; case TGSI_OPCODE_MUL: - EMIT_2ARG_ARITH(A0_MUL); + emit_simple_arith(p, inst, A0_MUL, 2); break; case TGSI_OPCODE_POW: @@ -652,7 +677,7 @@ i915_translate_instruction(struct i915_fp_compile *p, break; case TGSI_OPCODE_SGE: - EMIT_2ARG_ARITH(A0_SGE); + emit_simple_arith(p, inst, A0_SGE, 2); break; case TGSI_OPCODE_SIN: @@ -706,7 +731,7 @@ i915_translate_instruction(struct i915_fp_compile *p, break; case TGSI_OPCODE_SLT: - EMIT_2ARG_ARITH(A0_SLT); + emit_simple_arith(p, inst, A0_SLT, 2); break; case TGSI_OPCODE_SUB: @@ -769,20 +794,12 @@ i915_translate_instruction(struct i915_fp_compile *p, /** * Translate TGSI fragment shader into i915 hardware instructions. - * - * Possible concerns: - * - * SIN, COS -- could use another taylor step? - * LIT -- results seem a little different to sw mesa - * LOG -- different to mesa on negative numbers, but this is conformant. - * - * Parse failures -- Mesa doesn't currently give a good indication - * internally whether a particular program string parsed or not. This - * can lead to confusion -- hopefully we cope with it ok now. + * \param p the translation state + * \param tokens the TGSI token array */ -void -i915_translate_program(struct i915_fp_compile *p, - const struct tgsi_token *tokens) +static void +i915_translate_instructions(struct i915_fp_compile *p, + const struct tgsi_token *tokens) { struct tgsi_parse_context parse; @@ -794,10 +811,11 @@ i915_translate_program(struct i915_fp_compile *p, switch( parse.FullToken.Token.Type ) { case TGSI_TOKEN_TYPE_DECLARATION: - assert(0); + /* XXX no-op? */ break; case TGSI_TOKEN_TYPE_IMMEDIATE: + /* XXX no-op? */ assert(0); break; @@ -815,13 +833,139 @@ i915_translate_program(struct i915_fp_compile *p, } +static struct i915_fp_compile * +i915_init_compile(struct i915_context *i915, + struct pipe_shader_state *fs) +{ + struct i915_fp_compile *p = CALLOC_STRUCT(i915_fp_compile); + + p->shader = &i915->fs; + + /* a bit of a hack, need to improve constant buffer infrastructure */ + if (i915->fs.constants) + p->constants = i915->fs.constants; + else + p->constants = &i915->temp_constants; + + p->nr_tex_indirect = 1; /* correct? */ + p->nr_tex_insn = 0; + p->nr_alu_insn = 0; + p->nr_decl_insn = 0; + + memset(p->constant_flags, 0, sizeof(p->constant_flags)); + + p->csr = p->program; + p->decl = p->declarations; + p->decl_s = 0; + p->decl_t = 0; + p->temp_flag = 0xffff000; + p->utemp_flag = ~0x7; + + p->wpos_tex = -1; + + /* initialize the first program word */ + *(p->decl++) = _3DSTATE_PIXEL_SHADER_PROGRAM; + + return p; +} + +/* Copy compile results to the fragment program struct and destroy the + * compilation context. + */ +static void +i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p) +{ + uint program_size = p->csr - p->program; + uint decl_size = p->decl - p->declarations; + + if (p->nr_tex_indirect > I915_MAX_TEX_INDIRECT) + i915_program_error(p, "Exceeded max nr indirect texture lookups"); + + if (p->nr_tex_insn > I915_MAX_TEX_INSN) + i915_program_error(p, "Exceeded max TEX instructions"); + + if (p->nr_alu_insn > I915_MAX_ALU_INSN) + i915_program_error(p, "Exceeded max ALU instructions"); + + if (p->nr_decl_insn > I915_MAX_DECL_INSN) + i915_program_error(p, "Exceeded max DECL instructions"); + + if (p->error) { + p->NumNativeInstructions = 0; + p->NumNativeAluInstructions = 0; + p->NumNativeTexInstructions = 0; + p->NumNativeTexIndirections = 0; + + i915_use_passthrough_shader(i915); + } + else { + p->NumNativeInstructions = (p->nr_alu_insn + + p->nr_tex_insn + + p->nr_decl_insn); + p->NumNativeAluInstructions = p->nr_alu_insn; + p->NumNativeTexInstructions = p->nr_tex_insn; + p->NumNativeTexIndirections = p->nr_tex_indirect; + + /* patch in the program length */ + p->declarations[0] |= program_size + decl_size - 2; + + /* Copy compilation results to fragment program struct: + */ + i915->current.program + = (uint *) malloc((program_size + decl_size) * sizeof(uint)); + i915->current.program_len = program_size + decl_size; + + memcpy(i915->current.program, + p->declarations, + decl_size * sizeof(uint)); + memcpy(i915->current.program + decl_size, + p->program, + program_size * sizeof(uint)); -/* Rather than trying to intercept and jiggle depth writes during + i915->current.constants = (uint *) p->constants->constant; + i915->current.num_constants = p->constants->nr_constants; + } + + /* Release the compilation struct: + */ + free(p); +} + + +/** + * Find an unused texture coordinate slot to use for fragment WPOS. + * Update p->fp->wpos_tex with the result (-1 if no used texcoord slot is found). + */ +static void +i915_find_wpos_space(struct i915_fp_compile *p) +{ + const uint inputs = p->shader->inputs_read; + uint i; + + p->wpos_tex = -1; + + if (inputs & FRAG_BIT_WPOS) { + for (i = 0; i < I915_TEX_UNITS; i++) { + if ((inputs & (FRAG_BIT_TEX0 << i)) == 0) { + p->wpos_tex = i; + return; + } + } + + i915_program_error(p, "No free texcoord for wpos value"); + } +} + + + + +/** + * Rather than trying to intercept and jiggle depth writes during * emit, just move the value into its correct position at the end of * the program: */ -void +static void i915_fixup_depth_write(struct i915_fp_compile *p) { if (p->shader->outputs_written & (1<<FRAG_RESULT_DEPR)) { @@ -835,5 +979,16 @@ i915_fixup_depth_write(struct i915_fp_compile *p) } +void +i915_translate_fragment_program( struct i915_context *i915 ) +{ + struct i915_fp_compile *p = i915_init_compile(i915, &i915->fs); + const struct tgsi_token *tokens = i915->fs.tokens; + i915_find_wpos_space(p); + i915_translate_instructions(p, tokens); + i915_fixup_depth_write(p); + + i915_fini_compile(i915, p); +} diff --git a/src/mesa/pipe/i915simple/i915_state.c b/src/mesa/pipe/i915simple/i915_state.c index 1de6fea2e9..e8ffd1fd7b 100644 --- a/src/mesa/pipe/i915simple/i915_state.c +++ b/src/mesa/pipe/i915simple/i915_state.c @@ -27,7 +27,7 @@ /* Authors: Keith Whitwell <keith@tungstengraphics.com> */ -//#include "imports.h" + #include "pipe/draw/draw_context.h" diff --git a/src/mesa/pipe/i915simple/i915_state_derived.c b/src/mesa/pipe/i915simple/i915_state_derived.c index a01b193676..b4ec480f2d 100644 --- a/src/mesa/pipe/i915simple/i915_state_derived.c +++ b/src/mesa/pipe/i915simple/i915_state_derived.c @@ -149,6 +149,11 @@ void i915_update_derived( struct i915_context *i915 ) if (i915->dirty) i915_update_dynamic( i915 ); + if (i915->dirty & I915_NEW_FS) { + i915_translate_fragment_program(i915); + i915->hardware_dirty |= I915_HW_PROGRAM; /* XXX right? */ + } + /* HW emit currently references framebuffer state directly: */ if (i915->dirty & I915_NEW_FRAMEBUFFER) diff --git a/src/mesa/pipe/i915simple/i915_state_emit.c b/src/mesa/pipe/i915simple/i915_state_emit.c index a7ae92d93c..da9d541598 100644 --- a/src/mesa/pipe/i915simple/i915_state_emit.c +++ b/src/mesa/pipe/i915simple/i915_state_emit.c @@ -26,10 +26,6 @@ **************************************************************************/ - -//#include "glheader.h" -//#include "mtypes.h" - #include "i915_reg.h" #include "i915_context.h" #include "i915_winsys.h" @@ -116,9 +112,6 @@ i915_emit_hardware_state(struct i915_context *i915 ) } - - - if (i915->hardware_dirty & I915_HW_IMMEDIATE) { OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | @@ -143,8 +136,6 @@ i915_emit_hardware_state(struct i915_context *i915 ) } } - - if (i915->hardware_dirty & I915_HW_STATIC) { if (i915->framebuffer.cbufs[0]) { @@ -180,7 +171,6 @@ i915_emit_hardware_state(struct i915_context *i915 ) I915_BUFFER_ACCESS_WRITE, 0); } - { unsigned cformat = translate_format( i915->framebuffer.cbufs[0]->format ); @@ -198,19 +188,38 @@ i915_emit_hardware_state(struct i915_context *i915 ) cformat | zformat ); } - } + /* constants */ + if (i915->hardware_dirty & I915_HW_PROGRAM) + { + const uint nr = i915->current.num_constants; + if (nr > 0) { + const uint *c = (const uint *) i915->current.constants; + uint i; + OUT_BATCH( _3DSTATE_PIXEL_SHADER_CONSTANTS | (nr * 4) ); + OUT_BATCH( (1 << (nr - 1)) | ((1 << (nr - 1)) - 1) ); + for (i = 0; i < nr; i++) { + OUT_BATCH(*c++); + OUT_BATCH(*c++); + OUT_BATCH(*c++); + OUT_BATCH(*c++); + } + } + } - + /* Fragment program */ + if (i915->hardware_dirty & I915_HW_PROGRAM) { - unsigned i, dwords; - unsigned *prog = i915_passthrough_program( &dwords ); - - for (i = 0; i < dwords; i++) - OUT_BATCH( prog[i] ); + uint i; + /* we should always have, at least, a pass-through program */ + assert(i915->current.program_len > 0); + for (i = 0; i < i915->current.program_len; i++) { + OUT_BATCH(i915->current.program[i]); + } } + /* drawing surface size */ { int w = i915->framebuffer.cbufs[0]->width; int h = i915->framebuffer.cbufs[0]->height; |