182dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca/**************************************************************************
282dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca *
382dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
482dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * All Rights Reserved.
582dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca *
682dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * Permission is hereby granted, free of charge, to any person obtaining a
782dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * copy of this software and associated documentation files (the
882dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * "Software"), to deal in the Software without restriction, including
982dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * without limitation the rights to use, copy, modify, merge, publish,
1082dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * distribute, sub license, and/or sell copies of the Software, and to
1182dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * permit persons to whom the Software is furnished to do so, subject to
1282dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * the following conditions:
1382dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca *
1482dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * The above copyright notice and this permission notice (including the
1582dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * next paragraph) shall be included in all copies or substantial portions
1682dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * of the Software.
1782dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca *
1882dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1982dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2082dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
2182dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
2282dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2382dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2482dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2582dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca *
2682dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca **************************************************************************/
2782dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
2882dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca/**
2982dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * @file
3082dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * Buffer validation.
3182dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca *
3282dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca * @author Jose Fonseca <jrfonseca@tungstengraphics.com>
3382dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca */
3482dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
3582dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
3682dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca#include "pipe/p_compiler.h"
373a49497f102f2b64a8755d3cf65b7c0386e95aacJosé Fonseca#include "pipe/p_defines.h"
384f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
39ea4bf267e4b023b08043f91ac44592fed1736e7fJosé Fonseca#include "util/u_debug.h"
4082dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
4182dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca#include "pb_buffer.h"
427ffbfaccfb1484a4ffd5aea0e0e1fbb407977a56Michel Dänzer#include "pb_validate.h"
4382dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
4482dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
458eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca#define PB_VALIDATE_INITIAL_SIZE 1 /* 512 */
4682dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
4782dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
48e06474dbae6979177629fb6187331291ff230c65José Fonsecastruct pb_validate_entry
49e06474dbae6979177629fb6187331291ff230c65José Fonseca{
50e06474dbae6979177629fb6187331291ff230c65José Fonseca   struct pb_buffer *buf;
51e06474dbae6979177629fb6187331291ff230c65José Fonseca   unsigned flags;
52e06474dbae6979177629fb6187331291ff230c65José Fonseca};
53e06474dbae6979177629fb6187331291ff230c65José Fonseca
54e06474dbae6979177629fb6187331291ff230c65José Fonseca
558eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonsecastruct pb_validate
5682dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca{
57e06474dbae6979177629fb6187331291ff230c65José Fonseca   struct pb_validate_entry *entries;
588eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca   unsigned used;
598eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca   unsigned size;
608eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca};
6182dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
6282dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
6382dd0225e7e21a35ca66d439dce8cfa39d782470José Fonsecaenum pipe_error
6482dd0225e7e21a35ca66d439dce8cfa39d782470José Fonsecapb_validate_add_buffer(struct pb_validate *vl,
65e06474dbae6979177629fb6187331291ff230c65José Fonseca                       struct pb_buffer *buf,
66e06474dbae6979177629fb6187331291ff230c65José Fonseca                       unsigned flags)
6782dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca{
6882dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca   assert(buf);
6982dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca   if(!buf)
7082dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca      return PIPE_ERROR;
718eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca
72287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   assert(flags & PB_USAGE_GPU_READ_WRITE);
73287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   assert(!(flags & ~PB_USAGE_GPU_READ_WRITE));
74287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   flags &= PB_USAGE_GPU_READ_WRITE;
75e06474dbae6979177629fb6187331291ff230c65José Fonseca
768eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca   /* We only need to store one reference for each buffer, so avoid storing
77e06474dbae6979177629fb6187331291ff230c65José Fonseca    * consecutive references for the same buffer. It might not be the most
78e06474dbae6979177629fb6187331291ff230c65José Fonseca    * common pattern, but it is easy to implement.
798eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca    */
80e06474dbae6979177629fb6187331291ff230c65José Fonseca   if(vl->used && vl->entries[vl->used - 1].buf == buf) {
81e06474dbae6979177629fb6187331291ff230c65José Fonseca      vl->entries[vl->used - 1].flags |= flags;
828eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca      return PIPE_OK;
838eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca   }
8482dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
858eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca   /* Grow the table */
868eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca   if(vl->used == vl->size) {
878eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca      unsigned new_size;
88e06474dbae6979177629fb6187331291ff230c65José Fonseca      struct pb_validate_entry *new_entries;
898eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca
908eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca      new_size = vl->size * 2;
918eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca      if(!new_size)
928eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca	 return PIPE_ERROR_OUT_OF_MEMORY;
938eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca
94e06474dbae6979177629fb6187331291ff230c65José Fonseca      new_entries = (struct pb_validate_entry *)REALLOC(vl->entries,
95e06474dbae6979177629fb6187331291ff230c65José Fonseca                                                        vl->size*sizeof(struct pb_validate_entry),
96e06474dbae6979177629fb6187331291ff230c65José Fonseca                                                        new_size*sizeof(struct pb_validate_entry));
97e06474dbae6979177629fb6187331291ff230c65José Fonseca      if(!new_entries)
988eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca         return PIPE_ERROR_OUT_OF_MEMORY;
9982dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
100e06474dbae6979177629fb6187331291ff230c65José Fonseca      memset(new_entries + vl->size, 0, (new_size - vl->size)*sizeof(struct pb_validate_entry));
10182dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
1028eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca      vl->size = new_size;
103e06474dbae6979177629fb6187331291ff230c65José Fonseca      vl->entries = new_entries;
10482dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca   }
10582dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
106e06474dbae6979177629fb6187331291ff230c65José Fonseca   assert(!vl->entries[vl->used].buf);
107e06474dbae6979177629fb6187331291ff230c65José Fonseca   pb_reference(&vl->entries[vl->used].buf, buf);
108e06474dbae6979177629fb6187331291ff230c65José Fonseca   vl->entries[vl->used].flags = flags;
1098eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca   ++vl->used;
1108eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca
11182dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca   return PIPE_OK;
11282dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca}
11382dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
11482dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
11582dd0225e7e21a35ca66d439dce8cfa39d782470José Fonsecaenum pipe_error
116e06474dbae6979177629fb6187331291ff230c65José Fonsecapb_validate_foreach(struct pb_validate *vl,
117e06474dbae6979177629fb6187331291ff230c65José Fonseca                    enum pipe_error (*callback)(struct pb_buffer *buf, void *data),
118e06474dbae6979177629fb6187331291ff230c65José Fonseca                    void *data)
119e06474dbae6979177629fb6187331291ff230c65José Fonseca{
120e06474dbae6979177629fb6187331291ff230c65José Fonseca   unsigned i;
121e06474dbae6979177629fb6187331291ff230c65José Fonseca   for(i = 0; i < vl->used; ++i) {
122e06474dbae6979177629fb6187331291ff230c65José Fonseca      enum pipe_error ret;
123e06474dbae6979177629fb6187331291ff230c65José Fonseca      ret = callback(vl->entries[i].buf, data);
124e06474dbae6979177629fb6187331291ff230c65José Fonseca      if(ret != PIPE_OK)
125e06474dbae6979177629fb6187331291ff230c65José Fonseca         return ret;
126e06474dbae6979177629fb6187331291ff230c65José Fonseca   }
127e06474dbae6979177629fb6187331291ff230c65José Fonseca   return PIPE_OK;
128e06474dbae6979177629fb6187331291ff230c65José Fonseca}
129e06474dbae6979177629fb6187331291ff230c65José Fonseca
130e06474dbae6979177629fb6187331291ff230c65José Fonseca
131e06474dbae6979177629fb6187331291ff230c65José Fonsecaenum pipe_error
13282dd0225e7e21a35ca66d439dce8cfa39d782470José Fonsecapb_validate_validate(struct pb_validate *vl)
13382dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca{
134e06474dbae6979177629fb6187331291ff230c65José Fonseca   unsigned i;
135e06474dbae6979177629fb6187331291ff230c65José Fonseca
136e06474dbae6979177629fb6187331291ff230c65José Fonseca   for(i = 0; i < vl->used; ++i) {
137e06474dbae6979177629fb6187331291ff230c65José Fonseca      enum pipe_error ret;
138e06474dbae6979177629fb6187331291ff230c65José Fonseca      ret = pb_validate(vl->entries[i].buf, vl, vl->entries[i].flags);
139e06474dbae6979177629fb6187331291ff230c65José Fonseca      if(ret != PIPE_OK) {
140e06474dbae6979177629fb6187331291ff230c65José Fonseca         while(i--)
141e06474dbae6979177629fb6187331291ff230c65José Fonseca            pb_validate(vl->entries[i].buf, NULL, 0);
142e06474dbae6979177629fb6187331291ff230c65José Fonseca         return ret;
143e06474dbae6979177629fb6187331291ff230c65José Fonseca      }
144e06474dbae6979177629fb6187331291ff230c65José Fonseca   }
145e06474dbae6979177629fb6187331291ff230c65José Fonseca
14682dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca   return PIPE_OK;
14782dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca}
14882dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
14982dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
15082dd0225e7e21a35ca66d439dce8cfa39d782470José Fonsecavoid
15182dd0225e7e21a35ca66d439dce8cfa39d782470José Fonsecapb_validate_fence(struct pb_validate *vl,
15282dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca                  struct pipe_fence_handle *fence)
15382dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca{
1548eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca   unsigned i;
1558eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca   for(i = 0; i < vl->used; ++i) {
156e06474dbae6979177629fb6187331291ff230c65José Fonseca      pb_fence(vl->entries[i].buf, fence);
157e06474dbae6979177629fb6187331291ff230c65José Fonseca      pb_reference(&vl->entries[i].buf, NULL);
1588eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca   }
1598eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca   vl->used = 0;
16082dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca}
16182dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
16282dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
16382dd0225e7e21a35ca66d439dce8cfa39d782470José Fonsecavoid
16482dd0225e7e21a35ca66d439dce8cfa39d782470José Fonsecapb_validate_destroy(struct pb_validate *vl)
16582dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca{
1668eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca   unsigned i;
1678eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca   for(i = 0; i < vl->used; ++i)
168e06474dbae6979177629fb6187331291ff230c65José Fonseca      pb_reference(&vl->entries[i].buf, NULL);
169e06474dbae6979177629fb6187331291ff230c65José Fonseca   FREE(vl->entries);
17082dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca   FREE(vl);
17182dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca}
17282dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
17382dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
17482dd0225e7e21a35ca66d439dce8cfa39d782470José Fonsecastruct pb_validate *
17582dd0225e7e21a35ca66d439dce8cfa39d782470José Fonsecapb_validate_create()
17682dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca{
17782dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca   struct pb_validate *vl;
17882dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
17982dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca   vl = CALLOC_STRUCT(pb_validate);
18082dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca   if(!vl)
18182dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca      return NULL;
18282dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
1838eab7de888bb4056c34f80edfbc90a543736ea3bJosé Fonseca   vl->size = PB_VALIDATE_INITIAL_SIZE;
184e06474dbae6979177629fb6187331291ff230c65José Fonseca   vl->entries = (struct pb_validate_entry *)CALLOC(vl->size, sizeof(struct pb_validate_entry));
185e06474dbae6979177629fb6187331291ff230c65José Fonseca   if(!vl->entries) {
18682dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca      FREE(vl);
18782dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca      return NULL;
18882dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca   }
18982dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
19082dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca   return vl;
19182dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca}
19282dd0225e7e21a35ca66d439dce8cfa39d782470José Fonseca
193