Пример #1
0
static void
xa_yuv_bind_samplers(struct xa_context *r, struct xa_surface *yuv[])
{
    struct pipe_sampler_state *samplers[3];
    struct pipe_sampler_state sampler;
    struct pipe_sampler_view *views[3];
    struct pipe_sampler_view view_templ;
    unsigned int i;

    memset(&sampler, 0, sizeof(struct pipe_sampler_state));

    sampler.wrap_s = PIPE_TEX_WRAP_CLAMP;
    sampler.wrap_t = PIPE_TEX_WRAP_CLAMP;
    sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
    sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
    sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
    sampler.normalized_coords = 1;

    for (i = 0; i < 3; ++i) {
	samplers[i] = &sampler;
	if (!yuv[i]->view) {
	    u_sampler_view_default_template(&view_templ,
					    yuv[i]->tex, yuv[i]->tex->format);

	    yuv[i]->view = r->pipe->create_sampler_view(r->pipe,
							yuv[i]->tex,
							&view_templ);
	}
	views[i] = yuv[i]->view;
    }

    cso_set_samplers(r->cso, 3, (const struct pipe_sampler_state **)samplers);
    cso_set_fragment_sampler_views(r->cso, 3, views);
}
Пример #2
0
void
nine_pipe_context_clear(struct NineDevice9 *This)
{
    struct pipe_context *pipe = This->pipe;
    struct cso_context *cso = This->cso;
    pipe->bind_vs_state(pipe, NULL);
    pipe->bind_fs_state(pipe, NULL);

    /* Don't unbind constant buffers, they're device-private and
     * do not change on Reset.
     */

    cso_set_samplers(cso, PIPE_SHADER_VERTEX, 0, NULL);
    cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, 0, NULL);

    pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 0, NULL);
    pipe->set_sampler_views(pipe, PIPE_SHADER_VERTEX, 0, 0, NULL);

    pipe->set_vertex_buffers(pipe, 0, This->caps.MaxStreams, NULL);
    pipe->set_index_buffer(pipe, NULL);
}
Пример #3
0
XA_EXPORT int
xa_solid_prepare(struct xa_context *ctx, struct xa_surface *dst,
		 uint32_t fg)
{
    unsigned vs_traits, fs_traits;
    struct xa_shader shader;
    int width, height;
    int ret;

    ret = xa_ctx_srf_create(ctx, dst);
    if (ret != XA_ERR_NONE)
	return ret;

    if (ctx->srf->format == PIPE_FORMAT_L8_UNORM)
	xa_pixel_to_float4_a8(fg, ctx->solid_color);
    else
	xa_pixel_to_float4(fg, ctx->solid_color);
    ctx->has_solid_color = 1;

    ctx->dst = dst;
    width = ctx->srf->width;
    height = ctx->srf->height;

#if 0
    debug_printf("Color Pixel=(%d, %d, %d, %d), RGBA=(%f, %f, %f, %f)\n",
		 (fg >> 24) & 0xff, (fg >> 16) & 0xff,
		 (fg >> 8) & 0xff,  (fg >> 0) & 0xff,
		 exa->solid_color[0], exa->solid_color[1],
		 exa->solid_color[2], exa->solid_color[3]);
#endif

    vs_traits = VS_SOLID_FILL;
    fs_traits = FS_SOLID_FILL;

    renderer_bind_destination(ctx, ctx->srf, width, height);
    bind_solid_blend_state(ctx);
    cso_set_samplers(ctx->cso, PIPE_SHADER_FRAGMENT, 0, NULL);
    cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 0, NULL);

    shader = xa_shaders_get(ctx->shaders, vs_traits, fs_traits);
    cso_set_vertex_shader_handle(ctx->cso, shader.vs);
    cso_set_fragment_shader_handle(ctx->cso, shader.fs);

    renderer_begin_solid(ctx);

    xa_ctx_srf_destroy(ctx);
    return XA_ERR_NONE;
}
Пример #4
0
/**
 * Set custom renderer fragment shader, and optionally set samplers and views
 * and upload the fragment constant buffer.
 *
 * This function modifies fragment_shader, samplers and fragment_sampler_views
 * states.
 */
