/* Upload data for a particular image. */ void st_texture_image_data(struct st_context *st, struct pipe_texture *dst, GLuint face, GLuint level, void *src, GLuint src_row_stride, GLuint src_image_stride) { struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; GLuint depth = dst->depth[level]; GLuint i; const GLubyte *srcUB = src; struct pipe_transfer *dst_transfer; DBG("%s\n", __FUNCTION__); for (i = 0; i < depth; i++) { dst_transfer = st_no_flush_get_tex_transfer(st, dst, face, level, i, PIPE_TRANSFER_WRITE, 0, 0, dst->width[level], dst->height[level]); st_surface_data(pipe, dst_transfer, 0, 0, /* dstx, dsty */ srcUB, src_row_stride, 0, 0, /* source x, y */ dst->width[level], dst->height[level]); /* width, height */ screen->tex_transfer_destroy(dst_transfer); srcUB += src_image_stride; } }
/** * Map a teximage in a mipmap texture. * \param row_stride returns row stride in bytes * \param image_stride returns image stride in bytes (for 3D textures). * \return address of mapping */ 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_screen *screen = pipe->screen; struct pipe_texture *pt = stImage->pt; DBG("%s \n", __FUNCTION__); stImage->transfer = st_no_flush_get_tex_transfer(st, pt, stImage->face, stImage->level, zoffset, usage, x, y, w, h); if (stImage->transfer) return screen->transfer_map(screen, stImage->transfer); else return NULL; }
/** * Make texture containing an image for glDrawPixels image. * If 'pixels' is NULL, leave the texture image data undefined. */ static struct pipe_texture * make_texture(struct st_context *st, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels) { GLcontext *ctx = st->ctx; struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; const struct gl_texture_format *mformat; struct pipe_texture *pt; enum pipe_format pipeFormat; GLuint cpp; GLenum baseFormat; baseFormat = _mesa_base_format(format); mformat = st_ChooseTextureFormat(ctx, baseFormat, format, type); assert(mformat); pipeFormat = st_mesa_format_to_pipe_format(mformat->MesaFormat); assert(pipeFormat); cpp = st_sizeof_format(pipeFormat); pixels = _mesa_map_drawpix_pbo(ctx, unpack, pixels); if (!pixels) return NULL; pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, width, height, 1, PIPE_TEXTURE_USAGE_SAMPLER); if (!pt) { _mesa_unmap_drawpix_pbo(ctx, unpack); return NULL; } { struct pipe_transfer *transfer; static const GLuint dstImageOffsets = 0; GLboolean success; GLubyte *dest; const GLbitfield imageTransferStateSave = ctx->_ImageTransferState; /* we'll do pixel transfer in a fragment shader */ ctx->_ImageTransferState = 0x0; transfer = st_no_flush_get_tex_transfer(st, pt, 0, 0, 0, PIPE_TRANSFER_WRITE, 0, 0, width, height); /* map texture transfer */ dest = screen->transfer_map(screen, transfer); /* Put image into texture transfer. * Note that the image is actually going to be upside down in * the texture. We deal with that with texcoords. */ success = mformat->StoreImage(ctx, 2, /* dims */ baseFormat, /* baseInternalFormat */ mformat, /* gl_texture_format */ dest, /* dest */ 0, 0, 0, /* dstX/Y/Zoffset */ transfer->stride, /* dstRowStride, bytes */ &dstImageOffsets, /* dstImageOffsets */ width, height, 1, /* size */ format, type, /* src format/type */ pixels, /* data source */ unpack); /* unmap */ screen->transfer_unmap(screen, transfer); screen->tex_transfer_destroy(transfer); assert(success); /* restore */ ctx->_ImageTransferState = imageTransferStateSave; } _mesa_unmap_drawpix_pbo(ctx, unpack); return pt; }