diff options
Diffstat (limited to 'src/gallium')
| -rw-r--r-- | src/gallium/drivers/i915simple/i915_context.h | 42 | ||||
| -rw-r--r-- | src/gallium/drivers/i915simple/i915_fpc.h | 23 | ||||
| -rw-r--r-- | src/gallium/drivers/i915simple/i915_fpc_emit.c | 99 | ||||
| -rw-r--r-- | src/gallium/drivers/i915simple/i915_fpc_translate.c | 132 | ||||
| -rw-r--r-- | src/gallium/drivers/i915simple/i915_state.c | 36 | ||||
| -rw-r--r-- | src/gallium/drivers/i915simple/i915_state_derived.c | 3 | ||||
| -rw-r--r-- | src/gallium/drivers/i915simple/i915_state_emit.c | 39 | 
7 files changed, 225 insertions, 149 deletions
| diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 2d876925b2..5cc38cdc85 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -79,6 +79,40 @@  #define I915_MAX_CONSTANT  32 +/** See constant_flags[] below */ +#define I915_CONSTFLAG_USER 0x1f + + +/** + * Subclass of pipe_shader_state + */ +struct i915_fragment_shader +{ +   struct pipe_shader_state state; +   uint *program; +   uint program_len; + +   /** +    * constants introduced during translation. +    * These are placed at the end of the constant buffer and grow toward +    * the beginning (eg: slot 31, 30 29, ...) +    * User-provided constants start at 0. +    * This allows both types of constants to co-exist (until there's too many) +    * and doesn't require regenerating/changing the fragment program to +    * shuffle constants around. +    */ +   uint num_constants; +   float constants[I915_MAX_CONSTANT][4]; + +   /** +    * Status of each constant +    * if I915_CONSTFLAG_PARAM, the value must be taken from the corresponding +    * slot of the user's constant buffer. (set by pipe->set_constant_buffer()) +    * Else, the bitmask indicates which components are occupied by immediates. +    */ +   ubyte constant_flags[I915_MAX_CONSTANT]; +}; +  struct i915_cache_context; @@ -93,11 +127,6 @@ struct i915_state     float constants[PIPE_SHADER_TYPES][I915_MAX_CONSTANT][4];     /** number of constants passed in through a constant buffer */     uint num_user_constants[PIPE_SHADER_TYPES]; -   /** user constants, plus extra constants from shader translation */ -   uint num_constants[PIPE_SHADER_TYPES]; - -   uint *program; -   uint program_len;     /* texture sampler state */     unsigned sampler[I915_TEX_UNITS][3]; @@ -187,7 +216,8 @@ struct i915_context     const struct i915_sampler_state         *sampler[PIPE_MAX_SAMPLERS];     const struct i915_depth_stencil_state   *depth_stencil;     const struct i915_rasterizer_state      *rasterizer; -   const struct pipe_shader_state *fs; + +   struct i915_fragment_shader *fs;     struct pipe_blend_color blend_color;     struct pipe_clip_state clip; diff --git a/src/gallium/drivers/i915simple/i915_fpc.h b/src/gallium/drivers/i915simple/i915_fpc.h index 8c7b68aefb..250dfe6dbf 100644 --- a/src/gallium/drivers/i915simple/i915_fpc.h +++ b/src/gallium/drivers/i915simple/i915_fpc.h @@ -44,9 +44,16 @@   * Program translation state   */  struct i915_fp_compile { -   const struct pipe_shader_state *shader; +   struct i915_fragment_shader *shader;  /* the shader we're compiling */ -   struct vertex_info *vertex_info; +   boolean used_constants[I915_MAX_CONSTANT]; + +   /** maps TGSI immediate index to constant slot */ +   uint num_immediates; +   uint immediates_map[I915_MAX_CONSTANT]; +   float immediates[I915_MAX_CONSTANT][4]; + +   boolean first_instruction;     uint declarations[I915_PROGRAM_SIZE];     uint program[I915_PROGRAM_SIZE]; @@ -57,11 +64,6 @@ struct i915_fp_compile {     uint output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];     uint output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; -   /** points into the i915->current.constants array: */ -   float (*constants)[4]; -   uint num_constants; -   uint constant_flags[I915_MAX_CONSTANT]; /**< status of each constant */ -     uint *csr;            /**< Cursor, points into program. */     uint *decl;           /**< Cursor, points into declarations. */ @@ -155,7 +157,9 @@ swizzle(int reg, uint x, uint y, uint z, uint w)  /***********************************************************************   * Public interface for the compiler   */ -extern void i915_translate_fragment_program( struct i915_context *i915 ); +extern void +i915_translate_fragment_program( struct i915_context *i915, +                                 struct i915_fragment_shader *fs); @@ -206,8 +210,5 @@ extern void i915_disassemble_program(const uint * program, uint sz);  extern void  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/gallium/drivers/i915simple/i915_fpc_emit.c b/src/gallium/drivers/i915simple/i915_fpc_emit.c index 74924ff0a1..a59ee23403 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_emit.c +++ b/src/gallium/drivers/i915simple/i915_fpc_emit.c @@ -61,8 +61,6 @@    			   (REG_NR_MASK << UREG_NR_SHIFT)) -#define I915_CONSTFLAG_PARAM 0x1f -  uint  i915_get_temp(struct i915_fp_compile *p)  { @@ -235,6 +233,7 @@ uint i915_emit_texld( struct i915_fp_compile *p,  uint  i915_emit_const1f(struct i915_fp_compile * p, float c0)  { +   struct i915_fragment_shader *ifs = p->shader;     unsigned reg, idx;     if (c0 == 0.0) @@ -243,15 +242,15 @@ i915_emit_const1f(struct i915_fp_compile * p, float c0)        return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE);     for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { -      if (p->constant_flags[reg] == I915_CONSTFLAG_PARAM) +      if (ifs->constant_flags[reg] == I915_CONSTFLAG_USER)           continue;        for (idx = 0; idx < 4; idx++) { -         if (!(p->constant_flags[reg] & (1 << idx)) || -             p->constants[reg][idx] == c0) { -            p->constants[reg][idx] = c0; -            p->constant_flags[reg] |= 1 << idx; -            if (reg + 1 > p->num_constants) -               p->num_constants = reg + 1; +         if (!(ifs->constant_flags[reg] & (1 << idx)) || +             ifs->constants[reg][idx] == c0) { +            ifs->constants[reg][idx] = c0; +            ifs->constant_flags[reg] |= 1 << idx; +            if (reg + 1 > ifs->num_constants) +               ifs->num_constants = reg + 1;              return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE);           }        } @@ -264,6 +263,7 @@ i915_emit_const1f(struct i915_fp_compile * p, float c0)  uint  i915_emit_const2f(struct i915_fp_compile * p, float c0, float c1)  { +   struct i915_fragment_shader *ifs = p->shader;     unsigned reg, idx;     if (c0 == 0.0) @@ -277,16 +277,16 @@ i915_emit_const2f(struct i915_fp_compile * p, float c0, float c1)        return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W);     for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { -      if (p->constant_flags[reg] == 0xf || -          p->constant_flags[reg] == I915_CONSTFLAG_PARAM) +      if (ifs->constant_flags[reg] == 0xf || +          ifs->constant_flags[reg] == I915_CONSTFLAG_USER)           continue;        for (idx = 0; idx < 3; idx++) { -         if (!(p->constant_flags[reg] & (3 << idx))) { -            p->constants[reg][idx + 0] = c0; -            p->constants[reg][idx + 1] = c1; -            p->constant_flags[reg] |= 3 << idx; -            if (reg + 1 > p->num_constants) -               p->num_constants = reg + 1; +         if (!(ifs->constant_flags[reg] & (3 << idx))) { +            ifs->constants[reg][idx + 0] = c0; +            ifs->constants[reg][idx + 1] = c1; +            ifs->constant_flags[reg] |= 3 << idx; +            if (reg + 1 > ifs->num_constants) +               ifs->num_constants = reg + 1;              return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO, ONE);           }        } @@ -302,25 +302,26 @@ uint  i915_emit_const4f(struct i915_fp_compile * p,                    float c0, float c1, float c2, float c3)  { +   struct i915_fragment_shader *ifs = p->shader;     unsigned reg;     for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { -      if (p->constant_flags[reg] == 0xf && -          p->constants[reg][0] == c0 && -          p->constants[reg][1] == c1 && -          p->constants[reg][2] == c2 && -          p->constants[reg][3] == c3) { +      if (ifs->constant_flags[reg] == 0xf && +          ifs->constants[reg][0] == c0 && +          ifs->constants[reg][1] == c1 && +          ifs->constants[reg][2] == c2 && +          ifs->constants[reg][3] == c3) {           return UREG(REG_TYPE_CONST, reg);        } -      else if (p->constant_flags[reg] == 0) { +      else if (ifs->constant_flags[reg] == 0) { -         p->constants[reg][0] = c0; -         p->constants[reg][1] = c1; -         p->constants[reg][2] = c2; -         p->constants[reg][3] = c3; -         p->constant_flags[reg] = 0xf; -         if (reg + 1 > p->num_constants) -            p->num_constants = reg + 1; +         ifs->constants[reg][0] = c0; +         ifs->constants[reg][1] = c1; +         ifs->constants[reg][2] = c2; +         ifs->constants[reg][3] = c3; +         ifs->constant_flags[reg] = 0xf; +         if (reg + 1 > ifs->num_constants) +            ifs->num_constants = reg + 1;           return UREG(REG_TYPE_CONST, reg);        }     } @@ -335,41 +336,3 @@ i915_emit_const4fv(struct i915_fp_compile * p, const float * c)  {     return i915_emit_const4f(p, c[0], c[1], c[2], c[3]);  } - - -#if 00000/*UNUSED*/ -/* Reserve a slot in the constant file for a Mesa state parameter. - * These will later need to be tracked on statechanges, but that is - * done elsewhere. - */ -uint -i915_emit_param4fv(struct i915_fp_compile * p, const float * values) -{ -   struct i915_fragment_program *fp = p->fp; -   int i; - -   for (i = 0; i < fp->nr_params; i++) { -      if (fp->param[i].values == values) -         return UREG(REG_TYPE_CONST, fp->param[i].reg); -   } - -   if (p->constants->nr_constants == I915_MAX_CONSTANT || -       fp->nr_params == I915_MAX_CONSTANT) { -      i915_program_error(p, "i915_emit_param4fv: out of constants\n"); -      return 0; -   } - -   { -      int reg = p->constants->nr_constants++; -      int i = fp->nr_params++; - -      assert (p->constant_flags[reg] == 0); -      p->constant_flags[reg] = I915_CONSTFLAG_PARAM; - -      fp->param[i].values = values; -      fp->param[i].reg = reg; - -      return UREG(REG_TYPE_CONST, reg); -   } -} -#endif diff --git a/src/gallium/drivers/i915simple/i915_fpc_translate.c b/src/gallium/drivers/i915simple/i915_fpc_translate.c index 6c1524c768..afe7e25dce 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_translate.c +++ b/src/gallium/drivers/i915simple/i915_fpc_translate.c @@ -34,6 +34,7 @@  #include "pipe/p_shader_tokens.h"  #include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_dump.h"  #include "draw/draw_vertex.h" @@ -97,19 +98,19 @@ negate(int reg, int x, int y, int z, int w)  } +/** + * In the event of a translation failure, we'll generate a simple color + * pass-through program. + */  static void -i915_use_passthrough_shader(struct i915_context *i915) +i915_use_passthrough_shader(struct i915_fragment_shader *fs)  { -   debug_printf("**** Using i915 pass-through fragment shader\n"); - -   i915->current.program = (uint *) MALLOC(sizeof(passthrough)); -   if (i915->current.program) { -      memcpy(i915->current.program, passthrough, sizeof(passthrough)); -      i915->current.program_len = Elements(passthrough); +   fs->program = (uint *) MALLOC(sizeof(passthrough)); +   if (fs->program) { +      memcpy(fs->program, passthrough, sizeof(passthrough)); +      fs->program_len = Elements(passthrough);     } - -   i915->current.num_constants[PIPE_SHADER_FRAGMENT] = 0; -   i915->current.num_user_constants[PIPE_SHADER_FRAGMENT] = 0; +   fs->num_constants = 0;  } @@ -161,9 +162,6 @@ src_vector(struct i915_fp_compile *p,         * We also use a texture coordinate to pass wpos when possible.         */ -      /* use vertex format info to map a slot number to a VF attrib */ -      assert(index < p->vertex_info->num_attribs); -        sem_name = p->input_semantic_name[index];        sem_ind = p->input_semantic_index[index]; @@ -201,7 +199,8 @@ src_vector(struct i915_fp_compile *p,        break;     case TGSI_FILE_IMMEDIATE: -      /* XXX unfinished - need to append immediates onto const buffer */ +      assert(index < p->num_immediates); +      index = p->immediates_map[index];        /* fall-through */     case TGSI_FILE_CONSTANT:        src = UREG(REG_TYPE_CONST, index); @@ -896,6 +895,7 @@ static void  i915_translate_instructions(struct i915_fp_compile *p,                              const struct tgsi_token *tokens)  { +   struct i915_fragment_shader *ifs = p->shader;     struct tgsi_parse_context parse;     tgsi_parse_init( &parse, tokens ); @@ -928,13 +928,54 @@ i915_translate_instructions(struct i915_fp_compile *p,              p->output_semantic_name[ind] = sem;              p->output_semantic_index[ind] = semi;           } +         else if (parse.FullToken.FullDeclaration.Declaration.File +                  == TGSI_FILE_CONSTANT) { +            uint i; +            for (i = parse.FullToken.FullDeclaration.u.DeclarationRange.First; +                 i <= parse.FullToken.FullDeclaration.u.DeclarationRange.Last; +                 i++) { +               assert(ifs->constant_flags[i] == 0x0); +               ifs->constant_flags[i] = I915_CONSTFLAG_USER; +               ifs->num_constants = MAX2(ifs->num_constants, i + 1); +            } +         }           break;        case TGSI_TOKEN_TYPE_IMMEDIATE: -         /* XXX append the immediate to the const buffer... */ +         { +            const struct tgsi_full_immediate *imm +               = &parse.FullToken.FullImmediate; +            const uint pos = p->num_immediates++; +            uint j; +            for (j = 0; j < imm->Immediate.Size; j++) { +               p->immediates[pos][j] = imm->u.ImmediateFloat32[j].Float; +            } +         }           break;        case TGSI_TOKEN_TYPE_INSTRUCTION: +         if (p->first_instruction) { +            /* resolve location of immediates */ +            uint i, j; +            for (i = 0; i < p->num_immediates; i++) { +               /* find constant slot for this immediate */ +               for (j = 0; j < I915_MAX_CONSTANT; j++) { +                  if (ifs->constant_flags[j] == 0x0) { +                     memcpy(ifs->constants[j], +                            p->immediates[i], +                            4 * sizeof(float)); +                     /*printf("immediate %d maps to const %d\n", i, j);*/ +                     ifs->constant_flags[j] = 0xf;  /* all four comps used */ +                     p->immediates_map[i] = j; +                     ifs->num_constants = MAX2(ifs->num_constants, j + 1); +                     break; +                  } +               } +            } + +            p->first_instruction = FALSE; +         } +           i915_translate_instruction(p, &parse.FullToken.FullInstruction);           break; @@ -950,27 +991,28 @@ i915_translate_instructions(struct i915_fp_compile *p,  static struct i915_fp_compile *  i915_init_compile(struct i915_context *i915, -                  const struct pipe_shader_state *fs) +                  struct i915_fragment_shader *ifs)  {     struct i915_fp_compile *p = CALLOC_STRUCT(i915_fp_compile); -   p->shader = i915->fs; - -   p->vertex_info = &i915->current.vertex_info; +   p->shader = ifs; -   /* new constants found during translation get appended after the -    * user-provided constants. +   /* Put new constants at end of const buffer, growing downward. +    * The problem is we don't know how many user-defined constants might +    * be specified with pipe->set_constant_buffer(). +    * Should pre-scan the user's program to determine the highest-numbered +    * constant referenced.      */ -   p->constants = i915->current.constants[PIPE_SHADER_FRAGMENT]; -   p->num_constants = i915->current.num_user_constants[PIPE_SHADER_FRAGMENT]; +   ifs->num_constants = 0; +   memset(ifs->constant_flags, 0, sizeof(ifs->constant_flags)); + +   p->first_instruction = TRUE;     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; @@ -993,6 +1035,7 @@ i915_init_compile(struct i915_context *i915,  static void  i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p)  { +   struct i915_fragment_shader *ifs = p->shader;     unsigned long program_size = (unsigned long) (p->csr - p->program);     unsigned long decl_size = (unsigned long) (p->decl - p->declarations); @@ -1008,19 +1051,13 @@ i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p)     if (p->nr_decl_insn > I915_MAX_DECL_INSN)        i915_program_error(p, "Exceeded max DECL instructions"); -   /* free old program, if present */ -   if (i915->current.program) { -      FREE(i915->current.program); -      i915->current.program_len = 0; -   } -     if (p->error) {        p->NumNativeInstructions = 0;        p->NumNativeAluInstructions = 0;        p->NumNativeTexInstructions = 0;        p->NumNativeTexIndirections = 0; -      i915_use_passthrough_shader(i915); +      i915_use_passthrough_shader(ifs);     }     else {        p->NumNativeInstructions @@ -1034,24 +1071,20 @@ i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p)        /* Copy compilation results to fragment program struct:          */ -      i915->current.program +      assert(!ifs->program); +      ifs->program           = (uint *) MALLOC((program_size + decl_size) * sizeof(uint)); -      if (i915->current.program) { -         i915->current.program_len = program_size + decl_size; +      if (ifs->program) { +         ifs->program_len = program_size + decl_size; -         memcpy(i915->current.program, +         memcpy(ifs->program,                  p->declarations,                   decl_size * sizeof(uint)); -         memcpy(i915->current.program + decl_size,  +         memcpy(ifs->program + decl_size,                   p->program,                   program_size * sizeof(uint));        } - -      /* update number of constants */ -      i915->current.num_constants[PIPE_SHADER_FRAGMENT] = p->num_constants; -      assert(i915->current.num_constants[PIPE_SHADER_FRAGMENT] -             >= i915->current.num_user_constants[PIPE_SHADER_FRAGMENT]);     }     /* Release the compilation struct:  @@ -1085,7 +1118,7 @@ i915_find_wpos_space(struct i915_fp_compile *p)        i915_program_error(p, "No free texcoord for wpos value");     }  #else -   if (p->shader->input_semantic_name[0] == TGSI_SEMANTIC_POSITION) { +   if (p->shader->state.input_semantic_name[0] == TGSI_SEMANTIC_POSITION) {        /* frag shader using the fragment position input */  #if 0        assert(0); @@ -1106,7 +1139,7 @@ static void  i915_fixup_depth_write(struct i915_fp_compile *p)  {     /* XXX assuming pos/depth is always in output[0] */ -   if (p->shader->output_semantic_name[0] == TGSI_SEMANTIC_POSITION) { +   if (p->shader->state.output_semantic_name[0] == TGSI_SEMANTIC_POSITION) {        const uint depth = UREG(REG_TYPE_OD, 0);        i915_emit_arith(p, @@ -1121,13 +1154,18 @@ i915_fixup_depth_write(struct i915_fp_compile *p)  void -i915_translate_fragment_program( struct i915_context *i915 ) +i915_translate_fragment_program( struct i915_context *i915, +                                 struct i915_fragment_shader *fs)  { -   struct i915_fp_compile *p = i915_init_compile(i915, i915->fs); -   const struct tgsi_token *tokens = i915->fs->tokens; +   struct i915_fp_compile *p = i915_init_compile(i915, fs); +   const struct tgsi_token *tokens = fs->state.tokens;     i915_find_wpos_space(p); +#if 0 +   tgsi_dump(tokens, 0); +#endif +     i915_translate_instructions(p, tokens);     i915_fixup_depth_write(p); diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index e055eed7e0..e4288d4e31 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -38,6 +38,7 @@  #include "i915_reg.h"  #include "i915_state.h"  #include "i915_state_inlines.h" +#include "i915_fpc.h"  /* The i915 (and related graphics cores) do not support GL_CLAMP.  The @@ -416,26 +417,47 @@ static void i915_set_polygon_stipple( struct pipe_context *pipe,  } -static void * i915_create_fs_state(struct pipe_context *pipe, -                                   const struct pipe_shader_state *templ) + +static void * +i915_create_fs_state(struct pipe_context *pipe, +                     const struct pipe_shader_state *templ)  { -   return 0; +   struct i915_context *i915 = i915_context(pipe); +   struct i915_fragment_shader *ifs = CALLOC_STRUCT(i915_fragment_shader); +   if (!ifs) +      return NULL; + +   ifs->state = *templ; + +   /* The shader's compiled to i915 instructions here */ +   i915_translate_fragment_program(i915, ifs); + +   return ifs;  } -static void i915_bind_fs_state(struct pipe_context *pipe, void *fs) +static void +i915_bind_fs_state(struct pipe_context *pipe, void *shader)  {     struct i915_context *i915 = i915_context(pipe); -   i915->fs = (struct pipe_shader_state *)fs; +   i915->fs = (struct i915_fragment_shader*) shader;     i915->dirty |= I915_NEW_FS;  } -static void i915_delete_fs_state(struct pipe_context *pipe, void *shader) +static +void i915_delete_fs_state(struct pipe_context *pipe, void *shader)  { -   /*do nothing*/ +   struct i915_fragment_shader *ifs = (struct i915_fragment_shader *) shader; + +   if (ifs->program) +      FREE(ifs->program); +   ifs->program_len = 0; + +   FREE(ifs);  } +  static void *  i915_create_vs_state(struct pipe_context *pipe,                       const struct pipe_shader_state *templ) diff --git a/src/gallium/drivers/i915simple/i915_state_derived.c b/src/gallium/drivers/i915simple/i915_state_derived.c index 4767584fc6..f654f543cc 100644 --- a/src/gallium/drivers/i915simple/i915_state_derived.c +++ b/src/gallium/drivers/i915simple/i915_state_derived.c @@ -43,7 +43,7 @@   */  static void calculate_vertex_layout( struct i915_context *i915 )  { -   const struct pipe_shader_state *fs = i915->fs; +   const struct pipe_shader_state *fs = &i915->fs->state;     const enum interp_mode colorInterp = i915->rasterizer->color_interp;     struct vertex_info vinfo;     uint front0 = 0, back0 = 0, front1 = 0, back1 = 0; @@ -164,7 +164,6 @@ void i915_update_derived( struct i915_context *i915 )        i915_update_dynamic( i915 );     if (i915->dirty & I915_NEW_FS) { -      i915_translate_fragment_program(i915);        i915->hardware_dirty |= I915_HW_PROGRAM; /* XXX right? */     } diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index 3339287f49..6bbaac4e34 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -99,7 +99,11 @@ i915_emit_hardware_state(struct i915_context *i915 )                               2 + I915_TEX_UNITS*3 +                                2 + I915_TEX_UNITS*3 +                               2 + I915_MAX_CONSTANT*4 +  +#if 0                               i915->current.program_len +  +#else +                             i915->fs->program_len +  +#endif                               6                              ) * 3/2; /* plus 50% margin */     const unsigned relocs = ( I915_TEX_UNITS + @@ -325,15 +329,34 @@ i915_emit_hardware_state(struct i915_context *i915 )     /* 2 + I915_MAX_CONSTANT*4 dwords, 0 relocs */     if (i915->hardware_dirty & I915_HW_PROGRAM)     { -      const uint nr = i915->current.num_constants[PIPE_SHADER_FRAGMENT]; -      assert(nr <= I915_MAX_CONSTANT); -      if (nr > 0) { -         const uint *c -            = (const uint *) i915->current.constants[PIPE_SHADER_FRAGMENT]; +      /* Collate the user-defined constants with the fragment shader's +       * immediates according to the constant_flags[] array. +       */ +      const uint nr = i915->fs->num_constants; +      if (nr) {           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++) { +            const uint *c; +            if (i915->fs->constant_flags[i] == I915_CONSTFLAG_USER) { +               /* grab user-defined constant */ +               c = (uint *) i915->current.constants[PIPE_SHADER_FRAGMENT][i]; +            } +            else { +               /* emit program constant */ +               c = (uint *) i915->fs->constants[i]; +            } +#if 0 /* debug */ +            { +               float *f = (float *) c; +               printf("Const %2d: %f %f %f %f %s\n", i, f[0], f[1], f[2], f[3], +                      (i915->fs->constant_flags[i] == I915_CONSTFLAG_USER +                       ? "user" : "immediate")); +            } +#endif              OUT_BATCH(*c++);              OUT_BATCH(*c++);              OUT_BATCH(*c++); @@ -348,9 +371,9 @@ i915_emit_hardware_state(struct i915_context *i915 )     {        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]); +      assert(i915->fs->program_len > 0); +      for (i = 0; i < i915->fs->program_len; i++) { +         OUT_BATCH(i915->fs->program[i]);        }     } | 
