1fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie/**************************************************************************
2fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie *
3fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * Copyright 2008 Red Hat Inc.
4fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * All Rights Reserved.
5fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie *
6fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * Permission is hereby granted, free of charge, to any person obtaining a
7fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * copy of this software and associated documentation files (the
8fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * "Software"), to deal in the Software without restriction, including
9fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * without limitation the rights to use, copy, modify, merge, publish,
10fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * distribute, sub license, and/or sell copies of the Software, and to
11fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * permit persons to whom the Software is furnished to do so, subject to
12fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * the following conditions:
13fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie *
14fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * The above copyright notice and this permission notice (including the
15fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * next paragraph) shall be included in all copies or substantial portions
16fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * of the Software.
17fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie *
18fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie *
26fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie **************************************************************************/
27fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
28fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
29fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie#include "main/imports.h"
30fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie#include "main/macros.h"
31fb9c6e681f91c986b7cbe2d6e9f6baceda00c415Vinson Lee#include "main/mfeatures.h"
32fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie#include "main/mtypes.h"
334767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen#include "main/enums.h"
34fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie#include "main/fbobject.h"
35fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie#include "main/framebuffer.h"
36fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie#include "main/renderbuffer.h"
37fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie#include "main/context.h"
384fa01d705f0b795a5df30127925ced8e0522631fBrian Paul#include "swrast/swrast.h"
39ed14a4cb7bbcef45668a3ab6fe8efb267b7c4efdMaciej Cencora#include "drivers/common/meta.h"
40fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
41fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie#include "radeon_common.h"
42ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie#include "radeon_mipmap_tree.h"
43fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
444e0d99a63588c67a955f797733da32d04e6f4ee6Pauli Nieminen#define FILE_DEBUG_FLAG RADEON_TEXTURE
45230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie#define DBG(...) do {                                           \
46230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie        if (RADEON_DEBUG & FILE_DEBUG_FLAG)                      \
47298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg                printf(__VA_ARGS__);                      \
48230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie} while(0)
49230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
50fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airliestatic struct gl_framebuffer *
51f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergradeon_new_framebuffer(struct gl_context *ctx, GLuint name)
52fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie{
53fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie  return _mesa_new_framebuffer(ctx, name);
54fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie}
55fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
56fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airliestatic void
579d4ab9a663d4088ec553edaae0eeafb746d2490dBrian Paulradeon_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
58fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie{
59fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie  struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
60fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
614767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
624767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen		"%s(rb %p, rrb %p) \n",
634767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen		__func__, rb, rrb);
644767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen
65fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie  ASSERT(rrb);
66fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
67fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie  if (rrb && rrb->bo) {
68fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie    radeon_bo_unref(rrb->bo);
69fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie  }
709d4ab9a663d4088ec553edaae0eeafb746d2490dBrian Paul  _mesa_delete_renderbuffer(ctx, rb);
71fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie}
72fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
73781a204bcf5599716991e5d36b08a36db5209441Dave Airlie#if defined(RADEON_R100)
74781a204bcf5599716991e5d36b08a36db5209441Dave Airliestatic GLuint get_depth_z32(const struct radeon_renderbuffer * rrb,
75781a204bcf5599716991e5d36b08a36db5209441Dave Airlie			       GLint x, GLint y)
76781a204bcf5599716991e5d36b08a36db5209441Dave Airlie{
77781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    GLuint ba, address = 0;
78781a204bcf5599716991e5d36b08a36db5209441Dave Airlie
79781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    ba = (y >> 4) * (rrb->pitch >> 6) + (x >> 4);
80781a204bcf5599716991e5d36b08a36db5209441Dave Airlie
81781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    address |= (x & 0x7) << 2;
82781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    address |= (y & 0x3) << 5;
83781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    address |= (((x & 0x10) >> 2) ^ (y & 0x4)) << 5;
84781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    address |= (ba & 3) << 8;
85781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    address |= (y & 0x8) << 7;
86781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    address |= (((x & 0x8) << 1) ^ (y & 0x10)) << 7;
87781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    address |= (ba & ~0x3) << 10;
88781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    return address;
89781a204bcf5599716991e5d36b08a36db5209441Dave Airlie}
90781a204bcf5599716991e5d36b08a36db5209441Dave Airlie
91781a204bcf5599716991e5d36b08a36db5209441Dave Airliestatic GLuint get_depth_z16(const struct radeon_renderbuffer * rrb,
92781a204bcf5599716991e5d36b08a36db5209441Dave Airlie			       GLint x, GLint y)
93781a204bcf5599716991e5d36b08a36db5209441Dave Airlie{
94781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    GLuint ba, address = 0;                   /* a[0]    = 0           */
95781a204bcf5599716991e5d36b08a36db5209441Dave Airlie
96781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    ba = (y / 16) * (rrb->pitch >> 6) + (x / 32);
97781a204bcf5599716991e5d36b08a36db5209441Dave Airlie
98781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    address |= (x & 0x7) << 1;                /* a[1..3] = x[0..2]     */
99781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    address |= (y & 0x7) << 4;                /* a[4..6] = y[0..2]     */
100781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    address |= (x & 0x8) << 4;                /* a[7]    = x[3]        */
101781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    address |= (ba & 0x3) << 8;               /* a[8..9] = ba[0..1]    */
102781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    address |= (y & 0x8) << 7;                /* a[10]   = y[3]        */
103781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    address |= ((x & 0x10) ^ (y & 0x10)) << 7;/* a[11]   = x[4] ^ y[4] */
104781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    address |= (ba & ~0x3) << 10;             /* a[12..] = ba[2..] */
105781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    return address;
106781a204bcf5599716991e5d36b08a36db5209441Dave Airlie}
107781a204bcf5599716991e5d36b08a36db5209441Dave Airlie#endif
108781a204bcf5599716991e5d36b08a36db5209441Dave Airlie
1097d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie#if defined(RADEON_R200)
110781a204bcf5599716991e5d36b08a36db5209441Dave Airliestatic GLuint get_depth_z32(const struct radeon_renderbuffer * rrb,
1117d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie				 GLint x, GLint y)
1127d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie{
1137d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    GLuint offset;
1147d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    GLuint b;
1157d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    offset = 0;
1167d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    b = (((y & 0x7ff) >> 4) * (rrb->pitch >> 7) + (x >> 5));
1177d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    offset += (b >> 1) << 12;
1187d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    offset += (((rrb->pitch >> 7) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11;
1197d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    offset += ((y >> 2) & 0x3) << 9;
1207d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    offset += ((x >> 2) & 0x1) << 8;
1217d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    offset += ((x >> 3) & 0x3) << 6;
1227d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    offset += ((y >> 1) & 0x1) << 5;
1237d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    offset += ((x >> 1) & 0x1) << 4;
1247d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    offset += (y & 0x1) << 3;
1257d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    offset += (x & 0x1) << 2;
1267d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie
1277d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    return offset;
1287d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie}
1297d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie
130781a204bcf5599716991e5d36b08a36db5209441Dave Airliestatic GLuint get_depth_z16(const struct radeon_renderbuffer *rrb,
1311136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie			       GLint x, GLint y)
1321136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie{
1331136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   GLuint offset;
1341136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   GLuint b;
1351136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie
1361136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   offset = 0;
1371136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   b = (((y  >> 4) * (rrb->pitch >> 7) + (x >> 6)));
1381136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   offset += (b >> 1) << 12;
1391136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   offset += (((rrb->pitch >> 7) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11;
1401136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   offset += ((y >> 2) & 0x3) << 9;
1411136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   offset += ((x >> 3) & 0x1) << 8;
1421136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   offset += ((x >> 4) & 0x3) << 6;
1431136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   offset += ((x >> 2) & 0x1) << 5;
1441136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   offset += ((y >> 1) & 0x1) << 4;
1451136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   offset += ((x >> 1) & 0x1) << 3;
1461136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   offset += (y & 0x1) << 2;
1471136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   offset += (x & 0x1) << 1;
1481136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie
1491136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   return offset;
1501136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie}
151781a204bcf5599716991e5d36b08a36db5209441Dave Airlie#endif
1521136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie
1537d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airliestatic void
1547d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlieradeon_map_renderbuffer_s8z24(struct gl_context *ctx,
1557d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie		       struct gl_renderbuffer *rb,
1567d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie		       GLuint x, GLuint y, GLuint w, GLuint h,
1577d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie		       GLbitfield mode,
1587d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie		       GLubyte **out_map,
1597d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie		       GLint *out_stride)
1607d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie{
1617d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
1627d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    uint32_t *untiled_s8z24_map, *tiled_s8z24_map;
1637d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    int ret;
1647d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    int y_flip = (rb->Name == 0) ? -1 : 1;
1657d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
1667d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    uint32_t pitch = w * rrb->cpp;
1677d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie
1687d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    rrb->map_pitch = pitch;
1697d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie
1707d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    rrb->map_buffer = malloc(w * h * 4);
1717d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT));
172781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    assert(!ret);
1737d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    untiled_s8z24_map = rrb->map_buffer;
1747d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    tiled_s8z24_map = rrb->bo->ptr;
1757d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie
1767d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    for (uint32_t pix_y = 0; pix_y < h; ++ pix_y) {
1777d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie	for (uint32_t pix_x = 0; pix_x < w; ++pix_x) {
1787d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie	    uint32_t flipped_y = y_flip * (int32_t)(y + pix_y) + y_bias;
179781a204bcf5599716991e5d36b08a36db5209441Dave Airlie	    uint32_t src_offset = get_depth_z32(rrb, x + pix_x, flipped_y);
1807d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie	    uint32_t dst_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp;
1817d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie	    untiled_s8z24_map[dst_offset/4] = tiled_s8z24_map[src_offset/4];
1827d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie	}
1837d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    }
1847d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie
1857d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    radeon_bo_unmap(rrb->bo);
1867d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie
1877d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    *out_map = rrb->map_buffer;
1887d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie    *out_stride = rrb->map_pitch;
1897d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie}
1901136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie
1911136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airliestatic void
1921136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlieradeon_map_renderbuffer_z16(struct gl_context *ctx,
1931136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie			    struct gl_renderbuffer *rb,
1941136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie			    GLuint x, GLuint y, GLuint w, GLuint h,
1951136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie			    GLbitfield mode,
1961136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie			    GLubyte **out_map,
1971136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie			    GLint *out_stride)
1981136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie{
1991136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie    struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
2001136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie    uint16_t *untiled_z16_map, *tiled_z16_map;
2011136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie    int ret;
2021136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie    int y_flip = (rb->Name == 0) ? -1 : 1;
2031136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie    int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
2041136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie    uint32_t pitch = w * rrb->cpp;
2051136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie
2061136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie    rrb->map_pitch = pitch;
2071136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie
2081136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie    rrb->map_buffer = malloc(w * h * 2);
2091136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie    ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT));
210781a204bcf5599716991e5d36b08a36db5209441Dave Airlie    assert(!ret);
2111136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie
2121136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie    untiled_z16_map = rrb->map_buffer;
2131136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie    tiled_z16_map = rrb->bo->ptr;
2141136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie
2151136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie    for (uint32_t pix_y = 0; pix_y < h; ++ pix_y) {
2161136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie	for (uint32_t pix_x = 0; pix_x < w; ++pix_x) {
2171136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie	    uint32_t flipped_y = y_flip * (int32_t)(y + pix_y) + y_bias;
218781a204bcf5599716991e5d36b08a36db5209441Dave Airlie	    uint32_t src_offset = get_depth_z16(rrb, x + pix_x, flipped_y);
2191136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie	    uint32_t dst_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp;
2201136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie	    untiled_z16_map[dst_offset/2] = tiled_z16_map[src_offset/2];
2211136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie	}
2221136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie    }
2231136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie
2241136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie    radeon_bo_unmap(rrb->bo);
2251136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie
2261136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie    *out_map = rrb->map_buffer;
2271136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie    *out_stride = rrb->map_pitch;
2281136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie}
2297d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie
230425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholtstatic void
231425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholtradeon_map_renderbuffer(struct gl_context *ctx,
232425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt		       struct gl_renderbuffer *rb,
233425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt		       GLuint x, GLuint y, GLuint w, GLuint h,
234425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt		       GLbitfield mode,
235425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt		       GLubyte **out_map,
236425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt		       GLint *out_stride)
237425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt{
238425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   struct radeon_context *const rmesa = RADEON_CONTEXT(ctx);
239425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
240425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   GLubyte *map;
241425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   GLboolean ok;
242b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   int stride, flip_stride;
243b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   int ret;
244b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   int src_x, src_y;
245b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie
246b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   if (!rrb || !rrb->bo) {
247b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie	   *out_map = NULL;
248b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie	   *out_stride = 0;
249b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie	   return;
250b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   }
251b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie
252425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   rrb->map_mode = mode;
253425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   rrb->map_x = x;
254425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   rrb->map_y = y;
255425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   rrb->map_w = w;
256425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   rrb->map_h = h;
257b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   rrb->map_pitch = rrb->pitch;
258b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie
259b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   ok = rmesa->vtbl.check_blit(rb->Format, rrb->pitch / rrb->cpp);
260b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   if (ok) {
261b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie       if (rb->Name) {
262b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie	   src_x = x;
263b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie	   src_y = y;
264b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie       } else {
265b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie	   src_x = x;
266c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul	   src_y = rrb->base.Base.Height - y - h;
267b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie       }
268b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie
269b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie       /* Make a temporary buffer and blit the current contents of the renderbuffer
270b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie	* out to it.  This gives us linear access to the buffer, instead of having
271b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie	* to do detiling in software.
272b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie	*/
273b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie
274b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie       rrb->map_pitch = rrb->pitch;
275b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie
276b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie       assert(!rrb->map_bo);
277b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie       rrb->map_bo = radeon_bo_open(rmesa->radeonScreen->bom, 0,
278b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie				    rrb->map_pitch * h, 4,
279b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie				    RADEON_GEM_DOMAIN_GTT, 0);
280b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie
281b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie       ok = rmesa->vtbl.blit(ctx, rrb->bo, rrb->draw_offset,
282b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie			     rb->Format, rrb->pitch / rrb->cpp,
283b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie			     rb->Width, rb->Height,
284b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie			     src_x, src_y,
285b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie			     rrb->map_bo, 0,
286b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie			     rb->Format, rrb->map_pitch / rrb->cpp,
287b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie			     w, h,
288b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie			     0, 0,
289b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie			     w, h,
290b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie			     GL_FALSE);
291b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie       assert(ok);
292b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie
293b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie       ret = radeon_bo_map(rrb->map_bo, !!(mode & GL_MAP_WRITE_BIT));
294b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie       assert(!ret);
295b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie
296b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie       map = rrb->map_bo->ptr;
297b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie
298b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie       if (rb->Name) {
299b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie	   *out_map = map;
300b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie	   *out_stride = rrb->map_pitch;
301b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie       } else {
302b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie	   *out_map = map + (h - 1) * rrb->map_pitch;
303b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie	   *out_stride = -rrb->map_pitch;
304b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie       }
305b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie       return;
306b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   }
307b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie
308b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   /* sw fallback flush stuff */
309b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   if (radeon_bo_is_referenced_by_cs(rrb->bo, rmesa->cmdbuf.cs)) {
310b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie      radeon_firevertices(rmesa);
311b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   }
312425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt
313781a204bcf5599716991e5d36b08a36db5209441Dave Airlie   if ((rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_DEPTH_ALWAYS_TILED) && !rrb->has_surface) {
314781a204bcf5599716991e5d36b08a36db5209441Dave Airlie       if (rb->Format == MESA_FORMAT_S8_Z24 || rb->Format == MESA_FORMAT_X8_Z24) {
315781a204bcf5599716991e5d36b08a36db5209441Dave Airlie	   radeon_map_renderbuffer_s8z24(ctx, rb, x, y, w, h,
316781a204bcf5599716991e5d36b08a36db5209441Dave Airlie					 mode, out_map, out_stride);
317781a204bcf5599716991e5d36b08a36db5209441Dave Airlie	   return;
318781a204bcf5599716991e5d36b08a36db5209441Dave Airlie       }
319781a204bcf5599716991e5d36b08a36db5209441Dave Airlie       if (rb->Format == MESA_FORMAT_Z16) {
320781a204bcf5599716991e5d36b08a36db5209441Dave Airlie	   radeon_map_renderbuffer_z16(ctx, rb, x, y, w, h,
321781a204bcf5599716991e5d36b08a36db5209441Dave Airlie				       mode, out_map, out_stride);
322781a204bcf5599716991e5d36b08a36db5209441Dave Airlie	   return;
323781a204bcf5599716991e5d36b08a36db5209441Dave Airlie       }
3247d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie   }
3251136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie
326b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT));
327425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   assert(!ret);
328425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt
329b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   map = rrb->bo->ptr;
330b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   stride = rrb->map_pitch;
331425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt
332425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   if (rb->Name == 0) {
333b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie      y = rb->Height - 1 - y;
334b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie      flip_stride = -stride;
335b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   } else {
336b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie      flip_stride = stride;
337b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie      map += rrb->draw_offset;
338425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   }
339425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt
340b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   map += x * rrb->cpp;
341425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   map += (int)y * stride;
342425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt
343425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   *out_map = map;
344b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   *out_stride = flip_stride;
345425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt}
346425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt
3477d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airliestatic void
3487d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlieradeon_unmap_renderbuffer_s8z24(struct gl_context *ctx,
3497d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie			  struct gl_renderbuffer *rb)
3507d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie{
3517d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
3527d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie
3537d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie   if (!rrb->map_buffer)
3547d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie     return;
3557d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie
3567d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie   if (rrb->map_mode & GL_MAP_WRITE_BIT) {
3577d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie       uint32_t *untiled_s8z24_map = rrb->map_buffer;
3587d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie       uint32_t *tiled_s8z24_map;
3597d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie       int y_flip = (rb->Name == 0) ? -1 : 1;
3607d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie       int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
3617d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie
3627d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie       radeon_bo_map(rrb->bo, 1);
3637d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie
3647d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie       tiled_s8z24_map = rrb->bo->ptr;
3657d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie
3667d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie       for (uint32_t pix_y = 0; pix_y < rrb->map_h; pix_y++) {
3677d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie	   for (uint32_t pix_x = 0; pix_x < rrb->map_w; pix_x++) {
3687d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie	       uint32_t flipped_y = y_flip * (int32_t)(pix_y + rrb->map_y) + y_bias;
369781a204bcf5599716991e5d36b08a36db5209441Dave Airlie	       uint32_t dst_offset = get_depth_z32(rrb, rrb->map_x + pix_x, flipped_y);
3707d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie	       uint32_t src_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp;
3717d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie	       tiled_s8z24_map[dst_offset/4] = untiled_s8z24_map[src_offset/4];
3727d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie	   }
3737d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie       }
3747d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie       radeon_bo_unmap(rrb->bo);
3757d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie   }
3767d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie   free(rrb->map_buffer);
3777d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie   rrb->map_buffer = NULL;
3787d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie}
3791136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie
3801136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airliestatic void
3811136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlieradeon_unmap_renderbuffer_z16(struct gl_context *ctx,
3821136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie			      struct gl_renderbuffer *rb)
3831136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie{
3841136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
3851136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie
3861136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   if (!rrb->map_buffer)
3871136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie     return;
3881136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie
3891136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   if (rrb->map_mode & GL_MAP_WRITE_BIT) {
3901136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie       uint16_t *untiled_z16_map = rrb->map_buffer;
3911136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie       uint16_t *tiled_z16_map;
3921136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie       int y_flip = (rb->Name == 0) ? -1 : 1;
3931136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie       int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
3941136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie
3951136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie       radeon_bo_map(rrb->bo, 1);
3961136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie
3971136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie       tiled_z16_map = rrb->bo->ptr;
3981136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie
3991136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie       for (uint32_t pix_y = 0; pix_y < rrb->map_h; pix_y++) {
4001136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie	   for (uint32_t pix_x = 0; pix_x < rrb->map_w; pix_x++) {
4011136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie	       uint32_t flipped_y = y_flip * (int32_t)(pix_y + rrb->map_y) + y_bias;
402781a204bcf5599716991e5d36b08a36db5209441Dave Airlie	       uint32_t dst_offset = get_depth_z16(rrb, rrb->map_x + pix_x, flipped_y);
4031136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie	       uint32_t src_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp;
4041136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie	       tiled_z16_map[dst_offset/2] = untiled_z16_map[src_offset/2];
4051136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie	   }
4061136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie       }
4071136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie       radeon_bo_unmap(rrb->bo);
4081136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   }
4091136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   free(rrb->map_buffer);
4101136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   rrb->map_buffer = NULL;
4111136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie}
412781a204bcf5599716991e5d36b08a36db5209441Dave Airlie
4137d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie
414425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholtstatic void
415425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholtradeon_unmap_renderbuffer(struct gl_context *ctx,
416425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt			  struct gl_renderbuffer *rb)
417425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt{
418425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   struct radeon_context *const rmesa = RADEON_CONTEXT(ctx);
419425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
420425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   GLboolean ok;
421425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt
422781a204bcf5599716991e5d36b08a36db5209441Dave Airlie   if ((rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_DEPTH_ALWAYS_TILED) && !rrb->has_surface) {
423781a204bcf5599716991e5d36b08a36db5209441Dave Airlie       if (rb->Format == MESA_FORMAT_S8_Z24 || rb->Format == MESA_FORMAT_X8_Z24) {
424781a204bcf5599716991e5d36b08a36db5209441Dave Airlie	   radeon_unmap_renderbuffer_s8z24(ctx, rb);
425781a204bcf5599716991e5d36b08a36db5209441Dave Airlie	   return;
426781a204bcf5599716991e5d36b08a36db5209441Dave Airlie       }
427781a204bcf5599716991e5d36b08a36db5209441Dave Airlie       if (rb->Format == MESA_FORMAT_Z16) {
428781a204bcf5599716991e5d36b08a36db5209441Dave Airlie	   radeon_unmap_renderbuffer_z16(ctx, rb);
429781a204bcf5599716991e5d36b08a36db5209441Dave Airlie	   return;
430781a204bcf5599716991e5d36b08a36db5209441Dave Airlie       }
4311136da9c6bea8f579c0d92e5c263bde83a1fd0cfDave Airlie   }
4327d91ecf7a3a08c01a704f2d427444f7a97991680Dave Airlie
433b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   if (!rrb->map_bo) {
434b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie	   if (rrb->bo)
435b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie		   radeon_bo_unmap(rrb->bo);
436b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie	   return;
437b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   }
438b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie
439425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   radeon_bo_unmap(rrb->map_bo);
440425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt
441425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   if (rrb->map_mode & GL_MAP_WRITE_BIT) {
442425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt      ok = rmesa->vtbl.blit(ctx, rrb->map_bo, 0,
443b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie			    rb->Format, rrb->map_pitch / rrb->cpp,
444425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt			    rrb->map_w, rrb->map_h,
445425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt			    0, 0,
446425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt			    rrb->bo, rrb->draw_offset,
447425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt			    rb->Format, rrb->pitch / rrb->cpp,
448425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt			    rb->Width, rb->Height,
449425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt			    rrb->map_x, rrb->map_y,
450425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt			    rrb->map_w, rrb->map_h,
451425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt			    GL_FALSE);
452425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt      assert(ok);
453425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   }
454425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt
455425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   radeon_bo_unref(rrb->map_bo);
456425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt   rrb->map_bo = NULL;
457425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt}
458425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt
459fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
460fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie/**
461fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * Called via glRenderbufferStorageEXT() to set the format and allocate
462fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie * storage for a user-created renderbuffer.
463fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie */
464fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airliestatic GLboolean
465f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergradeon_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
466fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie                                 GLenum internalFormat,
467fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie                                 GLuint width, GLuint height)
468fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie{
469fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie  struct radeon_context *radeon = RADEON_CONTEXT(ctx);
470fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie  struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
471964c5195a2195165017fb8eb9bc3e5756735cc57Eric Anholt  uint32_t size, pitch;
472fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie  int cpp;
473fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
4744767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
4754767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen		"%s(%p, rb %p) \n",
4764767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen		__func__, ctx, rb);
4774767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen
478fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie   ASSERT(rb->Name != 0);
479230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie  switch (internalFormat) {
480230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_R3_G3_B2:
481230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_RGB4:
482230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_RGB5:
483c2711cdfb68d92ede740e2cc1fd7d78f604dc201Kristian Høgsberg      rb->Format = _radeon_texformat_rgb565;
484230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      cpp = 2;
485230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      break;
486230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_RGB:
487230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_RGB8:
488230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_RGB10:
489230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_RGB12:
490230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_RGB16:
491c2711cdfb68d92ede740e2cc1fd7d78f604dc201Kristian Høgsberg      rb->Format = _radeon_texformat_argb8888;
492230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      cpp = 4;
493230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      break;
494230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_RGBA:
495230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_RGBA2:
496230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_RGBA4:
497230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_RGB5_A1:
498230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_RGBA8:
499230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_RGB10_A2:
500230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_RGBA12:
501230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_RGBA16:
502c2711cdfb68d92ede740e2cc1fd7d78f604dc201Kristian Høgsberg      rb->Format = _radeon_texformat_argb8888;
503230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      cpp = 4;
504230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      break;
505230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_STENCIL_INDEX:
506230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_STENCIL_INDEX1_EXT:
507230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_STENCIL_INDEX4_EXT:
508230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_STENCIL_INDEX8_EXT:
509230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_STENCIL_INDEX16_EXT:
510230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      /* alloc a depth+stencil buffer */
511c47b03ebebd4db30bf5ed17b44c0f8757306b197Brian Paul      rb->Format = MESA_FORMAT_S8_Z24;
512230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      cpp = 4;
513230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      break;
514230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_DEPTH_COMPONENT16:
51545e76d2665b38ba3787548310efc59e969124c01Brian Paul      rb->Format = MESA_FORMAT_Z16;
516230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      cpp = 2;
517230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      break;
518230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_DEPTH_COMPONENT:
519230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_DEPTH_COMPONENT24:
520230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_DEPTH_COMPONENT32:
521e2131e017184a595a735e7ea1eced1552b8a7d22Brian Paul      rb->Format = MESA_FORMAT_X8_Z24;
522230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      cpp = 4;
523230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      break;
524230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_DEPTH_STENCIL_EXT:
525230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   case GL_DEPTH24_STENCIL8_EXT:
526c47b03ebebd4db30bf5ed17b44c0f8757306b197Brian Paul      rb->Format = MESA_FORMAT_S8_Z24;
527230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      cpp = 4;
528230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      break;
529230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   default:
530230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      _mesa_problem(ctx,
531e2131e017184a595a735e7ea1eced1552b8a7d22Brian Paul                    "Unexpected format in radeon_alloc_renderbuffer_storage");
532230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      return GL_FALSE;
533230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   }
534fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
53545e76d2665b38ba3787548310efc59e969124c01Brian Paul  rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
53645e76d2665b38ba3787548310efc59e969124c01Brian Paul
537a0d4a12614fce072fa1eb5516e626909171c95e1Alex Deucher  if (ctx->Driver.Flush)
538a0d4a12614fce072fa1eb5516e626909171c95e1Alex Deucher	  ctx->Driver.Flush(ctx); /* +r6/r7 */
539230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
540230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie  if (rrb->bo)
541230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie    radeon_bo_unref(rrb->bo);
542964c5195a2195165017fb8eb9bc3e5756735cc57Eric Anholt
543964c5195a2195165017fb8eb9bc3e5756735cc57Eric Anholt   pitch = ((cpp * width + 63) & ~63) / cpp;
544964c5195a2195165017fb8eb9bc3e5756735cc57Eric Anholt
545964c5195a2195165017fb8eb9bc3e5756735cc57Eric Anholt   if (RADEON_DEBUG & RADEON_MEMORY)
546964c5195a2195165017fb8eb9bc3e5756735cc57Eric Anholt      fprintf(stderr,"Allocating %d x %d radeon RBO (pitch %d)\n", width,
547964c5195a2195165017fb8eb9bc3e5756735cc57Eric Anholt	      height, pitch);
548964c5195a2195165017fb8eb9bc3e5756735cc57Eric Anholt
549964c5195a2195165017fb8eb9bc3e5756735cc57Eric Anholt   size = pitch * height * cpp;
550964c5195a2195165017fb8eb9bc3e5756735cc57Eric Anholt   rrb->pitch = pitch * cpp;
551964c5195a2195165017fb8eb9bc3e5756735cc57Eric Anholt   rrb->cpp = cpp;
552964c5195a2195165017fb8eb9bc3e5756735cc57Eric Anholt   rrb->bo = radeon_bo_open(radeon->radeonScreen->bom,
553964c5195a2195165017fb8eb9bc3e5756735cc57Eric Anholt			    0,
554964c5195a2195165017fb8eb9bc3e5756735cc57Eric Anholt			    size,
555964c5195a2195165017fb8eb9bc3e5756735cc57Eric Anholt			    0,
556964c5195a2195165017fb8eb9bc3e5756735cc57Eric Anholt			    RADEON_GEM_DOMAIN_VRAM,
557964c5195a2195165017fb8eb9bc3e5756735cc57Eric Anholt			    0);
558964c5195a2195165017fb8eb9bc3e5756735cc57Eric Anholt   rb->Width = width;
559964c5195a2195165017fb8eb9bc3e5756735cc57Eric Anholt   rb->Height = height;
560964c5195a2195165017fb8eb9bc3e5756735cc57Eric Anholt   return GL_TRUE;
561fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie}
562fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
563d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff#if FEATURE_OES_EGL_image
564d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloffstatic void
565d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloffradeon_image_target_renderbuffer_storage(struct gl_context *ctx,
566d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff                                         struct gl_renderbuffer *rb,
567d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff                                         void *image_handle)
568d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff{
569d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   radeonContextPtr radeon = RADEON_CONTEXT(ctx);
570d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   struct radeon_renderbuffer *rrb;
571d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   __DRIscreen *screen;
572d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   __DRIimage *image;
573d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff
574d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   screen = radeon->radeonScreen->driScreen;
575d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   image = screen->dri2.image->lookupEGLImage(screen, image_handle,
576d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff					      screen->loaderPrivate);
577d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   if (image == NULL)
578d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff      return;
579d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff
580d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   rrb = radeon_renderbuffer(rb);
581d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff
582d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   if (ctx->Driver.Flush)
583d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff      ctx->Driver.Flush(ctx); /* +r6/r7 */
584d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff
585d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   if (rrb->bo)
586d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff      radeon_bo_unref(rrb->bo);
587d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   rrb->bo = image->bo;
588d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   radeon_bo_ref(rrb->bo);
589d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   fprintf(stderr, "image->bo: %p, name: %d, rbs: w %d -> p %d\n", image->bo, image->bo->handle,
590d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff           image->width, image->pitch);
591d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff
592d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   rrb->cpp = image->cpp;
593d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   rrb->pitch = image->pitch * image->cpp;
594d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff
595d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   rb->Format = image->format;
596d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   rb->InternalFormat = image->internal_format;
597d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   rb->Width = image->width;
598d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   rb->Height = image->height;
599d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   rb->Format = image->format;
600d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff   rb->_BaseFormat = _mesa_base_fbo_format(radeon->glCtx,
601d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff                                           image->internal_format);
602d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff}
603d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff#endif
604230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
605230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie/**
606230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie * Called for each hardware renderbuffer when a _window_ is resized.
607230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie * Just update fields.
608230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie * Not used for user-created renderbuffers!
609230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie */
610230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airliestatic GLboolean
611f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergradeon_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
612230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie                           GLenum internalFormat, GLuint width, GLuint height)
613230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie{
614230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   ASSERT(rb->Name == 0);
615230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   rb->Width = width;
616230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   rb->Height = height;
61745e76d2665b38ba3787548310efc59e969124c01Brian Paul   rb->InternalFormat = internalFormat;
6184767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
6194767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen		"%s(%p, rb %p) \n",
6204767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen		__func__, ctx, rb);
6214767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen
622230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
623230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   return GL_TRUE;
624230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie}
625230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
626230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
627230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airliestatic void
628f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergradeon_resize_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
629230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie		     GLuint width, GLuint height)
630230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie{
631230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie     struct radeon_framebuffer *radeon_fb = (struct radeon_framebuffer*)fb;
632230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   int i;
633230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
6344767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
6354767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen		"%s(%p, fb %p) \n",
6364767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen		__func__, ctx, fb);
6374767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen
638230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   _mesa_resize_framebuffer(ctx, fb, width, height);
639230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
640230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   fb->Initialized = GL_TRUE; /* XXX remove someday */
641230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
642230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   if (fb->Name != 0) {
643230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      return;
644230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   }
645230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
646230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   /* Make sure all window system renderbuffers are up to date */
647230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   for (i = 0; i < 2; i++) {
648c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul      struct gl_renderbuffer *rb = &radeon_fb->color_rb[i]->base.Base;
649230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
650230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      /* only resize if size is changing */
651230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      if (rb && (rb->Width != width || rb->Height != height)) {
652230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie	 rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height);
653230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      }
654230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   }
655230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie}
656230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
657230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
658230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie/** Dummy function for gl_renderbuffer::AllocStorage() */
659230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airliestatic GLboolean
660f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergradeon_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
661230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie			 GLenum internalFormat, GLuint width, GLuint height)
662230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie{
663230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   _mesa_problem(ctx, "radeon_op_alloc_storage should never be called.");
664230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   return GL_FALSE;
665230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie}
666230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
667cf0e25d4c89b62f37ff8d1f11c50efcab6557c7fBrian Paul
668cf0e25d4c89b62f37ff8d1f11c50efcab6557c7fBrian Paul/**
669cf0e25d4c89b62f37ff8d1f11c50efcab6557c7fBrian Paul * Create a renderbuffer for a window's color, depth and/or stencil buffer.
670cf0e25d4c89b62f37ff8d1f11c50efcab6557c7fBrian Paul * Not used for user-created renderbuffers.
671cf0e25d4c89b62f37ff8d1f11c50efcab6557c7fBrian Paul */
6728c7e30fb950c83f5e9e29e60735e999ac608145aDave Airliestruct radeon_renderbuffer *
673d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsbergradeon_create_renderbuffer(gl_format format, __DRIdrawable *driDrawPriv)
674230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie{
675230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie    struct radeon_renderbuffer *rrb;
676c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul    struct gl_renderbuffer *rb;
677230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
678230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie    rrb = CALLOC_STRUCT(radeon_renderbuffer);
6794767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen
6804767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen    radeon_print(RADEON_TEXTURE, RADEON_TRACE,
6814767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen		"%s( rrb %p ) \n",
6824767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen		__func__, rrb);
6834767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen
684230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie    if (!rrb)
685230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie	return NULL;
686230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
687c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul    rb = &rrb->base.Base;
688230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
689c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul    _mesa_init_renderbuffer(rb, 0);
690c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul    rb->ClassID = RADEON_RB_CLASS;
691c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul    rb->Format = format;
692c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul    rb->_BaseFormat = _mesa_get_format_base_format(format);
693c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul    rb->InternalFormat = _mesa_get_format_base_format(format);
694230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
695230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie    rrb->dPriv = driDrawPriv;
696230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
697c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul    rb->Delete = radeon_delete_renderbuffer;
698c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul    rb->AllocStorage = radeon_alloc_window_storage;
699230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
700230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie    rrb->bo = NULL;
7018c7e30fb950c83f5e9e29e60735e999ac608145aDave Airlie    return rrb;
702230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie}
703230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
704fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airliestatic struct gl_renderbuffer *
705f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergradeon_new_renderbuffer(struct gl_context * ctx, GLuint name)
706fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie{
707fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie  struct radeon_renderbuffer *rrb;
708c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul  struct gl_renderbuffer *rb;
709c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul
710fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
711fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie  rrb = CALLOC_STRUCT(radeon_renderbuffer);
7124767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen
7134767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
7144767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen		"%s(%p, rrb %p) \n",
7154767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen		__func__, ctx, rrb);
7164767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen
717fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie  if (!rrb)
718fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie    return NULL;
719fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
720c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul  rb = &rrb->base.Base;
721fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
722c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul  _mesa_init_renderbuffer(rb, name);
723c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul  rb->ClassID = RADEON_RB_CLASS;
724c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul  rb->Delete = radeon_delete_renderbuffer;
725c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul  rb->AllocStorage = radeon_alloc_renderbuffer_storage;
726fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
727c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul  return rb;
728fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie}
729fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
730fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airliestatic void
731f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergradeon_bind_framebuffer(struct gl_context * ctx, GLenum target,
732fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie                       struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
733fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie{
7344767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
7354767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen		"%s(%p, fb %p, target %s) \n",
7364767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen		__func__, ctx, fb,
7374767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen		_mesa_lookup_enum_by_nr(target));
7384767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen
739fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie   if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
740fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie      radeon_draw_buffer(ctx, fb);
741fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie   }
742fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie   else {
743fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie      /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
744fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie   }
745fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie}
746fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
747fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airliestatic void
748f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergradeon_framebuffer_renderbuffer(struct gl_context * ctx,
749fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie                               struct gl_framebuffer *fb,
750fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie                               GLenum attachment, struct gl_renderbuffer *rb)
751fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie{
752fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
753a0d4a12614fce072fa1eb5516e626909171c95e1Alex Deucher	if (ctx->Driver.Flush)
754a0d4a12614fce072fa1eb5516e626909171c95e1Alex Deucher		ctx->Driver.Flush(ctx); /* +r6/r7 */
755fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
7564767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen	radeon_print(RADEON_TEXTURE, RADEON_TRACE,
7574767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen		"%s(%p, fb %p, rb %p) \n",
7584767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen		__func__, ctx, fb, rb);
7594767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen
760fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie   _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
761fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie   radeon_draw_buffer(ctx, fb);
762fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie}
763fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
764230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airliestatic GLboolean
765f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergradeon_update_wrapper(struct gl_context *ctx, struct radeon_renderbuffer *rrb,
766230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie		     struct gl_texture_image *texImage)
767230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie{
768c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul	struct gl_renderbuffer *rb = &rrb->base.Base;
769c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul
7704767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen	radeon_print(RADEON_TEXTURE, RADEON_TRACE,
771b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora		"%s(%p, rrb %p, texImage %p, texFormat %s) \n",
772b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora		__func__, ctx, rrb, texImage, _mesa_get_format_name(texImage->TexFormat));
773b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora
774b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora	rrb->cpp = _mesa_get_format_bytes(texImage->TexFormat);
775f9d272fa414ec04d9cc608840436f29e6adf84bcDave Airlie	rrb->pitch = texImage->Width * rrb->cpp;
776c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul	rb->Format = texImage->TexFormat;
777c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul	rb->InternalFormat = texImage->InternalFormat;
778c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul	rb->_BaseFormat = _mesa_base_fbo_format(ctx, rb->InternalFormat);
779c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul	rb->Width = texImage->Width;
780c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul	rb->Height = texImage->Height;
781c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul	rb->Delete = radeon_delete_renderbuffer;
782c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul	rb->AllocStorage = radeon_nop_alloc_storage;
783b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora
784f9d272fa414ec04d9cc608840436f29e6adf84bcDave Airlie	return GL_TRUE;
785230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie}
786230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
787230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
788fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airliestatic struct radeon_renderbuffer *
789f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergradeon_wrap_texture(struct gl_context * ctx, struct gl_texture_image *texImage)
790fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie{
791230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie  const GLuint name = ~0;   /* not significant, but distinct for debugging */
792230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie  struct radeon_renderbuffer *rrb;
793230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
794230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   /* make an radeon_renderbuffer to wrap the texture image */
795230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   rrb = CALLOC_STRUCT(radeon_renderbuffer);
7964767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen
7974767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
7984767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen		"%s(%p, rrb %p, texImage %p) \n",
7994767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen		__func__, ctx, rrb, texImage);
8004767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen
801230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   if (!rrb) {
802230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture");
803230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      return NULL;
804230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   }
805230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
806c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul   _mesa_init_renderbuffer(&rrb->base.Base, name);
807c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul   rrb->base.Base.ClassID = RADEON_RB_CLASS;
808230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
809230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   if (!radeon_update_wrapper(ctx, rrb, texImage)) {
81032f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg      free(rrb);
811230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie      return NULL;
812230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   }
813fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
814230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie   return rrb;
815230abc06f817b5d9868f7e6a094f56bb3294b476Dave Airlie
816fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie}
817fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airliestatic void
818f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergradeon_render_texture(struct gl_context * ctx,
819fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie                     struct gl_framebuffer *fb,
820fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie                     struct gl_renderbuffer_attachment *att)
821fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie{
822ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie   struct gl_texture_image *newImage
823ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie      = att->Texture->Image[att->CubeMapFace][att->TextureLevel];
824ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie   struct radeon_renderbuffer *rrb = radeon_renderbuffer(att->Renderbuffer);
825ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie   radeon_texture_image *radeon_image;
826ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie   GLuint imageOffset;
827ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie
8284767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
82977e6fb17d96ed9d9b3c2f52999e93da12a466405Pauli Nieminen		"%s(%p, fb %p, rrb %p, att %p)\n",
8304767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen		__func__, ctx, fb, rrb, att);
8314767d27ee32cc30ee00ab5265ecbb8eeefcab8c9Pauli Nieminen
832ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie   (void) fb;
833ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie
834ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie   ASSERT(newImage);
835ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie
836f49da110a81cc964100efa6a09e0fcdc7a35a935Will Dyson   radeon_image = (radeon_texture_image *)newImage;
837f49da110a81cc964100efa6a09e0fcdc7a35a935Will Dyson
838b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   if (!radeon_image->mt) {
839f49da110a81cc964100efa6a09e0fcdc7a35a935Will Dyson      /* Fallback on drawing to a texture without a miptree.
840ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie       */
841ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie      _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
842755f2e2ae597df9208523b0996bbdabf3db463b0Brian Paul      _swrast_render_texture(ctx, fb, att);
843ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie      return;
844ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie   }
845ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie   else if (!rrb) {
846ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie      rrb = radeon_wrap_texture(ctx, newImage);
847ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie      if (rrb) {
848ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie         /* bind the wrapper to the attachment point */
849c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul         _mesa_reference_renderbuffer(&att->Renderbuffer, &rrb->base.Base);
850ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie      }
851ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie      else {
852ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie         /* fallback to software rendering */
853755f2e2ae597df9208523b0996bbdabf3db463b0Brian Paul         _swrast_render_texture(ctx, fb, att);
854ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie         return;
855ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie      }
856ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie   }
857ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie
858ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie   if (!radeon_update_wrapper(ctx, rrb, newImage)) {
859ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie       _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
860755f2e2ae597df9208523b0996bbdabf3db463b0Brian Paul       _swrast_render_texture(ctx, fb, att);
861ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie       return;
862ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie   }
863fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
864f96e8a033b212b54a80622839579c99dff2378fcVinson Lee   DBG("Begin render texture tid %lx tex=%u w=%d h=%d refcount=%d\n",
865ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie       _glthread_GetID(),
866ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie       att->Texture->Name, newImage->Width, newImage->Height,
867c080202db5363a18a759a9a7c82b40ac558c8abeBrian Paul       rrb->base.Base.RefCount);
868ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie
869ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie   /* point the renderbufer's region to the texture image region */
870ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie   if (rrb->bo != radeon_image->mt->bo) {
871ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie      if (rrb->bo)
872ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie  	radeon_bo_unref(rrb->bo);
873ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie      rrb->bo = radeon_image->mt->bo;
874ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie      radeon_bo_ref(rrb->bo);
875ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie   }
876ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie
877ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie   /* compute offset of the particular 2D image within the texture region */
878ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie   imageOffset = radeon_miptree_image_offset(radeon_image->mt,
879ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie                                            att->CubeMapFace,
880ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie                                            att->TextureLevel);
881ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie
882ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie   if (att->Texture->Target == GL_TEXTURE_3D) {
8837c6f51cdccdd0ed6370ce86ba21549991f4f4293Andre Maasikas      imageOffset += radeon_image->mt->levels[att->TextureLevel].rowstride *
8847c6f51cdccdd0ed6370ce86ba21549991f4f4293Andre Maasikas                     radeon_image->mt->levels[att->TextureLevel].height *
8857c6f51cdccdd0ed6370ce86ba21549991f4f4293Andre Maasikas                     att->Zoffset;
886ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie   }
887ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie
8883f30b0709b5a71915df336194f9f805e4c306cefOwen Taylor   /* store that offset in the region, along with the correct pitch for
8893f30b0709b5a71915df336194f9f805e4c306cefOwen Taylor    * the image we are rendering to */
890c607a664dd005c001afda1fff1a68d41925fa86eDave Airlie   rrb->draw_offset = imageOffset;
8913f30b0709b5a71915df336194f9f805e4c306cefOwen Taylor   rrb->pitch = radeon_image->mt->levels[att->TextureLevel].rowstride;
892b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie   radeon_image->used_as_render_target = GL_TRUE;
89306cb6f7aa799e25b4a53f8c547a8f4ca909fe245Dave Airlie
894ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie   /* update drawing region, etc */
895ba890ad35b3ff52603665bdb576f9efcbb3a108aDave Airlie   radeon_draw_buffer(ctx, fb);
896fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie}
897fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
898fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airliestatic void
899f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergradeon_finish_render_texture(struct gl_context * ctx,
900fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie                            struct gl_renderbuffer_attachment *att)
901fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie{
902b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie    struct gl_texture_object *tex_obj = att->Texture;
903b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie    struct gl_texture_image *image =
904b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie	tex_obj->Image[att->CubeMapFace][att->TextureLevel];
905b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie    radeon_texture_image *radeon_image = (radeon_texture_image *)image;
906b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie
907b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie    if (radeon_image)
908b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie	radeon_image->used_as_render_target = GL_FALSE;
909b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie
910b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie    if (ctx->Driver.Flush)
911b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9Dave Airlie        ctx->Driver.Flush(ctx); /* +r6/r7 */
912fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie}
913fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airliestatic void
914f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergradeon_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
915fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie{
916b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
917b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora	gl_format mesa_format;
918b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora	int i;
919b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora
920b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora	for (i = -2; i < (GLint) ctx->Const.MaxColorAttachments; i++) {
921b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora		struct gl_renderbuffer_attachment *att;
922b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora		if (i == -2) {
923b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora			att = &fb->Attachment[BUFFER_DEPTH];
924b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora		} else if (i == -1) {
925b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora			att = &fb->Attachment[BUFFER_STENCIL];
926b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora		} else {
927b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora			att = &fb->Attachment[BUFFER_COLOR0 + i];
928b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora		}
929b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora
930b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora		if (att->Type == GL_TEXTURE) {
931b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora			mesa_format = att->Texture->Image[att->CubeMapFace][att->TextureLevel]->TexFormat;
932b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora		} else {
933b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora			/* All renderbuffer formats are renderable, but not sampable */
934b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora			continue;
935b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora		}
936b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora
937b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora		if (!radeon->vtbl.is_format_renderable(mesa_format)){
938b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora			fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
939b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora			radeon_print(RADEON_TEXTURE, RADEON_TRACE,
940b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora						"%s: HW doesn't support format %s as output format of attachment %d\n",
941b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora						__FUNCTION__, _mesa_get_format_name(mesa_format), i);
942b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora			return;
943b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora		}
944b70dcabafce0c1a8a9fbbd84ff196e46b0782ca7Maciej Cencora	}
945fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie}
946fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
947fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlievoid radeon_fbo_init(struct radeon_context *radeon)
948fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie{
949234a06517185efd972ec162bf9536183c5bc04c3nobled#if FEATURE_EXT_framebuffer_object
950fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie  radeon->glCtx->Driver.NewFramebuffer = radeon_new_framebuffer;
951fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie  radeon->glCtx->Driver.NewRenderbuffer = radeon_new_renderbuffer;
952425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt  radeon->glCtx->Driver.MapRenderbuffer = radeon_map_renderbuffer;
953425b8d54b8c97bcbd433393f34a27027e4ff8c4dEric Anholt  radeon->glCtx->Driver.UnmapRenderbuffer = radeon_unmap_renderbuffer;
954fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie  radeon->glCtx->Driver.BindFramebuffer = radeon_bind_framebuffer;
955fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie  radeon->glCtx->Driver.FramebufferRenderbuffer = radeon_framebuffer_renderbuffer;
956fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie  radeon->glCtx->Driver.RenderTexture = radeon_render_texture;
957fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie  radeon->glCtx->Driver.FinishRenderTexture = radeon_finish_render_texture;
958fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie  radeon->glCtx->Driver.ResizeBuffers = radeon_resize_buffers;
959fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie  radeon->glCtx->Driver.ValidateFramebuffer = radeon_validate_framebuffer;
960234a06517185efd972ec162bf9536183c5bc04c3nobled#endif
961234a06517185efd972ec162bf9536183c5bc04c3nobled#if FEATURE_EXT_framebuffer_blit
9624de8e2123ebeb50db252b2bb57fb167058fa4683Brian Paul  radeon->glCtx->Driver.BlitFramebuffer = _mesa_meta_BlitFramebuffer;
963234a06517185efd972ec162bf9536183c5bc04c3nobled#endif
964d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff#if FEATURE_OES_EGL_image
965d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff  radeon->glCtx->Driver.EGLImageTargetRenderbufferStorage =
966d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff	  radeon_image_target_renderbuffer_storage;
967d7855ee3323e8493f139af70db9d0cdb853c2a08Johann Rudloff#endif
968fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie}
969fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
970fabce837f9740df2553b6cc0dd991b2cb8b8fc5bDave Airlie
9718c7e30fb950c83f5e9e29e60735e999ac608145aDave Airlievoid radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb,
9728c7e30fb950c83f5e9e29e60735e999ac608145aDave Airlie				struct radeon_bo *bo)
9738c7e30fb950c83f5e9e29e60735e999ac608145aDave Airlie{
9748c7e30fb950c83f5e9e29e60735e999ac608145aDave Airlie  struct radeon_bo *old;
9758c7e30fb950c83f5e9e29e60735e999ac608145aDave Airlie  old = rb->bo;
9768c7e30fb950c83f5e9e29e60735e999ac608145aDave Airlie  rb->bo = bo;
9778c7e30fb950c83f5e9e29e60735e999ac608145aDave Airlie  radeon_bo_ref(bo);
9788c7e30fb950c83f5e9e29e60735e999ac608145aDave Airlie  if (old)
9798c7e30fb950c83f5e9e29e60735e999ac608145aDave Airlie    radeon_bo_unref(old);
9808c7e30fb950c83f5e9e29e60735e999ac608145aDave Airlie}
981