1fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri/**************************************************************************
2fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri *
3fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * Copyright 2010 Luca Barbieri
4fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri *
5fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * Permission is hereby granted, free of charge, to any person obtaining
6fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * a copy of this software and associated documentation files (the
7fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * "Software"), to deal in the Software without restriction, including
8fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * without limitation the rights to use, copy, modify, merge, publish,
9fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * distribute, sublicense, and/or sell copies of the Software, and to
10fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * permit persons to whom the Software is furnished to do so, subject to
11fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * the following conditions:
12fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri *
13fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * The above copyright notice and this permission notice (including the
14fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * next paragraph) shall be included in all copies or substantial
15fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * portions of the Software.
16fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri *
17fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri *
25fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri **************************************************************************/
26fa32fde26cbb770c6ffa0a0ead529d511eab1eb1Luca Barbieri
27b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri#include "util/u_staging.h"
28b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri#include "pipe/p_context.h"
29b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri#include "util/u_memory.h"
30b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri#include "util/u_inlines.h"
31b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri
32b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieristatic void
33b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieriutil_staging_resource_template(struct pipe_resource *pt, unsigned width, unsigned height, unsigned depth, struct pipe_resource *template)
34b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri{
35b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   memset(template, 0, sizeof(struct pipe_resource));
36b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   if(pt->target != PIPE_BUFFER && depth <= 1)
374a9bfb24eb907080b2e3e49215ad9912758d56c6Luca Barbieri      template->target = PIPE_TEXTURE_RECT;
38b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   else
39b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri      template->target = pt->target;
40b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   template->format = pt->format;
41b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   template->width0 = width;
42b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   template->height0 = height;
43b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   template->depth0 = depth;
444c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   template->array_size = 1;
45b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   template->last_level = 0;
46b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   template->nr_samples = pt->nr_samples;
47b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   template->bind = 0;
48b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   template->usage = PIPE_USAGE_STAGING;
49b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   template->flags = 0;
50b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri}
51b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri
5241c7ff11e6aa4d82d1175446aea0984bf28e3905Luca Barbieristruct util_staging_transfer *
533aaec4750d6fda39b3bb4fc0a159fba1655feedeLuca Barbieriutil_staging_transfer_init(struct pipe_context *pipe,
54b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri           struct pipe_resource *pt,
554c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger           unsigned level,
56b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri           unsigned usage,
57b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri           const struct pipe_box *box,
585f2deba9f3f3f9230a9fdd2848e20c1e23e98b8fBrian Paul           boolean direct, struct util_staging_transfer *tx)
59b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri{
60b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   struct pipe_screen *pscreen = pipe->screen;
61b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri
623aaec4750d6fda39b3bb4fc0a159fba1655feedeLuca Barbieri   struct pipe_resource staging_resource_template;
63b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri
64b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   pipe_resource_reference(&tx->base.resource, pt);
654c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   tx->base.level = level;
66b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   tx->base.usage = usage;
67b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   tx->base.box = *box;
68b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri
69b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   if (direct)
70b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   {
71b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri      tx->staging_resource = pt;
72b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri      return tx;
73b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   }
74b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri
75b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   util_staging_resource_template(pt, box->width, box->height, box->depth, &staging_resource_template);
76b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   tx->staging_resource = pscreen->resource_create(pscreen, &staging_resource_template);
77b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   if (!tx->staging_resource)
78b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   {
79b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri      pipe_resource_reference(&tx->base.resource, NULL);
80b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri      FREE(tx);
81b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri      return NULL;
82b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   }
83b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri
84b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   if (usage & PIPE_TRANSFER_READ)
85b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   {
864c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      /* XXX this looks wrong dst is always the same but looping over src z? */
8727fe2347bc2ddf88cb666a95adfb0b12a39d42b9Vinson Lee      unsigned zi;
884c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      struct pipe_box sbox;
894c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      sbox.x = box->x;
904c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      sbox.y = box->y;
914c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      sbox.z = box->z;
924c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      sbox.width = box->width;
934c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      sbox.height = box->height;
944c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      sbox.depth = 1;
954c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      for(zi = 0; zi < box->depth; ++zi) {
964c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         sbox.z = sbox.z + zi;
974c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         pipe->resource_copy_region(pipe, tx->staging_resource, 0, 0, 0, 0,
984c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                    tx->base.resource, level, &sbox);
994c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      }
100b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   }
101b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri
102b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   return tx;
103b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri}
104b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri
105b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbierivoid
106b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieriutil_staging_transfer_destroy(struct pipe_context *pipe, struct pipe_transfer *ptx)
107b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri{
108b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   struct util_staging_transfer *tx = (struct util_staging_transfer *)ptx;
109b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri
110b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   if (tx->staging_resource != tx->base.resource)
111b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   {
112b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri      if(tx->base.usage & PIPE_TRANSFER_WRITE) {
1134c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         /* XXX this looks wrong src is always the same but looping over dst z? */
11427fe2347bc2ddf88cb666a95adfb0b12a39d42b9Vinson Lee         unsigned zi;
1154c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         struct pipe_box sbox;
1164c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         sbox.x = 0;
1174c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         sbox.y = 0;
1184c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         sbox.z = 0;
1194c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         sbox.width = tx->base.box.width;
1204c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         sbox.height = tx->base.box.height;
1214c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         sbox.depth = 1;
12227fe2347bc2ddf88cb666a95adfb0b12a39d42b9Vinson Lee         for(zi = 0; zi < tx->base.box.depth; ++zi)
1234c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            pipe->resource_copy_region(pipe, tx->base.resource, tx->base.level, tx->base.box.x, tx->base.box.y, tx->base.box.z + zi,
1244c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                       tx->staging_resource, 0, &sbox);
125b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri      }
126b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri
127b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri      pipe_resource_reference(&tx->staging_resource, NULL);
128b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   }
129b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri
130b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   pipe_resource_reference(&ptx->resource, NULL);
131b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri   FREE(ptx);
132b85c71d4e1e4ed788be834dff5b7b3c0cd0402acLuca Barbieri}
133