diff options
Diffstat (limited to 'src/gallium/winsys/drm/intel/gem/intel_be_device.c')
-rw-r--r-- | src/gallium/winsys/drm/intel/gem/intel_be_device.c | 76 |
1 files changed, 65 insertions, 11 deletions
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.c b/src/gallium/winsys/drm/intel/gem/intel_be_device.c index 907ac86637..c7e88271ec 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_device.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.c @@ -16,6 +16,8 @@ #include "intel_be_api.h" #include <stdio.h> +#define I915_TILING_X 1 + /* * Buffer */ @@ -25,9 +27,10 @@ intel_be_buffer_map(struct pipe_winsys *winsys, struct pipe_buffer *buf, unsigned flags) { + struct intel_be_buffer *buffer = intel_be_buffer(buf); drm_intel_bo *bo = intel_bo(buf); int write = 0; - int ret; + int ret = 0; if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) { /* Remove this when drm_intel_bo_map supports DONTBLOCK @@ -38,19 +41,37 @@ intel_be_buffer_map(struct pipe_winsys *winsys, if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) write = 1; - ret = drm_intel_bo_map(bo, write); + if (buffer->map_count) + goto out; + + if (buffer->map_gtt) + ret = drm_intel_gem_bo_map_gtt(bo); + else + ret = drm_intel_bo_map(bo, write); + + buffer->ptr = bo->virtual; +out: if (ret) return NULL; - return bo->virtual; + buffer->map_count++; + return buffer->ptr; } static void intel_be_buffer_unmap(struct pipe_winsys *winsys, struct pipe_buffer *buf) { - drm_intel_bo_unmap(intel_bo(buf)); + struct intel_be_buffer *buffer = intel_be_buffer(buf); + + if (--buffer->map_count) + return; + + if (buffer->map_gtt) + drm_intel_gem_bo_unmap_gtt(intel_bo(buf)); + else + drm_intel_bo_unmap(intel_bo(buf)); } static void @@ -80,8 +101,13 @@ intel_be_buffer_create(struct pipe_winsys *winsys, buffer->base.size = size; buffer->flinked = FALSE; buffer->flink = 0; + buffer->map_gtt = FALSE; - if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) { + if (usage & I915_BUFFER_USAGE_SCANOUT) { + /* Scanout buffer */ + name = "gallium3d_scanout"; + pool = dev->pools.gem; + } else if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) { /* Local buffer */ name = "gallium3d_local"; pool = dev->pools.gem; @@ -96,6 +122,12 @@ intel_be_buffer_create(struct pipe_winsys *winsys, } buffer->bo = drm_intel_bo_alloc(pool, name, size, alignment); + if (usage & I915_BUFFER_USAGE_SCANOUT) { + unsigned tiling = I915_TILING_X; + unsigned stride = 2048 * 4; /* TODO do something smarter here */ + drm_intel_bo_set_tiling(buffer->bo, &tiling, stride); + buffer->map_gtt = TRUE; + } if (!buffer->bo) goto err; @@ -142,8 +174,27 @@ err: return NULL; } +boolean +intel_be_get_texture_buffer(struct drm_api *api, + struct pipe_texture *texture, + struct pipe_buffer **buffer, + unsigned *stride) +{ + struct intel_be_device *dev; + + if (!texture) + return FALSE; + + dev = intel_be_device(texture->screen->winsys); + if (dev->softpipe) + return softpipe_get_texture_buffer(texture, buffer, stride); + else + return i915_get_texture_buffer(texture, buffer, stride); +} + struct pipe_buffer * -intel_be_buffer_from_handle(struct pipe_screen *screen, +intel_be_buffer_from_handle(struct drm_api *api, + struct pipe_screen *screen, const char* name, unsigned handle) { struct intel_be_device *dev = intel_be_device(screen->winsys); @@ -174,7 +225,8 @@ err: } boolean -intel_be_handle_from_buffer(struct pipe_screen *screen, +intel_be_handle_from_buffer(struct drm_api *api, + struct pipe_screen *screen, struct pipe_buffer *buffer, unsigned *handle) { @@ -186,7 +238,8 @@ intel_be_handle_from_buffer(struct pipe_screen *screen, } boolean -intel_be_global_handle_from_buffer(struct pipe_screen *screen, +intel_be_global_handle_from_buffer(struct drm_api *api, + struct pipe_screen *screen, struct pipe_buffer *buffer, unsigned *handle) { @@ -296,6 +349,7 @@ intel_be_get_device_id(unsigned int *device_id) { char path[512]; FILE *file; + void *shutup_gcc; /* * FIXME: Fix this up to use a drm ioctl or whatever. @@ -307,13 +361,14 @@ intel_be_get_device_id(unsigned int *device_id) return; } - fgets(path, sizeof(path), file); + shutup_gcc = fgets(path, sizeof(path), file); sscanf(path, "%x", device_id); fclose(file); } struct pipe_screen * -intel_be_create_screen(int drmFD, struct drm_create_screen_arg *arg) +intel_be_create_screen(struct drm_api *api, int drmFD, + struct drm_create_screen_arg *arg) { struct intel_be_device *dev; struct pipe_screen *screen; @@ -339,7 +394,6 @@ intel_be_create_screen(int drmFD, struct drm_create_screen_arg *arg) if (dev->softpipe) { screen = softpipe_create_screen(&dev->base); - drm_api_hooks.buffer_from_texture = softpipe_get_texture_buffer; } else screen = i915_create_screen(&dev->base, deviceID); |