Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  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. }
  133.