Beispiel #1
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, num_samplers, samplers);
      cso_set_fragment_sampler_views(renderer->cso, 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, const_buffer_len);
         pipe_buffer_write(renderer->pipe, cbuf, 0,
               const_buffer_len, const_buffer);
         renderer->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;
         }
      }
   }
}
Beispiel #2
0
enum pipe_error cso_set_fragment_shader(struct cso_context *ctx,
                                        const struct pipe_shader_state *templ)
{
   const struct tgsi_token *tokens = templ->tokens;
   unsigned num_tokens = tgsi_num_tokens(tokens);
   size_t tokens_size = num_tokens*sizeof(struct tgsi_token);
   unsigned hash_key = cso_construct_key((void*)tokens, tokens_size);
   struct cso_hash_iter iter = cso_find_state_template(ctx->cache,
                                                       hash_key, 
                                                       CSO_FRAGMENT_SHADER,
                                                       (void*)tokens,
                                                       sizeof(*templ)); /* XXX correct? tokens_size? */
   void *handle = NULL;

   if (cso_hash_iter_is_null(iter)) {
      struct cso_fragment_shader *cso = MALLOC(sizeof(struct cso_fragment_shader) + tokens_size);
      struct tgsi_token *cso_tokens = (struct tgsi_token *)((char *)cso + sizeof(*cso));

      if (!cso)
         return PIPE_ERROR_OUT_OF_MEMORY;

      memcpy(cso_tokens, tokens, tokens_size);
      cso->state.tokens = cso_tokens;
      cso->data = ctx->pipe->create_fs_state(ctx->pipe, &cso->state);
      cso->delete_state = (cso_state_callback)ctx->pipe->delete_fs_state;
      cso->context = ctx->pipe;

      iter = cso_insert_state(ctx->cache, hash_key, CSO_FRAGMENT_SHADER, cso);
      if (cso_hash_iter_is_null(iter)) {
         FREE(cso);
         return PIPE_ERROR_OUT_OF_MEMORY;
      }

      handle = cso->data;
   }
   else {
      handle = ((struct cso_fragment_shader *)cso_hash_iter_data(iter))->data;
   }

   return cso_set_fragment_shader_handle( ctx, handle );
}
Beispiel #3
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]);
}
Beispiel #4
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;
}
Beispiel #5
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;

    /* 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;

	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_single_sampler(r->cso, 0, &sampler);
	cso_single_sampler_done(r->cso);
    }

    renderer_bind_destination(r, dst_surface,
			      dst_surface->width, dst_surface->height);

    /* 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_fragment_sampler_views(r->cso, 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;
}
Beispiel #6
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);
}
static void update_clip_state(struct vg_context *ctx)
{
   struct pipe_depth_stencil_alpha_state *dsa = &ctx->state.g3d.dsa;
   struct vg_state *state =  &ctx->state.vg;

   memset(dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));

   if (state->scissoring) {
      struct pipe_blend_state *blend = &ctx->state.g3d.blend;
      struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb;
      int i;

      dsa->depth.writemask = 1;/*glDepthMask(TRUE);*/
      dsa->depth.func = PIPE_FUNC_ALWAYS;
      dsa->depth.enabled = 1;

      cso_save_blend(ctx->cso_context);
      cso_save_fragment_shader(ctx->cso_context);
      /* set a passthrough shader */
      if (!ctx->pass_through_depth_fs)
         ctx->pass_through_depth_fs = shader_create_from_text(ctx->pipe,
                                                              pass_through_depth_asm,
                                                              40,
                                                              PIPE_SHADER_FRAGMENT);
      cso_set_fragment_shader_handle(ctx->cso_context,
                                     ctx->pass_through_depth_fs->driver);
      cso_set_depth_stencil_alpha(ctx->cso_context, dsa);

      ctx->pipe->clear(ctx->pipe, PIPE_CLEAR_DEPTHSTENCIL, NULL, 1.0, 0);

      /* disable color writes */
      blend->rt[0].colormask = 0; /*disable colorwrites*/
      cso_set_blend(ctx->cso_context, blend);

      /* enable scissoring */
      for (i = 0; i < state->scissor_rects_num; ++i) {
         const float x      = state->scissor_rects[i * 4 + 0].f;
         const float y      = state->scissor_rects[i * 4 + 1].f;
         const float width  = state->scissor_rects[i * 4 + 2].f;
         const float height = state->scissor_rects[i * 4 + 3].f;
         VGfloat minx, miny, maxx, maxy;

         minx = 0;
         miny = 0;
         maxx = fb->width;
         maxy = fb->height;

         if (x > minx)
            minx = x;
         if (y > miny)
            miny = y;

         if (x + width < maxx)
            maxx = x + width;
         if (y + height < maxy)
            maxy = y + height;

         /* check for null space */
         if (minx >= maxx || miny >= maxy)
            minx = miny = maxx = maxy = 0;

         /*glClear(GL_DEPTH_BUFFER_BIT);*/
         renderer_draw_quad(ctx->renderer, minx, miny, maxx, maxy, 0.0f);
      }

      cso_restore_blend(ctx->cso_context);
      cso_restore_fragment_shader(ctx->cso_context);

      dsa->depth.enabled = 1; /* glEnable(GL_DEPTH_TEST); */
      dsa->depth.writemask = 0;/*glDepthMask(FALSE);*/
      dsa->depth.func = PIPE_FUNC_GEQUAL;
   }
}
Beispiel #8
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);

   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, 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);

   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 */
   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);

   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;
}
Beispiel #9
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(GLcontext *ctx,
                GLboolean color, GLboolean depth, GLboolean stencil)
{
   struct st_context *st = ctx->st;
   const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin;
   const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax;
   GLfloat y0, y1;

   if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
      y0 = (GLfloat) (ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymax);
      y1 = (GLfloat) (ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymin);
   }
   else {
      y0 = (GLfloat) ctx->DrawBuffer->_Ymin;
      y1 = (GLfloat) ctx->DrawBuffer->_Ymax;
   }

   /*
   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_depth_stencil_alpha(st->cso_context);
   cso_save_rasterizer(st->cso_context);
   cso_save_fragment_shader(st->cso_context);
   cso_save_vertex_shader(st->cso_context);

   /* blend state: RGBA masking */
   {
      struct pipe_blend_state blend;
      memset(&blend, 0, sizeof(blend));
      blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
      blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
      blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
      blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
      if (color) {
         if (ctx->Color.ColorMask[0])
            blend.colormask |= PIPE_MASK_R;
         if (ctx->Color.ColorMask[1])
            blend.colormask |= PIPE_MASK_G;
         if (ctx->Color.ColorMask[2])
            blend.colormask |= PIPE_MASK_B;
         if (ctx->Color.ColorMask[3])
            blend.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 (depth) {
         depth_stencil.depth.enabled = 1;
         depth_stencil.depth.writemask = 1;
         depth_stencil.depth.func = PIPE_FUNC_ALWAYS;
      }

      if (stencil) {
         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].ref_value = ctx->Stencil.Clear;
         depth_stencil.stencil[0].valuemask = 0xff;
         depth_stencil.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff;
      }

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

   cso_set_rasterizer(st->cso_context, &st->clear.raster);

   cso_set_fragment_shader_handle(st->cso_context, st->clear.fs);
   cso_set_vertex_shader_handle(st->cso_context, st->clear.vs);

   /* draw quad matching scissor rect (XXX verify coord round-off) */
   draw_quad(ctx, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, ctx->Color.ClearColor);

   /* Restore pipe state */
   cso_restore_blend(st->cso_context);
   cso_restore_depth_stencil_alpha(st->cso_context);
   cso_restore_rasterizer(st->cso_context);
   cso_restore_fragment_shader(st->cso_context);
   cso_restore_vertex_shader(st->cso_context);
}
Beispiel #10
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);
}
Beispiel #11
0
static void
draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
                   GLsizei width, GLsizei height,
                   GLfloat zoomX, GLfloat zoomY,
                   struct pipe_sampler_view **sv,
                   int num_sampler_view,
                   void *driver_vp,
                   void *driver_fp,
                   const GLfloat *color,
                   GLboolean invertTex,
                   GLboolean write_depth, GLboolean write_stencil)
{
   struct st_context *st = st_context(ctx);
   struct pipe_context *pipe = st->pipe;
   struct cso_context *cso = st->cso_context;
   GLfloat x0, y0, x1, y1;
   GLsizei maxSize;
   boolean normalized = sv[0]->texture->target != PIPE_TEXTURE_RECT;

   /* limit checks */
   /* XXX if DrawPixels image is larger than 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 <= maxSize);
   assert(height <= maxSize);

   cso_save_rasterizer(cso);
   cso_save_viewport(cso);
   cso_save_samplers(cso);
   cso_save_fragment_sampler_views(cso);
   cso_save_fragment_shader(cso);
   cso_save_vertex_shader(cso);
   cso_save_vertex_elements(cso);
   cso_save_vertex_buffers(cso);
   if (write_stencil) {
      cso_save_depth_stencil_alpha(cso);
      cso_save_blend(cso);
   }

   /* rasterizer state: just scissor */
   {
      struct pipe_rasterizer_state rasterizer;
      memset(&rasterizer, 0, sizeof(rasterizer));
      rasterizer.clamp_fragment_color = ctx->Color._ClampFragmentColor;
      rasterizer.gl_rasterization_rules = 1;
      rasterizer.scissor = ctx->Scissor.Enabled;
      cso_set_rasterizer(cso, &rasterizer);
   }

   if (write_stencil) {
      /* Stencil writing bypasses the normal fragment pipeline to
       * disable color writing and set stencil test to always pass.
       */
      struct pipe_depth_stencil_alpha_state dsa;
      struct pipe_blend_state blend;

      /* depth/stencil */
      memset(&dsa, 0, sizeof(dsa));
      dsa.stencil[0].enabled = 1;
      dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
      dsa.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff;
      dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
      if (write_depth) {
         /* writing depth+stencil: depth test always passes */
         dsa.depth.enabled = 1;
         dsa.depth.writemask = ctx->Depth.Mask;
         dsa.depth.func = PIPE_FUNC_ALWAYS;
      }
      cso_set_depth_stencil_alpha(cso, &dsa);

      /* blend (colormask) */
      memset(&blend, 0, sizeof(blend));
      cso_set_blend(cso, &blend);
   }

   /* fragment shader state: TEX lookup program */
   cso_set_fragment_shader_handle(cso, driver_fp);

   /* vertex shader state: position + texcoord pass-through */
   cso_set_vertex_shader_handle(cso, driver_vp);


   /* texture sampling state: */
   {
      struct pipe_sampler_state sampler;
      memset(&sampler, 0, sizeof(sampler));
      sampler.wrap_s = PIPE_TEX_WRAP_CLAMP;
      sampler.wrap_t = PIPE_TEX_WRAP_CLAMP;
      sampler.wrap_r = PIPE_TEX_WRAP_CLAMP;
      sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
      sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
      sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
      sampler.normalized_coords = normalized;

      cso_single_sampler(cso, 0, &sampler);
      if (num_sampler_view > 1) {
         cso_single_sampler(cso, 1, &sampler);
      }
      cso_single_sampler_done(cso);
   }

   /* viewport state: viewport matching window dims */
   {
      const float w = (float) ctx->DrawBuffer->Width;
      const float h = (float) ctx->DrawBuffer->Height;
      struct pipe_viewport_state vp;
      vp.scale[0] =  0.5f * w;
      vp.scale[1] = -0.5f * h;
      vp.scale[2] = 0.5f;
      vp.scale[3] = 1.0f;
      vp.translate[0] = 0.5f * w;
      vp.translate[1] = 0.5f * h;
      vp.translate[2] = 0.5f;
      vp.translate[3] = 0.0f;
      cso_set_viewport(cso, &vp);
   }

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

   /* texture state: */
   cso_set_fragment_sampler_views(cso, num_sampler_view, sv);

   /* Compute Gallium window coords (y=0=top) with pixel zoom.
    * Recall that these coords are transformed by the current
    * vertex shader and viewport transformation.
    */
   if (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM) {
      y = ctx->DrawBuffer->Height - (int) (y + height * ctx->Pixel.ZoomY);
      invertTex = !invertTex;
   }

   x0 = (GLfloat) x;
   x1 = x + width * ctx->Pixel.ZoomX;
   y0 = (GLfloat) y;
   y1 = y + height * ctx->Pixel.ZoomY;

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

   draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex,
             normalized ? ((GLfloat) width / sv[0]->texture->width0) : (GLfloat)width,
             normalized ? ((GLfloat) height / sv[0]->texture->height0) : (GLfloat)height);

   /* restore state */
   cso_restore_rasterizer(cso);
   cso_restore_viewport(cso);
   cso_restore_samplers(cso);
   cso_restore_fragment_sampler_views(cso);
   cso_restore_fragment_shader(cso);
   cso_restore_vertex_shader(cso);
   cso_restore_vertex_elements(cso);
   cso_restore_vertex_buffers(cso);
   if (write_stencil) {
      cso_restore_depth_stencil_alpha(cso);
      cso_restore_blend(cso);
   }
}
Beispiel #12
0
struct st_context *
st_context_create(struct st_device *st_dev) 
{
   struct st_context *st_ctx;
   
   st_ctx = CALLOC_STRUCT(st_context);
   if(!st_ctx)
      return NULL;
   
   st_device_reference(&st_ctx->st_dev, st_dev);
   
   st_ctx->real_pipe = st_dev->st_ws->context_create(st_dev->real_screen);
   if(!st_ctx->real_pipe) {
      st_context_destroy(st_ctx);
      return NULL;
   }
   
   st_ctx->pipe = trace_context_create(st_dev->screen, st_ctx->real_pipe);
   if(!st_ctx->pipe) {
      st_context_destroy(st_ctx);
      return NULL;
   }

   st_ctx->cso = cso_create_context(st_ctx->pipe);
   if(!st_ctx->cso) {
      st_context_destroy(st_ctx);
      return NULL;
   }
   
   /* disabled blending/masking */
   {
      struct pipe_blend_state blend;
      memset(&blend, 0, sizeof(blend));
      blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
      blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
      blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
      blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
      blend.colormask = PIPE_MASK_RGBA;
      cso_set_blend(st_ctx->cso, &blend);
   }

   /* no-op depth/stencil/alpha */
   {
      struct pipe_depth_stencil_alpha_state depthstencil;
      memset(&depthstencil, 0, sizeof(depthstencil));
      cso_set_depth_stencil_alpha(st_ctx->cso, &depthstencil);
   }

   /* rasterizer */
   {
      struct pipe_rasterizer_state rasterizer;
      memset(&rasterizer, 0, sizeof(rasterizer));
      rasterizer.front_winding = PIPE_WINDING_CW;
      rasterizer.cull_mode = PIPE_WINDING_NONE;
      cso_set_rasterizer(st_ctx->cso, &rasterizer);
   }

   /* clip */
   {
      struct pipe_clip_state clip;
      memset(&clip, 0, sizeof(clip));
      st_ctx->pipe->set_clip_state(st_ctx->pipe, &clip);
   }

   /* identity viewport */
   {
      struct pipe_viewport_state viewport;
      viewport.scale[0] = 1.0;
      viewport.scale[1] = 1.0;
      viewport.scale[2] = 1.0;
      viewport.scale[3] = 1.0;
      viewport.translate[0] = 0.0;
      viewport.translate[1] = 0.0;
      viewport.translate[2] = 0.0;
      viewport.translate[3] = 0.0;
      cso_set_viewport(st_ctx->cso, &viewport);
   }

   /* samplers */
   {
      struct pipe_sampler_state sampler;
      unsigned i;
      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_NEAREST;
      sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
      sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
      sampler.normalized_coords = 1;
      for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
         cso_single_sampler(st_ctx->cso, i, &sampler);
      cso_single_sampler_done(st_ctx->cso);
   }

   /* default textures */
   {
      struct pipe_screen *screen = st_dev->screen;
      struct pipe_texture templat;
      struct pipe_transfer *transfer;
      unsigned i;

      memset( &templat, 0, sizeof( templat ) );
      templat.target = PIPE_TEXTURE_2D;
      templat.format = PIPE_FORMAT_A8R8G8B8_UNORM;
      templat.block.size = 4;
      templat.block.width = 1;
      templat.block.height = 1;
      templat.width[0] = 1;
      templat.height[0] = 1;
      templat.depth[0] = 1;
      templat.last_level = 0;
   
      st_ctx->default_texture = screen->texture_create( screen, &templat );
      if(st_ctx->default_texture) {
         transfer = screen->get_tex_transfer(screen,
                                             st_ctx->default_texture,
                                             0, 0, 0,
                                             PIPE_TRANSFER_WRITE,
                                             0, 0,
                                             st_ctx->default_texture->width[0],
                                             st_ctx->default_texture->height[0]);
         if (transfer) {
            uint32_t *map;
            map = (uint32_t *) screen->transfer_map(screen, transfer);
            if(map) {
               *map = 0x00000000;
               screen->transfer_unmap(screen, transfer);
            }
            screen->tex_transfer_destroy(transfer);
         }
      }
   
      for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
         pipe_texture_reference(&st_ctx->sampler_textures[i], st_ctx->default_texture);
      
      cso_set_sampler_textures(st_ctx->cso, PIPE_MAX_SAMPLERS, st_ctx->sampler_textures);
   }
   
   /* vertex shader */
   {
      const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
                                      TGSI_SEMANTIC_GENERIC };
      const uint semantic_indexes[] = { 0, 0 };
      st_ctx->vs = util_make_vertex_passthrough_shader(st_ctx->pipe, 
                                                       2, 
                                                       semantic_names,
                                                       semantic_indexes);
      cso_set_vertex_shader_handle(st_ctx->cso, st_ctx->vs);
   }

   /* fragment shader */
   {
      st_ctx->fs = util_make_fragment_passthrough_shader(st_ctx->pipe);
      cso_set_fragment_shader_handle(st_ctx->cso, st_ctx->fs);
   }

   return st_ctx;
}
Beispiel #13
0
void renderer_copy_surface(struct renderer *ctx,
                           struct pipe_surface *src,
                           int srcX0, int srcY0,
                           int srcX1, int srcY1,
                           struct pipe_surface *dst,
                           int dstX0, int dstY0,
                           int dstX1, int dstY1,
                           float z, unsigned filter)
{
   struct pipe_context *pipe = ctx->pipe;
   struct pipe_screen *screen = pipe->screen;
   struct pipe_buffer *buf;
   struct pipe_texture texTemp, *tex;
   struct pipe_surface *texSurf;
   struct pipe_framebuffer_state fb;
   struct st_framebuffer *stfb = ctx->owner->draw_buffer;
   const int srcW = abs(srcX1 - srcX0);
   const int srcH = abs(srcY1 - srcY0);
   const int srcLeft = MIN2(srcX0, srcX1);
   const int srcTop = MIN2(srcY0, srcY1);

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

   if (srcLeft != srcX0) {
      /* left-right flip */
      int tmp = dstX0;
      dstX0 = dstX1;
      dstX1 = tmp;
   }

   if (srcTop != srcY0) {
      /* up-down flip */
      int tmp = dstY0;
      dstY0 = dstY1;
      dstY1 = tmp;
   }

   assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D,
                                      PIPE_TEXTURE_USAGE_SAMPLER, 0));
   assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
                                      PIPE_TEXTURE_USAGE_SAMPLER, 0));
   assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
                                      PIPE_TEXTURE_USAGE_RENDER_TARGET, 0));

   /*
    * XXX for now we're always creating a temporary texture.
    * Strictly speaking that's not always needed.
    */

   /* create temp texture */
   memset(&texTemp, 0, sizeof(texTemp));
   texTemp.target = PIPE_TEXTURE_2D;
   texTemp.format = src->format;
   texTemp.last_level = 0;
   texTemp.width0 = srcW;
   texTemp.height0 = srcH;
   texTemp.depth0 = 1;

   tex = screen->texture_create(screen, &texTemp);
   if (!tex)
      return;

   texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0,
                                     PIPE_BUFFER_USAGE_GPU_WRITE);

   /* load temp texture */
   if (pipe->surface_copy) {
      pipe->surface_copy(pipe,
                         texSurf, 0, 0,   /* dest */
                         src, srcLeft, srcTop, /* src */
                         srcW, srcH);     /* size */
   } else {
      util_surface_copy(pipe, FALSE,
                        texSurf, 0, 0,   /* dest */
                        src, srcLeft, srcTop, /* src */
                        srcW, srcH);     /* size */
   }

   /* free the surface, update the texture if necessary.*/
   screen->tex_surface_destroy(texSurf);

   /* save state (restored below) */
   cso_save_blend(ctx->cso);
   cso_save_samplers(ctx->cso);
   cso_save_sampler_textures(ctx->cso);
   cso_save_framebuffer(ctx->cso);
   cso_save_fragment_shader(ctx->cso);
   cso_save_vertex_shader(ctx->cso);
   cso_save_viewport(ctx->cso);

   /* 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(ctx->cso, &blend);
   }

   vg_set_viewport(ctx->owner, VEGA_Y0_TOP);

   /* sampler */
   {
      struct pipe_sampler_state 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_single_sampler(ctx->cso, 0, &sampler);
      cso_single_sampler_done(ctx->cso);
   }

   /* texture */
   cso_set_sampler_textures(ctx->cso, 1, &tex);

   /* shaders */
   cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
   cso_set_vertex_shader_handle(ctx->cso, vg_texture_vs(ctx->owner));

   /* drawing dest */
   if (stfb->strb->surface != dst) {
      memset(&fb, 0, sizeof(fb));
      fb.width = dst->width;
      fb.height = dst->height;
      fb.nr_cbufs = 1;
      fb.cbufs[0] = dst;
      fb.zsbuf = stfb->dsrb->surface;
      cso_set_framebuffer(ctx->cso, &fb);
   }

   /* draw quad */
   buf = setup_vertex_data(ctx,
                           (float) dstX0, (float) dstY0,
                           (float) dstX1, (float) dstY1, z);

   if (buf) {
      util_draw_vertex_buffer(ctx->pipe, buf, 0,
                              PIPE_PRIM_TRIANGLE_FAN,
                              4,  /* verts */
                              2); /* attribs/vert */

      pipe_buffer_reference( &buf,
                             NULL );
   }


   /* restore state we changed */
   cso_restore_blend(ctx->cso);
   cso_restore_samplers(ctx->cso);
   cso_restore_sampler_textures(ctx->cso);
   cso_restore_framebuffer(ctx->cso);
   cso_restore_fragment_shader(ctx->cso);
   cso_restore_vertex_shader(ctx->cso);
   cso_restore_viewport(ctx->cso);

   pipe_texture_reference(&tex, NULL);
}
Beispiel #14
0
void renderer_copy_texture(struct renderer *ctx,
                           struct pipe_texture *src,
                           VGfloat sx1, VGfloat sy1,
                           VGfloat sx2, VGfloat sy2,
                           struct pipe_texture *dst,
                           VGfloat dx1, VGfloat dy1,
                           VGfloat dx2, VGfloat dy2)
{
   struct pipe_context *pipe = ctx->pipe;
   struct pipe_screen *screen = pipe->screen;
   struct pipe_buffer *buf;
   struct pipe_surface *dst_surf = screen->get_tex_surface(
      screen, dst, 0, 0, 0,
      PIPE_BUFFER_USAGE_GPU_WRITE);
   struct pipe_framebuffer_state fb;
   float s0, t0, s1, t1;

   assert(src->width0 != 0);
   assert(src->height0 != 0);
   assert(dst->width0 != 0);
   assert(dst->height0 != 0);

#if 0
   debug_printf("copy texture [%f, %f, %f, %f], [%f, %f, %f, %f]\n",
                sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
#endif

#if 1
   s0 = sx1 / src->width0;
   s1 = sx2 / src->width0;
   t0 = sy1 / src->height0;
   t1 = sy2 / src->height0;
#else
   s0 = 0;
   s1 = 1;
   t0 = 0;
   t1 = 1;
#endif

   assert(screen->is_format_supported(screen, dst_surf->format, PIPE_TEXTURE_2D,
                                      PIPE_TEXTURE_USAGE_RENDER_TARGET, 0));

   /* save state (restored below) */
   cso_save_blend(ctx->cso);
   cso_save_samplers(ctx->cso);
   cso_save_sampler_textures(ctx->cso);
   cso_save_framebuffer(ctx->cso);
   cso_save_fragment_shader(ctx->cso);
   cso_save_vertex_shader(ctx->cso);

   cso_save_viewport(ctx->cso);


   /* 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(ctx->cso, &blend);
   }

   /* sampler */
   {
      struct pipe_sampler_state 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_single_sampler(ctx->cso, 0, &sampler);
      cso_single_sampler_done(ctx->cso);
   }

   vg_set_viewport(ctx->owner, VEGA_Y0_TOP);

   /* texture */
   cso_set_sampler_textures(ctx->cso, 1, &src);

   /* shaders */
   cso_set_vertex_shader_handle(ctx->cso, vg_texture_vs(ctx->owner));
   cso_set_fragment_shader_handle(ctx->cso, ctx->fs);

   /* drawing dest */
   memset(&fb, 0, sizeof(fb));
   fb.width = dst_surf->width;
   fb.height = dst_surf->height;
   fb.nr_cbufs = 1;
   fb.cbufs[0] = dst_surf;
   {
      VGint i;
      for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i)
         fb.cbufs[i] = 0;
   }
   cso_set_framebuffer(ctx->cso, &fb);

   /* draw quad */
   buf = setup_vertex_data_tex(ctx,
                         dx1, dy1,
                         dx2, dy2,
                         s0, t0, s1, t1,
                         0.0f);

   if (buf) {
      util_draw_vertex_buffer(ctx->pipe, buf, 0,
                              PIPE_PRIM_TRIANGLE_FAN,
                              4,  /* verts */
                              2); /* attribs/vert */

      pipe_buffer_reference( &buf,
                             NULL );
   }

   /* restore state we changed */
   cso_restore_blend(ctx->cso);
   cso_restore_samplers(ctx->cso);
   cso_restore_sampler_textures(ctx->cso);
   cso_restore_framebuffer(ctx->cso);
   cso_restore_vertex_shader(ctx->cso);
   cso_restore_fragment_shader(ctx->cso);
   cso_restore_viewport(ctx->cso);

   pipe_surface_reference(&dst_surf, NULL);
}
Beispiel #15
0
static void
draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
                   GLsizei width, GLsizei height,
                   GLfloat zoomX, GLfloat zoomY,
                   struct pipe_texture *pt,
                   struct st_vertex_program *stvp,
                   struct st_fragment_program *stfp,
                   const GLfloat *color,
                   GLboolean invertTex)
{
   struct st_context *st = ctx->st;
   struct pipe_context *pipe = ctx->st->pipe;
   struct cso_context *cso = ctx->st->cso_context;
   GLfloat x0, y0, x1, y1;
   GLsizei maxSize;

   /* limit checks */
   /* XXX if DrawPixels image is larger than 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 <= maxSize);
   assert(height <= maxSize);

   cso_save_rasterizer(cso);
   cso_save_viewport(cso);
   cso_save_samplers(cso);
   cso_save_sampler_textures(cso);
   cso_save_fragment_shader(cso);
   cso_save_vertex_shader(cso);

   /* rasterizer state: just scissor */
   {
      struct pipe_rasterizer_state rasterizer;
      memset(&rasterizer, 0, sizeof(rasterizer));
      rasterizer.gl_rasterization_rules = 1;
      rasterizer.scissor = ctx->Scissor.Enabled;
      cso_set_rasterizer(cso, &rasterizer);
   }

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

   /* vertex shader state: position + texcoord pass-through */
   cso_set_vertex_shader_handle(cso, stvp->driver_shader);


   /* texture sampling state: */
   {
      struct pipe_sampler_state sampler;
      memset(&sampler, 0, sizeof(sampler));
      sampler.wrap_s = PIPE_TEX_WRAP_CLAMP;
      sampler.wrap_t = PIPE_TEX_WRAP_CLAMP;
      sampler.wrap_r = PIPE_TEX_WRAP_CLAMP;
      sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
      sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
      sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
      sampler.normalized_coords = 1;

      cso_single_sampler(cso, 0, &sampler);
      if (st->pixel_xfer.pixelmap_enabled) {
         cso_single_sampler(cso, 1, &sampler);
      }
      cso_single_sampler_done(cso);
   }

   /* viewport state: viewport matching window dims */
   {
      const float width = (float) ctx->DrawBuffer->Width;
      const float height = (float) ctx->DrawBuffer->Height;
      struct pipe_viewport_state vp;
      vp.scale[0] =  0.5f * width;
      vp.scale[1] = -0.5f * height;
      vp.scale[2] = 1.0f;
      vp.scale[3] = 1.0f;
      vp.translate[0] = 0.5f * width;
      vp.translate[1] = 0.5f * height;
      vp.translate[2] = 0.0f;
      vp.translate[3] = 0.0f;
      cso_set_viewport(cso, &vp);
   }

   /* texture state: */
   if (st->pixel_xfer.pixelmap_enabled) {
      struct pipe_texture *textures[2];
      textures[0] = pt;
      textures[1] = st->pixel_xfer.pixelmap_texture;
      pipe->set_sampler_textures(pipe, 2, textures);
   }
   else {
      pipe->set_sampler_textures(pipe, 1, &pt);
   }

   /* Compute window coords (y=0=bottom) with pixel zoom.
    * Recall that these coords are transformed by the current
    * vertex shader and viewport transformation.
    */
   x0 = (GLfloat) x;
   x1 = x + width * ctx->Pixel.ZoomX;
   y0 = (GLfloat) y;
   y1 = y + height * ctx->Pixel.ZoomY;

   draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex);

   /* restore state */
   cso_restore_rasterizer(cso);
   cso_restore_viewport(cso);
   cso_restore_samplers(cso);
   cso_restore_sampler_textures(cso);
   cso_restore_fragment_shader(cso);
   cso_restore_vertex_shader(cso);
}
Beispiel #16
0
static void
test_texture_barrier(struct pipe_context *ctx, bool use_fbfetch,
                     unsigned num_samples)
{
   struct cso_context *cso;
   struct pipe_resource *cb;
   struct pipe_sampler_view *view = NULL;
   char name[256];
   const char *text;

   assert(num_samples >= 1 && num_samples <= 8);

   util_snprintf(name, sizeof(name), "%s: %s, %u samples", __func__,
                 use_fbfetch ? "FBFETCH" : "sampler", MAX2(num_samples, 1));

   if (!ctx->screen->get_param(ctx->screen, PIPE_CAP_TEXTURE_BARRIER)) {
      util_report_result_helper(SKIP, name);
      return;
   }
   if (use_fbfetch &&
       !ctx->screen->get_param(ctx->screen, PIPE_CAP_TGSI_FS_FBFETCH)) {
      util_report_result_helper(SKIP, name);
      return;
   }

   cso = cso_create_context(ctx, 0);
   cb = util_create_texture2d(ctx->screen, 256, 256,
                              PIPE_FORMAT_R8G8B8A8_UNORM, num_samples);
   util_set_common_states_and_clear(cso, ctx, cb);

   /* Clear each sample to a different value. */
   if (num_samples > 1) {
      void *fs =
         util_make_fragment_passthrough_shader(ctx, TGSI_SEMANTIC_GENERIC,
                                               TGSI_INTERPOLATE_LINEAR, TRUE);
      cso_set_fragment_shader_handle(cso, fs);

      /* Vertex shader. */
      void *vs = util_set_passthrough_vertex_shader(cso, ctx, false);

      for (unsigned i = 0; i < num_samples / 2; i++) {
         float value;

         /* 2 consecutive samples should have the same color to test MSAA
          * compression properly.
          */
         if (num_samples == 2) {
            value = 0.1;
         } else {
            /* The average value must be 0.1 */
            static const float values[] = {
               0.0, 0.2, 0.05, 0.15
            };
            value = values[i];
         }

         ctx->set_sample_mask(ctx, 0x3 << (i * 2));
         util_draw_fullscreen_quad_fill(cso, value, value, value, value);
      }
      ctx->set_sample_mask(ctx, ~0);

      cso_set_vertex_shader_handle(cso, NULL);
      cso_set_fragment_shader_handle(cso, NULL);
      ctx->delete_vs_state(ctx, vs);
      ctx->delete_fs_state(ctx, fs);
   }

   if (use_fbfetch) {
      /* Fragment shader. */
      text = "FRAG\n"
             "DCL OUT[0], COLOR[0]\n"
             "DCL TEMP[0]\n"
             "IMM[0] FLT32 { 0.1, 0.2, 0.3, 0.4}\n"

             "FBFETCH TEMP[0], OUT[0]\n"
             "ADD OUT[0], TEMP[0], IMM[0]\n"
             "END\n";
   } else {
      struct pipe_sampler_view templ = {{0}};
      templ.format = cb->format;
      templ.target = cb->target;
      templ.swizzle_r = PIPE_SWIZZLE_X;
      templ.swizzle_g = PIPE_SWIZZLE_Y;
      templ.swizzle_b = PIPE_SWIZZLE_Z;
      templ.swizzle_a = PIPE_SWIZZLE_W;
      view = ctx->create_sampler_view(ctx, cb, &templ);
      ctx->set_sampler_views(ctx, PIPE_SHADER_FRAGMENT, 0, 1, &view);

      /* Fragment shader. */
      if (num_samples > 1) {
         text = "FRAG\n"
                "DCL SV[0], POSITION\n"
                "DCL SV[1], SAMPLEID\n"
                "DCL SAMP[0]\n"
                "DCL SVIEW[0], 2D_MSAA, FLOAT\n"
                "DCL OUT[0], COLOR[0]\n"
                "DCL TEMP[0]\n"
                "IMM[0] FLT32 { 0.1, 0.2, 0.3, 0.4}\n"

                "F2I TEMP[0].xy, SV[0].xyyy\n"
                "MOV TEMP[0].w, SV[1].xxxx\n"
                "TXF TEMP[0], TEMP[0], SAMP[0], 2D_MSAA\n"
                "ADD OUT[0], TEMP[0], IMM[0]\n"
                "END\n";
      } else {
         text = "FRAG\n"
                "DCL SV[0], POSITION\n"
                "DCL SAMP[0]\n"
                "DCL SVIEW[0], 2D, FLOAT\n"
                "DCL OUT[0], COLOR[0]\n"
                "DCL TEMP[0]\n"
                "IMM[0] FLT32 { 0.1, 0.2, 0.3, 0.4}\n"
                "IMM[1] INT32 { 0, 0, 0, 0}\n"

                "F2I TEMP[0].xy, SV[0].xyyy\n"
                "MOV TEMP[0].zw, IMM[1]\n"
                "TXF TEMP[0], TEMP[0], SAMP[0], 2D\n"
                "ADD OUT[0], TEMP[0], IMM[0]\n"
                "END\n";
      }
   }

   struct tgsi_token tokens[1000];
   struct pipe_shader_state state;

   if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) {
      assert(0);
      util_report_result_helper(FAIL, name);
      return;
   }
   pipe_shader_state_from_tgsi(&state, tokens);

   void *fs = ctx->create_fs_state(ctx, &state);
   cso_set_fragment_shader_handle(cso, fs);

   /* Vertex shader. */
   void *vs = util_set_passthrough_vertex_shader(cso, ctx, false);

   if (num_samples > 1 && !use_fbfetch)
      ctx->set_min_samples(ctx, num_samples);

   for (int i = 0; i < 2; i++) {
      ctx->texture_barrier(ctx,
                           use_fbfetch ? PIPE_TEXTURE_BARRIER_FRAMEBUFFER :
                                         PIPE_TEXTURE_BARRIER_SAMPLER);
      util_draw_fullscreen_quad(cso);
   }
   if (num_samples > 1 && !use_fbfetch)
      ctx->set_min_samples(ctx, 1);

   /* Probe pixels.
    *
    * For single sample:
    *   result = 0.1 (clear) + (0.1, 0.2, 0.3, 0.4) * 2 = (0.3, 0.5, 0.7, 0.9)
    *
    * For MSAA 4x:
    *   sample0 = 0.0 (clear) + (0.1, 0.2, 0.3, 0.4) * 2 = (0.2, 0.4, 0.6, 0.8)
    *   sample1 = sample0
    *   sample2 = 0.2 (clear) + (0.1, 0.2, 0.3, 0.4) * 2 = (0.4, 0.6, 0.8, 1.0)
    *   sample3 = sample2
    *   resolved = sum(sample[0:3]) / 4 = (0.3, 0.5, 0.7, 0.9)
    */
   static const float expected[] = {0.3, 0.5, 0.7, 0.9};
   bool pass = util_probe_rect_rgba(ctx, cb, 0, 0,
                                    cb->width0, cb->height0, expected);

   /* Cleanup. */
   cso_destroy_context(cso);
   ctx->delete_vs_state(ctx, vs);
   ctx->delete_fs_state(ctx, fs);
   pipe_sampler_view_reference(&view, NULL);
   pipe_resource_reference(&cb, NULL);

   util_report_result_helper(pass, name);
}