Commit 910a3daf by jchen10 Committed by Commit Bot

ES31 program query: support TRANSFORM_FEEDBACK_VARYING

TRANSFORM_FEEDBACK_VARYING corresponds to the set of output variables in the last non-fragment stage of program that would be captured when transform feedback is active. The resources enumerated by this query are listed as specified by the most recent call to TransformFeedbackVaryings before the last call to LinkProgram. This mainly collects these resources for query. BUG=angleproject:1920 TEST=angle_end2end_tests:ProgramInterfaceTest* dEQP-GLES31.functional.program_interface_query.transform_feedback_varying.* Change-Id: I0655b12c6d82cef1b44d4ca57ea55bb60d1f78fb Reviewed-on: https://chromium-review.googlesource.com/770450 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent c8c9a24a
...@@ -2014,6 +2014,25 @@ bool Program::linkValidateShaders(const Context *context, InfoLog &infoLog) ...@@ -2014,6 +2014,25 @@ bool Program::linkValidateShaders(const Context *context, InfoLog &infoLog)
return true; return true;
} }
GLuint Program::getTransformFeedbackVaryingResourceIndex(const GLchar *name) const
{
for (GLuint tfIndex = 0; tfIndex < mState.mLinkedTransformFeedbackVaryings.size(); ++tfIndex)
{
const auto &tf = mState.mLinkedTransformFeedbackVaryings[tfIndex];
if (tf.nameWithArrayIndex() == name)
{
return tfIndex;
}
}
return GL_INVALID_INDEX;
}
const TransformFeedbackVarying &Program::getTransformFeedbackVaryingResource(GLuint index) const
{
ASSERT(index < mState.mLinkedTransformFeedbackVaryings.size());
return mState.mLinkedTransformFeedbackVaryings[index];
}
bool Program::linkVaryings(const Context *context, InfoLog &infoLog) const bool Program::linkVaryings(const Context *context, InfoLog &infoLog) const
{ {
Shader *vertexShader = mState.mAttachedVertexShader; Shader *vertexShader = mState.mAttachedVertexShader;
......
...@@ -578,6 +578,8 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -578,6 +578,8 @@ class Program final : angle::NonCopyable, public LabeledObject
GLsizei getTransformFeedbackVaryingCount() const; GLsizei getTransformFeedbackVaryingCount() const;
GLsizei getTransformFeedbackVaryingMaxLength() const; GLsizei getTransformFeedbackVaryingMaxLength() const;
GLenum getTransformFeedbackBufferMode() const; GLenum getTransformFeedbackBufferMode() const;
GLuint getTransformFeedbackVaryingResourceIndex(const GLchar *name) const;
const TransformFeedbackVarying &getTransformFeedbackVaryingResource(GLuint index) const;
static bool LinkValidateInterfaceBlockFields(InfoLog &infoLog, static bool LinkValidateInterfaceBlockFields(InfoLog &infoLog,
const std::string &uniformName, const std::string &uniformName,
......
...@@ -512,6 +512,28 @@ GLint GetOutputResourceProperty(const Program *program, GLuint index, const GLen ...@@ -512,6 +512,28 @@ GLint GetOutputResourceProperty(const Program *program, GLuint index, const GLen
} }
} }
GLint GetTransformFeedbackVaryingResourceProperty(const Program *program,
GLuint index,
const GLenum prop)
{
const auto &tfVariable = program->getTransformFeedbackVaryingResource(index);
switch (prop)
{
case GL_TYPE:
return clampCast<GLint>(tfVariable.type);
case GL_ARRAY_SIZE:
return clampCast<GLint>(tfVariable.size());
case GL_NAME_LENGTH:
return clampCast<GLint>(tfVariable.nameWithArrayIndex().size() + 1);
default:
UNREACHABLE();
return GL_INVALID_VALUE;
}
}
GLint QueryProgramInterfaceActiveResources(const Program *program, GLenum programInterface) GLint QueryProgramInterfaceActiveResources(const Program *program, GLenum programInterface)
{ {
switch (programInterface) switch (programInterface)
...@@ -537,10 +559,8 @@ GLint QueryProgramInterfaceActiveResources(const Program *program, GLenum progra ...@@ -537,10 +559,8 @@ GLint QueryProgramInterfaceActiveResources(const Program *program, GLenum progra
case GL_SHADER_STORAGE_BLOCK: case GL_SHADER_STORAGE_BLOCK:
return clampCast<GLint>(program->getState().getShaderStorageBlocks().size()); return clampCast<GLint>(program->getState().getShaderStorageBlocks().size());
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING: case GL_TRANSFORM_FEEDBACK_VARYING:
UNIMPLEMENTED(); return clampCast<GLint>(program->getTransformFeedbackVaryingCount());
return 0;
default: default:
UNREACHABLE(); UNREACHABLE();
...@@ -592,10 +612,9 @@ GLint QueryProgramInterfaceMaxNameLength(const Program *program, GLenum programI ...@@ -592,10 +612,9 @@ GLint QueryProgramInterfaceMaxNameLength(const Program *program, GLenum programI
FindMaxSize(program->getState().getShaderStorageBlocks(), &InterfaceBlock::name); FindMaxSize(program->getState().getShaderStorageBlocks(), &InterfaceBlock::name);
break; break;
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING: case GL_TRANSFORM_FEEDBACK_VARYING:
UNIMPLEMENTED(); maxNameLength = clampCast<GLint>(program->getTransformFeedbackVaryingMaxLength() - 1);
return 0; break;
default: default:
UNREACHABLE(); UNREACHABLE();
...@@ -968,7 +987,7 @@ void QueryProgramiv(const Context *context, const Program *program, GLenum pname ...@@ -968,7 +987,7 @@ void QueryProgramiv(const Context *context, const Program *program, GLenum pname
*params = program->getTransformFeedbackBufferMode(); *params = program->getTransformFeedbackBufferMode();
break; break;
case GL_TRANSFORM_FEEDBACK_VARYINGS: case GL_TRANSFORM_FEEDBACK_VARYINGS:
*params = program->getTransformFeedbackVaryingCount(); *params = clampCast<GLint>(program->getTransformFeedbackVaryingCount());
break; break;
case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
*params = program->getTransformFeedbackVaryingMaxLength(); *params = program->getTransformFeedbackVaryingMaxLength();
...@@ -1471,10 +1490,8 @@ GLuint QueryProgramResourceIndex(const Program *program, ...@@ -1471,10 +1490,8 @@ GLuint QueryProgramResourceIndex(const Program *program,
case GL_UNIFORM_BLOCK: case GL_UNIFORM_BLOCK:
return program->getUniformBlockIndex(name); return program->getUniformBlockIndex(name);
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING: case GL_TRANSFORM_FEEDBACK_VARYING:
UNIMPLEMENTED(); return program->getTransformFeedbackVaryingResourceIndex(name);
return GL_INVALID_INDEX;
default: default:
UNREACHABLE(); UNREACHABLE();
...@@ -1515,9 +1532,8 @@ void QueryProgramResourceName(const Program *program, ...@@ -1515,9 +1532,8 @@ void QueryProgramResourceName(const Program *program,
program->getActiveUniformBlockName(index, bufSize, length, name); program->getActiveUniformBlockName(index, bufSize, length, name);
break; break;
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING: case GL_TRANSFORM_FEEDBACK_VARYING:
UNIMPLEMENTED(); program->getTransformFeedbackVarying(index, bufSize, length, nullptr, nullptr, name);
break; break;
default: default:
...@@ -1602,10 +1618,10 @@ void QueryProgramResourceiv(const Program *program, ...@@ -1602,10 +1618,10 @@ void QueryProgramResourceiv(const Program *program,
GetAtomicCounterBufferResourceProperty(program, index, props[i], params, bufSize, GetAtomicCounterBufferResourceProperty(program, index, props[i], params, bufSize,
&pos); &pos);
break; break;
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING: case GL_TRANSFORM_FEEDBACK_VARYING:
UNIMPLEMENTED(); params[i] = GetTransformFeedbackVaryingResourceProperty(program, index, props[i]);
params[i] = GL_INVALID_VALUE; ++pos;
break; break;
default: default:
......
...@@ -272,10 +272,8 @@ bool ValidateProgramResourceIndex(const Program *programObject, ...@@ -272,10 +272,8 @@ bool ValidateProgramResourceIndex(const Program *programObject,
case GL_ATOMIC_COUNTER_BUFFER: case GL_ATOMIC_COUNTER_BUFFER:
return (index < programObject->getActiveAtomicCounterBufferCount()); return (index < programObject->getActiveAtomicCounterBufferCount());
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING: case GL_TRANSFORM_FEEDBACK_VARYING:
UNIMPLEMENTED(); return (index < static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()));
return false;
default: default:
UNREACHABLE(); UNREACHABLE();
......
...@@ -795,6 +795,109 @@ TEST_P(ProgramInterfaceTestES31, GetShaderStorageBlockProperties) ...@@ -795,6 +795,109 @@ TEST_P(ProgramInterfaceTestES31, GetShaderStorageBlockProperties)
EXPECT_EQ("blockName1[0]", std::string(name)); EXPECT_EQ("blockName1[0]", std::string(name));
} }
// Tests transform feedback varying qeury works correctly.
TEST_P(ProgramInterfaceTestES31, QueryTransformFeedbackVarying)
{
const std::string &vertexShaderSource =
R"(#version 310 es
in vec3 position;\
out float outSingleType;
out vec2 outWholeArray[2];
out vec3 outArrayElements[16];
void main() {
outSingleType = 0.0;
outWholeArray[0] = vec2(position);
outArrayElements[7] = vec3(0, 0, 0);
outArrayElements[15] = position;
gl_Position = vec4(position, 1);
})";
const std::string &fragmentShaderSource =
R"(#version 310 es
precision mediump float;
out vec4 color;
in float outSingleType;
in vec2 outWholeArray[2];
in vec3 outArrayElements[16];
void main() {
color = vec4(0);
})";
std::vector<std::string> tfVaryings;
tfVaryings.push_back("outArrayElements[7]");
tfVaryings.push_back("outArrayElements[15]");
tfVaryings.push_back("outSingleType");
tfVaryings.push_back("outWholeArray");
GLuint program = CompileProgramWithTransformFeedback(vertexShaderSource, fragmentShaderSource,
tfVaryings, GL_INTERLEAVED_ATTRIBS);
ASSERT_NE(0u, program);
GLint num;
glGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, &num);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(4, num);
glGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, &num);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(21, num); // outArrayElements[15]
// GLES 3.10, Page 77:
// For TRANSFORM_FEEDBACK_VARYING, the active resource list will use the variable order
// specified in the most recent call to TransformFeedbackVaryings before the last call to
// LinkProgram.
GLuint index =
glGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "outArrayElements[7]");
EXPECT_GL_NO_ERROR();
EXPECT_EQ(0u, index);
index =
glGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "outArrayElements[15]");
EXPECT_GL_NO_ERROR();
EXPECT_EQ(1u, index);
index = glGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "outSingleType");
EXPECT_GL_NO_ERROR();
EXPECT_EQ(2u, index);
index = glGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "outWholeArray");
EXPECT_GL_NO_ERROR();
EXPECT_EQ(3u, index);
// GLES 3.10, Page 80:
// For TRANSFORM_FEEDBACK_VARYING resources, name must match one of the variables to be captured
// as specified by a previous call to TransformFeedbackVaryings. Otherwise, INVALID_INDEX is
// returned.
// If name does not match a resource as described above, the value INVALID_INDEX is returned,
// but no GL error is generated.
index = glGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "outWholeArray[0]");
EXPECT_GL_NO_ERROR();
EXPECT_EQ(GL_INVALID_INDEX, index);
GLenum props[] = {GL_TYPE, GL_ARRAY_SIZE, GL_NAME_LENGTH};
GLsizei propCount = static_cast<GLsizei>(ArraySize(props));
GLint params[ArraySize(props)];
GLsizei length = 0;
// Query properties of 'outArrayElements[15]'.
glGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, 1, propCount, props, propCount,
&length, params);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(propCount, length);
EXPECT_EQ(GL_FLOAT_VEC3, params[0]); // type
EXPECT_EQ(1, params[1]); // array_size
EXPECT_EQ(21, params[2]); // name_length
// Query properties of 'outWholeArray'.
glGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, 3, propCount, props, propCount,
&length, params);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(propCount, length);
EXPECT_EQ(GL_FLOAT_VEC2, params[0]); // type
EXPECT_EQ(2, params[1]); // array_size
EXPECT_EQ(14, params[2]); // name_length
glDeleteProgram(program);
}
ANGLE_INSTANTIATE_TEST(ProgramInterfaceTestES31, ES31_OPENGL(), ES31_OPENGLES()); ANGLE_INSTANTIATE_TEST(ProgramInterfaceTestES31, ES31_OPENGL(), ES31_OPENGLES());
} // anonymous namespace } // anonymous namespace
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