i965/msaa: Validate Gen7 surface state constraints.
authorPaul Berry <stereotype441@gmail.com>
Tue, 8 May 2012 22:30:33 +0000 (15:30 -0700)
committerPaul Berry <stereotype441@gmail.com>
Fri, 25 May 2012 15:45:11 +0000 (08:45 -0700)
When a Gen7 SURFACE_STATE is configured for MSAA, a number of
additional constaints come in to play.  This patch adds a function
gen7_check_surface_setup() which verifies that all of those
constraints are met.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_state.h
src/mesa/drivers/dri/i965/gen7_blorp.cpp
src/mesa/drivers/dri/i965/gen7_wm_surface_state.c

index 89d096370818341df5a61a90378460cf509a5260..31853eae051f12d56ac239f50c2489382d880baf 100644 (file)
@@ -201,6 +201,8 @@ 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_check_surface_setup(struct gen7_surface_state *surf,
+                              bool is_render_target);
 void gen7_init_vtable_surface_functions(struct brw_context *brw);
 void gen7_create_constant_surface(struct brw_context *brw,
                                  drm_intel_bo *bo,
index 58da3893d0a9ee4c5fcef12e001cc94fcafc3570..c860cbf7c7864714d7ad1c4c8f7e9675f7e52381 100644 (file)
@@ -136,7 +136,8 @@ static uint32_t
 gen7_blorp_emit_surface_state(struct brw_context *brw,
                               const brw_blorp_params *params,
                               const brw_blorp_surface_info *surface,
-                              uint32_t read_domains, uint32_t write_domain)
+                              uint32_t read_domains, uint32_t write_domain,
+                              bool is_render_target)
 {
    struct intel_context *intel = &brw->intel;
 
@@ -204,6 +205,8 @@ gen7_blorp_emit_surface_state(struct brw_context *brw,
                            surf->ss1.base_addr - region->bo->offset,
                            read_domains, write_domain);
 
+   gen7_check_surface_setup(surf, is_render_target);
+
    return wm_surf_offset;
 }
 
