draw: Never allocate duplicate extra vertex attribs.
Prevents mismatches when the VS outputs generic attributes not used by the FS. Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user