/** * Create a new texture object, using the given template info. */ static struct pipe_resource * fd_resource_create(struct pipe_screen *pscreen, const struct pipe_resource *tmpl) { struct fd_resource *rsc = CALLOC_STRUCT(fd_resource); struct pipe_resource *prsc = &rsc->base.b; uint32_t size; DBG("target=%d, format=%s, %ux%ux%u, array_size=%u, last_level=%u, " "nr_samples=%u, usage=%u, bind=%x, flags=%x", tmpl->target, util_format_name(tmpl->format), tmpl->width0, tmpl->height0, tmpl->depth0, tmpl->array_size, tmpl->last_level, tmpl->nr_samples, tmpl->usage, tmpl->bind, tmpl->flags); if (!rsc) return NULL; *prsc = *tmpl; pipe_reference_init(&prsc->reference, 1); list_inithead(&rsc->list); prsc->screen = pscreen; util_range_init(&rsc->valid_buffer_range); rsc->base.vtbl = &fd_resource_vtbl; rsc->cpp = util_format_get_blocksize(tmpl->format); assert(rsc->cpp); if (is_a4xx(fd_screen(pscreen))) { switch (tmpl->target) { case PIPE_TEXTURE_3D: /* TODO 3D_ARRAY? */ rsc->layer_first = false; break; default: rsc->layer_first = true; break; } } size = setup_slices(rsc, slice_alignment(pscreen, tmpl)); if (rsc->layer_first) { rsc->layer_size = align(size, 4096); size = rsc->layer_size * prsc->array_size; } realloc_bo(rsc, size); if (!rsc->bo) goto fail; return prsc; fail: fd_resource_destroy(pscreen, prsc); return NULL; }
/** * Create a new texture object, using the given template info. */ static struct pipe_resource * fd_resource_create(struct pipe_screen *pscreen, const struct pipe_resource *tmpl) { struct fd_resource *rsc = CALLOC_STRUCT(fd_resource); struct pipe_resource *prsc = &rsc->base.b; enum pipe_format format = tmpl->format; uint32_t size, alignment; DBG("target=%d, format=%s, %ux%ux%u, array_size=%u, last_level=%u, " "nr_samples=%u, usage=%u, bind=%x, flags=%x", tmpl->target, util_format_name(format), tmpl->width0, tmpl->height0, tmpl->depth0, tmpl->array_size, tmpl->last_level, tmpl->nr_samples, tmpl->usage, tmpl->bind, tmpl->flags); if (!rsc) return NULL; *prsc = *tmpl; pipe_reference_init(&prsc->reference, 1); list_inithead(&rsc->list); prsc->screen = pscreen; util_range_init(&rsc->valid_buffer_range); rsc->base.vtbl = &fd_resource_vtbl; if (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) format = PIPE_FORMAT_Z32_FLOAT; else if (fd_screen(pscreen)->gpu_id < 400 && util_format_description(format)->layout == UTIL_FORMAT_LAYOUT_RGTC) format = PIPE_FORMAT_R8G8B8A8_UNORM; rsc->internal_format = format; rsc->cpp = util_format_get_blocksize(format); assert(rsc->cpp); alignment = slice_alignment(pscreen, tmpl); if (is_a4xx(fd_screen(pscreen))) { switch (tmpl->target) { case PIPE_TEXTURE_3D: rsc->layer_first = false; break; default: rsc->layer_first = true; alignment = 1; break; } } size = setup_slices(rsc, alignment, format); if (rsc->layer_first) { rsc->layer_size = align(size, 4096); size = rsc->layer_size * prsc->array_size; } realloc_bo(rsc, size); if (!rsc->bo) goto fail; /* There is no native Z32F_S8 sampling or rendering format, so this must * be emulated via two separate textures. The depth texture still keeps * its Z32F_S8 format though, and we also keep a reference to a separate * S8 texture. */ if (tmpl->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) { struct pipe_resource stencil = *tmpl; stencil.format = PIPE_FORMAT_S8_UINT; rsc->stencil = fd_resource(fd_resource_create(pscreen, &stencil)); if (!rsc->stencil) goto fail; } return prsc; fail: fd_resource_destroy(pscreen, prsc); return NULL; }