コード例 #1
0
ファイル: gs-test.c プロジェクト: DirectFB/mesa
static void init_fs_constbuf( void )
{
   struct pipe_resource templat;
   struct pipe_box box;

   templat.target = PIPE_BUFFER;
   templat.format = PIPE_FORMAT_R8_UNORM;
   templat.width0 = sizeof(constants1);
   templat.height0 = 1;
   templat.depth0 = 1;
   templat.array_size = 1;
   templat.last_level = 0;
   templat.nr_samples = 1;
   templat.bind = PIPE_BIND_CONSTANT_BUFFER;

   constbuf1 = screen->resource_create(screen, &templat);
   if (constbuf1 == NULL)
      exit(4);
   constbuf2 = screen->resource_create(screen, &templat);
   if (constbuf2 == NULL)
      exit(4);

   {
      u_box_2d(0,0,sizeof(constants1),1, &box);

      ctx->transfer_inline_write(ctx,
                                 constbuf1,
                                 0,
                                 PIPE_TRANSFER_WRITE,
                                 &box,
                                 constants1,
                                 sizeof constants1,
                                 sizeof constants1);


      pipe_set_constant_buffer(ctx,
                               PIPE_SHADER_GEOMETRY, 0,
                               constbuf1);
   }
   {
      u_box_2d(0,0,sizeof(constants2),1, &box);

      ctx->transfer_inline_write(ctx,
                                 constbuf2,
                                 0,
                                 PIPE_TRANSFER_WRITE,
                                 &box,
                                 constants2,
                                 sizeof constants2,
                                 sizeof constants2);


      pipe_set_constant_buffer(ctx,
                               PIPE_SHADER_GEOMETRY, 1,
                               constbuf2);
   }
}
コード例 #2
0
ファイル: xorg_exa.c プロジェクト: ChillyWillyGuru/RSXGL
static void
ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
	int width, int height)
{
   ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
   modesettingPtr ms = modesettingPTR(pScrn);
   struct exa_context *exa = ms->exa;
   struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap);

   exa_debug_printf("\tExaCopy(srcx=%d, srcy=%d, dstX=%d, dstY=%d, w=%d, h=%d)\n",
                srcX, srcY, dstX, dstY, width, height);

   debug_assert(priv == exa->copy.dst);
   (void) priv;

   if (exa->copy.use_surface_copy) {
      struct pipe_box src_box;
      u_box_2d(srcX, srcY, width, height, &src_box);
      exa->pipe->resource_copy_region( exa->pipe,
                                       exa->copy.dst->tex,
                                       0,
                                       dstX, dstY, 0,
                                       exa->copy.src->tex,
                                       0, &src_box);
   }
   else {
      renderer_copy_pixmap(exa->renderer, 
                           dstX, dstY,
                           srcX, srcY,
                           width, height,
                           exa->copy.src_texture->width0,
                           exa->copy.src_texture->height0);
   }
}
コード例 #3
0
ファイル: osmesa.c プロジェクト: karolherbst/mesa
/**
 * Return information about the depth buffer associated with an OSMesa context.
 * Input:  c - the OSMesa context
 * Output:  width, height - size of buffer in pixels
 *          bytesPerValue - bytes per depth value (2 or 4)
 *          buffer - pointer to depth buffer values
 * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
 */
GLAPI GLboolean GLAPIENTRY
OSMesaGetDepthBuffer(OSMesaContext c, GLint *width, GLint *height,
                     GLint *bytesPerValue, void **buffer)
{
    struct osmesa_buffer *osbuffer = c->current_buffer;
    struct pipe_context *pipe = c->stctx->pipe;
    struct pipe_resource *res = osbuffer->textures[ST_ATTACHMENT_DEPTH_STENCIL];
    struct pipe_transfer *transfer = NULL;
    struct pipe_box box;

    /*
     * Note: we can't really implement this function with gallium as
     * we did for swrast.  We can't just map the resource and leave it
     * mapped (and there's no OSMesaUnmapDepthBuffer() function) so
     * we unmap the buffer here and return a 'stale' pointer.  This should
     * actually be OK in most cases where the caller of this function
     * immediately uses the pointer.
     */

    u_box_2d(0, 0, res->width0, res->height0, &box);

    *buffer = pipe->transfer_map(pipe, res, 0, PIPE_TRANSFER_READ, &box,
                                 &transfer);
    if (!*buffer) {
        return GL_FALSE;
    }

    *width = res->width0;
    *height = res->height0;
    *bytesPerValue = util_format_get_blocksize(res->format);

    pipe->transfer_unmap(pipe, transfer);

    return GL_TRUE;
}
コード例 #4
0
ファイル: xm_st.c プロジェクト: GunioRobot/mesa-7.10.2-PS3
/**
 * Copy the contents between the attachments.
 */
static void
xmesa_st_framebuffer_copy_textures(struct st_framebuffer_iface *stfbi,
                                   enum st_attachment_type src_statt,
                                   enum st_attachment_type dst_statt,
                                   unsigned x, unsigned y,
                                   unsigned width, unsigned height)
{
   struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
   struct pipe_resource *src_ptex = xstfb->textures[src_statt];
   struct pipe_resource *dst_ptex = xstfb->textures[dst_statt];
   struct pipe_box src_box;
   struct pipe_context *pipe;

   if (!src_ptex || !dst_ptex)
      return;

   pipe = xstfb->display->pipe;
   if (!pipe) {
      pipe = xstfb->screen->context_create(xstfb->screen, NULL);
      if (!pipe)
         return;
      xstfb->display->pipe = pipe;
   }

   u_box_2d(x, y, width, height, &src_box);

   if (src_ptex && dst_ptex)
      pipe->resource_copy_region(pipe, dst_ptex, 0, x, y, 0,
                                 src_ptex, 0, &src_box);
}
コード例 #5
0
static void
fd_resource_transfer_unmap(struct pipe_context *pctx,
		struct pipe_transfer *ptrans)
{
	struct fd_context *ctx = fd_context(pctx);
	struct fd_resource *rsc = fd_resource(ptrans->resource);
	struct fd_transfer *trans = fd_transfer(ptrans);

	if (trans->staging && !(ptrans->usage & PIPE_TRANSFER_FLUSH_EXPLICIT)) {
		struct pipe_box box;
		u_box_2d(0, 0, ptrans->box.width, ptrans->box.height, &box);
		fd_resource_flush(trans, &box);
	}

