Ejemplo n.º 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;
}
Ejemplo n.º 2
0
bool
brw_fs_precompile(struct gl_context *ctx,
                  struct gl_shader_program *shader_prog,
                  struct gl_program *prog)
{
   struct brw_context *brw = brw_context(ctx);
   struct brw_wm_prog_key key;

   struct gl_fragment_program *fp = (struct gl_fragment_program *) prog;
   struct brw_fragment_program *bfp = brw_fragment_program(fp);
   bool program_uses_dfdy = fp->UsesDFdy;

   memset(&key, 0, sizeof(key));

   if (brw->gen < 6) {
      if (fp->UsesKill)
         key.iz_lookup |= IZ_PS_KILL_ALPHATEST_BIT;

      if (fp->Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
         key.iz_lookup |= IZ_PS_COMPUTES_DEPTH_BIT;

      /* Just assume depth testing. */
      key.iz_lookup |= IZ_DEPTH_TEST_ENABLE_BIT;
      key.iz_lookup |= IZ_DEPTH_WRITE_ENABLE_BIT;
   }

   if (brw->gen < 6 || _mesa_bitcount_64(fp->Base.InputsRead &
                                         BRW_FS_VARYING_INPUT_MASK) > 16)
      key.input_slots_valid = fp->Base.InputsRead | VARYING_BIT_POS;

   brw_setup_tex_for_precompile(brw, &key.tex, &fp->Base);

   if (fp->Base.InputsRead & VARYING_BIT_POS) {
      key.drawable_height = ctx->DrawBuffer->Height;
   }

   key.nr_color_regions = _mesa_bitcount_64(fp->Base.OutputsWritten &
         ~(BITFIELD64_BIT(FRAG_RESULT_DEPTH) |
         BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK)));

   if ((fp->Base.InputsRead & VARYING_BIT_POS) || program_uses_dfdy) {
      key.render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer) ||
                          key.nr_color_regions > 1;
   }

   key.program_string_id = bfp->id;

   uint32_t old_prog_offset = brw->wm.base.prog_offset;
   struct brw_wm_prog_data *old_prog_data = brw->wm.prog_data;

   bool success = brw_codegen_wm_prog(brw, shader_prog, bfp, &key);

   brw->wm.base.prog_offset = old_prog_offset;
   brw->wm.prog_data = old_prog_data;

   return success;
}
Ejemplo n.º 3
0
static void brwDeleteProgram( GLcontext *ctx,
			      struct gl_program *prog )
{
   if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
      struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog;
      struct brw_fragment_program *brw_fprog = brw_fragment_program(fprog);
      dri_bo_unreference(brw_fprog->const_buffer);
   }

   _mesa_delete_program( ctx, prog );
}
Ejemplo n.º 4
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);
   }
}
static GLboolean
brwProgramStringNotify(struct gl_context *ctx,
		       GLenum target,
		       struct gl_program *prog)
{
   struct brw_context *brw = brw_context(ctx);
   const struct brw_compiler *compiler = brw->intelScreen->compiler;

   switch (target) {
   case 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 (newFP == curFP)
	 brw->ctx.NewDriverState |= BRW_NEW_FRAGMENT_PROGRAM;
      newFP->id = get_new_program_id(brw->intelScreen);

      brw_add_texrect_params(prog);

      prog->nir = brw_create_nir(brw, NULL, prog, MESA_SHADER_FRAGMENT, true);

      brw_fs_precompile(ctx, NULL, prog);
      break;
   }
   case 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->ctx.NewDriverState |= BRW_NEW_VERTEX_PROGRAM;
      if (newVP->program.IsPositionInvariant) {
	 _mesa_insert_mvp_code(ctx, &newVP->program);
      }
      newVP->id = get_new_program_id(brw->intelScreen);

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

      brw_add_texrect_params(prog);

      prog->nir = brw_create_nir(brw, NULL, prog, MESA_SHADER_VERTEX,
                                 compiler->scalar_stage[MESA_SHADER_VERTEX]);

      brw_vs_precompile(ctx, NULL, prog);
      break;
   }
   default:
      /*
       * driver->ProgramStringNotify is only called for ARB programs, fixed
       * function vertex programs, and ir_to_mesa (which isn't used by the
       * i965 back-end).  Therefore, even after geometry shaders are added,
       * this function should only ever be called with a target of
       * GL_VERTEX_PROGRAM_ARB or GL_FRAGMENT_PROGRAM_ARB.
       */
      unreachable("Unexpected target in brwProgramStringNotify");
   }

   return true;
}
Ejemplo n.º 6
0
static GLboolean brwProgramStringNotify( struct gl_context *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 (newFP == curFP)
	 brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
      newFP->id = brw->program_id++;      

      /* 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
	  && shader_program->_LinkedShaders[MESA_SHADER_FRAGMENT]) {
	 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;
}