1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/************************************************************************** 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved. 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish, 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions: 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software. 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/ 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \brief Clipping stage 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \author Keith Whitwell <keith@tungstengraphics.com> 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h" 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_math.h" 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_shader_tokens.h" 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "draw_vs.h" 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "draw_pipe.h" 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "draw_fs.h" 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef IS_NEGATIVE 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define IS_NEGATIVE(X) ((X) < 0.0) 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef DIFFERENT_SIGNS 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DIFFERENT_SIGNS(x, y) ((x) * (y) <= 0.0F && (x) - (y) != 0.0F) 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MAX_CLIPPED_VERTICES ((2 * (6 + PIPE_MAX_CLIP_PLANES))+1) 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct clip_stage { 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct draw_stage stage; /**< base class */ 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* List of the attributes to be flatshaded. */ 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint num_flat_attribs; 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint flat_attribs[PIPE_MAX_SHADER_OUTPUTS]; 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Mask of attributes in noperspective mode */ 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean noperspective_attribs[PIPE_MAX_SHADER_OUTPUTS]; 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float (*plane)[4]; 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Cast wrapper */ 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE struct clip_stage *clip_stage( struct draw_stage *stage ) 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (struct clip_stage *)stage; 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT))) 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* All attributes are float[4], so this is easy: 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void interp_attr( float dst[4], 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float t, 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const float in[4], 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const float out[4] ) 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst[0] = LINTERP( t, out[0], in[0] ); 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst[1] = LINTERP( t, out[1], in[1] ); 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst[2] = LINTERP( t, out[2], in[2] ); 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst[3] = LINTERP( t, out[3], in[3] ); 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copy flat shaded attributes src vertex to dst vertex. 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void copy_flat( struct draw_stage *stage, 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vertex_header *dst, 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct vertex_header *src ) 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct clip_stage *clipper = clip_stage(stage); 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint i; 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < clipper->num_flat_attribs; i++) { 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const uint attr = clipper->flat_attribs[i]; 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org COPY_4FV(dst->data[attr], src->data[attr]); 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Interpolate between two vertices to produce a third. 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void interp( const struct clip_stage *clip, 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vertex_header *dst, 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float t, 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct vertex_header *out, 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct vertex_header *in ) 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned nr_attrs = draw_current_shader_outputs(clip->stage.draw); 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned pos_attr = draw_current_shader_position_output(clip->stage.draw); 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned clip_attr = draw_current_shader_clipvertex_output(clip->stage.draw); 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned j; 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float t_nopersp; 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Vertex header. 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->clipmask = 0; 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->edgeflag = 0; /* will get overwritten later */ 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->have_clipdist = in->have_clipdist; 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->vertex_id = UNDEFINED_VERTEX_ID; 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Interpolate the clip-space coords. 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org interp_attr(dst->clip, t, in->clip, out->clip); 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* interpolate the clip-space position */ 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org interp_attr(dst->pre_clip_pos, t, in->pre_clip_pos, out->pre_clip_pos); 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Do the projective divide and viewport transformation to get 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * new window coordinates: 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const float *pos = dst->pre_clip_pos; 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const float *scale = clip->stage.draw->viewport.scale; 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const float *trans = clip->stage.draw->viewport.translate; 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const float oow = 1.0f / pos[3]; 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->data[pos_attr][0] = pos[0] * oow * scale[0] + trans[0]; 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->data[pos_attr][1] = pos[1] * oow * scale[1] + trans[1]; 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->data[pos_attr][2] = pos[2] * oow * scale[2] + trans[2]; 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->data[pos_attr][3] = oow; 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compute the t in screen-space instead of 3d space to use 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * for noperspective interpolation. 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The points can be aligned with the X axis, so in that case try 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the Y. When both points are at the same screen position, we can 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * pick whatever value (the interpolated point won't be in front 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * anyway), so just use the 3d t. 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int k; 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t_nopersp = t; 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (k = 0; k < 2; k++) 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (in->data[pos_attr][k] != out->data[pos_attr][k]) { 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t_nopersp = (dst->data[pos_attr][k] - out->data[pos_attr][k]) / 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (in->data[pos_attr][k] - out->data[pos_attr][k]); 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Other attributes 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (j = 0; j < nr_attrs; j++) { 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (j != pos_attr && j != clip_attr) { 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (clip->noperspective_attribs[j]) 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org interp_attr(dst->data[j], t_nopersp, in->data[j], out->data[j]); 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org interp_attr(dst->data[j], t, in->data[j], out->data[j]); 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Emit a post-clip polygon to the next pipeline stage. The polygon 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * will be convex and the provoking vertex will always be vertex[0]. 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_poly( struct draw_stage *stage, 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vertex_header **inlist, 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const boolean *edgeflags, 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned n, 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct prim_header *origPrim) 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct prim_header header; 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ushort edge_first, edge_middle, edge_last; 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (stage->draw->rasterizer->flatshade_first) { 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org edge_first = DRAW_PIPE_EDGE_FLAG_0; 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org edge_middle = DRAW_PIPE_EDGE_FLAG_1; 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org edge_last = DRAW_PIPE_EDGE_FLAG_2; 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org edge_first = DRAW_PIPE_EDGE_FLAG_2; 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org edge_middle = DRAW_PIPE_EDGE_FLAG_0; 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org edge_last = DRAW_PIPE_EDGE_FLAG_1; 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!edgeflags[0]) 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org edge_first = 0; 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* later stages may need the determinant, but only the sign matters */ 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header.det = origPrim->det; 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header.flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header.pad = 0; 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 2; i < n; i++, header.flags = edge_middle) { 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* order the triangle verts to respect the provoking vertex mode */ 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (stage->draw->rasterizer->flatshade_first) { 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header.v[0] = inlist[0]; /* the provoking vertex */ 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header.v[1] = inlist[i-1]; 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header.v[2] = inlist[i]; 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header.v[0] = inlist[i-1]; 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header.v[1] = inlist[i]; 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header.v[2] = inlist[0]; /* the provoking vertex */ 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!edgeflags[i-1]) { 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header.flags &= ~edge_middle; 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (i == n - 1 && edgeflags[i]) 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header.flags |= edge_last; 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (0) { 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct draw_vertex_shader *vs = stage->draw->vs.vertex_shader; 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint j, k; 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("Clipped tri: (flat-shade-first = %d)\n", 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stage->draw->rasterizer->flatshade_first); 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (j = 0; j < 3; j++) { 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (k = 0; k < vs->info.num_outputs; k++) { 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf(" Vert %d: Attr %d: %f %f %f %f\n", j, k, 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header.v[j]->data[k][0], 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header.v[j]->data[k][1], 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header.v[j]->data[k][2], 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header.v[j]->data[k][3]); 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stage->next->tri( stage->next, &header ); 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE float 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdot4(const float *a, const float *b) 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (a[0] * b[0] + 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[1] * b[1] + 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[2] * b[2] + 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a[3] * b[3]); 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * this function extracts the clip distance for the current plane, 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * it first checks if the shader provided a clip distance, otherwise 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * it works out the value using the clipvertex 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE float getclipdist(const struct clip_stage *clipper, 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vertex_header *vert, 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int plane_idx) 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const float *plane; 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float dp; 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (vert->have_clipdist && plane_idx >= 6) { 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* pick the correct clipdistance element from the output vectors */ 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int _idx = plane_idx - 6; 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int cdi = _idx >= 4; 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int vidx = cdi ? _idx - 4 : _idx; 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dp = vert->data[draw_current_shader_clipdistance_output(clipper->stage.draw, cdi)][vidx]; 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org plane = clipper->plane[plane_idx]; 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dp = dot4(vert->clip, plane); 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return dp; 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Clip a triangle against the viewport and user clip planes. 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdo_clip_tri( struct draw_stage *stage, 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct prim_header *header, 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned clipmask ) 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct clip_stage *clipper = clip_stage( stage ); 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vertex_header *a[MAX_CLIPPED_VERTICES]; 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vertex_header *b[MAX_CLIPPED_VERTICES]; 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vertex_header **inlist = a; 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vertex_header **outlist = b; 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned tmpnr = 0; 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned n = 3; 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean aEdges[MAX_CLIPPED_VERTICES]; 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean bEdges[MAX_CLIPPED_VERTICES]; 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean *inEdges = aEdges; 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean *outEdges = bEdges; 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inlist[0] = header->v[0]; 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inlist[1] = header->v[1]; 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inlist[2] = header->v[2]; 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note: at this point we can't just use the per-vertex edge flags. 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * We have to observe the edge flag bits set in header->flags which 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * were set during primitive decomposition. Put those flags into 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * an edge flags array which parallels the vertex array. 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Later, in the 'unfilled' pipeline stage we'll draw the edge if both 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the header.flags bit is set AND the per-vertex edgeflag field is set. 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inEdges[0] = !!(header->flags & DRAW_PIPE_EDGE_FLAG_0); 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inEdges[1] = !!(header->flags & DRAW_PIPE_EDGE_FLAG_1); 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inEdges[2] = !!(header->flags & DRAW_PIPE_EDGE_FLAG_2); 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (clipmask && n >= 3) { 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned plane_idx = ffs(clipmask)-1; 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const boolean is_user_clip_plane = plane_idx >= 6; 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vertex_header *vert_prev = inlist[0]; 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean *edge_prev = &inEdges[0]; 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float dp_prev; 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned outcount = 0; 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dp_prev = getclipdist(clipper, vert_prev, plane_idx); 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clipmask &= ~(1<<plane_idx); 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(n < MAX_CLIPPED_VERTICES); 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (n >= MAX_CLIPPED_VERTICES) 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inlist[n] = inlist[0]; /* prevent rotation of vertices */ 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inEdges[n] = inEdges[0]; 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 1; i <= n; i++) { 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vertex_header *vert = inlist[i]; 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean *edge = &inEdges[i]; 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float dp = getclipdist(clipper, vert, plane_idx); 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!IS_NEGATIVE(dp_prev)) { 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(outcount < MAX_CLIPPED_VERTICES); 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (outcount >= MAX_CLIPPED_VERTICES) 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org outEdges[outcount] = *edge_prev; 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org outlist[outcount++] = vert_prev; 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DIFFERENT_SIGNS(dp, dp_prev)) { 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vertex_header *new_vert; 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean *new_edge; 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(tmpnr < MAX_CLIPPED_VERTICES + 1); 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tmpnr >= MAX_CLIPPED_VERTICES + 1) 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_vert = clipper->stage.tmp[tmpnr++]; 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(outcount < MAX_CLIPPED_VERTICES); 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (outcount >= MAX_CLIPPED_VERTICES) 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_edge = &outEdges[outcount]; 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org outlist[outcount++] = new_vert; 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (IS_NEGATIVE(dp)) { 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Going out of bounds. Avoid division by zero as we 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * know dp != dp_prev from DIFFERENT_SIGNS, above. 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float t = dp / (dp - dp_prev); 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org interp( clipper, new_vert, t, vert, vert_prev ); 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Whether or not to set edge flag for the new vert depends 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * on whether it's a user-defined clipping plane. We're 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copying NVIDIA's behaviour here. 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (is_user_clip_plane) { 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* we want to see an edge along the clip plane */ 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *new_edge = TRUE; 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_vert->edgeflag = TRUE; 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* we don't want to see an edge along the frustum clip plane */ 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *new_edge = *edge_prev; 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_vert->edgeflag = FALSE; 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Coming back in. 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float t = dp_prev / (dp_prev - dp); 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org interp( clipper, new_vert, t, vert_prev, vert ); 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Copy starting vert's edgeflag: 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_vert->edgeflag = vert_prev->edgeflag; 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *new_edge = *edge_prev; 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vert_prev = vert; 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org edge_prev = edge; 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dp_prev = dp; 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* swap in/out lists */ 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vertex_header **tmp = inlist; 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inlist = outlist; 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org outlist = tmp; 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org n = outcount; 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean *tmp = inEdges; 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inEdges = outEdges; 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org outEdges = tmp; 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If flat-shading, copy provoking vertex color to polygon vertex[0] 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (n >= 3) { 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (clipper->num_flat_attribs) { 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (stage->draw->rasterizer->flatshade_first) { 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inlist[0] != header->v[0]) { 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(tmpnr < MAX_CLIPPED_VERTICES + 1); 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tmpnr >= MAX_CLIPPED_VERTICES + 1) 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inlist[0] = dup_vert(stage, inlist[0], tmpnr++); 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org copy_flat(stage, inlist[0], header->v[0]); 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inlist[0] != header->v[2]) { 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(tmpnr < MAX_CLIPPED_VERTICES + 1); 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tmpnr >= MAX_CLIPPED_VERTICES + 1) 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inlist[0] = dup_vert(stage, inlist[0], tmpnr++); 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org copy_flat(stage, inlist[0], header->v[2]); 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Emit the polygon as triangles to the setup stage: 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_poly( stage, inlist, inEdges, n, header ); 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Clip a line against the viewport and user clip planes. 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdo_clip_line( struct draw_stage *stage, 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct prim_header *header, 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned clipmask ) 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct clip_stage *clipper = clip_stage( stage ); 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vertex_header *v0 = header->v[0]; 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vertex_header *v1 = header->v[1]; 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float t0 = 0.0F; 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float t1 = 0.0F; 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct prim_header newprim; 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (clipmask) { 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned plane_idx = ffs(clipmask)-1; 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const float dp0 = getclipdist(clipper, v0, plane_idx); 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const float dp1 = getclipdist(clipper, v1, plane_idx); 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dp1 < 0.0F) { 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float t = dp1 / (dp1 - dp0); 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t1 = MAX2(t1, t); 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dp0 < 0.0F) { 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float t = dp0 / (dp0 - dp1); 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t0 = MAX2(t0, t); 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (t0 + t1 >= 1.0F) 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; /* discard */ 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clipmask &= ~(1 << plane_idx); /* turn off this plane's bit */ 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (v0->clipmask) { 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org interp( clipper, stage->tmp[0], t0, v0, v1 ); 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org copy_flat(stage, stage->tmp[0], v0); 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org newprim.v[0] = stage->tmp[0]; 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org newprim.v[0] = v0; 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (v1->clipmask) { 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org interp( clipper, stage->tmp[1], t1, v1, v0 ); 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org newprim.v[1] = stage->tmp[1]; 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org newprim.v[1] = v1; 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stage->next->line( stage->next, &newprim ); 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclip_point( struct draw_stage *stage, 521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct prim_header *header ) 522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (header->v[0]->clipmask == 0) 524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stage->next->point( stage->next, header ); 525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclip_line( struct draw_stage *stage, 530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct prim_header *header ) 531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned clipmask = (header->v[0]->clipmask | 533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header->v[1]->clipmask); 534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (clipmask == 0) { 536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* no clipping needed */ 537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stage->next->line( stage->next, header ); 538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if ((header->v[0]->clipmask & 540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header->v[1]->clipmask) == 0) { 541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org do_clip_line(stage, header, clipmask); 542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* else, totally clipped */ 544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclip_tri( struct draw_stage *stage, 549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct prim_header *header ) 550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned clipmask = (header->v[0]->clipmask | 552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header->v[1]->clipmask | 553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header->v[2]->clipmask); 554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (clipmask == 0) { 556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* no clipping needed */ 557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stage->next->tri( stage->next, header ); 558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if ((header->v[0]->clipmask & 560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header->v[1]->clipmask & 561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header->v[2]->clipmask) == 0) { 562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org do_clip_tri(stage, header, clipmask); 563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Update state. Could further delay this until we hit the first 568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * primitive that really requires clipping. 569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclip_init_state( struct draw_stage *stage ) 572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct clip_stage *clipper = clip_stage( stage ); 574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct draw_vertex_shader *vs = stage->draw->vs.vertex_shader; 575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct draw_fragment_shader *fs = stage->draw->fs.fragment_shader; 576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint i; 577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* We need to know for each attribute what kind of interpolation is 579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * done on it (flat, smooth or noperspective). But the information 580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is not directly accessible for outputs, only for inputs. So we 581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * have to match semantic name and index between the VS (or GS/ES) 582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * outputs and the FS inputs to get to the interpolation mode. 583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The only hitch is with gl_FrontColor/gl_BackColor which map to 585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * gl_Color, and their Secondary versions. First there are (up to) 586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * two outputs for one input, so we tuck the information in a 587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * specific array. Second if they don't have qualifiers, the 588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * default value has to be picked from the global shade mode. 589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Of course, if we don't have a fragment shader in the first 591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * place, defaults should be used. 592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* First pick up the interpolation mode for 595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * gl_Color/gl_SecondaryColor, with the correct default. 596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int indexed_interp[2]; 598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org indexed_interp[0] = indexed_interp[1] = stage->draw->rasterizer->flatshade ? 599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TGSI_INTERPOLATE_CONSTANT : TGSI_INTERPOLATE_PERSPECTIVE; 600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (fs) { 602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < fs->info.num_inputs; i++) { 603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (fs->info.input_semantic_name[i] == TGSI_SEMANTIC_COLOR) { 604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (fs->info.input_interpolate[i] != TGSI_INTERPOLATE_COLOR) 605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org indexed_interp[fs->info.input_semantic_index[i]] = fs->info.input_interpolate[i]; 606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Then resolve the interpolation mode for every output attribute. 611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Given how the rest of the code, the most efficient way is to 613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * have a vector of flat-mode attributes, and a mask for 614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * noperspective attributes. 615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clipper->num_flat_attribs = 0; 618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(clipper->noperspective_attribs, 0, sizeof(clipper->noperspective_attribs)); 619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < vs->info.num_outputs; i++) { 620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Find the interpolation mode for a specific attribute 621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int interp; 623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If it's gl_{Front,Back}{,Secondary}Color, pick up the mode 625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * from the array we've filled before. */ 626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR || 627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { 628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org interp = indexed_interp[vs->info.output_semantic_index[i]]; 629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Otherwise, search in the FS inputs, with a decent default 631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * if we don't find it. 632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint j; 634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org interp = TGSI_INTERPOLATE_PERSPECTIVE; 635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (fs) { 636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (j = 0; j < fs->info.num_inputs; j++) { 637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (vs->info.output_semantic_name[i] == fs->info.input_semantic_name[j] && 638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vs->info.output_semantic_index[i] == fs->info.input_semantic_index[j]) { 639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org interp = fs->info.input_interpolate[j]; 640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If it's flat, add it to the flat vector. Otherwise update 647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the noperspective mask. 648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (interp == TGSI_INTERPOLATE_CONSTANT) { 650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clipper->flat_attribs[clipper->num_flat_attribs] = i; 651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clipper->num_flat_attribs++; 652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else 653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clipper->noperspective_attribs[i] = interp == TGSI_INTERPOLATE_LINEAR; 654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stage->tri = clip_tri; 657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stage->line = clip_line; 658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void clip_first_tri( struct draw_stage *stage, 663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct prim_header *header ) 664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clip_init_state( stage ); 666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stage->tri( stage, header ); 667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void clip_first_line( struct draw_stage *stage, 670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct prim_header *header ) 671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clip_init_state( stage ); 673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stage->line( stage, header ); 674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void clip_flush( struct draw_stage *stage, 678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned flags ) 679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stage->tri = clip_first_tri; 681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stage->line = clip_first_line; 682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stage->next->flush( stage->next, flags ); 683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void clip_reset_stipple_counter( struct draw_stage *stage ) 687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stage->next->reset_stipple_counter( stage->next ); 689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void clip_destroy( struct draw_stage *stage ) 693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org draw_free_temp_verts( stage ); 695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE( stage ); 696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Allocate a new clipper stage. 701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return pointer to new stage object 702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct draw_stage *draw_clip_stage( struct draw_context *draw ) 704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct clip_stage *clipper = CALLOC_STRUCT(clip_stage); 706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (clipper == NULL) 707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto fail; 708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clipper->stage.draw = draw; 710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clipper->stage.name = "clipper"; 711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clipper->stage.point = clip_point; 712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clipper->stage.line = clip_first_line; 713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clipper->stage.tri = clip_first_tri; 714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clipper->stage.flush = clip_flush; 715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clipper->stage.reset_stipple_counter = clip_reset_stipple_counter; 716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clipper->stage.destroy = clip_destroy; 717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clipper->plane = draw->plane; 719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!draw_alloc_temp_verts( &clipper->stage, MAX_CLIPPED_VERTICES+1 )) 721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto fail; 722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &clipper->stage; 724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fail: 726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (clipper) 727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clipper->stage.destroy( &clipper->stage ); 728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 731