	if (!(ptrans->usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
		fd_bo_cpu_fini(rsc->bo);
		if (rsc->stencil)
			fd_bo_cpu_fini(rsc->stencil->bo);
	}

	util_range_add(&rsc->valid_buffer_range,
				   ptrans->box.x,
				   ptrans->box.x + ptrans->box.width);

	pipe_resource_reference(&ptrans->resource, NULL);
	util_slab_free(&ctx->transfer_pool, ptrans);

	free(trans->staging);
}
コード例 #6
0
ファイル: r600_blit.c プロジェクト: josephharding/gluttest
static void r600_color_resolve(struct pipe_context *ctx,
			       const struct pipe_resolve_info *info)
{
	struct r600_context *rctx = (struct r600_context *)ctx;
	struct pipe_screen *screen = ctx->screen;
	struct pipe_resource *tmp, templ;
	struct pipe_box box;
	unsigned sample_mask =
		rctx->chip_class == CAYMAN ? ~0 : ((1ull << MAX2(1, info->src.res->nr_samples)) - 1);

	assert((info->mask & PIPE_MASK_RGBA) == PIPE_MASK_RGBA);

	if (is_simple_resolve(info)) {
		r600_blitter_begin(ctx, R600_COLOR_RESOLVE);
		util_blitter_custom_resolve_color(rctx->blitter,
						  info->dst.res, info->dst.level, info->dst.layer,
						  info->src.res, info->src.layer,
						  sample_mask, rctx->custom_blend_resolve);
		r600_blitter_end(ctx);
		return;
	}

	/* resolve into a temporary texture, then blit */
	templ.target = PIPE_TEXTURE_2D;
	templ.format = info->src.res->format;
	templ.width0 = info->src.res->width0;
	templ.height0 = info->src.res->height0;
	templ.depth0 = 1;
	templ.array_size = 1;
	templ.last_level = 0;
	templ.nr_samples = 0;
	templ.usage = PIPE_USAGE_STATIC;
	templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
	templ.flags = 0;

	tmp = screen->resource_create(screen, &templ);

	/* XXX use scissor, so that only the needed part of the resource is resolved */
	r600_blitter_begin(ctx, R600_COLOR_RESOLVE);
	util_blitter_custom_resolve_color(rctx->blitter,
					  tmp, 0, 0,
					  info->src.res, info->src.layer,
					  sample_mask, rctx->custom_blend_resolve);
	r600_blitter_end(ctx);

	/* this is correct for upside-down blits too */
	u_box_2d(info->src.x0,
		 info->src.y0,
		 info->src.x1 - info->src.x0,
		 info->src.y1 - info->src.y0, &box);

	r600_blitter_begin(ctx, R600_COPY_TEXTURE);
	util_blitter_copy_texture(rctx->blitter, info->dst.res, info->dst.level,
				  ~0, info->dst.x0, info->dst.y0, info->dst.layer,
				  tmp, 0, 0, &box);
	r600_blitter_end(ctx);

	pipe_resource_reference(&tmp, NULL);
}
コード例 #7
0
/** Upload the constants. */
static void
up_consts(struct pipe_context *pipe)
{
    struct pipe_box box;

    u_box_2d(0, 0, sizeof(constants), 1, &box);
    pipe->transfer_inline_write(pipe, constbuf, 0, PIPE_TRANSFER_WRITE,
                                &box, constants, sizeof(constants),
                                sizeof(constants));
}
コード例 #8
0
ファイル: xorg_exa.c プロジェクト: anupamkaul/mesa
static void
ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
	int width, int height)
{
   ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen);
   modesettingPtr ms = modesettingPTR(pScrn);
   struct exa_context *exa = ms->exa;
   struct pipe_box src_box;

   exa_debug_printf("\tExaCopy(srcx=%d, srcy=%d, dstX=%d, dstY=%d, w=%d, h=%d)\n",
                srcX, srcY, dstX, dstY, width, height);

   debug_assert(exaGetPixmapDriverPrivate(pDstPixmap) == exa->copy.dst);

   u_box_2d(srcX, srcY, width, height, &src_box);

   /* If source and destination overlap, we have to copy to/from a scratch
    * pixmap.
    */
   if (exa->copy.dst == exa->copy.src &&
       !((dstX + width) < srcX || dstX > (srcX + width) ||
	 (dstY + height) < srcY || dstY > (srcY + height))) {
      struct exa_pixmap_priv *tmp_priv;

      if (!exa->copy.tmp_pix) {
         exa->copy.tmp_pix = pScrn->pScreen->CreatePixmap(pScrn->pScreen,
                                                         pDstPixmap->drawable.width,
                                                         pDstPixmap->drawable.height,
                                                         pDstPixmap->drawable.depth,
                                                         pDstPixmap->drawable.width);
         exaMoveInPixmap(exa->copy.tmp_pix);
      }

      tmp_priv = exaGetPixmapDriverPrivate(exa->copy.tmp_pix);

      exa->pipe->resource_copy_region( exa->pipe,
                                       tmp_priv->tex,
                                       0,
                                       srcX, srcY, 0,
                                       exa->copy.src->tex,
                                       0, &src_box);
      exa->pipe->resource_copy_region( exa->pipe,
                                       exa->copy.dst->tex,
                                       0,
                                       dstX, dstY, 0,
                                       tmp_priv->tex,
                                       0, &src_box);
   } else
      exa->pipe->resource_copy_region( exa->pipe,
                                       exa->copy.dst->tex,
                                       0,
                                       dstX, dstY, 0,
                                       exa->copy.src->tex,
                                       0, &src_box);
}
コード例 #9
0
static void pipe_copy(struct gralloc_drm_drv_t *drv,
		struct gralloc_drm_bo_t *dst_bo,
		struct gralloc_drm_bo_t *src_bo,
		short x1, short y1, short x2, short y2)
{
	struct pipe_manager *pm = (struct pipe_manager *) drv;
	struct pipe_buffer *dst = (struct pipe_buffer *) dst_bo;
	struct pipe_buffer *src = (struct pipe_buffer *) src_bo;
	struct pipe_box src_box;

	if (dst_bo->handle->width != src_bo->handle->width ||
	    dst_bo->handle->height != src_bo->handle->height ||
	    dst_bo->handle->stride != src_bo->handle->stride ||
	    dst_bo->handle->format != src_bo->handle->format) {
		LOGE("copy between incompatible buffers");
		return;
	}

	if (x1 < 0)
		x1 = 0;
	if (y1 < 0)
		y1 = 0;
	if (x2 > dst_bo->handle->width)
		x2 = dst_bo->handle->width;
	if (y2 > dst_bo->handle->height)
		y2 = dst_bo->handle->height;

	if (x2 <= x1 || y2 <= y1)
		return;

	u_box_2d(x1, y1, x2 - x1, y2 - y1, &src_box);

	pthread_mutex_lock(&pm->mutex);

	/* need a context for copying */
	if (!pm->context) {
		pm->context = pm->screen->context_create(pm->screen, NULL);
		if (!pm->context) {
			LOGE("failed to create pipe context");
			pthread_mutex_unlock(&pm->mutex);
			return;
		}
	}

	pm->context->resource_copy_region(pm->context,
			dst->resource, 0, x1, y1, 0,
			src->resource, 0, &src_box);
	pm->context->flush(pm->context, NULL);

	pthread_mutex_unlock(&pm->mutex);
}
コード例 #10
0
ファイル: r600_blit.c プロジェクト: josephharding/gluttest
static void r600_copy_first_sample(struct pipe_context *ctx,
				   const struct pipe_resolve_info *info)
{
	struct r600_context *rctx = (struct r600_context *)ctx;
	struct r600_texture *rsrc = (struct r600_texture*)info->src.res;
	struct pipe_surface *dst_view, dst_templ;
	struct pipe_sampler_view src_templ, *src_view;
	struct pipe_box box;

	if (rsrc->is_depth && !rsrc->is_flushing_texture) {
		if (!r600_init_flushed_depth_texture(ctx, info->src.res, NULL))
			return; /* error */

		/* Decompress the first sample only. */
		r600_blit_decompress_depth(ctx,	rsrc, NULL,
					   0, 0,
					   info->src.layer, info->src.layer,
					   0, 0);
	}
	if (rctx->chip_class != CAYMAN && rsrc->fmask_size && rsrc->cmask_size) {
		r600_blit_decompress_color(ctx, rsrc,
					   0, 0,
					   info->src.layer, info->src.layer);
	}

	/* this is correct for upside-down blits too */
	u_box_2d(info->src.x0,
		 info->src.y0,
		 info->src.x1 - info->src.x0,
		 info->src.y1 - info->src.y0, &box);

	/* Initialize the surface. */
	util_blitter_default_dst_texture(&dst_templ, info->dst.res,
					 info->dst.level, info->dst.layer, &box);
	dst_view = ctx->create_surface(ctx, info->dst.res, &dst_templ);

	/* Initialize the sampler view. */
	util_blitter_default_src_texture(&src_templ, info->src.res, 0);
	src_view = ctx->create_sampler_view(ctx, info->src.res, &src_templ);

	/* Copy the first sample into dst. */
	r600_blitter_begin(ctx, R600_COPY_TEXTURE);
	util_blitter_copy_texture_view(rctx->blitter, dst_view, ~0, info->dst.x0,
				       info->dst.y0, src_view, 0, &box,
				       info->src.res->width0, info->src.res->height0,
				       info->mask);
	r600_blitter_end(ctx);

	pipe_surface_reference(&dst_view, NULL);
	pipe_sampler_view_reference(&src_view, NULL);
}
コード例 #11
0
ファイル: osmesa.c プロジェクト: CSRedRat/mesa-1
/**
 * Called via glFlush/glFinish.  This is where we copy the contents
 * of the driver's color buffer into the user-specified buffer.
 */
