mesa: helper for checking renderbuffer sample count
authorChris Forbes <chrisf@ijw.co.nz>
Wed, 6 Feb 2013 07:42:53 +0000 (20:42 +1300)
committerChris Forbes <chrisf@ijw.co.nz>
Sun, 24 Mar 2013 03:38:18 +0000 (16:38 +1300)
Pulls the checking of the sample count into a helper function, and
extends the existing logic to include the interactions with both
ARB_texture_multisample and ARB_internalformat_query.

_mesa_check_sample_count() checks a desired sample count against a
a combination of target/internalformat, and returns the error enum
to be produced, if any. Unfortunately the conditions are messy and the
errors vary.

V2: - Tidy up spurious block.
    - Move _mesa_check_sample_count() to multisample.c instead; It
      doesn't really belong in fbobject.c or teximage.c.
    - Inlined spec quotes

Signed-off-by: Chris Forbes <chrisf@ijw.co.nz>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/main/fbobject.c
src/mesa/main/multisample.c
src/mesa/main/multisample.h

index d7e15e1ce6cf1a34fb146b1fff9f4c4d66be3efb..3fdf62667b9b1464631154bda5f0f2ad7f1d93e7 100644 (file)
@@ -43,6 +43,7 @@
 #include "hash.h"
 #include "macros.h"
 #include "mfeatures.h"
+#include "multisample.h"
 #include "mtypes.h"
 #include "renderbuffer.h"
 #include "state.h"
@@ -1492,6 +1493,7 @@ renderbuffer_storage(GLenum target, GLenum internalFormat,
       "glRenderbufferStorage" : "glRenderbufferStorageMultisample";
    struct gl_renderbuffer *rb;
    GLenum baseFormat;
+   GLenum sample_count_error;
    GET_CURRENT_CONTEXT(ctx);
 
    if (MESA_VERBOSE & VERBOSE_API) {
@@ -1535,9 +1537,14 @@ renderbuffer_storage(GLenum target, GLenum internalFormat,
       /* NumSamples == 0 indicates non-multisampling */
       samples = 0;
    }
-   else if (samples > (GLsizei) ctx->Const.MaxSamples) {
-      /* note: driver may choose to use more samples than what's requested */
-      _mesa_error(ctx, GL_INVALID_VALUE, "%s(samples)", func);
+
+   /* check the sample count;
+    * note: driver may choose to use more samples than what's requested
+    */
+   sample_count_error = _mesa_check_sample_count(ctx, target,
+         internalFormat, samples);
+   if (sample_count_error != GL_NO_ERROR) {
+      _mesa_error(ctx, sample_count_error, "%s(samples)", func);
       return;
    }
 
index 2484946158f008bde93eff5099be1f2ecdfe840b..8e5a969e3a8c3019e15afdb6e971dc72a5f9eec3 100644 (file)
@@ -29,6 +29,7 @@
 #include "main/multisample.h"
 #include "main/mtypes.h"
 #include "main/fbobject.h"
+#include "main/glformats.h"
 
 
 /**
@@ -112,3 +113,56 @@ _mesa_SampleMaski(GLuint index, GLbitfield mask)
    FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
    ctx->Multisample.SampleMaskValue = mask;
 }
+
+
+/* Helper for checking a requested sample count against the limit
+ * for a particular (target, internalFormat) pair. The limit imposed,
+ * and the error generated, both depend on which extensions are supported.
+ *
+ * Returns a GL error enum, or GL_NO_ERROR if the requested sample count is
+ * acceptable.
+ */
+GLenum
+_mesa_check_sample_count(struct gl_context *ctx, GLenum target,
+                         GLenum internalFormat, GLsizei samples)
+{
+   /* If ARB_internalformat_query is supported, then treat its highest returned sample
+    * count as the absolute maximum for this format; it is allowed to exceed MAX_SAMPLES.
+    *
+    * From the ARB_internalformat_query spec:
+    *
+    * "If <samples is greater than the maximum number of samples supported
+    * for <internalformat> then the error INVALID_OPERATION is generated."
+    */
+   if (ctx->Extensions.ARB_internalformat_query) {
+      GLint buffer[16];
+      int count = ctx->Driver.QuerySamplesForFormat(ctx, target, internalFormat, buffer);
+      int limit = count ? buffer[0] : -1;
+
+      return samples > limit ? GL_INVALID_OPERATION : GL_NO_ERROR;
+   }
+
+   /* If ARB_texture_multisample is supported, we have separate limits for
+    * integer formats.
+    *
+    * From the ARB_texture_multisample spec:
+    *
+    * "If <internalformat> is a signed or unsigned integer format and
+    * <samples> is greater than the value of MAX_INTEGER_SAMPLES, then the
+    * error INVALID_OPERATION is generated"
+    */
+
+   if (ctx->Extensions.ARB_texture_multisample) {
+      if (_mesa_is_enum_format_integer(internalFormat))
+         return samples > ctx->Const.MaxIntegerSamples ? GL_INVALID_OPERATION : GL_NO_ERROR;
+   }
+
+   /* No more specific limit is available, so just use MAX_SAMPLES:
+    *
+    * On p205 of the GL3.1 spec:
+    *
+    * "... or if samples is greater than MAX_SAMPLES, then the error
+    * INVALID_VALUE is generated"
+    */
+   return samples > ctx->Const.MaxSamples ? GL_INVALID_VALUE : GL_NO_ERROR;
+}
index 9e6b8e0d3f836723720cb300e99299b59feb43ae..f2f01de5c65ac4af3545beba40abf31c82a727dd 100644 (file)
@@ -44,4 +44,9 @@ _mesa_GetMultisamplefv(GLenum pname, GLuint index, GLfloat* val);
 extern void GLAPIENTRY
 _mesa_SampleMaski(GLuint index, GLbitfield mask);
 
+
+extern GLenum
+_mesa_check_sample_count(struct gl_context *ctx, GLenum target,
+                   GLenum internalFormat, GLsizei samples);
+
 #endif