i915g: Treat primary textures as scanout buffers
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user