Beispiel #1
0
static GLboolean brwProgramStringNotify( GLcontext *ctx,
        GLenum target,
        struct gl_program *prog )
{
    struct brw_context *brw = brw_context(ctx);
    int i;

    if (target == GL_FRAGMENT_PROGRAM_ARB) {
        struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog;
        struct brw_fragment_program *newFP = brw_fragment_program(fprog);
        const struct brw_fragment_program *curFP =
            brw_fragment_program_const(brw->fragment_program);

        if (fprog->FogOption) {
            _mesa_append_fog_code(ctx, fprog);
            fprog->FogOption = GL_NONE;
        }

        if (newFP == curFP)
            brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
        newFP->id = brw->program_id++;
        newFP->isGLSL = brw_wm_is_glsl(fprog);
    }
    else if (target == GL_VERTEX_PROGRAM_ARB) {
        struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog;
        struct brw_vertex_program *newVP = brw_vertex_program(vprog);
        const struct brw_vertex_program *curVP =
            brw_vertex_program_const(brw->vertex_program);

        if (newVP == curVP)
            brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM;
        if (newVP->program.IsPositionInvariant) {
            _mesa_insert_mvp_code(ctx, &newVP->program);
        }
        newVP->id = brw->program_id++;

        /* Also tell tnl about it:
         */
        _tnl_program_string(ctx, target, prog);
    }

    /* Reject programs with subroutines, which are totally broken at the moment
     * (all program flows return when any program flow returns, and
     * the VS also hangs if a function call calls a function.
     *
     * See piglit glsl-{vs,fs}-functions-[23] tests.
     */
    for (i = 0; i < prog->NumInstructions; i++) {
        if (prog->Instructions[i].Opcode == OPCODE_CAL) {
            shader_error(ctx, prog,
                         "i965 driver doesn't yet support uninlined function "
                         "calls.  Move to using a single return statement at "
                         "the end of the function to work around it.");
            return GL_FALSE;
        }
    }

    return GL_TRUE;
}
static void
i915ProgramStringNotify(GLcontext * ctx,
                        GLenum target, struct gl_program *prog)
{
   if (target == GL_FRAGMENT_PROGRAM_ARB) {
      struct i915_fragment_program *p = (struct i915_fragment_program *) prog;
      p->translated = 0;

      /* Hack: make sure fog is correctly enabled according to this
       * fragment program's fog options.
       */
      if (p->FragProg.FogOption) {
         /* add extra instructions to do fog, then turn off FogOption field */
         _mesa_append_fog_code(ctx, &p->FragProg);
         p->FragProg.FogOption = GL_NONE;
      }
   }

   _tnl_program_string(ctx, target, prog);
}
Beispiel #3
0
static void brwProgramStringNotify( GLcontext *ctx,
				    GLenum target,
				    struct gl_program *prog )
{
   struct brw_context *brw = brw_context(ctx);

   if (target == GL_FRAGMENT_PROGRAM_ARB) {
      struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog;
      struct brw_fragment_program *newFP = brw_fragment_program(fprog);
      const struct brw_fragment_program *curFP =
         brw_fragment_program_const(brw->fragment_program);

      if (fprog->FogOption) {
         _mesa_append_fog_code(ctx, fprog);
         fprog->FogOption = GL_NONE;
      }

      if (newFP == curFP)
	 brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
      newFP->id = brw->program_id++;      
      newFP->isGLSL = brw_wm_is_glsl(fprog);
   }
   else if (target == GL_VERTEX_PROGRAM_ARB) {
      struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog;
      struct brw_vertex_program *newVP = brw_vertex_program(vprog);
      const struct brw_vertex_program *curVP =
         brw_vertex_program_const(brw->vertex_program);

      if (newVP == curVP)
	 brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM;
      if (newVP->program.IsPositionInvariant) {
	 _mesa_insert_mvp_code(ctx, &newVP->program);
      }
      newVP->id = brw->program_id++;      

      /* Also tell tnl about it:
       */
      _tnl_program_string(ctx, target, prog);
   }
}
void
_mesa_parse_arb_fragment_program(struct gl_context* ctx, GLenum target,
                                 const GLvoid *str, GLsizei len,
                                 struct gl_fragment_program *program)
{
   struct gl_program prog;
   struct asm_parser_state state;
   GLuint i;

