Beispiel #1
0
bool
brw_wm_do_compile(struct brw_context *brw,
                  struct brw_wm_compile *c)
{
   struct gl_context *ctx = &brw->ctx;
   struct gl_shader *fs = NULL;

   if (c->shader_prog)
      fs = c->shader_prog->_LinkedShaders[MESA_SHADER_FRAGMENT];

   /* Allocate the references to the uniforms that will end up in the
    * prog_data associated with the compiled program, and which will be freed
    * by the state cache.
    */
   int param_count;
   if (fs) {
      param_count = fs->num_uniform_components;
   } else {
      param_count = c->fp->program.Base.Parameters->NumParameters * 4;
   }
   /* The backend also sometimes adds params for texture size. */
   param_count += 2 * ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits;
   c->prog_data.base.param = rzalloc_array(NULL, const float *, param_count);
   c->prog_data.base.pull_param =
      rzalloc_array(NULL, const float *, param_count);
   c->prog_data.base.nr_params = param_count;

   c->prog_data.barycentric_interp_modes =
      brw_compute_barycentric_interp_modes(brw, c->key.flat_shade,
                                           c->key.persample_shading,
                                           &c->fp->program);

   c->program = brw_wm_fs_emit(brw, c,
         &c->fp->program, c->shader_prog, &c->program_size);
   if (c->program == NULL)
      return false;

   /* Scratch space is used for register spilling */
   if (c->last_scratch) {
      perf_debug("Fragment shader triggered register spilling.  "
                 "Try reducing the number of live scalar values to "
                 "improve performance.\n");

      c->prog_data.total_scratch = brw_get_scratch_size(c->last_scratch);
   }

   if (unlikely(INTEL_DEBUG & DEBUG_WM))
      fprintf(stderr, "\n");

   return true;
}
Beispiel #2
0
/**
 * All Mesa program -> GPU code generation goes through this function.
 * Depending on the instructions used (i.e. flow control instructions)
 * we'll use one of two code generators.
 */
bool
brw_codegen_wm_prog(struct brw_context *brw,
                    struct gl_shader_program *prog,
                    struct brw_fragment_program *fp,
                    struct brw_wm_prog_key *key)
{
   struct gl_context *ctx = &brw->ctx;
   void *mem_ctx = ralloc_context(NULL);
   struct brw_wm_prog_data prog_data;
   const GLuint *program;
   struct gl_shader *fs = NULL;
   GLuint program_size;

   if (prog)
      fs = prog->_LinkedShaders[MESA_SHADER_FRAGMENT];

   memset(&prog_data, 0, sizeof(prog_data));
   /* key->alpha_test_func means simulating alpha testing via discards,
    * so the shader definitely kills pixels.
    */
   prog_data.uses_kill = fp->program.UsesKill || key->alpha_test_func;
   prog_data.uses_omask =
      fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK);
   prog_data.computed_depth_mode = computed_depth_mode(&fp->program);

   /* Use ALT floating point mode for ARB programs so that 0^0 == 1. */
   if (!prog)
      prog_data.base.use_alt_mode = true;

   /* Allocate the references to the uniforms that will end up in the
    * prog_data associated with the compiled program, and which will be freed
    * by the state cache.
    */
   int param_count;
   if (fs) {
      param_count = fs->num_uniform_components;
   } else {
      param_count = fp->program.Base.Parameters->NumParameters * 4;
   }
   /* The backend also sometimes adds params for texture size. */
   param_count += 2 * ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits;
   prog_data.base.param =
      rzalloc_array(NULL, const gl_constant_value *, param_count);
   prog_data.base.pull_param =
      rzalloc_array(NULL, const gl_constant_value *, param_count);
   prog_data.base.nr_params = param_count;

   prog_data.barycentric_interp_modes =
      brw_compute_barycentric_interp_modes(brw, key->flat_shade,
                                           key->persample_shading,
                                           &fp->program);

   program = brw_wm_fs_emit(brw, mem_ctx, key, &prog_data,
                            &fp->program, prog, &program_size);
   if (program == NULL) {
      ralloc_free(mem_ctx);
      return false;
   }

   if (prog_data.base.total_scratch) {
      brw_get_scratch_bo(brw, &brw->wm.base.scratch_bo,
			 prog_data.base.total_scratch * brw->max_wm_threads);
   }

   if (unlikely(INTEL_DEBUG & DEBUG_WM))
      fprintf(stderr, "\n");

   brw_upload_cache(&brw->cache, BRW_CACHE_FS_PROG,
		    key, sizeof(struct brw_wm_prog_key),
		    program, program_size,
		    &prog_data, sizeof(prog_data),
		    &brw->wm.base.prog_offset, &brw->wm.prog_data);

   ralloc_free(mem_ctx);

   return true;
}
Beispiel #3
0
/**
 * All Mesa program -> GPU code generation goes through this function.
 * Depending on the instructions used (i.e. flow control instructions)
 * we'll use one of two code generators.
 */
