Transform feedback varyings API
Implemented the API functions to set and get
the varyings used for transform feedback.
Change-Id: I0d6451cfbd4a4b1b96dd9c064bb9b310b46764c4
Reviewed-on: https://swiftshader-review.googlesource.com/3462
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libGLESv2/Program.cpp b/src/OpenGL/libGLESv2/Program.cpp
index 2482f8d..3d13afe 100644
--- a/src/OpenGL/libGLESv2/Program.cpp
+++ b/src/OpenGL/libGLESv2/Program.cpp
@@ -92,6 +92,16 @@
{
}
+ LinkedVarying::LinkedVarying()
+ {
+ }
+
+ LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size, const std::string &semanticName,
+ unsigned int semanticIndex, unsigned int semanticIndexCount)
+ : name(name), type(type), size(size), semanticName(semanticName), semanticIndex(semanticIndex), semanticIndexCount(semanticIndexCount)
+ {
+ }
+
Program::Program(ResourceManager *manager, GLuint handle) : resourceManager(manager), handle(handle), serial(issueSerial())
{
device = getDevice();
@@ -2579,6 +2589,80 @@
return maxLength;
}
+ void Program::setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode)
+ {
+ transformFeedbackVaryings.resize(count);
+ for(GLsizei i = 0; i < count; i++)
+ {
+ transformFeedbackVaryings[i] = varyings[i];
+ }
+
+ transformFeedbackBufferMode = bufferMode;
+ }
+
+ void Program::getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const
+ {
+ if(linked)
+ {
+ ASSERT(index < transformFeedbackLinkedVaryings.size());
+ const LinkedVarying &varying = transformFeedbackLinkedVaryings[index];
+ GLsizei lastNameIdx = std::min(bufSize - 1, static_cast<GLsizei>(varying.name.length()));
+ if(length)
+ {
+ *length = lastNameIdx;
+ }
+ if(size)
+ {
+ *size = varying.size;
+ }
+ if(type)
+ {
+ *type = varying.type;
+ }
+ if(name)
+ {
+ memcpy(name, varying.name.c_str(), lastNameIdx);
+ name[lastNameIdx] = '\0';
+ }
+ }
+ }
+
+ GLsizei Program::getTransformFeedbackVaryingCount() const
+ {
+ if(linked)
+ {
+ return static_cast<GLsizei>(transformFeedbackLinkedVaryings.size());
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ GLsizei Program::getTransformFeedbackVaryingMaxLength() const
+ {
+ if(linked)
+ {
+ GLsizei maxSize = 0;
+ for(size_t i = 0; i < transformFeedbackLinkedVaryings.size(); i++)
+ {
+ const LinkedVarying &varying = transformFeedbackLinkedVaryings[i];
+ maxSize = std::max(maxSize, static_cast<GLsizei>(varying.name.length() + 1));
+ }
+
+ return maxSize;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ GLenum Program::getTransformFeedbackBufferMode() const
+ {
+ return transformFeedbackBufferMode;
+ }
+
void Program::flagForDeletion()
{
orphaned = true;
diff --git a/src/OpenGL/libGLESv2/Program.h b/src/OpenGL/libGLESv2/Program.h
index 0550819..5a1284f 100644
--- a/src/OpenGL/libGLESv2/Program.h
+++ b/src/OpenGL/libGLESv2/Program.h
@@ -104,6 +104,24 @@
unsigned int index;
};
+ struct LinkedVarying
+ {
+ LinkedVarying();
+ LinkedVarying(const std::string &name, GLenum type, GLsizei size, const std::string &semanticName,
+ unsigned int semanticIndex, unsigned int semanticIndexCount);
+
+ // Original GL name
+ std::string name;
+
+ GLenum type;
+ GLsizei size;
+
+ // DirectX semantic information
+ std::string semanticName;
+ unsigned int semanticIndex;
+ unsigned int semanticIndexCount;
+ };
+
class Program
{
public:
@@ -180,6 +198,12 @@
GLint getActiveUniformBlockCount() const;
GLint getActiveUniformBlockMaxLength() const;
+ void setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode);
+ void getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const;
+ GLsizei getTransformFeedbackVaryingCount() const;
+ GLsizei getTransformFeedbackVaryingMaxLength() const;
+ GLenum getTransformFeedbackBufferMode() const;
+
void addRef();
void release();
unsigned int getRefCount() const;
@@ -253,6 +277,9 @@
GLuint uniformBlockBindings[MAX_UNIFORM_BUFFER_BINDINGS];
+ std::vector<std::string> transformFeedbackVaryings;
+ GLenum transformFeedbackBufferMode;
+
struct Sampler
{
bool active;
@@ -269,6 +296,8 @@
UniformIndex uniformIndex;
typedef std::vector<UniformBlock*> UniformBlockArray;
UniformBlockArray uniformBlocks;
+ typedef std::vector<LinkedVarying> LinkedVaryingArray;
+ LinkedVaryingArray transformFeedbackLinkedVaryings;
bool linked;
bool orphaned; // Flag to indicate that the program can be deleted when no longer in use
diff --git a/src/OpenGL/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp
index c05bd3a..c6c7ef8 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -3196,6 +3196,33 @@
return;
}
else return error(GL_INVALID_ENUM);
+ case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
+ if(clientVersion >= 3)
+ {
+ *params = programObject->getTransformFeedbackBufferMode();
+ return;
+ }
+ else return error(GL_INVALID_ENUM);
+ case GL_TRANSFORM_FEEDBACK_VARYINGS:
+ if(clientVersion >= 3)
+ {
+ *params = programObject->getTransformFeedbackVaryingCount();
+ return;
+ }
+ else return error(GL_INVALID_ENUM);
+ case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
+ if(clientVersion >= 3)
+ {
+ *params = programObject->getTransformFeedbackVaryingMaxLength();
+ return;
+ }
+ else return error(GL_INVALID_ENUM);
+ case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
+ if(clientVersion >= 3)
+ {
+ UNIMPLEMENTED();
+ }
+ else return error(GL_INVALID_ENUM);
default:
return error(GL_INVALID_ENUM);
}
diff --git a/src/OpenGL/libGLESv2/libGLESv3.cpp b/src/OpenGL/libGLESv2/libGLESv3.cpp
index 9a87b73..ea5a572 100644
--- a/src/OpenGL/libGLESv2/libGLESv3.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv3.cpp
@@ -1971,9 +1971,9 @@
{
return error(GL_INVALID_VALUE);
}
- }
- UNIMPLEMENTED();
+ programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
+ }
}
GL_APICALL void GL_APIENTRY glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name)
@@ -1981,6 +1981,11 @@
TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufSize = %d, GLsizei *length = %p, GLsizei *size = %p, GLenum *type = %p, GLchar *name = %p)",
program, index, bufSize, length, size, type, name);
+ if(bufSize < 0)
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
es2::Context *context = es2::getContext();
if(context)
@@ -1991,9 +1996,14 @@
{
return error(GL_INVALID_VALUE);
}
- }
- UNIMPLEMENTED();
+ if(index >= static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()))
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
+ }
}
GL_APICALL void GL_APIENTRY glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer)