u_staging.c revision 41c7ff11e6aa4d82d1175446aea0984bf28e3905
1b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri#include "util/u_staging.h" 2b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri#include "pipe/p_context.h" 3b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri#include "util/u_memory.h" 4b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri#include "util/u_inlines.h" 5b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri 6b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieristatic void 7b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieriutil_staging_resource_template(struct pipe_resource *pt, unsigned width, unsigned height, unsigned depth, struct pipe_resource *template) 8b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri{ 9b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri memset(template, 0, sizeof(struct pipe_resource)); 10b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri if(pt->target != PIPE_BUFFER && depth <= 1) 11b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri template->target = PIPE_TEXTURE_2D; 12b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri else 13b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri template->target = pt->target; 14b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri template->format = pt->format; 15b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri template->width0 = width; 16b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri template->height0 = height; 17b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri template->depth0 = depth; 18b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri template->last_level = 0; 19b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri template->nr_samples = pt->nr_samples; 20b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri template->bind = 0; 21b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri template->usage = PIPE_USAGE_STAGING; 22b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri template->flags = 0; 23b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri} 24b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri 2541c7ff11e6aa4d82d1175446aea0984bf28e3905Luca Barbieristruct util_staging_transfer * 26b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieriutil_staging_transfer_new(struct pipe_context *pipe, 27b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri struct pipe_resource *pt, 28b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri struct pipe_subresource sr, 29b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri unsigned usage, 30b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri const struct pipe_box *box, 31b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri bool direct) 32b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri{ 33b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri struct pipe_screen *pscreen = pipe->screen; 34b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri struct util_staging_transfer *tx; 35b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri struct pipe_resource staging_resource_template; 36b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri 37b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri tx = CALLOC_STRUCT(util_staging_transfer); 38b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri if (!tx) 39b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri return NULL; 40b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri 41b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri pipe_resource_reference(&tx->base.resource, pt); 42b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri tx->base.sr = sr; 43b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri tx->base.usage = usage; 44b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri tx->base.box = *box; 45b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri 46b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri if (direct) 47b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri { 48b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri tx->staging_resource = pt; 49b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri return tx; 50b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri } 51b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri 52b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri util_staging_resource_template(pt, box->width, box->height, box->depth, &staging_resource_template); 53b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri tx->staging_resource = pscreen->resource_create(pscreen, &staging_resource_template); 54b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri if (!tx->staging_resource) 55b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri { 56b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri pipe_resource_reference(&tx->base.resource, NULL); 57b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri FREE(tx); 58b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri return NULL; 59b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri } 60b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri 61b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri if (usage & PIPE_TRANSFER_READ) 62b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri { 63b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri struct pipe_subresource dstsr; 6427fe2347bc2ddf88cb666a95adfb0b12a39d42b9Vinson Lee unsigned zi; 65b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri dstsr.face = 0; 66b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri dstsr.level = 0; 6727fe2347bc2ddf88cb666a95adfb0b12a39d42b9Vinson Lee for(zi = 0; zi < box->depth; ++zi) 68b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri pipe->resource_copy_region(pipe, tx->staging_resource, dstsr, 0, 0, 0, tx->base.resource, sr, box->x, box->y, box->z + zi, box->width, box->height); 69b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri } 70b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri 71b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri return tx; 72b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri} 73b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri 74b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbierivoid 75b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieriutil_staging_transfer_destroy(struct pipe_context *pipe, struct pipe_transfer *ptx) 76b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri{ 77b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri struct util_staging_transfer *tx = (struct util_staging_transfer *)ptx; 78b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri 79b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri if (tx->staging_resource != tx->base.resource) 80b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri { 81b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri if(tx->base.usage & PIPE_TRANSFER_WRITE) { 82b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri struct pipe_subresource srcsr; 8327fe2347bc2ddf88cb666a95adfb0b12a39d42b9Vinson Lee unsigned zi; 84b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri srcsr.face = 0; 85b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri srcsr.level = 0; 8627fe2347bc2ddf88cb666a95adfb0b12a39d42b9Vinson Lee for(zi = 0; zi < tx->base.box.depth; ++zi) 87b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri pipe->resource_copy_region(pipe, tx->base.resource, tx->base.sr, tx->base.box.x, tx->base.box.y, tx->base.box.z + zi, tx->staging_resource, srcsr, 0, 0, 0, tx->base.box.width, tx->base.box.height); 88b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri } 89b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri 90b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri pipe_resource_reference(&tx->staging_resource, NULL); 91b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri } 92b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri 93b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri pipe_resource_reference(&ptx->resource, NULL); 94b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri FREE(ptx); 95b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri} 96