summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/util
diff options
context:
space:
mode:
authorChristian König <[email protected]>2011-03-19 01:02:40 +0100
committerChristian König <[email protected]>2011-03-19 01:02:40 +0100
commit2bf95c519e755146704f4942b1703d47d18bfeaa (patch)
tree9d29c5d56014377013770615611f903cd5b25292 /src/gallium/auxiliary/util
parentf36846c77ee196881c0da560229279fc7ed88170 (diff)
parent8042d751debb7a8375e8bc587189fea9a5a8371d (diff)
Merge remote branch 'origin/master' into pipe-video
Conflicts: src/gallium/drivers/r600/r600_asm.c src/gallium/tests/unit/SConscript
Diffstat (limited to 'src/gallium/auxiliary/util')
-rw-r--r--src/gallium/auxiliary/util/u_blit.c156
-rw-r--r--src/gallium/auxiliary/util/u_blitter.c7
-rw-r--r--src/gallium/auxiliary/util/u_cache.c170
-rw-r--r--src/gallium/auxiliary/util/u_cache.h4
-rw-r--r--src/gallium/auxiliary/util/u_caps.c3
-rw-r--r--src/gallium/auxiliary/util/u_draw_quad.c4
-rw-r--r--src/gallium/auxiliary/util/u_format.csv6
-rw-r--r--src/gallium/auxiliary/util/u_format_latc.c328
-rw-r--r--src/gallium/auxiliary/util/u_format_latc.h108
-rw-r--r--src/gallium/auxiliary/util/u_format_rgtc.c20
-rw-r--r--src/gallium/auxiliary/util/u_format_rgtc.h6
-rwxr-xr-xsrc/gallium/auxiliary/util/u_format_table.py1
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c108
-rw-r--r--src/gallium/auxiliary/util/u_inlines.h9
-rw-r--r--src/gallium/auxiliary/util/u_pstipple.c434
-rw-r--r--src/gallium/auxiliary/util/u_pstipple.h56
-rw-r--r--src/gallium/auxiliary/util/u_resource.c8
-rw-r--r--src/gallium/auxiliary/util/u_simple_screen.h3
-rw-r--r--src/gallium/auxiliary/util/u_surface.c2
-rw-r--r--src/gallium/auxiliary/util/u_transfer.c7
-rw-r--r--src/gallium/auxiliary/util/u_transfer.h12
-rw-r--r--src/gallium/auxiliary/util/u_upload_mgr.c4
-rw-r--r--src/gallium/auxiliary/util/u_vbuf_mgr.c15
23 files changed, 1295 insertions, 176 deletions
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index 76bd7ace526..421726b40e0 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -128,21 +128,6 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
}
- /* vertex shader - still required to provide the linkage between
- * fragment shader input semantics and vertex_element/buffers.
- */
- {
- const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
- TGSI_SEMANTIC_GENERIC };
- const uint semantic_indexes[] = { 0, 0 };
- ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
- semantic_indexes);
- }
-
- /* fragment shader */
- ctx->fs[TGSI_WRITEMASK_XYZW] =
- util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D,
- TGSI_INTERPOLATE_LINEAR);
ctx->vbuf = NULL;
/* init vertex data that doesn't change */
@@ -170,7 +155,8 @@ util_destroy_blit(struct blit_state *ctx)
struct pipe_context *pipe = ctx->pipe;
unsigned i;
- pipe->delete_vs_state(pipe, ctx->vs);
+ if (ctx->vs)
+ pipe->delete_vs_state(pipe, ctx->vs);
for (i = 0; i < Elements(ctx->fs); i++)
if (ctx->fs[i])
@@ -186,6 +172,59 @@ util_destroy_blit(struct blit_state *ctx)
/**
+ * Helper function to set the fragment shaders.
+ */
+static INLINE void
+set_fragment_shader(struct blit_state *ctx, uint writemask)
+{
+ if (!ctx->fs[writemask])
+ ctx->fs[writemask] =
+ util_make_fragment_tex_shader_writemask(ctx->pipe, TGSI_TEXTURE_2D,
+ TGSI_INTERPOLATE_LINEAR,
+ writemask);
+
+ cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]);
+}
+
+
+/**
+ * Helper function to set the depthwrite shader.
+ */
+static INLINE void
+set_depth_fragment_shader(struct blit_state *ctx)
+{
+ if (!ctx->fs_depth)
+ ctx->fs_depth =
+ util_make_fragment_tex_shader_writedepth(ctx->pipe, TGSI_TEXTURE_2D,
+ TGSI_INTERPOLATE_LINEAR);
+
+ cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth);
+}
+
+
+/**
+ * Helper function to set the vertex shader.
+ */
+static INLINE void
+set_vertex_shader(struct blit_state *ctx)
+{
+ /* vertex shader - still required to provide the linkage between
+ * fragment shader input semantics and vertex_element/buffers.
+ */
+ if (!ctx->vs) {
+ const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
+ TGSI_SEMANTIC_GENERIC };
+ const uint semantic_indexes[] = { 0, 0 };
+ ctx->vs = util_make_vertex_passthrough_shader(ctx->pipe, 2,
+ semantic_names,
+ semantic_indexes);
+ }
+
+ cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
+}
+
+
+/**
* Get offset of next free slot in vertex buffer for quad vertices.
*/
static unsigned
@@ -304,8 +343,10 @@ util_blit_pixels_writemask(struct blit_state *ctx,
{
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
+ enum pipe_format src_format, dst_format;
struct pipe_sampler_view *sampler_view = NULL;
struct pipe_sampler_view sv_templ;
+ struct pipe_surface *dst_surface;
struct pipe_framebuffer_state fb;
const int srcW = abs(srcX1 - srcX0);
const int srcH = abs(srcY1 - srcY0);
@@ -326,12 +367,15 @@ util_blit_pixels_writemask(struct blit_state *ctx,
regions_overlap(srcX0, srcY0, srcX1, srcY1,
dstX0, dstY0, dstX1, dstY1);
+ src_format = util_format_linear(src_tex->format);
+ dst_format = util_format_linear(dst->format);
+
/*
* 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_tex->format &&
+ if (dst_format == src_format &&
srcX0 < srcX1 &&
dstX0 < dstX1 &&
srcY0 < srcY1 &&
@@ -354,6 +398,14 @@ util_blit_pixels_writemask(struct blit_state *ctx,
return;
}
+ if (dst_format == dst->format) {
+ dst_surface = dst;
+ } else {
+ struct pipe_surface templ = *dst;
+ templ.format = dst_format;
+ dst_surface = pipe->create_surface(pipe, dst->texture, &templ);
+ }
+
/* Create a temporary texture when src and dest alias or when src
* is anything other than a 2d texture.
* XXX should just use appropriate shader to access 1d / 3d slice / cube face,
@@ -361,9 +413,9 @@ util_blit_pixels_writemask(struct blit_state *ctx,
*
* This can still be improved upon.
*/
- if ((src_tex == dst->texture &&
- dst->u.tex.level == src_level &&
- dst->u.tex.first_layer == srcZ0) ||
+ if ((src_tex == dst_surface->texture &&
+ dst_surface->u.tex.level == src_level &&
+ dst_surface->u.tex.first_layer == srcZ0) ||
(src_tex->target != PIPE_TEXTURE_2D &&
src_tex->target != PIPE_TEXTURE_2D &&
src_tex->target != PIPE_TEXTURE_RECT))
@@ -392,7 +444,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
/* create temp texture */
memset(&texTemp, 0, sizeof(texTemp));
texTemp.target = ctx->internal_target;
- texTemp.format = src_tex->format;
+ texTemp.format = src_format;
texTemp.last_level = 0;
texTemp.width0 = srcW;
texTemp.height0 = srcH;
@@ -439,7 +491,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
pipe_resource_reference(&tex, NULL);
}
else {
- u_sampler_view_default_template(&sv_templ, src_tex, src_tex->format);
+ u_sampler_view_default_template(&sv_templ, src_tex, src_format);
sampler_view = pipe->create_sampler_view(pipe, src_tex, &sv_templ);
if (!sampler_view) {
@@ -460,15 +512,15 @@ util_blit_pixels_writemask(struct blit_state *ctx,
}
}
- dst_is_depth = util_format_is_depth_or_stencil(dst->format);
+ dst_is_depth = util_format_is_depth_or_stencil(dst_format);
assert(screen->is_format_supported(screen, sampler_view->format, ctx->internal_target,
sampler_view->texture->nr_samples,
- PIPE_BIND_SAMPLER_VIEW, 0));
- assert(screen->is_format_supported(screen, dst->format, ctx->internal_target,
- dst->texture->nr_samples,
+ PIPE_BIND_SAMPLER_VIEW));
+ assert(screen->is_format_supported(screen, dst_format, ctx->internal_target,
+ dst_surface->texture->nr_samples,
dst_is_depth ? PIPE_BIND_DEPTH_STENCIL :
- PIPE_BIND_RENDER_TARGET, 0));
+ PIPE_BIND_RENDER_TARGET));
/* save state (restored below) */
cso_save_blend(ctx->cso);
cso_save_depth_stencil_alpha(ctx->cso);
@@ -502,12 +554,12 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_single_sampler_done(ctx->cso);
/* viewport */
- ctx->viewport.scale[0] = 0.5f * dst->width;
- ctx->viewport.scale[1] = 0.5f * dst->height;
+ ctx->viewport.scale[0] = 0.5f * dst_surface->width;
+ ctx->viewport.scale[1] = 0.5f * dst_surface->height;
ctx->viewport.scale[2] = 0.5f;
ctx->viewport.scale[3] = 1.0f;
- ctx->viewport.translate[0] = 0.5f * dst->width;
- ctx->viewport.translate[1] = 0.5f * dst->height;
+ ctx->viewport.translate[0] = 0.5f * dst_surface->width;
+ ctx->viewport.translate[1] = 0.5f * dst_surface->height;
ctx->viewport.translate[2] = 0.5f;
ctx->viewport.translate[3] = 0.0f;
cso_set_viewport(ctx->cso, &ctx->viewport);
@@ -517,41 +569,30 @@ util_blit_pixels_writemask(struct blit_state *ctx,
/* shaders */
if (dst_is_depth) {
- if (ctx->fs_depth == NULL)
- ctx->fs_depth =
- util_make_fragment_tex_shader_writedepth(pipe, TGSI_TEXTURE_2D,
- TGSI_INTERPOLATE_LINEAR);
-
- cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth);
+ set_depth_fragment_shader(ctx);
} else {
- if (ctx->fs[writemask] == NULL)
- ctx->fs[writemask] =
- util_make_fragment_tex_shader_writemask(pipe, TGSI_TEXTURE_2D,
- TGSI_INTERPOLATE_LINEAR,
- writemask);
-
- cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]);
+ set_fragment_shader(ctx, writemask);
}
- cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
+ set_vertex_shader(ctx);
/* drawing dest */
memset(&fb, 0, sizeof(fb));
- fb.width = dst->width;
- fb.height = dst->height;
+ fb.width = dst_surface->width;
+ fb.height = dst_surface->height;
if (dst_is_depth) {
- fb.zsbuf = dst;
+ fb.zsbuf = dst_surface;
} else {
fb.nr_cbufs = 1;
- fb.cbufs[0] = dst;
+ fb.cbufs[0] = dst_surface;
}
cso_set_framebuffer(ctx->cso, &fb);
/* draw quad */
offset = setup_vertex_data_tex(ctx,
- (float) dstX0 / dst->width * 2.0f - 1.0f,
- (float) dstY0 / dst->height * 2.0f - 1.0f,
- (float) dstX1 / dst->width * 2.0f - 1.0f,
- (float) dstY1 / dst->height * 2.0f - 1.0f,
+ (float) dstX0 / dst_surface->width * 2.0f - 1.0f,
+ (float) dstY0 / dst_surface->height * 2.0f - 1.0f,
+ (float) dstX1 / dst_surface->width * 2.0f - 1.0f,
+ (float) dstY1 / dst_surface->height * 2.0f - 1.0f,
s0, t0,
s1, t1,
z);
@@ -576,6 +617,8 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_restore_vertex_buffers(ctx->cso);
pipe_sampler_view_reference(&sampler_view, NULL);
+ if (dst_surface != dst)
+ pipe_surface_reference(&dst_surface, NULL);
}
@@ -660,8 +703,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
assert(ctx->pipe->screen->is_format_supported(ctx->pipe->screen, dst->format,
PIPE_TEXTURE_2D,
dst->texture->nr_samples,
- PIPE_BIND_RENDER_TARGET,
- 0));
+ PIPE_BIND_RENDER_TARGET));
/* save state (restored below) */
cso_save_blend(ctx->cso);
@@ -706,8 +748,8 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_set_fragment_sampler_views(ctx->cso, 1, &src_sampler_view);
/* shaders */
- cso_set_fragment_shader_handle(ctx->cso, ctx->fs[TGSI_WRITEMASK_XYZW]);
- cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
+ set_fragment_shader(ctx, TGSI_WRITEMASK_XYZW);
+ set_vertex_shader(ctx);
/* drawing dest */
memset(&fb, 0, sizeof(fb));
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index fd1c2b72d04..a4c399052fd 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -772,9 +772,9 @@ void util_blitter_copy_region(struct blitter_context *blitter,
/* (assuming copying a stencil buffer is not possible) */
if ((!ignore_stencil && is_stencil) ||
!screen->is_format_supported(screen, dst->format, dst->target,
- dst->nr_samples, bind, 0) ||
+ dst->nr_samples, bind) ||
!screen->is_format_supported(screen, src->format, src->target,
- src->nr_samples, PIPE_BIND_SAMPLER_VIEW, 0)) {
+ src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) {
ctx->base.running = TRUE;
util_resource_copy_region(pipe, dst, dstlevel, dstx, dsty, dstz,
src, srclevel, srcbox);
@@ -785,6 +785,7 @@ void util_blitter_copy_region(struct blitter_context *blitter,
/* Get surface. */
memset(&surf_templ, 0, sizeof(surf_templ));
u_surface_default_template(&surf_templ, dst, bind);
+ surf_templ.format = util_format_linear(dst->format);
surf_templ.u.tex.level = dstlevel;
surf_templ.u.tex.first_layer = dstz;
surf_templ.u.tex.last_layer = dstz;
@@ -823,7 +824,7 @@ void util_blitter_copy_region(struct blitter_context *blitter,
normalized = src->target != PIPE_TEXTURE_RECT;
/* Initialize sampler view. */
- u_sampler_view_default_template(&viewTempl, src, src->format);
+ u_sampler_view_default_template(&viewTempl, src, util_format_linear(src->format));
view = pipe->create_sampler_view(pipe, src, &viewTempl);
/* Set rasterizer state, shaders, and textures. */
diff --git a/src/gallium/auxiliary/util/u_cache.c b/src/gallium/auxiliary/util/u_cache.c
index 15f4a8831f2..df08ec302a2 100644
--- a/src/gallium/auxiliary/util/u_cache.c
+++ b/src/gallium/auxiliary/util/u_cache.c
@@ -27,9 +27,10 @@
/**
* @file
- * Simple cache implementation.
+ * Improved cache implementation.
*
- * We simply have fixed size array, and destroy previous values on collision.
+ * Fixed size array with linear probing on collision and LRU eviction
+ * on full.
*
* @author Jose Fonseca <[email protected]>
*/
@@ -41,10 +42,17 @@
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_cache.h"
+#include "util/u_simple_list.h"
struct util_cache_entry
{
+ enum { EMPTY = 0, FILLED, DELETED } state;
+ uint32_t hash;
+
+ struct util_cache_entry *next;
+ struct util_cache_entry *prev;
+
void *key;
void *value;
@@ -69,11 +77,14 @@ struct util_cache
struct util_cache_entry *entries;
-#ifdef DEBUG
unsigned count;
-#endif
+ struct util_cache_entry lru;
};
+static void
+ensure_sanity(const struct util_cache *cache);
+
+#define CACHE_DEFAULT_ALPHA 2
struct util_cache *
util_cache_create(uint32_t (*hash)(const void *key),
@@ -90,6 +101,10 @@ util_cache_create(uint32_t (*hash)(const void *key),
cache->hash = hash;
cache->compare = compare;
cache->destroy = destroy;
+
+ make_empty_list(&cache->lru);
+
+ size *= CACHE_DEFAULT_ALPHA;
cache->size = size;
cache->entries = CALLOC(size, sizeof(struct util_cache_entry));
@@ -98,19 +113,46 @@ util_cache_create(uint32_t (*hash)(const void *key),
return NULL;
}
+ ensure_sanity(cache);
return cache;
}
-static INLINE struct util_cache_entry *
+static struct util_cache_entry *
util_cache_entry_get(struct util_cache *cache,
+ uint32_t hash,
const void *key)
{
- uint32_t hash;
-
- hash = cache->hash(key);
+ struct util_cache_entry *first_unfilled = NULL;
+ uint32_t index = hash % cache->size;
+ uint32_t probe;
+
+ /* Probe until we find either a matching FILLED entry or an EMPTY
+ * slot (which has never been occupied).
+ *
+ * Deleted or non-matching slots are not indicative of completion
+ * as a previous linear probe for the same key could have continued
+ * past this point.
+ */
+ for (probe = 0; probe < cache->size; probe++) {
+ uint32_t i = (index + probe) % cache->size;
+ struct util_cache_entry *current = &cache->entries[i];
+
+ if (current->state == FILLED) {
+ if (current->hash == hash &&
+ cache->compare(key, current->key) == 0)
+ return current;
+ }
+ else {
+ if (!first_unfilled)
+ first_unfilled = current;
+
+ if (current->state == EMPTY)
+ return first_unfilled;
+ }
+ }
- return &cache->entries[hash % cache->size];
+ return NULL;
}
static INLINE void
@@ -123,9 +165,15 @@ util_cache_entry_destroy(struct util_cache *cache,
entry->key = NULL;
entry->value = NULL;
- if(key || value)
+ if (entry->state == FILLED) {
+ remove_from_list(entry);
+ cache->count--;
+
if(cache->destroy)
cache->destroy(key, value);
+
+ entry->state = DELETED;
+ }
}
@@ -135,21 +183,33 @@ util_cache_set(struct util_cache *cache,
void *value)
{
struct util_cache_entry *entry;
+ uint32_t hash = cache->hash(key);
assert(cache);
if (!cache)
return;
- entry = util_cache_entry_get(cache, key);
+ entry = util_cache_entry_get(cache, hash, key);
+ if (!entry)
+ entry = cache->lru.prev;
+
+ if (cache->count >= cache->size / CACHE_DEFAULT_ALPHA)
+ util_cache_entry_destroy(cache, cache->lru.prev);
+
util_cache_entry_destroy(cache, entry);
#ifdef DEBUG
++entry->count;
- ++cache->count;
#endif
entry->key = key;
+ entry->hash = hash;
entry->value = value;
+ entry->state = FILLED;
+ insert_at_head(&cache->lru, entry);
+ cache->count++;
+
+ ensure_sanity(cache);
}
@@ -158,17 +218,18 @@ util_cache_get(struct util_cache *cache,
const void *key)
{
struct util_cache_entry *entry;
+ uint32_t hash = cache->hash(key);
assert(cache);
if (!cache)
return NULL;
- entry = util_cache_entry_get(cache, key);
- if(!entry->key && !entry->value)
- return NULL;
-
- if(cache->compare(key, entry->key) != 0)
+ entry = util_cache_entry_get(cache, hash, key);
+ if (!entry)
return NULL;
+
+ if (entry->state == FILLED)
+ move_to_head(&cache->lru, entry);
return entry->value;
}
@@ -183,8 +244,14 @@ util_cache_clear(struct util_cache *cache)
if (!cache)
return;
- for(i = 0; i < cache->size; ++i)
+ for(i = 0; i < cache->size; ++i) {
util_cache_entry_destroy(cache, &cache->entries[i]);
+ cache->entries[i].state = EMPTY;
+ }
+
+ assert(cache->count == 0);
+ assert(is_empty_list(&cache->lru));
+ ensure_sanity(cache);
}
@@ -215,3 +282,70 @@ util_cache_destroy(struct util_cache *cache)
FREE(cache->entries);
FREE(cache);
}
+
+
+void
+util_cache_remove(struct util_cache *cache,
+ const void *key)
+{
+ struct util_cache_entry *entry;
+ uint32_t hash;
+
+ assert(cache);
+ if (!cache)
+ return;
+
+ hash = cache->hash(key);
+
+ entry = util_cache_entry_get(cache, hash, key);
+ if (!entry)
+ return;
+
+ if (entry->state == FILLED)
+ util_cache_entry_destroy(cache, entry);
+
+ ensure_sanity(cache);
+}
+
+
+static void
+ensure_sanity(const struct util_cache *cache)
+{
+#ifdef DEBUG
+ unsigned i, cnt = 0;
+
+ assert(cache);
+ for (i = 0; i < cache->size; i++) {
+ struct util_cache_entry *header = &cache->entries[i];
+
+ assert(header);
+ assert(header->state == FILLED ||
+ header->state == EMPTY ||
+ header->state == DELETED);
+ if (header->state == FILLED) {
+ cnt++;
+ assert(header->hash == cache->hash(header->key));
+ }
+ }
+
+ assert(cnt == cache->count);
+ assert(cache->size >= cnt);
+
+ if (cache->count == 0) {
+ assert (is_empty_list(&cache->lru));
+ }
+ else {
+ struct util_cache_entry *header = cache->lru.next;
+
+ assert (header);
+ assert (!is_empty_list(&cache->lru));
+
+ for (i = 0; i < cache->count; i++)
+ header = header->next;
+
+ assert(header == &cache->lru);
+ }
+#endif
+
+ (void)cache;
+}
diff --git a/src/gallium/auxiliary/util/u_cache.h b/src/gallium/auxiliary/util/u_cache.h
index 8a612c6585f..be3631b7254 100644
--- a/src/gallium/auxiliary/util/u_cache.h
+++ b/src/gallium/auxiliary/util/u_cache.h
@@ -79,6 +79,10 @@ util_cache_clear(struct util_cache *cache);
void
util_cache_destroy(struct util_cache *cache);
+void
+util_cache_remove(struct util_cache *cache,
+ const void *key);
+
#ifdef __cplusplus
}
diff --git a/src/gallium/auxiliary/util/u_caps.c b/src/gallium/auxiliary/util/u_caps.c
index e209a98b706..75677b2b133 100644
--- a/src/gallium/auxiliary/util/u_caps.c
+++ b/src/gallium/auxiliary/util/u_caps.c
@@ -69,8 +69,7 @@ util_check_caps_out(struct pipe_screen *screen, const unsigned *list, int *out)
list[i++],
PIPE_TEXTURE_2D,
0,
- PIPE_BIND_SAMPLER_VIEW,
- 0)) {
+ PIPE_BIND_SAMPLER_VIEW)) {
*out = i - 2;
return FALSE;
}
diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c
index 0defd919974..8ed3b3c0959 100644
--- a/src/gallium/auxiliary/util/u_draw_quad.c
+++ b/src/gallium/auxiliary/util/u_draw_quad.c
@@ -82,7 +82,7 @@ util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso,
uint numAttribs = 2, i, j;
uint vertexBytes = 4 * (4 * numAttribs * sizeof(float));
struct pipe_resource *vbuf = NULL;
- uint *v = NULL;
+ float *v = NULL;
v = MALLOC(vertexBytes);
if (v == NULL)
@@ -121,7 +121,7 @@ util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso,
vbuf = pipe_user_buffer_create(pipe->screen, v, vertexBytes,
PIPE_BIND_VERTEX_BUFFER);
- if (!vbuf)
+ if (!vbuf)
goto out;
util_draw_vertex_buffer(pipe, cso, vbuf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv
index 0ae15c9cc0a..22c63ae162a 100644
--- a/src/gallium/auxiliary/util/u_format.csv
+++ b/src/gallium/auxiliary/util/u_format.csv
@@ -141,6 +141,7 @@ PIPE_FORMAT_R8G8Bx_SNORM , other, 1, 1, sn8 , sn8 , , , x
# - http://en.wikipedia.org/wiki/S3_Texture_Compression
# - http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt
# - http://www.opengl.org/registry/specs/ARB/texture_compression_rgtc.txt
+# - http://www.opengl.org/registry/specs/EXT/texture_compression_latc.txt
# - http://msdn.microsoft.com/en-us/library/bb694531.aspx
PIPE_FORMAT_DXT1_RGB , s3tc, 4, 4, x64 , , , , xyz1, rgb
PIPE_FORMAT_DXT1_RGBA , s3tc, 4, 4, x64 , , , , xyzw, rgb
@@ -156,6 +157,11 @@ PIPE_FORMAT_RGTC1_SNORM , rgtc, 4, 4, x64, , , , x001, rg
PIPE_FORMAT_RGTC2_UNORM , rgtc, 4, 4, x128, , , , xy01, rgb
PIPE_FORMAT_RGTC2_SNORM , rgtc, 4, 4, x128, , , , xy01, rgb
+PIPE_FORMAT_LATC1_UNORM , rgtc, 4, 4, x64, , , , xxx1, rgb
+PIPE_FORMAT_LATC1_SNORM , rgtc, 4, 4, x64, , , , xxx1, rgb
+PIPE_FORMAT_LATC2_UNORM , rgtc, 4, 4, x128, , , , xxxy, rgb
+PIPE_FORMAT_LATC2_SNORM , rgtc, 4, 4, x128, , , , xxxy, rgb
+
# Straightforward D3D10-like formats (also used for
# vertex buffer element description)
#
diff --git a/src/gallium/auxiliary/util/u_format_latc.c b/src/gallium/auxiliary/util/u_format_latc.c
new file mode 100644
index 00000000000..e84c493bb1e
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_format_latc.c
@@ -0,0 +1,328 @@
+/**************************************************************************
+ *
+ * Copyright (C) 2011 Red Hat Inc.
+ *
+ * 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, sublicense,
+ * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL 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.
+ *
+ **************************************************************************/
+
+#include <stdio.h>
+#include "u_math.h"
+#include "u_format.h"
+#include "u_format_rgtc.h"
+#include "u_format_latc.h"
+
+static void u_format_unsigned_encode_rgtc_chan(uint8_t *blkaddr, uint8_t srccolors[4][4],
+ int numxpixels, int numypixels);
+
+static void u_format_unsigned_fetch_texel_rgtc(unsigned srcRowStride, const uint8_t *pixdata,
+ unsigned i, unsigned j, uint8_t *value, unsigned comps);
+
+static void u_format_signed_encode_rgtc_chan(int8_t *blkaddr, int8_t srccolors[4][4],
+ int numxpixels, int numypixels);
+
+static void u_format_signed_fetch_texel_rgtc(unsigned srcRowStride, const int8_t *pixdata,
+ unsigned i, unsigned j, int8_t *value, unsigned comps);
+
+void
+util_format_latc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
+{
+ /* Fix warnings here: */
+ (void) u_format_unsigned_encode_rgtc_chan;
+ (void) u_format_signed_encode_rgtc_chan;
+
+ u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1);
+}
+
+void
+util_format_latc1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ util_format_rgtc1_unorm_unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
+}
+
+void
+util_format_latc1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row,
+ unsigned src_stride, unsigned width, unsigned height)
+{
+ util_format_rgtc1_unorm_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
+}
+
+void
+util_format_latc1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ unsigned x, y, i, j;
+ int block_size = 8;
+
+ for(y = 0; y < height; y += 4) {
+ const uint8_t *src = src_row;
+ for(x = 0; x < width; x += 4) {
+ for(j = 0; j < 4; ++j) {
+ for(i = 0; i < 4; ++i) {
+ float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
+ uint8_t tmp_r;
+ u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
+ dst[0] =
+ dst[1] =
+ dst[2] = ubyte_to_float(tmp_r);
+ dst[3] = 1.0;
+ }
+ }
+ src += block_size;
+ }
+ src_row += src_stride;
+ }
+}
+
+void
+util_format_latc1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ util_format_rgtc1_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height);
+}
+
+void
+util_format_latc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
+{
+ uint8_t tmp_r;
+
+ u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
+ dst[0] =
+ dst[1] =
+ dst[2] = ubyte_to_float(tmp_r);
+ dst[3] = 1.0;
+}
+
+void
+util_format_latc1_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
+{
+ fprintf(stderr,"%s\n", __func__);
+}
+
+void
+util_format_latc1_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ fprintf(stderr,"%s\n", __func__);
+}
+
+void
+util_format_latc1_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ fprintf(stderr,"%s\n", __func__);
+}
+
+void
+util_format_latc1_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ util_format_rgtc1_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height);
+}
+
+void
+util_format_latc1_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ unsigned x, y, i, j;
+ int block_size = 8;
+
+ for(y = 0; y < height; y += 4) {
+ const int8_t *src = (int8_t *)src_row;
+ for(x = 0; x < width; x += 4) {
+ for(j = 0; j < 4; ++j) {
+ for(i = 0; i < 4; ++i) {
+ float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
+ int8_t tmp_r;
+ u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
+ dst[0] =
+ dst[1] =
+ dst[2] = byte_to_float_tex(tmp_r);
+ dst[3] = 1.0;
+ }
+ }
+ src += block_size;
+ }
+ src_row += src_stride;
+ }
+}
+
+void
+util_format_latc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
+{
+ int8_t tmp_r;
+
+ u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 1);
+ dst[0] =
+ dst[1] =
+ dst[2] = byte_to_float_tex(tmp_r);
+ dst[3] = 1.0;
+}
+
+
+void
+util_format_latc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
+{
+ puts(__func__);
+
+ u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2);
+ u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2);
+}
+
+void
+util_format_latc2_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ util_format_rgtc2_unorm_unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
+}
+
+void
+util_format_latc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ util_format_rgtc2_unorm_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
+}
+
+void
+util_format_latc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ util_format_rxtc2_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 3);
+}
+
+void
+util_format_latc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ unsigned x, y, i, j;
+ int block_size = 16;
+
+ for(y = 0; y < height; y += 4) {
+ const uint8_t *src = src_row;
+ for(x = 0; x < width; x += 4) {
+ for(j = 0; j < 4; ++j) {
+ for(i = 0; i < 4; ++i) {
+ float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
+ uint8_t tmp_r, tmp_g;
+ u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
+ u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
+ dst[0] =
+ dst[1] =
+ dst[2] = ubyte_to_float(tmp_r);
+ dst[3] = ubyte_to_float(tmp_g);
+ }
+ }
+ src += block_size;
+ }
+ src_row += src_stride;
+ }
+}
+
+void
+util_format_latc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
+{
+ uint8_t tmp_r, tmp_g;
+
+ u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
+ u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
+ dst[0] =
+ dst[1] =
+ dst[2] = ubyte_to_float(tmp_r);
+ dst[3] = ubyte_to_float(tmp_g);
+}
+
+
+void
+util_format_latc2_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
+{
+ fprintf(stderr,"%s\n", __func__);
+}
+
+void
+util_format_latc2_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ fprintf(stderr,"%s\n", __func__);
+}
+
+void
+util_format_latc2_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ fprintf(stderr,"%s\n", __func__);
+}
+
+void
+util_format_latc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ unsigned x, y, i, j;
+ int block_size = 16;
+
+ for(y = 0; y < height; y += 4) {
+ const int8_t *src = (int8_t *)src_row;
+ for(x = 0; x < width; x += 4) {
+ for(j = 0; j < 4; ++j) {
+ for(i = 0; i < 4; ++i) {
+ float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
+ int8_t tmp_r, tmp_g;
+ u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
+ u_format_signed_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
+ dst[0] =
+ dst[1] =
+ dst[2] = byte_to_float_tex(tmp_r);
+ dst[3] = byte_to_float_tex(tmp_g);
+ }
+ }
+ src += block_size;
+ }
+ src_row += src_stride;
+ }
+}
+
+void
+util_format_latc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ util_format_rxtc2_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 3);
+}
+
+void
+util_format_latc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
+{
+ int8_t tmp_r, tmp_g;
+
+ u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 2);
+ u_format_signed_fetch_texel_rgtc(0, (int8_t *)src + 8, i, j, &tmp_g, 2);
+ dst[0] =
+ dst[1] =
+ dst[2] = byte_to_float_tex(tmp_r);
+ dst[3] = byte_to_float_tex(tmp_g);
+}
+
+
+#define TAG(x) u_format_unsigned_##x
+#define TYPE uint8_t
+#define T_MIN 0
+#define T_MAX 255
+
+#include "../../../mesa/main/texcompress_rgtc_tmp.h"
+
+#undef TYPE
+#undef TAG
+#undef T_MIN
+#undef T_MAX
+
+
+#define TAG(x) u_format_signed_##x
+#define TYPE int8_t
+#define T_MIN (int8_t)-128
+#define T_MAX (int8_t)127
+
+#include "../../../mesa/main/texcompress_rgtc_tmp.h"
+
+#undef TYPE
+#undef TAG
+#undef T_MIN
+#undef T_MAX
diff --git a/src/gallium/auxiliary/util/u_format_latc.h b/src/gallium/auxiliary/util/u_format_latc.h
new file mode 100644
index 00000000000..1f08887533d
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_format_latc.h
@@ -0,0 +1,108 @@
+/**************************************************************************
+ *
+ * Copyright 2011 Red Hat Inc.
+ * 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.
+ *
+ **************************************************************************/
+
+#ifndef U_FORMAT_LATC_H_
+#define U_FORMAT_LATC_H_
+
+void
+util_format_latc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j);
+
+void
+util_format_latc1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j);
+
+
+
+void
+util_format_latc1_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j);
+
+void
+util_format_latc1_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc1_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc1_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc1_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j);
+
+
+void
+util_format_latc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j);
+
+void
+util_format_latc2_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j);
+
+
+void
+util_format_latc2_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j);
+
+void
+util_format_latc2_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc2_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j);
+
+
+#endif
diff --git a/src/gallium/auxiliary/util/u_format_rgtc.c b/src/gallium/auxiliary/util/u_format_rgtc.c
index 6ffcd7e99ef..c929fd47e99 100644
--- a/src/gallium/auxiliary/util/u_format_rgtc.c
+++ b/src/gallium/auxiliary/util/u_format_rgtc.c
@@ -281,7 +281,7 @@ util_format_rgtc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
}
void
-util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
+util_format_rxtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off)
{
const unsigned bw = 4, bh = 4, bytes_per_block = 16;
unsigned x, y, i, j;
@@ -294,7 +294,7 @@ util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, c
for(j = 0; j < bh; ++j) {
for(i = 0; i < bw; ++i) {
tmp_r[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
- tmp_g[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + 1]);
+ tmp_g[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]);
}
}
u_format_unsigned_encode_rgtc_chan(dst, tmp_r, 4, 4);
@@ -306,6 +306,12 @@ util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, c
}
void
+util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ util_format_rxtc2_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 1);
+}
+
+void
util_format_rgtc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
{
unsigned x, y, i, j;
@@ -389,7 +395,7 @@ util_format_rgtc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, c
}
void
-util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
+util_format_rxtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off)
{
const unsigned bw = 4, bh = 4, bytes_per_block = 16;
unsigned x, y, i, j;
@@ -402,7 +408,7 @@ util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, c
for(j = 0; j < bh; ++j) {
for(i = 0; i < bw; ++i) {
tmp_r[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
- tmp_g[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + 1]);
+ tmp_g[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]);
}
}
u_format_signed_encode_rgtc_chan(dst, tmp_r, 4, 4);
@@ -414,6 +420,12 @@ util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, c
}
void
+util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ util_format_rxtc2_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 1);
+}
+
+void
util_format_rgtc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
{
int8_t tmp_r, tmp_g;
diff --git a/src/gallium/auxiliary/util/u_format_rgtc.h b/src/gallium/auxiliary/util/u_format_rgtc.h
index 3e8636d110c..67ac4728e56 100644
--- a/src/gallium/auxiliary/util/u_format_rgtc.h
+++ b/src/gallium/auxiliary/util/u_format_rgtc.h
@@ -77,6 +77,9 @@ void
util_format_rgtc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
void
+util_format_rxtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off);
+
+void
util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height);
void
@@ -99,6 +102,9 @@ void
util_format_rgtc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
void
+util_format_rxtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off);
+
+void
util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height);
void
diff --git a/src/gallium/auxiliary/util/u_format_table.py b/src/gallium/auxiliary/util/u_format_table.py
index 7468bc38b32..55e0f7827ef 100755
--- a/src/gallium/auxiliary/util/u_format_table.py
+++ b/src/gallium/auxiliary/util/u_format_table.py
@@ -88,6 +88,7 @@ def write_format_table(formats):
print '#include "u_format.h"'
print '#include "u_format_s3tc.h"'
print '#include "u_format_rgtc.h"'
+ print '#include "u_format_latc.h"'
print
u_format_pack.generate(formats)
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index 4f1b0e71934..4a1662462e5 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -67,7 +67,7 @@ struct gen_mipmap_state
struct pipe_vertex_element velem[2];
void *vs;
- void *fs1d, *fs2d, *fs3d, *fsCube, *fs1da, *fs2da;
+ void *fs[TGSI_TEXTURE_COUNT]; /**< Not all are used, but simplifies code */
struct pipe_resource *vbuf; /**< quad vertices */
unsigned vbuf_slot;
@@ -1301,34 +1301,6 @@ util_create_gen_mipmap(struct pipe_context *pipe,
ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
}
- /* vertex shader - still needed to specify mapping from fragment
- * shader input semantics to vertex elements
- */
- {
- const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
- TGSI_SEMANTIC_GENERIC };
- const uint semantic_indexes[] = { 0, 0 };
- ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
- semantic_indexes);
- }
-
- /* fragment shader */
- ctx->fs1d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_1D,
- TGSI_INTERPOLATE_LINEAR);
- ctx->fs2d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D,
- TGSI_INTERPOLATE_LINEAR);
- ctx->fs3d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_3D,
- TGSI_INTERPOLATE_LINEAR);
- ctx->fsCube = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_CUBE,
- TGSI_INTERPOLATE_LINEAR);
- if (pipe->screen->get_param(pipe->screen, PIPE_CAP_ARRAY_TEXTURES)) {
- ctx->fs1da = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_1D_ARRAY,
- TGSI_INTERPOLATE_LINEAR);
- ctx->fs2da = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D_ARRAY,
- TGSI_INTERPOLATE_LINEAR);
- }
-
-
/* vertex data that doesn't change */
for (i = 0; i < 4; i++) {
ctx->vertices[i][0][2] = 0.0f; /* z */
@@ -1343,6 +1315,44 @@ util_create_gen_mipmap(struct pipe_context *pipe,
/**
+ * Helper function to set the fragment shaders.
+ */
+static INLINE void
+set_fragment_shader(struct gen_mipmap_state *ctx, uint type)
+{
+ if (!ctx->fs[type])
+ ctx->fs[type] =
+ util_make_fragment_tex_shader(ctx->pipe, type,
+ TGSI_INTERPOLATE_LINEAR);
+
+ cso_set_fragment_shader_handle(ctx->cso, ctx->fs[type]);
+}
+
+
+/**
+ * Helper function to set the vertex shader.
+ */
+static INLINE void
+set_vertex_shader(struct gen_mipmap_state *ctx)
+{
+ /* vertex shader - still required to provide the linkage between
+ * fragment shader input semantics and vertex_element/buffers.
+ */
+ if (!ctx->vs)
+ {
+ const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
+ TGSI_SEMANTIC_GENERIC };
+ const uint semantic_indexes[] = { 0, 0 };
+ ctx->vs = util_make_vertex_passthrough_shader(ctx->pipe, 2,
+ semantic_names,
+ semantic_indexes);
+ }
+
+ cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
+}
+
+
+/**
* Get next "slot" of vertex space in the vertex buffer.
* We're allocating one large vertex buffer and using it piece by piece.
*/
@@ -1450,16 +1460,14 @@ void
util_destroy_gen_mipmap(struct gen_mipmap_state *ctx)
{
struct pipe_context *pipe = ctx->pipe;
+ unsigned i;
+
+ for (i = 0; i < Elements(ctx->fs); i++)
+ if (ctx->fs[i])
+ pipe->delete_fs_state(pipe, ctx->fs[i]);
- if (ctx->fs2da)
- pipe->delete_fs_state(pipe, ctx->fs2da);
- if (ctx->fs1da)
- pipe->delete_fs_state(pipe, ctx->fs1da);
- pipe->delete_fs_state(pipe, ctx->fsCube);
- pipe->delete_fs_state(pipe, ctx->fs3d);
- pipe->delete_fs_state(pipe, ctx->fs2d);
- pipe->delete_fs_state(pipe, ctx->fs1d);
- pipe->delete_vs_state(pipe, ctx->vs);
+ if (ctx->vs)
+ pipe->delete_vs_state(pipe, ctx->vs);
pipe_resource_reference(&ctx->vbuf, NULL);
@@ -1498,9 +1506,9 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
struct pipe_screen *screen = pipe->screen;
struct pipe_framebuffer_state fb;
struct pipe_resource *pt = psv->texture;
- void *fs;
uint dstLevel;
uint offset;
+ uint type;
/* The texture object should have room for the levels which we're
* about to generate.
@@ -1515,31 +1523,31 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
switch (pt->target) {
case PIPE_TEXTURE_1D:
- fs = ctx->fs1d;
+ type = TGSI_TEXTURE_1D;
break;
case PIPE_TEXTURE_2D:
- fs = ctx->fs2d;
+ type = TGSI_TEXTURE_2D;
break;
case PIPE_TEXTURE_3D:
- fs = ctx->fs3d;
+ type = TGSI_TEXTURE_3D;
break;
case PIPE_TEXTURE_CUBE:
- fs = ctx->fsCube;
+ type = TGSI_TEXTURE_CUBE;
break;
case PIPE_TEXTURE_1D_ARRAY:
- fs = ctx->fs1da;
+ type = TGSI_TEXTURE_1D_ARRAY;
break;
case PIPE_TEXTURE_2D_ARRAY:
- fs = ctx->fs2da;
+ type = TGSI_TEXTURE_2D_ARRAY;
break;
default:
assert(0);
- fs = ctx->fs2d;
+ type = TGSI_TEXTURE_2D;
}
/* check if we can render in the texture's format */
if (!screen->is_format_supported(screen, psv->format, pt->target,
- pt->nr_samples, PIPE_BIND_RENDER_TARGET, 0)) {
+ pt->nr_samples, PIPE_BIND_RENDER_TARGET)) {
fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel);
return;
}
@@ -1564,8 +1572,8 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
cso_set_clip(ctx->cso, &ctx->clip);
cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
- cso_set_fragment_shader_handle(ctx->cso, fs);
- cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
+ set_fragment_shader(ctx, type);
+ set_vertex_shader(ctx);
/* init framebuffer state */
memset(&fb, 0, sizeof(fb));
@@ -1660,8 +1668,6 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
4, /* verts */
2); /* attribs/vert */
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
-
/* need to signal that the texture has changed _after_ rendering to it */
pipe_surface_reference( &surf, NULL );
}
diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h
index 98889fb70ac..ddb81b5b957 100644
--- a/src/gallium/auxiliary/util/u_inlines.h
+++ b/src/gallium/auxiliary/util/u_inlines.h
@@ -299,13 +299,20 @@ pipe_buffer_write(struct pipe_context *pipe,
const void *data)
{
struct pipe_box box;
+ unsigned usage = PIPE_TRANSFER_WRITE;
+
+ if (offset == 0 && size == buf->width0) {
+ usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
+ } else {
+ usage |= PIPE_TRANSFER_DISCARD_RANGE;
+ }
u_box_1d(offset, size, &box);
pipe->transfer_inline_write( pipe,
buf,
0,
- PIPE_TRANSFER_WRITE,
+ usage,
&box,
data,
size,
diff --git a/src/gallium/auxiliary/util/u_pstipple.c b/src/gallium/auxiliary/util/u_pstipple.c
new file mode 100644
index 00000000000..f79a6938d1d
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_pstipple.c
@@ -0,0 +1,434 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2010 VMware, Inc.
+ * 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.
+ *
+ **************************************************************************/
+
+/**
+ * Polygon stipple helper module. Drivers/GPUs which don't support polygon
+ * stipple natively can use this module to simulate it.
+ *
+ * Basically, modify fragment shader to sample the 32x32 stipple pattern
+ * texture and do a fragment kill for the 'off' bits.
+ *
+ * This was originally a 'draw' module stage, but since we don't need
+ * vertex window coords or anything, it can be a stand-alone utility module.
+ *
+ * Authors: Brian Paul
+ */
+
+
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_shader_tokens.h"
+#include "util/u_inlines.h"
+
+#include "util/u_format.h"
+#include "util/u_memory.h"
+#include "util/u_pstipple.h"
+#include "util/u_sampler.h"
+
+#include "tgsi/tgsi_transform.h"
+#include "tgsi/tgsi_dump.h"
+
+/** Approx number of new tokens for instructions in pstip_transform_inst() */
+#define NUM_NEW_TOKENS 50
+
+
+static void
+util_pstipple_update_stipple_texture(struct pipe_context *pipe,
+ struct pipe_resource *tex,
+ const uint32_t pattern[32])
+{
+ static const uint bit31 = 1 << 31;
+ struct pipe_transfer *transfer;
+ ubyte *data;
+ int i, j;
+
+ /* map texture memory */
+ transfer = pipe_get_transfer(pipe, tex, 0, 0,
+ PIPE_TRANSFER_WRITE, 0, 0, 32, 32);
+ data = pipe->transfer_map(pipe, transfer);
+
+ /*
+ * Load alpha texture.
+ * Note: 0 means keep the fragment, 255 means kill it.
+ * We'll negate the texel value and use KILP which kills if value
+ * is negative.
+ */
+ for (i = 0; i < 32; i++) {
+ for (j = 0; j < 32; j++) {
+ if (pattern[i] & (bit31 >> j)) {
+ /* fragment "on" */
+ data[i * transfer->stride + j] = 0;
+ }
+ else {
+ /* fragment "off" */
+ data[i * transfer->stride + j] = 255;
+ }
+ }
+ }
+
+ /* unmap */
+ pipe->transfer_unmap(pipe, transfer);
+ pipe->transfer_destroy(pipe, transfer);
+}
+
+
+/**
+ * Create a 32x32 alpha8 texture that encodes the given stipple pattern.
+ */
+struct pipe_resource *
+util_pstipple_create_stipple_texture(struct pipe_context *pipe,
+ const uint32_t pattern[32])
+{
+ struct pipe_screen *screen = pipe->screen;
+ struct pipe_resource templat, *tex;
+
+ memset(&templat, 0, sizeof(templat));
+ templat.target = PIPE_TEXTURE_2D;
+ templat.format = PIPE_FORMAT_A8_UNORM;
+ templat.last_level = 0;
+ templat.width0 = 32;
+ templat.height0 = 32;
+ templat.depth0 = 1;
+ templat.array_size = 1;
+ templat.bind = PIPE_BIND_SAMPLER_VIEW;
+
+ tex = screen->resource_create(screen, &templat);
+
+ if (tex)
+ util_pstipple_update_stipple_texture(pipe, tex, pattern);
+
+ return tex;
+}
+
+
+/**
+ * Create sampler view to sample the stipple texture.
+ */
+struct pipe_sampler_view *
+util_pstipple_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_resource *tex)
+{
+ struct pipe_sampler_view templat, *sv;
+
+ u_sampler_view_default_template(&templat, tex, tex->format);
+ sv = pipe->create_sampler_view(pipe, tex, &templat);
+
+ return sv;
+}
+
+
+/**
+ * Create the sampler CSO that'll be used for stippling.
+ */
+void *
+util_pstipple_create_sampler(struct pipe_context *pipe)
+{
+ struct pipe_sampler_state templat;
+ void *s;
+
+ memset(&templat, 0, sizeof(templat));
+ templat.wrap_s = PIPE_TEX_WRAP_REPEAT;
+ templat.wrap_t = PIPE_TEX_WRAP_REPEAT;
+ templat.wrap_r = PIPE_TEX_WRAP_REPEAT;
+ templat.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+ templat.min_img_filter = PIPE_TEX_FILTER_NEAREST;
+ templat.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
+ templat.normalized_coords = 1;
+ templat.min_lod = 0.0f;
+ templat.max_lod = 0.0f;
+
+ s = pipe->create_sampler_state(pipe, &templat);
+ return s;
+}
+
+
+
+/**
+ * Subclass of tgsi_transform_context, used for transforming the
+ * user's fragment shader to add the extra texture sample and fragment kill
+ * instructions.
+ */
+struct pstip_transform_context {
+ struct tgsi_transform_context base;
+ uint tempsUsed; /**< bitmask */
+ int wincoordInput;
+ int maxInput;
+ uint samplersUsed; /**< bitfield of samplers used */
+ int freeSampler; /** an available sampler for the pstipple */
+ int texTemp; /**< temp registers */
+ int numImmed;
+ boolean firstInstruction;
+};
+
+
+/**
+ * TGSI declaration transform callback.
+ * Look for a free sampler, a free input attrib, and two free temp regs.
+ */
+static void
+pstip_transform_decl(struct tgsi_transform_context *ctx,
+ struct tgsi_full_declaration *decl)
+{
+ struct pstip_transform_context *pctx =
+ (struct pstip_transform_context *) ctx;
+
+ if (decl->Declaration.File == TGSI_FILE_SAMPLER) {
+ uint i;
+ for (i = decl->Range.First;
+ i <= decl->Range.Last; i++) {
+ pctx->samplersUsed |= 1 << i;
+ }
+ }
+ else if (decl->Declaration.File == TGSI_FILE_INPUT) {
+ pctx->maxInput = MAX2(pctx->maxInput, (int) decl->Range.Last);
+ if (decl->Semantic.Name == TGSI_SEMANTIC_POSITION)
+ pctx->wincoordInput = (int) decl->Range.First;
+ }
+ else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
+ uint i;
+ for (i = decl->Range.First;
+ i <= decl->Range.Last; i++) {
+ pctx->tempsUsed |= (1 << i);
+ }
+ }
+
+ ctx->emit_declaration(ctx, decl);
+}
+
+
+static void
+pstip_transform_immed(struct tgsi_transform_context *ctx,
+ struct tgsi_full_immediate *immed)
+{
+ struct pstip_transform_context *pctx =
+ (struct pstip_transform_context *) ctx;
+ pctx->numImmed++;
+}
+
+
+/**
+ * Find the lowest zero bit in the given word, or -1 if bitfield is all ones.
+ */
+static int
+free_bit(uint bitfield)
+{
+ return ffs(~bitfield) - 1;
+}
+
+
+/**
+ * TGSI instruction transform callback.
+ * Replace writes to result.color w/ a temp reg.
+ * Upon END instruction, insert texture sampling code for antialiasing.
+ */
+static void
+pstip_transform_inst(struct tgsi_transform_context *ctx,
+ struct tgsi_full_instruction *inst)
+{
+ struct pstip_transform_context *pctx =
+ (struct pstip_transform_context *) ctx;
+
+ if (pctx->firstInstruction) {
+ /* emit our new declarations before the first instruction */
+
+ struct tgsi_full_declaration decl;
+ struct tgsi_full_instruction newInst;
+ uint i;
+ int wincoordInput;
+
+ /* find free sampler */
+ pctx->freeSampler = free_bit(pctx->samplersUsed);
+ if (pctx->freeSampler >= PIPE_MAX_SAMPLERS)
+ pctx->freeSampler = PIPE_MAX_SAMPLERS - 1;
+
+ if (pctx->wincoordInput < 0)
+ wincoordInput = pctx->maxInput + 1;
+ else
+ wincoordInput = pctx->wincoordInput;
+
+ /* find one free temp reg */
+ for (i = 0; i < 32; i++) {
+ if ((pctx->tempsUsed & (1 << i)) == 0) {
+ /* found a free temp */
+ if (pctx->texTemp < 0)
+ pctx->texTemp = i;
+ else
+ break;
+ }
+ }
+ assert(pctx->texTemp >= 0);
+
+ if (pctx->wincoordInput < 0) {
+ /* declare new position input reg */
+ decl = tgsi_default_full_declaration();
+ decl.Declaration.File = TGSI_FILE_INPUT;
+ decl.Declaration.Interpolate = TGSI_INTERPOLATE_LINEAR;
+ decl.Declaration.Semantic = 1;
+ decl.Semantic.Name = TGSI_SEMANTIC_POSITION;
+ decl.Semantic.Index = 0;
+ decl.Range.First =
+ decl.Range.Last = wincoordInput;
+ ctx->emit_declaration(ctx, &decl);
+ }
+
+ /* declare new sampler */
+ decl = tgsi_default_full_declaration();
+ decl.Declaration.File = TGSI_FILE_SAMPLER;
+ decl.Range.First =
+ decl.Range.Last = pctx->freeSampler;
+ ctx->emit_declaration(ctx, &decl);
+
+ /* declare new temp regs */
+ decl = tgsi_default_full_declaration();
+ decl.Declaration.File = TGSI_FILE_TEMPORARY;
+ decl.Range.First =
+ decl.Range.Last = pctx->texTemp;
+ ctx->emit_declaration(ctx, &decl);
+
+ /* emit immediate = {1/32, 1/32, 1, 1}
+ * The index/position of this immediate will be pctx->numImmed
+ */
+ {
+ static const float value[4] = { 1.0/32, 1.0/32, 1.0, 1.0 };
+ struct tgsi_full_immediate immed;
+ uint size = 4;
+ immed = tgsi_default_full_immediate();
+ immed.Immediate.NrTokens = 1 + size; /* one for the token itself */
+ immed.u[0].Float = value[0];
+ immed.u[1].Float = value[1];
+ immed.u[2].Float = value[2];
+ immed.u[3].Float = value[3];
+ ctx->emit_immediate(ctx, &immed);
+ }
+
+ pctx->firstInstruction = FALSE;
+
+
+ /*
+ * Insert new MUL/TEX/KILP instructions at start of program
+ * Take gl_FragCoord, divide by 32 (stipple size), sample the
+ * texture and kill fragment if needed.
+ *
+ * We'd like to use non-normalized texcoords to index into a RECT
+ * texture, but we can only use REPEAT wrap mode with normalized
+ * texcoords. Darn.
+ */
+
+ /* XXX invert wincoord if origin isn't lower-left... */
+
+ /* MUL texTemp, INPUT[wincoord], 1/32; */
+ newInst = tgsi_default_full_instruction();
+ newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
+ newInst.Instruction.NumDstRegs = 1;
+ newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
+ newInst.Dst[0].Register.Index = pctx->texTemp;
+ newInst.Instruction.NumSrcRegs = 2;
+ newInst.Src[0].Register.File = TGSI_FILE_INPUT;
+ newInst.Src[0].Register.Index = wincoordInput;
+ newInst.Src[1].Register.File = TGSI_FILE_IMMEDIATE;
+ newInst.Src[1].Register.Index = pctx->numImmed;
+ ctx->emit_instruction(ctx, &newInst);
+
+ /* TEX texTemp, texTemp, sampler; */
+ newInst = tgsi_default_full_instruction();
+ newInst.Instruction.Opcode = TGSI_OPCODE_TEX;
+ newInst.Instruction.NumDstRegs = 1;
+ newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
+ newInst.Dst[0].Register.Index = pctx->texTemp;
+ newInst.Instruction.NumSrcRegs = 2;
+ newInst.Instruction.Texture = TRUE;
+ newInst.Texture.Texture = TGSI_TEXTURE_2D;
+ newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+ newInst.Src[0].Register.Index = pctx->texTemp;
+ newInst.Src[1].Register.File = TGSI_FILE_SAMPLER;
+ newInst.Src[1].Register.Index = pctx->freeSampler;
+ ctx->emit_instruction(ctx, &newInst);
+
+ /* KIL -texTemp; # if -texTemp < 0, KILL fragment */
+ newInst = tgsi_default_full_instruction();
+ newInst.Instruction.Opcode = TGSI_OPCODE_KIL;
+ newInst.Instruction.NumDstRegs = 0;
+ newInst.Instruction.NumSrcRegs = 1;
+ newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+ newInst.Src[0].Register.Index = pctx->texTemp;
+ newInst.Src[0].Register.Negate = 1;
+ ctx->emit_instruction(ctx, &newInst);
+ }
+
+ /* emit this instruction */
+ ctx->emit_instruction(ctx, inst);
+}
+
+
+/**
+ * Given a fragment shader, return a new fragment shader which
+ * samples a stipple texture and executes KILL.
+ */
+struct pipe_shader_state *
+util_pstipple_create_fragment_shader(struct pipe_context *pipe,
+ struct pipe_shader_state *fs,
+ unsigned *samplerUnitOut)
+{
+ struct pipe_shader_state *new_fs;
+ struct pstip_transform_context transform;
+ const uint newLen = tgsi_num_tokens(fs->tokens) + NUM_NEW_TOKENS;
+
+ new_fs = MALLOC(sizeof(*new_fs));
+ if (!new_fs)
+ return NULL;
+
+ new_fs->tokens = tgsi_alloc_tokens(newLen);
+ if (!new_fs->tokens) {
+ FREE(new_fs);
+ return NULL;
+ }
+
+ memset(&transform, 0, sizeof(transform));
+ transform.wincoordInput = -1;
+ transform.maxInput = -1;
+ transform.texTemp = -1;
+ transform.firstInstruction = TRUE;
+ transform.base.transform_instruction = pstip_transform_inst;
+ transform.base.transform_declaration = pstip_transform_decl;
+ transform.base.transform_immediate = pstip_transform_immed;
+
+ tgsi_transform_shader(fs->tokens,
+ (struct tgsi_token *) new_fs->tokens,
+ newLen, &transform.base);
+
+#if 0 /* DEBUG */
+ tgsi_dump(fs->tokens, 0);
+ tgsi_dump(pstip_fs.tokens, 0);
+#endif
+
+ assert(transform.freeSampler < PIPE_MAX_SAMPLERS);
+ *samplerUnitOut = transform.freeSampler;
+
+ return new_fs;
+}
+
diff --git a/src/gallium/auxiliary/util/u_pstipple.h b/src/gallium/auxiliary/util/u_pstipple.h
new file mode 100644
index 00000000000..1c2f5f48af4
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_pstipple.h
@@ -0,0 +1,56 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2010 VMware, Inc.
+ * 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.
+ *
+ **************************************************************************/
+
+#ifndef U_PSTIPPLE_H
+#define U_PSTIPPLE_H
+
+#include "pipe/p_compiler.h"
+
+struct pipe_context;
+struct pipe_resource;
+struct pipe_shader_state;
+
+
+extern struct pipe_resource *
+util_pstipple_create_stipple_texture(struct pipe_context *pipe,
+ const uint32_t pattern[32]);
+
+extern struct pipe_sampler_view *
+util_pstipple_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_resource *tex);
+
+extern void *
+util_pstipple_create_sampler(struct pipe_context *pipe);
+
+extern struct pipe_shader_state *
+util_pstipple_create_fragment_shader(struct pipe_context *pipe,
+ struct pipe_shader_state *fs,
+ unsigned *samplerUnitOut);
+
+
+#endif
diff --git a/src/gallium/auxiliary/util/u_resource.c b/src/gallium/auxiliary/util/u_resource.c
index ea6896b430f..50a7cd4d55b 100644
--- a/src/gallium/auxiliary/util/u_resource.c
+++ b/src/gallium/auxiliary/util/u_resource.c
@@ -24,14 +24,6 @@ void u_resource_destroy_vtbl(struct pipe_screen *screen,
ur->vtbl->resource_destroy(screen, resource);
}
-unsigned u_is_resource_referenced_vtbl( struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned level, int layer)
-{
- struct u_resource *ur = u_resource(resource);
- return ur->vtbl->is_resource_referenced(pipe, resource, level, layer);
-}
-
struct pipe_transfer *u_get_transfer_vtbl(struct pipe_context *context,
struct pipe_resource *resource,
unsigned level,
diff --git a/src/gallium/auxiliary/util/u_simple_screen.h b/src/gallium/auxiliary/util/u_simple_screen.h
index 7139aaabc56..7caeb75cd27 100644
--- a/src/gallium/auxiliary/util/u_simple_screen.h
+++ b/src/gallium/auxiliary/util/u_simple_screen.h
@@ -159,7 +159,8 @@ struct pipe_winsys
*/
int (*fence_finish)( struct pipe_winsys *ws,
struct pipe_fence_handle *fence,
- unsigned flag );
+ unsigned flags,
+ uint64_t timeout );
};
diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c
index 4eddd3f519e..9caf76c802b 100644
--- a/src/gallium/auxiliary/util/u_surface.c
+++ b/src/gallium/auxiliary/util/u_surface.c
@@ -84,7 +84,7 @@ util_create_rgba_surface(struct pipe_context *pipe,
/* Choose surface format */
for (i = 0; rgbaFormats[i]; i++) {
if (screen->is_format_supported(screen, rgbaFormats[i],
- target, 0, bind, 0)) {
+ target, 0, bind)) {
format = rgbaFormats[i];
break;
}
diff --git a/src/gallium/auxiliary/util/u_transfer.c b/src/gallium/auxiliary/util/u_transfer.c
index b6c63d9642f..7e72a59ee00 100644
--- a/src/gallium/auxiliary/util/u_transfer.c
+++ b/src/gallium/auxiliary/util/u_transfer.c
@@ -73,13 +73,6 @@ void u_default_transfer_flush_region( struct pipe_context *pipe,
*/
}
-unsigned u_default_is_resource_referenced( struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned level, int layer)
-{
- return 0;
-}
-
struct pipe_transfer * u_default_get_transfer(struct pipe_context *context,
struct pipe_resource *resource,
unsigned level,
diff --git a/src/gallium/auxiliary/util/u_transfer.h b/src/gallium/auxiliary/util/u_transfer.h
index 8cf9c418b04..5b5ddeb4aba 100644
--- a/src/gallium/auxiliary/util/u_transfer.h
+++ b/src/gallium/auxiliary/util/u_transfer.h
@@ -27,10 +27,6 @@ void u_default_transfer_flush_region( struct pipe_context *pipe,
struct pipe_transfer *transfer,
const struct pipe_box *box);
-unsigned u_default_is_resource_referenced( struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned level, int layer);
-
struct pipe_transfer * u_default_get_transfer(struct pipe_context *context,
struct pipe_resource *resource,
unsigned level,
@@ -57,10 +53,6 @@ struct u_resource_vtbl {
void (*resource_destroy)(struct pipe_screen *,
struct pipe_resource *pt);
- unsigned (*is_resource_referenced)(struct pipe_context *pipe,
- struct pipe_resource *texture,
- unsigned level, int layer);
-
struct pipe_transfer *(*get_transfer)(struct pipe_context *,
struct pipe_resource *resource,
unsigned level,
@@ -104,10 +96,6 @@ boolean u_resource_get_handle_vtbl(struct pipe_screen *screen,
void u_resource_destroy_vtbl(struct pipe_screen *screen,
struct pipe_resource *resource);
-unsigned u_is_resource_referenced_vtbl( struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned level, int layer);
-
struct pipe_transfer *u_get_transfer_vtbl(struct pipe_context *context,
struct pipe_resource *resource,
unsigned level,
diff --git a/src/gallium/auxiliary/util/u_upload_mgr.c b/src/gallium/auxiliary/util/u_upload_mgr.c
index dcf800a1e8e..9562acb8210 100644
--- a/src/gallium/auxiliary/util/u_upload_mgr.c
+++ b/src/gallium/auxiliary/util/u_upload_mgr.c
@@ -85,9 +85,9 @@ void u_upload_flush( struct u_upload_mgr *upload )
{
/* Unmap and unreference the upload buffer. */
if (upload->transfer) {
- if (upload->size) {
+ if (upload->offset) {
pipe_buffer_flush_mapped_range(upload->pipe, upload->transfer,
- 0, upload->size);
+ 0, upload->offset);
}
pipe_transfer_unmap(upload->pipe, upload->transfer);
pipe_transfer_destroy(upload->pipe, upload->transfer);
diff --git a/src/gallium/auxiliary/util/u_vbuf_mgr.c b/src/gallium/auxiliary/util/u_vbuf_mgr.c
index 7d157c99ccc..521ac07747c 100644
--- a/src/gallium/auxiliary/util/u_vbuf_mgr.c
+++ b/src/gallium/auxiliary/util/u_vbuf_mgr.c
@@ -87,27 +87,27 @@ static void u_vbuf_mgr_init_format_caps(struct u_vbuf_mgr_priv *mgr)
mgr->caps.format_fixed32 =
screen->is_format_supported(screen, PIPE_FORMAT_R32_FIXED, PIPE_BUFFER,
- 0, PIPE_BIND_VERTEX_BUFFER, 0);
+ 0, PIPE_BIND_VERTEX_BUFFER);
mgr->caps.format_float16 =
screen->is_format_supported(screen, PIPE_FORMAT_R16_FLOAT, PIPE_BUFFER,
- 0, PIPE_BIND_VERTEX_BUFFER, 0);
+ 0, PIPE_BIND_VERTEX_BUFFER);
mgr->caps.format_float64 =
screen->is_format_supported(screen, PIPE_FORMAT_R64_FLOAT, PIPE_BUFFER,
- 0, PIPE_BIND_VERTEX_BUFFER, 0);
+ 0, PIPE_BIND_VERTEX_BUFFER);
mgr->caps.format_norm32 =
screen->is_format_supported(screen, PIPE_FORMAT_R32_UNORM, PIPE_BUFFER,
- 0, PIPE_BIND_VERTEX_BUFFER, 0) &&
+ 0, PIPE_BIND_VERTEX_BUFFER) &&
screen->is_format_supported(screen, PIPE_FORMAT_R32_SNORM, PIPE_BUFFER,
- 0, PIPE_BIND_VERTEX_BUFFER, 0);
+ 0, PIPE_BIND_VERTEX_BUFFER);
mgr->caps.format_scaled32 =
screen->is_format_supported(screen, PIPE_FORMAT_R32_USCALED, PIPE_BUFFER,
- 0, PIPE_BIND_VERTEX_BUFFER, 0) &&
+ 0, PIPE_BIND_VERTEX_BUFFER) &&
screen->is_format_supported(screen, PIPE_FORMAT_R32_SSCALED, PIPE_BUFFER,
- 0, PIPE_BIND_VERTEX_BUFFER, 0);
+ 0, PIPE_BIND_VERTEX_BUFFER);
}
struct u_vbuf_mgr *
@@ -170,6 +170,7 @@ static void u_vbuf_translate_begin(struct u_vbuf_mgr_priv *mgr,
/* Initialize the translate key, i.e. the recipe how vertices should be
* translated. */
+ memset(&key, 0, sizeof key);
for (i = 0; i < mgr->ve->count; i++) {
struct pipe_vertex_buffer *vb =
&mgr->b.vertex_buffer[mgr->ve->ve[i].vertex_buffer_index];