Example #1
0
/**
*	Main run function of the PP queue. Called on swapbuffers/flush.
*
*	Runs all requested filters in order and handles shuffling the temp
*	buffers in between.
*/
void
pp_run(struct pp_queue_t *ppq, struct pipe_resource *in,
       struct pipe_resource *out, struct pipe_resource *indepth)
{
   struct pipe_resource *refin = NULL, *refout = NULL;
   unsigned int i;
   struct cso_context *cso = ppq->p->cso;

   if (ppq->n_filters == 0)
      return;

   assert(ppq->pp_queue);
   assert(ppq->tmp[0]);

   if (in->width0 != ppq->p->framebuffer.width ||
       in->height0 != ppq->p->framebuffer.height) {
      pp_debug("Resizing the temp pp buffers\n");
      pp_free_fbos(ppq);
      pp_init_fbos(ppq, in->width0, in->height0);
   }

   if (in == out && ppq->n_filters == 1) {
      /* Make a copy of in to tmp[0] in this case. */
      unsigned int w = ppq->p->framebuffer.width;
      unsigned int h = ppq->p->framebuffer.height;


      pp_blit(ppq->p->pipe, in, 0, 0,
              w, h, 0, ppq->tmps[0],
              0, 0, w, h);

      in = ppq->tmp[0];
   }

   /* save state (restored below) */
   cso_save_state(cso, (CSO_BIT_BLEND |
                        CSO_BIT_DEPTH_STENCIL_ALPHA |
                        CSO_BIT_FRAGMENT_SHADER |
                        CSO_BIT_FRAMEBUFFER |
                        CSO_BIT_TESSCTRL_SHADER |
                        CSO_BIT_TESSEVAL_SHADER |
                        CSO_BIT_GEOMETRY_SHADER |
                        CSO_BIT_RASTERIZER |
                        CSO_BIT_SAMPLE_MASK |
                        CSO_BIT_MIN_SAMPLES |
                        CSO_BIT_FRAGMENT_SAMPLERS |
                        CSO_BIT_FRAGMENT_SAMPLER_VIEWS |
                        CSO_BIT_STENCIL_REF |
                        CSO_BIT_STREAM_OUTPUTS |
                        CSO_BIT_VERTEX_ELEMENTS |
                        CSO_BIT_VERTEX_SHADER |
                        CSO_BIT_VIEWPORT |
                        CSO_BIT_AUX_VERTEX_BUFFER_SLOT |
                        CSO_BIT_RENDER_CONDITION));
   cso_save_constant_buffer_slot0(cso, PIPE_SHADER_VERTEX);
   cso_save_constant_buffer_slot0(cso, PIPE_SHADER_FRAGMENT);

   /* set default state */
   cso_set_sample_mask(cso, ~0);
   cso_set_min_samples(cso, 1);
   cso_set_stream_outputs(cso, 0, NULL, NULL);
   cso_set_tessctrl_shader_handle(cso, NULL);
   cso_set_tesseval_shader_handle(cso, NULL);
   cso_set_geometry_shader_handle(cso, NULL);
   cso_set_render_condition(cso, NULL, FALSE, 0);

   // Kept only for this frame.
   pipe_resource_reference(&ppq->depth, indepth);
   pipe_resource_reference(&refin, in);
   pipe_resource_reference(&refout, out);

   switch (ppq->n_filters) {
   case 0:
      /* Failsafe, but never reached. */
      break;
   case 1:                     /* No temp buf */
      ppq->pp_queue[0] (ppq, in, out, 0);
      break;
   case 2:                     /* One temp buf */

      ppq->pp_queue[0] (ppq, in, ppq->tmp[0], 0);
      ppq->pp_queue[1] (ppq, ppq->tmp[0], out, 1);

      break;
   default:                    /* Two temp bufs */
      assert(ppq->tmp[1]);
      ppq->pp_queue[0] (ppq, in, ppq->tmp[0], 0);

      for (i = 1; i < (ppq->n_filters - 1); i++) {
         if (i % 2 == 0)
            ppq->pp_queue[i] (ppq, ppq->tmp[1], ppq->tmp[0], i);

         else
            ppq->pp_queue[i] (ppq, ppq->tmp[0], ppq->tmp[1], i);
      }

      if (i % 2 == 0)
         ppq->pp_queue[i] (ppq, ppq->tmp[1], out, i);

      else
         ppq->pp_queue[i] (ppq, ppq->tmp[0], out, i);

      break;
   }