static boolean
osmesa_st_framebuffer_flush_front(struct st_context_iface *stctx,
                                  struct st_framebuffer_iface *stfbi,
                                  enum st_attachment_type statt)
{
   OSMesaContext osmesa = OSMesaGetCurrentContext();
   struct osmesa_buffer *osbuffer = stfbi_to_osbuffer(stfbi);
   struct pipe_context *pipe = stctx->pipe;
   struct pipe_resource *res = osbuffer->textures[statt];
   struct pipe_transfer *transfer = NULL;
   struct pipe_box box;
   void *map;
   ubyte *src, *dst;
   unsigned y, bytes, bpp;
   int dst_stride;

   u_box_2d(0, 0, res->width0, res->height0, &box);

   map = pipe->transfer_map(pipe, res, 0, PIPE_TRANSFER_READ, &box,
                            &transfer);

   /*
    * Copy the color buffer from the resource to the user's buffer.
    */
   bpp = util_format_get_blocksize(osbuffer->visual.color_format);
   src = map;
   dst = osbuffer->map;
   if (osmesa->user_row_length)
      dst_stride = bpp * osmesa->user_row_length;
   else
      dst_stride = bpp * osbuffer->width;
   bytes = bpp * res->width0;

   if (osmesa->y_up) {
      /* need to flip image upside down */
      dst = dst + (res->height0 - 1) * dst_stride;
      dst_stride = -dst_stride;
   }

   for (y = 0; y < res->height0; y++) {
      memcpy(dst, src, bytes);
      dst += dst_stride;
      src += transfer->stride;
   }

   pipe->transfer_unmap(pipe, transfer);

   return TRUE;
}
コード例 #12
0
ファイル: xa_context.c プロジェクト: nikai3d/mesa
void
xa_copy(struct xa_context *ctx,
	int dx, int dy, int sx, int sy, int width, int height)
{
    struct pipe_box src_box;

    if (ctx->simple_copy) {
	u_box_2d(sx, sy, width, height, &src_box);
	ctx->pipe->resource_copy_region(ctx->pipe,
					ctx->dst->tex, 0, dx, dy, 0,
					ctx->src->tex,
					0, &src_box);
    } else
	renderer_copy(ctx, dx, dy, sx, sy, width, height,
		      (float) width, (float) height);
}
コード例 #13
0
ファイル: xa_context.c プロジェクト: MIPS/external-mesa3d
XA_EXPORT void
xa_copy(struct xa_context *ctx,
	int dx, int dy, int sx, int sy, int width, int height)
{
    struct pipe_box src_box;

    xa_scissor_update(ctx, dx, dy, dx + width, dy + height);

    if (ctx->simple_copy) {
	u_box_2d(sx, sy, width, height, &src_box);
	ctx->pipe->resource_copy_region(ctx->pipe,
					ctx->dst->tex, 0, dx, dy, 0,
					ctx->src->tex,
					0, &src_box);
    } else
	renderer_copy(ctx, dx, dy, sx, sy, width, height,
		      (float) ctx->src->tex->width0,
		      (float) ctx->src->tex->height0);
}
コード例 #14
0
static void
drisw_copy_sub_buffer(__DRIdrawable *dPriv, int x, int y,
                      int w, int h)
{
   struct dri_context *ctx = dri_get_current(dPriv->driScreenPriv);
   struct dri_drawable *drawable = dri_drawable(dPriv);
   struct pipe_resource *ptex;
   struct pipe_box box;
   if (!ctx)
      return;

   ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];

   if (ptex) {
      if (ctx->pp && drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL])
         pp_run(ctx->pp, ptex, ptex, drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL]);

      ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL);

      u_box_2d(x, dPriv->h - y - h, w, h, &box);
      drisw_present_texture(dPriv, ptex, &box);
   }
}
コード例 #15
0
ファイル: st_cb_drawpixels.c プロジェクト: iquiw/xsrc
/**
 * Try to do a glCopyPixels for simple cases with a blit by calling
 * pipe->resource_copy_region().
 *
 * We can do this when we're copying color pixels (depth/stencil
 * eventually) with no pixel zoom, no pixel transfer ops, no
 * per-fragment ops, the src/dest regions don't overlap and the
 * src/dest pixel formats are the same.
 */
