Bug 911394 - Allow non-instanced drawing with no zero divisor attrib. - r=bjacob

This commit is contained in:
Jeff Gilbert 2013-09-19 15:30:19 -07:00
parent 35beb3fa52
commit c584f65275
2 changed files with 35 additions and 24 deletions

View File

@ -777,6 +777,7 @@ private:
bool DrawArrays_check(GLint first, GLsizei count, GLsizei primcount, const char* info);
bool DrawElements_check(GLsizei count, GLenum type, WebGLintptr byteOffset,
GLsizei primcount, const char* info);
bool DrawInstanced_check(const char* info);
void Draw_cleanup();
void VertexAttrib1fv_base(GLuint idx, uint32_t arrayLength, const GLfloat* ptr);

View File

@ -245,10 +245,10 @@ WebGLContext::GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
{
if (!ValidateAttribIndex(index, "getVertexAttrib"))
return JS::NullValue();
if (!mBoundVertexArray->mAttribBuffers[index].enabled)
return JS::Int32Value(4);
// Don't break; fall through.
}
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE:
@ -377,7 +377,7 @@ WebGLContext::VertexAttribPointer(GLuint index, GLint size, GLenum type,
if (byteOffset & requiredAlignmentMask) {
return ErrorInvalidOperation("vertexAttribPointer: byteOffset doesn't satisfy the alignment "
"requirement of given type");
}
InvalidateBufferFetching();
@ -423,6 +423,30 @@ WebGLContext::VertexAttribDivisor(GLuint index, GLuint divisor)
gl->fVertexAttribDivisor(index, divisor);
}
bool
WebGLContext::DrawInstanced_check(const char* info)
{
// This restriction was removed in GLES3, so WebGL2 shouldn't have it.
if (!IsWebGL2() &&
IsExtensionEnabled(ANGLE_instanced_arrays) &&
!mBufferFetchingHasPerVertex)
{
/* http://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_instanced_arrays.txt
* If all of the enabled vertex attribute arrays that are bound to active
* generic attributes in the program have a non-zero divisor, the draw
* call should return INVALID_OPERATION.
*
* NB: This also appears to apply to NV_instanced_arrays, though the
* INVALID_OPERATION emission is not explicitly stated.
* ARB_instanced_arrays does not have this restriction.
*/
ErrorInvalidOperation("%s: at least one vertex attribute divisor should be 0", info);
return false;
}
return true;
}
bool WebGLContext::DrawArrays_check(GLint first, GLsizei count, GLsizei primcount, const char* info)
{
if (first < 0 || count < 0) {
@ -471,16 +495,6 @@ bool WebGLContext::DrawArrays_check(GLint first, GLsizei count, GLsizei primcoun
return false;
}
if (!mBufferFetchingHasPerVertex && !IsWebGL2()) {
/* http://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_instanced_arrays.txt
* If all of the enabled vertex attribute arrays that are bound to active
* generic attributes in the program have a non-zero divisor, the draw
* call should return INVALID_OPERATION.
*/
ErrorInvalidOperation("%s: at least one vertex attribute divisor should be 0", info);
return false;
}
MakeContextCurrent();
if (mBoundFramebuffer) {
@ -528,6 +542,9 @@ WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsiz
if (!DrawArrays_check(first, count, primcount, "drawArraysInstanced"))
return;
if (!DrawInstanced_check("drawArraysInstanced"))
return;
SetupContextLossTimer();
gl->fDrawArraysInstanced(mode, first, count, primcount);
@ -635,16 +652,6 @@ WebGLContext::DrawElements_check(GLsizei count, GLenum type, WebGLintptr byteOff
return false;
}
if (!mBufferFetchingHasPerVertex && !IsWebGL2()) {
/* http://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_instanced_arrays.txt
* If all of the enabled vertex attribute arrays that are bound to active
* generic attributes in the program have a non-zero divisor, the draw
* call should return INVALID_OPERATION.
*/
ErrorInvalidOperation("%s: at least one vertex attribute divisor should be 0", info);
return false;
}
MakeContextCurrent();
if (mBoundFramebuffer) {
@ -694,6 +701,9 @@ WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
if (!DrawElements_check(count, type, byteOffset, primcount, "drawElementsInstanced"))
return;
if (!DrawInstanced_check("drawElementsInstanced"))
return;
SetupContextLossTimer();
gl->fDrawElementsInstanced(mode, count, type, reinterpret_cast<GLvoid*>(byteOffset), primcount);
@ -714,7 +724,7 @@ void WebGLContext::Draw_cleanup()
if (gl->WorkAroundDriverBugs()) {
if (gl->Renderer() == gl::GLContext::RendererTegra) {
mDrawCallsSinceLastFlush++;
if (mDrawCallsSinceLastFlush >= MAX_DRAW_CALLS_SINCE_FLUSH) {
gl->fFlush();
mDrawCallsSinceLastFlush = 0;