diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2010-05-13 05:49:44 -0400 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2010-05-26 17:13:36 -0400 |
commit | 778c35444f7bbb8f1816d40ada650e19c5da9c02 (patch) | |
tree | de99bcb4a102591dc63f37e37edf200e7998c60c | |
parent | a7de64e540d2017a8e44dec1ca9d88a509aa7e05 (diff) |
drm/i915: combine all small integers into one single bitfield
This saves a whooping 7 dwords. Zero functional changes. Because
some of the refcounts are rather tightly calculated, I've put
BUG_ONs in the code to check for overflows.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Eric Anholt <eric@anholt.net>
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 75 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 5 |
2 files changed, 54 insertions, 26 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 91b3a1c20ef8..cccf8019f65a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -658,19 +658,64 @@ struct drm_i915_gem_object { | |||
658 | * (has pending rendering), and is not set if it's on inactive (ready | 658 | * (has pending rendering), and is not set if it's on inactive (ready |
659 | * to be unbound). | 659 | * to be unbound). |
660 | */ | 660 | */ |
661 | int active; | 661 | unsigned int active : 1; |
662 | 662 | ||
663 | /** | 663 | /** |
664 | * This is set if the object has been written to since last bound | 664 | * This is set if the object has been written to since last bound |
665 | * to the GTT | 665 | * to the GTT |
666 | */ | 666 | */ |
667 | int dirty; | 667 | unsigned int dirty : 1; |
668 | |||
669 | /** | ||
670 | * Fence register bits (if any) for this object. Will be set | ||
671 | * as needed when mapped into the GTT. | ||
672 | * Protected by dev->struct_mutex. | ||
673 | * | ||
674 | * Size: 4 bits for 16 fences + sign (for FENCE_REG_NONE) | ||
675 | */ | ||
676 | int fence_reg : 5; | ||
677 | |||
678 | /** | ||
679 | * Used for checking the object doesn't appear more than once | ||
680 | * in an execbuffer object list. | ||
681 | */ | ||
682 | unsigned int in_execbuffer : 1; | ||
683 | |||
684 | /** | ||
685 | * Advice: are the backing pages purgeable? | ||
686 | */ | ||
687 | unsigned int madv : 2; | ||
688 | |||
689 | /** | ||
690 | * Refcount for the pages array. With the current locking scheme, there | ||
691 | * are at most two concurrent users: Binding a bo to the gtt and | ||
692 | * pwrite/pread using physical addresses. So two bits for a maximum | ||
693 | * of two users are enough. | ||
694 | */ | ||
695 | unsigned int pages_refcount : 2; | ||
696 | #define DRM_I915_GEM_OBJECT_MAX_PAGES_REFCOUNT 0x3 | ||
697 | |||
698 | /** | ||
699 | * Current tiling mode for the object. | ||
700 | */ | ||
701 | unsigned int tiling_mode : 2; | ||
702 | |||
703 | /** How many users have pinned this object in GTT space. The following | ||
704 | * users can each hold at most one reference: pwrite/pread, pin_ioctl | ||
705 | * (via user_pin_count), execbuffer (objects are not allowed multiple | ||
706 | * times for the same batchbuffer), and the framebuffer code. When | ||
707 | * switching/pageflipping, the framebuffer code has at most two buffers | ||
708 | * pinned per crtc. | ||
709 | * | ||
710 | * In the worst case this is 1 + 1 + 1 + 2*2 = 7. That would fit into 3 | ||
711 | * bits with absolutely no headroom. So use 4 bits. */ | ||
712 | int pin_count : 4; | ||
713 | #define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf | ||
668 | 714 | ||
669 | /** AGP memory structure for our GTT binding. */ | 715 | /** AGP memory structure for our GTT binding. */ |
670 | DRM_AGP_MEM *agp_mem; | 716 | DRM_AGP_MEM *agp_mem; |
671 | 717 | ||
672 | struct page **pages; | 718 | struct page **pages; |
673 | int pages_refcount; | ||
674 | 719 | ||
675 | /** | 720 | /** |
676 | * Current offset of the object in GTT space. | 721 | * Current offset of the object in GTT space. |
@@ -687,21 +732,10 @@ struct drm_i915_gem_object { | |||
687 | */ | 732 | */ |
688 | uint64_t mmap_offset; | 733 | uint64_t mmap_offset; |
689 | 734 | ||
690 | /** | ||
691 | * Fence register bits (if any) for this object. Will be set | ||
692 | * as needed when mapped into the GTT. | ||
693 | * Protected by dev->struct_mutex. | ||
694 | */ | ||
695 | int fence_reg; | ||
696 | |||
697 | /** How many users have pinned this object in GTT space */ | ||
698 | int pin_count; | ||
699 | |||
700 | /** Breadcrumb of last rendering to the buffer. */ | 735 | /** Breadcrumb of last rendering to the buffer. */ |
701 | uint32_t last_rendering_seqno; | 736 | uint32_t last_rendering_seqno; |
702 | 737 | ||
703 | /** Current tiling mode for the object. */ | 738 | /** Current tiling stride for the object, if it's tiled. */ |
704 | uint32_t tiling_mode; | ||
705 | uint32_t stride; | 739 | uint32_t stride; |
706 | 740 | ||
707 | /** Record of address bit 17 of each page at last unbind. */ | 741 | /** Record of address bit 17 of each page at last unbind. */ |
@@ -724,17 +758,6 @@ struct drm_i915_gem_object { | |||
724 | struct drm_i915_gem_phys_object *phys_obj; | 758 | struct drm_i915_gem_phys_object *phys_obj; |
725 | 759 | ||
726 | /** | 760 | /** |
727 | * Used for checking the object doesn't appear more than once | ||
728 | * in an execbuffer object list. | ||
729 | */ | ||
730 | int in_execbuffer; | ||
731 | |||
732 | /** | ||
733 | * Advice: are the backing pages purgeable? | ||
734 | */ | ||
735 | int madv; | ||
736 | |||
737 | /** | ||
738 | * Number of crtcs where this object is currently the fb, but | 761 | * Number of crtcs where this object is currently the fb, but |
739 | * will be page flipped away on the next vblank. When it | 762 | * will be page flipped away on the next vblank. When it |
740 | * reaches 0, dev_priv->pending_flip_queue will be woken up. | 763 | * reaches 0, dev_priv->pending_flip_queue will be woken up. |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c51495f15718..bf703551343a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -2247,6 +2247,9 @@ i915_gem_object_get_pages(struct drm_gem_object *obj, | |||
2247 | struct inode *inode; | 2247 | struct inode *inode; |
2248 | struct page *page; | 2248 | struct page *page; |
2249 | 2249 | ||
2250 | BUG_ON(obj_priv->pages_refcount | ||
2251 | == DRM_I915_GEM_OBJECT_MAX_PAGES_REFCOUNT); | ||
2252 | |||
2250 | if (obj_priv->pages_refcount++ != 0) | 2253 | if (obj_priv->pages_refcount++ != 0) |
2251 | return 0; | 2254 | return 0; |
2252 | 2255 | ||
@@ -4156,6 +4159,8 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | |||
4156 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 4159 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
4157 | int ret; | 4160 | int ret; |
4158 | 4161 | ||
4162 | BUG_ON(obj_priv->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT); | ||
4163 | |||
4159 | i915_verify_inactive(dev, __FILE__, __LINE__); | 4164 | i915_verify_inactive(dev, __FILE__, __LINE__); |
4160 | if (obj_priv->gtt_space == NULL) { | 4165 | if (obj_priv->gtt_space == NULL) { |
4161 | ret = i915_gem_object_bind_to_gtt(obj, alignment); | 4166 | ret = i915_gem_object_bind_to_gtt(obj, alignment); |