Implements glRenderbufferMultisampleStorage
TRAC #12714
Signed-off-by: Nicolas Capens
Signed-off-by: Daniel Koch
Author: Shannon Woods
git-svn-id: https://angleproject.googlecode.com/svn/trunk@390 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 71e687d..0f4217d 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -158,6 +158,7 @@
mHasBeenCurrent = false;
+ mMaxSupportedSamples = 0;
mMaskedClearSavedState = NULL;
markAllStateDirty();
}
@@ -179,6 +180,12 @@
deleteFramebuffer(mFramebufferMap.begin()->first);
}
+ while (!mMultiSampleSupport.empty())
+ {
+ delete [] mMultiSampleSupport.begin()->second;
+ mMultiSampleSupport.erase(mMultiSampleSupport.begin());
+ }
+
for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
{
for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++)
@@ -232,6 +239,31 @@
mIndexDataManager = new IndexDataManager(this, mBufferBackEnd);
mBlit = new Blit(this);
+ const D3DFORMAT renderBufferFormats[] =
+ {
+ D3DFMT_A8R8G8B8,
+ D3DFMT_R5G6B5,
+ D3DFMT_D24S8
+ };
+
+ int max = 0;
+ for (int i = 0; i < sizeof(renderBufferFormats) / sizeof(D3DFORMAT); ++i)
+ {
+ bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1];
+ display->getMultiSampleSupport(renderBufferFormats[i], multisampleArray);
+ mMultiSampleSupport[renderBufferFormats[i]] = multisampleArray;
+
+ for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j)
+ {
+ if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max)
+ {
+ max = j;
+ }
+ }
+ }
+
+ mMaxSupportedSamples = max;
+
initExtensionString();
mState.viewportX = 0;
@@ -1152,8 +1184,49 @@
case GL_SUBPIXEL_BITS: *params = 4; break;
case GL_MAX_TEXTURE_SIZE: *params = gl::MAX_TEXTURE_SIZE; break;
case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = gl::MAX_CUBE_MAP_TEXTURE_SIZE; break;
- case GL_SAMPLE_BUFFERS: *params = 0; break;
- case GL_SAMPLES: *params = 0; break;
+ case GL_MAX_SAMPLES_ANGLE:
+ {
+ GLsizei maxSamples = getMaxSupportedSamples();
+ if (maxSamples != 0)
+ {
+ *params = maxSamples;
+ }
+ else
+ {
+ return false;
+ }
+
+ break;
+ }
+ case GL_SAMPLE_BUFFERS:
+ case GL_SAMPLES:
+ {
+ gl::Framebuffer *framebuffer = getDrawFramebuffer();
+ if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
+ {
+ switch (pname)
+ {
+ case GL_SAMPLE_BUFFERS:
+ if (framebuffer->getSamples() != 0)
+ {
+ *params = 1;
+ }
+ else
+ {
+ *params = 0;
+ }
+ break;
+ case GL_SAMPLES:
+ *params = framebuffer->getSamples();
+ break;
+ }
+ }
+ else
+ {
+ *params = 0;
+ }
+ }
+ break;
case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = gl::IMPLEMENTATION_COLOR_READ_TYPE; break;
case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = gl::IMPLEMENTATION_COLOR_READ_FORMAT; break;
case GL_MAX_VIEWPORT_DIMS:
@@ -1341,6 +1414,19 @@
*numParams = 1;
}
break;
+ case GL_MAX_SAMPLES_ANGLE:
+ {
+ if (getMaxSupportedSamples() != 0)
+ {
+ *type = GL_INT;
+ *numParams = 1;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ break;
case GL_MAX_VIEWPORT_DIMS:
{
*type = GL_INT;
@@ -1905,6 +1991,11 @@
return error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
+ if (getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
IDirect3DSurface9 *renderTarget = framebuffer->getRenderTarget();
IDirect3DDevice9 *device = getDevice();
@@ -2614,6 +2705,35 @@
return mSupportsShaderModel3;
}
+int Context::getMaxSupportedSamples() const
+{
+ return mMaxSupportedSamples;
+}
+
+int Context::getNearestSupportedSamples(D3DFORMAT format, int requested) const
+{
+ if (requested == 0)
+ {
+ return requested;
+ }
+
+ std::map<D3DFORMAT, bool *>::const_iterator itr = mMultiSampleSupport.find(format);
+ if (itr == mMultiSampleSupport.end())
+ {
+ return -1;
+ }
+
+ for (int i = requested; i <= D3DMULTISAMPLE_16_SAMPLES; ++i)
+ {
+ if (itr->second[i] && i != D3DMULTISAMPLE_NONMASKABLE)
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
void Context::detachBuffer(GLuint buffer)
{
// [OpenGL ES 2.0.24] section 2.9 page 22:
@@ -2809,6 +2929,11 @@
mExtensionString += "GL_EXT_read_format_bgra ";
mExtensionString += "GL_ANGLE_framebuffer_blit ";
+ if (getMaxSupportedSamples() == 0)
+ {
+ mExtensionString += "GL_ANGLE_framebuffer_multisample ";
+ }
+
if (mBufferBackEnd->supportIntIndices())
{
mExtensionString += "GL_OES_element_index_uint ";
@@ -2841,6 +2966,11 @@
return error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
+ if (drawFramebuffer->getSamples() != 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
RECT sourceRect;
RECT destRect;
@@ -2982,6 +3112,16 @@
sourceTrimmedRect.bottom -= yDiff;
}
+ bool partialBufferCopy = false;
+ if (sourceTrimmedRect.bottom - sourceTrimmedRect.top < readFramebuffer->getColorbuffer()->getHeight() ||
+ sourceTrimmedRect.right - sourceTrimmedRect.left < readFramebuffer->getColorbuffer()->getWidth() ||
+ destTrimmedRect.bottom - destTrimmedRect.top < drawFramebuffer->getColorbuffer()->getHeight() ||
+ destTrimmedRect.right - destTrimmedRect.left < drawFramebuffer->getColorbuffer()->getWidth() ||
+ sourceTrimmedRect.top != 0 || destTrimmedRect.top != 0 || sourceTrimmedRect.left != 0 || destTrimmedRect.left != 0)
+ {
+ partialBufferCopy = true;
+ }
+
if (mask & GL_COLOR_BUFFER_BIT)
{
if (readFramebuffer->getColorbufferType() != drawFramebuffer->getColorbufferType() ||
@@ -2990,6 +3130,11 @@
ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");
return error(GL_INVALID_OPERATION);
}
+
+ if (partialBufferCopy && readFramebuffer->getSamples() != 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
blitRenderTarget = true;
@@ -3035,15 +3180,16 @@
}
}
- if (sourceTrimmedRect.bottom - sourceTrimmedRect.top < readDSBuffer->getHeight() ||
- sourceTrimmedRect.right - sourceTrimmedRect.left < readDSBuffer->getWidth() ||
- destTrimmedRect.bottom - destTrimmedRect.top < drawDSBuffer->getHeight() ||
- destTrimmedRect.right - destTrimmedRect.left < drawDSBuffer->getWidth() ||
- sourceTrimmedRect.top != 0 || destTrimmedRect.top != 0 || sourceTrimmedRect.left != 0 || destTrimmedRect.left != 0)
+ if (partialBufferCopy)
{
ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
return error(GL_INVALID_OPERATION); // only whole-buffer copies are permitted
}
+
+ if (drawDSBuffer->getSamples() != 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
}
if (blitRenderTarget || blitDepthStencil)