From 7b3263af696e504ec68b91b0ce128d46a0691dce Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Tue, 3 Jul 2012 11:36:39 -0700 Subject: [PATCH] i965/msaa: Set SURFACE_STATE properly when CMS MSAA is in use. When a buffer using Gen7's CMS MSAA layout is bound to a texture or a render target, the SURFACE_STATE structure needs to point to the MCS buffer and to indicate its pitch. This patch updates the functions that emit SURFACE_STATE to handle CMS layout properly. Reviewed-by: Chad Versace --- src/mesa/drivers/dri/i965/brw_state.h | 5 +++ src/mesa/drivers/dri/i965/gen7_blorp.cpp | 4 ++ .../drivers/dri/i965/gen7_wm_surface_state.c | 45 +++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index 31853eae051..1c70db29e38 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -201,6 +201,11 @@ GLuint translate_tex_format(gl_format mesa_format, void gen7_set_surface_tiling(struct gen7_surface_state *surf, uint32_t tiling); void gen7_set_surface_num_multisamples(struct gen7_surface_state *surf, unsigned num_samples); +void gen7_set_surface_mcs_info(struct brw_context *brw, + struct gen7_surface_state *surf, + uint32_t surf_offset, + const struct intel_mipmap_tree *mcs_mt, + bool is_render_target); void gen7_check_surface_setup(struct gen7_surface_state *surf, bool is_render_target); void gen7_init_vtable_surface_functions(struct brw_context *brw); diff --git a/src/mesa/drivers/dri/i965/gen7_blorp.cpp b/src/mesa/drivers/dri/i965/gen7_blorp.cpp index ec6312078b7..f087dbdc66a 100644 --- a/src/mesa/drivers/dri/i965/gen7_blorp.cpp +++ b/src/mesa/drivers/dri/i965/gen7_blorp.cpp @@ -181,6 +181,10 @@ gen7_blorp_emit_surface_state(struct brw_context *brw, surf->ss3.pitch = pitch_bytes - 1; gen7_set_surface_num_multisamples(surf, surface->num_samples); + if (surface->msaa_layout == INTEL_MSAA_LAYOUT_CMS) { + gen7_set_surface_mcs_info(brw, surf, wm_surf_offset, + surface->mt->mcs_mt, is_render_target); + } if (intel->is_haswell) { surf->ss7.shader_chanel_select_r = HSW_SCS_RED; diff --git a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c index 52312c9787c..f0370268be8 100644 --- a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c @@ -68,6 +68,46 @@ gen7_set_surface_num_multisamples(struct gen7_surface_state *surf, } +void +gen7_set_surface_mcs_info(struct brw_context *brw, + struct gen7_surface_state *surf, + uint32_t surf_offset, + const struct intel_mipmap_tree *mcs_mt, + bool is_render_target) +{ + /* From the Ivy Bridge PRM, Vol4 Part1 p76, "MCS Base Address": + * + * "The MCS surface must be stored as Tile Y." + */ + assert(mcs_mt->region->tiling == I915_TILING_Y); + + /* Compute the pitch in units of tiles. To do this we need to divide the + * pitch in bytes by 128, since a single Y-tile is 128 bytes wide. + */ + unsigned pitch_bytes = mcs_mt->region->pitch * mcs_mt->cpp; + unsigned pitch_tiles = pitch_bytes / 128; + + /* The upper 20 bits of surface state DWORD 6 are the upper 20 bits of the + * GPU address of the MCS buffer; the lower 12 bits contain other control + * information. Since buffer addresses are always on 4k boundaries (and + * thus have their lower 12 bits zero), we can use an ordinary reloc to do + * the necessary address translation. + */ + assert ((mcs_mt->region->bo->offset & 0xfff) == 0); + surf->ss6.mcs_enabled.mcs_enable = 1; + surf->ss6.mcs_enabled.mcs_surface_pitch = pitch_tiles - 1; + surf->ss6.mcs_enabled.mcs_base_address = mcs_mt->region->bo->offset >> 12; + drm_intel_bo_emit_reloc(brw->intel.batch.bo, + surf_offset + + offsetof(struct gen7_surface_state, ss6), + mcs_mt->region->bo, + surf->ss6.raw_data & 0xfff, + is_render_target ? I915_GEM_DOMAIN_RENDER + : I915_GEM_DOMAIN_SAMPLER, + is_render_target ? I915_GEM_DOMAIN_RENDER : 0); +} + + void gen7_check_surface_setup(struct gen7_surface_state *surf, bool is_render_target) @@ -452,6 +492,11 @@ gen7_update_renderbuffer_surface(struct brw_context *brw, gen7_set_surface_num_multisamples(surf, irb->mt->num_samples); + if (irb->mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS) { + gen7_set_surface_mcs_info(brw, surf, brw->wm.surf_offset[unit], + irb->mt->mcs_mt, true /* is_render_target */); + } + if (intel->is_haswell) { surf->ss7.shader_chanel_select_r = HSW_SCS_RED; surf->ss7.shader_chanel_select_g = HSW_SCS_GREEN; -- 2.30.2