pb_buffer.h revision a6d866f72c88d48d2bcfb3e3c882fdb639b5a8ce
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 return buf->vtbl->map(buf, flags); 163} 164 165 166static INLINE void 167pb_unmap(struct pb_buffer *buf) 168{ 169 assert(buf); 170 if(!buf) 171 return; 172 buf->vtbl->unmap(buf); 173} 174 175 176static INLINE void 177pb_get_base_buffer( struct pb_buffer *buf, 178 struct pb_buffer **base_buf, 179 unsigned *offset ) 180{ 181 assert(buf); 182 if(!buf) { 183 base_buf = NULL; 184 offset = 0; 185 return; 186 } 187 assert(buf->vtbl->get_base_buffer); 188 buf->vtbl->get_base_buffer(buf, base_buf, offset); 189} 190 191 192static INLINE enum pipe_error 193pb_validate(struct pb_buffer *buf, struct pb_validate *vl, unsigned flags) 194{ 195 assert(buf); 196 if(!buf) 197 return PIPE_ERROR; 198 assert(buf->vtbl->validate); 199 return buf->vtbl->validate(buf, vl, flags); 200} 201 202 203static INLINE void 204pb_fence(struct pb_buffer *buf, struct pipe_fence_handle *fence) 205{ 206 assert(buf); 207 if(!buf) 208 return; 209 assert(buf->vtbl->fence); 210 buf->vtbl->fence(buf, fence); 211} 212 213 214static INLINE void 215pb_destroy(struct pb_buffer *buf) 216{ 217 assert(buf); 218 if(!buf) 219 return; 220 buf->vtbl->destroy(buf); 221} 222 223 224/* XXX: thread safety issues! 225 */ 226static INLINE void 227pb_reference(struct pb_buffer **dst, 228 struct pb_buffer *src) 229{ 230 if (src) 231 src->base.refcount++; 232 233 if (*dst && --(*dst)->base.refcount == 0) 234 pb_destroy( *dst ); 235 236 *dst = src; 237} 238 239 240/** 241 * Utility function to check whether the provided alignment is consistent with 242 * the requested or not. 243 */ 244static INLINE boolean 245pb_check_alignment(size_t requested, size_t provided) 246{ 247 return requested <= provided && (provided % requested) == 0 ? TRUE : FALSE; 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_usage(unsigned requested, unsigned provided) 257{ 258 return (requested & provided) == requested ? TRUE : FALSE; 259} 260 261 262/** 263 * Malloc-based buffer to store data that can't be used by the graphics 264 * hardware. 265 */ 266struct pb_buffer * 267pb_malloc_buffer_create(size_t size, 268 const struct pb_desc *desc); 269 270 271void 272pb_init_winsys(struct pipe_winsys *winsys); 273 274 275#ifdef __cplusplus 276} 277#endif 278 279#endif /*PB_BUFFER_H_*/ 280