+void
+st_update_renderbuffer_surface(struct st_context *st,
+ struct st_renderbuffer *strb)
+{
+ struct pipe_context *pipe = st->pipe;
+ struct pipe_resource *resource = strb->texture;
+ const struct st_texture_object *stTexObj = NULL;
+ unsigned rtt_width = strb->Base.Width;
+ unsigned rtt_height = strb->Base.Height;
+ unsigned rtt_depth = strb->Base.Depth;
+
+ /*
+ * For winsys fbo, it is possible that the renderbuffer is sRGB-capable but
+ * the format of strb->texture is linear (because we have no control over
+ * the format). Check strb->Base.Format instead of strb->texture->format
+ * to determine if the rb is sRGB-capable.
+ */
+ boolean enable_srgb = st->ctx->Color.sRGBEnabled &&
+ _mesa_is_format_srgb(strb->Base.Format);
+ enum pipe_format format = resource->format;
+
+ if (strb->is_rtt) {
+ stTexObj = st_texture_object(strb->Base.TexImage->TexObject);
+ if (stTexObj->surface_based)
+ format = stTexObj->surface_format;
+ }
+
+ format = enable_srgb ? util_format_srgb(format) : util_format_linear(format);
+
+ if (resource->target == PIPE_TEXTURE_1D_ARRAY) {
+ rtt_depth = rtt_height;
+ rtt_height = 1;
+ }
+
+ /* find matching mipmap level size */
+ unsigned level;
+ for (level = 0; level <= resource->last_level; level++) {
+ if (u_minify(resource->width0, level) == rtt_width &&
+ u_minify(resource->height0, level) == rtt_height &&
+ (resource->target != PIPE_TEXTURE_3D ||
+ u_minify(resource->depth0, level) == rtt_depth)) {
+ break;
+ }
+ }
+ assert(level <= resource->last_level);
+
+ /* determine the layer bounds */
+ unsigned first_layer, last_layer;
+ if (strb->rtt_layered) {
+ first_layer = 0;
+ last_layer = util_max_layer(strb->texture, level);
+ }
+ else {
+ first_layer =
+ last_layer = strb->rtt_face + strb->rtt_slice;
+ }
+
+ /* Adjust for texture views */
+ if (strb->is_rtt && resource->array_size > 1 &&
+ stTexObj->base.Immutable) {
+ const struct gl_texture_object *tex = &stTexObj->base;
+ first_layer += tex->MinLayer;
+ if (!strb->rtt_layered)
+ last_layer += tex->MinLayer;
+ else
+ last_layer = MIN2(first_layer + tex->NumLayers - 1, last_layer);
+ }
+
+ struct pipe_surface **psurf =
+ enable_srgb ? &strb->surface_srgb : &strb->surface_linear;
+ struct pipe_surface *surf = *psurf;
+
+ if (!surf ||
+ surf->texture->nr_samples != strb->Base.NumSamples ||
+ surf->texture->nr_storage_samples != strb->Base.NumStorageSamples ||
+ surf->format != format ||
+ surf->texture != resource ||
+ surf->width != rtt_width ||
+ surf->height != rtt_height ||
+ surf->nr_samples != strb->rtt_nr_samples ||
+ surf->u.tex.level != level ||
+ surf->u.tex.first_layer != first_layer ||
+ surf->u.tex.last_layer != last_layer) {
+ /* create a new pipe_surface */
+ struct pipe_surface surf_tmpl;
+ memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+ surf_tmpl.format = format;
+ surf_tmpl.nr_samples = strb->rtt_nr_samples;
+ surf_tmpl.u.tex.level = level;
+ surf_tmpl.u.tex.first_layer = first_layer;
+ surf_tmpl.u.tex.last_layer = last_layer;
+
+ pipe_surface_release(pipe, psurf);
+
+ *psurf = pipe->create_surface(pipe, resource, &surf_tmpl);
+ }
+ strb->surface = *psurf;
+}
+
+
+/**
+ * Return the pipe_resource which stores a particular texture image.
+ */
+static struct pipe_resource *
+get_teximage_resource(struct gl_texture_object *texObj,
+ unsigned face, unsigned level)