@@ -758,10 +761,12 @@ gen7_blorp_exec(struct intel_context *intel,
       wm_surf_offset_renderbuffer =
          gen7_blorp_emit_surface_state(brw, params, &params->dst,
                                        I915_GEM_DOMAIN_RENDER,
-                                       I915_GEM_DOMAIN_RENDER);
+                                       I915_GEM_DOMAIN_RENDER,
+                                       true /* is_render_target */);
       wm_surf_offset_texture =
          gen7_blorp_emit_surface_state(brw, params, &params->src,
-                                       I915_GEM_DOMAIN_SAMPLER, 0);
+                                       I915_GEM_DOMAIN_SAMPLER, 0,
+                                       false /* is_render_target */);
       wm_bind_bo_offset =
          gen6_blorp_emit_binding_table(brw, params,
                                        wm_surf_offset_renderbuffer,
index 9a01ddf68affbf9996d9d18627a9b02cfe9c26ba..d34bf53d4800ac4ccbbfadacf2ca93d41ec2f437 100644 (file)
@@ -68,6 +68,95 @@ gen7_set_surface_num_multisamples(struct gen7_surface_state *surf,
 }
 
 
+void
+gen7_check_surface_setup(struct gen7_surface_state *surf,
+                         bool is_render_target)
+{
+   bool is_multisampled =
+      surf->ss4.num_multisamples != GEN7_SURFACE_MULTISAMPLECOUNT_1;
+   /* From the Graphics BSpec: vol5c Shared Functions [SNB+] > State >
+    * SURFACE_STATE > SURFACE_STATE for most messages [DevIVB]: Surface Array
+    * Spacing:
+    *
+    *   If Multisampled Surface Storage Format is MSFMT_MSS and Number of
+    *   Multisamples is not MULTISAMPLECOUNT_1, this field must be set to
+    *   ARYSPC_LOD0.
+    */
+   if (surf->ss4.multisampled_surface_storage_format == GEN7_SURFACE_MSFMT_MSS
+       && is_multisampled)
+      assert(surf->ss0.surface_array_spacing == GEN7_SURFACE_ARYSPC_LOD0);
+
+   /* From the Graphics BSpec: vol5c Shared Functions [SNB+] > State >
+    * SURFACE_STATE > SURFACE_STATE for most messages [DevIVB]: Multisampled
+    * Surface Storage Format:
+    *
+    *   All multisampled render target surfaces must have this field set to
+    *   MSFMT_MSS.
+    *
+    * But also:
+    *
+    *   This field is ignored if Number of Multisamples is MULTISAMPLECOUNT_1.
+    */
+   if (is_render_target && is_multisampled) {
+      assert(surf->ss4.multisampled_surface_storage_format ==
+             GEN7_SURFACE_MSFMT_MSS);
+   }
+
+   /* From the Graphics BSpec: vol5c Shared Functions [SNB+] > State >
+    * SURFACE_STATE > SURFACE_STATE for most messages [DevIVB]: Multisampled
+    * Surface Storage Format:
+    *
+    *   If the surface’s Number of Multisamples is MULTISAMPLECOUNT_8, Width
+    *   is >= 8192 (meaning the actual surface width is >= 8193 pixels), this
+    *   field must be set to MSFMT_MSS.
+    */
+   if (surf->ss4.num_multisamples == GEN7_SURFACE_MULTISAMPLECOUNT_8 &&
+       surf->ss2.width >= 8192) {
+      assert(surf->ss4.multisampled_surface_storage_format ==
+             GEN7_SURFACE_MSFMT_MSS);
+   }
+
+   /* From the Graphics BSpec: vol5c Shared Functions [SNB+] > State >
+    * SURFACE_STATE > SURFACE_STATE for most messages [DevIVB]: Multisampled
+    * Surface Storage Format:
+    *
+    *   If the surface’s Number of Multisamples is MULTISAMPLECOUNT_8,
+    *   ((Depth+1) * (Height+1)) is > 4,194,304, OR if the surface’s Number of
+    *   Multisamples is MULTISAMPLECOUNT_4, ((Depth+1) * (Height+1)) is >
+    *   8,388,608, this field must be set to MSFMT_DEPTH_STENCIL.This field
+    *   must be set to MSFMT_DEPTH_STENCIL if Surface Format is one of the
+    *   following: I24X8_UNORM, L24X8_UNORM, A24X8_UNORM, or
+    *   R24_UNORM_X8_TYPELESS.
+    *
+    * But also:
+    *
+    *   This field is ignored if Number of Multisamples is MULTISAMPLECOUNT_1.
+    */
+   uint32_t depth = surf->ss3.depth + 1;
+   uint32_t height = surf->ss2.height + 1;
+   if (surf->ss4.num_multisamples == GEN7_SURFACE_MULTISAMPLECOUNT_8 &&
+       depth * height > 4194304) {
+      assert(surf->ss4.multisampled_surface_storage_format ==
+             GEN7_SURFACE_MSFMT_DEPTH_STENCIL);
+   }
+   if (surf->ss4.num_multisamples == GEN7_SURFACE_MULTISAMPLECOUNT_4 &&
+       depth * height > 8388608) {
+      assert(surf->ss4.multisampled_surface_storage_format ==
+             GEN7_SURFACE_MSFMT_DEPTH_STENCIL);
+   }
+   if (is_multisampled) {
+      switch (surf->ss0.surface_format) {
+      case BRW_SURFACEFORMAT_I24X8_UNORM:
+      case BRW_SURFACEFORMAT_L24X8_UNORM:
+      case BRW_SURFACEFORMAT_A24X8_UNORM:
+      case BRW_SURFACEFORMAT_R24_UNORM_X8_TYPELESS:
+         assert(surf->ss4.multisampled_surface_storage_format ==
+                GEN7_SURFACE_MSFMT_DEPTH_STENCIL);
+      }
+   }
+}
+
+
 static void
 gen7_update_buffer_texture_surface(struct gl_context *ctx, GLuint unit)
 {
@@ -122,6 +211,8 @@ gen7_update_buffer_texture_surface(struct gl_context *ctx, GLuint unit)
    }
 
    gen7_set_surface_tiling(surf, I915_TILING_NONE);
+
+   gen7_check_surface_setup(surf, false /* is_render_target */);
 }
 
 static void
@@ -214,6 +305,8 @@ gen7_update_texture_surface(struct gl_context *ctx, GLuint unit)
                           offsetof(struct gen7_surface_state, ss1),
                           intelObj->mt->region->bo, 0,
                           I915_GEM_DOMAIN_SAMPLER, 0);
+
+   gen7_check_surface_setup(surf, false /* is_render_target */);
 }
 
 /**
@@ -263,6 +356,8 @@ gen7_create_constant_surface(struct brw_context *brw,
                            offsetof(struct gen7_surface_state, ss1)),
                           bo, 0,
                           I915_GEM_DOMAIN_SAMPLER, 0);
+
+   gen7_check_surface_setup(surf, false /* is_render_target */);
 }
 
 static void
@@ -276,6 +371,8 @@ gen7_update_null_renderbuffer_surface(struct brw_context *brw, unsigned unit)
 
    surf->ss0.surface_type = BRW_SURFACE_NULL;
    surf->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+
+   gen7_check_surface_setup(surf, true /* is_render_target */);
 }
 
 /**
@@ -368,6 +465,8 @@ gen7_update_renderbuffer_surface(struct brw_context *brw,
                           surf->ss1.base_addr - region->bo->offset,
                           I915_GEM_DOMAIN_RENDER,
                           I915_GEM_DOMAIN_RENDER);
+
+   gen7_check_surface_setup(surf, true /* is_render_target */);
 }
 
 void