Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3770 Serge 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
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 *
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
      int 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
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
         int 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
}