Пример #1
0
/**
 * Save all the CSO state items specified by the state_mask bitmask
 * of CSO_BIT_x flags.
 */
void
cso_save_state(struct cso_context *cso, unsigned state_mask)
{
    assert(cso->saved_state == 0);

    cso->saved_state = state_mask;

    if (state_mask & CSO_BIT_AUX_VERTEX_BUFFER_SLOT)
        cso_save_aux_vertex_buffer_slot(cso);
    if (state_mask & CSO_BIT_BLEND)
        cso_save_blend(cso);
    if (state_mask & CSO_BIT_DEPTH_STENCIL_ALPHA)
        cso_save_depth_stencil_alpha(cso);
    if (state_mask & CSO_BIT_FRAGMENT_SAMPLERS)
        cso_save_fragment_samplers(cso);
    if (state_mask & CSO_BIT_FRAGMENT_SAMPLER_VIEWS)
        cso_save_fragment_sampler_views(cso);
    if (state_mask & CSO_BIT_FRAGMENT_SHADER)
        cso_save_fragment_shader(cso);
    if (state_mask & CSO_BIT_FRAMEBUFFER)
        cso_save_framebuffer(cso);
    if (state_mask & CSO_BIT_GEOMETRY_SHADER)
        cso_save_geometry_shader(cso);
    if (state_mask & CSO_BIT_MIN_SAMPLES)
        cso_save_min_samples(cso);
    if (state_mask & CSO_BIT_RASTERIZER)
        cso_save_rasterizer(cso);
    if (state_mask & CSO_BIT_RENDER_CONDITION)
        cso_save_render_condition(cso);
    if (state_mask & CSO_BIT_SAMPLE_MASK)
        cso_save_sample_mask(cso);
    if (state_mask & CSO_BIT_STENCIL_REF)
        cso_save_stencil_ref(cso);
    if (state_mask & CSO_BIT_STREAM_OUTPUTS)
        cso_save_stream_outputs(cso);
    if (state_mask & CSO_BIT_TESSCTRL_SHADER)
        cso_save_tessctrl_shader(cso);
    if (state_mask & CSO_BIT_TESSEVAL_SHADER)
        cso_save_tesseval_shader(cso);
    if (state_mask & CSO_BIT_VERTEX_ELEMENTS)
        cso_save_vertex_elements(cso);
    if (state_mask & CSO_BIT_VERTEX_SHADER)
        cso_save_vertex_shader(cso);
    if (state_mask & CSO_BIT_VIEWPORT)
        cso_save_viewport(cso);
    if (state_mask & CSO_BIT_PAUSE_QUERIES)
        cso->pipe->set_active_query_state(cso->pipe, false);
}
Пример #2
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_min_samples(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_min_samples(ctx->cso, 1);
   cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
   cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
   cso_set_stream_outputs(ctx->cso, 0, NULL, NULL);

   /* 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_min_samples(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);
}
Пример #3
0
/**
 * Do glClear by drawing a quadrilateral.
 * The vertices of the quad will be computed from the
 * ctx->DrawBuffer->_X/Ymin/max fields.
 */
static void
clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
{
   struct st_context *st = st_context(ctx);
   const struct gl_framebuffer *fb = ctx->DrawBuffer;
   const GLfloat fb_width = (GLfloat) fb->Width;
   const GLfloat fb_height = (GLfloat) fb->Height;
   const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin / fb_width * 2.0f - 1.0f;
   const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax / fb_width * 2.0f - 1.0f;
   const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin / fb_height * 2.0f - 1.0f;
   const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax / fb_height * 2.0f - 1.0f;
   unsigned num_layers =
      util_framebuffer_get_num_layers(&st->state.framebuffer);

   /*
   printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__, 
	  color ? "color, " : "",
	  depth ? "depth, " : "",
	  stencil ? "stencil" : "",
	  x0, y0,
	  x1, y1);
   */

   cso_save_blend(st->cso_context);
   cso_save_stencil_ref(st->cso_context);
   cso_save_depth_stencil_alpha(st->cso_context);
   cso_save_rasterizer(st->cso_context);
   cso_save_sample_mask(st->cso_context);
   cso_save_min_samples(st->cso_context);
   cso_save_viewport(st->cso_context);
   cso_save_fragment_shader(st->cso_context);
   cso_save_stream_outputs(st->cso_context);
   cso_save_vertex_shader(st->cso_context);
   cso_save_geometry_shader(st->cso_context);
   cso_save_vertex_elements(st->cso_context);
   cso_save_aux_vertex_buffer_slot(st->cso_context);

   /* blend state: RGBA masking */
   {
      struct pipe_blend_state blend;
      memset(&blend, 0, sizeof(blend));
      if (clear_buffers & PIPE_CLEAR_COLOR) {
         int num_buffers = ctx->Extensions.EXT_draw_buffers2 ?
                           ctx->DrawBuffer->_NumColorDrawBuffers : 1;
         int i;

         blend.independent_blend_enable = num_buffers > 1;

         for (i = 0; i < num_buffers; i++) {
            if (!(clear_buffers & (PIPE_CLEAR_COLOR0 << i)))
               continue;

            if (ctx->Color.ColorMask[i][0])
               blend.rt[i].colormask |= PIPE_MASK_R;
            if (ctx->Color.ColorMask[i][1])
               blend.rt[i].colormask |= PIPE_MASK_G;
            if (ctx->Color.ColorMask[i][2])
               blend.rt[i].colormask |= PIPE_MASK_B;
            if (ctx->Color.ColorMask[i][3])
               blend.rt[i].colormask |= PIPE_MASK_A;
         }

         if (st->ctx->Color.DitherFlag)
            blend.dither = 1;
      }
      cso_set_blend(st->cso_context, &blend);
   }

   /* depth_stencil state: always pass/set to ref value */
   {
      struct pipe_depth_stencil_alpha_state depth_stencil;
      memset(&depth_stencil, 0, sizeof(depth_stencil));
      if (clear_buffers & PIPE_CLEAR_DEPTH) {
         depth_stencil.depth.enabled = 1;
         depth_stencil.depth.writemask = 1;
         depth_stencil.depth.func = PIPE_FUNC_ALWAYS;
      }

      if (clear_buffers & PIPE_CLEAR_STENCIL) {
         struct pipe_stencil_ref stencil_ref;
         memset(&stencil_ref, 0, sizeof(stencil_ref));
         depth_stencil.stencil[0].enabled = 1;
         depth_stencil.stencil[0].func = PIPE_FUNC_ALWAYS;
         depth_stencil.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
         depth_stencil.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
         depth_stencil.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
         depth_stencil.stencil[0].valuemask = 0xff;
         depth_stencil.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff;
         stencil_ref.ref_value[0] = ctx->Stencil.Clear;
         cso_set_stencil_ref(st->cso_context, &stencil_ref);
      }

      cso_set_depth_stencil_alpha(st->cso_context, &depth_stencil);
   }

   cso_set_vertex_elements(st->cso_context, 2, st->velems_util_draw);
   cso_set_stream_outputs(st->cso_context, 0, NULL, NULL);
   cso_set_sample_mask(st->cso_context, ~0);
   cso_set_min_samples(st->cso_context, 1);
   cso_set_rasterizer(st->cso_context, &st->clear.raster);

   /* viewport state: viewport matching window dims */
   {
      const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP);
      struct pipe_viewport_state vp;
      vp.scale[0] = 0.5f * fb_width;
      vp.scale[1] = fb_height * (invert ? -0.5f : 0.5f);
      vp.scale[2] = 1.0f;
      vp.scale[3] = 1.0f;
      vp.translate[0] = 0.5f * fb_width;
      vp.translate[1] = 0.5f * fb_height;
      vp.translate[2] = 0.0f;
      vp.translate[3] = 0.0f;
      cso_set_viewport(st->cso_context, &vp);
   }

   set_fragment_shader(st);
   cso_set_geometry_shader_handle(st->cso_context, NULL);

   if (num_layers > 1)
      set_vertex_shader_layered(st);
   else
      set_vertex_shader(st);

   /* We can't translate the clear color to the colorbuffer format,
    * because different colorbuffers may have different formats.
    */

   /* draw quad matching scissor rect */
   draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, num_layers,
             (union pipe_color_union*)&ctx->Color.ClearColor);

   /* Restore pipe state */
   cso_restore_blend(st->cso_context);
   cso_restore_stencil_ref(st->cso_context);
   cso_restore_depth_stencil_alpha(st->cso_context);
   cso_restore_rasterizer(st->cso_context);
   cso_restore_sample_mask(st->cso_context);
   cso_restore_min_samples(st->cso_context);
   cso_restore_viewport(st->cso_context);
   cso_restore_fragment_shader(st->cso_context);
   cso_restore_vertex_shader(st->cso_context);
   cso_restore_geometry_shader(st->cso_context);
   cso_restore_vertex_elements(st->cso_context);
   cso_restore_aux_vertex_buffer_slot(st->cso_context);
   cso_restore_stream_outputs(st->cso_context);
}