summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/util
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2008-03-25 12:14:49 +1100
committerBen Skeggs <skeggsb@gmail.com>2008-03-25 12:14:49 +1100
commit9e1f7b2c57154704d5881362a44da703b7a4a00f (patch)
tree9cd0ca55f1eb9a0908ae76f65cfda107a7aec0ca /src/gallium/auxiliary/util
parent601b018a9a6143c634239d5bb51616724c2e593d (diff)
parent4654803e2595ea041ea83baf5e13e6c68890e9a7 (diff)
Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
Diffstat (limited to 'src/gallium/auxiliary/util')
-rw-r--r--src/gallium/auxiliary/util/SConscript1
-rw-r--r--src/gallium/auxiliary/util/p_debug.c213
-rw-r--r--src/gallium/auxiliary/util/p_debug_mem.c172
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c26
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.h3
5 files changed, 347 insertions, 68 deletions
diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript
index b44f2d5e39..9b3929eb2d 100644
--- a/src/gallium/auxiliary/util/SConscript
+++ b/src/gallium/auxiliary/util/SConscript
@@ -4,6 +4,7 @@ util = env.ConvenienceLibrary(
target = 'util',
source = [
'p_debug.c',
+ 'p_debug_mem.c',
'p_tile.c',
'p_util.c',
'u_blit.c',
diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c
index c51e9e6a69..cc036dabf8 100644
--- a/src/gallium/auxiliary/util/p_debug.c
+++ b/src/gallium/auxiliary/util/p_debug.c
@@ -58,7 +58,7 @@ int rpl_snprintf(char *str, size_t size, const char *format, ...);
#endif
-void debug_vprintf(const char *format, va_list ap)
+void _debug_vprintf(const char *format, va_list ap)
{
#ifdef WIN32
#ifndef WINCE
@@ -76,15 +76,7 @@ void debug_vprintf(const char *format, va_list ap)
}
-void debug_printf(const char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
- debug_vprintf(format, ap);
- va_end(ap);
-}
-
-
+#ifdef DEBUG
void debug_print_blob( const char *name,
const void *blob,
unsigned size )
@@ -99,12 +91,10 @@ void debug_print_blob( const char *name,
debug_printf("%d:\t%08x\n", i, ublob[i]);
}
}
+#endif
-/* TODO: implement a debug_abort that calls EngBugCheckEx on WIN32 */
-
-
-static INLINE void debug_break(void)
+void _debug_break(void)
{
#if (defined(__i386__) || defined(__386__)) && defined(__GNUC__)
__asm("int3");
@@ -117,6 +107,150 @@ static INLINE void debug_break(void)
#endif
}
+
+#ifdef WIN32
+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 *
+debug_get_option(const char *name, const char *dfault)
+{
+ const char *result;
+#ifdef WIN32
+ 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)
+ result = dfault;
+ else {
+ 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);
+ }
+#else
+
+ result = getenv(name);
+ if(!result)
+ result = dfault;
+#endif
+
+ if(result)
+ debug_printf("%s: %s = %s\n", __FUNCTION__, name, result);
+ else
+ debug_printf("%s: %s = (null)\n", __FUNCTION__, name);
+
+ return result;
+}
+
+boolean
+debug_get_bool_option(const char *name, boolean dfault)
+{
+ const char *str = debug_get_option(name, NULL);
+ boolean result;
+
+ if(str == NULL)
+ result = dfault;
+ else if(!strcmp(str, "no"))
+ result = FALSE;
+ else if(!strcmp(str, "0"))
+ result = FALSE;
+ else if(!strcmp(str, "f"))
+ result = FALSE;
+ else if(!strcmp(str, "false"))
+ result = FALSE;
+ else
+ result = TRUE;
+
+ debug_printf("%s: %s = %s\n", __FUNCTION__, name, result ? "TRUE" : "FALSE");
+
+ return result;
+}
+
+
+long
+debug_get_num_option(const char *name, long dfault)
+{
+ /* FIXME */
+ return dfault;
+}
+
+
+unsigned long
+debug_get_flags_option(const char *name,
+ const struct debug_named_value *flags,
+ unsigned long dfault)
+{
+ unsigned long result;
+ const char *str;
+
+ str = debug_get_option(name, NULL);
+ if(!str)
+ result = dfault;
+ else {
+ result = 0;
+ while( flags->name ) {
+ if (!strcmp(str, "all") || strstr(str, flags->name ))
+ result |= flags->value;
+ ++flags;
+ }
+ }
+
+ debug_printf("%s: %s = 0x%lx\n", __FUNCTION__, name, result);
+
+ return result;
+}
+
+
#if defined(WIN32)
ULONG_PTR debug_config_file = 0;
void *mapped_config_file = 0;
@@ -126,7 +260,7 @@ enum {
};
/* Check for aborts enabled. */
-static unsigned abort_en()
+static unsigned abort_en(void)
{
if (!mapped_config_file)
{
@@ -149,59 +283,28 @@ static unsigned abort_en()
return ((((char *)mapped_config_file)[0]) - 0x30) & eAssertAbortEn;
}
#else /* WIN32 */
-static unsigned abort_en()
+static unsigned abort_en(void)
{
return !GETENV("GALLIUM_ABORT_ON_ASSERT");
}
#endif
-void debug_assert_fail(const char *expr, const char *file, unsigned line)
+void _debug_assert_fail(const char *expr,
+ const char *file,
+ unsigned line,
+ const char *function)
{
- debug_printf("%s:%i: Assertion `%s' failed.\n", file, line, expr);
+ _debug_printf("%s:%u:%s: Assertion `%s' failed.\n", file, line, function, expr);
if (abort_en())
{
debug_break();
} else
{
- debug_printf("continuing...\n");
+ _debug_printf("continuing...\n");
}
}
-#define DEBUG_MASK_TABLE_SIZE 256
-
-
-/**
- * Mask hash table.
- *
- * For now we just take the lower bits of the key, and do no attempt to solve
- * collisions. Use a proper hash table when we have dozens of drivers.
- */
-static uint32_t debug_mask_table[DEBUG_MASK_TABLE_SIZE];
-
-
-void debug_mask_set(uint32_t uuid, uint32_t mask)
-{
- unsigned hash = uuid & (DEBUG_MASK_TABLE_SIZE - 1);
- debug_mask_table[hash] = mask;
-}
-
-
-uint32_t debug_mask_get(uint32_t uuid)
-{
- unsigned hash = uuid & (DEBUG_MASK_TABLE_SIZE - 1);
- return debug_mask_table[hash];
-}
-
-
-void debug_mask_vprintf(uint32_t uuid, uint32_t what, const char *format, va_list ap)
-{
- uint32_t mask = debug_mask_get(uuid);
- if(mask & what)
- debug_vprintf(format, ap);
-}
-
-
const char *
debug_dump_enum(const struct debug_named_value *names,
unsigned long value)
@@ -214,7 +317,7 @@ debug_dump_enum(const struct debug_named_value *names,
++names;
}
- snprintf(rest, sizeof(rest), "0x%08x", value);
+ snprintf(rest, sizeof(rest), "0x%08lx", value);
return rest;
}
@@ -247,7 +350,7 @@ debug_dump_flags(const struct debug_named_value *names,
else
first = 0;
- snprintf(rest, sizeof(rest), "0x%08x", value);
+ snprintf(rest, sizeof(rest), "0x%08lx", value);
strncat(output, rest, sizeof(output));
}
diff --git a/src/gallium/auxiliary/util/p_debug_mem.c b/src/gallium/auxiliary/util/p_debug_mem.c
new file mode 100644
index 0000000000..c160afe5b7
--- /dev/null
+++ b/src/gallium/auxiliary/util/p_debug_mem.c
@@ -0,0 +1,172 @@
+/**************************************************************************
+ *
+ * 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
+ * Memory debugging.
+ *
+ * @author José Fonseca <jrfonseca@tungstengraphics.com>
+ */
+
+#ifdef WIN32
+#include <windows.h>
+#include <winddi.h>
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+
+#include "pipe/p_debug.h"
+#include "util/u_double_list.h"
+
+
+#define DEBUG_MEMORY_MAGIC 0x6e34090aU
+
+
+#if defined(WIN32) && !defined(WINCE)
+#define real_malloc(_size) EngAllocMem(0, _size, 'D3AG')
+#define real_free(_ptr) EngFreeMem(_ptr)
+#else
+#define real_malloc(_size) malloc(_size)
+#define real_free(_ptr) free(_ptr)
+#endif
+
+
+struct debug_memory_header
+{
+ struct list_head head;
+
+ unsigned long no;
+ const char *file;
+ unsigned line;
+ const char *function;
+ size_t size;
+ unsigned magic;
+};
+
+static struct list_head list = { &list, &list };
+
+static unsigned long start_no = 0;
+static unsigned long end_no = 0;
+
+
+void *
+debug_malloc(const char *file, unsigned line, const char *function,
+ size_t size)
+{
+ struct debug_memory_header *hdr;
+
+ hdr = real_malloc(sizeof(*hdr) + size);
+ if(!hdr)
+ return NULL;
+
+ hdr->no = end_no++;
+ hdr->file = file;
+ hdr->line = line;
+ hdr->function = function;
+ hdr->size = size;
+ hdr->magic = DEBUG_MEMORY_MAGIC;
+
+ LIST_ADDTAIL(&hdr->head, &list);
+
+ return (void *)((char *)hdr + sizeof(*hdr));
+}
+
+void
+debug_free(const char *file, unsigned line, const char *function,
+ void *ptr)
+{
+ struct debug_memory_header *hdr;
+
+ if(!ptr)
+ return;
+
+ hdr = (struct debug_memory_header *)((char *)ptr - sizeof(*hdr));
+ if(hdr->magic != DEBUG_MEMORY_MAGIC) {
+ debug_printf("%s:%u:%s: freeing bad or corrupted memory %p\n",
+ file, line, function,
+ ptr);
+ debug_assert(0);
+ return;
+ }
+
+ LIST_DEL(&hdr->head);
+ hdr->magic = 0;
+
+ real_free(hdr);
+}
+
+void *
+debug_calloc(const char *file, unsigned line, const char *function,
+ size_t count, size_t size )
+{
+ void *ptr = debug_malloc( file, line, function, count * size );
+ if( ptr )
+ memset( ptr, 0, count * size );
+ return ptr;
+}
+
+void *
+debug_realloc(const char *file, unsigned line, const char *function,
+ void *old_ptr, size_t old_size, size_t new_size )
+{
+ void *new_ptr = NULL;
+
+ if (new_size != 0) {
+ new_ptr = debug_malloc( file, line, function, new_size );
+
+ if( new_ptr && old_ptr )
+ memcpy( new_ptr, old_ptr, old_size );
+ }
+
+ debug_free( file, line, function, old_ptr );
+ return new_ptr;
+}
+
+void
+debug_memory_reset(void)
+{
+ start_no = end_no;
+}
+
+void
+debug_memory_report(void)
+{
+ struct list_head *entry;
+
+ entry = list.prev;
+ for (; entry != &list; entry = entry->prev) {
+ struct debug_memory_header *hdr;
+ void *ptr;
+ hdr = LIST_ENTRY(struct debug_memory_header, entry, head);
+ ptr = (void *)((char *)hdr + sizeof(*hdr));
+ if(hdr->no >= start_no)
+ debug_printf("%s:%u:%s: %u bytes at %p not freed\n",
+ hdr->file, hdr->line, hdr->function,
+ hdr->size, ptr);
+ }
+}
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index cf02f00b1b..e129c062be 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -719,8 +719,6 @@ util_create_gen_mipmap(struct pipe_context *pipe,
ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
- ctx->sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
- ctx->sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
ctx->sampler.normalized_coords = 1;
@@ -774,23 +772,23 @@ set_vertex_data(struct gen_mipmap_state *ctx, float width, float height)
{
void *buf;
- ctx->vertices[0][0][0] = 0.0f; /*x*/
- ctx->vertices[0][0][1] = 0.0f; /*y*/
+ ctx->vertices[0][0][0] = -0.5f; /*x*/
+ ctx->vertices[0][0][1] = -0.5f; /*y*/
ctx->vertices[0][1][0] = 0.0f; /*s*/
ctx->vertices[0][1][1] = 0.0f; /*t*/
- ctx->vertices[1][0][0] = width; /*x*/
- ctx->vertices[1][0][1] = 0.0f; /*y*/
+ ctx->vertices[1][0][0] = width - 0.5f; /*x*/
+ ctx->vertices[1][0][1] = -0.5f; /*y*/
ctx->vertices[1][1][0] = 1.0f; /*s*/
ctx->vertices[1][1][1] = 0.0f; /*t*/
- ctx->vertices[2][0][0] = width;
- ctx->vertices[2][0][1] = height;
+ ctx->vertices[2][0][0] = width - 0.5f;
+ ctx->vertices[2][0][1] = height - 0.5f;
ctx->vertices[2][1][0] = 1.0f;
ctx->vertices[2][1][1] = 1.0f;
- ctx->vertices[3][0][0] = 0.0f;
- ctx->vertices[3][0][1] = height;
+ ctx->vertices[3][0][0] = -0.5f;
+ ctx->vertices[3][0][1] = height - 0.5f;
ctx->vertices[3][1][0] = 0.0f;
ctx->vertices[3][1][1] = 1.0f;
@@ -849,11 +847,13 @@ simple_viewport(struct pipe_context *pipe, uint width, uint height)
* \param face which cube face to generate mipmaps for (0 for non-cube maps)
* \param baseLevel the first mipmap level to use as a src
* \param lastLevel the last mipmap level to generate
+ * \param filter the minification filter used to generate mipmap levels with
+ * \param filter one of PIPE_TEX_FILTER_LINEAR, PIPE_TEX_FILTER_NEAREST
*/
void
util_gen_mipmap(struct gen_mipmap_state *ctx,
struct pipe_texture *pt,
- uint face, uint baseLevel, uint lastLevel)
+ uint face, uint baseLevel, uint lastLevel, uint filter)
{
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
@@ -890,6 +890,10 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
memset(&fb, 0, sizeof(fb));
fb.num_cbufs = 1;
+ /* set min/mag to same filter for faster sw speed */
+ ctx->sampler.mag_img_filter = filter;
+ ctx->sampler.min_img_filter = filter;
+
/*
* XXX for small mipmap levels, it may be faster to use the software
* fallback path...
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.h b/src/gallium/auxiliary/util/u_gen_mipmap.h
index eeabf3bf07..bd9af54fb7 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.h
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.h
@@ -50,7 +50,6 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx);
extern void
util_gen_mipmap(struct gen_mipmap_state *ctx,
struct pipe_texture *pt,
- uint face, uint baseLevel, uint lastLevel);
-
+ uint face, uint baseLevel, uint lastLevel, uint filter);
#endif