Home | History | Annotate | Download | only in util
      1 /**************************************************************************
      2  *
      3  * Copyright 2012 Marek Olk <maraeo (at) gmail.com>
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sub license, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the
     15  * next paragraph) shall be included in all copies or substantial portions
     16  * of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     21  * IN NO EVENT SHALL THE AUTHORS AND/OR THEIR SUPPLIERS BE LIABLE FOR
     22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     25  *
     26  **************************************************************************/
     27 
     28 #include "util/u_helpers.h"
     29 #include "util/u_inlines.h"
     30 
     31 /**
     32  * This function is used to copy an array of pipe_vertex_buffer structures,
     33  * while properly referencing the pipe_vertex_buffer::buffer member.
     34  *
     35  * enabled_buffers is updated such that the bits corresponding to the indices
     36  * of disabled buffers are set to 0 and the enabled ones are set to 1.
     37  *
     38  * \sa util_copy_framebuffer_state
     39  */
     40 void util_set_vertex_buffers_mask(struct pipe_vertex_buffer *dst,
     41                                   uint32_t *enabled_buffers,
     42                                   const struct pipe_vertex_buffer *src,
     43                                   unsigned start_slot, unsigned count)
     44 {
     45    unsigned i;
     46    uint32_t bitmask = 0;
     47 
     48    dst += start_slot;
     49 
     50    if (src) {
     51       for (i = 0; i < count; i++) {
     52          if (src[i].buffer || src[i].user_buffer) {
     53             bitmask |= 1 << i;
     54          }
     55          pipe_resource_reference(&dst[i].buffer, src[i].buffer);
     56       }
     57 
     58       /* Copy over the other members of pipe_vertex_buffer. */
     59       memcpy(dst, src, count * sizeof(struct pipe_vertex_buffer));
     60 
     61       *enabled_buffers &= ~(((1ull << count) - 1) << start_slot);
     62       *enabled_buffers |= bitmask << start_slot;
     63    }
     64    else {
     65       /* Unreference the buffers. */
     66       for (i = 0; i < count; i++) {
     67          pipe_resource_reference(&dst[i].buffer, NULL);
     68          dst[i].user_buffer = NULL;
     69       }
     70 
     71       *enabled_buffers &= ~(((1ull << count) - 1) << start_slot);
     72    }
     73 }
     74 
     75 /**
     76  * Same as util_set_vertex_buffers_mask, but it only returns the number
     77  * of bound buffers.
     78  */
     79 void util_set_vertex_buffers_count(struct pipe_vertex_buffer *dst,
     80                                    unsigned *dst_count,
     81                                    const struct pipe_vertex_buffer *src,
     82                                    unsigned start_slot, unsigned count)
     83 {
     84    unsigned i;
     85    uint32_t enabled_buffers = 0;
     86 
     87    for (i = 0; i < *dst_count; i++) {
     88       if (dst[i].buffer || dst[i].user_buffer)
     89          enabled_buffers |= (1ull << i);
     90    }
     91 
     92    util_set_vertex_buffers_mask(dst, &enabled_buffers, src, start_slot,
     93                                 count);
     94 
     95    *dst_count = util_last_bit(enabled_buffers);
     96 }
     97 
     98 
     99 void
    100 util_set_index_buffer(struct pipe_index_buffer *dst,
    101                       const struct pipe_index_buffer *src)
    102 {
    103    if (src) {
    104       pipe_resource_reference(&dst->buffer, src->buffer);
    105       memcpy(dst, src, sizeof(*dst));
    106    }
    107    else {
    108       pipe_resource_reference(&dst->buffer, NULL);
    109       memset(dst, 0, sizeof(*dst));
    110    }
    111 }
    112