diff options
author | Jason Ekstrand <jason.ekstrand@intel.com> | 2015-12-27 23:23:05 -0800 |
---|---|---|
committer | Jason Ekstrand <jason.ekstrand@intel.com> | 2015-12-27 23:23:05 -0800 |
commit | ea77b384e8c575922eca1c05398e19fcbfda9b09 (patch) | |
tree | 4f8659bd8b48af785896daa224f6698a5ee269ec /src/gallium/auxiliary/draw/draw_pipe_clip.c | |
parent | f948767471ba83427cbcdc244a511fbb954ca9e0 (diff) | |
parent | 109c348284843054f708f4403260739b7db18275 (diff) | |
download | external_mesa3d-ea77b384e8c575922eca1c05398e19fcbfda9b09.zip external_mesa3d-ea77b384e8c575922eca1c05398e19fcbfda9b09.tar.gz external_mesa3d-ea77b384e8c575922eca1c05398e19fcbfda9b09.tar.bz2 |
Merge remote-tracking branch 'mesa-public/master' into vulkan
This pulls in tessellation and the store_var changes that go with it.
Diffstat (limited to 'src/gallium/auxiliary/draw/draw_pipe_clip.c')
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pipe_clip.c | 100 |
1 files changed, 71 insertions, 29 deletions
diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c index 47765cd..67d8eca 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_clip.c +++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c @@ -59,6 +59,8 @@ struct clip_stage { struct draw_stage stage; /**< base class */ unsigned pos_attr; + boolean have_clipdist; + int cv_attr; /* List of the attributes to be constant interpolated. */ uint num_const_attribs; @@ -145,20 +147,23 @@ static void interp(const struct clip_stage *clip, */ dst->clipmask = 0; dst->edgeflag = 0; /* will get overwritten later */ - dst->have_clipdist = in->have_clipdist; + dst->pad = 0; dst->vertex_id = UNDEFINED_VERTEX_ID; /* Interpolate the clip-space coords. */ - interp_attr(dst->clip, t, in->clip, out->clip); + if (clip->cv_attr >= 0) { + interp_attr(dst->data[clip->cv_attr], t, + in->data[clip->cv_attr], out->data[clip->cv_attr]); + } /* interpolate the clip-space position */ - interp_attr(dst->pre_clip_pos, t, in->pre_clip_pos, out->pre_clip_pos); + interp_attr(dst->clip_pos, t, in->clip_pos, out->clip_pos); /* Do the projective divide and viewport transformation to get * new window coordinates: */ { - const float *pos = dst->pre_clip_pos; + const float *pos = dst->clip_pos; const float *scale = clip->stage.draw->viewports[viewport_index].scale; const float *trans = @@ -192,11 +197,11 @@ static void interp(const struct clip_stage *clip, t_nopersp = t; /* find either in.x != out.x or in.y != out.y */ for (k = 0; k < 2; k++) { - if (in->pre_clip_pos[k] != out->pre_clip_pos[k]) { + if (in->clip_pos[k] != out->clip_pos[k]) { /* do divide by W, then compute linear interpolation factor */ - float in_coord = in->pre_clip_pos[k] / in->pre_clip_pos[3]; - float out_coord = out->pre_clip_pos[k] / out->pre_clip_pos[3]; - float dst_coord = dst->pre_clip_pos[k] / dst->pre_clip_pos[3]; + float in_coord = in->clip_pos[k] / in->clip_pos[3]; + float out_coord = out->clip_pos[k] / out->clip_pos[3]; + float dst_coord = dst->clip_pos[k] / dst->clip_pos[3]; t_nopersp = (dst_coord - out_coord) / (in_coord - out_coord); break; } @@ -214,9 +219,9 @@ static void interp(const struct clip_stage *clip, * Triangle is considered null/empty if its area is equal to zero. */ static inline boolean -is_tri_null(struct draw_context *draw, const struct prim_header *header) +is_tri_null(const struct clip_stage *clip, const struct prim_header *header) { - const unsigned pos_attr = draw_current_shader_position_output(draw); + const unsigned pos_attr = clip->pos_attr; float x1 = header->v[1]->data[pos_attr][0] - header->v[0]->data[pos_attr][0]; float y1 = header->v[1]->data[pos_attr][1] - header->v[0]->data[pos_attr][1]; float z1 = header->v[1]->data[pos_attr][2] - header->v[0]->data[pos_attr][2]; @@ -242,6 +247,7 @@ static void emit_poly(struct draw_stage *stage, unsigned n, const struct prim_header *origPrim) { + const struct clip_stage *clipper = clip_stage(stage); struct prim_header header; unsigned i; ushort edge_first, edge_middle, edge_last; @@ -281,7 +287,7 @@ static void emit_poly(struct draw_stage *stage, header.v[2] = inlist[0]; /* the provoking vertex */ } - tri_null = is_tri_null(stage->draw, &header); + tri_null = is_tri_null(clipper, &header); /* If we generated a triangle with an area, aka. non-null triangle, * or if the previous triangle was also null then skip all subsequent * null triangles */ @@ -306,11 +312,18 @@ static void emit_poly(struct draw_stage *stage, debug_printf("Clipped tri: (flat-shade-first = %d)\n", stage->draw->rasterizer->flatshade_first); for (j = 0; j < 3; j++) { - debug_printf(" Vert %d: clip: %f %f %f %f\n", j, - header.v[j]->clip[0], - header.v[j]->clip[1], - header.v[j]->clip[2], - header.v[j]->clip[3]); + debug_printf(" Vert %d: clip pos: %f %f %f %f\n", j, + header.v[j]->clip_pos[0], + header.v[j]->clip_pos[1], + header.v[j]->clip_pos[2], + header.v[j]->clip_pos[3]); + if (clipper->cv_attr >= 0) { + debug_printf(" Vert %d: cv: %f %f %f %f\n", j, + header.v[j]->data[clipper->cv_attr][0], + header.v[j]->data[clipper->cv_attr][1], + header.v[j]->data[clipper->cv_attr][2], + header.v[j]->data[clipper->cv_attr][3]); + } for (k = 0; k < draw_num_shader_outputs(stage->draw); k++) { debug_printf(" Vert %d: Attr %d: %f %f %f %f\n", j, k, header.v[j]->data[k][0], @@ -320,7 +333,7 @@ static void emit_poly(struct draw_stage *stage, } } } - stage->next->tri( stage->next, &header ); + stage->next->tri(stage->next, &header); } } @@ -345,15 +358,28 @@ static inline float getclipdist(const struct clip_stage *clipper, { const float *plane; float dp; - if (vert->have_clipdist && plane_idx >= 6) { + if (plane_idx < 6) { + /* ordinary xyz view volume clipping uses pos output */ + plane = clipper->plane[plane_idx]; + dp = dot4(vert->clip_pos, plane); + } + else if (clipper->have_clipdist) { /* pick the correct clipdistance element from the output vectors */ int _idx = plane_idx - 6; int cdi = _idx >= 4; int vidx = cdi ? _idx - 4 : _idx; dp = vert->data[draw_current_shader_clipdistance_output(clipper->stage.draw, cdi)][vidx]; } else { + /* + * legacy user clip planes or gl_ClipVertex + */ plane = clipper->plane[plane_idx]; - dp = dot4(vert->clip, plane); + if (clipper->cv_attr >= 0) { + dp = dot4(vert->data[clipper->cv_attr], plane); + } + else { + dp = dot4(vert->clip_pos, plane); + } } return dp; } @@ -400,13 +426,22 @@ do_clip_tri(struct draw_stage *stage, viewport_index = draw_viewport_index(clipper->stage.draw, prov_vertex); if (DEBUG_CLIP) { - const float *v0 = header->v[0]->clip; - const float *v1 = header->v[1]->clip; - const float *v2 = header->v[2]->clip; - debug_printf("Clip triangle:\n"); + const float *v0 = header->v[0]->clip_pos; + const float *v1 = header->v[1]->clip_pos; + const float *v2 = header->v[2]->clip_pos; + debug_printf("Clip triangle pos:\n"); debug_printf(" %f, %f, %f, %f\n", v0[0], v0[1], v0[2], v0[3]); debug_printf(" %f, %f, %f, %f\n", v1[0], v1[1], v1[2], v1[3]); debug_printf(" %f, %f, %f, %f\n", v2[0], v2[1], v2[2], v2[3]); + if (clipper->cv_attr >= 0) { + const float *v0 = header->v[0]->data[clipper->cv_attr]; + const float *v1 = header->v[1]->data[clipper->cv_attr]; + const float *v2 = header->v[2]->data[clipper->cv_attr]; + debug_printf("Clip triangle cv:\n"); + debug_printf(" %f, %f, %f, %f\n", v0[0], v0[1], v0[2], v0[3]); + debug_printf(" %f, %f, %f, %f\n", v1[0], v1[1], v1[2], v1[3]); + debug_printf(" %f, %f, %f, %f\n", v2[0], v2[1], v2[2], v2[3]); + } } /* @@ -555,7 +590,7 @@ do_clip_tri(struct draw_stage *stage, /* Emit the polygon as triangles to the setup stage: */ - emit_poly( stage, inlist, inEdges, n, header ); + emit_poly(stage, inlist, inEdges, n, header); } } @@ -567,7 +602,7 @@ do_clip_line(struct draw_stage *stage, struct prim_header *header, unsigned clipmask) { - const struct clip_stage *clipper = clip_stage( stage ); + const struct clip_stage *clipper = clip_stage(stage); struct vertex_header *v0 = header->v[0]; struct vertex_header *v1 = header->v[1]; struct vertex_header *prov_vertex; @@ -671,9 +706,9 @@ clip_point_guard_xy(struct draw_stage *stage, struct prim_header *header) * automatically). These would usually be captured by depth clip * too but this can be disabled. */ - if (header->v[0]->clip[3] <= 0.0f || - util_is_inf_or_nan(header->v[0]->clip[0]) || - util_is_inf_or_nan(header->v[0]->clip[1])) + if (header->v[0]->clip_pos[3] <= 0.0f || + util_is_inf_or_nan(header->v[0]->clip_pos[0]) || + util_is_inf_or_nan(header->v[0]->clip_pos[1])) return; } stage->next->point(stage->next, header); @@ -773,7 +808,7 @@ find_interp(const struct draw_fragment_shader *fs, int *indexed_interp, static void clip_init_state(struct draw_stage *stage) { - struct clip_stage *clipper = clip_stage( stage ); + struct clip_stage *clipper = clip_stage(stage); const struct draw_context *draw = stage->draw; const struct draw_fragment_shader *fs = draw->fs.fragment_shader; const struct tgsi_shader_info *info = draw_get_shader_info(draw); @@ -781,6 +816,13 @@ clip_init_state(struct draw_stage *stage) int indexed_interp[2]; clipper->pos_attr = draw_current_shader_position_output(draw); + clipper->have_clipdist = draw_current_shader_num_written_clipdistances(draw) > 0; + if (draw_current_shader_clipvertex_output(draw) != clipper->pos_attr) { + clipper->cv_attr = (int)draw_current_shader_clipvertex_output(draw); + } + else { + clipper->cv_attr = -1; + } /* We need to know for each attribute what kind of interpolation is * done on it (flat, smooth or noperspective). But the information |