Ejemplo n.º 1
0
/**
 * Copy pixel block from src sampler view to dst surface.
 *
 * The sampler view's first_level field indicates the source
 * mipmap level to use.
 *
 * The sampler view's first_layer indicate the layer to use, but for
 * cube maps it must point to the first face.  Face is passed in src_face.
 *
 * The main advantage over util_blit_pixels is that it allows to specify swizzles in
 * pipe_sampler_view::swizzle_?.
 *
 * But there is no control over blitting Z and/or stencil.
 */
void
util_blit_pixels_tex(struct blit_state *ctx,
                     struct pipe_sampler_view *src_sampler_view,
                     int srcX0, int srcY0,
                     int srcX1, int srcY1,
                     unsigned src_face,
                     struct pipe_surface *dst,
                     int dstX0, int dstY0,
                     int dstX1, int dstY1,
                     float z, uint filter)
{
   boolean normalized = src_sampler_view->texture->target != PIPE_TEXTURE_RECT;
   struct pipe_framebuffer_state fb;
   float s0, t0, s1, t1;
   unsigned offset;
   struct pipe_resource *tex = src_sampler_view->texture;

   assert(filter == PIPE_TEX_MIPFILTER_NEAREST ||
          filter == PIPE_TEX_MIPFILTER_LINEAR);

   assert(tex);
   assert(tex->width0 != 0);
   assert(tex->height0 != 0);

   s0 = (float) srcX0;
   s1 = (float) srcX1;
   t0 = (float) srcY0;
   t1 = (float) srcY1;

   if(normalized)
   {
      /* normalize according to the mipmap level's size */
      int level = src_sampler_view->u.tex.first_level;
      float w = (float) u_minify(tex->width0, level);
      float h = (float) u_minify(tex->height0, level);
      s0 /= w;
      s1 /= w;
      t0 /= h;
      t1 /= h;
   }

   assert(ctx->pipe->screen->is_format_supported(ctx->pipe->screen, dst->format,
                                                 PIPE_TEXTURE_2D,
                                                 dst->texture->nr_samples,
                                                 PIPE_BIND_RENDER_TARGET));

   /* save state (restored below) */
   cso_save_blend(ctx->cso);
   cso_save_depth_stencil_alpha(ctx->cso);
   cso_save_rasterizer(ctx->cso);
   cso_save_sample_mask(ctx->cso);
   cso_save_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
   cso_save_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
   cso_save_stream_outputs(ctx->cso);
   cso_save_viewport(ctx->cso);
   cso_save_framebuffer(ctx->cso);
   cso_save_fragment_shader(ctx->cso);
   cso_save_vertex_shader(ctx->cso);
   cso_save_geometry_shader(ctx->cso);
   cso_save_vertex_elements(ctx->cso);
   cso_save_aux_vertex_buffer_slot(ctx->cso);

   /* set misc state we care about */
   cso_set_blend(ctx->cso, &ctx->blend_write_color);
   cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_keep_depthstencil);
   cso_set_sample_mask(ctx->cso, ~0);
   cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
   cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
   cso_set_stream_outputs(ctx->cso, 0, NULL, 0);

   /* sampler */
   ctx->sampler.normalized_coords = normalized;
   ctx->sampler.min_img_filter = filter;
   ctx->sampler.mag_img_filter = filter;
   cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler);
   cso_single_sampler_done(ctx->cso, PIPE_SHADER_FRAGMENT);

   /* viewport */
   ctx->viewport.scale[0] = 0.5f * dst->width;
   ctx->viewport.scale[1] = 0.5f * dst->height;
   ctx->viewport.scale[2] = 0.5f;
   ctx->viewport.scale[3] = 1.0f;
   ctx->viewport.translate[0] = 0.5f * dst->width;
   ctx->viewport.translate[1] = 0.5f * dst->height;
   ctx->viewport.translate[2] = 0.5f;
   ctx->viewport.translate[3] = 0.0f;
   cso_set_viewport(ctx->cso, &ctx->viewport);

   /* texture */
   cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 1, &src_sampler_view);

   /* shaders */
   set_fragment_shader(ctx, TGSI_WRITEMASK_XYZW,
                       src_sampler_view->texture->target);
   set_vertex_shader(ctx);
   cso_set_geometry_shader_handle(ctx->cso, NULL);

   /* drawing dest */
   memset(&fb, 0, sizeof(fb));
   fb.width = dst->width;
   fb.height = dst->height;
   fb.nr_cbufs = 1;
   fb.cbufs[0] = dst;
   cso_set_framebuffer(ctx->cso, &fb);

   /* draw quad */
   offset = setup_vertex_data_tex(ctx,
                                  src_sampler_view->texture->target,
                                  src_face,
                                  (float) dstX0 / dst->width * 2.0f - 1.0f,
                                  (float) dstY0 / dst->height * 2.0f - 1.0f,
                                  (float) dstX1 / dst->width * 2.0f - 1.0f,
                                  (float) dstY1 / dst->height * 2.0f - 1.0f,
                                  s0, t0, s1, t1,
                                  z);

   util_draw_vertex_buffer(ctx->pipe, ctx->cso, ctx->vbuf,
                           cso_get_aux_vertex_buffer_slot(ctx->cso),
                           offset,
                           PIPE_PRIM_TRIANGLE_FAN,
                           4,  /* verts */
                           2); /* attribs/vert */

   /* restore state we changed */
   cso_restore_blend(ctx->cso);
   cso_restore_depth_stencil_alpha(ctx->cso);
   cso_restore_rasterizer(ctx->cso);
   cso_restore_sample_mask(ctx->cso);
   cso_restore_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
   cso_restore_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
   cso_restore_viewport(ctx->cso);
   cso_restore_framebuffer(ctx->cso);
   cso_restore_fragment_shader(ctx->cso);
   cso_restore_vertex_shader(ctx->cso);
   cso_restore_geometry_shader(ctx->cso);
   cso_restore_vertex_elements(ctx->cso);
   cso_restore_aux_vertex_buffer_slot(ctx->cso);
   cso_restore_stream_outputs(ctx->cso);
}
Ejemplo n.º 2
0
/** Run function of the MLAA filter. */
static void
pp_jimenezmlaa_run(struct pp_queue_t *ppq, struct pipe_resource *in,
                   struct pipe_resource *out, unsigned int n, bool iscolor)
{

