Commit 191381fd by jchen10 Committed by Commit Bot

ES31: Add glGetProgramResourceLocation API

Add API entry and validation checks(GLES 3.1 section 7.3). Add the first 2 interfaces(PROGRAM_INPUT and PROGRAM_OUTPUT) implementation. BUG=angleproject:1920 TEST=angle_end2end_tests:ProgramInterfaceTestES31.* Change-Id: I5128cda43b0d9176c910b036cdc76bf37757670e Reviewed-on: https://chromium-review.googlesource.com/474212 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 24fe74c1
......@@ -2166,6 +2166,14 @@ void Context::getProgramResourceName(GLuint program,
QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
}
GLint Context::getProgramResourceLocation(GLuint program,
GLenum programInterface,
const GLchar *name)
{
const auto *programObject = getProgram(program);
return QueryProgramResourceLocation(programObject, programInterface, name);
}
void Context::handleError(const Error &error)
{
if (error.isError())
......
......@@ -217,6 +217,7 @@ class Context final : public ValidationContext
GLsizei bufSize,
GLsizei *length,
GLchar *name);
GLint getProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar *name);
Buffer *getBuffer(GLuint handle) const;
FenceNV *getFenceNV(GLuint handle);
......
......@@ -1050,7 +1050,7 @@ GLuint QueryProgramResourceIndex(const Program *program,
case GL_PROGRAM_OUTPUT:
return program->getOutputResourceIndex(name);
// TODO(Jie): more interfaces.
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_UNIFORM:
case GL_UNIFORM_BLOCK:
case GL_TRANSFORM_FEEDBACK_VARYING:
......@@ -1082,7 +1082,7 @@ void QueryProgramResourceName(const Program *program,
program->getOutputResourceName(index, bufSize, length, name);
break;
// TODO(Jie): more interfaces.
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_UNIFORM:
case GL_UNIFORM_BLOCK:
case GL_TRANSFORM_FEEDBACK_VARYING:
......@@ -1096,6 +1096,33 @@ void QueryProgramResourceName(const Program *program,
}
}
GLint QueryProgramResourceLocation(const Program *program,
GLenum programInterface,
const GLchar *name)
{
switch (programInterface)
{
case GL_PROGRAM_INPUT:
return program->getAttributeLocation(name);
case GL_PROGRAM_OUTPUT:
return program->getFragDataLocation(name);
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_UNIFORM:
case GL_UNIFORM_BLOCK:
case GL_TRANSFORM_FEEDBACK_VARYING:
case GL_BUFFER_VARIABLE:
case GL_SHADER_STORAGE_BLOCK:
UNIMPLEMENTED();
return -1;
default:
UNREACHABLE();
return -1;
}
}
} // namespace gl
namespace egl
......
......@@ -128,6 +128,10 @@ void QueryProgramResourceName(const Program *program,
GLsizei *length,
GLchar *name);
GLint QueryProgramResourceLocation(const Program *program,
GLenum programInterface,
const GLchar *name);
} // namespace gl
namespace egl
......
......@@ -41,6 +41,19 @@ bool ValidateNamedProgramInterface(GLenum programInterface)
}
}
bool ValidateLocationProgramInterface(GLenum programInterface)
{
switch (programInterface)
{
case GL_UNIFORM:
case GL_PROGRAM_INPUT:
case GL_PROGRAM_OUTPUT:
return true;
default:
return false;
}
}
bool ValidateProgramResourceIndex(const Program *programObject,
GLenum programInterface,
GLuint index)
......@@ -895,4 +908,36 @@ bool ValidateBindImageTexture(Context *context,
return true;
}
bool ValidateGetProgramResourceLocation(Context *context,
GLuint program,
GLenum programInterface,
const GLchar *name)
{
if (context->getClientVersion() < ES_3_1)
{
context->handleError(InvalidOperation() << "Context does not support GLES3.1.");
return false;
}
Program *programObject = GetValidProgram(context, program);
if (programObject == nullptr)
{
return false;
}
if (!programObject->isLinked())
{
context->handleError(InvalidOperation() << "Program is not successfully linked.");
return false;
}
if (!ValidateLocationProgramInterface(programInterface))
{
context->handleError(InvalidEnum() << "Invalid program interface.");
return false;
}
return true;
}
} // namespace gl
......@@ -65,6 +65,10 @@ bool ValidateGetProgramResourceName(Context *context,
GLsizei bufSize,
GLsizei *length,
GLchar *name);
bool ValidateGetProgramResourceLocation(Context *context,
GLuint program,
GLenum programInterface,
const GLchar *name);
bool ValidateBindVertexBuffer(ValidationContext *context,
GLuint bindingIndex,
......
......@@ -154,7 +154,7 @@ GLuint GL_APIENTRY GetProgramResourceIndex(GLuint program,
}
return context->getProgramResourceIndex(program, programInterface, name);
}
return 0u;
return GL_INVALID_INDEX;
}
void GL_APIENTRY GetProgramResourceName(GLuint program,
......@@ -215,13 +215,14 @@ GLint GL_APIENTRY GetProgramResourceLocation(GLuint program,
Context *context = GetValidGlobalContext();
if (context)
{
if (!context->skipValidation())
if (!context->skipValidation() &&
!ValidateGetProgramResourceLocation(context, program, programInterface, name))
{
context->handleError(InvalidOperation() << "Entry point not implemented");
return -1;
}
UNIMPLEMENTED();
return context->getProgramResourceLocation(program, programInterface, name);
}
return 0;
return -1;
}
void GL_APIENTRY UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
......
......@@ -134,5 +134,64 @@ TEST_P(ProgramInterfaceTestES31, GetResourceName)
EXPECT_EQ("oColor[", std::string(name));
}
// Tests glGetProgramResourceLocation.
TEST_P(ProgramInterfaceTestES31, GetResourceLocation)
{
const std::string &vertexShaderSource =
"#version 310 es\n"
"precision highp float;\n"
"layout(location = 3) in highp vec4 position;\n"
"in highp vec4 noLocationSpecified;\n"
"void main()\n"
"{\n"
" gl_Position = position;\n"
"}";
const std::string &fragmentShaderSource =
"#version 310 es\n"
"precision highp float;\n"
"uniform vec4 color;\n"
"layout(location = 2) out vec4 oColor[4];\n"
"void main()\n"
"{\n"
" oColor[0] = color;\n"
"}";
ANGLE_GL_PROGRAM(program, vertexShaderSource, fragmentShaderSource);
std::array<GLenum, 5> invalidInterfaces = {{GL_UNIFORM_BLOCK, GL_TRANSFORM_FEEDBACK_VARYING,
GL_BUFFER_VARIABLE, GL_SHADER_STORAGE_BLOCK,
GL_ATOMIC_COUNTER_BUFFER}};
GLint location;
for (auto &invalidInterface : invalidInterfaces)
{
location = glGetProgramResourceLocation(program, invalidInterface, "any");
EXPECT_GL_ERROR(GL_INVALID_ENUM);
EXPECT_EQ(-1, location);
}
location = glGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position");
EXPECT_GL_NO_ERROR();
EXPECT_EQ(3, location);
location = glGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "noLocationSpecified");
EXPECT_GL_NO_ERROR();
EXPECT_EQ(-1, location);
location = glGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "missing");
EXPECT_GL_NO_ERROR();
EXPECT_EQ(-1, location);
location = glGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "oColor");
EXPECT_GL_NO_ERROR();
EXPECT_EQ(2, location);
location = glGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "oColor[0]");
EXPECT_GL_NO_ERROR();
EXPECT_EQ(2, location);
location = glGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "oColor[3]");
EXPECT_GL_NO_ERROR();
EXPECT_EQ(5, location);
}
ANGLE_INSTANTIATE_TEST(ProgramInterfaceTestES31, ES31_OPENGL(), ES31_D3D11(), ES31_OPENGLES());
} // 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