summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/util
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2008-07-23 14:05:22 +1000
committerBen Skeggs <skeggsb@gmail.com>2008-07-23 14:05:22 +1000
commit704dca40c4e0e983c07d84c3a32f8f9dc78a5543 (patch)
treebdcc585315d88274ec795b7206a143d562f54a76 /src/gallium/auxiliary/util
parent0c25ac52425e6d6eb037b99ab90f41b47e3f4491 (diff)
parent7f3d6e74817e8880a0712c85f2b41fd88cf6a347 (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/p_debug.c32
-rw-r--r--src/gallium/auxiliary/util/p_debug_prof.c269
-rw-r--r--src/gallium/auxiliary/util/p_tile.c119
-rw-r--r--src/gallium/auxiliary/util/p_tile.h7
-rw-r--r--src/gallium/auxiliary/util/u_blit.c12
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c3
6 files changed, 321 insertions, 121 deletions
diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c
index 7b28900a25..b0240ad737 100644
--- a/src/gallium/auxiliary/util/p_debug.c
+++ b/src/gallium/auxiliary/util/p_debug.c
@@ -174,20 +174,19 @@ copy(char *dst, const char *start, const char *end, size_t n)
#endif
-const char *
-debug_get_option(const char *name, const char *dfault)
+static INLINE const char *
+_debug_get_option(const char *name)
{
- const char *result;
#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];
- result = dfault;
pMap = EngMapFile(L"\\??\\c:\\gallium.cfg", 0, &iFile);
if(pMap) {
sol = (const char *)pMap;
@@ -208,18 +207,27 @@ debug_get_option(const char *name, const char *dfault)
}
EngUnmapFile(iFile);
}
+ return result;
#else
- result = dfault;
+ return NULL;
#endif
#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE)
/* TODO: implement */
- result = dfault;
+ return NULL;
#else
- result = getenv(name);
- if(!result)
- result = dfault;
+ return getenv(name);
#endif
+}
+const char *
+debug_get_option(const char *name, const char *dfault)
+{
+ const char *result;
+
+ result = _debug_get_option(name);
+ if(!result)
+ result = dfault;
+
debug_printf("%s: %s = %s\n", __FUNCTION__, name, result ? result : "(null)");
return result;
@@ -228,7 +236,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, NULL);
+ const char *str = _debug_get_option(name);
boolean result;
if(str == NULL)
@@ -258,7 +266,7 @@ debug_get_num_option(const char *name, long dfault)
long result;
const char *str;
- str = debug_get_option(name, NULL);
+ str = _debug_get_option(name);
if(!str)
result = dfault;
else {
@@ -294,7 +302,7 @@ debug_get_flags_option(const char *name,
unsigned long result;
const char *str;
- str = debug_get_option(name, NULL);
+ str = _debug_get_option(name);
if(!str)
result = dfault;
else {
diff --git a/src/gallium/auxiliary/util/p_debug_prof.c b/src/gallium/auxiliary/util/p_debug_prof.c
index 958f99c327..5f9772ef91 100644
--- a/src/gallium/auxiliary/util/p_debug_prof.c
+++ b/src/gallium/auxiliary/util/p_debug_prof.c
@@ -46,15 +46,86 @@
#include "util/u_string.h"
-#define PROFILE_FILE_SIZE 4*1024*1024
+#define PROFILE_TABLE_SIZE (1024*1024)
#define FILE_NAME_SIZE 256
-static WCHAR wFileName[FILE_NAME_SIZE];
+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 void *pMap = NULL;
-static void *pMapEnd = NULL;
+
+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.
*
@@ -63,27 +134,49 @@ static void *pMapEnd = NULL;
void __declspec(naked) __cdecl
_penter(void) {
_asm {
- push ebx
- mov ebx, [pMap]
- test ebx, ebx
- jz done
- cmp ebx, [pMapEnd]
- je done
push eax
+ mov eax, [enabled]
+ test eax, eax
+ jz skip
+
push edx
- mov eax, [esp+12]
- and eax, 0xfffffffe
- mov [ebx], eax
- add ebx, 4
+
rdtsc
- mov [ebx], eax
- add ebx, 4
- mov [pMap], ebx
+ 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
-done:
- pop ebx
- ret
+ ret
}
}
@@ -96,46 +189,60 @@ done:
void __declspec(naked) __cdecl
_pexit(void) {
_asm {
- push ebx
- mov ebx, [pMap]
- test ebx, ebx
- jz done
- cmp ebx, [pMapEnd]
- je done
push eax
+ mov eax, [enabled]
+ test eax, eax
+ jz skip
+
push edx
- mov eax, [esp+12]
- or eax, 0x00000001
- mov [ebx], eax
- add ebx, 4
+
rdtsc
- mov [ebx], eax
- add ebx, 4
- mov [pMap], ebx
- pop edx
- pop eax
-done:
+ 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
- ret
- }
-}
+ mov eax, 1
+ mov [enabled], eax
-void __declspec(naked)
-__debug_profile_reference1(void) {
- _asm {
- call _penter
- call _pexit
+ 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_reference2(void) {
+__debug_profile_reference(void) {
_asm {
call _penter
- call __debug_profile_reference1
call _pexit
ret
}
@@ -145,31 +252,69 @@ __debug_profile_reference2(void) {
void
debug_profile_start(void)
{
- static unsigned no = 0;
- char filename[FILE_NAME_SIZE];
- unsigned i;
+ WCHAR *p;
- util_snprintf(filename, sizeof(filename), "\\??\\c:\\%03u.prof", ++no);
- for(i = 0; i < FILE_NAME_SIZE; ++i)
- wFileName[i] = (WCHAR)filename[i];
-
- pMap = EngMapFile(wFileName, PROFILE_FILE_SIZE, &iFile);
- if(pMap) {
- pMapEnd = (unsigned char*)pMap + PROFILE_FILE_SIZE;
- /* reference functions for calibration purposes */
- __debug_profile_reference2();
+ // 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)
{
- if(iFile) {
+ enabled = 0;
+
+ if(iFile)
EngUnmapFile(iFile);
- /* TODO: truncate file */
- }
iFile = 0;
- pMapEnd = pMap = NULL;
+ table = NULL;
+ free_table_entries = max_table_entries = 0;
}
#endif /* PROFILE */
diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c
index 1a1a2d96cc..1bf0d72733 100644
--- a/src/gallium/auxiliary/util/p_tile.c
+++ b/src/gallium/auxiliary/util/p_tile.c
@@ -346,7 +346,7 @@ r5g6b5_get_tile_rgba(ushort *src,
static void
-r5g5b5_put_tile_rgba(ushort *dst,
+r5g6b5_put_tile_rgba(ushort *dst,
unsigned w, unsigned h,
const float *p,
unsigned src_stride)
@@ -632,13 +632,10 @@ ycbcr_get_tile_rgba(ushort *src,
const float scale = 1.0f / 255.0f;
unsigned i, j;
- /* we're assuming we're being asked for an even number of texels */
- assert((w & 1) == 0);
-
for (i = 0; i < h; i++) {
float *pRow = p;
/* do two texels at a time */
- for (j = 0; j < w; j += 2, src += 2) {
+ for (j = 0; j < (w & ~1); j += 2, src += 2) {
const ushort t0 = src[0];
const ushort t1 = src[1];
const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */
@@ -676,87 +673,125 @@ ycbcr_get_tile_rgba(ushort *src,
pRow += 4;
}
+ /* do the last texel */
+ if (w & 1) {
+ const ushort t0 = src[0];
+ const ushort t1 = src[1];
+ const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */
+ ubyte cb, cr;
+ float r, g, b;
+
+ if (rev) {
+ cb = t1 & 0xff; /* chroma U */
+ cr = t0 & 0xff; /* chroma V */
+ }
+ else {
+ cb = t0 & 0xff; /* chroma U */
+ cr = t1 & 0xff; /* chroma V */
+ }
+
+ /* even pixel: y0,cr,cb */
+ r = 1.164f * (y0-16) + 1.596f * (cr-128);
+ g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
+ b = 1.164f * (y0-16) + 2.018f * (cb-128);
+ pRow[0] = r * scale;
+ pRow[1] = g * scale;
+ pRow[2] = b * scale;
+ pRow[3] = 1.0f;
+ pRow += 4;
+ }
p += dst_stride;
}
}
void
-pipe_get_tile_rgba(struct pipe_surface *ps,
- uint x, uint y, uint w, uint h,
- float *p)
+pipe_tile_raw_to_rgba(enum pipe_format format,
+ void *src,
+ uint w, uint h,
+ float *dst, unsigned dst_stride)
{
- unsigned dst_stride = w * 4;
- void *packed;
-
- if (pipe_clip_tile(x, y, &w, &h, ps))
- return;
-
- packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size);
-
- if (!packed)
- return;
-
- pipe_get_tile_raw(ps, x, y, w, h, packed, 0);
-
- switch (ps->format) {
+ switch (format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
- a8r8g8b8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
+ a8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_X8R8G8B8_UNORM:
- x8r8g8b8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
+ x8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_B8G8R8A8_UNORM:
- b8g8r8a8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
+ b8g8r8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_A1R5G5B5_UNORM:
- a1r5g5b5_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
+ a1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_A4R4G4B4_UNORM:
- a4r4g4b4_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
+ a4r4g4b4_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_R5G6B5_UNORM:
- r5g6b5_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
+ r5g6b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_L8_UNORM:
- l8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride);
+ l8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_A8_UNORM:
- a8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride);
+ a8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_I8_UNORM:
- i8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride);
+ i8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_A8L8_UNORM:
- a8_l8_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
+ a8_l8_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_R16G16B16A16_SNORM:
- r16g16b16a16_get_tile_rgba((short *) packed, w, h, p, dst_stride);
+ r16g16b16a16_get_tile_rgba((short *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_Z16_UNORM:
- z16_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
+ z16_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_Z32_UNORM:
- z32_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
+ z32_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_S8Z24_UNORM:
case PIPE_FORMAT_X8Z24_UNORM:
- s8z24_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
+ s8z24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_Z24S8_UNORM:
- z24s8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
+ z24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_YCBCR:
- assert((x & 1) == 0);
- ycbcr_get_tile_rgba((ushort *) packed, w, h, p, dst_stride, FALSE);
+ ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, FALSE);
break;
case PIPE_FORMAT_YCBCR_REV:
- assert((x & 1) == 0);
- ycbcr_get_tile_rgba((ushort *) packed, w, h, p, dst_stride, TRUE);
+ ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, TRUE);
break;
default:
assert(0);
}
+}
+
+
+void
+pipe_get_tile_rgba(struct pipe_surface *ps,
+ uint x, uint y, uint w, uint h,
+ float *p)
+{
+ unsigned dst_stride = w * 4;
+ void *packed;
+
+ if (pipe_clip_tile(x, y, &w, &h, ps))
+ return;
+
+ packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size);
+
+ if (!packed)
+ return;
+
+ if(ps->format == PIPE_FORMAT_YCBCR || ps->format == PIPE_FORMAT_YCBCR_REV)
+ assert((x & 1) == 0);
+
+ pipe_get_tile_raw(ps, x, y, w, h, packed, 0);
+
+ pipe_tile_raw_to_rgba(ps->format, packed, w, h, p, dst_stride);
FREE(packed);
}
@@ -792,7 +827,7 @@ pipe_put_tile_rgba(struct pipe_surface *ps,
/*a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
break;
case PIPE_FORMAT_R5G6B5_UNORM:
- r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
+ r5g6b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
break;
case PIPE_FORMAT_R8G8B8A8_UNORM:
assert(0);
diff --git a/src/gallium/auxiliary/util/p_tile.h b/src/gallium/auxiliary/util/p_tile.h
index adfec8bcee..a8ac805308 100644
--- a/src/gallium/auxiliary/util/p_tile.h
+++ b/src/gallium/auxiliary/util/p_tile.h
@@ -87,6 +87,13 @@ pipe_put_tile_z(struct pipe_surface *ps,
uint x, uint y, uint w, uint h,
const uint *z);
+void
+pipe_tile_raw_to_rgba(enum pipe_format format,
+ void *src,
+ uint w, uint h,
+ float *dst, unsigned dst_stride);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index 3dc9fdd11e..ae087df4cf 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -307,8 +307,10 @@ util_blit_pixels(struct blit_state *ctx,
dstY1 = tmp;
}
- assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE));
- assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE));
+ assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_SAMPLER, 0));
+ assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_SAMPLER, 0));
if(dst->format == src->format && (dstX1 - dstX0) == srcW && (dstY1 - dstY0) == srcH) {
/* FIXME: this will most surely fail for overlapping rectangles */
@@ -319,7 +321,8 @@ util_blit_pixels(struct blit_state *ctx,
return;
}
- assert(screen->is_format_supported(screen, dst->format, PIPE_SURFACE));
+ 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.
@@ -449,7 +452,8 @@ util_blit_pixels_tex(struct blit_state *ctx,
t0 = srcY0 / (float)tex->height[0];
t1 = srcY1 / (float)tex->height[0];
- assert(screen->is_format_supported(screen, dst->format, PIPE_SURFACE));
+ assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_RENDER_TARGET, 0));
/* save state (restored below) */
cso_save_blend(ctx->cso);
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index 5313a8008a..4999822068 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -858,7 +858,8 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
uint zslice = 0;
/* check if we can render in the texture's format */
- if (!screen->is_format_supported(screen, pt->format, PIPE_SURFACE)) {
+ if (!screen->is_format_supported(screen, pt->format, PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) {
fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel);
return;
}