static void renderer_set_custom_fs(struct renderer *renderer,
                                   void *fs,
                                   const struct pipe_sampler_state **samplers,
                                   struct pipe_sampler_view **views,
                                   VGint num_samplers,
                                   const void *const_buffer,
                                   VGint const_buffer_len)
{
   cso_set_fragment_shader_handle(renderer->cso, fs);

   /* set samplers and views */
   if (num_samplers) {
      cso_set_samplers(renderer->cso, PIPE_SHADER_FRAGMENT, num_samplers, samplers);
      cso_set_sampler_views(renderer->cso, PIPE_SHADER_FRAGMENT, num_samplers, views);
   }

   /* upload fs constant buffer */
   if (const_buffer_len) {
      struct pipe_resource *cbuf = renderer->fs_cbuf;

      if (!cbuf || renderer->fs_cbuf_len != const_buffer_len ||
          memcmp(renderer->fs_cbuf_data, const_buffer, const_buffer_len)) {
         pipe_resource_reference(&cbuf, NULL);

         cbuf = pipe_buffer_create(renderer->pipe->screen,
               PIPE_BIND_CONSTANT_BUFFER, PIPE_USAGE_STATIC,
               const_buffer_len);
         pipe_buffer_write(renderer->pipe, cbuf, 0,
               const_buffer_len, const_buffer);
         pipe_set_constant_buffer(renderer->pipe,
               PIPE_SHADER_FRAGMENT, 0, cbuf);

         renderer->fs_cbuf = cbuf;
         if (const_buffer_len <= sizeof(renderer->fs_cbuf_data)) {
            memcpy(renderer->fs_cbuf_data, const_buffer, const_buffer_len);
            renderer->fs_cbuf_len = const_buffer_len;
         }
         else {
            renderer->fs_cbuf_len = 0;
         }
      }
   }
}
Пример #5
0
/**
 * Update the gallium driver's sampler state for fragment, vertex or
 * geometry shader stage.
 */
