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/u_blit.c82
-rw-r--r--src/gallium/auxiliary/util/u_debug.c2
-rw-r--r--src/gallium/auxiliary/util/u_math.h75
-rw-r--r--src/gallium/auxiliary/util/u_simple_screen.c3
-rw-r--r--src/gallium/auxiliary/util/u_surface.h17
-rw-r--r--src/gallium/auxiliary/util/u_timed_winsys.c3
6 files changed, 141 insertions, 41 deletions
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index 414cf91025..cda6dbd46d 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -45,6 +45,7 @@
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_simple_shaders.h"
+#include "util/u_surface.h"
#include "cso_cache/cso_context.h"
@@ -155,7 +156,11 @@ util_destroy_blit(struct blit_state *ctx)
}
-static unsigned get_next_slot( struct blit_state *ctx )
+/**
+ * Get offset of next free slot in vertex buffer for quad vertices.
+ */
+static unsigned
+get_next_slot( struct blit_state *ctx )
{
const unsigned max_slots = 4096 / sizeof ctx->vertices;
@@ -173,7 +178,6 @@ static unsigned get_next_slot( struct blit_state *ctx )
}
-
/**
* Setup vertex data for the textured quad we'll draw.
* Note: y=0=top
@@ -260,9 +264,38 @@ setup_vertex_data_tex(struct blit_state *ctx,
return offset;
}
+
+
+/**
+ * \return TRUE if two regions overlap, FALSE otherwise
+ */
+static boolean
+regions_overlap(int srcX0, int srcY0,
+ int srcX1, int srcY1,
+ int dstX0, int dstY0,
+ int dstX1, int dstY1)
+{
+ if (MAX2(srcX0, srcX1) < MIN2(dstX0, dstX1))
+ return FALSE; /* src completely left of dst */
+
+ if (MAX2(dstX0, dstX1) < MIN2(srcX0, srcX1))
+ return FALSE; /* dst completely left of src */
+
+ if (MAX2(srcY0, srcY1) < MIN2(dstY0, dstY1))
+ return FALSE; /* src completely above dst */
+
+ if (MAX2(dstY0, dstY1) < MIN2(srcY0, srcY1))
+ return FALSE; /* dst completely above src */
+
+ return TRUE; /* some overlap */
+}
+
+
/**
* Copy pixel block from src surface to dst surface.
* Overlapping regions are acceptable.
+ * Flipping and stretching are supported.
+ * XXX what about clipping???
* XXX need some control over blitting Z and/or stencil.
*/
void
@@ -285,10 +318,41 @@ util_blit_pixels(struct blit_state *ctx,
const int srcLeft = MIN2(srcX0, srcX1);
const int srcTop = MIN2(srcY0, srcY1);
unsigned offset;
+ boolean overlap;
assert(filter == PIPE_TEX_MIPFILTER_NEAREST ||
filter == PIPE_TEX_MIPFILTER_LINEAR);
+ 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_RENDER_TARGET, 0));
+
+ /* do the regions overlap? */
+ overlap = util_same_surface(src, dst) &&
+ regions_overlap(srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1);
+
+ /*
+ * Check for simple case: no format conversion, no flipping, no stretching,
+ * no overlapping.
+ * Filter mode should not matter since there's no stretching.
+ */
+ if (dst->format == src->format &&
+ srcX0 < srcX1 &&
+ dstX0 < dstX1 &&
+ srcY0 < srcY1 &&
+ dstY0 < dstY1 &&
+ (dstX1 - dstX0) == (srcX1 - srcX0) &&
+ (dstY1 - dstY0) == (srcY1 - srcY0) &&
+ !overlap) {
+ pipe->surface_copy(pipe,
+ dst, dstX0, dstY0, /* dest */
+ src, srcX0, srcY0, /* src */
+ srcW, srcH); /* size */
+ return;
+ }
+
if (srcLeft != srcX0) {
/* left-right flip */
int tmp = dstX0;
@@ -303,20 +367,6 @@ util_blit_pixels(struct blit_state *ctx,
dstY1 = tmp;
}
- 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 */
- pipe->surface_copy(pipe,
- dst, dstX0, dstY0, /* dest */
- src, srcX0, srcY0, /* src */
- srcW, srcH); /* size */
- return;
- }
-
assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0));
diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c
index a5ca0b72bd..96d400c839 100644
--- a/src/gallium/auxiliary/util/u_debug.c
+++ b/src/gallium/auxiliary/util/u_debug.c
@@ -143,11 +143,9 @@ void _debug_vprintf(const char *format, va_list ap)
#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
/* TODO */
#else /* !PIPE_SUBSYSTEM_WINDOWS */
-#ifdef DEBUG
fflush(stdout);
vfprintf(stderr, format, ap);
#endif
-#endif
}
diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h
index e5003af01d..57410e78b0 100644
--- a/src/gallium/auxiliary/util/u_math.h
+++ b/src/gallium/auxiliary/util/u_math.h
@@ -53,11 +53,11 @@ __inline double ceil(double val)
{
double ceil_val;
- if((val - (long) val) == 0) {
+ if ((val - (long) val) == 0) {
ceil_val = val;
}
else {
- if(val > 0) {
+ if (val > 0) {
ceil_val = (long) val + 1;
}
else {
@@ -73,11 +73,11 @@ __inline double floor(double val)
{
double floor_val;
- if((val - (long) val) == 0) {
+ if ((val - (long) val) == 0) {
floor_val = val;
}
else {
- if(val > 0) {
+ if (val > 0) {
floor_val = (long) val;
}
else {
@@ -189,7 +189,10 @@ static INLINE double log2( double x )
extern float pow2_table[POW2_TABLE_SIZE];
-
+/**
+ * Initialize math module. This should be called before using any
+ * other functions in this module.
+ */
extern void
util_init_math(void);
@@ -216,23 +219,24 @@ util_fast_exp2(float x)
int32_t ipart;
float fpart, mpart;
union fi epart;
-
+
if(x > 129.00000f)
return 3.402823466e+38f;
-
- if(x < -126.99999f)
+
+ if (x < -126.99999f)
return 0.0f;
ipart = (int32_t) x;
fpart = x - (float) ipart;
-
+
/* same as
* epart.f = (float) (1 << ipart)
- * but faster and without integer overflow for ipart > 31 */
+ * but faster and without integer overflow for ipart > 31
+ */
epart.i = (ipart + 127 ) << 23;
-
+
mpart = pow2_table[POW2_TABLE_OFFSET + (int)(fpart * POW2_TABLE_SCALE)];
-
+
return epart.f * mpart;
}
@@ -254,6 +258,9 @@ util_fast_exp(float x)
extern float log2_table[LOG2_TABLE_SIZE];
+/**
+ * Fast approximation to log2(x).
+ */
static INLINE float
util_fast_log2(float x)
{
@@ -267,6 +274,9 @@ util_fast_log2(float x)
}
+/**
+ * Fast approximation to x^y.
+ */
static INLINE float
util_fast_pow(float x, float y)
{
@@ -274,7 +284,6 @@ util_fast_pow(float x, float y)
}
-
/**
* Floor(x), returned as int.
*/
@@ -284,8 +293,8 @@ util_ifloor(float f)
int ai, bi;
double af, bf;
union fi u;
- af = (3 << 22) + 0.5 + (double)f;
- bf = (3 << 22) + 0.5 - (double)f;
+ af = (3 << 22) + 0.5 + (double) f;
+ bf = (3 << 22) + 0.5 - (double) f;
u.f = (float) af; ai = u.i;
u.f = (float) bf; bi = u.i;
return (ai - bi) >> 1;
@@ -305,9 +314,9 @@ util_iround(float f)
#elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)
int r;
_asm {
- fld f
- fistp r
- }
+ fld f
+ fistp r
+ }
return r;
#else
if (f >= 0.0f)
@@ -340,7 +349,7 @@ static INLINE
unsigned long ffs( unsigned long u )
{
unsigned long i;
- if(_BitScanForward(&i, u))
+ if (_BitScanForward(&i, u))
return i + 1;
else
return 0;
@@ -351,7 +360,7 @@ unsigned ffs( unsigned u )
{
unsigned i;
- if( u == 0 ) {
+ if (u == 0) {
return 0;
}
@@ -378,7 +387,10 @@ fui( float f )
}
-
+/**
+ * Convert ubyte to float in [0, 1].
+ * XXX a 256-entry lookup table would be slightly faster.
+ */
static INLINE float
ubyte_to_float(ubyte ub)
{
@@ -409,7 +421,23 @@ float_to_ubyte(float f)
}
+/**
+ * Calc log base 2
+ */
+static INLINE unsigned
+util_logbase2(unsigned n)
+{
+ unsigned log2 = 0;
+ while (n >>= 1)
+ ++log2;
+ return log2;
+}
+
+/**
+ * Clamp X to [MIN, MAX].
+ * This is a macro to allow float, int, uint, etc. types.
+ */
#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) )
@@ -422,6 +450,11 @@ align(int value, int alignment)
return (value + alignment - 1) & ~(alignment - 1);
}
+static INLINE unsigned
+minify(unsigned value)
+{
+ return MAX2(1, value >> 1);
+}
#ifndef COPY_4V
#define COPY_4V( DST, SRC ) \
diff --git a/src/gallium/auxiliary/util/u_simple_screen.c b/src/gallium/auxiliary/util/u_simple_screen.c
index 8114b53cd0..f01296b40f 100644
--- a/src/gallium/auxiliary/util/u_simple_screen.c
+++ b/src/gallium/auxiliary/util/u_simple_screen.c
@@ -65,12 +65,13 @@ pass_surface_buffer_create(struct pipe_screen *screen,
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride)
{
struct pipe_buffer *buffer =
screen->winsys->surface_buffer_create(screen->winsys,
width, height,
- format, usage, stride);
+ format, usage, tex_usage, stride);
buffer->screen = screen;
diff --git a/src/gallium/auxiliary/util/u_surface.h b/src/gallium/auxiliary/util/u_surface.h
index a5b73cfc20..ce84ed7ad0 100644
--- a/src/gallium/auxiliary/util/u_surface.h
+++ b/src/gallium/auxiliary/util/u_surface.h
@@ -37,6 +37,23 @@ struct pipe_texture;
struct pipe_surface;
+/**
+ * Are s1 and s2 the same surface?
+ * Surfaces are basically views into textures so check if the two surfaces
+ * name the same part of the same texture.
+ */
+static INLINE boolean
+util_same_surface(const struct pipe_surface *s1, const struct pipe_surface *s2)
+{
+ return (s1->texture == s2->texture &&
+ s1->face == s2->face &&
+ s1->level == s2->level &&
+ s1->zslice == s2->zslice);
+}
+
+
+
+
extern boolean
util_create_rgba_surface(struct pipe_screen *screen,
uint width, uint height,
diff --git a/src/gallium/auxiliary/util/u_timed_winsys.c b/src/gallium/auxiliary/util/u_timed_winsys.c
index 77b2a3a1c8..178acdca4d 100644
--- a/src/gallium/auxiliary/util/u_timed_winsys.c
+++ b/src/gallium/auxiliary/util/u_timed_winsys.c
@@ -212,13 +212,14 @@ timed_surface_buffer_create(struct pipe_winsys *winsys,
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride)
{
struct pipe_winsys *backend = timed_winsys(winsys)->backend;
uint64_t start = time_start();
struct pipe_buffer *ret = backend->surface_buffer_create( backend, width, height,
- format, usage, stride );
+ format, usage, tex_usage, stride );
time_finish(winsys, start, 7, __FUNCTION__);