• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright 2010 Luca Barbieri
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the
14  * next paragraph) shall be included in all copies or substantial
15  * portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  *
25  **************************************************************************/
26 
27 #include "util/u_staging.h"
28 #include "pipe/p_context.h"
29 #include "util/u_memory.h"
30 #include "util/u_inlines.h"
31 
32 static void
util_staging_resource_template(struct pipe_resource * pt,unsigned width,unsigned height,unsigned depth,struct pipe_resource * template)33 util_staging_resource_template(struct pipe_resource *pt, unsigned width, unsigned height, unsigned depth, struct pipe_resource *template)
34 {
35    memset(template, 0, sizeof(struct pipe_resource));
36    if(pt->target != PIPE_BUFFER && depth <= 1)
37       template->target = PIPE_TEXTURE_RECT;
38    else
39       template->target = pt->target;
40    template->format = pt->format;
41    template->width0 = width;
42    template->height0 = height;
43    template->depth0 = depth;
44    template->array_size = 1;
45    template->last_level = 0;
46    template->nr_samples = pt->nr_samples;
47    template->bind = 0;
48    template->usage = PIPE_USAGE_STAGING;
49    template->flags = 0;
50 }
51 
52 struct util_staging_transfer *
util_staging_transfer_init(struct pipe_context * pipe,struct pipe_resource * pt,unsigned level,unsigned usage,const struct pipe_box * box,boolean direct,struct util_staging_transfer * tx)53 util_staging_transfer_init(struct pipe_context *pipe,
54            struct pipe_resource *pt,
55            unsigned level,
56            unsigned usage,
57            const struct pipe_box *box,
58            boolean direct, struct util_staging_transfer *tx)
59 {
60    struct pipe_screen *pscreen = pipe->screen;
61 
62    struct pipe_resource staging_resource_template;
63 
64    pipe_resource_reference(&tx->base.resource, pt);
65    tx->base.level = level;
66    tx->base.usage = usage;
67    tx->base.box = *box;
68 
69    if (direct)
70    {
71       tx->staging_resource = pt;
72       return tx;
73    }
74 
75    util_staging_resource_template(pt, box->width, box->height, box->depth, &staging_resource_template);
76    tx->staging_resource = pscreen->resource_create(pscreen, &staging_resource_template);
77    if (!tx->staging_resource)
78    {
79       pipe_resource_reference(&tx->base.resource, NULL);
80       FREE(tx);
81       return NULL;
82    }
83 
84    if (usage & PIPE_TRANSFER_READ)
85    {
86       /* XXX this looks wrong dst is always the same but looping over src z? */
87       unsigned zi;
88       struct pipe_box sbox;
89       sbox.x = box->x;
90       sbox.y = box->y;
91       sbox.z = box->z;
92       sbox.width = box->width;
93       sbox.height = box->height;
94       sbox.depth = 1;
95       for(zi = 0; zi < box->depth; ++zi) {
96          sbox.z = sbox.z + zi;
97          pipe->resource_copy_region(pipe, tx->staging_resource, 0, 0, 0, 0,
98                                     tx->base.resource, level, &sbox);
99       }
100    }
101 
102    return tx;
103 }
104 
105 void
util_staging_transfer_destroy(struct pipe_context * pipe,struct pipe_transfer * ptx)106 util_staging_transfer_destroy(struct pipe_context *pipe, struct pipe_transfer *ptx)
107 {
108    struct util_staging_transfer *tx = (struct util_staging_transfer *)ptx;
109 
110    if (tx->staging_resource != tx->base.resource)
111    {
112       if(tx->base.usage & PIPE_TRANSFER_WRITE) {
113          /* XXX this looks wrong src is always the same but looping over dst z? */
114          unsigned zi;
115          struct pipe_box sbox;
116          sbox.x = 0;
117          sbox.y = 0;
118          sbox.z = 0;
119          sbox.width = tx->base.box.width;
120          sbox.height = tx->base.box.height;
121          sbox.depth = 1;
122          for(zi = 0; zi < tx->base.box.depth; ++zi)
123             pipe->resource_copy_region(pipe, tx->base.resource, tx->base.level, tx->base.box.x, tx->base.box.y, tx->base.box.z + zi,
124                                        tx->staging_resource, 0, &sbox);
125       }
126 
127       pipe_resource_reference(&tx->staging_resource, NULL);
128    }
129 
130    pipe_resource_reference(&ptx->resource, NULL);
131    FREE(ptx);
132 }
133