static void
update_shader_samplers(struct st_context *st,
                       unsigned shader_stage,
                       const struct gl_program *prog,
                       unsigned max_units,
                       struct pipe_sampler_state *samplers,
                       unsigned *num_samplers)
{
   GLuint unit;
   GLbitfield samplers_used;
   const GLuint old_max = *num_samplers;
   const struct pipe_sampler_state *states[PIPE_MAX_SAMPLERS];

   samplers_used = prog->SamplersUsed;

   if (*num_samplers == 0 && samplers_used == 0x0)
      return;

   *num_samplers = 0;

   /* loop over sampler units (aka tex image units) */
   for (unit = 0; unit < max_units; unit++, samplers_used >>= 1) {
      struct pipe_sampler_state *sampler = samplers + unit;

      if (samplers_used & 1) {
         const GLuint texUnit = prog->SamplerUnits[unit];

         convert_sampler(st, sampler, texUnit);
         states[unit] = sampler;
         *num_samplers = unit + 1;
      }
      else if (samplers_used != 0 || unit < old_max) {
         states[unit] = NULL;
      }
      else {
         /* if we've reset all the old samplers and we have no more new ones */
         break;
      }
   }

   cso_set_samplers(st->cso_context, shader_stage, *num_samplers, states);
}
Пример #6
0
static void draw(struct program *p)
{
	const struct pipe_sampler_state *samplers[] = {&p->sampler};

	/* set the render target */
	cso_set_framebuffer(p->cso, &p->framebuffer);

	/* clear the render target */
	p->pipe->clear(p->pipe, PIPE_CLEAR_COLOR, &p->clear_color, 0, 0);

	/* set misc state we care about */
	cso_set_blend(p->cso, &p->blend);
	cso_set_depth_stencil_alpha(p->cso, &p->depthstencil);
	cso_set_rasterizer(p->cso, &p->rasterizer);
	cso_set_viewport(p->cso, &p->viewport);

	/* sampler */
	cso_set_samplers(p->cso, PIPE_SHADER_FRAGMENT, 1, samplers);

	/* texture sampler view */
	cso_set_sampler_views(p->cso, PIPE_SHADER_FRAGMENT, 1, &p->view);

	/* shaders */
	cso_set_fragment_shader_handle(p->cso, p->fs);
	cso_set_vertex_shader_handle(p->cso, p->vs);

	/* vertex element data */
	cso_set_vertex_elements(p->cso, 2, p->velem);

	util_draw_vertex_buffer(p->pipe, p->cso,
	                        p->vbuf, 0, 0,
	                        PIPE_PRIM_QUADS,
	                        4,  /* verts */
	                        2); /* attribs/vert */

        p->pipe->flush(p->pipe, NULL, 0);

	debug_dump_surface_bmp(p->pipe, "result.bmp", p->framebuffer.cbufs[0]);
}
Пример #7
0
boolean xorg_solid_bind_state(struct exa_context *exa,
                              struct exa_pixmap_priv *pixmap,
                              Pixel fg)
{
   struct pipe_surface *dst_surf = xorg_gpu_surface(exa->pipe, pixmap);
   unsigned vs_traits, fs_traits;
   struct xorg_shader shader;

   pixel_to_float4(fg, exa->solid_color, pixmap->tex->format);
   exa->has_solid_color = TRUE;

#if 0
   debug_printf("Color Pixel=(%d, %d, %d, %d), RGBA=(%f, %f, %f, %f)\n",
                (fg >> 24) & 0xff, (fg >> 16) & 0xff,
                (fg >> 8) & 0xff,  (fg >> 0) & 0xff,
                exa->solid_color[0], exa->solid_color[1],
                exa->solid_color[2], exa->solid_color[3]);
#endif

   vs_traits = VS_SOLID_FILL;
   fs_traits = FS_SOLID_FILL;

   renderer_bind_destination(exa->renderer, dst_surf, 
                             pixmap->width, pixmap->height);
   bind_blend_state(exa, PictOpSrc, NULL, NULL, NULL);
   cso_set_samplers(exa->renderer->cso, PIPE_SHADER_FRAGMENT, 0, NULL);
   cso_set_sampler_views(exa->renderer->cso, PIPE_SHADER_FRAGMENT, 0, NULL);

   shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
   cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs);
   cso_set_fragment_shader_handle(exa->renderer->cso, shader.fs);

   renderer_begin_solid(exa->renderer);

   pipe_surface_reference(&dst_surf, NULL);
   return TRUE;
}
Пример #8
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.Base.Parameters,
                            PIPE_SHADER_FRAGMENT);
        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_samplers[PIPE_SHADER_FRAGMENT]);
        uint i;
        for (i = 0; i < st->state.num_samplers[PIPE_SHADER_FRAGMENT]; i++) {
            samplers[i] = &st->state.samplers[PIPE_SHADER_FRAGMENT][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.sampler_views[PIPE_SHADER_FRAGMENT],
               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.framebuffer.width,
                          st->state.framebuffer.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);
}
Пример #9
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_FILTER_NEAREST ||
          filter == PIPE_TEX_FILTER_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_state(ctx->cso, (CSO_BIT_BLEND |
                             CSO_BIT_DEPTH_STENCIL_ALPHA |
                             CSO_BIT_RASTERIZER |
                             CSO_BIT_SAMPLE_MASK |
                             CSO_BIT_MIN_SAMPLES |
                             CSO_BIT_FRAGMENT_SAMPLERS |
                             CSO_BIT_FRAGMENT_SAMPLER_VIEWS |
                             CSO_BIT_STREAM_OUTPUTS |
                             CSO_BIT_VIEWPORT |
                             CSO_BIT_FRAMEBUFFER |
                             CSO_BIT_PAUSE_QUERIES |
                             CSO_BIT_FRAGMENT_SHADER |
                             CSO_BIT_VERTEX_SHADER |
                             CSO_BIT_TESSCTRL_SHADER |
                             CSO_BIT_TESSEVAL_SHADER |
                             CSO_BIT_GEOMETRY_SHADER |
                             CSO_BIT_VERTEX_ELEMENTS |
                             CSO_BIT_AUX_VERTEX_BUFFER_SLOT));

   /* 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;
   {
      const struct pipe_sampler_state *samplers[] = {&ctx->sampler};
      cso_set_samplers(ctx->cso, PIPE_SHADER_FRAGMENT, 1, samplers);
   }

   /* 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.translate[0] = 0.5f * dst->width;
   ctx->viewport.translate[1] = 0.5f * dst->height;
   ctx->viewport.translate[2] = 0.5f;
   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->format,
                       src_sampler_view->texture->target);
   set_vertex_shader(ctx);
   cso_set_tessctrl_shader_handle(ctx->cso, NULL);
   cso_set_tesseval_shader_handle(ctx->cso, NULL);
   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_state(ctx->cso);
}
Пример #10
0
static void
bind_samplers(struct exa_context *exa, int op,
              PicturePtr pSrcPicture, PicturePtr pMaskPicture,
              PicturePtr pDstPicture,
              struct exa_pixmap_priv *pSrc,
              struct exa_pixmap_priv *pMask,
              struct exa_pixmap_priv *pDst)
{
   struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS] = {0};
   struct pipe_sampler_state src_sampler, mask_sampler;
   struct pipe_sampler_view view_templ;
   struct pipe_sampler_view *src_view;
   struct pipe_context *pipe = exa->pipe;

   exa->num_bound_samplers = 0;

   memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
   memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));

   if (pSrcPicture && pSrc) {
      if (exa->has_solid_color) {
         debug_assert(!"solid color with textures");
         samplers[0] = NULL;
         pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
      } else {
         unsigned src_wrap = render_repeat_to_gallium(
            pSrcPicture->repeatType);
         int filter;

         render_filter_to_gallium(pSrcPicture->filter, &filter);

         src_sampler.wrap_s = src_wrap;
         src_sampler.wrap_t = src_wrap;
         src_sampler.min_img_filter = filter;
         src_sampler.mag_img_filter = filter;
         src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
         src_sampler.normalized_coords = 1;
         samplers[0] = &src_sampler;
         exa->num_bound_samplers = 1;
         u_sampler_view_default_template(&view_templ,
                                         pSrc->tex,
                                         pSrc->tex->format);
         src_view = pipe->create_sampler_view(pipe, pSrc->tex, &view_templ);
         pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
         exa->bound_sampler_views[0] = src_view;
      }
   }

   if (pMaskPicture && pMask) {
      unsigned mask_wrap = render_repeat_to_gallium(
         pMaskPicture->repeatType);
      int filter;

      render_filter_to_gallium(pMaskPicture->filter, &filter);

      mask_sampler.wrap_s = mask_wrap;
      mask_sampler.wrap_t = mask_wrap;
      mask_sampler.min_img_filter = filter;
      mask_sampler.mag_img_filter = filter;
      src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
      mask_sampler.normalized_coords = 1;
      samplers[1] = &mask_sampler;
      exa->num_bound_samplers = 2;
      u_sampler_view_default_template(&view_templ,
                                      pMask->tex,
                                      pMask->tex->format);
      src_view = pipe->create_sampler_view(pipe, pMask->tex, &view_templ);
      pipe_sampler_view_reference(&exa->bound_sampler_views[1], NULL);
      exa->bound_sampler_views[1] = src_view;
   }

   cso_set_samplers(exa->renderer->cso, PIPE_SHADER_FRAGMENT,
                    exa->num_bound_samplers,
                    (const struct pipe_sampler_state **)samplers);
   cso_set_sampler_views(exa->renderer->cso, PIPE_SHADER_FRAGMENT,
                         exa->num_bound_samplers,
                         exa->bound_sampler_views);
}
Пример #11
0
/**
 * Render a glBitmap by drawing a textured quad
 */
