+ so->base.texture = NULL;
+ pipe_resource_reference(&so->base.texture, prsc);
+ so->base.reference.count = 1;
+ so->base.context = pctx;
+
+ /* There is no hardware level clamping, and the start address of a
+ * texture may be misaligned, so in that case we have to copy to a
+ * temporary.
+ *
+ * Also, Raspberry Pi doesn't support sampling from raster textures,
+ * so we also have to copy to a temporary then.
+ */
+ if ((cso->u.tex.first_level &&
+ (cso->u.tex.first_level != cso->u.tex.last_level)) ||
+ rsc->vc4_format == VC4_TEXTURE_TYPE_RGBA32R ||
+ rsc->vc4_format == ~0) {
+ struct vc4_resource *shadow_parent = rsc;
+ struct pipe_resource tmpl = {
+ .target = prsc->target,
+ .format = prsc->format,
+ .width0 = u_minify(prsc->width0,
+ cso->u.tex.first_level),
+ .height0 = u_minify(prsc->height0,
+ cso->u.tex.first_level),
+ .bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET,
+ .last_level = cso->u.tex.last_level - cso->u.tex.first_level,
+ .nr_samples = prsc->nr_samples,
+ };
+
+ /* Create the shadow texture. The rest of the texture
+ * parameter setup will use the shadow.
+ */
+ prsc = vc4_resource_create(pctx->screen, &tmpl);
+ if (!prsc) {
+ free(so);
+ return NULL;
+ }
+ rsc = vc4_resource(prsc);
+ vc4_bo_label(vc4_screen(pctx->screen), rsc->bo,
+ "tiling shadow %dx%d",
+ tmpl.width0, tmpl.height0);
+
+ /* Flag it as needing update of the contents from the parent. */
+ rsc->writes = shadow_parent->writes - 1;
+ assert(rsc->vc4_format != VC4_TEXTURE_TYPE_RGBA32R);
+
+ so->texture = prsc;
+ } else {
+ pipe_resource_reference(&so->texture, prsc);
+
+ if (cso->u.tex.first_level) {
+ so->force_first_level = true;
+ }
+ }
+
+ so->texture_p0 =
+ (VC4_SET_FIELD((rsc->slices[0].offset +
+ cso->u.tex.first_layer *
+ rsc->cube_map_stride) >> 12, VC4_TEX_P0_OFFSET) |
+ VC4_SET_FIELD(rsc->vc4_format & 15, VC4_TEX_P0_TYPE) |
+ VC4_SET_FIELD(so->force_first_level ?
+ cso->u.tex.last_level :
+ cso->u.tex.last_level -
+ cso->u.tex.first_level, VC4_TEX_P0_MIPLVLS) |
+ VC4_SET_FIELD(cso->target == PIPE_TEXTURE_CUBE,
+ VC4_TEX_P0_CMMODE));
+ so->texture_p1 =
+ (VC4_SET_FIELD(rsc->vc4_format >> 4, VC4_TEX_P1_TYPE4) |
+ VC4_SET_FIELD(prsc->height0 & 2047, VC4_TEX_P1_HEIGHT) |
+ VC4_SET_FIELD(prsc->width0 & 2047, VC4_TEX_P1_WIDTH));
+
+ if (prsc->format == PIPE_FORMAT_ETC1_RGB8)
+ so->texture_p1 |= VC4_TEX_P1_ETCFLIP_MASK;
+
+ return &so->base;