summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary
diff options
context:
space:
mode:
authorJosé Fonseca <[email protected]>2010-02-05 13:48:35 +0000
committerJosé Fonseca <[email protected]>2010-02-05 13:48:35 +0000
commita1af8eec66c5f7ec421e8011b41c1a7c36319f9f (patch)
treebc76a431699807cf60cf8ba82ff6b3b1ff34f309 /src/gallium/auxiliary
parentc036d13d7d2cc905226fe53ebd86a18da808963f (diff)
parentbee9964b29b2428ee75e2d1efc0e1d2c2518a417 (diff)
Merge remote branch 'origin/lp-binning'
Conflicts: src/gallium/auxiliary/util/u_dl.c src/gallium/auxiliary/util/u_time.h src/gallium/drivers/llvmpipe/lp_state_derived.c src/gallium/drivers/llvmpipe/lp_state_surface.c src/gallium/drivers/llvmpipe/lp_tex_cache.c src/gallium/drivers/llvmpipe/lp_tile_cache.c
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r--src/gallium/auxiliary/os/os_thread.h151
-rw-r--r--src/gallium/auxiliary/util/u_debug.c75
-rw-r--r--src/gallium/auxiliary/util/u_debug.h4
-rw-r--r--src/gallium/auxiliary/util/u_ringbuffer.c21
-rw-r--r--src/gallium/auxiliary/util/u_surface.c71
-rw-r--r--src/gallium/auxiliary/util/u_surface.h19
-rw-r--r--src/gallium/auxiliary/util/u_time.h12
7 files changed, 338 insertions, 15 deletions
diff --git a/src/gallium/auxiliary/os/os_thread.h b/src/gallium/auxiliary/os/os_thread.h
index 2da5fd77386..24a2309976a 100644
--- a/src/gallium/auxiliary/os/os_thread.h
+++ b/src/gallium/auxiliary/os/os_thread.h
@@ -27,7 +27,8 @@
/**
* @file
*
- * Thread, mutex, condition var and thread-specific data functions.
+ * Thread, mutex, condition variable, barrier, semaphore and
+ * thread-specific data functions.
*/
@@ -46,6 +47,8 @@
#define PIPE_THREAD_HAVE_CONDVAR
+/* pipe_thread
+ */
typedef pthread_t pipe_thread;
#define PIPE_THREAD_ROUTINE( name, param ) \
@@ -69,8 +72,10 @@ static INLINE int pipe_thread_destroy( pipe_thread thread )
return pthread_detach( thread );
}
+
+/* pipe_mutex
+ */
typedef pthread_mutex_t pipe_mutex;
-typedef pthread_cond_t pipe_condvar;
#define pipe_static_mutex(mutex) \
static pipe_mutex mutex = PTHREAD_MUTEX_INITIALIZER
@@ -87,6 +92,11 @@ typedef pthread_cond_t pipe_condvar;
#define pipe_mutex_unlock(mutex) \
(void) pthread_mutex_unlock(&(mutex))
+
+/* pipe_condvar
+ */
+typedef pthread_cond_t pipe_condvar;
+
#define pipe_static_condvar(mutex) \
static pipe_condvar mutex = PTHREAD_COND_INITIALIZER
@@ -106,10 +116,32 @@ typedef pthread_cond_t pipe_condvar;
pthread_cond_broadcast(&(cond))
+/* pipe_barrier
+ */
+typedef pthread_barrier_t pipe_barrier;
+
+static INLINE void pipe_barrier_init(pipe_barrier *barrier, unsigned count)
+{
+ pthread_barrier_init(barrier, NULL, count);
+}
+
+static INLINE void pipe_barrier_destroy(pipe_barrier *barrier)
+{
+ pthread_barrier_destroy(barrier);
+}
+
+static INLINE void pipe_barrier_wait(pipe_barrier *barrier)
+{
+ pthread_barrier_wait(barrier);
+}
+
+
#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
#include <windows.h>
+/* pipe_thread
+ */
typedef HANDLE pipe_thread;
#define PIPE_THREAD_ROUTINE( name, param ) \
@@ -135,6 +167,9 @@ static INLINE int pipe_thread_destroy( pipe_thread thread )
return -1;
}
+
+/* pipe_mutex
+ */
typedef CRITICAL_SECTION pipe_mutex;
#define pipe_static_mutex(mutex) \
@@ -152,15 +187,48 @@ typedef CRITICAL_SECTION pipe_mutex;
#define pipe_mutex_unlock(mutex) \
LeaveCriticalSection(&mutex)
-/* XXX: dummy definitions, make it compile */
+/* pipe_condvar (XXX FIX THIS)
+ */
typedef unsigned pipe_condvar;
-#define pipe_condvar_init(condvar) \
- (void) condvar
+#define pipe_condvar_init(cond) \
+ (void) cond
+
+#define pipe_condvar_destroy(cond) \
+ (void) cond
+
+#define pipe_condvar_wait(cond, mutex) \
+ (void) cond; (void) mutex
+
+#define pipe_condvar_signal(cond) \
+ (void) cond
+
+#define pipe_condvar_broadcast(cond) \
+ (void) cond
+
+
+/* pipe_barrier (XXX FIX THIS)
+ */
+typedef unsigned pipe_barrier;
+
+static INLINE void pipe_barrier_init(pipe_barrier *barrier, unsigned count)
+{
+ /* XXX we could implement barriers with a mutex and condition var */
+ assert(0);
+}
+
+static INLINE void pipe_barrier_destroy(pipe_barrier *barrier)
+{
+ assert(0);
+}
+
+static INLINE void pipe_barrier_wait(pipe_barrier *barrier)
+{
+ assert(0);
+}
+
-#define pipe_condvar_broadcast(condvar) \
- (void) condvar
#else
@@ -188,6 +256,7 @@ static INLINE int pipe_thread_destroy( pipe_thread thread )
typedef unsigned pipe_mutex;
typedef unsigned pipe_condvar;
+typedef unsigned pipe_barrier;
#define pipe_static_mutex(mutex) \
static pipe_mutex mutex = 0
@@ -223,9 +292,77 @@ typedef unsigned pipe_condvar;
(void) condvar
+static INLINE void pipe_barrier_init(pipe_barrier *barrier, unsigned count)
+{
+ /* XXX we could implement barriers with a mutex and condition var */
+ assert(0);
+}
+
+static INLINE void pipe_barrier_destroy(pipe_barrier *barrier)
+{
+ assert(0);
+}
+
+static INLINE void pipe_barrier_wait(pipe_barrier *barrier)
+{
+ assert(0);
+}
+
+
+
#endif /* PIPE_OS_? */
+/*
+ * Semaphores
+ */
+
+typedef struct
+{
+ pipe_mutex mutex;
+ pipe_condvar cond;
+ int counter;
+} pipe_semaphore;
+
+
+static INLINE void
+pipe_semaphore_init(pipe_semaphore *sema, int init_val)
+{
+ pipe_mutex_init(sema->mutex);
+ pipe_condvar_init(sema->cond);
+ sema->counter = init_val;
+}
+
+static INLINE void
+pipe_semaphore_destroy(pipe_semaphore *sema)
+{
+ pipe_mutex_destroy(sema->mutex);
+ pipe_condvar_destroy(sema->cond);
+}
+
+/** Signal/increment semaphore counter */
+static INLINE void
+pipe_semaphore_signal(pipe_semaphore *sema)
+{
+ pipe_mutex_lock(sema->mutex);
+ sema->counter++;
+ pipe_condvar_signal(sema->cond);
+ pipe_mutex_unlock(sema->mutex);
+}
+
+/** Wait for semaphore counter to be greater than zero */
+static INLINE void
+pipe_semaphore_wait(pipe_semaphore *sema)
+{
+ pipe_mutex_lock(sema->mutex);
+ while (sema->counter <= 0) {
+ pipe_condvar_wait(sema->cond, sema->mutex);
+ }
+ sema->counter--;
+ pipe_mutex_unlock(sema->mutex);
+}
+
+
/*
* Thread-specific data.
diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c
index a8d18333d89..4821b8a1434 100644
--- a/src/gallium/auxiliary/util/u_debug.c
+++ b/src/gallium/auxiliary/util/u_debug.c
@@ -440,6 +440,14 @@ const char *u_prim_name( unsigned prim )
#ifdef DEBUG
+/**
+ * Dump an image to a .raw or .ppm file (depends on OS).
+ * \param format PIPE_FORMAT_x
+ * \param cpp bytes per pixel
+ * \param width width in pixels
+ * \param height height in pixels
+ * \param stride row stride in bytes
+ */
void debug_dump_image(const char *prefix,
unsigned format, unsigned cpp,
unsigned width, unsigned height,
@@ -481,6 +489,52 @@ void debug_dump_image(const char *prefix,
}
EngUnmapFile(iFile);
+#elif defined(PIPE_OS_UNIX)
+ /* write a ppm file */
+ char filename[256];
+ FILE *f;
+
+ util_snprintf(filename, sizeof(filename), "%s.ppm", prefix);
+
+ f = fopen(filename, "w");
+ if (f) {
+ int i, x, y;
+ int r, g, b;
+ const uint8_t *ptr = (uint8_t *) data;
+
+ /* XXX this is a hack */
+ switch (format) {
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ r = 2;
+ g = 1;
+ b = 0;
+ break;
+ default:
+ r = 0;
+ g = 1;
+ b = 1;
+ }
+
+ fprintf(f, "P6\n");
+ fprintf(f, "# ppm-file created by osdemo.c\n");
+ fprintf(f, "%i %i\n", width, height);
+ fprintf(f, "255\n");
+ fclose(f);
+
+ f = fopen(filename, "ab"); /* reopen in binary append mode */
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ i = y * stride + x * cpp;
+ fputc(ptr[i + r], f); /* write red */
+ fputc(ptr[i + g], f); /* write green */
+ fputc(ptr[i + b], f); /* write blue */
+ }
+ }
+ fclose(f);
+ }
+ else {
+ fprintf(stderr, "Can't open %s for writing\n", filename);
+ }
#endif
}
@@ -521,6 +575,27 @@ error:
}
+void debug_dump_texture(const char *prefix,
+ struct pipe_texture *texture)
+{
+ struct pipe_surface *surface;
+ struct pipe_screen *screen;
+
+ if (!texture)
+ return;
+
+ screen = texture->screen;
+
+ /* XXX for now, just dump image for face=0, level=0 */
+ surface = screen->get_tex_surface(screen, texture, 0, 0, 0,
+ PIPE_TEXTURE_USAGE_SAMPLER);
+ if (surface) {
+ debug_dump_surface(prefix, surface);
+ screen->tex_surface_destroy(surface);
+ }
+}
+
+
#pragma pack(push,2)
struct bmp_file_header {
uint16_t bfType;
diff --git a/src/gallium/auxiliary/util/u_debug.h b/src/gallium/auxiliary/util/u_debug.h
index eadc08fe2a0..efcf065d276 100644
--- a/src/gallium/auxiliary/util/u_debug.h
+++ b/src/gallium/auxiliary/util/u_debug.h
@@ -314,6 +314,8 @@ debug_memory_end(unsigned long beginning);
#ifdef DEBUG
struct pipe_surface;
struct pipe_transfer;
+struct pipe_texture;
+
void debug_dump_image(const char *prefix,
unsigned format, unsigned cpp,
unsigned width, unsigned height,
@@ -321,6 +323,8 @@ void debug_dump_image(const char *prefix,
const void *data);
void debug_dump_surface(const char *prefix,
struct pipe_surface *surface);
+void debug_dump_texture(const char *prefix,
+ struct pipe_texture *texture);
void debug_dump_surface_bmp(const char *filename,
struct pipe_surface *surface);
void debug_dump_transfer_bmp(const char *filename,
diff --git a/src/gallium/auxiliary/util/u_ringbuffer.c b/src/gallium/auxiliary/util/u_ringbuffer.c
index 95d45ebb71f..648b105b137 100644
--- a/src/gallium/auxiliary/util/u_ringbuffer.c
+++ b/src/gallium/auxiliary/util/u_ringbuffer.c
@@ -53,11 +53,22 @@ void util_ringbuffer_destroy( struct util_ringbuffer *ring )
FREE(ring);
}
+/**
+ * Return number of free entries in the ring
+ */
static INLINE unsigned util_ringbuffer_space( const struct util_ringbuffer *ring )
{
return (ring->tail - (ring->head + 1)) & ring->mask;
}
+/**
+ * Is the ring buffer empty?
+ */
+static INLINE boolean util_ringbuffer_empty( const struct util_ringbuffer *ring )
+{
+ return util_ringbuffer_space(ring) == ring->mask;
+}
+
void util_ringbuffer_enqueue( struct util_ringbuffer *ring,
const struct util_packet *packet )
{
@@ -67,6 +78,10 @@ void util_ringbuffer_enqueue( struct util_ringbuffer *ring,
*/
pipe_mutex_lock(ring->mutex);
+ /* make sure we don't request an impossible amount of space
+ */
+ assert(packet->dwords <= ring->mask);
+
/* Wait for free space:
*/
while (util_ringbuffer_space(ring) < packet->dwords)
@@ -104,14 +119,14 @@ enum pipe_error util_ringbuffer_dequeue( struct util_ringbuffer *ring,
*/
pipe_mutex_lock(ring->mutex);
- /* Wait for free space:
+ /* Get next ring entry:
*/
if (wait) {
- while (util_ringbuffer_space(ring) == 0)
+ while (util_ringbuffer_empty(ring))
pipe_condvar_wait(ring->change, ring->mutex);
}
else {
- if (util_ringbuffer_space(ring) == 0) {
+ if (util_ringbuffer_empty(ring)) {
ret = PIPE_ERROR_OUT_OF_MEMORY;
goto out;
}
diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c
index 6053c111e34..c9f1c9c210f 100644
--- a/src/gallium/auxiliary/util/u_surface.c
+++ b/src/gallium/auxiliary/util/u_surface.c
@@ -37,6 +37,7 @@
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
+#include "util/u_memory.h"
#include "util/u_surface.h"
@@ -111,3 +112,73 @@ util_destroy_rgba_surface(struct pipe_texture *texture,
pipe_texture_reference(&texture, NULL);
}
+
+
+/**
+ * Compare pipe_framebuffer_state objects.
+ * \return TRUE if same, FALSE if different
+ */
+boolean
+util_framebuffer_state_equal(const struct pipe_framebuffer_state *dst,
+ const struct pipe_framebuffer_state *src)
+{
+ unsigned i;
+
+ if (dst->width != src->width ||
+ dst->height != src->height)
+ return FALSE;
+
+ for (i = 0; i < Elements(src->cbufs); i++) {
+ if (dst->cbufs[i] != src->cbufs[i]) {
+ return FALSE;
+ }
+ }
+
+ if (dst->nr_cbufs != src->nr_cbufs) {
+ return FALSE;
+ }
+
+ if (dst->zsbuf != src->zsbuf) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/**
+ * Copy framebuffer state from src to dst, updating refcounts.
+ */
+void
+util_copy_framebuffer_state(struct pipe_framebuffer_state *dst,
+ const struct pipe_framebuffer_state *src)
+{
+ unsigned i;
+
+ dst->width = src->width;
+ dst->height = src->height;
+
+ for (i = 0; i < Elements(src->cbufs); i++) {
+ pipe_surface_reference(&dst->cbufs[i], src->cbufs[i]);
+ }
+
+ dst->nr_cbufs = src->nr_cbufs;
+
+ pipe_surface_reference(&dst->zsbuf, src->zsbuf);
+}
+
+
+void
+util_unreference_framebuffer_state(struct pipe_framebuffer_state *fb)
+{
+ unsigned i;
+
+ for (i = 0; i < fb->nr_cbufs; i++) {
+ pipe_surface_reference(&fb->cbufs[i], NULL);
+ }
+
+ pipe_surface_reference(&fb->zsbuf, NULL);
+
+ fb->width = fb->height = 0;
+ fb->nr_cbufs = 0;
+}
diff --git a/src/gallium/auxiliary/util/u_surface.h b/src/gallium/auxiliary/util/u_surface.h
index ce84ed7ad06..3c60df2c3e5 100644
--- a/src/gallium/auxiliary/util/u_surface.h
+++ b/src/gallium/auxiliary/util/u_surface.h
@@ -30,11 +30,7 @@
#include "pipe/p_compiler.h"
-
-
-struct pipe_screen;
-struct pipe_texture;
-struct pipe_surface;
+#include "pipe/p_state.h"
/**
@@ -66,4 +62,17 @@ util_destroy_rgba_surface(struct pipe_texture *texture,
struct pipe_surface *surface);
+extern boolean
+util_framebuffer_state_equal(const struct pipe_framebuffer_state *dst,
+ const struct pipe_framebuffer_state *src);
+
+extern void
+util_copy_framebuffer_state(struct pipe_framebuffer_state *dst,
+ const struct pipe_framebuffer_state *src);
+
+
+extern void
+util_unreference_framebuffer_state(struct pipe_framebuffer_state *fb);
+
+
#endif /* U_SURFACE_H */
diff --git a/src/gallium/auxiliary/util/u_time.h b/src/gallium/auxiliary/util/u_time.h
index 7580ac0de4c..15899c2c884 100644
--- a/src/gallium/auxiliary/util/u_time.h
+++ b/src/gallium/auxiliary/util/u_time.h
@@ -67,6 +67,9 @@ util_time_get(struct util_time *t)
}
+/**
+ * Return t2 = t1 + usecs
+ */
PIPE_DEPRECATED
static INLINE void
util_time_add(const struct util_time *t1,
@@ -77,6 +80,9 @@ util_time_add(const struct util_time *t1,
}
+/**
+ * Return difference between times, in microseconds
+ */
PIPE_DEPRECATED
static INLINE int64_t
util_time_diff(const struct util_time *t1,
@@ -105,6 +111,9 @@ _util_time_compare(const struct util_time *t1,
}
+/**
+ * Returns non-zero when the timeout expires.
+ */
PIPE_DEPRECATED
static INLINE boolean
util_time_timeout(const struct util_time *start,
@@ -115,6 +124,9 @@ util_time_timeout(const struct util_time *start,
}
+/**
+ * Return current time in microseconds
+ */
PIPE_DEPRECATED
static INLINE int64_t
util_time_micros(void)