1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2008 Red Hat Inc.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/imports.h"
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/macros.h"
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/mfeatures.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/mtypes.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/enums.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/fbobject.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/framebuffer.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/renderbuffer.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/context.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "swrast/swrast.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "drivers/common/meta.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_common.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_mipmap_tree.h"
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define FILE_DEBUG_FLAG RADEON_TEXTURE
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DBG(...) do {                                           \
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (RADEON_DEBUG & FILE_DEBUG_FLAG)                      \
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                printf(__VA_ARGS__);                      \
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} while(0)
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct gl_framebuffer *
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_new_framebuffer(struct gl_context *ctx, GLuint name)
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return _mesa_new_framebuffer(ctx, name);
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"%s(rb %p, rrb %p) \n",
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		__func__, rb, rrb);
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ASSERT(rrb);
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (rrb && rrb->bo) {
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    radeon_bo_unref(rrb->bo);
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  _mesa_delete_renderbuffer(ctx, rb);
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(RADEON_R100)
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLuint get_depth_z32(const struct radeon_renderbuffer * rrb,
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       GLint x, GLint y)
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    GLuint ba, address = 0;
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ba = (y >> 4) * (rrb->pitch >> 6) + (x >> 4);
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    address |= (x & 0x7) << 2;
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    address |= (y & 0x3) << 5;
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    address |= (((x & 0x10) >> 2) ^ (y & 0x4)) << 5;
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    address |= (ba & 3) << 8;
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    address |= (y & 0x8) << 7;
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    address |= (((x & 0x8) << 1) ^ (y & 0x10)) << 7;
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    address |= (ba & ~0x3) << 10;
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return address;
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLuint get_depth_z16(const struct radeon_renderbuffer * rrb,
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       GLint x, GLint y)
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    GLuint ba, address = 0;                   /* a[0]    = 0           */
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ba = (y / 16) * (rrb->pitch >> 6) + (x / 32);
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    address |= (x & 0x7) << 1;                /* a[1..3] = x[0..2]     */
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    address |= (y & 0x7) << 4;                /* a[4..6] = y[0..2]     */
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    address |= (x & 0x8) << 4;                /* a[7]    = x[3]        */
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    address |= (ba & 0x3) << 8;               /* a[8..9] = ba[0..1]    */
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    address |= (y & 0x8) << 7;                /* a[10]   = y[3]        */
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    address |= ((x & 0x10) ^ (y & 0x10)) << 7;/* a[11]   = x[4] ^ y[4] */
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    address |= (ba & ~0x3) << 10;             /* a[12..] = ba[2..] */
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return address;
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(RADEON_R200)
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLuint get_depth_z32(const struct radeon_renderbuffer * rrb,
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 GLint x, GLint y)
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    GLuint offset;
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    GLuint b;
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    offset = 0;
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    b = (((y & 0x7ff) >> 4) * (rrb->pitch >> 7) + (x >> 5));
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    offset += (b >> 1) << 12;
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    offset += (((rrb->pitch >> 7) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11;
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    offset += ((y >> 2) & 0x3) << 9;
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    offset += ((x >> 2) & 0x1) << 8;
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    offset += ((x >> 3) & 0x3) << 6;
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    offset += ((y >> 1) & 0x1) << 5;
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    offset += ((x >> 1) & 0x1) << 4;
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    offset += (y & 0x1) << 3;
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    offset += (x & 0x1) << 2;
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return offset;
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLuint get_depth_z16(const struct radeon_renderbuffer *rrb,
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       GLint x, GLint y)
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint offset;
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint b;
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset = 0;
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   b = (((y  >> 4) * (rrb->pitch >> 7) + (x >> 6)));
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset += (b >> 1) << 12;
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset += (((rrb->pitch >> 7) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11;
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset += ((y >> 2) & 0x3) << 9;
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset += ((x >> 3) & 0x1) << 8;
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset += ((x >> 4) & 0x3) << 6;
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset += ((x >> 2) & 0x1) << 5;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset += ((y >> 1) & 0x1) << 4;
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset += ((x >> 1) & 0x1) << 3;
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset += (y & 0x1) << 2;
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset += (x & 0x1) << 1;
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return offset;
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_map_renderbuffer_s8z24(struct gl_context *ctx,
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       struct gl_renderbuffer *rb,
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       GLuint x, GLuint y, GLuint w, GLuint h,
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       GLbitfield mode,
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       GLubyte **out_map,
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       GLint *out_stride)
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    uint32_t *untiled_s8z24_map, *tiled_s8z24_map;
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int ret;
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int y_flip = (rb->Name == 0) ? -1 : 1;
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    uint32_t pitch = w * rrb->cpp;
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    rrb->map_pitch = pitch;
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    rrb->map_buffer = malloc(w * h * 4);
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT));
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(!ret);
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    untiled_s8z24_map = rrb->map_buffer;
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    tiled_s8z24_map = rrb->bo->ptr;
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (uint32_t pix_y = 0; pix_y < h; ++ pix_y) {
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (uint32_t pix_x = 0; pix_x < w; ++pix_x) {
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    uint32_t flipped_y = y_flip * (int32_t)(y + pix_y) + y_bias;
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    uint32_t src_offset = get_depth_z32(rrb, x + pix_x, flipped_y);
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    uint32_t dst_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp;
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    untiled_s8z24_map[dst_offset/4] = tiled_s8z24_map[src_offset/4];
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    radeon_bo_unmap(rrb->bo);
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *out_map = rrb->map_buffer;
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *out_stride = rrb->map_pitch;
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_map_renderbuffer_z16(struct gl_context *ctx,
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    struct gl_renderbuffer *rb,
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    GLuint x, GLuint y, GLuint w, GLuint h,
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    GLbitfield mode,
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    GLubyte **out_map,
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    GLint *out_stride)
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    uint16_t *untiled_z16_map, *tiled_z16_map;
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int ret;
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int y_flip = (rb->Name == 0) ? -1 : 1;
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    uint32_t pitch = w * rrb->cpp;
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    rrb->map_pitch = pitch;
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    rrb->map_buffer = malloc(w * h * 2);
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT));
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(!ret);
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    untiled_z16_map = rrb->map_buffer;
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    tiled_z16_map = rrb->bo->ptr;
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (uint32_t pix_y = 0; pix_y < h; ++ pix_y) {
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (uint32_t pix_x = 0; pix_x < w; ++pix_x) {
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    uint32_t flipped_y = y_flip * (int32_t)(y + pix_y) + y_bias;
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    uint32_t src_offset = get_depth_z16(rrb, x + pix_x, flipped_y);
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    uint32_t dst_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp;
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    untiled_z16_map[dst_offset/2] = tiled_z16_map[src_offset/2];
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    radeon_bo_unmap(rrb->bo);
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *out_map = rrb->map_buffer;
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *out_stride = rrb->map_pitch;
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_map_renderbuffer(struct gl_context *ctx,
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       struct gl_renderbuffer *rb,
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       GLuint x, GLuint y, GLuint w, GLuint h,
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       GLbitfield mode,
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       GLubyte **out_map,
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       GLint *out_stride)
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct radeon_context *const rmesa = RADEON_CONTEXT(ctx);
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLubyte *map;
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLboolean ok;
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int stride, flip_stride;
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int ret;
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int src_x, src_y;
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!rrb || !rrb->bo) {
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   *out_map = NULL;
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   *out_stride = 0;
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   return;
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rrb->map_mode = mode;
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rrb->map_x = x;
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rrb->map_y = y;
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rrb->map_w = w;
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rrb->map_h = h;
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rrb->map_pitch = rrb->pitch;
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ok = rmesa->vtbl.check_blit(rb->Format, rrb->pitch / rrb->cpp);
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ok) {
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       if (rb->Name) {
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   src_x = x;
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   src_y = y;
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       } else {
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   src_x = x;
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   src_y = rrb->base.Base.Height - y - h;
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       }
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       /* Make a temporary buffer and blit the current contents of the renderbuffer
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	* out to it.  This gives us linear access to the buffer, instead of having
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	* to do detiling in software.
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	*/
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       rrb->map_pitch = rrb->pitch;
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       assert(!rrb->map_bo);
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       rrb->map_bo = radeon_bo_open(rmesa->radeonScreen->bom, 0,
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				    rrb->map_pitch * h, 4,
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				    RADEON_GEM_DOMAIN_GTT, 0);
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       ok = rmesa->vtbl.blit(ctx, rrb->bo, rrb->draw_offset,
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     rb->Format, rrb->pitch / rrb->cpp,
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     rb->Width, rb->Height,
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     src_x, src_y,
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     rrb->map_bo, 0,
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     rb->Format, rrb->map_pitch / rrb->cpp,
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     w, h,
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     0, 0,
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     w, h,
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     GL_FALSE);
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       assert(ok);
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       ret = radeon_bo_map(rrb->map_bo, !!(mode & GL_MAP_WRITE_BIT));
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       assert(!ret);
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       map = rrb->map_bo->ptr;
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       if (rb->Name) {
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   *out_map = map;
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   *out_stride = rrb->map_pitch;
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       } else {
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   *out_map = map + (h - 1) * rrb->map_pitch;
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   *out_stride = -rrb->map_pitch;
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       }
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       return;
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* sw fallback flush stuff */
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (radeon_bo_is_referenced_by_cs(rrb->bo, rmesa->cmdbuf.cs)) {
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      radeon_firevertices(rmesa);
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_DEPTH_ALWAYS_TILED) && !rrb->has_surface) {
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       if (rb->Format == MESA_FORMAT_S8_Z24 || rb->Format == MESA_FORMAT_X8_Z24) {
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   radeon_map_renderbuffer_s8z24(ctx, rb, x, y, w, h,
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					 mode, out_map, out_stride);
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   return;
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       }
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       if (rb->Format == MESA_FORMAT_Z16) {
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   radeon_map_renderbuffer_z16(ctx, rb, x, y, w, h,
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       mode, out_map, out_stride);
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   return;
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       }
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT));
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(!ret);
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   map = rrb->bo->ptr;
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   stride = rrb->map_pitch;
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (rb->Name == 0) {
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      y = rb->Height - 1 - y;
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      flip_stride = -stride;
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      flip_stride = stride;
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      map += rrb->draw_offset;
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   map += x * rrb->cpp;
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   map += (int)y * stride;
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *out_map = map;
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *out_stride = flip_stride;
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_unmap_renderbuffer_s8z24(struct gl_context *ctx,
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  struct gl_renderbuffer *rb)
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!rrb->map_buffer)
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     return;
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (rrb->map_mode & GL_MAP_WRITE_BIT) {
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       uint32_t *untiled_s8z24_map = rrb->map_buffer;
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       uint32_t *tiled_s8z24_map;
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       int y_flip = (rb->Name == 0) ? -1 : 1;
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       radeon_bo_map(rrb->bo, 1);
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       tiled_s8z24_map = rrb->bo->ptr;
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       for (uint32_t pix_y = 0; pix_y < rrb->map_h; pix_y++) {
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   for (uint32_t pix_x = 0; pix_x < rrb->map_w; pix_x++) {
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       uint32_t flipped_y = y_flip * (int32_t)(pix_y + rrb->map_y) + y_bias;
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       uint32_t dst_offset = get_depth_z32(rrb, rrb->map_x + pix_x, flipped_y);
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       uint32_t src_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp;
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       tiled_s8z24_map[dst_offset/4] = untiled_s8z24_map[src_offset/4];
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   }
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       }
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       radeon_bo_unmap(rrb->bo);
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(rrb->map_buffer);
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rrb->map_buffer = NULL;
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_unmap_renderbuffer_z16(struct gl_context *ctx,
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      struct gl_renderbuffer *rb)
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!rrb->map_buffer)
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     return;
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (rrb->map_mode & GL_MAP_WRITE_BIT) {
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       uint16_t *untiled_z16_map = rrb->map_buffer;
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       uint16_t *tiled_z16_map;
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       int y_flip = (rb->Name == 0) ? -1 : 1;
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       radeon_bo_map(rrb->bo, 1);
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       tiled_z16_map = rrb->bo->ptr;
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       for (uint32_t pix_y = 0; pix_y < rrb->map_h; pix_y++) {
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   for (uint32_t pix_x = 0; pix_x < rrb->map_w; pix_x++) {
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       uint32_t flipped_y = y_flip * (int32_t)(pix_y + rrb->map_y) + y_bias;
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       uint32_t dst_offset = get_depth_z16(rrb, rrb->map_x + pix_x, flipped_y);
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       uint32_t src_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp;
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       tiled_z16_map[dst_offset/2] = untiled_z16_map[src_offset/2];
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   }
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       }
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       radeon_bo_unmap(rrb->bo);
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(rrb->map_buffer);
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rrb->map_buffer = NULL;
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_unmap_renderbuffer(struct gl_context *ctx,
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  struct gl_renderbuffer *rb)
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct radeon_context *const rmesa = RADEON_CONTEXT(ctx);
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLboolean ok;
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_DEPTH_ALWAYS_TILED) && !rrb->has_surface) {
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       if (rb->Format == MESA_FORMAT_S8_Z24 || rb->Format == MESA_FORMAT_X8_Z24) {
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   radeon_unmap_renderbuffer_s8z24(ctx, rb);
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   return;
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       }
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       if (rb->Format == MESA_FORMAT_Z16) {
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   radeon_unmap_renderbuffer_z16(ctx, rb);
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   return;
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       }
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!rrb->map_bo) {
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   if (rrb->bo)
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   radeon_bo_unmap(rrb->bo);
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   return;
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   radeon_bo_unmap(rrb->map_bo);
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (rrb->map_mode & GL_MAP_WRITE_BIT) {
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ok = rmesa->vtbl.blit(ctx, rrb->map_bo, 0,
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    rb->Format, rrb->map_pitch / rrb->cpp,
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    rrb->map_w, rrb->map_h,
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    0, 0,
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    rrb->bo, rrb->draw_offset,
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    rb->Format, rrb->pitch / rrb->cpp,
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    rb->Width, rb->Height,
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    rrb->map_x, rrb->map_y,
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    rrb->map_w, rrb->map_h,
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    GL_FALSE);
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ok);
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   radeon_bo_unref(rrb->map_bo);
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rrb->map_bo = NULL;
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called via glRenderbufferStorageEXT() to set the format and allocate
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * storage for a user-created renderbuffer.
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 GLenum internalFormat,
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 GLuint width, GLuint height)
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  struct radeon_context *radeon = RADEON_CONTEXT(ctx);
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  uint32_t size, pitch;
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int cpp;
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"%s(%p, rb %p) \n",
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		__func__, ctx, rb);
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(rb->Name != 0);
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  switch (internalFormat) {
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_R3_G3_B2:
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RGB4:
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RGB5:
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rb->Format = _radeon_texformat_rgb565;
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cpp = 2;
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RGB:
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RGB8:
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RGB10:
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RGB12:
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RGB16:
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rb->Format = _radeon_texformat_argb8888;
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cpp = 4;
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RGBA:
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RGBA2:
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RGBA4:
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RGB5_A1:
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RGBA8:
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RGB10_A2:
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RGBA12:
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RGBA16:
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rb->Format = _radeon_texformat_argb8888;
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cpp = 4;
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_STENCIL_INDEX:
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_STENCIL_INDEX1_EXT:
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_STENCIL_INDEX4_EXT:
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_STENCIL_INDEX8_EXT:
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_STENCIL_INDEX16_EXT:
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* alloc a depth+stencil buffer */
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rb->Format = MESA_FORMAT_S8_Z24;
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cpp = 4;
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEPTH_COMPONENT16:
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rb->Format = MESA_FORMAT_Z16;
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cpp = 2;
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEPTH_COMPONENT:
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEPTH_COMPONENT24:
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEPTH_COMPONENT32:
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rb->Format = MESA_FORMAT_X8_Z24;
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cpp = 4;
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEPTH_STENCIL_EXT:
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEPTH24_STENCIL8_EXT:
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rb->Format = MESA_FORMAT_S8_Z24;
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cpp = 4;
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_problem(ctx,
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    "Unexpected format in radeon_alloc_renderbuffer_storage");
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GL_FALSE;
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (ctx->Driver.Flush)
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  ctx->Driver.Flush(ctx); /* +r6/r7 */
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (rrb->bo)
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    radeon_bo_unref(rrb->bo);
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pitch = ((cpp * width + 63) & ~63) / cpp;
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (RADEON_DEBUG & RADEON_MEMORY)
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fprintf(stderr,"Allocating %d x %d radeon RBO (pitch %d)\n", width,
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      height, pitch);
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   size = pitch * height * cpp;
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rrb->pitch = pitch * cpp;
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rrb->cpp = cpp;
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rrb->bo = radeon_bo_open(radeon->radeonScreen->bom,
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    0,
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    size,
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    0,
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    RADEON_GEM_DOMAIN_VRAM,
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    0);
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rb->Width = width;
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rb->Height = height;
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return GL_TRUE;
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if FEATURE_OES_EGL_image
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_image_target_renderbuffer_storage(struct gl_context *ctx,
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         struct gl_renderbuffer *rb,
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         void *image_handle)
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   radeonContextPtr radeon = RADEON_CONTEXT(ctx);
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct radeon_renderbuffer *rrb;
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __DRIscreen *screen;
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __DRIimage *image;
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   screen = radeon->radeonScreen->driScreen;
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   image = screen->dri2.image->lookupEGLImage(screen, image_handle,
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					      screen->loaderPrivate);
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (image == NULL)
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rrb = radeon_renderbuffer(rb);
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->Driver.Flush)
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx->Driver.Flush(ctx); /* +r6/r7 */
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (rrb->bo)
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      radeon_bo_unref(rrb->bo);
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rrb->bo = image->bo;
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   radeon_bo_ref(rrb->bo);
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fprintf(stderr, "image->bo: %p, name: %d, rbs: w %d -> p %d\n", image->bo, image->bo->handle,
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           image->width, image->pitch);
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rrb->cpp = image->cpp;
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rrb->pitch = image->pitch * image->cpp;
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rb->Format = image->format;
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rb->InternalFormat = image->internal_format;
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rb->Width = image->width;
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rb->Height = image->height;
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rb->Format = image->format;
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rb->_BaseFormat = _mesa_base_fbo_format(radeon->glCtx,
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           image->internal_format);
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called for each hardware renderbuffer when a _window_ is resized.
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Just update fields.
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Not used for user-created renderbuffers!
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           GLenum internalFormat, GLuint width, GLuint height)
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(rb->Name == 0);
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rb->Width = width;
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rb->Height = height;
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rb->InternalFormat = internalFormat;
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"%s(%p, rb %p) \n",
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		__func__, ctx, rb);
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return GL_TRUE;
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_resize_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		     GLuint width, GLuint height)
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     struct radeon_framebuffer *radeon_fb = (struct radeon_framebuffer*)fb;
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"%s(%p, fb %p) \n",
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		__func__, ctx, fb);
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _mesa_resize_framebuffer(ctx, fb, width, height);
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb->Initialized = GL_TRUE; /* XXX remove someday */
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (fb->Name != 0) {
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Make sure all window system renderbuffers are up to date */
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 2; i++) {
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct gl_renderbuffer *rb = &radeon_fb->color_rb[i]->base.Base;
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* only resize if size is changing */
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (rb && (rb->Width != width || rb->Height != height)) {
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height);
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Dummy function for gl_renderbuffer::AllocStorage() */
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 GLenum internalFormat, GLuint width, GLuint height)
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _mesa_problem(ctx, "radeon_op_alloc_storage should never be called.");
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return GL_FALSE;
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Create a renderbuffer for a window's color, depth and/or stencil buffer.
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Not used for user-created renderbuffers.
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct radeon_renderbuffer *
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_create_renderbuffer(gl_format format, __DRIdrawable *driDrawPriv)
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct radeon_renderbuffer *rrb;
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct gl_renderbuffer *rb;
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    rrb = CALLOC_STRUCT(radeon_renderbuffer);
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    radeon_print(RADEON_TEXTURE, RADEON_TRACE,
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"%s( rrb %p ) \n",
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		__func__, rrb);
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!rrb)
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return NULL;
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    rb = &rrb->base.Base;
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    _mesa_init_renderbuffer(rb, 0);
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    rb->ClassID = RADEON_RB_CLASS;
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    rb->Format = format;
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    rb->_BaseFormat = _mesa_get_format_base_format(format);
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    rb->InternalFormat = _mesa_get_format_base_format(format);
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    rrb->dPriv = driDrawPriv;
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    rb->Delete = radeon_delete_renderbuffer;
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    rb->AllocStorage = radeon_alloc_window_storage;
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    rrb->bo = NULL;
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return rrb;
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct gl_renderbuffer *
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_new_renderbuffer(struct gl_context * ctx, GLuint name)
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  struct radeon_renderbuffer *rrb;
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  struct gl_renderbuffer *rb;
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  rrb = CALLOC_STRUCT(radeon_renderbuffer);
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"%s(%p, rrb %p) \n",
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		__func__, ctx, rrb);
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!rrb)
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return NULL;
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  rb = &rrb->base.Base;
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  _mesa_init_renderbuffer(rb, name);
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  rb->ClassID = RADEON_RB_CLASS;
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  rb->Delete = radeon_delete_renderbuffer;
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  rb->AllocStorage = radeon_alloc_renderbuffer_storage;
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return rb;
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_bind_framebuffer(struct gl_context * ctx, GLenum target,
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"%s(%p, fb %p, target %s) \n",
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		__func__, ctx, fb,
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		_mesa_lookup_enum_by_nr(target));
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      radeon_draw_buffer(ctx, fb);
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_framebuffer_renderbuffer(struct gl_context * ctx,
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               struct gl_framebuffer *fb,
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               GLenum attachment, struct gl_renderbuffer *rb)
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (ctx->Driver.Flush)
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ctx->Driver.Flush(ctx); /* +r6/r7 */
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	radeon_print(RADEON_TEXTURE, RADEON_TRACE,
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"%s(%p, fb %p, rb %p) \n",
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		__func__, ctx, fb, rb);
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   radeon_draw_buffer(ctx, fb);
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_update_wrapper(struct gl_context *ctx, struct radeon_renderbuffer *rrb,
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		     struct gl_texture_image *texImage)
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct gl_renderbuffer *rb = &rrb->base.Base;
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	radeon_print(RADEON_TEXTURE, RADEON_TRACE,
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"%s(%p, rrb %p, texImage %p, texFormat %s) \n",
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		__func__, ctx, rrb, texImage, _mesa_get_format_name(texImage->TexFormat));
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rrb->cpp = _mesa_get_format_bytes(texImage->TexFormat);
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rrb->pitch = texImage->Width * rrb->cpp;
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rb->Format = texImage->TexFormat;
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rb->InternalFormat = texImage->InternalFormat;
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rb->_BaseFormat = _mesa_base_fbo_format(ctx, rb->InternalFormat);
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rb->Width = texImage->Width;
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rb->Height = texImage->Height;
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rb->Delete = radeon_delete_renderbuffer;
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	rb->AllocStorage = radeon_nop_alloc_storage;
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return GL_TRUE;
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct radeon_renderbuffer *
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_wrap_texture(struct gl_context * ctx, struct gl_texture_image *texImage)
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const GLuint name = ~0;   /* not significant, but distinct for debugging */
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  struct radeon_renderbuffer *rrb;
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* make an radeon_renderbuffer to wrap the texture image */
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rrb = CALLOC_STRUCT(radeon_renderbuffer);
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"%s(%p, rrb %p, texImage %p) \n",
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		__func__, ctx, rrb, texImage);
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!rrb) {
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture");
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _mesa_init_renderbuffer(&rrb->base.Base, name);
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rrb->base.Base.ClassID = RADEON_RB_CLASS;
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!radeon_update_wrapper(ctx, rrb, texImage)) {
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      free(rrb);
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return rrb;
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_render_texture(struct gl_context * ctx,
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     struct gl_framebuffer *fb,
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     struct gl_renderbuffer_attachment *att)
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_texture_image *newImage
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      = att->Texture->Image[att->CubeMapFace][att->TextureLevel];
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct radeon_renderbuffer *rrb = radeon_renderbuffer(att->Renderbuffer);
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   radeon_texture_image *radeon_image;
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint imageOffset;
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"%s(%p, fb %p, rrb %p, att %p)\n",
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		__func__, ctx, fb, rrb, att);
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) fb;
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(newImage);
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   radeon_image = (radeon_texture_image *)newImage;
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!radeon_image->mt) {
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Fallback on drawing to a texture without a miptree.
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _swrast_render_texture(ctx, fb, att);
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (!rrb) {
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rrb = radeon_wrap_texture(ctx, newImage);
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (rrb) {
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* bind the wrapper to the attachment point */
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_reference_renderbuffer(&att->Renderbuffer, &rrb->base.Base);
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* fallback to software rendering */
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _swrast_render_texture(ctx, fb, att);
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return;
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!radeon_update_wrapper(ctx, rrb, newImage)) {
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       _swrast_render_texture(ctx, fb, att);
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       return;
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   DBG("Begin render texture tid %lx tex=%u w=%d h=%d refcount=%d\n",
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       _glthread_GetID(),
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       att->Texture->Name, newImage->Width, newImage->Height,
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       rrb->base.Base.RefCount);
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* point the renderbufer's region to the texture image region */
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (rrb->bo != radeon_image->mt->bo) {
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (rrb->bo)
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  	radeon_bo_unref(rrb->bo);
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rrb->bo = radeon_image->mt->bo;
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      radeon_bo_ref(rrb->bo);
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* compute offset of the particular 2D image within the texture region */
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   imageOffset = radeon_miptree_image_offset(radeon_image->mt,
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                            att->CubeMapFace,
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                            att->TextureLevel);
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (att->Texture->Target == GL_TEXTURE_3D) {
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      imageOffset += radeon_image->mt->levels[att->TextureLevel].rowstride *
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     radeon_image->mt->levels[att->TextureLevel].height *
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     att->Zoffset;
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* store that offset in the region, along with the correct pitch for
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * the image we are rendering to */
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rrb->draw_offset = imageOffset;
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rrb->pitch = radeon_image->mt->levels[att->TextureLevel].rowstride;
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   radeon_image->used_as_render_target = GL_TRUE;
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* update drawing region, etc */
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   radeon_draw_buffer(ctx, fb);
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_finish_render_texture(struct gl_context * ctx,
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            struct gl_renderbuffer_attachment *att)
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct gl_texture_object *tex_obj = att->Texture;
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct gl_texture_image *image =
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	tex_obj->Image[att->CubeMapFace][att->TextureLevel];
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    radeon_texture_image *radeon_image = (radeon_texture_image *)image;
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (radeon_image)
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	radeon_image->used_as_render_target = GL_FALSE;
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (ctx->Driver.Flush)
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ctx->Driver.Flush(ctx); /* +r6/r7 */
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradeon_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	gl_format mesa_format;
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int i;
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (i = -2; i < (GLint) ctx->Const.MaxColorAttachments; i++) {
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct gl_renderbuffer_attachment *att;
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (i == -2) {
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			att = &fb->Attachment[BUFFER_DEPTH];
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} else if (i == -1) {
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			att = &fb->Attachment[BUFFER_STENCIL];
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} else {
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			att = &fb->Attachment[BUFFER_COLOR0 + i];
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (att->Type == GL_TEXTURE) {
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			mesa_format = att->Texture->Image[att->CubeMapFace][att->TextureLevel]->TexFormat;
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} else {
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			/* All renderbuffer formats are renderable, but not sampable */
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			continue;
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (!radeon->vtbl.is_format_renderable(mesa_format)){
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			radeon_print(RADEON_TEXTURE, RADEON_TRACE,
940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						"%s: HW doesn't support format %s as output format of attachment %d\n",
941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						__FUNCTION__, _mesa_get_format_name(mesa_format), i);
942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return;
943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid radeon_fbo_init(struct radeon_context *radeon)
948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if FEATURE_EXT_framebuffer_object
950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  radeon->glCtx->Driver.NewFramebuffer = radeon_new_framebuffer;
951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  radeon->glCtx->Driver.NewRenderbuffer = radeon_new_renderbuffer;
952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  radeon->glCtx->Driver.MapRenderbuffer = radeon_map_renderbuffer;
953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  radeon->glCtx->Driver.UnmapRenderbuffer = radeon_unmap_renderbuffer;
954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  radeon->glCtx->Driver.BindFramebuffer = radeon_bind_framebuffer;
955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  radeon->glCtx->Driver.FramebufferRenderbuffer = radeon_framebuffer_renderbuffer;
956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  radeon->glCtx->Driver.RenderTexture = radeon_render_texture;
957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  radeon->glCtx->Driver.FinishRenderTexture = radeon_finish_render_texture;
958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  radeon->glCtx->Driver.ResizeBuffers = radeon_resize_buffers;
959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  radeon->glCtx->Driver.ValidateFramebuffer = radeon_validate_framebuffer;
960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if FEATURE_EXT_framebuffer_blit
962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  radeon->glCtx->Driver.BlitFramebuffer = _mesa_meta_BlitFramebuffer;
963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if FEATURE_OES_EGL_image
965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  radeon->glCtx->Driver.EGLImageTargetRenderbufferStorage =
966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  radeon_image_target_renderbuffer_storage;
967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb,
972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				struct radeon_bo *bo)
973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  struct radeon_bo *old;
975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  old = rb->bo;
976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  rb->bo = bo;
977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  radeon_bo_ref(bo);
978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (old)
979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    radeon_bo_unref(old);
980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
981