static void
draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
                 GLsizei width, GLsizei height,
                 struct pipe_sampler_view *sv,
                 const GLfloat *color)
{
   struct st_context *st = st_context(ctx);
   struct pipe_context *pipe = st->pipe;
   struct cso_context *cso = st->cso_context;
   struct st_fp_variant *fpv;
   struct st_fp_variant_key key;
   GLuint maxSize;
   GLuint offset;
   struct pipe_resource *vbuf = NULL;

   memset(&key, 0, sizeof(key));
   key.st = st;
   key.bitmap = GL_TRUE;
   key.clamp_color = st->clamp_frag_color_in_shader &&
                     st->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, fpv->parameters, PIPE_SHADER_FRAGMENT);
      COPY_4V(ctx->Current.Attrib[VERT_ATTRIB_COLOR0], colorSave);
   }


   /* limit checks */
   /* XXX if the bitmap is larger than the max texture size, break
    * it up into chunks.
    */
   maxSize = 1 << (pipe->screen->get_param(pipe->screen,
                                    PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
   assert(width <= (GLsizei)maxSize);
   assert(height <= (GLsizei)maxSize);

   cso_save_rasterizer(cso);
   cso_save_samplers(cso, PIPE_SHADER_FRAGMENT);
   cso_save_sampler_views(cso, PIPE_SHADER_FRAGMENT);
   cso_save_viewport(cso);
   cso_save_fragment_shader(cso);
   cso_save_stream_outputs(cso);
   cso_save_vertex_shader(cso);
   cso_save_tessctrl_shader(cso);
   cso_save_tesseval_shader(cso);
   cso_save_geometry_shader(cso);
   cso_save_vertex_elements(cso);
   cso_save_aux_vertex_buffer_slot(cso);

   /* 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_samplers[PIPE_SHADER_FRAGMENT]);
      uint i;
      for (i = 0; i < st->state.num_samplers[PIPE_SHADER_FRAGMENT]; i++) {
         samplers[i] = &st->state.samplers[PIPE_SHADER_FRAGMENT][i];
      }
      samplers[fpv->bitmap_sampler] =
         &st->bitmap.samplers[sv->texture->target != PIPE_TEXTURE_RECT];
      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.sampler_views[PIPE_SHADER_FRAGMENT],
             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 */
   {
      const GLboolean invert = st->state.fb_orientation == Y_0_TOP;
      const GLfloat width = (GLfloat)st->state.framebuffer.width;
      const GLfloat height = (GLfloat)st->state.framebuffer.height;
      struct pipe_viewport_state vp;
      vp.scale[0] =  0.5f * width;
      vp.scale[1] = height * (invert ? -0.5f : 0.5f);
      vp.scale[2] = 0.5f;
      vp.translate[0] = 0.5f * width;
      vp.translate[1] = 0.5f * height;
      vp.translate[2] = 0.5f;
      cso_set_viewport(cso, &vp);
   }

   cso_set_vertex_elements(cso, 3, st->velems_util_draw);
   cso_set_stream_outputs(st->cso_context, 0, NULL, NULL);

   /* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */
   z = z * 2.0f - 1.0f;

   /* draw textured quad */
   setup_bitmap_vertex_data(st, sv->texture->target != PIPE_TEXTURE_RECT,
			    x, y, width, height, z, color, &vbuf, &offset);

   if (vbuf) {
      util_draw_vertex_buffer(pipe, st->cso_context, vbuf,
                              cso_get_aux_vertex_buffer_slot(st->cso_context),
                              offset,
                              PIPE_PRIM_TRIANGLE_FAN,
                              4,  /* verts */
                              3); /* attribs/vert */
   }

   /* restore state */
   cso_restore_rasterizer(cso);
   cso_restore_samplers(cso, PIPE_SHADER_FRAGMENT);
   cso_restore_sampler_views(cso, PIPE_SHADER_FRAGMENT);
   cso_restore_viewport(cso);
   cso_restore_fragment_shader(cso);
   cso_restore_vertex_shader(cso);
   cso_restore_tessctrl_shader(cso);
   cso_restore_tesseval_shader(cso);
   cso_restore_geometry_shader(cso);
   cso_restore_vertex_elements(cso);
   cso_restore_aux_vertex_buffer_slot(cso);
   cso_restore_stream_outputs(cso);

   pipe_resource_reference(&vbuf, NULL);
}
Пример #12
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 pp_program *p = ppq->p;

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

   unsigned int w = 0;
   unsigned int h = 0;

   const struct pipe_stencil_ref ref = { {1} };

   /* Insufficient initialization checks. */
   assert(p);
   assert(ppq);
   assert(ppq->constbuf);
   assert(ppq->areamaptex);
   assert(ppq->inner_tmp);
   assert(ppq->shaders[n]);

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

   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.0f / p->framebuffer.width;
      constants[1] = 1.0f / p->framebuffer.height;

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

   cso_set_constant_buffer_resource(p->cso, PIPE_SHADER_VERTEX,
                                    0, ppq->constbuf);
   cso_set_constant_buffer_resource(p->cso, PIPE_SHADER_FRAGMENT,
                                    0, ppq->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_COLOR0,
                  &p->clear_color, 0, 0);

   {
      const struct pipe_sampler_state *samplers[] = {&p->sampler_point};
      cso_set_samplers(p->cso, PIPE_SHADER_FRAGMENT, 1, samplers);
   }
   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, ppq->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);

   {
      const struct pipe_sampler_state *samplers[] =
         {&p->sampler_point, &p->sampler_point, &p->sampler};
      cso_set_samplers(p->cso, PIPE_SHADER_FRAGMENT, 3, samplers);
   }

   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 */
   pp_blit(p->pipe, in, 0, 0,
           w, h, 0, p->framebuffer.cbufs[0],
           0, 0, w, h);

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

   {
      const struct pipe_sampler_state *samplers[] =
         {&p->sampler_point, &p->sampler_point};
      cso_set_samplers(p->cso, PIPE_SHADER_FRAGMENT, 2, samplers);
   }

   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;
}
static void
bind_samplers(struct xa_context *ctx,
	      const struct xa_composite *comp)
{
    struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
    struct pipe_sampler_state src_sampler, mask_sampler;
    struct pipe_sampler_view view_templ;
    struct pipe_sampler_view *src_view;
    struct pipe_context *pipe = ctx->pipe;
    struct xa_picture *src_pic = comp->src;
    struct xa_picture *mask_pic = comp->mask;

    ctx->num_bound_samplers = 0;

    memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
    memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));

    if (src_pic) {
	if (ctx->has_solid_color) {
	    samplers[0] = NULL;
	    pipe_sampler_view_reference(&ctx->bound_sampler_views[0], NULL);
	} else {
	    unsigned src_wrap = xa_repeat_to_gallium(src_pic->wrap);
	    int filter;

	    (void) xa_filter_to_gallium(src_pic->filter, &filter);

	    src_sampler.wrap_s = src_wrap;
	    src_sampler.wrap_t = src_wrap;
	    src_sampler.min_img_filter = filter;
	    src_sampler.mag_img_filter = filter;
	    src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
	    src_sampler.normalized_coords = 1;
	    samplers[0] = &src_sampler;
	    ctx->num_bound_samplers = 1;
	    u_sampler_view_default_template(&view_templ,
					    src_pic->srf->tex,
					    src_pic->srf->tex->format);
	    src_view = pipe->create_sampler_view(pipe, src_pic->srf->tex,
						 &view_templ);
	    pipe_sampler_view_reference(&ctx->bound_sampler_views[0], NULL);
	    ctx->bound_sampler_views[0] = src_view;
	}
    }

    if (mask_pic) {
	unsigned mask_wrap = xa_repeat_to_gallium(mask_pic->wrap);
	int filter;

	(void) xa_filter_to_gallium(mask_pic->filter, &filter);

	mask_sampler.wrap_s = mask_wrap;
	mask_sampler.wrap_t = mask_wrap;
	mask_sampler.min_img_filter = filter;
	mask_sampler.mag_img_filter = filter;
	src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
	mask_sampler.normalized_coords = 1;
	samplers[1] = &mask_sampler;
	ctx->num_bound_samplers = 2;
	u_sampler_view_default_template(&view_templ,
					mask_pic->srf->tex,
					mask_pic->srf->tex->format);
	src_view = pipe->create_sampler_view(pipe, mask_pic->srf->tex,
					     &view_templ);
	pipe_sampler_view_reference(&ctx->bound_sampler_views[1], NULL);
	ctx->bound_sampler_views[1] = src_view;


	/*
	 * If src is a solid color, we have no src view, so set up a
	 * dummy one that will not be used anyway.
	 */
	if (ctx->bound_sampler_views[0] == NULL)
	    pipe_sampler_view_reference(&ctx->bound_sampler_views[0],
					src_view);

    }

    cso_set_samplers(ctx->cso, PIPE_SHADER_FRAGMENT, ctx->num_bound_samplers,
		     (const struct pipe_sampler_state **)samplers);
    cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, ctx->num_bound_samplers,
				   ctx->bound_sampler_views);
}
Пример #14
0
/**
 * Update the gallium driver's sampler state for fragment, vertex or
 * geometry shader stage.
 */
