1848b8605Smrg/************************************************************************** 2848b8605Smrg * 3848b8605Smrg * Copyright 2007 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 * Generic code for buffers. 31b8e80941Smrg * 32b8e80941Smrg * Behind a pipe buffle handle there can be DMA buffers, client (or user) 33b8e80941Smrg * buffers, regular malloced buffers, etc. This file provides an abstract base 34b8e80941Smrg * buffer handle that allows the driver to cope with all those kinds of buffers 35848b8605Smrg * in a more flexible way. 36b8e80941Smrg * 37848b8605Smrg * There is no obligation of a winsys driver to use this library. And a pipe 38848b8605Smrg * driver should be completly agnostic about it. 39b8e80941Smrg * 40848b8605Smrg * \author Jose Fonseca <jfonseca@vmware.com> 41848b8605Smrg */ 42848b8605Smrg 43848b8605Smrg#ifndef PB_BUFFER_H_ 44848b8605Smrg#define PB_BUFFER_H_ 45848b8605Smrg 46848b8605Smrg 47848b8605Smrg#include "pipe/p_compiler.h" 48848b8605Smrg#include "util/u_debug.h" 49848b8605Smrg#include "util/u_inlines.h" 50848b8605Smrg#include "pipe/p_defines.h" 51848b8605Smrg 52848b8605Smrg 53848b8605Smrg#ifdef __cplusplus 54848b8605Smrgextern "C" { 55848b8605Smrg#endif 56848b8605Smrg 57848b8605Smrg 58848b8605Smrgstruct pb_vtbl; 59848b8605Smrgstruct pb_validate; 60848b8605Smrgstruct pipe_fence_handle; 61848b8605Smrg 62b8e80941Smrgenum pb_usage_flags { 63b8e80941Smrg PB_USAGE_CPU_READ = (1 << 0), 64b8e80941Smrg PB_USAGE_CPU_WRITE = (1 << 1), 65b8e80941Smrg PB_USAGE_GPU_READ = (1 << 2), 66b8e80941Smrg PB_USAGE_GPU_WRITE = (1 << 3), 67b8e80941Smrg PB_USAGE_DONTBLOCK = (1 << 9), 68b8e80941Smrg PB_USAGE_UNSYNCHRONIZED = (1 << 10), 69b8e80941Smrg}; 70848b8605Smrg 71b8e80941Smrg/* For error checking elsewhere */ 72b8e80941Smrg#define PB_USAGE_ALL (PB_USAGE_CPU_READ | \ 73b8e80941Smrg PB_USAGE_CPU_WRITE | \ 74b8e80941Smrg PB_USAGE_GPU_READ | \ 75b8e80941Smrg PB_USAGE_GPU_WRITE | \ 76b8e80941Smrg PB_USAGE_DONTBLOCK | \ 77b8e80941Smrg PB_USAGE_UNSYNCHRONIZED) 78b8e80941Smrg 79b8e80941Smrg#define PB_USAGE_CPU_READ_WRITE (PB_USAGE_CPU_READ | PB_USAGE_CPU_WRITE) 80b8e80941Smrg#define PB_USAGE_GPU_READ_WRITE (PB_USAGE_GPU_READ | PB_USAGE_GPU_WRITE) 81b8e80941Smrg#define PB_USAGE_WRITE (PB_USAGE_CPU_WRITE | PB_USAGE_GPU_WRITE) 82848b8605Smrg 83848b8605Smrg 84848b8605Smrg/** 85848b8605Smrg * Buffer description. 86b8e80941Smrg * 87848b8605Smrg * Used when allocating the buffer. 88848b8605Smrg */ 89848b8605Smrgstruct pb_desc 90848b8605Smrg{ 91848b8605Smrg unsigned alignment; 92b8e80941Smrg enum pb_usage_flags usage; 93848b8605Smrg}; 94848b8605Smrg 95848b8605Smrg 96848b8605Smrg/** 97b8e80941Smrg * 64-bit type for GPU buffer sizes and offsets. 98848b8605Smrg */ 99b8e80941Smrgtypedef uint64_t pb_size; 100848b8605Smrg 101848b8605Smrg 102848b8605Smrg/** 103848b8605Smrg * Base class for all pb_* buffers. 104848b8605Smrg */ 105b8e80941Smrgstruct pb_buffer 106848b8605Smrg{ 107848b8605Smrg struct pipe_reference reference; 108848b8605Smrg unsigned alignment; 109b8e80941Smrg pb_size size; 110b8e80941Smrg enum pb_usage_flags usage; 111848b8605Smrg 112848b8605Smrg /** 113848b8605Smrg * Pointer to the virtual function table. 114848b8605Smrg * 115b8e80941Smrg * Avoid accessing this table directly. Use the inline functions below 116b8e80941Smrg * instead to avoid mistakes. 117848b8605Smrg */ 118848b8605Smrg const struct pb_vtbl *vtbl; 119848b8605Smrg}; 120848b8605Smrg 121848b8605Smrg 122848b8605Smrg/** 123848b8605Smrg * Virtual function table for the buffer storage operations. 124b8e80941Smrg * 125848b8605Smrg * Note that creation is not done through this table. 126848b8605Smrg */ 127848b8605Smrgstruct pb_vtbl 128848b8605Smrg{ 129b8e80941Smrg void (*destroy)(struct pb_buffer *buf); 130848b8605Smrg 131b8e80941Smrg /** 132848b8605Smrg * Map the entire data store of a buffer object into the client's address. 133b8e80941Smrg * flags is bitmask of PB_USAGE_CPU_READ/WRITE. 134848b8605Smrg */ 135b8e80941Smrg void *(*map)(struct pb_buffer *buf, 136b8e80941Smrg enum pb_usage_flags flags, void *flush_ctx); 137b8e80941Smrg 138b8e80941Smrg void (*unmap)(struct pb_buffer *buf); 139848b8605Smrg 140b8e80941Smrg enum pipe_error (*validate)(struct pb_buffer *buf, 141b8e80941Smrg struct pb_validate *vl, 142b8e80941Smrg enum pb_usage_flags flags); 143848b8605Smrg 144b8e80941Smrg void (*fence)(struct pb_buffer *buf, 145b8e80941Smrg struct pipe_fence_handle *fence); 146848b8605Smrg 147848b8605Smrg /** 148848b8605Smrg * Get the base buffer and the offset. 149b8e80941Smrg * 150848b8605Smrg * A buffer can be subdivided in smaller buffers. This method should return 151848b8605Smrg * the underlaying buffer, and the relative offset. 152b8e80941Smrg * 153b8e80941Smrg * Buffers without an underlaying base buffer should return themselves, with 154848b8605Smrg * a zero offset. 155b8e80941Smrg * 156848b8605Smrg * Note that this will increase the reference count of the base buffer. 157848b8605Smrg */ 158b8e80941Smrg void (*get_base_buffer)(struct pb_buffer *buf, 159b8e80941Smrg struct pb_buffer **base_buf, 160b8e80941Smrg pb_size *offset); 161848b8605Smrg}; 162848b8605Smrg 163848b8605Smrg 164848b8605Smrg 165848b8605Smrg/* Accessor functions for pb->vtbl: 166848b8605Smrg */ 167b8e80941Smrgstatic inline void * 168b8e80941Smrgpb_map(struct pb_buffer *buf, enum pb_usage_flags flags, void *flush_ctx) 169848b8605Smrg{ 170848b8605Smrg assert(buf); 171b8e80941Smrg if (!buf) 172848b8605Smrg return NULL; 173848b8605Smrg assert(pipe_is_referenced(&buf->reference)); 174848b8605Smrg return buf->vtbl->map(buf, flags, flush_ctx); 175848b8605Smrg} 176848b8605Smrg 177848b8605Smrg 178b8e80941Smrgstatic inline void 179848b8605Smrgpb_unmap(struct pb_buffer *buf) 180848b8605Smrg{ 181848b8605Smrg assert(buf); 182b8e80941Smrg if (!buf) 183848b8605Smrg return; 184848b8605Smrg assert(pipe_is_referenced(&buf->reference)); 185848b8605Smrg buf->vtbl->unmap(buf); 186848b8605Smrg} 187848b8605Smrg 188848b8605Smrg 189b8e80941Smrgstatic inline void 190b8e80941Smrgpb_get_base_buffer(struct pb_buffer *buf, 191b8e80941Smrg struct pb_buffer **base_buf, 192b8e80941Smrg pb_size *offset) 193848b8605Smrg{ 194848b8605Smrg assert(buf); 195b8e80941Smrg if (!buf) { 196848b8605Smrg base_buf = NULL; 197848b8605Smrg offset = 0; 198848b8605Smrg return; 199848b8605Smrg } 200848b8605Smrg assert(pipe_is_referenced(&buf->reference)); 201848b8605Smrg assert(buf->vtbl->get_base_buffer); 202848b8605Smrg buf->vtbl->get_base_buffer(buf, base_buf, offset); 203848b8605Smrg assert(*base_buf); 204848b8605Smrg assert(*offset < (*base_buf)->size); 205848b8605Smrg} 206848b8605Smrg 207848b8605Smrg 208b8e80941Smrgstatic inline enum pipe_error 209b8e80941Smrgpb_validate(struct pb_buffer *buf, struct pb_validate *vl, 210b8e80941Smrg enum pb_usage_flags flags) 211848b8605Smrg{ 212848b8605Smrg assert(buf); 213b8e80941Smrg if (!buf) 214848b8605Smrg return PIPE_ERROR; 215848b8605Smrg assert(buf->vtbl->validate); 216848b8605Smrg return buf->vtbl->validate(buf, vl, flags); 217848b8605Smrg} 218848b8605Smrg 219848b8605Smrg 220b8e80941Smrgstatic inline void 221848b8605Smrgpb_fence(struct pb_buffer *buf, struct pipe_fence_handle *fence) 222848b8605Smrg{ 223848b8605Smrg assert(buf); 224b8e80941Smrg if (!buf) 225848b8605Smrg return; 226848b8605Smrg assert(buf->vtbl->fence); 227848b8605Smrg buf->vtbl->fence(buf, fence); 228848b8605Smrg} 229848b8605Smrg 230848b8605Smrg 231b8e80941Smrgstatic inline void 232848b8605Smrgpb_destroy(struct pb_buffer *buf) 233848b8605Smrg{ 234848b8605Smrg assert(buf); 235b8e80941Smrg if (!buf) 236848b8605Smrg return; 237848b8605Smrg assert(!pipe_is_referenced(&buf->reference)); 238848b8605Smrg buf->vtbl->destroy(buf); 239848b8605Smrg} 240848b8605Smrg 241b8e80941Smrg 242b8e80941Smrgstatic inline void 243848b8605Smrgpb_reference(struct pb_buffer **dst, 244848b8605Smrg struct pb_buffer *src) 245848b8605Smrg{ 246848b8605Smrg struct pb_buffer *old = *dst; 247848b8605Smrg 248848b8605Smrg if (pipe_reference(&(*dst)->reference, &src->reference)) 249b8e80941Smrg pb_destroy(old); 250848b8605Smrg *dst = src; 251848b8605Smrg} 252848b8605Smrg 253848b8605Smrg 254848b8605Smrg/** 255848b8605Smrg * Utility function to check whether the provided alignment is consistent with 256848b8605Smrg * the requested or not. 257848b8605Smrg */ 258b8e80941Smrgstatic inline boolean 259848b8605Smrgpb_check_alignment(pb_size requested, pb_size provided) 260848b8605Smrg{ 261b8e80941Smrg if (!requested) 262848b8605Smrg return TRUE; 263b8e80941Smrg if (requested > provided) 264848b8605Smrg return FALSE; 265b8e80941Smrg if (provided % requested != 0) 266848b8605Smrg return FALSE; 267848b8605Smrg return TRUE; 268848b8605Smrg} 269848b8605Smrg 270848b8605Smrg 271848b8605Smrg/** 272848b8605Smrg * Utility function to check whether the provided alignment is consistent with 273848b8605Smrg * the requested or not. 274848b8605Smrg */ 275b8e80941Smrgstatic inline boolean 276848b8605Smrgpb_check_usage(unsigned requested, unsigned provided) 277848b8605Smrg{ 278848b8605Smrg return (requested & provided) == requested ? TRUE : FALSE; 279848b8605Smrg} 280848b8605Smrg 281848b8605Smrg 282848b8605Smrg/** 283b8e80941Smrg * Malloc-based buffer to store data that can't be used by the graphics 284848b8605Smrg * hardware. 285848b8605Smrg */ 286848b8605Smrgstruct pb_buffer * 287b8e80941Smrgpb_malloc_buffer_create(pb_size size, 288848b8605Smrg const struct pb_desc *desc); 289848b8605Smrg 290848b8605Smrg 291848b8605Smrg#ifdef __cplusplus 292848b8605Smrg} 293848b8605Smrg#endif 294848b8605Smrg 295848b8605Smrg#endif /*PB_BUFFER_H_*/ 296