1848b8605Smrg/************************************************************************** 2848b8605Smrg * 3848b8605Smrg * Copyright 2008 VMware, Inc. 4848b8605Smrg * All Rights Reserved. 5848b8605Smrg * 6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7848b8605Smrg * copy of this software and associated documentation files (the 8848b8605Smrg * "Software"), to deal in the Software without restriction, including 9848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish, 10848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to 11848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to 12848b8605Smrg * the following conditions: 13848b8605Smrg * 14848b8605Smrg * The above copyright notice and this permission notice (including the 15848b8605Smrg * next paragraph) shall be included in all copies or substantial portions 16848b8605Smrg * of the Software. 17848b8605Smrg * 18848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20848b8605Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21848b8605Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22848b8605Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23848b8605Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24848b8605Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25848b8605Smrg * 26848b8605Smrg **************************************************************************/ 27848b8605Smrg 28848b8605Smrg/** 29848b8605Smrg * @file 30848b8605Smrg * Buffer validation. 31848b8605Smrg * 32848b8605Smrg * @author Jose Fonseca <jfonseca@vmware.com> 33848b8605Smrg */ 34848b8605Smrg 35848b8605Smrg 36848b8605Smrg#include "pipe/p_compiler.h" 37848b8605Smrg#include "pipe/p_defines.h" 38848b8605Smrg#include "util/u_memory.h" 39848b8605Smrg#include "util/u_debug.h" 40848b8605Smrg 41848b8605Smrg#include "pb_buffer.h" 42848b8605Smrg#include "pb_validate.h" 43848b8605Smrg 44848b8605Smrg 45848b8605Smrg#define PB_VALIDATE_INITIAL_SIZE 1 /* 512 */ 46848b8605Smrg 47848b8605Smrg 48848b8605Smrgstruct pb_validate_entry 49848b8605Smrg{ 50848b8605Smrg struct pb_buffer *buf; 51848b8605Smrg unsigned flags; 52848b8605Smrg}; 53848b8605Smrg 54848b8605Smrg 55848b8605Smrgstruct pb_validate 56848b8605Smrg{ 57848b8605Smrg struct pb_validate_entry *entries; 58848b8605Smrg unsigned used; 59848b8605Smrg unsigned size; 60848b8605Smrg}; 61848b8605Smrg 62848b8605Smrg 63848b8605Smrgenum pipe_error 64848b8605Smrgpb_validate_add_buffer(struct pb_validate *vl, 65848b8605Smrg struct pb_buffer *buf, 66b8e80941Smrg enum pb_usage_flags flags) 67848b8605Smrg{ 68848b8605Smrg assert(buf); 69b8e80941Smrg if (!buf) 70848b8605Smrg return PIPE_ERROR; 71848b8605Smrg 72848b8605Smrg assert(flags & PB_USAGE_GPU_READ_WRITE); 73848b8605Smrg assert(!(flags & ~PB_USAGE_GPU_READ_WRITE)); 74848b8605Smrg flags &= PB_USAGE_GPU_READ_WRITE; 75848b8605Smrg 76848b8605Smrg /* We only need to store one reference for each buffer, so avoid storing 77848b8605Smrg * consecutive references for the same buffer. It might not be the most 78848b8605Smrg * common pattern, but it is easy to implement. 79848b8605Smrg */ 80848b8605Smrg if(vl->used && vl->entries[vl->used - 1].buf == buf) { 81848b8605Smrg vl->entries[vl->used - 1].flags |= flags; 82848b8605Smrg return PIPE_OK; 83848b8605Smrg } 84848b8605Smrg 85848b8605Smrg /* Grow the table */ 86848b8605Smrg if(vl->used == vl->size) { 87848b8605Smrg unsigned new_size; 88848b8605Smrg struct pb_validate_entry *new_entries; 89848b8605Smrg 90848b8605Smrg new_size = vl->size * 2; 91848b8605Smrg if(!new_size) 92848b8605Smrg return PIPE_ERROR_OUT_OF_MEMORY; 93848b8605Smrg 94848b8605Smrg new_entries = (struct pb_validate_entry *)REALLOC(vl->entries, 95848b8605Smrg vl->size*sizeof(struct pb_validate_entry), 96848b8605Smrg new_size*sizeof(struct pb_validate_entry)); 97b8e80941Smrg if (!new_entries) 98848b8605Smrg return PIPE_ERROR_OUT_OF_MEMORY; 99848b8605Smrg 100848b8605Smrg memset(new_entries + vl->size, 0, (new_size - vl->size)*sizeof(struct pb_validate_entry)); 101848b8605Smrg 102848b8605Smrg vl->size = new_size; 103848b8605Smrg vl->entries = new_entries; 104848b8605Smrg } 105848b8605Smrg 106848b8605Smrg assert(!vl->entries[vl->used].buf); 107848b8605Smrg pb_reference(&vl->entries[vl->used].buf, buf); 108848b8605Smrg vl->entries[vl->used].flags = flags; 109848b8605Smrg ++vl->used; 110848b8605Smrg 111848b8605Smrg return PIPE_OK; 112848b8605Smrg} 113848b8605Smrg 114848b8605Smrg 115848b8605Smrgenum pipe_error 116848b8605Smrgpb_validate_foreach(struct pb_validate *vl, 117848b8605Smrg enum pipe_error (*callback)(struct pb_buffer *buf, void *data), 118848b8605Smrg void *data) 119848b8605Smrg{ 120848b8605Smrg unsigned i; 121848b8605Smrg for(i = 0; i < vl->used; ++i) { 122848b8605Smrg enum pipe_error ret; 123848b8605Smrg ret = callback(vl->entries[i].buf, data); 124848b8605Smrg if(ret != PIPE_OK) 125848b8605Smrg return ret; 126848b8605Smrg } 127848b8605Smrg return PIPE_OK; 128848b8605Smrg} 129848b8605Smrg 130848b8605Smrg 131848b8605Smrgenum pipe_error 132848b8605Smrgpb_validate_validate(struct pb_validate *vl) 133848b8605Smrg{ 134848b8605Smrg unsigned i; 135848b8605Smrg 136848b8605Smrg for(i = 0; i < vl->used; ++i) { 137848b8605Smrg enum pipe_error ret; 138848b8605Smrg ret = pb_validate(vl->entries[i].buf, vl, vl->entries[i].flags); 139848b8605Smrg if(ret != PIPE_OK) { 140848b8605Smrg while(i--) 141848b8605Smrg pb_validate(vl->entries[i].buf, NULL, 0); 142848b8605Smrg return ret; 143848b8605Smrg } 144848b8605Smrg } 145848b8605Smrg 146848b8605Smrg return PIPE_OK; 147848b8605Smrg} 148848b8605Smrg 149848b8605Smrg 150848b8605Smrgvoid 151848b8605Smrgpb_validate_fence(struct pb_validate *vl, 152848b8605Smrg struct pipe_fence_handle *fence) 153848b8605Smrg{ 154848b8605Smrg unsigned i; 155848b8605Smrg for(i = 0; i < vl->used; ++i) { 156848b8605Smrg pb_fence(vl->entries[i].buf, fence); 157848b8605Smrg pb_reference(&vl->entries[i].buf, NULL); 158848b8605Smrg } 159848b8605Smrg vl->used = 0; 160848b8605Smrg} 161848b8605Smrg 162848b8605Smrg 163848b8605Smrgvoid 164848b8605Smrgpb_validate_destroy(struct pb_validate *vl) 165848b8605Smrg{ 166848b8605Smrg unsigned i; 167848b8605Smrg for(i = 0; i < vl->used; ++i) 168848b8605Smrg pb_reference(&vl->entries[i].buf, NULL); 169848b8605Smrg FREE(vl->entries); 170848b8605Smrg FREE(vl); 171848b8605Smrg} 172848b8605Smrg 173848b8605Smrg 174848b8605Smrgstruct pb_validate * 175848b8605Smrgpb_validate_create() 176848b8605Smrg{ 177848b8605Smrg struct pb_validate *vl; 178848b8605Smrg 179848b8605Smrg vl = CALLOC_STRUCT(pb_validate); 180b8e80941Smrg if (!vl) 181848b8605Smrg return NULL; 182848b8605Smrg 183848b8605Smrg vl->size = PB_VALIDATE_INITIAL_SIZE; 184848b8605Smrg vl->entries = (struct pb_validate_entry *)CALLOC(vl->size, sizeof(struct pb_validate_entry)); 185848b8605Smrg if(!vl->entries) { 186848b8605Smrg FREE(vl); 187848b8605Smrg return NULL; 188848b8605Smrg } 189848b8605Smrg 190848b8605Smrg return vl; 191848b8605Smrg} 192848b8605Smrg 193