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, ...@@ -2166,6 +2166,14 @@ void Context::getProgramResourceName(GLuint program,
QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name); 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) void Context::handleError(const Error &error)
{ {
if (error.isError()) if (error.isError())
......
...@@ -217,6 +217,7 @@ class Context final : public ValidationContext ...@@ -217,6 +217,7 @@ class Context final : public ValidationContext
GLsizei bufSize, GLsizei bufSize,
GLsizei *length, GLsizei *length,
GLchar *name); GLchar *name);
GLint getProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar *name);
Buffer *getBuffer(GLuint handle) const; Buffer *getBuffer(GLuint handle) const;
FenceNV *getFenceNV(GLuint handle); FenceNV *getFenceNV(GLuint handle);
......
...@@ -1050,7 +1050,7 @@ GLuint QueryProgramResourceIndex(const Program *program, ...@@ -1050,7 +1050,7 @@ GLuint QueryProgramResourceIndex(const Program *program,
case GL_PROGRAM_OUTPUT: case GL_PROGRAM_OUTPUT:
return program->getOutputResourceIndex(name); return program->getOutputResourceIndex(name);
// TODO(Jie): more interfaces. // TODO(jie.a.chen@intel.com): more interfaces.
case GL_UNIFORM: case GL_UNIFORM:
case GL_UNIFORM_BLOCK: case GL_UNIFORM_BLOCK:
case GL_TRANSFORM_FEEDBACK_VARYING: case GL_TRANSFORM_FEEDBACK_VARYING:
...@@ -1082,7 +1082,7 @@ void QueryProgramResourceName(const Program *program, ...@@ -1082,7 +1082,7 @@ void QueryProgramResourceName(const Program *program,
program->getOutputResourceName(index, bufSize, length, name); program->getOutputResourceName(index, bufSize, length, name);
break; break;
// TODO(Jie): more interfaces. // TODO(jie.a.chen@intel.com): more interfaces.
case GL_UNIFORM: case GL_UNIFORM:
case GL_UNIFORM_BLOCK: case GL_UNIFORM_BLOCK:
case GL_TRANSFORM_FEEDBACK_VARYING: case GL_TRANSFORM_FEEDBACK_VARYING:
...@@ -1096,6 +1096,33 @@ void QueryProgramResourceName(const Program *program, ...@@ -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 gl
namespace egl namespace egl
......
...@@ -128,6 +128,10 @@ void QueryProgramResourceName(const Program *program, ...@@ -128,6 +128,10 @@ void QueryProgramResourceName(const Program *program,
GLsizei *length, GLsizei *length,
GLchar *name); GLchar *name);
GLint QueryProgramResourceLocation(const Program *program,
GLenum programInterface,
const GLchar *name);
} // namespace gl } // namespace gl
namespace egl namespace egl
......
...@@ -41,6 +41,19 @@ bool ValidateNamedProgramInterface(GLenum programInterface) ...@@ -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, bool ValidateProgramResourceIndex(const Program *programObject,
GLenum programInterface, GLenum programInterface,
GLuint index) GLuint index)
...@@ -895,4 +908,36 @@ bool ValidateBindImageTexture(Context *context, ...@@ -895,4 +908,36 @@ bool ValidateBindImageTexture(Context *context,
return true; 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 } // namespace gl
...@@ -65,6 +65,10 @@ bool ValidateGetProgramResourceName(Context *context, ...@@ -65,6 +65,10 @@ bool ValidateGetProgramResourceName(Context *context,
GLsizei bufSize, GLsizei bufSize,
GLsizei *length, GLsizei *length,
GLchar *name); GLchar *name);
bool ValidateGetProgramResourceLocation(Context *context,
GLuint program,
GLenum programInterface,
const GLchar *name);
bool ValidateBindVertexBuffer(ValidationContext *context, bool ValidateBindVertexBuffer(ValidationContext *context,
GLuint bindingIndex, GLuint bindingIndex,
......
...@@ -154,7 +154,7 @@ GLuint GL_APIENTRY GetProgramResourceIndex(GLuint program, ...@@ -154,7 +154,7 @@ GLuint GL_APIENTRY GetProgramResourceIndex(GLuint program,
} }
return context->getProgramResourceIndex(program, programInterface, name); return context->getProgramResourceIndex(program, programInterface, name);
} }
return 0u; return GL_INVALID_INDEX;
} }
void GL_APIENTRY GetProgramResourceName(GLuint program, void GL_APIENTRY GetProgramResourceName(GLuint program,
...@@ -215,13 +215,14 @@ GLint GL_APIENTRY GetProgramResourceLocation(GLuint program, ...@@ -215,13 +215,14 @@ GLint GL_APIENTRY GetProgramResourceLocation(GLuint program,
Context *context = GetValidGlobalContext(); Context *context = GetValidGlobalContext();
if (context) 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) void GL_APIENTRY UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
......
...@@ -134,5 +134,64 @@ TEST_P(ProgramInterfaceTestES31, GetResourceName) ...@@ -134,5 +134,64 @@ TEST_P(ProgramInterfaceTestES31, GetResourceName)
EXPECT_EQ("oColor[", std::string(name)); 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()); ANGLE_INSTANTIATE_TEST(ProgramInterfaceTestES31, ES31_OPENGL(), ES31_D3D11(), 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