diff options
Diffstat (limited to 'src/gallium/include/pipe')
-rw-r--r-- | src/gallium/include/pipe/internal/p_winsys_screen.h | 8 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_atomic.h | 382 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_config.h | 8 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_context.h | 1 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_debug.h | 361 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_defines.h | 12 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_format.h | 3 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_inlines.h | 175 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_refcnt.h | 88 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_screen.h | 60 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_shader_tokens.h | 6 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_state.h | 85 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_thread.h | 32 |
13 files changed, 699 insertions, 522 deletions
diff --git a/src/gallium/include/pipe/internal/p_winsys_screen.h b/src/gallium/include/pipe/internal/p_winsys_screen.h index ee835578b2..f4a29e63c7 100644 --- a/src/gallium/include/pipe/internal/p_winsys_screen.h +++ b/src/gallium/include/pipe/internal/p_winsys_screen.h @@ -68,6 +68,11 @@ struct pipe_winsys const char *(*get_name)( struct pipe_winsys *ws ); /** + * Do any special operations to ensure buffer size is correct + */ + void (*update_buffer)( struct pipe_winsys *ws, + void *context_private ); + /** * Do any special operations to ensure frontbuffer contents are * displayed, eg copy fake frontbuffer. */ @@ -149,8 +154,7 @@ struct pipe_winsys void (*buffer_unmap)( struct pipe_winsys *ws, struct pipe_buffer *buf ); - void (*buffer_destroy)( struct pipe_winsys *ws, - struct pipe_buffer *buf ); + void (*buffer_destroy)( struct pipe_buffer *buf ); /** Set ptr = fence, with reference counting */ diff --git a/src/gallium/include/pipe/p_atomic.h b/src/gallium/include/pipe/p_atomic.h new file mode 100644 index 0000000000..f2fe083efa --- /dev/null +++ b/src/gallium/include/pipe/p_atomic.h @@ -0,0 +1,382 @@ +/** + * Many similar implementations exist. See for example libwsbm + * or the linux kernel include/atomic.h + * + * No copyright claimed on this file. + * + */ + +#ifndef P_ATOMIC_H +#define P_ATOMIC_H + +#include "p_compiler.h" +#include "p_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Favor OS-provided implementations. + */ +#define PIPE_ATOMIC_OS_UNLOCKED \ + (defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || \ + defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)) + +#define PIPE_ATOMIC_OS_MS_INTERLOCK \ + (!defined(PIPE_CC_GCC) && \ + !PIPE_ATOMIC_OS_UNLOCKED && \ + defined(PIPE_SUBSYSTEM_WINDOWS_USER)) + +#define PIPE_ATOMIC_OS_PROVIDED \ + (PIPE_ATOMIC_OS_UNLOCKED || \ + PIPE_ATOMIC_OS_MS_INTERLOCK) + +/* Where no OS-provided implementation is available, fall back to + * either locally coded assembly or ultimately a mutex-based + * implementation: + */ +#define PIPE_ATOMIC_ASM_GCC_X86 \ + (!PIPE_ATOMIC_OS_PROVIDED && \ + defined(PIPE_CC_GCC) && \ + defined(PIPE_ARCH_X86)) + +/* KW: this was originally used when x86 asm wasn't available. + * Maintain that logic here. + */ +#define PIPE_ATOMIC_GCC_INTRINISIC \ + (!PIPE_ATOMIC_OS_PROVIDED && \ + !PIPE_ATOMIC_ASM_GCC_X86 && \ + defined(PIPE_CC_GCC)) + +#define PIPE_ATOMIC_ASM_MSVC_X86 \ + (!PIPE_ATOMIC_OS_PROVIDED && \ + defined(PIPE_CC_MSVC) && \ + defined(PIPE_ARCH_X86)) + +#define PIPE_ATOMIC_ASM \ + (PIPE_ATOMIC_ASM_GCC_X86 || \ + PIPE_ATOMIC_ASM_GCC_INTRINSIC || \ + PIPE_ATOMIC_ASM_MSVC_X86) + + +/* Where no OS-provided or locally-coded assembly implemenation is + * available, use pipe_mutex: + */ +#define PIPE_ATOMIC_MUTEX \ + (!PIPE_ATOMIC_OS_PROVIDED && \ + !PIPE_ATOMIC_ASM) + + + +#if (PIPE_ATOMIC_ASM_GCC_X86) + +#define PIPE_ATOMIC "GCC x86 assembly" + +struct pipe_atomic { + int32_t count; +}; + +#define p_atomic_set(_v, _i) ((_v)->count = (_i)) +#define p_atomic_read(_v) ((_v)->count) + + +static INLINE boolean +p_atomic_dec_zero(struct pipe_atomic *v) +{ + unsigned char c; + + __asm__ __volatile__("lock; decl %0; sete %1":"+m"(v->count), "=qm"(c) + ::"memory"); + + return c != 0; +} + +static INLINE void +p_atomic_inc(struct pipe_atomic *v) +{ + __asm__ __volatile__("lock; incl %0":"+m"(v->count)); +} + +static INLINE void +p_atomic_dec(struct pipe_atomic *v) +{ + __asm__ __volatile__("lock; decl %0":"+m"(v->count)); +} + +static INLINE int32_t +p_atomic_cmpxchg(struct pipe_atomic *v, int32_t old, int32_t _new) +{ + return __sync_val_compare_and_swap(&v->count, old, _new); +} +#endif + + + +/* Implementation using GCC-provided synchronization intrinsics + */ +#if (PIPE_ATOMIC_ASM_GCC_INTRINSIC) + +#define PIPE_ATOMIC "GCC Sync Intrinsics" + +struct pipe_atomic { + int32_t count; +}; + +#define p_atomic_set(_v, _i) ((_v)->count = (_i)) +#define p_atomic_read(_v) ((_v)->count) + + +static INLINE boolean +p_atomic_dec_zero(struct pipe_atomic *v) +{ + return (__sync_sub_and_fetch(&v->count, 1) == 0); +} + +static INLINE void +p_atomic_inc(struct pipe_atomic *v) +{ + (void) __sync_add_and_fetch(&v->count, 1); +} + +static INLINE void +p_atomic_dec(struct pipe_atomic *v) +{ + (void) __sync_sub_and_fetch(&v->count, 1); +} + +static INLINE int32_t +p_atomic_cmpxchg(struct pipe_atomic *v, int32_t old, int32_t _new) +{ + return __sync_val_compare_and_swap(&v->count, old, _new); +} +#endif + + + +/* Unlocked version for single threaded environments, such as some + * windows kernel modules. + */ +#if (PIPE_ATOMIC_OS_UNLOCKED) + +#define PIPE_ATOMIC "Unlocked" + +struct pipe_atomic +{ + int32_t count; +}; + +#define p_atomic_set(_v, _i) ((_v)->count = (_i)) +#define p_atomic_read(_v) ((_v)->count) +#define p_atomic_dec_zero(_v) ((boolean) --(_v)->count) +#define p_atomic_inc(_v) ((void) (_v)->count++) +#define p_atomic_dec(_v) ((void) (_v)->count--) +#define p_atomic_cmpxchg(_v, old, _new) ((_v)->count == old ? (_v)->count = (_new) : (_v)->count) + +#endif + + +/* Locally coded assembly for MSVC on x86: + */ +#if (PIPE_ATOMIC_ASM_MSVC_X86) + +#define PIPE_ATOMIC "MSVC x86 assembly" + +struct pipe_atomic +{ + int32_t count; +}; + +#define p_atomic_set(_v, _i) ((_v)->count = (_i)) +#define p_atomic_read(_v) ((_v)->count) + +static INLINE boolean +p_atomic_dec_zero(struct pipe_atomic *v) +{ + int32_t *pcount = &v->count; + unsigned char c; + + __asm { + mov eax, [pcount] + lock dec dword ptr [eax] + sete byte ptr [c] + } + + return c != 0; +} + +static INLINE void +p_atomic_inc(struct pipe_atomic *v) +{ + int32_t *pcount = &v->count; + + __asm { + mov eax, [pcount] + lock inc dword ptr [eax] + } +} + +static INLINE void +p_atomic_dec(struct pipe_atomic *v) +{ + int32_t *pcount = &v->count; + + __asm { + mov eax, [pcount] + lock dec dword ptr [eax] + } +} + +static INLINE int32_t +p_atomic_cmpxchg(struct pipe_atomic *v, int32_t old, int32_t _new) +{ + int32_t *pcount = &v->count; + int32_t orig; + + __asm { + mov ecx, [pcount] + mov eax, [old] + mov edx, [_new] + lock cmpxchg [ecx], edx + mov [orig], eax + } + + return orig; +} +#endif + + +#if (PIPE_ATOMIC_OS_MS_INTERLOCK) + +#define PIPE_ATOMIC "MS userspace interlocks" + +#include <windows.h> + +struct pipe_atomic +{ + long count; +}; + +#define p_atomic_set(_v, _i) ((_v)->count = (_i)) +#define p_atomic_read(_v) ((_v)->count) + +static INLINE boolean +p_atomic_dec_zero(struct pipe_atomic *v) +{ + return InterlockedDecrement(&v->count); +} + +static INLINE void +p_atomic_inc(struct pipe_atomic *v) +{ + InterlockedIncrement(&v->count); +} + +static INLINE void +p_atomic_dec(struct pipe_atomic *v) +{ + InterlockedDecrement(&v->count); +} + +static INLINE int32_t +p_atomic_cmpxchg(struct pipe_atomic *v, int32_t old, int32_t _new) +{ + return InterlockedCompareExchange(&v->count, _new, old); +} + +#endif + + + +#if (PIPE_ATOMIC_MUTEX) + +#define PIPE_ATOMIC "mutex-based fallback" + +#include "pipe/p_thread.h" + +/** + * This implementation should really not be used. + * Add an assembly port instead. It may abort and + * doesn't destroy used mutexes. + */ + +struct pipe_atomic { + pipe_mutex mutex; + int32_t count; +}; + +static INLINE void +p_atomic_set(struct pipe_atomic *v, int32_t i) +{ + pipe_mutex_init(v->mutex); + pipe_mutex_lock(v->mutex); + v->count = i; + pipe_mutex_unlock(v->mutex); +} + +static INLINE int32_t +p_atomic_read(struct pipe_atomic *v) +{ + int32_t ret; + + pipe_mutex_lock(v->mutex); + ret = v->count; + pipe_mutex_unlock(v->mutex); + return ret; +} + +static INLINE void +p_atomic_inc(struct pipe_atomic *v) +{ + pipe_mutex_lock(v->mutex); + ++v->count; + pipe_mutex_unlock(v->mutex); +} + +static INLINE void +p_atomic_dec(struct pipe_atomic *v) +{ + pipe_mutex_lock(v->mutex); + --v->count; + pipe_mutex_unlock(v->mutex); +} + +static INLINE boolean +p_atomic_dec_zero(struct pipe_atomic *v) +{ + boolean ret; + + pipe_mutex_lock(v->mutex); + ret = (--v->count == 0); + pipe_mutex_unlock(v->mutex); + return ret; +} + +static INLINE int32_t +p_atomic_cmpxchg(struct pipe_atomic *v, int32_t old, int32_t _new) +{ + int32_t ret; + + pipe_mutex_lock(v->mutex); + ret = v->count; + if (ret == old) + v->count = _new; + pipe_mutex_unlock(v->mutex); + + return ret; +} + +#endif + + +#ifndef PIPE_ATOMIC +#error "No pipe_atomic implementation selected" +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif /* P_ATOMIC_H */ diff --git a/src/gallium/include/pipe/p_config.h b/src/gallium/include/pipe/p_config.h index 05cbd2fc4d..7f7657031d 100644 --- a/src/gallium/include/pipe/p_config.h +++ b/src/gallium/include/pipe/p_config.h @@ -111,6 +111,10 @@ #define PIPE_OS_LINUX #endif +#if defined(__FreeBSD__) +#define PIPE_OS_BSD +#endif + #if defined(_WIN32) || defined(WIN32) #define PIPE_OS_WINDOWS #endif @@ -122,9 +126,9 @@ * NOTE: There is no way to auto-detect most of these. */ -#if defined(PIPE_OS_LINUX) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) #define PIPE_SUBSYSTEM_DRI -#endif /* PIPE_OS_LINUX */ +#endif /* PIPE_OS_LINUX || PIPE_OS_BSD */ #if defined(PIPE_OS_WINDOWS) #if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 9454cc87db..2452bf3522 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -193,7 +193,6 @@ struct pipe_context { */ /*@{*/ void (*surface_copy)(struct pipe_context *pipe, - boolean do_flip,/**< flip surface contents vertically */ struct pipe_surface *dest, unsigned destx, unsigned desty, struct pipe_surface *src, /* don't make this const - diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h deleted file mode 100644 index e9c95982dd..0000000000 --- a/src/gallium/include/pipe/p_debug.h +++ /dev/null @@ -1,361 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * @file - * Cross-platform debugging helpers. - * - * For now it just has assert and printf replacements, but it might be extended - * with stack trace reports and more advanced logging in the near future. - * - * @author Jose Fonseca <jrfonseca@tungstengraphics.com> - */ - -#ifndef P_DEBUG_H_ -#define P_DEBUG_H_ - - -#include <stdarg.h> - -#include "p_compiler.h" - - -#ifdef __cplusplus -extern "C" { -#endif - - -#if defined(DBG) || defined(DEBUG) -#ifndef DEBUG -#define DEBUG 1 -#endif -#else -#ifndef NDEBUG -#define NDEBUG 1 -#endif -#endif - - -/* MSVC bebore VC7 does not have the __FUNCTION__ macro */ -#if defined(_MSC_VER) && _MSC_VER < 1300 -#define __FUNCTION__ "???" -#endif - - -void _debug_vprintf(const char *format, va_list ap); - - -static INLINE void -_debug_printf(const char *format, ...) -{ - va_list ap; - va_start(ap, format); - _debug_vprintf(format, ap); - va_end(ap); -} - - -/** - * Print debug messages. - * - * The actual channel used to output debug message is platform specific. To - * avoid misformating or truncation, follow these rules of thumb: - * - output whole lines - * - avoid outputing large strings (512 bytes is the current maximum length - * that is guaranteed to be printed in all platforms) - */ -static INLINE void -debug_printf(const char *format, ...) -{ -#ifdef DEBUG - va_list ap; - va_start(ap, format); - _debug_vprintf(format, ap); - va_end(ap); -#else - (void) format; /* silence warning */ -#endif -} - - -#ifdef DEBUG -#define debug_vprintf(_format, _ap) _debug_vprintf(_format, _ap) -#else -#define debug_vprintf(_format, _ap) ((void)0) -#endif - - -#ifdef DEBUG -/** - * Dump a blob in hex to the same place that debug_printf sends its - * messages. - */ -void debug_print_blob( const char *name, const void *blob, unsigned size ); - -/* Print a message along with a prettified format string - */ -void debug_print_format(const char *msg, unsigned fmt ); -#else -#define debug_print_blob(_name, _blob, _size) ((void)0) -#define debug_print_format(_msg, _fmt) ((void)0) -#endif - - -void _debug_break(void); - - -/** - * Hard-coded breakpoint. - */ -#ifdef DEBUG -#if defined(PIPE_ARCH_X86) && defined(PIPE_CC_GCC) -#define debug_break() __asm("int3") -#elif defined(PIPE_ARCH_X86) && defined(PIPE_CC_MSVC) -#define debug_break() do { _asm {int 3} } while(0) -#else -#define debug_break() _debug_break() -#endif -#else /* !DEBUG */ -#define debug_break() ((void)0) -#endif /* !DEBUG */ - - -long -debug_get_num_option(const char *name, long dfault); - -void _debug_assert_fail(const char *expr, - const char *file, - unsigned line, - const char *function); - - -/** - * Assert macro - * - * Do not expect that the assert call terminates -- errors must be handled - * regardless of assert behavior. - */ -#ifdef DEBUG -#define debug_assert(expr) ((expr) ? (void)0 : _debug_assert_fail(#expr, __FILE__, __LINE__, __FUNCTION__)) -#else -#define debug_assert(expr) ((void)0) -#endif - - -/** Override standard assert macro */ -#ifdef assert -#undef assert -#endif -#define assert(expr) debug_assert(expr) - - -/** - * Output the current function name. - */ -#ifdef DEBUG -#define debug_checkpoint() \ - _debug_printf("%s\n", __FUNCTION__) -#else -#define debug_checkpoint() \ - ((void)0) -#endif - - -/** - * Output the full source code position. - */ -#ifdef DEBUG -#define debug_checkpoint_full() \ - _debug_printf("%s:%u:%s", __FILE__, __LINE__, __FUNCTION__) -#else -#define debug_checkpoint_full() \ - ((void)0) -#endif - - -/** - * Output a warning message. Muted on release version. - */ -#ifdef DEBUG -#define debug_warning(__msg) \ - _debug_printf("%s:%u:%s: warning: %s\n", __FILE__, __LINE__, __FUNCTION__, __msg) -#else -#define debug_warning(__msg) \ - ((void)0) -#endif - - -/** - * Output an error message. Not muted on release version. - */ -#ifdef DEBUG -#define debug_error(__msg) \ - _debug_printf("%s:%u:%s: error: %s\n", __FILE__, __LINE__, __FUNCTION__, __msg) -#else -#define debug_error(__msg) \ - _debug_printf("error: %s\n", __msg) -#endif - - -/** - * Used by debug_dump_enum and debug_dump_flags to describe symbols. - */ -struct debug_named_value -{ - const char *name; - unsigned long value; -}; - - -/** - * Some C pre-processor magic to simplify creating named values. - * - * Example: - * @code - * static const debug_named_value my_names[] = { - * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_X), - * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Y), - * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Z), - * DEBUG_NAMED_VALUE_END - * }; - * - * ... - * debug_printf("%s = %s\n", - * name, - * debug_dump_enum(my_names, my_value)); - * ... - * @endcode - */ -#define DEBUG_NAMED_VALUE(__symbol) {#__symbol, (unsigned long)__symbol} -#define DEBUG_NAMED_VALUE_END {NULL, 0} - - -/** - * Convert a enum value to a string. - */ -const char * -debug_dump_enum(const struct debug_named_value *names, - unsigned long value); - -const char * -debug_dump_enum_noprefix(const struct debug_named_value *names, - const char *prefix, - unsigned long value); - - -/** - * Convert binary flags value to a string. - */ -const char * -debug_dump_flags(const struct debug_named_value *names, - unsigned long value); - - -/** - * Get option. - * - * It is an alias for getenv on Linux. - * - * On Windows it reads C:\gallium.cfg, which is a text file with CR+LF line - * endings with one option per line as - * - * NAME=value - * - * This file must be terminated with an extra empty line. - */ -const char * -debug_get_option(const char *name, const char *dfault); - -boolean -debug_get_bool_option(const char *name, boolean dfault); - -long -debug_get_num_option(const char *name, long dfault); - -unsigned long -debug_get_flags_option(const char *name, - const struct debug_named_value *flags, - unsigned long dfault); - - -void * -debug_malloc(const char *file, unsigned line, const char *function, - size_t size); - -void -debug_free(const char *file, unsigned line, const char *function, - void *ptr); - -void * -debug_calloc(const char *file, unsigned line, const char *function, - size_t count, size_t size ); - -void * -debug_realloc(const char *file, unsigned line, const char *function, - void *old_ptr, size_t old_size, size_t new_size ); - -unsigned long -debug_memory_begin(void); - -void -debug_memory_end(unsigned long beginning); - - -#if defined(PROFILE) && defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) - -void -debug_profile_start(void); - -void -debug_profile_stop(void); - -#endif - - -#ifdef DEBUG -struct pipe_surface; -void debug_dump_image(const char *prefix, - unsigned format, unsigned cpp, - unsigned width, unsigned height, - unsigned stride, - const void *data); -void debug_dump_surface(const char *prefix, - struct pipe_surface *surface); -void debug_dump_surface_bmp(const char *filename, - struct pipe_surface *surface); -#else -#define debug_dump_image(prefix, format, cpp, width, height, stride, data) ((void)0) -#define debug_dump_surface(prefix, surface) ((void)0) -#define debug_dump_surface_bmp(filename, surface) ((void)0) -#endif - - -#ifdef __cplusplus -} -#endif - -#endif /* P_DEBUG_H_ */ diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 4f0b301f31..52d443970b 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -194,6 +194,16 @@ enum pipe_texture_target { /** + * Transfer object usage flags + */ +enum pipe_transfer_usage { + PIPE_TRANSFER_READ, + PIPE_TRANSFER_WRITE, + PIPE_TRANSFER_READ_WRITE //< Read/modify/write +}; + + +/** * Buffer usage flags */ #define PIPE_BUFFER_USAGE_CPU_READ (1 << 0) @@ -205,6 +215,7 @@ enum pipe_texture_target { #define PIPE_BUFFER_USAGE_INDEX (1 << 6) #define PIPE_BUFFER_USAGE_CONSTANT (1 << 7) #define PIPE_BUFFER_USAGE_DISCARD (1 << 8) +#define PIPE_BUFFER_USAGE_DONTBLOCK (1 << 9) /** Pipe driver custom usage flags should be greater or equal to this value */ #define PIPE_BUFFER_USAGE_CUSTOM (1 << 16) @@ -247,6 +258,7 @@ enum pipe_texture_target { #define PIPE_PRIM_QUADS 7 #define PIPE_PRIM_QUAD_STRIP 8 #define PIPE_PRIM_POLYGON 9 +#define PIPE_PRIM_MAX 10 /** diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index b42f98ceba..3f65a60436 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -30,8 +30,9 @@ #define PIPE_FORMAT_H #include "p_compiler.h" -#include "p_debug.h" +/* FIXME: remove these header dependencies */ +#include "util/u_debug.h" #include "util/u_string.h" #ifdef __cplusplus diff --git a/src/gallium/include/pipe/p_inlines.h b/src/gallium/include/pipe/p_inlines.h index 1219c817b4..1232c87968 100644 --- a/src/gallium/include/pipe/p_inlines.h +++ b/src/gallium/include/pipe/p_inlines.h @@ -38,95 +38,6 @@ extern "C" { #endif -/* XXX: these are a kludge. will fix when all surfaces are views into - * textures, and free-floating winsys surfaces go away. - */ -static INLINE void * -pipe_surface_map( struct pipe_surface *surf, unsigned flags ) -{ - struct pipe_screen *screen; - assert(surf->texture); - screen = surf->texture->screen; - return screen->surface_map( screen, surf, flags ); -} - -static INLINE void -pipe_surface_unmap( struct pipe_surface *surf ) -{ - struct pipe_screen *screen; - assert(surf->texture); - screen = surf->texture->screen; - screen->surface_unmap( screen, surf ); -} - - - -/** - * Set 'ptr' to point to 'surf' and update reference counting. - * The old thing pointed to, if any, will be unreferenced first. - * 'surf' may be NULL. - */ -static INLINE void -pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf) -{ - /* bump the refcount first */ - if (surf) { - assert(surf->refcount); - surf->refcount++; - } - - if (*ptr) { - struct pipe_screen *screen; - assert((*ptr)->refcount); - assert((*ptr)->texture); - screen = (*ptr)->texture->screen; - screen->tex_surface_release( screen, ptr ); - assert(!*ptr); - } - - *ptr = surf; -} - - -/** - * \sa pipe_surface_reference - */ -static INLINE void -pipe_texture_reference(struct pipe_texture **ptr, - struct pipe_texture *pt) -{ - assert(ptr); - - if (pt) { - assert(pt->refcount); - pt->refcount++; - } - - if (*ptr) { - struct pipe_screen *screen = (*ptr)->screen; - assert(screen); - assert((*ptr)->refcount); - screen->texture_release(screen, ptr); - - assert(!*ptr); - } - - *ptr = pt; -} - - -static INLINE void -pipe_texture_release(struct pipe_texture **ptr) -{ - struct pipe_screen *screen; - assert(ptr); - screen = (*ptr)->screen; - assert((*ptr)->refcount); - screen->texture_release(screen, ptr); - *ptr = NULL; -} - - /** * Convenience wrappers for screen buffer functions. */ @@ -149,7 +60,13 @@ pipe_buffer_map(struct pipe_screen *screen, struct pipe_buffer *buf, unsigned usage) { - return screen->buffer_map(screen, buf, usage); + if(screen->buffer_map_range) { + unsigned offset = 0; + unsigned length = buf->size; + return screen->buffer_map_range(screen, buf, offset, length, usage); + } + else + return screen->buffer_map(screen, buf, usage); } static INLINE void @@ -159,26 +76,74 @@ pipe_buffer_unmap(struct pipe_screen *screen, screen->buffer_unmap(screen, buf); } -/* XXX: thread safety issues! - */ +static INLINE void * +pipe_buffer_map_range(struct pipe_screen *screen, + struct pipe_buffer *buf, + unsigned offset, + unsigned length, + unsigned usage) +{ + assert(offset < buf->size); + assert(offset + length <= buf->size); + assert(length); + if(screen->buffer_map_range) + return screen->buffer_map_range(screen, buf, offset, length, usage); + else + return screen->buffer_map(screen, buf, usage); +} + static INLINE void -pipe_buffer_reference(struct pipe_screen *screen, - struct pipe_buffer **ptr, - struct pipe_buffer *buf) +pipe_buffer_flush_mapped_range(struct pipe_screen *screen, + struct pipe_buffer *buf, + unsigned offset, + unsigned length) { - if (buf) { - assert(buf->refcount); - buf->refcount++; - } + assert(offset < buf->size); + assert(offset + length <= buf->size); + assert(length); + if(screen->buffer_flush_mapped_range) + screen->buffer_flush_mapped_range(screen, buf, offset, length); +} - if (*ptr) { - assert((*ptr)->refcount); - if(--(*ptr)->refcount == 0) { - screen->buffer_destroy( screen, *ptr ); - } +static INLINE void +pipe_buffer_write(struct pipe_screen *screen, + struct pipe_buffer *buf, + unsigned offset, unsigned size, + const void *data) +{ + uint8_t *map; + + assert(offset < buf->size); + assert(offset + size <= buf->size); + assert(size); + + map = pipe_buffer_map_range(screen, buf, offset, size, PIPE_BUFFER_USAGE_CPU_WRITE); + assert(map); + if(map) { + memcpy(map + offset, data, size); + pipe_buffer_flush_mapped_range(screen, buf, offset, size); + pipe_buffer_unmap(screen, buf); } +} - *ptr = buf; +static INLINE void +pipe_buffer_read(struct pipe_screen *screen, + struct pipe_buffer *buf, + unsigned offset, unsigned size, + void *data) +{ + uint8_t *map; + + assert(offset < buf->size); + assert(offset + size <= buf->size); + assert(size); + + map = pipe_buffer_map_range(screen, buf, offset, size, PIPE_BUFFER_USAGE_CPU_READ); + assert(map); + if(map) { + memcpy(data, map + offset, size); + pipe_buffer_unmap(screen, buf); + } } diff --git a/src/gallium/include/pipe/p_refcnt.h b/src/gallium/include/pipe/p_refcnt.h new file mode 100644 index 0000000000..60844e40a5 --- /dev/null +++ b/src/gallium/include/pipe/p_refcnt.h @@ -0,0 +1,88 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef P_REFCNT_H +#define P_REFCNT_H + + +#include "p_defines.h" +#include "p_atomic.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +struct pipe_reference +{ + struct pipe_atomic count; +}; + + +static INLINE void +pipe_reference_init(struct pipe_reference *reference, unsigned count) +{ + p_atomic_set(&reference->count, count); +} + + +/** + * Set 'ptr' to point to 'reference' and update reference counting. + * The old thing pointed to, if any, will be unreferenced first. + * 'reference' may be NULL. + * + * XXX: thread safety issues! + */ +static INLINE bool +pipe_reference(struct pipe_reference **ptr, struct pipe_reference *reference) +{ + bool destroy = FALSE; + + /* bump the reference.count first */ + if (reference) { + assert(p_atomic_read(&reference->count) != 0); + p_atomic_inc(&reference->count); + } + + if (*ptr) { + assert(p_atomic_read(&(*ptr)->count) != 0); + if (p_atomic_dec_zero(&(*ptr)->count)) { + destroy = TRUE; + } + } + + *ptr = reference; + + return destroy; +} + +#ifdef __cplusplus +} +#endif + +#endif /* P_REFCNT_H */ diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index 17d1548253..ed3a026023 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -55,6 +55,7 @@ struct pipe_winsys; struct pipe_buffer; + /** * Gallium screen/adapter context. Basically everything * hardware-specific that doesn't actually require a rendering @@ -112,8 +113,7 @@ struct pipe_screen { const unsigned *stride, struct pipe_buffer *buffer); - void (*texture_release)(struct pipe_screen *, - struct pipe_texture **pt); + void (*texture_destroy)(struct pipe_texture *pt); /** Get a surface which is a "view" into a texture */ struct pipe_surface *(*get_tex_surface)(struct pipe_screen *, @@ -122,18 +122,25 @@ struct pipe_screen { unsigned zslice, unsigned usage ); - /* Surfaces allocated by the above must be released here: - */ - void (*tex_surface_release)( struct pipe_screen *, - struct pipe_surface ** ); + void (*tex_surface_destroy)(struct pipe_surface *); - void *(*surface_map)( struct pipe_screen *, - struct pipe_surface *surface, - unsigned flags ); + /** Get a transfer object for transferring data to/from a texture */ + struct pipe_transfer *(*get_tex_transfer)(struct pipe_screen *, + struct pipe_texture *texture, + unsigned face, unsigned level, + unsigned zslice, + enum pipe_transfer_usage usage, + unsigned x, unsigned y, + unsigned w, unsigned h); + + void (*tex_transfer_destroy)(struct pipe_transfer *); + + void *(*transfer_map)( struct pipe_screen *, + struct pipe_transfer *transfer ); - void (*surface_unmap)( struct pipe_screen *, - struct pipe_surface *surface ); + void (*transfer_unmap)( struct pipe_screen *, + struct pipe_transfer *transfer ); /** @@ -195,12 +202,37 @@ struct pipe_screen { void *(*buffer_map)( struct pipe_screen *screen, struct pipe_buffer *buf, unsigned usage ); + /** + * Map a subrange of the buffer data store into the client's address space. + * + * The returned pointer is always relative to buffer start, regardless of + * the specified range. This is different from the ARB_map_buffer_range + * semantics because we don't forbid multiple mappings of the same buffer + * (yet). + */ + void *(*buffer_map_range)( struct pipe_screen *screen, + struct pipe_buffer *buf, + unsigned offset, + unsigned length, + unsigned usage); + + /** + * Notify a range that was actually written into. + * + * The range is relative to the buffer start, regardless of the range + * specified to buffer_map_range. This is different from the + * ARB_map_buffer_range semantics because we don't forbid multiple mappings + * of the same buffer (yet). + */ + void (*buffer_flush_mapped_range)( struct pipe_screen *screen, + struct pipe_buffer *buf, + unsigned offset, + unsigned length); void (*buffer_unmap)( struct pipe_screen *screen, - struct pipe_buffer *buf ); + struct pipe_buffer *buf ); - void (*buffer_destroy)( struct pipe_screen *screen, - struct pipe_buffer *buf ); + void (*buffer_destroy)( struct pipe_buffer *buf ); /** diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index 35df70e7b7..4dafdd6f0a 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -191,8 +191,8 @@ struct tgsi_immediate_float32 /* * GL_EXT_vertex_shader */ -#define TGSI_OPCODE_INDEX 22 -#define TGSI_OPCODE_NEGATE 23 +#define TGSI_OPCODE_INDEX 22 /* considered for removal */ +#define TGSI_OPCODE_NEGATE 23 /* considered for removal */ #define TGSI_OPCODE_MADD TGSI_OPCODE_MAD #define TGSI_OPCODE_FRAC 24 #define TGSI_OPCODE_SETGE TGSI_OPCODE_SGE @@ -206,7 +206,7 @@ struct tgsi_immediate_float32 #define TGSI_OPCODE_RECIP TGSI_OPCODE_RCP #define TGSI_OPCODE_RECIPSQRT TGSI_OPCODE_RSQ #define TGSI_OPCODE_CROSSPRODUCT 31 -#define TGSI_OPCODE_MULTIPLYMATRIX 32 +#define TGSI_OPCODE_MULTIPLYMATRIX 32 /* considered for removal */ /* * GL_NV_vertex_program1_1 diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 9dc541630c..aad41fab11 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -43,6 +43,8 @@ #include "p_compiler.h" #include "p_defines.h" #include "p_format.h" +#include "p_refcnt.h" +#include "p_screen.h" #ifdef __cplusplus @@ -64,23 +66,20 @@ extern "C" { /* fwd decls */ -struct pipe_screen; struct pipe_surface; - /** * The driver will certainly subclass this to include actual memory * management information. */ struct pipe_buffer { + struct pipe_reference reference; + struct pipe_screen *screen; unsigned alignment; unsigned usage; unsigned size; - - /** Reference count */ - unsigned refcount; }; @@ -109,9 +108,15 @@ struct pipe_rasterizer_state unsigned line_stipple_factor:8; /**< [1..256] actually */ unsigned line_stipple_pattern:16; unsigned line_last_pixel:1; - unsigned bypass_clipping:1; - unsigned bypass_vs:1; /**< Skip the vertex shader. Note that the shader is - still needed though, to indicate inputs/outputs */ + + /** + * Vertex coordinates are pre-transformed to screen space. Skip + * the vertex shader, clipping and viewport processing. Note that + * a vertex shader is still needed though, to indicate the mapping + * from vertex elements to fragment shader input semantics. + */ + unsigned bypass_vs_clip_and_viewport:1; + unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */ unsigned flatshade_first:1; /**< take color attribute from the first vertex of a primitive */ unsigned gl_rasterization_rules:1; /**< enable tweaks for GL rasterization? */ @@ -275,18 +280,14 @@ struct pipe_sampler_state */ struct pipe_surface { + struct pipe_reference reference; enum pipe_format format; /**< PIPE_FORMAT_x */ unsigned status; /**< PIPE_SURFACE_STATUS_x */ unsigned clear_value; /**< XXX may be temporary */ unsigned width; /**< logical width in pixels */ unsigned height; /**< logical height in pixels */ - struct pipe_format_block block; - unsigned nblocksx; /**< allocated width in blocks */ - unsigned nblocksy; /**< allocated height in blocks */ - unsigned stride; /**< stride in bytes between rows of blocks */ unsigned layout; /**< PIPE_SURFACE_LAYOUT_x */ unsigned offset; /**< offset from start of buffer, in bytes */ - unsigned refcount; unsigned usage; /**< PIPE_BUFFER_USAGE_* */ struct pipe_texture *texture; /**< texture into which this is a view */ @@ -297,10 +298,35 @@ struct pipe_surface /** + * Transfer object. For data transfer to/from a texture. + */ +struct pipe_transfer +{ + enum pipe_format format; /**< PIPE_FORMAT_x */ + unsigned x; /**< x offset from start of texture image */ + unsigned y; /**< y offset from start of texture image */ + unsigned width; /**< logical width in pixels */ + unsigned height; /**< logical height in pixels */ + struct pipe_format_block block; + unsigned nblocksx; /**< allocated width in blocks */ + unsigned nblocksy; /**< allocated height in blocks */ + unsigned stride; /**< stride in bytes between rows of blocks */ + unsigned usage; /**< PIPE_TRANSFER_* */ + + struct pipe_texture *texture; /**< texture to transfer to/from */ + unsigned face; + unsigned level; + unsigned zslice; +}; + + +/** * Texture object. */ struct pipe_texture { + struct pipe_reference reference; + enum pipe_texture_target target; /**< PIPE_TEXTURE_x */ enum pipe_format format; /**< PIPE_FORMAT_x */ @@ -319,10 +345,6 @@ struct pipe_texture unsigned tex_usage; /* PIPE_TEXTURE_USAGE_* */ - /* These are also refcounted: - */ - unsigned refcount; - struct pipe_screen *screen; /**< screen that this texture belongs to */ }; @@ -359,6 +381,35 @@ struct pipe_vertex_element }; +/* Reference counting helper functions */ +static INLINE void +pipe_buffer_reference(struct pipe_buffer **ptr, struct pipe_buffer *buf) +{ + struct pipe_buffer *old_buf = *ptr; + + if (pipe_reference((struct pipe_reference **)ptr, &buf->reference)) + old_buf->screen->buffer_destroy(old_buf); +} + +static INLINE void +pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf) +{ + struct pipe_surface *old_surf = *ptr; + + if (pipe_reference((struct pipe_reference **)ptr, &surf->reference)) + old_surf->texture->screen->tex_surface_destroy(old_surf); +} + +static INLINE void +pipe_texture_reference(struct pipe_texture **ptr, struct pipe_texture *tex) +{ + struct pipe_texture *old_tex = *ptr; + + if (pipe_reference((struct pipe_reference **)ptr, &tex->reference)) + old_tex->screen->texture_destroy(old_tex); +} + + #ifdef __cplusplus } #endif diff --git a/src/gallium/include/pipe/p_thread.h b/src/gallium/include/pipe/p_thread.h index 8af3cd958b..a9cd77541d 100644 --- a/src/gallium/include/pipe/p_thread.h +++ b/src/gallium/include/pipe/p_thread.h @@ -38,7 +38,7 @@ #include "pipe/p_compiler.h" -#if defined(PIPE_OS_LINUX) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) #include <pthread.h> /* POSIX threads headers */ #include <stdio.h> /* for perror() */ @@ -73,7 +73,7 @@ typedef pthread_cond_t pipe_condvar; static pipe_mutex mutex = PTHREAD_MUTEX_INITIALIZER #define pipe_mutex_init(mutex) \ - pthread_mutex_init(&(mutex), NULL) + (void) pthread_mutex_init(&(mutex), NULL) #define pipe_mutex_destroy(mutex) \ pthread_mutex_destroy(&(mutex)) @@ -134,20 +134,20 @@ static INLINE int pipe_thread_destroy( pipe_thread thread ) typedef CRITICAL_SECTION pipe_mutex; -#define pipe_static_mutex(name) \ - /*static*/ pipe_mutex name = {0,0,0,0,0,0} +#define pipe_static_mutex(mutex) \ + /*static*/ pipe_mutex mutex = {0,0,0,0,0,0} -#define pipe_mutex_init(name) \ - InitializeCriticalSection(&name) +#define pipe_mutex_init(mutex) \ + InitializeCriticalSection(&mutex) -#define pipe_mutex_destroy(name) \ - DeleteCriticalSection(&name) +#define pipe_mutex_destroy(mutex) \ + DeleteCriticalSection(&mutex) -#define pipe_mutex_lock(name) \ - EnterCriticalSection(&name) +#define pipe_mutex_lock(mutex) \ + EnterCriticalSection(&mutex) -#define pipe_mutex_unlock(name) \ - LeaveCriticalSection(&name) +#define pipe_mutex_unlock(mutex) \ + LeaveCriticalSection(&mutex) /* XXX: dummy definitions, make it compile */ @@ -210,7 +210,7 @@ typedef unsigned pipe_condvar; */ typedef struct { -#if defined(PIPE_OS_LINUX) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) pthread_key_t key; #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) DWORD key; @@ -225,7 +225,7 @@ typedef struct { static INLINE void pipe_tsd_init(pipe_tsd *tsd) { -#if defined(PIPE_OS_LINUX) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) { perror("pthread_key_create(): failed to allocate key for thread specific data"); exit(-1); @@ -242,7 +242,7 @@ pipe_tsd_get(pipe_tsd *tsd) if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) { pipe_tsd_init(tsd); } -#if defined(PIPE_OS_LINUX) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) return pthread_getspecific(tsd->key); #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) assert(0); @@ -259,7 +259,7 @@ pipe_tsd_set(pipe_tsd *tsd, void *value) if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) { pipe_tsd_init(tsd); } -#if defined(PIPE_OS_LINUX) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) if (pthread_setspecific(tsd->key, value) != 0) { perror("pthread_set_specific() failed"); exit(-1); |