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
This commit is contained in:
daniel@transgaming.com
2010-08-24 19:20:36 +00:00
parent 4cbc590fb5
commit 1f135d86ab
14 changed files with 328 additions and 31 deletions

View File

@@ -362,6 +362,13 @@ typedef void* GLeglImageOES;
#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA
#endif
/* GL_ANGLE_framebuffer_multisample */
#ifndef GL_ANGLE_framebuffer_multisample
#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56
#define GL_MAX_SAMPLES_ANGLE 0x8D57
#endif
/*------------------------------------------------------------------------*
* End of extension tokens, start of corresponding extension functions
*------------------------------------------------------------------------*/
@@ -795,6 +802,17 @@ typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint sr
GLbitfield mask, GLenum filter);
#endif
/* GL_ANGLE_framebuffer_multisample */
#ifndef GL_ANGLE_framebuffer_multisample
#define GL_ANGLE_framebuffer_multisample 1
#ifdef GL_GLEXT_PROTOTYPES
GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat,
GLsizei width, GLsizei height);
#endif
typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat,
GLsizei width, GLsizei height);
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -164,7 +164,7 @@ bool Display::initialize()
if (SUCCEEDED(result))
{
// FIXME: Enumerate multi-sampling
// FIXME: enumerate multi-sampling
configSet.add(currentDisplayMode, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, 0);
}
@@ -468,4 +468,15 @@ D3DCAPS9 Display::getDeviceCaps()
{
return mDeviceCaps;
}
void Display::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray)
{
for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++)
{
HRESULT result = mD3d9->CheckDeviceMultiSampleType(mAdapter, mDeviceType, format,
TRUE, (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL);
multiSampleArray[multiSampleIndex] = SUCCEEDED(result);
}
}
}

View File

@@ -60,6 +60,7 @@ class Display
virtual IDirect3DDevice9 *getDevice();
virtual D3DCAPS9 getDeviceCaps();
virtual void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
private:
DISALLOW_COPY_AND_ASSIGN(Display);

View File

@@ -158,6 +158,7 @@ Context::Context(const egl::Config *config, const gl::Context *shareContext)
mHasBeenCurrent = false;
mMaxSupportedSamples = 0;
mMaskedClearSavedState = NULL;
markAllStateDirty();
}
@@ -179,6 +180,12 @@ Context::~Context()
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 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
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 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
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 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
*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 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
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 @@ bool Context::supportsShaderModel3() const
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 @@ void Context::initExtensionString()
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 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
return error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
if (drawFramebuffer->getSamples() != 0)
{
return error(GL_INVALID_OPERATION);
}
RECT sourceRect;
RECT destRect;
@@ -2982,6 +3112,16 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
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 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
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 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
}
}
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)

View File

@@ -374,6 +374,8 @@ class Context
GLenum getError();
bool supportsShaderModel3() const;
GLsizei getMaxSupportedSamples() const;
int getNearestSupportedSamples(D3DFORMAT format, int requested) const;
const char *getExtensionString() const;
void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
@@ -438,6 +440,8 @@ class Context
unsigned int mAppliedStencilbufferSerial;
bool mSupportsShaderModel3;
std::map<D3DFORMAT, bool *> mMultiSampleSupport;
GLsizei mMaxSupportedSamples;
// state caching flags
bool mClearStateDirty;

View File