static GLboolean
blit_copy_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
                 GLsizei width, GLsizei height,
                 GLint dstx, GLint dsty, GLenum type)
{
   struct st_context *st = st_context(ctx);
   struct pipe_context *pipe = st->pipe;
   struct gl_pixelstore_attrib pack, unpack;
   GLint readX, readY, readW, readH;

   if (type == GL_COLOR &&
       ctx->Pixel.ZoomX == 1.0 &&
       ctx->Pixel.ZoomY == 1.0 &&
       ctx->_ImageTransferState == 0x0 &&
       !ctx->Color.BlendEnabled &&
       !ctx->Color.AlphaEnabled &&
       !ctx->Depth.Test &&
       !ctx->Fog.Enabled &&
       !ctx->Stencil.Enabled &&
       !ctx->FragmentProgram.Enabled &&
       !ctx->VertexProgram.Enabled &&
       !ctx->Shader.CurrentFragmentProgram &&
       st_fb_orientation(ctx->ReadBuffer) == st_fb_orientation(ctx->DrawBuffer) &&
       ctx->DrawBuffer->_NumColorDrawBuffers == 1 &&
       !ctx->Query.CondRenderQuery) {
      struct st_renderbuffer *rbRead, *rbDraw;
      GLint drawX, drawY;

      /*
       * Clip the read region against the src buffer bounds.
       * We'll still allocate a temporary buffer/texture for the original
       * src region size but we'll only read the region which is on-screen.
       * This may mean that we draw garbage pixels into the dest region, but
       * that's expected.
       */
      readX = srcx;
      readY = srcy;
      readW = width;
      readH = height;
      pack = ctx->DefaultPacking;
      if (!_mesa_clip_readpixels(ctx, &readX, &readY, &readW, &readH, &pack))
         return GL_TRUE; /* all done */

      /* clip against dest buffer bounds and scissor box */
      drawX = dstx + pack.SkipPixels;
      drawY = dsty + pack.SkipRows;
      unpack = pack;
      if (!_mesa_clip_drawpixels(ctx, &drawX, &drawY, &readW, &readH, &unpack))
         return GL_TRUE; /* all done */

      readX = readX - pack.SkipPixels + unpack.SkipPixels;
      readY = readY - pack.SkipRows + unpack.SkipRows;

      rbRead = st_get_color_read_renderbuffer(ctx);
      rbDraw = st_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);

      if ((rbRead != rbDraw ||
           !regions_overlap(readX, readY, drawX, drawY, readW, readH)) &&
          rbRead->Base.Format == rbDraw->Base.Format) {
         struct pipe_box srcBox;

         /* flip src/dst position if needed */
         if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
            /* both buffers will have the same orientation */
            readY = ctx->ReadBuffer->Height - readY - readH;
            drawY = ctx->DrawBuffer->Height - drawY - readH;
         }

         u_box_2d(readX, readY, readW, readH, &srcBox);

         pipe->resource_copy_region(pipe,
                                    rbDraw->texture,
                                    rbDraw->rtt_level, drawX, drawY, 0,
                                    rbRead->texture,
                                    rbRead->rtt_level, &srcBox);
         return GL_TRUE;
      }
   }

   return GL_FALSE;
}
コード例 #16
0
ファイル: osmesa.c プロジェクト: karolherbst/mesa
/**
 * Called via glFlush/glFinish.  This is where we copy the contents
 * of the driver's color buffer into the user-specified buffer.
 */
static boolean
osmesa_st_framebuffer_flush_front(struct st_context_iface *stctx,
                                  struct st_framebuffer_iface *stfbi,
                                  enum st_attachment_type statt)
{
    OSMesaContext osmesa = OSMesaGetCurrentContext();
    struct osmesa_buffer *osbuffer = stfbi_to_osbuffer(stfbi);
    struct pipe_context *pipe = stctx->pipe;
    struct pipe_resource *res = osbuffer->textures[statt];
    struct pipe_transfer *transfer = NULL;
    struct pipe_box box;
    void *map;
    ubyte *src, *dst;
    unsigned y, bytes, bpp;
    int dst_stride;

    if (osmesa->pp) {
        struct pipe_resource *zsbuf = NULL;
        unsigned i;

        /* Find the z/stencil buffer if there is one */
        for (i = 0; i < ARRAY_SIZE(osbuffer->textures); i++) {
            struct pipe_resource *res = osbuffer->textures[i];
            if (res) {
                const struct util_format_description *desc =
                    util_format_description(res->format);

                if (util_format_has_depth(desc)) {
                    zsbuf = res;
                    break;
                }
            }
        }

        /* run the postprocess stage(s) */
        pp_run(osmesa->pp, res, res, zsbuf);
    }

    u_box_2d(0, 0, res->width0, res->height0, &box);

    map = pipe->transfer_map(pipe, res, 0, PIPE_TRANSFER_READ, &box,
                             &transfer);

    /*
     * Copy the color buffer from the resource to the user's buffer.
     */
    bpp = util_format_get_blocksize(osbuffer->visual.color_format);
    src = map;
    dst = osbuffer->map;
    if (osmesa->user_row_length)
        dst_stride = bpp * osmesa->user_row_length;
    else
        dst_stride = bpp * osbuffer->width;
    bytes = bpp * res->width0;

    if (osmesa->y_up) {
        /* need to flip image upside down */
        dst = dst + (res->height0 - 1) * dst_stride;
        dst_stride = -dst_stride;
    }

    for (y = 0; y < res->height0; y++) {
        memcpy(dst, src, bytes);
        dst += dst_stride;
        src += transfer->stride;
    }

    pipe->transfer_unmap(pipe, transfer);

