diff options
author | Dave Airlie <airlied@redhat.com> | 2011-12-05 19:15:04 +0000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-12-05 19:15:04 +0000 |
commit | 7d91ecf7a3a08c01a704f2d427444f7a97991680 (patch) | |
tree | 249754b8dff2ba4675199188330497a91f7e43fc | |
parent | c48763643ebd87013a09c5498d9a5d3713dc1014 (diff) |
radeon/r200: add draw/stencil buffer detiling
This moves the detiling to the fbo mapping, r200 depth is always tiled,
and we can't detile it with the blitter.
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_common_context.h | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_fbo.c | 110 |
2 files changed, 111 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h index b8c6bf00ebc..5a320790478 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h | |||
@@ -90,6 +90,7 @@ struct radeon_renderbuffer | |||
90 | GLbitfield map_mode; | 90 | GLbitfield map_mode; |
91 | int map_x, map_y, map_w, map_h; | 91 | int map_x, map_y, map_w, map_h; |
92 | int map_pitch; | 92 | int map_pitch; |
93 | void *map_buffer; | ||
93 | 94 | ||
94 | uint32_t draw_offset; /* FBO */ | 95 | uint32_t draw_offset; /* FBO */ |
95 | /* boo Xorg 6.8.2 compat */ | 96 | /* boo Xorg 6.8.2 compat */ |
diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c index 5aad67f1a75..4dd523f0e34 100644 --- a/src/mesa/drivers/dri/radeon/radeon_fbo.c +++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c | |||
@@ -70,6 +70,66 @@ radeon_delete_renderbuffer(struct gl_renderbuffer *rb) | |||
70 | free(rrb); | 70 | free(rrb); |
71 | } | 71 | } |
72 | 72 | ||
73 | #if defined(RADEON_R200) | ||
74 | static GLuint r200_depth_4byte(const struct radeon_renderbuffer * rrb, | ||
75 | GLint x, GLint y) | ||
76 | { | ||
77 | GLuint offset; | ||
78 | GLuint b; | ||
79 | offset = 0; | ||
80 | b = (((y & 0x7ff) >> 4) * (rrb->pitch >> 7) + (x >> 5)); | ||
81 | offset += (b >> 1) << 12; | ||
82 | offset += (((rrb->pitch >> 7) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11; | ||
83 | offset += ((y >> 2) & 0x3) << 9; | ||
84 | offset += ((x >> 2) & 0x1) << 8; | ||
85 | offset += ((x >> 3) & 0x3) << 6; | ||
86 | offset += ((y >> 1) & 0x1) << 5; | ||
87 | offset += ((x >> 1) & 0x1) << 4; | ||
88 | offset += (y & 0x1) << 3; | ||
89 | offset += (x & 0x1) << 2; | ||
90 | |||
91 | return offset; | ||
92 | } | ||
93 | |||
94 | static void | ||
95 | radeon_map_renderbuffer_s8z24(struct gl_context *ctx, | ||
96 | struct gl_renderbuffer *rb, | ||
97 | GLuint x, GLuint y, GLuint w, GLuint h, | ||
98 | GLbitfield mode, | ||
99 | GLubyte **out_map, | ||
100 | GLint *out_stride) | ||
101 | { | ||
102 | struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); | ||
103 | uint32_t *untiled_s8z24_map, *tiled_s8z24_map; | ||
104 | int ret; | ||
105 | int y_flip = (rb->Name == 0) ? -1 : 1; | ||
106 | int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0; | ||
107 | uint32_t pitch = w * rrb->cpp; | ||
108 | |||
109 | rrb->map_pitch = pitch; | ||
110 | |||
111 | rrb->map_buffer = malloc(w * h * 4); | ||
112 | ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT)); | ||
113 | |||
114 | untiled_s8z24_map = rrb->map_buffer; | ||
115 | tiled_s8z24_map = rrb->bo->ptr; | ||
116 | |||
117 | for (uint32_t pix_y = 0; pix_y < h; ++ pix_y) { | ||
118 | for (uint32_t pix_x = 0; pix_x < w; ++pix_x) { | ||
119 | uint32_t flipped_y = y_flip * (int32_t)(y + pix_y) + y_bias; | ||
120 | uint32_t src_offset = r200_depth_4byte(rrb, x + pix_x, flipped_y); | ||
121 | uint32_t dst_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp; | ||
122 | untiled_s8z24_map[dst_offset/4] = tiled_s8z24_map[src_offset/4]; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | radeon_bo_unmap(rrb->bo); | ||
127 | |||
128 | *out_map = rrb->map_buffer; | ||
129 | *out_stride = rrb->map_pitch; | ||
130 | } | ||
131 | #endif | ||
132 | |||
73 | static void | 133 | static void |
74 | radeon_map_renderbuffer(struct gl_context *ctx, | 134 | radeon_map_renderbuffer(struct gl_context *ctx, |
75 | struct gl_renderbuffer *rb, | 135 | struct gl_renderbuffer *rb, |
@@ -153,6 +213,13 @@ radeon_map_renderbuffer(struct gl_context *ctx, | |||
153 | radeon_firevertices(rmesa); | 213 | radeon_firevertices(rmesa); |
154 | } | 214 | } |
155 | 215 | ||
216 | #if defined(RADEON_R200) | ||
217 | if (rb->Format == MESA_FORMAT_S8_Z24 && !rrb->has_surface) { | ||
218 | radeon_map_renderbuffer_s8z24(ctx, rb, x, y, w, h, | ||
219 | mode, out_map, out_stride); | ||
220 | return; | ||
221 | } | ||
222 | #endif | ||
156 | ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT)); | 223 | ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT)); |
157 | assert(!ret); | 224 | assert(!ret); |
158 | 225 | ||
@@ -174,6 +241,42 @@ radeon_map_renderbuffer(struct gl_context *ctx, | |||
174 | *out_stride = flip_stride; | 241 | *out_stride = flip_stride; |
175 | } | 242 | } |
176 | 243 | ||
244 | #if defined(RADEON_R200) | ||
245 | static void | ||
246 | radeon_unmap_renderbuffer_s8z24(struct gl_context *ctx, | ||
247 | struct gl_renderbuffer *rb) | ||
248 | { | ||
249 | struct radeon_context *const rmesa = RADEON_CONTEXT(ctx); | ||
250 | struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); | ||
251 | |||
252 | if (!rrb->map_buffer) | ||
253 | return; | ||
254 | |||
255 | if (rrb->map_mode & GL_MAP_WRITE_BIT) { | ||
256 | uint32_t *untiled_s8z24_map = rrb->map_buffer; | ||
257 | uint32_t *tiled_s8z24_map; | ||
258 | int y_flip = (rb->Name == 0) ? -1 : 1; | ||
259 | int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0; | ||
260 | |||
261 | radeon_bo_map(rrb->bo, 1); | ||
262 | |||
263 | tiled_s8z24_map = rrb->bo->ptr; | ||
264 | |||
265 | for (uint32_t pix_y = 0; pix_y < rrb->map_h; pix_y++) { | ||
266 | for (uint32_t pix_x = 0; pix_x < rrb->map_w; pix_x++) { | ||
267 | uint32_t flipped_y = y_flip * (int32_t)(pix_y + rrb->map_y) + y_bias; | ||
268 | uint32_t dst_offset = r200_depth_4byte(rrb, rrb->map_x + pix_x, flipped_y); | ||
269 | uint32_t src_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp; | ||
270 | tiled_s8z24_map[dst_offset/4] = untiled_s8z24_map[src_offset/4]; | ||
271 | } | ||
272 | } | ||
273 | radeon_bo_unmap(rrb->bo); | ||
274 | } | ||
275 | free(rrb->map_buffer); | ||
276 | rrb->map_buffer = NULL; | ||
277 | } | ||
278 | #endif | ||
279 | |||
177 | static void | 280 | static void |
178 | radeon_unmap_renderbuffer(struct gl_context *ctx, | 281 | radeon_unmap_renderbuffer(struct gl_context *ctx, |
179 | struct gl_renderbuffer *rb) | 282 | struct gl_renderbuffer *rb) |
@@ -182,6 +285,13 @@ radeon_unmap_renderbuffer(struct gl_context *ctx, | |||
182 | struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); | 285 | struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); |
183 | GLboolean ok; | 286 | GLboolean ok; |
184 | 287 | ||
288 | #ifdef RADEON_R200 | ||
289 | if (rb->Format == MESA_FORMAT_S8_Z24 && !rrb->has_surface) { | ||
290 | radeon_unmap_renderbuffer_s8z24(ctx, rb); | ||
291 | return; | ||
292 | } | ||
293 | #endif | ||
294 | |||
185 | if (!rrb->map_bo) { | 295 | if (!rrb->map_bo) { |
186 | if (rrb->bo) | 296 | if (rrb->bo) |
187 | radeon_bo_unmap(rrb->bo); | 297 | radeon_bo_unmap(rrb->bo); |