From 92054cd94e2188c9f4d56ddf9377c5aeb8a4e64e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 11 Oct 2011 14:22:45 -0700 Subject: [PATCH] intel: Add an implementation of MapRenderbuffer. v2: Add separate stencil S8 W-tile swizzling/deswizzling. Tested for the swizzling case with env INTEL_SEPARATE_STENCIL=1 INTEL_HIZ=1 ./bin/hiz-depth-stencil-test-fbo-d24-s8 v3: Apply Chad's fix for S8 window system buffers. Reviewed-by: Chad Versace --- src/mesa/drivers/dri/intel/intel_fbo.c | 125 ++++++++++++++++++++++++ src/mesa/drivers/dri/intel/intel_fbo.h | 3 + src/mesa/drivers/dri/intel/intel_span.c | 2 +- src/mesa/drivers/dri/intel/intel_span.h | 1 + 4 files changed, 130 insertions(+), 1 deletion(-) diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c index b7f07bb40ee..9df51d389a3 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.c +++ b/src/mesa/drivers/dri/intel/intel_fbo.c @@ -84,6 +84,129 @@ intel_delete_renderbuffer(struct gl_renderbuffer *rb) free(irb); } +static void +intel_map_renderbuffer(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; + + /* We sometimes get called with this by our intel_span.c usage. */ + if (!irb->region) { + *out_map = NULL; + *out_stride = 0; + return; + } + + 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->Format == MESA_FORMAT_S8) { + GLuint pix_x, pix_y; + uint8_t *tiled_s8_map, *untiled_s8_map; + + /* Flip the Y axis for the default framebuffer. */ + int y_flip = (rb->Name == 0) ? -1 : 1; + int y_bias = (rb->Name == 0) ? (2 * irb->region->height - 1) : 0; + + /* Perform W-tile deswizzling for stencil buffers into a temporary. */ + stride = w; + irb->map_buffer = malloc(stride * h); + untiled_s8_map = irb->map_buffer; + + tiled_s8_map = intel_region_map(intel, irb->region, mode); + + for (pix_y = 0; pix_y < h; pix_y++) { + for (pix_x = 0; pix_x < w; pix_x++) { + GLuint flipped_y = y_flip * (y + pix_y) + y_bias; + intptr_t offset = intel_offset_S8(irb->region->pitch, + x + pix_x, + flipped_y); + + untiled_s8_map[pix_y * stride + pix_x] = tiled_s8_map[offset]; + } + } + *out_map = untiled_s8_map; + *out_stride = stride; + + 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); + + return; + } + + map = intel_region_map(intel, irb->region, mode); + stride = irb->region->pitch * irb->region->cpp; + + if (rb->Name == 0) { + map += stride * (irb->region->height - 1); + stride = -stride; + } else { + map += irb->draw_x * irb->region->cpp; + map += (int)irb->draw_y * stride; + } + + map += x * irb->region->cpp; + map += (int)y * stride; + + *out_map = map; + *out_stride = stride; +} + +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 (irb->map_buffer) { + if (irb->map_mode & GL_MAP_WRITE_BIT) { + GLuint pix_x, pix_y; + uint8_t *tiled_s8_map = irb->map_buffer; + uint8_t *untiled_s8_map = irb->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) ? (2 * irb->region->height - 1) : 0; + + /* Perform W-tile swizzling back out of the temporary. */ + for (pix_y = 0; pix_y < irb->map_h; pix_y++) { + for (pix_x = 0; pix_x < irb->map_w; pix_x++) { + GLuint flipped_y = y_flip * (pix_y + irb->map_y) + y_bias; + intptr_t offset = intel_offset_S8(irb->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->region); + free(irb->map_buffer); + irb->map_buffer = NULL; + } else { + if (irb->region) + intel_region_unmap(intel, irb->region); + } +} /** * Return a pointer to a specific pixel in a renderbuffer. @@ -938,6 +1061,8 @@ intel_fbo_init(struct intel_context *intel) { intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer; intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer; + intel->ctx.Driver.MapRenderbuffer = intel_map_renderbuffer; + intel->ctx.Driver.UnmapRenderbuffer = intel_unmap_renderbuffer; intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer; intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer; intel->ctx.Driver.RenderTexture = intel_render_texture; diff --git a/src/mesa/drivers/dri/intel/intel_fbo.h b/src/mesa/drivers/dri/intel/intel_fbo.h index e12d0fdab9c..4bcbecdc9c7 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.h +++ b/src/mesa/drivers/dri/intel/intel_fbo.h @@ -44,6 +44,9 @@ struct intel_renderbuffer { struct gl_renderbuffer Base; struct intel_region *region; + void *map_buffer; + GLuint map_x, map_y, map_w, map_h; + GLbitfield map_mode; /** Only used by depth renderbuffers for which HiZ is enabled. */ struct intel_region *hiz_region; diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c index bdc4a0e158c..2819acb443b 100644 --- a/src/mesa/drivers/dri/intel/intel_span.c +++ b/src/mesa/drivers/dri/intel/intel_span.c @@ -165,7 +165,7 @@ intel_set_span_functions(struct intel_context *intel, * commit e8b1c6d6f55f5be3bef25084fdd8b6127517e137 * mesa: Fix return type of _mesa_get_format_bytes() (#37351) */ -static inline intptr_t +intptr_t intel_offset_S8(uint32_t stride, uint32_t x, uint32_t y) { uint32_t tile_size = 4096; diff --git a/src/mesa/drivers/dri/intel/intel_span.h b/src/mesa/drivers/dri/intel/intel_span.h index 5a4c4e8e52a..d546ecd1585 100644 --- a/src/mesa/drivers/dri/intel/intel_span.h +++ b/src/mesa/drivers/dri/intel/intel_span.h @@ -42,5 +42,6 @@ void intel_renderbuffer_unmap(struct intel_context *intel, void intel_map_vertex_shader_textures(struct gl_context *ctx); void intel_unmap_vertex_shader_textures(struct gl_context *ctx); bool intel_span_supports_format(gl_format format); +intptr_t intel_offset_S8(uint32_t stride, uint32_t x, uint32_t y); #endif -- 2.30.2