   struct program *p = ppq->p;

   struct pipe_depth_stencil_alpha_state mstencil;
   struct pipe_sampler_view v_tmp, *arr[3];

   unsigned int w = p->framebuffer.width;
   unsigned int h = p->framebuffer.height;

   const struct pipe_stencil_ref ref = { {1} };
   memset(&mstencil, 0, sizeof(mstencil));
   cso_set_stencil_ref(p->cso, &ref);

   /* Init the pixel size constant */
   if (dimensions[0] != p->framebuffer.width ||
       dimensions[1] != p->framebuffer.height) {
      constants[0] = 1.0 / p->framebuffer.width;
      constants[1] = 1.0 / p->framebuffer.height;

      up_consts(p->pipe);
      dimensions[0] = p->framebuffer.width;
      dimensions[1] = p->framebuffer.height;
   }

   pipe_set_constant_buffer(p->pipe, PIPE_SHADER_VERTEX, 0, constbuf);
   pipe_set_constant_buffer(p->pipe, PIPE_SHADER_FRAGMENT, 0, constbuf);

   mstencil.stencil[0].enabled = 1;
   mstencil.stencil[0].valuemask = mstencil.stencil[0].writemask = ~0;
   mstencil.stencil[0].func = PIPE_FUNC_ALWAYS;
   mstencil.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
   mstencil.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
   mstencil.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;

   p->framebuffer.zsbuf = ppq->stencils;

   /* First pass: depth edge detection */
   if (iscolor)
      pp_filter_setup_in(p, in);
   else
      pp_filter_setup_in(p, ppq->depth);

   pp_filter_setup_out(p, ppq->inner_tmp[0]);

   pp_filter_set_fb(p);
   pp_filter_misc_state(p);
   cso_set_depth_stencil_alpha(p->cso, &mstencil);
   p->pipe->clear(p->pipe, PIPE_CLEAR_STENCIL | PIPE_CLEAR_COLOR,
                  &p->clear_color, 0, 0);

