intel: Move separate-stencil s8 mapping logic to intel_miptree_map.
We're going to want to reuse this logic in mapping of fake packed miptrees wrapping separate depth/stencil miptrees. Reviewed-by: Chad Versace <chad.versace@linux.intel.com>
This commit is contained in:
@@ -255,68 +255,6 @@ intel_map_renderbuffer_blit(struct gl_context *ctx,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Map a stencil renderbuffer.
|
||||
*
|
||||
* Stencil buffers are W-tiled. Since the GTT has no W fence, we must detile
|
||||
* the buffer in software.
|
||||
*
|
||||
* This function allocates a temporary malloc'd buffer at
|
||||
* intel_renderbuffer::map_buffer, detiles the stencil buffer into it, then
|
||||
* returns the temporary buffer as the map.
|
||||
*
|
||||
* \see intel_renderbuffer::map_buffer
|
||||
* \see intel_map_renderbuffer()
|
||||
* \see intel_unmap_renderbuffer_s8()
|
||||
*/
|
||||
static void
|
||||
intel_map_renderbuffer_s8(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 intel_context *intel = intel_context(ctx);
|
||||
struct intel_renderbuffer *irb = intel_renderbuffer(rb);
|
||||
uint8_t *tiled_s8_map;
|
||||
uint8_t *untiled_s8_map;
|
||||
|
||||
assert(rb->Format == MESA_FORMAT_S8);
|
||||
assert(irb->mt);
|
||||
|
||||
irb->map_mode = mode;
|
||||
irb->map_x = x;
|
||||
irb->map_y = y;
|
||||
irb->map_w = w;
|
||||
irb->map_h = h;
|
||||
|
||||
/* Flip the Y axis for the default framebuffer. */
|
||||
int y_flip = (rb->Name == 0) ? -1 : 1;
|
||||
int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
|
||||
|
||||
irb->map_buffer = malloc(w * h);
|
||||
untiled_s8_map = irb->map_buffer;
|
||||
tiled_s8_map = intel_region_map(intel, irb->mt->region, mode);
|
||||
|
||||
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;
|
||||
ptrdiff_t offset = intel_offset_S8(irb->mt->region->pitch,
|
||||
x + pix_x,
|
||||
flipped_y);
|
||||
untiled_s8_map[pix_y * w + pix_x] = tiled_s8_map[offset];
|
||||
}
|
||||
}
|
||||
|
||||
*out_map = untiled_s8_map;
|
||||
*out_stride = w;
|
||||
|
||||
DBG("%s: rb %d (%s) s8 detiled mapped: (%d, %d) (%dx%d) -> %p/%d\n",
|
||||
__FUNCTION__, rb->Name, _mesa_get_format_name(rb->Format),
|
||||
x, y, w, h, *out_map, *out_stride);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Map a depthstencil buffer with separate stencil.
|
||||
*
|
||||
@@ -412,8 +350,32 @@ intel_map_renderbuffer(struct gl_context *ctx,
|
||||
}
|
||||
|
||||
if (rb->Format == MESA_FORMAT_S8) {
|
||||
intel_map_renderbuffer_s8(ctx, rb, x, y, w, h, mode,
|
||||
out_map, out_stride);
|
||||
void *map;
|
||||
int stride;
|
||||
|
||||
/* For a window-system renderbuffer, we need to flip the mapping we
|
||||
* receive upside-down. So we need to ask for a rectangle on flipped
|
||||
* vertically, and we then return a pointer to the bottom of it with a
|
||||
* negative stride.
|
||||
*/
|
||||
if (rb->Name == 0) {
|
||||
y = rb->Height - y - h;
|
||||
}
|
||||
|
||||
intel_miptree_map(intel, irb->mt, irb->mt_level, irb->mt_layer,
|
||||
x, y, w, h, mode, &map, &stride);
|
||||
|
||||
if (rb->Name == 0) {
|
||||
map += (h - 1) * stride;
|
||||
stride = -stride;
|
||||
}
|
||||
|
||||
DBG("%s: rb %d (%s) mt mapped: (%d, %d) (%dx%d) -> %p/%d\n",
|
||||
__FUNCTION__, rb->Name, _mesa_get_format_name(rb->Format),
|
||||
x, y, w, h, *out_map, *out_stride);
|
||||
|
||||
*out_map = map;
|
||||
*out_stride = stride;
|
||||
} else if (irb->wrapped_depth) {
|
||||
intel_map_renderbuffer_separate_s8z24(ctx, rb, x, y, w, h, mode,
|
||||
out_map, out_stride);
|
||||
@@ -428,52 +390,6 @@ intel_map_renderbuffer(struct gl_context *ctx,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \see intel_map_renderbuffer_s8()
|
||||
*/
|
||||
static void
|
||||
intel_unmap_renderbuffer_s8(struct gl_context *ctx,
|
||||
struct gl_renderbuffer *rb)
|
||||
{
|
||||
struct intel_context *intel = intel_context(ctx);
|
||||
struct intel_renderbuffer *irb = intel_renderbuffer(rb);
|
||||
|
||||
DBG("%s: rb %d (%s)\n", __FUNCTION__,
|
||||
rb->Name, _mesa_get_format_name(rb->Format));
|
||||
|
||||
assert(rb->Format == MESA_FORMAT_S8);
|
||||
|
||||
if (!irb->map_buffer)
|
||||
return;
|
||||
|
||||
if (irb->map_mode & GL_MAP_WRITE_BIT) {
|
||||
/* The temporary buffer was written to, so we must copy its pixels into
|
||||
* the real buffer.
|
||||
*/
|
||||
uint8_t *untiled_s8_map = irb->map_buffer;
|
||||
uint8_t *tiled_s8_map = irb->mt->region->bo->virtual;
|
||||
|
||||
/* Flip the Y axis for the default framebuffer. */
|
||||
int y_flip = (rb->Name == 0) ? -1 : 1;
|
||||
int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
|
||||
|
||||
for (uint32_t pix_y = 0; pix_y < irb->map_h; pix_y++) {
|
||||
for (uint32_t pix_x = 0; pix_x < irb->map_w; pix_x++) {
|
||||
uint32_t flipped_y = y_flip * (int32_t)(pix_y + irb->map_y) + y_bias;
|
||||
ptrdiff_t offset = intel_offset_S8(irb->mt->region->pitch,
|
||||
pix_x + irb->map_x,
|
||||
flipped_y);
|
||||
tiled_s8_map[offset] =
|
||||
untiled_s8_map[pix_y * irb->map_w + pix_x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
intel_region_unmap(intel, irb->mt->region);
|
||||
free(irb->map_buffer);
|
||||
irb->map_buffer = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Unmap a depthstencil renderbuffer with separate stencil.
|
||||
*
|
||||
@@ -539,13 +455,14 @@ static void
|
||||
intel_unmap_renderbuffer(struct gl_context *ctx,
|
||||
struct gl_renderbuffer *rb)
|
||||
{
|
||||
struct intel_context *intel = intel_context(ctx);
|
||||
struct intel_renderbuffer *irb = intel_renderbuffer(rb);
|
||||
|
||||
DBG("%s: rb %d (%s)\n", __FUNCTION__,
|
||||
rb->Name, _mesa_get_format_name(rb->Format));
|
||||
|
||||
if (rb->Format == MESA_FORMAT_S8) {
|
||||
intel_unmap_renderbuffer_s8(ctx, rb);
|
||||
intel_miptree_unmap(intel, irb->mt, irb->mt_level, irb->mt_layer);
|
||||
} else if (irb->wrapped_depth) {
|
||||
intel_unmap_renderbuffer_separate_s8z24(ctx, rb);
|
||||
} else if (irb->map_bo) {
|
||||
|
@@ -801,6 +801,80 @@ intel_miptree_unmap_gtt(struct intel_context *intel,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
intel_miptree_map_s8(struct intel_context *intel,
|
||||
struct intel_mipmap_tree *mt,
|
||||
struct intel_miptree_map *map,
|
||||
unsigned int level, unsigned int slice)
|
||||
{
|
||||
map->stride = map->w;
|
||||
map->buffer = map->ptr = malloc(map->stride * map->h);
|
||||
if (!map->buffer)
|
||||
return;
|
||||
|
||||
/* One of either READ_BIT or WRITE_BIT or both is set. READ_BIT implies no
|
||||
* INVALIDATE_RANGE_BIT. WRITE_BIT needs the original values read in unless
|
||||
* invalidate is set, since we'll be writing the whole rectangle from our
|
||||
* temporary buffer back out.
|
||||
*/
|
||||
if (!(map->mode & GL_MAP_INVALIDATE_RANGE_BIT)) {
|
||||
uint8_t *untiled_s8_map = map->ptr;
|
||||
uint8_t *tiled_s8_map = intel_region_map(intel, mt->region,
|
||||
GL_MAP_READ_BIT);
|
||||
unsigned int image_x, image_y;
|
||||
|
||||
intel_miptree_get_image_offset(mt, level, 0, slice, &image_x, &image_y);
|
||||
|
||||
for (uint32_t y = 0; y < map->h; y++) {
|
||||
for (uint32_t x = 0; x < map->w; x++) {
|
||||
ptrdiff_t offset = intel_offset_S8(mt->region->pitch,
|
||||
x + image_x + map->x,
|
||||
y + image_y + map->y);
|
||||
untiled_s8_map[y * map->w + x] = tiled_s8_map[offset];
|
||||
}
|
||||
}
|
||||
|
||||
intel_region_unmap(intel, mt->region);
|
||||
|
||||
DBG("%s: %d,%d %dx%d from mt %p %d,%d = %p/%d\n", __FUNCTION__,
|
||||
map->x, map->y, map->w, map->h,
|
||||
mt, map->x + image_x, map->y + image_y, map->ptr, map->stride);
|
||||
} else {
|
||||
DBG("%s: %d,%d %dx%d from mt %p = %p/%d\n", __FUNCTION__,
|
||||
map->x, map->y, map->w, map->h,
|
||||
mt, map->ptr, map->stride);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
intel_miptree_unmap_s8(struct intel_context *intel,
|
||||
struct intel_mipmap_tree *mt,
|
||||
struct intel_miptree_map *map,
|
||||
unsigned int level,
|
||||
unsigned int slice)
|
||||
{
|
||||
if (map->mode & GL_MAP_WRITE_BIT) {
|
||||
unsigned int image_x, image_y;
|
||||
uint8_t *untiled_s8_map = map->ptr;
|
||||
uint8_t *tiled_s8_map = intel_region_map(intel, mt->region, map->mode);
|
||||
|
||||
intel_miptree_get_image_offset(mt, level, 0, slice, &image_x, &image_y);
|
||||
|
||||
for (uint32_t y = 0; y < map->h; y++) {
|
||||
for (uint32_t x = 0; x < map->w; x++) {
|
||||
ptrdiff_t offset = intel_offset_S8(mt->region->pitch,
|
||||
x + map->x,
|
||||
y + map->y);
|
||||
tiled_s8_map[offset] = untiled_s8_map[y * map->w + x];
|
||||
}
|
||||
}
|
||||
|
||||
intel_region_unmap(intel, mt->region);
|
||||
}
|
||||
|
||||
free(map->buffer);
|
||||
}
|
||||
|
||||
void
|
||||
intel_miptree_map(struct intel_context *intel,
|
||||
struct intel_mipmap_tree *mt,
|
||||
@@ -836,7 +910,11 @@ intel_miptree_map(struct intel_context *intel,
|
||||
intel_miptree_slice_set_needs_hiz_resolve(mt, level, slice);
|
||||
}
|
||||
|
||||
intel_miptree_map_gtt(intel, mt, map, level, slice);
|
||||
if (mt->format == MESA_FORMAT_S8) {
|
||||
intel_miptree_map_s8(intel, mt, map, level, slice);
|
||||
} else {
|
||||
intel_miptree_map_gtt(intel, mt, map, level, slice);
|
||||
}
|
||||
|
||||
*out_ptr = map->ptr;
|
||||
*out_stride = map->stride;
|
||||
@@ -856,7 +934,11 @@ intel_miptree_unmap(struct intel_context *intel,
|
||||
DBG("%s: mt %p (%s) level %d slice %d\n", __FUNCTION__,
|
||||
mt, _mesa_get_format_name(mt->format), level, slice);
|
||||
|
||||
intel_miptree_unmap_gtt(intel, mt, map, level, slice);
|
||||
if (mt->format == MESA_FORMAT_S8) {
|
||||
intel_miptree_unmap_s8(intel, mt, map, level, slice);
|
||||
} else {
|
||||
intel_miptree_unmap_gtt(intel, mt, map, level, slice);
|
||||
}
|
||||
|
||||
mt->level[level].slice[slice].map = NULL;
|
||||
free(map);
|
||||
|
Reference in New Issue
Block a user