mesa: add functional FBO changes for AMD_framebuffer_multisample_advanced
- relax FBO completeness rules - validate sample counts Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
@@ -969,7 +969,9 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
|
|||||||
GLuint numImages;
|
GLuint numImages;
|
||||||
GLenum intFormat = GL_NONE; /* color buffers' internal format */
|
GLenum intFormat = GL_NONE; /* color buffers' internal format */
|
||||||
GLuint minWidth = ~0, minHeight = ~0, maxWidth = 0, maxHeight = 0;
|
GLuint minWidth = ~0, minHeight = ~0, maxWidth = 0, maxHeight = 0;
|
||||||
GLint numSamples = -1;
|
GLint numColorSamples = -1;
|
||||||
|
GLint numColorStorageSamples = -1;
|
||||||
|
GLint numDepthSamples = -1;
|
||||||
GLint fixedSampleLocations = -1;
|
GLint fixedSampleLocations = -1;
|
||||||
GLint i;
|
GLint i;
|
||||||
GLuint j;
|
GLuint j;
|
||||||
@@ -1046,6 +1048,8 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
|
|||||||
|
|
||||||
/* get width, height, format of the renderbuffer/texture
|
/* get width, height, format of the renderbuffer/texture
|
||||||
*/
|
*/
|
||||||
|
unsigned attNumSamples, attNumStorageSamples;
|
||||||
|
|
||||||
if (att->Type == GL_TEXTURE) {
|
if (att->Type == GL_TEXTURE) {
|
||||||
const struct gl_texture_image *texImg = att->Renderbuffer->TexImage;
|
const struct gl_texture_image *texImg = att->Renderbuffer->TexImage;
|
||||||
att_tex_target = att->Texture->Target;
|
att_tex_target = att->Texture->Target;
|
||||||
@@ -1066,14 +1070,6 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numSamples < 0)
|
|
||||||
numSamples = texImg->NumSamples;
|
|
||||||
else if (numSamples != texImg->NumSamples) {
|
|
||||||
fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
|
|
||||||
fbo_incomplete(ctx, "inconsistent sample count", -1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fixedSampleLocations < 0)
|
if (fixedSampleLocations < 0)
|
||||||
fixedSampleLocations = texImg->FixedSampleLocations;
|
fixedSampleLocations = texImg->FixedSampleLocations;
|
||||||
else if (fixedSampleLocations != texImg->FixedSampleLocations) {
|
else if (fixedSampleLocations != texImg->FixedSampleLocations) {
|
||||||
@@ -1081,6 +1077,9 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
|
|||||||
fbo_incomplete(ctx, "inconsistent fixed sample locations", -1);
|
fbo_incomplete(ctx, "inconsistent fixed sample locations", -1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attNumSamples = texImg->NumSamples;
|
||||||
|
attNumStorageSamples = texImg->NumSamples;
|
||||||
}
|
}
|
||||||
else if (att->Type == GL_RENDERBUFFER_EXT) {
|
else if (att->Type == GL_RENDERBUFFER_EXT) {
|
||||||
minWidth = MIN2(minWidth, att->Renderbuffer->Width);
|
minWidth = MIN2(minWidth, att->Renderbuffer->Width);
|
||||||
@@ -1091,14 +1090,6 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
|
|||||||
attFormat = att->Renderbuffer->Format;
|
attFormat = att->Renderbuffer->Format;
|
||||||
numImages++;
|
numImages++;
|
||||||
|
|
||||||
if (numSamples < 0)
|
|
||||||
numSamples = att->Renderbuffer->NumSamples;
|
|
||||||
else if (numSamples != att->Renderbuffer->NumSamples) {
|
|
||||||
fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
|
|
||||||
fbo_incomplete(ctx, "inconsistent sample count", -1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RENDERBUFFER has fixedSampleLocations implicitly true */
|
/* RENDERBUFFER has fixedSampleLocations implicitly true */
|
||||||
if (fixedSampleLocations < 0)
|
if (fixedSampleLocations < 0)
|
||||||
fixedSampleLocations = GL_TRUE;
|
fixedSampleLocations = GL_TRUE;
|
||||||
@@ -1107,12 +1098,38 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
|
|||||||
fbo_incomplete(ctx, "inconsistent fixed sample locations", -1);
|
fbo_incomplete(ctx, "inconsistent fixed sample locations", -1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attNumSamples = att->Renderbuffer->NumSamples;
|
||||||
|
attNumStorageSamples = att->Renderbuffer->NumStorageSamples;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert(att->Type == GL_NONE);
|
assert(att->Type == GL_NONE);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i >= 0) {
|
||||||
|
/* Color buffers. */
|
||||||
|
if (numColorSamples < 0) {
|
||||||
|
assert(numColorStorageSamples < 0);
|
||||||
|
numColorSamples = attNumSamples;
|
||||||
|
numColorStorageSamples = attNumStorageSamples;
|
||||||
|
} else if (numColorSamples != attNumSamples ||
|
||||||
|
numColorStorageSamples != attNumStorageSamples) {
|
||||||
|
fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
|
||||||
|
fbo_incomplete(ctx, "inconsistent sample counts", -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Depth/stencil buffers. */
|
||||||
|
if (numDepthSamples < 0) {
|
||||||
|
numDepthSamples = attNumSamples;
|
||||||
|
} else if (numDepthSamples != attNumSamples) {
|
||||||
|
fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
|
||||||
|
fbo_incomplete(ctx, "inconsistent sample counts", -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Update flags describing color buffer datatypes */
|
/* Update flags describing color buffer datatypes */
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
GLenum type = _mesa_get_format_datatype(attFormat);
|
GLenum type = _mesa_get_format_datatype(attFormat);
|
||||||
@@ -1218,6 +1235,51 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx->Extensions.AMD_framebuffer_multisample_advanced) {
|
||||||
|
/* See if non-matching sample counts are supported. */
|
||||||
|
if (numColorSamples >= 0 && numDepthSamples >= 0) {
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
assert(numColorStorageSamples != -1);
|
||||||
|
|
||||||
|
numColorSamples = MAX2(numColorSamples, 1);
|
||||||
|
numColorStorageSamples = MAX2(numColorStorageSamples, 1);
|
||||||
|
numDepthSamples = MAX2(numDepthSamples, 1);
|
||||||
|
|
||||||
|
if (numColorSamples == 1 && numColorStorageSamples == 1 &&
|
||||||
|
numDepthSamples == 1) {
|
||||||
|
found = true;
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < ctx->Const.NumSupportedMultisampleModes; i++) {
|
||||||
|
GLint *counts =
|
||||||
|
&ctx->Const.SupportedMultisampleModes[i].NumColorSamples;
|
||||||
|
|
||||||
|
if (counts[0] == numColorSamples &&
|
||||||
|
counts[1] == numColorStorageSamples &&
|
||||||
|
counts[2] == numDepthSamples) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
|
||||||
|
fbo_incomplete(ctx, "unsupported sample counts", -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* If the extension is unsupported, all sample counts must be equal. */
|
||||||
|
if (numColorSamples >= 0 &&
|
||||||
|
(numColorSamples != numColorStorageSamples ||
|
||||||
|
(numDepthSamples >= 0 && numColorSamples != numDepthSamples))) {
|
||||||
|
fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
|
||||||
|
fbo_incomplete(ctx, "inconsistent sample counts", -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fb->MaxNumLayers = max_layer_count;
|
fb->MaxNumLayers = max_layer_count;
|
||||||
|
|
||||||
if (numImages == 0) {
|
if (numImages == 0) {
|
||||||
|
@@ -226,6 +226,58 @@ _mesa_check_sample_count(struct gl_context *ctx, GLenum target,
|
|||||||
return GL_INVALID_OPERATION;
|
return GL_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx->Extensions.AMD_framebuffer_multisample_advanced &&
|
||||||
|
target == GL_RENDERBUFFER) {
|
||||||
|
if (!_mesa_is_depth_or_stencil_format(internalFormat)) {
|
||||||
|
/* From the AMD_framebuffer_multisample_advanced spec:
|
||||||
|
*
|
||||||
|
* "An INVALID_OPERATION error is generated if <internalformat>
|
||||||
|
* is a color format and <storageSamples> is greater than
|
||||||
|
* the implementation-dependent limit MAX_COLOR_FRAMEBUFFER_-
|
||||||
|
* STORAGE_SAMPLES_AMD."
|
||||||
|
*/
|
||||||
|
if (samples > ctx->Const.MaxColorFramebufferSamples)
|
||||||
|
return GL_INVALID_OPERATION;
|
||||||
|
|
||||||
|
/* From the AMD_framebuffer_multisample_advanced spec:
|
||||||
|
*
|
||||||
|
* "An INVALID_OPERATION error is generated if <internalformat>
|
||||||
|
* is a color format and <storageSamples> is greater than
|
||||||
|
* the implementation-dependent limit MAX_COLOR_FRAMEBUFFER_-
|
||||||
|
* STORAGE_SAMPLES_AMD."
|
||||||
|
*/
|
||||||
|
if (storageSamples > ctx->Const.MaxColorFramebufferStorageSamples)
|
||||||
|
return GL_INVALID_OPERATION;
|
||||||
|
|
||||||
|
/* From the AMD_framebuffer_multisample_advanced spec:
|
||||||
|
*
|
||||||
|
* "An INVALID_OPERATION error is generated if <storageSamples> is
|
||||||
|
* greater than <samples>."
|
||||||
|
*/
|
||||||
|
if (storageSamples > samples)
|
||||||
|
return GL_INVALID_OPERATION;
|
||||||
|
|
||||||
|
/* Color renderbuffer sample counts are now fully validated
|
||||||
|
* according to AMD_framebuffer_multisample_advanced.
|
||||||
|
*/
|
||||||
|
return GL_NO_ERROR;
|
||||||
|
} else {
|
||||||
|
/* From the AMD_framebuffer_multisample_advanced spec:
|
||||||
|
*
|
||||||
|
* "An INVALID_OPERATION error is generated if <internalformat> is
|
||||||
|
* a depth or stencil format and <storageSamples> is not equal to
|
||||||
|
* <samples>."
|
||||||
|
*/
|
||||||
|
if (storageSamples != samples)
|
||||||
|
return GL_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* If the extension is unsupported, it's not possible to set
|
||||||
|
* storageSamples differently.
|
||||||
|
*/
|
||||||
|
assert(samples == storageSamples);
|
||||||
|
}
|
||||||
|
|
||||||
/* If ARB_internalformat_query is supported, then treat its highest
|
/* If ARB_internalformat_query is supported, then treat its highest
|
||||||
* returned sample count as the absolute maximum for this format; it is
|
* returned sample count as the absolute maximum for this format; it is
|
||||||
* allowed to exceed MAX_SAMPLES.
|
* allowed to exceed MAX_SAMPLES.
|
||||||
|
Reference in New Issue
Block a user