gallium/draw: add limits to the clip and cull distances

There are strict limits on those registers. Define the maximums
and use them instead of magic numbers. Also allows us to add
some extra sanity checks.
Suggested by Brian.

Signed-off-by: Zack Rusin <zackr@vmware.com>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
This commit is contained in:
Zack Rusin
2013-06-10 23:36:59 -04:00
parent b63eeaf7b7
commit 5507c11f85
7 changed files with 41 additions and 14 deletions

View File

@@ -738,6 +738,7 @@ draw_current_shader_clipvertex_output(const struct draw_context *draw)
uint uint
draw_current_shader_clipdistance_output(const struct draw_context *draw, int index) draw_current_shader_clipdistance_output(const struct draw_context *draw, int index)
{ {
debug_assert(index < PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT);
if (draw->gs.geometry_shader) if (draw->gs.geometry_shader)
return draw->gs.geometry_shader->clipdistance_output[index]; return draw->gs.geometry_shader->clipdistance_output[index];
return draw->vs.clipdistance_output[index]; return draw->vs.clipdistance_output[index];
@@ -756,6 +757,7 @@ draw_current_shader_num_written_clipdistances(const struct draw_context *draw)
uint uint
draw_current_shader_culldistance_output(const struct draw_context *draw, int index) draw_current_shader_culldistance_output(const struct draw_context *draw, int index)
{ {
debug_assert(index < PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT);
if (draw->gs.geometry_shader) if (draw->gs.geometry_shader)
return draw->gs.geometry_shader->culldistance_output[index]; return draw->gs.geometry_shader->culldistance_output[index];
return draw->vs.vertex_shader->culldistance_output[index]; return draw->vs.vertex_shader->culldistance_output[index];

View File

@@ -792,13 +792,13 @@ draw_create_geometry_shader(struct draw_context *draw,
if (gs->info.output_semantic_name[i] == TGSI_SEMANTIC_VIEWPORT_INDEX) if (gs->info.output_semantic_name[i] == TGSI_SEMANTIC_VIEWPORT_INDEX)
gs->viewport_index_output = i; gs->viewport_index_output = i;
if (gs->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPDIST) { if (gs->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPDIST) {
if (gs->info.output_semantic_index[i] == 0) debug_assert(gs->info.output_semantic_index[i] <
gs->clipdistance_output[0] = i; PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT);
else gs->clipdistance_output[gs->info.output_semantic_index[i]] = i;
gs->clipdistance_output[1] = i;
} }
if (gs->info.output_semantic_name[i] == TGSI_SEMANTIC_CULLDIST) { if (gs->info.output_semantic_name[i] == TGSI_SEMANTIC_CULLDIST) {
debug_assert(gs->info.output_semantic_index[i] < Elements(gs->culldistance_output)); debug_assert(gs->info.output_semantic_index[i] <
PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT);
gs->culldistance_output[gs->info.output_semantic_index[i]] = i; gs->culldistance_output[gs->info.output_semantic_index[i]] = i;
} }
} }

View File

@@ -67,8 +67,8 @@ struct draw_geometry_shader {
struct tgsi_shader_info info; struct tgsi_shader_info info;
unsigned position_output; unsigned position_output;
unsigned viewport_index_output; unsigned viewport_index_output;
unsigned clipdistance_output[2]; unsigned clipdistance_output[PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT];
unsigned culldistance_output[2]; unsigned culldistance_output[PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT];
unsigned max_output_vertices; unsigned max_output_vertices;
unsigned primitive_boundary; unsigned primitive_boundary;

View File

@@ -86,12 +86,12 @@ draw_create_vertex_shader(struct draw_context *draw,
found_clipvertex = TRUE; found_clipvertex = TRUE;
vs->clipvertex_output = i; vs->clipvertex_output = i;
} else if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPDIST) { } else if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPDIST) {
if (vs->info.output_semantic_index[i] == 0) debug_assert(vs->info.output_semantic_index[i] <
vs->clipdistance_output[0] = i; PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT);
else vs->clipdistance_output[vs->info.output_semantic_index[i]] = i;
vs->clipdistance_output[1] = i;
} else if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_CULLDIST) { } else if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_CULLDIST) {
debug_assert(vs->info.output_semantic_index[i] < Elements(vs->culldistance_output)); debug_assert(vs->info.output_semantic_index[i] <
PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT);
vs->culldistance_output[vs->info.output_semantic_index[i]] = i; vs->culldistance_output[vs->info.output_semantic_index[i]] = i;
} }
} }

View File

@@ -112,8 +112,8 @@ struct draw_vertex_shader {
unsigned position_output; unsigned position_output;
unsigned edgeflag_output; unsigned edgeflag_output;
unsigned clipvertex_output; unsigned clipvertex_output;
unsigned clipdistance_output[2]; unsigned clipdistance_output[PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT];
unsigned culldistance_output[2]; unsigned culldistance_output[PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT];
/* Extracted from shader: /* Extracted from shader:
*/ */
const float (*immediates)[4]; const float (*immediates)[4];

View File

@@ -2435,6 +2435,29 @@ float32 signed distance to a plane. Primitives will be completely
discarded if the plane distance for all of the vertices in the discarded if the plane distance for all of the vertices in the
primitive are < 0. If a vertex has a cull distance of NaN, that primitive are < 0. If a vertex has a cull distance of NaN, that
vertex counts as "out" (as if its < 0); vertex counts as "out" (as if its < 0);
The limits on both clip and cull distances are bound
by the PIPE_MAX_CLIP_OR_CULL_DISTANCE_COUNT define which defines
the maximum number of components that can be used to hold the
distances and by the PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT
which specifies the maximum number of registers which can be
annotated with those semantics.
TGSI_SEMANTIC_CLIPDIST
""""""""""""""""""""""
When components of vertex elements are identified this way, these
values are each assumed to be a float32 signed distance to a plane.
Primitive setup only invokes rasterization on pixels for which
the interpolated plane distances are >= 0. Multiple clip planes
can be implemented simultaneously, by annotating multiple
components of one or more vertex elements with the above specified
semantic. The limits on both clip and cull distances are bound
by the PIPE_MAX_CLIP_OR_CULL_DISTANCE_COUNT define which defines
the maximum number of components that can be used to hold the
distances and by the PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT
which specifies the maximum number of registers which can be
annotated with those semantics.
Declaration Interpolate Declaration Interpolate

View File

@@ -66,6 +66,8 @@ extern "C" {
#define PIPE_MAX_SO_BUFFERS 4 #define PIPE_MAX_SO_BUFFERS 4
#define PIPE_MAX_SO_OUTPUTS 64 #define PIPE_MAX_SO_OUTPUTS 64
#define PIPE_MAX_VIEWPORTS 16 #define PIPE_MAX_VIEWPORTS 16
#define PIPE_MAX_CLIP_OR_CULL_DISTANCE_COUNT 8
#define PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT 2
struct pipe_reference struct pipe_reference