    return TRUE;
}
コード例 #17
0
ファイル: pp_mlaa.c プロジェクト: DirectFB/mesa
/** The init function of the MLAA filter. */
static bool
pp_jimenezmlaa_init_run(struct pp_queue_t *ppq, unsigned int n,
                        unsigned int val, bool iscolor)
{

   struct pipe_box box;
   struct pipe_resource res;
   char *tmp_text = NULL;

   tmp_text = CALLOC(sizeof(blend2fs_1) + sizeof(blend2fs_2) +
                     IMM_SPACE, sizeof(char));

   if (tmp_text == NULL) {
      pp_debug("Failed to allocate shader space\n");
      return FALSE;
   }

   ppq->constbuf = pipe_buffer_create(ppq->p->screen,
                                      PIPE_BIND_CONSTANT_BUFFER,
                                      PIPE_USAGE_DEFAULT,
                                      sizeof(constants));
   if (ppq->constbuf == NULL) {
      pp_debug("Failed to allocate constant buffer\n");
      goto fail;
   }

   pp_debug("mlaa: using %u max search steps\n", val);

   util_sprintf(tmp_text, "%s"
                "IMM FLT32 {    %.8f,     0.0000,     0.0000,     0.0000}\n"
                "%s\n", blend2fs_1, (float) val, blend2fs_2);

   memset(&res, 0, sizeof(res));

   res.target = PIPE_TEXTURE_2D;
   res.format = PIPE_FORMAT_R8G8_UNORM;
   res.width0 = res.height0 = 165;
   res.bind = PIPE_BIND_SAMPLER_VIEW;
   res.usage = PIPE_USAGE_DEFAULT;
   res.depth0 = res.array_size = res.nr_samples = 1;

   if (!ppq->p->screen->is_format_supported(ppq->p->screen, res.format,
                                            res.target, 1, res.bind))
      pp_debug("Areamap format not supported\n");

   ppq->areamaptex = ppq->p->screen->resource_create(ppq->p->screen, &res);
   
   if (ppq->areamaptex == NULL) {
      pp_debug("Failed to allocate area map texture\n");
      goto fail;
   }
   
   u_box_2d(0, 0, 165, 165, &box);

   ppq->p->pipe->transfer_inline_write(ppq->p->pipe, ppq->areamaptex, 0,
                                       PIPE_TRANSFER_WRITE, &box,
                                       areamap, 165 * 2, sizeof(areamap));

   ppq->shaders[n][1] = pp_tgsi_to_state(ppq->p->pipe, offsetvs, true,
                                         "offsetvs");
   if (iscolor)
      ppq->shaders[n][2] = pp_tgsi_to_state(ppq->p->pipe, color1fs,
                                            false, "color1fs");
   else
      ppq->shaders[n][2] = pp_tgsi_to_state(ppq->p->pipe, depth1fs,
                                            false, "depth1fs");
   ppq->shaders[n][3] = pp_tgsi_to_state(ppq->p->pipe, tmp_text, false,
                                         "blend2fs");
   ppq->shaders[n][4] = pp_tgsi_to_state(ppq->p->pipe, neigh3fs, false,
                                         "neigh3fs");

   FREE(tmp_text);

   return TRUE;

 fail:
   
   FREE(tmp_text);

   /*
    * Call the common free function for destruction of partially initialized
    * resources.
    */
   pp_jimenezmlaa_free(ppq, n);

   return FALSE;
}
コード例 #18
0
ファイル: u_tests.c プロジェクト: ValveSoftware/steamos_mesa
static void
test_sync_file_fences(struct pipe_context *ctx)
{
   struct pipe_screen *screen = ctx->screen;
   bool pass = true;
   enum pipe_fd_type fd_type = PIPE_FD_TYPE_NATIVE_SYNC;

   if (!screen->get_param(screen, PIPE_CAP_NATIVE_FENCE_FD))
      return;

   struct cso_context *cso = cso_create_context(ctx, 0);
   struct pipe_resource *buf =
      pipe_buffer_create(screen, 0, PIPE_USAGE_DEFAULT, 1024 * 1024);
   struct pipe_resource *tex =
      util_create_texture2d(screen, 4096, 1024, PIPE_FORMAT_R8_UNORM, 0);
   struct pipe_fence_handle *buf_fence = NULL, *tex_fence = NULL;

   /* Run 2 clears, get fencess. */
   uint32_t value = 0;
   ctx->clear_buffer(ctx, buf, 0, buf->width0, &value, sizeof(value));
   ctx->flush(ctx, &buf_fence, PIPE_FLUSH_FENCE_FD);

   struct pipe_box box;
   u_box_2d(0, 0, tex->width0, tex->height0, &box);
   ctx->clear_texture(ctx, tex, 0, &box, &value);
   ctx->flush(ctx, &tex_fence, PIPE_FLUSH_FENCE_FD);
   pass = pass && buf_fence && tex_fence;

   /* Export fences. */
   int buf_fd = screen->fence_get_fd(screen, buf_fence);
   int tex_fd = screen->fence_get_fd(screen, tex_fence);
   pass = pass && buf_fd >= 0 && tex_fd >= 0;

   /* Merge fences. */
   int merged_fd = sync_merge("test", buf_fd, tex_fd);
   pass = pass && merged_fd >= 0;

   /* (Re)import all fences. */
   struct pipe_fence_handle *re_buf_fence = NULL, *re_tex_fence = NULL;
   struct pipe_fence_handle *merged_fence = NULL;
   ctx->create_fence_fd(ctx, &re_buf_fence, buf_fd, fd_type);
   ctx->create_fence_fd(ctx, &re_tex_fence, tex_fd, fd_type);
   ctx->create_fence_fd(ctx, &merged_fence, merged_fd, fd_type);
   pass = pass && re_buf_fence && re_tex_fence && merged_fence;

   /* Run another clear after waiting for everything. */
   struct pipe_fence_handle *final_fence = NULL;
   ctx->fence_server_sync(ctx, merged_fence);
   value = 0xff;
   ctx->clear_buffer(ctx, buf, 0, buf->width0, &value, sizeof(value));
   ctx->flush(ctx, &final_fence, PIPE_FLUSH_FENCE_FD);
   pass = pass && final_fence;

   /* Wait for the last fence. */
   int final_fd = screen->fence_get_fd(screen, final_fence);
   pass = pass && final_fd >= 0;
   pass = pass && sync_wait(final_fd, -1) == 0;

   /* Check that all fences are signalled. */
   pass = pass && sync_wait(buf_fd, 0) == 0;
   pass = pass && sync_wait(tex_fd, 0) == 0;
   pass = pass && sync_wait(merged_fd, 0) == 0;

   pass = pass && screen->fence_finish(screen, NULL, buf_fence, 0);
   pass = pass && screen->fence_finish(screen, NULL, tex_fence, 0);
   pass = pass && screen->fence_finish(screen, NULL, re_buf_fence, 0);
   pass = pass && screen->fence_finish(screen, NULL, re_tex_fence, 0);
   pass = pass && screen->fence_finish(screen, NULL, merged_fence, 0);
   pass = pass && screen->fence_finish(screen, NULL, final_fence, 0);

   /* Cleanup. */
#ifndef PIPE_OS_WINDOWS
   if (buf_fd >= 0)
      close(buf_fd);
   if (tex_fd >= 0)
      close(tex_fd);
   if (merged_fd >= 0)
      close(merged_fd);
   if (final_fd >= 0)
      close(final_fd);
#endif

   screen->fence_reference(screen, &buf_fence, NULL);
   screen->fence_reference(screen, &tex_fence, NULL);
   screen->fence_reference(screen, &re_buf_fence, NULL);
   screen->fence_reference(screen, &re_tex_fence, NULL);
   screen->fence_reference(screen, &merged_fence, NULL);
   screen->fence_reference(screen, &final_fence, NULL);

   cso_destroy_context(cso);
   pipe_resource_reference(&buf, NULL);
   pipe_resource_reference(&tex, NULL);

   util_report_result(pass);
}
コード例 #19
0
/* In the case of transfer_map of a multi-sample resource, call back into
 * pctx->transfer_map() to map the staging resource, to handle cases of
 * MSAA + separate_z32s8 or fake_rgtc
 */
static void *
transfer_map_msaa(struct pipe_context *pctx,
                  struct pipe_resource *prsc,
                  unsigned level, unsigned usage,
                  const struct pipe_box *box,
                  struct pipe_transfer **pptrans)
{
   struct pipe_screen *pscreen = pctx->screen;
   struct u_transfer *trans = calloc(1, sizeof(*trans));
   if (!trans)
      return NULL;
   struct pipe_transfer *ptrans = &trans->base;

   pipe_resource_reference(&ptrans->resource, prsc);
   ptrans->level = level;
   ptrans->usage = usage;
   ptrans->box = *box;

   struct pipe_resource tmpl = {
         .target = prsc->target,
         .format = prsc->format,
         .width0 = box->width,
         .height0 = box->height,
         .depth0 = 1,
         .array_size = 1,
   };
   trans->ss = pscreen->resource_create(pscreen, &tmpl);
   if (!trans->ss) {
      free(trans);
      return NULL;
   }

   if (needs_pack(usage)) {
      struct pipe_blit_info blit;
      memset(&blit, 0, sizeof(blit));

      blit.src.resource = ptrans->resource;
      blit.src.format = ptrans->resource->format;
      blit.src.level = ptrans->level;
      blit.src.box = *box;

      blit.dst.resource = trans->ss;
      blit.dst.format = trans->ss->format;
      blit.dst.box.width = box->width;
      blit.dst.box.height = box->height;
      blit.dst.box.depth = 1;

      blit.mask = util_format_get_mask(prsc->format);
      blit.filter = PIPE_TEX_FILTER_NEAREST;

      pctx->blit(pctx, &blit);
   }

   struct pipe_box map_box = *box;
   map_box.x = 0;
   map_box.y = 0;

   void *ss_map = pctx->transfer_map(pctx, trans->ss, 0, usage, &map_box,
         &trans->trans);
   if (!ss_map) {
      free(trans);
      return NULL;
   }

