pb_buffer.h revision e06474dbae6979177629fb6187331291ff230c65
1/************************************************************************** 2 * 3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 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 TUNGSTEN GRAPHICS AND/OR ITS 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/** 29 * \file 30 * Generic code for buffers. 31 * 32 * Behind a pipe buffle handle there can be DMA buffers, client (or user) 33 * buffers, regular malloced buffers, etc. This file provides an abstract base 34 * buffer handle that allows the driver to cope with all those kinds of buffers 35 * in a more flexible way. 36 * 37 * There is no obligation of a winsys driver to use this library. And a pipe 38 * driver should be completly agnostic about it. 39 * 40 * \author Jose Fonseca <jrfonseca@tungstengraphics.com> 41 */ 42 43#ifndef PB_BUFFER_H_ 44#define PB_BUFFER_H_ 45 46 47#include "pipe/p_compiler.h" 48#include "pipe/p_debug.h" 49#include "pipe/p_error.h" 50#include "pipe/p_state.h" 51#include "pipe/p_inlines.h" 52 53 54#ifdef __cplusplus 55extern "C" { 56#endif 57 58 59struct pb_vtbl; 60struct pb_validate; 61 62 63/** 64 * Buffer description. 65 * 66 * Used when allocating the buffer. 67 */ 68struct pb_desc 69{ 70 unsigned alignment; 71 unsigned usage; 72}; 73 74 75/** 76 * Base class for all pb_* buffers. 77 */ 78struct pb_buffer 79{ 80 struct pipe_buffer base; 81 82 /** 83 * Pointer to the virtual function table. 84 * 85 * Avoid accessing this table directly. Use the inline functions below 86 * instead to avoid mistakes. 87 */ 88 const struct pb_vtbl *vtbl; 89}; 90 91 92/** 93 * Virtual function table for the buffer storage operations. 94 * 95 * Note that creation is not done through this table. 96 */ 97struct pb_vtbl 98{ 99 void (*destroy)( struct pb_buffer *buf ); 100 101 /** 102 * Map the entire data store of a buffer object into the client's address. 103 * flags is bitmask of PIPE_BUFFER_FLAG_READ/WRITE. 104 */ 105 void *(*map)( struct pb_buffer *buf, 106 unsigned flags ); 107 108 void (*unmap)( struct pb_buffer *buf ); 109 110 enum pipe_error (*validate)( struct pb_buffer *buf, 111 struct pb_validate *vl, 112 unsigned flags ); 113 114 void (*fence)( struct pb_buffer *buf, 115 struct pipe_fence_handle *fence ); 116 117 /** 118 * Get the base buffer and the offset. 119 * 120 * A buffer can be subdivided in smaller buffers. This method should return 121 * the underlaying buffer, and the relative offset. 122 * 123 * Buffers without an underlaying base buffer should return themselves, with 124 * a zero offset. 125 * 126 * Note that this will increase the reference count of the base buffer. 127 */ 128 void (*get_base_buffer)( struct pb_buffer *buf, 129 struct pb_buffer **base_buf, 130 unsigned *offset ); 131 132}; 133 134 135static INLINE struct pipe_buffer * 136pb_pipe_buffer( struct pb_buffer *pbuf ) 137{ 138 assert(pbuf); 139 return &pbuf->base; 140} 141 142 143static INLINE struct pb_buffer * 144pb_buffer( struct pipe_buffer *buf ) 145{ 146 assert(buf); 147 /* Could add a magic cookie check on debug builds. 148 */ 149 return (struct pb_buffer *)buf; 150} 151 152 153/* Accessor functions for pb->vtbl: 154 */ 155static INLINE void * 156pb_map(struct pb_buffer *buf, 157 unsigned flags) 158{ 159 assert(buf); 160 if(!buf) 161 return NULL; 162 assert(buf->base.refcount > 0); 163 return buf->vtbl->map(buf, flags); 164} 165 166 167static INLINE void 168pb_unmap(struct pb_buffer *buf) 169{ 170 assert(buf); 171 if(!buf) 172 return; 173 assert(buf->base.refcount > 0); 174 buf->vtbl->unmap(buf); 175} 176 177 178static INLINE void 179pb_get_base_buffer( struct pb_buffer *buf, 180 struct pb_buffer **base_buf, 181 unsigned *offset ) 182{ 183 assert(buf); 184 if(!buf) { 185 base_buf = NULL; 186 offset = 0; 187 return; 188 } 189 assert(buf->base.refcount > 0); 190 assert(buf->vtbl->get_base_buffer); 191 buf->vtbl->get_base_buffer(buf, base_buf, offset); 192 assert(*base_buf); 193 assert(*offset < (*base_buf)->base.size); 194} 195 196 197static INLINE enum pipe_error 198pb_validate(struct pb_buffer *buf, struct pb_validate *vl, unsigned flags) 199{ 200 assert(buf); 201 if(!buf) 202 return PIPE_ERROR; 203 assert(buf->vtbl->validate); 204 return buf->vtbl->validate(buf, vl, flags); 205} 206 207 208static INLINE void 209pb_fence(struct pb_buffer *buf, struct pipe_fence_handle *fence) 210{ 211 assert(buf); 212 if(!buf) 213 return; 214 assert(buf->vtbl->fence); 215 buf->vtbl->fence(buf, fence); 216} 217 218 219static INLINE void 220pb_destroy(struct pb_buffer *buf) 221{ 222 assert(buf); 223 if(!buf) 224 return; 225 assert(buf->base.refcount == 0); 226 buf->vtbl->destroy(buf); 227} 228 229 230/* XXX: thread safety issues! 231 */ 232static INLINE void 233pb_reference(struct pb_buffer **dst, 234 struct pb_buffer *src) 235{ 236 if (src) { 237 assert(src->base.refcount); 238 src->base.refcount++; 239 } 240 241 if (*dst) { 242 assert((*dst)->base.refcount); 243 if(--(*dst)->base.refcount == 0) 244 pb_destroy( *dst ); 245 } 246 247 *dst = src; 248} 249 250 251/** 252 * Utility function to check whether the provided alignment is consistent with 253 * the requested or not. 254 */ 255static INLINE boolean 256pb_check_alignment(size_t requested, size_t provided) 257{ 258 return requested <= provided && (provided % requested) == 0 ? TRUE : FALSE; 259} 260 261 262/** 263 * Utility function to check whether the provided alignment is consistent with 264 * the requested or not. 265 */ 266static INLINE boolean 267pb_check_usage(unsigned requested, unsigned provided) 268{ 269 return (requested & provided) == requested ? TRUE : FALSE; 270} 271 272 273/** 274 * Malloc-based buffer to store data that can't be used by the graphics 275 * hardware. 276 */ 277struct pb_buffer * 278pb_malloc_buffer_create(size_t size, 279 const struct pb_desc *desc); 280 281 282#ifdef __cplusplus 283} 284#endif 285 286#endif /*PB_BUFFER_H_*/ 287