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