@@ -272,6 +272,7 @@ GLenum Framebuffer::completeness()
{
int width = 0;
int height = 0;
int samples = -1;
if (mColorbufferType != GL_NONE)
{
@@ -289,6 +290,7 @@ GLenum Framebuffer::completeness()
width = colorbuffer->getWidth();
height = colorbuffer->getHeight();
samples = colorbuffer->getSamples();
}
else
{
@@ -321,6 +323,15 @@ GLenum Framebuffer::completeness()
{
return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
}
if (samples == -1)
{
samples = depthbuffer->getSamples();
}
else if (samples != depthbuffer->getSamples())
{
return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
}
}
if (mStencilbufferType != GL_NONE)
@@ -346,6 +357,15 @@ GLenum Framebuffer::completeness()
{
return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
}
if (samples == -1)
{
samples = stencilbuffer->getSamples();
}
else if (samples != stencilbuffer->getSamples())
{
return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
}
}
if (mDepthbufferType == GL_RENDERBUFFER && mStencilbufferType == GL_RENDERBUFFER)
@@ -374,6 +394,18 @@ DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *color, DepthStencilbuffer *d
mStencilbufferPointer.set(depthStencilRenderbuffer);
}
int Framebuffer::getSamples()
{
if (completeness() == GL_FRAMEBUFFER_COMPLETE)
{
return getColorbuffer()->getSamples();
}
else
{
return 0;
}
}
GLenum DefaultFramebuffer::completeness()
{
return GL_FRAMEBUFFER_COMPLETE;

View File

@@ -59,6 +59,7 @@ class Framebuffer
GLuint getStencilbufferHandle();
bool hasStencil();
int getSamples();
virtual GLenum completeness();

View File

@@ -146,6 +146,11 @@ D3DFORMAT RenderbufferStorage::getD3DFormat() const
return mD3DFormat;
}
GLsizei RenderbufferStorage::getSamples() const
{
return mSamples;
}
unsigned int RenderbufferStorage::getSerial() const
{
return mSerial;
@@ -167,25 +172,34 @@ Colorbuffer::Colorbuffer(IDirect3DSurface9 *renderTarget) : mRenderTarget(render
setSize(description.Width, description.Height);
mD3DFormat = description.Format;
mSamples = es2dx::GetSamplesFromMultisampleType(description.MultiSampleType);
}
else
{
mD3DFormat = D3DFMT_UNKNOWN;
mSamples = 0;
}
}
Colorbuffer::Colorbuffer(int width, int height, GLenum format)
Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples)
{
IDirect3DDevice9 *device = getDevice();
mRenderTarget = NULL;
D3DFORMAT requestedFormat = es2dx::ConvertRenderbufferFormat(format);
int supportedSamples = getContext()->getNearestSupportedSamples(requestedFormat, samples);
if (supportedSamples == -1)
{
error(GL_OUT_OF_MEMORY);
return;
}
if (width > 0 && height > 0)
{
HRESULT result = device->CreateRenderTarget(width, height, requestedFormat,
D3DMULTISAMPLE_NONE, 0, FALSE, &mRenderTarget, NULL);
es2dx::GetMultisampleTypeFromSamples(supportedSamples), 0, FALSE, &mRenderTarget, NULL);
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
@@ -202,12 +216,14 @@ Colorbuffer::Colorbuffer(int width, int height, GLenum format)
setSize(width, height);
mFormat = format;
mD3DFormat = requestedFormat;
mSamples = supportedSamples;
}
else
{
setSize(0, 0);
mFormat = GL_RGBA4;
mD3DFormat = D3DFMT_UNKNOWN;
mSamples = 0;
}
}
@@ -291,21 +307,34 @@ DepthStencilbuffer::DepthStencilbuffer(IDirect3DSurface9 *depthStencil) : mDepth
depthStencil->GetDesc(&description);
setSize(description.Width, description.Height);
mFormat = (description.Format == D3DFMT_D16 ? GL_DEPTH_COMPONENT16 : GL_DEPTH24_STENCIL8_OES);
mFormat = (description.Format == D3DFMT_D16 ? GL_DEPTH_COMPONENT16 : GL_DEPTH24_STENCIL8_OES);
mSamples = es2dx::GetSamplesFromMultisampleType(description.MultiSampleType);
mD3DFormat = description.Format;
}
else
{
mD3DFormat = D3DFMT_UNKNOWN;
mD3DFormat = D3DFMT_UNKNOWN;
mSamples = 0;
}
}
DepthStencilbuffer::DepthStencilbuffer(int width, int height)
DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples)
{
IDirect3DDevice9 *device = getDevice();
mDepthStencil = NULL;
HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, 0);
int supportedSamples = getContext()->getNearestSupportedSamples(D3DFMT_D24S8, samples);
if (supportedSamples == -1)
{
error(GL_OUT_OF_MEMORY);
return;
}
HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, es2dx::GetMultisampleTypeFromSamples(supportedSamples),
0, FALSE, &mDepthStencil, 0);
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
@@ -319,14 +348,16 @@ DepthStencilbuffer::DepthStencilbuffer(int width, int height)
if (mDepthStencil)
{
setSize(width, height);
mFormat = GL_DEPTH24_STENCIL8_OES;
mFormat = GL_DEPTH24_STENCIL8_OES;
mD3DFormat = D3DFMT_D24S8;
mSamples = supportedSamples;
}
else
{
setSize(0, 0);
mFormat = GL_RGBA4; //default format
mD3DFormat = D3DFMT_UNKNOWN;
mSamples = 0;
}
}
@@ -389,7 +420,7 @@ Depthbuffer::Depthbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(d
}
}
Depthbuffer::Depthbuffer(int width, int height) : DepthStencilbuffer(width, height)
Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
{
if (getDepthStencil())
{
@@ -427,7 +458,7 @@ Stencilbuffer::Stencilbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuff
}
}
Stencilbuffer::Stencilbuffer(int width, int height) : DepthStencilbuffer(width, height)
Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
{
if (getDepthStencil())
{

View File

@@ -43,6 +43,7 @@ class RenderbufferStorage
virtual int getHeight() const;
GLenum getFormat() const;
D3DFORMAT getD3DFormat() const;
GLsizei getSamples() const;
unsigned int getSerial() const;
static unsigned int issueSerial();
@@ -51,6 +52,7 @@ class RenderbufferStorage
void setSize(int width, int height);
GLenum mFormat;
D3DFORMAT mD3DFormat;
GLsizei mSamples;
unsigned int mSerial;
private:
@@ -98,7 +100,7 @@ class Colorbuffer : public RenderbufferStorage
{
public:
explicit Colorbuffer(IDirect3DSurface9 *renderTarget);
Colorbuffer(int width, int height, GLenum format);
Colorbuffer(int width, int height, GLenum format, GLsizei samples);
~Colorbuffer();
@@ -122,7 +124,7 @@ class DepthStencilbuffer : public RenderbufferStorage
{
public:
explicit DepthStencilbuffer(IDirect3DSurface9 *depthStencil);
DepthStencilbuffer(int width, int height);
DepthStencilbuffer(int width, int height, GLsizei samples);
~DepthStencilbuffer();
@@ -143,7 +145,7 @@ class Depthbuffer : public DepthStencilbuffer
{
public:
explicit Depthbuffer(IDirect3DSurface9 *depthStencil);
Depthbuffer(int width, int height);
Depthbuffer(int width, int height, GLsizei samples);
~Depthbuffer();
@@ -158,7 +160,7 @@ class Stencilbuffer : public DepthStencilbuffer
{
public:
explicit Stencilbuffer(IDirect3DSurface9 *depthStencil);
Stencilbuffer(int width, int height);
Stencilbuffer(int width, int height, GLsizei samples);
~Stencilbuffer();

View File

@@ -331,7 +331,7 @@ void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
{
if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
{
Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(0, 0, GL_RGBA4));
Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(0, 0, GL_RGBA4, 0));
mRenderbufferMap[renderbuffer] = renderbufferObject;
renderbufferObject->addRef();
}

View File

@@ -870,6 +870,11 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
return error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
{
return error(GL_INVALID_OPERATION);
}
gl::Colorbuffer *source = framebuffer->getColorbuffer();
if (target == GL_TEXTURE_2D)
{
@@ -943,6 +948,11 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
return error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
{
return error(GL_INVALID_OPERATION);
}
gl::Colorbuffer *source = framebuffer->getColorbuffer();
if (target == GL_TEXTURE_2D)
{
@@ -2629,6 +2639,18 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
*params = 0;
}
break;
case GL_RENDERBUFFER_SAMPLES_ANGLE:
{
if (context->getMaxSupportedSamples() != 0)
{
*params = renderbuffer->getStorage()->getSamples();
}
else
{
return error(GL_INVALID_ENUM);
}
}
break;
default:
return error(GL_INVALID_ENUM);
}
@@ -3596,10 +3618,10 @@ void __stdcall glReleaseShaderCompiler(void)
}
}
void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
{
TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
target, internalformat, width, height);
TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
target, samples, internalformat, width, height);
try
{
@@ -3624,7 +3646,7 @@ void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsiz
return error(GL_INVALID_ENUM);
}
if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE || samples < 0)
{
return error(GL_INVALID_VALUE);
}
@@ -3633,6 +3655,11 @@ void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsiz
if (context)
{
if (samples > context->getMaxSupportedSamples())
{
return error(GL_INVALID_VALUE);
}
GLuint handle = context->getRenderbufferHandle();
if (handle == 0)
{
@@ -3642,18 +3669,18 @@ void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsiz
switch (internalformat)
{
case GL_DEPTH_COMPONENT16:
context->setRenderbufferStorage(new gl::Depthbuffer(width, height));
context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
break;
case GL_RGBA4:
case GL_RGB5_A1:
case GL_RGB565:
context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat));
context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
break;
case GL_STENCIL_INDEX8:
context->setRenderbufferStorage(new gl::Stencilbuffer(width, height));
context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
break;
case GL_DEPTH24_STENCIL8_OES:
context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height));
context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
break;
default:
return error(GL_INVALID_ENUM);
@@ -3666,6 +3693,11 @@ void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsiz
}
}
void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
{
glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
}
void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
{
TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);

View File

@@ -146,6 +146,7 @@ EXPORTS
; Extensions
glTexImage3DOES @143
glBlitFramebufferANGLE @149
glRenderbufferStorageMultisampleANGLE @150
; EGL dependencies
glCreateContext @144 NONAME

View File

@@ -610,4 +610,20 @@ D3DFORMAT ConvertRenderbufferFormat(GLenum format)
}
}
GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type)
{
if (type == D3DMULTISAMPLE_NONMASKABLE)
return 0;
else
return type;
}
D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples)
{
if (samples <= 1)
return D3DMULTISAMPLE_NONE;
else
return (D3DMULTISAMPLE_TYPE)samples;
}
}

View File

@@ -57,6 +57,8 @@ unsigned int GetStencilSize(D3DFORMAT stencilFormat);
bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount,
D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount);
D3DFORMAT ConvertRenderbufferFormat(GLenum format);
D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples);
GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type);
}