   cso_single_sampler(p->cso, PIPE_SHADER_FRAGMENT, 0, &p->sampler_point);
   cso_single_sampler_done(p->cso, PIPE_SHADER_FRAGMENT);
   cso_set_sampler_views(p->cso, PIPE_SHADER_FRAGMENT, 1, &p->view);

   cso_set_vertex_shader_handle(p->cso, ppq->shaders[n][1]);    /* offsetvs */
   cso_set_fragment_shader_handle(p->cso, ppq->shaders[n][2]);

   pp_filter_draw(p);
   pp_filter_end_pass(p);


   /* Second pass: blend weights */
   /* Sampler order: areamap, edgesmap, edgesmapL (reversed, thx compiler) */
   mstencil.stencil[0].func = PIPE_FUNC_EQUAL;
   mstencil.stencil[0].zpass_op = PIPE_STENCIL_OP_KEEP;
   cso_set_depth_stencil_alpha(p->cso, &mstencil);

   pp_filter_setup_in(p, areamaptex);
   pp_filter_setup_out(p, ppq->inner_tmp[1]);

   u_sampler_view_default_template(&v_tmp, ppq->inner_tmp[0],
                                   ppq->inner_tmp[0]->format);
   arr[1] = arr[2] = p->pipe->create_sampler_view(p->pipe,
                                                  ppq->inner_tmp[0], &v_tmp);

   pp_filter_set_clear_fb(p);

   cso_single_sampler(p->cso, PIPE_SHADER_FRAGMENT, 0, &p->sampler_point);
   cso_single_sampler(p->cso, PIPE_SHADER_FRAGMENT, 1, &p->sampler_point);
   cso_single_sampler(p->cso, PIPE_SHADER_FRAGMENT, 2, &p->sampler);
   cso_single_sampler_done(p->cso, PIPE_SHADER_FRAGMENT);

   arr[0] = p->view;
   cso_set_sampler_views(p->cso, PIPE_SHADER_FRAGMENT, 3, arr);

   cso_set_vertex_shader_handle(p->cso, ppq->shaders[n][0]);    /* passvs */
   cso_set_fragment_shader_handle(p->cso, ppq->shaders[n][3]);

   pp_filter_draw(p);
   pp_filter_end_pass(p);
   pipe_sampler_view_reference(&arr[1], NULL);


   /* Third pass: smoothed edges */
   /* Sampler order: colormap, blendmap (wtf compiler) */
   pp_filter_setup_in(p, ppq->inner_tmp[1]);
   pp_filter_setup_out(p, out);

   pp_filter_set_fb(p);

   /* Blit the input to the output */
   util_blit_pixels(p->blitctx, in, 0, 0, 0,
                    w, h, 0, p->framebuffer.cbufs[0],
                    0, 0, w, h, 0, PIPE_TEX_MIPFILTER_NEAREST,
                    TGSI_WRITEMASK_XYZW, 0);

   u_sampler_view_default_template(&v_tmp, in, in->format);
   arr[0] = p->pipe->create_sampler_view(p->pipe, in, &v_tmp);

   cso_single_sampler(p->cso, PIPE_SHADER_FRAGMENT, 0, &p->sampler_point);
   cso_single_sampler(p->cso, PIPE_SHADER_FRAGMENT, 1, &p->sampler_point);
   cso_single_sampler_done(p->cso, PIPE_SHADER_FRAGMENT);

   arr[1] = p->view;
   cso_set_sampler_views(p->cso, PIPE_SHADER_FRAGMENT, 2, arr);

   cso_set_vertex_shader_handle(p->cso, ppq->shaders[n][1]);    /* offsetvs */
   cso_set_fragment_shader_handle(p->cso, ppq->shaders[n][4]);

   p->blend.rt[0].blend_enable = 1;
   cso_set_blend(p->cso, &p->blend);

   pp_filter_draw(p);
   pp_filter_end_pass(p);
   pipe_sampler_view_reference(&arr[0], NULL);

   p->blend.rt[0].blend_enable = 0;
   p->framebuffer.zsbuf = NULL;
}