summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/i915simple/i915_texture.c25
-rw-r--r--src/gallium/drivers/i915simple/i915_winsys.h1
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_device.c42
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_device.h4
4 files changed, 58 insertions, 14 deletions
diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c
index ca8e87af8d1..ac38bb50ac6 100644
--- a/src/gallium/drivers/i915simple/i915_texture.c
+++ b/src/gallium/drivers/i915simple/i915_texture.c
@@ -160,10 +160,10 @@ i915_miptree_set_image_offset(struct i915_texture *tex,
/**
- * Special case to deal with display targets.
+ * Special case to deal with scanout textures.
*/
static boolean
-i915_displaytarget_layout(struct i915_texture *tex)
+i915_scanout_layout(struct i915_texture *tex)
{
struct pipe_texture *pt = &tex->base;
@@ -177,9 +177,13 @@ i915_displaytarget_layout(struct i915_texture *tex)
i915_miptree_set_image_offset( tex, 0, 0, 0, 0 );
if (tex->base.width[0] >= 128) {
+#if 0
tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size);
+#else
+ tex->stride = 2048 * 4; /* TODO fix when backend is smarter */
+#endif
tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
-#if 0 /* used for tiled display targets */
+#if 0 /* used for tiled textures */
tex->tiled = 1;
#endif
} else {
@@ -209,9 +213,9 @@ i945_miptree_layout_2d( struct i915_texture *tex )
unsigned nblocksx = pt->nblocksx[0];
unsigned nblocksy = pt->nblocksy[0];
- /* used for tiled display targets */
- if (0)
- if (i915_displaytarget_layout(tex))
+ /* used for scanouts that need special layouts */
+ if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
+ if (i915_scanout_layout(tex))
return;
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
@@ -584,6 +588,7 @@ i915_texture_create(struct pipe_screen *screen,
struct i915_screen *i915screen = i915_screen(screen);
struct i915_texture *tex = CALLOC_STRUCT(i915_texture);
size_t tex_size;
+ unsigned buf_usage = 0;
if (!tex)
return NULL;
@@ -605,9 +610,11 @@ i915_texture_create(struct pipe_screen *screen,
tex_size = tex->stride * tex->total_nblocksy;
- tex->buffer = screen->buffer_create(screen, 64,
- PIPE_BUFFER_USAGE_PIXEL,
- tex_size);
+ buf_usage = PIPE_BUFFER_USAGE_PIXEL;
+ if (templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
+ buf_usage |= I915_BUFFER_USAGE_SCANOUT;
+
+ tex->buffer = screen->buffer_create(screen, 64, buf_usage, tex_size);
if (!tex->buffer)
goto fail;
diff --git a/src/gallium/drivers/i915simple/i915_winsys.h b/src/gallium/drivers/i915simple/i915_winsys.h
index ff5b34f193a..711db91c367 100644
--- a/src/gallium/drivers/i915simple/i915_winsys.h
+++ b/src/gallium/drivers/i915simple/i915_winsys.h
@@ -109,6 +109,7 @@ struct i915_winsys {
#define I915_BUFFER_ACCESS_READ 0x2
#define I915_BUFFER_USAGE_LIT_VERTEX (PIPE_BUFFER_USAGE_CUSTOM << 0)
+#define I915_BUFFER_USAGE_SCANOUT (PIPE_BUFFER_USAGE_CUSTOM << 1)
/**
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 e3630f5d120..c7e88271ec6 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;
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.h b/src/gallium/winsys/drm/intel/gem/intel_be_device.h
index 56d95bd7fe0..3f3f2a76a3d 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_device.h
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.h
@@ -47,6 +47,10 @@ intel_be_init_device(struct intel_be_device *device, int fd, unsigned id);
struct intel_be_buffer {
struct pipe_buffer base;
+ void *ptr;
+ unsigned map_count;
+ boolean map_gtt;
+
drm_intel_bo *bo;
boolean flinked;
unsigned flink;