0,0 → 1,239 |
|
#include "state_tracker/drm_driver.h" |
#include "i915_drm_winsys.h" |
#include "util/u_memory.h" |
|
#include "i915_drm.h" |
|
static char *i915_drm_type_to_name(enum i915_winsys_buffer_type type) |
{ |
char *name; |
|
if (type == I915_NEW_TEXTURE) { |
name = "gallium3d_texture"; |
} else if (type == I915_NEW_VERTEX) { |
name = "gallium3d_vertex"; |
} else if (type == I915_NEW_SCANOUT) { |
name = "gallium3d_scanout"; |
} else { |
assert(0); |
name = "gallium3d_unknown"; |
} |
|
return name; |
} |
|
static struct i915_winsys_buffer * |
i915_drm_buffer_create(struct i915_winsys *iws, |
unsigned size, |
enum i915_winsys_buffer_type type) |
{ |
struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer); |
struct i915_drm_winsys *idws = i915_drm_winsys(iws); |
|
if (!buf) |
return NULL; |
|
buf->magic = 0xDEAD1337; |
buf->flinked = FALSE; |
buf->flink = 0; |
|
buf->bo = drm_intel_bo_alloc(idws->gem_manager, |
i915_drm_type_to_name(type), size, 0); |
|
if (!buf->bo) |
goto err; |
|
return (struct i915_winsys_buffer *)buf; |
|
err: |
assert(0); |
FREE(buf); |
return NULL; |
} |
|
static struct i915_winsys_buffer * |
i915_drm_buffer_create_tiled(struct i915_winsys *iws, |
unsigned *stride, unsigned height, |
enum i915_winsys_buffer_tile *tiling, |
enum i915_winsys_buffer_type type) |
{ |
struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer); |
struct i915_drm_winsys *idws = i915_drm_winsys(iws); |
unsigned long pitch = 0; |
uint32_t tiling_mode = *tiling; |
|
if (!buf) |
return NULL; |
|
buf->magic = 0xDEAD1337; |
buf->flinked = FALSE; |
buf->flink = 0; |
|
buf->bo = drm_intel_bo_alloc_tiled(idws->gem_manager, |
i915_drm_type_to_name(type), |
*stride, height, 1, |
&tiling_mode, &pitch, 0); |
|
if (!buf->bo) |
goto err; |
|
*stride = pitch; |
*tiling = tiling_mode; |
return (struct i915_winsys_buffer *)buf; |
|
err: |
assert(0); |
FREE(buf); |
return NULL; |
} |
|
static struct i915_winsys_buffer * |
i915_drm_buffer_from_handle(struct i915_winsys *iws, |
struct winsys_handle *whandle, |
enum i915_winsys_buffer_tile *tiling, |
unsigned *stride) |
{ |
struct i915_drm_winsys *idws = i915_drm_winsys(iws); |
struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer); |
uint32_t tile = 0, swizzle = 0; |
|
if (!buf) |
return NULL; |
|
buf->magic = 0xDEAD1337; |
buf->bo = drm_intel_bo_gem_create_from_name(idws->gem_manager, "gallium3d_from_handle", whandle->handle); |
buf->flinked = TRUE; |
buf->flink = whandle->handle; |
|
if (!buf->bo) |
goto err; |
|
drm_intel_bo_get_tiling(buf->bo, &tile, &swizzle); |
|
*stride = whandle->stride; |
*tiling = tile; |
|
return (struct i915_winsys_buffer *)buf; |
|
err: |
FREE(buf); |
return NULL; |
} |
|
static boolean |
i915_drm_buffer_get_handle(struct i915_winsys *iws, |
struct i915_winsys_buffer *buffer, |
struct winsys_handle *whandle, |
unsigned stride) |
{ |
struct i915_drm_buffer *buf = i915_drm_buffer(buffer); |
|
if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { |
if (!buf->flinked) { |
if (drm_intel_bo_flink(buf->bo, &buf->flink)) |
return FALSE; |
buf->flinked = TRUE; |
} |
|
whandle->handle = buf->flink; |
} else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) { |
whandle->handle = buf->bo->handle; |
} else { |
assert(!"unknown usage"); |
return FALSE; |
} |
|
whandle->stride = stride; |
return TRUE; |
} |
|
static void * |
i915_drm_buffer_map(struct i915_winsys *iws, |
struct i915_winsys_buffer *buffer, |
boolean write) |
{ |
struct i915_drm_buffer *buf = i915_drm_buffer(buffer); |
drm_intel_bo *bo = intel_bo(buffer); |
int ret = 0; |
|
assert(bo); |
|
if (buf->map_count) |
goto out; |
|
ret = drm_intel_gem_bo_map_gtt(bo); |
|
buf->ptr = bo->virtual; |
|
assert(ret == 0); |
out: |
if (ret) |
return NULL; |
|
buf->map_count++; |
return buf->ptr; |
} |
|
static void |
i915_drm_buffer_unmap(struct i915_winsys *iws, |
struct i915_winsys_buffer *buffer) |
{ |
struct i915_drm_buffer *buf = i915_drm_buffer(buffer); |
|
if (--buf->map_count) |
return; |
|
drm_intel_gem_bo_unmap_gtt(intel_bo(buffer)); |
} |
|
static int |
i915_drm_buffer_write(struct i915_winsys *iws, |
struct i915_winsys_buffer *buffer, |
size_t offset, |
size_t size, |
const void *data) |
{ |
struct i915_drm_buffer *buf = i915_drm_buffer(buffer); |
|
return drm_intel_bo_subdata(buf->bo, offset, size, (void*)data); |
} |
|
static void |
i915_drm_buffer_destroy(struct i915_winsys *iws, |
struct i915_winsys_buffer *buffer) |
{ |
drm_intel_bo_unreference(intel_bo(buffer)); |
|
#ifdef DEBUG |
i915_drm_buffer(buffer)->magic = 0; |
i915_drm_buffer(buffer)->bo = NULL; |
#endif |
|
FREE(buffer); |
} |
|
static boolean |
i915_drm_buffer_is_busy(struct i915_winsys *iws, |
struct i915_winsys_buffer *buffer) |
{ |
struct i915_drm_buffer* i915_buffer = i915_drm_buffer(buffer); |
if (!i915_buffer) |
return FALSE; |
return drm_intel_bo_busy(i915_buffer->bo); |
} |
|
|
void |
i915_drm_winsys_init_buffer_functions(struct i915_drm_winsys *idws) |
{ |
idws->base.buffer_create = i915_drm_buffer_create; |
idws->base.buffer_create_tiled = i915_drm_buffer_create_tiled; |
idws->base.buffer_from_handle = i915_drm_buffer_from_handle; |
idws->base.buffer_get_handle = i915_drm_buffer_get_handle; |
idws->base.buffer_map = i915_drm_buffer_map; |
idws->base.buffer_unmap = i915_drm_buffer_unmap; |
idws->base.buffer_write = i915_drm_buffer_write; |
idws->base.buffer_destroy = i915_drm_buffer_destroy; |
idws->base.buffer_is_busy = i915_drm_buffer_is_busy; |
} |