X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fgallium%2Fdrivers%2Fllvmpipe%2Flp_setup_tri.c;h=d24a4b4afe74a88a26930357cd9e499224db8e6a;hb=3263c9824ebf35a24380e401bb1b1852d538a46d;hp=98243a12de1b65edfc59441b976ab452d1168df6;hpb=7f6a0cb29c89a03441be744680a2145445be3a3c;p=mesa.git diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 98243a12de1..d24a4b4afe7 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -46,23 +46,20 @@ #if defined(PIPE_ARCH_SSE) #include -#elif defined(_ARCH_PWR8) && defined(PIPE_ARCH_LITTLE_ENDIAN) +#elif defined(_ARCH_PWR8) && UTIL_ARCH_LITTLE_ENDIAN #include #include "util/u_pwr8.h" #endif +#if !defined(PIPE_ARCH_SSE) + static inline int subpixel_snap(float a) { return util_iround(FIXED_ONE * a); } -static inline float -fixed_to_float(int a) -{ - return a * (1.0f / FIXED_ONE); -} - +#endif /* Position and area in fixed point coordinates */ struct fixed_position { @@ -276,7 +273,9 @@ do_triangle_ccw(struct lp_setup_context *setup, const struct lp_setup_variant_key *key = &setup->setup.variant->key; struct lp_rast_triangle *tri; struct lp_rast_plane *plane; - struct u_rect bbox; + const struct u_rect *scissor; + struct u_rect bbox, bboxpos; + boolean s_planes[4]; unsigned tri_bytes; int nr_planes = 3; unsigned viewport_index = 0; @@ -335,12 +334,14 @@ do_triangle_ccw(struct lp_setup_context *setup, return TRUE; } + bboxpos = bbox; + /* Can safely discard negative regions, but need to keep hold of * information about when the triangle extends past screen * boundaries. See trimmed_box in lp_setup_bin_triangle(). */ - bbox.x0 = MAX2(bbox.x0, 0); - bbox.y0 = MAX2(bbox.y0, 0); + bboxpos.x0 = MAX2(bboxpos.x0, 0); + bboxpos.y0 = MAX2(bboxpos.y0, 0); nr_planes = 3; /* @@ -349,8 +350,8 @@ do_triangle_ccw(struct lp_setup_context *setup, */ if (setup->scissor_test) { /* why not just use draw_regions */ - boolean s_planes[4]; - scissor_planes_needed(s_planes, &bbox, &setup->scissors[viewport_index]); + scissor = &setup->scissors[viewport_index]; + scissor_planes_needed(s_planes, &bboxpos, scissor); nr_planes += s_planes[0] + s_planes[1] + s_planes[2] + s_planes[3]; } @@ -361,7 +362,7 @@ do_triangle_ccw(struct lp_setup_context *setup, if (!tri) return FALSE; -#if 0 +#ifdef DEBUG tri->v[0][0] = v0[0][0]; tri->v[1][0] = v1[0][0]; tri->v[2][0] = v2[0][0]; @@ -488,7 +489,7 @@ do_triangle_ccw(struct lp_setup_context *setup, eo = _mm_shuffle_epi32(eo, _MM_SHUFFLE(0,0,0,2)); plane[2].eo = (uint32_t)_mm_cvtsi128_si32(eo); } else -#elif defined(_ARCH_PWR8) && defined(PIPE_ARCH_LITTLE_ENDIAN) +#elif defined(_ARCH_PWR8) && UTIL_ARCH_LITTLE_ENDIAN /* * XXX this code is effectively disabled for all practical purposes, * as the allowed fb size is tiny if FIXED_ORDER is 8. @@ -512,7 +513,7 @@ do_triangle_ccw(struct lp_setup_context *setup, __m128i zero = vec_splats((unsigned char) 0); PIPE_ALIGN_VAR(16) int32_t temp_vec[4]; -#ifdef PIPE_ARCH_LITTLE_ENDIAN +#if UTIL_ARCH_LITTLE_ENDIAN vshuf_mask.i[0] = 0x07060504; vshuf_mask.i[1] = 0x0B0A0908; vshuf_mask.i[2] = 0x03020100; @@ -683,13 +684,10 @@ do_triangle_ccw(struct lp_setup_context *setup, */ if (nr_planes > 3) { /* why not just use draw_regions */ - const struct u_rect *scissor = &setup->scissors[viewport_index]; struct lp_rast_plane *plane_s = &plane[3]; - boolean s_planes[4]; - scissor_planes_needed(s_planes, &bbox, scissor); if (s_planes[0]) { - plane_s->dcdx = -1 << 8; + plane_s->dcdx = ~0U << 8; plane_s->dcdy = 0; plane_s->c = (1-scissor->x0) << 8; plane_s->eo = 1 << 8; @@ -711,7 +709,7 @@ do_triangle_ccw(struct lp_setup_context *setup, } if (s_planes[3]) { plane_s->dcdx = 0; - plane_s->dcdy = -1 << 8; + plane_s->dcdy = ~0U << 8; plane_s->c = (scissor->y1+1) << 8; plane_s->eo = 0; plane_s++; @@ -719,7 +717,7 @@ do_triangle_ccw(struct lp_setup_context *setup, assert(plane_s == &plane[nr_planes]); } - return lp_setup_bin_triangle(setup, tri, &bbox, nr_planes, viewport_index); + return lp_setup_bin_triangle(setup, tri, &bbox, &bboxpos, nr_planes, viewport_index); } /* @@ -736,7 +734,8 @@ floor_pot(uint32_t n) __asm__("bsr %1,%0" : "=r" (n) - : "rm" (n)); + : "rm" (n) + : "cc"); return 1 << n; #else n |= (n >> 1); @@ -750,11 +749,12 @@ floor_pot(uint32_t n) boolean -lp_setup_bin_triangle( struct lp_setup_context *setup, - struct lp_rast_triangle *tri, - const struct u_rect *bbox, - int nr_planes, - unsigned viewport_index ) +lp_setup_bin_triangle(struct lp_setup_context *setup, + struct lp_rast_triangle *tri, + const struct u_rect *bboxorig, + const struct u_rect *bbox, + int nr_planes, + unsigned viewport_index) { struct lp_scene *scene = setup->scene; struct u_rect trimmed_box = *bbox; @@ -770,7 +770,16 @@ lp_setup_bin_triangle( struct lp_setup_context *setup, int max_sz = ((bbox->x1 - (bbox->x0 & ~3)) | (bbox->y1 - (bbox->y0 & ~3))); int sz = floor_pot(max_sz); - boolean use_32bits = max_sz <= MAX_FIXED_LENGTH32; + + /* + * NOTE: It is important to use the original bounding box + * which might contain negative values here, because if the + * plane math may overflow or not with the 32bit rasterization + * functions depends on the original extent of the triangle. + */ + int max_szorig = ((bboxorig->x1 - (bboxorig->x0 & ~3)) | + (bboxorig->y1 - (bboxorig->y0 & ~3))); + boolean use_32bits = max_szorig <= MAX_FIXED_LENGTH32; /* Now apply scissor, etc to the bounding box. Could do this * earlier, but it confuses the logic for tri-16 and would force @@ -1119,6 +1128,11 @@ static void triangle_cw(struct lp_setup_context *setup, const float (*v2)[4]) { PIPE_ALIGN_VAR(16) struct fixed_position position; + struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe; + + if (lp_context->active_statistics_queries) { + lp_context->pipeline_statistics.c_primitives++; + } calc_fixed_position(setup, &position, v0, v1, v2); @@ -1140,6 +1154,11 @@ static void triangle_ccw(struct lp_setup_context *setup, const float (*v2)[4]) { PIPE_ALIGN_VAR(16) struct fixed_position position; + struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe; + + if (lp_context->active_statistics_queries) { + lp_context->pipeline_statistics.c_primitives++; + } calc_fixed_position(setup, &position, v0, v1, v2); @@ -1158,8 +1177,7 @@ static void triangle_both(struct lp_setup_context *setup, PIPE_ALIGN_VAR(16) struct fixed_position position; struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe; - if (lp_context->active_statistics_queries && - !llvmpipe_rasterization_disabled(lp_context)) { + if (lp_context->active_statistics_queries) { lp_context->pipeline_statistics.c_primitives++; } @@ -1188,17 +1206,21 @@ static void triangle_both(struct lp_setup_context *setup, } -static void triangle_nop( struct lp_setup_context *setup, - const float (*v0)[4], - const float (*v1)[4], - const float (*v2)[4] ) +static void triangle_noop(struct lp_setup_context *setup, + const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4]) { } void -lp_setup_choose_triangle( struct lp_setup_context *setup ) +lp_setup_choose_triangle(struct lp_setup_context *setup) { + if (setup->rasterizer_discard) { + setup->triangle = triangle_noop; + return; + } switch (setup->cullmode) { case PIPE_FACE_NONE: setup->triangle = triangle_both; @@ -1210,7 +1232,7 @@ lp_setup_choose_triangle( struct lp_setup_context *setup ) setup->triangle = setup->ccw_is_frontface ? triangle_cw : triangle_ccw; break; default: - setup->triangle = triangle_nop; + setup->triangle = triangle_noop; break; } }