Skip to content

Commit

Permalink
draw: account for separate shader objects in geometry shader code
Browse files Browse the repository at this point in the history
The geometry shader code seems to have been originally written with the
assumptions that there are the same number of VS outputs as GS outputs and
that VS outputs are in the same order as their corresponding GS inputs. Since
TGSI uses separate shader objects, these are both wrong assumptions. This
was causing several valid vertex/geometry shader combinations to either render
incorrectly or trigger an assertion.
  • Loading branch information
Plombo committed Aug 21, 2012
1 parent 50fa989 commit bae89df
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 4 deletions.
31 changes: 27 additions & 4 deletions src/gallium/auxiliary/draw/draw_gs.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,22 @@ void draw_delete_geometry_shader(struct draw_context *draw,
FREE(dgs);
}

static INLINE int
draw_gs_get_input_index(int semantic, int index,
const struct tgsi_shader_info *input_info)
{
int i;
const ubyte *input_semantic_names = input_info->output_semantic_name;
const ubyte *input_semantic_indices = input_info->output_semantic_index;
for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
if (input_semantic_names[i] == semantic &&
input_semantic_indices[i] == index)
return i;
}
debug_assert(0);
return -1;
}

/*#define DEBUG_OUTPUTS 1*/
static INLINE void
draw_geometry_fetch_outputs(struct draw_geometry_shader *shader,
Expand Down Expand Up @@ -239,6 +255,10 @@ static void draw_fetch_gs_input(struct draw_geometry_shader *shader,
machine->Inputs[idx].xyzw[3].f[prim_idx] =
(float)shader->in_prim_idx;
} else {
vs_slot = draw_gs_get_input_index(
shader->info.input_semantic_name[slot],
shader->info.input_semantic_index[slot],
shader->input_info);
#if DEBUG_INPUTS
debug_printf("\tSlot = %d, vs_slot = %d, idx = %d:\n",
slot, vs_slot, idx);
Expand Down Expand Up @@ -392,12 +412,14 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS],
const struct draw_vertex_info *input_verts,
const struct draw_prim_info *input_prim,
const struct tgsi_shader_info *input_info,
struct draw_vertex_info *output_verts,
struct draw_prim_info *output_prims )
{
const float (*input)[4] = (const float (*)[4])input_verts->verts->data;
unsigned input_stride = input_verts->vertex_size;
unsigned vertex_size = input_verts->vertex_size;
unsigned num_outputs = shader->info.num_outputs;
unsigned vertex_size = sizeof(struct vertex_header) + num_outputs * 4 * sizeof(float);
struct tgsi_exec_machine *machine = shader->machine;
unsigned num_input_verts = input_prim->linear ?
input_verts->count :
Expand All @@ -409,11 +431,11 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
shader->max_output_vertices)
* num_in_primitives;

output_verts->vertex_size = input_verts->vertex_size;
output_verts->stride = input_verts->vertex_size;
output_verts->vertex_size = vertex_size;
output_verts->stride = output_verts->vertex_size;
output_verts->verts =
(struct vertex_header *)MALLOC(sizeof(struct vertex_header) +
input_verts->vertex_size *
output_verts->vertex_size *
num_in_primitives *
shader->max_output_vertices);

Expand All @@ -436,6 +458,7 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
shader->in_prim_idx = 0;
shader->input_vertex_stride = input_stride;
shader->input = input;
shader->input_info = input_info;
if (shader->primitive_lengths) {
FREE(shader->primitive_lengths);
}
Expand Down
2 changes: 2 additions & 0 deletions src/gallium/auxiliary/draw/draw_gs.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ struct draw_geometry_shader {
unsigned in_prim_idx;
unsigned input_vertex_stride;
const float (*input)[4];
const struct tgsi_shader_info *input_info;
};

/*
Expand All @@ -76,6 +77,7 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS],
const struct draw_vertex_info *input_verts,
const struct draw_prim_info *input_prim,
const struct tgsi_shader_info *input_info,
struct draw_vertex_info *output_verts,
struct draw_prim_info *output_prims );

Expand Down
1 change: 1 addition & 0 deletions src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle,
draw->pt.user.gs_constants_size,
vert_info,
prim_info,
&vshader->info,
&gs_vert_info,
&gs_prim_info);

Expand Down

0 comments on commit bae89df

Please sign in to comment.