bool do_wm_prog(struct brw_context *brw,
		struct gl_shader_program *prog,
		struct brw_fragment_program *fp,
		struct brw_wm_prog_key *key)
{
   struct brw_wm_compile *c;
   const GLuint *program;
   struct gl_shader *fs = NULL;
   GLuint program_size;

   if (prog)
      fs = prog->_LinkedShaders[MESA_SHADER_FRAGMENT];

   c = rzalloc(NULL, struct brw_wm_compile);

   /* Allocate the references to the uniforms that will end up in the
    * prog_data associated with the compiled program, and which will be freed
    * by the state cache.
    */
   int param_count;
   if (fs) {
      param_count = fs->num_uniform_components;
   } else {
      param_count = fp->program.Base.Parameters->NumParameters * 4;
   }
   /* The backend also sometimes adds params for texture size. */
   param_count += 2 * BRW_MAX_TEX_UNIT;
   c->prog_data.param = rzalloc_array(NULL, const float *, param_count);
   c->prog_data.pull_param = rzalloc_array(NULL, const float *, param_count);

   memcpy(&c->key, key, sizeof(*key));

   c->prog_data.barycentric_interp_modes =
      brw_compute_barycentric_interp_modes(brw, c->key.flat_shade,
                                           &fp->program);

   program = brw_wm_fs_emit(brw, c, &fp->program, prog, &program_size);
   if (program == NULL)
      return false;

   /* Scratch space is used for register spilling */
   if (c->last_scratch) {
      perf_debug("Fragment shader triggered register spilling.  "
                 "Try reducing the number of live scalar values to "
                 "improve performance.\n");

      c->prog_data.total_scratch = brw_get_scratch_size(c->last_scratch);

      brw_get_scratch_bo(brw, &brw->wm.scratch_bo,
			 c->prog_data.total_scratch * brw->max_wm_threads);
   }

   if (unlikely(INTEL_DEBUG & DEBUG_WM))
      fprintf(stderr, "\n");

   brw_upload_cache(&brw->cache, BRW_WM_PROG,
		    &c->key, sizeof(c->key),
		    program, program_size,
		    &c->prog_data, sizeof(c->prog_data),
		    &brw->wm.prog_offset, &brw->wm.prog_data);

   ralloc_free(c);

   return true;
}
Beispiel #4
0
/**
 * All Mesa program -> GPU code generation goes through this function.
 * Depending on the instructions used (i.e. flow control instructions)
 * we'll use one of two code generators.
 */
bool do_wm_prog(struct brw_context *brw,
		struct gl_shader_program *prog,
		struct brw_fragment_program *fp,
		struct brw_wm_prog_key *key)
{
   struct gl_context *ctx = &brw->ctx;
   void *mem_ctx = ralloc_context(NULL);
   struct brw_wm_prog_data prog_data;
   const GLuint *program;
   struct gl_shader *fs = NULL;
   GLuint program_size;

   if (prog)
      fs = prog->_LinkedShaders[MESA_SHADER_FRAGMENT];

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

   /* Allocate the references to the uniforms that will end up in the
    * prog_data associated with the compiled program, and which will be freed
    * by the state cache.
    */
   int param_count;
   if (fs) {
      param_count = fs->num_uniform_components;
   } else {
      param_count = fp->program.Base.Parameters->NumParameters * 4;
   }
   /* The backend also sometimes adds params for texture size. */
   param_count += 2 * ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits;
   prog_data.base.param =
      rzalloc_array(NULL, const gl_constant_value *, param_count);
   prog_data.base.pull_param =
      rzalloc_array(NULL, const gl_constant_value *, param_count);
   prog_data.base.nr_params = param_count;

   prog_data.barycentric_interp_modes =
      brw_compute_barycentric_interp_modes(brw, key->flat_shade,
                                           key->persample_shading,
                                           &fp->program);

   program = brw_wm_fs_emit(brw, mem_ctx, key, &prog_data,
                            &fp->program, prog, &program_size);
   if (program == NULL) {
      ralloc_free(mem_ctx);
      return false;
   }

   if (prog_data.total_scratch) {
      brw_get_scratch_bo(brw, &brw->wm.base.scratch_bo,
			 prog_data.total_scratch * brw->max_wm_threads);
   }

   if (unlikely(INTEL_DEBUG & DEBUG_WM))
      fprintf(stderr, "\n");

   brw_upload_cache(&brw->cache, BRW_WM_PROG,
		    key, sizeof(struct brw_wm_prog_key),
		    program, program_size,
		    &prog_data, sizeof(prog_data),
		    &brw->wm.base.prog_offset, &brw->wm.prog_data);

   ralloc_free(mem_ctx);

   return true;
}