From 90b5a2425a5f362ef51ae7bb4d296fc682b92f46 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Wed, 6 Feb 2013 20:42:53 +1300 Subject: [PATCH] mesa: helper for checking renderbuffer sample count 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 Reviewed-by: Kenneth Graunke --- src/mesa/main/fbobject.c | 13 ++++++--- src/mesa/main/multisample.c | 54 +++++++++++++++++++++++++++++++++++++ src/mesa/main/multisample.h | 5 ++++ 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 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 is a signed or unsigned integer format and + * 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 -- 2.30.2