i965g: Conversion to winsys handle
This commit is contained in:
parent
0e1eb1b876
commit
45089784e3
|
@ -303,6 +303,119 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct pipe_texture *
|
||||
brw_texture_from_handle(struct pipe_screen *screen,
|
||||
const struct pipe_texture *templ,
|
||||
struct winsys_handle *whandle)
|
||||
{
|
||||
struct brw_screen *bscreen = brw_screen(screen);
|
||||
struct brw_texture *tex;
|
||||
struct brw_winsys_buffer *buffer;
|
||||
unsigned tiling;
|
||||
unsigned pitch;
|
||||
|
||||
if (templ->target != PIPE_TEXTURE_2D ||
|
||||
templ->last_level != 0 ||
|
||||
templ->depth0 != 1)
|
||||
return NULL;
|
||||
|
||||
if (util_format_is_compressed(templ->format))
|
||||
return NULL;
|
||||
|
||||
tex = CALLOC_STRUCT(brw_texture);
|
||||
if (!tex)
|
||||
return NULL;
|
||||
|
||||
if (bscreen->sws->bo_from_handle(bscreen->sws, whandle, &pitch, &tiling, &buffer) != PIPE_OK)
|
||||
goto fail;
|
||||
|
||||
memcpy(&tex->base, templ, sizeof *templ);
|
||||
pipe_reference_init(&tex->base.reference, 1);
|
||||
tex->base.screen = screen;
|
||||
|
||||
/* XXX: cpp vs. blocksize
|
||||
*/
|
||||
tex->cpp = util_format_get_blocksize(tex->base.format);
|
||||
tex->tiling = tiling;
|
||||
|
||||
make_empty_list(&tex->views[0]);
|
||||
make_empty_list(&tex->views[1]);
|
||||
|
||||
if (!brw_texture_layout(bscreen, tex))
|
||||
goto fail;
|
||||
|
||||
/* XXX Maybe some more checks? */
|
||||
if ((pitch / tex->cpp) < tex->pitch)
|
||||
goto fail;
|
||||
|
||||
tex->pitch = pitch / tex->cpp;
|
||||
|
||||
tex->bo = buffer;
|
||||
|
||||
/* fix this warning */
|
||||
#if 0
|
||||
if (tex->size > buffer->size)
|
||||
goto fail;
|
||||
#endif
|
||||
|
||||
tex->ss.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
|
||||
tex->ss.ss0.surface_type = translate_tex_target(tex->base.target);
|
||||
tex->ss.ss0.surface_format = translate_tex_format(tex->base.format);
|
||||
assert(tex->ss.ss0.surface_format != BRW_SURFACEFORMAT_INVALID);
|
||||
|
||||
/* This is ok for all textures with channel width 8bit or less:
|
||||
*/
|
||||
/* tex->ss.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
|
||||
|
||||
|
||||
/* XXX: what happens when tex->bo->offset changes???
|
||||
*/
|
||||
tex->ss.ss1.base_addr = 0; /* reloc */
|
||||
tex->ss.ss2.mip_count = tex->base.last_level;
|
||||
tex->ss.ss2.width = tex->base.width0 - 1;
|
||||
tex->ss.ss2.height = tex->base.height0 - 1;
|
||||
|
||||
switch (tex->tiling) {
|
||||
case BRW_TILING_NONE:
|
||||
tex->ss.ss3.tiled_surface = 0;
|
||||
tex->ss.ss3.tile_walk = 0;
|
||||
break;
|
||||
case BRW_TILING_X:
|
||||
tex->ss.ss3.tiled_surface = 1;
|
||||
tex->ss.ss3.tile_walk = BRW_TILEWALK_XMAJOR;
|
||||
break;
|
||||
case BRW_TILING_Y:
|
||||
tex->ss.ss3.tiled_surface = 1;
|
||||
tex->ss.ss3.tile_walk = BRW_TILEWALK_YMAJOR;
|
||||
break;
|
||||
}
|
||||
|
||||
tex->ss.ss3.pitch = (tex->pitch * tex->cpp) - 1;
|
||||
tex->ss.ss3.depth = tex->base.depth0 - 1;
|
||||
|
||||
tex->ss.ss4.min_lod = 0;
|
||||
|
||||
return &tex->base;
|
||||
|
||||
fail:
|
||||
FREE(tex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static boolean
|
||||
brw_texture_get_handle(struct pipe_screen *screen,
|
||||
struct pipe_texture *texture,
|
||||
struct winsys_handle *whandle)
|
||||
{
|
||||
struct brw_screen *bscreen = brw_screen(screen);
|
||||
struct brw_texture *tex = brw_texture(texture);
|
||||
unsigned stride;
|
||||
|
||||
stride = tex->pitch * tex->cpp;
|
||||
|
||||
return bscreen->sws->bo_get_handle(tex->bo, whandle, stride);
|
||||
}
|
||||
|
||||
static struct pipe_texture *brw_texture_blanket(struct pipe_screen *screen,
|
||||
const struct pipe_texture *templ,
|
||||
const unsigned *stride,
|
||||
|
@ -451,125 +564,12 @@ brw_tex_transfer_destroy(struct pipe_transfer *trans)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Functions exported to the winsys
|
||||
*/
|
||||
|
||||
boolean brw_texture_get_winsys_buffer(struct pipe_texture *texture,
|
||||
struct brw_winsys_buffer **buffer,
|
||||
unsigned *stride)
|
||||
{
|
||||
struct brw_texture *tex = brw_texture(texture);
|
||||
|
||||
*buffer = tex->bo;
|
||||
if (stride)
|
||||
*stride = tex->pitch * tex->cpp;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
struct pipe_texture *
|
||||
brw_texture_blanket_winsys_buffer(struct pipe_screen *screen,
|
||||
const struct pipe_texture *templ,
|
||||
unsigned pitch,
|
||||
unsigned tiling,
|
||||
struct brw_winsys_buffer *buffer)
|
||||
{
|
||||
struct brw_screen *bscreen = brw_screen(screen);
|
||||
struct brw_texture *tex;
|
||||
GLuint format;
|
||||
|
||||
if (templ->target != PIPE_TEXTURE_2D ||
|
||||
templ->last_level != 0 ||
|
||||
templ->depth0 != 1)
|
||||
return NULL;
|
||||
|
||||
if (util_format_is_compressed(templ->format))
|
||||
return NULL;
|
||||
|
||||
tex = CALLOC_STRUCT(brw_texture);
|
||||
if (!tex)
|
||||
return NULL;
|
||||
|
||||
memcpy(&tex->base, templ, sizeof *templ);
|
||||
pipe_reference_init(&tex->base.reference, 1);
|
||||
tex->base.screen = screen;
|
||||
|
||||
/* XXX: cpp vs. blocksize
|
||||
*/
|
||||
tex->cpp = util_format_get_blocksize(tex->base.format);
|
||||
tex->tiling = tiling;
|
||||
|
||||
make_empty_list(&tex->views[0]);
|
||||
make_empty_list(&tex->views[1]);
|
||||
|
||||
if (!brw_texture_layout(bscreen, tex))
|
||||
goto fail;
|
||||
|
||||
/* XXX Maybe some more checks? */
|
||||
if ((pitch / tex->cpp) < tex->pitch)
|
||||
goto fail;
|
||||
|
||||
tex->pitch = pitch / tex->cpp;
|
||||
|
||||
tex->bo = buffer;
|
||||
|
||||
/* fix this warning */
|
||||
#if 0
|
||||
if (tex->size > buffer->size)
|
||||
goto fail;
|
||||
#endif
|
||||
|
||||
tex->ss.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
|
||||
tex->ss.ss0.surface_type = translate_tex_target(tex->base.target);
|
||||
|
||||
format = translate_tex_format(tex->base.format);
|
||||
assert(format != BRW_SURFACEFORMAT_INVALID);
|
||||
tex->ss.ss0.surface_format = format;
|
||||
|
||||
/* This is ok for all textures with channel width 8bit or less:
|
||||
*/
|
||||
/* tex->ss.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
|
||||
|
||||
|
||||
/* XXX: what happens when tex->bo->offset changes???
|
||||
*/
|
||||
tex->ss.ss1.base_addr = 0; /* reloc */
|
||||
tex->ss.ss2.mip_count = tex->base.last_level;
|
||||
tex->ss.ss2.width = tex->base.width0 - 1;
|
||||
tex->ss.ss2.height = tex->base.height0 - 1;
|
||||
|
||||
switch (tex->tiling) {
|
||||
case BRW_TILING_NONE:
|
||||
tex->ss.ss3.tiled_surface = 0;
|
||||
tex->ss.ss3.tile_walk = 0;
|
||||
break;
|
||||
case BRW_TILING_X:
|
||||
tex->ss.ss3.tiled_surface = 1;
|
||||
tex->ss.ss3.tile_walk = BRW_TILEWALK_XMAJOR;
|
||||
break;
|
||||
case BRW_TILING_Y:
|
||||
tex->ss.ss3.tiled_surface = 1;
|
||||
tex->ss.ss3.tile_walk = BRW_TILEWALK_YMAJOR;
|
||||
break;
|
||||
}
|
||||
|
||||
tex->ss.ss3.pitch = (tex->pitch * tex->cpp) - 1;
|
||||
tex->ss.ss3.depth = tex->base.depth0 - 1;
|
||||
|
||||
tex->ss.ss4.min_lod = 0;
|
||||
|
||||
return &tex->base;
|
||||
|
||||
fail:
|
||||
FREE(tex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void brw_screen_tex_init( struct brw_screen *brw_screen )
|
||||
{
|
||||
brw_screen->base.is_format_supported = brw_is_format_supported;
|
||||
brw_screen->base.texture_create = brw_texture_create;
|
||||
brw_screen->base.texture_from_handle = brw_texture_from_handle;
|
||||
brw_screen->base.texture_get_handle = brw_texture_get_handle;
|
||||
brw_screen->base.texture_destroy = brw_texture_destroy;
|
||||
brw_screen->base.texture_blanket = brw_texture_blanket;
|
||||
brw_screen->base.get_tex_transfer = brw_get_tex_transfer;
|
||||
|
|
|
@ -162,6 +162,16 @@ struct brw_winsys_screen {
|
|||
unsigned alignment,
|
||||
struct brw_winsys_buffer **bo_out);
|
||||
|
||||
enum pipe_error (*bo_from_handle)(struct brw_winsys_screen *sws,
|
||||
struct winsys_handle *whandle,
|
||||
unsigned *stride,
|
||||
unsigned *tiling,
|
||||
struct brw_winsys_buffer **bo_out);
|
||||
|
||||
enum pipe_error (*bo_get_handle)(struct brw_winsys_buffer *buffer,
|
||||
struct winsys_handle *whandle,
|
||||
unsigned stride);
|
||||
|
||||
/* Destroy a buffer when our refcount goes to zero:
|
||||
*/
|
||||
void (*bo_destroy)(struct brw_winsys_buffer *buffer);
|
||||
|
|
|
@ -37,129 +37,6 @@ i965_libdrm_get_device_id(unsigned int *device_id)
|
|||
fclose(file);
|
||||
}
|
||||
|
||||
static struct i965_libdrm_buffer *
|
||||
i965_libdrm_buffer_from_handle(struct i965_libdrm_winsys *idws,
|
||||
const char* name, unsigned handle)
|
||||
{
|
||||
struct i965_libdrm_buffer *buf = CALLOC_STRUCT(i965_libdrm_buffer);
|
||||
uint32_t swizzle = 0;
|
||||
|
||||
if (BRW_DUMP)
|
||||
debug_printf("%s\n", __FUNCTION__);
|
||||
|
||||
if (!buf)
|
||||
return NULL;
|
||||
pipe_reference_init(&buf->base.reference, 1);
|
||||
buf->bo = drm_intel_bo_gem_create_from_name(idws->gem, name, handle);
|
||||
buf->base.size = buf->bo->size;
|
||||
buf->base.sws = &idws->base;
|
||||
buf->flinked = TRUE;
|
||||
buf->flink = handle;
|
||||
|
||||
|
||||
if (!buf->bo)
|
||||
goto err;
|
||||
|
||||
drm_intel_bo_get_tiling(buf->bo, &buf->tiling, &swizzle);
|
||||
if (buf->tiling != 0)
|
||||
buf->map_gtt = TRUE;
|
||||
|
||||
return buf;
|
||||
|
||||
err:
|
||||
FREE(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Exported functions
|
||||
*/
|
||||
|
||||
|
||||
static struct pipe_texture *
|
||||
i965_libdrm_texture_from_shared_handle(struct drm_api *api,
|
||||
struct pipe_screen *screen,
|
||||
struct pipe_texture *template,
|
||||
const char* name,
|
||||
unsigned pitch,
|
||||
unsigned handle)
|
||||
{
|
||||
/* XXX: this is silly -- there should be a way to get directly from
|
||||
* the "drm_api" struct to ourselves, without peering into
|
||||
* unrelated code:
|
||||
*/
|
||||
struct i965_libdrm_winsys *idws = i965_libdrm_winsys(brw_screen(screen)->sws);
|
||||
struct i965_libdrm_buffer *buffer;
|
||||
|
||||
if (BRW_DUMP)
|
||||
debug_printf("%s %s pitch %d handle 0x%x\n", __FUNCTION__,
|
||||
name, pitch, handle);
|
||||
|
||||
buffer = i965_libdrm_buffer_from_handle(idws, name, handle);
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
return brw_texture_blanket_winsys_buffer(screen, template, pitch,
|
||||
buffer->tiling,
|
||||
&buffer->base);
|
||||
}
|
||||
|
||||
|
||||
static boolean
|
||||
i965_libdrm_shared_handle_from_texture(struct drm_api *api,
|
||||
struct pipe_screen *screen,
|
||||
struct pipe_texture *texture,
|
||||
unsigned *pitch,
|
||||
unsigned *handle)
|
||||
{
|
||||
struct i965_libdrm_buffer *buf = NULL;
|
||||
struct brw_winsys_buffer *buffer = NULL;
|
||||
|
||||
if (BRW_DUMP)
|
||||
debug_printf("%s\n", __FUNCTION__);
|
||||
|
||||
if (!brw_texture_get_winsys_buffer(texture, &buffer, pitch))
|
||||
return FALSE;
|
||||
|
||||
buf = i965_libdrm_buffer(buffer);
|
||||
if (!buf->flinked) {
|
||||
if (drm_intel_bo_flink(buf->bo, &buf->flink))
|
||||
return FALSE;
|
||||
buf->flinked = TRUE;
|
||||
}
|
||||
|
||||
*handle = buf->flink;
|
||||
|
||||
if (BRW_DUMP)
|
||||
debug_printf(" -> pitch %d handle 0x%x\n", *pitch, *handle);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static boolean
|
||||
i965_libdrm_local_handle_from_texture(struct drm_api *api,
|
||||
struct pipe_screen *screen,
|
||||
struct pipe_texture *texture,
|
||||
unsigned *pitch,
|
||||
unsigned *handle)
|
||||
{
|
||||
struct brw_winsys_buffer *buffer = NULL;
|
||||
|
||||
if (BRW_DUMP)
|
||||
debug_printf("%s\n", __FUNCTION__);
|
||||
|
||||
if (!brw_texture_get_winsys_buffer(texture, &buffer, pitch))
|
||||
return FALSE;
|
||||
|
||||
*handle = i965_libdrm_buffer(buffer)->bo->handle;
|
||||
|
||||
if (BRW_DUMP)
|
||||
debug_printf(" -> pitch %d handle 0x%x\n", *pitch, *handle);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
i965_libdrm_winsys_destroy(struct brw_winsys_screen *iws)
|
||||
{
|
||||
|
@ -225,9 +102,6 @@ struct drm_api i965_libdrm_api =
|
|||
{
|
||||
.name = "i965",
|
||||
.create_screen = i965_libdrm_create_screen,
|
||||
.texture_from_shared_handle = i965_libdrm_texture_from_shared_handle,
|
||||
.shared_handle_from_texture = i965_libdrm_shared_handle_from_texture,
|
||||
.local_handle_from_texture = i965_libdrm_local_handle_from_texture,
|
||||
.destroy = destroy,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
|
||||
#include "state_tracker/drm_api.h"
|
||||
#include "i965_drm_winsys.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_inlines.h"
|
||||
|
@ -122,6 +123,78 @@ err:
|
|||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
static enum pipe_error
|
||||
i965_libdrm_bo_from_handle(struct brw_winsys_screen *sws,
|
||||
struct winsys_handle *whandle,
|
||||
unsigned *stride,
|
||||
unsigned *tile,
|
||||
struct brw_winsys_buffer **bo_out)
|
||||
{
|
||||
struct i965_libdrm_winsys *idws = i965_libdrm_winsys(sws);
|
||||
struct i965_libdrm_buffer *buf = CALLOC_STRUCT(i965_libdrm_buffer);
|
||||
uint32_t swizzle = 0;
|
||||
|
||||
if (BRW_DUMP)
|
||||
debug_printf("%s\n", __FUNCTION__);
|
||||
|
||||
if (!buf)
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
pipe_reference_init(&buf->base.reference, 1);
|
||||
buf->bo = drm_intel_bo_gem_create_from_name(idws->gem, "FROM_HANDLE", whandle->handle);
|
||||
buf->base.size = buf->bo->size;
|
||||
buf->base.sws = &idws->base;
|
||||
buf->flinked = TRUE;
|
||||
buf->flink = whandle->handle;
|
||||
|
||||
|
||||
if (!buf->bo)
|
||||
goto err;
|
||||
|
||||
drm_intel_bo_get_tiling(buf->bo, &buf->tiling, &swizzle);
|
||||
if (buf->tiling != 0)
|
||||
buf->map_gtt = TRUE;
|
||||
|
||||
*tile = buf->tiling;
|
||||
*stride = whandle->stride;
|
||||
|
||||
*bo_out = &buf->base;
|
||||
return PIPE_OK;
|
||||
|
||||
err:
|
||||
FREE(buf);
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
static enum pipe_error
|
||||
i965_libdrm_bo_get_handle(struct brw_winsys_buffer *buffer,
|
||||
struct winsys_handle *whandle,
|
||||
unsigned stride)
|
||||
{
|
||||
struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
|
||||
|
||||
if (BRW_DUMP)
|
||||
debug_printf("%s\n", __FUNCTION__);
|
||||
|
||||
if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
|
||||
if (!buf->flinked) {
|
||||
if (drm_intel_bo_flink(buf->bo, &buf->flink))
|
||||
return PIPE_ERROR_BAD_INPUT;
|
||||
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 PIPE_ERROR_BAD_INPUT;
|
||||
}
|
||||
|
||||
whandle->stride = stride;
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
i965_libdrm_bo_destroy(struct brw_winsys_buffer *buffer)
|
||||
{
|
||||
|
@ -415,6 +488,8 @@ void
|
|||
i965_libdrm_winsys_init_buffer_functions(struct i965_libdrm_winsys *idws)
|
||||
{
|
||||
idws->base.bo_alloc = i965_libdrm_bo_alloc;
|
||||
idws->base.bo_from_handle = i965_libdrm_bo_from_handle;
|
||||
idws->base.bo_get_handle = i965_libdrm_bo_get_handle;
|
||||
idws->base.bo_destroy = i965_libdrm_bo_destroy;
|
||||
idws->base.bo_emit_reloc = i965_libdrm_bo_emit_reloc;
|
||||
idws->base.bo_exec = i965_libdrm_bo_exec;
|
||||
|
|
Loading…
Reference in New Issue