static bool tex_alloc_bos(struct ilo_texture *tex, const struct winsys_handle *handle) { 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; } /* allocate separate stencil resource */ if (tex->layout.separate_stencil && !tex_create_separate_stencil(tex)) return false; switch (tex->layout.aux) { case ILO_LAYOUT_AUX_HIZ: if (!tex_create_hiz(tex)) { /* Separate Stencil Buffer requires HiZ to be enabled */ if (ilo_dev_gen(&is->dev) == ILO_GEN(6) && tex->layout.separate_stencil) return false; } break; case ILO_LAYOUT_AUX_MCS: if (!tex_create_mcs(tex)) return false; break; default: break; } return true; }
static struct pipe_resource * tex_create(struct pipe_screen *screen, const struct pipe_resource *templ, const struct winsys_handle *handle) { struct tex_layout layout; struct ilo_texture *tex; tex = CALLOC_STRUCT(ilo_texture); if (!tex) return NULL; tex->base = *templ; tex->base.screen = screen; pipe_reference_init(&tex->base.reference, 1); if (!tex_alloc_slices(tex)) { FREE(tex); return NULL; } tex->imported = (handle != NULL); if (tex->base.bind & (PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET)) tex->bo_flags |= INTEL_ALLOC_FOR_RENDER; tex_layout_init(&layout, screen, templ, tex->slices); switch (templ->target) { case PIPE_TEXTURE_1D: case PIPE_TEXTURE_2D: case PIPE_TEXTURE_CUBE: case PIPE_TEXTURE_RECT: case PIPE_TEXTURE_1D_ARRAY: case PIPE_TEXTURE_2D_ARRAY: case PIPE_TEXTURE_CUBE_ARRAY: tex_layout_2d(&layout); break; case PIPE_TEXTURE_3D: tex_layout_3d(&layout); break; default: assert(!"unknown resource target"); break; } tex_layout_validate(&layout); /* make sure the bo can be mapped through GTT if tiled */ if (layout.tiling != INTEL_TILING_NONE) { /* * Usually only the first 256MB of the GTT is mappable. * * See also how intel_context::max_gtt_map_object_size is calculated. */ const size_t mappable_gtt_size = 256 * 1024 * 1024; const size_t size = tex_layout_estimate_size(&layout); /* be conservative */ if (size > mappable_gtt_size / 4) tex_layout_force_linear(&layout); } tex_layout_apply(&layout, tex); if (!tex_create_bo(tex, handle)) { tex_free_slices(tex); FREE(tex); return NULL; } /* allocate separate stencil resource */ if (layout.separate_stencil && !tex_create_separate_stencil(tex)) { tex_destroy(tex); return NULL; } if (layout.hiz && !tex_create_hiz(tex, &layout)) { /* Separate Stencil Buffer requires HiZ to be enabled */ if (layout.dev->gen == ILO_GEN(6) && layout.separate_stencil) { tex_destroy(tex); return NULL; } } return &tex->base; }