mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-18 00:58:30 +09:00
[Fix, Test] (GLState): keep the atomic-counter and storage blocks out of the GL uniform-block list
This commit is contained in:
@@ -680,7 +680,9 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
|
||||
break;
|
||||
case GL_ACTIVE_UNIFORM_BLOCKS: // GL >= 3.1
|
||||
*params = programObject->GetActiveUniformBlocksCount();
|
||||
// Uniform blocks only. GetActiveUniformBlocksCount() is the internal block space,
|
||||
// which also carries the storage blocks and the synthesized atomic counter blocks.
|
||||
*params = programObject->GetGlUniformBlockCount();
|
||||
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
|
||||
break;
|
||||
case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: // ditto.
|
||||
@@ -1716,7 +1718,10 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
return GL_INVALID_INDEX;
|
||||
}
|
||||
|
||||
const auto& index = programObject->GetUniformBlockIndex(uniformBlockName);
|
||||
// GetGlUniformBlockIndex, not GetUniformBlockIndex: the latter answers in the internal
|
||||
// block space, which also resolves storage blocks and the synthesized atomic counter
|
||||
// blocks. Neither is a uniform block (GL 4.6 core 7.6), so both are GL_INVALID_INDEX here.
|
||||
const auto index = programObject->GetGlUniformBlockIndex(uniformBlockName);
|
||||
MGLOG_D("GBI prog=%u name='%s' -> %d", program, uniformBlockName ? uniformBlockName : "(null)", (Int)index);
|
||||
return index;
|
||||
}
|
||||
@@ -1730,7 +1735,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
"Program object" + std::to_string(program) + " that has been linked."));
|
||||
return;
|
||||
}
|
||||
if (!programObject->IsActiveUniformBlock(uniformBlockIndex)) {
|
||||
if (!programObject->IsActiveGlUniformBlock(uniformBlockIndex)) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidValue,
|
||||
MakeUnique<GenericErrorInfo>(
|
||||
@@ -1741,8 +1746,11 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
std::to_string(program) + "."));
|
||||
return;
|
||||
}
|
||||
// The GL_UNIFORM_BLOCK index space skips the storage and atomic counter blocks the
|
||||
// block-keyed tables still carry; translate before touching them.
|
||||
const Uint blockIndex = static_cast<Uint>(programObject->BlockIndexFromGlUniformBlock(uniformBlockIndex));
|
||||
MGLOG_D("UBB prog=%u idx=%u binding=%u", program, uniformBlockIndex, uniformBlockBinding);
|
||||
programObject->SetUniformBlockBinding(uniformBlockIndex, uniformBlockBinding);
|
||||
programObject->SetUniformBlockBinding(blockIndex, uniformBlockBinding);
|
||||
}
|
||||
|
||||
void GetActiveUniformBlockiv_State(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) {
|
||||
@@ -1754,7 +1762,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
"Program object" + std::to_string(program) + " that has been linked."));
|
||||
return;
|
||||
}
|
||||
if (!programObject->IsActiveUniformBlock(uniformBlockIndex)) {
|
||||
if (!programObject->IsActiveGlUniformBlock(uniformBlockIndex)) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidValue,
|
||||
MakeUnique<GenericErrorInfo>(
|
||||
@@ -1765,61 +1773,68 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
std::to_string(program) + "."));
|
||||
return;
|
||||
}
|
||||
// The GL_UNIFORM_BLOCK index space skips the storage and atomic counter blocks the
|
||||
// block-keyed tables still carry; every accessor below is indexed by the block space.
|
||||
const Uint blockIndex = static_cast<Uint>(programObject->BlockIndexFromGlUniformBlock(uniformBlockIndex));
|
||||
switch (pname) {
|
||||
case GL_UNIFORM_BLOCK_DATA_SIZE: {
|
||||
*params = (GLint)programObject->GetUBOSizeAt(uniformBlockIndex);
|
||||
*params = (GLint)programObject->GetUBOSizeAt(blockIndex);
|
||||
MGLOG_D("%s: GL_UNIFORM_BLOCK_DATA_SIZE = %d", __func__, *params);
|
||||
break;
|
||||
}
|
||||
case GL_UNIFORM_BLOCK_NAME_LENGTH: {
|
||||
*params = (GLint)programObject->GetUniformBlockName(uniformBlockIndex).length() + 1;
|
||||
*params = (GLint)programObject->GetUniformBlockName(blockIndex).length() + 1;
|
||||
MGLOG_D("%s: GL_UNIFORM_BLOCK_NAME_LENGTH = %d", __func__, *params);
|
||||
break;
|
||||
}
|
||||
case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: {
|
||||
*params = programObject->GetUniformBlockActiveUniformCount(uniformBlockIndex);
|
||||
*params = programObject->GetUniformBlockActiveUniformCount(blockIndex);
|
||||
MGLOG_D("%s: GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS = %d", __func__, *params);
|
||||
break;
|
||||
}
|
||||
case GL_UNIFORM_BLOCK_BINDING: {
|
||||
*params = static_cast<GLint>(programObject->GetUniformBlockBinding(uniformBlockIndex));
|
||||
*params = static_cast<GLint>(programObject->GetUniformBlockBinding(blockIndex));
|
||||
MGLOG_D("%s: GL_UNIFORM_BLOCK_BINDING = %d", __func__, *params);
|
||||
break;
|
||||
}
|
||||
case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
|
||||
*params = BoolToGLInt(programObject->IsUniformBlockReferencedByStage(uniformBlockIndex, EShLangVertex));
|
||||
*params = BoolToGLInt(programObject->IsUniformBlockReferencedByStage(blockIndex, EShLangVertex));
|
||||
MGLOG_D("%s: GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = %d", __func__, *params);
|
||||
break;
|
||||
case GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER:
|
||||
*params =
|
||||
BoolToGLInt(programObject->IsUniformBlockReferencedByStage(uniformBlockIndex, EShLangTessControl));
|
||||
BoolToGLInt(programObject->IsUniformBlockReferencedByStage(blockIndex, EShLangTessControl));
|
||||
MGLOG_D("%s: GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER = %d", __func__, *params);
|
||||
break;
|
||||
case GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER:
|
||||
*params =
|
||||
BoolToGLInt(programObject->IsUniformBlockReferencedByStage(uniformBlockIndex, EShLangTessEvaluation));
|
||||
BoolToGLInt(programObject->IsUniformBlockReferencedByStage(blockIndex, EShLangTessEvaluation));
|
||||
MGLOG_D("%s: GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER = %d", __func__, *params);
|
||||
break;
|
||||
case GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER:
|
||||
*params = BoolToGLInt(programObject->IsUniformBlockReferencedByStage(uniformBlockIndex, EShLangGeometry));
|
||||
*params = BoolToGLInt(programObject->IsUniformBlockReferencedByStage(blockIndex, EShLangGeometry));
|
||||
MGLOG_D("%s: GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER = %d", __func__, *params);
|
||||
break;
|
||||
case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
|
||||
*params = BoolToGLInt(programObject->IsUniformBlockReferencedByStage(uniformBlockIndex, EShLangFragment));
|
||||
*params = BoolToGLInt(programObject->IsUniformBlockReferencedByStage(blockIndex, EShLangFragment));
|
||||
MGLOG_D("%s: GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = %d", __func__, *params);
|
||||
break;
|
||||
case GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER:
|
||||
*params = BoolToGLInt(programObject->IsUniformBlockReferencedByStage(uniformBlockIndex, EShLangCompute));
|
||||
*params = BoolToGLInt(programObject->IsUniformBlockReferencedByStage(blockIndex, EShLangCompute));
|
||||
MGLOG_D("%s: GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER = %d", __func__, *params);
|
||||
break;
|
||||
case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: {
|
||||
// Member entries of an arrayed block are recorded against the first instance;
|
||||
// every instance of the array reports that shared member set (matches
|
||||
// GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, which scans with the same owner index).
|
||||
const Int ownerIndex = static_cast<Int>(programObject->GetUniformBlockMemberOwnerIndex(uniformBlockIndex));
|
||||
//
|
||||
// Both sides of the comparison are BLOCK indices: GetUniformBlockMemberOwnerIndex
|
||||
// answers in that space, so the scan uses GetActiveUniformOwnerBlockIndex rather
|
||||
// than the GL_UNIFORM_BLOCK-space GetActiveUniformBlockIndex.
|
||||
const Int ownerIndex = static_cast<Int>(programObject->GetUniformBlockMemberOwnerIndex(blockIndex));
|
||||
GLint uniformIndexCount = 0;
|
||||
for (Uint uniformIndex = 0; uniformIndex < programObject->GetUniformCount(); ++uniformIndex) {
|
||||
if (programObject->GetActiveUniformBlockIndex(uniformIndex) != ownerIndex) {
|
||||
if (programObject->GetActiveUniformOwnerBlockIndex(uniformIndex) != ownerIndex) {
|
||||
continue;
|
||||
}
|
||||
params[uniformIndexCount++] = static_cast<GLint>(uniformIndex);
|
||||
@@ -1849,7 +1864,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
" is not a program object that has been linked."));
|
||||
return;
|
||||
}
|
||||
if (!programObject->IsActiveUniformBlock(uniformBlockIndex)) {
|
||||
if (!programObject->IsActiveGlUniformBlock(uniformBlockIndex)) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidValue,
|
||||
MakeUnique<GenericErrorInfo>(
|
||||
@@ -1859,7 +1874,8 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
"not the index of an active uniform block in program."));
|
||||
return;
|
||||
}
|
||||
const auto& name = programObject->GetUniformBlockName(uniformBlockIndex);
|
||||
const auto& name = programObject->GetUniformBlockName(
|
||||
static_cast<Uint>(programObject->BlockIndexFromGlUniformBlock(uniformBlockIndex)));
|
||||
CopyStr(bufSize, length, uniformBlockName, name.c_str(), (GLsizei)name.length());
|
||||
MGLOG_D("%s: \"%s\" at uniformBlockIndex %02d, length = %d", __func__, uniformBlockName, uniformBlockIndex,
|
||||
length ? *length : 0);
|
||||
|
||||
@@ -305,13 +305,17 @@ namespace MobileGL::MG_Impl::GLImpl::ProgramInterface {
|
||||
// GL_UNIFORM_BLOCK keeps the index space glUniformBlockBinding and
|
||||
// glGetActiveUniformBlockiv already use, so an index handed out here is usable
|
||||
// with them (which is exactly what the CTS does).
|
||||
const Int glBlockCount = program.GetActiveUniformBlocksCount();
|
||||
const Int glBlockCount = program.GetGlUniformBlockCount();
|
||||
for (Int glIndex = 0; glIndex < glBlockCount; ++glIndex) {
|
||||
// The block-space index the block-keyed accessors want; the two spaces differ
|
||||
// whenever the program also has a storage or atomic counter block, which
|
||||
// glslang files under the same reflection list (no EShReflectionSeparateBuffers).
|
||||
const Int blockIndex = program.BlockIndexFromGlUniformBlock(static_cast<Uint>(glIndex));
|
||||
Resource resource;
|
||||
resource.name = program.GetUniformBlockName(glIndex);
|
||||
resource.bufferBinding = static_cast<GLint>(program.GetUniformBlockBinding(glIndex));
|
||||
resource.bufferDataSize = static_cast<GLint>(program.GetUBOSizeAt(glIndex));
|
||||
const Int tIndex = program.TProgramBlockIndex(static_cast<Uint>(glIndex));
|
||||
resource.name = program.GetUniformBlockName(static_cast<Uint>(blockIndex));
|
||||
resource.bufferBinding = static_cast<GLint>(program.GetUniformBlockBinding(static_cast<Uint>(blockIndex)));
|
||||
resource.bufferDataSize = static_cast<GLint>(program.GetUBOSizeAt(static_cast<Uint>(blockIndex)));
|
||||
const Int tIndex = program.TProgramBlockIndex(static_cast<Uint>(blockIndex));
|
||||
if (tIndex >= 0 && tIndex < blockCount) {
|
||||
resource.stages = UniformBlockStages(reflection.blockReflection[tIndex],
|
||||
stagesFromMembers, tIndex);
|
||||
@@ -388,12 +392,16 @@ namespace MobileGL::MG_Impl::GLImpl::ProgramInterface {
|
||||
static_cast<GLuint>(i));
|
||||
}
|
||||
}
|
||||
for (SizeT blockIndex = 0; blockIndex < model.uniformBlocks.size(); ++blockIndex) {
|
||||
for (SizeT glBlockIndex = 0; glBlockIndex < model.uniformBlocks.size(); ++glBlockIndex) {
|
||||
// Members of an arrayed block are reflected once, against instance [0].
|
||||
const Int owner = static_cast<Int>(program.GetUniformBlockMemberOwnerIndex(static_cast<Uint>(blockIndex)));
|
||||
// GetUniformBlockMemberOwnerIndex takes and answers BLOCK indices, while
|
||||
// Resource::blockIndex is a GL_UNIFORM_BLOCK index, so translate both ways.
|
||||
const Int blockIndex = program.BlockIndexFromGlUniformBlock(static_cast<Uint>(glBlockIndex));
|
||||
const Int owner = program.GlUniformBlockIndexFromBlock(
|
||||
static_cast<Int>(program.GetUniformBlockMemberOwnerIndex(static_cast<Uint>(blockIndex))));
|
||||
for (SizeT i = 0; i < model.uniforms.size(); ++i) {
|
||||
if (model.uniforms[i].blockIndex == owner) {
|
||||
model.uniformBlocks[blockIndex].activeVariables.push_back(static_cast<GLuint>(i));
|
||||
model.uniformBlocks[glBlockIndex].activeVariables.push_back(static_cast<GLuint>(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user