diff options
Diffstat (limited to 'src/gallium/auxiliary/util')
21 files changed, 948 insertions, 969 deletions
diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile index ae8d330a78..1d8bb55bbd 100644 --- a/src/gallium/auxiliary/util/Makefile +++ b/src/gallium/auxiliary/util/Makefile @@ -10,6 +10,7 @@ C_SOURCES = \ u_debug_stack.c \ u_blit.c \ u_cache.c \ + u_cpu_detect.c \ u_draw_quad.c \ u_format.c \ u_format_access.c \ diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript index 28a5ab4256..8d99106d0b 100644 --- a/src/gallium/auxiliary/util/SConscript +++ b/src/gallium/auxiliary/util/SConscript @@ -24,10 +24,10 @@ util = env.ConvenienceLibrary( 'u_bitmask.c', 'u_blit.c', 'u_cache.c', + 'u_cpu_detect.c', 'u_debug.c', 'u_debug_dump.c', 'u_debug_memory.c', - 'u_debug_profile.c', 'u_debug_stack.c', 'u_debug_symbol.c', 'u_draw_quad.c', diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index c516317d70..5038642599 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -46,6 +46,7 @@ #include "util/u_memory.h" #include "util/u_simple_shaders.h" #include "util/u_surface.h" +#include "util/u_rect.h" #include "cso_cache/cso_context.h" @@ -182,47 +183,7 @@ get_next_slot( struct blit_state *ctx ) } -/** - * Setup vertex data for the textured quad we'll draw. - * Note: y=0=top - */ -static unsigned -setup_vertex_data(struct blit_state *ctx, - float x0, float y0, float x1, float y1, float z) -{ - unsigned offset; - - ctx->vertices[0][0][0] = x0; - ctx->vertices[0][0][1] = y0; - ctx->vertices[0][0][2] = z; - ctx->vertices[0][1][0] = 0.0f; /*s*/ - ctx->vertices[0][1][1] = 0.0f; /*t*/ - - ctx->vertices[1][0][0] = x1; - ctx->vertices[1][0][1] = y0; - ctx->vertices[1][0][2] = z; - ctx->vertices[1][1][0] = 1.0f; /*s*/ - ctx->vertices[1][1][1] = 0.0f; /*t*/ - - ctx->vertices[2][0][0] = x1; - ctx->vertices[2][0][1] = y1; - ctx->vertices[2][0][2] = z; - ctx->vertices[2][1][0] = 1.0f; - ctx->vertices[2][1][1] = 1.0f; - ctx->vertices[3][0][0] = x0; - ctx->vertices[3][0][1] = y1; - ctx->vertices[3][0][2] = z; - ctx->vertices[3][1][0] = 0.0f; - ctx->vertices[3][1][1] = 1.0f; - - offset = get_next_slot( ctx ); - - pipe_buffer_write(ctx->pipe->screen, ctx->vbuf, - offset, sizeof(ctx->vertices), ctx->vertices); - - return offset; -} /** @@ -315,15 +276,13 @@ util_blit_pixels_writemask(struct blit_state *ctx, { struct pipe_context *pipe = ctx->pipe; struct pipe_screen *screen = pipe->screen; - struct pipe_texture texTemp, *tex; - struct pipe_surface *texSurf; + struct pipe_texture *tex = NULL; struct pipe_framebuffer_state fb; const int srcW = abs(srcX1 - srcX0); const int srcH = abs(srcY1 - srcY0); - const int srcLeft = MIN2(srcX0, srcX1); - const int srcTop = MIN2(srcY0, srcY1); unsigned offset; boolean overlap; + float s0, t0, s1, t1; assert(filter == PIPE_TEX_MIPFILTER_NEAREST || filter == PIPE_TEX_MIPFILTER_LINEAR); @@ -343,7 +302,8 @@ util_blit_pixels_writemask(struct blit_state *ctx, * no overlapping. * Filter mode should not matter since there's no stretching. */ - if (dst->format == src->format && + if (pipe->surface_copy && + dst->format == src->format && srcX0 < srcX1 && dstX0 < dstX1 && srcY0 < srcY1 && @@ -358,54 +318,83 @@ util_blit_pixels_writemask(struct blit_state *ctx, return; } - if (srcLeft != srcX0) { - /* left-right flip */ - int tmp = dstX0; - dstX0 = dstX1; - dstX1 = tmp; - } - - if (srcTop != srcY0) { - /* up-down flip */ - int tmp = dstY0; - dstY0 = dstY1; - dstY1 = tmp; - } - assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)); - /* - * XXX for now we're always creating a temporary texture. - * Strictly speaking that's not always needed. + /* Create a temporary texture when src and dest alias or when src + * is anything other than a single-level 2d texture. + * + * This can still be improved upon. */ + if (util_same_surface(src, dst) || + src->texture->target != PIPE_TEXTURE_2D || + src->texture->last_level != 0) + { + struct pipe_texture texTemp; + struct pipe_surface *texSurf; + const int srcLeft = MIN2(srcX0, srcX1); + const int srcTop = MIN2(srcY0, srcY1); + + if (srcLeft != srcX0) { + /* left-right flip */ + int tmp = dstX0; + dstX0 = dstX1; + dstX1 = tmp; + } + + if (srcTop != srcY0) { + /* up-down flip */ + int tmp = dstY0; + dstY0 = dstY1; + dstY1 = tmp; + } + + /* create temp texture */ + memset(&texTemp, 0, sizeof(texTemp)); + texTemp.target = PIPE_TEXTURE_2D; + texTemp.format = src->format; + texTemp.last_level = 0; + texTemp.width[0] = srcW; + texTemp.height[0] = srcH; + texTemp.depth[0] = 1; + pf_get_block(src->format, &texTemp.block); + + tex = screen->texture_create(screen, &texTemp); + if (!tex) + return; + + texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_WRITE); + + /* load temp texture */ + if (pipe->surface_copy) { + pipe->surface_copy(pipe, + texSurf, 0, 0, /* dest */ + src, srcLeft, srcTop, /* src */ + srcW, srcH); /* size */ + } else { + util_surface_copy(pipe, FALSE, + texSurf, 0, 0, /* dest */ + src, srcLeft, srcTop, /* src */ + srcW, srcH); /* size */ + } + + /* free the surface, update the texture if necessary. + */ + pipe_surface_reference(&texSurf, NULL); + s0 = 0.0f; + s1 = 1.0f; + t0 = 0.0f; + t1 = 1.0f; + } + else { + pipe_texture_reference(&tex, src->texture); + s0 = srcX0 / (float)tex->width[0]; + s1 = srcX1 / (float)tex->width[0]; + t0 = srcY0 / (float)tex->height[0]; + t1 = srcY1 / (float)tex->height[0]; + } - /* create temp texture */ - memset(&texTemp, 0, sizeof(texTemp)); - texTemp.target = PIPE_TEXTURE_2D; - texTemp.format = src->format; - texTemp.last_level = 0; - texTemp.width[0] = srcW; - texTemp.height[0] = srcH; - texTemp.depth[0] = 1; - pf_get_block(src->format, &texTemp.block); - - tex = screen->texture_create(screen, &texTemp); - if (!tex) - return; - - texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0, - PIPE_BUFFER_USAGE_GPU_WRITE); - - /* load temp texture */ - pipe->surface_copy(pipe, - texSurf, 0, 0, /* dest */ - src, srcLeft, srcTop, /* src */ - srcW, srcH); /* size */ - - /* free the surface, update the texture if necessary. - */ - pipe_surface_reference(&texSurf, NULL); /* save state (restored below) */ cso_save_blend(ctx->cso); @@ -447,9 +436,12 @@ util_blit_pixels_writemask(struct blit_state *ctx, cso_set_framebuffer(ctx->cso, &fb); /* draw quad */ - offset = setup_vertex_data(ctx, - (float) dstX0, (float) dstY0, - (float) dstX1, (float) dstY1, z); + offset = setup_vertex_data_tex(ctx, + (float) dstX0, (float) dstY0, + (float) dstX1, (float) dstY1, + s0, t0, + s1, t1, + z); util_draw_vertex_buffer(ctx->pipe, ctx->vbuf, offset, PIPE_PRIM_TRIANGLE_FAN, diff --git a/src/gallium/auxiliary/util/u_clear.h b/src/gallium/auxiliary/util/u_clear.h index 7035c68aed..6be5ca2297 100644 --- a/src/gallium/auxiliary/util/u_clear.h +++ b/src/gallium/auxiliary/util/u_clear.h @@ -32,6 +32,7 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" #include "util/u_pack_color.h" +#include "util/u_rect.h" /** @@ -48,13 +49,22 @@ util_clear(struct pipe_context *pipe, unsigned color = 0; util_pack_color(rgba, ps->format, &color); - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, color); + if (pipe->surface_fill) { + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, color); + } else { + util_surface_fill(pipe, ps, 0, 0, ps->width, ps->height, color); + } } if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { struct pipe_surface *ps = framebuffer->zsbuf; - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, - util_pack_z_stencil(ps->format, depth, stencil)); + if (pipe->surface_fill) { + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, + util_pack_z_stencil(ps->format, depth, stencil)); + } else { + util_surface_fill(pipe, ps, 0, 0, ps->width, ps->height, + util_pack_z_stencil(ps->format, depth, stencil)); + } } } diff --git a/src/gallium/auxiliary/util/u_cpu_detect.c b/src/gallium/auxiliary/util/u_cpu_detect.c index f78706f447..a08241971c 100644 --- a/src/gallium/auxiliary/util/u_cpu_detect.c +++ b/src/gallium/auxiliary/util/u_cpu_detect.c @@ -24,23 +24,21 @@ * **************************************************************************/ -/* - * Based on the work of Eric Anholt <anholt@FreeBSD.org> +/** + * @file + * CPU feature detection. + * + * @author Dennis Smit + * @author Based on the work of Eric Anholt <anholt@FreeBSD.org> */ -/* FIXME: clean this entire file up */ +#include "pipe/p_config.h" +#include "u_debug.h" #include "u_cpu_detect.h" -#ifdef __linux__ -#define OS_LINUX -#endif -#ifdef WIN32 -#define OS_WIN32 -#endif - -#if defined(ARCH_POWERPC) -#if defined(OS_DARWIN) +#if defined(PIPE_ARCH_PPC) +#if defined(PIPE_OS_DARWIN) #include <sys/sysctl.h> #else #include <signal.h> @@ -48,140 +46,147 @@ #endif #endif -#if defined(OS_NETBSD) || defined(OS_OPENBSD) +#if defined(PIPE_OS_NETBSD) || defined(PIPE_OS_OPENBSD) #include <sys/param.h> #include <sys/sysctl.h> #include <machine/cpu.h> #endif -#if defined(OS_FREEBSD) +#if defined(PIPE_OS_FREEBSD) #include <sys/types.h> #include <sys/sysctl.h> #endif -#if defined(OS_LINUX) +#if defined(PIPE_OS_LINUX) #include <signal.h> #endif -#if defined(OS_WIN32) -#include <windows.h> +#ifdef PIPE_OS_UNIX +#include <unistd.h> #endif -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> +#if defined(PIPE_OS_WINDOWS) +#include <windows.h> +#if defined(MSVC) +#include <intrin.h> +#endif +#endif -static struct cpu_detect_caps __cpu_detect_caps; -static int __cpu_detect_initialized = 0; +struct util_cpu_caps util_cpu_caps; static int has_cpuid(void); -static int cpuid(unsigned int ax, unsigned int *p); + +#if defined(PIPE_ARCH_X86) /* The sigill handlers */ -#if defined(ARCH_X86) /* x86 (linux katmai handler check thing) */ -#if defined(OS_LINUX) && defined(_POSIX_SOURCE) && defined(X86_FXSR_MAGIC) -static void sigill_handler_sse(int signal, struct sigcontext sc) +#if defined(PIPE_OS_LINUX) /*&& defined(_POSIX_SOURCE) && defined(X86_FXSR_MAGIC)*/ +static void +sigill_handler_sse(int signal, struct sigcontext sc) { - /* Both the "xorps %%xmm0,%%xmm0" and "divps %xmm0,%%xmm1" - * instructions are 3 bytes long. We must increment the instruction - * pointer manually to avoid repeated execution of the offending - * instruction. - * - * If the SIGILL is caused by a divide-by-zero when unmasked - * exceptions aren't supported, the SIMD FPU status and control - * word will be restored at the end of the test, so we don't need - * to worry about doing it here. Besides, we may not be able to... - */ - sc.eip += 3; - - __cpu_detect_caps.hasSSE=0; + /* Both the "xorps %%xmm0,%%xmm0" and "divps %xmm0,%%xmm1" + * instructions are 3 bytes long. We must increment the instruction + * pointer manually to avoid repeated execution of the offending + * instruction. + * + * If the SIGILL is caused by a divide-by-zero when unmasked + * exceptions aren't supported, the SIMD FPU status and control + * word will be restored at the end of the test, so we don't need + * to worry about doing it here. Besides, we may not be able to... + */ + sc.eip += 3; + + util_cpu_caps.has_sse=0; } -static void sigfpe_handler_sse(int signal, struct sigcontext sc) +static void +sigfpe_handler_sse(int signal, struct sigcontext sc) { - if (sc.fpstate->magic != 0xffff) { - /* Our signal context has the extended FPU state, so reset the - * divide-by-zero exception mask and clear the divide-by-zero - * exception bit. - */ - sc.fpstate->mxcsr |= 0x00000200; - sc.fpstate->mxcsr &= 0xfffffffb; - } else { - /* If we ever get here, we're completely hosed. - */ - } + if (sc.fpstate->magic != 0xffff) { + /* Our signal context has the extended FPU state, so reset the + * divide-by-zero exception mask and clear the divide-by-zero + * exception bit. + */ + sc.fpstate->mxcsr |= 0x00000200; + sc.fpstate->mxcsr &= 0xfffffffb; + } else { + /* If we ever get here, we're completely hosed. + */ + } } -#endif -#endif /* OS_LINUX && _POSIX_SOURCE && X86_FXSR_MAGIC */ +#endif /* PIPE_OS_LINUX && _POSIX_SOURCE && X86_FXSR_MAGIC */ -#if defined(OS_WIN32) -LONG CALLBACK win32_sig_handler_sse(EXCEPTION_POINTERS* ep) +#if defined(PIPE_OS_WINDOWS) +static LONG CALLBACK +win32_sig_handler_sse(EXCEPTION_POINTERS* ep) { - if(ep->ExceptionRecord->ExceptionCode==EXCEPTION_ILLEGAL_INSTRUCTION){ - ep->ContextRecord->Eip +=3; - __cpu_detect_caps.hasSSE=0; - return EXCEPTION_CONTINUE_EXECUTION; - } - return EXCEPTION_CONTINUE_SEARCH; + if(ep->ExceptionRecord->ExceptionCode==EXCEPTION_ILLEGAL_INSTRUCTION){ + ep->ContextRecord->Eip +=3; + util_cpu_caps.has_sse=0; + return EXCEPTION_CONTINUE_EXECUTION; + } + return EXCEPTION_CONTINUE_SEARCH; } -#endif /* OS_WIN32 */ +#endif /* PIPE_OS_WINDOWS */ +#endif /* PIPE_ARCH_X86 */ -#if defined(ARCH_POWERPC) && !defined(OS_DARWIN) -static sigjmp_buf __lv_powerpc_jmpbuf; -static volatile sig_atomic_t __lv_powerpc_canjump = 0; -static void sigill_handler (int sig); +#if defined(PIPE_ARCH_PPC) && !defined(PIPE_OS_DARWIN) +static jmp_buf __lv_powerpc_jmpbuf; +static volatile sig_atomic_t __lv_powerpc_canjump = 0; -static void sigill_handler (int sig) +static void +sigill_handler(int sig) { - if (!__lv_powerpc_canjump) { - signal (sig, SIG_DFL); - raise (sig); - } + if (!__lv_powerpc_canjump) { + signal (sig, SIG_DFL); + raise (sig); + } - __lv_powerpc_canjump = 0; - siglongjmp(__lv_powerpc_jmpbuf, 1); + __lv_powerpc_canjump = 0; + longjmp(__lv_powerpc_jmpbuf, 1); } +#endif -static void check_os_altivec_support(void) +#if defined(PIPE_ARCH_PPC) +static void +check_os_altivec_support(void) { -#if defined(OS_DARWIN) - int sels[2] = {CTL_HW, HW_VECTORUNIT}; - int has_vu = 0; - int len = sizeof (has_vu); - int err; - - err = sysctl(sels, 2, &has_vu, &len, NULL, 0); - - if (err == 0) { - if (has_vu != 0) { - __cpu_detect_caps.hasAltiVec = 1; - } - } -#else /* !OS_DARWIN */ - /* no Darwin, do it the brute-force way */ - /* this is borrowed from the libmpeg2 library */ - signal(SIGILL, sigill_handler); - if (sigsetjmp(__lv_powerpc_jmpbuf, 1)) { - signal(SIGILL, SIG_DFL); - } else { - __lv_powerpc_canjump = 1; - - __asm __volatile - ("mtspr 256, %0\n\t" - "vand %%v0, %%v0, %%v0" - : - : "r" (-1)); - - signal(SIGILL, SIG_DFL); - __cpu_detect_caps.hasAltiVec = 1; - } -#endif +#if defined(PIPE_OS_DARWIN) + int sels[2] = {CTL_HW, HW_VECTORUNIT}; + int has_vu = 0; + int len = sizeof (has_vu); + int err; + + err = sysctl(sels, 2, &has_vu, &len, NULL, 0); + + if (err == 0) { + if (has_vu != 0) { + util_cpu_caps.has_altivec = 1; + } + } +#else /* !PIPE_OS_DARWIN */ + /* no Darwin, do it the brute-force way */ + /* this is borrowed from the libmpeg2 library */ + signal(SIGILL, sigill_handler); + if (setjmp(__lv_powerpc_jmpbuf)) { + signal(SIGILL, SIG_DFL); + } else { + __lv_powerpc_canjump = 1; + + __asm __volatile + ("mtspr 256, %0\n\t" + "vand %%v0, %%v0, %%v0" + : + : "r" (-1)); + + signal(SIGILL, SIG_DFL); + util_cpu_caps.has_altivec = 1; + } +#endif /* PIPE_OS_DARWIN */ } -#endif +#endif /* PIPE_ARCH_PPC */ /* If we're running on a processor that can do SSE, let's see if we * are allowed to or not. This will catch 2.4.0 or later kernels that @@ -189,318 +194,327 @@ static void check_os_altivec_support(void) * and RedHat patched 2.2 kernels that have broken exception handling * support for user space apps that do SSE. */ -static void check_os_katmai_support(void) +#if defined(PIPE_ARCH_X86) || defined (PIPE_ARCH_X86_64) +static void +check_os_katmai_support(void) { -#if defined(ARCH_X86) -#if defined(OS_FREEBSD) - int has_sse=0, ret; - int len = sizeof (has_sse); - - ret = sysctlbyname("hw.instruction_sse", &has_sse, &len, NULL, 0); - if (ret || !has_sse) - __cpu_detect_caps.hasSSE=0; - -#elif defined(OS_NETBSD) || defined(OS_OPENBSD) - int has_sse, has_sse2, ret, mib[2]; - int varlen; - - mib[0] = CTL_MACHDEP; - mib[1] = CPU_SSE; - varlen = sizeof (has_sse); - - ret = sysctl(mib, 2, &has_sse, &varlen, NULL, 0); - if (ret < 0 || !has_sse) { - __cpu_detect_caps.hasSSE = 0; - } else { - __cpu_detect_caps.hasSSE = 1; - } - - mib[1] = CPU_SSE2; - varlen = sizeof (has_sse2); - ret = sysctl(mib, 2, &has_sse2, &varlen, NULL, 0); - if (ret < 0 || !has_sse2) { - __cpu_detect_caps.hasSSE2 = 0; - } else { - __cpu_detect_caps.hasSSE2 = 1; - } - __cpu_detect_caps.hasSSE = 0; /* FIXME ?!?!? */ - -#elif defined(OS_WIN32) - LPTOP_LEVEL_EXCEPTION_FILTER exc_fil; - if (__cpu_detect_caps.hasSSE) { - exc_fil = SetUnhandledExceptionFilter(win32_sig_handler_sse); - __asm __volatile ("xorps %xmm0, %xmm0"); - SetUnhandledExceptionFilter(exc_fil); - } -#elif defined(OS_LINUX) - struct sigaction saved_sigill; - struct sigaction saved_sigfpe; - - /* Save the original signal handlers. - */ - sigaction(SIGILL, NULL, &saved_sigill); - sigaction(SIGFPE, NULL, &saved_sigfpe); - - signal(SIGILL, (void (*)(int))sigill_handler_sse); - signal(SIGFPE, (void (*)(int))sigfpe_handler_sse); - - /* Emulate test for OSFXSR in CR4. The OS will set this bit if it - * supports the extended FPU save and restore required for SSE. If - * we execute an SSE instruction on a PIII and get a SIGILL, the OS - * doesn't support Streaming SIMD Exceptions, even if the processor - * does. - */ - if (__cpu_detect_caps.hasSSE) { - __asm __volatile ("xorps %xmm1, %xmm0"); - } - - /* Emulate test for OSXMMEXCPT in CR4. The OS will set this bit if - * it supports unmasked SIMD FPU exceptions. If we unmask the - * exceptions, do a SIMD divide-by-zero and get a SIGILL, the OS - * doesn't support unmasked SIMD FPU exceptions. If we get a SIGFPE - * as expected, we're okay but we need to clean up after it. - * - * Are we being too stringent in our requirement that the OS support - * unmasked exceptions? Certain RedHat 2.2 kernels enable SSE by - * setting CR4.OSFXSR but don't support unmasked exceptions. Win98 - * doesn't even support them. We at least know the user-space SSE - * support is good in kernels that do support unmasked exceptions, - * and therefore to be safe I'm going to leave this test in here. - */ - if (__cpu_detect_caps.hasSSE) { - /* test_os_katmai_exception_support(); */ - } - - /* Restore the original signal handlers. - */ - sigaction(SIGILL, &saved_sigill, NULL); - sigaction(SIGFPE, &saved_sigfpe, NULL); +#if defined(PIPE_ARCH_X86) +#if defined(PIPE_OS_FREEBSD) + int has_sse=0, ret; + int len = sizeof (has_sse); + + ret = sysctlbyname("hw.instruction_sse", &has_sse, &len, NULL, 0); + if (ret || !has_sse) + util_cpu_caps.has_sse=0; + +#elif defined(PIPE_OS_NETBSD) || defined(PIPE_OS_OPENBSD) + int has_sse, has_sse2, ret, mib[2]; + int varlen; + + mib[0] = CTL_MACHDEP; + mib[1] = CPU_SSE; + varlen = sizeof (has_sse); + + ret = sysctl(mib, 2, &has_sse, &varlen, NULL, 0); + if (ret < 0 || !has_sse) { + util_cpu_caps.has_sse = 0; + } else { + util_cpu_caps.has_sse = 1; + } + + mib[1] = CPU_SSE2; + varlen = sizeof (has_sse2); + ret = sysctl(mib, 2, &has_sse2, &varlen, NULL, 0); + if (ret < 0 || !has_sse2) { + util_cpu_caps.has_sse2 = 0; + } else { + util_cpu_caps.has_sse2 = 1; + } + util_cpu_caps.has_sse = 0; /* FIXME ?!?!? */ + +#elif defined(PIPE_OS_WINDOWS) + LPTOP_LEVEL_EXCEPTION_FILTER exc_fil; + if (util_cpu_caps.has_sse) { + exc_fil = SetUnhandledExceptionFilter(win32_sig_handler_sse); +#if defined(PIPE_CC_GCC) + __asm __volatile ("xorps %xmm0, %xmm0"); +#elif defined(PIPE_CC_MSVC) + __asm { + xorps xmm0, xmm0 /* executing SSE instruction */ + } +#else +#error Unsupported compiler +#endif + SetUnhandledExceptionFilter(exc_fil); + } +#elif defined(PIPE_OS_LINUX) + struct sigaction saved_sigill; + struct sigaction saved_sigfpe; + + /* Save the original signal handlers. + */ + sigaction(SIGILL, NULL, &saved_sigill); + sigaction(SIGFPE, NULL, &saved_sigfpe); + + signal(SIGILL, (void (*)(int))sigill_handler_sse); + signal(SIGFPE, (void (*)(int))sigfpe_handler_sse); + + /* Emulate test for OSFXSR in CR4. The OS will set this bit if it + * supports the extended FPU save and restore required for SSE. If + * we execute an SSE instruction on a PIII and get a SIGILL, the OS + * doesn't support Streaming SIMD Exceptions, even if the processor + * does. + */ + if (util_cpu_caps.has_sse) { + __asm __volatile ("xorps %xmm1, %xmm0"); + } + + /* Emulate test for OSXMMEXCPT in CR4. The OS will set this bit if + * it supports unmasked SIMD FPU exceptions. If we unmask the + * exceptions, do a SIMD divide-by-zero and get a SIGILL, the OS + * doesn't support unmasked SIMD FPU exceptions. If we get a SIGFPE + * as expected, we're okay but we need to clean up after it. + * + * Are we being too stringent in our requirement that the OS support + * unmasked exceptions? Certain RedHat 2.2 kernels enable SSE by + * setting CR4.OSFXSR but don't support unmasked exceptions. Win98 + * doesn't even support them. We at least know the user-space SSE + * support is good in kernels that do support unmasked exceptions, + * and therefore to be safe I'm going to leave this test in here. + */ + if (util_cpu_caps.has_sse) { + /* test_os_katmai_exception_support(); */ + } + + /* Restore the original signal handlers. + */ + sigaction(SIGILL, &saved_sigill, NULL); + sigaction(SIGFPE, &saved_sigfpe, NULL); #else - /* We can't use POSIX signal handling to test the availability of - * SSE, so we disable it by default. - */ - __cpu_detect_caps.hasSSE = 0; + /* We can't use POSIX signal handling to test the availability of + * SSE, so we disable it by default. + */ + util_cpu_caps.has_sse = 0; #endif /* __linux__ */ #endif + +#if defined(PIPE_ARCH_X86_64) + util_cpu_caps.has_sse = 1; +#endif } static int has_cpuid(void) { -#if defined(ARCH_X86) - int a, c; - - __asm __volatile - ("pushf\n" - "popl %0\n" - "movl %0, %1\n" - "xorl $0x200000, %0\n" - "push %0\n" - "popf\n" - "pushf\n" - "popl %0\n" - : "=a" (a), "=c" (c) - : - : "cc"); - - return a != c; +#if defined(PIPE_ARCH_X86) +#if defined(PIPE_OS_GCC) + int a, c; + + __asm __volatile + ("pushf\n" + "popl %0\n" + "movl %0, %1\n" + "xorl $0x200000, %0\n" + "push %0\n" + "popf\n" + "pushf\n" + "popl %0\n" + : "=a" (a), "=c" (c) + : + : "cc"); + + return a != c; +#else + /* FIXME */ + return 1; +#endif +#elif defined(PIPE_ARCH_X86_64) + return 1; #else - return 0; + return 0; #endif } -static int cpuid(unsigned int ax, unsigned int *p) + +/** + * @sa cpuid.h included in gcc-4.3 onwards. + * @sa http://msdn.microsoft.com/en-us/library/hskdteyh.aspx + */ +static INLINE void +cpuid(uint32_t ax, uint32_t *p) { -#if defined(ARCH_X86) - unsigned int flags; - - __asm __volatile - ("movl %%ebx, %%esi\n\t" - "cpuid\n\t" - "xchgl %%ebx, %%esi" - : "=a" (p[0]), "=S" (p[1]), - "=c" (p[2]), "=d" (p[3]) - : "0" (ax)); - - return 0; +#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86) + __asm __volatile ( + "xchgl %%ebx, %1\n\t" + "cpuid\n\t" + "xchgl %%ebx, %1" + : "=a" (p[0]), + "=S" (p[1]), + "=c" (p[2]), + "=d" (p[3]) + : "0" (ax) + ); +#elif defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86_64) + __asm __volatile ( + "cpuid\n\t" + : "=a" (p[0]), + "=b" (p[1]), + "=c" (p[2]), + "=d" (p[3]) + : "0" (ax) + ); +#elif defined(PIPE_CC_MSVC) + __cpuid(p, ax); #else - return -1; + p[0] = 0; + p[1] = 0; + p[2] = 0; + p[3] = 0; #endif } +#endif /* X86 or X86_64 */ -void cpu_detect_initialize() +void +util_cpu_detect(void) { - unsigned int regs[4]; - unsigned int regs2[4]; - - int mib[2], ncpu; - int len; - - memset(&__cpu_detect_caps, 0, sizeof (struct cpu_detect_caps)); - - /* Check for arch type */ -#if defined(ARCH_MIPS) - __cpu_detect_caps.type = CPU_DETECT_TYPE_MIPS; -#elif defined(ARCH_ALPHA) - __cpu_detect_caps.type = CPU_DETECT_TYPE_ALPHA; -#elif defined(ARCH_SPARC) - __cpu_detect_caps.type = CPU_DETECT_TYPE_SPARC; -#elif defined(ARCH_X86) - __cpu_detect_caps.type = CPU_DETECT_TYPE_X86; -#elif defined(ARCH_POWERPC) - __cpu_detect_caps.type = CPU_DETECT_TYPE_POWERPC; + static boolean util_cpu_detect_initialized = FALSE; + + if(util_cpu_detect_initialized) + return; + + memset(&util_cpu_caps, 0, sizeof util_cpu_caps); + + /* Check for arch type */ +#if defined(PIPE_ARCH_MIPS) + util_cpu_caps.arch = UTIL_CPU_ARCH_MIPS; +#elif defined(PIPE_ARCH_ALPHA) + util_cpu_caps.arch = UTIL_CPU_ARCH_ALPHA; +#elif defined(PIPE_ARCH_SPARC) + util_cpu_caps.arch = UTIL_CPU_ARCH_SPARC; +#elif defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) + util_cpu_caps.arch = UTIL_CPU_ARCH_X86; + util_cpu_caps.little_endian = 1; +#elif defined(PIPE_ARCH_PPC) + util_cpu_caps.arch = UTIL_CPU_ARCH_POWERPC; + util_cpu_caps.little_endian = 0; #else - __cpu_detect_caps.type = CPU_DETECT_TYPE_OTHER; + util_cpu_caps.arch = UTIL_CPU_ARCH_UNKNOWN; #endif - /* Count the number of CPUs in system */ -#if !defined(OS_WIN32) && !defined(OS_UNKNOWN) && defined(_SC_NPROCESSORS_ONLN) - __cpu_detect_caps.nrcpu = sysconf(_SC_NPROCESSORS_ONLN); - if (__cpu_detect_caps.nrcpu == -1) - __cpu_detect_caps.nrcpu = 1; - -#elif defined(OS_NETBSD) || defined(OS_FREEBSD) || defined(OS_OPENBSD) - - mib[0] = CTL_HW; - mib[1] = HW_NCPU; - - len = sizeof (ncpu); - sysctl(mib, 2, &ncpu, &len, NULL, 0); - __cpu_detect_caps.nrcpu = ncpu; - + /* Count the number of CPUs in system */ +#if defined(PIPE_OS_WINDOWS) + { + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + util_cpu_caps.nr_cpus = system_info.dwNumberOfProcessors; + } +#elif defined(PIPE_OS_UNIX) && defined(_SC_NPROCESSORS_ONLN) + util_cpu_caps.nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); + if (util_cpu_caps.nr_cpus == -1) + util_cpu_caps.nr_cpus = 1; +#elif defined(PIPE_OS_BSD) + { + int mib[2], ncpu; + int len; + + mib[0] = CTL_HW; + mib[1] = HW_NCPU; + + len = sizeof (ncpu); + sysctl(mib, 2, &ncpu, &len, NULL, 0); + util_cpu_caps.nr_cpus = ncpu; + } #else - __cpu_detect_caps.nrcpu = 1; + util_cpu_caps.nr_cpus = 1; #endif -#if defined(ARCH_X86) - /* No cpuid, old 486 or lower */ - if (has_cpuid() == 0) - return; - - __cpu_detect_caps.cacheline = 32; - - /* Get max cpuid level */ - cpuid(0x00000000, regs); - - if (regs[0] >= 0x00000001) { - unsigned int cacheline; - - cpuid (0x00000001, regs2); - - __cpu_detect_caps.x86cpuType = (regs2[0] >> 8) & 0xf; - if (__cpu_detect_caps.x86cpuType == 0xf) - __cpu_detect_caps.x86cpuType = 8 + ((regs2[0] >> 20) & 255); /* use extended family (P4, IA64) */ - - /* general feature flags */ - __cpu_detect_caps.hasTSC = (regs2[3] & (1 << 8 )) >> 8; /* 0x0000010 */ - __cpu_detect_caps.hasMMX = (regs2[3] & (1 << 23 )) >> 23; /* 0x0800000 */ - __cpu_detect_caps.hasSSE = (regs2[3] & (1 << 25 )) >> 25; /* 0x2000000 */ - __cpu_detect_caps.hasSSE2 = (regs2[3] & (1 << 26 )) >> 26; /* 0x4000000 */ - __cpu_detect_caps.hasSSE3 = (regs2[2] & (1)); /* 0x0000001 */ - __cpu_detect_caps.hasSSSE3 = (regs2[2] & (1 << 9 )) >> 9; /* 0x0000020 */ - __cpu_detect_caps.hasMMX2 = __cpu_detect_caps.hasSSE; /* SSE cpus supports mmxext too */ - - cacheline = ((regs2[1] >> 8) & 0xFF) * 8; - if (cacheline > 0) - __cpu_detect_caps.cacheline = cacheline; - } - - cpuid(0x80000000, regs); - - if (regs[0] >= 0x80000001) { - - cpuid(0x80000001, regs2); - - __cpu_detect_caps.hasMMX |= (regs2[3] & (1 << 23 )) >> 23; /* 0x0800000 */ - __cpu_detect_caps.hasMMX2 |= (regs2[3] & (1 << 22 )) >> 22; /* 0x400000 */ - __cpu_detect_caps.has3DNow = (regs2[3] & (1 << 31 )) >> 31; /* 0x80000000 */ - __cpu_detect_caps.has3DNowExt = (regs2[3] & (1 << 30 )) >> 30; - } - - if (regs[0] >= 0x80000006) { - cpuid(0x80000006, regs2); - __cpu_detect_caps.cacheline = regs2[2] & 0xFF; - } - - -#if defined(OS_LINUX) || defined(OS_FREEBSD) || defined(OS_NETBSD) || defined(OS_CYGWIN) || defined(OS_OPENBSD) - if (__cpu_detect_caps.hasSSE) - check_os_katmai_support(); - - if (!__cpu_detect_caps.hasSSE) { - __cpu_detect_caps.hasSSE2 = 0; - __cpu_detect_caps.hasSSE3 = 0; - __cpu_detect_caps.hasSSSE3 = 0; - } -#else - __cpu_detect_caps.hasSSE = 0; - __cpu_detect_caps.hasSSE2 = 0; - __cpu_detect_caps.hasSSE3 = 0; - __cpu_detect_caps.hasSSSE3 = 0; +#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) + if (has_cpuid()) { + uint32_t regs[4]; + uint32_t regs2[4]; + + util_cpu_caps.cacheline = 32; + + /* Get max cpuid level */ + cpuid(0x00000000, regs); + + if (regs[0] >= 0x00000001) { + unsigned int cacheline; + + cpuid (0x00000001, regs2); + + util_cpu_caps.x86_cpu_type = (regs2[0] >> 8) & 0xf; + if (util_cpu_caps.x86_cpu_type == 0xf) + util_cpu_caps.x86_cpu_type = 8 + ((regs2[0] >> 20) & 255); /* use extended family (P4, IA64) */ + + /* general feature flags */ + util_cpu_caps.has_tsc = (regs2[3] & (1 << 8 )) >> 8; /* 0x0000010 */ + util_cpu_caps.has_mmx = (regs2[3] & (1 << 23 )) >> 23; /* 0x0800000 */ + util_cpu_caps.has_sse = (regs2[3] & (1 << 25 )) >> 25; /* 0x2000000 */ + util_cpu_caps.has_sse2 = (regs2[3] & (1 << 26 )) >> 26; /* 0x4000000 */ + util_cpu_caps.has_sse3 = (regs2[2] & (1)); /* 0x0000001 */ + util_cpu_caps.has_ssse3 = (regs2[2] & (1 << 9 )) >> 9; /* 0x0000020 */ + util_cpu_caps.has_sse4_1 = (regs2[2] & (1 << 19)) >> 19; + util_cpu_caps.has_mmx2 = util_cpu_caps.has_sse; /* SSE cpus supports mmxext too */ + + cacheline = ((regs2[1] >> 8) & 0xFF) * 8; + if (cacheline > 0) + util_cpu_caps.cacheline = cacheline; + } + + cpuid(0x80000000, regs); + + if (regs[0] >= 0x80000001) { + + cpuid(0x80000001, regs2); + + util_cpu_caps.has_mmx |= (regs2[3] & (1 << 23 )) >> 23; /* 0x0800000 */ + util_cpu_caps.has_mmx2 |= (regs2[3] & (1 << 22 )) >> 22; /* 0x400000 */ + util_cpu_caps.has_3dnow = (regs2[3] & (1 << 31 )) >> 31; /* 0x80000000 */ + util_cpu_caps.has_3dnow_ext = (regs2[3] & (1 << 30 )) >> 30; + } + + if (regs[0] >= 0x80000006) { + cpuid(0x80000006, regs2); + util_cpu_caps.cacheline = regs2[2] & 0xFF; + } + + if (util_cpu_caps.has_sse) + check_os_katmai_support(); + + if (!util_cpu_caps.has_sse) { + util_cpu_caps.has_sse2 = 0; + util_cpu_caps.has_sse3 = 0; + util_cpu_caps.has_ssse3 = 0; + util_cpu_caps.has_sse4_1 = 0; + } + } +#endif /* PIPE_ARCH_X86 || PIPE_ARCH_X86_64 */ + +#if defined(PIPE_ARCH_PPC) + check_os_altivec_support(); +#endif /* PIPE_ARCH_PPC */ + +#ifdef DEBUG + debug_printf("util_cpu_caps.arch = %i\n", util_cpu_caps.arch); + debug_printf("util_cpu_caps.nr_cpus = %u\n", util_cpu_caps.nr_cpus); + + debug_printf("util_cpu_caps.x86_cpu_type = %u\n", util_cpu_caps.x86_cpu_type); + debug_printf("util_cpu_caps.cacheline = %u\n", util_cpu_caps.cacheline); + + debug_printf("util_cpu_caps.has_tsc = %u\n", util_cpu_caps.has_tsc); + debug_printf("util_cpu_caps.has_mmx = %u\n", util_cpu_caps.has_mmx); + debug_printf("util_cpu_caps.has_mmx2 = %u\n", util_cpu_caps.has_mmx2); + debug_printf("util_cpu_caps.has_sse = %u\n", util_cpu_caps.has_sse); + debug_printf("util_cpu_caps.has_sse2 = %u\n", util_cpu_caps.has_sse2); + debug_printf("util_cpu_caps.has_sse3 = %u\n", util_cpu_caps.has_sse3); + debug_printf("util_cpu_caps.has_ssse3 = %u\n", util_cpu_caps.has_ssse3); + debug_printf("util_cpu_caps.has_sse4_1 = %u\n", util_cpu_caps.has_sse4_1); + debug_printf("util_cpu_caps.has_3dnow = %u\n", util_cpu_caps.has_3dnow); + debug_printf("util_cpu_caps.has_3dnow_ext = %u\n", util_cpu_caps.has_3dnow_ext); + debug_printf("util_cpu_caps.has_altivec = %u\n", util_cpu_caps.has_altivec); #endif -#endif /* ARCH_X86 */ - -#if defined(ARCH_POWERPC) - check_os_altivec_support(); -#endif /* ARCH_POWERPC */ - - __cpu_detect_initialized = 1; -} - -struct cpu_detect_caps *cpu_detect_get_caps() -{ - return &__cpu_detect_caps; -} - -/* The getters and setters for feature flags */ -int cpu_detect_get_tsc() -{ - return __cpu_detect_caps.hasTSC; -} - -int cpu_detect_get_mmx() -{ - return __cpu_detect_caps.hasMMX; -} - -int cpu_detect_get_mmx2() -{ - return __cpu_detect_caps.hasMMX2; -} -int cpu_detect_get_sse() -{ - return __cpu_detect_caps.hasSSE; -} - -int cpu_detect_get_sse2() -{ - return __cpu_detect_caps.hasSSE2; -} - -int cpu_detect_get_sse3() -{ - return __cpu_detect_caps.hasSSE3; -} - -int cpu_detect_get_ssse3() -{ - return __cpu_detect_caps.hasSSSE3; + util_cpu_detect_initialized = TRUE; } - -int cpu_detect_get_3dnow() -{ - return __cpu_detect_caps.has3DNow; -} - -int cpu_detect_get_3dnow2() -{ - return __cpu_detect_caps.has3DNowExt; -} - -int cpu_detect_get_altivec() -{ - return __cpu_detect_caps.hasAltiVec; -} - diff --git a/src/gallium/auxiliary/util/u_cpu_detect.h b/src/gallium/auxiliary/util/u_cpu_detect.h index 1612d49286..4b3dc39c34 100644 --- a/src/gallium/auxiliary/util/u_cpu_detect.h +++ b/src/gallium/auxiliary/util/u_cpu_detect.h @@ -24,55 +24,55 @@ * ***************************************************************************/ -/* - * Based on the work of Eric Anholt <anholt@FreeBSD.org> +/** + * @file + * CPU feature detection. + * + * @author Dennis Smit + * @author Based on the work of Eric Anholt <anholt@FreeBSD.org> */ -#ifndef _CPU_DETECT_H -#define _CPU_DETECT_H +#ifndef _UTIL_CPU_DETECT_H +#define _UTIL_CPU_DETECT_H + +#include "pipe/p_compiler.h" -typedef enum { - CPU_DETECT_TYPE_MIPS, - CPU_DETECT_TYPE_ALPHA, - CPU_DETECT_TYPE_SPARC, - CPU_DETECT_TYPE_X86, - CPU_DETECT_TYPE_POWERPC, - CPU_DETECT_TYPE_OTHER -} cpu_detect_type; +enum util_cpu_arch { + UTIL_CPU_ARCH_UNKNOWN = 0, + UTIL_CPU_ARCH_MIPS, + UTIL_CPU_ARCH_ALPHA, + UTIL_CPU_ARCH_SPARC, + UTIL_CPU_ARCH_X86, + UTIL_CPU_ARCH_POWERPC +}; -struct cpu_detect_caps { - cpu_detect_type type; - int nrcpu; +struct util_cpu_caps { + enum util_cpu_arch arch; + unsigned nr_cpus; - /* Feature flags */ - int x86cpuType; - int cacheline; + /* Feature flags */ + int x86_cpu_type; + unsigned cacheline; - int hasTSC; - int hasMMX; - int hasMMX2; - int hasSSE; - int hasSSE2; - int hasSSE3; - int hasSSSE3; - int has3DNow; - int has3DNowExt; - int hasAltiVec; + unsigned little_endian:1; + + unsigned has_tsc:1; + unsigned has_mmx:1; + unsigned has_mmx2:1; + unsigned has_sse:1; + unsigned has_sse2:1; + unsigned has_sse3:1; + unsigned has_ssse3:1; + unsigned has_sse4_1:1; + unsigned has_3dnow:1; + unsigned has_3dnow_ext:1; + unsigned has_altivec:1; }; -/* prototypes */ -void cpu_detect_initialize(void); -struct cpu_detect_caps *cpu_detect_get_caps(void); +extern struct util_cpu_caps +util_cpu_caps; + +void util_cpu_detect(void); -int cpu_detect_get_tsc(void); -int cpu_detect_get_mmx(void); -int cpu_detect_get_mmx2(void); -int cpu_detect_get_sse(void); -int cpu_detect_get_sse2(void); -int cpu_detect_get_sse3(void); -int cpu_detect_get_ssse3(void); -int cpu_detect_get_3dnow(void); -int cpu_detect_get_3dnow2(void); -int cpu_detect_get_altivec(void); -#endif /* _CPU_DETECT_H */ +#endif /* _UTIL_CPU_DETECT_H */ diff --git a/src/gallium/auxiliary/util/u_debug.h b/src/gallium/auxiliary/util/u_debug.h index 1380d98d7e..abd834c741 100644 --- a/src/gallium/auxiliary/util/u_debug.h +++ b/src/gallium/auxiliary/util/u_debug.h @@ -65,6 +65,11 @@ extern "C" { #define __FUNCTION__ "???" #endif +#if defined(__GNUC__) +#define _util_printf_format(fmt, list) __attribute__ ((format (printf, fmt, list))) +#else +#define _util_printf_format(fmt, list) +#endif void _debug_vprintf(const char *format, va_list ap); @@ -82,14 +87,17 @@ _debug_printf(const char *format, ...) /** * Print debug messages. * - * The actual channel used to output debug message is platform specific. To - * avoid misformating or truncation, follow these rules of thumb: + * 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 + * - avoid outputing large strings (512 bytes is the current maximum length * that is guaranteed to be printed in all platforms) */ #if !defined(PIPE_OS_HAIKU) static INLINE void +debug_printf(const char *format, ...) _util_printf_format(1,2); + +static INLINE void debug_printf(const char *format, ...) { #ifdef DEBUG @@ -173,11 +181,14 @@ void _debug_assert_fail(const char *expr, * * Do not expect that the assert call terminates -- errors must be handled * regardless of assert behavior. + * + * For non debug builds the assert macro will expand to a no-op, so do not + * call functions with side effects in the assert expression. */ #ifdef DEBUG #define debug_assert(expr) ((expr) ? (void)0 : _debug_assert_fail(#expr, __FILE__, __LINE__, __FUNCTION__)) #else -#define debug_assert(expr) ((void)(expr)) +#define debug_assert(expr) ((void)0) #endif @@ -340,17 +351,6 @@ 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; struct pipe_transfer; diff --git a/src/gallium/auxiliary/util/u_debug_dump.c b/src/gallium/auxiliary/util/u_debug_dump.c index 6bdecde048..09866880ae 100644 --- a/src/gallium/auxiliary/util/u_debug_dump.c +++ b/src/gallium/auxiliary/util/u_debug_dump.c @@ -187,3 +187,83 @@ debug_dump_func_short_names[] = { }; DEFINE_DEBUG_DUMP_CONTINUOUS(func) + + +static const char * +debug_dump_tex_target_names[] = { + "PIPE_TEXTURE_1D", + "PIPE_TEXTURE_2D", + "PIPE_TEXTURE_3D", + "PIPE_TEXTURE_CUBE" +}; + +static const char * +debug_dump_tex_target_short_names[] = { + "1d", + "2d", + "3d", + "cube" +}; + +DEFINE_DEBUG_DUMP_CONTINUOUS(tex_target) + + +static const char * +debug_dump_tex_wrap_names[] = { + "PIPE_TEX_WRAP_REPEAT", + "PIPE_TEX_WRAP_CLAMP", + "PIPE_TEX_WRAP_CLAMP_TO_EDGE", + "PIPE_TEX_WRAP_CLAMP_TO_BORDER", + "PIPE_TEX_WRAP_MIRROR_REPEAT", + "PIPE_TEX_WRAP_MIRROR_CLAMP", + "PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE", + "PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER" +}; + +static const char * +debug_dump_tex_wrap_short_names[] = { + "repeat", + "clamp", + "clamp_to_edge", + "clamp_to_border", + "mirror_repeat", + "mirror_clamp", + "mirror_clamp_to_edge", + "mirror_clamp_to_border" +}; + +DEFINE_DEBUG_DUMP_CONTINUOUS(tex_wrap) + + +static const char * +debug_dump_tex_mipfilter_names[] = { + "PIPE_TEX_MIPFILTER_NEAREST", + "PIPE_TEX_MIPFILTER_LINEAR", + "PIPE_TEX_MIPFILTER_NONE" +}; + +static const char * +debug_dump_tex_mipfilter_short_names[] = { + "nearest", + "linear", + "none" +}; + +DEFINE_DEBUG_DUMP_CONTINUOUS(tex_mipfilter) + + +static const char * +debug_dump_tex_filter_names[] = { + "PIPE_TEX_FILTER_NEAREST", + "PIPE_TEX_FILTER_LINEAR", + "PIPE_TEX_FILTER_ANISO" +}; + +static const char * +debug_dump_tex_filter_short_names[] = { + "nearest", + "linear", + "aniso" +}; + +DEFINE_DEBUG_DUMP_CONTINUOUS(tex_filter) diff --git a/src/gallium/auxiliary/util/u_debug_dump.h b/src/gallium/auxiliary/util/u_debug_dump.h index 102935559c..19b130ad18 100644 --- a/src/gallium/auxiliary/util/u_debug_dump.h +++ b/src/gallium/auxiliary/util/u_debug_dump.h @@ -54,6 +54,18 @@ debug_dump_blend_func(unsigned value, boolean shortened); const char * debug_dump_func(unsigned value, boolean shortened); +const char * +debug_dump_tex_target(unsigned value, boolean shortened); + +const char * +debug_dump_tex_wrap(unsigned value, boolean shortened); + +const char * +debug_dump_tex_mipfilter(unsigned value, boolean shortened); + +const char * +debug_dump_tex_filter(unsigned value, boolean shortened); + /* FIXME: Move the other debug_dump_xxx functions out of u_debug.h into here. */ diff --git a/src/gallium/auxiliary/util/u_debug_profile.c b/src/gallium/auxiliary/util/u_debug_profile.c deleted file mode 100644 index d765b50144..0000000000 --- a/src/gallium/auxiliary/util/u_debug_profile.c +++ /dev/null @@ -1,320 +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 - * Poor-man profiling. - * - * @author José Fonseca <jrfonseca@tungstengraphics.com> - * - * @sa http://blogs.msdn.com/joshpoley/archive/2008/03/12/poor-man-s-profiler.aspx - * @sa http://www.johnpanzer.com/aci_cuj/index.html - */ - -#include "pipe/p_config.h" - -#if defined(PROFILE) && defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) - -#include <windows.h> -#include <winddi.h> - -#include "util/u_debug.h" -#include "util/u_string.h" - - -#define PROFILE_TABLE_SIZE (1024*1024) -#define FILE_NAME_SIZE 256 - -struct debug_profile_entry -{ - uintptr_t caller; - uintptr_t callee; - uint64_t samples; -}; - -static unsigned long enabled = 0; - -static WCHAR wFileName[FILE_NAME_SIZE] = L"\\??\\c:\\00000000.prof"; -static ULONG_PTR iFile = 0; - -static struct debug_profile_entry *table = NULL; -static unsigned long free_table_entries = 0; -static unsigned long max_table_entries = 0; - -uint64_t start_stamp = 0; -uint64_t end_stamp = 0; - - -static void -debug_profile_entry(uintptr_t caller, uintptr_t callee, uint64_t samples) -{ - unsigned hash = ( caller + callee ) & PROFILE_TABLE_SIZE - 1; - - while(1) { - if(table[hash].caller == 0 && table[hash].callee == 0) { - table[hash].caller = caller; - table[hash].callee = callee; - table[hash].samples = samples; - --free_table_entries; - break; - } - else if(table[hash].caller == caller && table[hash].callee == callee) { - table[hash].samples += samples; - break; - } - else { - ++hash; - } - } -} - - -static uintptr_t caller_stack[1024]; -static unsigned last_caller = 0; - - -static int64_t delta(void) { - int64_t result = end_stamp - start_stamp; - if(result > UINT64_C(0xffffffff)) - result = 0; - return result; -} - - -static void __cdecl -debug_profile_enter(uintptr_t callee) -{ - uintptr_t caller = last_caller ? caller_stack[last_caller - 1] : 0; - - if (caller) - debug_profile_entry(caller, 0, delta()); - debug_profile_entry(caller, callee, 1); - caller_stack[last_caller++] = callee; -} - - -static void __cdecl -debug_profile_exit(uintptr_t callee) -{ - debug_profile_entry(callee, 0, delta()); - if(last_caller) - --last_caller; -} - - -/** - * Called at the start of every method or function. - * - * @sa http://msdn.microsoft.com/en-us/library/c63a9b7h.aspx - */ -void __declspec(naked) __cdecl -_penter(void) { - _asm { - push eax - mov eax, [enabled] - test eax, eax - jz skip - - push edx - - rdtsc - mov dword ptr [end_stamp], eax - mov dword ptr [end_stamp+4], edx - - xor eax, eax - mov [enabled], eax - - mov eax, [esp+8] - - push ebx - push ecx - push ebp - push edi - push esi - - push eax - call debug_profile_enter - add esp, 4 - - pop esi - pop edi - pop ebp - pop ecx - pop ebx - - mov eax, 1 - mov [enabled], eax - - rdtsc - mov dword ptr [start_stamp], eax - mov dword ptr [start_stamp+4], edx - - pop edx -skip: - pop eax - ret - } -} - - -/** - * Called at the end of Calls the end of every method or function. - * - * @sa http://msdn.microsoft.com/en-us/library/xc11y76y.aspx - */ -void __declspec(naked) __cdecl -_pexit(void) { - _asm { - push eax - mov eax, [enabled] - test eax, eax - jz skip - - push edx - - rdtsc - mov dword ptr [end_stamp], eax - mov dword ptr [end_stamp+4], edx - - xor eax, eax - mov [enabled], eax - - mov eax, [esp+8] - - push ebx - push ecx - push ebp - push edi - push esi - - push eax - call debug_profile_exit - add esp, 4 - - pop esi - pop edi - pop ebp - pop ecx - pop ebx - - mov eax, 1 - mov [enabled], eax - - rdtsc - mov dword ptr [start_stamp], eax - mov dword ptr [start_stamp+4], edx - - pop edx -skip: - pop eax - ret - } -} - - -/** - * Reference function for calibration. - */ -void __declspec(naked) -__debug_profile_reference(void) { - _asm { - call _penter - call _pexit - ret - } -} - - -void -debug_profile_start(void) -{ - WCHAR *p; - - /* increment starting from the less significant digit */ - p = &wFileName[14]; - while(1) { - if(*p == '9') { - *p-- = '0'; - } - else { - *p += 1; - break; - } - } - - table = EngMapFile(wFileName, - PROFILE_TABLE_SIZE*sizeof(struct debug_profile_entry), - &iFile); - if(table) { - unsigned i; - - free_table_entries = max_table_entries = PROFILE_TABLE_SIZE; - memset(table, 0, PROFILE_TABLE_SIZE*sizeof(struct debug_profile_entry)); - - table[0].caller = (uintptr_t)&__debug_profile_reference; - table[0].callee = 0; - table[0].samples = 0; - --free_table_entries; - - _asm { - push edx - push eax - - rdtsc - mov dword ptr [start_stamp], eax - mov dword ptr [start_stamp+4], edx - - pop edx - pop eax - } - - last_caller = 0; - - enabled = 1; - - for(i = 0; i < 8; ++i) { - _asm { - call __debug_profile_reference - } - } - } -} - - -void -debug_profile_stop(void) -{ - enabled = 0; - - if(iFile) - EngUnmapFile(iFile); - iFile = 0; - table = NULL; - free_table_entries = max_table_entries = 0; -} - -#endif /* PROFILE */ diff --git a/src/gallium/auxiliary/util/u_fifo.h b/src/gallium/auxiliary/util/u_fifo.h new file mode 100644 index 0000000000..9e007de1ad --- /dev/null +++ b/src/gallium/auxiliary/util/u_fifo.h @@ -0,0 +1,94 @@ +/************************************************************************** + * + * Copyright © 2009 Jakob Bornecrantz + * + * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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_FIFO_H +#define U_FIFO_H + +#include "util/u_memory.h" + +struct util_fifo +{ + size_t head; + size_t tail; + size_t num; + size_t size; +}; + +static INLINE struct util_fifo * +u_fifo_create(size_t size) +{ + struct util_fifo *fifo; + fifo = MALLOC(sizeof(*fifo) + size * sizeof(void*)); + + fifo->head = 0; + fifo->tail = 0; + fifo->num = 0; + fifo->size = size; + + return fifo; +} + +static INLINE boolean +u_fifo_add(struct util_fifo *fifo, void *ptr) +{ + void **array = (void**)&fifo[1]; + if (fifo->num >= fifo->size) + return FALSE; + + if (++fifo->head >= fifo->size) + fifo->head = 0; + + array[fifo->head] = ptr; + + ++fifo->num; + + return TRUE; +} + +static INLINE boolean +u_fifo_pop(struct util_fifo *fifo, void **ptr) +{ + void **array = (void**)&fifo[1]; + + if (!fifo->num) + return FALSE; + + if (++fifo->tail >= fifo->size) + fifo->tail = 0; + + *ptr = array[fifo->tail]; + + ++fifo->num; + + return TRUE; +} + +static INLINE void +u_fifo_destroy(struct util_fifo *fifo) +{ + FREE(fifo); +} + +#endif diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv index 00a46d0cc4..f1bf94f17d 100644 --- a/src/gallium/auxiliary/util/u_format.csv +++ b/src/gallium/auxiliary/util/u_format.csv @@ -2,7 +2,7 @@ PIPE_FORMAT_A8R8G8B8_UNORM , arith , 1, 1, un8 , un8 , un8 , un8 , zyxw, PIPE_FORMAT_X8R8G8B8_UNORM , arith , 1, 1, un8 , un8 , un8 , un8 , zyx1, rgb PIPE_FORMAT_B8G8R8A8_UNORM , arith , 1, 1, un8 , un8 , un8 , un8 , yzwx, rgb PIPE_FORMAT_B8G8R8X8_UNORM , arith , 1, 1, un8 , un8 , un8 , un8 , yzw1, rgb -PIPE_FORMAT_A1R5G5B5_UNORM , arith , 1, 1, un1 , un5 , un5 , un5 , zyxw, rgb +PIPE_FORMAT_A1R5G5B5_UNORM , arith , 1, 1, un5 , un5 , un5 , un1 , zyxw, rgb PIPE_FORMAT_A4R4G4B4_UNORM , arith , 1, 1, un4 , un4 , un4 , un4 , zyxw, rgb PIPE_FORMAT_R5G6B5_UNORM , arith , 1, 1, un5 , un6 , un5 , , zyx1, rgb PIPE_FORMAT_A2B10G10R10_UNORM , arith , 1, 1, un10, un10, un10, un2 , xyzw, rgb @@ -14,10 +14,10 @@ PIPE_FORMAT_L16_UNORM , arith , 1, 1, un16, , , , xxx1, PIPE_FORMAT_Z16_UNORM , array , 1, 1, un16, , , , x___, zs PIPE_FORMAT_Z32_UNORM , array , 1, 1, un32, , , , x___, zs PIPE_FORMAT_Z32_FLOAT , array , 1, 1, f32 , , , , x___, zs -PIPE_FORMAT_S8Z24_UNORM , arith , 1, 1, un8 , un24, , , yx__, zs -PIPE_FORMAT_Z24S8_UNORM , arith , 1, 1, un24, un8 , , , xy__, zs -PIPE_FORMAT_X8Z24_UNORM , arith , 1, 1, un8 , un24, , , y___, zs -PIPE_FORMAT_Z24X8_UNORM , arith , 1, 1, un24, un8 , , , x___, zs +PIPE_FORMAT_S8Z24_UNORM , arith , 1, 1, un24, un8 , , , xy__, zs +PIPE_FORMAT_Z24S8_UNORM , arith , 1, 1, un8 , un24, , , yx__, zs +PIPE_FORMAT_X8Z24_UNORM , arith , 1, 1, un24, un8 , , , x___, zs +PIPE_FORMAT_Z24X8_UNORM , arith , 1, 1, un8 , un24, , , y___, zs PIPE_FORMAT_S8_UNORM , array , 1, 1, un8 , , , , _x__, zs PIPE_FORMAT_R64_FLOAT , array , 1, 1, f64 , , , , x001, rgb PIPE_FORMAT_R64G64_FLOAT , array , 1, 1, f64 , f64 , , , xy01, rgb diff --git a/src/gallium/auxiliary/util/u_hash_table.c b/src/gallium/auxiliary/util/u_hash_table.c index 8c2a8f454c..5604e3ac37 100644 --- a/src/gallium/auxiliary/util/u_hash_table.c +++ b/src/gallium/auxiliary/util/u_hash_table.c @@ -47,7 +47,7 @@ #include "util/u_hash_table.h" -struct hash_table +struct util_hash_table { struct cso_hash *cso; @@ -61,27 +61,27 @@ struct hash_table }; -struct hash_table_item +struct util_hash_table_item { void *key; void *value; }; -static INLINE struct hash_table_item * -hash_table_item(struct cso_hash_iter iter) +static INLINE struct util_hash_table_item * +util_hash_table_item(struct cso_hash_iter iter) { - return (struct hash_table_item *)cso_hash_iter_data(iter); + return (struct util_hash_table_item *)cso_hash_iter_data(iter); } -struct hash_table * -hash_table_create(unsigned (*hash)(void *key), - int (*compare)(void *key1, void *key2)) +struct util_hash_table * +util_hash_table_create(unsigned (*hash)(void *key), + int (*compare)(void *key1, void *key2)) { - struct hash_table *ht; + struct util_hash_table *ht; - ht = MALLOC_STRUCT(hash_table); + ht = MALLOC_STRUCT(util_hash_table); if(!ht) return NULL; @@ -99,16 +99,16 @@ hash_table_create(unsigned (*hash)(void *key), static INLINE struct cso_hash_iter -hash_table_find_iter(struct hash_table *ht, - void *key, - unsigned key_hash) +util_hash_table_find_iter(struct util_hash_table *ht, + void *key, + unsigned key_hash) { struct cso_hash_iter iter; - struct hash_table_item *item; + struct util_hash_table_item *item; iter = cso_hash_find(ht->cso, key_hash); while (!cso_hash_iter_is_null(iter)) { - item = (struct hash_table_item *)cso_hash_iter_data(iter); + item = (struct util_hash_table_item *)cso_hash_iter_data(iter); if (!ht->compare(item->key, key)) break; iter = cso_hash_iter_next(iter); @@ -118,17 +118,17 @@ hash_table_find_iter(struct hash_table *ht, } -static INLINE struct hash_table_item * -hash_table_find_item(struct hash_table *ht, - void *key, - unsigned key_hash) +static INLINE struct util_hash_table_item * +util_hash_table_find_item(struct util_hash_table *ht, + void *key, + unsigned key_hash) { struct cso_hash_iter iter; - struct hash_table_item *item; + struct util_hash_table_item *item; iter = cso_hash_find(ht->cso, key_hash); while (!cso_hash_iter_is_null(iter)) { - item = (struct hash_table_item *)cso_hash_iter_data(iter); + item = (struct util_hash_table_item *)cso_hash_iter_data(iter); if (!ht->compare(item->key, key)) return item; iter = cso_hash_iter_next(iter); @@ -139,12 +139,12 @@ hash_table_find_item(struct hash_table *ht, enum pipe_error -hash_table_set(struct hash_table *ht, - void *key, - void *value) +util_hash_table_set(struct util_hash_table *ht, + void *key, + void *value) { unsigned key_hash; - struct hash_table_item *item; + struct util_hash_table_item *item; struct cso_hash_iter iter; assert(ht); @@ -153,14 +153,14 @@ hash_table_set(struct hash_table *ht, key_hash = ht->hash(key); - item = hash_table_find_item(ht, key, key_hash); + item = util_hash_table_find_item(ht, key, key_hash); if(item) { /* TODO: key/value destruction? */ item->value = value; return PIPE_OK; } - item = MALLOC_STRUCT(hash_table_item); + item = MALLOC_STRUCT(util_hash_table_item); if(!item) return PIPE_ERROR_OUT_OF_MEMORY; @@ -178,11 +178,11 @@ hash_table_set(struct hash_table *ht, void * -hash_table_get(struct hash_table *ht, - void *key) +util_hash_table_get(struct util_hash_table *ht, + void *key) { unsigned key_hash; - struct hash_table_item *item; + struct util_hash_table_item *item; assert(ht); if (!ht) @@ -190,7 +190,7 @@ hash_table_get(struct hash_table *ht, key_hash = ht->hash(key); - item = hash_table_find_item(ht, key, key_hash); + item = util_hash_table_find_item(ht, key, key_hash); if(!item) return NULL; @@ -199,12 +199,12 @@ hash_table_get(struct hash_table *ht, void -hash_table_remove(struct hash_table *ht, - void *key) +util_hash_table_remove(struct util_hash_table *ht, + void *key) { unsigned key_hash; struct cso_hash_iter iter; - struct hash_table_item *item; + struct util_hash_table_item *item; assert(ht); if (!ht) @@ -212,11 +212,11 @@ hash_table_remove(struct hash_table *ht, key_hash = ht->hash(key); - iter = hash_table_find_iter(ht, key, key_hash); + iter = util_hash_table_find_iter(ht, key, key_hash); if(cso_hash_iter_is_null(iter)) return; - item = hash_table_item(iter); + item = util_hash_table_item(iter); assert(item); FREE(item); @@ -225,10 +225,10 @@ hash_table_remove(struct hash_table *ht, void -hash_table_clear(struct hash_table *ht) +util_hash_table_clear(struct util_hash_table *ht) { struct cso_hash_iter iter; - struct hash_table_item *item; + struct util_hash_table_item *item; assert(ht); if (!ht) @@ -236,7 +236,7 @@ hash_table_clear(struct hash_table *ht) iter = cso_hash_first_node(ht->cso); while (!cso_hash_iter_is_null(iter)) { - item = (struct hash_table_item *)cso_hash_take(ht->cso, cso_hash_iter_key(iter)); + item = (struct util_hash_table_item *)cso_hash_take(ht->cso, cso_hash_iter_key(iter)); FREE(item); iter = cso_hash_first_node(ht->cso); } @@ -244,12 +244,13 @@ hash_table_clear(struct hash_table *ht) enum pipe_error -hash_table_foreach(struct hash_table *ht, - enum pipe_error (*callback)(void *key, void *value, void *data), - void *data) +util_hash_table_foreach(struct util_hash_table *ht, + enum pipe_error (*callback) + (void *key, void *value, void *data), + void *data) { struct cso_hash_iter iter; - struct hash_table_item *item; + struct util_hash_table_item *item; enum pipe_error result; assert(ht); @@ -258,7 +259,7 @@ hash_table_foreach(struct hash_table *ht, iter = cso_hash_first_node(ht->cso); while (!cso_hash_iter_is_null(iter)) { - item = (struct hash_table_item *)cso_hash_iter_data(iter); + item = (struct util_hash_table_item *)cso_hash_iter_data(iter); result = callback(item->key, item->value, data); if(result != PIPE_OK) return result; @@ -270,10 +271,10 @@ hash_table_foreach(struct hash_table *ht, void -hash_table_destroy(struct hash_table *ht) +util_hash_table_destroy(struct util_hash_table *ht) { struct cso_hash_iter iter; - struct hash_table_item *item; + struct util_hash_table_item *item; assert(ht); if (!ht) @@ -281,7 +282,7 @@ hash_table_destroy(struct hash_table *ht) iter = cso_hash_first_node(ht->cso); while (!cso_hash_iter_is_null(iter)) { - item = (struct hash_table_item *)cso_hash_iter_data(iter); + item = (struct util_hash_table_item *)cso_hash_iter_data(iter); FREE(item); iter = cso_hash_iter_next(iter); } diff --git a/src/gallium/auxiliary/util/u_hash_table.h b/src/gallium/auxiliary/util/u_hash_table.h index feee881582..51ec10a804 100644 --- a/src/gallium/auxiliary/util/u_hash_table.h +++ b/src/gallium/auxiliary/util/u_hash_table.h @@ -35,7 +35,7 @@ #define U_HASH_TABLE_H_ -#include "pipe/p_error.h" +#include "pipe/p_defines.h" #ifdef __cplusplus @@ -46,7 +46,7 @@ extern "C" { /** * Generic purpose hash table. */ -struct hash_table; +struct util_hash_table; /** @@ -55,37 +55,38 @@ struct hash_table; * @param hash hash function * @param compare should return 0 for two equal keys. */ -struct hash_table * -hash_table_create(unsigned (*hash)(void *key), - int (*compare)(void *key1, void *key2)); +struct util_hash_table * +util_hash_table_create(unsigned (*hash)(void *key), + int (*compare)(void *key1, void *key2)); enum pipe_error -hash_table_set(struct hash_table *ht, - void *key, - void *value); +util_hash_table_set(struct util_hash_table *ht, + void *key, + void *value); void * -hash_table_get(struct hash_table *ht, - void *key); +util_hash_table_get(struct util_hash_table *ht, + void *key); void -hash_table_remove(struct hash_table *ht, - void *key); +util_hash_table_remove(struct util_hash_table *ht, + void *key); void -hash_table_clear(struct hash_table *ht); +util_hash_table_clear(struct util_hash_table *ht); enum pipe_error -hash_table_foreach(struct hash_table *ht, - enum pipe_error (*callback)(void *key, void *value, void *data), - void *data); +util_hash_table_foreach(struct util_hash_table *ht, + enum pipe_error (*callback) + (void *key, void *value, void *data), + void *data); void -hash_table_destroy(struct hash_table *ht); +util_hash_table_destroy(struct util_hash_table *ht); #ifdef __cplusplus diff --git a/src/gallium/auxiliary/util/u_keymap.c b/src/gallium/auxiliary/util/u_keymap.c index 508a2ee063..c4b9eb3d9b 100644 --- a/src/gallium/auxiliary/util/u_keymap.c +++ b/src/gallium/auxiliary/util/u_keymap.c @@ -28,7 +28,7 @@ /** * Key lookup/associative container. * - * Like Jose's u_hash_table, based on CSO cache code for now. + * Like Jose's util_hash_table, based on CSO cache code for now. * * Author: Brian Paul */ @@ -36,7 +36,7 @@ #include "pipe/p_compiler.h" #include "util/u_debug.h" -#include "pipe/p_error.h" +#include "pipe/p_defines.h" #include "cso_cache/cso_hash.h" diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h index 4c6c2bc00e..75b075f160 100644 --- a/src/gallium/auxiliary/util/u_math.h +++ b/src/gallium/auxiliary/util/u_math.h @@ -283,6 +283,14 @@ util_fast_pow(float x, float y) return util_fast_exp2(util_fast_log2(x) * y); } +/* Note that this counts zero as a power of two. + */ +static INLINE boolean +util_is_power_of_two( unsigned v ) +{ + return (v & (v-1)) == 0; +} + /** * Floor(x), returned as int. @@ -341,10 +349,22 @@ util_is_inf_or_nan(float x) /** + * Test whether x is a power of two. + */ +static INLINE boolean +util_is_pot(unsigned x) +{ + return (x & (x - 1)) == 0; +} + + +/** * Find first bit set in word. Least significant bit is 1. * Return 0 if no bits set. */ -#if defined(_MSC_VER) && _MSC_VER >= 1300 +#if defined(_MSC_VER) && _MSC_VER >= 1300 && (_M_IX86 || _M_AMD64 || _M_IA64) +unsigned char _BitScanForward(unsigned long* Index, unsigned long Mask); +#pragma intrinsic(_BitScanForward) static INLINE unsigned long ffs( unsigned long u ) { @@ -451,6 +471,26 @@ util_logbase2(unsigned n) /** + * Returns the smallest power of two >= x + */ +static INLINE unsigned +util_next_power_of_two(unsigned x) +{ + unsigned i; + + if (x == 0) + return 1; + + --x; + + for (i = 1; i < sizeof(unsigned) * 8; i <<= 1) + x |= x >> i; + + return x + 1; +} + + +/** * Clamp X to [MIN, MAX]. * This is a macro to allow float, int, uint, etc. types. */ diff --git a/src/gallium/auxiliary/util/u_mm.c b/src/gallium/auxiliary/util/u_mm.c index 4b75d4ba1d..82f83702d1 100644 --- a/src/gallium/auxiliary/util/u_mm.c +++ b/src/gallium/auxiliary/util/u_mm.c @@ -39,13 +39,20 @@ u_mmDumpMemInfo(const struct mem_block *heap) } else { const struct mem_block *p; + int total_used = 0, total_free = 0; for (p = heap->next; p != heap; p = p->next) { debug_printf(" Offset:%08x, Size:%08x, %c%c\n", p->ofs, p->size, p->free ? 'F':'.', p->reserved ? 'R':'.'); + if (p->free) + total_free += p->size; + else + total_used += p->size; } + debug_printf("'\nMemory stats: total = %d, used = %d, free = %d\n", + total_used + total_free, total_used, total_free); debug_printf("\nFree list:\n"); for (p = heap->next_free; p != heap; p = p->next_free) { diff --git a/src/gallium/auxiliary/util/u_simple_screen.c b/src/gallium/auxiliary/util/u_simple_screen.c index f01296b40f..5238299015 100644 --- a/src/gallium/auxiliary/util/u_simple_screen.c +++ b/src/gallium/auxiliary/util/u_simple_screen.c @@ -52,8 +52,7 @@ pass_user_buffer_create(struct pipe_screen *screen, unsigned bytes) { struct pipe_buffer *buffer = - screen->winsys->user_buffer_create(screen->winsys, - ptr, bytes); + screen->winsys->user_buffer_create(screen->winsys, ptr, bytes); buffer->screen = screen; @@ -69,9 +68,8 @@ pass_surface_buffer_create(struct pipe_screen *screen, unsigned *stride) { struct pipe_buffer *buffer = - screen->winsys->surface_buffer_create(screen->winsys, - width, height, - format, usage, tex_usage, stride); + screen->winsys->surface_buffer_create(screen->winsys, width, height, + format, usage, tex_usage, stride); buffer->screen = screen; @@ -83,8 +81,7 @@ pass_buffer_map(struct pipe_screen *screen, struct pipe_buffer *buf, unsigned usage) { - return screen->winsys->buffer_map(screen->winsys, - buf, usage); + return screen->winsys->buffer_map(screen->winsys, buf, usage); } static void @@ -106,8 +103,7 @@ pass_flush_frontbuffer(struct pipe_screen *screen, struct pipe_surface *surf, void *context_private) { - screen->winsys->flush_frontbuffer(screen->winsys, - surf, context_private); + screen->winsys->flush_frontbuffer(screen->winsys, surf, context_private); } static void @@ -115,8 +111,7 @@ pass_fence_reference(struct pipe_screen *screen, struct pipe_fence_handle **ptr, struct pipe_fence_handle *fence) { - screen->winsys->fence_reference(screen->winsys, - ptr, fence); + screen->winsys->fence_reference(screen->winsys, ptr, fence); } static int @@ -124,8 +119,7 @@ pass_fence_signalled(struct pipe_screen *screen, struct pipe_fence_handle *fence, unsigned flag) { - return screen->winsys->fence_signalled(screen->winsys, - fence, flag); + return screen->winsys->fence_signalled(screen->winsys, fence, flag); } static int @@ -133,11 +127,11 @@ pass_fence_finish(struct pipe_screen *screen, struct pipe_fence_handle *fence, unsigned flag) { - return screen->winsys->fence_finish(screen->winsys, - fence, flag); + return screen->winsys->fence_finish(screen->winsys, fence, flag); } -void u_simple_screen_init(struct pipe_screen *screen) +void +u_simple_screen_init(struct pipe_screen *screen) { screen->buffer_create = pass_buffer_create; screen->user_buffer_create = pass_user_buffer_create; @@ -152,7 +146,8 @@ void u_simple_screen_init(struct pipe_screen *screen) screen->fence_finish = pass_fence_finish; } -const char* u_simple_screen_winsys_name(struct pipe_screen *screen) +const char * +u_simple_screen_winsys_name(struct pipe_screen *screen) { return screen->winsys->get_name(screen->winsys); } diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c index ab754296fa..1c8b157d91 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/src/gallium/auxiliary/util/u_simple_shaders.c @@ -34,14 +34,8 @@ #include "pipe/p_context.h" -#include "util/u_debug.h" -#include "pipe/p_defines.h" -#include "pipe/p_screen.h" #include "pipe/p_shader_tokens.h" - -#include "util/u_memory.h" #include "util/u_simple_shaders.h" - #include "tgsi/tgsi_ureg.h" @@ -67,9 +61,7 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe, struct ureg_src src; struct ureg_dst dst; - src = ureg_DECL_vs_input( ureg, - semantic_names[i], - semantic_indexes[i]); + src = ureg_DECL_vs_input( ureg, i ); dst = ureg_DECL_output( ureg, semantic_names[i], @@ -116,7 +108,15 @@ util_make_fragment_tex_shader_writemask(struct pipe_context *pipe, TGSI_SEMANTIC_COLOR, 0 ); - ureg_TEX( ureg, out, TGSI_TEXTURE_2D, tex, sampler ); + if (writemask != TGSI_WRITEMASK_XYZW) { + struct ureg_src imm = ureg_imm4f( ureg, 0, 0, 0, 1 ); + + ureg_MOV( ureg, out, imm ); + } + + ureg_TEX( ureg, + ureg_writemask(out, writemask), + TGSI_TEXTURE_2D, tex, sampler ); ureg_END( ureg ); return ureg_create_shader_and_destroy( ureg, pipe ); diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c index 1235a67d26..8a22f584be 100644 --- a/src/gallium/auxiliary/util/u_tile.c +++ b/src/gallium/auxiliary/util/u_tile.c @@ -170,7 +170,7 @@ x8r8g8b8_get_tile_rgba(const unsigned *src, pRow[0] = ubyte_to_float((pixel >> 16) & 0xff); pRow[1] = ubyte_to_float((pixel >> 8) & 0xff); pRow[2] = ubyte_to_float((pixel >> 0) & 0xff); - pRow[3] = ubyte_to_float(0xff); + pRow[3] = 1.0F; } p += dst_stride; } @@ -394,6 +394,52 @@ r5g6b5_put_tile_rgba(ushort *dst, +/*** PIPE_FORMAT_R8G8B8_UNORM ***/ + +static void +r8g8b8_get_tile_rgba(const ubyte *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + pRow[0] = ubyte_to_float(src[0]); + pRow[1] = ubyte_to_float(src[1]); + pRow[2] = ubyte_to_float(src[2]); + pRow[3] = 1.0f; + src += 3; + } + p += dst_stride; + } +} + + +static void +r8g8b8_put_tile_rgba(ubyte *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + dst[0] = float_to_ubyte(pRow[0]); + dst[1] = float_to_ubyte(pRow[1]); + dst[2] = float_to_ubyte(pRow[2]); + dst += 3; + } + p += src_stride; + } +} + + + /*** PIPE_FORMAT_Z16_UNORM ***/ /** @@ -1106,6 +1152,9 @@ pipe_tile_raw_to_rgba(enum pipe_format format, case PIPE_FORMAT_R5G6B5_UNORM: r5g6b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); break; + case PIPE_FORMAT_R8G8B8_UNORM: + r8g8b8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); + break; case PIPE_FORMAT_L8_UNORM: l8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); break; @@ -1222,6 +1271,9 @@ pipe_put_tile_rgba(struct pipe_transfer *pt, case PIPE_FORMAT_R5G6B5_UNORM: r5g6b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); break; + case PIPE_FORMAT_R8G8B8_UNORM: + r8g8b8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); + break; case PIPE_FORMAT_R8G8B8A8_UNORM: assert(0); break; @@ -1400,7 +1452,7 @@ pipe_put_tile_z(struct pipe_transfer *pt, case PIPE_FORMAT_S8Z24_UNORM: { uint *pDest = (uint *) (map + y * pt->stride + x*4); - assert(pt->usage == PIPE_TRANSFER_READ_WRITE); + assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 32-bit Z to 24-bit Z, preserve stencil */ @@ -1427,7 +1479,7 @@ pipe_put_tile_z(struct pipe_transfer *pt, case PIPE_FORMAT_Z24S8_UNORM: { uint *pDest = (uint *) (map + y * pt->stride + x*4); - assert(pt->usage == PIPE_TRANSFER_READ_WRITE); + assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 32-bit Z to 24-bit Z, preserve stencil */ diff --git a/src/gallium/auxiliary/util/u_upload_mgr.c b/src/gallium/auxiliary/util/u_upload_mgr.c index eb635c9f14..975ee89c45 100644 --- a/src/gallium/auxiliary/util/u_upload_mgr.c +++ b/src/gallium/auxiliary/util/u_upload_mgr.c @@ -29,7 +29,7 @@ * coalescing small buffers into larger ones. */ -#include "pipe/p_error.h" +#include "pipe/p_defines.h" #include "pipe/p_inlines.h" #include "pipe/p_screen.h" #include "util/u_memory.h" |