Enabling Transform Feedback
This cl enables transform feedback in Context by calling
Program::applyTransformFeedback(). It also adds the code
required to compute vertex offsets between different draw
calls, when multiple successive draw calls write into the
same transform feedback buffer(s).
Change-Id: Ib3bc4bdd1308486642f233f425d0088a55cb1333
Reviewed-on: https://swiftshader-review.googlesource.com/5301
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index da9aedd..de4626b 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -2171,16 +2171,14 @@
*params = 2;
break;
case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: // integer, at least 64
- UNIMPLEMENTED();
- *params = 64;
+ *params = sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS;
break;
case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: // integer, at least 4
UNIMPLEMENTED();
*params = MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS;
break;
case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: // integer, at least 4
- UNIMPLEMENTED();
- *params = 4;
+ *params = sw::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS;
break;
case GL_MAX_UNIFORM_BLOCK_SIZE: // integer, at least 16384
*params = MAX_UNIFORM_BLOCK_SIZE;
@@ -3012,6 +3010,7 @@
mAppliedProgramSerial = programObject->getSerial();
}
+ programObject->applyTransformFeedback(getTransformFeedback());
programObject->applyUniformBuffers(mState.uniformBuffers);
programObject->applyUniforms();
}
@@ -3438,8 +3437,9 @@
sw::DrawType primitiveType;
int primitiveCount;
+ int verticesPerPrimitive;
- if(!es2sw::ConvertPrimitiveType(mode, count, GL_NONE, primitiveType, primitiveCount))
+ if(!es2sw::ConvertPrimitiveType(mode, count, GL_NONE, primitiveType, primitiveCount, verticesPerPrimitive))
return error(GL_INVALID_ENUM);
if(primitiveCount <= 0)
@@ -3472,10 +3472,15 @@
return error(GL_INVALID_OPERATION);
}
- if(!cullSkipsDraw(mode))
+ TransformFeedback* transformFeedback = getTransformFeedback();
+ if(!cullSkipsDraw(mode) || (transformFeedback->isActive() && !transformFeedback->isPaused()))
{
device->drawPrimitive(primitiveType, primitiveCount);
}
+ if(transformFeedback)
+ {
+ transformFeedback->addVertexOffset(primitiveCount * verticesPerPrimitive);
+ }
}
}
@@ -3493,8 +3498,9 @@
sw::DrawType primitiveType;
int primitiveCount;
+ int verticesPerPrimitive;
- if(!es2sw::ConvertPrimitiveType(mode, count, type, primitiveType, primitiveCount))
+ if(!es2sw::ConvertPrimitiveType(mode, count, type, primitiveType, primitiveCount, verticesPerPrimitive))
return error(GL_INVALID_ENUM);
if(primitiveCount <= 0)
@@ -3535,10 +3541,15 @@
return error(GL_INVALID_OPERATION);
}
- if(!cullSkipsDraw(mode))
+ TransformFeedback* transformFeedback = getTransformFeedback();
+ if(!cullSkipsDraw(mode) || (transformFeedback->isActive() && !transformFeedback->isPaused()))
{
device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount);
}
+ if(transformFeedback)
+ {
+ transformFeedback->addVertexOffset(primitiveCount * verticesPerPrimitive);
+ }
}
}
diff --git a/src/OpenGL/libGLESv2/utilities.cpp b/src/OpenGL/libGLESv2/utilities.cpp
index 09e5975..1143546 100644
--- a/src/OpenGL/libGLESv2/utilities.cpp
+++ b/src/OpenGL/libGLESv2/utilities.cpp
@@ -1422,37 +1422,44 @@
}
}
- bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, GLenum elementType, sw::DrawType &drawType, int &primitiveCount)
+ bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, GLenum elementType, sw::DrawType &drawType, int &primitiveCount, int &verticesPerPrimitive)
{
switch(primitiveType)
{
case GL_POINTS:
drawType = sw::DRAW_POINTLIST;
primitiveCount = elementCount;
+ verticesPerPrimitive = 1;
break;
case GL_LINES:
drawType = sw::DRAW_LINELIST;
primitiveCount = elementCount / 2;
+ verticesPerPrimitive = 2;
break;
case GL_LINE_LOOP:
drawType = sw::DRAW_LINELOOP;
primitiveCount = elementCount;
+ verticesPerPrimitive = 2;
break;
case GL_LINE_STRIP:
drawType = sw::DRAW_LINESTRIP;
primitiveCount = elementCount - 1;
+ verticesPerPrimitive = 2;
break;
case GL_TRIANGLES:
drawType = sw::DRAW_TRIANGLELIST;
primitiveCount = elementCount / 3;
+ verticesPerPrimitive = 3;
break;
case GL_TRIANGLE_STRIP:
drawType = sw::DRAW_TRIANGLESTRIP;
primitiveCount = elementCount - 2;
+ verticesPerPrimitive = 3;
break;
case GL_TRIANGLE_FAN:
drawType = sw::DRAW_TRIANGLEFAN;
primitiveCount = elementCount - 2;
+ verticesPerPrimitive = 3;
break;
default:
return false;
diff --git a/src/OpenGL/libGLESv2/utilities.h b/src/OpenGL/libGLESv2/utilities.h
index 2aa983c..d2d9084 100644
--- a/src/OpenGL/libGLESv2/utilities.h
+++ b/src/OpenGL/libGLESv2/utilities.h
@@ -80,7 +80,7 @@
unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha);
sw::MipmapType ConvertMipMapFilter(GLenum minFilter);
sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy);
- bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, GLenum elementType, sw::DrawType &swPrimitiveType, int &primitiveCount);
+ bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, GLenum elementType, sw::DrawType &swPrimitiveType, int &primitiveCount, int &verticesPerPrimitive);
sw::Format ConvertRenderbufferFormat(GLenum format);
}