   ptrans->stride = trans->trans->stride;
   *pptrans = ptrans;
   return ss_map;
}

void *
u_transfer_helper_transfer_map(struct pipe_context *pctx,
                               struct pipe_resource *prsc,
                               unsigned level, unsigned usage,
                               const struct pipe_box *box,
                               struct pipe_transfer **pptrans)
{
   struct u_transfer_helper *helper = pctx->screen->transfer_helper;
   struct u_transfer *trans;
   struct pipe_transfer *ptrans;
   enum pipe_format format = prsc->format;
   unsigned width = box->width;
   unsigned height = box->height;

   if (!handle_transfer(prsc))
      return helper->vtbl->transfer_map(pctx, prsc, level, usage, box, pptrans);

   if (helper->msaa_map && (prsc->nr_samples > 1))
      return transfer_map_msaa(pctx, prsc, level, usage, box, pptrans);

   debug_assert(box->depth == 1);

   trans = calloc(1, sizeof(*trans));
   if (!trans)
      return NULL;

   ptrans = &trans->base;
   pipe_resource_reference(&ptrans->resource, prsc);
   ptrans->level = level;
   ptrans->usage = usage;
   ptrans->box   = *box;
   ptrans->stride = util_format_get_stride(format, box->width);
   ptrans->layer_stride = ptrans->stride * box->height;

   trans->staging = malloc(ptrans->layer_stride);
   if (!trans->staging)
      goto fail;

   trans->ptr = helper->vtbl->transfer_map(pctx, prsc, level, usage, box,
                                           &trans->trans);
   if (!trans->ptr)
      goto fail;

   if (prsc->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
      struct pipe_resource *stencil = helper->vtbl->get_stencil(prsc);
      trans->ptr2 = helper->vtbl->transfer_map(pctx, stencil, level,
                                               usage, box, &trans->trans2);

      if (needs_pack(usage)) {
         util_format_z32_float_s8x24_uint_pack_z_float(trans->staging,
                                                       ptrans->stride,
                                                       trans->ptr,
                                                       trans->trans->stride,
                                                       width, height);
         util_format_z32_float_s8x24_uint_pack_s_8uint(trans->staging,
                                                       ptrans->stride,
                                                       trans->ptr2,
                                                       trans->trans2->stride,
                                                       width, height);
      }
   } else if (needs_pack(usage) &&
              util_format_description(prsc->format)->layout == UTIL_FORMAT_LAYOUT_RGTC) {
      switch (prsc->format) {
      case PIPE_FORMAT_RGTC1_UNORM:
      case PIPE_FORMAT_RGTC1_SNORM:
      case PIPE_FORMAT_LATC1_UNORM:
      case PIPE_FORMAT_LATC1_SNORM:
         util_format_rgtc1_unorm_pack_rgba_8unorm(trans->staging,
                                                  ptrans->stride,
                                                  trans->ptr,
                                                  trans->trans->stride,
                                                  width, height);
         break;
      case PIPE_FORMAT_RGTC2_UNORM:
      case PIPE_FORMAT_RGTC2_SNORM:
      case PIPE_FORMAT_LATC2_UNORM:
      case PIPE_FORMAT_LATC2_SNORM:
         util_format_rgtc2_unorm_pack_rgba_8unorm(trans->staging,
                                                  ptrans->stride,
                                                  trans->ptr,
                                                  trans->trans->stride,
                                                  width, height);
         break;
      default:
         assert(!"Unexpected format");
         break;
      }
   } else {
      unreachable("bleh");
   }

   *pptrans = ptrans;
   return trans->staging;

fail:
   if (trans->trans)
      helper->vtbl->transfer_unmap(pctx, trans->trans);
   if (trans->trans2)
      helper->vtbl->transfer_unmap(pctx, trans->trans2);
   pipe_resource_reference(&ptrans->resource, NULL);
   free(trans->staging);
   free(trans);
   return NULL;
}

static void
flush_region(struct pipe_context *pctx, struct pipe_transfer *ptrans,
             const struct pipe_box *box)
{
   struct u_transfer_helper *helper = pctx->screen->transfer_helper;
   struct u_transfer *trans = u_transfer(ptrans);
   enum pipe_format iformat, format = ptrans->resource->format;
   unsigned width = box->width;
   unsigned height = box->height;
   void *src, *dst;

   if (!(ptrans->usage & PIPE_TRANSFER_WRITE))
      return;

   if (trans->ss) {
      struct pipe_blit_info blit;
      memset(&blit, 0, sizeof(blit));

      blit.src.resource = trans->ss;
      blit.src.format = trans->ss->format;
      blit.src.box = *box;

      blit.dst.resource = ptrans->resource;
      blit.dst.format = ptrans->resource->format;
      blit.dst.level = ptrans->level;

      u_box_2d(ptrans->box.x + box->x,
               ptrans->box.y + box->y,
               box->width, box->height,
               &blit.dst.box);

      blit.mask = util_format_get_mask(ptrans->resource->format);
      blit.filter = PIPE_TEX_FILTER_NEAREST;

      pctx->blit(pctx, &blit);

      return;
   }

   iformat = helper->vtbl->get_internal_format(ptrans->resource);

   src = (uint8_t *)trans->staging +
         (box->y * ptrans->stride) +
         (box->x * util_format_get_blocksize(format));
   dst = (uint8_t *)trans->ptr +
         (box->y * trans->trans->stride) +
         (box->x * util_format_get_blocksize(iformat));

   switch (format) {
   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
      util_format_z32_float_s8x24_uint_unpack_z_float(dst,
                                                      trans->trans->stride,
                                                      src,
                                                      ptrans->stride,
                                                      width, height);
      /* fallthru */
   case PIPE_FORMAT_X32_S8X24_UINT:
      dst = (uint8_t *)trans->ptr2 +
            (box->y * trans->trans2->stride) +
            (box->x * util_format_get_blocksize(PIPE_FORMAT_S8_UINT));

      util_format_z32_float_s8x24_uint_unpack_s_8uint(dst,
                                                      trans->trans2->stride,
                                                      src,
                                                      ptrans->stride,
                                                      width, height);
      break;
   case PIPE_FORMAT_RGTC1_UNORM:
   case PIPE_FORMAT_RGTC1_SNORM:
   case PIPE_FORMAT_LATC1_UNORM:
   case PIPE_FORMAT_LATC1_SNORM:
      util_format_rgtc1_unorm_unpack_rgba_8unorm(dst,
                                                 trans->trans->stride,
                                                 src,
                                                 ptrans->stride,
                                                 width, height);
      break;
   case PIPE_FORMAT_RGTC2_UNORM:
   case PIPE_FORMAT_RGTC2_SNORM:
   case PIPE_FORMAT_LATC2_UNORM:
   case PIPE_FORMAT_LATC2_SNORM:
      util_format_rgtc2_unorm_unpack_rgba_8unorm(dst,
                                                 trans->trans->stride,
                                                 src,
                                                 ptrans->stride,
                                                 width, height);
      break;
   default:
      assert(!"Unexpected staging transfer type");
      break;
   }
}

