From 102bf6e2a70f565f03d5e9c4995b29d61c0aa165 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 23 Sep 2011 19:55:47 +0100 Subject: [PATCH] draw: Never allocate duplicate extra vertex attribs. Prevents mismatches when the VS outputs generic attributes not used by the FS. Reviewed-by: Brian Paul --- src/gallium/auxiliary/draw/draw_context.c | 50 ++++++++++++------- src/gallium/auxiliary/draw/draw_context.h | 3 ++ src/gallium/auxiliary/draw/draw_pipe_aaline.c | 8 +-- .../auxiliary/draw/draw_pipe_aapoint.c | 21 ++++---- .../auxiliary/draw/draw_pipe_wide_point.c | 18 ++----- 5 files changed, 54 insertions(+), 46 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index b8f8623ee5d..6a85b79a02c 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -450,7 +450,9 @@ draw_set_force_passthrough( struct draw_context *draw, boolean enable ) /** - * Allocate an extra vertex/geometry shader vertex attribute. + * Allocate an extra vertex/geometry shader vertex attribute, if it doesn't + * exist already. + * * This is used by some of the optional draw module stages such * as wide_point which may need to allocate additional generic/texcoord * attributes. @@ -459,8 +461,17 @@ int draw_alloc_extra_vertex_attrib(struct draw_context *draw, uint semantic_name, uint semantic_index) { - const int num_outputs = draw_current_shader_outputs(draw); - const int n = draw->extra_shader_outputs.num; + int slot; + uint num_outputs; + uint n; + + slot = draw_find_shader_output(draw, semantic_name, semantic_index); + if (slot > 0) { + return slot; + } + + num_outputs = draw_current_shader_outputs(draw); + n = draw->extra_shader_outputs.num; assert(n < Elements(draw->extra_shader_outputs.semantic_name)); @@ -484,6 +495,22 @@ draw_remove_extra_vertex_attribs(struct draw_context *draw) } +/** + * If a geometry shader is present, return its info, else the vertex shader's + * info. + */ +struct tgsi_shader_info * +draw_get_shader_info(const struct draw_context *draw) +{ + + if (draw->gs.geometry_shader) { + return &draw->gs.geometry_shader->info; + } else { + return &draw->vs.vertex_shader->info; + } +} + + /** * Ask the draw module for the location/slot of the given vertex attribute in * a post-transformed vertex. @@ -503,13 +530,8 @@ int draw_find_shader_output(const struct draw_context *draw, uint semantic_name, uint semantic_index) { - const struct draw_vertex_shader *vs = draw->vs.vertex_shader; - const struct draw_geometry_shader *gs = draw->gs.geometry_shader; + const struct tgsi_shader_info *info = draw_get_shader_info(draw); uint i; - const struct tgsi_shader_info *info = &vs->info; - - if (gs) - info = &gs->info; for (i = 0; i < info->num_outputs; i++) { if (info->output_semantic_name[i] == semantic_name && @@ -541,16 +563,10 @@ draw_find_shader_output(const struct draw_context *draw, uint draw_num_shader_outputs(const struct draw_context *draw) { + const struct tgsi_shader_info *info = draw_get_shader_info(draw); uint count; - /* If a geometry shader is present, its outputs go to the - * driver, else the vertex shader's outputs. - */ - if (draw->gs.geometry_shader) - count = draw->gs.geometry_shader->info.num_outputs; - else - count = draw->vs.vertex_shader->info.num_outputs; - + count = info->num_outputs; count += draw->extra_shader_outputs.num; return count; diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 9a7bf361393..799eb94f013 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -96,6 +96,9 @@ boolean draw_install_pstipple_stage(struct draw_context *draw, struct pipe_context *pipe); +struct tgsi_shader_info * +draw_get_shader_info(const struct draw_context *draw); + int draw_find_shader_output(const struct draw_context *draw, uint semantic_name, uint semantic_index); diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index 7ecd2aa3f45..0b368da6747 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -374,7 +374,9 @@ generate_aaline_fs(struct aaline_stage *aaline) newLen, &transform.base); #if 0 /* DEBUG */ + debug_printf("draw_aaline, orig shader:\n"); tgsi_dump(orig_fs->tokens, 0); + debug_printf("draw_aaline, new shader:\n"); tgsi_dump(aaline_fs.tokens, 0); #endif @@ -692,12 +694,12 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) } /* update vertex attrib info */ - aaline->tex_slot = draw_current_shader_outputs(draw); aaline->pos_slot = draw_current_shader_position_output(draw);; /* allocate the extra post-transformed vertex attribute */ - (void) draw_alloc_extra_vertex_attrib(draw, TGSI_SEMANTIC_GENERIC, - aaline->fs->generic_attrib); + aaline->tex_slot = draw_alloc_extra_vertex_attrib(draw, + TGSI_SEMANTIC_GENERIC, + aaline->fs->generic_attrib); /* how many samplers? */ /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index 698ab13cddb..248f26b91fd 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -519,9 +519,9 @@ generate_aapoint_fs(struct aapoint_stage *aapoint) newLen, &transform.base); #if 0 /* DEBUG */ - printf("draw_aapoint, orig shader:\n"); + debug_printf("draw_aapoint, orig shader:\n"); tgsi_dump(orig_fs->tokens, 0); - printf("draw_aapoint, new shader:\n"); + debug_printf("draw_aapoint, new shader:\n"); tgsi_dump(aapoint_fs.tokens, 0); #endif @@ -696,23 +696,22 @@ aapoint_first_point(struct draw_stage *stage, struct prim_header *header) bind_aapoint_fragment_shader(aapoint); /* update vertex attrib info */ - aapoint->tex_slot = draw_current_shader_outputs(draw); - assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */ - aapoint->pos_slot = draw_current_shader_position_output(draw); /* allocate the extra post-transformed vertex attribute */ - (void) draw_alloc_extra_vertex_attrib(draw, TGSI_SEMANTIC_GENERIC, - aapoint->fs->generic_attrib); + aapoint->tex_slot = draw_alloc_extra_vertex_attrib(draw, + TGSI_SEMANTIC_GENERIC, + aapoint->fs->generic_attrib); + assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */ /* find psize slot in post-transform vertex */ aapoint->psize_slot = -1; if (draw->rasterizer->point_size_per_vertex) { - /* find PSIZ vertex output */ - const struct draw_vertex_shader *vs = draw->vs.vertex_shader; + const struct tgsi_shader_info *info = draw_get_shader_info(draw); uint i; - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { + /* find PSIZ vertex output */ + for (i = 0; i < info->num_outputs; i++) { + if (info->output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { aapoint->psize_slot = i; break; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c index 3646c6a7145..0b86ba1e928 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c @@ -245,21 +245,9 @@ widepoint_first_point(struct draw_stage *stage, /* OK, this generic attribute needs to be replaced with a * texcoord (see above). */ - int slot = draw_find_shader_output(draw, - TGSI_SEMANTIC_GENERIC, - generic_index); - - if (slot > 0) { - /* there's already a post-vertex shader attribute - * for this fragment shader input attribute. - */ - } - else { - /* need to allocate a new post-vertex shader attribute */ - slot = draw_alloc_extra_vertex_attrib(draw, - TGSI_SEMANTIC_GENERIC, - generic_index); - } + int slot = draw_alloc_extra_vertex_attrib(draw, + TGSI_SEMANTIC_GENERIC, + generic_index); /* add this slot to the texcoord-gen list */ wide->texcoord_gen_slot[wide->num_texcoord_gen++] = slot; -- 2.30.2