summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/main/fbobject.c13
-rw-r--r--src/mesa/main/multisample.c54
-rw-r--r--src/mesa/main/multisample.h5
3 files changed, 69 insertions, 3 deletions
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index d7e15e1ce6c..3fdf62667b9 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -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;
}
diff --git a/src/mesa/main/multisample.c b/src/mesa/main/multisample.c
index 2484946158f..8e5a969e3a8 100644
--- a/src/mesa/main/multisample.c
+++ b/src/mesa/main/multisample.c
@@ -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;
+}
diff --git a/src/mesa/main/multisample.h b/src/mesa/main/multisample.h
index 9e6b8e0d3f8..f2f01de5c65 100644
--- a/src/mesa/main/multisample.h
+++ b/src/mesa/main/multisample.h
@@ -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