void
u_transfer_helper_transfer_flush_region(struct pipe_context *pctx,
                                        struct pipe_transfer *ptrans,
                                        const struct pipe_box *box)
{
   struct u_transfer_helper *helper = pctx->screen->transfer_helper;

   if (handle_transfer(ptrans->resource)) {
      struct u_transfer *trans = u_transfer(ptrans);

      flush_region(pctx, ptrans, box);

      /* handle MSAA case, since there could be multiple levels of
       * wrapped transfer, call pctx->transfer_flush_region()
       * instead of helper->vtbl->transfer_flush_region()
       */
      if (trans->ss) {
         pctx->transfer_flush_region(pctx, trans->trans, box);
         return;
      }

      helper->vtbl->transfer_flush_region(pctx, trans->trans, box);
      if (trans->trans2)
         helper->vtbl->transfer_flush_region(pctx, trans->trans2, box);

   } else {
      helper->vtbl->transfer_flush_region(pctx, ptrans, box);
   }
}

void
u_transfer_helper_transfer_unmap(struct pipe_context *pctx,
                                 struct pipe_transfer *ptrans)
{
   struct u_transfer_helper *helper = pctx->screen->transfer_helper;

   if (handle_transfer(ptrans->resource)) {
      struct u_transfer *trans = u_transfer(ptrans);

      if (!(ptrans->usage & PIPE_TRANSFER_FLUSH_EXPLICIT)) {
         struct pipe_box box;
         u_box_2d(0, 0, ptrans->box.width, ptrans->box.height, &box);
         flush_region(pctx, ptrans, &box);
      }

      /* in MSAA case, there could be multiple levels of wrapping
       * so don't call helper->vtbl->transfer_unmap() directly
       */
      if (trans->ss) {
         pctx->transfer_unmap(pctx, trans->trans);
         pipe_resource_reference(&trans->ss, NULL);
      } else {
         helper->vtbl->transfer_unmap(pctx, trans->trans);
         if (trans->trans2)
            helper->vtbl->transfer_unmap(pctx, trans->trans2);
      }

      free(trans);
   } else {
      helper->vtbl->transfer_unmap(pctx, ptrans);
   }
}

struct u_transfer_helper *
u_transfer_helper_create(const struct u_transfer_vtbl *vtbl,
                         bool separate_z32s8,
                         bool fake_rgtc,
                         bool msaa_map)
{
   struct u_transfer_helper *helper = calloc(1, sizeof(*helper));

   helper->vtbl = vtbl;
   helper->separate_z32s8 = separate_z32s8;
   helper->fake_rgtc = fake_rgtc;
   helper->msaa_map = msaa_map;

   return helper;
}

