diff options
Diffstat (limited to 'src/mesa/drivers/dri/radeon')
-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 GLbitfield map_mode; int map_x, map_y, map_w, map_h; int map_pitch; + void *map_buffer; uint32_t draw_offset; /* FBO */ /* 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) free(rrb); } +#if defined(RADEON_R200) +static GLuint r200_depth_4byte(const struct radeon_renderbuffer * rrb, + GLint x, GLint y) +{ + GLuint offset; + GLuint b; + offset = 0; + b = (((y & 0x7ff) >> 4) * (rrb->pitch >> 7) + (x >> 5)); + offset += (b >> 1) << 12; + offset += (((rrb->pitch >> 7) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11; + offset += ((y >> 2) & 0x3) << 9; + offset += ((x >> 2) & 0x1) << 8; + offset += ((x >> 3) & 0x3) << 6; + offset += ((y >> 1) & 0x1) << 5; + offset += ((x >> 1) & 0x1) << 4; + offset += (y & 0x1) << 3; + offset += (x & 0x1) << 2; + + return offset; +} + +static void +radeon_map_renderbuffer_s8z24(struct gl_context *ctx, + struct gl_renderbuffer *rb, + GLuint x, GLuint y, GLuint w, GLuint h, + GLbitfield mode, + GLubyte **out_map, + GLint *out_stride) +{ + struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); + uint32_t *untiled_s8z24_map, *tiled_s8z24_map; + int ret; + int y_flip = (rb->Name == 0) ? -1 : 1; + int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0; + uint32_t pitch = w * rrb->cpp; + + rrb->map_pitch = pitch; + + rrb->map_buffer = malloc(w * h * 4); + ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT)); + + untiled_s8z24_map = rrb->map_buffer; + tiled_s8z24_map = rrb->bo->ptr; + + for (uint32_t pix_y = 0; pix_y < h; ++ pix_y) { + for (uint32_t pix_x = 0; pix_x < w; ++pix_x) { + uint32_t flipped_y = y_flip * (int32_t)(y + pix_y) + y_bias; + uint32_t src_offset = r200_depth_4byte(rrb, x + pix_x, flipped_y); + uint32_t dst_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp; + untiled_s8z24_map[dst_offset/4] = tiled_s8z24_map[src_offset/4]; + } + } + + radeon_bo_unmap(rrb->bo); + + *out_map = rrb->map_buffer; + *out_stride = rrb->map_pitch; +} +#endif + static void radeon_map_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb, @@ -153,6 +213,13 @@ radeon_map_renderbuffer(struct gl_context *ctx, radeon_firevertices(rmesa); } +#if defined(RADEON_R200) + if (rb->Format == MESA_FORMAT_S8_Z24 && !rrb->has_surface) { + radeon_map_renderbuffer_s8z24(ctx, rb, x, y, w, h, + mode, out_map, out_stride); + return; + } +#endif ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT)); assert(!ret); @@ -174,6 +241,42 @@ radeon_map_renderbuffer(struct gl_context *ctx, *out_stride = flip_stride; } +#if defined(RADEON_R200) +static void +radeon_unmap_renderbuffer_s8z24(struct gl_context *ctx, + struct gl_renderbuffer *rb) +{ + struct radeon_context *const rmesa = RADEON_CONTEXT(ctx); + struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); + + if (!rrb->map_buffer) + return; + + if (rrb->map_mode & GL_MAP_WRITE_BIT) { + uint32_t *untiled_s8z24_map = rrb->map_buffer; + uint32_t *tiled_s8z24_map; + int y_flip = (rb->Name == 0) ? -1 : 1; + int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0; + + radeon_bo_map(rrb->bo, 1); + + tiled_s8z24_map = rrb->bo->ptr; + + for (uint32_t pix_y = 0; pix_y < rrb->map_h; pix_y++) { + for (uint32_t pix_x = 0; pix_x < rrb->map_w; pix_x++) { + uint32_t flipped_y = y_flip * (int32_t)(pix_y + rrb->map_y) + y_bias; + uint32_t dst_offset = r200_depth_4byte(rrb, rrb->map_x + pix_x, flipped_y); + uint32_t src_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp; + tiled_s8z24_map[dst_offset/4] = untiled_s8z24_map[src_offset/4]; + } + } + radeon_bo_unmap(rrb->bo); + } + free(rrb->map_buffer); + rrb->map_buffer = NULL; +} +#endif + static void radeon_unmap_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb) @@ -182,6 +285,13 @@ radeon_unmap_renderbuffer(struct gl_context *ctx, struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); GLboolean ok; +#ifdef RADEON_R200 + if (rb->Format == MESA_FORMAT_S8_Z24 && !rrb->has_surface) { + radeon_unmap_renderbuffer_s8z24(ctx, rb); + return; + } +#endif + if (!rrb->map_bo) { if (rrb->bo) radeon_bo_unmap(rrb->bo); |