intel: Add a vtbl hook for determining if a format is renderable.
authorEric Anholt <eric@anholt.net>
Fri, 7 Jan 2011 23:45:33 +0000 (15:45 -0800)
committerEric Anholt <eric@anholt.net>
Sat, 8 Jan 2011 01:49:03 +0000 (17:49 -0800)
By relying on just intel_span_supports_format, some formats that
aren't supported pre-gen4 were not reporting FBO incomplete.  And we
also complained in stderr when it happened on i915 because draw_region
gets called before framebuffer completeness validation.

src/mesa/drivers/dri/i915/i830_vtbl.c
src/mesa/drivers/dri/i915/i915_vtbl.c
src/mesa/drivers/dri/i965/brw_vtbl.c
src/mesa/drivers/dri/i965/brw_wm.h
src/mesa/drivers/dri/i965/brw_wm_surface_state.c
src/mesa/drivers/dri/intel/intel_context.h
src/mesa/drivers/dri/intel/intel_fbo.c

index 1621c9544acdd176ec686efbdac0249486df292e..fa0129169b89196b4c421e9ea767e87a7efa862a 100644 (file)
@@ -585,6 +585,27 @@ i830_destroy_context(struct intel_context *intel)
    _tnl_free_vertices(&intel->ctx);
 }
 
+static uint32_t i830_render_target_format_for_mesa_format[MESA_FORMAT_COUNT] =
+{
+   [MESA_FORMAT_ARGB8888] = DV_PF_8888,
+   [MESA_FORMAT_XRGB8888] = DV_PF_8888,
+   [MESA_FORMAT_RGB565] = DV_PF_565,
+   [MESA_FORMAT_ARGB1555] = DV_PF_1555,
+   [MESA_FORMAT_ARGB4444] = DV_PF_4444,
+};
+
+static bool
+i830_render_target_supported(gl_format format)
+{
+   if (format == MESA_FORMAT_S8_Z24 ||
+       format == MESA_FORMAT_X8_Z24 ||
+       format == MESA_FORMAT_Z16) {
+      return true;
+   }
+
+   return i830_render_target_format_for_mesa_format[format] != 0;
+}
+
 static void
 i830_set_draw_region(struct intel_context *intel,
                      struct intel_region *color_regions[],
@@ -624,24 +645,7 @@ i830_set_draw_region(struct intel_context *intel,
             DSTORG_VERT_BIAS(0x8) | DEPTH_IS_Z);    /* .5 */
 
    if (irb != NULL) {
-      switch (irb->Base.Format) {
-      case MESA_FORMAT_ARGB8888:
-      case MESA_FORMAT_XRGB8888:
-        value |= DV_PF_8888;
-        break;
-      case MESA_FORMAT_RGB565:
-        value |= DV_PF_565;
-        break;
-      case MESA_FORMAT_ARGB1555:
-        value |= DV_PF_1555;
-        break;
-      case MESA_FORMAT_ARGB4444:
-        value |= DV_PF_4444;
-        break;
-      default:
-        _mesa_problem(ctx, "Bad renderbuffer format: %d\n",
-                      irb->Base.Format);
-      }
+      value |= i830_render_target_format_for_mesa_format[irb->Base.Format];
    }
 
    if (depth_region && depth_region->cpp == 4) {
@@ -729,4 +733,5 @@ i830InitVtbl(struct i830_context *i830)
    i830->intel.vtbl.assert_not_dirty = i830_assert_not_dirty;
    i830->intel.vtbl.finish_batch = intel_finish_vb;
    i830->intel.vtbl.invalidate_state = i830_invalidate_state;
+   i830->intel.vtbl.render_target_supported = i830_render_target_supported;
 }
index 8d9020f5ef3c7a855afa5956b16800646d93015e..21e3a8b740ba0c8c4b08430658bbeea6249ad747 100644 (file)
@@ -524,6 +524,27 @@ i915_set_buf_info_for_region(uint32_t *state, struct intel_region *region,
    }
 }
 
