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>
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user