- intel_region_release(&irb->region);
- intel_region_release(&irb->hiz_region);
-
- _mesa_reference_renderbuffer(&irb->wrapped_depth, NULL);
- _mesa_reference_renderbuffer(&irb->wrapped_stencil, NULL);
-
- free(irb);
-}
-
-/**
- * \brief Map a renderbuffer through the GTT.
- *
- * \see intel_map_renderbuffer()
- */
-static void
-intel_map_renderbuffer_gtt(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);
- GLubyte *map;
- int stride, flip_stride;
-
- assert(irb->region);
-
- irb->map_mode = mode;
- irb->map_x = x;
- irb->map_y = y;
- irb->map_w = w;
- irb->map_h = h;
-
- stride = irb->region->pitch * irb->region->cpp;
-
- if (rb->Name == 0) {
- y = irb->region->height - 1 - y;
- flip_stride = -stride;
- } else {
- x += irb->draw_x;
- y += irb->draw_y;
- flip_stride = stride;
- }
-
- if (drm_intel_bo_references(intel->batch.bo, irb->region->bo)) {
- intel_batchbuffer_flush(intel);
- }
-
- drm_intel_gem_bo_map_gtt(irb->region->bo);
-
- map = irb->region->bo->virtual;
- map += x * irb->region->cpp;
- map += (int)y * stride;
-
- *out_map = map;
- *out_stride = flip_stride;
-
- DBG("%s: rb %d (%s) gtt 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 renderbuffer by blitting it to a temporary gem buffer.
- *
- * On gen6+, we have LLC sharing, which means we can get high-performance
- * access to linear-mapped buffers.
- *
- * This function allocates a temporary gem buffer at
- * intel_renderbuffer::map_bo, then blits the renderbuffer into it, and
- * returns a map of that. (Note: Only X tiled buffers can be blitted).
- *
- * \see intel_renderbuffer::map_bo
- * \see intel_map_renderbuffer()
- */
-static void
-intel_map_renderbuffer_blit(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);
-
- int src_x, src_y;
- int dst_stride;
-
- assert(irb->region);
- assert(intel->gen >= 6);
- assert(!(mode & GL_MAP_WRITE_BIT));
- assert(irb->region->tiling == I915_TILING_X);
-
- irb->map_mode = mode;
- irb->map_x = x;
- irb->map_y = y;
- irb->map_w = w;
- irb->map_h = h;
-
- dst_stride = ALIGN(w * irb->region->cpp, 4);
-
- if (rb->Name) {
- src_x = x + irb->draw_x;
- src_y = y + irb->draw_y;
- } else {
- src_x = x;
- src_y = irb->region->height - y - h;
- }
-
- irb->map_bo = drm_intel_bo_alloc(intel->bufmgr, "MapRenderbuffer() temp",
- dst_stride * h, 4096);
-
- /* We don't do the flip in the blit, because it's always so tricky to get
- * right.
- */
- if (irb->map_bo &&
- intelEmitCopyBlit(intel,
- irb->region->cpp,
- irb->region->pitch, irb->region->bo,
- 0, irb->region->tiling,
- dst_stride / irb->region->cpp, irb->map_bo,
- 0, I915_TILING_NONE,
- src_x, src_y,
- 0, 0,
- w, h,
- GL_COPY)) {
- intel_batchbuffer_flush(intel);
- drm_intel_bo_map(irb->map_bo, false);
-
- if (rb->Name) {
- *out_map = irb->map_bo->virtual;
- *out_stride = dst_stride;
- } else {
- *out_map = irb->map_bo->virtual + (h - 1) * dst_stride;
- *out_stride = -dst_stride;
- }
-
- DBG("%s: rb %d (%s) blit mapped: (%d, %d) (%dx%d) -> %p/%d\n",
- __FUNCTION__, rb->Name, _mesa_get_format_name(rb->Format),
- src_x, src_y, w, h, *out_map, *out_stride);
- } else {
- /* Fallback to GTT mapping. */
- drm_intel_bo_unreference(irb->map_bo);
- irb->map_bo = NULL;
- intel_map_renderbuffer_gtt(ctx, rb,
- x, y, w, h,
- mode,
- out_map, out_stride);
- }
-}
-
-/**
- * \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->region);
-
- 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->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->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.
- *
- * A depthstencil renderbuffer, if using separate stencil, consists of a depth
- * renderbuffer and a hidden stencil renderbuffer. This function maps the
- * depth buffer, whose format is MESA_FORMAT_X8_Z24, through the GTT and
- * returns that as the mapped pointer. The caller need not be aware of the
- * hidden stencil buffer and may safely assume that the mapped pointer points
- * to a MESA_FORMAT_S8_Z24 buffer
- *
- * The consistency between the depth buffer's S8 bits and the hidden stencil
- * buffer is managed within intel_map_renderbuffer() and
- * intel_unmap_renderbuffer() by scattering or gathering the stencil bits
- * according to the map mode.
- *
- * \see intel_map_renderbuffer()
- * \see intel_unmap_renderbuffer_separate_s8z24()
- */
-static void
-intel_map_renderbuffer_separate_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 intel_context *intel = intel_context(ctx);
- struct intel_renderbuffer *irb = intel_renderbuffer(rb);
-
- uint8_t *s8z24_map;
- int32_t s8z24_stride;
-
- struct intel_renderbuffer *s8_irb;
- uint8_t *s8_map;
-
- assert(rb->Name != 0);
- assert(rb->Format == MESA_FORMAT_S8_Z24);
- assert(irb->wrapped_depth != NULL);
- assert(irb->wrapped_stencil != NULL);
-
- irb->map_mode = mode;
- irb->map_x = x;
- irb->map_y = y;
- irb->map_w = w;
- irb->map_h = h;
-
- /* Map with write mode for the gather below. */
- intel_map_renderbuffer_gtt(ctx, irb->wrapped_depth,
- x, y, w, h, mode | GL_MAP_WRITE_BIT,
- &s8z24_map, &s8z24_stride);
-
- s8_irb = intel_renderbuffer(irb->wrapped_stencil);
- s8_map = intel_region_map(intel, s8_irb->region, GL_MAP_READ_BIT);
-
- /* Gather the stencil buffer into the depth buffer. */
- for (uint32_t pix_y = 0; pix_y < h; ++pix_y) {
- for (uint32_t pix_x = 0; pix_x < w; ++pix_x) {
- ptrdiff_t s8_offset = intel_offset_S8(s8_irb->region->pitch,
- x + pix_x,
- y + pix_y);
- ptrdiff_t s8z24_offset = pix_y * s8z24_stride
- + pix_x * 4
- + 3;
- s8z24_map[s8z24_offset] = s8_map[s8_offset];
- }
- }
-
- intel_region_unmap(intel, s8_irb->region);