aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Berry <[email protected]>2012-07-03 11:36:39 -0700
committerPaul Berry <[email protected]>2012-07-11 15:14:49 -0700
commit7b3263af696e504ec68b91b0ce128d46a0691dce (patch)
tree049f5d9958c53e0c9eb8d9ea9e79da38ba657e18 /src
parent0ba813506d770ead7eb181fb2bf48d5a408fe0ea (diff)
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 <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/i965/brw_state.h5
-rw-r--r--src/mesa/drivers/dri/i965/gen7_blorp.cpp4
-rw-r--r--src/mesa/drivers/dri/i965/gen7_wm_surface_state.c45
3 files changed, 54 insertions, 0 deletions
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
@@ -69,6 +69,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;