diff options
author | Ben Skeggs <skeggsb@gmail.com> | 2008-03-16 12:49:46 +1100 |
---|---|---|
committer | Ben Skeggs <skeggsb@gmail.com> | 2008-03-16 12:49:46 +1100 |
commit | c4354f84603cabb0e33ea3f586cc89bfdc27f79b (patch) | |
tree | 01585e52a3cca102c212630d8bac345058e150f6 | |
parent | 5e17088ee3d0ddfa8871d92d262bb5242bdd92bd (diff) | |
parent | cb98f71d42e4c714dfb0c3e29d28d8418a1ee86b (diff) |
Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
67 files changed, 2194 insertions, 1317 deletions
diff --git a/progs/trivial/tri-mask-tri.c b/progs/trivial/tri-mask-tri.c index 96a1ea7168..38ecd20a73 100644 --- a/progs/trivial/tri-mask-tri.c +++ b/progs/trivial/tri-mask-tri.c @@ -70,8 +70,11 @@ static void Key(unsigned char key, int x, int y) static void Draw(void) { + glColorMask(1,1,1,1); + glClear(GL_COLOR_BUFFER_BIT); + /* right triangle: green */ glBegin(GL_TRIANGLES); glColor3f(0,1,0); glVertex3f( 0.9, -0.9, -30.0); @@ -81,6 +84,7 @@ static void Draw(void) glColorMask(1,0,1,0); + /* left triangle: white&mask: purple middle region: white */ glBegin(GL_TRIANGLES); glColor3f(1,1,1); glVertex3f(-0.9, -0.9, -30.0); diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index f7f4aebb16..fd86bfaca9 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 5cad5d3be7..ddce3822f7 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 84b45a5963..73c4742006 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 <zack@tungstengraphics.com> - */ + * @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 <zack@tungstengraphics.com> + */ #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 2daa1636f3..21e9f737b7 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 5cb7664c85..d7fb86d992 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 6b1e640ae9..f2b983374e 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 99e9e9fe34..67a7a8ebab 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 fed2b6e759..4cca965ac1 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 df63e91a22..dae687e590 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 a51fa0ab23..d16f056191 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 7d6cd43410..888fa536ea 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 4147472d45..1c65c3d1b2 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 8b3e84a9a0..09d542002f 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 b43295b586..33e5559508 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 71ac73912b..f83b441e93 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 daf1ef4b80..970adc95e7 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 267c74203b..abd2017ed3 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 901ff20a7e..f4e29a6293 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 55bec14116..364693e0b4 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 65bd50f2b8..c53f7e6cb3 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 89d513afd0..6f83b56a72 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 3ef51dcaff..b9104ea286 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 24c14e1b69..4d658be520 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 3f65865a5a..ab9e7a06fb 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 f2ed9e0353..78e7dec569 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 0da3b0bdb7..4e80597b3f 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 ceb407b884..7d292778ad 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 b983b38226..51d79a0362 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 5ccb5bfcf6..40083728d6 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 2abbe9500e..2016c6fb1f 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 2030214aa7..154a3eca8c 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 09cabdae25..bb84e8096d 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 8a298f7c41..d25872972a 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 <jrfonseca@tungstengraphics.com> @@ -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 51fc273865..a2f1f604ad 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 <jrfonseca@tungstengraphics.com> @@ -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 0000000000..ac2cb1b540 --- /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 <jrfonseca@tungstengraphics.com> + */ + + +#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 0000000000..d941f2c6b1 --- /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 <jrfonseca@tungstengraphics.com> + */ + +#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_ */ diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index c568922cbd..b221424323 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -37,13 +37,14 @@ #include "cell_winsys.h" #include "cell/common.h" #include "rtasm/rtasm_ppc_spe.h" - +#include "tgsi/util/tgsi_scan.h" struct cell_vbuf_render; struct cell_vertex_shader_state { struct pipe_shader_state shader; + struct tgsi_shader_info info; void *draw_data; }; @@ -51,6 +52,7 @@ struct cell_vertex_shader_state struct cell_fragment_shader_state { struct pipe_shader_state shader; + struct tgsi_shader_info info; void *data; }; diff --git a/src/gallium/drivers/cell/ppu/cell_state_derived.c b/src/gallium/drivers/cell/ppu/cell_state_derived.c index 0c46829258..5c240a55c0 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_derived.c +++ b/src/gallium/drivers/cell/ppu/cell_state_derived.c @@ -36,14 +36,14 @@ static int -find_vs_output(const struct pipe_shader_state *vs, +find_vs_output(const struct cell_vertex_shader_state *vs, uint semantic_name, uint semantic_index) { uint i; - for (i = 0; i < vs->num_outputs; i++) { - if (vs->output_semantic_name[i] == semantic_name && - vs->output_semantic_index[i] == semantic_index) + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == semantic_name && + vs->info.output_semantic_index[i] == semantic_index) return i; } return -1; @@ -58,8 +58,8 @@ find_vs_output(const struct pipe_shader_state *vs, static void calculate_vertex_layout( struct cell_context *cell ) { - const struct pipe_shader_state *vs = &cell->vs->shader; - const struct pipe_shader_state *fs = &cell->fs->shader; + const struct cell_vertex_shader_state *vs = cell->vs; + const struct cell_fragment_shader_state *fs = cell->fs; const enum interp_mode colorInterp = cell->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; struct vertex_info *vinfo = &cell->vertex_info; @@ -91,15 +91,15 @@ calculate_vertex_layout( struct cell_context *cell ) * Loop over fragment shader inputs, searching for the matching output * from the vertex shader. */ - for (i = 0; i < fs->num_inputs; i++) { - switch (fs->input_semantic_name[i]) { + for (i = 0; i < fs->info.num_inputs; i++) { + switch (fs->info.input_semantic_name[i]) { case TGSI_SEMANTIC_POSITION: /* already done above */ break; case TGSI_SEMANTIC_COLOR: src = find_vs_output(vs, TGSI_SEMANTIC_COLOR, - fs->input_semantic_index[i]); + fs->info.input_semantic_index[i]); assert(src >= 0); draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src); break; @@ -117,7 +117,7 @@ calculate_vertex_layout( struct cell_context *cell ) case TGSI_SEMANTIC_GENERIC: /* this includes texcoords and varying vars */ src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC, - fs->input_semantic_index[i]); + fs->info.input_semantic_index[i]); assert(src >= 0); draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); break; diff --git a/src/gallium/drivers/cell/ppu/cell_state_shader.c b/src/gallium/drivers/cell/ppu/cell_state_shader.c index 269a5c15ba..fb2e940348 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_state_shader.c @@ -54,27 +54,7 @@ cell_create_fs_state(struct pipe_context *pipe, state->shader = *templ; -#if 0 - if (cell->dump_fs) { - tgsi_dump(state->shader.tokens, 0); - } - -#if defined(__i386__) || defined(__386__) - if (cell->use_sse) { - x86_init_func( &state->sse2_program ); - tgsi_emit_sse2_fs( state->shader.tokens, &state->sse2_program ); - } -#endif - -#ifdef MESA_LLVM - state->llvm_prog = 0; - if (!gallivm_global_cpu_engine()) { - gallivm_cpu_engine_create(state->llvm_prog); - } - else - gallivm_cpu_jit_compile(gallivm_global_cpu_engine(), state->llvm_prog); -#endif -#endif + tgsi_scan_shader(templ->tokens, &state->info); return state; } @@ -113,6 +93,7 @@ cell_create_vs_state(struct pipe_context *pipe, return NULL; state->shader = *templ; + tgsi_scan_shader(templ->tokens, &state->info); state->draw_data = draw_create_vertex_shader(cell->draw, &state->shader); if (state->draw_data == NULL) { diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c index 1560c0f157..061fbebf61 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.c +++ b/src/gallium/drivers/cell/spu/spu_exec.c @@ -672,7 +672,7 @@ fetch_texel( struct spu_sampler *sampler, static void exec_tex(struct spu_exec_machine *mach, const struct tgsi_full_instruction *inst, - boolean biasLod) + boolean biasLod, boolean projected) { const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index; union spu_exec_channel r[8]; @@ -686,17 +686,9 @@ exec_tex(struct spu_exec_machine *mach, FETCH(&r[0], 0, CHAN_X); - switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { - case TGSI_EXTSWIZZLE_W: + if (projected) { FETCH(&r[1], 0, CHAN_W); r[0].q = micro_div(r[0].q, r[1].q); - break; - - case TGSI_EXTSWIZZLE_ONE: - break; - - default: - assert (0); } if (biasLod) { @@ -718,19 +710,11 @@ exec_tex(struct spu_exec_machine *mach, FETCH(&r[1], 0, CHAN_Y); FETCH(&r[2], 0, CHAN_Z); - switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { - case TGSI_EXTSWIZZLE_W: + if (projected) { FETCH(&r[3], 0, CHAN_W); r[0].q = micro_div(r[0].q, r[3].q); r[1].q = micro_div(r[1].q, r[3].q); r[2].q = micro_div(r[2].q, r[3].q); - break; - - case TGSI_EXTSWIZZLE_ONE: - break; - - default: - assert (0); } if (biasLod) { @@ -752,19 +736,11 @@ exec_tex(struct spu_exec_machine *mach, FETCH(&r[1], 0, CHAN_Y); FETCH(&r[2], 0, CHAN_Z); - switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { - case TGSI_EXTSWIZZLE_W: + if (projected) { FETCH(&r[3], 0, CHAN_W); r[0].q = micro_div(r[0].q, r[3].q); r[1].q = micro_div(r[1].q, r[3].q); r[2].q = micro_div(r[2].q, r[3].q); - break; - - case TGSI_EXTSWIZZLE_ONE: - break; - - default: - assert (0); } if (biasLod) { @@ -1450,14 +1426,14 @@ exec_instruction( /* simple texture lookup */ /* src[0] = texcoord */ /* src[1] = sampler unit */ - exec_tex(mach, inst, FALSE); + exec_tex(mach, inst, FALSE, FALSE); break; case TGSI_OPCODE_TXB: /* Texture lookup with lod bias */ /* src[0] = texcoord (src[0].w = load bias) */ /* src[1] = sampler unit */ - exec_tex(mach, inst, TRUE); + exec_tex(mach, inst, TRUE, FALSE); break; case TGSI_OPCODE_TXD: @@ -1473,7 +1449,14 @@ exec_instruction( /* Texture lookup with explit LOD */ /* src[0] = texcoord (src[0].w = load bias) */ /* src[1] = sampler unit */ - exec_tex(mach, inst, TRUE); + exec_tex(mach, inst, TRUE, FALSE); + break; + + case TGSI_OPCODE_TXP: + /* Texture lookup with projection + /* src[0] = texcoord (src[0].w = projection) */ + /* src[1] = sampler unit */ + exec_tex(mach, inst, TRUE, TRUE); break; case TGSI_OPCODE_UP2H: diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index 503c092400..1cec36e206 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -516,7 +516,7 @@ static void i915_set_constant_buffer(struct pipe_context *pipe, * stays the same. In that case we should only be updating the first * N constants, leaving any extras from shader translation alone. */ - { + if (buf) { void *mapped; if (buf->size && (mapped = ws->buffer_map(ws, buf->buffer, diff --git a/src/gallium/drivers/softpipe/sp_clear.c b/src/gallium/drivers/softpipe/sp_clear.c index 8d295a30ca..39aed151c7 100644 --- a/src/gallium/drivers/softpipe/sp_clear.c +++ b/src/gallium/drivers/softpipe/sp_clear.c @@ -55,6 +55,7 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, if (ps == sp_tile_cache_get_surface(softpipe->zsbuf_cache)) { sp_tile_cache_clear(softpipe->zsbuf_cache, clearValue); + softpipe->framebuffer.zsbuf->status = PIPE_SURFACE_STATUS_CLEAR; #if TILE_CLEAR_OPTIMIZATION return; #endif @@ -63,6 +64,7 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) { if (ps == sp_tile_cache_get_surface(softpipe->cbuf_cache[i])) { sp_tile_cache_clear(softpipe->cbuf_cache[i], clearValue); + softpipe->framebuffer.cbufs[i]->status = PIPE_SURFACE_STATUS_CLEAR; } } diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 316ae552b8..16fb06f176 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -1,243 +1,243 @@ -/**************************************************************************
- *
- * Copyright 2007 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.
- *
- **************************************************************************/
-
-/* Author:
- * Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#include "draw/draw_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_inlines.h"
-#include "pipe/p_util.h"
-#include "sp_clear.h"
-#include "sp_context.h"
-#include "sp_flush.h"
-#include "sp_prim_setup.h"
-#include "sp_prim_vbuf.h"
-#include "sp_state.h"
-#include "sp_surface.h"
-#include "sp_tile_cache.h"
-#include "sp_texture.h"
-#include "sp_winsys.h"
-#include "sp_query.h"
-
-
-
-/**
- * Map any drawing surfaces which aren't already mapped
- */
-void
-softpipe_map_surfaces(struct softpipe_context *sp)
-{
- unsigned i;
-
- for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
- sp_tile_cache_map_surfaces(sp->cbuf_cache[i]);
- }
-
- sp_tile_cache_map_surfaces(sp->zsbuf_cache);
-}
-
-
-/**
- * Unmap any mapped drawing surfaces
- */
-void
-softpipe_unmap_surfaces(struct softpipe_context *sp)
-{
- uint i;
-
- for (i = 0; i < sp->framebuffer.num_cbufs; i++)
- sp_flush_tile_cache(sp, sp->cbuf_cache[i]);
- sp_flush_tile_cache(sp, sp->zsbuf_cache);
-
- for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
- sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]);
- }
- sp_tile_cache_unmap_surfaces(sp->zsbuf_cache);
-}
-
-
-static void softpipe_destroy( struct pipe_context *pipe )
-{
- struct softpipe_context *softpipe = softpipe_context( pipe );
- struct pipe_winsys *ws = pipe->winsys;
- uint i;
-
- draw_destroy( softpipe->draw );
-
- softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple );
- softpipe->quad.earlyz->destroy( softpipe->quad.earlyz );
- softpipe->quad.shade->destroy( softpipe->quad.shade );
- softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test );
- softpipe->quad.depth_test->destroy( softpipe->quad.depth_test );
- softpipe->quad.stencil_test->destroy( softpipe->quad.stencil_test );
- softpipe->quad.occlusion->destroy( softpipe->quad.occlusion );
- softpipe->quad.coverage->destroy( softpipe->quad.coverage );
- softpipe->quad.bufloop->destroy( softpipe->quad.bufloop );
- softpipe->quad.blend->destroy( softpipe->quad.blend );
- softpipe->quad.colormask->destroy( softpipe->quad.colormask );
- softpipe->quad.output->destroy( softpipe->quad.output );
-
- for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
- sp_destroy_tile_cache(softpipe->cbuf_cache[i]);
- sp_destroy_tile_cache(softpipe->zsbuf_cache);
-
- for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
- sp_destroy_tile_cache(softpipe->tex_cache[i]);
-
- for (i = 0; i < Elements(softpipe->constants); i++) {
- if (softpipe->constants[i].buffer) {
- pipe_buffer_reference(ws, &softpipe->constants[i].buffer, NULL);
- }
- }
-
- FREE( softpipe );
-}
-
-
-struct pipe_context *
-softpipe_create( struct pipe_screen *screen,
- struct pipe_winsys *pipe_winsys,
- struct softpipe_winsys *softpipe_winsys )
-{
- struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context);
- uint i;
-
-#if defined(__i386__) || defined(__386__)
- softpipe->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL;
-#else
- softpipe->use_sse = FALSE;
-#endif
-
- softpipe->dump_fs = GETENV( "GALLIUM_DUMP_FS" ) != NULL;
-
- softpipe->pipe.winsys = pipe_winsys;
- softpipe->pipe.screen = screen;
- softpipe->pipe.destroy = softpipe_destroy;
-
- /* state setters */
- softpipe->pipe.create_blend_state = softpipe_create_blend_state;
- softpipe->pipe.bind_blend_state = softpipe_bind_blend_state;
- softpipe->pipe.delete_blend_state = softpipe_delete_blend_state;
-
- softpipe->pipe.create_sampler_state = softpipe_create_sampler_state;
- softpipe->pipe.bind_sampler_states = softpipe_bind_sampler_states;
- softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state;
-
- softpipe->pipe.create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state;
- softpipe->pipe.bind_depth_stencil_alpha_state = softpipe_bind_depth_stencil_state;
- softpipe->pipe.delete_depth_stencil_alpha_state = softpipe_delete_depth_stencil_state;
-
- softpipe->pipe.create_rasterizer_state = softpipe_create_rasterizer_state;
- softpipe->pipe.bind_rasterizer_state = softpipe_bind_rasterizer_state;
- softpipe->pipe.delete_rasterizer_state = softpipe_delete_rasterizer_state;
-
- softpipe->pipe.create_fs_state = softpipe_create_fs_state;
- softpipe->pipe.bind_fs_state = softpipe_bind_fs_state;
- softpipe->pipe.delete_fs_state = softpipe_delete_fs_state;
-
- softpipe->pipe.create_vs_state = softpipe_create_vs_state;
- softpipe->pipe.bind_vs_state = softpipe_bind_vs_state;
- softpipe->pipe.delete_vs_state = softpipe_delete_vs_state;
-
- softpipe->pipe.set_blend_color = softpipe_set_blend_color;
- softpipe->pipe.set_clip_state = softpipe_set_clip_state;
- softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer;
- softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
- softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple;
- softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;
- softpipe->pipe.set_sampler_textures = softpipe_set_sampler_textures;
- softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
-
- softpipe->pipe.set_vertex_buffer = softpipe_set_vertex_buffer;
- softpipe->pipe.set_vertex_element = softpipe_set_vertex_element;
-
- softpipe->pipe.draw_arrays = softpipe_draw_arrays;
- softpipe->pipe.draw_elements = softpipe_draw_elements;
-
- softpipe->pipe.clear = softpipe_clear;
- softpipe->pipe.flush = softpipe_flush;
-
- softpipe_init_query_funcs( softpipe );
- softpipe_init_texture_funcs( softpipe );
-
- /*
- * Alloc caches for accessing drawing surfaces and textures.
- * Must be before quad stage setup!
- */
- for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
- softpipe->cbuf_cache[i] = sp_create_tile_cache();
- softpipe->zsbuf_cache = sp_create_tile_cache();
-
- for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
- softpipe->tex_cache[i] = sp_create_tile_cache();
-
-
- /* setup quad rendering stages */
- softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe);
- softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe);
- softpipe->quad.shade = sp_quad_shade_stage(softpipe);
- softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe);
- softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe);
- softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe);
- softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe);
- softpipe->quad.coverage = sp_quad_coverage_stage(softpipe);
- softpipe->quad.bufloop = sp_quad_bufloop_stage(softpipe);
- softpipe->quad.blend = sp_quad_blend_stage(softpipe);
- softpipe->quad.colormask = sp_quad_colormask_stage(softpipe);
- softpipe->quad.output = sp_quad_output_stage(softpipe);
-
- softpipe->winsys = softpipe_winsys;
-
- /*
- * Create drawing context and plug our rendering stage into it.
- */
- softpipe->draw = draw_create();
- assert(softpipe->draw);
- softpipe->setup = sp_draw_render_stage(softpipe);
-
- if (GETENV( "SP_VBUF" ) != NULL) {
- sp_init_vbuf(softpipe);
- }
- else {
- draw_set_rasterize_stage(softpipe->draw, softpipe->setup);
- }
-
- /* plug in AA line/point stages */
- draw_install_aaline_stage(softpipe->draw, &softpipe->pipe);
- draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe);
-
-#if USE_DRAW_STAGE_PSTIPPLE
- /* Do polygon stipple w/ texture map + frag prog? */
- draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe);
-#endif
-
- sp_init_surface_functions(softpipe);
-
- return &softpipe->pipe;
-}
+/************************************************************************** + * + * Copyright 2007 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. + * + **************************************************************************/ + +/* Author: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "draw/draw_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "sp_clear.h" +#include "sp_context.h" +#include "sp_flush.h" +#include "sp_prim_setup.h" +#include "sp_prim_vbuf.h" +#include "sp_state.h" +#include "sp_surface.h" +#include "sp_tile_cache.h" +#include "sp_texture.h" +#include "sp_winsys.h" +#include "sp_query.h" + + + +/** + * Map any drawing surfaces which aren't already mapped + */ +void +softpipe_map_surfaces(struct softpipe_context *sp) +{ + unsigned i; + + for (i = 0; i < sp->framebuffer.num_cbufs; i++) { + sp_tile_cache_map_surfaces(sp->cbuf_cache[i]); + } + + sp_tile_cache_map_surfaces(sp->zsbuf_cache); +} + + +/** + * Unmap any mapped drawing surfaces + */ +void +softpipe_unmap_surfaces(struct softpipe_context *sp) +{ + uint i; + + for (i = 0; i < sp->framebuffer.num_cbufs; i++) + sp_flush_tile_cache(sp, sp->cbuf_cache[i]); + sp_flush_tile_cache(sp, sp->zsbuf_cache); + + for (i = 0; i < sp->framebuffer.num_cbufs; i++) { + sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]); + } + sp_tile_cache_unmap_surfaces(sp->zsbuf_cache); +} + + +static void softpipe_destroy( struct pipe_context *pipe ) +{ + struct softpipe_context *softpipe = softpipe_context( pipe ); + struct pipe_winsys *ws = pipe->winsys; + uint i; + + draw_destroy( softpipe->draw ); + + softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple ); + softpipe->quad.earlyz->destroy( softpipe->quad.earlyz ); + softpipe->quad.shade->destroy( softpipe->quad.shade ); + softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test ); + softpipe->quad.depth_test->destroy( softpipe->quad.depth_test ); + softpipe->quad.stencil_test->destroy( softpipe->quad.stencil_test ); + softpipe->quad.occlusion->destroy( softpipe->quad.occlusion ); + softpipe->quad.coverage->destroy( softpipe->quad.coverage ); + softpipe->quad.bufloop->destroy( softpipe->quad.bufloop ); + softpipe->quad.blend->destroy( softpipe->quad.blend ); + softpipe->quad.colormask->destroy( softpipe->quad.colormask ); + softpipe->quad.output->destroy( softpipe->quad.output ); + + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) + sp_destroy_tile_cache(softpipe->cbuf_cache[i]); + sp_destroy_tile_cache(softpipe->zsbuf_cache); + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + sp_destroy_tile_cache(softpipe->tex_cache[i]); + + for (i = 0; i < Elements(softpipe->constants); i++) { + if (softpipe->constants[i].buffer) { + pipe_buffer_reference(ws, &softpipe->constants[i].buffer, NULL); + } + } + + FREE( softpipe ); +} + + +struct pipe_context * +softpipe_create( struct pipe_screen *screen, + struct pipe_winsys *pipe_winsys, + struct softpipe_winsys *softpipe_winsys ) +{ + struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context); + uint i; + +#if defined(__i386__) || defined(__386__) + softpipe->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL; +#else + softpipe->use_sse = FALSE; +#endif + + softpipe->dump_fs = GETENV( "GALLIUM_DUMP_FS" ) != NULL; + + softpipe->pipe.winsys = pipe_winsys; + softpipe->pipe.screen = screen; + softpipe->pipe.destroy = softpipe_destroy; + + /* state setters */ + softpipe->pipe.create_blend_state = softpipe_create_blend_state; + softpipe->pipe.bind_blend_state = softpipe_bind_blend_state; + softpipe->pipe.delete_blend_state = softpipe_delete_blend_state; + + softpipe->pipe.create_sampler_state = softpipe_create_sampler_state; + softpipe->pipe.bind_sampler_states = softpipe_bind_sampler_states; + softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state; + + softpipe->pipe.create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state; + softpipe->pipe.bind_depth_stencil_alpha_state = softpipe_bind_depth_stencil_state; + softpipe->pipe.delete_depth_stencil_alpha_state = softpipe_delete_depth_stencil_state; + + softpipe->pipe.create_rasterizer_state = softpipe_create_rasterizer_state; + softpipe->pipe.bind_rasterizer_state = softpipe_bind_rasterizer_state; + softpipe->pipe.delete_rasterizer_state = softpipe_delete_rasterizer_state; + + softpipe->pipe.create_fs_state = softpipe_create_fs_state; + softpipe->pipe.bind_fs_state = softpipe_bind_fs_state; + softpipe->pipe.delete_fs_state = softpipe_delete_fs_state; + + softpipe->pipe.create_vs_state = softpipe_create_vs_state; + softpipe->pipe.bind_vs_state = softpipe_bind_vs_state; + softpipe->pipe.delete_vs_state = softpipe_delete_vs_state; + + softpipe->pipe.set_blend_color = softpipe_set_blend_color; + softpipe->pipe.set_clip_state = softpipe_set_clip_state; + softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer; + softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; + softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple; + softpipe->pipe.set_scissor_state = softpipe_set_scissor_state; + softpipe->pipe.set_sampler_textures = softpipe_set_sampler_textures; + softpipe->pipe.set_viewport_state = softpipe_set_viewport_state; + + softpipe->pipe.set_vertex_buffer = softpipe_set_vertex_buffer; + softpipe->pipe.set_vertex_element = softpipe_set_vertex_element; + + softpipe->pipe.draw_arrays = softpipe_draw_arrays; + softpipe->pipe.draw_elements = softpipe_draw_elements; + + softpipe->pipe.clear = softpipe_clear; + softpipe->pipe.flush = softpipe_flush; + + softpipe_init_query_funcs( softpipe ); + softpipe_init_texture_funcs( softpipe ); + + /* + * Alloc caches for accessing drawing surfaces and textures. + * Must be before quad stage setup! + */ + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) + softpipe->cbuf_cache[i] = sp_create_tile_cache(); + softpipe->zsbuf_cache = sp_create_tile_cache(); + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + softpipe->tex_cache[i] = sp_create_tile_cache(); + + + /* setup quad rendering stages */ + softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe); + softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe); + softpipe->quad.shade = sp_quad_shade_stage(softpipe); + softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe); + softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe); + softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe); + softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe); + softpipe->quad.coverage = sp_quad_coverage_stage(softpipe); + softpipe->quad.bufloop = sp_quad_bufloop_stage(softpipe); + softpipe->quad.blend = sp_quad_blend_stage(softpipe); + softpipe->quad.colormask = sp_quad_colormask_stage(softpipe); + softpipe->quad.output = sp_quad_output_stage(softpipe); + + softpipe->winsys = softpipe_winsys; + + /* + * Create drawing context and plug our rendering stage into it. + */ + softpipe->draw = draw_create(); + assert(softpipe->draw); + softpipe->setup = sp_draw_render_stage(softpipe); + + if (GETENV( "SP_VBUF" ) != NULL) { + sp_init_vbuf(softpipe); + } + else { + draw_set_rasterize_stage(softpipe->draw, softpipe->setup); + } + + /* plug in AA line/point stages */ + draw_install_aaline_stage(softpipe->draw, &softpipe->pipe); + draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe); + +#if USE_DRAW_STAGE_PSTIPPLE + /* Do polygon stipple w/ texture map + frag prog? */ + draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe); +#endif + + sp_init_surface_functions(softpipe); + + return &softpipe->pipe; +} diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index 2049afda34..5b5a0fe573 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -62,6 +62,14 @@ softpipe_unmap_constant_buffers(struct softpipe_context *sp) { struct pipe_winsys *ws = sp->pipe.winsys; uint i; + + /* really need to flush all prims since the vert/frag shaders const buffers + * are going away now. + */ + draw_flush(sp->draw); + + draw_set_mapped_constant_buffer(sp->draw, NULL); + for (i = 0; i < 2; i++) { if (sp->constants[i].size) ws->buffer_unmap(ws, sp->constants[i].buffer); diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c index 2feee5c485..7aa9cf8e85 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -1164,11 +1164,22 @@ static void setup_begin( struct draw_stage *stage ) struct setup_stage *setup = setup_stage(stage); struct softpipe_context *sp = setup->softpipe; const struct sp_fragment_shader *fs = setup->softpipe->fs; + uint i; if (sp->dirty) { softpipe_update_derived(sp); } + /* Mark surfaces as defined now */ + for (i = 0; i < sp->framebuffer.num_cbufs; i++){ + if (sp->framebuffer.cbufs[i]) { + sp->framebuffer.cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED; + } + } + if (sp->framebuffer.zsbuf) { + sp->framebuffer.zsbuf->status = PIPE_SURFACE_STATUS_DEFINED; + } + setup->quad.nr_attrs = fs->info.num_inputs; sp->quad.first->begin(sp->quad.first); diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index 69bea8a8f5..db0913cb2b 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -183,6 +183,60 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr_indices) } +/** + * This function is hit when the draw module is working in pass-through mode. + * It's up to us to convert the vertex array into point/line/tri prims. + */ +static void +sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) +{ + struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); + struct softpipe_context *softpipe = cvbr->softpipe; + struct draw_stage *setup = softpipe->setup; + struct prim_header prim; + const void *vertex_buffer = cvbr->vertex_buffer; + const unsigned vertex_size = softpipe->vertex_info_vbuf.size * sizeof(float); + unsigned i; + + prim.det = 0; + prim.reset_line_stipple = 0; + prim.edgeflags = 0; + prim.pad = 0; + +#define VERTEX(I) \ + (struct vertex_header *) ((char *) vertex_buffer + (I) * vertex_size) + + switch (cvbr->prim) { + case PIPE_PRIM_TRIANGLES: + assert(nr % 3 == 0); + for (i = 0; i < nr; i += 3) { + prim.v[0] = VERTEX(i + 0); + prim.v[1] = VERTEX(i + 1); + prim.v[2] = VERTEX(i + 2); + calc_det(&prim); + setup->tri( setup, &prim ); + } + break; + case PIPE_PRIM_POLYGON: + /* draw as tri fan */ + for (i = 2; i < nr; i++) { + prim.v[0] = VERTEX(0); + prim.v[1] = VERTEX(i - 1); + prim.v[2] = VERTEX(i); + calc_det(&prim); + setup->tri( setup, &prim ); + } + break; + default: + /* XXX finish remaining prim types */ + assert(0); + } + +#undef VERTEX +} + + + static void sp_vbuf_destroy(struct vbuf_render *vbr) { @@ -210,6 +264,7 @@ sp_init_vbuf(struct softpipe_context *sp) sp->vbuf_render->base.allocate_vertices = sp_vbuf_allocate_vertices; sp->vbuf_render->base.set_primitive = sp_vbuf_set_primitive; sp->vbuf_render->base.draw = sp_vbuf_draw; + sp->vbuf_render->base.draw_arrays = sp_vbuf_draw_arrays; sp->vbuf_render->base.release_vertices = sp_vbuf_release_vertices; sp->vbuf_render->base.destroy = sp_vbuf_destroy; @@ -218,4 +273,6 @@ sp_init_vbuf(struct softpipe_context *sp) sp->vbuf = draw_vbuf_stage(sp->draw, &sp->vbuf_render->base); draw_set_rasterize_stage(sp->draw, sp->vbuf); + + draw_set_render(sp->draw, &sp->vbuf_render->base); } diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index 9198198db3..861285101f 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -1,209 +1,209 @@ -/**************************************************************************
- *
- * Copyright 2007 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.
- *
- **************************************************************************/
-
-/* Vertices are just an array of floats, with all the attributes
- * packed. We currently assume a layout like:
- *
- * attr[0][0..3] - window position
- * attr[1..n][0..3] - remaining attributes.
- *
- * Attributes are assumed to be 4 floats wide but are packed so that
- * all the enabled attributes run contiguously.
- */
-
-#include "pipe/p_util.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_shader_tokens.h"
-
-#include "sp_context.h"
-#include "sp_state.h"
-#include "sp_headers.h"
-#include "sp_quad.h"
-#include "sp_texture.h"
-#include "sp_tex_sample.h"
-
-
-struct quad_shade_stage
-{
- struct quad_stage stage;
- struct tgsi_sampler samplers[PIPE_MAX_SAMPLERS];
- struct tgsi_exec_machine machine;
- struct tgsi_exec_vector *inputs, *outputs;
- int colorOutSlot, depthOutSlot;
-};
-
-
-/** cast wrapper */
-static INLINE struct quad_shade_stage *
-quad_shade_stage(struct quad_stage *qs)
-{
- return (struct quad_shade_stage *) qs;
-}
-
-
-
-/**
- * Execute fragment shader for the four fragments in the quad.
- */
-static void
-shade_quad(
- struct quad_stage *qs,
- struct quad_header *quad )
-{
- struct quad_shade_stage *qss = quad_shade_stage( qs );
- struct softpipe_context *softpipe = qs->softpipe;
- struct tgsi_exec_machine *machine = &qss->machine;
-
- /* Consts do not require 16 byte alignment. */
- machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT];
-
- machine->InterpCoefs = quad->coef;
-
- /* run shader */
- quad->mask &= softpipe->fs->run( softpipe->fs,
- &qss->machine,
- quad );
-
- /* store result color */
- if (qss->colorOutSlot >= 0) {
- /* XXX need to handle multiple color outputs someday */
- assert(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot]
- == TGSI_SEMANTIC_COLOR);
- memcpy(
- quad->outputs.color,
- &machine->Outputs[qss->colorOutSlot].xyzw[0].f[0],
- sizeof( quad->outputs.color ) );
- }
-
- /*
- * XXX the following code for updating quad->outputs.depth
- * isn't really needed if we did early z testing.
- */
-
- /* store result Z */
- if (qss->depthOutSlot >= 0) {
- /* output[slot] is new Z */
- uint i;
- for (i = 0; i < 4; i++) {
- quad->outputs.depth[i] = machine->Outputs[0].xyzw[2].f[i];
- }
- }
- else {
- /* copy input Z (which was interpolated by the executor) to output Z */
- uint i;
- for (i = 0; i < 4; i++) {
- quad->outputs.depth[i] = machine->Inputs[0].xyzw[2].f[i];
- /* XXX not sure the above line is always correct. The following
- * might be better:
- quad->outputs.depth[i] = machine->QuadPos.xyzw[2].f[i];
- */
- }
- }
-
- /* shader may cull fragments */
- if( quad->mask ) {
- qs->next->run( qs->next, quad );
- }
-}
-
-/**
- * Per-primitive (or per-begin?) setup
- */
-static void shade_begin(struct quad_stage *qs)
-{
- struct quad_shade_stage *qss = quad_shade_stage(qs);
- struct softpipe_context *softpipe = qs->softpipe;
- unsigned i;
- unsigned num = MAX2(softpipe->num_textures, softpipe->num_samplers);
-
- /* set TGSI sampler state that varies */
- for (i = 0; i < num; i++) {
- qss->samplers[i].state = softpipe->sampler[i];
- qss->samplers[i].texture = softpipe->texture[i];
- }
-
- /* find output slots for depth, color */
- qss->colorOutSlot = -1;
- qss->depthOutSlot = -1;
- for (i = 0; i < qss->stage.softpipe->fs->info.num_outputs; i++) {
- switch (qss->stage.softpipe->fs->info.output_semantic_name[i]) {
- case TGSI_SEMANTIC_POSITION:
- qss->depthOutSlot = i;
- break;
- case TGSI_SEMANTIC_COLOR:
- qss->colorOutSlot = i;
- break;
- }
- }
-
- softpipe->fs->prepare( softpipe->fs,
- &qss->machine,
- qss->samplers );
-
- qs->next->begin(qs->next);
-}
-
-
-static void shade_destroy(struct quad_stage *qs)
-{
- struct quad_shade_stage *qss = (struct quad_shade_stage *) qs;
-
- tgsi_exec_machine_free_data(&qss->machine);
- FREE( qss->inputs );
- FREE( qss->outputs );
- FREE( qs );
-}
-
-
-struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe )
-{
- struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage);
- uint i;
-
- /* allocate storage for program inputs/outputs, aligned to 16 bytes */
- qss->inputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->inputs) + 16);
- qss->outputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->outputs) + 16);
- qss->machine.Inputs = align16(qss->inputs);
- qss->machine.Outputs = align16(qss->outputs);
-
- qss->stage.softpipe = softpipe;
- qss->stage.begin = shade_begin;
- qss->stage.run = shade_quad;
- qss->stage.destroy = shade_destroy;
-
- /* set TGSI sampler state that's constant */
- for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- assert(softpipe->tex_cache[i]);
- qss->samplers[i].get_samples = sp_get_samples;
- qss->samplers[i].pipe = &softpipe->pipe;
- qss->samplers[i].cache = softpipe->tex_cache[i];
- }
-
- tgsi_exec_machine_init( &qss->machine );
-
- return &qss->stage;
-}
+/************************************************************************** + * + * Copyright 2007 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. + * + **************************************************************************/ + +/* Vertices are just an array of floats, with all the attributes + * packed. We currently assume a layout like: + * + * attr[0][0..3] - window position + * attr[1..n][0..3] - remaining attributes. + * + * Attributes are assumed to be 4 floats wide but are packed so that + * all the enabled attributes run contiguously. + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" + +#include "sp_context.h" +#include "sp_state.h" +#include "sp_headers.h" +#include "sp_quad.h" +#include "sp_texture.h" +#include "sp_tex_sample.h" + + +struct quad_shade_stage +{ + struct quad_stage stage; + struct tgsi_sampler samplers[PIPE_MAX_SAMPLERS]; + struct tgsi_exec_machine machine; + struct tgsi_exec_vector *inputs, *outputs; + int colorOutSlot, depthOutSlot; +}; + + +/** cast wrapper */ +static INLINE struct quad_shade_stage * +quad_shade_stage(struct quad_stage *qs) +{ + return (struct quad_shade_stage *) qs; +} + + + +/** + * Execute fragment shader for the four fragments in the quad. + */ +static void +shade_quad( + struct quad_stage *qs, + struct quad_header *quad ) +{ + struct quad_shade_stage *qss = quad_shade_stage( qs ); + struct softpipe_context *softpipe = qs->softpipe; + struct tgsi_exec_machine *machine = &qss->machine; + + /* Consts do not require 16 byte alignment. */ + machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT]; + + machine->InterpCoefs = quad->coef; + + /* run shader */ + quad->mask &= softpipe->fs->run( softpipe->fs, + &qss->machine, + quad ); + + /* store result color */ + if (qss->colorOutSlot >= 0) { + /* XXX need to handle multiple color outputs someday */ + assert(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot] + == TGSI_SEMANTIC_COLOR); + memcpy( + quad->outputs.color, + &machine->Outputs[qss->colorOutSlot].xyzw[0].f[0], + sizeof( quad->outputs.color ) ); + } + + /* + * XXX the following code for updating quad->outputs.depth + * isn't really needed if we did early z testing. + */ + + /* store result Z */ + if (qss->depthOutSlot >= 0) { + /* output[slot] is new Z */ + uint i; + for (i = 0; i < 4; i++) { + quad->outputs.depth[i] = machine->Outputs[0].xyzw[2].f[i]; + } + } + else { + /* copy input Z (which was interpolated by the executor) to output Z */ + uint i; + for (i = 0; i < 4; i++) { + quad->outputs.depth[i] = machine->Inputs[0].xyzw[2].f[i]; + /* XXX not sure the above line is always correct. The following + * might be better: + quad->outputs.depth[i] = machine->QuadPos.xyzw[2].f[i]; + */ + } + } + + /* shader may cull fragments */ + if( quad->mask ) { + qs->next->run( qs->next, quad ); + } +} + +/** + * Per-primitive (or per-begin?) setup + */ +static void shade_begin(struct quad_stage *qs) +{ + struct quad_shade_stage *qss = quad_shade_stage(qs); + struct softpipe_context *softpipe = qs->softpipe; + unsigned i; + unsigned num = MAX2(softpipe->num_textures, softpipe->num_samplers); + + /* set TGSI sampler state that varies */ + for (i = 0; i < num; i++) { + qss->samplers[i].state = softpipe->sampler[i]; + qss->samplers[i].texture = softpipe->texture[i]; + } + + /* find output slots for depth, color */ + qss->colorOutSlot = -1; + qss->depthOutSlot = -1; + for (i = 0; i < qss->stage.softpipe->fs->info.num_outputs; i++) { + switch (qss->stage.softpipe->fs->info.output_semantic_name[i]) { + case TGSI_SEMANTIC_POSITION: + qss->depthOutSlot = i; + break; + case TGSI_SEMANTIC_COLOR: + qss->colorOutSlot = i; + break; + } + } + + softpipe->fs->prepare( softpipe->fs, + &qss->machine, + qss->samplers ); + + qs->next->begin(qs->next); +} + + +static void shade_destroy(struct quad_stage *qs) +{ + struct quad_shade_stage *qss = (struct quad_shade_stage *) qs; + + tgsi_exec_machine_free_data(&qss->machine); + FREE( qss->inputs ); + FREE( qss->outputs ); + FREE( qs ); +} + + +struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe ) +{ + struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage); + uint i; + + /* allocate storage for program inputs/outputs, aligned to 16 bytes */ + qss->inputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->inputs) + 16); + qss->outputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->outputs) + 16); + qss->machine.Inputs = align16(qss->inputs); + qss->machine.Outputs = align16(qss->outputs); + + qss->stage.softpipe = softpipe; + qss->stage.begin = shade_begin; + qss->stage.run = shade_quad; + qss->stage.destroy = shade_destroy; + + /* set TGSI sampler state that's constant */ + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + assert(softpipe->tex_cache[i]); + qss->samplers[i].get_samples = sp_get_samples; + qss->samplers[i].pipe = &softpipe->pipe; + qss->samplers[i].cache = softpipe->tex_cache[i]; + } + + tgsi_exec_machine_init( &qss->machine ); + + return &qss->stage; +} diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 45d159143f..0bb1095aec 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -1,195 +1,195 @@ -/**************************************************************************
- *
- * Copyright 2007 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.
- *
- **************************************************************************/
-
-/* Authors: Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#ifndef SP_STATE_H
-#define SP_STATE_H
-
-#include "pipe/p_state.h"
-#include "tgsi/util/tgsi_scan.h"
-
-
-#define SP_NEW_VIEWPORT 0x1
-#define SP_NEW_RASTERIZER 0x2
-#define SP_NEW_FS 0x4
-#define SP_NEW_BLEND 0x8
-#define SP_NEW_CLIP 0x10
-#define SP_NEW_SCISSOR 0x20
-#define SP_NEW_STIPPLE 0x40
-#define SP_NEW_FRAMEBUFFER 0x80
-#define SP_NEW_DEPTH_STENCIL_ALPHA 0x100
-#define SP_NEW_CONSTANTS 0x200
-#define SP_NEW_SAMPLER 0x400
-#define SP_NEW_TEXTURE 0x800
-#define SP_NEW_VERTEX 0x1000
-#define SP_NEW_VS 0x2000
-#define SP_NEW_QUERY 0x4000
-
-
-struct tgsi_sampler;
-struct tgsi_exec_machine;
-
-
-/** Subclass of pipe_shader_state (though it doesn't really need to be).
- *
- * This is starting to look an awful lot like a quad pipeline stage...
- */
-struct sp_fragment_shader {
- struct pipe_shader_state shader;
-
- struct tgsi_shader_info info;
-
- void (*prepare)( const struct sp_fragment_shader *shader,
- struct tgsi_exec_machine *machine,
- struct tgsi_sampler *samplers);
-
- /* Run the shader - this interface will get cleaned up in the
- * future:
- */
- unsigned (*run)( const struct sp_fragment_shader *shader,
- struct tgsi_exec_machine *machine,
- struct quad_header *quad );
-
-
- void (*delete)( struct sp_fragment_shader * );
-};
-
-struct vertex_info;
-
-/** Subclass of pipe_shader_state */
-struct sp_vertex_shader {
- struct pipe_shader_state shader;
- struct draw_vertex_shader *draw_data;
-};
-
-
-
-void *
-softpipe_create_blend_state(struct pipe_context *,
- const struct pipe_blend_state *);
-void softpipe_bind_blend_state(struct pipe_context *,
- void *);
-void softpipe_delete_blend_state(struct pipe_context *,
- void *);
-
-void *
-softpipe_create_sampler_state(struct pipe_context *,
- const struct pipe_sampler_state *);
-void softpipe_bind_sampler_states(struct pipe_context *, unsigned, void **);
-void softpipe_delete_sampler_state(struct pipe_context *, void *);
-
-void *
-softpipe_create_depth_stencil_state(struct pipe_context *,
- const struct pipe_depth_stencil_alpha_state *);
-void softpipe_bind_depth_stencil_state(struct pipe_context *, void *);
-void softpipe_delete_depth_stencil_state(struct pipe_context *, void *);
-
-void *
-softpipe_create_rasterizer_state(struct pipe_context *,
- const struct pipe_rasterizer_state *);
-void softpipe_bind_rasterizer_state(struct pipe_context *, void *);
-void softpipe_delete_rasterizer_state(struct pipe_context *, void *);
-
-void softpipe_set_framebuffer_state( struct pipe_context *,
- const struct pipe_framebuffer_state * );
-
-void softpipe_set_blend_color( struct pipe_context *pipe,
- const struct pipe_blend_color *blend_color );
-
-void softpipe_set_clip_state( struct pipe_context *,
- const struct pipe_clip_state * );
-
-void softpipe_set_constant_buffer(struct pipe_context *,
- uint shader, uint index,
- const struct pipe_constant_buffer *buf);
-
-void *softpipe_create_fs_state(struct pipe_context *,
- const struct pipe_shader_state *);
-void softpipe_bind_fs_state(struct pipe_context *, void *);
-void softpipe_delete_fs_state(struct pipe_context *, void *);
-void *softpipe_create_vs_state(struct pipe_context *,
- const struct pipe_shader_state *);
-void softpipe_bind_vs_state(struct pipe_context *, void *);
-void softpipe_delete_vs_state(struct pipe_context *, void *);
-
-void softpipe_set_polygon_stipple( struct pipe_context *,
- const struct pipe_poly_stipple * );
-
-void softpipe_set_scissor_state( struct pipe_context *,
- const struct pipe_scissor_state * );
-
-void softpipe_set_sampler_textures( struct pipe_context *,
- unsigned num,
- struct pipe_texture ** );
-
-void softpipe_set_viewport_state( struct pipe_context *,
- const struct pipe_viewport_state * );
-
-void softpipe_set_vertex_element(struct pipe_context *,
- unsigned index,
- const struct pipe_vertex_element *);
-
-void softpipe_set_vertex_buffer(struct pipe_context *,
- unsigned index,
- const struct pipe_vertex_buffer *);
-
-
-void softpipe_update_derived( struct softpipe_context *softpipe );
-
-
-boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
- unsigned start, unsigned count);
-
-boolean softpipe_draw_elements(struct pipe_context *pipe,
- struct pipe_buffer *indexBuffer,
- unsigned indexSize,
- unsigned mode, unsigned start, unsigned count);
-
-
-void
-softpipe_map_surfaces(struct softpipe_context *sp);
-
-void
-softpipe_unmap_surfaces(struct softpipe_context *sp);
-
-void
-softpipe_map_texture_surfaces(struct softpipe_context *sp);
-
-void
-softpipe_unmap_texture_surfaces(struct softpipe_context *sp);
-
-
-struct vertex_info *
-softpipe_get_vertex_info(struct softpipe_context *softpipe);
-
-struct vertex_info *
-softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe);
-
-
-#endif
+/************************************************************************** + * + * Copyright 2007 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. + * + **************************************************************************/ + +/* Authors: Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef SP_STATE_H +#define SP_STATE_H + +#include "pipe/p_state.h" +#include "tgsi/util/tgsi_scan.h" + + +#define SP_NEW_VIEWPORT 0x1 +#define SP_NEW_RASTERIZER 0x2 +#define SP_NEW_FS 0x4 +#define SP_NEW_BLEND 0x8 +#define SP_NEW_CLIP 0x10 +#define SP_NEW_SCISSOR 0x20 +#define SP_NEW_STIPPLE 0x40 +#define SP_NEW_FRAMEBUFFER 0x80 +#define SP_NEW_DEPTH_STENCIL_ALPHA 0x100 +#define SP_NEW_CONSTANTS 0x200 +#define SP_NEW_SAMPLER 0x400 +#define SP_NEW_TEXTURE 0x800 +#define SP_NEW_VERTEX 0x1000 +#define SP_NEW_VS 0x2000 +#define SP_NEW_QUERY 0x4000 + + +struct tgsi_sampler; +struct tgsi_exec_machine; + + +/** Subclass of pipe_shader_state (though it doesn't really need to be). + * + * This is starting to look an awful lot like a quad pipeline stage... + */ +struct sp_fragment_shader { + struct pipe_shader_state shader; + + struct tgsi_shader_info info; + + void (*prepare)( const struct sp_fragment_shader *shader, + struct tgsi_exec_machine *machine, + struct tgsi_sampler *samplers); + + /* Run the shader - this interface will get cleaned up in the + * future: + */ + unsigned (*run)( const struct sp_fragment_shader *shader, + struct tgsi_exec_machine *machine, + struct quad_header *quad ); + + + void (*delete)( struct sp_fragment_shader * ); +}; + +struct vertex_info; + +/** Subclass of pipe_shader_state */ +struct sp_vertex_shader { + struct pipe_shader_state shader; + struct draw_vertex_shader *draw_data; +}; + + + +void * +softpipe_create_blend_state(struct pipe_context *, + const struct pipe_blend_state *); +void softpipe_bind_blend_state(struct pipe_context *, + void *); +void softpipe_delete_blend_state(struct pipe_context *, + void *); + +void * +softpipe_create_sampler_state(struct pipe_context *, + const struct pipe_sampler_state *); +void softpipe_bind_sampler_states(struct pipe_context *, unsigned, void **); +void softpipe_delete_sampler_state(struct pipe_context *, void *); + +void * +softpipe_create_depth_stencil_state(struct pipe_context *, + const struct pipe_depth_stencil_alpha_state *); +void softpipe_bind_depth_stencil_state(struct pipe_context *, void *); +void softpipe_delete_depth_stencil_state(struct pipe_context *, void *); + +void * +softpipe_create_rasterizer_state(struct pipe_context *, + const struct pipe_rasterizer_state *); +void softpipe_bind_rasterizer_state(struct pipe_context *, void *); +void softpipe_delete_rasterizer_state(struct pipe_context *, void *); + +void softpipe_set_framebuffer_state( struct pipe_context *, + const struct pipe_framebuffer_state * ); + +void softpipe_set_blend_color( struct pipe_context *pipe, + const struct pipe_blend_color *blend_color ); + +void softpipe_set_clip_state( struct pipe_context *, + const struct pipe_clip_state * ); + +void softpipe_set_constant_buffer(struct pipe_context *, + uint shader, uint index, + const struct pipe_constant_buffer *buf); + +void *softpipe_create_fs_state(struct pipe_context *, + const struct pipe_shader_state *); +void softpipe_bind_fs_state(struct pipe_context *, void *); +void softpipe_delete_fs_state(struct pipe_context *, void *); +void *softpipe_create_vs_state(struct pipe_context *, + const struct pipe_shader_state *); +void softpipe_bind_vs_state(struct pipe_context *, void *); +void softpipe_delete_vs_state(struct pipe_context *, void *); + +void softpipe_set_polygon_stipple( struct pipe_context *, + const struct pipe_poly_stipple * ); + +void softpipe_set_scissor_state( struct pipe_context *, + const struct pipe_scissor_state * ); + +void softpipe_set_sampler_textures( struct pipe_context *, + unsigned num, + struct pipe_texture ** ); + +void softpipe_set_viewport_state( struct pipe_context *, + const struct pipe_viewport_state * ); + +void softpipe_set_vertex_element(struct pipe_context *, + unsigned index, + const struct pipe_vertex_element *); + +void softpipe_set_vertex_buffer(struct pipe_context *, + unsigned index, + const struct pipe_vertex_buffer *); + + +void softpipe_update_derived( struct softpipe_context *softpipe ); + + +boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, + unsigned start, unsigned count); + +boolean softpipe_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count); + + +void +softpipe_map_surfaces(struct softpipe_context *sp); + +void +softpipe_unmap_surfaces(struct softpipe_context *sp); + +void +softpipe_map_texture_surfaces(struct softpipe_context *sp); + +void +softpipe_unmap_texture_surfaces(struct softpipe_context *sp); + + +struct vertex_info * +softpipe_get_vertex_info(struct softpipe_context *softpipe); + +struct vertex_info * +softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe); + + +#endif diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index eafbaed4b9..82cb31ece7 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -71,11 +71,25 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe) * simply emit the whole post-xform vertex as-is: */ struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf; +#if 0 vinfo_vbuf->num_attribs = 0; + /* special-case to allow memcpy of whole vertex */ draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0); /* size in dwords or floats */ vinfo_vbuf->size = 4 * draw_num_vs_outputs(softpipe->draw) + sizeof(struct vertex_header) / 4; +#else + /* for pass-through mode, we need a more explicit list of attribs */ + const uint num = draw_num_vs_outputs(softpipe->draw); + uint i; + + vinfo_vbuf->num_attribs = 0; + draw_emit_vertex_attr(vinfo_vbuf, EMIT_HEADER, INTERP_NONE, 0); + for (i = 0; i < num; i++) { + draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i); + } + draw_compute_vertex_size(vinfo_vbuf); +#endif } /* diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index bbf2d80308..64bf353aa4 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -1,202 +1,202 @@ -/**************************************************************************
- *
- * Copyright 2006 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.
- *
- **************************************************************************/
- /*
- * Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
- * Michel Dänzer <michel@tungstengraphics.com>
- */
-
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_inlines.h"
-#include "pipe/p_util.h"
-#include "pipe/p_winsys.h"
-
-#include "sp_context.h"
-#include "sp_state.h"
-#include "sp_texture.h"
-#include "sp_tile_cache.h"
-
-
-/* Simple, maximally packed layout.
- */
-
-static unsigned minify( unsigned d )
-{
- return MAX2(1, d>>1);
-}
-
-
-static void
-softpipe_texture_layout(struct softpipe_texture * spt)
-{
- struct pipe_texture *pt = &spt->base;
- unsigned level;
- unsigned width = pt->width[0];
- unsigned height = pt->height[0];
- unsigned depth = pt->depth[0];
-
- spt->buffer_size = 0;
-
- for (level = 0; level <= pt->last_level; level++) {
- pt->width[level] = width;
- pt->height[level] = height;
- pt->depth[level] = depth;
-
- spt->level_offset[level] = spt->buffer_size;
-
- spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) *
- ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *
- width * pt->cpp;
-
- width = minify(width);
- height = minify(height);
- depth = minify(depth);
- }
-}
-
-
-static struct pipe_texture *
-softpipe_texture_create_screen(struct pipe_screen *screen,
- const struct pipe_texture *templat)
-{
- struct pipe_winsys *ws = screen->winsys;
- struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture);
- if (!spt)
- return NULL;
-
- spt->base = *templat;
- spt->base.refcount = 1;
- spt->base.screen = screen;
-
- softpipe_texture_layout(spt);
-
- spt->buffer = ws->buffer_create(ws, 32,
- PIPE_BUFFER_USAGE_PIXEL,
- spt->buffer_size);
- if (!spt->buffer) {
- FREE(spt);
- return NULL;
- }
-
- assert(spt->base.refcount == 1);
-
- return &spt->base;
-}
-
-
-static void
-softpipe_texture_release_screen(struct pipe_screen *screen,
- struct pipe_texture **pt)
-{
- if (!*pt)
- return;
-
- /*
- DBG("%s %p refcount will be %d\n",
- __FUNCTION__, (void *) *pt, (*pt)->refcount - 1);
- */
- if (--(*pt)->refcount <= 0) {
- struct softpipe_texture *spt = softpipe_texture(*pt);
-
- /*
- DBG("%s deleting %p\n", __FUNCTION__, (void *) spt);
- */
-
- pipe_buffer_reference(screen->winsys, &spt->buffer, NULL);
-
- FREE(spt);
- }
- *pt = NULL;
-}
-
-
-static struct pipe_surface *
-softpipe_get_tex_surface_screen(struct pipe_screen *screen,
- struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice)
-{
- struct pipe_winsys *ws = screen->winsys;
- struct softpipe_texture *spt = softpipe_texture(pt);
- struct pipe_surface *ps;
-
- assert(level <= pt->last_level);
-
- ps = ws->surface_alloc(ws);
- if (ps) {
- assert(ps->refcount);
- assert(ps->winsys);
- pipe_buffer_reference(ws, &ps->buffer, spt->buffer);
- ps->format = pt->format;
- ps->cpp = pt->cpp;
- ps->width = pt->width[level];
- ps->height = pt->height[level];
- ps->pitch = ps->width;
- ps->offset = spt->level_offset[level];
-
- if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) {
- ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) *
- (pt->compressed ? ps->height/4 : ps->height) *
- ps->width * ps->cpp;
- }
- else {
- assert(face == 0);
- assert(zslice == 0);
- }
- }
- return ps;
-}
-
-
-static void
-softpipe_texture_update(struct pipe_context *pipe,
- struct pipe_texture *texture)
-{
- struct softpipe_context *softpipe = softpipe_context(pipe);
- uint unit;
- for (unit = 0; unit < softpipe->num_textures; unit++) {
- if (softpipe->texture[unit] == texture) {
- sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]);
- }
- }
-}
-
-
-void
-softpipe_init_texture_funcs( struct softpipe_context *softpipe )
-{
- softpipe->pipe.texture_update = softpipe_texture_update;
-}
-
-
-void
-softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
-{
- screen->texture_create = softpipe_texture_create_screen;
- screen->texture_release = softpipe_texture_release_screen;
- screen->get_tex_surface = softpipe_get_tex_surface_screen;
-}
+/************************************************************************** + * + * Copyright 2006 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. + * + **************************************************************************/ + /* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + * Michel Dänzer <michel@tungstengraphics.com> + */ + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" + +#include "sp_context.h" +#include "sp_state.h" +#include "sp_texture.h" +#include "sp_tile_cache.h" + + +/* Simple, maximally packed layout. + */ + +static unsigned minify( unsigned d ) +{ + return MAX2(1, d>>1); +} + + +static void +softpipe_texture_layout(struct softpipe_texture * spt) +{ + struct pipe_texture *pt = &spt->base; + unsigned level; + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; + unsigned depth = pt->depth[0]; + + spt->buffer_size = 0; + + for (level = 0; level <= pt->last_level; level++) { + pt->width[level] = width; + pt->height[level] = height; + pt->depth[level] = depth; + + spt->level_offset[level] = spt->buffer_size; + + spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) * + ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * + width * pt->cpp; + + width = minify(width); + height = minify(height); + depth = minify(depth); + } +} + + +static struct pipe_texture * +softpipe_texture_create_screen(struct pipe_screen *screen, + const struct pipe_texture *templat) +{ + struct pipe_winsys *ws = screen->winsys; + struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture); + if (!spt) + return NULL; + + spt->base = *templat; + spt->base.refcount = 1; + spt->base.screen = screen; + + softpipe_texture_layout(spt); + + spt->buffer = ws->buffer_create(ws, 32, + PIPE_BUFFER_USAGE_PIXEL, + spt->buffer_size); + if (!spt->buffer) { + FREE(spt); + return NULL; + } + + assert(spt->base.refcount == 1); + + return &spt->base; +} + + +static void +softpipe_texture_release_screen(struct pipe_screen *screen, + struct pipe_texture **pt) +{ + if (!*pt) + return; + + /* + DBG("%s %p refcount will be %d\n", + __FUNCTION__, (void *) *pt, (*pt)->refcount - 1); + */ + if (--(*pt)->refcount <= 0) { + struct softpipe_texture *spt = softpipe_texture(*pt); + + /* + DBG("%s deleting %p\n", __FUNCTION__, (void *) spt); + */ + + pipe_buffer_reference(screen->winsys, &spt->buffer, NULL); + + FREE(spt); + } + *pt = NULL; +} + + +static struct pipe_surface * +softpipe_get_tex_surface_screen(struct pipe_screen *screen, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct pipe_winsys *ws = screen->winsys; + struct softpipe_texture *spt = softpipe_texture(pt); + struct pipe_surface *ps; + + assert(level <= pt->last_level); + + ps = ws->surface_alloc(ws); + if (ps) { + assert(ps->refcount); + assert(ps->winsys); + pipe_buffer_reference(ws, &ps->buffer, spt->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = ps->width; + ps->offset = spt->level_offset[level]; + + if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) { + ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * + (pt->compressed ? ps->height/4 : ps->height) * + ps->width * ps->cpp; + } + else { + assert(face == 0); + assert(zslice == 0); + } + } + return ps; +} + + +static void +softpipe_texture_update(struct pipe_context *pipe, + struct pipe_texture *texture) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + uint unit; + for (unit = 0; unit < softpipe->num_textures; unit++) { + if (softpipe->texture[unit] == texture) { + sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]); + } + } +} + + +void +softpipe_init_texture_funcs( struct softpipe_context *softpipe ) +{ + softpipe->pipe.texture_update = softpipe_texture_update; +} + + +void +softpipe_init_screen_texture_funcs(struct pipe_screen *screen) +{ + screen->texture_create = softpipe_texture_create_screen; + screen->texture_release = softpipe_texture_release_screen; + screen->get_tex_surface = softpipe_get_tex_surface_screen; +} diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index f45363f355..f971ad3adc 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -121,7 +121,8 @@ uint32_t debug_mask_get(uint32_t uuid); * @code * #define MYDRIVER_UUID 0x12345678 // random 32 bit identifier * - * static inline mydriver_debug(uint32_t what, const char *format, ...) + * static void inline + * mydriver_debug(uint32_t what, const char *format, ...) * { * #ifdef DEBUG * va_list ap; diff --git a/src/gallium/include/pipe/p_error.h b/src/gallium/include/pipe/p_error.h new file mode 100644 index 0000000000..b865b22635 --- /dev/null +++ b/src/gallium/include/pipe/p_error.h @@ -0,0 +1,65 @@ +/************************************************************************** + * + * 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 + * Gallium error codes. + * + * @author José Fonseca <jrfonseca@tungstengraphics.com> + */ + +#ifndef P_ERROR_H_ +#define P_ERROR_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Gallium error codes. + * + * - A zero value always means success. + * - A negative value always means failure. + * - The meaning of a positive value is function dependent. + */ +enum pipe_error { + PIPE_OK = 0, + PIPE_ERROR = -1, /**< Generic error */ + PIPE_ERROR_BAD_INPUT = -2, + PIPE_ERROR_OUT_OF_MEMORY = -3, + PIPE_ERROR_RETRY = -4 + /* TODO */ +}; + + +#ifdef __cplusplus +} +#endif + +#endif /* P_ERROR_H_ */ diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index 210169f54f..f05e1a34b3 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -227,22 +227,22 @@ struct tgsi_immediate_float32 #define TGSI_OPCODE_STR 51 #define TGSI_OPCODE_TEX 52 #define TGSI_OPCODE_TXD 53 -#define TGSI_OPCODE_TXP 134 -#define TGSI_OPCODE_UP2H 54 -#define TGSI_OPCODE_UP2US 55 -#define TGSI_OPCODE_UP4B 56 -#define TGSI_OPCODE_UP4UB 57 -#define TGSI_OPCODE_X2D 58 +#define TGSI_OPCODE_TXP 54 +#define TGSI_OPCODE_UP2H 55 +#define TGSI_OPCODE_UP2US 56 +#define TGSI_OPCODE_UP4B 57 +#define TGSI_OPCODE_UP4UB 58 +#define TGSI_OPCODE_X2D 59 /* * GL_NV_vertex_program2 */ -#define TGSI_OPCODE_ARA 59 -#define TGSI_OPCODE_ARR 60 -#define TGSI_OPCODE_BRA 61 -#define TGSI_OPCODE_CAL 62 -#define TGSI_OPCODE_RET 63 -#define TGSI_OPCODE_SSG 64 +#define TGSI_OPCODE_ARA 60 +#define TGSI_OPCODE_ARR 61 +#define TGSI_OPCODE_BRA 62 +#define TGSI_OPCODE_CAL 63 +#define TGSI_OPCODE_RET 64 +#define TGSI_OPCODE_SSG 65 /* * GL_ARB_vertex_program @@ -253,9 +253,9 @@ struct tgsi_immediate_float32 /* * GL_ARB_fragment_program */ -#define TGSI_OPCODE_CMP 65 -#define TGSI_OPCODE_SCS 66 -#define TGSI_OPCODE_TXB 67 +#define TGSI_OPCODE_CMP 66 +#define TGSI_OPCODE_SCS 67 +#define TGSI_OPCODE_TXB 68 /* * GL_NV_fragment_program_option @@ -265,19 +265,19 @@ struct tgsi_immediate_float32 /* * GL_NV_fragment_program2 */ -#define TGSI_OPCODE_NRM 68 -#define TGSI_OPCODE_DIV 69 -#define TGSI_OPCODE_DP2 70 +#define TGSI_OPCODE_NRM 69 +#define TGSI_OPCODE_DIV 70 +#define TGSI_OPCODE_DP2 71 #define TGSI_OPCODE_DP2A TGSI_OPCODE_DOT2ADD -#define TGSI_OPCODE_TXL 71 -#define TGSI_OPCODE_BRK 72 -#define TGSI_OPCODE_IF 73 -#define TGSI_OPCODE_LOOP 74 -#define TGSI_OPCODE_REP 75 -#define TGSI_OPCODE_ELSE 76 -#define TGSI_OPCODE_ENDIF 77 -#define TGSI_OPCODE_ENDLOOP 78 -#define TGSI_OPCODE_ENDREP 79 +#define TGSI_OPCODE_TXL 72 +#define TGSI_OPCODE_BRK 73 +#define TGSI_OPCODE_IF 74 +#define TGSI_OPCODE_LOOP 75 +#define TGSI_OPCODE_REP 76 +#define TGSI_OPCODE_ELSE 77 +#define TGSI_OPCODE_ENDIF 78 +#define TGSI_OPCODE_ENDLOOP 79 +#define TGSI_OPCODE_ENDREP 80 /* * GL_NV_vertex_program2_option @@ -286,26 +286,26 @@ struct tgsi_immediate_float32 /* * GL_NV_vertex_program3 */ -#define TGSI_OPCODE_PUSHA 80 -#define TGSI_OPCODE_POPA 81 +#define TGSI_OPCODE_PUSHA 81 +#define TGSI_OPCODE_POPA 82 /* * GL_NV_gpu_program4 */ -#define TGSI_OPCODE_CEIL 82 -#define TGSI_OPCODE_I2F 83 -#define TGSI_OPCODE_NOT 84 -#define TGSI_OPCODE_TRUNC 85 -#define TGSI_OPCODE_SHL 86 -#define TGSI_OPCODE_SHR 87 -#define TGSI_OPCODE_AND 88 -#define TGSI_OPCODE_OR 89 -#define TGSI_OPCODE_MOD 90 -#define TGSI_OPCODE_XOR 91 -#define TGSI_OPCODE_SAD 92 -#define TGSI_OPCODE_TXF 93 -#define TGSI_OPCODE_TXQ 94 -#define TGSI_OPCODE_CONT 95 +#define TGSI_OPCODE_CEIL 83 +#define TGSI_OPCODE_I2F 84 +#define TGSI_OPCODE_NOT 85 +#define TGSI_OPCODE_TRUNC 86 +#define TGSI_OPCODE_SHL 87 +#define TGSI_OPCODE_SHR 88 +#define TGSI_OPCODE_AND 89 +#define TGSI_OPCODE_OR 90 +#define TGSI_OPCODE_MOD 91 +#define TGSI_OPCODE_XOR 92 +#define TGSI_OPCODE_SAD 93 +#define TGSI_OPCODE_TXF 94 +#define TGSI_OPCODE_TXQ 95 +#define TGSI_OPCODE_CONT 96 /* * GL_NV_vertex_program4 @@ -321,72 +321,53 @@ struct tgsi_immediate_float32 * GL_NV_geometry_program4 */ /* Same as GL_NV_gpu_program4 */ -#define TGSI_OPCODE_EMIT 96 -#define TGSI_OPCODE_ENDPRIM 97 +#define TGSI_OPCODE_EMIT 97 +#define TGSI_OPCODE_ENDPRIM 98 /* * GLSL */ -#define TGSI_OPCODE_BGNLOOP2 98 -#define TGSI_OPCODE_BGNSUB 99 -#define TGSI_OPCODE_ENDLOOP2 100 -#define TGSI_OPCODE_ENDSUB 101 +#define TGSI_OPCODE_BGNLOOP2 99 +#define TGSI_OPCODE_BGNSUB 100 +#define TGSI_OPCODE_ENDLOOP2 101 +#define TGSI_OPCODE_ENDSUB 102 #define TGSI_OPCODE_INT TGSI_OPCODE_TRUNC -#define TGSI_OPCODE_NOISE1 102 -#define TGSI_OPCODE_NOISE2 103 -#define TGSI_OPCODE_NOISE3 104 -#define TGSI_OPCODE_NOISE4 105 -#define TGSI_OPCODE_NOP 106 +#define TGSI_OPCODE_NOISE1 103 +#define TGSI_OPCODE_NOISE2 104 +#define TGSI_OPCODE_NOISE3 105 +#define TGSI_OPCODE_NOISE4 106 +#define TGSI_OPCODE_NOP 107 /* * ps_1_1 */ -#define TGSI_OPCODE_TEXCOORD TGSI_OPCODE_NOP #define TGSI_OPCODE_TEXKILL TGSI_OPCODE_KILP -#define TGSI_OPCODE_TEXBEM 107 -#define TGSI_OPCODE_TEXBEML 108 -#define TGSI_OPCODE_TEXREG2AR 109 -#define TGSI_OPCODE_TEXM3X2PAD 110 -#define TGSI_OPCODE_TEXM3X2TEX 111 -#define TGSI_OPCODE_TEXM3X3PAD 112 -#define TGSI_OPCODE_TEXM3X3TEX 113 -#define TGSI_OPCODE_TEXM3X3SPEC 114 -#define TGSI_OPCODE_TEXM3X3VSPEC 115 /* * ps_1_2 */ -#define TGSI_OPCODE_TEXREG2GB 116 -#define TGSI_OPCODE_TEXREG2RGB 117 -#define TGSI_OPCODE_TEXDP3TEX 118 -#define TGSI_OPCODE_TEXDP3 119 -#define TGSI_OPCODE_TEXM3X3 120 /* CMP - use TGSI_OPCODE_CND0 */ /* * ps_1_3 */ -#define TGSI_OPCODE_TEXM3X2DEPTH 121 /* CMP - use TGSI_OPCODE_CND0 */ /* * ps_1_4 */ -#define TGSI_OPCODE_TEXCRD TGSI_OPCODE_TEXCOORD #define TGSI_OPCODE_TEXLD TGSI_OPCODE_TEX -#define TGSI_OPCODE_TEXDEPTH 122 -#define TGSI_OPCODE_BEM 123 /* * ps_2_0 */ #define TGSI_OPCODE_M4X4 TGSI_OPCODE_MULTIPLYMATRIX -#define TGSI_OPCODE_M4X3 124 -#define TGSI_OPCODE_M3X4 125 -#define TGSI_OPCODE_M3X3 126 -#define TGSI_OPCODE_M3X2 127 +#define TGSI_OPCODE_M4X3 108 +#define TGSI_OPCODE_M3X4 109 +#define TGSI_OPCODE_M3X3 110 +#define TGSI_OPCODE_M3X2 111 #define TGSI_OPCODE_CRS TGSI_OPCODE_XPD -#define TGSI_OPCODE_NRM4 128 +#define TGSI_OPCODE_NRM4 112 #define TGSI_OPCODE_SINCOS TGSI_OPCODE_SCS #define TGSI_OPCODE_TEXLDB TGSI_OPCODE_TXB #define TGSI_OPCODE_DP2ADD TGSI_OPCODE_DP2A @@ -395,10 +376,10 @@ struct tgsi_immediate_float32 * ps_2_x */ #define TGSI_OPCODE_CALL TGSI_OPCODE_CAL -#define TGSI_OPCODE_CALLNZ 129 -#define TGSI_OPCODE_IFC 130 +#define TGSI_OPCODE_CALLNZ 113 +#define TGSI_OPCODE_IFC 114 #define TGSI_OPCODE_BREAK TGSI_OPCODE_BRK -#define TGSI_OPCODE_BREAKC 131 +#define TGSI_OPCODE_BREAKC 115 #define TGSI_OPCODE_DSX TGSI_OPCODE_DDX #define TGSI_OPCODE_DSY TGSI_OPCODE_DDY #define TGSI_OPCODE_TEXLDD TGSI_OPCODE_TXD @@ -419,10 +400,10 @@ struct tgsi_immediate_float32 * vs_2_x */ -#define TGSI_OPCODE_KIL 132 /* unpredicated kill */ -#define TGSI_OPCODE_END 133 /* aka HALT */ +#define TGSI_OPCODE_KIL 116 /* unpredicated kill */ +#define TGSI_OPCODE_END 117 /* aka HALT */ -#define TGSI_OPCODE_LAST 135 +#define TGSI_OPCODE_LAST 118 #define TGSI_SAT_NONE 0 /* do not saturate */ #define TGSI_SAT_ZERO_ONE 1 /* clamp to [0,1] */ diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index e338a27383..5791a10119 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -110,6 +110,7 @@ struct pipe_rasterizer_state unsigned line_stipple_pattern:16; unsigned line_last_pixel:1; unsigned bypass_clipping:1; + unsigned bypass_vs:1; /**< vertices are already fully transformed */ unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */ float line_width; @@ -162,13 +163,6 @@ struct pipe_constant_buffer struct pipe_shader_state { const struct tgsi_token *tokens; - /* XXX these are going away */ - ubyte num_inputs; - ubyte num_outputs; - ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; /**< TGSI_SEMANTIC_x */ - ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS]; - ubyte output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; /**< TGSI_SEMANTIC_x */ - ubyte output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; }; diff --git a/src/gallium/winsys/Makefile b/src/gallium/winsys/Makefile index 3dc5ea5744..2360a6a94a 100644 --- a/src/gallium/winsys/Makefile +++ b/src/gallium/winsys/Makefile @@ -18,3 +18,7 @@ subdirs: clean: rm -f `find . -name \*.[oa]` + + +# Dummy install target +install: diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c index 04ece4cda8..f648d081c0 100644 --- a/src/mesa/main/ffvertex_prog.c +++ b/src/mesa/main/ffvertex_prog.c @@ -1398,12 +1398,13 @@ static void build_pointsize( struct tnl_program *p ) /* 1 / sqrt(factor) */ emit_op1(p, OPCODE_RSQ, ut, WRITEMASK_X, ut ); -#if 1 +#if 0 /* out = pointSize / sqrt(factor) */ emit_op2(p, OPCODE_MUL, out, WRITEMASK_X, ut, state_size); #else - /* not sure, might make sense to do clamping here, - but it's not done in t_vb_points neither */ + /* this is a good place to clamp the point size since there's likely + * no hardware registers to clamp point size at rasterization time. + */ emit_op2(p, OPCODE_MUL, ut, WRITEMASK_X, ut, state_size); emit_op2(p, OPCODE_MAX, ut, WRITEMASK_X, ut, swizzle1(state_size, Y)); emit_op2(p, OPCODE_MIN, out, WRITEMASK_X, ut, swizzle1(state_size, Z)); diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 767ba3ffb4..0de2b0a57e 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -1087,7 +1087,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, slang_operation_copy(inlined, fun->body); /*** XXX review this */ - assert(inlined->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE); + assert(inlined->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE); inlined->type = SLANG_OPER_BLOCK_NEW_SCOPE; #if 0 diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 2b08e7020f..382b13ff05 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -677,6 +677,7 @@ static struct prog_instruction * emit_clamp(slang_emit_info *emitInfo, slang_ir_node *n) { struct prog_instruction *inst; + slang_ir_node tmpNode; assert(n->Opcode == IR_CLAMP); /* ch[0] = value @@ -722,18 +723,27 @@ emit_clamp(slang_emit_info *emitInfo, slang_ir_node *n) emit(emitInfo, n->Children[1]); emit(emitInfo, n->Children[2]); + /* Some GPUs don't allow reading from output registers. So if the + * dest for this clamp() is an output reg, we can't use that reg for + * the intermediate result. Use a temp register instead. + */ + _mesa_bzero(&tmpNode, sizeof(tmpNode)); + alloc_temp_storage(emitInfo, &tmpNode, n->Store->Size); + /* tmp = max(ch[0], ch[1]) */ inst = new_instruction(emitInfo, OPCODE_MAX); - storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); + storage_to_dst_reg(&inst->DstReg, tmpNode.Store, n->Writemask); storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Store); - /* tmp = min(tmp, ch[2]) */ + /* n->dest = min(tmp, ch[2]) */ inst = new_instruction(emitInfo, OPCODE_MIN); storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); - storage_to_src_reg(&inst->SrcReg[0], n->Store); + storage_to_src_reg(&inst->SrcReg[0], tmpNode.Store); storage_to_src_reg(&inst->SrcReg[1], n->Children[2]->Store); + free_temp_storage(emitInfo->vt, &tmpNode); + return inst; } diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c index 77cef9236b..17d77f90ae 100644 --- a/src/mesa/state_tracker/st_atom_rasterizer.c +++ b/src/mesa/state_tracker/st_atom_rasterizer.c @@ -223,7 +223,12 @@ static void update_raster_state( struct st_context *st ) raster->point_size_per_vertex = ctx->VertexProgram.PointSizeEnabled; } } - + if (!raster->point_size_per_vertex) { + /* clamp size now */ + raster->point_size = CLAMP(ctx->Point.Size, + ctx->Point.MinSize, + ctx->Point.MaxSize); + } /* _NEW_LINE */ diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index cc8a136292..5865071439 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -52,7 +52,8 @@ #include "cso_cache/cso_context.h" - +/* XXX for testing draw module vertex passthrough: */ +#define TEST_DRAW_PASSTHROUGH 0 static GLuint @@ -229,6 +230,12 @@ draw_quad(GLcontext *ctx, GLfloat verts[4][2][4]; /* four verts, two attribs, XYZW */ GLuint i; +#if TEST_DRAW_PASSTHROUGH + /* invert Y coords (may be off by one pixel) */ + y0 = ctx->DrawBuffer->Height - y0; + y1 = ctx->DrawBuffer->Height - y1; +#endif + /* positions */ verts[0][0][0] = x0; verts[0][0][1] = y0; @@ -252,7 +259,13 @@ draw_quad(GLcontext *ctx, verts[i][1][3] = color[3]; } - st_draw_vertices(ctx, PIPE_PRIM_QUADS, 4, (float *) verts, 2, GL_FALSE); + st_draw_vertices(ctx, PIPE_PRIM_POLYGON, 4, (float *) verts, 2, +#if TEST_DRAW_PASSTHROUGH + GL_TRUE +#else + GL_FALSE +#endif + ); } @@ -336,6 +349,10 @@ clear_with_quad(GLcontext *ctx, if (ctx->Scissor.Enabled) raster.scissor = 1; #endif +#if TEST_DRAW_PASSTHROUGH + raster.bypass_clipping = 1; + raster.bypass_vs = 1; +#endif cso_set_rasterizer(st->cso_context, &raster); } @@ -348,6 +365,7 @@ clear_with_quad(GLcontext *ctx, pipe->bind_fs_state(pipe, stfp->driver_shader); } +#if !TEST_DRAW_PASSTHROUGH /* vertex shader state: color/position pass-through */ { static struct st_vertex_program *stvp = NULL; @@ -356,7 +374,9 @@ clear_with_quad(GLcontext *ctx, } pipe->bind_vs_state(pipe, stvp->driver_shader); } +#endif +#if !TEST_DRAW_PASSTHROUGH /* viewport state: viewport matching window dims */ { const float width = ctx->DrawBuffer->Width; @@ -372,6 +392,7 @@ clear_with_quad(GLcontext *ctx, vp.translate[3] = 0.0; pipe->set_viewport_state(pipe, &vp); } +#endif /* draw quad matching scissor rect (XXX verify coord round-off) */ draw_quad(ctx, x0, y0, x1, y1, ctx->Depth.Clear, ctx->Color.ClearColor); diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c index 4dc76f19b1..0a62e20e0c 100644 --- a/src/mesa/state_tracker/st_cb_program.c +++ b/src/mesa/state_tracker/st_cb_program.c @@ -178,6 +178,11 @@ static void st_program_string_notify( GLcontext *ctx, stfp->param_state = stfp->Base.Base.Parameters->StateFlags; + if (stfp->state.tokens) { + FREE((void *) stfp->state.tokens); + stfp->state.tokens = NULL; + } + if (st->fp == stfp) st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM; } @@ -201,6 +206,11 @@ static void st_program_string_notify( GLcontext *ctx, stvp->param_state = stvp->Base.Base.Parameters->StateFlags; + if (stvp->state.tokens) { + FREE((void *) stvp->state.tokens); + stvp->state.tokens = NULL; + } + if (st->vp == stvp) st->dirty.st |= ST_NEW_VERTEX_PROGRAM; } diff --git a/src/mesa/state_tracker/st_debug.c b/src/mesa/state_tracker/st_debug.c index 9c13010da8..8b9b91aa34 100644 --- a/src/mesa/state_tracker/st_debug.c +++ b/src/mesa/state_tracker/st_debug.c @@ -52,10 +52,12 @@ st_print_current(void) struct st_context *st = ctx->st; int i; +#if 0 printf("Vertex Transform Inputs:\n"); for (i = 0; i < st->vp->state.num_inputs; i++) { printf(" Slot %d: VERT_ATTRIB_%d\n", i, st->vp->index_to_input[i]); } +#endif tgsi_dump( st->vp->state.tokens, 0 ); if (st->vp->Base.Base.Parameters) diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 98504e46c1..5ebd0bbcce 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -223,7 +223,7 @@ st_draw_vbo(GLcontext *ctx, /* loop over TGSI shader inputs to determine vertex buffer * and attribute info */ - for (attr = 0; attr < vs->num_inputs; attr++) { + for (attr = 0; attr < /*vs*/vp->num_inputs; attr++) { const GLuint mesaAttr = vp->index_to_input[attr]; struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj; struct pipe_vertex_element velement; @@ -333,7 +333,7 @@ st_draw_vbo(GLcontext *ctx, } /* unreference buffers (frees wrapped user-space buffer objects) */ - for (attr = 0; attr < vs->num_inputs; attr++) { + for (attr = 0; attr < /*vs*/vp->num_inputs; attr++) { pipe_buffer_reference(winsys, &vbuffer[attr].buffer, NULL); assert(!vbuffer[attr].buffer); pipe->set_vertex_buffer(pipe, attr, &vbuffer[attr]); @@ -502,7 +502,7 @@ st_feedback_draw_vbo(GLcontext *ctx, /* loop over TGSI shader inputs to determine vertex buffer * and attribute info */ - for (attr = 0; attr < vs->num_inputs; attr++) { + for (attr = 0; attr < /*vs*/vp->num_inputs; attr++) { const GLuint mesaAttr = vp->index_to_input[attr]; struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj; struct pipe_vertex_element velement; diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 0f8784e132..d9d11ee0e8 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -85,6 +85,14 @@ st_translate_vertex_program(struct st_context *st, GLuint num_generic = 0; GLuint num_tokens; + ubyte vs_input_semantic_name[PIPE_MAX_SHADER_INPUTS]; + ubyte vs_input_semantic_index[PIPE_MAX_SHADER_INPUTS]; + uint vs_num_inputs = 0; + + ubyte vs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; + ubyte vs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; + uint vs_num_outputs = 0; + memset(&vs, 0, sizeof(vs)); /* @@ -93,36 +101,36 @@ st_translate_vertex_program(struct st_context *st, */ for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) { if (stvp->Base.Base.InputsRead & (1 << attr)) { - const GLuint slot = vs.num_inputs; + const GLuint slot = vs_num_inputs; - vs.num_inputs++; + vs_num_inputs++; stvp->input_to_index[attr] = slot; stvp->index_to_input[slot] = attr; switch (attr) { case VERT_ATTRIB_POS: - vs.input_semantic_name[slot] = TGSI_SEMANTIC_POSITION; - vs.input_semantic_index[slot] = 0; + vs_input_semantic_name[slot] = TGSI_SEMANTIC_POSITION; + vs_input_semantic_index[slot] = 0; break; case VERT_ATTRIB_WEIGHT: /* fall-through */ case VERT_ATTRIB_NORMAL: /* just label as a generic */ - vs.input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - vs.input_semantic_index[slot] = 0; + vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; + vs_input_semantic_index[slot] = 0; break; case VERT_ATTRIB_COLOR0: - vs.input_semantic_name[slot] = TGSI_SEMANTIC_COLOR; - vs.input_semantic_index[slot] = 0; + vs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR; + vs_input_semantic_index[slot] = 0; break; case VERT_ATTRIB_COLOR1: - vs.input_semantic_name[slot] = TGSI_SEMANTIC_COLOR; - vs.input_semantic_index[slot] = 1; + vs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR; + vs_input_semantic_index[slot] = 1; break; case VERT_ATTRIB_FOG: - vs.input_semantic_name[slot] = TGSI_SEMANTIC_FOG; - vs.input_semantic_index[slot] = 0; + vs_input_semantic_name[slot] = TGSI_SEMANTIC_FOG; + vs_input_semantic_index[slot] = 0; break; case VERT_ATTRIB_TEX0: case VERT_ATTRIB_TEX1: @@ -132,8 +140,8 @@ st_translate_vertex_program(struct st_context *st, case VERT_ATTRIB_TEX5: case VERT_ATTRIB_TEX6: case VERT_ATTRIB_TEX7: - vs.input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - vs.input_semantic_index[slot] = num_generic++; + vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; + vs_input_semantic_index[slot] = num_generic++; break; case VERT_ATTRIB_GENERIC0: case VERT_ATTRIB_GENERIC1: @@ -144,8 +152,8 @@ st_translate_vertex_program(struct st_context *st, case VERT_ATTRIB_GENERIC6: case VERT_ATTRIB_GENERIC7: assert(attr < VERT_ATTRIB_MAX); - vs.input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - vs.input_semantic_index[slot] = num_generic++; + vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; + vs_input_semantic_index[slot] = num_generic++; break; default: assert(0); @@ -155,8 +163,8 @@ st_translate_vertex_program(struct st_context *st, /* initialize output semantics to defaults */ for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) { - vs.output_semantic_name[i] = TGSI_SEMANTIC_GENERIC; - vs.output_semantic_index[i] = 0; + vs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC; + vs_output_semantic_index[i] = 0; } num_generic = 0; @@ -173,8 +181,8 @@ st_translate_vertex_program(struct st_context *st, assert(slot != ~0); } else { - slot = vs.num_outputs; - vs.num_outputs++; + slot = vs_num_outputs; + vs_num_outputs++; defaultOutputMapping[attr] = slot; } @@ -185,32 +193,32 @@ st_translate_vertex_program(struct st_context *st, switch (attr) { case VERT_RESULT_HPOS: assert(slot == 0); - vs.output_semantic_name[slot] = TGSI_SEMANTIC_POSITION; - vs.output_semantic_index[slot] = 0; + vs_output_semantic_name[slot] = TGSI_SEMANTIC_POSITION; + vs_output_semantic_index[slot] = 0; break; case VERT_RESULT_COL0: - vs.output_semantic_name[slot] = TGSI_SEMANTIC_COLOR; - vs.output_semantic_index[slot] = 0; + vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR; + vs_output_semantic_index[slot] = 0; break; case VERT_RESULT_COL1: - vs.output_semantic_name[slot] = TGSI_SEMANTIC_COLOR; - vs.output_semantic_index[slot] = 1; + vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR; + vs_output_semantic_index[slot] = 1; break; case VERT_RESULT_BFC0: - vs.output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR; - vs.output_semantic_index[slot] = 0; + vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR; + vs_output_semantic_index[slot] = 0; break; case VERT_RESULT_BFC1: - vs.output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR; - vs.output_semantic_index[slot] = 1; + vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR; + vs_output_semantic_index[slot] = 1; break; case VERT_RESULT_FOGC: - vs.output_semantic_name[slot] = TGSI_SEMANTIC_FOG; - vs.output_semantic_index[slot] = 0; + vs_output_semantic_name[slot] = TGSI_SEMANTIC_FOG; + vs_output_semantic_index[slot] = 0; break; case VERT_RESULT_PSIZ: - vs.output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE; - vs.output_semantic_index[slot] = 0; + vs_output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE; + vs_output_semantic_index[slot] = 0; break; case VERT_RESULT_EDGE: assert(0); @@ -223,30 +231,30 @@ st_translate_vertex_program(struct st_context *st, case VERT_RESULT_TEX5: case VERT_RESULT_TEX6: case VERT_RESULT_TEX7: - vs.output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - vs.output_semantic_index[slot] = num_generic++; + vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; + vs_output_semantic_index[slot] = num_generic++; break; case VERT_RESULT_VAR0: /* fall-through */ default: assert(attr - VERT_RESULT_VAR0 < MAX_VARYING); - vs.output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - vs.output_semantic_index[slot] = num_generic++; + vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; + vs_output_semantic_index[slot] = num_generic++; } } } - assert(vs.output_semantic_name[0] == TGSI_SEMANTIC_POSITION); + assert(vs_output_semantic_name[0] == TGSI_SEMANTIC_POSITION); if (outputMapping) { - /* find max output slot referenced to compute vs.num_outputs */ + /* find max output slot referenced to compute vs_num_outputs */ GLuint maxSlot = 0; for (attr = 0; attr < VERT_RESULT_MAX; attr++) { if (outputMapping[attr] != ~0 && outputMapping[attr] > maxSlot) maxSlot = outputMapping[attr]; } - vs.num_outputs = maxSlot + 1; + vs_num_outputs = maxSlot + 1; } else { outputMapping = defaultOutputMapping; @@ -257,22 +265,23 @@ st_translate_vertex_program(struct st_context *st, num_tokens = tgsi_translate_mesa_program( TGSI_PROCESSOR_VERTEX, &stvp->Base.Base, /* inputs */ - vs.num_inputs, + vs_num_inputs, stvp->input_to_index, - vs.input_semantic_name, - vs.input_semantic_index, + vs_input_semantic_name, + vs_input_semantic_index, NULL, /* outputs */ - vs.num_outputs, + vs_num_outputs, outputMapping, - vs.output_semantic_name, - vs.output_semantic_index, + vs_output_semantic_name, + vs_output_semantic_index, /* tokenized result */ tokens, ST_MAX_SHADER_TOKENS); vs.tokens = (struct tgsi_token *) mem_dup(tokens, num_tokens * sizeof(tokens[0])); + stvp->num_inputs = vs_num_inputs; stvp->state = vs; /* struct copy */ stvp->driver_shader = pipe->create_vs_state(pipe, &vs); @@ -310,6 +319,14 @@ st_translate_fragment_program(struct st_context *st, GLuint num_generic = 0; GLuint num_tokens; + ubyte fs_input_semantic_name[PIPE_MAX_SHADER_INPUTS]; + ubyte fs_input_semantic_index[PIPE_MAX_SHADER_INPUTS]; + uint fs_num_inputs = 0; + + ubyte fs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; + ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; + uint fs_num_outputs = 0; + memset(&fs, 0, sizeof(fs)); /* which vertex output goes to the first fragment input: */ @@ -323,33 +340,33 @@ st_translate_fragment_program(struct st_context *st, */ for (attr = 0; attr < FRAG_ATTRIB_MAX; attr++) { if (inputsRead & (1 << attr)) { - const GLuint slot = fs.num_inputs; + const GLuint slot = fs_num_inputs; defaultInputMapping[attr] = slot; stfp->input_map[slot] = vslot++; - fs.num_inputs++; + fs_num_inputs++; switch (attr) { case FRAG_ATTRIB_WPOS: - fs.input_semantic_name[slot] = TGSI_SEMANTIC_POSITION; - fs.input_semantic_index[slot] = 0; + fs_input_semantic_name[slot] = TGSI_SEMANTIC_POSITION; + fs_input_semantic_index[slot] = 0; interpMode[slot] = TGSI_INTERPOLATE_LINEAR; break; case FRAG_ATTRIB_COL0: - fs.input_semantic_name[slot] = TGSI_SEMANTIC_COLOR; - fs.input_semantic_index[slot] = 0; + fs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR; + fs_input_semantic_index[slot] = 0; interpMode[slot] = TGSI_INTERPOLATE_LINEAR; break; case FRAG_ATTRIB_COL1: - fs.input_semantic_name[slot] = TGSI_SEMANTIC_COLOR; - fs.input_semantic_index[slot] = 1; + fs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR; + fs_input_semantic_index[slot] = 1; interpMode[slot] = TGSI_INTERPOLATE_LINEAR; break; case FRAG_ATTRIB_FOGC: - fs.input_semantic_name[slot] = TGSI_SEMANTIC_FOG; - fs.input_semantic_index[slot] = 0; + fs_input_semantic_name[slot] = TGSI_SEMANTIC_FOG; + fs_input_semantic_index[slot] = 0; interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE; break; case FRAG_ATTRIB_TEX0: @@ -360,15 +377,15 @@ st_translate_fragment_program(struct st_context *st, case FRAG_ATTRIB_TEX5: case FRAG_ATTRIB_TEX6: case FRAG_ATTRIB_TEX7: - fs.input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - fs.input_semantic_index[slot] = num_generic++; + fs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; + fs_input_semantic_index[slot] = num_generic++; interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE; break; case FRAG_ATTRIB_VAR0: /* fall-through */ default: - fs.input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - fs.input_semantic_index[slot] = num_generic++; + fs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; + fs_input_semantic_index[slot] = num_generic++; interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE; } } @@ -383,10 +400,10 @@ st_translate_fragment_program(struct st_context *st, /* if z is written, emit that first */ if (outputsWritten & (1 << FRAG_RESULT_DEPR)) { - fs.output_semantic_name[fs.num_outputs] = TGSI_SEMANTIC_POSITION; - fs.output_semantic_index[fs.num_outputs] = 0; - outputMapping[FRAG_RESULT_DEPR] = fs.num_outputs; - fs.num_outputs++; + fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_POSITION; + fs_output_semantic_index[fs_num_outputs] = 0; + outputMapping[FRAG_RESULT_DEPR] = fs_num_outputs; + fs_num_outputs++; outputsWritten &= ~(1 << FRAG_RESULT_DEPR); } @@ -399,15 +416,15 @@ st_translate_fragment_program(struct st_context *st, assert(0); break; case FRAG_RESULT_COLR: - fs.output_semantic_name[fs.num_outputs] = TGSI_SEMANTIC_COLOR; - fs.output_semantic_index[fs.num_outputs] = numColors; - outputMapping[attr] = fs.num_outputs; + fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_COLOR; + fs_output_semantic_index[fs_num_outputs] = numColors; + outputMapping[attr] = fs_num_outputs; numColors++; break; default: assert(0); } - fs.num_outputs++; + fs_num_outputs++; } } } @@ -420,16 +437,16 @@ st_translate_fragment_program(struct st_context *st, num_tokens = tgsi_translate_mesa_program( TGSI_PROCESSOR_FRAGMENT, &stfp->Base.Base, /* inputs */ - fs.num_inputs, + fs_num_inputs, inputMapping, - fs.input_semantic_name, - fs.input_semantic_index, + fs_input_semantic_name, + fs_input_semantic_index, interpMode, /* outputs */ - fs.num_outputs, + fs_num_outputs, outputMapping, - fs.output_semantic_name, - fs.output_semantic_index, + fs_output_semantic_name, + fs_output_semantic_index, /* tokenized result */ tokens, ST_MAX_SHADER_TOKENS); diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index 78786dcbb6..9ef2a07eaa 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -85,6 +85,8 @@ struct st_vertex_program /** maps a TGSI input index back to a Mesa VERT_ATTRIB_x */ GLuint index_to_input[PIPE_MAX_SHADER_INPUTS]; + GLuint num_inputs; + struct pipe_shader_state state; struct pipe_shader_state *driver_shader; diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index 35dc0e768f..b7f4d8a307 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -309,23 +309,16 @@ static void vbo_exec_fixup_vertex( GLcontext *ctx, GLuint attr, GLuint sz ) { struct vbo_exec_context *exec = &vbo_context(ctx)->exec; - static const GLfloat id[4] = { 0, 0, 0, 1 }; int i; - if (exec->vtx.prim_count == 0) { - GLfloat *current = (GLfloat *)vbo_context(ctx)->currval[attr].Ptr; - exec->vtx.attrptr[attr] = current; - memcpy(current, id, sizeof(id)); - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; - return; - } - else if (sz > exec->vtx.attrsz[attr]) { + if (sz > exec->vtx.attrsz[attr]) { /* New size is larger. Need to flush existing vertices and get * an enlarged vertex format. */ vbo_exec_wrap_upgrade_vertex( exec, attr, sz ); } else if (sz < exec->vtx.active_sz[attr]) { + static const GLfloat id[4] = { 0, 0, 0, 1 }; /* New size is smaller - just need to fill in some * zeros. Don't need to flush or wrap. |