void
u_transfer_helper_destroy(struct u_transfer_helper *helper)
{
   free(helper);
}
コード例 #20
0
ファイル: fs-test.c プロジェクト: mlankhorst/Mesa-3D
static void init_tex( void )
{ 
   struct pipe_sampler_view sv_template;
   struct pipe_sampler_state sampler_desc;
   struct pipe_resource templat;
   struct pipe_box box;
   ubyte tex2d[SIZE][SIZE][4];
   int s, t;

#if (SIZE != 2)
   for (s = 0; s < SIZE; s++) {
      for (t = 0; t < SIZE; t++) {
         if (0) {
            int x = (s ^ t) & 1;
	    tex2d[t][s][0] = (x) ? 0 : 63;
	    tex2d[t][s][1] = (x) ? 0 : 128;
	    tex2d[t][s][2] = 0;
	    tex2d[t][s][3] = 0xff;
         }
         else {
            int x = ((s ^ t) >> 2) & 1;
	    tex2d[t][s][0] = s*255/(SIZE-1);
	    tex2d[t][s][1] = t*255/(SIZE-1);
	    tex2d[t][s][2] = (x) ? 0 : 128;
	    tex2d[t][s][3] = 0xff;
         }
      }
   }
#else
   tex2d[0][0][0] = 0;
   tex2d[0][0][1] = 255;
   tex2d[0][0][2] = 255;
   tex2d[0][0][3] = 0;

   tex2d[0][1][0] = 0;
   tex2d[0][1][1] = 0;
   tex2d[0][1][2] = 255;
   tex2d[0][1][3] = 255;

   tex2d[1][0][0] = 255;
   tex2d[1][0][1] = 255;
   tex2d[1][0][2] = 0;
   tex2d[1][0][3] = 255;

   tex2d[1][1][0] = 255;
   tex2d[1][1][1] = 0;
   tex2d[1][1][2] = 0;
   tex2d[1][1][3] = 255;
#endif

   templat.target = PIPE_TEXTURE_2D;
   templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;
   templat.width0 = SIZE;
   templat.height0 = SIZE;
   templat.depth0 = 1;
   templat.array_size = 1;
   templat.last_level = 0;
   templat.nr_samples = 1;
   templat.bind = PIPE_BIND_SAMPLER_VIEW;

   
   samptex = screen->resource_create(screen,
                                 &templat);
   if (samptex == NULL)
      exit(4);

   u_box_2d(0,0,SIZE,SIZE, &box);

   ctx->transfer_inline_write(ctx,
                              samptex,
                              0,
                              PIPE_TRANSFER_WRITE,
                              &box,
                              tex2d,
                              sizeof tex2d[0],
                              sizeof tex2d);

   /* Possibly read back & compare against original data:
    */
   if (0)
   {
      struct pipe_transfer *t;
      uint32_t *ptr;
      t = pipe_get_transfer(ctx, samptex,
                            0, 0, /* level, layer */
                            PIPE_TRANSFER_READ,
                            0, 0, SIZE, SIZE); /* x, y, width, height */

      ptr = ctx->transfer_map(ctx, t);

      if (memcmp(ptr, tex2d, sizeof tex2d) != 0) {
         assert(0);
         exit(9);
      }

      ctx->transfer_unmap(ctx, t);

      ctx->transfer_destroy(ctx, t);
   }

   memset(&sv_template, 0, sizeof sv_template);
   sv_template.format = samptex->format;
   sv_template.texture = samptex;
   sv_template.swizzle_r = 0;
   sv_template.swizzle_g = 1;
   sv_template.swizzle_b = 2;
   sv_template.swizzle_a = 3;
   sv = ctx->create_sampler_view(ctx, samptex, &sv_template);
   if (sv == NULL)
      exit(5);

   ctx->set_fragment_sampler_views(ctx, 1, &sv);
   

   memset(&sampler_desc, 0, sizeof sampler_desc);
   sampler_desc.wrap_s = PIPE_TEX_WRAP_REPEAT;
   sampler_desc.wrap_t = PIPE_TEX_WRAP_REPEAT;
   sampler_desc.wrap_r = PIPE_TEX_WRAP_REPEAT;
   sampler_desc.min_img_filter = PIPE_TEX_FILTER_NEAREST;
   sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
   sampler_desc.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
   sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE;
   sampler_desc.compare_func = 0;
   sampler_desc.normalized_coords = 1;
   sampler_desc.max_anisotropy = 0;
   
   sampler = ctx->create_sampler_state(ctx, &sampler_desc);
   if (sampler == NULL)
      exit(6);

   ctx->bind_fragment_sampler_states(ctx, 1, &sampler);
   
}
コード例 #21
0
ファイル: st_cb_drawpixels.c プロジェクト: iquiw/xsrc
static void
st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
              GLsizei width, GLsizei height,
              GLint dstx, GLint dsty, GLenum type)
{
   struct st_context *st = st_context(ctx);
   struct pipe_context *pipe = st->pipe;
   struct pipe_screen *screen = pipe->screen;
   struct st_renderbuffer *rbRead;
   void *driver_vp, *driver_fp;
   struct pipe_resource *pt;
   struct pipe_sampler_view *sv[2];
   int num_sampler_view = 1;
   GLfloat *color;
   enum pipe_format srcFormat, texFormat;
   GLboolean invertTex = GL_FALSE;
   GLint readX, readY, readW, readH;
   GLuint sample_count;
   struct gl_pixelstore_attrib pack = ctx->DefaultPacking;
   struct st_fp_variant *fpv;

   st_validate_state(st);

   if (type == GL_STENCIL) {
      /* can't use texturing to do stencil */
      copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty);
      return;
   }

   if (blit_copy_pixels(ctx, srcx, srcy, width, height, dstx, dsty, type))
      return;

   /*
    * The subsequent code implements glCopyPixels by copying the source
    * pixels into a temporary texture that's then applied to a textured quad.
    * When we draw the textured quad, all the usual per-fragment operations
    * are handled.
    */


   /*
    * Get vertex/fragment shaders
    */
   if (type == GL_COLOR) {
      rbRead = st_get_color_read_renderbuffer(ctx);
      color = NULL;

      fpv = get_color_fp_variant(st);
      driver_fp = fpv->driver_shader;

      driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);

      if (st->pixel_xfer.pixelmap_enabled) {
	  sv[1] = st->pixel_xfer.pixelmap_sampler_view;
	  num_sampler_view++;
      }
   }
   else {
      assert(type == GL_DEPTH);
      rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer);
      color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];

      fpv = get_depth_stencil_fp_variant(st, GL_TRUE, GL_FALSE);
      driver_fp = fpv->driver_shader;

      driver_vp = make_passthrough_vertex_shader(st, GL_TRUE);
   }

   /* update fragment program constants */
   st_upload_constants(st, fpv->parameters, PIPE_SHADER_FRAGMENT);


   if (rbRead->Base.Wrapped)
      rbRead = st_renderbuffer(rbRead->Base.Wrapped);

   sample_count = rbRead->texture->nr_samples;
   /* I believe this would be legal, presumably would need to do a resolve
      for color, and for depth/stencil spec says to just use one of the
      depth/stencil samples per pixel? Need some transfer clarifications. */
   assert(sample_count < 2);

   srcFormat = rbRead->texture->format;

   if (screen->is_format_supported(screen, srcFormat, st->internal_target,
                                   sample_count,
                                   PIPE_BIND_SAMPLER_VIEW)) {
      texFormat = srcFormat;
   }
   else {
      /* srcFormat can't be used as a texture format */
      if (type == GL_DEPTH) {
         texFormat = st_choose_format(screen, GL_DEPTH_COMPONENT,
                                      GL_NONE, GL_NONE, st->internal_target,
				      sample_count, PIPE_BIND_DEPTH_STENCIL);
         assert(texFormat != PIPE_FORMAT_NONE);
      }
      else {
         /* default color format */
         texFormat = st_choose_format(screen, GL_RGBA,
                                      GL_NONE, GL_NONE, st->internal_target,
                                      sample_count, PIPE_BIND_SAMPLER_VIEW);
         assert(texFormat != PIPE_FORMAT_NONE);
      }
   }

   /* Invert src region if needed */
   if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
      srcy = ctx->ReadBuffer->Height - srcy - height;
      invertTex = !invertTex;
   }

   /* Clip the read region against the src buffer bounds.
    * We'll still allocate a temporary buffer/texture for the original
    * src region size but we'll only read the region which is on-screen.
    * This may mean that we draw garbage pixels into the dest region, but
    * that's expected.
    */
   readX = srcx;
   readY = srcy;
   readW = width;
   readH = height;
   _mesa_clip_readpixels(ctx, &readX, &readY, &readW, &readH, &pack);
   readW = MAX2(0, readW);
   readH = MAX2(0, readH);

   /* alloc temporary texture */
   pt = alloc_texture(st, width, height, texFormat);
   if (!pt)
      return;

   sv[0] = st_create_texture_sampler_view(st->pipe, pt);
   if (!sv[0]) {
      pipe_resource_reference(&pt, NULL);
      return;
   }

   /* Make temporary texture which is a copy of the src region.
    */
   if (srcFormat == texFormat) {
      struct pipe_box src_box;
      u_box_2d(readX, readY, readW, readH, &src_box);
      /* copy source framebuffer surface into mipmap/texture */
      pipe->resource_copy_region(pipe,
                                 pt,                                /* dest tex */
                                 0,                                 /* dest lvl */
                                 pack.SkipPixels, pack.SkipRows, 0, /* dest pos */
                                 rbRead->texture,                   /* src tex */
                                 rbRead->rtt_level,                 /* src lvl */
                                 &src_box);

   }
   else {
      /* CPU-based fallback/conversion */
      struct pipe_transfer *ptRead =
         pipe_get_transfer(st->pipe, rbRead->texture,
                           rbRead->rtt_level,
                           rbRead->rtt_face + rbRead->rtt_slice,
                           PIPE_TRANSFER_READ,
                           readX, readY, readW, readH);
      struct pipe_transfer *ptTex;
      enum pipe_transfer_usage transfer_usage;

      if (ST_DEBUG & DEBUG_FALLBACK)
         debug_printf("%s: fallback processing\n", __FUNCTION__);

      if (type == GL_DEPTH && util_format_is_depth_and_stencil(pt->format))
         transfer_usage = PIPE_TRANSFER_READ_WRITE;
      else
         transfer_usage = PIPE_TRANSFER_WRITE;

      ptTex = pipe_get_transfer(st->pipe, pt, 0, 0, transfer_usage,
                                0, 0, width, height);

      /* copy image from ptRead surface to ptTex surface */
      if (type == GL_COLOR) {
         /* alternate path using get/put_tile() */
         GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
         enum pipe_format readFormat, drawFormat;
         readFormat = util_format_linear(rbRead->texture->format);
         drawFormat = util_format_linear(pt->format);
         pipe_get_tile_rgba_format(pipe, ptRead, 0, 0, readW, readH,
                                   readFormat, buf);
         pipe_put_tile_rgba_format(pipe, ptTex, pack.SkipPixels, pack.SkipRows,
                                   readW, readH, drawFormat, buf);
         free(buf);
      }
      else {
         /* GL_DEPTH */
         GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint));
         pipe_get_tile_z(pipe, ptRead, 0, 0, readW, readH, buf);
         pipe_put_tile_z(pipe, ptTex, pack.SkipPixels, pack.SkipRows,
                         readW, readH, buf);
         free(buf);
      }

      pipe->transfer_destroy(pipe, ptRead);
      pipe->transfer_destroy(pipe, ptTex);
   }

   /* OK, the texture 'pt' contains the src image/pixels.  Now draw a
    * textured quad with that texture.
    */
   draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
                      width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
                      sv,
                      num_sampler_view,
                      driver_vp, 
                      driver_fp,
                      color, invertTex, GL_FALSE, GL_FALSE);

   pipe_resource_reference(&pt, NULL);
   pipe_sampler_view_reference(&sv[0], NULL);
}