Commit e98b1b5d by Jamie Madill Committed by Commit Bot

Framebuffer: Handle errors in checkStatus.

This pipes a lot more errors around in the Validation, where they now will be caught. Bug: angleproject:2372 Change-Id: Ibb4e47ddc932995a02dd92e10578b7a4097182a9 Reviewed-on: https://chromium-review.googlesource.com/954406Reviewed-by: 's avatarLuc Ferron <lucferron@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 7c9492eb
...@@ -1593,7 +1593,7 @@ void Context::getIntegervImpl(GLenum pname, GLint *params) ...@@ -1593,7 +1593,7 @@ void Context::getIntegervImpl(GLenum pname, GLint *params)
*params = mCaps.maxGeometryShaderStorageBlocks; *params = mCaps.maxGeometryShaderStorageBlocks;
break; break;
default: default:
mGLState.getIntegerv(this, pname, params); handleError(mGLState.getIntegerv(this, pname, params));
break; break;
} }
} }
...@@ -3339,7 +3339,9 @@ void Context::invalidateFramebuffer(GLenum target, ...@@ -3339,7 +3339,9 @@ void Context::invalidateFramebuffer(GLenum target,
Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target); Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
ASSERT(framebuffer); ASSERT(framebuffer);
if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE) bool complete = false;
ANGLE_CONTEXT_TRY(framebuffer->isComplete(this, &complete));
if (!complete)
{ {
return; return;
} }
...@@ -3361,7 +3363,9 @@ void Context::invalidateSubFramebuffer(GLenum target, ...@@ -3361,7 +3363,9 @@ void Context::invalidateSubFramebuffer(GLenum target,
Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target); Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
ASSERT(framebuffer); ASSERT(framebuffer);
if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE) bool complete = false;
ANGLE_CONTEXT_TRY(framebuffer->isComplete(this, &complete));
if (!complete)
{ {
return; return;
} }
...@@ -4419,7 +4423,14 @@ GLenum Context::checkFramebufferStatus(GLenum target) ...@@ -4419,7 +4423,14 @@ GLenum Context::checkFramebufferStatus(GLenum target)
Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target); Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
ASSERT(framebuffer); ASSERT(framebuffer);
return framebuffer->checkStatus(this); GLenum status = GL_NONE;
Error err = framebuffer->checkStatus(this, &status);
if (err.isError())
{
handleError(err);
return 0;
}
return status;
} }
void Context::compileShader(GLuint shader) void Context::compileShader(GLuint shader)
......
...@@ -981,7 +981,7 @@ void Framebuffer::invalidateCompletenessCache() ...@@ -981,7 +981,7 @@ void Framebuffer::invalidateCompletenessCache()
} }
} }
GLenum Framebuffer::checkStatus(const Context *context) Error Framebuffer::checkStatus(const Context *context, GLenum *statusOut)
{ {
// The default framebuffer is always complete except when it is surfaceless in which // The default framebuffer is always complete except when it is surfaceless in which
// case it is always unsupported. We return early because the default framebuffer may // case it is always unsupported. We return early because the default framebuffer may
...@@ -991,18 +991,29 @@ GLenum Framebuffer::checkStatus(const Context *context) ...@@ -991,18 +991,29 @@ GLenum Framebuffer::checkStatus(const Context *context)
ASSERT(mCachedStatus.valid()); ASSERT(mCachedStatus.valid());
ASSERT(mCachedStatus.value() == GL_FRAMEBUFFER_COMPLETE || ASSERT(mCachedStatus.value() == GL_FRAMEBUFFER_COMPLETE ||
mCachedStatus.value() == GL_FRAMEBUFFER_UNDEFINED_OES); mCachedStatus.value() == GL_FRAMEBUFFER_UNDEFINED_OES);
return mCachedStatus.value(); *statusOut = mCachedStatus.value();
return NoError();
} }
if (hasAnyDirtyBit() || !mCachedStatus.valid()) if (hasAnyDirtyBit() || !mCachedStatus.valid())
{ {
mCachedStatus = checkStatusImpl(context); mCachedStatus = checkStatusWithGLFrontEnd(context);
if (mCachedStatus.value() == GL_FRAMEBUFFER_COMPLETE)
{
ANGLE_TRY(syncState(context));
if (!mImpl->checkStatus(context))
{
mCachedStatus = GL_FRAMEBUFFER_UNSUPPORTED;
}
}
} }
return mCachedStatus.value(); *statusOut = mCachedStatus.value();
return NoError();
} }
GLenum Framebuffer::checkStatusImpl(const Context *context) GLenum Framebuffer::checkStatusWithGLFrontEnd(const Context *context)
{ {
const ContextState &state = context->getContextState(); const ContextState &state = context->getContextState();
...@@ -1199,13 +1210,6 @@ GLenum Framebuffer::checkStatusImpl(const Context *context) ...@@ -1199,13 +1210,6 @@ GLenum Framebuffer::checkStatusImpl(const Context *context)
} }
} }
// TODO(jmadill): Don't swallow an error here. http://anglebug.com/2372
ANGLE_SWALLOW_ERR(syncState(context));
if (!mImpl->checkStatus(context))
{
return GL_FRAMEBUFFER_UNSUPPORTED;
}
return GL_FRAMEBUFFER_COMPLETE; return GL_FRAMEBUFFER_COMPLETE;
} }
...@@ -1425,14 +1429,12 @@ Error Framebuffer::blit(const Context *context, ...@@ -1425,14 +1429,12 @@ Error Framebuffer::blit(const Context *context,
return mImpl->blit(context, sourceArea, destArea, blitMask, filter); return mImpl->blit(context, sourceArea, destArea, blitMask, filter);
} }
int Framebuffer::getSamples(const Context *context) Error Framebuffer::getSamples(const Context *context, int *samplesOut)
{ {
if (complete(context)) bool completeness = false;
{ ANGLE_TRY(isComplete(context, &completeness));
return getCachedSamples(context); *samplesOut = completeness ? getCachedSamples(context) : 0;
} return NoError();
return 0;
} }
int Framebuffer::getCachedSamples(const Context *context) int Framebuffer::getCachedSamples(const Context *context)
...@@ -1724,6 +1726,8 @@ void Framebuffer::updateAttachment(const Context *context, ...@@ -1724,6 +1726,8 @@ void Framebuffer::updateAttachment(const Context *context,
mDirtyBits.set(dirtyBit); mDirtyBits.set(dirtyBit);
mState.mResourceNeedsInit.set(dirtyBit, attachment->initState() == InitState::MayNeedInit); mState.mResourceNeedsInit.set(dirtyBit, attachment->initState() == InitState::MayNeedInit);
onDirtyBinding->bind(resource ? resource->getSubject() : nullptr); onDirtyBinding->bind(resource ? resource->getSubject() : nullptr);
invalidateCompletenessCache();
} }
void Framebuffer::resetAttachment(const Context *context, GLenum binding) void Framebuffer::resetAttachment(const Context *context, GLenum binding)
...@@ -1738,10 +1742,6 @@ Error Framebuffer::syncState(const Context *context) ...@@ -1738,10 +1742,6 @@ Error Framebuffer::syncState(const Context *context)
mDirtyBitsGuard = mDirtyBits; mDirtyBitsGuard = mDirtyBits;
ANGLE_TRY(mImpl->syncState(context, mDirtyBits)); ANGLE_TRY(mImpl->syncState(context, mDirtyBits));
mDirtyBits.reset(); mDirtyBits.reset();
if (mId != 0)
{
mCachedStatus.reset();
}
mDirtyBitsGuard.reset(); mDirtyBitsGuard.reset();
} }
return NoError(); return NoError();
...@@ -1788,9 +1788,12 @@ FramebufferAttachment *Framebuffer::getAttachmentFromSubjectIndex(angle::Subject ...@@ -1788,9 +1788,12 @@ FramebufferAttachment *Framebuffer::getAttachmentFromSubjectIndex(angle::Subject
} }
} }
bool Framebuffer::complete(const Context *context) Error Framebuffer::isComplete(const Context *context, bool *completeOut)
{ {
return (checkStatus(context) == GL_FRAMEBUFFER_COMPLETE); GLenum status = GL_NONE;
ANGLE_TRY(checkStatus(context, &status));
*completeOut = (status == GL_FRAMEBUFFER_COMPLETE);
return NoError();
} }
bool Framebuffer::formsRenderingFeedbackLoopWith(const State &state) const bool Framebuffer::formsRenderingFeedbackLoopWith(const State &state) const
...@@ -1901,24 +1904,28 @@ void Framebuffer::setDefaultWidth(GLint defaultWidth) ...@@ -1901,24 +1904,28 @@ void Framebuffer::setDefaultWidth(GLint defaultWidth)
{ {
mState.mDefaultWidth = defaultWidth; mState.mDefaultWidth = defaultWidth;
mDirtyBits.set(DIRTY_BIT_DEFAULT_WIDTH); mDirtyBits.set(DIRTY_BIT_DEFAULT_WIDTH);
invalidateCompletenessCache();
} }
void Framebuffer::setDefaultHeight(GLint defaultHeight) void Framebuffer::setDefaultHeight(GLint defaultHeight)
{ {
mState.mDefaultHeight = defaultHeight; mState.mDefaultHeight = defaultHeight;
mDirtyBits.set(DIRTY_BIT_DEFAULT_HEIGHT); mDirtyBits.set(DIRTY_BIT_DEFAULT_HEIGHT);
invalidateCompletenessCache();
} }
void Framebuffer::setDefaultSamples(GLint defaultSamples) void Framebuffer::setDefaultSamples(GLint defaultSamples)
{ {
mState.mDefaultSamples = defaultSamples; mState.mDefaultSamples = defaultSamples;
mDirtyBits.set(DIRTY_BIT_DEFAULT_SAMPLES); mDirtyBits.set(DIRTY_BIT_DEFAULT_SAMPLES);
invalidateCompletenessCache();
} }
void Framebuffer::setDefaultFixedSampleLocations(bool defaultFixedSampleLocations) void Framebuffer::setDefaultFixedSampleLocations(bool defaultFixedSampleLocations)
{ {
mState.mDefaultFixedSampleLocations = defaultFixedSampleLocations; mState.mDefaultFixedSampleLocations = defaultFixedSampleLocations;
mDirtyBits.set(DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS); mDirtyBits.set(DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS);
invalidateCompletenessCache();
} }
GLsizei Framebuffer::getNumViews() const GLsizei Framebuffer::getNumViews() const
......
...@@ -214,7 +214,7 @@ class Framebuffer final : public angle::ObserverInterface, public LabeledObject ...@@ -214,7 +214,7 @@ class Framebuffer final : public angle::ObserverInterface, public LabeledObject
bool usingExtendedDrawBuffers() const; bool usingExtendedDrawBuffers() const;
// This method calls checkStatus. // This method calls checkStatus.
int getSamples(const Context *context); Error getSamples(const Context *context, int *samplesOut);
Error getSamplePosition(size_t index, GLfloat *xy) const; Error getSamplePosition(size_t index, GLfloat *xy) const;
...@@ -229,13 +229,13 @@ class Framebuffer final : public angle::ObserverInterface, public LabeledObject ...@@ -229,13 +229,13 @@ class Framebuffer final : public angle::ObserverInterface, public LabeledObject
void invalidateCompletenessCache(); void invalidateCompletenessCache();
GLenum checkStatus(const Context *context); Error checkStatus(const Context *context, GLenum *statusOut);
// For when we don't want to check completeness in getSamples(). // For when we don't want to check completeness in getSamples().
int getCachedSamples(const Context *context); int getCachedSamples(const Context *context);
// Helper for checkStatus == GL_FRAMEBUFFER_COMPLETE. // Helper for checkStatus == GL_FRAMEBUFFER_COMPLETE.
bool complete(const Context *context); Error isComplete(const Context *context, bool *completeOut);
bool hasValidDepthStencil() const; bool hasValidDepthStencil() const;
...@@ -328,7 +328,7 @@ class Framebuffer final : public angle::ObserverInterface, public LabeledObject ...@@ -328,7 +328,7 @@ class Framebuffer final : public angle::ObserverInterface, public LabeledObject
GLenum matchType, GLenum matchType,
GLuint matchId, GLuint matchId,
size_t dirtyBit); size_t dirtyBit);
GLenum checkStatusImpl(const Context *context); GLenum checkStatusWithGLFrontEnd(const Context *context);
void setAttachment(const Context *context, void setAttachment(const Context *context,
GLenum type, GLenum type,
GLenum binding, GLenum binding,
......
...@@ -1831,7 +1831,7 @@ void State::getFloatv(GLenum pname, GLfloat *params) ...@@ -1831,7 +1831,7 @@ void State::getFloatv(GLenum pname, GLfloat *params)
} }
} }
void State::getIntegerv(const Context *context, GLenum pname, GLint *params) Error State::getIntegerv(const Context *context, GLenum pname, GLint *params)
{ {
if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT) if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
{ {
...@@ -1839,7 +1839,7 @@ void State::getIntegerv(const Context *context, GLenum pname, GLint *params) ...@@ -1839,7 +1839,7 @@ void State::getIntegerv(const Context *context, GLenum pname, GLint *params)
ASSERT(colorAttachment < mMaxDrawBuffers); ASSERT(colorAttachment < mMaxDrawBuffers);
Framebuffer *framebuffer = mDrawFramebuffer; Framebuffer *framebuffer = mDrawFramebuffer;
*params = framebuffer->getDrawBufferState(colorAttachment); *params = framebuffer->getDrawBufferState(colorAttachment);
return; return NoError();
} }
// Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
...@@ -1934,12 +1934,16 @@ void State::getIntegerv(const Context *context, GLenum pname, GLint *params) ...@@ -1934,12 +1934,16 @@ void State::getIntegerv(const Context *context, GLenum pname, GLint *params)
case GL_SAMPLES: case GL_SAMPLES:
{ {
Framebuffer *framebuffer = mDrawFramebuffer; Framebuffer *framebuffer = mDrawFramebuffer;
if (framebuffer->checkStatus(context) == GL_FRAMEBUFFER_COMPLETE) bool complete = false;
ANGLE_TRY(framebuffer->isComplete(context, &complete));
if (complete)
{ {
GLint samples = 0;
ANGLE_TRY(framebuffer->getSamples(context, &samples));
switch (pname) switch (pname)
{ {
case GL_SAMPLE_BUFFERS: case GL_SAMPLE_BUFFERS:
if (framebuffer->getSamples(context) != 0) if (samples != 0)
{ {
*params = 1; *params = 1;
} }
...@@ -1949,7 +1953,7 @@ void State::getIntegerv(const Context *context, GLenum pname, GLint *params) ...@@ -1949,7 +1953,7 @@ void State::getIntegerv(const Context *context, GLenum pname, GLint *params)
} }
break; break;
case GL_SAMPLES: case GL_SAMPLES:
*params = framebuffer->getSamples(context); *params = samples;
break; break;
} }
} }
...@@ -2123,6 +2127,8 @@ void State::getIntegerv(const Context *context, GLenum pname, GLint *params) ...@@ -2123,6 +2127,8 @@ void State::getIntegerv(const Context *context, GLenum pname, GLint *params)
UNREACHABLE(); UNREACHABLE();
break; break;
} }
return NoError();
} }
void State::getPointerv(GLenum pname, void **params) const void State::getPointerv(GLenum pname, void **params) const
......
...@@ -333,7 +333,7 @@ class State : public angle::ObserverInterface, angle::NonCopyable ...@@ -333,7 +333,7 @@ class State : public angle::ObserverInterface, angle::NonCopyable
// State query functions // State query functions
void getBooleanv(GLenum pname, GLboolean *params); void getBooleanv(GLenum pname, GLboolean *params);
void getFloatv(GLenum pname, GLfloat *params); void getFloatv(GLenum pname, GLfloat *params);
void getIntegerv(const Context *context, GLenum pname, GLint *params); Error getIntegerv(const Context *context, GLenum pname, GLint *params);
void getPointerv(GLenum pname, void **params) const; void getPointerv(GLenum pname, void **params) const;
void getIntegeri_v(GLenum target, GLuint index, GLint *data); void getIntegeri_v(GLenum target, GLuint index, GLint *data);
void getInteger64i_v(GLenum target, GLuint index, GLint64 *data); void getInteger64i_v(GLenum target, GLuint index, GLint64 *data);
......
...@@ -1245,15 +1245,13 @@ bool ValidateBlitFramebufferParameters(Context *context, ...@@ -1245,15 +1245,13 @@ bool ValidateBlitFramebufferParameters(Context *context,
return false; return false;
} }
if (readFramebuffer->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE) if (!ValidateFramebufferComplete(context, readFramebuffer, true))
{ {
context->handleError(InvalidFramebufferOperation());
return false; return false;
} }
if (drawFramebuffer->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE) if (!ValidateFramebufferComplete(context, drawFramebuffer, true))
{ {
context->handleError(InvalidFramebufferOperation());
return false; return false;
} }
...@@ -1263,9 +1261,8 @@ bool ValidateBlitFramebufferParameters(Context *context, ...@@ -1263,9 +1261,8 @@ bool ValidateBlitFramebufferParameters(Context *context,
return false; return false;
} }
if (drawFramebuffer->getSamples(context) != 0) if (!ValidateFramebufferNotMultisampled(context, drawFramebuffer))
{ {
context->handleError(InvalidOperation());
return false; return false;
} }
...@@ -2183,23 +2180,21 @@ bool ValidateStateQuery(Context *context, GLenum pname, GLenum *nativeType, unsi ...@@ -2183,23 +2180,21 @@ bool ValidateStateQuery(Context *context, GLenum pname, GLenum *nativeType, unsi
case GL_IMPLEMENTATION_COLOR_READ_TYPE: case GL_IMPLEMENTATION_COLOR_READ_TYPE:
case GL_IMPLEMENTATION_COLOR_READ_FORMAT: case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
{ {
if (context->getGLState().getReadFramebuffer()->checkStatus(context) != Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
GL_FRAMEBUFFER_COMPLETE) ASSERT(readFramebuffer);
if (!ValidateFramebufferComplete(context, readFramebuffer, false))
{ {
context->handleError(InvalidOperation());
return false; return false;
} }
const Framebuffer *framebuffer = context->getGLState().getReadFramebuffer(); if (readFramebuffer->getReadBufferState() == GL_NONE)
ASSERT(framebuffer);
if (framebuffer->getReadBufferState() == GL_NONE)
{ {
ANGLE_VALIDATION_ERR(context, InvalidOperation(), ReadBufferNone); ANGLE_VALIDATION_ERR(context, InvalidOperation(), ReadBufferNone);
return false; return false;
} }
const FramebufferAttachment *attachment = framebuffer->getReadColorbuffer(); const FramebufferAttachment *attachment = readFramebuffer->getReadColorbuffer();
if (!attachment) if (!attachment)
{ {
context->handleError(InvalidOperation()); context->handleError(InvalidOperation());
...@@ -2293,17 +2288,15 @@ bool ValidateCopyTexImageParametersBase(Context *context, ...@@ -2293,17 +2288,15 @@ bool ValidateCopyTexImageParametersBase(Context *context,
return false; return false;
} }
const auto &state = context->getGLState(); const gl::State &state = context->getGLState();
Framebuffer *readFramebuffer = state.getReadFramebuffer(); Framebuffer *readFramebuffer = state.getReadFramebuffer();
if (readFramebuffer->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE) if (!ValidateFramebufferComplete(context, readFramebuffer, true))
{ {
context->handleError(InvalidFramebufferOperation());
return false; return false;
} }
if (readFramebuffer->id() != 0 && readFramebuffer->getSamples(context) != 0) if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
{ {
context->handleError(InvalidOperation());
return false; return false;
} }
...@@ -2510,9 +2503,8 @@ bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count) ...@@ -2510,9 +2503,8 @@ bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count)
} }
} }
if (framebuffer->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE) if (!ValidateFramebufferComplete(context, framebuffer, true))
{ {
context->handleError(InvalidFramebufferOperation());
return false; return false;
} }
...@@ -5169,15 +5161,13 @@ bool ValidateReadPixelsBase(Context *context, ...@@ -5169,15 +5161,13 @@ bool ValidateReadPixelsBase(Context *context,
Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer(); Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
if (readFramebuffer->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE) if (!ValidateFramebufferComplete(context, readFramebuffer, true))
{ {
context->handleError(InvalidFramebufferOperation());
return false; return false;
} }
if (readFramebuffer->id() != 0 && readFramebuffer->getSamples(context) != 0) if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
{ {
context->handleError(InvalidOperation());
return false; return false;
} }
...@@ -5924,4 +5914,38 @@ bool ValidateGetInternalFormativBase(Context *context, ...@@ -5924,4 +5914,38 @@ bool ValidateGetInternalFormativBase(Context *context,
return true; return true;
} }
// We should check with Khronos if returning INVALID_FRAMEBUFFER_OPERATION is OK when querying
// implementation format info for incomplete framebuffers. It seems like these queries are
// incongruent with the other errors.
bool ValidateFramebufferComplete(Context *context, Framebuffer *framebuffer, bool isFramebufferOp)
{
bool complete = false;
ANGLE_VALIDATION_TRY(framebuffer->isComplete(context, &complete));
if (!complete)
{
if (isFramebufferOp)
{
context->handleError(InvalidFramebufferOperation());
}
else
{
context->handleError(InvalidOperation());
}
return false;
}
return true;
}
bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuffer)
{
GLint samples = 0;
ANGLE_VALIDATION_TRY(framebuffer->getSamples(context, &samples));
if (samples != 0)
{
context->handleError(InvalidOperation());
return false;
}
return true;
}
} // namespace gl } // namespace gl
...@@ -26,6 +26,7 @@ namespace gl ...@@ -26,6 +26,7 @@ namespace gl
{ {
class Context; class Context;
struct Format; struct Format;
class Framebuffer;
struct LinkedUniform; struct LinkedUniform;
class Program; class Program;
class Shader; class Shader;
...@@ -592,6 +593,15 @@ bool ValidateGetInternalFormativBase(Context *context, ...@@ -592,6 +593,15 @@ bool ValidateGetInternalFormativBase(Context *context,
GLsizei bufSize, GLsizei bufSize,
GLsizei *numParams); GLsizei *numParams);
bool ValidateFramebufferComplete(Context *context, Framebuffer *framebuffer, bool isFramebufferOp);
bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuffer);
// Utility macro for handling implementation methods inside Validation.
#define ANGLE_HANDLE_VALIDATION_ERR(X) \
context->handleError(X); \
return false;
#define ANGLE_VALIDATION_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_VALIDATION_ERR);
} // namespace gl } // namespace gl
#endif // LIBANGLE_VALIDATION_ES_H_ #endif // LIBANGLE_VALIDATION_ES_H_
...@@ -2493,7 +2493,9 @@ bool ValidateBlitFramebufferANGLE(Context *context, ...@@ -2493,7 +2493,9 @@ bool ValidateBlitFramebufferANGLE(Context *context,
} }
} }
if (readFramebuffer->getSamples(context) != 0 && GLint samples = 0;
ANGLE_VALIDATION_TRY(readFramebuffer->getSamples(context, &samples));
if (samples != 0 &&
IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0, IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
srcX1, srcY1, dstX0, dstY0, dstX1, dstY1)) srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
{ {
...@@ -2542,9 +2544,9 @@ bool ValidateBlitFramebufferANGLE(Context *context, ...@@ -2542,9 +2544,9 @@ bool ValidateBlitFramebufferANGLE(Context *context,
bool ValidateClear(Context *context, GLbitfield mask) bool ValidateClear(Context *context, GLbitfield mask)
{ {
Framebuffer *fbo = context->getGLState().getDrawFramebuffer(); Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
if (fbo->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
if (!ValidateFramebufferComplete(context, fbo, true))
{ {
context->handleError(InvalidFramebufferOperation());
return false; return false;
} }
......
...@@ -808,15 +808,13 @@ bool ValidateES3CopyTexImageParametersBase(Context *context, ...@@ -808,15 +808,13 @@ bool ValidateES3CopyTexImageParametersBase(Context *context,
gl::Framebuffer *framebuffer = state.getReadFramebuffer(); gl::Framebuffer *framebuffer = state.getReadFramebuffer();
GLuint readFramebufferID = framebuffer->id(); GLuint readFramebufferID = framebuffer->id();
if (framebuffer->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE) if (!ValidateFramebufferComplete(context, framebuffer, true))
{ {
context->handleError(InvalidFramebufferOperation());
return false; return false;
} }
if (readFramebufferID != 0 && framebuffer->getSamples(context) != 0) if (readFramebufferID != 0 && !ValidateFramebufferNotMultisampled(context, framebuffer))
{ {
context->handleError(InvalidOperation());
return false; return false;
} }
...@@ -1246,9 +1244,8 @@ bool ValidateClearBuffer(Context *context) ...@@ -1246,9 +1244,8 @@ bool ValidateClearBuffer(Context *context)
return false; return false;
} }
if (context->getGLState().getDrawFramebuffer()->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE) if (!ValidateFramebufferComplete(context, context->getGLState().getDrawFramebuffer(), true))
{ {
context->handleError(InvalidFramebufferOperation());
return false; return false;
} }
......
...@@ -1048,8 +1048,10 @@ bool ValidateGetMultisamplefv(Context *context, GLenum pname, GLuint index, GLfl ...@@ -1048,8 +1048,10 @@ bool ValidateGetMultisamplefv(Context *context, GLenum pname, GLuint index, GLfl
} }
Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer(); Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
GLint samples = 0;
ANGLE_VALIDATION_TRY(framebuffer->getSamples(context, &samples));
if (index >= static_cast<GLuint>(framebuffer->getSamples(context))) if (index >= static_cast<GLuint>(samples))
{ {
context->handleError(InvalidValue() << "Index must be less than the value of SAMPLES."); context->handleError(InvalidValue() << "Index must be less than the value of SAMPLES.");
return false; return false;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment