i965: Fix clears of layered framebuffers with mismatched layer counts.
authorPaul Berry <stereotype441@gmail.com>
Tue, 7 Jan 2014 14:29:47 +0000 (06:29 -0800)
committerPaul Berry <stereotype441@gmail.com>
Fri, 10 Jan 2014 13:58:49 +0000 (05:58 -0800)
Previously, Mesa enforced the following rule (from
ARB_geometry_shader4's list of criteria for framebuffer completeness):

  * If any framebuffer attachment is layered, all attachments must have
    the same layer count.  For three-dimensional textures, the layer count
    is the depth of the attached volume.  For cube map textures, the layer
    count is always six.  For one- and two-dimensional array textures, the
    layer count is simply the number of layers in the array texture.
    { FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB }

However, when ARB_geometry_shader4 was adopted into GL 3.2, this rule
was dropped; GL 3.2 permits different attachments to have different
layer counts.  This patch brings Mesa in line with GL 3.2.

In order to ensure that layered clears properly clear all layers, we
now have to keep track of the maximum number of layers in a layered
framebuffer.

Fixes the following piglit tests in spec/!OpenGL 3.2/layered-rendering:
- clear-color-all-types 1d_array mipmapped
- clear-color-all-types 1d_array single_level
- clear-color-mismatched-layer-count
- framebuffer-layer-count-mismatch

Reviewed-by: Anuj Phogat <anuj.phogat@gmail.com>
Reviewed-by: Chris Forbes <chrisf@ijw.co.nz>
src/mesa/drivers/common/meta.c
src/mesa/drivers/dri/i965/brw_blorp_clear.cpp
src/mesa/drivers/dri/i965/brw_clear.c
src/mesa/drivers/dri/i965/brw_wm_surface_state.c
src/mesa/drivers/dri/i965/gen6_clip_state.c
src/mesa/drivers/dri/i965/gen7_misc_state.c
src/mesa/main/fbobject.c
src/mesa/main/mtypes.h

index 7b41876b94594ddfffb7d5a83bd382d535e09927..129451471d5202be4f7f63c67cb9f36da8c65b45 100644 (file)
@@ -2407,9 +2407,9 @@ _mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers)
                       GL_DYNAMIC_DRAW_ARB);
 
    /* draw quad(s) */