+static uint32_t i915_render_target_format_for_mesa_format[MESA_FORMAT_COUNT] =
+{
+   [MESA_FORMAT_ARGB8888] = DV_PF_8888,
+   [MESA_FORMAT_XRGB8888] = DV_PF_8888,
+   [MESA_FORMAT_RGB565] = DV_PF_565 | DITHER_FULL_ALWAYS,
+   [MESA_FORMAT_ARGB1555] = DV_PF_1555 | DITHER_FULL_ALWAYS,
+   [MESA_FORMAT_ARGB4444] = DV_PF_4444 | DITHER_FULL_ALWAYS,
+};
+
+static bool
+i915_render_target_supported(gl_format format)
+{
+   if (format == MESA_FORMAT_S8_Z24 ||
+       format == MESA_FORMAT_X8_Z24 ||
+       format == MESA_FORMAT_Z16) {
+      return true;
+   }
+
+   return i915_render_target_format_for_mesa_format[format] != 0;
+}
+
 static void
 i915_set_draw_region(struct intel_context *intel,
                      struct intel_region *color_regions[],
@@ -563,24 +584,7 @@ i915_set_draw_region(struct intel_context *intel,
             DSTORG_VERT_BIAS(0x8) |     /* .5 */
             LOD_PRECLAMP_OGL | TEX_DEFAULT_COLOR_OGL);
    if (irb != NULL) {
-      switch (irb->Base.Format) {
-      case MESA_FORMAT_ARGB8888:
-      case MESA_FORMAT_XRGB8888:
-        value |= DV_PF_8888;
-        break;
-      case MESA_FORMAT_RGB565:
-        value |= DV_PF_565 | DITHER_FULL_ALWAYS;
-        break;
-      case MESA_FORMAT_ARGB1555:
-        value |= DV_PF_1555 | DITHER_FULL_ALWAYS;
-        break;
-      case MESA_FORMAT_ARGB4444:
-        value |= DV_PF_4444 | DITHER_FULL_ALWAYS;
-        break;
-      default:
-        _mesa_problem(ctx, "Bad renderbuffer format: %d\n",
-                      irb->Base.Format);
-      }
+      value |= i915_render_target_format_for_mesa_format[irb->Base.Format];
    }
 
    /* This isn't quite safe, thus being hidden behind an option.  When changing
@@ -687,4 +691,5 @@ i915InitVtbl(struct i915_context *i915)
    i915->intel.vtbl.update_texture_state = i915UpdateTextureState;
    i915->intel.vtbl.assert_not_dirty = i915_assert_not_dirty;
    i915->intel.vtbl.finish_batch = intel_finish_vb;
+   i915->intel.vtbl.render_target_supported = i915_render_target_supported;
 }
index 3d7a98c9812d1c3782e40be5ba0ad76eea05bb8b..100a21b59d723b0830c8bb7a32dbf5af9bc4d603 100644 (file)
@@ -203,4 +203,5 @@ void brwInitVtbl( struct brw_context *brw )
    brw->intel.vtbl.destroy = brw_destroy_context;
    brw->intel.vtbl.set_draw_region = brw_set_draw_region;
    brw->intel.vtbl.debug_batch = brw_debug_batch;
+   brw->intel.vtbl.render_target_supported = brw_render_target_supported;
 }
index e7f3cfbb75fab9abeaa868248425ed72f38b1ccc..d9cae75ab5b7861ce06d9b643d9eb7eeac7adb47 100644 (file)
@@ -474,5 +474,6 @@ struct gl_shader *brw_new_shader(struct gl_context *ctx, GLuint name, GLuint typ
 struct gl_shader_program *brw_new_shader_program(struct gl_context *ctx, GLuint name);
 
 bool brw_color_buffer_write_enabled(struct brw_context *brw);
+bool brw_render_target_supported(gl_format format);
 
 #endif
index 17699913066d286283c754c880380f39e94ea73c..4570af66cd92544218cf0735cf64e716b8a189b1 100644 (file)
@@ -42,7 +42,7 @@
 #include "brw_context.h"
 #include "brw_state.h"
 #include "brw_defines.h"
-
+#include "brw_wm.h"
 
 static GLuint translate_tex_target( GLenum target )
 {
@@ -103,6 +103,21 @@ static uint32_t brw_format_for_mesa_format[MESA_FORMAT_COUNT] =
    [MESA_FORMAT_SIGNED_RGBA8888_REV] = BRW_SURFACEFORMAT_R8G8B8A8_SNORM,
 };
 
+bool
+brw_render_target_supported(gl_format format)
+{
+   if (format == MESA_FORMAT_S8_Z24 ||
+       format == MESA_FORMAT_X8_Z24 ||
+       format == MESA_FORMAT_Z16) {
+      return true;
+   }
+
+   /* Not exactly true, as some of those formats are not renderable.
+    * But at least we know how to translate them.
+    */
+   return brw_format_for_mesa_format[format] != 0;
+}
+
 static GLuint translate_tex_format( gl_format mesa_format,
                                     GLenum internal_format,
                                    GLenum depth_mode )
index 53a11ba9a7e4f1b7f911979a09ffcc2726d37e83..fd3c3ba58fcb77a1534a7c2940ef643331db8bc9 100644 (file)
@@ -149,6 +149,7 @@ struct intel_context
       void (*assert_not_dirty) (struct intel_context *intel);
 
       void (*debug_batch)(struct intel_context *intel);
+      bool (*render_target_supported)(gl_format format);
    } vtbl;
 
    struct dri_metaops meta;
index f4aceee9d6a298efcba73045726d51a91848f525..1ab72a7ad98b9fec9cebedc876fbe78cfdacf5f2 100644 (file)
@@ -564,6 +564,7 @@ intel_finish_render_texture(struct gl_context * ctx,
 static void
 intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
 {
+   struct intel_context *intel = intel_context(ctx);
    const struct intel_renderbuffer *depthRb =
       intel_get_renderbuffer(fb, BUFFER_DEPTH);
    const struct intel_renderbuffer *stencilRb =
@@ -612,7 +613,8 @@ intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
         continue;
       }
 
-      if (!intel_span_supports_format(irb->Base.Format)) {
+      if (!intel_span_supports_format(irb->Base.Format) ||
+         !intel->vtbl.render_target_supported(irb->Base.Format)) {
         DBG("Unsupported texture/renderbuffer format attached: %s\n",
             _mesa_get_format_name(irb->Base.Format));
         fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;