/** * Specify the surface to cache. */ void sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, struct pipe_surface *ps) { struct pipe_context *pipe = tc->pipe; if (tc->transfer) { if (ps == tc->surface) return; if (tc->transfer_map) { pipe->transfer_unmap(pipe, tc->transfer); tc->transfer_map = NULL; } pipe->transfer_destroy(pipe, tc->transfer); tc->transfer = NULL; } tc->surface = ps; if (ps) { tc->transfer = pipe_get_transfer(pipe, ps->texture, ps->u.tex.level, ps->u.tex.first_layer, PIPE_TRANSFER_READ_WRITE | PIPE_TRANSFER_UNSYNCHRONIZED, 0, 0, ps->width, ps->height); tc->depth_stencil = util_format_is_depth_or_stencil(ps->format); } }
static Bool ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src, int src_pitch) { ScreenPtr pScreen = pPix->drawable.pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa = ms->exa; struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix); struct pipe_transfer *transfer; if (!priv || !priv->tex) return FALSE; transfer = pipe_get_transfer(exa->pipe, priv->tex, 0, 0, PIPE_TRANSFER_WRITE, x, y, w, h); if (!transfer) return FALSE; exa_debug_printf("++++++ ExaUploadToScreen(%d, %d, %d, %d, %d)\n", x, y, w, h, src_pitch); util_copy_rect(exa->pipe->transfer_map(exa->pipe, transfer), priv->tex->format, transfer->stride, 0, 0, w, h, (unsigned char*)src, src_pitch, 0, 0); exa->pipe->transfer_unmap(exa->pipe, transfer); exa->pipe->transfer_destroy(exa->pipe, transfer); return TRUE; }
void * xa_surface_map(struct xa_context *ctx, struct xa_surface *srf, unsigned int usage) { void *map; unsigned int transfer_direction = 0; struct pipe_context *pipe = ctx->pipe; if (srf->transfer) return NULL; if (usage & XA_MAP_READ) transfer_direction = PIPE_TRANSFER_READ; if (usage & XA_MAP_WRITE) transfer_direction = PIPE_TRANSFER_WRITE; if (!transfer_direction) return NULL; srf->transfer = pipe_get_transfer(pipe, srf->tex, 0, 0, transfer_direction, 0, 0, srf->tex->width0, srf->tex->height0); if (!srf->transfer) return NULL; map = pipe_transfer_map(pipe, srf->transfer); if (!map) pipe->transfer_destroy(pipe, srf->transfer); srf->mapping_pipe = pipe; return map; }
/* Upload data for a particular image. */ void st_texture_image_data(struct st_context *st, struct pipe_resource *dst, GLuint face, GLuint level, void *src, GLuint src_row_stride, GLuint src_image_stride) { struct pipe_context *pipe = st->pipe; GLuint depth = u_minify(dst->depth0, level); GLuint i; const GLubyte *srcUB = src; struct pipe_transfer *dst_transfer; DBG("%s\n", __FUNCTION__); for (i = 0; i < depth; i++) { dst_transfer = pipe_get_transfer(st->pipe, dst, face, level, i, PIPE_TRANSFER_WRITE, 0, 0, u_minify(dst->width0, level), u_minify(dst->height0, level)); st_surface_data(pipe, dst_transfer, 0, 0, /* dstx, dsty */ srcUB, src_row_stride, 0, 0, /* source x, y */ u_minify(dst->width0, level), u_minify(dst->height0, level)); /* width, height */ pipe->transfer_destroy(pipe, dst_transfer); srcUB += src_image_stride; } }
static INLINE struct pipe_resource *create_texture_1d(struct vg_context *ctx, const VGuint *color_data, const VGint color_data_len) { struct pipe_context *pipe = ctx->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_resource *tex = 0; struct pipe_resource templ; memset(&templ, 0, sizeof(templ)); templ.target = PIPE_TEXTURE_1D; templ.format = PIPE_FORMAT_B8G8R8A8_UNORM; templ.last_level = 0; templ.width0 = color_data_len; templ.height0 = 1; templ.depth0 = 1; templ.array_size = 1; templ.bind = PIPE_BIND_SAMPLER_VIEW; tex = screen->resource_create(screen, &templ); { /* upload color_data */ struct pipe_transfer *transfer = pipe_get_transfer(pipe, tex, 0, 0, PIPE_TRANSFER_READ_WRITE , 0, 0, tex->width0, tex->height0); void *map = pipe->transfer_map(pipe, transfer); memcpy(map, color_data, sizeof(VGint)*color_data_len); pipe->transfer_unmap(pipe, transfer); pipe->transfer_destroy(pipe, transfer); } return tex; }
void image_sub_data(struct vg_image *image, const void * data, VGint dataStride, VGImageFormat dataFormat, VGint x, VGint y, VGint width, VGint height) { const VGint yStep = 1; VGubyte *src = (VGubyte *)data; VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4]; VGfloat *df = (VGfloat*)temp; VGint i; struct vg_context *ctx = vg_current_context(); struct pipe_context *pipe = ctx->pipe; struct pipe_resource *texture = image_texture(image); VGint xoffset = 0, yoffset = 0; if (x < 0) { xoffset -= x; width += x; x = 0; } if (y < 0) { yoffset -= y; height += y; y = 0; } if (width <= 0 || height <= 0) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } if (x > image->width || y > image->width) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } if (x + width > image->width) { width = image->width - x; } if (y + height > image->height) { height = image->height - y; } { /* upload color_data */ struct pipe_transfer *transfer = pipe_get_transfer( pipe, texture, 0, 0, PIPE_TRANSFER_WRITE, 0, 0, texture->width0, texture->height0); src += (dataStride * yoffset); for (i = 0; i < height; i++) { _vega_unpack_float_span_rgba(ctx, width, xoffset, src, dataFormat, temp); pipe_put_tile_rgba(pipe, transfer, x+image->x, y+image->y, width, 1, df); y += yStep; src += dataStride; } pipe->transfer_destroy(pipe, transfer); } }
static cairo_status_t gallium_surface_acquire_source_image (void *abstract_surface, cairo_image_surface_t **image_out, void **image_extra) { gallium_surface_t *surface = abstract_surface; gallium_device_t *device = gallium_device (surface); cairo_format_t format; cairo_surface_t *image; cairo_status_t status; struct pipe_transfer *transfer; void *ptr; if (surface->fallback != NULL) { *image_out = (cairo_image_surface_t *) cairo_surface_reference (surface->fallback); *image_extra = NULL; return CAIRO_STATUS_SUCCESS; } if (unlikely (surface->drm.width == 0 || surface->drm.height == 0)) { image = cairo_image_surface_create (surface->drm.format, 0, 0); if (unlikely (image->status)) return image->status; *image_out = (cairo_image_surface_t *) image; *image_extra = NULL; return CAIRO_STATUS_SUCCESS; } format = _cairo_format_from_pipe_format (surface->pipe_format); if (format == CAIRO_FORMAT_INVALID) return CAIRO_INT_STATUS_UNSUPPORTED; status = cairo_device_acquire (&device->drm.base); if (unlikely (status)) return status; transfer = pipe_get_transfer (device->pipe, surface->texture, 0, 0, 0, PIPE_TRANSFER_READ, 0, 0, surface->drm.width, surface->drm.height); ptr = device->pipe->transfer_map (device->pipe, transfer); cairo_device_release (&device->drm.base); image = cairo_image_surface_create_for_data (ptr, format, surface->drm.width, surface->drm.height, surface->drm.stride); if (unlikely (image->status)) return image->status; *image_out = (cairo_image_surface_t *) image; *image_extra = transfer; return CAIRO_STATUS_SUCCESS; }
static Bool ExaPrepareAccess(PixmapPtr pPix, int index) { ScreenPtr pScreen = pPix->drawable.pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa = ms->exa; struct exa_pixmap_priv *priv; priv = exaGetPixmapDriverPrivate(pPix); if (!priv) return FALSE; if (!priv->tex) return FALSE; exa_debug_printf("ExaPrepareAccess %d\n", index); if (priv->map_count == 0) { assert(pPix->drawable.width <= priv->tex->width0); assert(pPix->drawable.height <= priv->tex->height0); priv->map_transfer = pipe_get_transfer(exa->pipe, priv->tex, 0, 0, #ifdef EXA_MIXED_PIXMAPS PIPE_TRANSFER_MAP_DIRECTLY | #endif PIPE_TRANSFER_READ_WRITE, 0, 0, pPix->drawable.width, pPix->drawable.height ); if (!priv->map_transfer) #ifdef EXA_MIXED_PIXMAPS return FALSE; #else FatalError("failed to create transfer\n"); #endif pPix->devPrivate.ptr = exa->pipe->transfer_map(exa->pipe, priv->map_transfer); pPix->devKind = priv->map_transfer->stride; } priv->map_count++; exa_debug_printf("ExaPrepareAccess %d prepared\n", index); return TRUE; }
int xa_surface_dma(struct xa_context *ctx, struct xa_surface *srf, void *data, unsigned int pitch, int to_surface, struct xa_box *boxes, unsigned int num_boxes) { struct pipe_transfer *transfer; void *map; int w, h, i; enum pipe_transfer_usage transfer_direction; struct pipe_context *pipe = ctx->pipe; transfer_direction = (to_surface ? PIPE_TRANSFER_WRITE : PIPE_TRANSFER_READ); for (i = 0; i < num_boxes; ++i, ++boxes) { w = boxes->x2 - boxes->x1; h = boxes->y2 - boxes->y1; transfer = pipe_get_transfer(pipe, srf->tex, 0, 0, transfer_direction, boxes->x1, boxes->y1, w, h); if (!transfer) return -XA_ERR_NORES; map = pipe_transfer_map(ctx->pipe, transfer); if (!map) goto out_no_map; if (to_surface) { util_copy_rect(map, srf->tex->format, transfer->stride, 0, 0, w, h, data, pitch, boxes->x1, boxes->y1); } else { util_copy_rect(data, srf->tex->format, pitch, boxes->x1, boxes->y1, w, h, map, transfer->stride, 0, 0); } pipe->transfer_unmap(pipe, transfer); pipe->transfer_destroy(pipe, transfer); if (to_surface) pipe->flush(pipe, &ctx->last_fence); } return XA_ERR_NONE; out_no_map: pipe->transfer_destroy(pipe, transfer); return -XA_ERR_NORES; }
static void crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image) { unsigned char *ptr; modesettingPtr ms = modesettingPTR(crtc->scrn); struct crtc_private *crtcp = crtc->driver_private; struct pipe_transfer *transfer; if (!crtcp->cursor_tex) { struct pipe_resource templat; struct winsys_handle whandle; memset(&templat, 0, sizeof(templat)); templat.bind |= PIPE_BIND_RENDER_TARGET; templat.bind |= PIPE_BIND_SCANOUT; templat.target = PIPE_TEXTURE_2D; templat.last_level = 0; templat.depth0 = 1; templat.array_size = 1; templat.format = PIPE_FORMAT_B8G8R8A8_UNORM; templat.width0 = 64; templat.height0 = 64; memset(&whandle, 0, sizeof(whandle)); whandle.type = DRM_API_HANDLE_TYPE_KMS; crtcp->cursor_tex = ms->screen->resource_create(ms->screen, &templat); ms->screen->resource_get_handle(ms->screen, crtcp->cursor_tex, &whandle); crtcp->cursor_handle = whandle.handle; } transfer = pipe_get_transfer(ms->ctx, crtcp->cursor_tex, 0, 0, PIPE_TRANSFER_WRITE, 0, 0, 64, 64); ptr = ms->ctx->transfer_map(ms->ctx, transfer); util_copy_rect(ptr, crtcp->cursor_tex->format, transfer->stride, 0, 0, 64, 64, (void*)image, 64 * 4, 0, 0); ms->ctx->transfer_unmap(ms->ctx, transfer); ms->ctx->transfer_destroy(ms->ctx, transfer); if (crtc->cursor_shown) drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, crtcp->cursor_handle, 64, 64); }
void debug_dump_surface_bmp(struct pipe_context *pipe, const char *filename, struct pipe_surface *surface) { struct pipe_transfer *transfer; struct pipe_resource *texture = surface->texture; transfer = pipe_get_transfer(pipe, texture, surface->u.tex.level, surface->u.tex.first_layer, PIPE_TRANSFER_READ, 0, 0, surface->width, surface->height); debug_dump_transfer_bmp(pipe, filename, transfer); pipe->transfer_destroy(pipe, transfer); }
/** * Create a texture which represents a bitmap image. */ static struct pipe_resource * make_bitmap_texture(struct gl_context *ctx, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap) { struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; struct pipe_transfer *transfer; ubyte *dest; struct pipe_resource *pt; /* PBO source... */ bitmap = _mesa_map_pbo_source(ctx, unpack, bitmap); if (!bitmap) { return NULL; } /** * Create texture to hold bitmap pattern. */ pt = st_texture_create(st, st->internal_target, st->bitmap.tex_format, 0, width, height, 1, 1, PIPE_BIND_SAMPLER_VIEW); if (!pt) { _mesa_unmap_pbo_source(ctx, unpack); return NULL; } transfer = pipe_get_transfer(st->pipe, pt, 0, 0, PIPE_TRANSFER_WRITE, 0, 0, width, height); dest = pipe_transfer_map(pipe, transfer); /* Put image into texture transfer */ memset(dest, 0xff, height * transfer->stride); unpack_bitmap(st, 0, 0, width, height, unpack, bitmap, dest, transfer->stride); _mesa_unmap_pbo_source(ctx, unpack); /* Release transfer */ pipe_transfer_unmap(pipe, transfer); pipe->transfer_destroy(pipe, transfer); return pt; }
static void accum_load(struct st_context *st, GLfloat value, GLint xpos, GLint ypos, GLint width, GLint height, struct st_renderbuffer *acc_strb, struct st_renderbuffer *color_strb) { struct pipe_context *pipe = st->pipe; struct pipe_transfer *color_trans; size_t stride = acc_strb->stride; GLubyte *data = acc_strb->data; GLfloat *buf; if (ST_DEBUG & DEBUG_FALLBACK) debug_printf("%s: fallback processing\n", __FUNCTION__); color_trans = pipe_get_transfer(st->pipe, color_strb->texture, 0, 0, 0, PIPE_TRANSFER_READ, xpos, ypos, width, height); buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); pipe_get_tile_rgba(pipe, color_trans, 0, 0, width, height, buf); switch (acc_strb->format) { case PIPE_FORMAT_R16G16B16A16_SNORM: { const GLfloat *color = buf; int i, j; for (i = 0; i < height; i++) { GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8); for (j = 0; j < width * 4; j++) { float val = *color++ * value; *acc++ = FLOAT_TO_SHORT(val); } } } break; default: _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()"); } free(buf); pipe->transfer_destroy(pipe, color_trans); }
static int pipe_map(struct gralloc_drm_drv_t *drv, struct gralloc_drm_bo_t *bo, int x, int y, int w, int h, int enable_write, void **addr) { struct pipe_manager *pm = (struct pipe_manager *) drv; struct pipe_buffer *buf = (struct pipe_buffer *) bo; int err = 0; pthread_mutex_lock(&pm->mutex); /* need a context to get transfer */ if (!pm->context) { pm->context = pm->screen->context_create(pm->screen, NULL); if (!pm->context) { LOGE("failed to create pipe context"); err = -ENOMEM; } } if (!err) { enum pipe_transfer_usage usage; usage = PIPE_TRANSFER_READ; if (enable_write) usage |= PIPE_TRANSFER_WRITE; assert(!buf->transfer); /* * ignore x, y, w and h so that returned addr points at the * start of the buffer */ buf->transfer = pipe_get_transfer(pm->context, buf->resource, 0, 0, usage, 0, 0, buf->resource->width0, buf->resource->height0); if (buf->transfer) *addr = pipe_transfer_map(pm->context, buf->transfer); else err = -ENOMEM; } pthread_mutex_unlock(&pm->mutex); return err; }
GalliumSurface::Transfer::Transfer (pipe_context *context, pipe_resource *texture) { resource = NULL; pipe = context; transfer = pipe_get_transfer (pipe, texture, 0, 0, 0, PIPE_TRANSFER_READ_WRITE, 0, 0, texture->width0, texture->height0); pipe_resource_reference (&resource, texture); }
/** * Map a texture image and return the address for a particular 2D face/slice/ * layer. The stImage indicates the cube face and mipmap level. The slice * of the 3D texture is passed in 'zoffset'. * \param usage one of the PIPE_TRANSFER_x values * \param x, y, w, h the region of interest of the 2D image. * \return address of mapping or NULL if any error */ GLubyte * st_texture_image_map(struct st_context *st, struct st_texture_image *stImage, GLuint zoffset, enum pipe_transfer_usage usage, GLuint x, GLuint y, GLuint w, GLuint h) { struct pipe_context *pipe = st->pipe; struct pipe_resource *pt = stImage->pt; DBG("%s \n", __FUNCTION__); stImage->transfer = pipe_get_transfer(st->pipe, pt, stImage->face, stImage->level, zoffset, usage, x, y, w, h); if (stImage->transfer) return pipe_transfer_map(pipe, stImage->transfer); else return NULL; }
static boolean wsw_dt_get_stride(struct wrapper_sw_displaytarget *wdt, unsigned *stride) { struct pipe_context *pipe = wdt->winsys->pipe; struct pipe_resource *tex = wdt->tex; struct pipe_transfer *tr; tr = pipe_get_transfer(pipe, tex, 0, 0, 0, PIPE_TRANSFER_READ_WRITE, 0, 0, wdt->width, wdt->height); if (!tr) return FALSE; *stride = tr->stride; wdt->stride = tr->stride; pipe->transfer_destroy(pipe, tr); return TRUE; }
/** * Create gallium pipe_transfer object for the bitmap cache. */ static void create_cache_trans(struct st_context *st) { struct pipe_context *pipe = st->pipe; struct bitmap_cache *cache = st->bitmap.cache; if (cache->trans) return; /* Map the texture transfer. * Subsequent glBitmap calls will write into the texture image. */ cache->trans = pipe_get_transfer(st->pipe, cache->texture, 0, 0, PIPE_TRANSFER_WRITE, 0, 0, BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT); cache->buffer = pipe_transfer_map(pipe, cache->trans); /* init image to all 0xff */ memset(cache->buffer, 0xff, cache->trans->stride * BITMAP_CACHE_HEIGHT); }
static void * wsw_dt_map(struct sw_winsys *ws, struct sw_displaytarget *dt, unsigned flags) { struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt); struct pipe_context *pipe = wdt->winsys->pipe; struct pipe_resource *tex = wdt->tex; struct pipe_transfer *tr; void *ptr; if (!wdt->map_count) { assert(!wdt->transfer); tr = pipe_get_transfer(pipe, tex, 0, 0, 0, PIPE_TRANSFER_READ_WRITE, 0, 0, wdt->width, wdt->height); if (!tr) return NULL; ptr = pipe->transfer_map(pipe, tr); if (!ptr) goto err; wdt->transfer = tr; wdt->ptr = ptr; /* XXX Handle this case */ assert(tr->stride == wdt->stride); } wdt->map_count++; return wdt->ptr; err: pipe->transfer_destroy(pipe, tr); return NULL; }
/* FIXME: dump resources, not surfaces... */ void debug_dump_surface(struct pipe_context *pipe, const char *prefix, struct pipe_surface *surface) { struct pipe_resource *texture; struct pipe_transfer *transfer; void *data; if (!surface) return; /* XXX: this doesn't necessarily work, as the driver may be using * temporary storage for the surface which hasn't been propagated * back into the texture. Need to nail down the semantics of views * and transfers a bit better before we can say if extra work needs * to be done here: */ texture = surface->texture; transfer = pipe_get_transfer(pipe, texture, surface->u.tex.level, surface->u.tex.first_layer, PIPE_TRANSFER_READ, 0, 0, surface->width, surface->height); data = pipe->transfer_map(pipe, transfer); if(!data) goto error; debug_dump_image(prefix, texture->format, util_format_get_blocksize(texture->format), util_format_get_nblocksx(texture->format, surface->width), util_format_get_nblocksy(texture->format, surface->height), transfer->stride, data); pipe->transfer_unmap(pipe, transfer); error: pipe->transfer_destroy(pipe, transfer); }
static cairo_surface_t * gallium_surface_map_to_image (gallium_surface_t *surface) { gallium_device_t *device = gallium_device (surface); cairo_status_t status; void *ptr = NULL; status = cairo_device_acquire (&device->drm.base); if (unlikely (status)) return _cairo_surface_create_in_error (status); surface->map_transfer = pipe_get_transfer (device->pipe, surface->texture, 0, 0, 0, PIPE_TRANSFER_MAP_DIRECTLY | PIPE_TRANSFER_READ_WRITE, 0, 0, surface->drm.width, surface->drm.height); if (likely (surface->map_transfer != NULL)) ptr = device->pipe->transfer_map (device->pipe, surface->map_transfer); cairo_device_release (&device->drm.base); if (unlikely (ptr == NULL)) { if (surface->map_transfer != NULL) { device->pipe->transfer_destroy (device->pipe, surface->map_transfer); surface->map_transfer = NULL; } return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); } return cairo_image_surface_create_for_data (ptr, surface->drm.format, surface->drm.width, surface->drm.height, surface->map_transfer->stride); }
/** * Fallback for pipe->clear_render_target() function. * XXX this looks too hackish to be really useful. * cpp > 4 looks like a gross hack at best... * Plus can't use these transfer fallbacks when clearing * multisampled surfaces for instance. */ void util_clear_render_target(struct pipe_context *pipe, struct pipe_surface *dst, const union pipe_color_union *color, unsigned dstx, unsigned dsty, unsigned width, unsigned height) { struct pipe_transfer *dst_trans; void *dst_map; union util_color uc; assert(dst->texture); if (!dst->texture) return; /* XXX: should handle multiple layers */ dst_trans = pipe_get_transfer(pipe, dst->texture, dst->u.tex.level, dst->u.tex.first_layer, PIPE_TRANSFER_WRITE, dstx, dsty, width, height); dst_map = pipe->transfer_map(pipe, dst_trans); assert(dst_map); if (dst_map) { assert(dst_trans->stride > 0); util_pack_color(color->f, dst->texture->format, &uc); util_fill_rect(dst_map, dst->texture->format, dst_trans->stride, 0, 0, width, height, &uc); } pipe->transfer_unmap(pipe, dst_trans); pipe->transfer_destroy(pipe, dst_trans); }
/** * Specify the surface to cache. */ void sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, struct pipe_surface *ps) { struct pipe_context *pipe = tc->pipe; if (tc->transfer) { if (ps == tc->surface) return; if (tc->transfer_map) { pipe->transfer_unmap(pipe, tc->transfer); tc->transfer_map = NULL; } pipe->transfer_destroy(pipe, tc->transfer); tc->transfer = NULL; } tc->surface = ps; if (ps) { tc->transfer = pipe_get_transfer(pipe, ps->texture, ps->face, ps->level, ps->zslice, PIPE_TRANSFER_READ_WRITE | PIPE_TRANSFER_UNSYNCHRONIZED, 0, 0, ps->width, ps->height); tc->depth_stencil = (ps->format == PIPE_FORMAT_Z24_UNORM_S8_USCALED || ps->format == PIPE_FORMAT_Z24X8_UNORM || ps->format == PIPE_FORMAT_S8_USCALED_Z24_UNORM || ps->format == PIPE_FORMAT_X8Z24_UNORM || ps->format == PIPE_FORMAT_Z16_UNORM || ps->format == PIPE_FORMAT_Z32_UNORM || ps->format == PIPE_FORMAT_S8_USCALED); } }
void image_get_sub_data(struct vg_image * image, void * data, VGint dataStride, VGImageFormat dataFormat, VGint sx, VGint sy, VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); struct pipe_context *pipe = ctx->pipe; VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4]; VGfloat *df = (VGfloat*)temp; VGint y = 0, yStep = 1; VGint i; VGubyte *dst = (VGubyte *)data; { struct pipe_transfer *transfer = pipe_get_transfer(pipe, image->sampler_view->texture, 0, 0, PIPE_TRANSFER_READ, 0, 0, image->x + image->width, image->y + image->height); /* Do a row at a time to flip image data vertically */ for (i = 0; i < height; i++) { #if 0 debug_printf("%d-%d == %d\n", sy, height, y); #endif pipe_get_tile_rgba(pipe, transfer, sx+image->x, y, width, 1, df); y += yStep; _vega_pack_rgba_span_float(ctx, width, temp, dataFormat, dst); dst += dataStride; } pipe->transfer_destroy(pipe, transfer); } }
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); }
PUBLIC void XMesaBindTexImage(Display *dpy, XMesaBuffer drawable, int buffer, const int *attrib_list) { struct st_context_iface *st = stapi->get_current(stapi); struct st_framebuffer_iface* stfbi = drawable->stfb; struct pipe_resource *res; int x, y, w, h; enum st_attachment_type st_attachment = xmesa_attachment_type(buffer); x = 0; y = 0; w = drawable->width; h = drawable->height; /* We need to validate our attachments before using them, * in case the texture doesn't exist yet. */ xmesa_st_framebuffer_validate_textures(stfbi, w, h, 1 << st_attachment); res = xmesa_get_attachment(stfbi, st_attachment); if (res) { struct pipe_context* pipe = xmesa_get_context(stfbi); enum pipe_format internal_format = res->format; struct pipe_transfer *tex_xfer; char *map; int line, ximage_stride; XImage *img; internal_format = choose_pixel_format(drawable->xm_visual); tex_xfer = pipe_get_transfer(pipe, res, 0, 0, /* level, layer */ PIPE_TRANSFER_WRITE, x, y, w, h); if (!tex_xfer) return; /* Grab the XImage that we want to turn into a texture. */ img = XGetImage(dpy, drawable->ws.drawable, x, y, w, h, AllPlanes, ZPixmap); if (!img) { pipe_transfer_destroy(pipe, tex_xfer); return; } map = pipe_transfer_map(pipe, tex_xfer); if (!map) { pipe_transfer_destroy(pipe, tex_xfer); return; } /* The pipe transfer has a pitch rounded up to the nearest 64 pixels. We assume 32 bit pixels. */ ximage_stride = w * 4; for (line = 0; line < h; line++) memcpy(&map[line * tex_xfer->stride], &img->data[line * ximage_stride], ximage_stride); pipe_transfer_unmap(pipe, tex_xfer); pipe_transfer_destroy(pipe, tex_xfer); st->teximage(st, ST_TEXTURE_2D, 0, /* level */ internal_format, res, FALSE /* no mipmap */); } }
/** * Called via ctx->Driver.MapRenderbuffer. */ static void st_MapRenderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint x, GLuint y, GLuint w, GLuint h, GLbitfield mode, GLubyte **mapOut, GLint *rowStrideOut) { struct st_context *st = st_context(ctx); struct st_renderbuffer *strb = st_renderbuffer(rb); struct pipe_context *pipe = st->pipe; const GLboolean invert = rb->Name == 0; unsigned usage; GLuint y2; if (strb->software) { /* software-allocated renderbuffer (probably an accum buffer) */ if (strb->data) { GLint bpp = _mesa_get_format_bytes(strb->Base.Format); GLint stride = _mesa_format_row_stride(strb->Base.Format, strb->Base.Width); *mapOut = (GLubyte *) strb->data + y * stride + x * bpp; *rowStrideOut = stride; } else { *mapOut = NULL; *rowStrideOut = 0; } return; } usage = 0x0; if (mode & GL_MAP_READ_BIT) usage |= PIPE_TRANSFER_READ; if (mode & GL_MAP_WRITE_BIT) usage |= PIPE_TRANSFER_WRITE; if (mode & GL_MAP_INVALIDATE_RANGE_BIT) usage |= PIPE_TRANSFER_DISCARD_RANGE; /* Note: y=0=bottom of buffer while y2=0=top of buffer. * 'invert' will be true for window-system buffers and false for * user-allocated renderbuffers and textures. */ if (invert) y2 = strb->Base.Height - y - h; else y2 = y; strb->transfer = pipe_get_transfer(pipe, strb->texture, strb->rtt_level, strb->rtt_face + strb->rtt_slice, usage, x, y2, w, h); if (strb->transfer) { GLubyte *map = pipe_transfer_map(pipe, strb->transfer); if (invert) { *rowStrideOut = -strb->transfer->stride; map += (h - 1) * strb->transfer->stride; } else { *rowStrideOut = strb->transfer->stride; } *mapOut = map; } else { *mapOut = NULL; *rowStrideOut = 0; } }
/** * Similar to sp_get_cached_tile() but for textures. * Tiles are read-only and indexed with more params. */ const struct softpipe_tex_cached_tile * sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc, union tex_tile_address addr ) { struct softpipe_tex_cached_tile *tile; tile = tc->entries + tex_cache_pos( addr ); if (addr.value != tile->addr.value) { /* cache miss. Most misses are because we've invaldiated the * texture cache previously -- most commonly on binding a new * texture. Currently we effectively flush the cache on texture * bind. */ #if 0 _debug_printf("miss at %u: x=%d y=%d z=%d face=%d level=%d\n" " tile %u: x=%d y=%d z=%d face=%d level=%d\n", pos, x/TILE_SIZE, y/TILE_SIZE, z, face, level, pos, tile->addr.bits.x, tile->addr.bits.y, tile->z, tile->face, tile->level); #endif /* check if we need to get a new transfer */ if (!tc->tex_trans || tc->tex_face != addr.bits.face || tc->tex_level != addr.bits.level || tc->tex_z != addr.bits.z) { /* get new transfer (view into texture) */ if (tc->tex_trans) { if (tc->tex_trans_map) { tc->pipe->transfer_unmap(tc->pipe, tc->tex_trans); tc->tex_trans_map = NULL; } tc->pipe->transfer_destroy(tc->pipe, tc->tex_trans); tc->tex_trans = NULL; } tc->tex_trans = pipe_get_transfer(tc->pipe, tc->texture, addr.bits.level, addr.bits.face + addr.bits.z, PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED, 0, 0, u_minify(tc->texture->width0, addr.bits.level), u_minify(tc->texture->height0, addr.bits.level)); tc->tex_trans_map = tc->pipe->transfer_map(tc->pipe, tc->tex_trans); tc->tex_face = addr.bits.face; tc->tex_level = addr.bits.level; tc->tex_z = addr.bits.z; } /* get tile from the transfer (view into texture) */ pipe_get_tile_swizzle(tc->pipe, tc->tex_trans, addr.bits.x * TILE_SIZE, addr.bits.y * TILE_SIZE, TILE_SIZE, TILE_SIZE, tc->swizzle_r, tc->swizzle_g, tc->swizzle_b, tc->swizzle_a, tc->format, (float *) tile->data.color); tile->addr = addr; } tc->last_tile = tile; return tile; }
/** * Do a CopyTexSubImage operation using a read transfer from the source, * a write transfer to the destination and get_tile()/put_tile() to access * the pixels/texels. * * Note: srcY=0=TOP of renderbuffer */ static void fallback_copy_texsubimage(struct gl_context *ctx, struct st_renderbuffer *strb, struct st_texture_image *stImage, GLenum baseFormat, GLint destX, GLint destY, GLint destZ, GLint srcX, GLint srcY, GLsizei width, GLsizei height) { struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; struct pipe_transfer *src_trans; GLvoid *texDest; enum pipe_transfer_usage transfer_usage; if (ST_DEBUG & DEBUG_FALLBACK) debug_printf("%s: fallback processing\n", __FUNCTION__); if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { srcY = strb->Base.Height - srcY - height; } src_trans = pipe_get_transfer(pipe, strb->texture, strb->rtt_level, strb->rtt_face + strb->rtt_slice, PIPE_TRANSFER_READ, srcX, srcY, width, height); if ((baseFormat == GL_DEPTH_COMPONENT || baseFormat == GL_DEPTH_STENCIL) && util_format_is_depth_and_stencil(stImage->pt->format)) transfer_usage = PIPE_TRANSFER_READ_WRITE; else transfer_usage = PIPE_TRANSFER_WRITE; /* XXX this used to ignore destZ param */ texDest = st_texture_image_map(st, stImage, destZ, transfer_usage, destX, destY, width, height); if (baseFormat == GL_DEPTH_COMPONENT || baseFormat == GL_DEPTH_STENCIL) { const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F); GLint row, yStep; uint *data; /* determine bottom-to-top vs. top-to-bottom order for src buffer */ if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { srcY = height - 1; yStep = -1; } else { srcY = 0; yStep = 1; } data = (uint *) malloc(width * sizeof(uint)); if (data) { /* To avoid a large temp memory allocation, do copy row by row */ for (row = 0; row < height; row++, srcY += yStep) { pipe_get_tile_z(pipe, src_trans, 0, srcY, width, 1, data); if (scaleOrBias) { _mesa_scale_and_bias_depth_uint(ctx, width, data); } pipe_put_tile_z(pipe, stImage->transfer, 0, row, width, 1, data); } } else { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage()"); } free(data); } else { /* RGBA format */ GLfloat *tempSrc = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); if (tempSrc && texDest) { const GLint dims = 2; const GLint dstRowStride = stImage->transfer->stride; struct gl_texture_image *texImage = &stImage->base; struct gl_pixelstore_attrib unpack = ctx->DefaultPacking; if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { unpack.Invert = GL_TRUE; } /* get float/RGBA image from framebuffer */ /* XXX this usually involves a lot of int/float conversion. * try to avoid that someday. */ pipe_get_tile_rgba_format(pipe, src_trans, 0, 0, width, height, util_format_linear(strb->texture->format), tempSrc); /* Store into texture memory. * Note that this does some special things such as pixel transfer * ops and format conversion. In particular, if the dest tex format * is actually RGBA but the user created the texture as GL_RGB we * need to fill-in/override the alpha channel with 1.0. */ _mesa_texstore(ctx, dims, texImage->_BaseFormat, texImage->TexFormat, dstRowStride, (GLubyte **) &texDest, width, height, 1, GL_RGBA, GL_FLOAT, tempSrc, /* src */ &unpack); } else { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); } if (tempSrc) free(tempSrc); } st_texture_image_unmap(st, stImage); pipe->transfer_destroy(pipe, src_trans); }
/** * glGetTexImage() helper: decompress a compressed texture by rendering * a textured quad. Store the results in the user's buffer. */ static void decompress_with_blit(struct gl_context * ctx, GLenum format, GLenum type, GLvoid *pixels, struct gl_texture_image *texImage) { struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; struct st_texture_image *stImage = st_texture_image(texImage); struct st_texture_object *stObj = st_texture_object(texImage->TexObject); struct pipe_sampler_view *src_view; const GLuint width = texImage->Width; const GLuint height = texImage->Height; struct pipe_surface *dst_surface; struct pipe_resource *dst_texture; struct pipe_transfer *tex_xfer; unsigned bind = (PIPE_BIND_RENDER_TARGET | /* util_blit may choose to render */ PIPE_BIND_TRANSFER_READ); /* create temp / dest surface */ if (!util_create_rgba_surface(pipe, width, height, bind, &dst_texture, &dst_surface)) { _mesa_problem(ctx, "util_create_rgba_surface() failed " "in decompress_with_blit()"); return; } /* Disable conditional rendering. */ if (st->render_condition) { pipe->render_condition(pipe, NULL, 0); } /* Create sampler view that limits fetches to the source mipmap level */ { struct pipe_sampler_view sv_temp; u_sampler_view_default_template(&sv_temp, stObj->pt, stObj->pt->format); sv_temp.format = util_format_linear(sv_temp.format); sv_temp.u.tex.first_level = sv_temp.u.tex.last_level = texImage->Level; src_view = pipe->create_sampler_view(pipe, stObj->pt, &sv_temp); if (!src_view) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); return; } } /* blit/render/decompress */ util_blit_pixels_tex(st->blit, src_view, /* pipe_resource (src) */ 0, 0, /* src x0, y0 */ width, height, /* src x1, y1 */ dst_surface, /* pipe_surface (dst) */ 0, 0, /* dst x0, y0 */ width, height, /* dst x1, y1 */ 0.0, /* z */ PIPE_TEX_MIPFILTER_NEAREST); /* Restore conditional rendering state. */ if (st->render_condition) { pipe->render_condition(pipe, st->render_condition, st->condition_mode); } /* map the dst_surface so we can read from it */ tex_xfer = pipe_get_transfer(pipe, dst_texture, 0, 0, PIPE_TRANSFER_READ, 0, 0, width, height); pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels); /* copy/pack data into user buffer */ if (_mesa_format_matches_format_and_type(stImage->base.TexFormat, format, type, ctx->Pack.SwapBytes)) { /* memcpy */ const uint bytesPerRow = width * util_format_get_blocksize(stImage->pt->format); ubyte *map = pipe_transfer_map(pipe, tex_xfer); GLuint row; for (row = 0; row < height; row++) { GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width, height, format, type, row, 0); memcpy(dest, map, bytesPerRow); map += tex_xfer->stride; } pipe_transfer_unmap(pipe, tex_xfer); } else { /* format translation via floats */ GLuint row; enum pipe_format pformat = util_format_linear(dst_texture->format); GLfloat *rgba; rgba = (GLfloat *) malloc(width * 4 * sizeof(GLfloat)); if (!rgba) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()"); goto end; } for (row = 0; row < height; row++) { const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */ GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width, height, format, type, row, 0); if (ST_DEBUG & DEBUG_FALLBACK) debug_printf("%s: fallback format translation\n", __FUNCTION__); /* get float[4] rgba row from surface */ pipe_get_tile_rgba_format(pipe, tex_xfer, 0, row, width, 1, pformat, rgba); _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, type, dest, &ctx->Pack, transferOps); } free(rgba); } end: _mesa_unmap_pbo_dest(ctx, &ctx->Pack); pipe->transfer_destroy(pipe, tex_xfer); /* destroy the temp / dest surface */ util_destroy_rgba_surface(dst_texture, dst_surface); pipe_sampler_view_release(pipe, &src_view); }