summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian <[email protected]>2007-08-21 20:13:31 -0600
committerBrian <[email protected]>2007-08-21 20:18:58 -0600
commit0d9bcdbeb11ad1ce7e5257f652ccf9ebf1aa59a7 (patch)
tree1870f28e4635270a9be238cec0ab4f61f8611c62
parentd70d41eefc1045bd2f8ddf2cb701d7789c671012 (diff)
Fragment shader translation seems to basically work now. More testing needed.
-rw-r--r--src/mesa/pipe/i915simple/Makefile1
-rw-r--r--src/mesa/pipe/i915simple/i915_context.h7
-rw-r--r--src/mesa/pipe/i915simple/i915_fpc.c146
-rw-r--r--src/mesa/pipe/i915simple/i915_fpc.h105
-rw-r--r--src/mesa/pipe/i915simple/i915_fpc_translate.c297
-rw-r--r--src/mesa/pipe/i915simple/i915_state.c2
-rw-r--r--src/mesa/pipe/i915simple/i915_state_derived.c5
-rw-r--r--src/mesa/pipe/i915simple/i915_state_emit.c43
8 files changed, 284 insertions, 322 deletions
diff --git a/src/mesa/pipe/i915simple/Makefile b/src/mesa/pipe/i915simple/Makefile
index fc825c7302f..2353d0df017 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 a3927bf8b8d..bc00d61d4be 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 fd0bbbc4824..3bf2231589d 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 0a8bffcd9ae..1acb69e8ed8 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 db6b92ad7fe..cf6a142075e 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 1de6fea2e90..e8ffd1fd7b8 100644
--- a/src/mesa/pipe/i915simple/i915_state.c
+++ b/src/mesa/pipe/i915simple/i915_state.c
@@ -27,7 +27,7 @@
/* Authors: Keith Whitwell <[email protected]>
*/
-//#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 a01b1936763..b4ec480f2d0 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 a7ae92d93c8..da9d5415981 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;