static void
update_shader_samplers(struct st_context *st,
                       enum pipe_shader_type shader_stage,
                       const struct gl_program *prog,
                       unsigned max_units,
                       struct pipe_sampler_state *samplers,
                       unsigned *num_samplers)
{
   GLbitfield samplers_used = prog->SamplersUsed;
   GLbitfield free_slots = ~prog->SamplersUsed;
   GLbitfield external_samplers_used = prog->ExternalSamplersUsed;
   GLuint unit;
   const GLuint old_max = *num_samplers;
   const struct pipe_sampler_state *states[PIPE_MAX_SAMPLERS];

   if (*num_samplers == 0 && samplers_used == 0x0)
      return;

   *num_samplers = 0;

   /* loop over sampler units (aka tex image units) */
   for (unit = 0; unit < max_units; unit++, samplers_used >>= 1) {
      struct pipe_sampler_state *sampler = samplers + unit;

      if (samplers_used & 1) {
         const GLuint texUnit = prog->SamplerUnits[unit];

         convert_sampler(st, sampler, texUnit);
         states[unit] = sampler;
         *num_samplers = unit + 1;
      }
      else if (samplers_used != 0 || unit < old_max) {
         states[unit] = NULL;
      }
      else {
         /* if we've reset all the old samplers and we have no more new ones */
         break;
      }
   }

   /* For any external samplers with multiplaner YUV, stuff the additional
    * sampler states we need at the end.
    *
    * Just re-use the existing sampler-state from the primary slot.
    */
   while (unlikely(external_samplers_used)) {
      GLuint unit = u_bit_scan(&external_samplers_used);
      GLuint extra = 0;
      struct st_texture_object *stObj =
            st_get_texture_object(st->ctx, prog, unit);
      struct pipe_sampler_state *sampler = samplers + unit;

      if (!stObj)
         continue;

      switch (st_get_view_format(stObj)) {
      case PIPE_FORMAT_NV12:
         /* we need one additional sampler: */
         extra = u_bit_scan(&free_slots);
         states[extra] = sampler;
         break;
      case PIPE_FORMAT_IYUV:
         /* we need two additional samplers: */
         extra = u_bit_scan(&free_slots);
         states[extra] = sampler;
         extra = u_bit_scan(&free_slots);
         states[extra] = sampler;
         break;
      default:
         break;
      }

      *num_samplers = MAX2(*num_samplers, extra + 1);
   }

   cso_set_samplers(st->cso_context, shader_stage, *num_samplers, states);
}
Пример #15
0
void
renderer_copy_prepare(struct xa_context *r,
		      struct pipe_surface *dst_surface,
		      struct pipe_resource *src_texture,
		      const enum xa_formats src_xa_format,
		      const enum xa_formats dst_xa_format)
{
    struct pipe_context *pipe = r->pipe;
    struct pipe_screen *screen = pipe->screen;
    struct xa_shader shader;
    uint32_t fs_traits = FS_COMPOSITE;

    assert(screen->is_format_supported(screen, dst_surface->format,
				       PIPE_TEXTURE_2D, 0,
				       PIPE_BIND_RENDER_TARGET));
    (void)screen;

    renderer_bind_destination(r, dst_surface);

    /* set misc state we care about */
    {
	struct pipe_blend_state blend;

	memset(&blend, 0, sizeof(blend));
	blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
	blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
	blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
	blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
	blend.rt[0].colormask = PIPE_MASK_RGBA;
	cso_set_blend(r->cso, &blend);
    }

    /* sampler */
    {
	struct pipe_sampler_state sampler;
        const struct pipe_sampler_state *p_sampler = &sampler;

	memset(&sampler, 0, sizeof(sampler));
	sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
	sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
	sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
	sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
	sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
	sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
	sampler.normalized_coords = 1;
        cso_set_samplers(r->cso, PIPE_SHADER_FRAGMENT, 1, &p_sampler);
        r->num_bound_samplers = 1;
    }

    /* texture/sampler view */
    {
	struct pipe_sampler_view templ;
	struct pipe_sampler_view *src_view;

	u_sampler_view_default_template(&templ,
					src_texture, src_texture->format);
	src_view = pipe->create_sampler_view(pipe, src_texture, &templ);
	cso_set_sampler_views(r->cso, PIPE_SHADER_FRAGMENT, 1, &src_view);
	pipe_sampler_view_reference(&src_view, NULL);
    }

    /* shaders */
    if (src_texture->format == PIPE_FORMAT_L8_UNORM)
	fs_traits |= FS_SRC_LUMINANCE;
    if (dst_surface->format == PIPE_FORMAT_L8_UNORM)
	fs_traits |= FS_DST_LUMINANCE;
    if (xa_format_a(dst_xa_format) != 0 &&
	xa_format_a(src_xa_format) == 0)
	fs_traits |= FS_SRC_SET_ALPHA;

    shader = xa_shaders_get(r->shaders, VS_COMPOSITE, fs_traits);
    cso_set_vertex_shader_handle(r->cso, shader.vs);
    cso_set_fragment_shader_handle(r->cso, shader.fs);

    r->buffer_size = 0;
    r->attrs_per_vertex = 2;
}