mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-13 06:38:31 +09:00
[Feat] (MG_State/Program, DirectGLES): plumb ubo to backend
This commit is contained in:
@@ -15,6 +15,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
void SyncNeccessaryBuffers() {
|
void SyncNeccessaryBuffers() {
|
||||||
// All buffers we need are:
|
// All buffers we need are:
|
||||||
// 1.VBOs 2.IBO 3.UBOs (TODO) 4.SSBOs (TODO)
|
// 1.VBOs 2.IBO 3.UBOs (TODO) 4.SSBOs (TODO)
|
||||||
|
|
||||||
Vector<SharedPtr<MG_State::GLState::BufferObject>> buffersToSync;
|
Vector<SharedPtr<MG_State::GLState::BufferObject>> buffersToSync;
|
||||||
const auto& currentVAOObject = MG_State::pGLContext->GetBoundVertexArray();
|
const auto& currentVAOObject = MG_State::pGLContext->GetBoundVertexArray();
|
||||||
if (!currentVAOObject) {
|
if (!currentVAOObject) {
|
||||||
@@ -22,6 +23,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VBO
|
||||||
for (const auto& attrib : currentVAOObject->GetAllAttributes()) {
|
for (const auto& attrib : currentVAOObject->GetAllAttributes()) {
|
||||||
if (!attrib.Enabled) continue;
|
if (!attrib.Enabled) continue;
|
||||||
const auto& bufferObject = attrib.Buffer;
|
const auto& bufferObject = attrib.Buffer;
|
||||||
@@ -29,11 +31,24 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
buffersToSync.push_back(bufferObject);
|
buffersToSync.push_back(bufferObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IBO
|
||||||
const auto& possibleIBO = currentVAOObject->GetIndexBufferBindingSlot().GetBoundObject();
|
const auto& possibleIBO = currentVAOObject->GetIndexBufferBindingSlot().GetBoundObject();
|
||||||
if (possibleIBO) {
|
if (possibleIBO) {
|
||||||
buffersToSync.push_back(possibleIBO);
|
buffersToSync.push_back(possibleIBO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UBO
|
||||||
|
auto uboBindingPointCnt = MG_State::pGLContext->GetBufferBindingPointCount(BufferTarget::Uniform);
|
||||||
|
for (SizeT i = 0; i < uboBindingPointCnt; ++i) {
|
||||||
|
auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::Uniform, i);
|
||||||
|
auto obj = point.GetBoundObject();
|
||||||
|
if (obj)
|
||||||
|
buffersToSync.push_back(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// PBO
|
||||||
const auto& pbo = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject();
|
const auto& pbo = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject();
|
||||||
if (pbo) {
|
if (pbo) {
|
||||||
buffersToSync.push_back(pbo);
|
buffersToSync.push_back(pbo);
|
||||||
@@ -300,20 +315,44 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
const auto& backendProgramIt = PrgramImpl::g_backendProgramObjects.find(currentProgram);
|
const auto& backendProgramIt = PrgramImpl::g_backendProgramObjects.find(currentProgram);
|
||||||
if (backendProgramIt != PrgramImpl::g_backendProgramObjects.end()) {
|
if (backendProgramIt != PrgramImpl::g_backendProgramObjects.end()) {
|
||||||
backendProgramIt->second->Use();
|
backendProgramIt->second->Use();
|
||||||
// UBO
|
auto backendProgramId = backendProgramIt->second->GetBackendProgramId();
|
||||||
|
// Global UBO
|
||||||
|
if (currentProgram->GetUBOSize() > 0) {
|
||||||
MG_External::GLES::glBindBuffer(GL_UNIFORM_BUFFER, backendProgramIt->second->GetBackendGlobalUBOId());
|
MG_External::GLES::glBindBuffer(GL_UNIFORM_BUFFER, backendProgramIt->second->GetBackendGlobalUBOId());
|
||||||
MG_External::GLES::glBufferSubData(GL_UNIFORM_BUFFER, 0, currentProgram->GetUBOSize(),
|
MG_External::GLES::glBufferSubData(GL_UNIFORM_BUFFER, 0, currentProgram->GetUBOSize(),
|
||||||
currentProgram->MapUBO());
|
currentProgram->MapUBO());
|
||||||
MG_External::GLES::glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
MG_External::GLES::glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
|
|
||||||
Uint blockIndex = MG_External::GLES::glGetUniformBlockIndex(
|
Uint blockIndex = MG_External::GLES::glGetUniformBlockIndex(
|
||||||
backendProgramIt->second->GetBackendProgramId(), MG_Util::ShaderTranspiler::GLOBAL_UBO_NAME);
|
backendProgramId, MG_Util::ShaderTranspiler::GLOBAL_UBO_NAME);
|
||||||
|
|
||||||
MG_External::GLES::glUniformBlockBinding(backendProgramIt->second->GetBackendProgramId(), blockIndex,
|
MG_External::GLES::glUniformBlockBinding(backendProgramId, blockIndex, 0);
|
||||||
0);
|
|
||||||
|
|
||||||
MG_External::GLES::glBindBufferBase(GL_UNIFORM_BUFFER, 0,
|
MG_External::GLES::glBindBufferBase(GL_UNIFORM_BUFFER, 0,
|
||||||
backendProgramIt->second->GetBackendGlobalUBOId());
|
backendProgramIt->second->GetBackendGlobalUBOId());
|
||||||
|
}
|
||||||
|
// Normal UBO
|
||||||
|
auto uboCount = currentProgram->GetActiveUniformBlocksCount();
|
||||||
|
for (Int i = 0; i < uboCount; ++i) {
|
||||||
|
// state binding point == backend binding point
|
||||||
|
|
||||||
|
// Connect program ubo index to backend binding point
|
||||||
|
auto binding = currentProgram->GetUniformBlockBinding(i);
|
||||||
|
auto& name = currentProgram->GetUniformBlockName(i);
|
||||||
|
GLuint backendBlkIdx = MG_External::GLES::glGetUniformBlockIndex(backendProgramId, name.c_str());
|
||||||
|
MG_External::GLES::glUniformBlockBinding(backendProgramId, backendBlkIdx, binding);
|
||||||
|
|
||||||
|
// Connect buffer to backend binding point
|
||||||
|
auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::Uniform, binding);
|
||||||
|
auto bufferObj = point.GetBoundObject();
|
||||||
|
auto range = point.GetRange();
|
||||||
|
if (range.end > bufferObj->GetSize()) {
|
||||||
|
MG_External::GLES::glBindBufferBase(GL_UNIFORM_BUFFER, binding, BufferImpl::g_backendBufferObjects[bufferObj]->GetBackendBufferId());
|
||||||
|
} else {
|
||||||
|
MG_External::GLES::glBindBufferRange(GL_UNIFORM_BUFFER, binding, BufferImpl::g_backendBufferObjects[bufferObj]->GetBackendBufferId(),
|
||||||
|
range.start, range.end - range.start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Sampler unit binding
|
// Sampler unit binding
|
||||||
auto maxUniformLoc = currentProgram->GetMaxUniformLocation();
|
auto maxUniformLoc = currentProgram->GetMaxUniformLocation();
|
||||||
|
|||||||
@@ -494,7 +494,7 @@ namespace MobileGL {
|
|||||||
return MG_State::pGLContext->ValidateBufferObject(buffer) ? GL_TRUE : GL_FALSE;
|
return MG_State::pGLContext->ValidateBufferObject(buffer) ? GL_TRUE : GL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BindBufferBase_State(GLenum target, GLuint index, GLuint buffer) {
|
void BindBufferBase_State(GLenum target, GLuint pointIndex, GLuint buffer) {
|
||||||
BufferTarget bufferTarget = MG_Util::ConvertGLEnumToBufferTarget(target);
|
BufferTarget bufferTarget = MG_Util::ConvertGLEnumToBufferTarget(target);
|
||||||
if (!BufferImpl::ValidateBufferBindingPointTarget(bufferTarget)) return;
|
if (!BufferImpl::ValidateBufferBindingPointTarget(bufferTarget)) return;
|
||||||
|
|
||||||
@@ -504,7 +504,7 @@ namespace MobileGL {
|
|||||||
bufferObject = MG_State::pGLContext->GetBufferObject(buffer);
|
bufferObject = MG_State::pGLContext->GetBufferObject(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& point = MG_State::pGLContext->GetBufferBindingPoint(bufferTarget, index);
|
auto& point = MG_State::pGLContext->GetBufferBindingPoint(bufferTarget, pointIndex);
|
||||||
point.Bind(bufferObject);
|
point.Bind(bufferObject);
|
||||||
point.ClearRange();
|
point.ClearRange();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ namespace MobileGL {
|
|||||||
auto programObject = TryToGetProgramObject(program);
|
auto programObject = TryToGetProgramObject(program);
|
||||||
if (!programObject) return;
|
if (!programObject) return;
|
||||||
|
|
||||||
|
MGLOG_D("%s: loc %02d = \"%s\"", __func__, index, name);
|
||||||
programObject->SetExplicitAttribLocation(index, name);
|
programObject->SetExplicitAttribLocation(index, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,43 +232,55 @@ namespace MobileGL {
|
|||||||
switch (pname) {
|
switch (pname) {
|
||||||
case GL_DELETE_STATUS:
|
case GL_DELETE_STATUS:
|
||||||
*params = programObject->GetDeleteStatus();
|
*params = programObject->GetDeleteStatus();
|
||||||
|
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
|
||||||
break;
|
break;
|
||||||
case GL_LINK_STATUS:
|
case GL_LINK_STATUS:
|
||||||
*params = programObject->GetLinkStatus();
|
*params = programObject->GetLinkStatus();
|
||||||
|
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
|
||||||
break;
|
break;
|
||||||
case GL_VALIDATE_STATUS:
|
case GL_VALIDATE_STATUS:
|
||||||
*params = programObject->GetValidateStatus();
|
*params = programObject->GetValidateStatus();
|
||||||
|
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
|
||||||
break;
|
break;
|
||||||
case GL_INFO_LOG_LENGTH: {
|
case GL_INFO_LOG_LENGTH: {
|
||||||
const auto& log = programObject->GetInfoLog();
|
const auto& log = programObject->GetInfoLog();
|
||||||
*params = log.length();
|
*params = log.length();
|
||||||
|
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GL_ATTACHED_SHADERS: {
|
case GL_ATTACHED_SHADERS: {
|
||||||
const auto& attachedShaders = programObject->GetAttachedShaders();
|
const auto& attachedShaders = programObject->GetAttachedShaders();
|
||||||
*params = attachedShaders.size();
|
*params = attachedShaders.size();
|
||||||
|
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
|
case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
|
||||||
*params = programObject->GetActiveAtomicCounterCount();
|
*params = programObject->GetActiveAtomicCounterCount();
|
||||||
|
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
|
||||||
break;
|
break;
|
||||||
case GL_ACTIVE_ATTRIBUTES:
|
case GL_ACTIVE_ATTRIBUTES:
|
||||||
*params = programObject->GetActiveAttributesCount();
|
*params = programObject->GetActiveAttributesCount();
|
||||||
|
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
|
||||||
break;
|
break;
|
||||||
case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
|
case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
|
||||||
*params = programObject->GetActiveAttributesMaxLength();
|
*params = programObject->GetActiveAttributesMaxLength();
|
||||||
|
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
|
||||||
break;
|
break;
|
||||||
case GL_ACTIVE_UNIFORMS:
|
case GL_ACTIVE_UNIFORMS:
|
||||||
*params = programObject->GetUniformCount();
|
*params = programObject->GetUniformCount();
|
||||||
|
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
|
||||||
break;
|
break;
|
||||||
case GL_ACTIVE_UNIFORM_MAX_LENGTH:
|
case GL_ACTIVE_UNIFORM_MAX_LENGTH:
|
||||||
*params = programObject->GetUniformMaxLength();
|
*params = programObject->GetUniformMaxLength();
|
||||||
|
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
|
||||||
break;
|
break;
|
||||||
case GL_ACTIVE_UNIFORM_BLOCKS: // GL >= 3.1
|
case GL_ACTIVE_UNIFORM_BLOCKS: // GL >= 3.1
|
||||||
*params = programObject->GetActiveUniformBlocksCount();
|
*params = programObject->GetActiveUniformBlocksCount();
|
||||||
|
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
|
||||||
break;
|
break;
|
||||||
case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: // ditto.
|
case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: // ditto.
|
||||||
*params = programObject->GetActiveUniformBlocksMaxNameLength();
|
*params = programObject->GetActiveUniformBlocksMaxNameLength();
|
||||||
|
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
|
||||||
break;
|
break;
|
||||||
case GL_COMPUTE_WORK_GROUP_SIZE: // GL >= 4.3
|
case GL_COMPUTE_WORK_GROUP_SIZE: // GL >= 4.3
|
||||||
|
|
||||||
@@ -280,6 +293,7 @@ namespace MobileGL {
|
|||||||
case GL_GEOMETRY_INPUT_TYPE:
|
case GL_GEOMETRY_INPUT_TYPE:
|
||||||
case GL_GEOMETRY_OUTPUT_TYPE:
|
case GL_GEOMETRY_OUTPUT_TYPE:
|
||||||
default:
|
default:
|
||||||
|
MGLOG_D("%s: %s", __func__, MG_Util::ConvertGLEnumToString(pname).c_str());
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
ErrorCode::InvalidEnum,
|
ErrorCode::InvalidEnum,
|
||||||
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`pname` is not an accepted value."));
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`pname` is not an accepted value."));
|
||||||
|
|||||||
@@ -25,6 +25,11 @@ namespace MobileGL {
|
|||||||
BindingSlot<BufferObject>& GetBindingSlot(BufferTarget target);
|
BindingSlot<BufferObject>& GetBindingSlot(BufferTarget target);
|
||||||
// For glBindBufferBase / glBindBufferRange
|
// For glBindBufferBase / glBindBufferRange
|
||||||
BindingSlotRange1D<BufferObject>& GetBindingPoint(BufferTarget target, Uint index);
|
BindingSlotRange1D<BufferObject>& GetBindingPoint(BufferTarget target, Uint index);
|
||||||
|
constexpr SizeT GetBindingPointCount(const BufferTarget target) const {
|
||||||
|
auto it = std::find(BufferBindPointTargets.begin(), BufferBindPointTargets.end(), target);
|
||||||
|
auto index = std::distance(BufferBindPointTargets.begin(), it);
|
||||||
|
return m_bufferBindPointTargets[index].size();
|
||||||
|
}
|
||||||
void MarkBufferObjectForDeletion(Uint index);
|
void MarkBufferObjectForDeletion(Uint index);
|
||||||
Bool ValidateName(Uint index) const;
|
Bool ValidateName(Uint index) const;
|
||||||
Bool ValidateBufferObject(Uint index) const;
|
Bool ValidateBufferObject(Uint index) const;
|
||||||
@@ -35,7 +40,7 @@ namespace MobileGL {
|
|||||||
Array<BindingSlot<BufferObject>, GlobalBufferTargets.size()> m_bindingSlots;
|
Array<BindingSlot<BufferObject>, GlobalBufferTargets.size()> m_bindingSlots;
|
||||||
// TODO: query the count somewhere globally?
|
// TODO: query the count somewhere globally?
|
||||||
// For glBindBufferBase / glBindBufferRange
|
// For glBindBufferBase / glBindBufferRange
|
||||||
Array<Array<BindingSlotRange1D<BufferObject>, 14>, BufferBindPointTargets.size()> m_bufferBindPointTargets;
|
Array<Array<BindingSlotRange1D<BufferObject>, 16>, BufferBindPointTargets.size()> m_bufferBindPointTargets;
|
||||||
};
|
};
|
||||||
} // namespace GLState
|
} // namespace GLState
|
||||||
} // namespace MG_State
|
} // namespace MG_State
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ namespace MobileGL {
|
|||||||
SharedPtr<BufferObject> GetBufferObject(Uint index);
|
SharedPtr<BufferObject> GetBufferObject(Uint index);
|
||||||
BindingSlot<BufferObject>& GetBufferBindingSlot(BufferTarget target);
|
BindingSlot<BufferObject>& GetBufferBindingSlot(BufferTarget target);
|
||||||
BindingSlotRange1D<BufferObject>& GetBufferBindingPoint(BufferTarget target, Uint index);
|
BindingSlotRange1D<BufferObject>& GetBufferBindingPoint(BufferTarget target, Uint index);
|
||||||
|
constexpr SizeT GetBufferBindingPointCount(BufferTarget target) const {
|
||||||
|
return m_bufferState.GetBindingPointCount(target);
|
||||||
|
}
|
||||||
SharedPtr<BufferObject> CreateBufferObject(Uint index);
|
SharedPtr<BufferObject> CreateBufferObject(Uint index);
|
||||||
void MarkBufferObjectForDeletion(Uint index);
|
void MarkBufferObjectForDeletion(Uint index);
|
||||||
Bool ValidateBufferName(Uint index) const;
|
Bool ValidateBufferName(Uint index) const;
|
||||||
|
|||||||
@@ -208,6 +208,9 @@ namespace MobileGL {
|
|||||||
auto& ubo = m_program->getUniformBlock(i);
|
auto& ubo = m_program->getUniformBlock(i);
|
||||||
m_uniformBlockNameMaxLength = std::max(m_uniformBlockNameMaxLength, (Int)ubo.name.length());
|
m_uniformBlockNameMaxLength = std::max(m_uniformBlockNameMaxLength, (Int)ubo.name.length());
|
||||||
m_uniformBlockIndexByName[ubo.name] = i;
|
m_uniformBlockIndexByName[ubo.name] = i;
|
||||||
|
// if there's binding defined in shader as layout(binding = ...),
|
||||||
|
// retrieve it here
|
||||||
|
m_uniformBlockBinding[i] = ubo.getBinding();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -103,6 +103,10 @@ namespace MobileGL {
|
|||||||
m_uniformBlockBinding[index] = binding;
|
m_uniformBlockBinding[index] = binding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Uint GetUniformBlockBinding(Uint index) const {
|
||||||
|
return m_uniformBlockBinding[index];
|
||||||
|
}
|
||||||
|
|
||||||
Vector<Vector<unsigned>>& GetGeneratedSpirv() { return m_generatedSpirv; }
|
Vector<Vector<unsigned>>& GetGeneratedSpirv() { return m_generatedSpirv; }
|
||||||
|
|
||||||
Uint GetExternalIndex() const { return m_externalIndex; }
|
Uint GetExternalIndex() const { return m_externalIndex; }
|
||||||
|
|||||||
Reference in New Issue
Block a user