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