ilo: add ilo_image_init_for_imported()

It replaces ilo_image_update_for_imported_bo() and enables more error
checkings for imported textures.
This commit is contained in:
Chia-I Wu 2015-05-02 14:14:15 +08:00
parent 938c9b8cea
commit f6ca4084c7
3 changed files with 66 additions and 60 deletions

View File

@ -484,8 +484,6 @@ img_init_tiling(struct ilo_image *img,
preferred_tilings &= IMAGE_TILING_NONE;
}
img->valid_tilings = params->valid_tilings;
/* prefer tiled over linear */
if (preferred_tilings & IMAGE_TILING_Y)
img->tiling = GEN6_TILING_Y;
@ -1349,7 +1347,6 @@ img_init_for_transfer(struct ilo_image *img,
img->block_size = util_format_get_blocksize(templ->format);
img->walk = ILO_IMAGE_WALK_LOD;
img->valid_tilings = IMAGE_TILING_NONE;
img->tiling = GEN6_TILING_NONE;
img->align_i = img->block_width;
@ -1397,23 +1394,31 @@ void ilo_image_init(struct ilo_image *img,
img_init(img, &params);
}
/**
* Update the tiling mode and bo stride (for imported resources).
*/
bool
ilo_image_update_for_imported_bo(struct ilo_image *img,
enum gen_surface_tiling tiling,
unsigned bo_stride)
ilo_image_init_for_imported(struct ilo_image *img,
const struct ilo_dev *dev,
const struct pipe_resource *templ,
enum gen_surface_tiling tiling,
unsigned bo_stride)
{
if (!(img->valid_tilings & (1 << tiling)))
return false;
struct ilo_image_params params;
if ((tiling == GEN6_TILING_X && bo_stride % 512) ||
(tiling == GEN6_TILING_Y && bo_stride % 128) ||
(tiling == GEN8_TILING_W && bo_stride % 64))
return false;
img->tiling = tiling;
memset(&params, 0, sizeof(params));
params.dev = dev;
params.templ = templ;
params.valid_tilings = 1 << tiling;
img_init(img, &params);
assert(img->tiling == tiling);
if (img->bo_stride > bo_stride)
return false;
img->bo_stride = bo_stride;
return true;

View File

@ -105,8 +105,6 @@ struct ilo_image {
enum ilo_image_walk_type walk;
bool interleaved_samples;
/* bitmask of valid tilings */
unsigned valid_tilings;
enum gen_surface_tiling tiling;
/* physical LOD slice alignments */
@ -150,9 +148,11 @@ ilo_image_init(struct ilo_image *img,
const struct pipe_resource *templ);
bool
ilo_image_update_for_imported_bo(struct ilo_image *img,
enum gen_surface_tiling tiling,
unsigned bo_stride);
ilo_image_init_for_imported(struct ilo_image *img,
const struct ilo_dev *dev,
const struct pipe_resource *templ,
enum gen_surface_tiling tiling,
unsigned bo_stride);
static inline void
ilo_image_cleanup(struct ilo_image *img)

View File

@ -153,34 +153,6 @@ tex_alloc_slices(struct ilo_texture *tex)
return true;
}
static bool
tex_import_handle(struct ilo_texture *tex,
const struct winsys_handle *handle)
{
struct ilo_screen *is = ilo_screen(tex->base.screen);
const char *name = resource_get_bo_name(&tex->base);
enum intel_tiling_mode tiling;
unsigned long pitch;
struct intel_bo *bo;
bo = intel_winsys_import_handle(is->dev.winsys, name, handle,
tex->image.bo_height, &tiling, &pitch);
if (!bo)
return false;
if (!ilo_image_update_for_imported_bo(&tex->image,
winsys_to_surface_tiling(tiling), pitch)) {
ilo_err("imported handle has incompatible tiling/pitch\n");
intel_bo_unref(bo);
return false;
}
ilo_image_set_bo(&tex->image, bo);
intel_bo_unref(bo);
return true;
}
static bool
tex_create_bo(struct ilo_texture *tex)
{
@ -302,18 +274,12 @@ tex_destroy(struct ilo_texture *tex)
}
static bool
tex_alloc_bos(struct ilo_texture *tex,
const struct winsys_handle *handle)
tex_alloc_bos(struct ilo_texture *tex)
{
struct ilo_screen *is = ilo_screen(tex->base.screen);
if (handle) {
if (!tex_import_handle(tex, handle))
return false;
} else {
if (!tex_create_bo(tex))
return false;
}
if (!tex->imported && !tex_create_bo(tex))
return false;
/* allocate separate stencil resource */
if (tex->image.separate_stencil && !tex_create_separate_stencil(tex))
@ -340,13 +306,50 @@ tex_alloc_bos(struct ilo_texture *tex,
}
static bool
tex_init_image(struct ilo_texture *tex)
tex_import_handle(struct ilo_texture *tex,
const struct winsys_handle *handle)
{
struct ilo_screen *is = ilo_screen(tex->base.screen);
const struct pipe_resource *templ = &tex->base;
const char *name = resource_get_bo_name(&tex->base);
enum intel_tiling_mode tiling;
unsigned long pitch;
struct intel_bo *bo;
bo = intel_winsys_import_handle(is->dev.winsys, name, handle,
tex->image.bo_height, &tiling, &pitch);
if (!bo)
return false;
if (!ilo_image_init_for_imported(&tex->image, &is->dev, templ,
winsys_to_surface_tiling(tiling), pitch)) {
ilo_err("failed to import handle for texture\n");
intel_bo_unref(bo);
return false;
}
ilo_image_set_bo(&tex->image, bo);
intel_bo_unref(bo);
tex->imported = true;
return true;
}
static bool
tex_init_image(struct ilo_texture *tex,
const struct winsys_handle *handle)
{
struct ilo_screen *is = ilo_screen(tex->base.screen);
const struct pipe_resource *templ = &tex->base;
struct ilo_image *img = &tex->image;
ilo_image_init(img, &is->dev, templ);
if (handle) {
if (!tex_import_handle(tex, handle))
return false;
} else {
ilo_image_init(img, &is->dev, templ);
}
if (img->bo_height > ilo_max_resource_size / img->bo_stride)
return false;
@ -379,14 +382,12 @@ tex_create(struct pipe_screen *screen,
tex->base.screen = screen;
pipe_reference_init(&tex->base.reference, 1);
tex->imported = (handle != NULL);
if (!tex_init_image(tex)) {
if (!tex_init_image(tex, handle)) {
FREE(tex);
return NULL;
}
if (!tex_alloc_bos(tex, handle)) {
if (!tex_alloc_bos(tex)) {
tex_destroy(tex);
return NULL;
}