diff options
Diffstat (limited to 'src/gallium/auxiliary')
50 files changed, 1753 insertions, 438 deletions
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile index da1fb6b299f..e38990a15f9 100644 --- a/src/gallium/auxiliary/Makefile +++ b/src/gallium/auxiliary/Makefile @@ -48,6 +48,7 @@ C_SOURCES = \ draw/draw_vs_sse.c \ indices/u_indices_gen.c \ indices/u_unfilled_gen.c \ + os/os_misc.c \ pipebuffer/pb_buffer_malloc.c \ pipebuffer/pb_bufmgr_alt.c \ pipebuffer/pb_bufmgr_cache.c \ diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript index 3aa782f81e6..bfc68bad2f9 100644 --- a/src/gallium/auxiliary/SConscript +++ b/src/gallium/auxiliary/SConscript @@ -82,6 +82,7 @@ source = [ #'indices/u_unfilled_indices.c', 'indices/u_indices_gen.c', 'indices/u_unfilled_gen.c', + 'os/os_misc.c', 'pipebuffer/pb_buffer_fenced.c', 'pipebuffer/pb_buffer_malloc.c', 'pipebuffer/pb_bufmgr_alt.c', diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index dec830ba93e..c638239e80b 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -36,6 +36,7 @@ */ #include "pipe/p_state.h" +#include "util/u_inlines.h" #include "util/u_memory.h" #include "tgsi/tgsi_parse.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index 11d6485dcf0..83dc1a35f4c 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -32,6 +32,7 @@ #include "draw/draw_private.h" #include "draw/draw_pipe.h" +#include "util/u_debug.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index d254e9d18fa..8f6ca15dfa2 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -35,6 +35,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_math.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 69d122a380d..d0d99aa331a 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -37,6 +37,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_math.h" diff --git a/src/gallium/auxiliary/draw/draw_pt_util.c b/src/gallium/auxiliary/draw/draw_pt_util.c index 17c3b8cec26..3236d38e6ab 100644 --- a/src/gallium/auxiliary/draw/draw_pt_util.c +++ b/src/gallium/auxiliary/draw/draw_pt_util.c @@ -33,6 +33,7 @@ #include "draw/draw_context.h" #include "draw/draw_private.h" #include "draw/draw_pt.h" +#include "util/u_debug.h" void draw_pt_split_prim(unsigned prim, unsigned *first, unsigned *incr) { diff --git a/src/gallium/auxiliary/draw/draw_vertex.h b/src/gallium/auxiliary/draw/draw_vertex.h index 554f4ac3c18..8c3c7befbc7 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.h +++ b/src/gallium/auxiliary/draw/draw_vertex.h @@ -39,7 +39,9 @@ #define DRAW_VERTEX_H +#include "pipe/p_compiler.h" #include "pipe/p_state.h" +#include "util/u_debug.h" /** diff --git a/src/gallium/auxiliary/os/os_memory.h b/src/gallium/auxiliary/os/os_memory.h new file mode 100644 index 00000000000..704aa0762be --- /dev/null +++ b/src/gallium/auxiliary/os/os_memory.h @@ -0,0 +1,84 @@ +/************************************************************************** + * + * Copyright 2010 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 VMWARE 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. + * + **************************************************************************/ + + +/* + * OS memory management abstractions + */ + + +#ifndef _OS_MEMORY_H_ +#define _OS_MEMORY_H_ + + +#include "pipe/p_config.h" +#include "pipe/p_compiler.h" + + +#if defined(PIPE_OS_EMBEDDED) + +#ifdef __cplusplus +extern "C" { +#endif + +void * +os_malloc(size_t size); + +void * +os_calloc(size_t count, size_t size); + +void +os_free(void *ptr); + +void * +os_realloc(void *ptr, size_t old_size, size_t new_size); + +void * +os_malloc_aligned(size_t size, uint alignment); + +void +os_free_aligned(void *ptr); + +#ifdef __cplusplus +} +#endif + +#elif defined(PIPE_OS_WINDOWS) && defined(DEBUG) && !defined(DEBUG_MEMORY_IMPLEMENTATION) + +# include "os_memory_debug.h" + +#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) + +# include "os_memory_win32k.h" + +#else + +# include "os_memory_stdc.h" + +#endif + +#endif /* _OS_MEMORY_H_ */ diff --git a/src/gallium/auxiliary/os/os_memory_aligned.h b/src/gallium/auxiliary/os/os_memory_aligned.h new file mode 100644 index 00000000000..d4528f73196 --- /dev/null +++ b/src/gallium/auxiliary/os/os_memory_aligned.h @@ -0,0 +1,72 @@ +/************************************************************************** + * + * Copyright 2008-2010 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 VMWARE 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. + * + **************************************************************************/ + + +/* + * Memory alignment wrappers. + */ + + +#ifndef _OS_MEMORY_H_ +#error "Must not be included directly. Include os_memory.h instead" +#endif + + +#include "pipe/p_compiler.h" + + +/** + * Return memory on given byte alignment + */ +static INLINE void * +os_malloc_aligned(size_t size, uint alignment) +{ + char *ptr, *buf; + + ptr = (char *) os_malloc(size + alignment + sizeof(void *)); + if (!ptr) + return NULL; + + buf = (char *)(((uintptr_t)ptr + sizeof(void *) + alignment - 1) & ~(alignment - 1)); + *(char **)(buf - sizeof(void *)) = ptr; + + return buf; +} + + +/** + * Free memory returned by align_malloc(). + */ +static INLINE void +os_free_aligned(void *ptr) +{ + if (ptr) { + void **cubbyHole = (void **) ((char *) ptr - sizeof(void *)); + void *realAddr = *cubbyHole; + os_free(realAddr); + } +} diff --git a/src/gallium/auxiliary/os/os_memory_debug.h b/src/gallium/auxiliary/os/os_memory_debug.h new file mode 100644 index 00000000000..c664be9aad5 --- /dev/null +++ b/src/gallium/auxiliary/os/os_memory_debug.h @@ -0,0 +1,83 @@ +/************************************************************************** + * + * Copyright 2008-2010 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 VMWARE 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. + * + **************************************************************************/ + + +/* + * Debugging wrappers for OS memory management abstractions. + */ + + +#ifndef _OS_MEMORY_H_ +#error "Must not be included directly. Include os_memory.h instead" +#endif + + +#include "pipe/p_compiler.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +void * +debug_malloc(const char *file, unsigned line, const char *function, + size_t size); + +void * +debug_calloc(const char *file, unsigned line, const char *function, + size_t count, size_t size ); + +void +debug_free(const char *file, unsigned line, const char *function, + void *ptr); + +void * +debug_realloc(const char *file, unsigned line, const char *function, + void *old_ptr, size_t old_size, size_t new_size ); + + +#ifdef __cplusplus +} +#endif + + +#ifndef DEBUG_MEMORY_IMPLEMENTATION + +#define os_malloc( _size ) \ + debug_malloc( __FILE__, __LINE__, __FUNCTION__, _size ) +#define os_calloc( _count, _size ) \ + debug_calloc(__FILE__, __LINE__, __FUNCTION__, _count, _size ) +#define os_free( _ptr ) \ + debug_free( __FILE__, __LINE__, __FUNCTION__, _ptr ) +#define os_realloc( _ptr, _old_size, _new_size ) \ + debug_realloc( __FILE__, __LINE__, __FUNCTION__, _ptr, _old_size, _new_size ) + +/* TODO: wrap os_malloc_aligned() and os_free_aligned() too */ +#include "os_memory_aligned.h" + +#endif /* !DEBUG_MEMORY_IMPLEMENTATION */ diff --git a/src/gallium/auxiliary/os/os_memory_stdc.h b/src/gallium/auxiliary/os/os_memory_stdc.h new file mode 100644 index 00000000000..806e5363568 --- /dev/null +++ b/src/gallium/auxiliary/os/os_memory_stdc.h @@ -0,0 +1,76 @@ +/************************************************************************** + * + * Copyright 2008-2010 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 VMWARE 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. + * + **************************************************************************/ + + +/* + * OS memory management abstractions for the standard C library. + */ + + +#ifndef _OS_MEMORY_H_ +#error "Must not be included directly. Include os_memory.h instead" +#endif + +#include <stdlib.h> + +#include "pipe/p_compiler.h" + + +#define os_malloc(_size) malloc(_size) +#define os_calloc(_count, _size ) calloc(_count, _size ) +#define os_free(_ptr) free(_ptr) + +#define os_realloc( _old_ptr, _old_size, _new_size) \ + realloc(_old_ptr, _new_size + 0*(_old_size)) + + +#if defined(HAVE_POSIX_MEMALIGN) + +static INLINE void * +os_malloc_aligned(size_t size, size_t alignment) +{ + void *ptr; + alignment = (alignment + sizeof(void*) - 1) & ~(sizeof(void*) - 1); + if(posix_memalign(&ptr, alignment, size) != 0) + return NULL; + return ptr; +} + +#define os_free_aligned(_ptr) free(_ptr) + +#elif defined(PIPE_OS_WINDOWS) + +#include <malloc.h> + +#define os_malloc_aligned(_size, _align) _aligned_malloc(_size, _align) +#define os_free_aligned(_ptr) _aligned_free(_ptr) + +#else + +#include "os_memory_aligned.h" + +#endif diff --git a/src/gallium/auxiliary/os/os_memory_win32k.h b/src/gallium/auxiliary/os/os_memory_win32k.h new file mode 100644 index 00000000000..d56d6908722 --- /dev/null +++ b/src/gallium/auxiliary/os/os_memory_win32k.h @@ -0,0 +1,123 @@ +/************************************************************************** + * + * Copyright 2008-2010 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 VMWARE 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. + * + **************************************************************************/ + + +/* + * OS memory management abstractions for Windows kernel. + */ + + +#ifndef _OS_MEMORY_H_ +#error "Must not be included directly. Include os_memory.h instead" +#endif + + +#include "pipe/p_compiler.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) + +void * __stdcall +EngAllocMem(unsigned long Flags, + unsigned long MemSize, + unsigned long Tag); + +void __stdcall +EngFreeMem(void *Mem); + +#define os_malloc(_size) EngAllocMem(0, _size, 'D3AG') +#define os_calloc(_count, _size) EngAllocMem(1, (_count)*(_size), 'D3AG') +#define _os_free(_ptr) EngFreeMem(_ptr) + +#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) + +void * +ExAllocatePool(unsigned long PoolType, + size_t NumberOfBytes); + +void +ExFreePool(void *P); + +#define os_malloc(_size) ExAllocatePool(0, _size) +#define _os_free(_ptr) ExFreePool(_ptr) + +static INLINE void * +os_calloc(unsigned count, unsigned size) +{ + void *ptr = os_malloc(count * size); + if (ptr) { + memset(ptr, 0, count * size); + } + return ptr; +} + +#else + +#error "Unsupported subsystem" + +#endif + + +static INLINE void +os_free( void *ptr ) +{ + if (ptr) { + _os_free(ptr); + } +} + + +static INLINE void * +os_realloc(void *old_ptr, unsigned old_size, unsigned new_size) +{ + void *new_ptr = NULL; + + if (new_size != 0) { + unsigned copy_size = old_size < new_size ? old_size : new_size; + new_ptr = os_malloc( new_size ); + if (new_ptr && old_ptr && copy_size) { + memcpy(new_ptr, old_ptr, copy_size); + } + } + + os_free(old_ptr); + + return new_ptr; +} + + +#ifdef __cplusplus +} +#endif + + +#include "os_memory_aligned.h" diff --git a/src/gallium/auxiliary/os/os_misc.c b/src/gallium/auxiliary/os/os_misc.c new file mode 100644 index 00000000000..384988017b7 --- /dev/null +++ b/src/gallium/auxiliary/os/os_misc.c @@ -0,0 +1,188 @@ +/************************************************************************** + * + * Copyright 2008-2010 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 VMWARE 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. + * + **************************************************************************/ + + +#include "os_misc.h" + +#include <stdarg.h> + + +#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY + +#include <windows.h> +#include <winddi.h> + +#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) + +#include <stdio.h> +#include <stdlib.h> +#include <windows.h> +#include <types.h> + +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#endif +#include <windows.h> +#include <stdio.h> + +#else + +#include <stdio.h> +#include <stdlib.h> + +#endif + + +#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY +static INLINE void +_EngDebugPrint(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + EngDebugPrint("", (PCHAR)format, ap); + va_end(ap); +} +#endif + + +void +os_log_message(const char *message) +{ +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) + _EngDebugPrint("%s", message); +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) + OutputDebugStringA(message); + if(GetConsoleWindow() && !IsDebuggerPresent()) { + fflush(stdout); + fputs(message, stderr); + fflush(stderr); + } +#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) + wchar_t *wide_format; + long wide_str_len; + /* Format is ascii - needs to be converted to wchar_t for printing */ + wide_str_len = MultiByteToWideChar(CP_ACP, 0, message, -1, NULL, 0); + wide_format = (wchar_t *) malloc((wide_str_len+1) * sizeof(wchar_t)); + if (wide_format) { + MultiByteToWideChar(CP_ACP, 0, message, -1, + wide_format, wide_str_len); + NKDbgPrintfW(wide_format, wide_format); + free(wide_format); + } +#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) + /* TODO */ +#else /* !PIPE_SUBSYSTEM_WINDOWS */ + fflush(stdout); + fputs(message, stderr); +#endif +} + + +#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY +static const char * +find(const char *start, const char *end, char c) +{ + const char *p; + for(p = start; !end || p != end; ++p) { + if(*p == c) + return p; + if(*p < 32) + break; + } + return NULL; +} + +static int +compare(const char *start, const char *end, const char *s) +{ + const char *p, *q; + for(p = start, q = s; p != end && *q != '\0'; ++p, ++q) { + if(*p != *q) + return 0; + } + return p == end && *q == '\0'; +} + +static void +copy(char *dst, const char *start, const char *end, size_t n) +{ + const char *p; + char *q; + for(p = start, q = dst, n = n - 1; p != end && n; ++p, ++q, --n) + *q = *p; + *q = '\0'; +} +#endif + + +const char * +os_get_option(const char *name) +{ +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) + /* EngMapFile creates the file if it does not exists, so it must either be + * disabled on release versions (or put in a less conspicuous place). */ +#ifdef DEBUG + const char *result = NULL; + ULONG_PTR iFile = 0; + const void *pMap = NULL; + const char *sol, *eol, *sep; + static char output[1024]; + + pMap = EngMapFile(L"\\??\\c:\\gallium.cfg", 0, &iFile); + if(pMap) { + sol = (const char *)pMap; + while(1) { + /* TODO: handle LF line endings */ + eol = find(sol, NULL, '\r'); + if(!eol || eol == sol) + break; + sep = find(sol, eol, '='); + if(!sep) + break; + if(compare(sol, sep, name)) { + copy(output, sep + 1, eol, sizeof(output)); + result = output; + break; + } + sol = eol + 2; + } + EngUnmapFile(iFile); + } + return result; +#else + return NULL; +#endif +#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) || defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) + /* TODO: implement */ + return NULL; +#else + return getenv(name); +#endif +} + diff --git a/src/gallium/auxiliary/os/os_misc.h b/src/gallium/auxiliary/os/os_misc.h new file mode 100644 index 00000000000..56e48ca9bee --- /dev/null +++ b/src/gallium/auxiliary/os/os_misc.h @@ -0,0 +1,95 @@ +/************************************************************************** + * + * Copyright 2010 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 VMWARE 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. + * + **************************************************************************/ + + +/* + * Miscellaneous OS services. + */ + + +#ifndef _OS_MISC_H_ +#define _OS_MISC_H_ + + +#include "pipe/p_compiler.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * Trap into the debugger. + */ +#if (defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)) && defined(PIPE_CC_GCC) +# define os_break() __asm("int3") +#elif defined(PIPE_CC_MSVC) +# define os_break() __debugbreak() +#elif defined(PIPE_OS_UNIX) +# include <signal.h> /* for kill() */ +# include <unistd.h> /* for getpid() */ +# define os_break() kill(getpid(), SIGTRAP) +#elif defined(PIPE_OS_EMBEDDED) +void os_break(void); +#else +# define os_break() abort() +#endif + + +/* + * Abort the program. + */ +#if defined(DEBUG) || defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) +# define os_abort() os_break() +#elif defined(PIPE_OS_EMBEDDED) +void os_abort(void); +#else +# define os_abort() abort() +#endif + + +/* + * Output a message. Message should preferably end in a newline. + */ +void +os_log_message(const char *message); + + +/* + * Get an option. Should return NULL if specified option is not set. + */ +const char * +os_get_option(const char *name); + + +#ifdef __cplusplus +} +#endif + + +#endif /* _OS_MISC_H_ */ diff --git a/src/gallium/auxiliary/os/os_thread.h b/src/gallium/auxiliary/os/os_thread.h new file mode 100644 index 00000000000..63108605d3a --- /dev/null +++ b/src/gallium/auxiliary/os/os_thread.h @@ -0,0 +1,279 @@ +/************************************************************************** + * + * Copyright 1999-2006 Brian Paul + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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 + * + * Thread, mutex, condition var and thread-specific data functions. + */ + + +#ifndef OS_THREAD_H_ +#define OS_THREAD_H_ + + +#include "pipe/p_compiler.h" +#include "util/u_debug.h" /* for assert */ + + +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) + +#include <pthread.h> /* POSIX threads headers */ +#include <stdio.h> /* for perror() */ + +#define PIPE_THREAD_HAVE_CONDVAR + +typedef pthread_t pipe_thread; + +#define PIPE_THREAD_ROUTINE( name, param ) \ + void *name( void *param ) + +static INLINE pipe_thread pipe_thread_create( void *(* routine)( void *), void *param ) +{ + pipe_thread thread; + if (pthread_create( &thread, NULL, routine, param )) + return 0; + return thread; +} + +static INLINE int pipe_thread_wait( pipe_thread thread ) +{ + return pthread_join( thread, NULL ); +} + +static INLINE int pipe_thread_destroy( pipe_thread thread ) +{ + return pthread_detach( thread ); +} + +typedef pthread_mutex_t pipe_mutex; +typedef pthread_cond_t pipe_condvar; + +#define pipe_static_mutex(mutex) \ + static pipe_mutex mutex = PTHREAD_MUTEX_INITIALIZER + +#define pipe_mutex_init(mutex) \ + (void) pthread_mutex_init(&(mutex), NULL) + +#define pipe_mutex_destroy(mutex) \ + pthread_mutex_destroy(&(mutex)) + +#define pipe_mutex_lock(mutex) \ + (void) pthread_mutex_lock(&(mutex)) + +#define pipe_mutex_unlock(mutex) \ + (void) pthread_mutex_unlock(&(mutex)) + +#define pipe_static_condvar(mutex) \ + static pipe_condvar mutex = PTHREAD_COND_INITIALIZER + +#define pipe_condvar_init(cond) \ + pthread_cond_init(&(cond), NULL) + +#define pipe_condvar_destroy(cond) \ + pthread_cond_destroy(&(cond)) + +#define pipe_condvar_wait(cond, mutex) \ + pthread_cond_wait(&(cond), &(mutex)) + +#define pipe_condvar_signal(cond) \ + pthread_cond_signal(&(cond)) + +#define pipe_condvar_broadcast(cond) \ + pthread_cond_broadcast(&(cond)) + + +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) + +#include <windows.h> + +typedef HANDLE pipe_thread; + +#define PIPE_THREAD_ROUTINE( name, param ) \ + void * WINAPI name( void *param ) + +static INLINE pipe_thread pipe_thread_create( void *(WINAPI * routine)( void *), void *param ) +{ + DWORD id; + return CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE) routine, param, 0, &id ); +} + +static INLINE int pipe_thread_wait( pipe_thread thread ) +{ + if (WaitForSingleObject( thread, INFINITE ) == WAIT_OBJECT_0) + return 0; + return -1; +} + +static INLINE int pipe_thread_destroy( pipe_thread thread ) +{ + if (CloseHandle( thread )) + return 0; + return -1; +} + +typedef CRITICAL_SECTION pipe_mutex; + +#define pipe_static_mutex(mutex) \ + /*static*/ pipe_mutex mutex = {0,0,0,0,0,0} + +#define pipe_mutex_init(mutex) \ + InitializeCriticalSection(&mutex) + +#define pipe_mutex_destroy(mutex) \ + DeleteCriticalSection(&mutex) + +#define pipe_mutex_lock(mutex) \ + EnterCriticalSection(&mutex) + +#define pipe_mutex_unlock(mutex) \ + LeaveCriticalSection(&mutex) + +/* XXX: dummy definitions, make it compile */ + +typedef unsigned pipe_condvar; + +#define pipe_condvar_init(condvar) \ + (void) condvar + +#define pipe_condvar_broadcast(condvar) \ + (void) condvar + +#else + +/** Dummy definitions */ + +typedef unsigned pipe_thread; +typedef unsigned pipe_mutex; +typedef unsigned pipe_condvar; + +#define pipe_static_mutex(mutex) \ + static pipe_mutex mutex = 0 + +#define pipe_mutex_init(mutex) \ + (void) mutex + +#define pipe_mutex_destroy(mutex) \ + (void) mutex + +#define pipe_mutex_lock(mutex) \ + (void) mutex + +#define pipe_mutex_unlock(mutex) \ + (void) mutex + +#define pipe_static_condvar(condvar) \ + static unsigned condvar = 0 + +#define pipe_condvar_init(condvar) \ + (void) condvar + +#define pipe_condvar_destroy(condvar) \ + (void) condvar + +#define pipe_condvar_wait(condvar, mutex) \ + (void) condvar + +#define pipe_condvar_signal(condvar) \ + (void) condvar + +#define pipe_condvar_broadcast(condvar) \ + (void) condvar + + +#endif /* PIPE_OS_? */ + + + +/* + * Thread-specific data. + */ + +typedef struct { +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) + pthread_key_t key; +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) + DWORD key; +#endif + int initMagic; +} pipe_tsd; + + +#define PIPE_TSD_INIT_MAGIC 0xff8adc98 + + +static INLINE void +pipe_tsd_init(pipe_tsd *tsd) +{ +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) + if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) { + perror("pthread_key_create(): failed to allocate key for thread specific data"); + exit(-1); + } +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) + assert(0); +#endif + tsd->initMagic = PIPE_TSD_INIT_MAGIC; +} + +static INLINE void * +pipe_tsd_get(pipe_tsd *tsd) +{ + if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) { + pipe_tsd_init(tsd); + } +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) + return pthread_getspecific(tsd->key); +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) + assert(0); + return NULL; +#else + assert(0); + return NULL; +#endif +} + +static INLINE void +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) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) + if (pthread_setspecific(tsd->key, value) != 0) { + perror("pthread_set_specific() failed"); + exit(-1); + } +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) + assert(0); +#else + assert(0); +#endif +} + + + +#endif /* OS_THREAD_H_ */ diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h index eb7e84be848..34b1b77df40 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h @@ -46,6 +46,7 @@ #include "pipe/p_compiler.h" #include "util/u_debug.h" +#include "util/u_inlines.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index ba087ac0f34..95eb5f65635 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -44,7 +44,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_defines.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_memory.h" #include "util/u_double_list.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c index 7b34c8e3578..c1498318dfb 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c @@ -36,7 +36,7 @@ #include "pipe/p_compiler.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_memory.h" #include "util/u_double_list.h" #include "util/u_time.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c index 8f74180a111..93f8960641f 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c @@ -35,7 +35,7 @@ #include "pipe/p_compiler.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_double_list.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c index 6400fc5b0a3..63195715d68 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c @@ -35,7 +35,7 @@ #include "pipe/p_defines.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_memory.h" #include "util/u_double_list.h" #include "util/u_mm.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c index 7fd65ed2261..fea234ae8c7 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c @@ -37,7 +37,7 @@ #include "pipe/p_compiler.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "pipe/p_defines.h" #include "util/u_memory.h" #include "util/u_double_list.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c index d21910d0bf0..c445cb578b0 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c @@ -38,7 +38,7 @@ #include "pipe/p_compiler.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "pipe/p_defines.h" #include "util/u_memory.h" #include "util/u_double_list.h" diff --git a/src/gallium/auxiliary/rtasm/rtasm_execmem.c b/src/gallium/auxiliary/rtasm/rtasm_execmem.c index ffed768f979..65d5ce795be 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_execmem.c +++ b/src/gallium/auxiliary/rtasm/rtasm_execmem.c @@ -32,7 +32,7 @@ #include "pipe/p_compiler.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_memory.h" #include "rtasm_execmem.h" @@ -58,7 +58,7 @@ #include <unistd.h> #include <sys/mman.h> -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_mm.h" #define EXEC_HEAP_SIZE (10*1024*1024) diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c index 96be353e264..f918151daaa 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c @@ -29,7 +29,7 @@ #include "util/u_memory.h" #include "util/u_prim.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "tgsi_text.h" #include "tgsi_build.h" #include "tgsi_info.h" diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c index e31ae8b4550..27960bac221 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c @@ -33,6 +33,7 @@ #include "tgsi/tgsi_info.h" #include "tgsi/tgsi_dump.h" #include "tgsi/tgsi_sanity.h" +#include "util/u_debug.h" #include "util/u_memory.h" #include "util/u_math.h" diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h index d6e8e5d553c..6be66d0694b 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h @@ -30,6 +30,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_shader_tokens.h" +#include "util/u_debug.h" #ifdef __cplusplus extern "C" { diff --git a/src/gallium/auxiliary/util/u_atomic.h b/src/gallium/auxiliary/util/u_atomic.h new file mode 100644 index 00000000000..1c042c3ede9 --- /dev/null +++ b/src/gallium/auxiliary/util/u_atomic.h @@ -0,0 +1,247 @@ +/** + * Many similar implementations exist. See for example libwsbm + * or the linux kernel include/atomic.h + * + * No copyright claimed on this file. + * + */ + +#ifndef U_ATOMIC_H +#define U_ATOMIC_H + +#include "pipe/p_compiler.h" +#include "pipe/p_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Favor OS-provided implementations. + * + * Where no OS-provided implementation is available, fall back to + * locally coded assembly, compiler intrinsic or ultimately a + * mutex-based implementation. + */ +#if (defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || \ + defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)) +#define PIPE_ATOMIC_OS_UNLOCKED +#elif defined(PIPE_CC_MSVC) +#define PIPE_ATOMIC_MSVC_INTRINSIC +#elif (defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)) +#define PIPE_ATOMIC_ASM_MSVC_X86 +#elif (defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86)) +#define PIPE_ATOMIC_ASM_GCC_X86 +#elif defined(PIPE_CC_GCC) +#define PIPE_ATOMIC_GCC_INTRINSIC +#else +#error "Unsupported platform" +#endif + + + +#if defined(PIPE_ATOMIC_ASM_GCC_X86) + +#define PIPE_ATOMIC "GCC x86 assembly" + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) + + +static INLINE boolean +p_atomic_dec_zero(int32_t *v) +{ + unsigned char c; + + __asm__ __volatile__("lock; decl %0; sete %1":"+m"(*v), "=qm"(c) + ::"memory"); + + return c != 0; +} + +static INLINE void +p_atomic_inc(int32_t *v) +{ + __asm__ __volatile__("lock; incl %0":"+m"(*v)); +} + +static INLINE void +p_atomic_dec(int32_t *v) +{ + __asm__ __volatile__("lock; decl %0":"+m"(*v)); +} + +static INLINE int32_t +p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new) +{ + return __sync_val_compare_and_swap(v, old, _new); +} +#endif + + + +/* Implementation using GCC-provided synchronization intrinsics + */ +#if defined(PIPE_ATOMIC_GCC_INTRINSIC) + +#define PIPE_ATOMIC "GCC Sync Intrinsics" + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) + + +static INLINE boolean +p_atomic_dec_zero(int32_t *v) +{ + return (__sync_sub_and_fetch(v, 1) == 0); +} + +static INLINE void +p_atomic_inc(int32_t *v) +{ + (void) __sync_add_and_fetch(v, 1); +} + +static INLINE void +p_atomic_dec(int32_t *v) +{ + (void) __sync_sub_and_fetch(v, 1); +} + +static INLINE int32_t +p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new) +{ + return __sync_val_compare_and_swap(v, old, _new); +} +#endif + + + +/* Unlocked version for single threaded environments, such as some + * windows kernel modules. + */ +#if defined(PIPE_ATOMIC_OS_UNLOCKED) + +#define PIPE_ATOMIC "Unlocked" + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) +#define p_atomic_dec_zero(_v) ((boolean) --(*(_v))) +#define p_atomic_inc(_v) ((void) (*(_v))++) +#define p_atomic_dec(_v) ((void) (*(_v))--) +#define p_atomic_cmpxchg(_v, old, _new) (*(_v) == old ? *(_v) = (_new) : *(_v)) + +#endif + + +/* Locally coded assembly for MSVC on x86: + */ +#if defined(PIPE_ATOMIC_ASM_MSVC_X86) + +#define PIPE_ATOMIC "MSVC x86 assembly" + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) + +static INLINE boolean +p_atomic_dec_zero(int32_t *v) +{ + unsigned char c; + + __asm { + mov eax, [v] + lock dec dword ptr [eax] + sete byte ptr [c] + } + + return c != 0; +} + +static INLINE void +p_atomic_inc(int32_t *v) +{ + __asm { + mov eax, [v] + lock inc dword ptr [eax] + } +} + +static INLINE void +p_atomic_dec(int32_t *v) +{ + __asm { + mov eax, [v] + lock dec dword ptr [eax] + } +} + +static INLINE int32_t +p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new) +{ + int32_t orig; + + __asm { + mov ecx, [v] + mov eax, [old] + mov edx, [_new] + lock cmpxchg [ecx], edx + mov [orig], eax + } + + return orig; +} +#endif + + +#if defined(PIPE_ATOMIC_MSVC_INTRINSIC) + +#define PIPE_ATOMIC "MSVC Intrinsics" + +#include <intrin.h> + +#pragma intrinsic(_InterlockedIncrement) +#pragma intrinsic(_InterlockedDecrement) +#pragma intrinsic(_InterlockedCompareExchange) + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) + +static INLINE boolean +p_atomic_dec_zero(int32_t *v) +{ + return _InterlockedDecrement(v) == 0; +} + +static INLINE void +p_atomic_inc(int32_t *v) +{ + _InterlockedIncrement(v); +} + +static INLINE void +p_atomic_dec(int32_t *v) +{ + _InterlockedDecrement(v); +} + +static INLINE int32_t +p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new) +{ + return _InterlockedCompareExchange(v, _new, old); +} + +#endif + + + +#ifndef PIPE_ATOMIC +#error "No pipe_atomic implementation selected" +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif /* U_ATOMIC_H */ diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index eb63bec7b50..f0bc58a558f 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -36,7 +36,7 @@ #include "pipe/p_context.h" #include "util/u_debug.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_shader_tokens.h" #include "pipe/p_state.h" diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 935e11c5d85..f3b4491d175 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -34,7 +34,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_shader_tokens.h" #include "pipe/p_state.h" diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c index 9b4e6ca2a73..1e92d69b9ad 100644 --- a/src/gallium/auxiliary/util/u_debug.c +++ b/src/gallium/auxiliary/util/u_debug.c @@ -29,41 +29,11 @@ #include "pipe/p_config.h" -#include <stdarg.h> - - -#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY - -#include <windows.h> -#include <winddi.h> - -#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) - -#include <stdio.h> -#include <stdlib.h> -#include <windows.h> -#include <types.h> - -#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -#endif -#include <windows.h> -#include <stdio.h> - -#else - -#include <stdio.h> -#include <stdlib.h> - -#endif - -#include "pipe/p_compiler.h" +#include "pipe/p_compiler.h" #include "util/u_debug.h" #include "pipe/p_format.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_memory.h" #include "util/u_string.h" @@ -73,81 +43,16 @@ #include "util/u_prim.h" -#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY -static INLINE void -_EngDebugPrint(const char *format, ...) -{ - va_list ap; - va_start(ap, format); - EngDebugPrint("", (PCHAR)format, ap); - va_end(ap); -} -#endif - - void _debug_vprintf(const char *format, va_list ap) { -#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) - /* EngDebugPrint does not handle float point arguments, so we need to use - * our own vsnprintf implementation. It is also very slow, so buffer until - * we find a newline. */ - static char buf[512] = {'\0'}; - size_t len = strlen(buf); - int ret = util_vsnprintf(buf + len, sizeof(buf) - len, format, ap); - if(ret > (int)(sizeof(buf) - len - 1) || util_strchr(buf + len, '\n')) { - _EngDebugPrint("%s", buf); - buf[0] = '\0'; - } -#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) - /* OutputDebugStringA can be very slow, so buffer until we find a newline. */ + /* We buffer until we find a newline. */ static char buf[4096] = {'\0'}; size_t len = strlen(buf); int ret = util_vsnprintf(buf + len, sizeof(buf) - len, format, ap); if(ret > (int)(sizeof(buf) - len - 1) || util_strchr(buf + len, '\n')) { - OutputDebugStringA(buf); + os_log_message(buf); buf[0] = '\0'; } - - if(GetConsoleWindow() && !IsDebuggerPresent()) { - fflush(stdout); - vfprintf(stderr, format, ap); - fflush(stderr); - } - -#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) - wchar_t *wide_format; - long wide_str_len; - char buf[512]; - int ret; -#if (_WIN32_WCE < 600) - ret = vsprintf(buf, format, ap); - if(ret < 0){ - sprintf(buf, "Cant handle debug print!"); - ret = 25; - } -#else - ret = vsprintf_s(buf, 512, format, ap); - if(ret < 0){ - sprintf_s(buf, 512, "Cant handle debug print!"); - ret = 25; - } -#endif - buf[ret] = '\0'; - /* Format is ascii - needs to be converted to wchar_t for printing */ - wide_str_len = MultiByteToWideChar(CP_ACP, 0, (const char *) buf, -1, NULL, 0); - wide_format = (wchar_t *) malloc((wide_str_len+1) * sizeof(wchar_t)); - if (wide_format) { - MultiByteToWideChar(CP_ACP, 0, (const char *) buf, -1, - wide_format, wide_str_len); - NKDbgPrintfW(wide_format, wide_format); - free(wide_format); - } -#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) - /* TODO */ -#else /* !PIPE_SUBSYSTEM_WINDOWS */ - fflush(stdout); - vfprintf(stderr, format, ap); -#endif } @@ -169,108 +74,12 @@ void debug_print_blob( const char *name, #endif -#ifndef debug_break -void debug_break(void) -{ -#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) - DebugBreak(); -#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) - EngDebugBreak(); -#else - abort(); -#endif -} -#endif - - -#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY -static const char * -find(const char *start, const char *end, char c) -{ - const char *p; - for(p = start; !end || p != end; ++p) { - if(*p == c) - return p; - if(*p < 32) - break; - } - return NULL; -} - -static int -compare(const char *start, const char *end, const char *s) -{ - const char *p, *q; - for(p = start, q = s; p != end && *q != '\0'; ++p, ++q) { - if(*p != *q) - return 0; - } - return p == end && *q == '\0'; -} - -static void -copy(char *dst, const char *start, const char *end, size_t n) -{ - const char *p; - char *q; - for(p = start, q = dst, n = n - 1; p != end && n; ++p, ++q, --n) - *q = *p; - *q = '\0'; -} -#endif - - -static INLINE const char * -_debug_get_option(const char *name) -{ -#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) - /* EngMapFile creates the file if it does not exists, so it must either be - * disabled on release versions (or put in a less conspicuous place). */ -#ifdef DEBUG - const char *result = NULL; - ULONG_PTR iFile = 0; - const void *pMap = NULL; - const char *sol, *eol, *sep; - static char output[1024]; - - pMap = EngMapFile(L"\\??\\c:\\gallium.cfg", 0, &iFile); - if(pMap) { - sol = (const char *)pMap; - while(1) { - /* TODO: handle LF line endings */ - eol = find(sol, NULL, '\r'); - if(!eol || eol == sol) - break; - sep = find(sol, eol, '='); - if(!sep) - break; - if(compare(sol, sep, name)) { - copy(output, sep + 1, eol, sizeof(output)); - result = output; - break; - } - sol = eol + 2; - } - EngUnmapFile(iFile); - } - return result; -#else - return NULL; -#endif -#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) || defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) - /* TODO: implement */ - return NULL; -#else - return getenv(name); -#endif -} - const char * debug_get_option(const char *name, const char *dfault) { const char *result; - result = _debug_get_option(name); + result = os_get_option(name); if(!result) result = dfault; @@ -282,7 +91,7 @@ debug_get_option(const char *name, const char *dfault) boolean debug_get_bool_option(const char *name, boolean dfault) { - const char *str = _debug_get_option(name); + const char *str = os_get_option(name); boolean result; if(str == NULL) @@ -312,7 +121,7 @@ debug_get_num_option(const char *name, long dfault) long result; const char *str; - str = _debug_get_option(name); + str = os_get_option(name); if(!str) result = dfault; else { @@ -348,7 +157,7 @@ debug_get_flags_option(const char *name, unsigned long result; const char *str; - str = _debug_get_option(name); + str = os_get_option(name); if(!str) result = dfault; else if (!util_strcmp(str, "help")) { @@ -389,7 +198,7 @@ void _debug_assert_fail(const char *expr, #else if (debug_get_bool_option("GALLIUM_ABORT_ON_ASSERT", TRUE)) #endif - debug_break(); + os_abort(); else _debug_printf("continuing...\n"); } diff --git a/src/gallium/auxiliary/util/u_debug.h b/src/gallium/auxiliary/util/u_debug.h index facc30a5534..eadc08fe2a0 100644 --- a/src/gallium/auxiliary/util/u_debug.h +++ b/src/gallium/auxiliary/util/u_debug.h @@ -39,9 +39,7 @@ #define U_DEBUG_H_ -#include <stdarg.h> - -#include "pipe/p_compiler.h" +#include "os/os_misc.h" #ifdef __cplusplus @@ -49,22 +47,6 @@ 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 - #if defined(__GNUC__) #define _util_printf_format(fmt, list) __attribute__ ((format (printf, fmt, list))) #else @@ -155,13 +137,7 @@ void debug_print_format(const char *msg, unsigned fmt ); * Hard-coded breakpoint. */ #ifdef DEBUG -#if (defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)) && defined(PIPE_CC_GCC) -#define debug_break() __asm("int3") -#elif defined(PIPE_CC_MSVC) -#define debug_break() __debugbreak() -#else -void debug_break(void); -#endif +#define debug_break() os_break() #else /* !DEBUG */ #define debug_break() ((void)0) #endif /* !DEBUG */ @@ -328,22 +304,6 @@ debug_get_flags_option(const char *name, 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); diff --git a/src/gallium/auxiliary/util/u_debug_memory.c b/src/gallium/auxiliary/util/u_debug_memory.c index d6484f4ad51..f1baa62f894 100644 --- a/src/gallium/auxiliary/util/u_debug_memory.c +++ b/src/gallium/auxiliary/util/u_debug_memory.c @@ -34,15 +34,10 @@ #include "pipe/p_config.h" -#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) -#include <windows.h> -#include <winddi.h> -#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) -#include <wdm.h> -#else -#include <stdio.h> -#include <stdlib.h> -#endif +#define DEBUG_MEMORY_IMPLEMENTATION + +#include "os/os_memory.h" +#include "os/os_memory_debug.h" #include "util/u_debug.h" #include "util/u_debug_stack.h" @@ -53,18 +48,6 @@ #define DEBUG_MEMORY_STACK 0 /* XXX: disabled until we have symbol lookup */ -#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) && !defined(WINCE) -#define real_malloc(_size) EngAllocMem(0, _size, 'D3AG') -#define real_free(_ptr) EngFreeMem(_ptr) -#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) -#define real_malloc(_size) ExAllocatePool(0, _size) -#define real_free(_ptr) ExFreePool(_ptr) -#else -#define real_malloc(_size) malloc(_size) -#define real_free(_ptr) free(_ptr) -#endif - - struct debug_memory_header { struct list_head head; @@ -127,7 +110,7 @@ debug_malloc(const char *file, unsigned line, const char *function, struct debug_memory_header *hdr; struct debug_memory_footer *ftr; - hdr = real_malloc(sizeof(*hdr) + size + sizeof(*ftr)); + hdr = os_malloc(sizeof(*hdr) + size + sizeof(*ftr)); if(!hdr) { debug_printf("%s:%u:%s: out of memory when trying to allocate %lu bytes\n", file, line, function, @@ -185,7 +168,7 @@ debug_free(const char *file, unsigned line, const char *function, hdr->magic = 0; ftr->magic = 0; - real_free(hdr); + os_free(hdr); } void * @@ -232,7 +215,7 @@ debug_realloc(const char *file, unsigned line, const char *function, } /* alloc new */ - new_hdr = real_malloc(sizeof(*new_hdr) + new_size + sizeof(*new_ftr)); + new_hdr = os_malloc(sizeof(*new_hdr) + new_size + sizeof(*new_ftr)); if(!new_hdr) { debug_printf("%s:%u:%s: out of memory when trying to allocate %lu bytes\n", file, line, function, @@ -258,7 +241,7 @@ debug_realloc(const char *file, unsigned line, const char *function, /* free old */ old_hdr->magic = 0; old_ftr->magic = 0; - real_free(old_hdr); + os_free(old_hdr); return new_ptr; } diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c index e2e23c3cdd8..14506e84519 100644 --- a/src/gallium/auxiliary/util/u_draw_quad.c +++ b/src/gallium/auxiliary/util/u_draw_quad.c @@ -28,7 +28,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_draw_quad.h" diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h index a558923b2ed..4323bc881bd 100644 --- a/src/gallium/auxiliary/util/u_format.h +++ b/src/gallium/auxiliary/util/u_format.h @@ -31,6 +31,7 @@ #include "pipe/p_format.h" +#include "util/u_debug.h" #ifdef __cplusplus extern "C" { diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 8611231ed70..4e358d3938c 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -37,7 +37,7 @@ #include "pipe/p_context.h" #include "util/u_debug.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_shader_tokens.h" #include "pipe/p_state.h" diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h new file mode 100644 index 00000000000..e95d58ea863 --- /dev/null +++ b/src/gallium/auxiliary/util/u_inlines.h @@ -0,0 +1,304 @@ +/************************************************************************** + * + * Copyright 2007 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. + * + **************************************************************************/ + +#ifndef U_INLINES_H +#define U_INLINES_H + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_screen.h" +#include "util/u_debug.h" +#include "util/u_atomic.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * Reference counting helper functions. + */ + + +static INLINE void +pipe_reference_init(struct pipe_reference *reference, unsigned count) +{ + p_atomic_set(&reference->count, count); +} + +static INLINE boolean +pipe_is_referenced(struct pipe_reference *reference) +{ + return p_atomic_read(&reference->count) != 0; +} + +/** + * Update reference counting. + * The old thing pointed to, if any, will be unreferenced. + * Both 'ptr' and 'reference' may be NULL. + * \return TRUE if the object's refcount hits zero and should be destroyed. + */ +static INLINE boolean +pipe_reference(struct pipe_reference *ptr, struct pipe_reference *reference) +{ + boolean destroy = FALSE; + + if(ptr != reference) { + /* bump the reference.count first */ + if (reference) { + assert(pipe_is_referenced(reference)); + p_atomic_inc(&reference->count); + } + + if (ptr) { + assert(pipe_is_referenced(ptr)); + if (p_atomic_dec_zero(&ptr->count)) { + destroy = TRUE; + } + } + } + + return destroy; +} + +static INLINE void +pipe_buffer_reference(struct pipe_buffer **ptr, struct pipe_buffer *buf) +{ + struct pipe_buffer *old_buf = *ptr; + + if (pipe_reference(&(*ptr)->reference, &buf->reference)) + old_buf->screen->buffer_destroy(old_buf); + *ptr = buf; +} + +static INLINE void +pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf) +{ + struct pipe_surface *old_surf = *ptr; + + if (pipe_reference(&(*ptr)->reference, &surf->reference)) + old_surf->texture->screen->tex_surface_destroy(old_surf); + *ptr = surf; +} + +static INLINE void +pipe_texture_reference(struct pipe_texture **ptr, struct pipe_texture *tex) +{ + struct pipe_texture *old_tex = *ptr; + + if (pipe_reference(&(*ptr)->reference, &tex->reference)) + old_tex->screen->texture_destroy(old_tex); + *ptr = tex; +} + + +/* + * Convenience wrappers for screen buffer functions. + */ + +static INLINE struct pipe_buffer * +pipe_buffer_create( struct pipe_screen *screen, + unsigned alignment, unsigned usage, unsigned size ) +{ + return screen->buffer_create(screen, alignment, usage, size); +} + +static INLINE struct pipe_buffer * +pipe_user_buffer_create( struct pipe_screen *screen, void *ptr, unsigned size ) +{ + return screen->user_buffer_create(screen, ptr, size); +} + +static INLINE void * +pipe_buffer_map(struct pipe_screen *screen, + struct pipe_buffer *buf, + unsigned 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 +pipe_buffer_unmap(struct pipe_screen *screen, + struct pipe_buffer *buf) +{ + screen->buffer_unmap(screen, buf); +} + +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_flush_mapped_range(struct pipe_screen *screen, + struct pipe_buffer *buf, + unsigned offset, + unsigned length) +{ + 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); +} + +static INLINE void +pipe_buffer_write(struct pipe_screen *screen, + struct pipe_buffer *buf, + unsigned offset, unsigned size, + const void *data) +{ + void *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 | + PIPE_BUFFER_USAGE_FLUSH_EXPLICIT | + PIPE_BUFFER_USAGE_DISCARD); + assert(map); + if(map) { + memcpy((uint8_t *)map + offset, data, size); + pipe_buffer_flush_mapped_range(screen, buf, offset, size); + pipe_buffer_unmap(screen, buf); + } +} + +/** + * Special case for writing non-overlapping ranges. + * + * We can avoid GPU/CPU synchronization when writing range that has never + * been written before. + */ +static INLINE void +pipe_buffer_write_nooverlap(struct pipe_screen *screen, + struct pipe_buffer *buf, + unsigned offset, unsigned size, + const void *data) +{ + void *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 | + PIPE_BUFFER_USAGE_FLUSH_EXPLICIT | + PIPE_BUFFER_USAGE_DISCARD | + PIPE_BUFFER_USAGE_UNSYNCHRONIZED); + assert(map); + if(map) { + memcpy((uint8_t *)map + offset, data, size); + pipe_buffer_flush_mapped_range(screen, buf, offset, size); + pipe_buffer_unmap(screen, buf); + } +} + +static INLINE void +pipe_buffer_read(struct pipe_screen *screen, + struct pipe_buffer *buf, + unsigned offset, unsigned size, + void *data) +{ + void *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, (const uint8_t *)map + offset, size); + pipe_buffer_unmap(screen, buf); + } +} + +static INLINE void * +pipe_transfer_map( struct pipe_transfer *transf ) +{ + struct pipe_screen *screen = transf->texture->screen; + return screen->transfer_map(screen, transf); +} + +static INLINE void +pipe_transfer_unmap( struct pipe_transfer *transf ) +{ + struct pipe_screen *screen = transf->texture->screen; + screen->transfer_unmap(screen, transf); +} + +static INLINE void +pipe_transfer_destroy( struct pipe_transfer *transf ) +{ + struct pipe_screen *screen = transf->texture->screen; + screen->tex_transfer_destroy(transf); +} + +static INLINE unsigned +pipe_transfer_buffer_flags( struct pipe_transfer *transf ) +{ + switch (transf->usage & PIPE_TRANSFER_READ_WRITE) { + case PIPE_TRANSFER_READ_WRITE: + return PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE; + case PIPE_TRANSFER_READ: + return PIPE_BUFFER_USAGE_CPU_READ; + case PIPE_TRANSFER_WRITE: + return PIPE_BUFFER_USAGE_CPU_WRITE; + default: + debug_assert(0); + return 0; + } +} + +#ifdef __cplusplus +} +#endif + +#endif /* U_INLINES_H */ diff --git a/src/gallium/auxiliary/util/u_memory.h b/src/gallium/auxiliary/util/u_memory.h index c3f8c918338..a2fc5973565 100644 --- a/src/gallium/auxiliary/util/u_memory.h +++ b/src/gallium/auxiliary/util/u_memory.h @@ -26,7 +26,7 @@ **************************************************************************/ -/** +/* * Memory functions */ @@ -37,6 +37,7 @@ #include "util/u_pointer.h" #include "util/u_debug.h" +#include "os/os_memory.h" #ifdef __cplusplus @@ -44,114 +45,13 @@ extern "C" { #endif -/* Define ENOMEM for WINCE */ -#if (_WIN32_WCE < 600) -#ifndef ENOMEM -#define ENOMEM 12 -#endif -#endif - - -#if defined(PIPE_OS_WINDOWS) && defined(DEBUG) - -/* memory debugging */ - -#include "util/u_debug.h" - -#define MALLOC( _size ) \ - debug_malloc( __FILE__, __LINE__, __FUNCTION__, _size ) -#define CALLOC( _count, _size ) \ - debug_calloc(__FILE__, __LINE__, __FUNCTION__, _count, _size ) -#define FREE( _ptr ) \ - debug_free( __FILE__, __LINE__, __FUNCTION__, _ptr ) -#define REALLOC( _ptr, _old_size, _size ) \ - debug_realloc( __FILE__, __LINE__, __FUNCTION__, _ptr, _old_size, _size ) - -#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) - -void * __stdcall -EngAllocMem( - unsigned long Flags, - unsigned long MemSize, - unsigned long Tag ); - -void __stdcall -EngFreeMem( - void *Mem ); - -#define MALLOC( _size ) EngAllocMem( 0, _size, 'D3AG' ) -#define _FREE( _ptr ) EngFreeMem( _ptr ) - -#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) - -void * -ExAllocatePool( - unsigned long PoolType, - size_t NumberOfBytes); - -void -ExFreePool(void *P); - -#define MALLOC(_size) ExAllocatePool(0, _size) -#define _FREE(_ptr) ExFreePool(_ptr) - -#else - -#define MALLOC( SIZE ) malloc( SIZE ) -#define CALLOC( COUNT, SIZE ) calloc( COUNT, SIZE ) -#define FREE( PTR ) free( PTR ) - -static INLINE void * -_REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) -{ - (void) old_size; - return realloc(old_ptr, new_size); -} -#define REALLOC( a, b, c ) _REALLOC( a, b, c ) -#endif - - -#ifndef CALLOC -static INLINE void * -CALLOC( unsigned count, unsigned size ) -{ - void *ptr = MALLOC( count * size ); - if( ptr ) { - memset( ptr, 0, count * size ); - } - return ptr; -} -#endif /* !CALLOC */ +#define MALLOC(_size) os_malloc(_size) -#ifndef FREE -static INLINE void -FREE( void *ptr ) -{ - if( ptr ) { - _FREE( ptr ); - } -} -#endif /* !FREE */ +#define CALLOC(_count, _size) os_calloc(_count, _size) -#ifndef REALLOC -static INLINE void * -REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) -{ - void *new_ptr = NULL; - - if (new_size != 0) { - unsigned copy_size = old_size < new_size ? old_size : new_size; - new_ptr = MALLOC( new_size ); - if (new_ptr && old_ptr && copy_size) { - memcpy( new_ptr, old_ptr, copy_size ); - } - } - - FREE( old_ptr ); - return new_ptr; -} -#endif /* !REALLOC */ +#define FREE(_ptr ) os_free(_ptr) +#define REALLOC(_ptr, _old_size, _size) os_realloc(_ptr, _old_size, _size) #define MALLOC_STRUCT(T) (struct T *) MALLOC(sizeof(struct T)) @@ -160,50 +60,8 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) #define CALLOC_VARIANT_LENGTH_STRUCT(T,more_size) ((struct T *) CALLOC(1, sizeof(struct T) + more_size)) -/** - * Return memory on given byte alignment - */ -static INLINE void * -align_malloc(size_t bytes, uint alignment) -{ -#if defined(HAVE_POSIX_MEMALIGN) - void *mem; - alignment = (alignment + (uint)sizeof(void*) - 1) & ~((uint)sizeof(void*) - 1); - if(posix_memalign(& mem, alignment, bytes) != 0) - return NULL; - return mem; -#else - char *ptr, *buf; - - assert( alignment > 0 ); - - ptr = (char *) MALLOC(bytes + alignment + sizeof(void *)); - if (!ptr) - return NULL; - - buf = (char *) align_pointer( ptr + sizeof(void *), alignment ); - *(char **)(buf - sizeof(void *)) = ptr; - - return buf; -#endif /* defined(HAVE_POSIX_MEMALIGN) */ -} - -/** - * Free memory returned by align_malloc(). - */ -static INLINE void -align_free(void *ptr) -{ -#if defined(HAVE_POSIX_MEMALIGN) - FREE(ptr); -#else - if (ptr) { - void **cubbyHole = (void **) ((char *) ptr - sizeof(void *)); - void *realAddr = *cubbyHole; - FREE(realAddr); - } -#endif /* defined(HAVE_POSIX_MEMALIGN) */ -} +#define align_malloc(_size, _alignment) os_malloc_aligned(_size, _alignment) +#define align_free(_ptr) os_free_aligned(_ptr) /** diff --git a/src/gallium/auxiliary/util/u_prim.h b/src/gallium/auxiliary/util/u_prim.h index 10a874f3416..799e8f168f1 100644 --- a/src/gallium/auxiliary/util/u_prim.h +++ b/src/gallium/auxiliary/util/u_prim.h @@ -35,6 +35,7 @@ extern "C" { #endif #include "pipe/p_defines.h" +#include "util/u_debug.h" static INLINE boolean u_validate_pipe_prim( unsigned pipe_prim, unsigned nr ) { diff --git a/src/gallium/auxiliary/util/u_ringbuffer.c b/src/gallium/auxiliary/util/u_ringbuffer.c index 3f43a19e018..95d45ebb71f 100644 --- a/src/gallium/auxiliary/util/u_ringbuffer.c +++ b/src/gallium/auxiliary/util/u_ringbuffer.c @@ -1,5 +1,5 @@ -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "pipe/p_defines.h" #include "util/u_ringbuffer.h" #include "util/u_math.h" diff --git a/src/gallium/auxiliary/util/u_simple_screen.c b/src/gallium/auxiliary/util/u_simple_screen.c index 52382990155..53f3c16dbcc 100644 --- a/src/gallium/auxiliary/util/u_simple_screen.c +++ b/src/gallium/auxiliary/util/u_simple_screen.c @@ -29,7 +29,7 @@ #include "pipe/p_screen.h" #include "pipe/p_state.h" -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" static struct pipe_buffer * diff --git a/src/gallium/auxiliary/util/u_simple_screen.h b/src/gallium/auxiliary/util/u_simple_screen.h index 6612a8a7c09..bb3f5ba102f 100644 --- a/src/gallium/auxiliary/util/u_simple_screen.h +++ b/src/gallium/auxiliary/util/u_simple_screen.h @@ -28,8 +28,145 @@ #ifndef U_SIMPLE_SCREEN_H #define U_SIMPLE_SCREEN_H +#include "pipe/p_format.h" + struct pipe_screen; -struct pipe_winsys; +struct pipe_fence_handle; +struct pipe_surface; +struct pipe_buffer; + +/** + * Gallium3D drivers are (meant to be!) independent of both GL and the + * window system. The window system provides a buffer manager and a + * set of additional hooks for things like command buffer submission, + * etc. + * + * There clearly has to be some agreement between the window system + * driver and the hardware driver about the format of command buffers, + * etc. + */ +struct pipe_winsys +{ + void (*destroy)( struct pipe_winsys *ws ); + + /** Returns name of this winsys interface */ + 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. + */ + void (*flush_frontbuffer)( struct pipe_winsys *ws, + struct pipe_surface *surf, + void *context_private ); + + + /** + * Buffer management. Buffer attributes are mostly fixed over its lifetime. + * + * Remember that gallium gets to choose the interface it needs, and the + * window systems must then implement that interface (rather than the + * other way around...). + * + * usage is a bitmask of PIPE_BUFFER_USAGE_PIXEL/VERTEX/INDEX/CONSTANT. This + * usage argument is only an optimization hint, not a guarantee, therefore + * proper behavior must be observed in all circumstances. + * + * alignment indicates the client's alignment requirements, eg for + * SSE instructions. + */ + struct pipe_buffer *(*buffer_create)( struct pipe_winsys *ws, + unsigned alignment, + unsigned usage, + unsigned size ); + + /** + * Create a buffer that wraps user-space data. + * + * Effectively this schedules a delayed call to buffer_create + * followed by an upload of the data at *some point in the future*, + * or perhaps never. Basically the allocate/upload is delayed + * until the buffer is actually passed to hardware. + * + * The intention is to provide a quick way to turn regular data + * into a buffer, and secondly to avoid a copy operation if that + * data subsequently turns out to be only accessed by the CPU. + * + * Common example is OpenGL vertex buffers that are subsequently + * processed either by software TNL in the driver or by passing to + * hardware. + * + * XXX: What happens if the delayed call to buffer_create() fails? + * + * Note that ptr may be accessed at any time upto the time when the + * buffer is destroyed, so the data must not be freed before then. + */ + struct pipe_buffer *(*user_buffer_create)(struct pipe_winsys *ws, + void *ptr, + unsigned bytes); + + /** + * Allocate storage for a display target surface. + * + * Often surfaces which are meant to be blitted to the front screen (i.e., + * display targets) must be allocated with special characteristics, memory + * pools, or obtained directly from the windowing system. + * + * This callback is invoked by the pipe_screenwhen creating a texture marked + * with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET flag to get the underlying + * buffer storage. + */ + struct pipe_buffer *(*surface_buffer_create)(struct pipe_winsys *ws, + unsigned width, unsigned height, + enum pipe_format format, + unsigned usage, + unsigned tex_usage, + unsigned *stride); + + + /** + * Map the entire data store of a buffer object into the client's address. + * flags is bitmask of PIPE_BUFFER_USAGE_CPU_READ/WRITE flags. + */ + void *(*buffer_map)( struct pipe_winsys *ws, + struct pipe_buffer *buf, + unsigned usage ); + + void (*buffer_unmap)( struct pipe_winsys *ws, + struct pipe_buffer *buf ); + + void (*buffer_destroy)( struct pipe_buffer *buf ); + + + /** Set ptr = fence, with reference counting */ + void (*fence_reference)( struct pipe_winsys *ws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence ); + + /** + * Checks whether the fence has been signalled. + * \param flags driver-specific meaning + * \return zero on success. + */ + int (*fence_signalled)( struct pipe_winsys *ws, + struct pipe_fence_handle *fence, + unsigned flag ); + + /** + * Wait for the fence to finish. + * \param flags driver-specific meaning + * \return zero on success. + */ + int (*fence_finish)( struct pipe_winsys *ws, + struct pipe_fence_handle *fence, + unsigned flag ); + +}; /** * The following function initializes a simple passthrough screen. diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c index b751e29ab62..019dda767d0 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/src/gallium/auxiliary/util/u_simple_shaders.c @@ -38,6 +38,7 @@ #include "pipe/p_context.h" #include "pipe/p_shader_tokens.h" #include "util/u_simple_shaders.h" +#include "util/u_debug.h" #include "tgsi/tgsi_ureg.h" diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c index f828908f0be..6053c111e34 100644 --- a/src/gallium/auxiliary/util/u_surface.c +++ b/src/gallium/auxiliary/util/u_surface.c @@ -35,6 +35,7 @@ #include "pipe/p_screen.h" #include "pipe/p_state.h" #include "pipe/p_defines.h" +#include "util/u_inlines.h" #include "util/u_surface.h" diff --git a/src/gallium/auxiliary/util/u_texture.c b/src/gallium/auxiliary/util/u_texture.c index cd477ab640f..d97e57a7903 100644 --- a/src/gallium/auxiliary/util/u_texture.c +++ b/src/gallium/auxiliary/util/u_texture.c @@ -37,6 +37,7 @@ #include "pipe/p_defines.h" +#include "util/u_debug.h" #include "util/u_texture.h" void util_map_texcoords2d_onto_cubemap(unsigned face, diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c index c25e1e52e9d..0051258e22a 100644 --- a/src/gallium/auxiliary/util/u_tile.c +++ b/src/gallium/auxiliary/util/u_tile.c @@ -32,7 +32,7 @@ #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_math.h" diff --git a/src/gallium/auxiliary/util/u_timed_winsys.c b/src/gallium/auxiliary/util/u_timed_winsys.c index 178acdca4df..59bdcd2c451 100644 --- a/src/gallium/auxiliary/util/u_timed_winsys.c +++ b/src/gallium/auxiliary/util/u_timed_winsys.c @@ -30,7 +30,7 @@ */ #include "pipe/p_state.h" -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" #include "u_timed_winsys.h" #include "util/u_memory.h" #include "util/u_time.h" diff --git a/src/gallium/auxiliary/util/u_upload_mgr.c b/src/gallium/auxiliary/util/u_upload_mgr.c index 55a65375c81..012b2ae2336 100644 --- a/src/gallium/auxiliary/util/u_upload_mgr.c +++ b/src/gallium/auxiliary/util/u_upload_mgr.c @@ -30,7 +30,7 @@ */ #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_screen.h" #include "util/u_memory.h" #include "util/u_math.h" diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c index a524e2fdfb3..6c5298daabc 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.c +++ b/src/gallium/auxiliary/vl/vl_compositor.c @@ -28,7 +28,7 @@ #include "vl_compositor.h" #include <assert.h> #include <pipe/p_context.h> -#include <pipe/p_inlines.h> +#include <util/u_inlines.h> #include <tgsi/tgsi_parse.h> #include <tgsi/tgsi_build.h> #include <util/u_memory.h> diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c index e43187545c5..c2552f40b4e 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c +++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c @@ -28,7 +28,7 @@ #include "vl_mpeg12_mc_renderer.h" #include <assert.h> #include <pipe/p_context.h> -#include <pipe/p_inlines.h> +#include <util/u_inlines.h> #include <util/u_format.h> #include <util/u_math.h> #include <util/u_memory.h> |