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 <chrisf@ijw.co.nz>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
Chris Forbes 2013-02-06 20:42:53 +13:00
parent 86b8380600
commit 90b5a2425a
3 changed files with 69 additions and 3 deletions

View 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;
}

View 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;
}

View 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