aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorSteven Fuerst <svfuerst@gmail.com>2012-08-15 18:07:15 -0400
committerAlex Deucher <alexander.deucher@amd.com>2012-09-20 13:10:34 -0400
commit747f49ba67b8895a5831ab539de551b916f3738c (patch)
treeb1b1561ae97f9f7fdab8ae44e019bd5dca0e62e4 /drivers/gpu/drm
parent7ff64fcaa7b7ba62d12758e49643f31dd9e90ece (diff)
Replace int2float() with an optimized version.
We use __fls() to find the most significant bit. Using that, the loop can be avoided. A second trick is to use the behaviour of the rotate instructions to expand the range of the unsigned int to float conversion to the full 32 bits in a branchless way. The routine is now exact up to 2^24. Above that, we truncate which is equivalent to rounding towards zero. Signed-off-by: Steven Fuerst <svfuerst@gmail.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/radeon/r600_blit.c51
1 files changed, 28 insertions, 23 deletions
diff --git a/drivers/gpu/drm/radeon/r600_blit.c b/drivers/gpu/drm/radeon/r600_blit.c
index ee1b815b5689..7d8ac42e3846 100644
--- a/drivers/gpu/drm/radeon/r600_blit.c
+++ b/drivers/gpu/drm/radeon/r600_blit.c
@@ -489,31 +489,36 @@ set_default_state(drm_radeon_private_t *dev_priv)
489 ADVANCE_RING(); 489 ADVANCE_RING();
490} 490}
491 491
492uint32_t int2float(uint32_t input) 492/* 23 bits of float fractional data */
493#define I2F_FRAC_BITS 23
494#define I2F_MASK ((1 << I2F_FRAC_BITS) - 1)
495
496/*
497 * Converts unsigned integer into 32-bit IEEE floating point representation.
498 * Will be exact from 0 to 2^24. Above that, we round towards zero
499 * as the fractional bits will not fit in a float. (It would be better to
500 * round towards even as the fpu does, but that is slower.)
501 */
502uint32_t int2float(uint32_t x)
493{ 503{
494 u32 result, i, exponent, fraction; 504 uint32_t msb, exponent, fraction;
495 505
496 if ((input & 0x3fff) == 0) 506 /* Zero is special */
497 result = 0; /* 0 is a special case */ 507 if (!x) return 0;
498 else { 508
499 exponent = 140; /* exponent biased by 127; */ 509 /* Get location of the most significant bit */
500 fraction = (input & 0x3fff) << 10; /* cheat and only 510 msb = __fls(x);
501 handle numbers below 2^^15 */
502 for (i = 0; i < 14; i++) {
503 if (fraction & 0x800000)
504 break;
505 else {
506 fraction = fraction << 1; /* keep
507 shifting left until top bit = 1 */
508 exponent = exponent - 1;
509 }
510 }
511 result = exponent << 23 | (fraction & 0x7fffff); /* mask
512 off top bit; assumed 1 */
513 }
514 return result;
515}
516 511
512 /*
513 * Use a rotate instead of a shift because that works both leftwards
514 * and rightwards due to the mod(32) behaviour. This means we don't
515 * need to check to see if we are above 2^24 or not.
516 */
517 fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;
518 exponent = (127 + msb) << I2F_FRAC_BITS;
519
520 return fraction + exponent;
521}
517 522
518static int r600_nomm_get_vb(struct drm_device *dev) 523static int r600_nomm_get_vb(struct drm_device *dev)
519{ 524{