Commit 3a9090fa by Jiajia Qin Committed by Commit Bot

ES31: Add BUFFER_VARIABLE and SHADER_STORAGE_BLOCK program interfaces

This patch collects the shader storage block members information. It implements getShaderStorageBlockMemberInfo and getShaderStorageBlockSize for OpenGL backend. Meanwhile, it implements BUFFER_VARIABLE and SHADER_STORAGE_BLOCK interfaces for program query. BUG=angleproject:1920 TEST=angle_end2end_tests:ProgramInterfaceTest* dEQP-GLES31.functional.layout_binding.ssbo* dEQP-GLES31.functional.compute.basic.empty dEQP-GLES31.functional.compute.basic.ssbo_rw* dEQP-GLES31.functional.compute.basic.ssbo_local_barrier* dEQP-GLES31.functional.compute.basic.copy_image_to_ssbo_small dEQP-GLES31.functional.compute.basic.copy_ssbo_multiple_groups dEQP-GLES31.functional.compute.basic.copy_ssbo_multiple_invocations dEQP-GLES31.functional.compute.basic.copy_ssbo_single_invocation dEQP-GLES31.functional.compute.basic.copy_ssbo_to_image_small dEQP-GLES31.functional.compute.basic.shared_var* dEQP-GLES31.functional.compute.basic.ubo_to_ssbo* dEQP-GLES31.functional.compute.basic.write_multiple_arr* dEQP-GLES31.functional.compute.shared_var.basic_type.* dEQP-GLES31.functional.compute.shared_var.work_group_size.* dEQP-GLES31.functional.atomic_counter.* Change-Id: Ie8b81fde5a2e919aab77adb3d137c9ff2f193409 Reviewed-on: https://chromium-review.googlesource.com/712235Reviewed-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 225bfa95
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
// Version number for shader translation API. // Version number for shader translation API.
// It is incremented every time the API changes. // It is incremented every time the API changes.
#define ANGLE_SH_VERSION 186 #define ANGLE_SH_VERSION 187
enum ShShaderSpec enum ShShaderSpec
{ {
......
...@@ -67,8 +67,8 @@ struct ShaderVariable ...@@ -67,8 +67,8 @@ struct ShaderVariable
ShaderVariable(const ShaderVariable &other); ShaderVariable(const ShaderVariable &other);
ShaderVariable &operator=(const ShaderVariable &other); ShaderVariable &operator=(const ShaderVariable &other);
bool isArray() const { return arraySize > 0; } bool isArray() const { return arraySize > 0 || isUnsizedArray; }
unsigned int elementCount() const { return std::max(1u, arraySize); } unsigned int elementCount() const { return isUnsizedArray ? 0 : std::max(1u, arraySize); }
bool isStruct() const { return !fields.empty(); } bool isStruct() const { return !fields.empty(); }
// Array size 0 means not an array when passed to or returned from these functions. // Array size 0 means not an array when passed to or returned from these functions.
...@@ -100,6 +100,7 @@ struct ShaderVariable ...@@ -100,6 +100,7 @@ struct ShaderVariable
bool staticUse; bool staticUse;
std::vector<ShaderVariable> fields; std::vector<ShaderVariable> fields;
std::string structName; std::string structName;
bool isUnsizedArray;
protected: protected:
bool isSameVariableAtLinkTime(const ShaderVariable &other, bool isSameVariableAtLinkTime(const ShaderVariable &other,
......
...@@ -86,6 +86,19 @@ void MarkStaticallyUsed(ShaderVariable *variable) ...@@ -86,6 +86,19 @@ void MarkStaticallyUsed(ShaderVariable *variable)
} }
} }
ShaderVariable *FindVariableInInterfaceBlock(const TString &name,
const TInterfaceBlock *interfaceBlock,
std::vector<InterfaceBlock> *infoList)
{
ASSERT(interfaceBlock);
InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), infoList);
ASSERT(namedBlock);
// Set static use on the parent interface block here
namedBlock->staticUse = true;
return FindVariable(name, &namedBlock->fields);
}
// Traverses the intermediate tree to collect all attributes, uniforms, varyings, fragment outputs, // Traverses the intermediate tree to collect all attributes, uniforms, varyings, fragment outputs,
// and interface blocks. // and interface blocks.
class CollectVariablesTraverser : public TIntermTraverser class CollectVariablesTraverser : public TIntermTraverser
...@@ -403,13 +416,7 @@ void CollectVariablesTraverser::visitSymbol(TIntermSymbol *symbol) ...@@ -403,13 +416,7 @@ void CollectVariablesTraverser::visitSymbol(TIntermSymbol *symbol)
const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock(); const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock();
if (interfaceBlock) if (interfaceBlock)
{ {
InterfaceBlock *namedBlock = var = FindVariableInInterfaceBlock(symbolName, interfaceBlock, mUniformBlocks);
FindVariable(interfaceBlock->name(), mUniformBlocks);
ASSERT(namedBlock);
var = FindVariable(symbolName, &namedBlock->fields);
// Set static use on the parent interface block here
namedBlock->staticUse = true;
} }
else else
{ {
...@@ -420,6 +427,13 @@ void CollectVariablesTraverser::visitSymbol(TIntermSymbol *symbol) ...@@ -420,6 +427,13 @@ void CollectVariablesTraverser::visitSymbol(TIntermSymbol *symbol)
ASSERT(symbolName.compare(0, 3, "gl_") != 0 || var); ASSERT(symbolName.compare(0, 3, "gl_") != 0 || var);
} }
break; break;
case EvqBuffer:
{
const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock();
var =
FindVariableInInterfaceBlock(symbolName, interfaceBlock, mShaderStorageBlocks);
}
break;
case EvqFragCoord: case EvqFragCoord:
recordBuiltInVaryingUsed("gl_FragCoord", &mFragCoordAdded, mInputVaryings); recordBuiltInVaryingUsed("gl_FragCoord", &mFragCoordAdded, mInputVaryings);
return; return;
...@@ -663,6 +677,7 @@ void CollectVariablesTraverser::recordInterfaceBlock(const TType &interfaceBlock ...@@ -663,6 +677,7 @@ void CollectVariablesTraverser::recordInterfaceBlock(const TType &interfaceBlock
setCommonVariableProperties(fieldType, TName(field->name()), &fieldVariable); setCommonVariableProperties(fieldType, TName(field->name()), &fieldVariable);
fieldVariable.isRowMajorLayout = fieldVariable.isRowMajorLayout =
(fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor); (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
fieldVariable.isUnsizedArray = fieldType.isUnsizedArray();
interfaceBlock->fields.push_back(fieldVariable); interfaceBlock->fields.push_back(fieldVariable);
} }
} }
......
...@@ -30,17 +30,18 @@ bool InterpolationTypesMatch(InterpolationType a, InterpolationType b) ...@@ -30,17 +30,18 @@ bool InterpolationTypesMatch(InterpolationType a, InterpolationType b)
return (GetNonAuxiliaryInterpolationType(a) == GetNonAuxiliaryInterpolationType(b)); return (GetNonAuxiliaryInterpolationType(a) == GetNonAuxiliaryInterpolationType(b));
} }
ShaderVariable::ShaderVariable() : type(0), precision(0), arraySize(0), staticUse(false) ShaderVariable::ShaderVariable()
: type(0), precision(0), arraySize(0), staticUse(false), isUnsizedArray(false)
{ {
} }
ShaderVariable::ShaderVariable(GLenum typeIn) ShaderVariable::ShaderVariable(GLenum typeIn)
: type(typeIn), precision(0), arraySize(0), staticUse(false) : type(typeIn), precision(0), arraySize(0), staticUse(false), isUnsizedArray(false)
{ {
} }
ShaderVariable::ShaderVariable(GLenum typeIn, unsigned int arraySizeIn) ShaderVariable::ShaderVariable(GLenum typeIn, unsigned int arraySizeIn)
: type(typeIn), precision(0), arraySize(arraySizeIn), staticUse(false) : type(typeIn), precision(0), arraySize(arraySizeIn), staticUse(false), isUnsizedArray(false)
{ {
ASSERT(arraySizeIn != 0); ASSERT(arraySizeIn != 0);
} }
...@@ -57,7 +58,8 @@ ShaderVariable::ShaderVariable(const ShaderVariable &other) ...@@ -57,7 +58,8 @@ ShaderVariable::ShaderVariable(const ShaderVariable &other)
arraySize(other.arraySize), arraySize(other.arraySize),
staticUse(other.staticUse), staticUse(other.staticUse),
fields(other.fields), fields(other.fields),
structName(other.structName) structName(other.structName),
isUnsizedArray(other.isUnsizedArray)
{ {
} }
...@@ -71,6 +73,7 @@ ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other) ...@@ -71,6 +73,7 @@ ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other)
staticUse = other.staticUse; staticUse = other.staticUse;
fields = other.fields; fields = other.fields;
structName = other.structName; structName = other.structName;
isUnsizedArray = other.isUnsizedArray;
return *this; return *this;
} }
...@@ -79,7 +82,7 @@ bool ShaderVariable::operator==(const ShaderVariable &other) const ...@@ -79,7 +82,7 @@ bool ShaderVariable::operator==(const ShaderVariable &other) const
if (type != other.type || precision != other.precision || name != other.name || if (type != other.type || precision != other.precision || name != other.name ||
mappedName != other.mappedName || arraySize != other.arraySize || mappedName != other.mappedName || arraySize != other.arraySize ||
staticUse != other.staticUse || fields.size() != other.fields.size() || staticUse != other.staticUse || fields.size() != other.fields.size() ||
structName != other.structName) structName != other.structName || isUnsizedArray != other.isUnsizedArray)
{ {
return false; return false;
} }
...@@ -189,6 +192,10 @@ bool ShaderVariable::isSameVariableAtLinkTime(const ShaderVariable &other, ...@@ -189,6 +192,10 @@ bool ShaderVariable::isSameVariableAtLinkTime(const ShaderVariable &other,
} }
if (structName != other.structName) if (structName != other.structName)
return false; return false;
if (isUnsizedArray != other.isUnsizedArray)
{
return false;
}
return true; return true;
} }
......
...@@ -27,22 +27,44 @@ struct InterfaceBlock; ...@@ -27,22 +27,44 @@ struct InterfaceBlock;
struct BlockMemberInfo struct BlockMemberInfo
{ {
BlockMemberInfo() : offset(-1), arrayStride(-1), matrixStride(-1), isRowMajorMatrix(false) {} BlockMemberInfo()
: offset(-1),
arrayStride(-1),
matrixStride(-1),
isRowMajorMatrix(false),
topLevelArrayStride(-1)
{
}
BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix) BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
: offset(offset), : offset(offset),
arrayStride(arrayStride), arrayStride(arrayStride),
matrixStride(matrixStride), matrixStride(matrixStride),
isRowMajorMatrix(isRowMajorMatrix) isRowMajorMatrix(isRowMajorMatrix),
topLevelArrayStride(-1)
{
}
BlockMemberInfo(int offset,
int arrayStride,
int matrixStride,
bool isRowMajorMatrix,
int topLevelArrayStride)
: offset(offset),
arrayStride(arrayStride),
matrixStride(matrixStride),
isRowMajorMatrix(isRowMajorMatrix),
topLevelArrayStride(topLevelArrayStride)
{ {
} }
static BlockMemberInfo getDefaultBlockInfo() { return BlockMemberInfo(-1, -1, -1, false); } static BlockMemberInfo getDefaultBlockInfo() { return BlockMemberInfo(-1, -1, -1, false, -1); }
int offset; int offset;
int arrayStride; int arrayStride;
int matrixStride; int matrixStride;
bool isRowMajorMatrix; bool isRowMajorMatrix;
int topLevelArrayStride; // Only used for shader storage block members.
}; };
class BlockLayoutEncoder class BlockLayoutEncoder
......
...@@ -90,6 +90,38 @@ void LoadShaderVariableBuffer(BinaryInputStream *stream, ShaderVariableBuffer *v ...@@ -90,6 +90,38 @@ void LoadShaderVariableBuffer(BinaryInputStream *stream, ShaderVariableBuffer *v
} }
} }
void WriteBufferVariable(BinaryOutputStream *stream, const BufferVariable &var)
{
WriteShaderVar(stream, var);
stream->writeInt(var.bufferIndex);
stream->writeInt(var.blockInfo.offset);
stream->writeInt(var.blockInfo.arrayStride);
stream->writeInt(var.blockInfo.matrixStride);
stream->writeInt(var.blockInfo.isRowMajorMatrix);
stream->writeInt(var.blockInfo.topLevelArrayStride);
stream->writeInt(var.topLevelArraySize);
stream->writeInt(var.vertexStaticUse);
stream->writeInt(var.fragmentStaticUse);
stream->writeInt(var.computeStaticUse);
}
void LoadBufferVariable(BinaryInputStream *stream, BufferVariable *var)
{
LoadShaderVar(stream, var);
var->bufferIndex = stream->readInt<int>();
var->blockInfo.offset = stream->readInt<int>();
var->blockInfo.arrayStride = stream->readInt<int>();
var->blockInfo.matrixStride = stream->readInt<int>();
var->blockInfo.isRowMajorMatrix = stream->readBool();
var->blockInfo.topLevelArrayStride = stream->readInt<int>();
var->topLevelArraySize = stream->readInt<int>();
var->vertexStaticUse = stream->readBool();
var->fragmentStaticUse = stream->readBool();
var->computeStaticUse = stream->readBool();
}
void WriteInterfaceBlock(BinaryOutputStream *stream, const InterfaceBlock &block) void WriteInterfaceBlock(BinaryOutputStream *stream, const InterfaceBlock &block)
{ {
stream->writeString(block.name); stream->writeString(block.name);
...@@ -257,6 +289,15 @@ LinkResult MemoryProgramCache::Deserialize(const Context *context, ...@@ -257,6 +289,15 @@ LinkResult MemoryProgramCache::Deserialize(const Context *context,
state->mActiveUniformBlockBindings.set(uniformBlockIndex, uniformBlock.binding != 0); state->mActiveUniformBlockBindings.set(uniformBlockIndex, uniformBlock.binding != 0);
} }
unsigned int bufferVariableCount = stream.readInt<unsigned int>();
ASSERT(state->mBufferVariables.empty());
for (unsigned int index = 0; index < bufferVariableCount; ++index)
{
BufferVariable bufferVariable;
LoadBufferVariable(&stream, &bufferVariable);
state->mBufferVariables.push_back(bufferVariable);
}
unsigned int shaderStorageBlockCount = stream.readInt<unsigned int>(); unsigned int shaderStorageBlockCount = stream.readInt<unsigned int>();
ASSERT(state->mShaderStorageBlocks.empty()); ASSERT(state->mShaderStorageBlocks.empty());
for (unsigned int shaderStorageBlockIndex = 0; for (unsigned int shaderStorageBlockIndex = 0;
...@@ -438,6 +479,12 @@ void MemoryProgramCache::Serialize(const Context *context, ...@@ -438,6 +479,12 @@ void MemoryProgramCache::Serialize(const Context *context,
WriteInterfaceBlock(&stream, uniformBlock); WriteInterfaceBlock(&stream, uniformBlock);
} }
stream.writeInt(state.getBufferVariables().size());
for (const BufferVariable &bufferVariable : state.getBufferVariables())
{
WriteBufferVariable(&stream, bufferVariable);
}
stream.writeInt(state.getShaderStorageBlocks().size()); stream.writeInt(state.getShaderStorageBlocks().size());
for (const InterfaceBlock &shaderStorageBlock : state.getShaderStorageBlocks()) for (const InterfaceBlock &shaderStorageBlock : state.getShaderStorageBlocks())
{ {
......
...@@ -258,6 +258,53 @@ bool validateInterfaceBlocksCount(GLuint maxInterfaceBlocks, ...@@ -258,6 +258,53 @@ bool validateInterfaceBlocksCount(GLuint maxInterfaceBlocks,
return true; return true;
} }
GLuint GetInterfaceBlockIndex(const std::vector<InterfaceBlock> &list, const std::string &name)
{
std::vector<unsigned int> subscripts;
std::string baseName = ParseResourceName(name, &subscripts);
unsigned int numBlocks = static_cast<unsigned int>(list.size());
for (unsigned int blockIndex = 0; blockIndex < numBlocks; blockIndex++)
{
const auto &block = list[blockIndex];
if (block.name == baseName)
{
const bool arrayElementZero =
(subscripts.empty() && (!block.isArray || block.arrayElement == 0));
const bool arrayElementMatches =
(subscripts.size() == 1 && subscripts[0] == block.arrayElement);
if (arrayElementMatches || arrayElementZero)
{
return blockIndex;
}
}
}
return GL_INVALID_INDEX;
}
void GetInterfaceBlockName(const GLuint index,
const std::vector<InterfaceBlock> &list,
GLsizei bufSize,
GLsizei *length,
GLchar *name)
{
ASSERT(index < list.size());
const auto &block = list[index];
if (bufSize > 0)
{
std::string blockName = block.name;
if (block.isArray)
{
blockName += ArrayString(block.arrayElement);
}
CopyStringToBuffer(name, blockName, bufSize, length);
}
}
void InitUniformBlockLinker(const gl::Context *context, void InitUniformBlockLinker(const gl::Context *context,
const ProgramState &state, const ProgramState &state,
UniformBlockLinker *blockLinker) UniformBlockLinker *blockLinker)
...@@ -440,6 +487,11 @@ GLuint ProgramState::getUniformIndexFromName(const std::string &name) const ...@@ -440,6 +487,11 @@ GLuint ProgramState::getUniformIndexFromName(const std::string &name) const
return GetResourceIndexFromName(mUniforms, name); return GetResourceIndexFromName(mUniforms, name);
} }
GLuint ProgramState::getBufferVariableIndexFromName(const std::string &name) const
{
return GetResourceIndexFromName(mBufferVariables, name);
}
GLuint ProgramState::getUniformIndexFromLocation(GLint location) const GLuint ProgramState::getUniformIndexFromLocation(GLint location) const
{ {
ASSERT(location >= 0 && static_cast<size_t>(location) < mUniformLocations.size()); ASSERT(location >= 0 && static_cast<size_t>(location) < mUniformLocations.size());
...@@ -771,9 +823,10 @@ Error Program::link(const gl::Context *context) ...@@ -771,9 +823,10 @@ Error Program::link(const gl::Context *context)
return NoError(); return NoError();
} }
ProgramLinkedResources resources = {{0, PackMode::ANGLE_RELAXED}, ProgramLinkedResources resources = {
{&mState.mUniformBlocks, &mState.mUniforms}, {0, PackMode::ANGLE_RELAXED},
{&mState.mShaderStorageBlocks}}; {&mState.mUniformBlocks, &mState.mUniforms},
{&mState.mShaderStorageBlocks, &mState.mBufferVariables}};
InitUniformBlockLinker(context, mState, &resources.uniformBlockLinker); InitUniformBlockLinker(context, mState, &resources.uniformBlockLinker);
InitShaderStorageBlockLinker(context, mState, &resources.shaderStorageBlockLinker); InitShaderStorageBlockLinker(context, mState, &resources.shaderStorageBlockLinker);
...@@ -843,9 +896,10 @@ Error Program::link(const gl::Context *context) ...@@ -843,9 +896,10 @@ Error Program::link(const gl::Context *context)
auto packMode = data.getExtensions().webglCompatibility ? PackMode::WEBGL_STRICT auto packMode = data.getExtensions().webglCompatibility ? PackMode::WEBGL_STRICT
: PackMode::ANGLE_RELAXED; : PackMode::ANGLE_RELAXED;
ProgramLinkedResources resources = {{data.getCaps().maxVaryingVectors, packMode}, ProgramLinkedResources resources = {
{&mState.mUniformBlocks, &mState.mUniforms}, {data.getCaps().maxVaryingVectors, packMode},
{&mState.mShaderStorageBlocks}}; {&mState.mUniformBlocks, &mState.mUniforms},
{&mState.mShaderStorageBlocks, &mState.mBufferVariables}};
InitUniformBlockLinker(context, mState, &resources.uniformBlockLinker); InitUniformBlockLinker(context, mState, &resources.uniformBlockLinker);
InitShaderStorageBlockLinker(context, mState, &resources.shaderStorageBlockLinker); InitShaderStorageBlockLinker(context, mState, &resources.shaderStorageBlockLinker);
...@@ -1248,6 +1302,14 @@ void Program::getUniformResourceName(GLuint index, ...@@ -1248,6 +1302,14 @@ void Program::getUniformResourceName(GLuint index,
getResourceName(index, mState.mUniforms, bufSize, length, name); getResourceName(index, mState.mUniforms, bufSize, length, name);
} }
void Program::getBufferVariableResourceName(GLuint index,
GLsizei bufSize,
GLsizei *length,
GLchar *name) const
{
getResourceName(index, mState.mBufferVariables, bufSize, length, name);
}
const sh::Attribute &Program::getInputResource(GLuint index) const const sh::Attribute &Program::getInputResource(GLuint index) const
{ {
ASSERT(index < mState.mAttributes.size()); ASSERT(index < mState.mAttributes.size());
...@@ -1316,6 +1378,11 @@ GLint Program::getActiveUniformCount() const ...@@ -1316,6 +1378,11 @@ GLint Program::getActiveUniformCount() const
} }
} }
size_t Program::getActiveBufferVariableCount() const
{
return mLinked ? mState.mBufferVariables.size() : 0;
}
GLint Program::getActiveUniformMaxLength() const GLint Program::getActiveUniformMaxLength() const
{ {
size_t maxLength = 0; size_t maxLength = 0;
...@@ -1369,6 +1436,12 @@ const LinkedUniform &Program::getUniformByIndex(GLuint index) const ...@@ -1369,6 +1436,12 @@ const LinkedUniform &Program::getUniformByIndex(GLuint index) const
return mState.mUniforms[index]; return mState.mUniforms[index];
} }
const BufferVariable &Program::getBufferVariableByIndex(GLuint index) const
{
ASSERT(index < static_cast<size_t>(mState.mBufferVariables.size()));
return mState.mBufferVariables[index];
}
GLint Program::getUniformLocation(const std::string &name) const GLint Program::getUniformLocation(const std::string &name) const
{ {
return GetVariableLocation(mState.mUniforms, mState.mUniformLocations, name); return GetVariableLocation(mState.mUniforms, mState.mUniformLocations, name);
...@@ -1690,24 +1763,21 @@ GLuint Program::getActiveShaderStorageBlockCount() const ...@@ -1690,24 +1763,21 @@ GLuint Program::getActiveShaderStorageBlockCount() const
return static_cast<GLuint>(mState.mShaderStorageBlocks.size()); return static_cast<GLuint>(mState.mShaderStorageBlocks.size());
} }
void Program::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const void Program::getActiveUniformBlockName(const GLuint blockIndex,
GLsizei bufSize,
GLsizei *length,
GLchar *blockName) const
{ {
ASSERT( GetInterfaceBlockName(blockIndex, mState.mUniformBlocks, bufSize, length, blockName);
uniformBlockIndex < }
mState.mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount()
const InterfaceBlock &uniformBlock = mState.mUniformBlocks[uniformBlockIndex];
if (bufSize > 0) void Program::getActiveShaderStorageBlockName(const GLuint blockIndex,
{ GLsizei bufSize,
std::string string = uniformBlock.name; GLsizei *length,
GLchar *blockName) const
{
if (uniformBlock.isArray) GetInterfaceBlockName(blockIndex, mState.mShaderStorageBlocks, bufSize, length, blockName);
{
string += ArrayString(uniformBlock.arrayElement);
}
CopyStringToBuffer(uniformBlockName, string, bufSize, length);
}
} }
GLint Program::getActiveUniformBlockMaxLength() const GLint Program::getActiveUniformBlockMaxLength() const
...@@ -1733,27 +1803,12 @@ GLint Program::getActiveUniformBlockMaxLength() const ...@@ -1733,27 +1803,12 @@ GLint Program::getActiveUniformBlockMaxLength() const
GLuint Program::getUniformBlockIndex(const std::string &name) const GLuint Program::getUniformBlockIndex(const std::string &name) const
{ {
std::vector<unsigned int> subscripts; return GetInterfaceBlockIndex(mState.mUniformBlocks, name);
std::string baseName = ParseResourceName(name, &subscripts); }
unsigned int numUniformBlocks = static_cast<unsigned int>(mState.mUniformBlocks.size());
for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
{
const InterfaceBlock &uniformBlock = mState.mUniformBlocks[blockIndex];
if (uniformBlock.name == baseName)
{
const bool arrayElementZero =
(subscripts.empty() && (!uniformBlock.isArray || uniformBlock.arrayElement == 0));
const bool arrayElementMatches =
(subscripts.size() == 1 && subscripts[0] == uniformBlock.arrayElement);
if (arrayElementMatches || arrayElementZero)
{
return blockIndex;
}
}
}
return GL_INVALID_INDEX; GLuint Program::getShaderStorageBlockIndex(const std::string &name) const
{
return GetInterfaceBlockIndex(mState.mShaderStorageBlocks, name);
} }
const InterfaceBlock &Program::getUniformBlockByIndex(GLuint index) const const InterfaceBlock &Program::getUniformBlockByIndex(GLuint index) const
...@@ -1762,6 +1817,12 @@ const InterfaceBlock &Program::getUniformBlockByIndex(GLuint index) const ...@@ -1762,6 +1817,12 @@ const InterfaceBlock &Program::getUniformBlockByIndex(GLuint index) const
return mState.mUniformBlocks[index]; return mState.mUniformBlocks[index];
} }
const InterfaceBlock &Program::getShaderStorageBlockByIndex(GLuint index) const
{
ASSERT(index < static_cast<GLuint>(mState.mShaderStorageBlocks.size()));
return mState.mShaderStorageBlocks[index];
}
void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding) void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
{ {
mState.mUniformBlocks[uniformBlockIndex].binding = uniformBlockBinding; mState.mUniformBlocks[uniformBlockIndex].binding = uniformBlockBinding;
......
...@@ -277,6 +277,7 @@ class ProgramState final : angle::NonCopyable ...@@ -277,6 +277,7 @@ class ProgramState final : angle::NonCopyable
{ {
return mShaderStorageBlocks; return mShaderStorageBlocks;
} }
const std::vector<BufferVariable> &getBufferVariables() const { return mBufferVariables; }
const std::vector<SamplerBinding> &getSamplerBindings() const { return mSamplerBindings; } const std::vector<SamplerBinding> &getSamplerBindings() const { return mSamplerBindings; }
const std::vector<ImageBinding> &getImageBindings() const { return mImageBindings; } const std::vector<ImageBinding> &getImageBindings() const { return mImageBindings; }
const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; } const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; }
...@@ -300,6 +301,8 @@ class ProgramState final : angle::NonCopyable ...@@ -300,6 +301,8 @@ class ProgramState final : angle::NonCopyable
GLuint getSamplerIndexFromUniformIndex(GLuint uniformIndex) const; GLuint getSamplerIndexFromUniformIndex(GLuint uniformIndex) const;
GLuint getAttributeLocation(const std::string &name) const; GLuint getAttributeLocation(const std::string &name) const;
GLuint getBufferVariableIndexFromName(const std::string &name) const;
int getNumViews() const { return mNumViews; } int getNumViews() const { return mNumViews; }
bool usesMultiview() const { return mNumViews != -1; } bool usesMultiview() const { return mNumViews != -1; }
...@@ -341,6 +344,7 @@ class ProgramState final : angle::NonCopyable ...@@ -341,6 +344,7 @@ class ProgramState final : angle::NonCopyable
std::vector<VariableLocation> mUniformLocations; std::vector<VariableLocation> mUniformLocations;
std::vector<InterfaceBlock> mUniformBlocks; std::vector<InterfaceBlock> mUniformBlocks;
std::vector<BufferVariable> mBufferVariables;
std::vector<InterfaceBlock> mShaderStorageBlocks; std::vector<InterfaceBlock> mShaderStorageBlocks;
std::vector<AtomicCounterBuffer> mAtomicCounterBuffers; std::vector<AtomicCounterBuffer> mAtomicCounterBuffers;
RangeUI mSamplerUniformRange; RangeUI mSamplerUniformRange;
...@@ -453,6 +457,7 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -453,6 +457,7 @@ class Program final : angle::NonCopyable, public LabeledObject
GLenum *type, GLenum *type,
GLchar *name) const; GLchar *name) const;
GLint getActiveUniformCount() const; GLint getActiveUniformCount() const;
size_t getActiveBufferVariableCount() const;
GLint getActiveUniformMaxLength() const; GLint getActiveUniformMaxLength() const;
bool isValidUniformLocation(GLint location) const; bool isValidUniformLocation(GLint location) const;
const LinkedUniform &getUniformByLocation(GLint location) const; const LinkedUniform &getUniformByLocation(GLint location) const;
...@@ -460,6 +465,8 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -460,6 +465,8 @@ class Program final : angle::NonCopyable, public LabeledObject
const std::vector<VariableLocation> &getUniformLocations() const; const std::vector<VariableLocation> &getUniformLocations() const;
const LinkedUniform &getUniformByIndex(GLuint index) const; const LinkedUniform &getUniformByIndex(GLuint index) const;
const BufferVariable &getBufferVariableByIndex(GLuint index) const;
enum SetUniformResult enum SetUniformResult
{ {
SamplerChanged, SamplerChanged,
...@@ -494,19 +501,28 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -494,19 +501,28 @@ class Program final : angle::NonCopyable, public LabeledObject
void getUniformiv(const Context *context, GLint location, GLint *params) const; void getUniformiv(const Context *context, GLint location, GLint *params) const;
void getUniformuiv(const Context *context, GLint location, GLuint *params) const; void getUniformuiv(const Context *context, GLint location, GLuint *params) const;
void getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const; void getActiveUniformBlockName(const GLuint blockIndex,
GLsizei bufSize,
GLsizei *length,
GLchar *blockName) const;
void getActiveShaderStorageBlockName(const GLuint blockIndex,
GLsizei bufSize,
GLsizei *length,
GLchar *blockName) const;
GLuint getActiveUniformBlockCount() const; GLuint getActiveUniformBlockCount() const;
GLuint getActiveAtomicCounterBufferCount() const; GLuint getActiveAtomicCounterBufferCount() const;
GLuint getActiveShaderStorageBlockCount() const; GLuint getActiveShaderStorageBlockCount() const;
GLint getActiveUniformBlockMaxLength() const; GLint getActiveUniformBlockMaxLength() const;
GLuint getUniformBlockIndex(const std::string &name) const; GLuint getUniformBlockIndex(const std::string &name) const;
GLuint getShaderStorageBlockIndex(const std::string &name) const;
void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding); void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding);
GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const; GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const;
GLuint getShaderStorageBlockBinding(GLuint shaderStorageBlockIndex) const; GLuint getShaderStorageBlockBinding(GLuint shaderStorageBlockIndex) const;
const InterfaceBlock &getUniformBlockByIndex(GLuint index) const; const InterfaceBlock &getUniformBlockByIndex(GLuint index) const;
const InterfaceBlock &getShaderStorageBlockByIndex(GLuint index) const;
void setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode); 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; void getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const;
...@@ -560,6 +576,10 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -560,6 +576,10 @@ class Program final : angle::NonCopyable, public LabeledObject
void getInputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, 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 getOutputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
void getUniformResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; void getUniformResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
void getBufferVariableResourceName(GLuint index,
GLsizei bufSize,
GLsizei *length,
GLchar *name) const;
const sh::Attribute &getInputResource(GLuint index) const; const sh::Attribute &getInputResource(GLuint index) const;
const sh::OutputVariable &getOutputResource(GLuint index) const; const sh::OutputVariable &getOutputResource(GLuint index) const;
......
...@@ -660,6 +660,7 @@ void InterfaceBlockLinker::linkBlocks(const GetBlockSize &getBlockSize, ...@@ -660,6 +660,7 @@ void InterfaceBlockLinker::linkBlocks(const GetBlockSize &getBlockSize,
if (block.name == priorBlock.name) if (block.name == priorBlock.name)
{ {
priorBlock.setStaticUse(shaderType, true); priorBlock.setStaticUse(shaderType, true);
// TODO(jiajia.qin@intel.com): update the block members static use.
} }
} }
} }
...@@ -678,7 +679,9 @@ void InterfaceBlockLinker::defineBlockMembers(const GetBlockMemberInfo &getMembe ...@@ -678,7 +679,9 @@ void InterfaceBlockLinker::defineBlockMembers(const GetBlockMemberInfo &getMembe
const std::vector<VarT> &fields, const std::vector<VarT> &fields,
const std::string &prefix, const std::string &prefix,
const std::string &mappedPrefix, const std::string &mappedPrefix,
int blockIndex) const int blockIndex,
bool outsideTopLevelArray,
int topLevelArraySize) const
{ {
for (const VarT &field : fields) for (const VarT &field : fields)
{ {
...@@ -689,14 +692,26 @@ void InterfaceBlockLinker::defineBlockMembers(const GetBlockMemberInfo &getMembe ...@@ -689,14 +692,26 @@ void InterfaceBlockLinker::defineBlockMembers(const GetBlockMemberInfo &getMembe
if (field.isStruct()) if (field.isStruct())
{ {
for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++) int nextArraySize = topLevelArraySize;
unsigned int elementCount = field.elementCount();
if (outsideTopLevelArray)
{
nextArraySize = elementCount;
// In OpenGL ES 3.10 spec, session 7.3.1.1 'For an active shader storage block
// member declared as an array of an aggregate type, an entry will be generated only
// for the first array element, regardless of its type.'
elementCount = 1;
}
for (unsigned int arrayElement = 0; arrayElement < elementCount; arrayElement++)
{ {
const std::string elementName = const std::string elementName =
fullName + (field.isArray() ? ArrayString(arrayElement) : ""); fullName + (field.isArray() ? ArrayString(arrayElement) : "");
const std::string elementMappedName = const std::string elementMappedName =
fullMappedName + (field.isArray() ? ArrayString(arrayElement) : ""); fullMappedName + (field.isArray() ? ArrayString(arrayElement) : "");
defineBlockMembers(getMemberInfo, field.fields, elementName, elementMappedName, defineBlockMembers(getMemberInfo, field.fields, elementName, elementMappedName,
blockIndex); blockIndex, false, nextArraySize);
} }
} }
else else
...@@ -714,7 +729,8 @@ void InterfaceBlockLinker::defineBlockMembers(const GetBlockMemberInfo &getMembe ...@@ -714,7 +729,8 @@ void InterfaceBlockLinker::defineBlockMembers(const GetBlockMemberInfo &getMembe
fullMappedName += "[0]"; fullMappedName += "[0]";
} }
defineBlockMember(field, fullName, fullMappedName, blockIndex, memberInfo); defineBlockMember(field, fullName, fullMappedName, blockIndex, memberInfo,
topLevelArraySize);
} }
} }
} }
...@@ -728,11 +744,12 @@ void InterfaceBlockLinker::defineInterfaceBlock(const GetBlockSize &getBlockSize ...@@ -728,11 +744,12 @@ void InterfaceBlockLinker::defineInterfaceBlock(const GetBlockSize &getBlockSize
std::vector<unsigned int> blockIndexes; std::vector<unsigned int> blockIndexes;
int blockIndex = static_cast<int>(mBlocksOut->size()); int blockIndex = static_cast<int>(mBlocksOut->size());
// Track the first and last uniform index to determine the range of active uniforms in the // Track the first and last block member index to determine the range of active block members in
// block. // the block.
size_t firstBlockMemberIndex = getCurrentBlockMemberIndex(); size_t firstBlockMemberIndex = getCurrentBlockMemberIndex();
defineBlockMembers(getMemberInfo, interfaceBlock.fields, interfaceBlock.fieldPrefix(), defineBlockMembers(getMemberInfo, interfaceBlock.fields, interfaceBlock.fieldPrefix(),
interfaceBlock.fieldMappedPrefix(), blockIndex); interfaceBlock.fieldMappedPrefix(), blockIndex,
interfaceBlock.blockType == sh::BlockType::BLOCK_BUFFER, 1);
size_t lastBlockMemberIndex = getCurrentBlockMemberIndex(); size_t lastBlockMemberIndex = getCurrentBlockMemberIndex();
for (size_t blockMemberIndex = firstBlockMemberIndex; blockMemberIndex < lastBlockMemberIndex; for (size_t blockMemberIndex = firstBlockMemberIndex; blockMemberIndex < lastBlockMemberIndex;
...@@ -748,23 +765,18 @@ void InterfaceBlockLinker::defineInterfaceBlock(const GetBlockSize &getBlockSize ...@@ -748,23 +765,18 @@ void InterfaceBlockLinker::defineInterfaceBlock(const GetBlockSize &getBlockSize
for (unsigned int arrayElement = 0; arrayElement < interfaceBlock.elementCount(); for (unsigned int arrayElement = 0; arrayElement < interfaceBlock.elementCount();
++arrayElement) ++arrayElement)
{ {
// We don't currently have the getBlockSize implemented for SSBOs. std::string blockArrayName = interfaceBlock.name;
// TODO(jiajia.qin@intel.com): Remove the if when we have getBlockSize for SSBOs. std::string blockMappedArrayName = interfaceBlock.mappedName;
if (interfaceBlock.blockType == sh::BlockType::BLOCK_UNIFORM) if (interfaceBlock.isArray())
{ {
std::string blockArrayName = interfaceBlock.name; blockArrayName += ArrayString(arrayElement);
std::string blockMappedArrayName = interfaceBlock.mappedName; blockMappedArrayName += ArrayString(arrayElement);
if (interfaceBlock.isArray()) }
{
blockArrayName += ArrayString(arrayElement);
blockMappedArrayName += ArrayString(arrayElement);
}
// Don't define this block at all if it's not active in the implementation. // Don't define this block at all if it's not active in the implementation.
if (!getBlockSize(blockArrayName, blockMappedArrayName, &blockSize)) if (!getBlockSize(blockArrayName, blockMappedArrayName, &blockSize))
{ {
continue; continue;
}
} }
InterfaceBlock block(interfaceBlock.name, interfaceBlock.mappedName, InterfaceBlock block(interfaceBlock.name, interfaceBlock.mappedName,
...@@ -795,11 +807,13 @@ void UniformBlockLinker::defineBlockMember(const sh::ShaderVariable &field, ...@@ -795,11 +807,13 @@ void UniformBlockLinker::defineBlockMember(const sh::ShaderVariable &field,
const std::string &fullName, const std::string &fullName,
const std::string &fullMappedName, const std::string &fullMappedName,
int blockIndex, int blockIndex,
const sh::BlockMemberInfo &memberInfo) const const sh::BlockMemberInfo &memberInfo,
int /* topLevelArraySize */) const
{ {
LinkedUniform newUniform(field.type, field.precision, fullName, field.arraySize, -1, -1, -1, LinkedUniform newUniform(field.type, field.precision, fullName, field.arraySize, -1, -1, -1,
blockIndex, memberInfo); blockIndex, memberInfo);
newUniform.mappedName = fullMappedName; newUniform.mappedName = fullMappedName;
// TODO(jiajia.qin@intel.com): update the block memeber static use.
// Since block uniforms have no location, we don't need to store them in the uniform locations // Since block uniforms have no location, we don't need to store them in the uniform locations
// list. // list.
...@@ -812,8 +826,9 @@ size_t UniformBlockLinker::getCurrentBlockMemberIndex() const ...@@ -812,8 +826,9 @@ size_t UniformBlockLinker::getCurrentBlockMemberIndex() const
} }
// ShaderStorageBlockLinker implementation. // ShaderStorageBlockLinker implementation.
ShaderStorageBlockLinker::ShaderStorageBlockLinker(std::vector<InterfaceBlock> *blocksOut) ShaderStorageBlockLinker::ShaderStorageBlockLinker(std::vector<InterfaceBlock> *blocksOut,
: InterfaceBlockLinker(blocksOut) std::vector<BufferVariable> *bufferVariablesOut)
: InterfaceBlockLinker(blocksOut), mBufferVariablesOut(bufferVariablesOut)
{ {
} }
...@@ -825,15 +840,22 @@ void ShaderStorageBlockLinker::defineBlockMember(const sh::ShaderVariable &field ...@@ -825,15 +840,22 @@ void ShaderStorageBlockLinker::defineBlockMember(const sh::ShaderVariable &field
const std::string &fullName, const std::string &fullName,
const std::string &fullMappedName, const std::string &fullMappedName,
int blockIndex, int blockIndex,
const sh::BlockMemberInfo &memberInfo) const const sh::BlockMemberInfo &memberInfo,
int topLevelArraySize) const
{ {
// TODO(jiajia.qin@intel.com): Add buffer variables support. BufferVariable newBufferVariable(field.type, field.precision, fullName, field.arraySize,
blockIndex, memberInfo);
newBufferVariable.mappedName = fullMappedName;
// TODO(jiajia.qin@intel.com): update the block memeber static use.
newBufferVariable.topLevelArraySize = topLevelArraySize;
mBufferVariablesOut->push_back(newBufferVariable);
} }
size_t ShaderStorageBlockLinker::getCurrentBlockMemberIndex() const size_t ShaderStorageBlockLinker::getCurrentBlockMemberIndex() const
{ {
// TODO(jiajia.qin@intel.com): Add buffer variables support. return mBufferVariablesOut->size();
return 0;
} }
} // namespace gl } // namespace gl
...@@ -147,13 +147,16 @@ class InterfaceBlockLinker : angle::NonCopyable ...@@ -147,13 +147,16 @@ class InterfaceBlockLinker : angle::NonCopyable
const std::vector<VarT> &fields, const std::vector<VarT> &fields,
const std::string &prefix, const std::string &prefix,
const std::string &mappedPrefix, const std::string &mappedPrefix,
int blockIndex) const; int blockIndex,
bool outsideTopLevelArray,
int topLevelArraySize) const;
virtual void defineBlockMember(const sh::ShaderVariable &field, virtual void defineBlockMember(const sh::ShaderVariable &field,
const std::string &fullName, const std::string &fullName,
const std::string &fullMappedName, const std::string &fullMappedName,
int blockIndex, int blockIndex,
const sh::BlockMemberInfo &memberInfo) const = 0; const sh::BlockMemberInfo &memberInfo,
int topLevelArraySize) const = 0;
virtual size_t getCurrentBlockMemberIndex() const = 0; virtual size_t getCurrentBlockMemberIndex() const = 0;
using ShaderBlocks = std::pair<GLenum, const std::vector<sh::InterfaceBlock> *>; using ShaderBlocks = std::pair<GLenum, const std::vector<sh::InterfaceBlock> *>;
...@@ -174,16 +177,17 @@ class UniformBlockLinker final : public InterfaceBlockLinker ...@@ -174,16 +177,17 @@ class UniformBlockLinker final : public InterfaceBlockLinker
const std::string &fullName, const std::string &fullName,
const std::string &fullMappedName, const std::string &fullMappedName,
int blockIndex, int blockIndex,
const sh::BlockMemberInfo &memberInfo) const override; const sh::BlockMemberInfo &memberInfo,
int topLevelArraySize) const override;
size_t getCurrentBlockMemberIndex() const override; size_t getCurrentBlockMemberIndex() const override;
std::vector<LinkedUniform> *mUniformsOut; std::vector<LinkedUniform> *mUniformsOut;
}; };
// TODO(jiajia.qin@intel.com): Add buffer variables support.
class ShaderStorageBlockLinker final : public InterfaceBlockLinker class ShaderStorageBlockLinker final : public InterfaceBlockLinker
{ {
public: public:
ShaderStorageBlockLinker(std::vector<InterfaceBlock> *blocksOut); ShaderStorageBlockLinker(std::vector<InterfaceBlock> *blocksOut,
std::vector<BufferVariable> *bufferVariablesOut);
virtual ~ShaderStorageBlockLinker(); virtual ~ShaderStorageBlockLinker();
private: private:
...@@ -191,8 +195,10 @@ class ShaderStorageBlockLinker final : public InterfaceBlockLinker ...@@ -191,8 +195,10 @@ class ShaderStorageBlockLinker final : public InterfaceBlockLinker
const std::string &fullName, const std::string &fullName,
const std::string &fullMappedName, const std::string &fullMappedName,
int blockIndex, int blockIndex,
const sh::BlockMemberInfo &memberInfo) const override; const sh::BlockMemberInfo &memberInfo,
int topLevelArraySize) const override;
size_t getCurrentBlockMemberIndex() const override; size_t getCurrentBlockMemberIndex() const override;
std::vector<BufferVariable> *mBufferVariablesOut;
}; };
// The link operation is responsible for finishing the link of uniform and interface blocks. // The link operation is responsible for finishing the link of uniform and interface blocks.
......
...@@ -144,6 +144,29 @@ size_t LinkedUniform::getElementComponents() const ...@@ -144,6 +144,29 @@ size_t LinkedUniform::getElementComponents() const
return typeInfo->componentCount; return typeInfo->componentCount;
} }
BufferVariable::BufferVariable()
: bufferIndex(-1), blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo()), topLevelArraySize(-1)
{
}
BufferVariable::BufferVariable(GLenum typeIn,
GLenum precisionIn,
const std::string &nameIn,
unsigned int arraySizeIn,
const int bufferIndexIn,
const sh::BlockMemberInfo &blockInfoIn)
: bufferIndex(bufferIndexIn), blockInfo(blockInfoIn), topLevelArraySize(-1)
{
type = typeIn;
precision = precisionIn;
name = nameIn;
arraySize = arraySizeIn;
}
BufferVariable::~BufferVariable()
{
}
ShaderVariableBuffer::ShaderVariableBuffer() : binding(0), dataSize(0) ShaderVariableBuffer::ShaderVariableBuffer() : binding(0), dataSize(0)
{ {
} }
......
...@@ -69,6 +69,23 @@ struct LinkedUniform : public sh::Uniform, public StaticallyUsed ...@@ -69,6 +69,23 @@ struct LinkedUniform : public sh::Uniform, public StaticallyUsed
sh::BlockMemberInfo blockInfo; sh::BlockMemberInfo blockInfo;
}; };
struct BufferVariable : public sh::ShaderVariable, public StaticallyUsed
{
BufferVariable();
BufferVariable(GLenum type,
GLenum precision,
const std::string &name,
unsigned int arraySize,
const int bufferIndex,
const sh::BlockMemberInfo &blockInfo);
~BufferVariable();
int bufferIndex;
sh::BlockMemberInfo blockInfo;
int topLevelArraySize;
};
// Parent struct for atomic counter, uniform block, and shader storage block buffer, which all // Parent struct for atomic counter, uniform block, and shader storage block buffer, which all
// contain a group of shader variables, and have a GL buffer backed. // contain a group of shader variables, and have a GL buffer backed.
struct ShaderVariableBuffer : public StaticallyUsed struct ShaderVariableBuffer : public StaticallyUsed
......
...@@ -539,10 +539,14 @@ GLint QueryProgramInterfaceActiveResources(const Program *program, GLenum progra ...@@ -539,10 +539,14 @@ GLint QueryProgramInterfaceActiveResources(const Program *program, GLenum progra
case GL_ATOMIC_COUNTER_BUFFER: case GL_ATOMIC_COUNTER_BUFFER:
return clampCast<GLint>(program->getState().getAtomicCounterBuffers().size()); return clampCast<GLint>(program->getState().getAtomicCounterBuffers().size());
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING:
case GL_BUFFER_VARIABLE: case GL_BUFFER_VARIABLE:
return clampCast<GLint>(program->getState().getBufferVariables().size());
case GL_SHADER_STORAGE_BLOCK: case GL_SHADER_STORAGE_BLOCK:
return clampCast<GLint>(program->getState().getShaderStorageBlocks().size());
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING:
UNIMPLEMENTED(); UNIMPLEMENTED();
return 0; return 0;
...@@ -586,10 +590,18 @@ GLint QueryProgramInterfaceMaxNameLength(const Program *program, GLenum programI ...@@ -586,10 +590,18 @@ GLint QueryProgramInterfaceMaxNameLength(const Program *program, GLenum programI
FindMaxSize(program->getState().getUniformBlocks(), &InterfaceBlock::name); FindMaxSize(program->getState().getUniformBlocks(), &InterfaceBlock::name);
break; break;
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING:
case GL_BUFFER_VARIABLE: case GL_BUFFER_VARIABLE:
maxNameLength =
FindMaxSize(program->getState().getBufferVariables(), &BufferVariable::name);
break;
case GL_SHADER_STORAGE_BLOCK: case GL_SHADER_STORAGE_BLOCK:
maxNameLength =
FindMaxSize(program->getState().getShaderStorageBlocks(), &InterfaceBlock::name);
break;
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING:
UNIMPLEMENTED(); UNIMPLEMENTED();
return 0; return 0;
...@@ -612,10 +624,9 @@ GLint QueryProgramInterfaceMaxNumActiveVariables(const Program *program, GLenum ...@@ -612,10 +624,9 @@ GLint QueryProgramInterfaceMaxNumActiveVariables(const Program *program, GLenum
return FindMaxSize(program->getState().getAtomicCounterBuffers(), return FindMaxSize(program->getState().getAtomicCounterBuffers(),
&AtomicCounterBuffer::memberIndexes); &AtomicCounterBuffer::memberIndexes);
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_SHADER_STORAGE_BLOCK: case GL_SHADER_STORAGE_BLOCK:
UNIMPLEMENTED(); return FindMaxSize(program->getState().getShaderStorageBlocks(),
return 0; &InterfaceBlock::memberIndexes);
default: default:
UNREACHABLE(); UNREACHABLE();
...@@ -747,6 +758,19 @@ void GetUniformBlockResourceProperty(const Program *program, ...@@ -747,6 +758,19 @@ void GetUniformBlockResourceProperty(const Program *program,
GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition); GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition);
} }
void GetShaderStorageBlockResourceProperty(const Program *program,
GLuint blockIndex,
GLenum pname,
GLint *params,
GLsizei bufSize,
GLsizei *outputPosition)
{
ASSERT(*outputPosition < bufSize);
const auto &block = program->getShaderStorageBlockByIndex(blockIndex);
GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition);
}
void GetAtomicCounterBufferResourceProperty(const Program *program, void GetAtomicCounterBufferResourceProperty(const Program *program,
GLuint index, GLuint index,
GLenum pname, GLenum pname,
...@@ -1383,6 +1407,57 @@ GLint GetUniformResourceProperty(const Program *program, GLuint index, const GLe ...@@ -1383,6 +1407,57 @@ GLint GetUniformResourceProperty(const Program *program, GLuint index, const GLe
} }
} }
GLint GetBufferVariableResourceProperty(const Program *program, GLuint index, const GLenum prop)
{
const auto &bufferVariable = program->getBufferVariableByIndex(index);
switch (prop)
{
case GL_TYPE:
return clampCast<GLint>(bufferVariable.type);
case GL_ARRAY_SIZE:
return clampCast<GLint>(bufferVariable.elementCount());
case GL_BLOCK_INDEX:
return bufferVariable.bufferIndex;
case GL_NAME_LENGTH:
// ES31 spec p84: This counts the terminating null char.
return clampCast<GLint>(bufferVariable.name.size() + 1u);
case GL_OFFSET:
return bufferVariable.blockInfo.offset;
case GL_ARRAY_STRIDE:
return bufferVariable.blockInfo.arrayStride;
case GL_MATRIX_STRIDE:
return bufferVariable.blockInfo.matrixStride;
case GL_IS_ROW_MAJOR:
return static_cast<GLint>(bufferVariable.blockInfo.isRowMajorMatrix);
case GL_REFERENCED_BY_VERTEX_SHADER:
return bufferVariable.vertexStaticUse;
case GL_REFERENCED_BY_FRAGMENT_SHADER:
return bufferVariable.fragmentStaticUse;
case GL_REFERENCED_BY_COMPUTE_SHADER:
return bufferVariable.computeStaticUse;
case GL_TOP_LEVEL_ARRAY_SIZE:
return bufferVariable.topLevelArraySize;
case GL_TOP_LEVEL_ARRAY_STRIDE:
return bufferVariable.blockInfo.topLevelArrayStride;
default:
UNREACHABLE();
return 0;
}
}
GLuint QueryProgramResourceIndex(const Program *program, GLuint QueryProgramResourceIndex(const Program *program,
GLenum programInterface, GLenum programInterface,
const GLchar *name) const GLchar *name)
...@@ -1398,13 +1473,17 @@ GLuint QueryProgramResourceIndex(const Program *program, ...@@ -1398,13 +1473,17 @@ GLuint QueryProgramResourceIndex(const Program *program,
case GL_UNIFORM: case GL_UNIFORM:
return program->getState().getUniformIndexFromName(name); return program->getState().getUniformIndexFromName(name);
case GL_BUFFER_VARIABLE:
return program->getState().getBufferVariableIndexFromName(name);
case GL_SHADER_STORAGE_BLOCK:
return program->getShaderStorageBlockIndex(name);
case GL_UNIFORM_BLOCK: case GL_UNIFORM_BLOCK:
return program->getUniformBlockIndex(name); return program->getUniformBlockIndex(name);
// TODO(jie.a.chen@intel.com): more interfaces. // TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING: case GL_TRANSFORM_FEEDBACK_VARYING:
case GL_BUFFER_VARIABLE:
case GL_SHADER_STORAGE_BLOCK:
UNIMPLEMENTED(); UNIMPLEMENTED();
return GL_INVALID_INDEX; return GL_INVALID_INDEX;
...@@ -1435,14 +1514,20 @@ void QueryProgramResourceName(const Program *program, ...@@ -1435,14 +1514,20 @@ void QueryProgramResourceName(const Program *program,
program->getUniformResourceName(index, bufSize, length, name); program->getUniformResourceName(index, bufSize, length, name);
break; break;
case GL_BUFFER_VARIABLE:
program->getBufferVariableResourceName(index, bufSize, length, name);
break;
case GL_SHADER_STORAGE_BLOCK:
program->getActiveShaderStorageBlockName(index, bufSize, length, name);
break;
case GL_UNIFORM_BLOCK: case GL_UNIFORM_BLOCK:
program->getActiveUniformBlockName(index, bufSize, length, name); program->getActiveUniformBlockName(index, bufSize, length, name);
break; break;
// TODO(jie.a.chen@intel.com): more interfaces. // TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING: case GL_TRANSFORM_FEEDBACK_VARYING:
case GL_BUFFER_VARIABLE:
case GL_SHADER_STORAGE_BLOCK:
UNIMPLEMENTED(); UNIMPLEMENTED();
break; break;
...@@ -1509,18 +1594,27 @@ void QueryProgramResourceiv(const Program *program, ...@@ -1509,18 +1594,27 @@ void QueryProgramResourceiv(const Program *program,
params[i] = GetUniformResourceProperty(program, index, props[i]); params[i] = GetUniformResourceProperty(program, index, props[i]);
++pos; ++pos;
break; break;
case GL_BUFFER_VARIABLE:
params[i] = GetBufferVariableResourceProperty(program, index, props[i]);
++pos;
break;
case GL_UNIFORM_BLOCK: case GL_UNIFORM_BLOCK:
GetUniformBlockResourceProperty(program, index, props[i], params, bufSize, &pos); GetUniformBlockResourceProperty(program, index, props[i], params, bufSize, &pos);
break; break;
case GL_SHADER_STORAGE_BLOCK:
GetShaderStorageBlockResourceProperty(program, index, props[i], params, bufSize,
&pos);
break;
case GL_ATOMIC_COUNTER_BUFFER: case GL_ATOMIC_COUNTER_BUFFER:
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. // TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING: case GL_TRANSFORM_FEEDBACK_VARYING:
case GL_BUFFER_VARIABLE:
case GL_SHADER_STORAGE_BLOCK:
UNIMPLEMENTED(); UNIMPLEMENTED();
params[i] = GL_INVALID_VALUE; params[i] = GL_INVALID_VALUE;
break; break;
......
...@@ -580,6 +580,60 @@ bool ProgramGL::getUniformBlockMemberInfo(const std::string & /* memberUniformNa ...@@ -580,6 +580,60 @@ bool ProgramGL::getUniformBlockMemberInfo(const std::string & /* memberUniformNa
return true; return true;
} }
bool ProgramGL::getShaderStorageBlockMemberInfo(const std::string & /* memberName */,
const std::string &memberUniformMappedName,
sh::BlockMemberInfo *memberInfoOut) const
{
const GLchar *memberNameGLStr = memberUniformMappedName.c_str();
GLuint index =
mFunctions->getProgramResourceIndex(mProgramID, GL_BUFFER_VARIABLE, memberNameGLStr);
if (index == GL_INVALID_INDEX)
{
*memberInfoOut = sh::BlockMemberInfo::getDefaultBlockInfo();
return false;
}
constexpr int kPropCount = 5;
std::array<GLenum, kPropCount> props = {
{GL_ARRAY_STRIDE, GL_IS_ROW_MAJOR, GL_MATRIX_STRIDE, GL_OFFSET, GL_TOP_LEVEL_ARRAY_STRIDE}};
std::array<GLint, kPropCount> params;
GLsizei length;
mFunctions->getProgramResourceiv(mProgramID, GL_BUFFER_VARIABLE, index, kPropCount,
props.data(), kPropCount, &length, params.data());
ASSERT(kPropCount == length);
memberInfoOut->arrayStride = params[0];
memberInfoOut->isRowMajorMatrix = params[1];
memberInfoOut->matrixStride = params[2];
memberInfoOut->offset = params[3];
memberInfoOut->topLevelArrayStride = params[4];
return true;
}
bool ProgramGL::getShaderStorageBlockSize(const std::string &name,
const std::string &mappedName,
size_t *sizeOut) const
{
const GLchar *nameGLStr = mappedName.c_str();
GLuint index =
mFunctions->getProgramResourceIndex(mProgramID, GL_SHADER_STORAGE_BLOCK, nameGLStr);
if (index == GL_INVALID_INDEX)
{
*sizeOut = 0;
return false;
}
GLenum prop = GL_BUFFER_DATA_SIZE;
GLsizei length = 0;
GLint dataSize = 0;
mFunctions->getProgramResourceiv(mProgramID, GL_SHADER_STORAGE_BLOCK, index, 1, &prop, 1,
&length, &dataSize);
*sizeOut = static_cast<size_t>(dataSize);
return true;
}
void ProgramGL::setPathFragmentInputGen(const std::string &inputName, void ProgramGL::setPathFragmentInputGen(const std::string &inputName,
GLenum genMode, GLenum genMode,
GLint components, GLint components,
...@@ -822,18 +876,16 @@ void ProgramGL::linkResources(const gl::ProgramLinkedResources &resources) ...@@ -822,18 +876,16 @@ void ProgramGL::linkResources(const gl::ProgramLinkedResources &resources)
resources.uniformBlockLinker.linkBlocks(getUniformBlockSize, getUniformBlockMemberInfo); resources.uniformBlockLinker.linkBlocks(getUniformBlockSize, getUniformBlockMemberInfo);
// TODO(jiajia.qin@intel.com): Determine correct shader storage block info. auto getShaderStorageBlockSize = [this](const std::string &name, const std::string &mappedName,
auto getShaderStorageBlockSize = [](const std::string &name, const std::string &mappedName, size_t *sizeOut) {
size_t *sizeOut) { return this->getShaderStorageBlockSize(name, mappedName, sizeOut);
*sizeOut = 0;
return true;
}; };
auto getShaderStorageBlockMemberInfo = auto getShaderStorageBlockMemberInfo = [this](const std::string &name,
[](const std::string &name, const std::string &mappedName, sh::BlockMemberInfo *infoOut) { const std::string &mappedName,
*infoOut = sh::BlockMemberInfo::getDefaultBlockInfo(); sh::BlockMemberInfo *infoOut) {
return true; return this->getShaderStorageBlockMemberInfo(name, mappedName, infoOut);
}; };
resources.shaderStorageBlockLinker.linkBlocks(getShaderStorageBlockSize, resources.shaderStorageBlockLinker.linkBlocks(getShaderStorageBlockSize,
getShaderStorageBlockMemberInfo); getShaderStorageBlockMemberInfo);
} }
......
...@@ -96,6 +96,12 @@ class ProgramGL : public ProgramImpl ...@@ -96,6 +96,12 @@ class ProgramGL : public ProgramImpl
bool getUniformBlockMemberInfo(const std::string &memberUniformName, bool getUniformBlockMemberInfo(const std::string &memberUniformName,
const std::string &memberUniformMappedName, const std::string &memberUniformMappedName,
sh::BlockMemberInfo *memberInfoOut) const; sh::BlockMemberInfo *memberInfoOut) const;
bool getShaderStorageBlockMemberInfo(const std::string &memberName,
const std::string &memberMappedName,
sh::BlockMemberInfo *memberInfoOut) const;
bool getShaderStorageBlockSize(const std::string &blockName,
const std::string &blockMappedName,
size_t *sizeOut) const;
void linkResources(const gl::ProgramLinkedResources &resources); void linkResources(const gl::ProgramLinkedResources &resources);
// Helper function, makes it simpler to type. // Helper function, makes it simpler to type.
......
...@@ -260,6 +260,12 @@ bool ValidateProgramResourceIndex(const Program *programObject, ...@@ -260,6 +260,12 @@ bool ValidateProgramResourceIndex(const Program *programObject,
case GL_UNIFORM: case GL_UNIFORM:
return (index < static_cast<GLuint>(programObject->getActiveUniformCount())); return (index < static_cast<GLuint>(programObject->getActiveUniformCount()));
case GL_BUFFER_VARIABLE:
return (index < static_cast<GLuint>(programObject->getActiveBufferVariableCount()));
case GL_SHADER_STORAGE_BLOCK:
return (index < static_cast<GLuint>(programObject->getActiveShaderStorageBlockCount()));
case GL_UNIFORM_BLOCK: case GL_UNIFORM_BLOCK:
return (index < programObject->getActiveUniformBlockCount()); return (index < programObject->getActiveUniformBlockCount());
...@@ -268,8 +274,6 @@ bool ValidateProgramResourceIndex(const Program *programObject, ...@@ -268,8 +274,6 @@ bool ValidateProgramResourceIndex(const Program *programObject,
// TODO(jie.a.chen@intel.com): more interfaces. // TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING: case GL_TRANSFORM_FEEDBACK_VARYING:
case GL_BUFFER_VARIABLE:
case GL_SHADER_STORAGE_BLOCK:
UNIMPLEMENTED(); UNIMPLEMENTED();
return false; return false;
......
...@@ -66,6 +66,31 @@ ...@@ -66,6 +66,31 @@
1442 D3D11 : dEQP-GLES31.functional.state_query.internal_format.renderbuffer.* = FAIL 1442 D3D11 : dEQP-GLES31.functional.state_query.internal_format.renderbuffer.* = FAIL
1679 D3D11 : dEQP-GLES31.functional.state_query.texture_level.texture_2d_multisample.* = FAIL 1679 D3D11 : dEQP-GLES31.functional.state_query.texture_level.texture_2d_multisample.* = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.program.compute_work_group_size_get_programiv = FAIL 1442 D3D11 : dEQP-GLES31.functional.state_query.program.compute_work_group_size_get_programiv = FAIL
1442 D3D11 : dEQP-GLES31.functional.layout_binding.ssbo.* = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.empty = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_local_barrier_single_invocation = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_local_barrier_single_group = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_local_barrier_multiple_groups = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_rw_single_invocation = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_rw_multiple_groups = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.copy_image_to_ssbo_small = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_multiple_groups = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_multiple_invocations = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_single_invocation = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_to_image_small = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.shared_var_single_invocation = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.shared_var_single_group = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.shared_var_multiple_invocations = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.shared_var_multiple_groups = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.write_multiple_arr_single_invocation = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.write_multiple_arr_multiple_groups = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_single_invocation = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_single_group = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_multiple_invocations = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_multiple_groups = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.shared_var.basic_type.* = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.shared_var.work_group_size.* = FAIL
1442 D3D11 : dEQP-GLES31.functional.atomic_counter.* = FAIL
1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.texture.texparameter* = SKIP 1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.texture.texparameter* = SKIP
1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.texparameter* = SKIP 1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.texparameter* = SKIP
1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.log.texture.texparameter* = SKIP 1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.log.texture.texparameter* = SKIP
...@@ -1153,38 +1178,17 @@ ...@@ -1153,38 +1178,17 @@
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_compute_work_group_count = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_compute_work_group_count = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_compute_work_group_size = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_compute_work_group_size = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.helper_invocation.* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.helper_invocation.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.empty = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_single_invocation = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_single_group = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_multiple_invocations = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_single_invocation = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_multiple_invocations = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_rw_single_invocation = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_rw_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_unsized_arr_single_invocation = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_unsized_arr_single_invocation = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_unsized_arr_multiple_groups = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_unsized_arr_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.write_multiple_arr_single_invocation = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.write_multiple_arr_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.write_multiple_unsized_arr_single_invocation = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.write_multiple_unsized_arr_single_invocation = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.write_multiple_unsized_arr_multiple_groups = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.write_multiple_unsized_arr_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_local_barrier_single_invocation = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_local_barrier_single_group = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_local_barrier_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_cmd_barrier_single = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_cmd_barrier_single = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_cmd_barrier_multiple = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_cmd_barrier_multiple = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_var_single_invocation = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_var_single_group = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_var_multiple_invocations = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_var_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_atomic_op_single_invocation = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_atomic_op_single_invocation = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_atomic_op_single_group = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_atomic_op_single_group = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_atomic_op_multiple_invocations = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_atomic_op_multiple_invocations = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_atomic_op_multiple_groups = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_atomic_op_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_image_to_ssbo_small = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_image_to_ssbo_large = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_image_to_ssbo_large = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_to_image_small = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_to_image_large = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_to_image_large = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.image_barrier_single = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.image_barrier_single = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.image_barrier_multiple = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.image_barrier_multiple = FAIL
...@@ -1192,7 +1196,7 @@ ...@@ -1192,7 +1196,7 @@
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.atomic_counter_single_group = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.atomic_counter_single_group = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.atomic_counter_multiple_invocations = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.atomic_counter_multiple_invocations = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.atomic_counter_multiple_groups = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.atomic_counter_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.shared_var.* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.shared_var.atomic.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.indirect_dispatch.* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.indirect_dispatch.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.ssbo.* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.ssbo.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.2_level_array.* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.2_level_array.* = FAIL
...@@ -1213,7 +1217,6 @@ ...@@ -1213,7 +1217,6 @@
1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_shared_buffer.22 = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_shared_buffer.22 = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_shared_buffer.37 = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_shared_buffer.37 = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_shared_buffer.38 = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_shared_buffer.38 = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.atomic_counter.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth32f_stencil8_2d = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth32f_stencil8_2d = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth32f_stencil8_2d_array = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth32f_stencil8_2d_array = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth32f_stencil8_cube = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth32f_stencil8_cube = FAIL
...@@ -1307,6 +1310,5 @@ ...@@ -1307,6 +1310,5 @@
1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_directive.tessellation_shader = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_directive.tessellation_shader = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.object_labels.program_pipeline = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.object_labels.program_pipeline = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.program_interface_query.* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.program_interface_query.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.ssbo.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.image.image2d.* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.image.image2d.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.image.image3d.* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.image.image3d.* = FAIL
...@@ -580,6 +580,221 @@ TEST_P(ProgramInterfaceTestES31, QueryAtomicCounteBuffer) ...@@ -580,6 +580,221 @@ TEST_P(ProgramInterfaceTestES31, QueryAtomicCounteBuffer)
EXPECT_EQ(0, params[4]); // referenced_by_compute_shader EXPECT_EQ(0, params[4]); // referenced_by_compute_shader
} }
// Tests the resource property query for buffer variable can be done correctly.
TEST_P(ProgramInterfaceTestES31, GetBufferVariableProperties)
{
const std::string &vertexShaderSource =
"#version 310 es\n"
"precision highp float;\n"
"struct S {\n"
" vec3 a;\n"
" ivec2 b[4];\n"
"};\n"
"layout(std140) buffer blockName0 {\n"
" S s0;\n"
" vec2 v0;\n"
" S s1[2];\n"
" uint u0;\n"
"};\n"
"layout(binding = 1) buffer blockName1 {\n"
" uint u1[2];\n"
" float f1;\n"
"} instanceName1[2];\n"
"void main()\n"
"{\n"
" gl_Position = vec4(instanceName1[0].f1, s1[0].a);\n"
"}\n";
const std::string &fragmentShaderSource =
"#version 310 es\n"
"precision highp float;\n"
"layout(binding = 1) buffer blockName1 {\n"
" uint u1[2];\n"
" float f1;\n"
"} instanceName1[2];\n"
"out vec4 oColor;\n"
"void main()\n"
"{\n"
" oColor = vec4(instanceName1[0].f1, 0, 0, 1);\n"
"}";
ANGLE_GL_PROGRAM(program, vertexShaderSource, fragmentShaderSource);
GLuint index = glGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, "blockName1.f1");
EXPECT_GL_NO_ERROR();
EXPECT_NE(GL_INVALID_INDEX, index);
GLchar name[64];
GLsizei length;
glGetProgramResourceName(program, GL_BUFFER_VARIABLE, index, sizeof(name), &length, name);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(13, length);
EXPECT_EQ("blockName1.f1", std::string(name));
GLenum props[] = {GL_ARRAY_SIZE,
GL_ARRAY_STRIDE,
GL_BLOCK_INDEX,
GL_IS_ROW_MAJOR,
GL_MATRIX_STRIDE,
GL_NAME_LENGTH,
GL_OFFSET,
GL_REFERENCED_BY_VERTEX_SHADER,
GL_REFERENCED_BY_FRAGMENT_SHADER,
GL_REFERENCED_BY_COMPUTE_SHADER,
GL_TOP_LEVEL_ARRAY_SIZE,
GL_TOP_LEVEL_ARRAY_STRIDE,
GL_TYPE};
GLsizei propCount = static_cast<GLsizei>(ArraySize(props));
constexpr int kBufSize = 256;
GLint params[kBufSize];
glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, index, propCount, props, kBufSize, &length,
params);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(propCount, length);
EXPECT_EQ(1, params[0]); // array_size
EXPECT_LE(0, params[1]); // array_stride
EXPECT_LE(0, params[2]); // block_index
EXPECT_EQ(0, params[3]); // is_row_major
EXPECT_EQ(0, params[4]); // matrix_stride
EXPECT_EQ(14, params[5]); // name_length
EXPECT_LE(0, params[6]); // offset
// TODO(jiajia.qin@intel.com): Enable them once the block member staticUse are implemented.
// EXPECT_EQ(1, params[7]); // referenced_by_vertex_shader
// EXPECT_EQ(1, params[8]); // referenced_by_fragment_shader
// EXPECT_EQ(0, params[9]); // referenced_by_compute_shader
EXPECT_EQ(1, params[10]); // top_level_array_size
EXPECT_LE(0, params[11]); // top_level_array_stride
EXPECT_EQ(GL_FLOAT, params[12]); // type
index = glGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, "s1[0].a");
EXPECT_GL_NO_ERROR();
EXPECT_NE(GL_INVALID_INDEX, index);
glGetProgramResourceName(program, GL_BUFFER_VARIABLE, index, sizeof(name), &length, name);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(7, length);
EXPECT_EQ("s1[0].a", std::string(name));
glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, index, propCount, props, kBufSize, &length,
params);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(propCount, length);
EXPECT_EQ(1, params[0]); // array_size
EXPECT_LE(0, params[1]); // array_stride
EXPECT_LE(0, params[2]); // block_index
EXPECT_EQ(0, params[3]); // is_row_major
EXPECT_EQ(0, params[4]); // matrix_stride
EXPECT_EQ(8, params[5]); // name_length
EXPECT_LE(0, params[6]); // offset
// TODO(jiajia.qin@intel.com): Enable them once the block member staticUse are implemented.
// EXPECT_EQ(1, params[7]); // referenced_by_vertex_shader
// EXPECT_EQ(0, params[8]); // referenced_by_fragment_shader
// EXPECT_EQ(0, params[9]); // referenced_by_compute_shader
EXPECT_EQ(2, params[10]); // top_level_array_size
EXPECT_EQ(80, params[11]); // top_level_array_stride
EXPECT_EQ(GL_FLOAT_VEC3, params[12]); // type
}
// Tests the resource property query for shader storage block can be done correctly.
TEST_P(ProgramInterfaceTestES31, GetShaderStorageBlockProperties)
{
const std::string &vertexShaderSource =
"#version 310 es\n"
"precision highp float;\n"
"struct S {\n"
" vec3 a;\n"
" ivec2 b[4];\n"
"};\n"
"layout(std140) buffer blockName0 {\n"
" S s0;\n"
" vec2 v0;\n"
" S s1[2];\n"
" uint u0;\n"
"};\n"
"layout(binding = 1) buffer blockName1 {\n"
" uint u1[2];\n"
" float f1;\n"
"} instanceName1[2];\n"
"layout(binding = 2) buffer blockName2 {\n"
" uint u2;\n"
" float f2;\n"
"};\n"
"void main()\n"
"{\n"
" gl_Position = vec4(instanceName1[0].f1, s1[0].a);\n"
"}\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_SHADER_STORAGE_BLOCK, "blockName0");
EXPECT_GL_NO_ERROR();
EXPECT_NE(GL_INVALID_INDEX, index);
GLchar name[64];
GLsizei length;
glGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, index, sizeof(name), &length, name);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(10, length);
EXPECT_EQ("blockName0", std::string(name));
GLenum props[] = {GL_ACTIVE_VARIABLES,
GL_BUFFER_BINDING,
GL_NUM_ACTIVE_VARIABLES,
GL_BUFFER_DATA_SIZE,
GL_NAME_LENGTH,
GL_REFERENCED_BY_VERTEX_SHADER,
GL_REFERENCED_BY_FRAGMENT_SHADER,
GL_REFERENCED_BY_COMPUTE_SHADER};
GLsizei propCount = static_cast<GLsizei>(ArraySize(props));
constexpr int kBufSize = 256;
GLint params[kBufSize];
glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, index, propCount, props, kBufSize,
&length, params);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(13, length);
EXPECT_LE(0, params[0]); // active_variables s0.a
EXPECT_LE(0, params[1]); // active_variables s0.b
EXPECT_LE(0, params[2]); // active_variables v0
EXPECT_LE(0, params[3]); // active_variables s1[0].a
EXPECT_LE(0, params[4]); // active_variables s1[0].b
EXPECT_LE(0, params[5]); // active_variables u0
EXPECT_EQ(0, params[6]); // buffer_binding
EXPECT_EQ(6, params[7]); // num_active_variables
EXPECT_LE(0, params[8]); // buffer_data_size
EXPECT_EQ(11, params[9]); // name_length
EXPECT_EQ(1, params[10]); // referenced_by_vertex_shader
EXPECT_EQ(0, params[11]); // referenced_by_fragment_shader
EXPECT_EQ(0, params[12]); // referenced_by_compute_shader
index = glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, "blockName1");
EXPECT_GL_NO_ERROR();
EXPECT_NE(GL_INVALID_INDEX, index);
glGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, index, sizeof(name), &length, name);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(13, length);
EXPECT_EQ("blockName1[0]", std::string(name));
}
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