summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/util')
-rw-r--r--src/gallium/auxiliary/util/Makefile5
-rw-r--r--src/gallium/auxiliary/util/SConscript2
-rw-r--r--src/gallium/auxiliary/util/p_debug.c111
-rw-r--r--src/gallium/auxiliary/util/u_blit.c22
-rw-r--r--src/gallium/auxiliary/util/u_draw_quad.c12
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c42
-rw-r--r--src/gallium/auxiliary/util/u_memory.h13
-rw-r--r--src/gallium/auxiliary/util/u_pack_color.h155
-rw-r--r--src/gallium/auxiliary/util/u_rect.c178
-rw-r--r--src/gallium/auxiliary/util/u_rect.h18
-rw-r--r--src/gallium/auxiliary/util/u_stream.h61
-rw-r--r--src/gallium/auxiliary/util/u_stream_stdc.c106
-rw-r--r--src/gallium/auxiliary/util/u_stream_wd.c224
-rw-r--r--src/gallium/auxiliary/util/u_time.c20
-rw-r--r--src/gallium/auxiliary/util/u_time.h3
-rw-r--r--src/gallium/auxiliary/util/u_timed_winsys.c346
-rw-r--r--src/gallium/auxiliary/util/u_timed_winsys.h41
17 files changed, 1316 insertions, 43 deletions
diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile
index 6e5fd26c05..d3951e4e7d 100644
--- a/src/gallium/auxiliary/util/Makefile
+++ b/src/gallium/auxiliary/util/Makefile
@@ -15,8 +15,11 @@ C_SOURCES = \
u_rect.c \
u_simple_shaders.c \
u_snprintf.c \
+ u_stream_stdc.c \
+ u_stream_wd.c \
u_tile.c \
- u_time.c
+ u_time.c \
+ u_timed_winsys.c
include ../../Makefile.template
diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript
index ce3fad7068..e65c17b1cc 100644
--- a/src/gallium/auxiliary/util/SConscript
+++ b/src/gallium/auxiliary/util/SConscript
@@ -16,6 +16,8 @@ util = env.ConvenienceLibrary(
'u_rect.c',
'u_simple_shaders.c',
'u_snprintf.c',
+ 'u_stream_stdc.c',
+ 'u_stream_wd.c',
'u_tile.c',
'u_time.c',
])
diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c
index 7d1dba5a24..b6cff281e6 100644
--- a/src/gallium/auxiliary/util/p_debug.c
+++ b/src/gallium/auxiliary/util/p_debug.c
@@ -55,7 +55,11 @@
#include "pipe/p_format.h"
#include "pipe/p_state.h"
#include "pipe/p_inlines.h"
+#include "util/u_memory.h"
#include "util/u_string.h"
+#include "util/u_stream.h"
+#include "util/u_math.h"
+#include "util/u_tile.h"
#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
@@ -76,7 +80,7 @@ void _debug_vprintf(const char *format, va_list ap)
/* EngDebugPrint does not handle float point arguments, so we need to use
* our own vsnprintf implementation. It is also very slow, so buffer until
* we find a newline. */
- static char buf[512 + 1] = {'\0'};
+ static char buf[512] = {'\0'};
size_t len = strlen(buf);
int ret = util_vsnprintf(buf + len, sizeof(buf) - len, format, ap);
if(ret > (int)(sizeof(buf) - len - 1) || util_strchr(buf + len, '\n')) {
@@ -584,4 +588,109 @@ error2:
error1:
;
}
+
+
+#pragma pack(push,2)
+struct bmp_file_header {
+ uint16_t bfType;
+ uint32_t bfSize;
+ uint16_t bfReserved1;
+ uint16_t bfReserved2;
+ uint32_t bfOffBits;
+};
+#pragma pack(pop)
+
+struct bmp_info_header {
+ uint32_t biSize;
+ int32_t biWidth;
+ int32_t biHeight;
+ uint16_t biPlanes;
+ uint16_t biBitCount;
+ uint32_t biCompression;
+ uint32_t biSizeImage;
+ int32_t biXPelsPerMeter;
+ int32_t biYPelsPerMeter;
+ uint32_t biClrUsed;
+ uint32_t biClrImportant;
+};
+
+struct bmp_rgb_quad {
+ uint8_t rgbBlue;
+ uint8_t rgbGreen;
+ uint8_t rgbRed;
+ uint8_t rgbAlpha;
+};
+
+void
+debug_dump_surface_bmp(const char *filename,
+ struct pipe_surface *surface)
+{
+ struct util_stream *stream;
+ unsigned surface_usage;
+ struct bmp_file_header bmfh;
+ struct bmp_info_header bmih;
+ float *rgba;
+ unsigned x, y;
+
+ if (!surface)
+ goto error1;
+
+ rgba = MALLOC(surface->width*4*sizeof(float));
+ if(!rgba)
+ goto error1;
+
+ bmfh.bfType = 0x4d42;
+ bmfh.bfSize = 14 + 40 + surface->height*surface->width*4;
+ bmfh.bfReserved1 = 0;
+ bmfh.bfReserved2 = 0;
+ bmfh.bfOffBits = 14 + 40;
+
+ bmih.biSize = 40;
+ bmih.biWidth = surface->width;
+ bmih.biHeight = surface->height;
+ bmih.biPlanes = 1;
+ bmih.biBitCount = 32;
+ bmih.biCompression = 0;
+ bmih.biSizeImage = surface->height*surface->width*4;
+ bmih.biXPelsPerMeter = 0;
+ bmih.biYPelsPerMeter = 0;
+ bmih.biClrUsed = 0;
+ bmih.biClrImportant = 0;
+
+ stream = util_stream_create(filename, bmfh.bfSize);
+ if(!stream)
+ goto error2;
+
+ util_stream_write(stream, &bmfh, 14);
+ util_stream_write(stream, &bmih, 40);
+
+ /* XXX: force mappable surface */
+ surface_usage = surface->usage;
+ surface->usage |= PIPE_BUFFER_USAGE_CPU_READ;
+
+ y = surface->height;
+ while(y--) {
+ pipe_get_tile_rgba(surface,
+ 0, y, surface->width, 1,
+ rgba);
+ for(x = 0; x < surface->width; ++x)
+ {
+ struct bmp_rgb_quad pixel;
+ pixel.rgbRed = float_to_ubyte(rgba[x*4 + 0]);
+ pixel.rgbGreen = float_to_ubyte(rgba[x*4 + 1]);
+ pixel.rgbBlue = float_to_ubyte(rgba[x*4 + 2]);
+ pixel.rgbAlpha = float_to_ubyte(rgba[x*4 + 3]);
+ util_stream_write(stream, &pixel, 4);
+ }
+ }
+
+ surface->usage = surface_usage;
+
+ util_stream_close(stream);
+error2:
+ FREE(rgba);
+error1:
+ ;
+}
+
#endif
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index 05399f9885..9adf72944e 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -138,10 +138,10 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
/* fragment shader */
ctx->fs = util_make_fragment_tex_shader(pipe, &ctx->frag_shader);
- ctx->vbuf = pipe->winsys->buffer_create(pipe->winsys,
- 32,
- PIPE_BUFFER_USAGE_VERTEX,
- sizeof(ctx->vertices));
+ ctx->vbuf = pipe_buffer_create(pipe->screen,
+ 32,
+ PIPE_BUFFER_USAGE_VERTEX,
+ sizeof(ctx->vertices));
if (!ctx->vbuf) {
FREE(ctx);
ctx->pipe->delete_fs_state(ctx->pipe, ctx->fs);
@@ -174,7 +174,7 @@ util_destroy_blit(struct blit_state *ctx)
FREE((void*) ctx->vert_shader.tokens);
FREE((void*) ctx->frag_shader.tokens);
- pipe->winsys->buffer_destroy(pipe->winsys, ctx->vbuf);
+ pipe_buffer_reference(pipe->screen, &ctx->vbuf, NULL);
FREE(ctx);
}
@@ -214,12 +214,12 @@ setup_vertex_data(struct blit_state *ctx,
ctx->vertices[3][1][0] = 0.0f;
ctx->vertices[3][1][1] = 1.0f;
- buf = ctx->pipe->winsys->buffer_map(ctx->pipe->winsys, ctx->vbuf,
- PIPE_BUFFER_USAGE_CPU_WRITE);
+ buf = pipe_buffer_map(ctx->pipe->screen, ctx->vbuf,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
memcpy(buf, ctx->vertices, sizeof(ctx->vertices));
- ctx->pipe->winsys->buffer_unmap(ctx->pipe->winsys, ctx->vbuf);
+ pipe_buffer_unmap(ctx->pipe->screen, ctx->vbuf);
}
@@ -259,12 +259,12 @@ setup_vertex_data_tex(struct blit_state *ctx,
ctx->vertices[3][1][0] = s0;
ctx->vertices[3][1][1] = t1;
- buf = ctx->pipe->winsys->buffer_map(ctx->pipe->winsys, ctx->vbuf,
- PIPE_BUFFER_USAGE_CPU_WRITE);
+ buf = pipe_buffer_map(ctx->pipe->screen, ctx->vbuf,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
memcpy(buf, ctx->vertices, sizeof(ctx->vertices));
- ctx->pipe->winsys->buffer_unmap(ctx->pipe->winsys, ctx->vbuf);
+ pipe_buffer_unmap(ctx->pipe->screen, ctx->vbuf);
}
/**
* Copy pixel block from src surface to dst surface.
diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c
index bf143815d8..8ecae71b64 100644
--- a/src/gallium/auxiliary/util/u_draw_quad.c
+++ b/src/gallium/auxiliary/util/u_draw_quad.c
@@ -86,11 +86,11 @@ util_draw_texquad(struct pipe_context *pipe,
vertexBytes = 4 * (4 * numAttribs * sizeof(float));
/* XXX create one-time */
- vbuf = pipe->winsys->buffer_create(pipe->winsys, 32,
- PIPE_BUFFER_USAGE_VERTEX, vertexBytes);
+ vbuf = pipe_buffer_create(pipe->screen, 32,
+ PIPE_BUFFER_USAGE_VERTEX, vertexBytes);
if (vbuf) {
- float *v = (float *) pipe->winsys->buffer_map(pipe->winsys, vbuf,
- PIPE_BUFFER_USAGE_CPU_WRITE);
+ float *v = (float *) pipe_buffer_map(pipe->screen, vbuf,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
if (v) {
/*
* Load vertex buffer
@@ -123,10 +123,10 @@ util_draw_texquad(struct pipe_context *pipe,
v[28] = 0.0;
v[29] = 1.0;
- pipe->winsys->buffer_unmap(pipe->winsys, vbuf);
+ pipe_buffer_unmap(pipe->screen, vbuf);
util_draw_vertex_buffer(pipe, vbuf, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
}
- pipe_buffer_reference(pipe->winsys, &vbuf, NULL);
+ pipe_buffer_reference(pipe->screen, &vbuf, NULL);
}
}
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index c1e2c19f87..b19a649bbc 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -580,7 +580,6 @@ make_1d_mipmap(struct gen_mipmap_state *ctx,
{
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
- struct pipe_winsys *winsys = pipe->winsys;
const uint zslice = 0;
uint dstLevel;
@@ -595,19 +594,19 @@ make_1d_mipmap(struct gen_mipmap_state *ctx,
dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
PIPE_BUFFER_USAGE_CPU_WRITE);
- srcMap = ((ubyte *) winsys->buffer_map(winsys, srcSurf->buffer,
- PIPE_BUFFER_USAGE_CPU_READ)
+ srcMap = ((ubyte *) pipe_buffer_map(screen, srcSurf->buffer,
+ PIPE_BUFFER_USAGE_CPU_READ)
+ srcSurf->offset);
- dstMap = ((ubyte *) winsys->buffer_map(winsys, dstSurf->buffer,
- PIPE_BUFFER_USAGE_CPU_WRITE)
+ dstMap = ((ubyte *) pipe_buffer_map(screen, dstSurf->buffer,
+ PIPE_BUFFER_USAGE_CPU_WRITE)
+ dstSurf->offset);
reduce_1d(pt->format,
srcSurf->width, srcMap,
dstSurf->width, dstMap);
- winsys->buffer_unmap(winsys, srcSurf->buffer);
- winsys->buffer_unmap(winsys, dstSurf->buffer);
+ pipe_buffer_unmap(screen, srcSurf->buffer);
+ pipe_buffer_unmap(screen, dstSurf->buffer);
pipe_surface_reference(&srcSurf, NULL);
pipe_surface_reference(&dstSurf, NULL);
@@ -622,7 +621,6 @@ make_2d_mipmap(struct gen_mipmap_state *ctx,
{
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
- struct pipe_winsys *winsys = pipe->winsys;
const uint zslice = 0;
uint dstLevel;
@@ -639,11 +637,11 @@ make_2d_mipmap(struct gen_mipmap_state *ctx,
dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
PIPE_BUFFER_USAGE_CPU_WRITE);
- srcMap = ((ubyte *) winsys->buffer_map(winsys, srcSurf->buffer,
- PIPE_BUFFER_USAGE_CPU_READ)
+ srcMap = ((ubyte *) pipe_buffer_map(screen, srcSurf->buffer,
+ PIPE_BUFFER_USAGE_CPU_READ)
+ srcSurf->offset);
- dstMap = ((ubyte *) winsys->buffer_map(winsys, dstSurf->buffer,
- PIPE_BUFFER_USAGE_CPU_WRITE)
+ dstMap = ((ubyte *) pipe_buffer_map(screen, dstSurf->buffer,
+ PIPE_BUFFER_USAGE_CPU_WRITE)
+ dstSurf->offset);
reduce_2d(pt->format,
@@ -652,8 +650,8 @@ make_2d_mipmap(struct gen_mipmap_state *ctx,
dstSurf->width, dstSurf->height,
dstSurf->stride, dstMap);
- winsys->buffer_unmap(winsys, srcSurf->buffer);
- winsys->buffer_unmap(winsys, dstSurf->buffer);
+ pipe_buffer_unmap(screen, srcSurf->buffer);
+ pipe_buffer_unmap(screen, dstSurf->buffer);
pipe_surface_reference(&srcSurf, NULL);
pipe_surface_reference(&dstSurf, NULL);
@@ -759,10 +757,10 @@ util_create_gen_mipmap(struct pipe_context *pipe,
/* fragment shader */
ctx->fs = util_make_fragment_tex_shader(pipe, &ctx->frag_shader);
- ctx->vbuf = pipe->winsys->buffer_create(pipe->winsys,
- 32,
- PIPE_BUFFER_USAGE_VERTEX,
- sizeof(ctx->vertices));
+ ctx->vbuf = pipe_buffer_create(pipe->screen,
+ 32,
+ PIPE_BUFFER_USAGE_VERTEX,
+ sizeof(ctx->vertices));
if (!ctx->vbuf) {
FREE(ctx);
return NULL;
@@ -805,12 +803,12 @@ set_vertex_data(struct gen_mipmap_state *ctx, float width, float height)
ctx->vertices[3][1][0] = 0.0f;
ctx->vertices[3][1][1] = 1.0f;
- buf = ctx->pipe->winsys->buffer_map(ctx->pipe->winsys, ctx->vbuf,
- PIPE_BUFFER_USAGE_CPU_WRITE);
+ buf = pipe_buffer_map(ctx->pipe->screen, ctx->vbuf,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
memcpy(buf, ctx->vertices, sizeof(ctx->vertices));
- ctx->pipe->winsys->buffer_unmap(ctx->pipe->winsys, ctx->vbuf);
+ pipe_buffer_unmap(ctx->pipe->screen, ctx->vbuf);
}
@@ -829,7 +827,7 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx)
FREE((void*) ctx->vert_shader.tokens);
FREE((void*) ctx->frag_shader.tokens);
- pipe->winsys->buffer_destroy(pipe->winsys, ctx->vbuf);
+ pipe_buffer_reference(pipe->screen, &ctx->vbuf, NULL);
FREE(ctx);
}
diff --git a/src/gallium/auxiliary/util/u_memory.h b/src/gallium/auxiliary/util/u_memory.h
index 8fbbb4e55d..857102719d 100644
--- a/src/gallium/auxiliary/util/u_memory.h
+++ b/src/gallium/auxiliary/util/u_memory.h
@@ -39,7 +39,12 @@
#include "pipe/p_debug.h"
- /* Define ENOMEM for WINCE */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Define ENOMEM for WINCE */
#if (_WIN32_WCE < 600)
#ifndef ENOMEM
#define ENOMEM 12
@@ -47,7 +52,6 @@
#endif
-
#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) && defined(DEBUG)
/* memory debugging */
@@ -220,4 +224,9 @@ mem_dup(const void *src, uint size)
+#ifdef __cplusplus
+}
+#endif
+
+
#endif /* U_MEMORY_H */
diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h
index 39e4ae9d07..e0e8aa8e9f 100644
--- a/src/gallium/auxiliary/util/u_pack_color.h
+++ b/src/gallium/auxiliary/util/u_pack_color.h
@@ -142,6 +142,161 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a,
/**
+ * Unpack RGBA from a packed pixel, returning values as ubytes in [0,255].
+ */
+static INLINE void
+util_unpack_color_ub(enum pipe_format format, const void *src,
+ ubyte *r, ubyte *g, ubyte *b, ubyte *a)
+{
+ switch (format) {
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
+ {
+ uint p = ((const uint *) src)[0];
+ *r = (ubyte) ((p >> 24) & 0xff);
+ *g = (ubyte) ((p >> 16) & 0xff);
+ *b = (ubyte) ((p >> 8) & 0xff);
+ *a = (ubyte) ((p >> 0) & 0xff);
+ }
+ return;
+ case PIPE_FORMAT_R8G8B8X8_UNORM:
+ {
+ uint p = ((const uint *) src)[0];
+ *r = (ubyte) ((p >> 24) & 0xff);
+ *g = (ubyte) ((p >> 16) & 0xff);
+ *b = (ubyte) ((p >> 8) & 0xff);
+ *a = (ubyte) 0xff;
+ }
+ return;
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ {
+ uint p = ((const uint *) src)[0];
+ *r = (ubyte) ((p >> 16) & 0xff);
+ *g = (ubyte) ((p >> 8) & 0xff);
+ *b = (ubyte) ((p >> 0) & 0xff);
+ *a = (ubyte) ((p >> 24) & 0xff);
+ }
+ return;
+ case PIPE_FORMAT_X8R8G8B8_UNORM:
+ {
+ uint p = ((const uint *) src)[0];
+ *r = (ubyte) ((p >> 16) & 0xff);
+ *g = (ubyte) ((p >> 8) & 0xff);
+ *b = (ubyte) ((p >> 0) & 0xff);
+ *a = (ubyte) 0xff;
+ }
+ return;
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ {
+ uint p = ((const uint *) src)[0];
+ *r = (ubyte) ((p >> 8) & 0xff);
+ *g = (ubyte) ((p >> 16) & 0xff);
+ *b = (ubyte) ((p >> 24) & 0xff);
+ *a = (ubyte) ((p >> 0) & 0xff);
+ }
+ return;
+ case PIPE_FORMAT_B8G8R8X8_UNORM:
+ {
+ uint p = ((const uint *) src)[0];
+ *r = (ubyte) ((p >> 8) & 0xff);
+ *g = (ubyte) ((p >> 16) & 0xff);
+ *b = (ubyte) ((p >> 24) & 0xff);
+ *a = (ubyte) 0xff;
+ }
+ return;
+ case PIPE_FORMAT_R5G6B5_UNORM:
+ {
+ ushort p = ((const ushort *) src)[0];
+ *r = (ubyte) (((p >> 8) & 0xf8) | ((p >> 13) & 0x7));
+ *g = (ubyte) (((p >> 3) & 0xfc) | ((p >> 9) & 0x3));
+ *b = (ubyte) (((p << 3) & 0xf8) | ((p >> 2) & 0x7));
+ *a = (ubyte) 0xff;
+ }
+ return;
+ case PIPE_FORMAT_A1R5G5B5_UNORM:
+ {
+ ushort p = ((const ushort *) src)[0];
+ *r = (ubyte) (((p >> 7) & 0xf8) | ((p >> 12) & 0x7));
+ *g = (ubyte) (((p >> 2) & 0xf8) | ((p >> 7) & 0x7));
+ *b = (ubyte) (((p << 3) & 0xf8) | ((p >> 2) & 0x7));
+ *a = (ubyte) (0xff * (p >> 15));
+ }
+ return;
+ case PIPE_FORMAT_A4R4G4B4_UNORM:
+ {
+ ushort p = ((const ushort *) src)[0];
+ *r = (ubyte) (((p >> 4) & 0xf0) | ((p >> 8) & 0xf));
+ *g = (ubyte) (((p >> 0) & 0xf0) | ((p >> 4) & 0xf));
+ *b = (ubyte) (((p << 4) & 0xf0) | ((p >> 0) & 0xf));
+ *a = (ubyte) (((p >> 8) & 0xf0) | ((p >> 12) & 0xf));
+ }
+ return;
+ case PIPE_FORMAT_A8_UNORM:
+ {
+ ubyte p = ((const ubyte *) src)[0];
+ *r = *g = *b = (ubyte) 0xff;
+ *a = p;
+ }
+ return;
+ case PIPE_FORMAT_L8_UNORM:
+ {
+ ubyte p = ((const ubyte *) src)[0];
+ *r = *g = *b = p;
+ *a = (ubyte) 0xff;
+ }
+ return;
+ case PIPE_FORMAT_I8_UNORM:
+ {
+ ubyte p = ((const ubyte *) src)[0];
+ *r = *g = *b = *a = p;
+ }
+ return;
+ case PIPE_FORMAT_R32G32B32A32_FLOAT:
+ {
+ const float *p = (const float *) src;
+ *r = float_to_ubyte(p[0]);
+ *g = float_to_ubyte(p[1]);
+ *b = float_to_ubyte(p[2]);
+ *a = float_to_ubyte(p[3]);
+ }
+ return;
+ case PIPE_FORMAT_R32G32B32_FLOAT:
+ {
+ const float *p = (const float *) src;
+ *r = float_to_ubyte(p[0]);
+ *g = float_to_ubyte(p[1]);
+ *b = float_to_ubyte(p[2]);
+ *a = (ubyte) 0xff;
+ }
+ return;
+
+ case PIPE_FORMAT_R32G32_FLOAT:
+ {
+ const float *p = (const float *) src;
+ *r = float_to_ubyte(p[0]);
+ *g = float_to_ubyte(p[1]);
+ *b = *a = (ubyte) 0xff;
+ }
+ return;
+
+ case PIPE_FORMAT_R32_FLOAT:
+ {
+ const float *p = (const float *) src;
+ *r = float_to_ubyte(p[0]);
+ *g = *b = *a = (ubyte) 0xff;
+ }
+ return;
+
+ /* XXX lots more cases to add */
+ default:
+ debug_print_format("gallium: unhandled format in util_unpack_color_ub()",
+ format);
+ assert(0);
+ }
+}
+
+
+
+/**
* Note rgba outside [0,1] will be clamped for int pixel formats.
*/
static INLINE void
diff --git a/src/gallium/auxiliary/util/u_rect.c b/src/gallium/auxiliary/util/u_rect.c
index b31ab5415f..f5619ef791 100644
--- a/src/gallium/auxiliary/util/u_rect.c
+++ b/src/gallium/auxiliary/util/u_rect.c
@@ -32,6 +32,8 @@
#include "pipe/p_defines.h"
#include "pipe/p_format.h"
+#include "pipe/p_context.h"
+#include "pipe/p_screen.h"
#include "util/u_rect.h"
@@ -148,3 +150,179 @@ pipe_fill_rect(ubyte * dst,
break;
}
}
+
+
+
+/**
+ * Fallback function for pipe->surface_copy().
+ * Note: (X,Y)=(0,0) is always the upper-left corner.
+ * if do_flip, flip the image vertically on its way from src rect to dst rect.
+ * XXX should probably put this in new u_surface.c file...
+ */
+void
+util_surface_copy(struct pipe_context *pipe,
+ boolean do_flip,
+ struct pipe_surface *dst,
+ unsigned dst_x, unsigned dst_y,
+ struct pipe_surface *src,
+ unsigned src_x, unsigned src_y,
+ unsigned w, unsigned h)
+{
+ struct pipe_screen *screen = pipe->screen;
+ struct pipe_surface *new_src = NULL, *new_dst = NULL;
+ void *dst_map;
+ const void *src_map;
+
+ assert(dst->block.size == src->block.size);
+ assert(dst->block.width == src->block.width);
+ assert(dst->block.height == src->block.height);
+
+ if ((src->usage & PIPE_BUFFER_USAGE_CPU_READ) == 0) {
+ /* Need to create new src surface which is CPU readable */
+ assert(src->texture);
+ if (!src->texture)
+ return;
+ new_src = screen->get_tex_surface(screen,
+ src->texture,
+ src->face,
+ src->level,
+ src->zslice,
+ PIPE_BUFFER_USAGE_CPU_READ);
+ src = new_src;
+ }
+
+ if ((dst->usage & PIPE_BUFFER_USAGE_CPU_WRITE) == 0) {
+ /* Need to create new dst surface which is CPU writable */
+ assert(dst->texture);
+ if (!dst->texture)
+ return;
+ new_dst = screen->get_tex_surface(screen,
+ dst->texture,
+ dst->face,
+ dst->level,
+ dst->zslice,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ dst = new_dst;
+ }
+
+ src_map = pipe->screen->surface_map(screen,
+ src, PIPE_BUFFER_USAGE_CPU_READ);
+ dst_map = pipe->screen->surface_map(screen,
+ dst, PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ assert(src_map);
+ assert(dst_map);
+
+ if (src_map && dst_map) {
+ /* If do_flip, invert src_y position and pass negative src stride */
+ pipe_copy_rect(dst_map,
+ &dst->block,
+ dst->stride,
+ dst_x, dst_y,
+ w, h,
+ src_map,
+ do_flip ? -(int) src->stride : src->stride,
+ src_x, src_y);
+ }
+
+ pipe->screen->surface_unmap(pipe->screen, src);
+ pipe->screen->surface_unmap(pipe->screen, dst);
+
+ if (new_src)
+ screen->tex_surface_release(screen, &new_src);
+ if (new_dst)
+ screen->tex_surface_release(screen, &new_dst);
+}
+
+
+
+static void *
+get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y)
+{
+ return (char *)dst_map
+ + y / dst->block.height * dst->stride
+ + x / dst->block.width * dst->block.size;
+}
+
+
+#define UBYTE_TO_USHORT(B) ((B) | ((B) << 8))
+
+
+/**
+ * Fallback for pipe->surface_fill() function.
+ * XXX should probably put this in new u_surface.c file...
+ */
+void
+util_surface_fill(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height, unsigned value)
+{
+ struct pipe_screen *screen = pipe->screen;
+ struct pipe_surface *new_dst = NULL;
+ void *dst_map;
+
+ if ((dst->usage & PIPE_BUFFER_USAGE_CPU_WRITE) == 0) {
+ /* Need to create new dst surface which is CPU writable */
+ assert(dst->texture);
+ if (!dst->texture)
+ return;
+ new_dst = screen->get_tex_surface(screen,
+ dst->texture,
+ dst->face,
+ dst->level,
+ dst->zslice,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ dst = new_dst;
+ }
+
+ dst_map = pipe->screen->surface_map(screen,
+ dst, PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ assert(dst_map);
+
+ if (dst_map) {
+ assert(dst->stride > 0);
+
+ switch (dst->block.size) {
+ case 1:
+ case 2:
+ case 4:
+ pipe_fill_rect(dst_map, &dst->block, dst->stride,
+ dstx, dsty, width, height, value);
+ break;
+ case 8:
+ {
+ /* expand the 4-byte clear value to an 8-byte value */
+ ushort *row = (ushort *) get_pointer(dst, dst_map, dstx, dsty);
+ ushort val0 = UBYTE_TO_USHORT((value >> 0) & 0xff);
+ ushort val1 = UBYTE_TO_USHORT((value >> 8) & 0xff);
+ ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff);
+ ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff);
+ unsigned i, j;
+ val0 = (val0 << 8) | val0;
+ val1 = (val1 << 8) | val1;
+ val2 = (val2 << 8) | val2;
+ val3 = (val3 << 8) | val3;
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j++) {
+ row[j*4+0] = val0;
+ row[j*4+1] = val1;
+ row[j*4+2] = val2;
+ row[j*4+3] = val3;
+ }
+ row += dst->stride/2;
+ }
+ }
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+
+ pipe->screen->surface_unmap(pipe->screen, dst);
+
+ if (new_dst)
+ screen->tex_surface_release(screen, &new_dst);
+}
diff --git a/src/gallium/auxiliary/util/u_rect.h b/src/gallium/auxiliary/util/u_rect.h
index fba4808864..59e842e16d 100644
--- a/src/gallium/auxiliary/util/u_rect.h
+++ b/src/gallium/auxiliary/util/u_rect.h
@@ -37,6 +37,9 @@
#include "pipe/p_format.h"
+struct pipe_context;
+struct pipe_surface;
+
extern void
pipe_copy_rect(ubyte * dst, const struct pipe_format_block *block,
@@ -50,5 +53,20 @@ pipe_fill_rect(ubyte * dst, const struct pipe_format_block *block,
unsigned width, unsigned height, uint32_t value);
+extern void
+util_surface_copy(struct pipe_context *pipe,
+ boolean do_flip,
+ struct pipe_surface *dst,
+ unsigned dst_x, unsigned dst_y,
+ struct pipe_surface *src,
+ unsigned src_x, unsigned src_y,
+ unsigned w, unsigned h);
+
+extern void
+util_surface_fill(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height, unsigned value);
+
#endif /* U_RECT_H */
diff --git a/src/gallium/auxiliary/util/u_stream.h b/src/gallium/auxiliary/util/u_stream.h
new file mode 100644
index 0000000000..a9d0f0121a
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_stream.h
@@ -0,0 +1,61 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Cross-platform sequential access stream abstraction.
+ */
+
+#ifndef U_STREAM_H
+#define U_STREAM_H
+
+
+#include "pipe/p_compiler.h"
+
+
+struct util_stream;
+
+
+/**
+ * Create a stream
+ * @param filename relative or absolute path (necessary for windows)
+ * @param optional maximum file size (0 for a growable size).
+ */
+struct util_stream *
+util_stream_create(const char *filename, size_t max_size);
+
+boolean
+util_stream_write(struct util_stream *stream, const void *data, size_t size);
+
+void
+util_stream_flush(struct util_stream *stream);
+
+void
+util_stream_close(struct util_stream *stream);
+
+
+#endif /* U_STREAM_H */
diff --git a/src/gallium/auxiliary/util/u_stream_stdc.c b/src/gallium/auxiliary/util/u_stream_stdc.c
new file mode 100644
index 0000000000..ca80bef0f3
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_stream_stdc.c
@@ -0,0 +1,106 @@
+/**************************************************************************
+ *
+ * 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
+ * Stream implementation based on the Standard C Library.
+ */
+
+#include "pipe/p_config.h"
+
+#if defined(PIPE_OS_LINUX) || defined(PIPE_SUBSYSTEM_WINDOWS_USER)
+
+#include <stdio.h>
+
+#include "util/u_memory.h"
+
+#include "u_stream.h"
+
+
+struct util_stream
+{
+ FILE *file;
+};
+
+
+struct util_stream *
+util_stream_create(const char *filename, size_t max_size)
+{
+ struct util_stream *stream;
+
+ (void)max_size;
+
+ stream = CALLOC_STRUCT(util_stream);
+ if(!stream)
+ goto error1;
+
+ stream->file = fopen(filename, "w");
+ if(!stream->file)
+ goto error2;
+
+ return stream;
+
+error2:
+ FREE(stream);
+error1:
+ return NULL;
+}
+
+
+boolean
+util_stream_write(struct util_stream *stream, const void *data, size_t size)
+{
+ if(!stream)
+ return FALSE;
+
+ return fwrite(data, size, 1, stream->file) == size ? TRUE : FALSE;
+}
+
+
+void
+util_stream_flush(struct util_stream *stream)
+{
+ if(!stream)
+ return;
+
+ fflush(stream->file);
+}
+
+
+void
+util_stream_close(struct util_stream *stream)
+{
+ if(!stream)
+ return;
+
+ fclose(stream->file);
+
+ FREE(stream);
+}
+
+
+#endif
diff --git a/src/gallium/auxiliary/util/u_stream_wd.c b/src/gallium/auxiliary/util/u_stream_wd.c
new file mode 100644
index 0000000000..864489e775
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_stream_wd.c
@@ -0,0 +1,224 @@
+/**************************************************************************
+ *
+ * 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
+ * Stream implementation for the Windows Display driver.
+ */
+
+#include "pipe/p_config.h"
+
+#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
+
+#include <windows.h>
+#include <winddi.h>
+
+#include "util/u_memory.h"
+#include "util/u_string.h"
+
+#include "u_stream.h"
+
+
+#define MAP_FILE_SIZE (4*1024*1024)
+
+
+struct util_stream
+{
+ char filename[MAX_PATH + 1];
+ WCHAR wFileName[MAX_PATH + 1];
+ boolean growable;
+ size_t map_size;
+ ULONG_PTR iFile;
+ char *pMap;
+ size_t written;
+ unsigned suffix;
+};
+
+
+static INLINE boolean
+util_stream_map(struct util_stream *stream)
+{
+ ULONG BytesInUnicodeString;
+ static char filename[MAX_PATH + 1];
+ unsigned filename_len;
+
+ if(stream->growable)
+ filename_len = util_snprintf(filename,
+ sizeof(filename),
+ "%s.%04x",
+ stream->filename,
+ stream->suffix++);
+ else
+ filename_len = util_snprintf(filename,
+ sizeof(filename),
+ "%s",
+ stream->filename);
+
+ EngMultiByteToUnicodeN(
+ stream->wFileName,
+ sizeof(stream->wFileName),
+ &BytesInUnicodeString,
+ filename,
+ filename_len);
+
+ stream->pMap = EngMapFile(stream->wFileName, stream->map_size, &stream->iFile);
+ if(!stream->pMap)
+ return FALSE;
+
+ memset(stream->pMap, 0, stream->map_size);
+ stream->written = 0;
+
+ return TRUE;
+}
+
+
+static INLINE void
+util_stream_unmap(struct util_stream *stream)
+{
+ EngUnmapFile(stream->iFile);
+ if(stream->written < stream->map_size) {
+ /* Truncate file size */
+ stream->pMap = EngMapFile(stream->wFileName, stream->written, &stream->iFile);
+ if(stream->pMap)
+ EngUnmapFile(stream->iFile);
+ }
+
+ stream->pMap = NULL;
+}
+
+
+static INLINE void
+util_stream_full_qualified_filename(char *dst, size_t size, const char *src)
+{
+ boolean need_drive, need_root;
+
+ if((('A' <= src[0] && src[0] <= 'Z') || ('a' <= src[0] && src[0] <= 'z')) && src[1] == ':') {
+ need_drive = FALSE;
+ need_root = src[2] == '\\' ? FALSE : TRUE;
+ }
+ else {
+ need_drive = TRUE;
+ need_root = src[0] == '\\' ? FALSE : TRUE;
+ }
+
+ util_snprintf(dst, size,
+ "\\??\\%s%s%s",
+ need_drive ? "C:" : "",
+ need_root ? "\\" : "",
+ src);
+}
+
+
+struct util_stream *
+util_stream_create(const char *filename, size_t max_size)
+{
+ struct util_stream *stream;
+
+ stream = CALLOC_STRUCT(util_stream);
+ if(!stream)
+ goto error1;
+
+ util_stream_full_qualified_filename(stream->filename,
+ sizeof(stream->filename),
+ filename);
+
+ if(max_size) {
+ stream->growable = FALSE;
+ stream->map_size = max_size;
+ }
+ else {
+ stream->growable = TRUE;
+ stream->map_size = MAP_FILE_SIZE;
+ }
+
+ if(!util_stream_map(stream))
+ goto error2;
+
+ return stream;
+
+error2:
+ FREE(stream);
+error1:
+ return NULL;
+}
+
+
+static INLINE void
+util_stream_copy(struct util_stream *stream, const char *data, size_t size)
+{
+ assert(stream->written + size <= stream->map_size);
+ memcpy(stream->pMap + stream->written, data, size);
+ stream->written += size;
+}
+
+
+boolean
+util_stream_write(struct util_stream *stream, const void *data, size_t size)
+{
+ if(!stream)
+ return FALSE;
+
+ if(!stream->pMap)
+ return FALSE;
+
+ while(stream->written + size > stream->map_size) {
+ size_t step = stream->map_size - stream->written;
+ util_stream_copy(stream, data, step);
+ data = (const char *)data + step;
+ size -= step;
+
+ util_stream_unmap(stream);
+ if(!stream->growable || !util_stream_map(stream))
+ return FALSE;
+ }
+
+ util_stream_copy(stream, data, size);
+
+ return TRUE;
+}
+
+
+void
+util_stream_flush(struct util_stream *stream)
+{
+ (void)stream;
+}
+
+
+void
+util_stream_close(struct util_stream *stream)
+{
+ if(!stream)
+ return;
+
+ util_stream_unmap(stream);
+
+ FREE(stream);
+}
+
+
+#endif
diff --git a/src/gallium/auxiliary/util/u_time.c b/src/gallium/auxiliary/util/u_time.c
index 49dce75289..bf7d1d1c8d 100644
--- a/src/gallium/auxiliary/util/u_time.c
+++ b/src/gallium/auxiliary/util/u_time.c
@@ -136,6 +136,26 @@ util_time_diff(const struct util_time *t1,
}
+
+uint64_t
+util_time_micros( void )
+{
+ struct util_time t1;
+
+ util_time_get(&t1);
+
+#if defined(PIPE_OS_LINUX)
+ return t1.tv.tv_usec + t1.tv.tv_sec*1000000LL;
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
+ util_time_get_frequency();
+ return t1.counter*INT64_C(1000000)/frequency;
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
+ return t1.counter/10;
+#endif
+}
+
+
+
/**
* Compare two time values.
*
diff --git a/src/gallium/auxiliary/util/u_time.h b/src/gallium/auxiliary/util/u_time.h
index f9963ce0e2..35d97d16c7 100644
--- a/src/gallium/auxiliary/util/u_time.h
+++ b/src/gallium/auxiliary/util/u_time.h
@@ -74,6 +74,9 @@ util_time_add(const struct util_time *t1,
int64_t usecs,
struct util_time *t2);
+uint64_t
+util_time_micros( void );
+
int64_t
util_time_diff(const struct util_time *t1,
const struct util_time *t2);
diff --git a/src/gallium/auxiliary/util/u_timed_winsys.c b/src/gallium/auxiliary/util/u_timed_winsys.c
new file mode 100644
index 0000000000..8beb3b4c88
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_timed_winsys.c
@@ -0,0 +1,346 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * 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 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
+ * THE COPYRIGHT HOLDERS, AUTHORS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com>
+ */
+
+#include "pipe/p_winsys.h"
+#include "u_timed_winsys.h"
+#include "util/u_memory.h"
+#include "util/u_time.h"
+
+
+struct timed_winsys {
+ struct pipe_winsys base;
+ struct pipe_winsys *backend;
+ uint64_t last_dump;
+ struct {
+ const char *name_key;
+ double total;
+ unsigned calls;
+ } funcs[13];
+};
+
+
+static struct timed_winsys *timed_winsys( struct pipe_winsys *winsys )
+{
+ return (struct timed_winsys *)winsys;
+}
+
+
+static uint64_t time_start( void )
+{
+ return util_time_micros();
+}
+
+
+static void time_display( struct pipe_winsys *winsys )
+{
+ struct timed_winsys *tws = timed_winsys(winsys);
+ unsigned i;
+ double overall = 0;
+
+ for (i = 0; i < Elements(tws->funcs); i++) {
+ if (tws->funcs[i].name_key) {
+ debug_printf("*** %-25s %5.3fms (%d calls, avg %.3fms)\n",
+ tws->funcs[i].name_key,
+ tws->funcs[i].total,
+ tws->funcs[i].calls,
+ tws->funcs[i].total / tws->funcs[i].calls);
+ overall += tws->funcs[i].total;
+ tws->funcs[i].calls = 0;
+ tws->funcs[i].total = 0;
+ }
+ }
+
+ debug_printf("*** %-25s %5.3fms\n",
+ "OVERALL WINSYS",
+ overall);
+}
+
+static void time_finish( struct pipe_winsys *winsys,
+ long long startval,
+ unsigned idx,
+ const char *name )
+{
+ struct timed_winsys *tws = timed_winsys(winsys);
+ uint64_t endval = util_time_micros();
+ double elapsed = (endval - startval)/1000.0;
+
+ if (endval - startval > 1000LL)
+ debug_printf("*** %s %.3f\n", name, elapsed );
+
+ assert( tws->funcs[idx].name_key == name ||
+ tws->funcs[idx].name_key == NULL);
+
+ tws->funcs[idx].name_key = name;
+ tws->funcs[idx].total += elapsed;
+ tws->funcs[idx].calls++;
+
+ if (endval - tws->last_dump > 10LL * 1000LL * 1000LL) {
+ time_display( winsys );
+ tws->last_dump = endval;
+ }
+}
+
+
+/* Pipe has no concept of pools, but the psb driver passes a flag that
+ * can be mapped onto pools in the backend.
+ */
+static struct pipe_buffer *
+timed_buffer_create(struct pipe_winsys *winsys,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size )
+{
+ struct pipe_winsys *backend = timed_winsys(winsys)->backend;
+ uint64_t start = time_start();
+
+ struct pipe_buffer *buf = backend->buffer_create( backend, alignment, usage, size );
+
+ time_finish(winsys, start, 0, __FUNCTION__);
+
+ return buf;
+}
+
+
+
+
+static struct pipe_buffer *
+timed_user_buffer_create(struct pipe_winsys *winsys,
+ void *data,
+ unsigned bytes)
+{
+ struct pipe_winsys *backend = timed_winsys(winsys)->backend;
+ uint64_t start = time_start();
+
+ struct pipe_buffer *buf = backend->user_buffer_create( backend, data, bytes );
+
+ time_finish(winsys, start, 1, __FUNCTION__);
+
+ return buf;
+}
+
+
+static void *
+timed_buffer_map(struct pipe_winsys *winsys,
+ struct pipe_buffer *buf,
+ unsigned flags)
+{
+ struct pipe_winsys *backend = timed_winsys(winsys)->backend;
+ uint64_t start = time_start();
+
+ void *map = backend->buffer_map( backend, buf, flags );
+
+ time_finish(winsys, start, 2, __FUNCTION__);
+
+ return map;
+}
+
+
+static void
+timed_buffer_unmap(struct pipe_winsys *winsys,
+ struct pipe_buffer *buf)
+{
+ struct pipe_winsys *backend = timed_winsys(winsys)->backend;
+ uint64_t start = time_start();
+
+ backend->buffer_unmap( backend, buf );
+
+ time_finish(winsys, start, 3, __FUNCTION__);
+}
+
+
+static void
+timed_buffer_destroy(struct pipe_winsys *winsys,
+ struct pipe_buffer *buf)
+{
+ struct pipe_winsys *backend = timed_winsys(winsys)->backend;
+ uint64_t start = time_start();
+
+ backend->buffer_destroy( backend, buf );
+
+ time_finish(winsys, start, 4, __FUNCTION__);
+}
+
+
+static void
+timed_flush_frontbuffer( struct pipe_winsys *winsys,
+ struct pipe_surface *surf,
+ void *context_private)
+{
+ struct pipe_winsys *backend = timed_winsys(winsys)->backend;
+ uint64_t start = time_start();
+
+ backend->flush_frontbuffer( backend, surf, context_private );
+
+ time_finish(winsys, start, 5, __FUNCTION__);
+}
+
+
+
+
+static struct pipe_surface *
+timed_surface_alloc(struct pipe_winsys *winsys)
+{
+ struct pipe_winsys *backend = timed_winsys(winsys)->backend;
+ uint64_t start = time_start();
+
+ struct pipe_surface *surf = backend->surface_alloc( backend );
+
+ time_finish(winsys, start, 6, __FUNCTION__);
+
+ return surf;
+}
+
+
+
+static int
+timed_surface_alloc_storage(struct pipe_winsys *winsys,
+ struct pipe_surface *surf,
+ unsigned width, unsigned height,
+ enum pipe_format format,
+ unsigned flags,
+ unsigned tex_usage)
+{
+ struct pipe_winsys *backend = timed_winsys(winsys)->backend;
+ uint64_t start = time_start();
+
+ int ret = backend->surface_alloc_storage( backend, surf, width, height,
+ format, flags, tex_usage );
+
+ time_finish(winsys, start, 7, __FUNCTION__);
+
+ return ret;
+}
+
+
+static void
+timed_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
+{
+ struct pipe_winsys *backend = timed_winsys(winsys)->backend;
+ uint64_t start = time_start();
+
+ backend->surface_release( backend, s );
+
+ time_finish(winsys, start, 8, __FUNCTION__);
+}
+
+
+
+static const char *
+timed_get_name( struct pipe_winsys *winsys )
+{
+ struct pipe_winsys *backend = timed_winsys(winsys)->backend;
+ uint64_t start = time_start();
+
+ const char *ret = backend->get_name( backend );
+
+ time_finish(winsys, start, 9, __FUNCTION__);
+
+ return ret;
+}
+
+static void
+timed_fence_reference(struct pipe_winsys *winsys,
+ struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence)
+{
+ struct pipe_winsys *backend = timed_winsys(winsys)->backend;
+ uint64_t start = time_start();
+
+ backend->fence_reference( backend, ptr, fence );
+
+ time_finish(winsys, start, 10, __FUNCTION__);
+}
+
+
+static int
+timed_fence_signalled( struct pipe_winsys *winsys,
+ struct pipe_fence_handle *fence,
+ unsigned flag )
+{
+ struct pipe_winsys *backend = timed_winsys(winsys)->backend;
+ uint64_t start = time_start();
+
+ int ret = backend->fence_signalled( backend, fence, flag );
+
+ time_finish(winsys, start, 11, __FUNCTION__);
+
+ return ret;
+}
+
+static int
+timed_fence_finish( struct pipe_winsys *winsys,
+ struct pipe_fence_handle *fence,
+ unsigned flag )
+{
+ struct pipe_winsys *backend = timed_winsys(winsys)->backend;
+ uint64_t start = time_start();
+
+ int ret = backend->fence_finish( backend, fence, flag );
+
+ time_finish(winsys, start, 12, __FUNCTION__);
+
+ return ret;
+}
+
+static void
+timed_winsys_destroy( struct pipe_winsys *winsys )
+{
+ struct pipe_winsys *backend = timed_winsys(winsys)->backend;
+ backend->destroy( backend );
+ FREE(winsys);
+}
+
+
+
+struct pipe_winsys *u_timed_winsys_create( struct pipe_winsys *backend )
+{
+ struct timed_winsys *ws = CALLOC_STRUCT(timed_winsys);
+
+ ws->base.user_buffer_create = timed_user_buffer_create;
+ ws->base.buffer_map = timed_buffer_map;
+ ws->base.buffer_unmap = timed_buffer_unmap;
+ ws->base.buffer_destroy = timed_buffer_destroy;
+ ws->base.buffer_create = timed_buffer_create;
+ ws->base.flush_frontbuffer = timed_flush_frontbuffer;
+ ws->base.get_name = timed_get_name;
+ ws->base.surface_alloc = timed_surface_alloc;
+ ws->base.surface_alloc_storage = timed_surface_alloc_storage;
+ ws->base.surface_release = timed_surface_release;
+ ws->base.fence_reference = timed_fence_reference;
+ ws->base.fence_signalled = timed_fence_signalled;
+ ws->base.fence_finish = timed_fence_finish;
+ ws->base.destroy = timed_winsys_destroy;
+
+ ws->backend = backend;
+
+ return &ws->base;
+}
+
diff --git a/src/gallium/auxiliary/util/u_timed_winsys.h b/src/gallium/auxiliary/util/u_timed_winsys.h
new file mode 100644
index 0000000000..542365112d
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_timed_winsys.h
@@ -0,0 +1,41 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * 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 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
+ * THE COPYRIGHT HOLDERS, AUTHORS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com>
+ */
+
+
+#ifndef U_TIMED_WINSYS_H
+#define U_TIMED_WINSYS_H
+
+
+struct pipe_winsys;
+struct pipe_winsys *u_timed_winsys_create( struct pipe_winsys *backend );
+
+
+#endif