summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary
diff options
context:
space:
mode:
authorBen Skeggs <[email protected]>2008-03-16 12:49:46 +1100
committerBen Skeggs <[email protected]>2008-03-16 12:49:46 +1100
commitc4354f84603cabb0e33ea3f586cc89bfdc27f79b (patch)
tree01585e52a3cca102c212630d8bac345058e150f6 /src/gallium/auxiliary
parent5e17088ee3d0ddfa8871d92d262bb5242bdd92bd (diff)
parentcb98f71d42e4c714dfb0c3e29d28d8418a1ee86b (diff)
Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.c2
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_hash.c25
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_hash.h59
-rw-r--r--src/gallium/auxiliary/draw/Makefile1
-rw-r--r--src/gallium/auxiliary/draw/SConscript2
-rw-r--r--src/gallium/auxiliary/draw/draw_aaline.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_aapoint.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c26
-rw-r--r--src/gallium/auxiliary/draw/draw_context.h5
-rw-r--r--src/gallium/auxiliary/draw/draw_passthrough.c106
-rw-r--r--src/gallium/auxiliary/draw/draw_prim.c47
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h6
-rw-r--r--src/gallium/auxiliary/draw/draw_pstipple.c20
-rw-r--r--src/gallium/auxiliary/draw/draw_validate.c63
-rw-r--r--src/gallium/auxiliary/draw/draw_vbuf.c5
-rw-r--r--src/gallium/auxiliary/draw/draw_vertex.c3
-rw-r--r--src/gallium/auxiliary/draw/draw_vertex.h1
-rw-r--r--src/gallium/auxiliary/draw/draw_vf.c8
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_exec.c13
-rw-r--r--src/gallium/auxiliary/draw/draw_wide_point.c3
-rw-r--r--src/gallium/auxiliary/gallivm/instructionssoa.cpp96
-rw-r--r--src/gallium/auxiliary/gallivm/instructionssoa.h6
-rw-r--r--src/gallium/auxiliary/gallivm/soabuiltins.c18
-rw-r--r--src/gallium/auxiliary/gallivm/tgsitollvm.cpp69
-rw-r--r--src/gallium/auxiliary/tgsi/exec/tgsi_exec.c34
-rwxr-xr-xsrc/gallium/auxiliary/tgsi/exec/tgsi_sse2.c18
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_dump.c68
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_dump.h4
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_parse.h2
-rw-r--r--src/gallium/auxiliary/util/Makefile1
-rw-r--r--src/gallium/auxiliary/util/SConscript1
-rw-r--r--src/gallium/auxiliary/util/p_debug.c30
-rw-r--r--src/gallium/auxiliary/util/u_handle_table.c89
-rw-r--r--src/gallium/auxiliary/util/u_handle_table.h11
-rw-r--r--src/gallium/auxiliary/util/u_hash_table.c199
-rw-r--r--src/gallium/auxiliary/util/u_hash_table.h86
36 files changed, 924 insertions, 215 deletions
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index f7f4aebb161..fd86bfaca9c 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -102,8 +102,6 @@ static void cso_release_all( struct cso_context *ctx )
void cso_destroy_context( struct cso_context *ctx )
{
- debug_printf("%s\n", __FUNCTION__);
-
if (ctx)
cso_release_all( ctx );
diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.c b/src/gallium/auxiliary/cso_cache/cso_hash.c
index 5cad5d3be71..ddce3822f7f 100644
--- a/src/gallium/auxiliary/cso_cache/cso_hash.c
+++ b/src/gallium/auxiliary/cso_cache/cso_hash.c
@@ -99,7 +99,7 @@ static void *cso_data_allocate_node(struct cso_hash_data *hash)
return MALLOC(hash->nodeSize);
}
-static void cso_data_free_node(struct cso_node *node)
+static void cso_free_node(struct cso_node *node)
{
FREE(node);
}
@@ -248,7 +248,7 @@ void cso_hash_delete(struct cso_hash *hash)
struct cso_node *cur = *bucket++;
while (cur != e_for_x) {
struct cso_node *next = cur->next;
- cso_data_free_node(cur);
+ cso_free_node(cur);
cur = next;
}
}
@@ -367,7 +367,7 @@ void * cso_hash_take(struct cso_hash *hash,
if (*node != hash->data.e) {
void *t = (*node)->value;
struct cso_node *next = (*node)->next;
- cso_data_free_node(*node);
+ cso_free_node(*node);
*node = next;
--hash->data.d->size;
cso_data_has_shrunk(hash->data.d);
@@ -393,3 +393,22 @@ int cso_hash_size(struct cso_hash *hash)
{
return hash->data.d->size;
}
+
+struct cso_hash_iter cso_hash_erase(struct cso_hash *hash, struct cso_hash_iter iter)
+{
+ struct cso_hash_iter ret = iter;
+ struct cso_node *node = iter.node;
+ struct cso_node **node_ptr;
+
+ if (node == hash->data.e)
+ return iter;
+
+ ret = cso_hash_iter_next(ret);
+ node_ptr = (struct cso_node**)(&hash->data.d->buckets[node->key % hash->data.d->numBuckets]);
+ while (*node_ptr != node)
+ node_ptr = &(*node_ptr)->next;
+ *node_ptr = node->next;
+ cso_free_node(node);
+ --hash->data.d->size;
+ return ret;
+}
diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.h b/src/gallium/auxiliary/cso_cache/cso_hash.h
index 84b45a5963e..73c47420068 100644
--- a/src/gallium/auxiliary/cso_cache/cso_hash.h
+++ b/src/gallium/auxiliary/cso_cache/cso_hash.h
@@ -26,19 +26,20 @@
**************************************************************************/
/**
- This file provides a hash implementation that is capable of dealing
- with collisions. It stores colliding entries in linked list. All
- functions operating on the hash return an iterator. The iterator
- itself points to the collision list. If there wasn't any collision
- the list will have just one entry, otherwise client code should
- iterate over the entries to find the exact entry among ones that
- had the same key (e.g. memcmp could be used on the data to check
- that)
-*/
- /*
- * Authors:
- * Zack Rusin <[email protected]>
- */
+ * @file
+ * Hash table implementation.
+ *
+ * This file provides a hash implementation that is capable of dealing
+ * with collisions. It stores colliding entries in linked list. All
+ * functions operating on the hash return an iterator. The iterator
+ * itself points to the collision list. If there wasn't any collision
+ * the list will have just one entry, otherwise client code should
+ * iterate over the entries to find the exact entry among ones that
+ * had the same key (e.g. memcmp could be used on the data to check
+ * that)
+ *
+ * @author Zack Rusin <[email protected]>
+ */
#ifndef CSO_HASH_H
#define CSO_HASH_H
@@ -48,24 +49,50 @@
extern "C" {
#endif
+
struct cso_hash;
struct cso_node;
+
struct cso_hash_iter {
struct cso_hash *hash;
struct cso_node *node;
};
+
struct cso_hash *cso_hash_create(void);
void cso_hash_delete(struct cso_hash *hash);
+
int cso_hash_size(struct cso_hash *hash);
+
+/**
+ * Adds a data with the given key to the hash. If entry with the given
+ * key is already in the hash, this current entry is instered before it
+ * in the collision list.
+ * Function returns iterator pointing to the inserted item in the hash.
+ */
struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, unsigned key,
void *data);
+/**
+ * Removes the item pointed to by the current iterator from the hash.
+ * Note that the data itself is not erased and if it was a malloc'ed pointer
+ * it will have to be freed after calling this function by the callee.
+ * Function returns iterator pointing to the item after the removed one in
+ * the hash.
+ */
+struct cso_hash_iter cso_hash_erase(struct cso_hash *hash, struct cso_hash_iter iter);
+
void *cso_hash_take(struct cso_hash *hash, unsigned key);
+
+
struct cso_hash_iter cso_hash_first_node(struct cso_hash *hash);
+
+/**
+ * Return an iterator pointing to the first entry in the collision list.
+ */
struct cso_hash_iter cso_hash_find(struct cso_hash *hash, unsigned key);
@@ -73,11 +100,15 @@ int cso_hash_iter_is_null(struct cso_hash_iter iter);
unsigned cso_hash_iter_key(struct cso_hash_iter iter);
void *cso_hash_iter_data(struct cso_hash_iter iter);
+
struct cso_hash_iter cso_hash_iter_next(struct cso_hash_iter iter);
struct cso_hash_iter cso_hash_iter_prev(struct cso_hash_iter iter);
-/* KW: a convenience routine:
+/**
+ * Convenience routine to iterate over the collision list while doing a memory
+ * comparison to see which entry in the list is a direct copy of our template
+ * and returns that entry.
*/
void *cso_hash_find_data_from_template( struct cso_hash *hash,
unsigned hash_key,
diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile
index 2daa1636f36..21e9f737b77 100644
--- a/src/gallium/auxiliary/draw/Makefile
+++ b/src/gallium/auxiliary/draw/Makefile
@@ -15,6 +15,7 @@ C_SOURCES = \
draw_debug.c \
draw_flatshade.c \
draw_offset.c \
+ draw_passthrough.c \
draw_prim.c \
draw_pstipple.c \
draw_stipple.c \
diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript
index 5cb7664c85d..d7fb86d992c 100644
--- a/src/gallium/auxiliary/draw/SConscript
+++ b/src/gallium/auxiliary/draw/SConscript
@@ -14,9 +14,9 @@ draw = env.ConvenienceLibrary(
'draw_debug.c',
'draw_flatshade.c',
'draw_offset.c',
+ 'draw_passthrough.c',
'draw_prim.c',
'draw_pstipple.c',
- 'draw_passthrough.c',
'draw_stipple.c',
'draw_twoside.c',
'draw_unfilled.c',
diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c
index 6b1e640ae90..f2b983374e6 100644
--- a/src/gallium/auxiliary/draw/draw_aaline.c
+++ b/src/gallium/auxiliary/draw/draw_aaline.c
@@ -340,12 +340,6 @@ generate_aaline_fs(struct aaline_stage *aaline)
tgsi_dump(aaline_fs.tokens, 0);
#endif
-#if 1 /* XXX remove */
- aaline_fs.input_semantic_name[aaline_fs.num_inputs] = TGSI_SEMANTIC_GENERIC;
- aaline_fs.input_semantic_index[aaline_fs.num_inputs] = transform.maxGeneric + 1;
- aaline_fs.num_inputs++;
-#endif
-
aaline->fs->aaline_fs
= aaline->driver_create_fs_state(aaline->pipe, &aaline_fs);
diff --git a/src/gallium/auxiliary/draw/draw_aapoint.c b/src/gallium/auxiliary/draw/draw_aapoint.c
index 99e9e9fe342..67a7a8ebaba 100644
--- a/src/gallium/auxiliary/draw/draw_aapoint.c
+++ b/src/gallium/auxiliary/draw/draw_aapoint.c
@@ -514,12 +514,6 @@ generate_aapoint_fs(struct aapoint_stage *aapoint)
tgsi_dump(aapoint_fs.tokens, 0);
#endif
-#if 1 /* XXX remove */
- aapoint_fs.input_semantic_name[aapoint_fs.num_inputs] = TGSI_SEMANTIC_GENERIC;
- aapoint_fs.input_semantic_index[aapoint_fs.num_inputs] = transform.maxGeneric + 1;
- aapoint_fs.num_inputs++;
-#endif
-
aapoint->fs->aapoint_fs
= aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs);
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index fed2b6e759a..4cca965ac10 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -85,6 +85,8 @@ struct draw_context *draw_create( void )
/* these defaults are oriented toward the needs of softpipe */
draw->wide_point_threshold = 1000000.0; /* infinity */
draw->wide_line_threshold = 1.0;
+ draw->line_stipple = TRUE;
+ draw->point_sprite = TRUE;
draw->reduced_prim = ~0; /* != any of PIPE_PRIM_x */
@@ -255,6 +257,28 @@ draw_wide_line_threshold(struct draw_context *draw, float threshold)
/**
+ * Tells the draw module whether or not to implement line stipple.
+ */
+void
+draw_enable_line_stipple(struct draw_context *draw, boolean enable)
+{
+ draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
+ draw->line_stipple = enable;
+}
+
+
+/**
+ * Tells draw module whether to convert points to quads for sprite mode.
+ */
+void
+draw_enable_point_sprites(struct draw_context *draw, boolean enable)
+{
+ draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
+ draw->point_sprite = enable;
+}
+
+
+/**
* Ask the draw module for the location/slot of the given vertex attribute in
* a post-transformed vertex.
*
@@ -299,7 +323,7 @@ uint
draw_num_vs_outputs(struct draw_context *draw)
{
uint count = draw->vertex_shader->info.num_outputs;
- if (draw->extra_vp_outputs.slot >= 0)
+ if (draw->extra_vp_outputs.slot > 0)
count++;
return count;
}
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index df63e91a22d..dae687e5906 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -94,6 +94,11 @@ void draw_wide_point_threshold(struct draw_context *draw, float threshold);
void draw_wide_line_threshold(struct draw_context *draw, float threshold);
+void draw_enable_line_stipple(struct draw_context *draw, boolean enable);
+
+void draw_enable_point_sprites(struct draw_context *draw, boolean enable);
+
+
boolean draw_use_sse(struct draw_context *draw);
void
diff --git a/src/gallium/auxiliary/draw/draw_passthrough.c b/src/gallium/auxiliary/draw/draw_passthrough.c
index a51fa0ab23c..d16f056191c 100644
--- a/src/gallium/auxiliary/draw/draw_passthrough.c
+++ b/src/gallium/auxiliary/draw/draw_passthrough.c
@@ -66,6 +66,95 @@
#include "draw/draw_vertex.h"
+/**
+ * General-purpose fetch from user's vertex arrays, emit to driver's
+ * vertex buffer.
+ *
+ * XXX this is totally temporary.
+ */
+static void
+fetch_store_general( struct draw_context *draw,
+ float *out,
+ unsigned start,
+ unsigned count )
+{
+ const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render);
+ const unsigned nr_attrs = vinfo->num_attribs;
+ uint i, j;
+
+ const unsigned *pitch = draw->vertex_fetch.pitch;
+ const ubyte **src = draw->vertex_fetch.src_ptr;
+
+ for (i = start; i < count; i++) {
+ for (j = 0; j < nr_attrs; j++) {
+ const uint jj = vinfo->src_index[j];
+ const enum pipe_format srcFormat = draw->vertex_element[jj].src_format;
+ const ubyte *from = src[jj] + i * pitch[jj];
+ float attrib[4];
+
+ switch (srcFormat) {
+ case PIPE_FORMAT_R32G32B32A32_FLOAT:
+ {
+ float *f = (float *) from;
+ attrib[0] = f[0];
+ attrib[1] = f[1];
+ attrib[2] = f[2];
+ attrib[3] = f[3];
+ }
+ break;
+ case PIPE_FORMAT_R32G32B32_FLOAT:
+ {
+ float *f = (float *) from;
+ attrib[0] = f[0];
+ attrib[1] = f[1];
+ attrib[2] = f[2];
+ attrib[3] = 1.0;
+ }
+ break;
+ case PIPE_FORMAT_R32G32_FLOAT:
+ {
+ float *f = (float *) from;
+ attrib[0] = f[0];
+ attrib[1] = f[1];
+ attrib[2] = 0.0;
+ attrib[3] = 1.0;
+ }
+ break;
+ case PIPE_FORMAT_R32_FLOAT:
+ {
+ float *f = (float *) from;
+ attrib[0] = f[0];
+ attrib[1] = 0.0;
+ attrib[2] = 0.0;
+ attrib[3] = 1.0;
+ }
+ break;
+ default:
+ abort();
+ }
+
+ /* XXX this will probably only work for softpipe */
+ switch (vinfo->emit[j]) {
+ case EMIT_HEADER:
+ memset(out, 0, sizeof(struct vertex_header));
+ out += sizeof(struct vertex_header) / 4;
+ break;
+ case EMIT_4F:
+ out[0] = attrib[0];
+ out[1] = attrib[1];
+ out[2] = attrib[2];
+ out[3] = attrib[3];
+ out += 4;
+ break;
+ default:
+ abort();
+ }
+
+ }
+ }
+}
+
+
/* Example of a fetch/emit passthrough shader which could be
* generated when bypass_clipping is enabled on a passthrough vertex
@@ -116,7 +205,6 @@ static void fetch_xyz_rgb_st( struct draw_context *draw,
}
}
-
static boolean update_shader( struct draw_context *draw )
{
const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render);
@@ -143,11 +231,15 @@ static boolean update_shader( struct draw_context *draw )
/* Just trying to figure out how this would work:
*/
- if (nr_attrs == 3 &&
- 0 /* some other tests */)
+ if (draw->rasterizer->bypass_vs ||
+ (nr_attrs == 3 && 0 /* some other tests */))
{
+#if 0
draw->vertex_fetch.pt_fetch = fetch_xyz_rgb_st;
- assert(vinfo->size == 10);
+#else
+ draw->vertex_fetch.pt_fetch = fetch_store_general;
+#endif
+ /*assert(vinfo->size == 10);*/
return TRUE;
}
@@ -175,7 +267,6 @@ static boolean set_prim( struct draw_context *draw,
}
-
boolean
draw_passthrough_arrays(struct draw_context *draw,
unsigned prim,
@@ -184,10 +275,13 @@ draw_passthrough_arrays(struct draw_context *draw,
{
float *hw_verts;
+ if (draw_need_pipeline(draw))
+ return FALSE;
+
if (!set_prim(draw, prim))
return FALSE;
- if (!update_shader( draw ))
+ if (!update_shader(draw))
return FALSE;
hw_verts = draw->render->allocate_vertices( draw->render,
diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c
index 7d6cd43410c..888fa536ea3 100644
--- a/src/gallium/auxiliary/draw/draw_prim.c
+++ b/src/gallium/auxiliary/draw/draw_prim.c
@@ -31,6 +31,7 @@
*/
#include "pipe/p_debug.h"
+#include "pipe/p_util.h"
#include "draw_private.h"
#include "draw_context.h"
@@ -118,7 +119,42 @@ static void draw_prim_queue_flush( struct draw_context *draw )
draw_vertex_cache_unreference( draw );
}
+static INLINE void fetch_and_store(struct draw_context *draw)
+{
+ /* run vertex shader on vertex cache entries, four per invokation */
+#if 0
+ {
+ const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render);
+ memcpy(draw->vs.queue[0].vertex, draw->vs.queue[i + j].elt,
+ count * vinfo->size);
+ }
+#elif 0
+ unsigned i;
+ draw_update_vertex_fetch(draw);
+ for (i = 0; i < draw->vs.queue_nr; i += 4) {
+ struct vertex_header *dests[4];
+ unsigned elts[4];
+ struct tgsi_exec_machine *machine = &draw->machine;
+ int j, n = MIN2(4, draw->vs.queue_nr - i);
+
+ for (j = 0; j < n; j++) {
+ elts[j] = draw->vs.queue[i + j].elt;
+ dests[j] = draw->vs.queue[i + j].vertex;
+ }
+
+ for ( ; j < 4; j++) {
+ elts[j] = elts[0];
+ dests[j] = draw->vs.queue[i + j].vertex;
+ }
+ //fetch directly into dests
+ draw->vertex_fetch.fetch_func(draw, machine, dests, count);
+ }
+#endif
+
+ draw->vs.post_nr = draw->vs.queue_nr;
+ draw->vs.queue_nr = 0;
+}
void draw_do_flush( struct draw_context *draw, unsigned flags )
{
@@ -134,7 +170,10 @@ void draw_do_flush( struct draw_context *draw, unsigned flags )
if (flags >= DRAW_FLUSH_SHADER_QUEUE) {
if (draw->vs.queue_nr)
- (*draw->shader_queue_flush)(draw);
+ if (draw->rasterizer->bypass_vs)
+ fetch_and_store(draw);
+ else
+ (*draw->shader_queue_flush)(draw);
if (flags >= DRAW_FLUSH_PRIM_QUEUE) {
if (draw->pq.queue_nr)
@@ -485,7 +524,11 @@ draw_arrays(struct draw_context *draw, unsigned prim,
}
/* drawing done here: */
- draw_prim(draw, prim, start, count);
+ if (!draw->rasterizer->bypass_vs ||
+ !draw_passthrough_arrays(draw, prim, start, count)) {
+ /* we have to run the whole pipeline */
+ draw_prim(draw, prim, start, count);
+ }
}
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index 4147472d451..1c65c3d1b2a 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -238,6 +238,8 @@ struct draw_context
float wide_point_threshold; /**< convert pnts to tris if larger than this */
float wide_line_threshold; /**< convert lines to tris if wider than this */
+ boolean line_stipple; /**< do line stipple? */
+ boolean point_sprite; /**< convert points to quads for sprites? */
boolean use_sse;
/* If a prim stage introduces new vertex attributes, they'll be stored here
@@ -344,10 +346,10 @@ extern void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw );
extern void draw_vertex_shader_queue_flush( struct draw_context *draw );
-struct tgsi_exec_machine;
-
extern void draw_update_vertex_fetch( struct draw_context *draw );
+extern boolean draw_need_pipeline(const struct draw_context *draw);
+
/* Prototype/hack
*/
diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c
index 8b3e84a9a08..09d542002f0 100644
--- a/src/gallium/auxiliary/draw/draw_pstipple.c
+++ b/src/gallium/auxiliary/draw/draw_pstipple.c
@@ -324,21 +324,13 @@ generate_pstip_fs(struct pstip_stage *pstip)
(struct tgsi_token *) pstip_fs.tokens,
MAX, &transform.base);
-#if 1 /* DEBUG */
+#if 0 /* DEBUG */
tgsi_dump(orig_fs->tokens, 0);
tgsi_dump(pstip_fs.tokens, 0);
#endif
pstip->sampler_unit = transform.maxSampler + 1;
-#if 1 /* XXX remove */
- if (transform.wincoordInput < 0) {
- pstip_fs.input_semantic_name[pstip_fs.num_inputs] = TGSI_SEMANTIC_POSITION;
- pstip_fs.input_semantic_index[pstip_fs.num_inputs] = (ubyte)transform.maxInput;
- pstip_fs.num_inputs++;
- }
-#endif
-
pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs);
}
@@ -488,16 +480,16 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header)
struct pipe_context *pipe = pstip->pipe;
uint num_samplers;
- /* how many samplers? */
- /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
- num_samplers = MAX2(pstip->num_textures, pstip->num_samplers);
- num_samplers = MAX2(num_samplers, pstip->sampler_unit + 1);
-
assert(stage->draw->rasterizer->poly_stipple_enable);
/* bind our fragprog */
bind_pstip_fragment_shader(pstip);
+ /* how many samplers? */
+ /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
+ num_samplers = MAX2(pstip->num_textures, pstip->num_samplers);
+ num_samplers = MAX2(num_samplers, pstip->sampler_unit + 1);
+
/* plug in our sampler, texture */
pstip->state.samplers[pstip->sampler_unit] = pstip->sampler_cso;
pstip->state.textures[pstip->sampler_unit] = pstip->texture;
diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c
index b43295b5860..33e55595081 100644
--- a/src/gallium/auxiliary/draw/draw_validate.c
+++ b/src/gallium/auxiliary/draw/draw_validate.c
@@ -33,6 +33,63 @@
#include "draw_private.h"
+/**
+ * Check if we need any special pipeline stages, or whether prims/verts
+ * can go through untouched.
+ */
+boolean
+draw_need_pipeline(const struct draw_context *draw)
+{
+ /* clipping */
+ if (!draw->rasterizer->bypass_clipping)
+ return TRUE;
+
+ /* vertex shader */
+ if (!draw->rasterizer->bypass_vs)
+ return TRUE;
+
+ /* line stipple */
+ if (draw->rasterizer->line_stipple_enable && draw->line_stipple)
+ return TRUE;
+
+ /* wide lines */
+ if (draw->rasterizer->line_width > draw->wide_line_threshold)
+ return TRUE;
+
+ /* large points */
+ if (draw->rasterizer->point_size > draw->wide_point_threshold)
+ return TRUE;
+
+ /* AA lines */
+ if (draw->rasterizer->line_smooth && draw->pipeline.aaline)
+ return TRUE;
+
+ /* AA points */
+ if (draw->rasterizer->point_smooth && draw->pipeline.aapoint)
+ return TRUE;
+
+ /* polygon stipple */
+ if (draw->rasterizer->poly_stipple_enable && draw->pipeline.pstipple)
+ return TRUE;
+
+ /* polygon offset */
+ if (draw->rasterizer->offset_cw || draw->rasterizer->offset_ccw)
+ return TRUE;
+
+ /* point sprites */
+ if (draw->rasterizer->point_sprite && draw->point_sprite)
+ return TRUE;
+
+ /* two-side lighting */
+ if (draw->rasterizer->light_twoside)
+ return TRUE;
+
+ /* polygon cull */
+ if (draw->rasterizer->cull_mode)
+ return TRUE;
+
+ return FALSE;
+}
@@ -57,7 +114,9 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage )
&& !draw->rasterizer->line_smooth);
/* drawing large points? */
- if (draw->rasterizer->point_smooth && draw->pipeline.aapoint)
+ if (draw->rasterizer->point_sprite && draw->point_sprite)
+ wide_points = TRUE;
+ else if (draw->rasterizer->point_smooth && draw->pipeline.aapoint)
wide_points = FALSE;
else if (draw->rasterizer->point_size > draw->wide_point_threshold)
wide_points = TRUE;
@@ -92,7 +151,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage )
next = draw->pipeline.wide_point;
}
- if (draw->rasterizer->line_stipple_enable) {
+ if (draw->rasterizer->line_stipple_enable && draw->line_stipple) {
draw->pipeline.stipple->next = next;
next = draw->pipeline.stipple;
precalc_flat = 1; /* only needed for lines really */
diff --git a/src/gallium/auxiliary/draw/draw_vbuf.c b/src/gallium/auxiliary/draw/draw_vbuf.c
index 71ac73912b8..f83b441e939 100644
--- a/src/gallium/auxiliary/draw/draw_vbuf.c
+++ b/src/gallium/auxiliary/draw/draw_vbuf.c
@@ -225,6 +225,11 @@ emit_vertex( struct vbuf_stage *vbuf,
vbuf->vertex_ptr += vinfo->size;
count += vinfo->size;
break;
+ case EMIT_HEADER:
+ memcpy(vbuf->vertex_ptr, vertex, sizeof(*vertex));
+ *vbuf->vertex_ptr += sizeof(*vertex) / 4;
+ count += sizeof(*vertex) / 4;
+ break;
case EMIT_1F:
*vbuf->vertex_ptr++ = fui(vertex->data[j][0]);
count++;
diff --git a/src/gallium/auxiliary/draw/draw_vertex.c b/src/gallium/auxiliary/draw/draw_vertex.c
index daf1ef4b80f..970adc95e74 100644
--- a/src/gallium/auxiliary/draw/draw_vertex.c
+++ b/src/gallium/auxiliary/draw/draw_vertex.c
@@ -52,6 +52,9 @@ draw_compute_vertex_size(struct vertex_info *vinfo)
switch (vinfo->emit[i]) {
case EMIT_OMIT:
break;
+ case EMIT_HEADER:
+ vinfo->size += sizeof(struct vertex_header) / 4;
+ break;
case EMIT_4UB:
/* fall-through */
case EMIT_1F_PSIZE:
diff --git a/src/gallium/auxiliary/draw/draw_vertex.h b/src/gallium/auxiliary/draw/draw_vertex.h
index 267c74203bd..abd2017ed33 100644
--- a/src/gallium/auxiliary/draw/draw_vertex.h
+++ b/src/gallium/auxiliary/draw/draw_vertex.h
@@ -48,6 +48,7 @@
enum attrib_emit {
EMIT_OMIT, /**< don't emit the attribute */
EMIT_ALL, /**< emit whole post-xform vertex, w/ header */
+ EMIT_HEADER, /**< emit vertex_header struct (XXX temp?) */
EMIT_1F,
EMIT_1F_PSIZE, /**< insert constant point size */
EMIT_2F,
diff --git a/src/gallium/auxiliary/draw/draw_vf.c b/src/gallium/auxiliary/draw/draw_vf.c
index 901ff20a7e7..f4e29a62932 100644
--- a/src/gallium/auxiliary/draw/draw_vf.c
+++ b/src/gallium/auxiliary/draw/draw_vf.c
@@ -263,6 +263,14 @@ void draw_vf_set_vertex_info( struct draw_vertex_fetch *vf,
}
break;
}
+ case EMIT_HEADER:
+ /* XXX emit new DRAW_EMIT_HEADER attribute??? */
+ attrs[nr_attrs].attrib = 0;
+ attrs[nr_attrs].format = DRAW_EMIT_PAD;
+ attrs[nr_attrs].offset = offsetof(struct vertex_header, data);
+ count += offsetof(struct vertex_header, data)/4;
+ nr_attrs++;
+ break;
case EMIT_1F:
attrs[nr_attrs].attrib = j;
attrs[nr_attrs].format = DRAW_EMIT_1F;
diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c
index 55bec14116a..364693e0b49 100644
--- a/src/gallium/auxiliary/draw/draw_vs_exec.c
+++ b/src/gallium/auxiliary/draw/draw_vs_exec.c
@@ -166,6 +166,19 @@ vs_exec_run( struct draw_vertex_shader *shader,
vOut[j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j];
vOut[j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j];
}
+
+#if 0 /*DEBUG*/
+ printf("Post xform vert:\n");
+ for (slot = 0; slot < draw->num_vs_outputs; slot++) {
+ printf("%d: %f %f %f %f\n", slot,
+ vOut[j]->data[slot][0],
+ vOut[j]->data[slot][1],
+ vOut[j]->data[slot][2],
+ vOut[j]->data[slot][3]);
+ }
+#endif
+
+
} /* loop over vertices */
}
diff --git a/src/gallium/auxiliary/draw/draw_wide_point.c b/src/gallium/auxiliary/draw/draw_wide_point.c
index 65bd50f2b8e..c53f7e6cb37 100644
--- a/src/gallium/auxiliary/draw/draw_wide_point.c
+++ b/src/gallium/auxiliary/draw/draw_wide_point.c
@@ -184,7 +184,8 @@ static void widepoint_first_point( struct draw_stage *stage,
wide->half_point_size = 0.5f * draw->rasterizer->point_size;
/* XXX we won't know the real size if it's computed by the vertex shader! */
- if (draw->rasterizer->point_size > draw->wide_point_threshold) {
+ if ((draw->rasterizer->point_size > draw->wide_point_threshold) ||
+ (draw->rasterizer->point_sprite && draw->point_sprite)) {
stage->point = widepoint_point;
}
else {
diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp
index 89d513afd0d..6f83b56a727 100644
--- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp
+++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp
@@ -143,8 +143,16 @@ std::vector<llvm::Value*> InstructionsSoa::extractVector(llvm::Value *vector)
void InstructionsSoa::createFunctionMap()
{
- m_functionsMap[TGSI_OPCODE_DP3] = "dp3";
- m_functionsMap[TGSI_OPCODE_DP4] = "dp4";
+ m_functionsMap[TGSI_OPCODE_DP3] = "dp3";
+ m_functionsMap[TGSI_OPCODE_DP4] = "dp4";
+ m_functionsMap[TGSI_OPCODE_POWER] = "pow";
+}
+
+void InstructionsSoa::createDependencies()
+{
+ std::vector<std::string> powDeps(1);
+ powDeps[0] = "powf";
+ m_builtinDependencies["pow"] = powDeps;
}
llvm::Function * InstructionsSoa::function(int op)
@@ -154,15 +162,14 @@ llvm::Function * InstructionsSoa::function(int op)
std::string name = m_functionsMap[op];
+ std::vector<std::string> deps = m_builtinDependencies[name];
+ for (unsigned int i = 0; i < deps.size(); ++i) {
+ injectFunction(m_builtins->getFunction(deps[i]));
+ }
+
llvm::Function *originalFunc = m_builtins->getFunction(name);
- llvm::Function *func = CloneFunction(originalFunc);
- currentModule()->getFunctionList().push_back(func);
- std::cout << "Func parent is "<<func->getParent()
- <<", cur is "<<currentModule() <<std::endl;
- func->dump();
- //func->setParent(currentModule());
- m_functions[op] = func;
- return func;
+ injectFunction(originalFunc, op);
+ return m_functions[op];
}
llvm::Module * InstructionsSoa::currentModule() const
@@ -177,6 +184,7 @@ llvm::Module * InstructionsSoa::currentModule() const
void InstructionsSoa::createBuiltins()
{
m_builtins = createSoaBuiltins();
+ createDependencies();
}
std::vector<llvm::Value*> InstructionsSoa::dp3(const std::vector<llvm::Value*> in1,
@@ -304,3 +312,71 @@ std::vector<Value*> InstructionsSoa::callBuiltin(llvm::Function *func, const std
return allocaToResult(allocaPtr);
}
+
+std::vector<llvm::Value*> InstructionsSoa::pow(const std::vector<llvm::Value*> in1,
+ const std::vector<llvm::Value*> in2)
+{
+ llvm::Function *func = function(TGSI_OPCODE_POWER);
+ return callBuiltin(func, in1, in2);
+}
+
+void checkFunction(Function *func)
+{
+ for (Function::const_iterator BI = func->begin(), BE = func->end();
+ BI != BE; ++BI) {
+ const BasicBlock &BB = *BI;
+ for (BasicBlock::const_iterator II = BB.begin(), IE = BB.end();
+ II != IE; ++II) {
+ const Instruction &I = *II;
+ std::cout<< "Instr = "<<I;
+ for (unsigned op = 0, E = I.getNumOperands(); op != E; ++op) {
+ const Value *Op = I.getOperand(op);
+ std::cout<< "\top = "<<Op<<"("<<op<<")"<<std::endl;
+ //I->setOperand(op, V);
+ }
+ }
+ }
+}
+
+void InstructionsSoa::injectFunction(llvm::Function *originalFunc, int op)
+{
+ assert(originalFunc);
+ std::cout << "injecting function originalFunc " <<originalFunc->getName() <<std::endl;
+ if (op != TGSI_OPCODE_LAST) {
+ /* in this case it's possible the function has been already
+ * injected as part of the dependency chain, which gets
+ * injected below */
+ llvm::Function *func = currentModule()->getFunction(originalFunc->getName());
+ if (func) {
+ m_functions[op] = func;
+ return;
+ }
+ }
+ llvm::Function *func = 0;
+ if (originalFunc->isDeclaration()) {
+ std::cout << "function decleration" <<std::endl;
+ func = new Function(originalFunc->getFunctionType(), GlobalValue::ExternalLinkage,
+ originalFunc->getName(), currentModule());
+ func->setCallingConv(CallingConv::C);
+ const ParamAttrsList *pal = 0;
+ func->setParamAttrs(pal);
+ currentModule()->dump();
+ } else {
+ DenseMap<const Value*, Value *> val;
+ val[m_builtins->getFunction("powf")] = currentModule()->getFunction("powf");
+ std::cout <<" replacing "<<m_builtins->getFunction("powf")
+ <<", with " <<currentModule()->getFunction("powf")<<std::endl;
+ func = CloneFunction(originalFunc, val);
+ std::cout<<"1111-------------------------------"<<std::endl;
+ checkFunction(originalFunc);
+ std::cout<<"2222-------------------------------"<<std::endl;
+ checkFunction(func);
+ std::cout <<"XXXX = " <<val[m_builtins->getFunction("powf")]<<std::endl;
+ currentModule()->getFunctionList().push_back(func);
+ std::cout << "Func parent is "<<func->getParent()
+ <<", cur is "<<currentModule() <<std::endl;
+ }
+ if (op != TGSI_OPCODE_LAST) {
+ m_functions[op] = func;
+ }
+}
diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.h b/src/gallium/auxiliary/gallivm/instructionssoa.h
index 3ef51dcaff7..b9104ea286d 100644
--- a/src/gallium/auxiliary/gallivm/instructionssoa.h
+++ b/src/gallium/auxiliary/gallivm/instructionssoa.h
@@ -28,6 +28,7 @@
#ifndef INSTRUCTIONSSOA_H
#define INSTRUCTIONSSOA_H
+#include <pipe/p_shader_tokens.h>
#include <llvm/Support/LLVMBuilder.h>
#include <map>
@@ -59,6 +60,8 @@ public:
const std::vector<llvm::Value*> in3);
std::vector<llvm::Value*> mul(const std::vector<llvm::Value*> in1,
const std::vector<llvm::Value*> in2);
+ std::vector<llvm::Value*> pow(const std::vector<llvm::Value*> in1,
+ const std::vector<llvm::Value*> in2);
void end();
std::vector<llvm::Value*> extractVector(llvm::Value *vector);
@@ -68,6 +71,7 @@ private:
llvm::Value *z, llvm::Value *w);
void createFunctionMap();
void createBuiltins();
+ void createDependencies();
llvm::Function *function(int);
llvm::Module *currentModule() const;
llvm::Value *allocaTemp();
@@ -81,6 +85,7 @@ private:
const std::vector<llvm::Value*> in1,
const std::vector<llvm::Value*> in2,
const std::vector<llvm::Value*> in3);
+ void injectFunction(llvm::Function *originalFunc, int op = TGSI_OPCODE_LAST);
private:
llvm::LLVMFoldingBuilder m_builder;
StorageSoa *m_storage;
@@ -88,6 +93,7 @@ private:
std::map<int, std::string> m_functionsMap;
std::map<int, llvm::Function*> m_functions;
llvm::Module *m_builtins;
+ std::map<std::string, std::vector<std::string> > m_builtinDependencies;
private:
mutable int m_idx;
diff --git a/src/gallium/auxiliary/gallivm/soabuiltins.c b/src/gallium/auxiliary/gallivm/soabuiltins.c
index 24c14e1b698..4d658be5208 100644
--- a/src/gallium/auxiliary/gallivm/soabuiltins.c
+++ b/src/gallium/auxiliary/gallivm/soabuiltins.c
@@ -60,6 +60,24 @@ void dp4(float4 *res,
res[3] = dot;
}
+extern float powf(float num, float p);
+
+void pow(float4 *res,
+ float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w,
+ float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w)
+{
+ float4 p;
+ p.x = powf(tmp0x.x, tmp1x.x);
+ p.y = powf(tmp0x.y, tmp1x.y);
+ p.z = powf(tmp0x.z, tmp1x.z);
+ p.w = powf(tmp0x.w, tmp1x.w);
+
+ res[0] = p;
+ res[1] = p;
+ res[2] = p;
+ res[3] = p;
+}
+
#if 0
void yo(float4 *out, float4 *in)
{
diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
index 3f65865a5a5..ab9e7a06fba 100644
--- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
+++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
@@ -588,40 +588,6 @@ translate_instruction(llvm::Module *module,
break;
case TGSI_OPCODE_NOP:
break;
- case TGSI_OPCODE_TEXBEM:
- break;
- case TGSI_OPCODE_TEXBEML:
- break;
- case TGSI_OPCODE_TEXREG2AR:
- break;
- case TGSI_OPCODE_TEXM3X2PAD:
- break;
- case TGSI_OPCODE_TEXM3X2TEX:
- break;
- case TGSI_OPCODE_TEXM3X3PAD:
- break;
- case TGSI_OPCODE_TEXM3X3TEX:
- break;
- case TGSI_OPCODE_TEXM3X3SPEC:
- break;
- case TGSI_OPCODE_TEXM3X3VSPEC:
- break;
- case TGSI_OPCODE_TEXREG2GB:
- break;
- case TGSI_OPCODE_TEXREG2RGB:
- break;
- case TGSI_OPCODE_TEXDP3TEX:
- break;
- case TGSI_OPCODE_TEXDP3:
- break;
- case TGSI_OPCODE_TEXM3X3:
- break;
- case TGSI_OPCODE_TEXM3X2DEPTH:
- break;
- case TGSI_OPCODE_TEXDEPTH:
- break;
- case TGSI_OPCODE_BEM:
- break;
case TGSI_OPCODE_M4X3:
break;
case TGSI_OPCODE_M3X4:
@@ -806,6 +772,7 @@ translate_instructionir(llvm::Module *module,
}
break;
case TGSI_OPCODE_POWER: {
+ out = instr->pow(inputs[0], inputs[1]);
}
break;
case TGSI_OPCODE_CROSSPRODUCT: {
@@ -980,40 +947,6 @@ translate_instructionir(llvm::Module *module,
break;
case TGSI_OPCODE_NOP:
break;
- case TGSI_OPCODE_TEXBEM:
- break;
- case TGSI_OPCODE_TEXBEML:
- break;
- case TGSI_OPCODE_TEXREG2AR:
- break;
- case TGSI_OPCODE_TEXM3X2PAD:
- break;
- case TGSI_OPCODE_TEXM3X2TEX:
- break;
- case TGSI_OPCODE_TEXM3X3PAD:
- break;
- case TGSI_OPCODE_TEXM3X3TEX:
- break;
- case TGSI_OPCODE_TEXM3X3SPEC:
- break;
- case TGSI_OPCODE_TEXM3X3VSPEC:
- break;
- case TGSI_OPCODE_TEXREG2GB:
- break;
- case TGSI_OPCODE_TEXREG2RGB:
- break;
- case TGSI_OPCODE_TEXDP3TEX:
- break;
- case TGSI_OPCODE_TEXDP3:
- break;
- case TGSI_OPCODE_TEXM3X3:
- break;
- case TGSI_OPCODE_TEXM3X2DEPTH:
- break;
- case TGSI_OPCODE_TEXDEPTH:
- break;
- case TGSI_OPCODE_BEM:
- break;
case TGSI_OPCODE_M4X3:
break;
case TGSI_OPCODE_M3X4:
diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c
index f2ed9e0353e..78e7dec5690 100644
--- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c
@@ -1516,11 +1516,41 @@ exec_instruction(
break;
case TGSI_OPCODE_EXP:
- assert (0);
+ debug_printf("TGSI: EXP opcode not implemented\n");
+ /* from ARB_v_p:
+ tmp = ScalarLoad(op0);
+ result.x = 2^floor(tmp);
+ result.y = tmp - floor(tmp);
+ result.z = RoughApprox2ToX(tmp);
+ result.w = 1.0;
+ */
+#if 0
+ /* something like this: */
+ FETCH( &r[0], 0, CHAN_X );
+ micro_exp2( &r[0], &r[0] );
+ FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+ STORE( &r[0], 0, chan_index );
+ }
+#endif
break;
case TGSI_OPCODE_LOG:
- assert (0);
+ debug_printf("TGSI: LOG opcode not implemented\n");
+ /* from ARB_v_p:
+ tmp = fabs(ScalarLoad(op0));
+ result.x = floor(log2(tmp));
+ result.y = tmp / 2^(floor(log2(tmp)));
+ result.z = RoughApproxLog2(tmp);
+ result.w = 1.0;
+ */
+#if 0
+ /* something like this: */
+ FETCH( &r[0], 0, CHAN_X );
+ micro_lg2( &r[0], &r[0] );
+ FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+ STORE( &r[0], 0, chan_index );
+ }
+#endif
break;
case TGSI_OPCODE_MUL:
diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c
index 0da3b0bdb75..4e80597b3f3 100755
--- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c
+++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c
@@ -1821,7 +1821,11 @@ emit_instruction(
STORE( func, *inst, 5, 0, CHAN_Z );
}
IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) {
- FETCH( func, *inst, 0, TGSI_EXEC_TEMP_ONE_I, TGSI_EXEC_TEMP_ONE_C );
+ emit_tempf(
+ func,
+ 0,
+ TGSI_EXEC_TEMP_ONE_I,
+ TGSI_EXEC_TEMP_ONE_C );
STORE( func, *inst, 0, 0, CHAN_W );
}
break;
@@ -2021,11 +2025,19 @@ emit_instruction(
STORE( func, *inst, 0, 0, CHAN_Y );
}
IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) {
- FETCH( func, *inst, 0, TGSI_EXEC_TEMP_00000000_I, TGSI_EXEC_TEMP_00000000_C );
+ emit_tempf(
+ func,
+ 0,
+ TGSI_EXEC_TEMP_00000000_I,
+ TGSI_EXEC_TEMP_00000000_C );
STORE( func, *inst, 0, 0, CHAN_Z );
}
IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) {
- FETCH( func, *inst, 0, TGSI_EXEC_TEMP_ONE_I, TGSI_EXEC_TEMP_ONE_C );
+ emit_tempf(
+ func,
+ 0,
+ TGSI_EXEC_TEMP_ONE_I,
+ TGSI_EXEC_TEMP_ONE_C );
STORE( func, *inst, 0, 0, CHAN_W );
}
break;
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c
index ceb407b884b..7d292778ad5 100644
--- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c
@@ -324,7 +324,7 @@ static const char *TGSI_IMMS_SHORT[] =
"FLT32"
};
-static const char *TGSI_OPCODES[] =
+static const char *TGSI_OPCODES[TGSI_OPCODE_LAST] =
{
"OPCODE_ARL",
"OPCODE_MOV",
@@ -380,6 +380,7 @@ static const char *TGSI_OPCODES[] =
"OPCODE_STR",
"OPCODE_TEX",
"OPCODE_TXD",
+ "OPCODE_TXP",
"OPCODE_UP2H",
"OPCODE_UP2US",
"OPCODE_UP4B",
@@ -433,23 +434,6 @@ static const char *TGSI_OPCODES[] =
"OPCODE_NOISE3",
"OPCODE_NOISE4",
"OPCODE_NOP",
- "OPCODE_TEXBEM",
- "OPCODE_TEXBEML",
- "OPCODE_TEXREG2AR",
- "OPCODE_TEXM3X2PAD",
- "OPCODE_TEXM3X2TEX",
- "OPCODE_TEXM3X3PAD",
- "OPCODE_TEXM3X3TEX",
- "OPCODE_TEXM3X3SPEC",
- "OPCODE_TEXM3X3VSPEC",
- "OPCODE_TEXREG2GB",
- "OPCODE_TEXREG2RGB",
- "OPCODE_TEXDP3TEX",
- "OPCODE_TEXDP3",
- "OPCODE_TEXM3X3",
- "OPCODE_TEXM3X2DEPTH",
- "OPCODE_TEXDEPTH",
- "OPCODE_BEM",
"OPCODE_M4X3",
"OPCODE_M3X4",
"OPCODE_M3X3",
@@ -459,11 +443,10 @@ static const char *TGSI_OPCODES[] =
"OPCODE_IFC",
"OPCODE_BREAKC",
"OPCODE_KIL",
- "OPCODE_END",
- "OPCODE_TXP"
+ "OPCODE_END"
};
-static const char *TGSI_OPCODES_SHORT[] =
+static const char *TGSI_OPCODES_SHORT[TGSI_OPCODE_LAST] =
{
"ARL",
"MOV",
@@ -519,6 +502,7 @@ static const char *TGSI_OPCODES_SHORT[] =
"STR",
"TEX",
"TXD",
+ "TXP",
"UP2H",
"UP2US",
"UP4B",
@@ -572,23 +556,6 @@ static const char *TGSI_OPCODES_SHORT[] =
"NOISE3",
"NOISE4",
"NOP",
- "TEXBEM",
- "TEXBEML",
- "TEXREG2AR",
- "TEXM3X2PAD",
- "TEXM3X2TEX",
- "TEXM3X3PAD",
- "TEXM3X3TEX",
- "TEXM3X3SPEC",
- "TEXM3X3VSPEC",
- "TEXREG2GB",
- "TEXREG2RGB",
- "TEXDP3TEX",
- "TEXDP3",
- "TEXM3X3",
- "TEXM3X2DEPTH",
- "TEXDEPTH",
- "BEM",
"M4X3",
"M3X4",
"M3X3",
@@ -598,8 +565,7 @@ static const char *TGSI_OPCODES_SHORT[] =
"IFC",
"BREAKC",
"KIL",
- "END",
- "TXP"
+ "END"
};
static const char *TGSI_SATS[] =
@@ -1597,3 +1563,25 @@ tgsi_dump_str(
*str = dump.text;
}
+
+
+void tgsi_debug_dump( struct tgsi_token *tokens )
+{
+ char *str, *p;
+
+ tgsi_dump_str( &str, tokens, 0 );
+
+ p = str;
+ while (p != NULL)
+ {
+ char *end = strchr( p, '\n' );
+ if (end != NULL)
+ {
+ *end++ = '\0';
+ }
+ debug_printf( "%s\n", p );
+ p = end;
+ }
+
+ FREE( str );
+}
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h
index b983b382268..51d79a0362e 100644
--- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h
@@ -20,6 +20,10 @@ tgsi_dump_str(
const struct tgsi_token *tokens,
unsigned flags );
+/* Dump to debug_printf()
+ */
+void tgsi_debug_dump( struct tgsi_token *tokens );
+
#if defined __cplusplus
}
#endif
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h
index 5ccb5bfcf68..40083728d64 100644
--- a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h
@@ -56,7 +56,7 @@ struct tgsi_full_immediate
};
#define TGSI_FULL_MAX_DST_REGISTERS 2
-#define TGSI_FULL_MAX_SRC_REGISTERS 3
+#define TGSI_FULL_MAX_SRC_REGISTERS 4 /* TXD has 4 */
struct tgsi_full_instruction
{
diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile
index 2abbe9500ec..2016c6fb1f7 100644
--- a/src/gallium/auxiliary/util/Makefile
+++ b/src/gallium/auxiliary/util/Makefile
@@ -8,6 +8,7 @@ C_SOURCES = \
p_tile.c \
p_util.c \
u_handle_table.c \
+ u_hash_table.c \
u_mm.c \
u_snprintf.c
diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript
index 2030214aa7e..154a3eca8cc 100644
--- a/src/gallium/auxiliary/util/SConscript
+++ b/src/gallium/auxiliary/util/SConscript
@@ -7,6 +7,7 @@ util = env.ConvenienceLibrary(
'p_tile.c',
'p_util.c',
'u_handle_table.c',
+ 'u_hash_table.c',
'u_mm.c',
'u_snprintf.c',
])
diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c
index 09cabdae25d..bb84e8096d2 100644
--- a/src/gallium/auxiliary/util/p_debug.c
+++ b/src/gallium/auxiliary/util/p_debug.c
@@ -109,20 +109,30 @@ enum {
/* Check for aborts enabled. */
static unsigned abort_en()
{
- if (!mapped_config_file)
- {
- /* Open an 8 byte file for configuration data. */
- mapped_config_file = EngMapFile(L"\\??\\c:\\gaDebug.cfg", 8, &debug_config_file);
- }
- /* An value of "0" (ascii) in the configuration file will clear the first 8 bits in the test byte. */
- /* An value of "1" (ascii) in the configuration file will set the first bit in the test byte. */
- /* An value of "2" (ascii) in the configuration file will set the second bit in the test byte. */
- return ((((char *)mapped_config_file)[0]) - 0x30) & eAssertAbortEn;
+ if (!mapped_config_file)
+ {
+ /* Open an 8 byte file for configuration data. */
+ mapped_config_file = EngMapFile(L"\\??\\c:\\gaDebug.cfg", 8, &debug_config_file);
+ }
+
+ /* A value of "0" (ascii) in the configuration file will clear the
+ * first 8 bits in the test byte.
+ *
+ * A value of "1" (ascii) in the configuration file will set the
+ * first bit in the test byte.
+ *
+ * A value of "2" (ascii) in the configuration file will set the
+ * second bit in the test byte.
+ *
+ * Currently the only interesting values are 0 and 1, which clear
+ * and set abort-on-assert behaviour respectively.
+ */
+ return ((((char *)mapped_config_file)[0]) - 0x30) & eAssertAbortEn;
}
#else /* WIN32 */
static unsigned abort_en()
{
- return !GETENV("GALLIUM_ABORT_ON_ASSERT");
+ return !GETENV("GALLIUM_ABORT_ON_ASSERT");
}
#endif
diff --git a/src/gallium/auxiliary/util/u_handle_table.c b/src/gallium/auxiliary/util/u_handle_table.c
index 8a298f7c413..d25872972aa 100644
--- a/src/gallium/auxiliary/util/u_handle_table.c
+++ b/src/gallium/auxiliary/util/u_handle_table.c
@@ -26,6 +26,7 @@
**************************************************************************/
/**
+ * @file
* Generic handle table implementation.
*
* @author José Fonseca <[email protected]>
@@ -90,6 +91,39 @@ handle_table_set_destroy(struct handle_table *ht,
}
+/**
+ * Resize the table if necessary
+ */
+static INLINE int
+handle_table_resize(struct handle_table *ht,
+ unsigned minimum_size)
+{
+ unsigned new_size;
+ void **new_objects;
+
+ if(ht->size > minimum_size)
+ return ht->size;
+
+ new_size = ht->size;
+ while(!(new_size > minimum_size))
+ new_size *= 2;
+ assert(new_size);
+
+ new_objects = (void **)REALLOC((void *)ht->objects,
+ ht->size*sizeof(void *),
+ new_size*sizeof(void *));
+ if(!new_objects)
+ return 0;
+
+ memset(new_objects + ht->size, 0, (new_size - ht->size)*sizeof(void *));
+
+ ht->size = new_size;
+ ht->objects = new_objects;
+
+ return ht->size;
+}
+
+
unsigned
handle_table_add(struct handle_table *ht,
void *object)
@@ -109,34 +143,17 @@ handle_table_add(struct handle_table *ht,
++ht->filled;
}
- /* grow the table */
- if(ht->filled == ht->size) {
- unsigned new_size;
- void **new_objects;
-
- new_size = ht->size*2;
- assert(new_size);
-
- new_objects = (void **)REALLOC((void *)ht->objects,
- ht->size*sizeof(void *),
- new_size*sizeof(void *));
- if(!new_objects)
- return 0;
-
- memset(new_objects + ht->size, 0, (new_size - ht->size)*sizeof(void *));
-
- ht->size = new_size;
- ht->objects = new_objects;
- }
-
index = ht->filled;
-
handle = index + 1;
/* check integer overflow */
if(!handle)
return 0;
+ /* grow the table if necessary */
+ if(!handle_table_resize(ht, index))
+ return 0;
+
assert(!ht->objects[index]);
ht->objects[index] = object;
++ht->filled;
@@ -145,6 +162,36 @@ handle_table_add(struct handle_table *ht,
}
+unsigned
+handle_table_set(struct handle_table *ht,
+ unsigned handle,
+ void *object)
+{
+ unsigned index;
+
+ assert(ht);
+ assert(handle > 0);
+ assert(handle <= ht->size);
+ if(!handle || handle > ht->size)
+ return 0;
+
+ assert(object);
+ if(!object)
+ return 0;
+
+ index = handle - 1;
+
+ /* grow the table if necessary */
+ if(!handle_table_resize(ht, index))
+ return 0;
+
+ assert(!ht->objects[index]);
+ ht->objects[index] = object;
+
+ return handle;
+}
+
+
void *
handle_table_get(struct handle_table *ht,
unsigned handle)
diff --git a/src/gallium/auxiliary/util/u_handle_table.h b/src/gallium/auxiliary/util/u_handle_table.h
index 51fc273865f..a2f1f604ade 100644
--- a/src/gallium/auxiliary/util/u_handle_table.h
+++ b/src/gallium/auxiliary/util/u_handle_table.h
@@ -26,6 +26,7 @@
**************************************************************************/
/**
+ * @file
* Generic handle table.
*
* @author José Fonseca <[email protected]>
@@ -42,6 +43,8 @@ extern "C" {
/**
* Abstract data type to map integer handles to objects.
+ *
+ * Also referred as "pointer array".
*/
struct handle_table;
@@ -71,6 +74,14 @@ handle_table_add(struct handle_table *ht,
void *object);
/**
+ * Returns zero on failure (out of memory).
+ */
+unsigned
+handle_table_set(struct handle_table *ht,
+ unsigned handle,
+ void *object);
+
+/**
* Fetch an existing object.
*
* Returns NULL for an invalid handle.
diff --git a/src/gallium/auxiliary/util/u_hash_table.c b/src/gallium/auxiliary/util/u_hash_table.c
new file mode 100644
index 00000000000..ac2cb1b540d
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_hash_table.c
@@ -0,0 +1,199 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * General purpose hash table implementation.
+ *
+ * Just uses the cso_hash for now, but it might be better switch to a linear
+ * probing hash table implementation at some point -- as it is said they have
+ * better lookup and cache performance and it appears to be possible to write
+ * a lock-free implementation of such hash tables .
+ *
+ * @author José Fonseca <[email protected]>
+ */
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_debug.h"
+#include "pipe/p_util.h"
+
+#include "cso_cache/cso_hash.h"
+#include "u_hash_table.h"
+
+
+struct hash_table
+{
+ struct cso_hash *cso;
+
+ /** Hash function */
+ unsigned (*hash)(void *key);
+
+ /** Compare two keys */
+ int (*compare)(void *key1, void *key2);
+
+ /* TODO: key, value destructors? */
+};
+
+
+struct hash_table_item
+{
+ void *key;
+ void *value;
+};
+
+
+struct hash_table *
+hash_table_create(unsigned (*hash)(void *key),
+ int (*compare)(void *key1, void *key2))
+{
+ struct hash_table *ht;
+
+ ht = MALLOC_STRUCT(hash_table);
+ if(!ht)
+ return NULL;
+
+ ht->cso = cso_hash_create();
+ if(!ht->cso) {
+ FREE(ht);
+ return NULL;
+ }
+
+ ht->hash = hash;
+ ht->compare = compare;
+
+ return ht;
+}
+
+
+static struct hash_table_item *
+hash_table_find_item(struct hash_table *ht,
+ void *key,
+ unsigned key_hash)
+{
+ struct cso_hash_iter iter;
+ struct hash_table_item *item;
+
+ iter = cso_hash_find(ht->cso, key_hash);
+ while (!cso_hash_iter_is_null(iter)) {
+ item = (struct hash_table_item *)cso_hash_iter_data(iter);
+ if (!ht->compare(item->key, key))
+ return item;
+ iter = cso_hash_iter_next(iter);
+ }
+
+ return NULL;
+}
+
+
+enum pipe_error
+hash_table_set(struct hash_table *ht,
+ void *key,
+ void *value)
+{
+ unsigned key_hash;
+ struct hash_table_item *item;
+
+ assert(ht);
+
+ key_hash = ht->hash(key);
+
+ item = hash_table_find_item(ht, key, key_hash);
+ if(item) {
+ /* TODO: key/value destruction? */
+ item->value = value;
+ return PIPE_OK;
+ }
+
+ item = MALLOC_STRUCT(hash_table_item);
+ if(!item)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ item->key = key;
+ item->value = value;
+
+ cso_hash_insert(ht->cso, key_hash, item);
+ /* FIXME: there is no OOM propagation in cso_hash */
+ if(0) {
+ FREE(item);
+ return PIPE_ERROR_OUT_OF_MEMORY;
+ }
+
+ return PIPE_OK;
+}
+
+
+void *
+hash_table_get(struct hash_table *ht,
+ void *key)
+{
+ unsigned key_hash;
+ struct hash_table_item *item;
+
+ assert(ht);
+
+ key_hash = ht->hash(key);
+
+ item = hash_table_find_item(ht, key, key_hash);
+ if(!item)
+ return NULL;
+
+ return item->value;
+}
+
+
+void
+hash_table_remove(struct hash_table *ht,
+ void *key)
+{
+ unsigned key_hash;
+ struct hash_table_item *item;
+
+ assert(ht);
+
+ key_hash = ht->hash(key);
+
+ item = hash_table_find_item(ht, key, key_hash);
+ if(!item)
+ return;
+
+ /* FIXME: cso_hash_take takes the first element of the collision list
+ * indiscriminately, so we can not take the item down. */
+ item->value = NULL;
+}
+
+
+void
+hash_table_destroy(struct hash_table *ht)
+{
+ assert(ht);
+
+ cso_hash_delete(ht->cso);
+
+ FREE(ht);
+}
+
diff --git a/src/gallium/auxiliary/util/u_hash_table.h b/src/gallium/auxiliary/util/u_hash_table.h
new file mode 100644
index 00000000000..d941f2c6b16
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_hash_table.h
@@ -0,0 +1,86 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * General purpose hash table.
+ *
+ * @author José Fonseca <[email protected]>
+ */
+
+#ifndef U_HASH_TABLE_H_
+#define U_HASH_TABLE_H_
+
+
+#include "pipe/p_error.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * Generic purpose hash table.
+ */
+struct hash_table;
+
+
+/**
+ * Create an hash table.
+ *
+ * @param hash hash function
+ * @param compare should return 0 for two equal keys.
+ */
+struct hash_table *
+hash_table_create(unsigned (*hash)(void *key),
+ int (*compare)(void *key1, void *key2));
+
+
+enum pipe_error
+hash_table_set(struct hash_table *ht,
+ void *key,
+ void *value);
+
+void *
+hash_table_get(struct hash_table *ht,
+ void *key);
+
+
+void
+hash_table_remove(struct hash_table *ht,
+ void *key);
+
+
+void
+hash_table_destroy(struct hash_table *ht);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* U_HASH_TABLE_H_ */