diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index 0b0df9d..9e1015b 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -116,6 +116,7 @@ struct r600_tiling_info *r600_get_tiling_info(struct radeon *radeon); unsigned r600_get_clock_crystal_freq(struct radeon *radeon); unsigned r600_get_minor_version(struct radeon *radeon); unsigned r600_get_num_backends(struct radeon *radeon); +unsigned r600_get_num_tile_pipes(struct radeon *radeon); /* r600_bo.c */ struct r600_bo; diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h index 836e749..9f639ec 100644 --- a/src/gallium/drivers/r600/r600_resource.h +++ b/src/gallium/drivers/r600/r600_resource.h @@ -68,6 +68,8 @@ struct r600_resource_texture { /* on some cards we have to use integer 64/128-bit types for s3tc blits, do this until gallium grows int formats */ boolean force_int_type; + /* HiZ data */ + struct r600_bo *hiz_bo; }; #define R600_TEX_IS_TILED(tex, level) ((tex)->array_mode[level] != V_038000_ARRAY_LINEAR_GENERAL && (tex)->array_mode[level] != V_038000_ARRAY_LINEAR_ALIGNED) diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 1e3f815..ff60e5c 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -209,7 +209,7 @@ static void *r600_create_dsa_state(struct pipe_context *ctx, rstate->id = R600_PIPE_STATE_DSA; /* depth TODO some of those db_shader_control field depend on shader adjust mask & add it to shader */ - db_shader_control = S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z); + db_shader_control = S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z); stencil_ref_mask = 0; stencil_ref_mask_bf = 0; db_depth_control = S_028800_Z_ENABLE(state->depth.enabled) | @@ -249,9 +249,22 @@ static void *r600_create_dsa_state(struct pipe_context *ctx, /* misc */ db_render_control = 0; - db_render_override = S_028D10_FORCE_HIZ_ENABLE(V_028D10_FORCE_DISABLE) | - S_028D10_FORCE_HIS_ENABLE0(V_028D10_FORCE_DISABLE) | - S_028D10_FORCE_HIS_ENABLE1(V_028D10_FORCE_DISABLE); + if (state->depth.enabled) { + //db_render_control |= S_028D0C_RESUMMARIZE_ENABLE(1); + } + + + if (debug_get_bool_option("R600_HIZ", FALSE)) { + printf("FORCE_HIZ = V_028D10_FORCE_ENABLE - I guess FORCE_OFF would be enough to enable HiZ\n"); + db_render_override = S_028D10_FORCE_HIZ_ENABLE(V_028D10_FORCE_ENABLE) | + S_028D10_FORCE_HIS_ENABLE0(V_028D10_FORCE_DISABLE) | + S_028D10_FORCE_HIS_ENABLE1(V_028D10_FORCE_DISABLE); + } else { + printf("FORCE_HIZ = V_028D10_FORCE_DISABLE\n"); + db_render_override = S_028D10_FORCE_HIZ_ENABLE(V_028D10_FORCE_DISABLE) | + S_028D10_FORCE_HIS_ENABLE0(V_028D10_FORCE_DISABLE) | + S_028D10_FORCE_HIS_ENABLE1(V_028D10_FORCE_DISABLE); + } /* TODO db_render_override depends on query */ r600_pipe_state_add_reg(rstate, R_028028_DB_STENCIL_CLEAR, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_02802C_DB_DEPTH_CLEAR, 0x3F800000, 0xFFFFFFFF, NULL); @@ -807,6 +820,56 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta 0x00000000, 0xFFFFFFFF, NULL); } +static unsigned r600_htile_settings(struct r600_pipe_context *rctx, struct pipe_resource *zbuf) +{ + unsigned num_tile_pipes; + unsigned tile_pipes_per_DB; + unsigned max_pixels_per_DB; + unsigned width_per_DB; + const unsigned k = 1024; + unsigned htile_settings = 0; + + /* ref : http://people.freedesktop.org/~agd5f/htile/6xx_7xx_eg_htile.txt */ + + num_tile_pipes = r600_get_num_tile_pipes(rctx->screen->radeon); + + tile_pipes_per_DB = num_tile_pipes / r600_get_num_backends(rctx->screen->radeon); + max_pixels_per_DB = (zbuf->width0 * zbuf->height0 * tile_pipes_per_DB) / num_tile_pipes; + + if (max_pixels_per_DB <= 64 * k) { + htile_settings = S_028D24_LINEAR(1) | S_028D24_PRELOAD(1); + } else if (max_pixels_per_DB <= 128 * k) { + htile_settings = S_028D24_FULL_CACHE(1) | S_028D24_LINEAR(1) | + S_028D24_PRELOAD(1); + } else if (max_pixels_per_DB <= 256 * k) { + htile_settings = S_028D24_HTILE_WIDTH(1) | S_028D24_FULL_CACHE(1) | + S_028D24_LINEAR(1) | S_028D24_PRELOAD(1); + } else if (max_pixels_per_DB <= 512 * k) { + htile_settings = S_028D24_HTILE_WIDTH(1) | S_028D24_HTILE_HEIGHT(1) | + S_028D24_FULL_CACHE(1) | S_028D24_LINEAR(1) | + S_028D24_PRELOAD(1); + } else { + width_per_DB = (zbuf->width0 * tile_pipes_per_DB) / num_tile_pipes; + if (width_per_DB <= 512) { + htile_settings = S_028D24_HTILE_WIDTH(1) | S_028D24_HTILE_HEIGHT(1) | + S_028D24_FULL_CACHE(1) | S_028D24_PRELOAD(1) | + S_028D24_PREFETCH_WIDTH(16) | S_028D24_PREFETCH_HEIGHT(4) | + S_028D24_HTILE_USES_PRELOAD_WIN(1); + } else if (width_per_DB <= 1024) { + htile_settings = S_028D24_HTILE_WIDTH(1) | S_028D24_HTILE_HEIGHT(1) | + S_028D24_FULL_CACHE(1) | S_028D24_PRELOAD(1) | + S_028D24_PREFETCH_WIDTH(16) | S_028D24_PREFETCH_HEIGHT(2) | + S_028D24_HTILE_USES_PRELOAD_WIN(1); + } else { + htile_settings = S_028D24_HTILE_WIDTH(1) | S_028D24_HTILE_HEIGHT(1) | + S_028D24_FULL_CACHE(1) | S_028D24_PRELOAD(1) | + S_028D24_PREFETCH_WIDTH(16) | + S_028D24_HTILE_USES_PRELOAD_WIN(1); + } + } + return htile_settings; +} + static void r600_db(struct r600_pipe_context *rctx, struct r600_pipe_state *rstate, const struct pipe_framebuffer_state *state) { @@ -836,17 +899,37 @@ static void r600_db(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta r600_pipe_state_add_reg(rstate, R_02800C_DB_DEPTH_BASE, (offset + r600_bo_offset(rbuffer->bo)) >> 8, 0xFFFFFFFF, rbuffer->bo); + + unsigned int enableTileSurface = 0; + + /* HiZ data */ + if (debug_get_bool_option("R600_HIZ", FALSE) && r600_get_minor_version(rctx->screen->radeon) >= 9) { + if (rtex->hiz_bo != NULL) { + r600_pipe_state_add_reg(rstate, R_028014_DB_HTILE_DATA_BASE, + (offset + r600_bo_offset(rtex->hiz_bo)) >> 8, 0xFFFFFFFF, rtex->hiz_bo); + + r600_pipe_state_add_reg(rstate, R_028D24_DB_HTILE_SURFACE, + r600_htile_settings(rctx, state->zsbuf->texture), 0xFFFFFFFF, NULL); + + enableTileSurface = S_028010_TILE_SURFACE_ENABLE(1); + } else { + printf("No Hiz allocated !\n"); + } + } + r600_pipe_state_add_reg(rstate, R_028000_DB_DEPTH_SIZE, S_028000_PITCH_TILE_MAX(pitch) | S_028000_SLICE_TILE_MAX(slice), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028004_DB_DEPTH_VIEW, 0x00000000, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_028010_DB_DEPTH_INFO, - S_028010_ARRAY_MODE(rtex->array_mode[level]) | S_028010_FORMAT(format), + S_028010_ARRAY_MODE(rtex->array_mode[level] ) | S_028010_FORMAT(format) | enableTileSurface, 0xFFFFFFFF, rbuffer->bo); r600_pipe_state_add_reg(rstate, R_028D34_DB_PREFETCH_LIMIT, (surf->aligned_height / 8) - 1, 0xFFFFFFFF, NULL); } + static void r600_set_framebuffer_state(struct pipe_context *ctx, const struct pipe_framebuffer_state *state) { @@ -1212,6 +1295,7 @@ void r600_init_config(struct r600_pipe_context *rctx) r600_pipe_state_add_reg(rstate, R_009830_DB_DEBUG, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_009838_DB_WATERMARKS, 0x00420204, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286C8_SPI_THREAD_GROUPING, 0x00000000, 0xFFFFFFFF, NULL); + // r600_pipe_state_add_reg(rstate, R_028A4C_PA_SC_MODE_CNTL, 0x00514002 | S_028A4C_KILL_PIX_POST_HI_Z(1), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028A4C_PA_SC_MODE_CNTL, 0x00514002, 0xFFFFFFFF, NULL); } else { r600_pipe_state_add_reg(rstate, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0x00000000, 0xFFFFFFFF, NULL); diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index eb696b7..cdae1cf 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -337,6 +337,12 @@ static void r600_texture_destroy(struct pipe_screen *screen, if (resource->bo) { r600_bo_reference(radeon, &resource->bo, NULL); } + + if (rtex->hiz_bo) { + printf("Unreferencing hiz_bo %p\n", rtex->hiz_bo); + r600_bo_reference(radeon, &rtex->hiz_bo, NULL); + } + FREE(rtex); } @@ -396,11 +402,37 @@ r600_texture_create_object(struct pipe_screen *screen, return rtex; } +static struct r600_bo * build_hiz_bo(struct pipe_screen *screen, const struct pipe_resource *templ, unsigned array_mode) { + struct r600_bo * hiz_bo = NULL; + enum pipe_format format = PIPE_FORMAT_Z32_FLOAT; // whatever format, as long as it's 32 bits wide + struct radeon * radeon = (struct radeon *)screen->winsys; + + unsigned base_align = r600_get_base_alignment(screen, format, V_038000_ARRAY_LINEAR_GENERAL); + unsigned size = (templ->width0 * templ->height0) / (4 * 4); // always allocatate for worst case (4x4 tiles) + + if (r600_get_minor_version(radeon) < 9) { + // HiZ not enabled + return NULL; + } + + printf("Allocating HiZ bo : size : 4 x %d = %d bytes ; alignement = %d ; bind = %d ; usage : %d ... ", size, 4*size, base_align, templ->bind /* ? */, templ->usage /* ? */); + hiz_bo = r600_bo(radeon, 4 * size, base_align, templ->bind /* ? */, templ->usage /* ? */); + + if (hiz_bo == NULL) { + printf("Failed to create bo!\n"); + } else { + printf(" : %p\n", hiz_bo); + } + + return hiz_bo; +} + struct pipe_resource *r600_texture_create(struct pipe_screen *screen, const struct pipe_resource *templ) { unsigned array_mode = 0; static int force_tiling = -1; + struct r600_resource_texture* result = NULL; /* Would like some magic "get_bool_option_once" routine. */ @@ -425,9 +457,15 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen, util_format_is_compressed(templ->format)) array_mode = V_038000_ARRAY_1D_TILED_THIN1; - return (struct pipe_resource *)r600_texture_create_object(screen, templ, array_mode, + result = r600_texture_create_object(screen, templ, array_mode, 0, 0, NULL); + if (debug_get_bool_option("R600_HIZ", FALSE) && util_format_is_depth_or_stencil(templ->format)) { + if (templ->bind & PIPE_BIND_DEPTH_STENCIL) + result->hiz_bo = build_hiz_bo(screen, templ, array_mode); + } + + return (struct pipe_resource *)result; } static struct pipe_surface *r600_create_surface(struct pipe_context *pipe, @@ -474,6 +512,7 @@ struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen, { struct radeon *rw = (struct radeon*)screen->winsys; struct r600_bo *bo = NULL; + struct r600_resource_texture* result = NULL; unsigned array_mode = 0; /* Support only 2D textures without mipmaps */ @@ -482,14 +521,22 @@ struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen, return NULL; bo = r600_bo_handle(rw, whandle->handle, &array_mode); + if (bo == NULL) { return NULL; } - return (struct pipe_resource *)r600_texture_create_object(screen, templ, array_mode, + result = r600_texture_create_object(screen, templ, array_mode, whandle->stride, 0, bo); + + if (debug_get_bool_option("R600_HIZ", FALSE) && util_format_is_depth_or_stencil(templ->format)) { + if (templ->bind & PIPE_BIND_DEPTH_STENCIL) + result->hiz_bo = build_hiz_bo(screen, templ, array_mode); + } + + return (struct pipe_resource *) result; } int r600_texture_depth_flush(struct pipe_context *ctx, @@ -686,8 +733,13 @@ void* r600_texture_transfer_map(struct pipe_context *ctx, } else { struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource; - if (rtex->flushed_depth_texture) + if (rtex->flushed_depth_texture) { bo = ((struct r600_resource *)rtex->flushed_depth_texture)->bo; + if (rtex->hiz_bo && debug_get_bool_option("R600_HIZ_READ_HACK", FALSE)) { + printf("%s : HACK - replacing depth bo with hiz bo !\n", __FUNCTION__); + bo = rtex->hiz_bo; + } + } else bo = ((struct r600_resource *)transfer->resource)->bo; @@ -740,6 +792,9 @@ void r600_texture_transfer_unmap(struct pipe_context *ctx, if (rtex->flushed_depth_texture) { bo = ((struct r600_resource *)rtex->flushed_depth_texture)->bo; + if (rtex->hiz_bo && debug_get_bool_option("R600_HIZ_READ_HACK", FALSE)) { + bo = rtex->hiz_bo; + } } else { bo = ((struct r600_resource *)transfer->resource)->bo; } diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h index 8296b52..83078f5 100644 --- a/src/gallium/drivers/r600/r600d.h +++ b/src/gallium/drivers/r600/r600d.h @@ -583,6 +583,7 @@ #define S_028004_SLICE_MAX(x) (((x) & 0x7FF) << 13) #define G_028004_SLICE_MAX(x) (((x) >> 13) & 0x7FF) #define C_028004_SLICE_MAX 0xFF001FFF +#define R_028014_DB_HTILE_DATA_BASE 0x028014 #define R_028D24_DB_HTILE_SURFACE 0x028D24 #define S_028D24_HTILE_WIDTH(x) (((x) & 0x1) << 0) #define G_028D24_HTILE_WIDTH(x) (((x) >> 0) & 0x1) diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c index 311324f..ec65764 100644 --- a/src/gallium/winsys/r600/drm/r600_drm.c +++ b/src/gallium/winsys/r600/drm/r600_drm.c @@ -75,6 +75,11 @@ unsigned r600_get_num_backends(struct radeon *radeon) return radeon->num_backends; } +unsigned r600_get_num_tile_pipes(struct radeon *radeon) +{ + return radeon->num_tile_pipes; +} + unsigned r600_get_minor_version(struct radeon *radeon) { return radeon->minor_version; @@ -228,6 +233,24 @@ static int radeon_get_num_backends(struct radeon *radeon) return 0; } +static int radeon_get_num_tile_pipes(struct radeon *radeon) +{ + struct drm_radeon_info info; + uint32_t num_tile_pipes; + int r; + + info.request = RADEON_INFO_NUM_TILE_PIPES; + info.value = (uintptr_t)&num_tile_pipes; + r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info, + sizeof(struct drm_radeon_info)); + if (r) + return r; + + radeon->num_tile_pipes = num_tile_pipes; + return 0; +} + static int radeon_init_fence(struct radeon *radeon) { @@ -339,8 +362,10 @@ static struct radeon *radeon_new(int fd, unsigned device) /* get the GPU counter frequency, failure is non fatal */ radeon_get_clock_crystal_freq(radeon); - if (radeon->minor_version >= 9) + if (radeon->minor_version >= 9) { radeon_get_num_backends(radeon); + radeon_get_num_tile_pipes(radeon); + } radeon->bomgr = r600_bomgr_create(radeon, 1000000); if (radeon->bomgr == NULL) { diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c index e28ef1f..c8007ac 100644 --- a/src/gallium/winsys/r600/drm/r600_hw_context.c +++ b/src/gallium/winsys/r600/drm/r600_hw_context.c @@ -334,6 +334,9 @@ static const struct r600_reg r600_context_reg_list[] = { {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028010_DB_DEPTH_INFO, REG_FLAG_NEED_BO, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028D0C_DB_RENDER_CONTROL, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028D10_DB_RENDER_OVERRIDE, 0, 0, 0}, + {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, + {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028014_DB_HTILE_DATA_BASE, REG_FLAG_NEED_BO, 0, 0}, + {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028D24_DB_HTILE_SURFACE, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028D30_DB_PRELOAD_CONTROL, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028D34_DB_PREFETCH_LIMIT, 0, 0, 0}, @@ -1157,10 +1160,13 @@ void r600_context_flush_dest_caches(struct r600_context *ctx) struct r600_bo *cb[8]; struct r600_bo *db; + struct r600_bo *hiz; + if (!(ctx->flags & R600_CONTEXT_DST_CACHES_DIRTY)) return; db = r600_context_reg_bo(ctx, R_02800C_DB_DEPTH_BASE); + hiz = r600_context_reg_bo(ctx, R_028014_DB_HTILE_DATA_BASE); cb[0] = r600_context_reg_bo(ctx, R_028040_CB_COLOR0_BASE); cb[1] = r600_context_reg_bo(ctx, R_028044_CB_COLOR1_BASE); cb[2] = r600_context_reg_bo(ctx, R_028048_CB_COLOR2_BASE); @@ -1183,6 +1189,9 @@ void r600_context_flush_dest_caches(struct r600_context *ctx) if (db) { r600_context_bo_flush(ctx, S_0085F0_DB_ACTION_ENA(1), 0, db); } + if (hiz) { + // TODO ? flush Hiz + } ctx->flags &= ~R600_CONTEXT_DST_CACHES_DIRTY; } @@ -1206,9 +1215,11 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw) if ((ctx->radeon->family > CHIP_R600) && (ctx->radeon->family < CHIP_RV770)) { struct r600_bo *cb[8]; - struct r600_bo *db; + struct r600_bo *db, *hiz; db = r600_context_reg_bo(ctx, R_02800C_DB_DEPTH_BASE); + // TODO ?? + // hiz = r600_context_reg_bo(ctx, R_028014_DB_HTILE_DATA_BASE); cb[0] = r600_context_reg_bo(ctx, R_028040_CB_COLOR0_BASE); cb[1] = r600_context_reg_bo(ctx, R_028044_CB_COLOR1_BASE); cb[2] = r600_context_reg_bo(ctx, R_028048_CB_COLOR2_BASE); diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h index 27bdf2b..1ff26a1 100644 --- a/src/gallium/winsys/r600/drm/r600_priv.h +++ b/src/gallium/winsys/r600/drm/r600_priv.h @@ -56,6 +56,7 @@ struct radeon { unsigned clock_crystal_freq; unsigned num_backends; unsigned minor_version; + unsigned num_tile_pipes; /* List of buffer handles and its mutex. */ struct util_hash_table *bo_handles; diff --git a/src/gallium/winsys/r600/drm/r600d.h b/src/gallium/winsys/r600/drm/r600d.h index 8042481..6d7b5a1 100644 --- a/src/gallium/winsys/r600/drm/r600d.h +++ b/src/gallium/winsys/r600/drm/r600d.h @@ -309,6 +309,7 @@ #define S_028004_SLICE_MAX(x) (((x) & 0x7FF) << 13) #define G_028004_SLICE_MAX(x) (((x) >> 13) & 0x7FF) #define C_028004_SLICE_MAX 0xFF001FFF +#define R_028014_DB_HTILE_DATA_BASE 0x028014 #define R_028D24_DB_HTILE_SURFACE 0x028D24 #define S_028D24_HTILE_WIDTH(x) (((x) & 0x1) << 0) #define G_028D24_HTILE_WIDTH(x) (((x) >> 0) & 0x1) @@ -815,6 +816,7 @@ #define R_028000_DB_DEPTH_SIZE 0x028000 #define R_028004_DB_DEPTH_VIEW 0x028004 #define R_028010_DB_DEPTH_INFO 0x028010 +#define R_028014_DB_HTILE_DATA_BASE 0x028014 #define R_028D24_DB_HTILE_SURFACE 0x028D24 #define R_028D34_DB_PREFETCH_LIMIT 0x028D34 #define R_0286D4_SPI_INTERP_CONTROL_0 0x0286D4 diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 732efe8..48a7f5f 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -241,6 +241,9 @@ radeonGetParam(__DRIscreen *sPriv, int param, void *value) case RADEON_INFO_TILE_CONFIG: info.request = RADEON_INFO_TILE_CONFIG; break; + case RADEON_INFO_NUM_TILE_PIPES: + info.request = RADEON_INFO_NUM_TILE_PIPES; + break; default: return -EINVAL; } diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 2a63799..e19c5ba 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -485,8 +485,15 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h const double scale = 1.0 / ((1 << 24) - 1); pipe_get_tile_raw(pipe, trans, 0, y, width, 1, ztemp, 0); y += yStep; - for (j = 0; j < width; j++) { - zfloat[j] = (float) (scale * (ztemp[j] & 0xffffff)); + if (debug_get_bool_option("R600_HIZ", FALSE) && debug_get_bool_option("R600_HIZ_READ_HACK", FALSE)) { + // temporary modification to allow intact HiZ buffer read + for (j = 0; j < width; j++) { + memcpy(&zfloat[j], &ztemp[j], sizeof(float)); + } + } else { + for (j = 0; j < width; j++) { + zfloat[j] = (float) (scale * (ztemp[j] & 0xffffff)); + } } _mesa_pack_depth_span(ctx, width, dst, type, zfloat, &clippedPacking);