   /* restore state we changed */
   cso_restore_state(cso);
   cso_restore_constant_buffer_slot0(cso, PIPE_SHADER_VERTEX);
   cso_restore_constant_buffer_slot0(cso, PIPE_SHADER_FRAGMENT);

   pipe_resource_reference(&ppq->depth, NULL);
   pipe_resource_reference(&refin, NULL);
   pipe_resource_reference(&refout, NULL);
}
Example #2
0
/**
 * Setup pipeline state prior to rendering the bitmap textured quad.
 */
static void
setup_render_state(struct gl_context *ctx,
                   struct pipe_sampler_view *sv,
                   const GLfloat *color,
                   bool atlas)
{
   struct st_context *st = st_context(ctx);
   struct cso_context *cso = st->cso_context;
   struct st_fp_variant *fpv;
   struct st_fp_variant_key key;

   memset(&key, 0, sizeof(key));
   key.st = st->has_shareable_shaders ? NULL : st;
   key.bitmap = GL_TRUE;
   key.clamp_color = st->clamp_frag_color_in_shader &&
                     ctx->Color._ClampFragmentColor;

   fpv = st_get_fp_variant(st, st->fp, &key);

   /* As an optimization, Mesa's fragment programs will sometimes get the
    * primary color from a statevar/constant rather than a varying variable.
    * when that's the case, we need to ensure that we use the 'color'
    * parameter and not the current attribute color (which may have changed
    * through glRasterPos and state validation.
    * So, we force the proper color here.  Not elegant, but it works.
    */
   {
      GLfloat colorSave[4];
      COPY_4V(colorSave, ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
      COPY_4V(ctx->Current.Attrib[VERT_ATTRIB_COLOR0], color);
      st_upload_constants(st, &st->fp->Base);
      COPY_4V(ctx->Current.Attrib[VERT_ATTRIB_COLOR0], colorSave);
   }

   cso_save_state(cso, (CSO_BIT_RASTERIZER |
                        CSO_BIT_FRAGMENT_SAMPLERS |
                        CSO_BIT_FRAGMENT_SAMPLER_VIEWS |
                        CSO_BIT_VIEWPORT |
                        CSO_BIT_STREAM_OUTPUTS |
                        CSO_BIT_VERTEX_ELEMENTS |
                        CSO_BIT_AUX_VERTEX_BUFFER_SLOT |
                        CSO_BITS_ALL_SHADERS));


   /* rasterizer state: just scissor */
   st->bitmap.rasterizer.scissor = ctx->Scissor.EnableFlags & 1;
   cso_set_rasterizer(cso, &st->bitmap.rasterizer);

   /* fragment shader state: TEX lookup program */
   cso_set_fragment_shader_handle(cso, fpv->driver_shader);

   /* vertex shader state: position + texcoord pass-through */
   cso_set_vertex_shader_handle(cso, st->bitmap.vs);

   /* disable other shaders */
   cso_set_tessctrl_shader_handle(cso, NULL);
   cso_set_tesseval_shader_handle(cso, NULL);
   cso_set_geometry_shader_handle(cso, NULL);

   /* user samplers, plus our bitmap sampler */
   {
      struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
      uint num = MAX2(fpv->bitmap_sampler + 1,
                      st->state.num_frag_samplers);
      uint i;
      for (i = 0; i < st->state.num_frag_samplers; i++) {
         samplers[i] = &st->state.frag_samplers[i];
      }
      if (atlas)
         samplers[fpv->bitmap_sampler] = &st->bitmap.atlas_sampler;
      else
         samplers[fpv->bitmap_sampler] = &st->bitmap.sampler;
      cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, num,
                       (const struct pipe_sampler_state **) samplers);
   }

   /* user textures, plus the bitmap texture */
   {
      struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
      uint num = MAX2(fpv->bitmap_sampler + 1,
                      st->state.num_sampler_views[PIPE_SHADER_FRAGMENT]);
      memcpy(sampler_views, st->state.frag_sampler_views,
             sizeof(sampler_views));
      sampler_views[fpv->bitmap_sampler] = sv;
      cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, num, sampler_views);
   }

   /* viewport state: viewport matching window dims */
   cso_set_viewport_dims(cso, st->state.fb_width,
                         st->state.fb_height,
                         st->state.fb_orientation == Y_0_TOP);

   cso_set_vertex_elements(cso, 3, st->util_velems);

   cso_set_stream_outputs(st->cso_context, 0, NULL, NULL);
}