   ASSERT(target == GL_FRAGMENT_PROGRAM_ARB);

   memset(&prog, 0, sizeof(prog));
   memset(&state, 0, sizeof(state));
   state.prog = &prog;

   if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len,
				&state)) {
      /* Error in the program. Just return. */
      return;
   }

   if (program->Base.String != NULL)
      free(program->Base.String);

   /* Copy the relevant contents of the arb_program struct into the
    * fragment_program struct.
    */
   program->Base.String          = prog.String;
   program->Base.NumInstructions = prog.NumInstructions;
   program->Base.NumTemporaries  = prog.NumTemporaries;
   program->Base.NumParameters   = prog.NumParameters;
   program->Base.NumAttributes   = prog.NumAttributes;
   program->Base.NumAddressRegs  = prog.NumAddressRegs;
   program->Base.NumNativeInstructions = prog.NumNativeInstructions;
   program->Base.NumNativeTemporaries = prog.NumNativeTemporaries;
   program->Base.NumNativeParameters = prog.NumNativeParameters;
   program->Base.NumNativeAttributes = prog.NumNativeAttributes;
   program->Base.NumNativeAddressRegs = prog.NumNativeAddressRegs;
   program->Base.NumAluInstructions   = prog.NumAluInstructions;
   program->Base.NumTexInstructions   = prog.NumTexInstructions;
   program->Base.NumTexIndirections   = prog.NumTexIndirections;
   program->Base.NumNativeAluInstructions = prog.NumAluInstructions;
   program->Base.NumNativeTexInstructions = prog.NumTexInstructions;
   program->Base.NumNativeTexIndirections = prog.NumTexIndirections;
   program->Base.InputsRead      = prog.InputsRead;
   program->Base.OutputsWritten  = prog.OutputsWritten;
   program->Base.IndirectRegisterFiles = prog.IndirectRegisterFiles;
   for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) {
      program->Base.TexturesUsed[i] = prog.TexturesUsed[i];
      if (prog.TexturesUsed[i])
         program->Base.SamplersUsed |= (1 << i);
   }
   program->Base.ShadowSamplers = prog.ShadowSamplers;
   program->OriginUpperLeft = state.option.OriginUpperLeft;
   program->PixelCenterInteger = state.option.PixelCenterInteger;

   program->UsesKill            = state.fragment.UsesKill;
   program->UsesDFdy            = state.fragment.UsesDFdy;

   if (program->Base.Instructions)
      free(program->Base.Instructions);
   program->Base.Instructions = prog.Instructions;

   if (program->Base.Parameters)
      _mesa_free_parameter_list(program->Base.Parameters);
   program->Base.Parameters    = prog.Parameters;

   /* Append fog instructions now if the program has "OPTION ARB_fog_exp"
    * or similar.  We used to leave this up to drivers, but it appears
    * there's no hardware that wants to do fog in a discrete stage separate
    * from the fragment shader.
    */
   if (state.option.Fog != OPTION_NONE) {
      static const GLenum fog_modes[4] = {
	 GL_NONE, GL_EXP, GL_EXP2, GL_LINEAR
      };

      /* XXX: we should somehow recompile this to remove clamping if disabled
       * On the ATI driver, this is unclampled if fragment clamping is disabled
       */
      _mesa_append_fog_code(ctx, program, fog_modes[state.option.Fog], GL_TRUE);
   }

#if DEBUG_FP
   printf("____________Fragment program %u ________\n", program->Base.Id);
   _mesa_print_program(&program->Base);
#endif
}
Beispiel #5
0
static GLboolean brwProgramStringNotify( GLcontext *ctx,
        GLenum target,
        struct gl_program *prog )
{
    struct brw_context *brw = brw_context(ctx);
    int i;

