+ if (fb->_ColorReadBufferIndex >= 0)
+ st_manager_add_color_renderbuffer(st, fb, fb->_ColorReadBufferIndex);
+}
+
+
+
+/**
+ * Called via ctx->Driver.MapRenderbuffer.
+ */
+static void
+st_MapRenderbuffer(struct gl_context *ctx,
+ struct gl_renderbuffer *rb,
+ GLuint x, GLuint y, GLuint w, GLuint h,
+ GLbitfield mode,
+ GLubyte **mapOut, GLint *rowStrideOut)
+{
+ struct st_context *st = st_context(ctx);
+ struct st_renderbuffer *strb = st_renderbuffer(rb);
+ struct pipe_context *pipe = st->pipe;
+ const GLboolean invert = rb->Name == 0;
+ unsigned usage;
+ GLuint y2;
+ GLubyte *map;
+
+ if (strb->software) {
+ /* software-allocated renderbuffer (probably an accum buffer) */
+ if (strb->data) {
+ GLint bpp = _mesa_get_format_bytes(strb->Base.Format);
+ GLint stride = _mesa_format_row_stride(strb->Base.Format,
+ strb->Base.Width);
+ *mapOut = (GLubyte *) strb->data + y * stride + x * bpp;
+ *rowStrideOut = stride;
+ }
+ else {
+ *mapOut = NULL;
+ *rowStrideOut = 0;
+ }
+ return;
+ }
+
+ usage = 0x0;
+ if (mode & GL_MAP_READ_BIT)
+ usage |= PIPE_TRANSFER_READ;
+ if (mode & GL_MAP_WRITE_BIT)
+ usage |= PIPE_TRANSFER_WRITE;
+ if (mode & GL_MAP_INVALIDATE_RANGE_BIT)
+ usage |= PIPE_TRANSFER_DISCARD_RANGE;
+
+ /* Note: y=0=bottom of buffer while y2=0=top of buffer.
+ * 'invert' will be true for window-system buffers and false for
+ * user-allocated renderbuffers and textures.
+ */
+ if (invert)
+ y2 = strb->Base.Height - y - h;
+ else
+ y2 = y;
+
+ map = pipe_transfer_map(pipe,
+ strb->texture,
+ strb->surface->u.tex.level,
+ strb->surface->u.tex.first_layer,
+ usage, x, y2, w, h, &strb->transfer);
+ if (map) {
+ if (invert) {
+ *rowStrideOut = -(int) strb->transfer->stride;
+ map += (h - 1) * strb->transfer->stride;
+ }
+ else {
+ *rowStrideOut = strb->transfer->stride;
+ }
+ *mapOut = map;
+ }
+ else {
+ *mapOut = NULL;
+ *rowStrideOut = 0;
+ }