Commit ef1a6243ef110b0b5fbaa81d74003db5d5d33c0d
- Diff rendering mode:
- inline
- side by side
src/egl/drivers/android/droid_intel.c
(103 / 56)
|   | |||
| 47 | 47 | #define INTEL_IS_I9xx(x) ((x) & (INTEL_GEN_3 | INTEL_GEN_4)) | |
| 48 | 48 | #define INTEL_IS_I8xx(x) ((x) & (INTEL_GEN_1 | INTEL_GEN_2)) | |
| 49 | 49 | ||
| 50 | #define INTEL_STRIDE_ALIGNMENT 64 | ||
| 51 | |||
| 52 | 50 | #define INTEL_HAS_128_BYTE_Y_TILING(x) \ | |
| 53 | 51 | (((x) & (INTEL_GEN_3 | INTEL_GEN_4 | INTEL_GEN_MINOR_MASK)) > INTEL_GEN_3) | |
| 54 | 52 | ||
| … | … | ||
| 73 | 73 | struct droid_backend base; | |
| 74 | 74 | int fd; | |
| 75 | 75 | int screen_number; | |
| 76 | |||
| 77 | uint32_t generation; | ||
| 78 | int pitch_align; | ||
| 79 | int enable_tiling; | ||
| 76 | 80 | }; | |
| 77 | 81 | ||
| 78 | 82 | struct droid_surface_intel { | |
| … | … | ||
| 128 | 128 | return &isurf->native_buffer; | |
| 129 | 129 | } | |
| 130 | 130 | ||
| 131 | static inline uint32_t | ||
| 131 | static INLINE uint32_t | ||
| 132 | 132 | align_to(uint32_t value, uint32_t align) | |
| 133 | 133 | { | |
| 134 | 134 | return (value + align - 1) & ~(align - 1); | |
| 135 | 135 | } | |
| 136 | 136 | ||
| 137 | static uint32_t | ||
| 138 | tiling_stride(int dev, int tiling_mode, uint32_t pitch) | ||
| 137 | static INLINE int | ||
| 138 | fence_pitch(struct droid_backend *backend, int pitch, int tiling) | ||
| 139 | 139 | { | |
| 140 | uint32_t tile_width; | ||
| 140 | struct droid_backend_intel *intel = lookup_backend(backend); | ||
| 141 | int pitch_align, tile_width; | ||
| 141 | 142 | ||
| 142 | if (tiling_mode == I915_TILING_NONE) | ||
| 143 | return pitch; | ||
| 144 | |||
| 145 | if (tiling_mode == I915_TILING_Y && INTEL_HAS_128_BYTE_Y_TILING(dev)) | ||
| 146 | tile_width = 128; | ||
| 147 | else | ||
| 143 | switch (tiling) { | ||
| 144 | case I915_TILING_NONE: | ||
| 145 | default: | ||
| 146 | pitch_align = intel->pitch_align; | ||
| 147 | tile_width = 1; /* not used */ | ||
| 148 | break; | ||
| 149 | case I915_TILING_X: | ||
| 150 | pitch_align = 512; | ||
| 148 | 151 | tile_width = 512; | |
| 152 | break; | ||
| 153 | case I915_TILING_Y: | ||
| 154 | pitch_align = 512; | ||
| 155 | tile_width = | ||
| 156 | (INTEL_HAS_128_BYTE_Y_TILING(intel->generation)) ? 128 : 512; | ||
| 157 | break; | ||
| 158 | } | ||
| 149 | 159 | ||
| 160 | pitch = align_to(pitch, pitch_align); | ||
| 161 | if (tiling == I915_TILING_NONE) | ||
| 162 | return pitch; | ||
| 163 | |||
| 150 | 164 | /* 965+ just needs multiples of tile width */ | |
| 151 | if (INTEL_IS_I965(dev)) | ||
| 152 | return align_to(pitch, tile_width); | ||
| 165 | if (INTEL_IS_I965(intel->generation)) { | ||
| 166 | pitch = align_to(pitch, tile_width); | ||
| 167 | } | ||
| 168 | else { | ||
| 169 | /* Pre-965 needs power of two tile widths */ | ||
| 170 | while (tile_width < pitch) | ||
| 171 | tile_width <<= 1; | ||
| 172 | pitch = tile_width; | ||
| 173 | } | ||
| 153 | 174 | ||
| 154 | /* Pre-965 needs power of two tile widths */ | ||
| 155 | while (tile_width < pitch) | ||
| 156 | tile_width <<= 1; | ||
| 157 | |||
| 158 | return tile_width; | ||
| 175 | return pitch; | ||
| 159 | 176 | } | |
| 160 | 177 | ||
| 161 | static uint32_t | ||
| 162 | tiling_size(int dev, uint32_t tiling, uint32_t size) | ||
| 178 | static INLINE uint32_t | ||
| 179 | fence_size(struct droid_backend *backend, int height, int pitch, int tiling) | ||
| 163 | 180 | { | |
| 164 | uint32_t fence; | ||
| 181 | struct droid_backend_intel *intel = lookup_backend(backend); | ||
| 182 | int height_align; | ||
| 183 | uint32_t size; | ||
| 165 | 184 | ||
| 185 | switch (tiling) { | ||
| 186 | case I915_TILING_NONE: | ||
| 187 | default: | ||
| 188 | /* Round the height up so that the GPU's access to a 2x2 aligned | ||
| 189 | * subspan doesn't address an invalid page offset beyond the | ||
| 190 | * end of the GTT. | ||
| 191 | */ | ||
| 192 | height_align = 2; | ||
| 193 | break; | ||
| 194 | case I915_TILING_X: | ||
| 195 | height_align = 8; | ||
| 196 | break; | ||
| 197 | case I915_TILING_Y: | ||
| 198 | height_align = 32; | ||
| 199 | break; | ||
| 200 | } | ||
| 201 | |||
| 202 | height = align_to(height, height_align); | ||
| 203 | size = pitch * height; | ||
| 166 | 204 | if (tiling == I915_TILING_NONE) | |
| 167 | 205 | return size; | |
| 168 | 206 | ||
| 169 | 207 | /* The 965 can have fences at any page boundary. */ | |
| 170 | if (INTEL_IS_I965(dev)) | ||
| 171 | return align_to(size, 4096); | ||
| 208 | if (INTEL_IS_I965(intel->generation)) { | ||
| 209 | size = align_to(size, 4096); | ||
| 210 | } | ||
| 211 | else { | ||
| 212 | uint32_t fence; | ||
| 172 | 213 | ||
| 173 | /* Align the size to a power of two greater than the smallest fence. */ | ||
| 174 | if (INTEL_IS_I9xx(dev)) | ||
| 175 | fence = 1024 * 1024; /* 1 MiB */ | ||
| 176 | else | ||
| 177 | fence = 512 * 1024; /* 512 KiB */ | ||
| 178 | while (fence < size) | ||
| 179 | fence <<= 1; | ||
| 214 | /* Align the size to a power of two greater than the smallest fence. */ | ||
| 215 | if (INTEL_IS_I9xx(intel->generation)) | ||
| 216 | fence = 1 << 20; /* 1 MiB */ | ||
| 217 | else | ||
| 218 | fence = 1 << 19; /* 512 KiB */ | ||
| 180 | 219 | ||
| 181 | return fence; | ||
| 220 | while (fence < size) | ||
| 221 | fence <<= 1; | ||
| 222 | |||
| 223 | size = fence; | ||
| 224 | } | ||
| 225 | |||
| 226 | return size; | ||
| 182 | 227 | } | |
| 183 | 228 | ||
| 184 | 229 | static int | |
| 185 | create_buffer(int fd, GLint width, GLint height, GLint cpp, __DRIbuffer *buffer) | ||
| 230 | create_buffer(struct droid_backend *backend, __DRIbuffer *buffer, | ||
| 231 | int width, int height, int cpp, int tiling) | ||
| 186 | 232 | { | |
| 233 | struct droid_backend_intel *intel = lookup_backend(backend); | ||
| 187 | 234 | struct drm_i915_gem_create create; | |
| 188 | 235 | struct drm_gem_flink flink; | |
| 189 | uint32_t size; | ||
| 190 | int tiling; | ||
| 191 | int dev = INTEL_GEN_4; /* XXX query using I915_GETPARAM + PARAM_CHIPSET_ID */ | ||
| 192 | 236 | ||
| 193 | tiling = I915_TILING_X; | ||
| 194 | buffer->pitch = align_to(width * cpp, INTEL_STRIDE_ALIGNMENT); | ||
| 195 | if (tiling != I915_TILING_NONE) { | ||
| 196 | buffer->pitch = tiling_stride(dev, tiling, buffer->pitch); | ||
| 197 | size = buffer->pitch * height; | ||
| 198 | size = tiling_size(dev, tiling, size); | ||
| 199 | } else { | ||
| 200 | size = buffer->pitch * height; | ||
| 201 | } | ||
| 202 | |||
| 203 | create.size = size; | ||
| 204 | if (ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create)) { | ||
| 237 | buffer->pitch = fence_pitch(backend, width * cpp, tiling); | ||
| 238 | create.size = fence_size(backend, height, buffer->pitch, tiling); | ||
| 239 | if (ioctl(intel->fd, DRM_IOCTL_I915_GEM_CREATE, &create)) { | ||
| 205 | 240 | LOGE("failed to create buffer"); | |
| 206 | 241 | return 0; | |
| 207 | 242 | } | |
| … | … | ||
| 249 | 249 | set_tiling.tiling_mode = tiling; | |
| 250 | 250 | set_tiling.stride = buffer->pitch; | |
| 251 | 251 | ||
| 252 | if (ioctl(fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling)) | ||
| 252 | if (ioctl(intel->fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling)) | ||
| 253 | 253 | LOGW("failed to enable tiling"); | |
| 254 | 254 | } | |
| 255 | 255 | ||
| 256 | 256 | flink.handle = create.handle; | |
| 257 | if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) { | ||
| 257 | if (ioctl(intel->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) { | ||
| 258 | 258 | LOGE("failed to flink buffer"); | |
| 259 | 259 | return 0; | |
| 260 | 260 | } | |
| … | … | ||
| 348 | 348 | isurf->handles[reuse] = 0; | |
| 349 | 349 | } | |
| 350 | 350 | else { | |
| 351 | int tiling = | ||
| 352 | (intel->enable_tiling) ? I915_TILING_X : I915_TILING_NONE; | ||
| 353 | |||
| 351 | 354 | buffers[num].attachment = att; | |
| 352 | 355 | ||
| 353 | 356 | if (isurf->type == INTEL_SURFACE_TYPE_IMAGE && | |
| … | … | ||
| 360 | 360 | handles[num] = 0; | |
| 361 | 361 | } else { | |
| 362 | 362 | buffers[num].attachment = att; | |
| 363 | handles[num] = create_buffer(intel->fd, | ||
| 364 | isurf->native_width, | ||
| 365 | isurf->native_height, | ||
| 366 | cpp, | ||
| 367 | &buffers[num]); | ||
| 363 | handles[num] = create_buffer(backend, &buffers[num], | ||
| 364 | isurf->native_width, | ||
| 365 | isurf->native_height, | ||
| 366 | cpp, | ||
| 367 | tiling); | ||
| 368 | 368 | } | |
| 369 | 369 | } | |
| 370 | 370 | num++; | |
| 371 | 371 | } | |
| 372 | 372 | ||
| 373 | /* delete buffers that are not re-used */ | ||
| 373 | /* delete old buffers that are not re-used */ | ||
| 374 | 374 | delete_buffers(backend, surf); | |
| 375 | 375 | ||
| 376 | 376 | memcpy(isurf->buffers, buffers, sizeof(buffers[0]) * num); | |
| … | … | ||
| 585 | 585 | } | |
| 586 | 586 | ||
| 587 | 587 | intel->screen_number = 0; | |
| 588 | |||
| 589 | /* XXX query using I915_GETPARAM + PARAM_CHIPSET_ID */ | ||
| 590 | intel->generation = INTEL_GEN_3; | ||
| 591 | |||
| 592 | intel->pitch_align = 64; | ||
| 593 | intel->enable_tiling = 1; | ||
| 594 | |||
| 588 | 595 | intel->base.driver_name = "i915"; | |
| 589 | 596 | intel->base.initialize = intel_initialize; | |
| 590 | 597 | intel->base.destroy = intel_destroy; |