    if (target == GL_FRAGMENT_PROGRAM_ARB) {
        struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog;
        struct brw_fragment_program *newFP = brw_fragment_program(fprog);
        const struct brw_fragment_program *curFP =
            brw_fragment_program_const(brw->fragment_program);
        struct gl_shader_program *shader_program;

        if (fprog->FogOption) {
            _mesa_append_fog_code(ctx, fprog);
            fprog->FogOption = GL_NONE;
        }

        if (newFP == curFP)
            brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
        newFP->id = brw->program_id++;
        newFP->isGLSL = brw_wm_is_glsl(fprog);

        /* Don't reject fragment shaders for their Mesa IR state when we're
         * using the new FS backend.
         */
        shader_program = _mesa_lookup_shader_program(ctx, prog->Id);
        if (shader_program) {
            for (i = 0; i < shader_program->_NumLinkedShaders; i++) {
                struct brw_shader *shader;

                shader = (struct brw_shader *)shader_program->_LinkedShaders[i];
                if (shader->base.Type == GL_FRAGMENT_SHADER && shader->ir) {
                    return GL_TRUE;
                }
            }
        }
    }
    else if (target == GL_VERTEX_PROGRAM_ARB) {
        struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog;
        struct brw_vertex_program *newVP = brw_vertex_program(vprog);
        const struct brw_vertex_program *curVP =
            brw_vertex_program_const(brw->vertex_program);

        if (newVP == curVP)
            brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM;
        if (newVP->program.IsPositionInvariant) {
            _mesa_insert_mvp_code(ctx, &newVP->program);
        }
        newVP->id = brw->program_id++;

        /* Also tell tnl about it:
         */
        _tnl_program_string(ctx, target, prog);
    }

    /* Reject programs with subroutines, which are totally broken at the moment
     * (all program flows return when any program flow returns, and
     * the VS also hangs if a function call calls a function.
     *
     * See piglit glsl-{vs,fs}-functions-[23] tests.
     */
    for (i = 0; i < prog->NumInstructions; i++) {
        struct prog_instruction *inst = prog->Instructions + i;
        int r;

        if (prog->Instructions[i].Opcode == OPCODE_CAL) {
            shader_error(ctx, prog,
                         "i965 driver doesn't yet support uninlined function "
                         "calls.  Move to using a single return statement at "
                         "the end of the function to work around it.\n");
            return GL_FALSE;
        }

        if (prog->Instructions[i].Opcode == OPCODE_RET) {
            shader_error(ctx, prog,
                         "i965 driver doesn't yet support \"return\" "
                         "from main().\n");
            return GL_FALSE;
        }

        for (r = 0; r < _mesa_num_inst_src_regs(inst->Opcode); r++) {
            if (prog->Instructions[i].SrcReg[r].RelAddr &&
                    prog->Instructions[i].SrcReg[r].File == PROGRAM_INPUT) {
                shader_error(ctx, prog,
                             "Variable indexing of shader inputs unsupported\n");
                return GL_FALSE;
            }
        }

        if (target == GL_FRAGMENT_PROGRAM_ARB &&
                prog->Instructions[i].DstReg.RelAddr &&
                prog->Instructions[i].DstReg.File == PROGRAM_OUTPUT) {
            shader_error(ctx, prog,
                         "Variable indexing of FS outputs unsupported\n");
            return GL_FALSE;
        }
        if (target == GL_FRAGMENT_PROGRAM_ARB) {
            if ((prog->Instructions[i].DstReg.RelAddr &&
                    prog->Instructions[i].DstReg.File == PROGRAM_TEMPORARY) ||
                    (prog->Instructions[i].SrcReg[0].RelAddr &&
                     prog->Instructions[i].SrcReg[0].File == PROGRAM_TEMPORARY) ||
                    (prog->Instructions[i].SrcReg[1].RelAddr &&
                     prog->Instructions[i].SrcReg[1].File == PROGRAM_TEMPORARY) ||
                    (prog->Instructions[i].SrcReg[2].RelAddr &&
                     prog->Instructions[i].SrcReg[2].File == PROGRAM_TEMPORARY)) {
                shader_error(ctx, prog,
                             "Variable indexing of variable arrays in the FS "
                             "unsupported\n");
                return GL_FALSE;
            }
        }
    }

    return GL_TRUE;
}