| |   |
| 42 | 42 | #include "droid.h" |
| 43 | 43 | #include "droid_ui.h" |
| 44 | 44 | |
| #define INTEL_IS_I965(x) ((x) & INTEL_GEN_4) |
| #define INTEL_IS_I915(x) ((x) & INTEL_GEN_3) |
| #define INTEL_IS_I9xx(x) ((x) & (INTEL_GEN_3 | INTEL_GEN_4)) |
| #define INTEL_IS_I8xx(x) ((x) & (INTEL_GEN_1 | INTEL_GEN_2)) |
|
| 45 | 50 | #define INTEL_STRIDE_ALIGNMENT 64 |
| 46 | 51 | |
| #define INTEL_HAS_128_BYTE_Y_TILING(x) \ |
| (((x) & (INTEL_GEN_3 | INTEL_GEN_4 | INTEL_GEN_MINOR_MASK)) > INTEL_GEN_3) |
|
| 47 | 55 | enum { |
| 48 | 56 | INTEL_SURFACE_TYPE_WINDOW, |
| 49 | 57 | INTEL_SURFACE_TYPE_IMAGE, |
| 50 | 58 | }; |
| 51 | 59 | |
| /* Look at xf86-video-intel/src/common.h for the full horror of device |
| * identification. |
| */ |
| enum { |
| INTEL_GEN_1 = 0x10, |
| INTEL_GEN_2 = 0x20, |
| INTEL_GEN_3 = 0x40, |
| INTEL_GEN_31 = 0x41, |
| INTEL_GEN_4 = 0x80, |
|
| INTEL_GEN_MAJOR_MASK = 0xf0, |
| INTEL_GEN_MINOR_MASK = 0x0f, |
| }; |
|
| 52 | 74 | struct droid_backend_intel { |
| 53 | 75 | struct droid_backend base; |
| 54 | 76 | int fd; |
| … | … | |
| 132 | 132 | return (value + align - 1) & ~(align - 1); |
| 133 | 133 | } |
| 134 | 134 | |
| static uint32_t |
| tiling_stride(int dev, int tiling_mode, uint32_t pitch) |
| { |
| uint32_t tile_width; |
|
| if (tiling_mode == I915_TILING_NONE) |
| return pitch; |
|
| if (tiling_mode == I915_TILING_Y && INTEL_HAS_128_BYTE_Y_TILING(dev)) |
| tile_width = 128; |
| else |
| tile_width = 512; |
|
| /* 965+ just needs multiples of tile width */ |
| if (INTEL_IS_I965(dev)) |
| return align_to(pitch, tile_width); |
|
| /* Pre-965 needs power of two tile widths */ |
| while (tile_width < pitch) |
| tile_width <<= 1; |
|
| return tile_width; |
| } |
|
| static uint32_t |
| tiling_size(int dev, uint32_t tiling, uint32_t size) |
| { |
| uint32_t fence; |
|
| if (tiling == I915_TILING_NONE) |
| return size; |
|
| /* The 965 can have fences at any page boundary. */ |
| if (INTEL_IS_I965(dev)) |
| return align_to(size, 4096); |
|
| /* Align the size to a power of two greater than the smallest fence. */ |
| if (INTEL_IS_I9xx(dev)) |
| fence = 1024 * 1024; /* 1 MiB */ |
| else |
| fence = 512 * 1024; /* 512 KiB */ |
| while (fence < size) |
| fence <<= 1; |
|
| return fence; |
| } |
|
| 135 | 182 | static int |
| 136 | 183 | create_buffer(int fd, GLint width, GLint height, GLint cpp, __DRIbuffer *buffer) |
| 137 | 184 | { |
| 138 | 185 | struct drm_i915_gem_create create; |
| 139 | 186 | struct drm_gem_flink flink; |
| 140 | 187 | uint32_t size; |
| int tiling; |
| int dev = INTEL_GEN_4; /* XXX query using I915_GETPARAM + PARAM_CHIPSET_ID */ |
| 141 | 190 | |
| tiling = I915_TILING_X; |
| 142 | 192 | buffer->pitch = align_to(width * cpp, INTEL_STRIDE_ALIGNMENT); |
| size = buffer->pitch * height; |
| if (tiling != I915_TILING_NONE) { |
| buffer->pitch = tiling_stride(dev, tiling, buffer->pitch); |
| size = buffer->pitch * height; |
| size = tiling_size(dev, tiling, size); |
| } else { |
| size = buffer->pitch * height; |
| } |
|
| 144 | 201 | create.size = size; |
| 145 | 202 | if (ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create)) { |
| 146 | 203 | LOGE("failed to create buffer"); |
| 147 | 204 | return 0; |
| } |
|
| if (tiling != I915_TILING_NONE) { |
| struct drm_i915_gem_set_tiling set_tiling; |
|
| memset(&set_tiling, 0, sizeof(set_tiling)); |
| set_tiling.handle = create.handle; |
| set_tiling.tiling_mode = tiling; |
| set_tiling.stride = buffer->pitch; |
|
| if (ioctl(fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling)) |
| LOGW("failed to enable tiling"); |
| 148 | 217 | } |
| 149 | 218 | |
| 150 | 219 | flink.handle = create.handle; |