aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r600_blit.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/r600_blit.c')
-rw-r--r--drivers/gpu/drm/radeon/r600_blit.c115
1 files changed, 60 insertions, 55 deletions
diff --git a/drivers/gpu/drm/radeon/r600_blit.c b/drivers/gpu/drm/radeon/r600_blit.c
index 3c031a48205d..661fec2a2cc1 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
492static uint32_t i2f(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 */
502__pure uint32_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{
@@ -632,20 +637,20 @@ r600_blit_copy(struct drm_device *dev,
632 vb = r600_nomm_get_vb_ptr(dev); 637 vb = r600_nomm_get_vb_ptr(dev);
633 } 638 }
634 639
635 vb[0] = i2f(dst_x); 640 vb[0] = int2float(dst_x);
636 vb[1] = 0; 641 vb[1] = 0;
637 vb[2] = i2f(src_x); 642 vb[2] = int2float(src_x);
638 vb[3] = 0; 643 vb[3] = 0;
639 644
640 vb[4] = i2f(dst_x); 645 vb[4] = int2float(dst_x);
641 vb[5] = i2f(h); 646 vb[5] = int2float(h);
642 vb[6] = i2f(src_x); 647 vb[6] = int2float(src_x);
643 vb[7] = i2f(h); 648 vb[7] = int2float(h);
644 649
645 vb[8] = i2f(dst_x + cur_size); 650 vb[8] = int2float(dst_x + cur_size);
646 vb[9] = i2f(h); 651 vb[9] = int2float(h);
647 vb[10] = i2f(src_x + cur_size); 652 vb[10] = int2float(src_x + cur_size);
648 vb[11] = i2f(h); 653 vb[11] = int2float(h);
649 654
650 /* src */ 655 /* src */
651 set_tex_resource(dev_priv, FMT_8, 656 set_tex_resource(dev_priv, FMT_8,
@@ -721,20 +726,20 @@ r600_blit_copy(struct drm_device *dev,
721 vb = r600_nomm_get_vb_ptr(dev); 726 vb = r600_nomm_get_vb_ptr(dev);
722 } 727 }
723 728
724 vb[0] = i2f(dst_x / 4); 729 vb[0] = int2float(dst_x / 4);
725 vb[1] = 0; 730 vb[1] = 0;
726 vb[2] = i2f(src_x / 4); 731 vb[2] = int2float(src_x / 4);
727 vb[3] = 0; 732 vb[3] = 0;
728 733
729 vb[4] = i2f(dst_x / 4); 734 vb[4] = int2float(dst_x / 4);
730 vb[5] = i2f(h); 735 vb[5] = int2float(h);
731 vb[6] = i2f(src_x / 4); 736 vb[6] = int2float(src_x / 4);
732 vb[7] = i2f(h); 737 vb[7] = int2float(h);
733 738
734 vb[8] = i2f((dst_x + cur_size) / 4); 739 vb[8] = int2float((dst_x + cur_size) / 4);
735 vb[9] = i2f(h); 740 vb[9] = int2float(h);
736 vb[10] = i2f((src_x + cur_size) / 4); 741 vb[10] = int2float((src_x + cur_size) / 4);
737 vb[11] = i2f(h); 742 vb[11] = int2float(h);
738 743
739 /* src */ 744 /* src */
740 set_tex_resource(dev_priv, FMT_8_8_8_8, 745 set_tex_resource(dev_priv, FMT_8_8_8_8,
@@ -804,20 +809,20 @@ r600_blit_swap(struct drm_device *dev,
804 dx2 = dx + w; 809 dx2 = dx + w;
805 dy2 = dy + h; 810 dy2 = dy + h;
806 811
807 vb[0] = i2f(dx); 812 vb[0] = int2float(dx);
808 vb[1] = i2f(dy); 813 vb[1] = int2float(dy);
809 vb[2] = i2f(sx); 814 vb[2] = int2float(sx);
810 vb[3] = i2f(sy); 815 vb[3] = int2float(sy);
811 816
812 vb[4] = i2f(dx); 817 vb[4] = int2float(dx);
813 vb[5] = i2f(dy2); 818 vb[5] = int2float(dy2);
814 vb[6] = i2f(sx); 819 vb[6] = int2float(sx);
815 vb[7] = i2f(sy2); 820 vb[7] = int2float(sy2);
816 821
817 vb[8] = i2f(dx2); 822 vb[8] = int2float(dx2);
818 vb[9] = i2f(dy2); 823 vb[9] = int2float(dy2);
819 vb[10] = i2f(sx2); 824 vb[10] = int2float(sx2);
820 vb[11] = i2f(sy2); 825 vb[11] = int2float(sy2);
821 826
822 switch(cpp) { 827 switch(cpp) {
823 case 4: 828 case 4: