Commit baf5d945 by jchen10 Committed by Commit Bot

ES31: Add UNIFORM support for ProgramInterface

Add program resource properties for uniform. BUG=angleproject:1920 TEST=angle_end2end_tests:ProgramInterfaceTest* Change-Id: Ia5cf6219db43b8b1f73efbb3565d21c86e9d3ec0 Reviewed-on: https://chromium-review.googlesource.com/638050 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent a99ed554
......@@ -5197,7 +5197,7 @@ void Context::getActiveUniformsiv(GLuint program,
for (int uniformId = 0; uniformId < uniformCount; uniformId++)
{
const GLuint index = uniformIndices[uniformId];
params[uniformId] = programObject->getActiveUniformi(index, pname);
params[uniformId] = GetUniformResourceProperty(programObject, index, pname);
}
}
......
......@@ -1134,20 +1134,12 @@ size_t Program::getOutputResourceCount() const
return (mLinked ? mState.mOutputVariables.size() : 0);
}
void Program::getInputResourceName(GLuint index,
GLsizei bufSize,
GLsizei *length,
GLchar *name) const
{
GLint size;
GLenum type;
getActiveAttribute(index, bufSize, length, &size, &type, name);
}
void Program::getOutputResourceName(GLuint index,
GLsizei bufSize,
GLsizei *length,
GLchar *name) const
template <typename T>
void Program::getResourceName(GLuint index,
const std::vector<T> &resources,
GLsizei bufSize,
GLsizei *length,
GLchar *name) const
{
if (length)
{
......@@ -1162,17 +1154,41 @@ void Program::getOutputResourceName(GLuint index,
}
return;
}
ASSERT(index < mState.mOutputVariables.size());
const auto &output = mState.mOutputVariables[index];
ASSERT(index < resources.size());
const auto &resource = resources[index];
if (bufSize > 0)
{
std::string nameWithArray = (output.isArray() ? output.name + "[0]" : output.name);
std::string nameWithArray = (resource.isArray() ? resource.name + "[0]" : resource.name);
CopyStringToBuffer(name, nameWithArray, bufSize, length);
}
}
void Program::getInputResourceName(GLuint index,
GLsizei bufSize,
GLsizei *length,
GLchar *name) const
{
getResourceName(index, mState.mAttributes, bufSize, length, name);
}
void Program::getOutputResourceName(GLuint index,
GLsizei bufSize,
GLsizei *length,
GLchar *name) const
{
getResourceName(index, mState.mOutputVariables, bufSize, length, name);
}
void Program::getUniformResourceName(GLuint index,
GLsizei bufSize,
GLsizei *length,
GLchar *name) const
{
getResourceName(index, mState.mUniforms, bufSize, length, name);
}
const sh::Attribute &Program::getInputResource(GLuint index) const
{
ASSERT(index < mState.mAttributes.size());
......@@ -1280,28 +1296,6 @@ GLint Program::getActiveUniformMaxLength() const
return static_cast<GLint>(maxLength);
}
GLint Program::getActiveUniformi(GLuint index, GLenum pname) const
{
ASSERT(static_cast<size_t>(index) < mState.mUniforms.size());
const LinkedUniform &uniform = mState.mUniforms[index];
switch (pname)
{
case GL_UNIFORM_TYPE: return static_cast<GLint>(uniform.type);
case GL_UNIFORM_SIZE: return static_cast<GLint>(uniform.elementCount());
case GL_UNIFORM_NAME_LENGTH: return static_cast<GLint>(uniform.name.size() + 1 + (uniform.isArray() ? 3 : 0));
case GL_UNIFORM_BLOCK_INDEX:
return uniform.bufferIndex;
case GL_UNIFORM_OFFSET: return uniform.blockInfo.offset;
case GL_UNIFORM_ARRAY_STRIDE: return uniform.blockInfo.arrayStride;
case GL_UNIFORM_MATRIX_STRIDE: return uniform.blockInfo.matrixStride;
case GL_UNIFORM_IS_ROW_MAJOR: return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);
default:
UNREACHABLE();
break;
}
return 0;
}
bool Program::isValidUniformLocation(GLint location) const
{
ASSERT(angle::IsValueInRangeForNumericType<GLint>(mState.mUniformLocations.size()));
......@@ -2777,8 +2771,15 @@ void Program::setUniformValuesFromBindingQualifiers()
void Program::gatherAtomicCounterBuffers()
{
// TODO(jie.a.chen@intel.com): Get the actual OFFSET and ARRAY_STRIDE from the backend for each
// counter.
for (unsigned int index : mState.mAtomicCounterUniformRange)
{
auto &uniform = mState.mUniforms[index];
uniform.blockInfo.offset = uniform.offset;
uniform.blockInfo.arrayStride = (uniform.isArray() ? 4 : 0);
uniform.blockInfo.matrixStride = 0;
uniform.blockInfo.isRowMajorMatrix = false;
}
// TODO(jie.a.chen@intel.com): Get the actual BUFFER_DATA_SIZE from backend for each buffer.
}
......@@ -2977,27 +2978,7 @@ void Program::defineInterfaceBlock(const sh::InterfaceBlock &interfaceBlock, GLe
InterfaceBlock block(interfaceBlock.name, interfaceBlock.mappedName, true, arrayElement,
blockBinding + arrayElement);
block.memberIndexes = blockIndexes;
switch (shaderType)
{
case GL_VERTEX_SHADER:
{
block.vertexStaticUse = interfaceBlock.staticUse;
break;
}
case GL_FRAGMENT_SHADER:
{
block.fragmentStaticUse = interfaceBlock.staticUse;
break;
}
case GL_COMPUTE_SHADER:
{
block.computeStaticUse = interfaceBlock.staticUse;
break;
}
default:
UNREACHABLE();
}
MarkResourceStaticUse(&block, shaderType, interfaceBlock.staticUse);
// Since all block elements in an array share the same active interface blocks, they
// will all be active once any block member is used. So, since interfaceBlock.name[0]
......@@ -3030,28 +3011,7 @@ void Program::defineInterfaceBlock(const sh::InterfaceBlock &interfaceBlock, GLe
InterfaceBlock block(interfaceBlock.name, interfaceBlock.mappedName, false, 0,
blockBinding);
block.memberIndexes = blockIndexes;
switch (shaderType)
{
case GL_VERTEX_SHADER:
{
block.vertexStaticUse = interfaceBlock.staticUse;
break;
}
case GL_FRAGMENT_SHADER:
{
block.fragmentStaticUse = interfaceBlock.staticUse;
break;
}
case GL_COMPUTE_SHADER:
{
block.computeStaticUse = interfaceBlock.staticUse;
break;
}
default:
UNREACHABLE();
}
MarkResourceStaticUse(&block, shaderType, interfaceBlock.staticUse);
block.dataSize = static_cast<unsigned int>(blockSize);
if (interfaceBlock.blockType == sh::BlockType::BLOCK_UNIFORM)
{
......
......@@ -443,7 +443,6 @@ class Program final : angle::NonCopyable, public LabeledObject
GLchar *name) const;
GLint getActiveUniformCount() const;
GLint getActiveUniformMaxLength() const;
GLint getActiveUniformi(GLuint index, GLenum pname) const;
bool isValidUniformLocation(GLint location) const;
const LinkedUniform &getUniformByLocation(GLint location) const;
const VariableLocation &getUniformLocation(GLint location) const;
......@@ -544,6 +543,7 @@ class Program final : angle::NonCopyable, public LabeledObject
GLuint getOutputResourceIndex(const GLchar *name) const;
void getInputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
void getOutputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
void getUniformResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
const sh::Attribute &getInputResource(GLuint index) const;
const sh::OutputVariable &getOutputResource(GLuint index) const;
......@@ -658,6 +658,13 @@ class Program final : angle::NonCopyable, public LabeledObject
GLenum nativeType,
int components) const;
template <typename T>
void getResourceName(GLuint index,
const std::vector<T> &resources,
GLsizei bufSize,
GLsizei *length,
GLchar *name) const;
ProgramState mState;
rx::ProgramImpl *mProgram;
......
......@@ -13,8 +13,38 @@
namespace gl
{
template <typename T>
void MarkResourceStaticUse(T *resource, GLenum shaderType, bool used)
{
switch (shaderType)
{
case GL_VERTEX_SHADER:
resource->vertexStaticUse = used;
break;
case GL_FRAGMENT_SHADER:
resource->fragmentStaticUse = used;
break;
case GL_COMPUTE_SHADER:
resource->computeStaticUse = used;
break;
default:
UNREACHABLE();
}
}
template void MarkResourceStaticUse(LinkedUniform *resource, GLenum shaderType, bool used);
template void MarkResourceStaticUse(InterfaceBlock *resource, GLenum shaderType, bool used);
LinkedUniform::LinkedUniform()
: typeInfo(nullptr), bufferIndex(-1), blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo())
: typeInfo(nullptr),
bufferIndex(-1),
blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo()),
vertexStaticUse(false),
fragmentStaticUse(false),
computeStaticUse(false)
{
}
......@@ -27,7 +57,12 @@ LinkedUniform::LinkedUniform(GLenum typeIn,
const int locationIn,
const int bufferIndexIn,
const sh::BlockMemberInfo &blockInfoIn)
: typeInfo(&GetUniformTypeInfo(typeIn)), bufferIndex(bufferIndexIn), blockInfo(blockInfoIn)
: typeInfo(&GetUniformTypeInfo(typeIn)),
bufferIndex(bufferIndexIn),
blockInfo(blockInfoIn),
vertexStaticUse(false),
fragmentStaticUse(false),
computeStaticUse(false)
{
type = typeIn;
precision = precisionIn;
......@@ -42,7 +77,10 @@ LinkedUniform::LinkedUniform(const sh::Uniform &uniform)
: sh::Uniform(uniform),
typeInfo(&GetUniformTypeInfo(type)),
bufferIndex(-1),
blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo())
blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo()),
vertexStaticUse(false),
fragmentStaticUse(false),
computeStaticUse(false)
{
}
......@@ -50,7 +88,11 @@ LinkedUniform::LinkedUniform(const LinkedUniform &uniform)
: sh::Uniform(uniform),
typeInfo(uniform.typeInfo),
bufferIndex(uniform.bufferIndex),
blockInfo(uniform.blockInfo)
blockInfo(uniform.blockInfo),
vertexStaticUse(uniform.vertexStaticUse),
fragmentStaticUse(uniform.fragmentStaticUse),
computeStaticUse(uniform.computeStaticUse)
{
}
......@@ -60,6 +102,9 @@ LinkedUniform &LinkedUniform::operator=(const LinkedUniform &uniform)
typeInfo = uniform.typeInfo;
bufferIndex = uniform.bufferIndex;
blockInfo = uniform.blockInfo;
vertexStaticUse = uniform.vertexStaticUse;
fragmentStaticUse = uniform.fragmentStaticUse;
computeStaticUse = uniform.computeStaticUse;
return *this;
}
......@@ -112,10 +157,6 @@ ShaderVariableBuffer::ShaderVariableBuffer()
{
}
ShaderVariableBuffer::~ShaderVariableBuffer()
{
}
InterfaceBlock::InterfaceBlock() : isArray(false), arrayElement(0)
{
}
......
......@@ -20,6 +20,9 @@ namespace gl
{
struct UniformTypeInfo;
template <typename T>
void MarkResourceStaticUse(T *resource, GLenum shaderType, bool used);
// Helper struct representing a single shader uniform
struct LinkedUniform : public sh::Uniform
{
......@@ -51,6 +54,10 @@ struct LinkedUniform : public sh::Uniform
// Identifies the containing buffer backed resource -- interface block or atomic counter buffer.
int bufferIndex;
sh::BlockMemberInfo blockInfo;
bool vertexStaticUse;
bool fragmentStaticUse;
bool computeStaticUse;
};
// Parent struct for atomic counter, uniform block, and shader storage block buffer, which all
......@@ -58,9 +65,7 @@ struct LinkedUniform : public sh::Uniform
struct ShaderVariableBuffer
{
ShaderVariableBuffer();
virtual ~ShaderVariableBuffer();
ShaderVariableBuffer(const ShaderVariableBuffer &other) = default;
ShaderVariableBuffer &operator=(const ShaderVariableBuffer &other) = default;
virtual ~ShaderVariableBuffer(){};
int numActiveVariables() const { return static_cast<int>(memberIndexes.size()); }
int binding;
......@@ -83,8 +88,6 @@ struct InterfaceBlock : public ShaderVariableBuffer
bool isArrayIn,
unsigned int arrayElementIn,
int bindingIn);
InterfaceBlock(const InterfaceBlock &other) = default;
InterfaceBlock &operator=(const InterfaceBlock &other) = default;
std::string nameWithArrayIndex() const;
std::string mappedNameWithArrayIndex() const;
......
......@@ -186,7 +186,7 @@ bool UniformLinker::indexUniforms(InfoLog &infoLog,
{
const LinkedUniform &uniform = mUniforms[uniformIndex];
if (uniform.isBuiltIn())
if (uniform.isBuiltIn() || IsAtomicCounterType(uniform.type))
{
continue;
}
......@@ -349,8 +349,8 @@ bool UniformLinker::flattenUniformsAndCheckCapsForShader(
ShaderUniformCount shaderUniformCount;
for (const sh::Uniform &uniform : shader->getUniforms(context))
{
shaderUniformCount +=
flattenUniform(uniform, &samplerUniforms, &imageUniforms, &atomicCounterUniforms);
shaderUniformCount += flattenUniform(uniform, &samplerUniforms, &imageUniforms,
&atomicCounterUniforms, shader->getType());
}
if (shaderUniformCount.vectorCount > maxUniformComponents)
......@@ -448,12 +448,14 @@ UniformLinker::ShaderUniformCount UniformLinker::flattenUniform(
const sh::Uniform &uniform,
std::vector<LinkedUniform> *samplerUniforms,
std::vector<LinkedUniform> *imageUniforms,
std::vector<LinkedUniform> *atomicCounterUniforms)
std::vector<LinkedUniform> *atomicCounterUniforms,
GLenum shaderType)
{
int location = uniform.location;
ShaderUniformCount shaderUniformCount = flattenUniformImpl(
uniform, uniform.name, uniform.mappedName, samplerUniforms, imageUniforms,
atomicCounterUniforms, uniform.staticUse, uniform.binding, uniform.offset, &location);
ShaderUniformCount shaderUniformCount =
flattenUniformImpl(uniform, uniform.name, uniform.mappedName, samplerUniforms,
imageUniforms, atomicCounterUniforms, shaderType, uniform.staticUse,
uniform.binding, uniform.offset, &location);
if (uniform.staticUse)
{
return shaderUniformCount;
......@@ -468,6 +470,7 @@ UniformLinker::ShaderUniformCount UniformLinker::flattenUniformImpl(
std::vector<LinkedUniform> *samplerUniforms,
std::vector<LinkedUniform> *imageUniforms,
std::vector<LinkedUniform> *atomicCounterUniforms,
GLenum shaderType,
bool markStaticUse,
int binding,
int offset,
......@@ -491,7 +494,7 @@ UniformLinker::ShaderUniformCount UniformLinker::flattenUniformImpl(
shaderUniformCount += flattenUniformImpl(
field, fieldFullName, fieldFullMappedName, samplerUniforms, imageUniforms,
atomicCounterUniforms, markStaticUse, -1, -1, location);
atomicCounterUniforms, shaderType, markStaticUse, -1, -1, location);
}
}
......@@ -533,15 +536,20 @@ UniformLinker::ShaderUniformCount UniformLinker::flattenUniformImpl(
if (markStaticUse)
{
existingUniform->staticUse = true;
MarkResourceStaticUse(existingUniform, shaderType, true);
}
}
else
{
LinkedUniform linkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize,
binding, -1, *location, -1,
binding, offset, *location, -1,
sh::BlockMemberInfo::getDefaultBlockInfo());
linkedUniform.mappedName = fullMappedName;
linkedUniform.staticUse = markStaticUse;
if (markStaticUse)
{
MarkResourceStaticUse(&linkedUniform, shaderType, true);
}
uniformList->push_back(linkedUniform);
}
......
......@@ -81,7 +81,8 @@ class UniformLinker
ShaderUniformCount flattenUniform(const sh::Uniform &uniform,
std::vector<LinkedUniform> *samplerUniforms,
std::vector<LinkedUniform> *imageUniforms,
std::vector<LinkedUniform> *atomicCounterUniforms);
std::vector<LinkedUniform> *atomicCounterUniforms,
GLenum shaderType);
// markStaticUse is given as a separate parameter because it is tracked here at struct
// granularity.
......@@ -91,6 +92,7 @@ class UniformLinker
std::vector<LinkedUniform> *samplerUniforms,
std::vector<LinkedUniform> *imageUniforms,
std::vector<LinkedUniform> *atomicCounterUniforms,
GLenum shaderType,
bool markStaticUse,
int binding,
int offset,
......
......@@ -477,10 +477,12 @@ GLint GetInputResourceProperty(const Program *program, GLuint index, GLenum prop
{
case GL_TYPE:
case GL_ARRAY_SIZE:
case GL_LOCATION:
case GL_NAME_LENGTH:
return GetLocationVariableProperty(attribute, prop);
case GL_LOCATION:
return program->getAttributeLocation(attribute.name);
case GL_REFERENCED_BY_VERTEX_SHADER:
return 1;
......@@ -501,10 +503,12 @@ GLint GetOutputResourceProperty(const Program *program, GLuint index, const GLen
{
case GL_TYPE:
case GL_ARRAY_SIZE:
case GL_LOCATION:
case GL_NAME_LENGTH:
return GetLocationVariableProperty(outputVariable, prop);
case GL_LOCATION:
return program->getFragDataLocation(outputVariable.name);
case GL_REFERENCED_BY_VERTEX_SHADER:
return 0;
......@@ -619,6 +623,32 @@ GLint QueryProgramInterfaceMaxNumActiveVariables(const Program *program, GLenum
}
}
GLenum GetUniformPropertyEnum(GLenum prop)
{
switch (prop)
{
case GL_UNIFORM_TYPE:
return GL_TYPE;
case GL_UNIFORM_SIZE:
return GL_ARRAY_SIZE;
case GL_UNIFORM_NAME_LENGTH:
return GL_NAME_LENGTH;
case GL_UNIFORM_BLOCK_INDEX:
return GL_BLOCK_INDEX;
case GL_UNIFORM_OFFSET:
return GL_OFFSET;
case GL_UNIFORM_ARRAY_STRIDE:
return GL_ARRAY_STRIDE;
case GL_UNIFORM_MATRIX_STRIDE:
return GL_MATRIX_STRIDE;
case GL_UNIFORM_IS_ROW_MAJOR:
return GL_IS_ROW_MAJOR;
default:
return prop;
}
}
} // anonymous namespace
void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer,
......@@ -1214,6 +1244,53 @@ void SetProgramParameteri(Program *program, GLenum pname, GLint value)
}
}
GLint GetUniformResourceProperty(const Program *program, GLuint index, const GLenum prop)
{
const auto &uniform = program->getUniformByIndex(index);
GLenum resourceProp = GetUniformPropertyEnum(prop);
switch (resourceProp)
{
case GL_TYPE:
case GL_ARRAY_SIZE:
case GL_NAME_LENGTH:
return GetLocationVariableProperty(uniform, resourceProp);
case GL_LOCATION:
return program->getUniformLocation(uniform.name);
case GL_BLOCK_INDEX:
return (uniform.isAtomicCounter() ? -1 : uniform.bufferIndex);
case GL_OFFSET:
return uniform.blockInfo.offset;
case GL_ARRAY_STRIDE:
return uniform.blockInfo.arrayStride;
case GL_MATRIX_STRIDE:
return uniform.blockInfo.matrixStride;
case GL_IS_ROW_MAJOR:
return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);
case GL_REFERENCED_BY_VERTEX_SHADER:
return uniform.vertexStaticUse;
case GL_REFERENCED_BY_FRAGMENT_SHADER:
return uniform.fragmentStaticUse;
case GL_REFERENCED_BY_COMPUTE_SHADER:
return uniform.computeStaticUse;
case GL_ATOMIC_COUNTER_BUFFER_INDEX:
return (uniform.isAtomicCounter() ? uniform.bufferIndex : -1);
default:
UNREACHABLE();
return 0;
}
}
GLuint QueryProgramResourceIndex(const Program *program,
GLenum programInterface,
const GLchar *name)
......@@ -1226,8 +1303,10 @@ GLuint QueryProgramResourceIndex(const Program *program,
case GL_PROGRAM_OUTPUT:
return program->getOutputResourceIndex(name);
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_UNIFORM:
return program->getState().getUniformIndexFromName(name);
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_UNIFORM_BLOCK:
case GL_TRANSFORM_FEEDBACK_VARYING:
case GL_BUFFER_VARIABLE:
......@@ -1258,8 +1337,11 @@ void QueryProgramResourceName(const Program *program,
program->getOutputResourceName(index, bufSize, length, name);
break;
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_UNIFORM:
program->getUniformResourceName(index, bufSize, length, name);
break;
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_UNIFORM_BLOCK:
case GL_TRANSFORM_FEEDBACK_VARYING:
case GL_BUFFER_VARIABLE:
......@@ -1284,8 +1366,10 @@ GLint QueryProgramResourceLocation(const Program *program,
case GL_PROGRAM_OUTPUT:
return program->getFragDataLocation(name);
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_UNIFORM:
return program->getState().getUniformLocation(name);
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_UNIFORM_BLOCK:
case GL_TRANSFORM_FEEDBACK_VARYING:
case GL_BUFFER_VARIABLE:
......@@ -1335,8 +1419,11 @@ void QueryProgramResourceiv(const Program *program,
params[i] = GetOutputResourceProperty(program, index, props[i]);
break;
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_UNIFORM:
params[i] = GetUniformResourceProperty(program, index, props[i]);
break;
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_UNIFORM_BLOCK:
case GL_TRANSFORM_FEEDBACK_VARYING:
case GL_BUFFER_VARIABLE:
......
......@@ -113,6 +113,8 @@ void SetFramebufferParameteri(Framebuffer *framebuffer, GLenum pname, GLint para
void SetProgramParameteri(Program *program, GLenum pname, GLint value);
GLint GetUniformResourceProperty(const Program *program, GLuint index, const GLenum prop);
GLuint QueryProgramResourceIndex(const Program *program,
GLenum programInterface,
const GLchar *name);
......
......@@ -257,8 +257,10 @@ bool ValidateProgramResourceIndex(const Program *programObject,
case GL_PROGRAM_OUTPUT:
return (index < static_cast<GLuint>(programObject->getOutputResourceCount()));
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_UNIFORM:
return (index < static_cast<GLuint>(programObject->getActiveUniformCount()));
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_UNIFORM_BLOCK:
case GL_TRANSFORM_FEEDBACK_VARYING:
case GL_BUFFER_VARIABLE:
......
......@@ -231,13 +231,13 @@ TEST_P(ProgramInterfaceTestES31, GetResource)
&length, params.data());
EXPECT_GL_NO_ERROR();
EXPECT_EQ(kPropCount, length);
EXPECT_EQ(GL_FLOAT_VEC4, params[0]);
EXPECT_EQ(1, params[1]);
EXPECT_EQ(3, params[2]);
EXPECT_EQ(9, params[3]);
EXPECT_EQ(1, params[4]);
EXPECT_EQ(0, params[5]);
EXPECT_EQ(0, params[6]);
EXPECT_EQ(GL_FLOAT_VEC4, params[0]); // type
EXPECT_EQ(1, params[1]); // array_size
EXPECT_EQ(3, params[2]); // location
EXPECT_EQ(9, params[3]); // name_length
EXPECT_EQ(1, params[4]); // referenced_by_vertex_shader
EXPECT_EQ(0, params[5]); // referenced_by_fragment_shader
EXPECT_EQ(0, params[6]); // referenced_by_compute_shader
index = glGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "oColor[0]");
EXPECT_GL_NO_ERROR();
......@@ -246,12 +246,12 @@ TEST_P(ProgramInterfaceTestES31, GetResource)
kPropCount - 1, &length, params.data());
EXPECT_GL_NO_ERROR();
EXPECT_EQ(kPropCount - 1, length);
EXPECT_EQ(GL_FLOAT_VEC4, params[0]);
EXPECT_EQ(4, params[1]);
EXPECT_EQ(2, params[2]);
EXPECT_EQ(10, params[3]);
EXPECT_EQ(0, params[4]);
EXPECT_EQ(1, params[5]);
EXPECT_EQ(GL_FLOAT_VEC4, params[0]); // type
EXPECT_EQ(4, params[1]); // array_size
EXPECT_EQ(2, params[2]); // location
EXPECT_EQ(10, params[3]); // name_length
EXPECT_EQ(0, params[4]); // referenced_by_vertex_shader
EXPECT_EQ(1, params[5]); // referenced_by_fragment_shader
GLenum invalidOutputProp = GL_OFFSET;
glGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, index, 1, &invalidOutputProp, 1, &length,
......@@ -334,5 +334,103 @@ TEST_P(ProgramInterfaceTestES31, GetProgramInterface)
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
ANGLE_INSTANTIATE_TEST(ProgramInterfaceTestES31, ES31_OPENGL(), ES31_D3D11(), ES31_OPENGLES());
// Tests the resource property query for uniform can be done correctly.
TEST_P(ProgramInterfaceTestES31, GetUniformProperties)
{
const std::string &vertexShaderSource =
"#version 310 es\n"
"precision highp float;\n"
"uniform layout(location=12) vec4 color;\n"
"layout(binding = 2, offset = 4) uniform atomic_uint foo;\n"
"void main()\n"
"{\n"
" atomicCounterIncrement(foo);\n"
"}";
const std::string &fragmentShaderSource =
"#version 310 es\n"
"precision highp float;\n"
"uniform vec4 color;\n"
"out vec4 oColor;\n"
"void main()\n"
"{\n"
" oColor = color;\n"
"}";
ANGLE_GL_PROGRAM(program, vertexShaderSource, fragmentShaderSource);
GLuint index = glGetProgramResourceIndex(program, GL_UNIFORM, "color");
EXPECT_GL_NO_ERROR();
EXPECT_NE(GL_INVALID_INDEX, index);
GLchar name[64];
GLsizei length;
glGetProgramResourceName(program, GL_UNIFORM, index, sizeof(name), &length, name);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(5, length);
EXPECT_EQ("color", std::string(name));
GLint location = glGetProgramResourceLocation(program, GL_UNIFORM, "color");
EXPECT_GL_NO_ERROR();
EXPECT_EQ(12, location);
constexpr int kPropCount = 13;
std::array<GLint, kPropCount> params;
std::array<GLenum, kPropCount> props = {
{GL_TYPE, GL_ARRAY_SIZE, GL_LOCATION, GL_NAME_LENGTH, GL_REFERENCED_BY_VERTEX_SHADER,
GL_REFERENCED_BY_FRAGMENT_SHADER, GL_REFERENCED_BY_COMPUTE_SHADER, GL_ARRAY_STRIDE,
GL_BLOCK_INDEX, GL_IS_ROW_MAJOR, GL_MATRIX_STRIDE, GL_OFFSET,
GL_ATOMIC_COUNTER_BUFFER_INDEX}};
glGetProgramResourceiv(program, GL_UNIFORM, index, kPropCount, props.data(), kPropCount,
&length, params.data());
EXPECT_GL_NO_ERROR();
EXPECT_EQ(kPropCount, length);
EXPECT_EQ(GL_FLOAT_VEC4, params[0]); // type
EXPECT_EQ(1, params[1]); // array_size
EXPECT_EQ(12, params[2]); // location
EXPECT_EQ(6, params[3]); // name_length
EXPECT_EQ(0, params[4]); // referenced_by_vertex_shader
EXPECT_EQ(1, params[5]); // referenced_by_fragment_shader
EXPECT_EQ(0, params[6]); // referenced_by_compute_shader
EXPECT_EQ(-1, params[7]); // array_stride
EXPECT_EQ(-1, params[8]); // block_index
EXPECT_EQ(0, params[9]); // is_row_major
EXPECT_EQ(-1, params[10]); // matrix_stride
EXPECT_EQ(-1, params[11]); // offset
EXPECT_EQ(-1, params[12]); // atomic_counter_buffer_index
index = glGetProgramResourceIndex(program, GL_UNIFORM, "foo");
EXPECT_GL_NO_ERROR();
EXPECT_NE(GL_INVALID_INDEX, index);
glGetProgramResourceName(program, GL_UNIFORM, index, sizeof(name), &length, name);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(3, length);
EXPECT_EQ("foo", std::string(name));
location = glGetProgramResourceLocation(program, GL_UNIFORM, "foo");
EXPECT_GL_NO_ERROR();
EXPECT_EQ(-1, location);
glGetProgramResourceiv(program, GL_UNIFORM, index, kPropCount, props.data(), kPropCount,
&length, params.data());
EXPECT_GL_NO_ERROR();
EXPECT_EQ(kPropCount, length);
EXPECT_EQ(GL_UNSIGNED_INT_ATOMIC_COUNTER, params[0]); // type
EXPECT_EQ(1, params[1]); // array_size
EXPECT_EQ(-1, params[2]); // location
EXPECT_EQ(4, params[3]); // name_length
EXPECT_EQ(1, params[4]); // referenced_by_vertex_shader
EXPECT_EQ(0, params[5]); // referenced_by_fragment_shader
EXPECT_EQ(0, params[6]); // referenced_by_compute_shader
EXPECT_EQ(0, params[7]); // array_stride
EXPECT_EQ(-1, params[8]); // block_index
EXPECT_EQ(0, params[9]); // is_row_major
EXPECT_EQ(0, params[10]); // matrix_stride
EXPECT_EQ(4, params[11]); // offset
EXPECT_NE(-1, params[12]); // atomic_counter_buffer_index
}
ANGLE_INSTANTIATE_TEST(ProgramInterfaceTestES31, ES31_OPENGL(), 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