-   if (fb->NumLayers > 0) {
+   if (fb->MaxNumLayers > 0) {
       unsigned layer;
-      for (layer = 0; layer < fb->NumLayers; layer++) {
+      for (layer = 0; layer < fb->MaxNumLayers; layer++) {
          if (fb->_IntegerColor)
             _mesa_Uniform1i(clear->IntegerLayerLocation, layer);
          else
index 072ad5581e66974c345c843ded53115a6e3cd834..c55108a69fde8411d9fe01135b15ce269c2e2b25 100644 (file)
@@ -573,14 +573,14 @@ brw_blorp_clear_color(struct brw_context *brw, struct gl_framebuffer *fb,
       if (rb == NULL)
          continue;
 
-      if (fb->NumLayers > 0) {
+      if (fb->MaxNumLayers > 0) {
          unsigned layer_multiplier =
             (irb->mt->msaa_layout == INTEL_MSAA_LAYOUT_UMS ||
              irb->mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS) ?
             irb->mt->num_samples : 1;
-         assert(fb->NumLayers * layer_multiplier ==
-                irb->mt->level[irb->mt_level].depth);
-         for (unsigned layer = 0; layer < fb->NumLayers; layer++) {
+         unsigned num_layers =
+            irb->mt->level[irb->mt_level].depth / layer_multiplier;
+         for (unsigned layer = 0; layer < num_layers; layer++) {
             if (!do_single_blorp_clear(brw, fb, rb, buf, partial_clear,
                                        layer * layer_multiplier)) {
                return false;
index 1cac996482de9792420537b199e45abefb5990c2..fe68d9efcb93366c5ad93aad07acb9297a9a6c07 100644 (file)
@@ -181,9 +181,9 @@ brw_fast_clear_depth(struct gl_context *ctx)
     */
    intel_batchbuffer_emit_mi_flush(brw);
 
-   if (fb->NumLayers > 0) {
-      assert(fb->NumLayers == depth_irb->mt->level[depth_irb->mt_level].depth);
-      for (unsigned layer = 0; layer < fb->NumLayers; layer++) {
+   if (fb->MaxNumLayers > 0) {
+      unsigned num_layers = depth_irb->mt->level[depth_irb->mt_level].depth;
+      for (unsigned layer = 0; layer < num_layers; layer++) {
          intel_hiz_exec(brw, mt, depth_irb->mt_level, layer,
                         GEN6_HIZ_OP_DEPTH_CLEAR);
       }
index acb1a40e63259ae4a31058ceee26fb383f876f4f..e83763137d714a75c54ca688aff67fc0d63d1a11 100644 (file)
@@ -700,7 +700,7 @@ brw_update_renderbuffer_surfaces(struct brw_context *brw)
       for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
         if (intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[i])) {
            brw->vtbl.update_renderbuffer_surface(brw, ctx->DrawBuffer->_ColorDrawBuffers[i],
-                                                  ctx->DrawBuffer->NumLayers > 0, i);
+                                                  ctx->DrawBuffer->MaxNumLayers > 0, i);
         } else {
            brw->vtbl.update_null_renderbuffer_surface(brw, i);
         }
index 37a39b83fb7aee6b96e303dba1668e5f8dd78e55..6cec0ff21ac67ed0acb45d8f391a371260db777d 100644 (file)
@@ -121,7 +121,7 @@ upload_clip_state(struct brw_context *brw)
             dw2);
    OUT_BATCH(U_FIXED(0.125, 3) << GEN6_CLIP_MIN_POINT_WIDTH_SHIFT |
              U_FIXED(255.875, 3) << GEN6_CLIP_MAX_POINT_WIDTH_SHIFT |
-             (fb->NumLayers > 0 ? 0 : GEN6_CLIP_FORCE_ZERO_RTAINDEX));
+             (fb->MaxNumLayers > 0 ? 0 : GEN6_CLIP_FORCE_ZERO_RTAINDEX));
    ADVANCE_BATCH();
 }
 
index 42519494d3c52dfeeb81c155f8af5aa69a219879..8fb0eec7765140166b167f6111511d7f0fc6a4fe 100644 (file)
@@ -81,7 +81,7 @@ gen7_emit_depth_stencil_hiz(struct brw_context *brw,
       break;
    }
 
-   if (fb->NumLayers > 0 || !irb) {
+   if (fb->MaxNumLayers > 0 || !irb) {
       min_array_element = 0;
    } else if (irb->mt->num_samples > 1) {
       /* Convert physical layer to logical layer. */
index 7ecc48ee53b00d63da2951e82dc8e5b77f313f97..dc7184ad42a6804c5336f0281ef8498e8e399ecd 100644 (file)
@@ -877,8 +877,10 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
    GLint fixedSampleLocations = -1;
    GLint i;
    GLuint j;
-   bool layer_info_valid = false; /* Covers layer_count and layer_tex_target */
-   GLuint layer_count = 0, att_layer_count;
+   /* Covers max_layer_count, is_layered, and layer_tex_target */
+   bool layer_info_valid = false;
+   GLuint max_layer_count = 0, att_layer_count;
+   bool is_layered;
    GLenum layer_tex_target = 0;
 
    assert(_mesa_is_user_fbo(fb));
@@ -1064,26 +1066,24 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
          att_layer_count = 0;
       }
       if (!layer_info_valid) {
-         layer_count = att_layer_count;
+         is_layered = att->Layered;
+         max_layer_count = att_layer_count;
          layer_tex_target = att_tex_target;
          layer_info_valid = true;
-      } else if (layer_count > 0 && layer_tex_target != att_tex_target) {
+      } else if (max_layer_count > 0 && layer_tex_target != att_tex_target) {
          fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS;
          fbo_incomplete(ctx, "layered framebuffer has mismatched targets", i);
          return;
-      } else if (layer_count != att_layer_count) {
-         if (layer_count == 0 || att_layer_count == 0) {
-            fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS;
-            fbo_incomplete(ctx, "framebuffer attachment layer mode is inconsistent", i);
-         } else {
-            fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB;
-            fbo_incomplete(ctx, "framebuffer attachment layer count is inconsistent", i);
-         }
+      } else if (is_layered != att->Layered) {
+         fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS;
+         fbo_incomplete(ctx, "framebuffer attachment layer mode is inconsistent", i);
          return;
+      } else if (att_layer_count > max_layer_count) {
+         max_layer_count = att_layer_count;
       }
    }
 
-   fb->NumLayers = layer_count;
+   fb->MaxNumLayers = max_layer_count;
 
    if (_mesa_is_desktop_gl(ctx) && !ctx->Extensions.ARB_ES2_compatibility) {
       /* Check that all DrawBuffers are present */
index 908ec30d8004e20137176ac922ebcb238166c0be..f23cd81182f8d59e882eec21b1ca332b6f169578 100644 (file)
@@ -3008,12 +3008,11 @@ struct gl_framebuffer
    struct gl_renderbuffer *_ColorReadBuffer;
 
    /**
-    * The number of layers in the framebuffer, or 0 if the framebuffer is not
-    * layered.  For cube maps, this value is 6.  For cube map arrays, this
-    * value is the "depth" value passed to TexImage3D (always a multiple of
-    * 6).
+    * The maximum number of layers in the framebuffer, or 0 if the framebuffer
+    * is not layered.  For cube maps and cube map arrays, each cube face
+    * counts as a layer.
     */
-   GLuint NumLayers;
+   GLuint MaxNumLayers;
 
    /** Delete this framebuffer */
    void (*Delete)(struct gl_framebuffer *fb);