Commit 80c32ccb by Jiawei Shao Committed by Commit Bot

ES31: Add extra transform feedback rules in EXT_geometry_shader

This patch adds the additional transform feedback rules required in EXT_geometry_shader. In this extension, more draw commands and render primitives are allowed for transform feedback. BUG=angleproject:1941 TEST=dEQP-GLES31.functional.geometry_shading.vertex_transform_feedback.* angle_end2end_tests Change-Id: Iedc27dca5c24ca45cd4226a1a0066107c0b40e1d Reviewed-on: https://chromium-review.googlesource.com/1055192Reviewed-by: 's avatarJiajia Qin <jiajia.qin@intel.com> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
parent 10e7e501
...@@ -211,6 +211,8 @@ ERRMSG(UniformBufferBoundForTransformFeedback, ...@@ -211,6 +211,8 @@ ERRMSG(UniformBufferBoundForTransformFeedback,
"It is undefined behavior to use an uniform buffer that is bound for transform feedback."); "It is undefined behavior to use an uniform buffer that is bound for transform feedback.");
ERRMSG(UniformSizeMismatch, "Uniform size does not match uniform method."); ERRMSG(UniformSizeMismatch, "Uniform size does not match uniform method.");
ERRMSG(UnknownParameter, "Unknown parameter value."); ERRMSG(UnknownParameter, "Unknown parameter value.");
ERRMSG(UnsupportedDrawModeForTransformFeedback,
"The draw command is unsupported when transform feedback is active and not paused.");
ERRMSG(VertexArrayNoBuffer, "An enabled vertex array has no buffer."); ERRMSG(VertexArrayNoBuffer, "An enabled vertex array has no buffer.");
ERRMSG(VertexArrayNoBufferPointer, "An enabled vertex array has no buffer and no pointer."); ERRMSG(VertexArrayNoBufferPointer, "An enabled vertex array has no buffer and no pointer.");
ERRMSG(VertexBufferBoundForTransformFeedback, ERRMSG(VertexBufferBoundForTransformFeedback,
......
...@@ -634,6 +634,38 @@ bool ValidTexture2DDestinationTarget(const Context *context, TextureTarget targe ...@@ -634,6 +634,38 @@ bool ValidTexture2DDestinationTarget(const Context *context, TextureTarget targe
} }
} }
bool ValidateTransformFeedbackPrimitiveMode(const Context *context,
GLenum transformFeedbackPrimitiveMode,
GLenum renderPrimitiveMode)
{
ASSERT(context);
if (!context->getExtensions().geometryShader)
{
// It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
// that does not match the current transform feedback object's draw mode (if transform
// feedback is active), (3.0.2, section 2.14, pg 86)
return transformFeedbackPrimitiveMode == renderPrimitiveMode;
}
// [GL_EXT_geometry_shader] Table 12.1gs
switch (transformFeedbackPrimitiveMode)
{
case GL_POINTS:
return renderPrimitiveMode == GL_POINTS;
case GL_TRIANGLES:
return renderPrimitiveMode == GL_TRIANGLES ||
renderPrimitiveMode == GL_TRIANGLE_STRIP ||
renderPrimitiveMode == GL_TRIANGLE_FAN;
case GL_LINES:
return renderPrimitiveMode == GL_LINES || renderPrimitiveMode == GL_LINE_LOOP ||
renderPrimitiveMode == GL_LINE_STRIP;
default:
UNREACHABLE();
return false;
}
}
bool ValidateDrawElementsInstancedBase(Context *context, bool ValidateDrawElementsInstancedBase(Context *context,
GLenum mode, GLenum mode,
GLsizei count, GLsizei count,
...@@ -2845,12 +2877,9 @@ bool ValidateDrawArraysCommon(Context *context, ...@@ -2845,12 +2877,9 @@ bool ValidateDrawArraysCommon(Context *context,
if (curTransformFeedback && curTransformFeedback->isActive() && if (curTransformFeedback && curTransformFeedback->isActive() &&
!curTransformFeedback->isPaused()) !curTransformFeedback->isPaused())
{ {
if (curTransformFeedback->getPrimitiveMode() != mode) if (!ValidateTransformFeedbackPrimitiveMode(context,
curTransformFeedback->getPrimitiveMode(), mode))
{ {
// It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
// that does not match the current transform feedback object's draw mode (if transform
// feedback
// is active), (3.0.2, section 2.14, pg 86)
ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDrawModeTransformFeedback); ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDrawModeTransformFeedback);
return false; return false;
} }
...@@ -2910,7 +2939,7 @@ bool ValidateDrawArraysInstancedANGLE(Context *context, ...@@ -2910,7 +2939,7 @@ bool ValidateDrawArraysInstancedANGLE(Context *context,
return ValidateDrawInstancedANGLE(context); return ValidateDrawInstancedANGLE(context);
} }
bool ValidateDrawElementsBase(Context *context, GLenum type) bool ValidateDrawElementsBase(Context *context, GLenum mode, GLenum type)
{ {
switch (type) switch (type)
{ {
...@@ -2935,11 +2964,26 @@ bool ValidateDrawElementsBase(Context *context, GLenum type) ...@@ -2935,11 +2964,26 @@ bool ValidateDrawElementsBase(Context *context, GLenum type)
if (curTransformFeedback && curTransformFeedback->isActive() && if (curTransformFeedback && curTransformFeedback->isActive() &&
!curTransformFeedback->isPaused()) !curTransformFeedback->isPaused())
{ {
// It is an invalid operation to call DrawElements, DrawRangeElements or // EXT_geometry_shader allows transform feedback to work with all draw commands.
// DrawElementsInstanced // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
// while transform feedback is active, (3.0.2, section 2.14, pg 86) if (context->getExtensions().geometryShader)
context->handleError(InvalidOperation()); {
return false; if (!ValidateTransformFeedbackPrimitiveMode(
context, curTransformFeedback->getPrimitiveMode(), mode))
{
ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDrawModeTransformFeedback);
return false;
}
}
else
{
// It is an invalid operation to call DrawElements, DrawRangeElements or
// DrawElementsInstanced while transform feedback is active, (3.0.2, section 2.14, pg
// 86)
ANGLE_VALIDATION_ERR(context, InvalidOperation(),
UnsupportedDrawModeForTransformFeedback);
return false;
}
} }
return true; return true;
...@@ -2952,7 +2996,7 @@ bool ValidateDrawElementsCommon(Context *context, ...@@ -2952,7 +2996,7 @@ bool ValidateDrawElementsCommon(Context *context,
const void *indices, const void *indices,
GLsizei primcount) GLsizei primcount)
{ {
if (!ValidateDrawElementsBase(context, type)) if (!ValidateDrawElementsBase(context, mode, type))
return false; return false;
const State &state = context->getGLState(); const State &state = context->getGLState();
......
...@@ -289,7 +289,7 @@ bool ValidateDrawArraysInstancedANGLE(Context *context, ...@@ -289,7 +289,7 @@ bool ValidateDrawArraysInstancedANGLE(Context *context,
GLsizei count, GLsizei count,
GLsizei primcount); GLsizei primcount);
bool ValidateDrawElementsBase(Context *context, GLenum type); bool ValidateDrawElementsBase(Context *context, GLenum mode, GLenum type);
bool ValidateDrawElementsCommon(Context *context, bool ValidateDrawElementsCommon(Context *context,
GLenum mode, GLenum mode,
GLsizei count, GLsizei count,
...@@ -679,6 +679,10 @@ bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuff ...@@ -679,6 +679,10 @@ bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuff
bool ValidateMultitextureUnit(Context *context, GLenum texture); bool ValidateMultitextureUnit(Context *context, GLenum texture);
bool ValidateTransformFeedbackPrimitiveMode(const Context *context,
GLenum transformFeedbackPrimitiveMode,
GLenum renderPrimitiveMode);
// Utility macro for handling implementation methods inside Validation. // Utility macro for handling implementation methods inside Validation.
#define ANGLE_HANDLE_VALIDATION_ERR(X) \ #define ANGLE_HANDLE_VALIDATION_ERR(X) \
context->handleError(X); \ context->handleError(X); \
......
...@@ -475,9 +475,25 @@ bool ValidateDrawArraysIndirect(Context *context, GLenum mode, const void *indir ...@@ -475,9 +475,25 @@ bool ValidateDrawArraysIndirect(Context *context, GLenum mode, const void *indir
if (curTransformFeedback && curTransformFeedback->isActive() && if (curTransformFeedback && curTransformFeedback->isActive() &&
!curTransformFeedback->isPaused()) !curTransformFeedback->isPaused())
{ {
// An INVALID_OPERATION error is generated if transform feedback is active and not paused. // EXT_geometry_shader allows transform feedback to work with all draw commands.
context->handleError(InvalidOperation() << "transform feedback is active and not paused."); // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
return false; if (context->getExtensions().geometryShader)
{
if (!ValidateTransformFeedbackPrimitiveMode(
context, curTransformFeedback->getPrimitiveMode(), mode))
{
ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDrawModeTransformFeedback);
return false;
}
}
else
{
// An INVALID_OPERATION error is generated if transform feedback is active and not
// paused.
ANGLE_VALIDATION_ERR(context, InvalidOperation(),
UnsupportedDrawModeForTransformFeedback);
return false;
}
} }
if (!ValidateDrawIndirectBase(context, mode, indirect)) if (!ValidateDrawIndirectBase(context, mode, indirect))
...@@ -502,8 +518,10 @@ bool ValidateDrawArraysIndirect(Context *context, GLenum mode, const void *indir ...@@ -502,8 +518,10 @@ bool ValidateDrawArraysIndirect(Context *context, GLenum mode, const void *indir
bool ValidateDrawElementsIndirect(Context *context, GLenum mode, GLenum type, const void *indirect) bool ValidateDrawElementsIndirect(Context *context, GLenum mode, GLenum type, const void *indirect)
{ {
if (!ValidateDrawElementsBase(context, type)) if (!ValidateDrawElementsBase(context, mode, type))
{
return false; return false;
}
const State &state = context->getGLState(); const State &state = context->getGLState();
const VertexArray *vao = state.getVertexArray(); const VertexArray *vao = state.getVertexArray();
......
...@@ -53,8 +53,6 @@ ...@@ -53,8 +53,6 @@
1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.layered.* = SKIP 1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.layered.* = SKIP
1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.instanced.invocation_per_layer_* = SKIP 1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.instanced.invocation_per_layer_* = SKIP
1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.instanced.multiple_layers_per_invocation_* = SKIP 1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.instanced.multiple_layers_per_invocation_* = SKIP
// TODO(jiawei.shao@intel.com): Implement validations on transform feedback required in OpenGL ES 3.1 extension GL_EXT_geometry_shader
1941 OPENGL D3D11 : dEQP-GLES31.functional.geometry_shading.vertex_transform_feedback.* = SKIP
// D3D11 Failing Tests // D3D11 Failing Tests
1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_compute_shared_memory_size_* = FAIL 1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_compute_shared_memory_size_* = FAIL
...@@ -1576,6 +1574,7 @@ ...@@ -1576,6 +1574,7 @@
1941 D3D11 : dEQP-GLES31.functional.geometry_shading.instanced.draw_* = FAIL 1941 D3D11 : dEQP-GLES31.functional.geometry_shading.instanced.draw_* = FAIL
1941 D3D11 : dEQP-GLES31.functional.geometry_shading.input.* = FAIL 1941 D3D11 : dEQP-GLES31.functional.geometry_shading.input.* = FAIL
1941 D3D11 : dEQP-GLES31.functional.geometry_shading.negative.* = FAIL 1941 D3D11 : dEQP-GLES31.functional.geometry_shading.negative.* = FAIL
1941 D3D11 : dEQP-GLES31.functional.geometry_shading.vertex_transform_feedback.* = FAIL
1941 D3D11 : dEQP-GLES31.functional.shaders.linkage.es31.geometry.* = FAIL 1941 D3D11 : dEQP-GLES31.functional.shaders.linkage.es31.geometry.* = FAIL
1941 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_directive.geometry_shader = FAIL 1941 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_directive.geometry_shader = FAIL
1941 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.log.shader_directive.geometry_shader = FAIL 1941 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.log.shader_directive.geometry_shader = FAIL
......
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