[Perf|Improvement] (All): Improve performance & optimize code.

This commit is contained in:
BZLZHH
2026-02-23 16:00:38 +08:00
parent d22d2d64f2
commit 15e24cda78
81 changed files with 7685 additions and 7924 deletions
-1
View File
@@ -14,7 +14,6 @@ bugprone-forwarding-reference-overload,
bugprone-inaccurate-erase, bugprone-inaccurate-erase,
bugprone-incorrect-roundings, bugprone-incorrect-roundings,
bugprone-integer-division, bugprone-integer-division,
bugprone-lambda-function-name,
bugprone-macro-parentheses, bugprone-macro-parentheses,
bugprone-macro-repeated-side-effects, bugprone-macro-repeated-side-effects,
bugprone-misplaced-operator-in-strlen-in-alloc, bugprone-misplaced-operator-in-strlen-in-alloc,
+4 -4
View File
@@ -34,10 +34,10 @@ namespace MobileGL {
void Destroy() { void Destroy() {
MGLOG_I("MobileGL closing..."); MGLOG_I("MobileGL closing...");
glslang::FinalizeProcess(); glslang::FinalizeProcess();
delete MG_State::pGLContext; MG_State::pGLContext.reset();
delete MG_State::pEGLContext; MG_State::pEGLContext.reset();
delete MG_Impl::GLImpl::TextureImpl::pProxyTextureManager; MG_Impl::GLImpl::TextureImpl::pProxyTextureManager.reset();
delete MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo; MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo.reset();
MG_Util::Debug::Close(); MG_Util::Debug::Close();
// TODO: add and use Destroy functions for other subsystems // TODO: add and use Destroy functions for other subsystems
+134 -146
View File
@@ -8,6 +8,7 @@
#include "DirectGLES.h" #include "DirectGLES.h"
#include "EGL/egl.h" #include "EGL/egl.h"
#include "MG_Util/Types.h"
#include "Utils.h" #include "Utils.h"
#include "Managers.h" #include "Managers.h"
#include <MG_Util/Converters/GLToMG/TextureEnumConverter.h> #include <MG_Util/Converters/GLToMG/TextureEnumConverter.h>
@@ -45,7 +46,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
namespace DebugImpl { namespace DebugImpl {
#if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG #if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG
void ErrorLopper::Loop(std::function<void(GLenum)> func) { void ErrorLopper::Loop(const std::function<void(GLenum)>& func) {
GLenum err = g_GLESFuncs.glGetError(); GLenum err = g_GLESFuncs.glGetError();
while (err != GL_NO_ERROR) { while (err != GL_NO_ERROR) {
func(err); func(err);
@@ -68,14 +69,14 @@ namespace MobileGL::MG_Backend::DirectGLES {
Clear(); Clear();
} }
#else #else
void ErrorLopper::Loop(std::function<void(GLenum)> func) {} void ErrorLopper::Loop(const std::function<void(GLenum)>& func) {}
void ErrorLopper::Clear() {} void ErrorLopper::Clear() {}
ErrorLopper::ErrorLopper() {} ErrorLopper::ErrorLopper() = default;
ErrorLopper::~ErrorLopper() {} ErrorLopper::~ErrorLopper() = default;
#endif #endif
#if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG #if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG
OpenGLScopeMarker::OpenGLScopeMarker(String scopeName) { OpenGLScopeMarker::OpenGLScopeMarker(const String& scopeName) {
g_GLESFuncs.glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, -1, scopeName.c_str()); g_GLESFuncs.glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, -1, scopeName.c_str());
} }
@@ -83,7 +84,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
g_GLESFuncs.glPopDebugGroup(); g_GLESFuncs.glPopDebugGroup();
} }
#else #else
OpenGLScopeMarker::OpenGLScopeMarker(String scopeName) {} OpenGLScopeMarker::OpenGLScopeMarker(const String& scopeName) {}
OpenGLScopeMarker::~OpenGLScopeMarker() {} OpenGLScopeMarker::~OpenGLScopeMarker() {}
#endif #endif
@@ -92,18 +93,16 @@ namespace MobileGL::MG_Backend::DirectGLES {
// TODO: deletion for deleted objects // TODO: deletion for deleted objects
namespace BufferImpl { namespace BufferImpl {
void CreateAndSyncBufferObject(SharedPtr<MG_State::GLState::BufferObject>& bufferObject) { void CreateAndSyncBufferObject(const SharedPtr<MG_State::GLState::BufferObject>& bufferObject) {
if (!(bufferObject->GetChangeBits() & BufferChangeBits::DirtyBit)) return; if (!(bufferObject->GetChangeBits() & BufferChangeBits::DirtyBit)) return;
const auto& backendBufferIt = g_backendBufferObjects.find(bufferObject); const auto& backendBufferIt = g_backendBufferObjects.find(bufferObject.get());
SharedPtr<BackendBufferObject> backendBufferObject; Bool exist = (backendBufferIt != g_backendBufferObjects.end());
if (backendBufferIt == g_backendBufferObjects.end()) { auto& backendObj = exist ? backendBufferIt->second : g_backendBufferObjects[bufferObject.get()];
backendBufferObject = MakeShared<BackendBufferObject>(); if (!exist) {
g_backendBufferObjects[bufferObject] = backendBufferObject; backendObj = MakeShared<BackendBufferObject>();
} else {
backendBufferObject = backendBufferIt->second;
} }
backendBufferObject->SyncToBackend(bufferObject); backendObj->SyncToBackend(bufferObject);
} }
void SyncNeccessaryBuffers(Bool includeIBO = false, Bool includeIndirectBuffer = false) { void SyncNeccessaryBuffers(Bool includeIBO = false, Bool includeIndirectBuffer = false) {
@@ -114,9 +113,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
// 1.VBO 2.IBO (if needed) 3.UBO 4.IndirectBuffer (if needed) 5.SSBO (TODO) // 1.VBO 2.IBO (if needed) 3.UBO 4.IndirectBuffer (if needed) 5.SSBO (TODO)
// PBO is not needed since it should be handled in frontend // PBO is not needed since it should be handled in frontend
// static Vector<SharedPtr<MG_State::GLState::BufferObject>> buffersToSync;
// buffersToSync.clear();
const auto& currentVAOObject = MG_State::pGLContext->GetBoundVertexArray(); const auto& currentVAOObject = MG_State::pGLContext->GetBoundVertexArray();
if (!currentVAOObject) { if (!currentVAOObject) {
MGLOG_E("No VAO is currently bound, cannot sync necessary buffers."); MGLOG_E("No VAO is currently bound, cannot sync necessary buffers.");
@@ -126,7 +122,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// VBO // VBO
for (const auto& attrib : currentVAOObject->GetAllAttributes()) { for (const auto& attrib : currentVAOObject->GetAllAttributes()) {
if (!attrib.Enabled) continue; if (!attrib.Enabled) continue;
auto bufferObject = attrib.Buffer; auto& bufferObject = attrib.Buffer;
if (bufferObject) { if (bufferObject) {
CreateAndSyncBufferObject(bufferObject); CreateAndSyncBufferObject(bufferObject);
} }
@@ -134,7 +130,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// IBO // IBO
if (includeIBO) { if (includeIBO) {
auto possibleIBO = currentVAOObject->GetIndexBufferBindingSlot().GetBoundObject(); auto& possibleIBO = currentVAOObject->GetIndexBufferBindingSlot().GetBoundObject();
if (possibleIBO) { if (possibleIBO) {
CreateAndSyncBufferObject(possibleIBO); CreateAndSyncBufferObject(possibleIBO);
} }
@@ -142,7 +138,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// Indirect Buffer Object // Indirect Buffer Object
if (includeIndirectBuffer) { if (includeIndirectBuffer) {
auto possibleIndirectBuffer = auto& possibleIndirectBuffer =
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject(); MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::DrawIndirect).GetBoundObject();
if (possibleIndirectBuffer) { if (possibleIndirectBuffer) {
CreateAndSyncBufferObject(possibleIndirectBuffer); CreateAndSyncBufferObject(possibleIndirectBuffer);
@@ -153,7 +149,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
auto uboBindingPointCnt = MG_State::pGLContext->GetBufferBindingPointCount(BufferTarget::Uniform); auto uboBindingPointCnt = MG_State::pGLContext->GetBufferBindingPointCount(BufferTarget::Uniform);
for (SizeT i = 0; i < uboBindingPointCnt; ++i) { for (SizeT i = 0; i < uboBindingPointCnt; ++i) {
auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::Uniform, i); auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::Uniform, i);
auto obj = point.GetBoundObject(); auto& obj = point.GetBoundObject();
if (obj) { if (obj) {
CreateAndSyncBufferObject(obj); CreateAndSyncBufferObject(obj);
} }
@@ -166,42 +162,39 @@ namespace MobileGL::MG_Backend::DirectGLES {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
auto currentVAOObject = MG_State::pGLContext->GetBoundVertexArray(); auto& currentVAOObject = MG_State::pGLContext->GetBoundVertexArray();
if (!currentVAOObject) { if (!currentVAOObject) {
MGLOG_E("No VAO is currently bound, cannot sync current VAO."); MGLOG_E("No VAO is currently bound, cannot sync current VAO.");
return; return;
} }
const auto& backendVAOIt = g_backendVertexArrayObjects.find(currentVAOObject); const auto& backendVAOIt = g_backendVertexArrayObjects.find(currentVAOObject.get());
SharedPtr<VertexArrayImpl::BackendVertexArrayObject> backendVAOObject; Bool exist = (backendVAOIt != g_backendVertexArrayObjects.end());
if (backendVAOIt == g_backendVertexArrayObjects.end()) { auto& backendObj = exist ? backendVAOIt->second : g_backendVertexArrayObjects[currentVAOObject.get()];
backendVAOObject = MakeShared<VertexArrayImpl::BackendVertexArrayObject>(); if (!exist) {
g_backendVertexArrayObjects[currentVAOObject] = backendVAOObject; backendObj = MakeShared<VertexArrayImpl::BackendVertexArrayObject>();
} else {
backendVAOObject = backendVAOIt->second;
} }
backendVAOObject->SyncToBackend(currentVAOObject); backendObj->SyncToBackend(currentVAOObject);
} }
} // namespace VertexArrayImpl } // namespace VertexArrayImpl
namespace TextureImpl { namespace TextureImpl {
SharedPtr<BackendTextureObject> SyncTextureObjectToBackend( SharedPtr<BackendTextureObject>& SyncTextureObjectToBackend(
SharedPtr<MG_State::GLState::ITextureObject>& textureObject) { const SharedPtr<MG_State::GLState::ITextureObject>& textureObject) {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
const auto& backendTextureIt = g_backendTextureObjects.find(textureObject); const auto& backendTextureIt = g_backendTextureObjects.find(textureObject.get());
SharedPtr<BackendTextureObject> backendTextureObject; Bool exist = (backendTextureIt != g_backendTextureObjects.end());
if (backendTextureIt == g_backendTextureObjects.end()) { auto& backendObj = exist ? backendTextureIt->second : g_backendTextureObjects[textureObject.get()];
backendTextureObject = MakeShared<BackendTextureObject>(); if (!exist) {
g_backendTextureObjects[textureObject] = backendTextureObject; backendObj = MakeShared<BackendTextureObject>();
} else {
backendTextureObject = backendTextureIt->second;
} }
backendTextureObject->SyncTextureParamsToBackend(textureObject); backendObj->SyncTextureParamsToBackend(textureObject);
backendTextureObject->SyncBuiltinSamplerToBackend(textureObject); backendObj->SyncBuiltinSamplerToBackend(textureObject);
backendTextureObject->SyncMipmapsToBackend(textureObject); backendObj->SyncMipmapsToBackend(textureObject);
return backendTextureObject;
return backendObj;
} }
void SyncNeccessaryTextures() { void SyncNeccessaryTextures() {
@@ -216,7 +209,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
for (int index = 0; index < MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS; ++index) { for (int index = 0; index < MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS; ++index) {
auto& unit = MG_State::pGLContext->GetTextureUnitObject(index); auto& unit = MG_State::pGLContext->GetTextureUnitObject(index);
for (const auto& bindingSlot : unit.GetAllBindingSlots()) { for (const auto& bindingSlot : unit.GetAllBindingSlots()) {
auto textureObject = bindingSlot.GetBoundObject(); auto& textureObject = bindingSlot.GetBoundObject();
if (textureObject) { if (textureObject) {
SyncTextureObjectToBackend(textureObject); SyncTextureObjectToBackend(textureObject);
} }
@@ -228,7 +221,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
if (currentFBO) { if (currentFBO) {
for (const auto& attachment : currentFBO->GetAllAttachmentObjects()) { for (const auto& attachment : currentFBO->GetAllAttachmentObjects()) {
if (!attachment.IsTexture()) continue; if (!attachment.IsTexture()) continue;
auto textureObject = attachment.GetTexture(); auto& textureObject = attachment.GetTexture();
if (textureObject) { if (textureObject) {
SyncTextureObjectToBackend(textureObject); SyncTextureObjectToBackend(textureObject);
} }
@@ -246,12 +239,12 @@ namespace MobileGL::MG_Backend::DirectGLES {
MG_State::GLState::FramebufferObject* lastUpdatedFBO = nullptr; MG_State::GLState::FramebufferObject* lastUpdatedFBO = nullptr;
for (auto target : fboTargets) { for (auto& target : fboTargets) {
auto slot = MG_State::pGLContext->GetFramebufferBindingSlot(target); auto& slot = MG_State::pGLContext->GetFramebufferBindingSlot(target);
auto version = slot.GetVersion(); auto version = slot.GetVersion();
if (version == g_fboBindVersions[SizeT(target)]) continue; if (version == g_fboBindVersions[SizeT(target)]) continue;
auto currentFBO = slot.GetBoundObject(); auto& currentFBO = slot.GetBoundObject();
if (!currentFBO) { if (!currentFBO) {
MGLOG_E("No FBO is currently bound, cannot sync current FBO."); MGLOG_E("No FBO is currently bound, cannot sync current FBO.");
@@ -263,21 +256,19 @@ namespace MobileGL::MG_Backend::DirectGLES {
continue; continue;
} }
const auto& backendFBOIt = g_backendFramebufferObjects.find(currentFBO);
SharedPtr<BackendFramebufferObject> backendFBOObject;
if (backendFBOIt == g_backendFramebufferObjects.end()) {
backendFBOObject = MakeShared<BackendFramebufferObject>();
g_backendFramebufferObjects[currentFBO] = backendFBOObject;
} else {
backendFBOObject = backendFBOIt->second;
}
if (currentFBO.get() == lastUpdatedFBO) { if (currentFBO.get() == lastUpdatedFBO) {
MGLOG_D("Draw FBO and read FBO are the same, skipping sync."); MGLOG_D("Draw FBO and read FBO are the same, skipping sync.");
} else { continue;
backendFBOObject->SyncToBackend(currentFBO, target);
} }
const auto& backendFBOIt = g_backendFramebufferObjects.find(currentFBO.get());
Bool exist = (backendFBOIt != g_backendFramebufferObjects.end());
auto& backendObj = exist ? backendFBOIt->second : g_backendFramebufferObjects[currentFBO.get()];
if (!exist) {
backendObj = MakeShared<BackendFramebufferObject>();
}
backendObj->SyncToBackend(currentFBO, target);
lastUpdatedFBO = currentFBO.get(); lastUpdatedFBO = currentFBO.get();
} }
} }
@@ -466,21 +457,20 @@ namespace MobileGL::MG_Backend::DirectGLES {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
auto currentProgram = MG_State::pGLContext->GetCurrentProgram(); auto& currentProgram = MG_State::pGLContext->GetCurrentProgram();
if (!currentProgram || !currentProgram->GetLinkStatus()) { if (!currentProgram || !currentProgram->GetLinkStatus()) {
g_GLESFuncs.glUseProgram(0); g_GLESFuncs.glUseProgram(0);
return; return;
} }
const auto& backendProgramIt = g_backendProgramObjects.find(currentProgram); const auto& backendProgramIt = g_backendProgramObjects.find(currentProgram.get());
SharedPtr<BackendProgramObjectImpl> backendProgram; Bool exist = (backendProgramIt != g_backendProgramObjects.end());
if (backendProgramIt == g_backendProgramObjects.end()) { auto& backendObj = exist ? backendProgramIt->second : g_backendProgramObjects[currentProgram.get()];
backendProgram = MakeShared<BackendProgramObjectImpl>(); if (!exist) {
g_backendProgramObjects[currentProgram] = backendProgram; backendObj = MakeShared<BackendProgramObjectImpl>();
backendProgram->SyncToBackend(currentProgram); backendObj->SyncToBackend(currentProgram);
} else { } else {
backendProgram = backendProgramIt->second; if (!backendObj->GetBackendProgramId()) {
if (!backendProgram->GetBackendProgramId()) { backendObj->SyncToBackend(currentProgram);
backendProgram->SyncToBackend(currentProgram);
} }
} }
} }
@@ -495,7 +485,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
const auto& currentFBO = slot.GetBoundObject(); const auto& currentFBO = slot.GetBoundObject();
if (currentFBO && currentFBO != MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo->defaultFBO) { if (currentFBO && currentFBO != MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo->defaultFBO) {
const auto& backendFBOIt = FramebufferImpl::g_backendFramebufferObjects.find(currentFBO); const auto& backendFBOIt = FramebufferImpl::g_backendFramebufferObjects.find(currentFBO.get());
if (backendFBOIt != FramebufferImpl::g_backendFramebufferObjects.end()) { if (backendFBOIt != FramebufferImpl::g_backendFramebufferObjects.end()) {
backendFBOIt->second->Bind(target); backendFBOIt->second->Bind(target);
} else { } else {
@@ -528,7 +518,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
#endif #endif
const auto& currentVAO = MG_State::pGLContext->GetBoundVertexArray(); const auto& currentVAO = MG_State::pGLContext->GetBoundVertexArray();
if (currentVAO) { if (currentVAO) {
const auto& backendVAOIt = VertexArrayImpl::g_backendVertexArrayObjects.find(currentVAO); const auto& backendVAOIt = VertexArrayImpl::g_backendVertexArrayObjects.find(currentVAO.get());
if (backendVAOIt != VertexArrayImpl::g_backendVertexArrayObjects.end()) { if (backendVAOIt != VertexArrayImpl::g_backendVertexArrayObjects.end()) {
backendVAOIt->second->Bind(); backendVAOIt->second->Bind();
} }
@@ -556,7 +546,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
MG_Util::ConvertTextureTargetToString(target).c_str()); MG_Util::ConvertTextureTargetToString(target).c_str());
continue; continue;
} }
const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject); const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject.get());
if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) continue; if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) continue;
GLenum targetGL = MG_Util::ConvertTextureTargetToGLEnum(target); GLenum targetGL = MG_Util::ConvertTextureTargetToGLEnum(target);
@@ -566,7 +556,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// Bind sampler object if necessary // Bind sampler object if necessary
const auto& samplerObject = textureUnit.GetSamplerObject(); const auto& samplerObject = textureUnit.GetSamplerObject();
if (samplerObject) { if (samplerObject) {
const auto& backendSamplerIt = SamplerImpl::g_backendSamplerObjects.find(samplerObject); const auto& backendSamplerIt = SamplerImpl::g_backendSamplerObjects.find(samplerObject.get());
if (backendSamplerIt != SamplerImpl::g_backendSamplerObjects.end()) { if (backendSamplerIt != SamplerImpl::g_backendSamplerObjects.end()) {
backendSamplerIt->second->Bind(unit); backendSamplerIt->second->Bind(unit);
} }
@@ -581,7 +571,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedNC("BindCurrentProgram", TRACY_ZONECOLOR_BACKEND); ZoneScopedNC("BindCurrentProgram", TRACY_ZONECOLOR_BACKEND);
#endif #endif
const auto& backendProgramIt = PrgramImpl::g_backendProgramObjects.find(currentProgram); const auto& backendProgramIt = PrgramImpl::g_backendProgramObjects.find(currentProgram.get());
if (backendProgramIt != PrgramImpl::g_backendProgramObjects.end()) { if (backendProgramIt != PrgramImpl::g_backendProgramObjects.end()) {
backendProgramIt->second->Use(); backendProgramIt->second->Use();
auto backendProgramId = backendProgramIt->second->GetBackendProgramId(); auto backendProgramId = backendProgramIt->second->GetBackendProgramId();
@@ -623,11 +613,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
// Connect buffer to backend binding point // Connect buffer to backend binding point
auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::Uniform, binding); auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::Uniform, binding);
auto bufferObj = point.GetBoundObject(); auto& bufferObj = point.GetBoundObject();
auto range = point.GetRange(); auto range = point.GetRange();
if (bufferObj) { if (bufferObj) {
const auto& backendBufferIt = BufferImpl::g_backendBufferObjects.find(bufferObj); const auto& backendBufferIt = BufferImpl::g_backendBufferObjects.find(bufferObj.get());
if (backendBufferIt != BufferImpl::g_backendBufferObjects.end()) { if (backendBufferIt != BufferImpl::g_backendBufferObjects.end()) {
const auto& backendBufferObject = backendBufferIt->second; const auto& backendBufferObject = backendBufferIt->second;
backendBufferObject->Bind(GL_UNIFORM_BUFFER); backendBufferObject->Bind(GL_UNIFORM_BUFFER);
@@ -635,9 +625,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
g_GLESFuncs.glBindBufferBase(GL_UNIFORM_BUFFER, lastUBOBinding, g_GLESFuncs.glBindBufferBase(GL_UNIFORM_BUFFER, lastUBOBinding,
backendBufferObject->GetBackendBufferId()); backendBufferObject->GetBackendBufferId());
} else { } else {
g_GLESFuncs.glBindBufferRange(GL_UNIFORM_BUFFER, lastUBOBinding, g_GLESFuncs.glBindBufferRange(
backendBufferObject->GetBackendBufferId(), GL_UNIFORM_BUFFER, lastUBOBinding, backendBufferObject->GetBackendBufferId(),
range.start, range.end - range.start); (GLintptr)range.start, (GLintptr)(range.end - range.start));
} }
} else { } else {
MGLOG_E("No backend buffer found for UBO binding, cannot bind UBO."); MGLOG_E("No backend buffer found for UBO binding, cannot bind UBO.");
@@ -660,18 +650,18 @@ namespace MobileGL::MG_Backend::DirectGLES {
backendProgramIt->second->GetBackendProgramId(), name.c_str()); backendProgramIt->second->GetBackendProgramId(), name.c_str());
g_GLESFuncs.glUniform1i(locAtBackend, unit); g_GLESFuncs.glUniform1i(locAtBackend, unit);
auto samplerObject = MG_State::pGLContext->GetTextureUnitObject(unit).GetSamplerObject(); auto& samplerObject = MG_State::pGLContext->GetTextureUnitObject(unit).GetSamplerObject();
if (samplerObject) { if (samplerObject) {
const auto& backendSamplerIt = SamplerImpl::g_backendSamplerObjects.find(samplerObject); const auto& backendSamplerIt =
SharedPtr<SamplerImpl::BackendSamplerObject> backendSamplerObject; SamplerImpl::g_backendSamplerObjects.find(samplerObject.get());
if (backendSamplerIt == SamplerImpl::g_backendSamplerObjects.end()) { Bool exist = (backendSamplerIt != SamplerImpl::g_backendSamplerObjects.end());
backendSamplerObject = MakeShared<SamplerImpl::BackendSamplerObject>(); auto& backendObj = exist ? backendSamplerIt->second
SamplerImpl::g_backendSamplerObjects[samplerObject] = backendSamplerObject; : SamplerImpl::g_backendSamplerObjects[samplerObject.get()];
} else { if (!exist) {
backendSamplerObject = backendSamplerIt->second; backendObj = MakeShared<SamplerImpl::BackendSamplerObject>();
} }
backendSamplerObject->SyncToBackend(samplerObject); backendObj->SyncToBackend(samplerObject);
} else { } else {
SamplerImpl::UnbindSampler(unit); SamplerImpl::UnbindSampler(unit);
} }
@@ -845,30 +835,29 @@ namespace MobileGL::MG_Backend::DirectGLES {
#if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG && MOBILEGL_ENABLE_SCOPE_MARKER #if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG && MOBILEGL_ENABLE_SCOPE_MARKER
DebugImpl::OpenGLScopeMarker marker(__func__); DebugImpl::OpenGLScopeMarker marker(__func__);
#endif #endif
DebugImpl::ErrorLopper errorLopper;
TextureImpl::SyncNeccessaryTextures(); TextureImpl::SyncNeccessaryTextures();
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
FramebufferImpl::SyncCurrentFBO(); FramebufferImpl::SyncCurrentFBO();
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
RenderStateImpl::SyncRenderState(); RenderStateImpl::SyncRenderState();
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
BindCurrentFBO(FramebufferTarget::Draw); BindCurrentFBO(FramebufferTarget::Draw);
BindCurrentFBO(FramebufferTarget::Read); BindCurrentFBO(FramebufferTarget::Read);
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
MGLOG_D("ES %s(%d, %d, %d, %d, %d, %d, %d, %d, 0x%x, %s)", __func__, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, MGLOG_D("ES %s(%d, %d, %d, %d, %d, %d, %d, %d, 0x%x, %s)", __func__, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
dstX1, dstY1, mask, MG_Util::ConvertGLEnumToString(filter).c_str()); dstX1, dstY1, mask, MG_Util::ConvertGLEnumToString(filter).c_str());
g_GLESFuncs.glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); g_GLESFuncs.glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
} }
@@ -895,15 +884,14 @@ namespace MobileGL::MG_Backend::DirectGLES {
MG_Util::ConvertTextureTargetToString(textureTarget).c_str()); MG_Util::ConvertTextureTargetToString(textureTarget).c_str());
} }
const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject); const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject.get());
SharedPtr<TextureImpl::BackendTextureObject> backendTextureObject; Bool exist = (backendTextureIt != TextureImpl::g_backendTextureObjects.end());
if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) { auto& backendObj =
backendTextureObject = MakeShared<TextureImpl::BackendTextureObject>(); exist ? backendTextureIt->second : TextureImpl::g_backendTextureObjects[textureObject.get()];
TextureImpl::g_backendTextureObjects[textureObject] = backendTextureObject; if (!exist) {
} else { backendObj = MakeShared<TextureImpl::BackendTextureObject>();
backendTextureObject = backendTextureIt->second;
} }
backendTextureObject->Bind(target, unit); backendObj->Bind(target, unit);
} }
return true; return true;
} }
@@ -953,15 +941,15 @@ namespace MobileGL::MG_Backend::DirectGLES {
DebugImpl::ErrorLopper errorLopper; DebugImpl::ErrorLopper errorLopper;
MGLOG_D("%s: Backend", __func__); MGLOG_D("%s: Backend", __func__);
TextureImpl::SyncNeccessaryTextures(); TextureImpl::SyncNeccessaryTextures();
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
FramebufferImpl::SyncCurrentFBO(); FramebufferImpl::SyncCurrentFBO();
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
RenderStateImpl::SyncRenderState(); RenderStateImpl::SyncRenderState();
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
if (!UpdateTextureBindingAtTarget(target)) return; if (!UpdateTextureBindingAtTarget(target)) return;
@@ -969,10 +957,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
// Bind necessary FBO and texture // Bind necessary FBO and texture
BindCurrentFBO(FramebufferTarget::Read); BindCurrentFBO(FramebufferTarget::Read);
Uint activeTextureUnit = MG_State::pGLContext->GetActiveTextureUnit(); Uint activeTextureUnit = MG_State::pGLContext->GetActiveTextureUnit();
const auto& textureObject = MG_State::pGLContext->GetTextureUnitObject(activeTextureUnit) const auto& textureObject = MG_State::pGLContext->GetTextureUnitObject((Int)activeTextureUnit)
.GetBindingSlot(MG_Util::ConvertGLEnumToTextureTarget(target)) .GetBindingSlot(MG_Util::ConvertGLEnumToTextureTarget(target))
.GetBoundObject(); .GetBoundObject();
const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject); const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject.get());
if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) { if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) {
MGLOG_E("CopyTexSubImage2D: No backend texture found for texture %u.", MGLOG_E("CopyTexSubImage2D: No backend texture found for texture %u.",
textureObject ? textureObject->GetExternalIndex() : 0); textureObject ? textureObject->GetExternalIndex() : 0);
@@ -998,19 +986,19 @@ namespace MobileGL::MG_Backend::DirectGLES {
if (!isDepthFormat) { if (!isDepthFormat) {
g_GLESFuncs.glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); g_GLESFuncs.glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
} else { } else {
MGLOG_D("%s: Backend depth", __func__); MGLOG_D("%s: Backend depth", __func__);
g_GLESFuncs.glTexImage2D(target, level, (GLint)internalformat, width, height, border, format, type, g_GLESFuncs.glTexImage2D(target, level, (GLint)internalformat, width, height, border, format, type,
nullptr); nullptr);
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
GLint currentTex = backendTextureIt->second->GetBackendTextureId(); auto currentTex = (GLint)backendTextureIt->second->GetBackendTextureId();
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
@@ -1026,7 +1014,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
g_GLESFuncs.glBlitFramebuffer(x, y, x + width, y + height, 0, 0, width, height, g_GLESFuncs.glBlitFramebuffer(x, y, x + width, y + height, 0, 0, width, height,
GL_DEPTH_BUFFER_BIT | (isStencilFormat ? GL_STENCIL_BUFFER_BIT : 0), GL_DEPTH_BUFFER_BIT | (isStencilFormat ? GL_STENCIL_BUFFER_BIT : 0),
GL_NEAREST); GL_NEAREST);
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
} }
@@ -1041,15 +1029,15 @@ namespace MobileGL::MG_Backend::DirectGLES {
MGLOG_D("%s: Backend", __func__); MGLOG_D("%s: Backend", __func__);
TextureImpl::SyncNeccessaryTextures(); TextureImpl::SyncNeccessaryTextures();
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
FramebufferImpl::SyncCurrentFBO(); FramebufferImpl::SyncCurrentFBO();
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
RenderStateImpl::SyncRenderState(); RenderStateImpl::SyncRenderState();
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
@@ -1057,11 +1045,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
// Bind necessary FBO and texture // Bind necessary FBO and texture
BindCurrentFBO(FramebufferTarget::Read); BindCurrentFBO(FramebufferTarget::Read);
Uint activeTextureUnit = MG_State::pGLContext->GetActiveTextureUnit(); auto activeTextureUnit = MG_State::pGLContext->GetActiveTextureUnit();
const auto& textureObject = MG_State::pGLContext->GetTextureUnitObject(activeTextureUnit) const auto& textureObject = MG_State::pGLContext->GetTextureUnitObject(activeTextureUnit)
.GetBindingSlot(MG_Util::ConvertGLEnumToTextureTarget(target)) .GetBindingSlot(MG_Util::ConvertGLEnumToTextureTarget(target))
.GetBoundObject(); .GetBoundObject();
const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject); const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject.get());
if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) { if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) {
MGLOG_E("CopyTexSubImage2D: No backend texture found for texture %u.", MGLOG_E("CopyTexSubImage2D: No backend texture found for texture %u.",
textureObject ? textureObject->GetExternalIndex() : 0); textureObject ? textureObject->GetExternalIndex() : 0);
@@ -1069,12 +1057,12 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
backendTextureIt->second->Bind(target, activeTextureUnit); backendTextureIt->second->Bind(target, activeTextureUnit);
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
GLenum internalFormat; GLenum internalFormat;
g_GLESFuncs.glGetTexLevelParameteriv(target, level, GL_TEXTURE_INTERNAL_FORMAT, (GLint*)&internalFormat); g_GLESFuncs.glGetTexLevelParameteriv(target, level, GL_TEXTURE_INTERNAL_FORMAT, (GLint*)&internalFormat);
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
auto mgInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalFormat); auto mgInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalFormat);
@@ -1084,19 +1072,19 @@ namespace MobileGL::MG_Backend::DirectGLES {
if (!isDepthFormat) { if (!isDepthFormat) {
g_GLESFuncs.glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); g_GLESFuncs.glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
} else { } else {
MGLOG_D("%s: Backend depth", __func__); MGLOG_D("%s: Backend depth", __func__);
GLint currentTex = backendTextureIt->second->GetBackendTextureId(); auto currentTex = backendTextureIt->second->GetBackendTextureId();
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
GLenum attachment = isStencilFormat ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT; GLenum attachment = isStencilFormat ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
TempFBOBinder tempFBOBinder(false); TempFBOBinder tempFBOBinder(false);
g_GLESFuncs.glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, target, currentTex, level); g_GLESFuncs.glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, target, currentTex, level);
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
if (g_GLESFuncs.glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { if (g_GLESFuncs.glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
@@ -1107,7 +1095,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
g_GLESFuncs.glBlitFramebuffer( g_GLESFuncs.glBlitFramebuffer(
x, y, x + width, y + height, xoffset, yoffset, xoffset + width, yoffset + height, x, y, x + width, y + height, xoffset, yoffset, xoffset + width, yoffset + height,
GL_DEPTH_BUFFER_BIT | (isStencilFormat ? GL_STENCIL_BUFFER_BIT : 0), GL_NEAREST); GL_DEPTH_BUFFER_BIT | (isStencilFormat ? GL_STENCIL_BUFFER_BIT : 0), GL_NEAREST);
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
} }
@@ -1120,8 +1108,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
auto unitIndex = MG_State::pGLContext->GetActiveTextureUnit(); auto unitIndex = MG_State::pGLContext->GetActiveTextureUnit();
auto& unit = MG_State::pGLContext->GetTextureUnitObject(unitIndex); auto& unit = MG_State::pGLContext->GetTextureUnitObject(unitIndex);
auto& slot = unit.GetBindingSlot(MG_Util::ConvertGLEnumToTextureTarget(target)); auto& slot = unit.GetBindingSlot(MG_Util::ConvertGLEnumToTextureTarget(target));
auto texture = slot.GetBoundObject(); auto& texture = slot.GetBoundObject();
auto backendTexture = TextureImpl::SyncTextureObjectToBackend(texture); auto& backendTexture = TextureImpl::SyncTextureObjectToBackend(texture);
backendTexture->Bind(target, unitIndex); backendTexture->Bind(target, unitIndex);
g_GLESFuncs.glGenerateMipmap(target); g_GLESFuncs.glGenerateMipmap(target);
@@ -1184,7 +1172,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
PixelStoreParameters m_prevParams; PixelStoreParameters m_prevParams;
PixelStoreParameters QueryCurrentGLPixelStoreParams(Bool isUnpack) { static PixelStoreParameters QueryCurrentGLPixelStoreParams(Bool isUnpack) {
PixelStoreParameters p; PixelStoreParameters p;
if (!isUnpack) { if (!isUnpack) {
g_GLESFuncs.glGetIntegerv(GL_PACK_ALIGNMENT, (GLint*)&p.Alignment); g_GLESFuncs.glGetIntegerv(GL_PACK_ALIGNMENT, (GLint*)&p.Alignment);
@@ -1214,7 +1202,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
return p; return p;
} }
void Sync(Bool isUnpack, const PixelStoreParameters& params) { static void Sync(Bool isUnpack, const PixelStoreParameters& params) {
if (!isUnpack) { if (!isUnpack) {
g_GLESFuncs.glPixelStorei(GL_PACK_ALIGNMENT, params.Alignment); g_GLESFuncs.glPixelStorei(GL_PACK_ALIGNMENT, params.Alignment);
g_GLESFuncs.glPixelStorei(GL_PACK_ROW_LENGTH, params.RowLength); g_GLESFuncs.glPixelStorei(GL_PACK_ROW_LENGTH, params.RowLength);
@@ -1271,7 +1259,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
// Handle PBO // Handle PBO
auto pixelPackBufferObject = auto& pixelPackBufferObject =
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject();
Bool usePBO; Bool usePBO;
GLuint prevPixelPackBuffer = 0; GLuint prevPixelPackBuffer = 0;
@@ -1279,7 +1267,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
BufferImpl::CreateAndSyncBufferObject(pixelPackBufferObject); BufferImpl::CreateAndSyncBufferObject(pixelPackBufferObject);
MGLOG_D("ReadPixels: Using PBO %u", pixelPackBufferObject->GetExternalIndex()); MGLOG_D("ReadPixels: Using PBO %u", pixelPackBufferObject->GetExternalIndex());
usePBO = true; usePBO = true;
const auto& backendBufferIt = BufferImpl::g_backendBufferObjects.find(pixelPackBufferObject); const auto& backendBufferIt = BufferImpl::g_backendBufferObjects.find(pixelPackBufferObject.get());
if (backendBufferIt == BufferImpl::g_backendBufferObjects.end()) { if (backendBufferIt == BufferImpl::g_backendBufferObjects.end()) {
MGLOG_E("ReadPixels: No backend buffer found for PBO %u.", MGLOG_E("ReadPixels: No backend buffer found for PBO %u.",
@@ -1299,8 +1287,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
if (usePBO) { if (usePBO) {
// pull back to client memory if PBO is used // pull back to client memory if PBO is used
MGLOG_D("ReadPixels: PBO used, mapping buffer to client memory"); MGLOG_D("ReadPixels: PBO used, mapping buffer to client memory");
GLvoid* pboMappedPtr = g_GLESFuncs.glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, GLvoid* pboMappedPtr = g_GLESFuncs.glMapBufferRange(
pixelPackBufferObject->GetSize(), GL_MAP_READ_BIT); GL_PIXEL_PACK_BUFFER, 0, (GLsizeiptr)pixelPackBufferObject->GetSize(), GL_MAP_READ_BIT);
if (pboMappedPtr) { if (pboMappedPtr) {
MGLOG_D("ReadPixels: Copying data from PBO to client memory"); MGLOG_D("ReadPixels: Copying data from PBO to client memory");
SizeT size = pixelPackBufferObject->GetSize(); SizeT size = pixelPackBufferObject->GetSize();
@@ -1345,7 +1333,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
MGLOG_D("GetTexImage: SyncCurrentFBO()"); MGLOG_D("GetTexImage: SyncCurrentFBO()");
FramebufferImpl::SyncCurrentFBO(); FramebufferImpl::SyncCurrentFBO();
Uint activeTextureUnit = MG_State::pGLContext->GetActiveTextureUnit(); auto activeTextureUnit = MG_State::pGLContext->GetActiveTextureUnit();
MGLOG_D("GetTexImage: active texture unit = %u", activeTextureUnit); MGLOG_D("GetTexImage: active texture unit = %u", activeTextureUnit);
const auto& textureObject = MG_State::pGLContext->GetTextureUnitObject(activeTextureUnit) const auto& textureObject = MG_State::pGLContext->GetTextureUnitObject(activeTextureUnit)
@@ -1355,7 +1343,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
MGLOG_D("GetTexImage: bound texture object = %p (name=%u)", textureObject.get(), MGLOG_D("GetTexImage: bound texture object = %p (name=%u)", textureObject.get(),
textureObject ? textureObject->GetExternalIndex() : 0); textureObject ? textureObject->GetExternalIndex() : 0);
const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject); const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject.get());
if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) { if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) {
MGLOG_E("GetTexImage: No backend texture found for texture %u.", MGLOG_E("GetTexImage: No backend texture found for texture %u.",
@@ -1383,14 +1371,14 @@ namespace MobileGL::MG_Backend::DirectGLES {
return; return;
} }
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
MGLOG_D("GetTexImage: Applying TempPixelStoreParameterSync (PACK)"); MGLOG_D("GetTexImage: Applying TempPixelStoreParameterSync (PACK)");
TempPixelStoreParameterSync tempPackParamsSync(false); TempPixelStoreParameterSync tempPackParamsSync(false);
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
@@ -1402,9 +1390,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
return; return;
} }
auto* textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get()); auto* textureMipmapObject = dynamic_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
auto levelRange = textureMipmapObject->GetLevelRange(); auto& levelRange = textureMipmapObject->GetLevelRange();
MGLOG_D("GetTexImage: mipmap level range = [%d, %d)", levelRange.x(), levelRange.y()); MGLOG_D("GetTexImage: mipmap level range = [%d, %d)", levelRange.x(), levelRange.y());
if (level < levelRange.x() || level >= levelRange.y()) { if (level < levelRange.x() || level >= levelRange.y()) {
@@ -1421,7 +1409,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
MGLOG_D("GetTexImage: mip level %d size = %dx%d", level, size.x(), size.y()); MGLOG_D("GetTexImage: mip level %d size = %dx%d", level, size.x(), size.y());
// Handle PBO // Handle PBO
auto pixelPackBufferObject = auto& pixelPackBufferObject =
MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject();
Bool usePBO; Bool usePBO;
GLuint prevPixelPackBuffer = 0; GLuint prevPixelPackBuffer = 0;
@@ -1429,7 +1417,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
BufferImpl::CreateAndSyncBufferObject(pixelPackBufferObject); BufferImpl::CreateAndSyncBufferObject(pixelPackBufferObject);
MGLOG_D("GetTexImage: Using PBO %u", pixelPackBufferObject->GetExternalIndex()); MGLOG_D("GetTexImage: Using PBO %u", pixelPackBufferObject->GetExternalIndex());
usePBO = true; usePBO = true;
const auto& backendBufferIt = BufferImpl::g_backendBufferObjects.find(pixelPackBufferObject); const auto& backendBufferIt = BufferImpl::g_backendBufferObjects.find(pixelPackBufferObject.get());
if (backendBufferIt == BufferImpl::g_backendBufferObjects.end()) { if (backendBufferIt == BufferImpl::g_backendBufferObjects.end()) {
MGLOG_E("GetTexImage: No backend buffer found for PBO %u.", MGLOG_E("GetTexImage: No backend buffer found for PBO %u.",
pixelPackBufferObject ? pixelPackBufferObject->GetExternalIndex() : 0); pixelPackBufferObject ? pixelPackBufferObject->GetExternalIndex() : 0);
@@ -1443,7 +1431,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
MGLOG_D("GetTexImage: Not using PBO"); MGLOG_D("GetTexImage: Not using PBO");
} }
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
MGLOG_D("GetTexImage: glReadPixels(0, 0, %d, %d, %s, %s, %p)", size.x(), size.y(), MGLOG_D("GetTexImage: glReadPixels(0, 0, %d, %d, %s, %s, %p)", size.x(), size.y(),
@@ -1451,14 +1439,14 @@ namespace MobileGL::MG_Backend::DirectGLES {
pixels); pixels);
g_GLESFuncs.glReadPixels(0, 0, size.x(), size.y(), esFormat, esType, pixels); g_GLESFuncs.glReadPixels(0, 0, size.x(), size.y(), esFormat, esType, pixels);
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
if (usePBO) { if (usePBO) {
// pull back to client memory if PBO is used // pull back to client memory if PBO is used
MGLOG_D("ReadPixels: PBO used, mapping buffer to client memory"); MGLOG_D("ReadPixels: PBO used, mapping buffer to client memory");
GLvoid* pboMappedPtr = g_GLESFuncs.glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, GLvoid* pboMappedPtr = g_GLESFuncs.glMapBufferRange(
pixelPackBufferObject->GetSize(), GL_MAP_READ_BIT); GL_PIXEL_PACK_BUFFER, 0, (GLsizeiptr)pixelPackBufferObject->GetSize(), GL_MAP_READ_BIT);
if (pboMappedPtr) { if (pboMappedPtr) {
MGLOG_D("ReadPixels: Copying data from PBO to client memory"); MGLOG_D("ReadPixels: Copying data from PBO to client memory");
SizeT size = pixelPackBufferObject->GetSize(); SizeT size = pixelPackBufferObject->GetSize();
@@ -1479,7 +1467,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
} }
errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__](auto err) {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
MGLOG_D("GetTexImage: finished"); MGLOG_D("GetTexImage: finished");
+104 -105
View File
@@ -7,10 +7,6 @@
// End of Source File Header // End of Source File Header
#include "Managers.h" #include "Managers.h"
#include "MG_State/GLState/TextureState/TextureEnum.h"
#include "MG_State/GLState/TextureState/TextureObject.h"
#include "MG_State/GLState/TextureState/TextureState.h"
#include "MG_Util/Converters/GLToMG/TextureEnumConverter.h"
#include "Utils.h" #include "Utils.h"
#include "DirectGLES.h" #include "DirectGLES.h"
@@ -18,6 +14,7 @@
#include <MG_Util/Converters/GLToStr/GLEnumConverter.h> #include <MG_Util/Converters/GLToStr/GLEnumConverter.h>
#include <MG_Util/Converters/MGToGL/DataTypeConverter.h> #include <MG_Util/Converters/MGToGL/DataTypeConverter.h>
#include <MG_Util/Converters/MGToGL/BufferEnumConverter.h> #include <MG_Util/Converters/MGToGL/BufferEnumConverter.h>
#include <MG_Util/Converters/GLToMG/TextureEnumConverter.h>
#include <MG_Util/Converters/MGToGL/ProgramEnumConverter.h> #include <MG_Util/Converters/MGToGL/ProgramEnumConverter.h>
#include <MG_Util/Converters/MGToGL/TextureEnumConverter.h> #include <MG_Util/Converters/MGToGL/TextureEnumConverter.h>
#include <MG_Util/Converters/MGToStr/TextureEnumConverter.h> #include <MG_Util/Converters/MGToStr/TextureEnumConverter.h>
@@ -44,7 +41,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
} }
void BackendBufferObject::SyncToBackend(SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject) { void BackendBufferObject::SyncToBackend(const SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject) {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
@@ -105,7 +102,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
void BackendBufferObject::SyncToBackend_glBufferData( void BackendBufferObject::SyncToBackend_glBufferData(
SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject) { const SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject) {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
@@ -117,11 +114,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
GLenum usage = MG_Util::ConvertBufferUsageToGLEnum(stateBufferObject->GetUsage()); GLenum usage = MG_Util::ConvertBufferUsageToGLEnum(stateBufferObject->GetUsage());
Bind(); Bind();
g_GLESFuncs.glBufferData(TempBufferTarget, size, data, usage); g_GLESFuncs.glBufferData(TempBufferTarget, (GLsizeiptr)size, data, usage);
} }
void BackendBufferObject::SyncToBackend_glBufferSubData( void BackendBufferObject::SyncToBackend_glBufferSubData(
SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject) { const SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject) {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
@@ -130,7 +127,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
const void* data = stateBufferObject->GetDataReadOnly()->data(); const void* data = stateBufferObject->GetDataReadOnly()->data();
// dirty range: [range.start, range.end) // dirty range: [range.start, range.end)
auto ranges = stateBufferObject->GetDirtyRanges(); auto& ranges = stateBufferObject->GetDirtyRanges();
if (ranges.empty()) { if (ranges.empty()) {
MGLOG_D("No dirty range to sync for buffer with ID: %u", m_backendBufferId); MGLOG_D("No dirty range to sync for buffer with ID: %u", m_backendBufferId);
return; return;
@@ -138,20 +135,21 @@ namespace MobileGL::MG_Backend::DirectGLES {
for (const auto& range : ranges) { for (const auto& range : ranges) {
Bind(); Bind();
g_GLESFuncs.glBufferSubData(TempBufferTarget, range.start, range.end - range.start, g_GLESFuncs.glBufferSubData(TempBufferTarget, (GLintptr)range.start,
(GLintptr)(range.end - range.start),
reinterpret_cast<const char*>(data) + range.start); reinterpret_cast<const char*>(data) + range.start);
} }
} }
void BackendBufferObject::SyncToBackend_glMapBufferRange( void BackendBufferObject::SyncToBackend_glMapBufferRange(
SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject, Bool invalidate, Bool unsynchronized) { const SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject, Bool invalidate, Bool unsynchronized) {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
MGLOG_D("Syncing buffer map (glMapBuffer) for object with ID : %u", m_backendBufferId); MGLOG_D("Syncing buffer map (glMapBuffer) for object with ID : %u", m_backendBufferId);
MGLOG_D("Mapping buffer with ID: %u", m_backendBufferId); MGLOG_D("Mapping buffer with ID: %u", m_backendBufferId);
auto ranges = stateBufferObject->GetDirtyRanges(); auto& ranges = stateBufferObject->GetDirtyRanges();
if (ranges.empty()) { if (ranges.empty()) {
MGLOG_D("No dirty range to sync for buffer with ID: %u", m_backendBufferId); MGLOG_D("No dirty range to sync for buffer with ID: %u", m_backendBufferId);
return; return;
@@ -159,18 +157,18 @@ namespace MobileGL::MG_Backend::DirectGLES {
SizeT minStart = ranges.GetOverallMinStart(); SizeT minStart = ranges.GetOverallMinStart();
SizeT maxEnd = ranges.GetOverallMaxEnd(); SizeT maxEnd = ranges.GetOverallMaxEnd();
Bind(); Bind();
void* mappedData = g_GLESFuncs.glMapBufferRange(TempBufferTarget, minStart, maxEnd - minStart, void* mappedData = g_GLESFuncs.glMapBufferRange(
(invalidate ? GL_MAP_INVALIDATE_RANGE_BIT : 0) | TempBufferTarget, (GLintptr)minStart, (GLintptr)(maxEnd - minStart),
(unsynchronized ? GL_MAP_UNSYNCHRONIZED_BIT : 0) | (invalidate ? GL_MAP_INVALIDATE_RANGE_BIT : 0) | (unsynchronized ? GL_MAP_UNSYNCHRONIZED_BIT : 0) |
GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
const void* data = stateBufferObject->GetDataReadOnly()->data(); const void* data = stateBufferObject->GetDataReadOnly()->data();
if (mappedData) { if (mappedData) {
MGLOG_D("Mapped buffer data successfully for object with ID: %u", m_backendBufferId); MGLOG_D("Mapped buffer data successfully for object with ID: %u", m_backendBufferId);
Memcpy(mappedData, reinterpret_cast<const char*>(data) + minStart, maxEnd - minStart); Memcpy(mappedData, reinterpret_cast<const char*>(data) + minStart, maxEnd - minStart);
// Explicitly flush the dirty ranges // Explicitly flush the dirty ranges
for (const auto& range : ranges) { for (const auto& range : ranges) {
g_GLESFuncs.glFlushMappedBufferRange(TempBufferTarget, range.start - minStart, g_GLESFuncs.glFlushMappedBufferRange(TempBufferTarget, (GLintptr)(range.start - minStart),
range.end - range.start); (GLintptr)(range.end - range.start));
} }
g_GLESFuncs.glUnmapBuffer(TempBufferTarget); g_GLESFuncs.glUnmapBuffer(TempBufferTarget);
} else { } else {
@@ -191,7 +189,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
g_GLESFuncs.glBindBuffer(target, m_backendBufferId); g_GLESFuncs.glBindBuffer(target, m_backendBufferId);
} }
UnorderedMap<SharedPtr<MG_State::GLState::BufferObject>, SharedPtr<BackendBufferObject>> g_backendBufferObjects; UnorderedMap<MG_State::GLState::BufferObject*, SharedPtr<BackendBufferObject>> g_backendBufferObjects;
BackendBufferObject* g_boundVertexBufferObject = nullptr; BackendBufferObject* g_boundVertexBufferObject = nullptr;
} // namespace BufferImpl } // namespace BufferImpl
@@ -209,22 +207,21 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
} }
void BackendVertexArrayObject::Bind() { void BackendVertexArrayObject::Bind() const {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
g_GLESFuncs.glBindVertexArray(m_backendVAOId); g_GLESFuncs.glBindVertexArray(m_backendVAOId);
} }
void BackendVertexArrayObject::BindAttributeBuffer(Uint index, inline void BindAttributeBuffer(const MG_State::GLState::VertexAttribute& attrib) {
const MG_State::GLState::VertexAttribute& attrib) {
const auto& bufferObject = attrib.Buffer; const auto& bufferObject = attrib.Buffer;
if (!bufferObject) { if (!bufferObject) {
MGLOG_W("Attribute has no bound buffer, skipping."); MGLOG_W("Attribute has no bound buffer, skipping.");
return; return;
} }
const auto& backendBufferIt = BufferImpl::g_backendBufferObjects.find(bufferObject); const auto& backendBufferIt = BufferImpl::g_backendBufferObjects.find(bufferObject.get());
if (backendBufferIt == BufferImpl::g_backendBufferObjects.end()) { if (backendBufferIt == BufferImpl::g_backendBufferObjects.end()) {
MGLOG_E("No backend buffer found for attribute's buffer, cannot bind attribute."); MGLOG_E("No backend buffer found for attribute's buffer, cannot bind attribute.");
return; return;
@@ -234,7 +231,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
backendBufferObject->Bind(GL_ARRAY_BUFFER); backendBufferObject->Bind(GL_ARRAY_BUFFER);
} }
void BackendVertexArrayObject::SyncToBackend(SharedPtr<MG_State::GLState::VertexArrayObject>& stateVAOObject) { void BackendVertexArrayObject::SyncToBackend(
const SharedPtr<MG_State::GLState::VertexArrayObject>& stateVAOObject) {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
@@ -268,7 +266,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
m_syncedAttributeVersions[attribIndex].BufferVersion; m_syncedAttributeVersions[attribIndex].BufferVersion;
if (!needsSyncFormat && !needsSyncBuffer) continue; if (!needsSyncFormat && !needsSyncBuffer) continue;
BindAttributeBuffer(attribIndex, attrib); BindAttributeBuffer(attrib);
if (!attrib.IsInteger) { if (!attrib.IsInteger) {
g_GLESFuncs.glVertexAttribPointer( g_GLESFuncs.glVertexAttribPointer(
@@ -289,7 +287,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
if (currentIndexBufferVersion != m_syncedIndexBufferVersion) { if (currentIndexBufferVersion != m_syncedIndexBufferVersion) {
const auto& indexBufferBinding = stateVAOObject->GetIndexBufferBindingSlot().GetBoundObject(); const auto& indexBufferBinding = stateVAOObject->GetIndexBufferBindingSlot().GetBoundObject();
if (indexBufferBinding) { if (indexBufferBinding) {
const auto& backendBufferIt = BufferImpl::g_backendBufferObjects.find(indexBufferBinding); const auto& backendBufferIt = BufferImpl::g_backendBufferObjects.find(indexBufferBinding.get());
if (backendBufferIt != BufferImpl::g_backendBufferObjects.end()) { if (backendBufferIt != BufferImpl::g_backendBufferObjects.end()) {
const auto& backendBufferObject = backendBufferIt->second; const auto& backendBufferObject = backendBufferIt->second;
backendBufferObject->Bind(GL_ELEMENT_ARRAY_BUFFER); backendBufferObject->Bind(GL_ELEMENT_ARRAY_BUFFER);
@@ -303,7 +301,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
m_syncedAttributeVersions = allAttributeVersions; m_syncedAttributeVersions = allAttributeVersions;
} }
UnorderedMap<SharedPtr<MG_State::GLState::VertexArrayObject>, SharedPtr<BackendVertexArrayObject>> UnorderedMap<MG_State::GLState::VertexArrayObject*, SharedPtr<BackendVertexArrayObject>>
g_backendVertexArrayObjects; g_backendVertexArrayObjects;
} // namespace VertexArrayImpl } // namespace VertexArrayImpl
@@ -336,7 +334,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
g_boundTexturesCache[unit][targetN] = this; g_boundTexturesCache[unit][targetN] = this;
} }
Uint BackendTextureObject::GetBackendTextureId() { Uint BackendTextureObject::GetBackendTextureId() const {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
@@ -344,7 +342,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
void BackendTextureObject::SyncMipmapsToBackend( void BackendTextureObject::SyncMipmapsToBackend(
SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject) { const SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject) {
if (!stateTextureObject) { if (!stateTextureObject) {
MGLOG_E("State texture object is null, cannot sync to backend."); MGLOG_E("State texture object is null, cannot sync to backend.");
return; return;
@@ -353,7 +351,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
DebugImpl::ErrorLopper errorLopper;
MGLOG_D("Syncing texture mipmaps with backend ID %u to backend for state ID %u", m_backendTextureId, MGLOG_D("Syncing texture mipmaps with backend ID %u to backend for state ID %u", m_backendTextureId,
stateTextureObject->GetExternalIndex()); stateTextureObject->GetExternalIndex());
@@ -381,7 +378,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
Bind(target); Bind(target);
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
MGLOG_D("%s(%s:%d) ES error: %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("%s(%s:%d) ES error: %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
const auto baseSize = stateTextureObject->GetBaseSize(); const auto baseSize = stateTextureObject->GetBaseSize();
@@ -394,7 +391,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
switch (stateTextureObject->GetStorageType()) { switch (stateTextureObject->GetStorageType()) {
case TextureStorageType::Mipmap: { case TextureStorageType::Mipmap: {
auto* textureMipmapObject = auto* textureMipmapObject =
static_cast<MG_State::GLState::TextureObjectMipmap*>(stateTextureObject.get()); dynamic_cast<MG_State::GLState::TextureObjectMipmap*>(stateTextureObject.get());
const auto mipmapCount = textureMipmapObject->GetMipmapLevelCount(); const auto mipmapCount = textureMipmapObject->GetMipmapLevelCount();
currentTextureInfo.mipmapLevels = mipmapCount; currentTextureInfo.mipmapLevels = mipmapCount;
@@ -414,7 +411,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
&glFormat, &glType); &glFormat, &glType);
const auto& uploadTargets = textureMipmapObject->GetUploadTargets(); const auto& uploadTargets = textureMipmapObject->GetUploadTargets();
for (auto uploadTarget : uploadTargets) { for (auto& uploadTarget : uploadTargets) {
for (SizeT level = 0; level < mipmapCount; ++level) { for (SizeT level = 0; level < mipmapCount; ++level) {
auto levelTexelSize = textureMipmapObject->GetMipmapTexelSize(uploadTarget, level); auto levelTexelSize = textureMipmapObject->GetMipmapTexelSize(uploadTarget, level);
auto levelByteSize = textureMipmapObject->GetMipmapByteSize(uploadTarget, level); auto levelByteSize = textureMipmapObject->GetMipmapByteSize(uploadTarget, level);
@@ -429,22 +426,22 @@ namespace MobileGL::MG_Backend::DirectGLES {
levelTexelSize.x(), levelTexelSize.y(), levelTexelSize.z(), levelByteSize, pData, levelTexelSize.x(), levelTexelSize.y(), levelTexelSize.z(), levelByteSize, pData,
levelDirty ? "true" : "false"); levelDirty ? "true" : "false");
errorLopper.Clear(); DebugImpl::ErrorLopper::Clear();
g_GLESFuncs.glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); g_GLESFuncs.glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
auto textureTarget = stateTextureObject->GetTarget(); auto textureTarget = stateTextureObject->GetTarget();
// TODO: handle more texture types // TODO: handle more texture types
switch (textureTarget) { switch (textureTarget) {
case TextureTarget::Texture2D: case TextureTarget::Texture2D:
case TextureTarget::TextureCubeMap: { case TextureTarget::TextureCubeMap: {
g_GLESFuncs.glTexImage2D(glUploadTarget, static_cast<GLint>(level), glInternalFormat, g_GLESFuncs.glTexImage2D(
static_cast<GLsizei>(levelTexelSize.x()), glUploadTarget, static_cast<GLint>(level), (GLint)glInternalFormat,
static_cast<GLsizei>(levelTexelSize.y()), 0, glFormat, glType, static_cast<GLsizei>(levelTexelSize.x()), static_cast<GLsizei>(levelTexelSize.y()),
pData); 0, glFormat, glType, pData);
break; break;
} }
case TextureTarget::Texture3D: { case TextureTarget::Texture3D: {
g_GLESFuncs.glTexImage3D( g_GLESFuncs.glTexImage3D(
glUploadTarget, static_cast<GLint>(level), glInternalFormat, glUploadTarget, static_cast<GLint>(level), (GLint)glInternalFormat,
static_cast<GLsizei>(levelTexelSize.x()), static_cast<GLsizei>(levelTexelSize.y()), static_cast<GLsizei>(levelTexelSize.x()), static_cast<GLsizei>(levelTexelSize.y()),
static_cast<GLsizei>(levelTexelSize.z()), 0, glFormat, glType, pData); static_cast<GLsizei>(levelTexelSize.z()), 0, glFormat, glType, pData);
break; break;
@@ -454,8 +451,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
MG_Util::ConvertTextureTargetToString(textureTarget).c_str()); MG_Util::ConvertTextureTargetToString(textureTarget).c_str());
} }
} }
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__, glUploadTarget, DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__, func = __func__,
glInternalFormat, glFormat, glType, pData](GLenum err) { glUploadTarget, glInternalFormat, glFormat, glType,
pData](GLenum err) {
MGLOG_D("%s(%s:%d) ES error: %s. glTexImage*: target=%s, internalformat=%s, format=%s, " MGLOG_D("%s(%s:%d) ES error: %s. glTexImage*: target=%s, internalformat=%s, format=%s, "
"type=%s, pixels=%p", "type=%s, pixels=%p",
func, file, line, MG_Util::ConvertGLEnumToString(err).c_str(), func, file, line, MG_Util::ConvertGLEnumToString(err).c_str(),
@@ -478,7 +476,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
TextureImpl::GenerateTextureFormatInfo(textureMipmapObject->GetFormat(), &glInternalFormat, TextureImpl::GenerateTextureFormatInfo(textureMipmapObject->GetFormat(), &glInternalFormat,
&glFormat, &glType); &glFormat, &glType);
const auto& uploadTargets = textureMipmapObject->GetUploadTargets(); const auto& uploadTargets = textureMipmapObject->GetUploadTargets();
for (auto uploadTarget : uploadTargets) { for (auto& uploadTarget : uploadTargets) {
for (SizeT level = 0; level < mipmapCount; ++level) { for (SizeT level = 0; level < mipmapCount; ++level) {
if (!textureMipmapObject->IsStorageDirty(uploadTarget, level)) { if (!textureMipmapObject->IsStorageDirty(uploadTarget, level)) {
continue; continue;
@@ -499,10 +497,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
auto glUploadTarget = MG_Util::ConvertTextureUploadTargetToGLEnum(uploadTarget); auto glUploadTarget = MG_Util::ConvertTextureUploadTargetToGLEnum(uploadTarget);
g_GLESFuncs.glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); g_GLESFuncs.glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { DebugImpl::ErrorLopper::Loop(
MGLOG_D("%s(%s:%d) ES error: %s", func, file, line, [file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("%s(%s:%d) ES error: %s", func, file, line,
}); MG_Util::ConvertGLEnumToString(err).c_str());
});
auto texelSize = textureMipmapObject->GetMipmapTexelSize(uploadTarget, level); auto texelSize = textureMipmapObject->GetMipmapTexelSize(uploadTarget, level);
g_GLESFuncs.glTexSubImage2D(glUploadTarget, static_cast<GLint>(level), 0, 0, g_GLESFuncs.glTexSubImage2D(glUploadTarget, static_cast<GLint>(level), 0, 0,
static_cast<GLsizei>(texelSize.x()), static_cast<GLsizei>(texelSize.x()),
@@ -516,9 +515,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
case TextureStorageType::Buffer: { case TextureStorageType::Buffer: {
auto* textureBufferObject = auto* textureBufferObject =
static_cast<MG_State::GLState::TextureObjectBuffer*>(stateTextureObject.get()); dynamic_cast<MG_State::GLState::TextureObjectBuffer*>(stateTextureObject.get());
auto& slot = textureBufferObject->GetBufferBindingSlot(); auto& slot = textureBufferObject->GetBufferBindingSlot();
auto buffer = slot.GetBoundObject(); auto& buffer = slot.GetBoundObject();
auto bufferIndex = buffer->GetExternalIndex(); auto bufferIndex = buffer->GetExternalIndex();
currentTextureInfo.bufferExternalIndex = bufferIndex; currentTextureInfo.bufferExternalIndex = bufferIndex;
@@ -530,10 +529,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
// Need to sync texture buffer if not synced yet // Need to sync texture buffer if not synced yet
auto& backendBuffers = BufferImpl::g_backendBufferObjects; auto& backendBuffers = BufferImpl::g_backendBufferObjects;
SharedPtr<BufferImpl::BackendBufferObject> backendBufferObject; SharedPtr<BufferImpl::BackendBufferObject> backendBufferObject;
const auto& backendBufferIt = backendBuffers.find(buffer); const auto& backendBufferIt = backendBuffers.find(buffer.get());
if (backendBufferIt == backendBuffers.end()) { if (backendBufferIt == backendBuffers.end()) {
backendBufferObject = MakeShared<BufferImpl::BackendBufferObject>(); backendBufferObject = MakeShared<BufferImpl::BackendBufferObject>();
backendBuffers[buffer] = backendBufferObject; backendBuffers[buffer.get()] = backendBufferObject;
} else { } else {
backendBufferObject = backendBufferIt->second; backendBufferObject = backendBufferIt->second;
} }
@@ -553,7 +552,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
THROW_UNIMPL_EXCEPTION; THROW_UNIMPL_EXCEPTION;
} }
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
MGLOG_D("%s(%s:%d) ES error: %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("%s(%s:%d) ES error: %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
@@ -561,11 +560,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
void BackendTextureObject::SyncBuiltinSamplerToBackend( void BackendTextureObject::SyncBuiltinSamplerToBackend(
SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject) { const SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject) {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
DebugImpl::ErrorLopper errorLopper;
if (!stateTextureObject) { if (!stateTextureObject) {
MGLOG_E("State texture object is null, cannot sync to backend."); MGLOG_E("State texture object is null, cannot sync to backend.");
return; return;
@@ -594,7 +593,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
Bind(target); Bind(target);
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
MGLOG_D("%s(%s:%d) ES error: %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("%s(%s:%d) ES error: %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
@@ -607,28 +606,29 @@ namespace MobileGL::MG_Backend::DirectGLES {
g_GLESFuncs.glTexParameteri(target, glName, \ g_GLESFuncs.glTexParameteri(target, glName, \
MG_Util::ConvertSampler##type##ToGLEnum(samplerParams.internalName)); \ MG_Util::ConvertSampler##type##ToGLEnum(samplerParams.internalName)); \
m_cacheSamplerParameters.internalName = samplerParams.internalName; \ m_cacheSamplerParameters.internalName = samplerParams.internalName; \
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__, \ DebugImpl::ErrorLopper::Loop( \
t = MG_Util::ConvertSampler##type##ToGLEnum(samplerParams.internalName)](GLenum err) { \ [file = __FILE__, line = __LINE__, func = __func__, \
MGLOG_D("%s(%s:%d) ES error %s, GL_TEXTURE_MIN_FILTER = %s", func, file, line, \ t = MG_Util::ConvertSampler##type##ToGLEnum(samplerParams.internalName)](GLenum err) { \
MG_Util::ConvertGLEnumToString(err).c_str(), MG_Util::ConvertGLEnumToString(t).c_str()); \ MGLOG_D("%s(%s:%d) ES error %s, GL_TEXTURE_MIN_FILTER = %s", func, file, line, \
}); \ MG_Util::ConvertGLEnumToString(err).c_str(), MG_Util::ConvertGLEnumToString(t).c_str()); \
}); \
} }
if (m_cacheSamplerParameters.minFilter != samplerParams.minFilter || if (m_cacheSamplerParameters.minFilter != samplerParams.minFilter ||
m_cacheSamplerParameters.mipmapMode != samplerParams.mipmapMode) { m_cacheSamplerParameters.mipmapMode != samplerParams.mipmapMode) {
g_GLESFuncs.glTexParameteri( g_GLESFuncs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
target, GL_TEXTURE_MIN_FILTER, (GLint)MG_Util::ConvertSamplerFilterModeToGLEnum(samplerParams.minFilter,
MG_Util::ConvertSamplerFilterModeToGLEnum(samplerParams.minFilter, samplerParams.mipmapMode)); samplerParams.mipmapMode));
m_cacheSamplerParameters.minFilter = samplerParams.minFilter; m_cacheSamplerParameters.minFilter = samplerParams.minFilter;
m_cacheSamplerParameters.mipmapMode = samplerParams.mipmapMode; m_cacheSamplerParameters.mipmapMode = samplerParams.mipmapMode;
} }
if (m_cacheSamplerParameters.magFilter != samplerParams.magFilter) { if (m_cacheSamplerParameters.magFilter != samplerParams.magFilter) {
g_GLESFuncs.glTexParameteri( g_GLESFuncs.glTexParameteri(
target, GL_TEXTURE_MAG_FILTER, target, GL_TEXTURE_MAG_FILTER,
MG_Util::ConvertSamplerFilterModeToGLEnum(samplerParams.magFilter, SamplerMipmapMode::None)); (GLint)MG_Util::ConvertSamplerFilterModeToGLEnum(samplerParams.magFilter, SamplerMipmapMode::None));
m_cacheSamplerParameters.magFilter = samplerParams.magFilter; m_cacheSamplerParameters.magFilter = samplerParams.magFilter;
} }
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
@@ -645,18 +645,18 @@ namespace MobileGL::MG_Backend::DirectGLES {
g_GLESFuncs.glTexParameterf(target, GL_TEXTURE_MAX_LOD, samplerParams.maxLod); g_GLESFuncs.glTexParameterf(target, GL_TEXTURE_MAX_LOD, samplerParams.maxLod);
m_cacheSamplerParameters.maxLod = samplerParams.maxLod; m_cacheSamplerParameters.maxLod = samplerParams.maxLod;
} }
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
#undef SYNC_TEX_SAMPLER_PARAM_IF_CHANGED #undef SYNC_TEX_SAMPLER_PARAM_IF_CHANGED
} }
void BackendTextureObject::SyncTextureParamsToBackend( void BackendTextureObject::SyncTextureParamsToBackend(
SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject) { const SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject) {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
DebugImpl::ErrorLopper errorLopper;
if (!stateTextureObject) { if (!stateTextureObject) {
MGLOG_E("State texture object is null, cannot sync to backend."); MGLOG_E("State texture object is null, cannot sync to backend.");
return; return;
@@ -683,7 +683,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
Bind(target); Bind(target);
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
MGLOG_D("%s(%s:%d) ES error: %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("%s(%s:%d) ES error: %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
@@ -696,14 +696,14 @@ namespace MobileGL::MG_Backend::DirectGLES {
g_GLESFuncs.glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, static_cast<GLint>(levelRange.x())); g_GLESFuncs.glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, static_cast<GLint>(levelRange.x()));
m_cacheLodRange.x() = levelRange.x(); m_cacheLodRange.x() = levelRange.x();
} }
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
if (m_cacheLodRange.y() != levelRange.y()) { if (m_cacheLodRange.y() != levelRange.y()) {
g_GLESFuncs.glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, static_cast<GLint>(levelRange.y())); g_GLESFuncs.glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, static_cast<GLint>(levelRange.y()));
m_cacheLodRange.y() = levelRange.y(); m_cacheLodRange.y() = levelRange.y();
} }
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
@@ -720,7 +720,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
SYNC_TEX_SWIZZLE_PARAM_IF_CHANGED(a(), GL_TEXTURE_SWIZZLE_A); SYNC_TEX_SWIZZLE_PARAM_IF_CHANGED(a(), GL_TEXTURE_SWIZZLE_A);
#undef SYNC_TEX_SWIZZLE_PARAM_IF_CHANGED #undef SYNC_TEX_SWIZZLE_PARAM_IF_CHANGED
m_cacheSwizzleParams = swizzleParams; m_cacheSwizzleParams = swizzleParams;
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
} }
@@ -730,7 +730,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
GLfloat borderColorArray[4] = {borderColor.x(), borderColor.y(), borderColor.z(), borderColor.w()}; GLfloat borderColorArray[4] = {borderColor.x(), borderColor.y(), borderColor.z(), borderColor.w()};
g_GLESFuncs.glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, borderColorArray); g_GLESFuncs.glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, borderColorArray);
m_cacheBorderColor = borderColor; m_cacheBorderColor = borderColor;
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str()); MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
}); });
} }
@@ -760,8 +760,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
Array<Array<BackendTextureObject*, (SizeT)TextureTarget::TextureTargetCount>, Array<Array<BackendTextureObject*, (SizeT)TextureTarget::TextureTargetCount>,
MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS> MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS>
g_boundTexturesCache; g_boundTexturesCache;
UnorderedMap<SharedPtr<MG_State::GLState::ITextureObject>, SharedPtr<BackendTextureObject>> UnorderedMap<MG_State::GLState::ITextureObject*, SharedPtr<BackendTextureObject>> g_backendTextureObjects;
g_backendTextureObjects;
} // namespace TextureImpl } // namespace TextureImpl
namespace FramebufferImpl { namespace FramebufferImpl {
@@ -778,7 +777,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
} }
void BackendFramebufferObject::Bind(FramebufferTarget target) { void BackendFramebufferObject::Bind(FramebufferTarget target) const {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
@@ -788,12 +787,12 @@ namespace MobileGL::MG_Backend::DirectGLES {
g_GLESFuncs.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_backendFBOId); g_GLESFuncs.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_backendFBOId);
} }
Bool BackendFramebufferObject::SyncAttachmentObject( static Bool SyncAttachmentObject(GLenum glFBOTarget,
GLenum glFBOTarget, const MG_State::GLState::FramebufferAttachmentObject& attachmentObject, const MG_State::GLState::FramebufferAttachmentObject& attachmentObject,
GLenum glBackendAttachment) { GLenum glBackendAttachment) {
if (attachmentObject.IsTexture()) { if (attachmentObject.IsTexture()) {
const auto& textureObject = attachmentObject.GetTexture(); const auto& textureObject = attachmentObject.GetTexture();
const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject); const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject.get());
if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) { if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) {
MGLOG_E("%s: No backend texture found for FBO attachment, cannot bind texture.", __func__); MGLOG_E("%s: No backend texture found for FBO attachment, cannot bind texture.", __func__);
return false; return false;
@@ -807,11 +806,12 @@ namespace MobileGL::MG_Backend::DirectGLES {
} else if (attachmentObject.IsRenderbuffer()) { } else if (attachmentObject.IsRenderbuffer()) {
const auto& renderbufferObject = attachmentObject.GetRenderbuffer(); const auto& renderbufferObject = attachmentObject.GetRenderbuffer();
const auto& backendRenderbufferIt = const auto& backendRenderbufferIt =
RenderbufferImpl::g_backendRenderbufferObjects.find(renderbufferObject); RenderbufferImpl::g_backendRenderbufferObjects.find(renderbufferObject.get());
SharedPtr<RenderbufferImpl::BackendRenderbufferObject> backendRenderbufferObject; SharedPtr<RenderbufferImpl::BackendRenderbufferObject> backendRenderbufferObject;
if (backendRenderbufferIt == RenderbufferImpl::g_backendRenderbufferObjects.end()) { if (backendRenderbufferIt == RenderbufferImpl::g_backendRenderbufferObjects.end()) {
backendRenderbufferObject = MakeShared<RenderbufferImpl::BackendRenderbufferObject>(); backendRenderbufferObject = MakeShared<RenderbufferImpl::BackendRenderbufferObject>();
RenderbufferImpl::g_backendRenderbufferObjects[renderbufferObject] = backendRenderbufferObject; RenderbufferImpl::g_backendRenderbufferObjects[renderbufferObject.get()] =
backendRenderbufferObject;
} else { } else {
backendRenderbufferObject = backendRenderbufferIt->second; backendRenderbufferObject = backendRenderbufferIt->second;
} }
@@ -824,8 +824,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
return true; return true;
} }
void BackendFramebufferObject::SyncToBackend(SharedPtr<MG_State::GLState::FramebufferObject>& stateFBOObject, void BackendFramebufferObject::SyncToBackend(
FramebufferTarget asTarget) { const SharedPtr<MG_State::GLState::FramebufferObject>& stateFBOObject, FramebufferTarget asTarget) {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
@@ -853,7 +853,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
std::fill(m_backendDrawBuffers, m_backendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS, GL_NONE); std::fill(m_backendDrawBuffers, m_backendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS, GL_NONE);
int nEffectiveBuffers = 0; int nEffectiveBuffers = 0;
for (GLint i = 0; i < FramebufferObject::MAX_DRAW_BUFFERS; ++i) { for (GLint i = 0; i < FramebufferObject::MAX_DRAW_BUFFERS; ++i) {
auto frontendBuf = stateDrawBuffers[i]; auto& frontendBuf = stateDrawBuffers[i];
if (frontendBuf == FramebufferAttachmentType::None) { if (frontendBuf == FramebufferAttachmentType::None) {
m_backendDrawBuffers[i] = GL_NONE; m_backendDrawBuffers[i] = GL_NONE;
continue; continue;
@@ -892,7 +892,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
const auto& attachmentVersions = stateFBOObject->GetAllFramebufferAttachmentVersions(); const auto& attachmentVersions = stateFBOObject->GetAllFramebufferAttachmentVersions();
for (SizeT i = 0; i < attachments.size(); ++i) { for (SizeT i = 0; i < attachments.size(); ++i) {
const auto& attachmentObject = attachments[i]; const auto& attachmentObject = attachments[i];
FramebufferAttachmentType frontendType = static_cast<FramebufferAttachmentType>(i); auto frontendType = static_cast<FramebufferAttachmentType>(i);
GLenum glBackendAttachment = GL_NONE; GLenum glBackendAttachment = GL_NONE;
if (frontendType >= FramebufferAttachmentType::Color0 && if (frontendType >= FramebufferAttachmentType::Color0 &&
frontendType <= FramebufferAttachmentType::Color31) frontendType <= FramebufferAttachmentType::Color31)
@@ -928,7 +928,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// Verify that the backend object's name and parameters match the frontend attachment state // Verify that the backend object's name and parameters match the frontend attachment state
if (attachmentObject.IsTexture()) { if (attachmentObject.IsTexture()) {
const auto& textureObject = attachmentObject.GetTexture(); const auto& textureObject = attachmentObject.GetTexture();
auto backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject); auto backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject.get());
MOBILEGL_ASSERT(backendTextureIt != TextureImpl::g_backendTextureObjects.end(), MOBILEGL_ASSERT(backendTextureIt != TextureImpl::g_backendTextureObjects.end(),
"No backend texture found while framebuffer reports texture attachment."); "No backend texture found while framebuffer reports texture attachment.");
GLuint backendTexId = backendTextureIt->second->GetBackendTextureId(); GLuint backendTexId = backendTextureIt->second->GetBackendTextureId();
@@ -944,7 +944,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
"Attachment texture level mismatch between GLES and state object."); "Attachment texture level mismatch between GLES and state object.");
} else if (attachmentObject.IsRenderbuffer()) { } else if (attachmentObject.IsRenderbuffer()) {
const auto& renderbufferObject = attachmentObject.GetRenderbuffer(); const auto& renderbufferObject = attachmentObject.GetRenderbuffer();
auto backendRboIt = RenderbufferImpl::g_backendRenderbufferObjects.find(renderbufferObject); auto backendRboIt =
RenderbufferImpl::g_backendRenderbufferObjects.find(renderbufferObject.get());
MOBILEGL_ASSERT( MOBILEGL_ASSERT(
backendRboIt != RenderbufferImpl::g_backendRenderbufferObjects.end(), backendRboIt != RenderbufferImpl::g_backendRenderbufferObjects.end(),
"No backend renderbuffer found while framebuffer reports renderbuffer attachment."); "No backend renderbuffer found while framebuffer reports renderbuffer attachment.");
@@ -975,14 +976,13 @@ namespace MobileGL::MG_Backend::DirectGLES {
return glBackendReadBuffer; return glBackendReadBuffer;
} }
UnorderedMap<SharedPtr<MG_State::GLState::FramebufferObject>, SharedPtr<BackendFramebufferObject>> UnorderedMap<MG_State::GLState::FramebufferObject*, SharedPtr<BackendFramebufferObject>>
g_backendFramebufferObjects; g_backendFramebufferObjects;
Array<Uint16, SizeT(FramebufferTarget::FramebufferTargetCount)> g_fboBindVersions = {0}; Array<Uint16, SizeT(FramebufferTarget::FramebufferTargetCount)> g_fboBindVersions = {0};
} // namespace FramebufferImpl } // namespace FramebufferImpl
namespace PrgramImpl { namespace PrgramImpl {
UnorderedMap<SharedPtr<MG_State::GLState::ProgramObject>, SharedPtr<BackendProgramObjectImpl>> UnorderedMap<MG_State::GLState::ProgramObject*, SharedPtr<BackendProgramObjectImpl>> g_backendProgramObjects;
g_backendProgramObjects;
BackendProgramObjectImpl::BackendProgramObjectImpl() { BackendProgramObjectImpl::BackendProgramObjectImpl() {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
@@ -1008,7 +1008,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
} }
void BackendProgramObjectImpl::SyncToBackend(SharedPtr<MG_State::GLState::ProgramObject>& stateProgramObject) { void BackendProgramObjectImpl::SyncToBackend(
const SharedPtr<MG_State::GLState::ProgramObject>& stateProgramObject) {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
@@ -1161,7 +1162,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
MGLOG_D("Program sync completed. backend ID %u", m_backendProgramId); MGLOG_D("Program sync completed. backend ID %u", m_backendProgramId);
} }
void BackendProgramObjectImpl::Use() { void BackendProgramObjectImpl::Use() const {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
@@ -1184,7 +1185,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
} }
void BackendSamplerObject::SyncToBackend(SharedPtr<MG_State::GLState::SamplerObject>& stateSamplerObject) { void BackendSamplerObject::SyncToBackend(
const SharedPtr<MG_State::GLState::SamplerObject>& stateSamplerObject) {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
@@ -1210,22 +1212,22 @@ namespace MobileGL::MG_Backend::DirectGLES {
#define SYNC_SAMPLER_PARAM_IF_CHANGED(internalName, glName, type) \ #define SYNC_SAMPLER_PARAM_IF_CHANGED(internalName, glName, type) \
if (m_cacheSamplerParameters.internalName != samplerParams.internalName) { \ if (m_cacheSamplerParameters.internalName != samplerParams.internalName) { \
g_GLESFuncs.glSamplerParameteri(m_backendSamplerId, glName, \ g_GLESFuncs.glSamplerParameteri(m_backendSamplerId, glName, \
MG_Util::ConvertSampler##type##ToGLEnum(samplerParams.internalName)); \ (GLint)MG_Util::ConvertSampler##type##ToGLEnum(samplerParams.internalName)); \
m_cacheSamplerParameters.internalName = samplerParams.internalName; \ m_cacheSamplerParameters.internalName = samplerParams.internalName; \
} }
if (m_cacheSamplerParameters.minFilter != samplerParams.minFilter || if (m_cacheSamplerParameters.minFilter != samplerParams.minFilter ||
m_cacheSamplerParameters.mipmapMode != samplerParams.mipmapMode) { m_cacheSamplerParameters.mipmapMode != samplerParams.mipmapMode) {
g_GLESFuncs.glSamplerParameteri( g_GLESFuncs.glSamplerParameteri(m_backendSamplerId, GL_TEXTURE_MIN_FILTER,
m_backendSamplerId, GL_TEXTURE_MIN_FILTER, (GLint)MG_Util::ConvertSamplerFilterModeToGLEnum(
MG_Util::ConvertSamplerFilterModeToGLEnum(samplerParams.minFilter, samplerParams.mipmapMode)); samplerParams.minFilter, samplerParams.mipmapMode));
m_cacheSamplerParameters.minFilter = samplerParams.minFilter; m_cacheSamplerParameters.minFilter = samplerParams.minFilter;
m_cacheSamplerParameters.mipmapMode = samplerParams.mipmapMode; m_cacheSamplerParameters.mipmapMode = samplerParams.mipmapMode;
} }
if (m_cacheSamplerParameters.magFilter != samplerParams.magFilter) { if (m_cacheSamplerParameters.magFilter != samplerParams.magFilter) {
g_GLESFuncs.glSamplerParameteri( g_GLESFuncs.glSamplerParameteri(
m_backendSamplerId, GL_TEXTURE_MAG_FILTER, m_backendSamplerId, GL_TEXTURE_MAG_FILTER,
MG_Util::ConvertSamplerFilterModeToGLEnum(samplerParams.magFilter, SamplerMipmapMode::None)); (GLint)MG_Util::ConvertSamplerFilterModeToGLEnum(samplerParams.magFilter, SamplerMipmapMode::None));
m_cacheSamplerParameters.magFilter = samplerParams.magFilter; m_cacheSamplerParameters.magFilter = samplerParams.magFilter;
} }
@@ -1256,7 +1258,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
g_boundSamplersCache[unit] = this; g_boundSamplersCache[unit] = this;
} }
Uint BackendSamplerObject::GetBackendSamplerId() { Uint BackendSamplerObject::GetBackendSamplerId() const {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
@@ -1271,8 +1273,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
Array<BackendSamplerObject*, MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS> g_boundSamplersCache; Array<BackendSamplerObject*, MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS> g_boundSamplersCache;
UnorderedMap<SharedPtr<MG_State::GLState::SamplerObject>, SharedPtr<BackendSamplerObject>> UnorderedMap<MG_State::GLState::SamplerObject*, SharedPtr<BackendSamplerObject>> g_backendSamplerObjects;
g_backendSamplerObjects;
} // namespace SamplerImpl } // namespace SamplerImpl
namespace RenderbufferImpl { namespace RenderbufferImpl {
@@ -1287,7 +1288,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
} }
void BackendRenderbufferObject::Bind() { void BackendRenderbufferObject::Bind() const {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
@@ -1334,9 +1335,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
MGLOG_D("RBO %u sync completed. backend ID %u", stateRBOObject->GetExternalIndex(), m_backendRBOId); MGLOG_D("RBO %u sync completed. backend ID %u", stateRBOObject->GetExternalIndex(), m_backendRBOId);
} }
UnorderedMap<SharedPtr<MG_State::GLState::RenderbufferObject>, SharedPtr<BackendRenderbufferObject>> UnorderedMap<MG_State::GLState::RenderbufferObject*, SharedPtr<BackendRenderbufferObject>>
g_backendRenderbufferObjects; g_backendRenderbufferObjects;
} // namespace RenderbufferImpl } // namespace RenderbufferImpl
namespace Utils {} // namespace Utils
} // namespace MobileGL::MG_Backend::DirectGLES } // namespace MobileGL::MG_Backend::DirectGLES
+28 -35
View File
@@ -20,14 +20,14 @@ namespace MobileGL::MG_Backend::DirectGLES {
class BackendBufferObject { class BackendBufferObject {
public: public:
BackendBufferObject(); BackendBufferObject();
void SyncToBackend(SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject); void SyncToBackend(const SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject);
Uint GetBackendBufferId() { return m_backendBufferId; } Uint GetBackendBufferId() const { return m_backendBufferId; }
void Bind(GLenum target = TempBufferTarget); void Bind(GLenum target = TempBufferTarget);
private: private:
void SyncToBackend_glBufferData(SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject); void SyncToBackend_glBufferData(const SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject);
void SyncToBackend_glBufferSubData(SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject); void SyncToBackend_glBufferSubData(const SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject);
void SyncToBackend_glMapBufferRange(SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject, void SyncToBackend_glMapBufferRange(const SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject,
Bool invalidate = true, Bool unsynchronized = true); Bool invalidate = true, Bool unsynchronized = true);
Uint m_backendBufferId = 0; Uint m_backendBufferId = 0;
@@ -36,21 +36,18 @@ namespace MobileGL::MG_Backend::DirectGLES {
}; };
extern BackendBufferObject* g_boundVertexBufferObject; extern BackendBufferObject* g_boundVertexBufferObject;
extern UnorderedMap<SharedPtr<MG_State::GLState::BufferObject>, SharedPtr<BackendBufferObject>> extern UnorderedMap<MG_State::GLState::BufferObject*, SharedPtr<BackendBufferObject>> g_backendBufferObjects;
g_backendBufferObjects;
} // namespace BufferImpl } // namespace BufferImpl
namespace VertexArrayImpl { namespace VertexArrayImpl {
class BackendVertexArrayObject { class BackendVertexArrayObject {
public: public:
BackendVertexArrayObject(); BackendVertexArrayObject();
void SyncToBackend(SharedPtr<MG_State::GLState::VertexArrayObject>& stateVAOObject); void SyncToBackend(const SharedPtr<MG_State::GLState::VertexArrayObject>& stateVAOObject);
Uint GetBackendVertexArrayId() { return m_backendVAOId; } Uint GetBackendVertexArrayId() const { return m_backendVAOId; }
void Bind(); void Bind() const;
private: private:
void BindAttributeBuffer(Uint index, const MG_State::GLState::VertexAttribute& attrib);
Uint m_backendVAOId = 0; Uint m_backendVAOId = 0;
Bool m_isInitialized = false; Bool m_isInitialized = false;
Uint16 m_syncedIndexBufferVersion = 0; Uint16 m_syncedIndexBufferVersion = 0;
@@ -58,7 +55,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
m_syncedAttributeVersions; m_syncedAttributeVersions;
}; };
extern UnorderedMap<SharedPtr<MG_State::GLState::VertexArrayObject>, SharedPtr<BackendVertexArrayObject>> extern UnorderedMap<MG_State::GLState::VertexArrayObject*, SharedPtr<BackendVertexArrayObject>>
g_backendVertexArrayObjects; g_backendVertexArrayObjects;
} // namespace VertexArrayImpl } // namespace VertexArrayImpl
@@ -92,11 +89,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
class BackendTextureObject { class BackendTextureObject {
public: public:
BackendTextureObject(); BackendTextureObject();
void SyncMipmapsToBackend(SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject); void SyncMipmapsToBackend(const SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject);
void SyncBuiltinSamplerToBackend(SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject); void SyncBuiltinSamplerToBackend(const SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject);
void SyncTextureParamsToBackend(SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject); void SyncTextureParamsToBackend(const SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject);
void Bind(GLenum target, Uint unit = TempTextureUnit); void Bind(GLenum target, Uint unit = TempTextureUnit);
Uint GetBackendTextureId(); Uint GetBackendTextureId() const;
private: private:
Uint m_backendTextureId = 0; Uint m_backendTextureId = 0;
@@ -113,7 +110,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
void ActivateTextureUnit(Uint unit); void ActivateTextureUnit(Uint unit);
void UnbindTexture(Uint unit, GLenum target); void UnbindTexture(Uint unit, GLenum target);
extern UnorderedMap<SharedPtr<MG_State::GLState::ITextureObject>, SharedPtr<BackendTextureObject>> extern UnorderedMap<MG_State::GLState::ITextureObject*, SharedPtr<BackendTextureObject>>
g_backendTextureObjects; g_backendTextureObjects;
extern Array<Array<BackendTextureObject*, (SizeT)TextureTarget::TextureTargetCount>, extern Array<Array<BackendTextureObject*, (SizeT)TextureTarget::TextureTargetCount>,
MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS> MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS>
@@ -125,13 +122,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
class BackendFramebufferObject { class BackendFramebufferObject {
public: public:
BackendFramebufferObject(); BackendFramebufferObject();
void SyncToBackend(SharedPtr<MG_State::GLState::FramebufferObject>& stateFBOObject, void SyncToBackend(const SharedPtr<MG_State::GLState::FramebufferObject>& stateFBOObject,
FramebufferTarget asTarget); FramebufferTarget asTarget);
Uint GetBackendFramebufferId() { return m_backendFBOId; } Uint GetBackendFramebufferId() const { return m_backendFBOId; }
void Bind(FramebufferTarget target); void Bind(FramebufferTarget target) const;
bool SyncAttachmentObject(GLenum glFBOTarget,
const MG_State::GLState::FramebufferAttachmentObject& attachmentObject,
GLenum glBackendAttachment);
// FramebufferAttachmentType GetCompactedAttachmentTypeAtDrawBufferIndex(Int index); // FramebufferAttachmentType GetCompactedAttachmentTypeAtDrawBufferIndex(Int index);
GLenum GetBackendAttachmentType(FramebufferAttachmentType frontendAtt) const; GLenum GetBackendAttachmentType(FramebufferAttachmentType frontendAtt) const;
@@ -159,7 +153,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
FramebufferObject::FramebufferAttachmentVersionArray m_syncedFrontendAttachmentVersions = {0}; FramebufferObject::FramebufferAttachmentVersionArray m_syncedFrontendAttachmentVersions = {0};
}; };
extern UnorderedMap<SharedPtr<MG_State::GLState::FramebufferObject>, SharedPtr<BackendFramebufferObject>> extern UnorderedMap<MG_State::GLState::FramebufferObject*, SharedPtr<BackendFramebufferObject>>
g_backendFramebufferObjects; g_backendFramebufferObjects;
extern Array<Uint16, SizeT(FramebufferTarget::FramebufferTargetCount)> g_fboBindVersions; extern Array<Uint16, SizeT(FramebufferTarget::FramebufferTargetCount)> g_fboBindVersions;
} // namespace FramebufferImpl } // namespace FramebufferImpl
@@ -169,8 +163,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
public: public:
BackendProgramObjectImpl(); BackendProgramObjectImpl();
~BackendProgramObjectImpl(); ~BackendProgramObjectImpl();
void SyncToBackend(SharedPtr<MG_State::GLState::ProgramObject>& stateProgramObject); void SyncToBackend(const SharedPtr<MG_State::GLState::ProgramObject>& stateProgramObject);
void Use(); void Use() const;
Uint GetBackendProgramId() const { return m_backendProgramId; } Uint GetBackendProgramId() const { return m_backendProgramId; }
Uint GetBackendGlobalUBOId() const { return m_backendGlobalUBOId; } Uint GetBackendGlobalUBOId() const { return m_backendGlobalUBOId; }
@@ -180,7 +174,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
Bool m_isInitialized = false; Bool m_isInitialized = false;
}; };
extern UnorderedMap<SharedPtr<MG_State::GLState::ProgramObject>, SharedPtr<BackendProgramObjectImpl>> extern UnorderedMap<MG_State::GLState::ProgramObject*, SharedPtr<BackendProgramObjectImpl>>
g_backendProgramObjects; g_backendProgramObjects;
} // namespace PrgramImpl } // namespace PrgramImpl
@@ -188,9 +182,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
class BackendSamplerObject { class BackendSamplerObject {
public: public:
BackendSamplerObject(); BackendSamplerObject();
void SyncToBackend(SharedPtr<MG_State::GLState::SamplerObject>& stateSamplerObject); void SyncToBackend(const SharedPtr<MG_State::GLState::SamplerObject>& stateSamplerObject);
void Bind(Uint unit); void Bind(Uint unit);
Uint GetBackendSamplerId(); Uint GetBackendSamplerId() const;
private: private:
Uint m_backendSamplerId = 0; Uint m_backendSamplerId = 0;
@@ -203,8 +197,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
extern Array<BackendSamplerObject*, MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS> extern Array<BackendSamplerObject*, MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS>
g_boundSamplersCache; g_boundSamplersCache;
extern UnorderedMap<SharedPtr<MG_State::GLState::SamplerObject>, SharedPtr<BackendSamplerObject>> extern UnorderedMap<MG_State::GLState::SamplerObject*, SharedPtr<BackendSamplerObject>> g_backendSamplerObjects;
g_backendSamplerObjects;
} // namespace SamplerImpl } // namespace SamplerImpl
namespace RenderbufferImpl { namespace RenderbufferImpl {
@@ -212,8 +205,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
public: public:
BackendRenderbufferObject(); BackendRenderbufferObject();
void SyncToBackend(const SharedPtr<MG_State::GLState::RenderbufferObject>& stateRBOObject); void SyncToBackend(const SharedPtr<MG_State::GLState::RenderbufferObject>& stateRBOObject);
Uint GetBackendRenderbufferId() { return m_backendRBOId; } Uint GetBackendRenderbufferId() const { return m_backendRBOId; }
void Bind(); void Bind() const;
private: private:
Uint m_backendRBOId = 0; Uint m_backendRBOId = 0;
@@ -223,7 +216,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
Int m_cacheHeight = 0; Int m_cacheHeight = 0;
}; };
extern UnorderedMap<SharedPtr<MG_State::GLState::RenderbufferObject>, SharedPtr<BackendRenderbufferObject>> extern UnorderedMap<MG_State::GLState::RenderbufferObject*, SharedPtr<BackendRenderbufferObject>>
g_backendRenderbufferObjects; g_backendRenderbufferObjects;
} // namespace RenderbufferImpl } // namespace RenderbufferImpl
} // namespace MobileGL::MG_Backend::DirectGLES } // namespace MobileGL::MG_Backend::DirectGLES
-9
View File
@@ -19,10 +19,6 @@
#include <MG_Util/Converters/MGToGL/FramebufferEnumConverter.h> #include <MG_Util/Converters/MGToGL/FramebufferEnumConverter.h>
namespace MobileGL::MG_Backend::DirectGLES { namespace MobileGL::MG_Backend::DirectGLES {
namespace BufferImpl {} // namespace BufferImpl
namespace VertexArrayImpl {} // namespace VertexArrayImpl
namespace TextureImpl { namespace TextureImpl {
void GenerateTextureFormatInfo(TextureInternalFormat internalFormat, GLenum* outInternalFormat, void GenerateTextureFormatInfo(TextureInternalFormat internalFormat, GLenum* outInternalFormat,
GLenum* outFormat, GLenum* outType) { GLenum* outFormat, GLenum* outType) {
@@ -36,9 +32,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
outInternalFormat, outFormat, outType); outInternalFormat, outFormat, outType);
} }
} // namespace TextureImpl } // namespace TextureImpl
namespace FramebufferImpl {} // namespace FramebufferImpl
namespace PrgramImpl { namespace PrgramImpl {
String ProcessOutColorLocations(const String& glslCode) { String ProcessOutColorLocations(const String& glslCode) {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
@@ -166,7 +159,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
return GL_UNIFORM_BUFFER_BINDING; return GL_UNIFORM_BUFFER_BINDING;
case GL_FRAMEBUFFER: case GL_FRAMEBUFFER:
return GL_FRAMEBUFFER_BINDING;
case GL_DRAW_FRAMEBUFFER: case GL_DRAW_FRAMEBUFFER:
return GL_DRAW_FRAMEBUFFER_BINDING; return GL_DRAW_FRAMEBUFFER_BINDING;
case GL_READ_FRAMEBUFFER: case GL_READ_FRAMEBUFFER:
@@ -176,7 +168,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
return GL_RENDERBUFFER_BINDING; return GL_RENDERBUFFER_BINDING;
case GL_VERTEX_ARRAY: case GL_VERTEX_ARRAY:
return GL_VERTEX_ARRAY_BINDING;
case GL_VERTEX_ARRAY_BINDING: case GL_VERTEX_ARRAY_BINDING:
return GL_VERTEX_ARRAY_BINDING; return GL_VERTEX_ARRAY_BINDING;
+3 -3
View File
@@ -14,15 +14,15 @@ namespace MobileGL::MG_Backend::DirectGLES {
namespace DebugImpl { namespace DebugImpl {
class ErrorLopper { class ErrorLopper {
public: public:
void Loop(std::function<void(GLenum)>); static void Loop(const std::function<void(GLenum)>&);
void Clear(); static void Clear();
ErrorLopper(); ErrorLopper();
~ErrorLopper(); ~ErrorLopper();
}; };
class OpenGLScopeMarker { class OpenGLScopeMarker {
public: public:
explicit OpenGLScopeMarker(String scopeName); explicit OpenGLScopeMarker(const String& scopeName);
~OpenGLScopeMarker(); ~OpenGLScopeMarker();
}; };
} // namespace DebugImpl } // namespace DebugImpl
@@ -297,7 +297,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
const auto& drawFboSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw); const auto& drawFboSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw);
const auto drawFbo = drawFboSlot.GetBoundObject(); const auto drawFbo = drawFboSlot.GetBoundObject();
const auto defaultFboInfo = MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo; const auto& defaultFboInfo = MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo;
const auto defaultFbo = defaultFboInfo ? defaultFboInfo->defaultFBO : nullptr; const auto defaultFbo = defaultFboInfo ? defaultFboInfo->defaultFBO : nullptr;
const Bool isDefaultFboTarget = (drawFbo == defaultFbo) || (drawFbo == nullptr && defaultFbo != nullptr); const Bool isDefaultFboTarget = (drawFbo == defaultFbo) || (drawFbo == nullptr && defaultFbo != nullptr);
Uint drawFboExternalIndex = 0; Uint drawFboExternalIndex = 0;
@@ -429,7 +429,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
const auto& drawFboSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw); const auto& drawFboSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw);
const auto readFbo = readFboSlot.GetBoundObject(); const auto readFbo = readFboSlot.GetBoundObject();
const auto drawFbo = drawFboSlot.GetBoundObject(); const auto drawFbo = drawFboSlot.GetBoundObject();
const auto defaultFboInfo = MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo; const auto& defaultFboInfo = MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo;
const auto defaultFbo = defaultFboInfo ? defaultFboInfo->defaultFBO : nullptr; const auto defaultFbo = defaultFboInfo ? defaultFboInfo->defaultFBO : nullptr;
const Bool readIsDefault = (readFbo == defaultFbo) || (readFbo == nullptr && defaultFbo != nullptr); const Bool readIsDefault = (readFbo == defaultFbo) || (readFbo == nullptr && defaultFbo != nullptr);
@@ -90,7 +90,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
const VkPipelineVertexInputStateCreateInfo& vertexInputState) { const VkPipelineVertexInputStateCreateInfo& vertexInputState) {
MOBILEGL_ASSERT(m_pipelineFactory != nullptr, "PipelineFactory is not initialized"); MOBILEGL_ASSERT(m_pipelineFactory != nullptr, "PipelineFactory is not initialized");
MOBILEGL_ASSERT(m_programFactory != nullptr, "ProgramFactory is not initialized"); MOBILEGL_ASSERT(m_programFactory != nullptr, "ProgramFactory is not initialized");
ProgramFactory::CompileOptionFlags transformFlags = GetShaderTransformFlags(m_swapchainObject.GetPreTransform()); ProgramFactory::CompileOptionFlags transformFlags =
GetShaderTransformFlags(m_swapchainObject.GetPreTransform());
auto& stages = m_programFactory->GetOrCreatePipelineShaderStages(program, transformFlags); auto& stages = m_programFactory->GetOrCreatePipelineShaderStages(program, transformFlags);
if (stages.empty()) { if (stages.empty()) {
MGLOG_D("GetOrCreatePipeline skipped: program has no shader stages"); MGLOG_D("GetOrCreatePipeline skipped: program has no shader stages");
@@ -178,7 +179,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
payload.dstAlphaBlendFactor = toVkBlendFactor(dstAlpha); payload.dstAlphaBlendFactor = toVkBlendFactor(dstAlpha);
payload.colorWriteMask = 0; payload.colorWriteMask = 0;
const BoolVec4 colorMask = MG_State::pGLContext->GetColorMask(); auto colorMask = MG_State::pGLContext->GetColorMask();
if (colorMask.x()) payload.colorWriteMask |= VK_COLOR_COMPONENT_R_BIT; if (colorMask.x()) payload.colorWriteMask |= VK_COLOR_COMPONENT_R_BIT;
if (colorMask.y()) payload.colorWriteMask |= VK_COLOR_COMPONENT_G_BIT; if (colorMask.y()) payload.colorWriteMask |= VK_COLOR_COMPONENT_G_BIT;
if (colorMask.z()) payload.colorWriteMask |= VK_COLOR_COMPONENT_B_BIT; if (colorMask.z()) payload.colorWriteMask |= VK_COLOR_COMPONENT_B_BIT;
@@ -442,7 +443,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
MG_State::pGLContext MG_State::pGLContext
? MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject() ? MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject()
: nullptr; : nullptr;
const auto defaultFboInfo = MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo; const auto& defaultFboInfo = MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo;
const auto defaultFbo = defaultFboInfo ? defaultFboInfo->defaultFBO : nullptr; const auto defaultFbo = defaultFboInfo ? defaultFboInfo->defaultFBO : nullptr;
const Bool drawTargetsDefault = (drawFbo == defaultFbo) || (drawFbo == nullptr && defaultFbo != nullptr); const Bool drawTargetsDefault = (drawFbo == defaultFbo) || (drawFbo == nullptr && defaultFbo != nullptr);
const Uint drawFboExternalIndex = const Uint drawFboExternalIndex =
@@ -2143,7 +2144,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
} }
Bool VulkanRenderer::GetMoreCapablePhysicalDevice(VkPhysicalDevice newVkDevice, VkSurfaceKHR surface, Bool VulkanRenderer::GetMoreCapablePhysicalDevice(VkPhysicalDevice newVkDevice, VkSurfaceKHR surface,
const PhysicalDevice& otherDevice, const PhysicalDevice& compareWithDevice,
PhysicalDevice& outBetterDevice) { PhysicalDevice& outBetterDevice) {
const auto deviceTypeToStr = [](VkPhysicalDeviceType type) { const auto deviceTypeToStr = [](VkPhysicalDeviceType type) {
switch (type) { switch (type) {
@@ -2175,7 +2176,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
// Check device extensions (including swapchain extension) // Check device extensions (including swapchain extension)
Bool deviceExtSupported = IsNecessaryDeviceExtensionSupported(newVkDevice); Bool deviceExtSupported = IsNecessaryDeviceExtensionSupported(newVkDevice);
if (!deviceExtSupported) { if (!deviceExtSupported) {
outBetterDevice = otherDevice; outBetterDevice = compareWithDevice;
MGLOG_I(" Ignored physical device. (Reason: Some of the required device extension not supported on this " MGLOG_I(" Ignored physical device. (Reason: Some of the required device extension not supported on this "
"device)"); "device)");
return false; return false;
@@ -2184,7 +2185,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
// Check swapchain capabilities // Check swapchain capabilities
auto swapchainCapabilities = SwapchainObject::GetSwapchainCapabilities(newVkDevice, surface); auto swapchainCapabilities = SwapchainObject::GetSwapchainCapabilities(newVkDevice, surface);
if (!swapchainCapabilities.IsComplete()) { if (!swapchainCapabilities.IsComplete()) {
outBetterDevice = otherDevice; outBetterDevice = compareWithDevice;
MGLOG_I(" Ignored physical device. (Reason: Swapchain capabilities not met)"); MGLOG_I(" Ignored physical device. (Reason: Swapchain capabilities not met)");
return false; return false;
} }
@@ -2193,7 +2194,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
Vector<VkQueueFamilyProperties> queueFamilies = GetQueueFamilyFromPhysicalDevice(newVkDevice); Vector<VkQueueFamilyProperties> queueFamilies = GetQueueFamilyFromPhysicalDevice(newVkDevice);
newDevice.queueFamilies.graphicsFamily = GetQueueFamilyIndex(queueFamilies, VK_QUEUE_GRAPHICS_BIT); newDevice.queueFamilies.graphicsFamily = GetQueueFamilyIndex(queueFamilies, VK_QUEUE_GRAPHICS_BIT);
if (newDevice.queueFamilies.graphicsFamily == -1) { if (newDevice.queueFamilies.graphicsFamily == -1) {
outBetterDevice = otherDevice; outBetterDevice = compareWithDevice;
MGLOG_I(" Ignored physical device. (Reason: No graphics queue family)"); MGLOG_I(" Ignored physical device. (Reason: No graphics queue family)");
return false; return false;
} }
@@ -2201,14 +2202,14 @@ namespace MobileGL::MG_Backend::DirectVulkan {
newDevice.queueFamilies.presentFamily = newDevice.queueFamilies.presentFamily =
GetPresentQueueFamilyIndex(newDevice, surface, queueFamilies, newDevice.queueFamilies.graphicsFamily); GetPresentQueueFamilyIndex(newDevice, surface, queueFamilies, newDevice.queueFamilies.graphicsFamily);
if (newDevice.queueFamilies.presentFamily == -1) { if (newDevice.queueFamilies.presentFamily == -1) {
outBetterDevice = otherDevice; outBetterDevice = compareWithDevice;
MGLOG_I(" Ignored physical device. (Reason: No present queue family)"); MGLOG_I(" Ignored physical device. (Reason: No present queue family)");
return false; return false;
} }
// Pick discrete GPU // Pick discrete GPU
if (newDevice.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && if (newDevice.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU &&
otherDevice.properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) { compareWithDevice.properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
outBetterDevice = newDevice; outBetterDevice = newDevice;
MGLOG_I(" Picked physical device. (Reason: Discrete GPU)"); MGLOG_I(" Picked physical device. (Reason: Discrete GPU)");
return true; return true;
@@ -2216,7 +2217,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
// Pick integrated GPU if no discrete GPU // Pick integrated GPU if no discrete GPU
if (newDevice.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU && if (newDevice.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU &&
otherDevice.properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) { compareWithDevice.properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
outBetterDevice = newDevice; outBetterDevice = newDevice;
MGLOG_I(" Picked physical device. (Reason: Integrated GPU and no discrete one found yet)"); MGLOG_I(" Picked physical device. (Reason: Integrated GPU and no discrete one found yet)");
return true; return true;
@@ -2224,7 +2225,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
// Ignore other GPU when discrete GPU found // Ignore other GPU when discrete GPU found
if (newDevice.properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && if (newDevice.properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU &&
otherDevice.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) { compareWithDevice.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
outBetterDevice = newDevice; outBetterDevice = newDevice;
MGLOG_I(" Ignored physical device. (Reason: Already picked discrete GPU)"); MGLOG_I(" Ignored physical device. (Reason: Already picked discrete GPU)");
return false; return false;
@@ -2487,7 +2488,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
VkRenderPass VulkanRenderer::GetDefaultLoadRenderPass() const { VkRenderPass VulkanRenderer::GetDefaultLoadRenderPass() const {
MOBILEGL_ASSERT(m_renderPassManager != nullptr, "GetDefaultLoadRenderPass: render pass manager is null"); MOBILEGL_ASSERT(m_renderPassManager != nullptr, "GetDefaultLoadRenderPass: render pass manager is null");
const VkRenderPass renderPass = m_renderPassManager->GetLoadRenderPass(); VkRenderPass renderPass = m_renderPassManager->GetLoadRenderPass();
MOBILEGL_ASSERT(renderPass != VK_NULL_HANDLE, MOBILEGL_ASSERT(renderPass != VK_NULL_HANDLE,
"GetDefaultLoadRenderPass: default load render pass is unavailable"); "GetDefaultLoadRenderPass: default load render pass is unavailable");
return renderPass; return renderPass;
@@ -2579,7 +2580,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
VkQueueFlagBits flag) { VkQueueFlagBits flag) {
for (Uint32 i = 0; i < queueFamilies.size(); i++) { for (Uint32 i = 0; i < queueFamilies.size(); i++) {
if (queueFamilies[i].queueFlags & flag) { if (queueFamilies[i].queueFlags & flag) {
return i; return (Int)i;
} }
} }
return -1; return -1;
@@ -2598,7 +2599,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
for (Uint32 i = 0; i < queueFamilies.size(); i++) { for (Uint32 i = 0; i < queueFamilies.size(); i++) {
VkBool32 supportsPresent = false; VkBool32 supportsPresent = false;
vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice.handle, i, surface, &supportsPresent); vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice.handle, i, surface, &supportsPresent);
if (supportsPresent) return i; if (supportsPresent) return (Int)i;
} }
return -1; return -1;
} }
@@ -2631,12 +2632,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
Bool VulkanRenderer::IsExtensionAlreadyEnabled(const Vector<const char*>& enabledExtensions, Bool VulkanRenderer::IsExtensionAlreadyEnabled(const Vector<const char*>& enabledExtensions,
const char* extensionName) { const char* extensionName) {
for (const char* enabledExtensionName : enabledExtensions) { return std::any_of(enabledExtensions.begin(), enabledExtensions.end(),
if (strcmp(enabledExtensionName, extensionName) == 0) { [&extensionName](const String& name) { return name == extensionName; });
return true;
}
}
return false;
} }
Bool VulkanRenderer::EnableOptionalDeviceExtension(const Vector<VkExtensionProperties>& availableExtensions, Bool VulkanRenderer::EnableOptionalDeviceExtension(const Vector<VkExtensionProperties>& availableExtensions,
+1 -1
View File
@@ -20,7 +20,7 @@ namespace MobileGL::MG_Impl::EGLImpl {
if (!MG_State::pEGLContext) { if (!MG_State::pEGLContext) {
MGLOG_E("pEGLContext is null. MG_State may not be initialized."); MGLOG_E("pEGLContext is null. MG_State may not be initialized.");
} }
return MG_State::pEGLContext; return MG_State::pEGLContext.get();
} }
MG_Backend::BackendObject* GetBackendObject(EGLStateContext* state) { MG_Backend::BackendObject* GetBackendObject(EGLStateContext* state) {
File diff suppressed because it is too large Load Diff
+18 -20
View File
@@ -9,24 +9,22 @@
#pragma once #pragma once
#include <Includes.h> #include <Includes.h>
namespace MobileGL { namespace MobileGL::MG_Impl::GLImpl {
namespace MG_Impl::GLImpl { /* @INSERTION_POINT:FUNCTION_DECLARATION@ */
/* @INSERTION_POINT:FUNCTION_DECLARATION@ */ void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params);
void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params); GLboolean IsBuffer(GLuint buffer);
GLboolean IsBuffer(GLuint buffer); void DeleteBuffers(GLsizei n, const GLuint* buffers);
void DeleteBuffers(GLsizei n, const GLuint* buffers); void FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length);
void FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length); GLboolean UnmapBuffer(GLenum target);
GLboolean UnmapBuffer(GLenum target); void* MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
void* MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); void* MapBuffer(GLenum target, GLenum access);
void* MapBuffer(GLenum target, GLenum access); void CopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset,
void CopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
GLsizeiptr size); void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void* data);
void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void* data); void BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
void BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage); void BindBuffer(GLenum target, GLuint buffer);
void BindBuffer(GLenum target, GLuint buffer); void GenBuffers(GLsizei n, GLuint* buffers);
void GenBuffers(GLsizei n, GLuint* buffers); void BindBufferBase(GLenum target, GLuint index, GLuint buffer);
void BindBufferBase(GLenum target, GLuint index, GLuint buffer); void BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
void BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
} // namespace MG_Impl::GLImpl } // namespace MobileGL::MG_Impl::GLImpl
} // namespace MobileGL
+87 -92
View File
@@ -13,105 +13,100 @@
#include <MG_Util/Converters/MGToGL/BufferEnumConverter.h> #include <MG_Util/Converters/MGToGL/BufferEnumConverter.h>
#include <MG_Util/Converters/MGToStr/BufferEnumConverter.h> #include <MG_Util/Converters/MGToStr/BufferEnumConverter.h>
namespace MobileGL::MG_Impl::GLImpl { namespace MobileGL::MG_Impl::GLImpl::BufferImpl {
namespace BufferImpl { Bool ValidateBufferTarget(BufferTarget target) {
Bool ValidateBufferTarget(BufferTarget target) { if (target == BufferTarget::Unknown) {
if (target == BufferTarget::Unknown) { using namespace MG_Util;
using namespace MG_Util; String bufferTargetStr = ConvertBufferTargetToString(target);
String bufferTargetStr = ConvertBufferTargetToString(target); String glTargetStr = ConvertGLEnumToString(ConvertBufferTargetToGLEnum(target));
String glTargetStr = ConvertGLEnumToString(ConvertBufferTargetToGLEnum(target));
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>(
"MG_Impl/GLImpl/BufferImpl", "ValidateBufferTarget",
std::format("Target {} ({}) is not valid.", bufferTargetStr, glTargetStr)));
return false;
}
if (target == BufferTarget::Index && MG_State::pGLContext->GetBoundVertexArray() == nullptr) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl/BufferImpl",
"ValidateBufferTarget",
"No vertex array object is bound."));
return false;
}
return true;
}
Bool ValidateBufferBindingPointTarget(BufferTarget target) {
if (target != BufferTarget::Uniform && target != BufferTarget::AtomicCounter &&
target != BufferTarget::TransformFeedback && target != BufferTarget::ShaderStorage) {
using namespace MG_Util;
String bufferTargetStr = ConvertBufferTargetToString(target);
String glTargetStr = ConvertGLEnumToString(ConvertBufferTargetToGLEnum(target));
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>(
"MG_Impl/GLImpl/BufferImpl", "ValidateBufferTarget",
std::format("Target {} ({}) is not valid.", bufferTargetStr, glTargetStr)));
return false;
}
return true;
}
Bool ValidateBufferName(Uint index, Bool allowZero) {
if (index == 0) {
if (allowZero) return true;
MG_State::pGLContext->RecordError(ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl/BufferImpl",
"ValidateBufferName",
"Buffer name 0 is not valid."));
return false;
}
Bool isValid = MG_State::pGLContext->ValidateBufferName(index);
if (isValid) return true;
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidEnum, MakeUnique<GenericErrorInfo>(
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl/BufferImpl", "ValidateBufferName", "MG_Impl/GLImpl/BufferImpl", "ValidateBufferTarget",
std::format("Buffer name {} is not valid.", index))); std::format("Target {} ({}) is not valid.", bufferTargetStr, glTargetStr)));
return false; return false;
} }
Bool ValidateBufferUsage(BufferUsage usage) { if (target == BufferTarget::Index && MG_State::pGLContext->GetBoundVertexArray() == nullptr) {
if (usage != BufferUsage::Unknown) { MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
return true; MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl/BufferImpl",
} "ValidateBufferTarget",
"No vertex array object is bound."));
return false;
}
return true;
}
Bool ValidateBufferBindingPointTarget(BufferTarget target) {
if (target != BufferTarget::Uniform && target != BufferTarget::AtomicCounter &&
target != BufferTarget::TransformFeedback && target != BufferTarget::ShaderStorage) {
using namespace MG_Util; using namespace MG_Util;
String bufferUsageStr = ConvertBufferUsageToString(usage); String bufferTargetStr = ConvertBufferTargetToString(target);
String glUsageStr = ConvertGLEnumToString(ConvertBufferUsageToGLEnum(usage)); String glTargetStr = ConvertGLEnumToString(ConvertBufferTargetToGLEnum(target));
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeUnique<GenericErrorInfo>(
"MG_Impl/GLImpl/BufferImpl", "ValidateBufferTarget",
std::format("Target {} ({}) is not valid.", bufferTargetStr, glTargetStr)));
return false;
}
return true;
}
Bool ValidateBufferName(Uint index, Bool allowZero) {
if (index == 0) {
if (allowZero) return true;
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl/BufferImpl", "ValidateBufferName",
"Buffer name 0 is not valid."));
return false;
}
Bool isValid = MG_State::pGLContext->ValidateBufferName(index);
if (isValid) return true;
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl/BufferImpl", "ValidateBufferName",
std::format("Buffer name {} is not valid.", index)));
return false;
}
Bool ValidateBufferUsage(BufferUsage usage) {
if (usage != BufferUsage::Unknown) {
return true;
}
using namespace MG_Util;
String bufferUsageStr = ConvertBufferUsageToString(usage);
String glUsageStr = ConvertGLEnumToString(ConvertBufferUsageToGLEnum(usage));
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>(
"MG_Impl/GLImpl/BufferImpl", "ValidateBufferUsage",
std::format("Usage {} ({}) is not one of the allowable values.", bufferUsageStr, glUsageStr)));
return false;
}
Bool ValidateBufferMappingAccess(Flags<BufferMappingAccessBit> accessBits) {
if (accessBits == BufferMappingAccessBit::Null) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl/BufferImpl",
"ValidateBufferMappingAccess",
"Access bits cannot be null."));
return false;
}
const auto validBits = BufferMappingAccessBit::Read | BufferMappingAccessBit::Write |
BufferMappingAccessBit::InvalidateRange | BufferMappingAccessBit::InvalidateBuffer |
BufferMappingAccessBit::FlushExplicit | BufferMappingAccessBit::Unsynchronized |
BufferMappingAccessBit::Persistent | BufferMappingAccessBit::Coherent;
if ((accessBits & validBits) != accessBits) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>( MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl/BufferImpl", "ValidateBufferMappingAccess",
"MG_Impl/GLImpl/BufferImpl", "ValidateBufferUsage", "Access bits cannot contain invalid flags."));
std::format("Usage {} ({}) is not one of the allowable values.", bufferUsageStr, glUsageStr)));
return false; return false;
} }
Bool ValidateBufferMappingAccess(Flags<BufferMappingAccessBit> accessBits) { return true;
if (accessBits == BufferMappingAccessBit::Null) { }
MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum, } // namespace MobileGL::MG_Impl::GLImpl::BufferImpl
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl/BufferImpl",
"ValidateBufferMappingAccess",
"Access bits cannot be null."));
return false;
}
const auto validBits = BufferMappingAccessBit::Read | BufferMappingAccessBit::Write |
BufferMappingAccessBit::InvalidateRange | BufferMappingAccessBit::InvalidateBuffer |
BufferMappingAccessBit::FlushExplicit | BufferMappingAccessBit::Unsynchronized |
BufferMappingAccessBit::Persistent | BufferMappingAccessBit::Coherent;
if ((accessBits & validBits) != accessBits) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl/BufferImpl", "ValidateBufferMappingAccess",
"Access bits cannot contain invalid flags."));
return false;
}
return true;
}
} // namespace BufferImpl
} // namespace MobileGL::MG_Impl::GLImpl
+7 -9
View File
@@ -10,12 +10,10 @@
#include <Includes.h> #include <Includes.h>
#include <MG_State/GLState/BufferState/BufferObject.h> #include <MG_State/GLState/BufferState/BufferObject.h>
namespace MobileGL::MG_Impl::GLImpl { namespace MobileGL::MG_Impl::GLImpl::BufferImpl {
namespace BufferImpl { Bool ValidateBufferTarget(BufferTarget target);
Bool ValidateBufferTarget(BufferTarget target); Bool ValidateBufferName(Uint index, Bool allowZero = false);
Bool ValidateBufferName(Uint index, Bool allowZero = false); Bool ValidateBufferUsage(BufferUsage usage);
Bool ValidateBufferUsage(BufferUsage usage); Bool ValidateBufferMappingAccess(Flags<BufferMappingAccessBit> accessBits);
Bool ValidateBufferMappingAccess(Flags<BufferMappingAccessBit> accessBits); Bool ValidateBufferBindingPointTarget(BufferTarget target);
Bool ValidateBufferBindingPointTarget(BufferTarget target); } // namespace MobileGL::MG_Impl::GLImpl::BufferImpl
} // namespace BufferImpl
} // namespace MobileGL::MG_Impl::GLImpl
+28 -31
View File
@@ -9,34 +9,31 @@
#pragma once #pragma once
#include <Includes.h> #include <Includes.h>
namespace MobileGL { namespace MobileGL::MG_Impl::GLImpl {
namespace MG_Impl::GLImpl { /* @INSERTION_POINT:FUNCTION_DECLARATION@ */
/* @INSERTION_POINT:FUNCTION_DECLARATION@ */ void MultiDrawElementsIndirect(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, GLsizei stride);
void MultiDrawElementsIndirect(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, void MultiDrawArraysIndirect(GLenum mode, const void* indirect, GLsizei drawcount, GLsizei stride);
GLsizei stride); void DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type,
void MultiDrawArraysIndirect(GLenum mode, const void* indirect, GLsizei drawcount, GLsizei stride); const void* indices, GLint basevertex);
void DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices);
const void* indices, GLint basevertex); void DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices,
void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices); GLsizei instancecount, GLint basevertex, GLuint baseinstance);
void DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices, void DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices,
GLsizei instancecount, GLint basevertex, GLuint baseinstance); GLsizei instancecount, GLint basevertex);
void DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices, void DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices,
GLsizei instancecount, GLint basevertex); GLsizei instancecount, GLuint baseinstance);
void DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices, void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount);
GLsizei instancecount, GLuint baseinstance); void DrawElementsIndirect(GLenum mode, GLenum type, const void* indirect);
void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount); void DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, GLsizei instancecount,
void DrawElementsIndirect(GLenum mode, GLenum type, const void* indirect); GLuint baseinstance);
void DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
GLuint baseinstance); void DrawArraysIndirect(GLenum mode, const void* indirect);
void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); void DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices, GLint basevertex);
void DrawArraysIndirect(GLenum mode, const void* indirect); void DrawArrays(GLenum mode, GLint first, GLsizei count);
void DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices, GLint basevertex); void MultiDrawElements(GLenum mode, const GLsizei* count, GLenum type, const void* const* indices,
void DrawArrays(GLenum mode, GLint first, GLsizei count); GLsizei drawcount);
void MultiDrawElements(GLenum mode, const GLsizei* count, GLenum type, const void* const* indices, void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei* count, GLenum type, const void* const* indices,
GLsizei drawcount); GLsizei drawcount, const GLint* basevertex);
void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei* count, GLenum type, const void* const* indices, void Clear(GLbitfield mask);
GLsizei drawcount, const GLint* basevertex); void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices);
void Clear(GLbitfield mask); } // namespace MobileGL::MG_Impl::GLImpl
void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices);
} // namespace MG_Impl::GLImpl
} // namespace MobileGL
@@ -38,11 +38,11 @@ namespace MobileGL::MG_Impl::GLImpl {
RenderbufferTarget rbTarget = MG_Util::ConvertGLEnumToRenderbufferTarget(target); RenderbufferTarget rbTarget = MG_Util::ConvertGLEnumToRenderbufferTarget(target);
if (!FramebufferImpl::ValidateRenderbufferTarget(rbTarget)) return; if (!FramebufferImpl::ValidateRenderbufferTarget(rbTarget)) return;
auto& bindingSlot = MG_State::pGLContext->GetRenderbufferBindingSlot(rbTarget); auto& bindingSlot = MG_State::pGLContext->GetRenderbufferBindingSlot(rbTarget);
auto renderbufferObject = bindingSlot.GetBoundObject(); auto& renderbufferObject = bindingSlot.GetBoundObject();
if (!renderbufferObject) { if (!renderbufferObject) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "RenderbufferStorage_State", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "RenderbufferStorage_State",
"Renderbuffer target is bound to no renderbuffer object.")); "Renderbuffer target is bound to no renderbuffer object."));
return; return;
} }
@@ -50,7 +50,7 @@ namespace MobileGL::MG_Impl::GLImpl {
if (!TextureImpl::ValidateTextureInternalFormat(format)) return; if (!TextureImpl::ValidateTextureInternalFormat(format)) return;
if (width < 0 || height < 0) { if (width < 0 || height < 0) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "RenderbufferStorage_State", ErrorCode::InvalidValue, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "RenderbufferStorage_State",
"Width and height must be non-negative.")); "Width and height must be non-negative."));
return; return;
} }
@@ -74,10 +74,11 @@ namespace MobileGL::MG_Impl::GLImpl {
if (n < 0) { if (n < 0) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GenRenderbuffers_State", "n must be non-negative")); MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "GenRenderbuffers_State", "n must be non-negative"));
return; return;
} }
auto renderbufferNames = MG_State::pGLContext->GenRenderbufferNames(n); static thread_local Vector<GLuint> renderbufferNames;
MG_State::pGLContext->GenRenderbufferNames(n, renderbufferNames);
Memcpy(renderbuffers, renderbufferNames.data(), sizeof(GLuint) * static_cast<SizeT>(n)); Memcpy(renderbuffers, renderbufferNames.data(), sizeof(GLuint) * static_cast<SizeT>(n));
} }
@@ -85,10 +86,11 @@ namespace MobileGL::MG_Impl::GLImpl {
if (n < 0) { if (n < 0) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GenFramebuffers_State", "n must be non-negative")); MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "GenFramebuffers_State", "n must be non-negative"));
return; return;
} }
auto framebuffersNames = MG_State::pGLContext->GenFramebufferNames(n); static thread_local Vector<GLuint> framebuffersNames;
MG_State::pGLContext->GenFramebufferNames(n, framebuffersNames);
Memcpy(framebuffers, framebuffersNames.data(), sizeof(GLuint) * static_cast<SizeT>(n)); Memcpy(framebuffers, framebuffersNames.data(), sizeof(GLuint) * static_cast<SizeT>(n));
} }
@@ -119,11 +121,11 @@ namespace MobileGL::MG_Impl::GLImpl {
if (!TextureImpl::ValidateTextureName(texture, true)) return; if (!TextureImpl::ValidateTextureName(texture, true)) return;
auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(framebufferTarget); auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(framebufferTarget);
auto framebufferObject = bindingSlot.GetBoundObject(); auto& framebufferObject = bindingSlot.GetBoundObject();
if (!framebufferObject) { if (!framebufferObject) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "FramebufferTexture2D_State", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "FramebufferTexture2D_State",
"Framebuffer target is bound to no framebuffer object.")); "Framebuffer target is bound to no framebuffer object."));
return; return;
} }
@@ -133,11 +135,11 @@ namespace MobileGL::MG_Impl::GLImpl {
return; return;
} }
auto textureObject = MG_State::pGLContext->GetTextureObject(texture); auto& textureObject = MG_State::pGLContext->GetTextureObject(texture);
if (!textureObject) { if (!textureObject) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "FramebufferTexture2D_State", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "FramebufferTexture2D_State",
std::format("Texture object {} is not valid.", texture))); std::format("Texture object {} is not valid.", texture)));
return; return;
} }
@@ -166,11 +168,11 @@ namespace MobileGL::MG_Impl::GLImpl {
if (!FramebufferImpl::ValidateFramebufferTarget(framebufferTarget)) return; if (!FramebufferImpl::ValidateFramebufferTarget(framebufferTarget)) return;
if (!FramebufferImpl::ValidateRenderbufferName(renderbuffer)) return; if (!FramebufferImpl::ValidateRenderbufferName(renderbuffer)) return;
auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(framebufferTarget); auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(framebufferTarget);
auto framebufferObject = bindingSlot.GetBoundObject(); auto& framebufferObject = bindingSlot.GetBoundObject();
if (!framebufferObject) { if (!framebufferObject) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "FramebufferRenderbuffer_State", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "FramebufferRenderbuffer_State",
"Framebuffer target is bound to no framebuffer object.")); "Framebuffer target is bound to no framebuffer object."));
return; return;
} }
@@ -180,11 +182,11 @@ namespace MobileGL::MG_Impl::GLImpl {
return; return;
} }
auto renderbufferObject = MG_State::pGLContext->GetRenderbufferObject(renderbuffer); auto& renderbufferObject = MG_State::pGLContext->GetRenderbufferObject(renderbuffer);
if (!renderbufferObject) { if (!renderbufferObject) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "FramebufferRenderbuffer_State", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "FramebufferRenderbuffer_State",
std::format("Renderbuffer object {} is not valid.", renderbuffer))); std::format("Renderbuffer object {} is not valid.", renderbuffer)));
return; return;
} }
@@ -196,18 +198,18 @@ namespace MobileGL::MG_Impl::GLImpl {
if (n < 0) { if (n < 0) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`n` is less than 0.")); MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`n` is less than 0."));
return; return;
} else if (n > MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS) { } else if (n > MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`n` is greater than `GL_MAX_DRAW_BUFFERS`.")); MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`n` is greater than `GL_MAX_DRAW_BUFFERS`."));
return; return;
} }
// Get bound framebuffer // Get bound framebuffer
auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw); auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw);
auto fbo = bindingSlot.GetBoundObject(); auto& fbo = bindingSlot.GetBoundObject();
bool isDefaultFBO = (fbo == FramebufferImpl::pDefaultFramebufferInfo->defaultFBO); bool isDefaultFBO = (fbo == FramebufferImpl::pDefaultFramebufferInfo->defaultFBO);
static int existenceMap[(SizeT)FramebufferAttachmentType::FramebufferAttachmentTypeCount] = {-1}; static int existenceMap[(SizeT)FramebufferAttachmentType::FramebufferAttachmentTypeCount] = {-1};
@@ -220,7 +222,7 @@ namespace MobileGL::MG_Impl::GLImpl {
if (attType == FramebufferAttachmentType::Unknown) { if (attType == FramebufferAttachmentType::Unknown) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
std::format("bufs[{}] = {} is not an accepted value.", i, std::format("bufs[{}] = {} is not an accepted value.", i,
MG_Util::ConvertGLEnumToString(bufs[i])))); MG_Util::ConvertGLEnumToString(bufs[i]))));
return; return;
@@ -230,7 +232,7 @@ namespace MobileGL::MG_Impl::GLImpl {
attType <= FramebufferAttachmentType::Color31) { attType <= FramebufferAttachmentType::Color31) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>( MakeUnique<GenericErrorInfo>(
"MG_Impl/GLImpl", __func__, "MG_Impl/GLImpl", __func__,
std::format( std::format(
"FBO is default FBO, but bufs[{}] = {} is one of the `GL_COLOR_ATTACHMENTn` tokens.", i, "FBO is default FBO, but bufs[{}] = {} is one of the `GL_COLOR_ATTACHMENTn` tokens.", i,
@@ -242,7 +244,7 @@ namespace MobileGL::MG_Impl::GLImpl {
attType <= FramebufferAttachmentType::BackRight) { attType <= FramebufferAttachmentType::BackRight) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>( MakeUnique<GenericErrorInfo>(
"MG_Impl/GLImpl", __func__, "MG_Impl/GLImpl", __func__,
std::format("FBO is not default FBO, but bufs[{}] = {} is anything other than `GL_NONE` or " std::format("FBO is not default FBO, but bufs[{}] = {} is anything other than `GL_NONE` or "
"one of the `GL_COLOR_ATTACHMENTn` tokens.", "one of the `GL_COLOR_ATTACHMENTn` tokens.",
@@ -253,7 +255,7 @@ namespace MobileGL::MG_Impl::GLImpl {
if (attType != FramebufferAttachmentType::None && existenceMap[(SizeT)attType] >= 0) { if (attType != FramebufferAttachmentType::None && existenceMap[(SizeT)attType] >= 0) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
std::format("a symbolic constant other than `GL_NONE` appears " std::format("a symbolic constant other than `GL_NONE` appears "
"more than once in bufs. bufs[{}] == bufs[{}] == {}.", "more than once in bufs. bufs[{}] == bufs[{}] == {}.",
i, existenceMap[(SizeT)attType], i, existenceMap[(SizeT)attType],
@@ -267,7 +269,7 @@ namespace MobileGL::MG_Impl::GLImpl {
(SizeT)FramebufferAttachmentType::Color0 + MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS) { (SizeT)FramebufferAttachmentType::Color0 + MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
std::format("bufs[{}] == {} indicates a color buffer that does " std::format("bufs[{}] == {} indicates a color buffer that does "
"not exist in the current GL context.", "not exist in the current GL context.",
i, MG_Util::ConvertGLEnumToString(bufs[i])))); i, MG_Util::ConvertGLEnumToString(bufs[i]))));
@@ -297,7 +299,7 @@ namespace MobileGL::MG_Impl::GLImpl {
if (attType == FramebufferAttachmentType::Unknown) { if (attType == FramebufferAttachmentType::Unknown) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>( MakeUnique<GenericErrorInfo>(
"MG_Impl/GLImpl", __func__, "MG_Impl/GLImpl", __func__,
std::format("`mode` = {} is not an accepted value.", MG_Util::ConvertGLEnumToString(mode)))); std::format("`mode` = {} is not an accepted value.", MG_Util::ConvertGLEnumToString(mode))));
return; return;
@@ -305,7 +307,7 @@ namespace MobileGL::MG_Impl::GLImpl {
// Get bound framebuffer // Get bound framebuffer
auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read); auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read);
auto fbo = bindingSlot.GetBoundObject(); auto& fbo = bindingSlot.GetBoundObject();
fbo->SetReadBuffer(attType); fbo->SetReadBuffer(attType);
} }
@@ -313,13 +315,13 @@ namespace MobileGL::MG_Impl::GLImpl {
if (n < 0) { if (n < 0) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "DeleteRenderbuffers_State", "n must be non-negative.")); MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "DeleteRenderbuffers_State", "n must be non-negative."));
return; return;
} }
if (!renderbuffers) { if (!renderbuffers) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "DeleteRenderbuffers_State", ErrorCode::InvalidValue, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "DeleteRenderbuffers_State",
"Renderbuffer names array cannot be null.")); "Renderbuffer names array cannot be null."));
return; return;
} }
@@ -336,13 +338,13 @@ namespace MobileGL::MG_Impl::GLImpl {
if (n < 0) { if (n < 0) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "DeleteFramebuffers_State", "n must be non-negative.")); MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "DeleteFramebuffers_State", "n must be non-negative."));
return; return;
} }
if (!framebuffers) { if (!framebuffers) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidValue, MG_State::pGLContext->RecordError(ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "DeleteFramebuffers_State", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "DeleteFramebuffers_State",
"Framebuffer names array cannot be null.")); "Framebuffer names array cannot be null."));
return; return;
} }
@@ -360,11 +362,11 @@ namespace MobileGL::MG_Impl::GLImpl {
if (!FramebufferImpl::ValidateFramebufferTarget(framebufferTarget)) return GL_FRAMEBUFFER_UNDEFINED; if (!FramebufferImpl::ValidateFramebufferTarget(framebufferTarget)) return GL_FRAMEBUFFER_UNDEFINED;
auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(framebufferTarget); auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(framebufferTarget);
auto framebufferObject = bindingSlot.GetBoundObject(); auto& framebufferObject = bindingSlot.GetBoundObject();
if (!framebufferObject) { if (!framebufferObject) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "CheckFramebufferStatus_State", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "CheckFramebufferStatus_State",
"Framebuffer target is bound to no framebuffer object.")); "Framebuffer target is bound to no framebuffer object."));
return GL_FRAMEBUFFER_UNDEFINED; return GL_FRAMEBUFFER_UNDEFINED;
} }
@@ -382,11 +384,11 @@ namespace MobileGL::MG_Impl::GLImpl {
RenderbufferTarget renderbufferTarget = MG_Util::ConvertGLEnumToRenderbufferTarget(target); RenderbufferTarget renderbufferTarget = MG_Util::ConvertGLEnumToRenderbufferTarget(target);
if (!FramebufferImpl::ValidateRenderbufferTarget(renderbufferTarget)) return; if (!FramebufferImpl::ValidateRenderbufferTarget(renderbufferTarget)) return;
auto renderbufferObject = MG_State::pGLContext->GetRenderbufferObject(renderbuffer); Bool doesRenderbufferCreated = MG_State::pGLContext->ValidateRenderbufferObject(renderbuffer);
if (!renderbufferObject) { if (!doesRenderbufferCreated) {
MG_State::pGLContext->CreateRenderbufferObject(renderbuffer); MG_State::pGLContext->CreateRenderbufferObject(renderbuffer);
renderbufferObject = MG_State::pGLContext->GetRenderbufferObject(renderbuffer);
} }
auto& renderbufferObject = MG_State::pGLContext->GetRenderbufferObject(renderbuffer);
auto& bindingSlot = MG_State::pGLContext->GetRenderbufferBindingSlot(renderbufferTarget); auto& bindingSlot = MG_State::pGLContext->GetRenderbufferBindingSlot(renderbufferTarget);
bindingSlot.Bind(renderbufferObject); bindingSlot.Bind(renderbufferObject);
@@ -403,11 +405,11 @@ namespace MobileGL::MG_Impl::GLImpl {
FramebufferTarget framebufferTarget = MG_Util::ConvertGLEnumToFramebufferTarget(target); FramebufferTarget framebufferTarget = MG_Util::ConvertGLEnumToFramebufferTarget(target);
if (!FramebufferImpl::ValidateFramebufferTarget(framebufferTarget)) return; if (!FramebufferImpl::ValidateFramebufferTarget(framebufferTarget)) return;
auto framebufferObject = MG_State::pGLContext->GetFramebufferObject(framebuffer); Bool doesFramebufferCreated = MG_State::pGLContext->ValidateFramebufferObject(framebuffer);
if (!framebufferObject) { if (!doesFramebufferCreated) {
MG_State::pGLContext->CreateFramebufferObject(framebuffer); MG_State::pGLContext->CreateFramebufferObject(framebuffer);
framebufferObject = MG_State::pGLContext->GetFramebufferObject(framebuffer);
} }
auto& framebufferObject = MG_State::pGLContext->GetFramebufferObject(framebuffer);
auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(framebufferTarget); auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(framebufferTarget);
bindingSlot.Bind(framebufferObject); bindingSlot.Bind(framebufferObject);
@@ -419,11 +421,11 @@ namespace MobileGL::MG_Impl::GLImpl {
RenderbufferTarget renderbufferTarget = MG_Util::ConvertGLEnumToRenderbufferTarget(target); RenderbufferTarget renderbufferTarget = MG_Util::ConvertGLEnumToRenderbufferTarget(target);
if (!FramebufferImpl::ValidateRenderbufferTarget(renderbufferTarget)) return; if (!FramebufferImpl::ValidateRenderbufferTarget(renderbufferTarget)) return;
auto& bindingSlot = MG_State::pGLContext->GetRenderbufferBindingSlot(renderbufferTarget); auto& bindingSlot = MG_State::pGLContext->GetRenderbufferBindingSlot(renderbufferTarget);
auto renderbufferObject = bindingSlot.GetBoundObject(); auto& renderbufferObject = bindingSlot.GetBoundObject();
if (!renderbufferObject) { if (!renderbufferObject) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GetRenderbufferParameteriv_State", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "GetRenderbufferParameteriv_State",
"Renderbuffer target is bound to no renderbuffer object.")); "Renderbuffer target is bound to no renderbuffer object."));
return; return;
} }
@@ -462,7 +464,7 @@ namespace MobileGL::MG_Impl::GLImpl {
default: default:
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>( MakeUnique<GenericErrorInfo>(
"MG_Impl/GLImpl", "GetRenderbufferParameteriv_State", "MG_Impl/GLImpl", "GetRenderbufferParameteriv_State",
std::format("pname {} is not an accepted value.", MG_Util::ConvertGLEnumToString(pname)))); std::format("pname {} is not an accepted value.", MG_Util::ConvertGLEnumToString(pname))));
return; return;
@@ -492,7 +494,7 @@ namespace MobileGL::MG_Impl::GLImpl {
// Check width/height // Check width/height
if (width < 0 || height < 0) { if (width < 0 || height < 0) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidValue, MG_State::pGLContext->RecordError(ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State",
"Width and height must be non-negative")); "Width and height must be non-negative"));
return; return;
} }
@@ -501,7 +503,7 @@ namespace MobileGL::MG_Impl::GLImpl {
if (!TextureImpl::ValidateTextureInputFormat(textureInputFormat)) { if (!TextureImpl::ValidateTextureInputFormat(textureInputFormat)) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State", "Invalid format")); MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State", "Invalid format"));
return; return;
} }
@@ -509,17 +511,17 @@ namespace MobileGL::MG_Impl::GLImpl {
if (!TextureImpl::ValidateTexturePixelDataType(texturePixelDataType)) { if (!TextureImpl::ValidateTexturePixelDataType(texturePixelDataType)) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State", "Invalid pixel data type")); MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State", "Invalid pixel data type"));
return; return;
} }
// Get bound framebuffer // Get bound framebuffer
auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read); auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read);
auto framebufferObject = bindingSlot.GetBoundObject(); auto& framebufferObject = bindingSlot.GetBoundObject();
if (!framebufferObject) { if (!framebufferObject) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation, MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State",
"No framebuffer bound to read target")); "No framebuffer bound to read target"));
return; return;
} }
@@ -528,7 +530,7 @@ namespace MobileGL::MG_Impl::GLImpl {
if (!framebufferObject->CheckCompleteness()) { if (!framebufferObject->CheckCompleteness()) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidFramebufferOperation, ErrorCode::InvalidFramebufferOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State", "Framebuffer is incomplete")); MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State", "Framebuffer is incomplete"));
return; return;
} }
@@ -537,7 +539,7 @@ namespace MobileGL::MG_Impl::GLImpl {
if (!framebufferObject->GetAttachment(FramebufferAttachmentType::Stencil).IsValid()) { if (!framebufferObject->GetAttachment(FramebufferAttachmentType::Stencil).IsValid()) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State",
"No stencil buffer for stencil index format")); "No stencil buffer for stencil index format"));
return; return;
} }
@@ -545,7 +547,7 @@ namespace MobileGL::MG_Impl::GLImpl {
if (!framebufferObject->GetAttachment(FramebufferAttachmentType::Depth).IsValid()) { if (!framebufferObject->GetAttachment(FramebufferAttachmentType::Depth).IsValid()) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State",
"No depth buffer for depth component format")); "No depth buffer for depth component format"));
return; return;
} }
@@ -554,7 +556,7 @@ namespace MobileGL::MG_Impl::GLImpl {
!framebufferObject->GetAttachment(FramebufferAttachmentType::Stencil).IsValid()) { !framebufferObject->GetAttachment(FramebufferAttachmentType::Stencil).IsValid()) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State",
"No depth/stencil buffer for depth-stencil format")); "No depth/stencil buffer for depth-stencil format"));
return; return;
} }
@@ -563,7 +565,7 @@ namespace MobileGL::MG_Impl::GLImpl {
if (texturePixelDataType != TexturePixelDataType::UnsignedInt248 && if (texturePixelDataType != TexturePixelDataType::UnsignedInt248 &&
texturePixelDataType != TexturePixelDataType::Float32UnsignedInt248Rev) { texturePixelDataType != TexturePixelDataType::Float32UnsignedInt248Rev) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State", ErrorCode::InvalidEnum, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State",
"Invalid type for depth-stencil format")); "Invalid type for depth-stencil format"));
return; return;
} }
@@ -577,7 +579,7 @@ namespace MobileGL::MG_Impl::GLImpl {
// Check if PBO is mapped // Check if PBO is mapped
if (pixelPackBufferObject->IsMapped()) { if (pixelPackBufferObject->IsMapped()) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State", ErrorCode::InvalidOperation, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State",
"Pixel pack buffer is currently mapped")); "Pixel pack buffer is currently mapped"));
return; return;
} }
@@ -587,7 +589,7 @@ namespace MobileGL::MG_Impl::GLImpl {
if (reinterpret_cast<uintptr_t>(pixels) % typeSize != 0) { if (reinterpret_cast<uintptr_t>(pixels) % typeSize != 0) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State",
"Pixel data not aligned for pixel pack buffer")); "Pixel data not aligned for pixel pack buffer"));
return; return;
} }
@@ -595,11 +597,11 @@ namespace MobileGL::MG_Impl::GLImpl {
// Check multisampling // Check multisampling
if (framebufferObject->GetAttachment(FramebufferAttachmentType::Color0).IsRenderbuffer()) { if (framebufferObject->GetAttachment(FramebufferAttachmentType::Color0).IsRenderbuffer()) {
auto rbo = framebufferObject->GetAttachment(FramebufferAttachmentType::Color0).GetRenderbuffer(); auto& rbo = framebufferObject->GetAttachment(FramebufferAttachmentType::Color0).GetRenderbuffer();
if (rbo && rbo->GetSamples() > 1) { if (rbo && rbo->GetSamples() > 1) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ReadPixels_State",
"ReadPixels not supported for multisampled framebuffers")); "ReadPixels not supported for multisampled framebuffers"));
return; return;
} }
@@ -732,6 +734,6 @@ namespace MobileGL::MG_Impl::GLImpl {
} }
namespace FramebufferImpl { namespace FramebufferImpl {
DefaultFramebufferInfo* pDefaultFramebufferInfo; UniquePtr<DefaultFramebufferInfo> pDefaultFramebufferInfo;
} // namespace FramebufferImpl } // namespace FramebufferImpl
} // namespace MobileGL::MG_Impl::GLImpl } // namespace MobileGL::MG_Impl::GLImpl
@@ -11,51 +11,49 @@
#include <Includes.h> #include <Includes.h>
#include <MG_State/GLState/Core.h> #include <MG_State/GLState/Core.h>
namespace MobileGL { namespace MobileGL::MG_Impl::GLImpl {
namespace MG_Impl::GLImpl { /* @INSERTION_POINT:FUNCTION_DECLARATION@ */
/* @INSERTION_POINT:FUNCTION_DECLARATION@ */ void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels);
void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels); void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); void ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value);
void ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value); void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value);
void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value); void ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value);
void ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value); void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width,
void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
GLsizei height); void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); GLboolean IsRenderbuffer(GLuint renderbuffer);
GLboolean IsRenderbuffer(GLuint renderbuffer); void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params);
void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params); void GenRenderbuffers(GLsizei n, GLuint* renderbuffers);
void GenRenderbuffers(GLsizei n, GLuint* renderbuffers); void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers);
void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers); void BindRenderbuffer(GLenum target, GLuint renderbuffer);
void BindRenderbuffer(GLenum target, GLuint renderbuffer); void SampleMaski(GLuint maskNumber, GLbitfield mask);
void SampleMaski(GLuint maskNumber, GLbitfield mask); GLboolean IsFramebuffer(GLuint framebuffer);
GLboolean IsFramebuffer(GLuint framebuffer); void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params);
void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params); void GenFramebuffers(GLsizei n, GLuint* framebuffers);
void GenFramebuffers(GLsizei n, GLuint* framebuffers); void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); void FramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level,
void FramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
GLint zoffset); void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); void FramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
void FramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); void FramebufferTexture(GLenum target, GLenum attachment, GLuint texture, GLint level);
void FramebufferTexture(GLenum target, GLenum attachment, GLuint texture, GLint level); void DrawBuffer(GLenum buf);
void DrawBuffer(GLenum buf); void DrawBuffers(GLsizei n, const GLenum* bufs);
void DrawBuffers(GLsizei n, const GLenum* bufs); void ReadBuffer(GLenum src);
void ReadBuffer(GLenum src); void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers);
void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers); GLenum CheckFramebufferStatus(GLenum target);
GLenum CheckFramebufferStatus(GLenum target); void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1,
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
GLint dstY1, GLbitfield mask, GLenum filter); void BindFramebuffer(GLenum target, GLuint framebuffer);
void BindFramebuffer(GLenum target, GLuint framebuffer);
namespace FramebufferImpl { namespace FramebufferImpl {
struct DefaultFramebufferInfo { struct DefaultFramebufferInfo {
SharedPtr<MG_State::GLState::FramebufferObject> defaultFBO; SharedPtr<MG_State::GLState::FramebufferObject> defaultFBO;
SharedPtr<MG_State::GLState::ITextureObject> colorAttachment; SharedPtr<MG_State::GLState::ITextureObject> colorAttachment;
SharedPtr<MG_State::GLState::ITextureObject> depthAttachment; SharedPtr<MG_State::GLState::ITextureObject> depthAttachment;
SharedPtr<MG_State::GLState::ITextureObject> stencilAttachment; SharedPtr<MG_State::GLState::ITextureObject> stencilAttachment;
}; };
extern DefaultFramebufferInfo* pDefaultFramebufferInfo; extern UniquePtr<DefaultFramebufferInfo> pDefaultFramebufferInfo;
} // namespace FramebufferImpl } // namespace FramebufferImpl
} // namespace MG_Impl::GLImpl } // namespace MobileGL::MG_Impl::GLImpl
} // namespace MobileGL
@@ -13,85 +13,82 @@
#include <MG_Util/Converters/MGToGL/FramebufferEnumConverter.h> #include <MG_Util/Converters/MGToGL/FramebufferEnumConverter.h>
#include <MG_Util/Converters/MGToStr/FramebufferEnumConverter.h> #include <MG_Util/Converters/MGToStr/FramebufferEnumConverter.h>
namespace MobileGL::MG_Impl::GLImpl { namespace MobileGL::MG_Impl::GLImpl::FramebufferImpl {
namespace FramebufferImpl { Bool ValidateFramebufferTarget(FramebufferTarget target) {
Bool ValidateFramebufferTarget(FramebufferTarget target) { if (target == FramebufferTarget::Unknown) {
if (target == FramebufferTarget::Unknown) { using namespace MG_Util;
using namespace MG_Util; String bufferTargetStr = ConvertFramebufferTargetToString(target);
String bufferTargetStr = ConvertFramebufferTargetToString(target); String glTargetStr = ConvertGLEnumToString(ConvertFramebufferTargetToGLEnum(target));
String glTargetStr = ConvertGLEnumToString(ConvertFramebufferTargetToGLEnum(target));
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>(
"MG_Impl/GLImpl/FramebufferImpl", "ValidateFramebufferTarget",
std::format("Target {} ({}) is not valid.", bufferTargetStr, glTargetStr)));
return false;
}
return true;
}
Bool ValidateFramebufferName(Uint index, Bool allowZero) {
if (index == 0 && !allowZero) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl/FramebufferImpl", "ValidateFramebufferName",
"Framebuffer name 0 is not valid in this situation."));
return false;
}
Bool isValid = MG_State::pGLContext->ValidateFramebufferName(index);
if (isValid) return true;
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidEnum, MakeUnique<GenericErrorInfo>(
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl/FramebufferImpl", "ValidateFramebufferName", "MG_Impl/GLImpl/FramebufferImpl", "ValidateFramebufferTarget",
std::format("Framebuffer name {} is not valid.", index))); std::format("Target {} ({}) is not valid.", bufferTargetStr, glTargetStr)));
return false; return false;
} }
return true;
}
Bool ValidateFramebufferAttachmentType(FramebufferAttachmentType attachment) { Bool ValidateFramebufferName(Uint index, Bool allowZero) {
if (attachment == FramebufferAttachmentType::Unknown) { if (index == 0 && !allowZero) {
using namespace MG_Util;
String attachmentStr = ConvertFramebufferAttachmentTypeToString(attachment);
String glAttachmentStr = ConvertGLEnumToString(ConvertFramebufferAttachmentTypeToGLEnum(attachment));
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>(
"MG_Impl/GLImpl/FramebufferImpl", "ValidateFramebufferAttachmentType",
std::format("Attachment type {} ({}) is not valid.", attachmentStr, glAttachmentStr)));
return false;
}
return true;
}
Bool ValidateRenderbufferTarget(RenderbufferTarget target) {
if (target == RenderbufferTarget::Unknown) {
using namespace MG_Util;
String renderbufferTargetStr = ConvertRenderbufferTargetToString(target);
String glTargetStr = ConvertGLEnumToString(ConvertRenderbufferTargetToGLEnum(target));
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>(
"MG_Impl/GLImpl/FramebufferImpl", "ValidateRenderbufferTarget",
std::format("Target {} ({}) is not valid.", renderbufferTargetStr, glTargetStr)));
return false;
}
return true;
}
Bool ValidateRenderbufferName(Uint index, Bool allowZero) {
if (index == 0 && !allowZero) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl/FramebufferImpl", "ValidateRenderbufferName",
"Renderbuffer name 0 is not valid in this situation."));
return false;
}
Bool isValid = MG_State::pGLContext->ValidateRenderbufferName(index);
if (isValid) return true;
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl/FramebufferImpl", "ValidateRenderbufferName", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl/FramebufferImpl", "ValidateFramebufferName",
std::format("Renderbuffer name {} is not valid.", index))); "Framebuffer name 0 is not valid in this situation."));
return false; return false;
} }
} // namespace FramebufferImpl Bool isValid = MG_State::pGLContext->ValidateFramebufferName(index);
} // namespace MobileGL::MG_Impl::GLImpl if (isValid) return true;
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl/FramebufferImpl", "ValidateFramebufferName",
std::format("Framebuffer name {} is not valid.", index)));
return false;
}
Bool ValidateFramebufferAttachmentType(FramebufferAttachmentType attachment) {
if (attachment == FramebufferAttachmentType::Unknown) {
using namespace MG_Util;
String attachmentStr = ConvertFramebufferAttachmentTypeToString(attachment);
String glAttachmentStr = ConvertGLEnumToString(ConvertFramebufferAttachmentTypeToGLEnum(attachment));
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>(
"MG_Impl/GLImpl/FramebufferImpl", "ValidateFramebufferAttachmentType",
std::format("Attachment type {} ({}) is not valid.", attachmentStr, glAttachmentStr)));
return false;
}
return true;
}
Bool ValidateRenderbufferTarget(RenderbufferTarget target) {
if (target == RenderbufferTarget::Unknown) {
using namespace MG_Util;
String renderbufferTargetStr = ConvertRenderbufferTargetToString(target);
String glTargetStr = ConvertGLEnumToString(ConvertRenderbufferTargetToGLEnum(target));
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>(
"MG_Impl/GLImpl/FramebufferImpl", "ValidateRenderbufferTarget",
std::format("Target {} ({}) is not valid.", renderbufferTargetStr, glTargetStr)));
return false;
}
return true;
}
Bool ValidateRenderbufferName(Uint index, Bool allowZero) {
if (index == 0 && !allowZero) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl/FramebufferImpl", "ValidateRenderbufferName",
"Renderbuffer name 0 is not valid in this situation."));
return false;
}
Bool isValid = MG_State::pGLContext->ValidateRenderbufferName(index);
if (isValid) return true;
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl/FramebufferImpl", "ValidateRenderbufferName",
std::format("Renderbuffer name {} is not valid.", index)));
return false;
}
} // namespace MobileGL::MG_Impl::GLImpl::FramebufferImpl
@@ -10,12 +10,10 @@
#include <Includes.h> #include <Includes.h>
#include <MG_State/GLState/FramebufferState/FramebufferObject.h> #include <MG_State/GLState/FramebufferState/FramebufferObject.h>
namespace MobileGL::MG_Impl::GLImpl { namespace MobileGL::MG_Impl::GLImpl::FramebufferImpl {
namespace FramebufferImpl { Bool ValidateFramebufferTarget(FramebufferTarget target);
Bool ValidateFramebufferTarget(FramebufferTarget target); Bool ValidateFramebufferName(Uint index, Bool allowZero = true);
Bool ValidateFramebufferName(Uint index, Bool allowZero = true); Bool ValidateFramebufferAttachmentType(FramebufferAttachmentType attachment);
Bool ValidateFramebufferAttachmentType(FramebufferAttachmentType attachment); Bool ValidateRenderbufferTarget(RenderbufferTarget target);
Bool ValidateRenderbufferTarget(RenderbufferTarget target); Bool ValidateRenderbufferName(Uint index, Bool allowZero = true);
Bool ValidateRenderbufferName(Uint index, Bool allowZero = true); } // namespace MobileGL::MG_Impl::GLImpl::FramebufferImpl
} // namespace FramebufferImpl
} // namespace MobileGL::MG_Impl::GLImpl
+15 -14
View File
@@ -7,8 +7,6 @@
// End of Source File Header // End of Source File Header
#include "GL_Getter.h" #include "GL_Getter.h"
#include "GL/gl.h"
#include "MG_Util/Debug/Log.h"
#include <Config.h> #include <Config.h>
#include <MGGitHash.h> #include <MGGitHash.h>
#include <MG_State/GLState/Core.h> #include <MG_State/GLState/Core.h>
@@ -127,7 +125,7 @@ namespace MobileGL::MG_Impl::GLImpl {
if (!params) { if (!params) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GetIntegerv", "params pointer cannot be null")); MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "GetIntegerv", "params pointer cannot be null"));
return; return;
} }
@@ -146,9 +144,9 @@ namespace MobileGL::MG_Impl::GLImpl {
*params = 0; // TODO *params = 0; // TODO
break; break;
case GL_ARRAY_BUFFER_BINDING: { case GL_ARRAY_BUFFER_BINDING: {
auto obj = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Vertex).GetBoundObject(); auto& obj = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Vertex).GetBoundObject();
if (obj) if (obj)
*params = obj->GetExternalIndex(); *params = (GLint)obj->GetExternalIndex();
else else
*params = 0; *params = 0;
break; break;
@@ -256,14 +254,14 @@ namespace MobileGL::MG_Impl::GLImpl {
break; break;
case GL_CURRENT_PROGRAM: { case GL_CURRENT_PROGRAM: {
const auto& currentProgram = MG_State::pGLContext->GetCurrentProgram(); const auto& currentProgram = MG_State::pGLContext->GetCurrentProgram();
*params = currentProgram ? currentProgram->GetExternalIndex() : 0; *params = currentProgram ? (GLint)currentProgram->GetExternalIndex() : 0;
break; break;
} }
case GL_DEPTH_CLEAR_VALUE: case GL_DEPTH_CLEAR_VALUE:
*params = MG_State::pGLContext->GetClearDepth(); *params = (GLint)MG_State::pGLContext->GetClearDepth();
break; break;
case GL_DEPTH_FUNC: case GL_DEPTH_FUNC:
*params = MG_Util::ConvertDepthTestFuncToGLEnum(MG_State::pGLContext->GetDepthFunc()); *params = (GLint)MG_Util::ConvertDepthTestFuncToGLEnum(MG_State::pGLContext->GetDepthFunc());
break; break;
case GL_DEPTH_RANGE: case GL_DEPTH_RANGE:
*params = 0; // TODO *params = 0; // TODO
@@ -288,12 +286,12 @@ namespace MobileGL::MG_Impl::GLImpl {
break; break;
case GL_DRAW_FRAMEBUFFER_BINDING: { case GL_DRAW_FRAMEBUFFER_BINDING: {
const auto& FBO = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); const auto& FBO = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject();
*params = FBO ? FBO->GetExternalIndex() : 0; *params = FBO ? (GLint)FBO->GetExternalIndex() : 0;
break; break;
} }
case GL_READ_FRAMEBUFFER_BINDING: { case GL_READ_FRAMEBUFFER_BINDING: {
const auto& FBO = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); const auto& FBO = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject();
*params = FBO ? FBO->GetExternalIndex() : 0; *params = FBO ? (GLint)FBO->GetExternalIndex() : 0;
break; break;
} }
case GL_ELEMENT_ARRAY_BUFFER_BINDING: { case GL_ELEMENT_ARRAY_BUFFER_BINDING: {
@@ -302,7 +300,7 @@ namespace MobileGL::MG_Impl::GLImpl {
break; break;
} }
const auto& bufferObject = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Index).GetBoundObject(); const auto& bufferObject = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Index).GetBoundObject();
*params = bufferObject ? bufferObject->GetExternalIndex() : 0; *params = bufferObject ? (GLint)bufferObject->GetExternalIndex() : 0;
break; break;
} }
case GL_FRAGMENT_SHADER_DERIVATIVE_HINT: case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
@@ -886,7 +884,7 @@ namespace MobileGL::MG_Impl::GLImpl {
default: default:
MGLOG_E("glGetIntegerv: Invalid enum %s (0x%X)", MG_Util::ConvertGLEnumToString(pname).c_str(), pname); MGLOG_E("glGetIntegerv: Invalid enum %s (0x%X)", MG_Util::ConvertGLEnumToString(pname).c_str(), pname);
MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum, MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GetIntegerv", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "GetIntegerv",
std::format("Invalid enum: 0x{:X}", pname))); std::format("Invalid enum: 0x{:X}", pname)));
break; break;
@@ -894,7 +892,10 @@ namespace MobileGL::MG_Impl::GLImpl {
} }
GLenum GetError() { GLenum GetError() {
ErrorCode errorCode = MG_State::pGLContext->PopGLError().value_or(Error{ErrorCode::NoError, nullptr}).code; auto error = MG_State::pGLContext->PopGLError();
return MG_Util::ConvertErrorCodeToGLEnum(errorCode); if (!error || !error->get()) {
return GL_NO_ERROR;
}
return MG_Util::ConvertErrorCodeToGLEnum(error->get()->code);
} }
} // namespace MobileGL::MG_Impl::GLImpl } // namespace MobileGL::MG_Impl::GLImpl
File diff suppressed because it is too large Load Diff
+56 -58
View File
@@ -9,61 +9,59 @@
#pragma once #pragma once
#include <Includes.h> #include <Includes.h>
namespace MobileGL { namespace MobileGL::MG_Impl::GLImpl {
namespace MG_Impl::GLImpl { void AttachShader(GLuint program, GLuint shader);
void AttachShader(GLuint program, GLuint shader); void BindAttribLocation(GLuint program, GLuint index, const GLchar* name);
void BindAttribLocation(GLuint program, GLuint index, const GLchar* name); void CompileShader(GLuint shader);
void CompileShader(GLuint shader); GLuint CreateProgram(void);
GLuint CreateProgram(void); GLuint CreateShader(GLenum type);
GLuint CreateShader(GLenum type); void DeleteProgram(GLuint program);
void DeleteProgram(GLuint program); void DeleteShader(GLuint shader);
void DeleteShader(GLuint shader); void DetachShader(GLuint program, GLuint shader);
void DetachShader(GLuint program, GLuint shader); void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size, GLenum* type,
void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
GLchar* name); void GetActiveUniform(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size, GLenum* type,
void GetActiveUniform(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
GLchar* name); void GetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders);
void GetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders); GLint GetAttribLocation(GLuint program, const GLchar* name);
GLint GetAttribLocation(GLuint program, const GLchar* name); void GetProgramiv(GLuint program, GLenum pname, GLint* params);
void GetProgramiv(GLuint program, GLenum pname, GLint* params); void GetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
void GetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog); void GetShaderiv(GLuint shader, GLenum pname, GLint* params);
void GetShaderiv(GLuint shader, GLenum pname, GLint* params); void GetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
void GetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog); void GetShaderSource(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* source);
void GetShaderSource(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* source); GLint GetUniformLocation(GLuint program, const GLchar* name);
GLint GetUniformLocation(GLuint program, const GLchar* name); void GetUniformfv(GLuint program, GLint location, GLfloat* params);
void GetUniformfv(GLuint program, GLint location, GLfloat* params); void GetUniformiv(GLuint program, GLint location, GLint* params);
void GetUniformiv(GLuint program, GLint location, GLint* params); GLboolean IsProgram(GLuint program);
GLboolean IsProgram(GLuint program); GLboolean IsShader(GLuint shader);
GLboolean IsShader(GLuint shader); void LinkProgram(GLuint program);
void LinkProgram(GLuint program); void ShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length);
void ShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length); void UseProgram(GLuint program);
void UseProgram(GLuint program); void Uniform1f(GLint location, GLfloat v0);
void Uniform1f(GLint location, GLfloat v0); void Uniform2f(GLint location, GLfloat v0, GLfloat v1);
void Uniform2f(GLint location, GLfloat v0, GLfloat v1); void Uniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
void Uniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); void Uniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
void Uniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); void Uniform1i(GLint location, GLint v0);
void Uniform1i(GLint location, GLint v0); void Uniform2i(GLint location, GLint v0, GLint v1);
void Uniform2i(GLint location, GLint v0, GLint v1); void Uniform3i(GLint location, GLint v0, GLint v1, GLint v2);
void Uniform3i(GLint location, GLint v0, GLint v1, GLint v2); void Uniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
void Uniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); void Uniform1fv(GLint location, GLsizei count, const GLfloat* value);
void Uniform1fv(GLint location, GLsizei count, const GLfloat* value); void Uniform2fv(GLint location, GLsizei count, const GLfloat* value);
void Uniform2fv(GLint location, GLsizei count, const GLfloat* value); void Uniform3fv(GLint location, GLsizei count, const GLfloat* value);
void Uniform3fv(GLint location, GLsizei count, const GLfloat* value); void Uniform4fv(GLint location, GLsizei count, const GLfloat* value);
void Uniform4fv(GLint location, GLsizei count, const GLfloat* value); void Uniform1iv(GLint location, GLsizei count, const GLint* value);
void Uniform1iv(GLint location, GLsizei count, const GLint* value); void Uniform2iv(GLint location, GLsizei count, const GLint* value);
void Uniform2iv(GLint location, GLsizei count, const GLint* value); void Uniform3iv(GLint location, GLsizei count, const GLint* value);
void Uniform3iv(GLint location, GLsizei count, const GLint* value); void Uniform4iv(GLint location, GLsizei count, const GLint* value);
void Uniform4iv(GLint location, GLsizei count, const GLint* value); void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); GLuint GetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName);
GLuint GetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName); void UniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
void UniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); void GetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params);
void GetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params); void GetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length,
void GetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName);
GLchar* uniformBlockName); void BindFragDataLocation(GLuint program, GLuint colorNumber, const char* name);
void BindFragDataLocation(GLuint program, GLuint colorNumber, const char* name); GLint GetFragDataLocation(GLuint program, const char* name);
GLint GetFragDataLocation(GLuint program, const char* name); void ValidateProgram(GLuint program);
void ValidateProgram(GLuint program); } // namespace MobileGL::MG_Impl::GLImpl
} // namespace MG_Impl::GLImpl
} // namespace MobileGL
@@ -7,474 +7,467 @@
// End of Source File Header // End of Source File Header
#include "GL_RenderState.h" #include "GL_RenderState.h"
#include "MG_State/GLState/RenderState/RenderState.h"
#include "MG_Util/Converters/GLToStr/GLEnumConverter.h"
#include <MG_State/GLState/Core.h> #include <MG_State/GLState/Core.h>
#include <MG_Util/Converters/GLToStr/GLEnumConverter.h>
#include <MG_Util/Converters/GLToMG/RenderStateEnumConverter.h> #include <MG_Util/Converters/GLToMG/RenderStateEnumConverter.h>
#include <MG_Util/Converters/MGToGL/RenderStateEnumConverter.h> #include <MG_Util/Converters/MGToGL/RenderStateEnumConverter.h>
#include <MG_Util/Converters/MGToStr/RenderStateEnumConverter.h> #include <MG_Util/Converters/MGToStr/RenderStateEnumConverter.h>
namespace MobileGL { namespace MobileGL::MG_Impl::GLImpl {
namespace MG_Impl::GLImpl { void Viewport_State(GLint x, GLint y, GLsizei width, GLsizei height) {
void Viewport_State(GLint x, GLint y, GLsizei width, GLsizei height) { if (width < 0 || height < 0) {
if (width < 0 || height < 0) { MG_State::pGLContext->RecordError(ErrorCode::InvalidValue,
MG_State::pGLContext->RecordError( MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "Viewport_State",
ErrorCode::InvalidValue, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "Viewport_State", "Width abd height must be non-negative."));
"Width abd height must be non-negative.")); return;
return; }
}
MG_State::pGLContext->SetViewport(IntVec4(x, y, width, height));
MG_State::pGLContext->SetViewport(IntVec4(x, y, width, height)); }
}
void StencilOpSeparate_State(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) {
void StencilOpSeparate_State(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) { // TODO: implement
// TODO: implement }
}
void StencilOp_State(GLenum fail, GLenum zfail, GLenum zpass) {
void StencilOp_State(GLenum fail, GLenum zfail, GLenum zpass) { // TODO: implement
// TODO: implement }
}
void StencilMaskSeparate_State(GLenum face, GLuint mask) {
void StencilMaskSeparate_State(GLenum face, GLuint mask) { // TODO: implement
// TODO: implement }
}
void StencilMask_State(GLuint mask) {
void StencilMask_State(GLuint mask) { // TODO: implement
// TODO: implement }
}
void StencilFuncSeparate_State(GLenum face, GLenum func, GLint ref, GLuint mask) {
void StencilFuncSeparate_State(GLenum face, GLenum func, GLint ref, GLuint mask) { // TODO: implement
// TODO: implement }
}
void StencilFunc_State(GLenum func, GLint ref, GLuint mask) {
void StencilFunc_State(GLenum func, GLint ref, GLuint mask) { // TODO: implement
// TODO: implement }
}
void Scissor_State(GLint x, GLint y, GLsizei width, GLsizei height) {
void Scissor_State(GLint x, GLint y, GLsizei width, GLsizei height) { if (width < 0 || height < 0) {
if (width < 0 || height < 0) { MG_State::pGLContext->RecordError(ErrorCode::InvalidValue,
MG_State::pGLContext->RecordError( MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "Scissor_State",
ErrorCode::InvalidValue, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "Scissor_State", "Width abd height must be non-negative."));
"Width abd height must be non-negative.")); return;
return; }
}
MG_State::pGLContext->SetScissorBox(IntVec4(x, y, width, height));
MG_State::pGLContext->SetScissorBox(IntVec4(x, y, width, height)); }
}
void SampleCoverage_State(GLfloat value, GLboolean invert) {
void SampleCoverage_State(GLfloat value, GLboolean invert) { // TODO: implement
// TODO: implement }
}
void PolygonOffset_State(GLfloat factor, GLfloat units) {
void PolygonOffset_State(GLfloat factor, GLfloat units) { // TODO: implement
// TODO: implement }
}
void PolygonMode_State(GLenum face, GLenum mode) {
void PolygonMode_State(GLenum face, GLenum mode) { // TODO: implement
// TODO: implement }
}
void PointSize_State(GLfloat size) {
void PointSize_State(GLfloat size) { // TODO: implement
// TODO: implement }
}
void PointParameterf_State(GLenum pname, GLfloat param) {
void PointParameterf_State(GLenum pname, GLfloat param) { // TODO: implement
// TODO: implement }
}
void PointParameteri_State(GLenum pname, GLint param) {
void PointParameteri_State(GLenum pname, GLint param) { // TODO: implement
// TODO: implement }
}
void PixelStorei_State(GLenum pname, GLint param) {
void PixelStorei_State(GLenum pname, GLint param) { MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), param);
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), param); PixelStoreParam pixelStoreParam = MG_Util::ConvertGLEnumToPixelStoreParam(pname);
PixelStoreParam pixelStoreParam = MG_Util::ConvertGLEnumToPixelStoreParam(pname); if (pixelStoreParam == PixelStoreParam::Unknown) {
if (pixelStoreParam == PixelStoreParam::Unknown) { MG_State::pGLContext->RecordError(
MG_State::pGLContext->RecordError( ErrorCode::InvalidEnum,
ErrorCode::InvalidEnum, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "PixelStorei_State",
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "PixelStorei_State", "Pixel store param enum " +
"Pixel store param enum " + MG_Util::ConvertPixelStoreParamToString(pixelStoreParam) + "(" +
MG_Util::ConvertPixelStoreParamToString(pixelStoreParam) + "(" + MG_Util::ConvertGLEnumToString(pname) + ") is not supported."));
MG_Util::ConvertGLEnumToString(pname) + ") is not supported.")); return;
return; }
}
MG_State::pGLContext->SetPixelStoreParam(pixelStoreParam, param);
MG_State::pGLContext->SetPixelStoreParam(pixelStoreParam, param); }
}
void LogicOp_State(GLenum opcode) {
void LogicOp_State(GLenum opcode) { // TODO: implement
// TODO: implement }
}
void LineWidth_State(GLfloat width) {
void LineWidth_State(GLfloat width) { // TODO: implement
// TODO: implement }
}
GLboolean IsEnabledi_State(GLenum target, GLuint index) {
GLboolean IsEnabledi_State(GLenum target, GLuint index) { CapabilityInput capInput = MG_Util::ConvertGLEnumToCapabilityInput(target);
CapabilityInput capInput = MG_Util::ConvertGLEnumToCapabilityInput(target); if (capInput == CapabilityInput::Unknown) {
if (capInput == CapabilityInput::Unknown) { MG_State::pGLContext->RecordError(
MG_State::pGLContext->RecordError( ErrorCode::InvalidEnum,
ErrorCode::InvalidEnum, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "IsEnabledi_State",
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "IsEnabledi_State", "Capability enum " + MG_Util::ConvertCapabilityInputToString(capInput) +
"Capability enum " + "(" + MG_Util::ConvertGLEnumToString(target) + ") is not supported."));
MG_Util::ConvertCapabilityInputToString(capInput) + "(" + return GL_FALSE;
MG_Util::ConvertGLEnumToString(target) + ") is not supported.")); }
return GL_FALSE;
} return MG_State::pGLContext->IsCapabilityEnabledIndexed(capInput, index) ? GL_TRUE : GL_FALSE;
}
return MG_State::pGLContext->IsCapabilityEnabledIndexed(capInput, index) ? GL_TRUE : GL_FALSE;
} GLboolean IsEnabled_State(GLenum cap) {
CapabilityInput capInput = MG_Util::ConvertGLEnumToCapabilityInput(cap);
GLboolean IsEnabled_State(GLenum cap) { if (capInput == CapabilityInput::Unknown) {
CapabilityInput capInput = MG_Util::ConvertGLEnumToCapabilityInput(cap); MG_State::pGLContext->RecordError(
if (capInput == CapabilityInput::Unknown) { ErrorCode::InvalidEnum,
MG_State::pGLContext->RecordError( MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "IsEnabled_State",
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>( "Capability enum " + MG_Util::ConvertCapabilityInputToString(capInput) +
"MG_Impl/GLImpl", "IsEnabled_State", "(" + MG_Util::ConvertGLEnumToString(cap) + ") is not supported."));
"Capability enum " + MG_Util::ConvertCapabilityInputToString(capInput) + return GL_FALSE;
"(" + MG_Util::ConvertGLEnumToString(cap) + ") is not supported.")); }
return GL_FALSE;
} return MG_State::pGLContext->IsCapabilityEnabled(capInput) ? GL_TRUE : GL_FALSE;
}
return MG_State::pGLContext->IsCapabilityEnabled(capInput) ? GL_TRUE : GL_FALSE;
} void Hint_State(GLenum target, GLenum mode) {
// TODO: implement
void Hint_State(GLenum target, GLenum mode) { }
// TODO: implement
} void FrontFace_State(GLenum mode) {
// TODO: implement
void FrontFace_State(GLenum mode) { }
// TODO: implement
} void Enable_State(GLenum cap) {
CapabilityInput capInput = MG_Util::ConvertGLEnumToCapabilityInput(cap);
void Enable_State(GLenum cap) { if (capInput == CapabilityInput::Unknown) {
CapabilityInput capInput = MG_Util::ConvertGLEnumToCapabilityInput(cap); MG_State::pGLContext->RecordError(
if (capInput == CapabilityInput::Unknown) { ErrorCode::InvalidEnum,
MG_State::pGLContext->RecordError( MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "Enable_State",
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>( "Capability enum " + MG_Util::ConvertCapabilityInputToString(capInput) +
"MG_Impl/GLImpl", "Enable_State", "(" + MG_Util::ConvertGLEnumToString(cap) + ") is not supported."));
"Capability enum " + MG_Util::ConvertCapabilityInputToString(capInput) + return;
"(" + MG_Util::ConvertGLEnumToString(cap) + ") is not supported.")); }
return;
} MG_State::pGLContext->SetCapability(capInput, true);
}
MG_State::pGLContext->SetCapability(capInput, true);
} void Disable_State(GLenum cap) {
CapabilityInput capInput = MG_Util::ConvertGLEnumToCapabilityInput(cap);
void Disable_State(GLenum cap) { if (capInput == CapabilityInput::Unknown) {
CapabilityInput capInput = MG_Util::ConvertGLEnumToCapabilityInput(cap); MG_State::pGLContext->RecordError(
if (capInput == CapabilityInput::Unknown) { ErrorCode::InvalidEnum,
MG_State::pGLContext->RecordError( MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "Disable_State",
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>( "Capability enum " + MG_Util::ConvertCapabilityInputToString(capInput) +
"MG_Impl/GLImpl", "Disable_State", "(" + MG_Util::ConvertGLEnumToString(cap) + ") is not supported."));
"Capability enum " + MG_Util::ConvertCapabilityInputToString(capInput) + return;
"(" + MG_Util::ConvertGLEnumToString(cap) + ") is not supported.")); }
return;
} MG_State::pGLContext->SetCapability(capInput, false);
}
MG_State::pGLContext->SetCapability(capInput, false);
} void DepthRange_State(GLclampd near_val, GLclampd far_val) {
// TODO: implement
void DepthRange_State(GLclampd near_val, GLclampd far_val) { }
// TODO: implement
} void DepthMask_State(GLboolean flag) {
MG_State::pGLContext->SetDepthMask(flag == GL_TRUE);
void DepthMask_State(GLboolean flag) { }
MG_State::pGLContext->SetDepthMask(flag == GL_TRUE);
} void DepthFunc_State(GLenum func) {
DepthTestFunc depthFunc = MG_Util::ConvertGLEnumToDepthTestFunc(func);
void DepthFunc_State(GLenum func) { if (depthFunc == DepthTestFunc::Unknown) {
DepthTestFunc depthFunc = MG_Util::ConvertGLEnumToDepthTestFunc(func); MG_State::pGLContext->RecordError(
if (depthFunc == DepthTestFunc::Unknown) { ErrorCode::InvalidEnum,
MG_State::pGLContext->RecordError( MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "DepthFunc_State",
ErrorCode::InvalidEnum, "Depth function enum " + MG_Util::ConvertDepthTestFuncToString(depthFunc) +
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "DepthFunc_State", "(" + MG_Util::ConvertGLEnumToString(func) + ") is not supported."));
"Depth function enum " + return;
MG_Util::ConvertDepthTestFuncToString(depthFunc) + "(" + }
MG_Util::ConvertGLEnumToString(func) + ") is not supported."));
return; MG_State::pGLContext->SetDepthFunc(depthFunc);
} }
MG_State::pGLContext->SetDepthFunc(depthFunc); void CullFace_State(GLenum mode) {
} CullFaceMode cullFaceMode = MG_Util::ConvertGLEnumToCullFaceMode(mode);
if (cullFaceMode == CullFaceMode::Unknown) {
void CullFace_State(GLenum mode) { MG_State::pGLContext->RecordError(
CullFaceMode cullFaceMode = MG_Util::ConvertGLEnumToCullFaceMode(mode); ErrorCode::InvalidEnum,
if (cullFaceMode == CullFaceMode::Unknown) { MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "CullFace_State",
MG_State::pGLContext->RecordError( "Cull face mode enum " +
ErrorCode::InvalidEnum, MG_Util::ConvertCullFaceModeToString(cullFaceMode) + "(" +
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "CullFace_State", MG_Util::ConvertGLEnumToString(mode) + ") is not supported."));
"Cull face mode enum " + return;
MG_Util::ConvertCullFaceModeToString(cullFaceMode) + "(" + }
MG_Util::ConvertGLEnumToString(mode) + ") is not supported."));
return; MG_State::pGLContext->SetCullFaceMode(cullFaceMode);
} }
MG_State::pGLContext->SetCullFaceMode(cullFaceMode); void ColorMask_State(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
} MG_State::pGLContext->SetColorMask(
BoolVec4(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE));
void ColorMask_State(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { }
MG_State::pGLContext->SetColorMask(
BoolVec4(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE)); void ClampColor_State(GLenum target, GLenum clamp) {
} // TODO: implement
}
void ClampColor_State(GLenum target, GLenum clamp) {
// TODO: implement void BlendFuncSeparate_State(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) {
} BlendFactor srcRGB = MG_Util::ConvertGLEnumToBlendFactor(sfactorRGB);
BlendFactor dstRGB = MG_Util::ConvertGLEnumToBlendFactor(dfactorRGB);
void BlendFuncSeparate_State(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) { BlendFactor srcAlpha = MG_Util::ConvertGLEnumToBlendFactor(sfactorAlpha);
BlendFactor srcRGB = MG_Util::ConvertGLEnumToBlendFactor(sfactorRGB); BlendFactor dstAlpha = MG_Util::ConvertGLEnumToBlendFactor(dfactorAlpha);
BlendFactor dstRGB = MG_Util::ConvertGLEnumToBlendFactor(dfactorRGB);
BlendFactor srcAlpha = MG_Util::ConvertGLEnumToBlendFactor(sfactorAlpha); if (srcRGB == BlendFactor::Unknown || dstRGB == BlendFactor::Unknown || srcAlpha == BlendFactor::Unknown ||
BlendFactor dstAlpha = MG_Util::ConvertGLEnumToBlendFactor(dfactorAlpha); dstAlpha == BlendFactor::Unknown) {
MG_State::pGLContext->RecordError(
if (srcRGB == BlendFactor::Unknown || dstRGB == BlendFactor::Unknown || srcAlpha == BlendFactor::Unknown || ErrorCode::InvalidEnum,
dstAlpha == BlendFactor::Unknown) { MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "BlendFuncSeparate_State",
MG_State::pGLContext->RecordError( "One of the blend factor enums is not supported: srcRGB " +
ErrorCode::InvalidEnum, MG_Util::ConvertBlendFactorToString(srcRGB) + "(" +
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "BlendFuncSeparate_State", MG_Util::ConvertGLEnumToString(sfactorRGB) + "), dstRGB " +
"One of the blend factor enums is not supported: srcRGB " + MG_Util::ConvertBlendFactorToString(dstRGB) + "(" +
MG_Util::ConvertBlendFactorToString(srcRGB) + "(" + MG_Util::ConvertGLEnumToString(dfactorRGB) + "), srcAlpha " +
MG_Util::ConvertGLEnumToString(sfactorRGB) + "), dstRGB " + MG_Util::ConvertBlendFactorToString(srcAlpha) + "(" +
MG_Util::ConvertBlendFactorToString(dstRGB) + "(" + MG_Util::ConvertGLEnumToString(sfactorAlpha) + "), dstAlpha " +
MG_Util::ConvertGLEnumToString(dfactorRGB) + "), srcAlpha " + MG_Util::ConvertBlendFactorToString(dstAlpha) + "(" +
MG_Util::ConvertBlendFactorToString(srcAlpha) + "(" + MG_Util::ConvertGLEnumToString(dfactorAlpha) + ")."));
MG_Util::ConvertGLEnumToString(sfactorAlpha) + "), dstAlpha " + return;
MG_Util::ConvertBlendFactorToString(dstAlpha) + "(" + }
MG_Util::ConvertGLEnumToString(dfactorAlpha) + ")."));
return; MG_State::pGLContext->SetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha);
} }
MG_State::pGLContext->SetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha); void BlendFunc_State(GLenum sfactor, GLenum dfactor) {
} BlendFuncSeparate_State(sfactor, dfactor, sfactor, dfactor);
}
void BlendFunc_State(GLenum sfactor, GLenum dfactor) {
BlendFuncSeparate_State(sfactor, dfactor, sfactor, dfactor); void BlendEquation_State(GLenum mode) {
} // TODO: implement
}
void BlendEquation_State(GLenum mode) {
// TODO: implement void BlendColor_State(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
} // TODO: implement
}
void BlendColor_State(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
// TODO: implement void ClearStencil_State(GLint s) {
} MG_State::pGLContext->SetClearStencil(static_cast<Int>(s));
}
void ClearStencil_State(GLint s) {
MG_State::pGLContext->SetClearStencil(static_cast<Int>(s)); void ClearDepth_State(GLclampd depth) {
} MG_State::pGLContext->SetClearDepth(static_cast<Float>(depth));
}
void ClearDepth_State(GLclampd depth) {
MG_State::pGLContext->SetClearDepth(static_cast<Float>(depth)); void ClearColor_State(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
} MG_State::pGLContext->SetClearColor(FloatVec4(red, green, blue, alpha));
}
void BlendFuncSeparatei_State(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
if (buf >= MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>(
"MG_Impl/GLImpl", "BlendFuncSeparatei_State",
"Buffer index " + std::to_string(buf) + " is out of range. Max supported is " +
std::to_string(MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS - 1) + "."));
return;
}
BlendFactor srcRGBM = MG_Util::ConvertGLEnumToBlendFactor(srcRGB);
BlendFactor dstRGBM = MG_Util::ConvertGLEnumToBlendFactor(dstRGB);
BlendFactor srcAlphaM = MG_Util::ConvertGLEnumToBlendFactor(srcAlpha);
BlendFactor dstAlphaM = MG_Util::ConvertGLEnumToBlendFactor(dstAlpha);
MG_State::pGLContext->SetBlendFuncIndexed(buf, srcRGBM, dstRGBM, srcAlphaM, dstAlphaM);
}
void Disablei_State(GLenum target, GLuint index) {
auto capInput = MG_Util::ConvertGLEnumToCapabilityInput(target);
if (capInput == CapabilityInput::Unknown) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "Disablei_State",
"Capability enum " + MG_Util::ConvertCapabilityInputToString(capInput) +
"(" + MG_Util::ConvertGLEnumToString(target) + ") is not supported."));
return;
}
MG_State::pGLContext->SetCapabilityIndexed(capInput, index, false);
}
void Enablei_State(GLenum target, GLuint index) {
auto capInput = MG_Util::ConvertGLEnumToCapabilityInput(target);
if (capInput == CapabilityInput::Unknown) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "Enablei_State",
"Capability enum " + MG_Util::ConvertCapabilityInputToString(capInput) +
"(" + MG_Util::ConvertGLEnumToString(target) + ") is not supported."));
return;
}
MG_State::pGLContext->SetCapabilityIndexed(capInput, index, true);
}
/* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */
void BlendFuncSeparatei(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
BlendFuncSeparatei_State(buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void Disablei(GLenum target, GLuint index) {
Disablei_State(target, index);
}
void Enablei(GLenum target, GLuint index) {
Enablei_State(target, index);
}
void BlendFunc(GLenum sfactor, GLenum dfactor) {
BlendFunc_State(sfactor, dfactor);
}
void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) {
Viewport_State(x, y, width, height);
}
void StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) {
StencilOpSeparate_State(face, sfail, dpfail, dppass);
}
void StencilOp(GLenum fail, GLenum zfail, GLenum zpass) {
StencilOp_State(fail, zfail, zpass);
}
void StencilMaskSeparate(GLenum face, GLuint mask) {
StencilMaskSeparate_State(face, mask);
}
void StencilMask(GLuint mask) {
StencilMask_State(mask);
}
void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) {
StencilFuncSeparate_State(face, func, ref, mask);
}
void StencilFunc(GLenum func, GLint ref, GLuint mask) {
StencilFunc_State(func, ref, mask);
}
void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) {
Scissor_State(x, y, width, height);
}
void SampleCoverage(GLfloat value, GLboolean invert) {
SampleCoverage_State(value, invert);
}
void PolygonOffset(GLfloat factor, GLfloat units) {
PolygonOffset_State(factor, units);
}
void PolygonMode(GLenum face, GLenum mode) {
PolygonMode_State(face, mode);
}
void PointSize(GLfloat size) {
PointSize_State(size);
}
void PointParameterf(GLenum pname, GLfloat param) {
PointParameterf_State(pname, param);
}
void PointParameteri(GLenum pname, GLint param) {
PointParameteri_State(pname, param);
}
void PixelStorei(GLenum pname, GLint param) {
PixelStorei_State(pname, param);
}
void LogicOp(GLenum opcode) {
LogicOp_State(opcode);
}
void ClearColor_State(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { void LineWidth(GLfloat width) {
MG_State::pGLContext->SetClearColor(FloatVec4(red, green, blue, alpha)); LineWidth_State(width);
} }
void BlendFuncSeparatei_State(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) { GLboolean IsEnabledi(GLenum target, GLuint index) {
if (buf >= MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS) { return IsEnabledi_State(target, index);
MG_State::pGLContext->RecordError( }
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>( GLboolean IsEnabled(GLenum cap) {
"MG_Impl/GLImpl", "BlendFuncSeparatei_State", return IsEnabled_State(cap);
"Buffer index " + std::to_string(buf) + " is out of range. Max supported is " + }
std::to_string(MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS - 1) + "."));
return;
}
BlendFactor srcRGBM = MG_Util::ConvertGLEnumToBlendFactor(srcRGB);
BlendFactor dstRGBM = MG_Util::ConvertGLEnumToBlendFactor(dstRGB);
BlendFactor srcAlphaM = MG_Util::ConvertGLEnumToBlendFactor(srcAlpha);
BlendFactor dstAlphaM = MG_Util::ConvertGLEnumToBlendFactor(dstAlpha);
MG_State::pGLContext->SetBlendFuncIndexed(buf, srcRGBM, dstRGBM, srcAlphaM, dstAlphaM);
}
void Disablei_State(GLenum target, GLuint index) {
auto capInput = MG_Util::ConvertGLEnumToCapabilityInput(target);
if (capInput == CapabilityInput::Unknown) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "Disablei_State",
"Capability enum " +
MG_Util::ConvertCapabilityInputToString(capInput) + "(" +
MG_Util::ConvertGLEnumToString(target) + ") is not supported."));
return;
}
MG_State::pGLContext->SetCapabilityIndexed(capInput, index, false);
}
void Enablei_State(GLenum target, GLuint index) {
auto capInput = MG_Util::ConvertGLEnumToCapabilityInput(target);
if (capInput == CapabilityInput::Unknown) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "Enablei_State",
"Capability enum " +
MG_Util::ConvertCapabilityInputToString(capInput) + "(" +
MG_Util::ConvertGLEnumToString(target) + ") is not supported."));
return;
}
MG_State::pGLContext->SetCapabilityIndexed(capInput, index, true);
}
/* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */
void BlendFuncSeparatei(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
BlendFuncSeparatei_State(buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void Disablei(GLenum target, GLuint index) {
Disablei_State(target, index);
}
void Enablei(GLenum target, GLuint index) {
Enablei_State(target, index);
}
void BlendFunc(GLenum sfactor, GLenum dfactor) {
BlendFunc_State(sfactor, dfactor);
}
void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) {
Viewport_State(x, y, width, height);
}
void StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) {
StencilOpSeparate_State(face, sfail, dpfail, dppass);
}
void StencilOp(GLenum fail, GLenum zfail, GLenum zpass) {
StencilOp_State(fail, zfail, zpass);
}
void StencilMaskSeparate(GLenum face, GLuint mask) {
StencilMaskSeparate_State(face, mask);
}
void StencilMask(GLuint mask) {
StencilMask_State(mask);
}
void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) {
StencilFuncSeparate_State(face, func, ref, mask);
}
void StencilFunc(GLenum func, GLint ref, GLuint mask) {
StencilFunc_State(func, ref, mask);
}
void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) {
Scissor_State(x, y, width, height);
}
void SampleCoverage(GLfloat value, GLboolean invert) {
SampleCoverage_State(value, invert);
}
void PolygonOffset(GLfloat factor, GLfloat units) {
PolygonOffset_State(factor, units);
}
void PolygonMode(GLenum face, GLenum mode) { void Hint(GLenum target, GLenum mode) {
PolygonMode_State(face, mode); Hint_State(target, mode);
} }
void PointSize(GLfloat size) { void FrontFace(GLenum mode) {
PointSize_State(size); FrontFace_State(mode);
} }
void Enable(GLenum cap) {
Enable_State(cap);
}
void PointParameterf(GLenum pname, GLfloat param) { void Disable(GLenum cap) {
PointParameterf_State(pname, param); Disable_State(cap);
} }
void PointParameteri(GLenum pname, GLint param) { void DepthRange(GLclampd near_val, GLclampd far_val) {
PointParameteri_State(pname, param); DepthRange_State(near_val, far_val);
} }
void PixelStorei(GLenum pname, GLint param) { void DepthMask(GLboolean flag) {
PixelStorei_State(pname, param); DepthMask_State(flag);
} }
void LogicOp(GLenum opcode) {
LogicOp_State(opcode);
}
void LineWidth(GLfloat width) {
LineWidth_State(width);
}
GLboolean IsEnabledi(GLenum target, GLuint index) { void DepthFunc(GLenum func) {
return IsEnabledi_State(target, index); DepthFunc_State(func);
} }
GLboolean IsEnabled(GLenum cap) { void CullFace(GLenum mode) {
return IsEnabled_State(cap); CullFace_State(mode);
} }
void Hint(GLenum target, GLenum mode) { void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
Hint_State(target, mode); ColorMask_State(red, green, blue, alpha);
} }
void FrontFace(GLenum mode) { void ClampColor(GLenum target, GLenum clamp) {
FrontFace_State(mode); ClampColor_State(target, clamp);
} }
void Enable(GLenum cap) { void BlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) {
Enable_State(cap); BlendFuncSeparate_State(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
} }
void Disable(GLenum cap) { void BlendEquation(GLenum mode) {
Disable_State(cap); BlendEquation_State(mode);
} }
void DepthRange(GLclampd near_val, GLclampd far_val) { void BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
DepthRange_State(near_val, far_val); BlendColor_State(red, green, blue, alpha);
} }
void DepthMask(GLboolean flag) { void ClearStencil(GLint s) {
DepthMask_State(flag); ClearStencil_State(s);
} }
void DepthFunc(GLenum func) { void ClearDepth(GLclampd depth) {
DepthFunc_State(func); ClearDepth_State(depth);
} }
void CullFace(GLenum mode) { void ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
CullFace_State(mode); ClearColor_State(red, green, blue, alpha);
} }
} // namespace MobileGL::MG_Impl::GLImpl
void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
ColorMask_State(red, green, blue, alpha);
}
void ClampColor(GLenum target, GLenum clamp) {
ClampColor_State(target, clamp);
}
void BlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) {
BlendFuncSeparate_State(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
}
void BlendEquation(GLenum mode) {
BlendEquation_State(mode);
}
void BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
BlendColor_State(red, green, blue, alpha);
}
void ClearStencil(GLint s) {
ClearStencil_State(s);
}
void ClearDepth(GLclampd depth) {
ClearDepth_State(depth);
}
void ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
ClearColor_State(red, green, blue, alpha);
}
} // namespace MG_Impl::GLImpl
} // namespace MobileGL
@@ -9,47 +9,45 @@
#pragma once #pragma once
#include <Includes.h> #include <Includes.h>
namespace MobileGL { namespace MobileGL::MG_Impl::GLImpl {
namespace MG_Impl::GLImpl { /* @INSERTION_POINT:FUNCTION_DECLARATION@ */
/* @INSERTION_POINT:FUNCTION_DECLARATION@ */ void BlendFuncSeparatei(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
void BlendFuncSeparatei(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); void Disablei(GLenum target, GLuint index);
void Disablei(GLenum target, GLuint index); void Enablei(GLenum target, GLuint index);
void Enablei(GLenum target, GLuint index); void BlendFunc(GLenum sfactor, GLenum dfactor);
void BlendFunc(GLenum sfactor, GLenum dfactor); void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
void Viewport(GLint x, GLint y, GLsizei width, GLsizei height); void StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
void StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); void StencilOp(GLenum fail, GLenum zfail, GLenum zpass);
void StencilOp(GLenum fail, GLenum zfail, GLenum zpass); void StencilMaskSeparate(GLenum face, GLuint mask);
void StencilMaskSeparate(GLenum face, GLuint mask); void StencilMask(GLuint mask);
void StencilMask(GLuint mask); void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask); void StencilFunc(GLenum func, GLint ref, GLuint mask);
void StencilFunc(GLenum func, GLint ref, GLuint mask); void Scissor(GLint x, GLint y, GLsizei width, GLsizei height);
void Scissor(GLint x, GLint y, GLsizei width, GLsizei height); void SampleCoverage(GLfloat value, GLboolean invert);
void SampleCoverage(GLfloat value, GLboolean invert); void PolygonOffset(GLfloat factor, GLfloat units);
void PolygonOffset(GLfloat factor, GLfloat units); void PolygonMode(GLenum face, GLenum mode);
void PolygonMode(GLenum face, GLenum mode); void PointSize(GLfloat size);
void PointSize(GLfloat size); void PointParameterf(GLenum pname, GLfloat param);
void PointParameterf(GLenum pname, GLfloat param); void PointParameteri(GLenum pname, GLint param);
void PointParameteri(GLenum pname, GLint param); void PixelStorei(GLenum pname, GLint param);
void PixelStorei(GLenum pname, GLint param); void LogicOp(GLenum opcode);
void LogicOp(GLenum opcode); void LineWidth(GLfloat width);
void LineWidth(GLfloat width); GLboolean IsEnabledi(GLenum target, GLuint index);
GLboolean IsEnabledi(GLenum target, GLuint index); GLboolean IsEnabled(GLenum cap);
GLboolean IsEnabled(GLenum cap); void Hint(GLenum target, GLenum mode);
void Hint(GLenum target, GLenum mode); void FrontFace(GLenum mode);
void FrontFace(GLenum mode); void Enable(GLenum cap);
void Enable(GLenum cap); void Disable(GLenum cap);
void Disable(GLenum cap); void DepthRange(GLclampd near_val, GLclampd far_val);
void DepthRange(GLclampd near_val, GLclampd far_val); void DepthMask(GLboolean flag);
void DepthMask(GLboolean flag); void DepthFunc(GLenum func);
void DepthFunc(GLenum func); void CullFace(GLenum mode);
void CullFace(GLenum mode); void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); void ClampColor(GLenum target, GLenum clamp);
void ClampColor(GLenum target, GLenum clamp); void BlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
void BlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); void BlendEquation(GLenum mode);
void BlendEquation(GLenum mode); void BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
void BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); void ClearStencil(GLint s);
void ClearStencil(GLint s); void ClearDepth(GLclampd depth);
void ClearDepth(GLclampd depth); void ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
void ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); } // namespace MobileGL::MG_Impl::GLImpl
} // namespace MG_Impl::GLImpl
} // namespace MobileGL
+233 -229
View File
@@ -12,254 +12,258 @@
#include <MG_Util/Converters/GLToMG/TextureEnumConverter.h> #include <MG_Util/Converters/GLToMG/TextureEnumConverter.h>
#include <MG_Util/Converters/MGToGL/TextureEnumConverter.h> #include <MG_Util/Converters/MGToGL/TextureEnumConverter.h>
namespace MobileGL { namespace MobileGL::MG_Impl::GLImpl {
namespace MG_Impl::GLImpl { void SetSamplerParam_State(GLuint sampler, GLenum pname, const void* param, bool isFloat, bool isInteger) {
void SetSamplerParam_State(GLuint sampler, GLenum pname, const void* param, bool isFloat, bool isInteger) { if (!SamplerImpl::ValidateSamplerName(sampler)) return;
Bool doesSamplerObjectCreated = MG_State::pGLContext->ValidateSamplerObject(sampler);
if (!doesSamplerObjectCreated) {
// Create one for compatibility
MG_State::pGLContext->CreateSamplerObject(sampler);
}
auto& samplerObj = MG_State::pGLContext->GetSamplerObject(sampler);
if (!SamplerImpl::ValidateSamplerObject(sampler)) return;
using namespace MG_Util;
switch (pname) {
case GL_TEXTURE_WRAP_S:
samplerObj->SetWrapS(MG_Util::ConvertGLEnumToSamplerWrapMode(*(const GLint*)param));
break;
case GL_TEXTURE_WRAP_T:
samplerObj->SetWrapT(MG_Util::ConvertGLEnumToSamplerWrapMode(*(const GLint*)param));
break;
case GL_TEXTURE_WRAP_R:
samplerObj->SetWrapR(MG_Util::ConvertGLEnumToSamplerWrapMode(*(const GLint*)param));
break;
case GL_TEXTURE_MIN_FILTER:
samplerObj->SetMinFilter(MG_Util::ConvertGLEnumToSamplerFilterMode(*(const GLint*)param));
samplerObj->SetMipmapMode(MG_Util::ConvertGLEnumToSamplerMipmapMode(*(const GLint*)param));
break;
case GL_TEXTURE_MAG_FILTER:
samplerObj->SetMagFilter(MG_Util::ConvertGLEnumToSamplerFilterMode(*(const GLint*)param));
break;
case GL_TEXTURE_MIN_LOD:
samplerObj->SetLodRange(*(const GLfloat*)param, samplerObj->GetMaxLod());
break;
case GL_TEXTURE_MAX_LOD:
samplerObj->SetLodRange(samplerObj->GetMinLod(), *(const GLfloat*)param);
break;
case GL_TEXTURE_LOD_BIAS:
samplerObj->SetLodBias(*(const GLfloat*)param);
break;
case GL_TEXTURE_COMPARE_MODE:
samplerObj->SetCompareMode(MG_Util::ConvertGLEnumToSamplerCompareMode(*(const GLint*)param));
break;
case GL_TEXTURE_COMPARE_FUNC:
samplerObj->SetSamplerCompareFunc(MG_Util::ConvertGLEnumToSamplerCompareFunc(*(const GLint*)param));
break;
default:
MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "SetSamplerParam_State",
"Invalid pname for sampler parameter"));
}
}
void GetSamplerParam_State(GLuint sampler, GLenum pname, void* params, bool isFloat, bool isInteger) {
if (!SamplerImpl::ValidateSamplerName(sampler)) return;
Bool doesSamplerObjectCreated = MG_State::pGLContext->ValidateSamplerObject(sampler);
if (!doesSamplerObjectCreated) {
// Create one for compatibility
MG_State::pGLContext->CreateSamplerObject(sampler);
}
auto& samplerObj = MG_State::pGLContext->GetSamplerObject(sampler);
if (!SamplerImpl::ValidateSamplerObject(sampler)) return;
using namespace MG_Util;
switch (pname) {
case GL_TEXTURE_WRAP_S:
*(GLuint*)params = MG_Util::ConvertSamplerWrapModeToGLEnum(samplerObj->GetWrapS());
break;
case GL_TEXTURE_WRAP_T:
*(GLuint*)params = MG_Util::ConvertSamplerWrapModeToGLEnum(samplerObj->GetWrapT());
break;
case GL_TEXTURE_WRAP_R:
*(GLuint*)params = MG_Util::ConvertSamplerWrapModeToGLEnum(samplerObj->GetWrapR());
break;
case GL_TEXTURE_MIN_FILTER:
*(GLuint*)params =
MG_Util::ConvertSamplerFilterModeToGLEnum(samplerObj->GetMinFilter(), samplerObj->GetMipmapMode());
break;
case GL_TEXTURE_MAG_FILTER:
*(GLuint*)params =
MG_Util::ConvertSamplerFilterModeToGLEnum(samplerObj->GetMagFilter(), SamplerMipmapMode::None);
break;
case GL_TEXTURE_MIN_LOD:
*(GLfloat*)params = samplerObj->GetMinLod();
break;
case GL_TEXTURE_MAX_LOD:
*(GLfloat*)params = samplerObj->GetMaxLod();
break;
case GL_TEXTURE_LOD_BIAS:
*(GLfloat*)params = samplerObj->GetLodBias();
break;
case GL_TEXTURE_COMPARE_MODE:
*(GLuint*)params = MG_Util::ConvertSamplerCompareModeToGLEnum(samplerObj->GetCompareMode());
break;
case GL_TEXTURE_COMPARE_FUNC:
*(GLuint*)params = MG_Util::ConvertSamplerCompareFuncToGLEnum(samplerObj->GetSamplerCompareFunc());
break;
default:
MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "GetSamplerParam_State",
"Invalid pname for sampler parameter"));
}
}
GLboolean IsSampler_State(GLuint sampler) {
return MG_State::pGLContext->ValidateSamplerObject(sampler) ? GL_TRUE : GL_FALSE;
}
// migrate below functions without "_State" into this section
void GenSamplers_State(GLsizei count, GLuint* samplers) {
if (count < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "GenSamplers", "count must be non-negative"));
return;
}
static thread_local Vector<GLuint> names;
MG_State::pGLContext->GenSamplerNames(count, names);
Memcpy(samplers, names.data(), count * sizeof(GLuint));
}
void DeleteSamplers_State(GLsizei count, const GLuint* samplers) {
if (count < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "DeleteSamplers", "count must be non-negative"));
return;
}
for (GLsizei i = 0; i < count; ++i) {
if (samplers[i] != 0) {
MG_State::pGLContext->MarkSamplerObjectForDeletion(samplers[i]);
}
}
}
void CreateSamplers_State(GLsizei n, GLuint* samplers) {
if (n < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "GenSamplers", "count must be non-negative"));
return;
}
static thread_local Vector<GLuint> names;
MG_State::pGLContext->GenSamplerNames(n, names);
Memcpy(samplers, names.data(), n * sizeof(GLuint));
for (GLsizei i = 0; i < n; ++i) {
samplers[i] = names[i];
MG_State::pGLContext->CreateSamplerObject(names[i]);
}
}
void BindSampler_State(GLuint unit, GLuint sampler) {
if (unit >= MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "BindSampler", "texture unit out of range"));
return;
}
auto& textureUnit = MG_State::pGLContext->GetTextureUnitObject((Int)unit);
if (sampler == 0) {
textureUnit.SetSamplerObject(nullptr);
} else {
if (!SamplerImpl::ValidateSamplerName(sampler)) return; if (!SamplerImpl::ValidateSamplerName(sampler)) return;
Bool doesSamplerObjectCreated = MG_State::pGLContext->ValidateSamplerObject(sampler);
auto samplerObj = MG_State::pGLContext->GetSamplerObject(sampler); if (!doesSamplerObjectCreated) {
if (!samplerObj) { MG_State::pGLContext->CreateSamplerObject(sampler);
samplerObj = MG_State::pGLContext->CreateSamplerObject(sampler); // for compatibility
} }
if (!SamplerImpl::ValidateSamplerObject(sampler)) return; auto& samplerObject = MG_State::pGLContext->GetSamplerObject(sampler);
using namespace MG_Util; textureUnit.SetSamplerObject(MG_State::pGLContext->GetSamplerObject(sampler));
switch (pname) { }
case GL_TEXTURE_WRAP_S: }
samplerObj->SetWrapS(MG_Util::ConvertGLEnumToSamplerWrapMode(*(const GLint*)param));
break; void BindSamplers_State(GLuint first, GLsizei count, const GLuint* samplers) {
case GL_TEXTURE_WRAP_T: if (count < 0) {
samplerObj->SetWrapT(MG_Util::ConvertGLEnumToSamplerWrapMode(*(const GLint*)param)); MG_State::pGLContext->RecordError(
break; ErrorCode::InvalidValue,
case GL_TEXTURE_WRAP_R: MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "BindSamplers", "count must be non-negative"));
samplerObj->SetWrapR(MG_Util::ConvertGLEnumToSamplerWrapMode(*(const GLint*)param)); return;
break;
case GL_TEXTURE_MIN_FILTER:
samplerObj->SetMinFilter(MG_Util::ConvertGLEnumToSamplerFilterMode(*(const GLint*)param));
samplerObj->SetMipmapMode(MG_Util::ConvertGLEnumToSamplerMipmapMode(*(const GLint*)param));
break;
case GL_TEXTURE_MAG_FILTER:
samplerObj->SetMagFilter(MG_Util::ConvertGLEnumToSamplerFilterMode(*(const GLint*)param));
break;
case GL_TEXTURE_MIN_LOD:
samplerObj->SetLodRange(*(const GLfloat*)param, samplerObj->GetMaxLod());
break;
case GL_TEXTURE_MAX_LOD:
samplerObj->SetLodRange(samplerObj->GetMinLod(), *(const GLfloat*)param);
break;
case GL_TEXTURE_LOD_BIAS:
samplerObj->SetLodBias(*(const GLfloat*)param);
break;
case GL_TEXTURE_COMPARE_MODE:
samplerObj->SetCompareMode(MG_Util::ConvertGLEnumToSamplerCompareMode(*(const GLint*)param));
break;
case GL_TEXTURE_COMPARE_FUNC:
samplerObj->SetSamplerCompareFunc(MG_Util::ConvertGLEnumToSamplerCompareFunc(*(const GLint*)param));
break;
default:
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "SetSamplerParam_State",
"Invalid pname for sampler parameter"));
}
} }
void GetSamplerParam_State(GLuint sampler, GLenum pname, void* params, bool isFloat, bool isInteger) { for (GLsizei i = 0; i < count; ++i) {
if (!SamplerImpl::ValidateSamplerName(sampler)) return; BindSampler_State(first + i, samplers ? samplers[i] : 0);
auto samplerObj = MG_State::pGLContext->GetSamplerObject(sampler);
if (!samplerObj) {
samplerObj = MG_State::pGLContext->CreateSamplerObject(sampler); // for compatibility
}
if (!SamplerImpl::ValidateSamplerObject(sampler)) return;
using namespace MG_Util;
switch (pname) {
case GL_TEXTURE_WRAP_S:
*(GLint*)params = MG_Util::ConvertSamplerWrapModeToGLEnum(samplerObj->GetWrapS());
break;
case GL_TEXTURE_WRAP_T:
*(GLint*)params = MG_Util::ConvertSamplerWrapModeToGLEnum(samplerObj->GetWrapT());
break;
case GL_TEXTURE_WRAP_R:
*(GLint*)params = MG_Util::ConvertSamplerWrapModeToGLEnum(samplerObj->GetWrapR());
break;
case GL_TEXTURE_MIN_FILTER:
*(GLint*)params =
MG_Util::ConvertSamplerFilterModeToGLEnum(samplerObj->GetMinFilter(), samplerObj->GetMipmapMode());
break;
case GL_TEXTURE_MAG_FILTER:
*(GLint*)params =
MG_Util::ConvertSamplerFilterModeToGLEnum(samplerObj->GetMagFilter(), SamplerMipmapMode::None);
break;
case GL_TEXTURE_MIN_LOD:
*(GLfloat*)params = samplerObj->GetMinLod();
break;
case GL_TEXTURE_MAX_LOD:
*(GLfloat*)params = samplerObj->GetMaxLod();
break;
case GL_TEXTURE_LOD_BIAS:
*(GLfloat*)params = samplerObj->GetLodBias();
break;
case GL_TEXTURE_COMPARE_MODE:
*(GLint*)params = MG_Util::ConvertSamplerCompareModeToGLEnum(samplerObj->GetCompareMode());
break;
case GL_TEXTURE_COMPARE_FUNC:
*(GLint*)params = MG_Util::ConvertSamplerCompareFuncToGLEnum(samplerObj->GetSamplerCompareFunc());
break;
default:
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GetSamplerParam_State",
"Invalid pname for sampler parameter"));
}
} }
}
GLboolean IsSampler_State(GLuint sampler) { /* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */
return MG_State::pGLContext->ValidateSamplerObject(sampler) ? GL_TRUE : GL_FALSE; void GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) {
} GetSamplerParam_State(sampler, pname, params, false, false);
}
// migrate below functions without "_State" into this section void SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint* param) {
void GenSamplers_State(GLsizei count, GLuint* samplers) { SetSamplerParam_State(sampler, pname, param, false, true);
if (count < 0) { }
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GenSamplers", "count must be non-negative"));
return;
}
auto names = MG_State::pGLContext->GenSamplerNames(count); void SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint* param) {
for (GLsizei i = 0; i < count; ++i) { SetSamplerParam_State(sampler, pname, param, false, true);
samplers[i] = names[i]; }
}
}
void DeleteSamplers_State(GLsizei count, const GLuint* samplers) { void SamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param) {
if (count < 0) { SetSamplerParam_State(sampler, pname, param, false, false);
MG_State::pGLContext->RecordError( }
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "DeleteSamplers", "count must be non-negative"));
return;
}
for (GLsizei i = 0; i < count; ++i) { void SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param) {
if (samplers[i] != 0) { SetSamplerParam_State(sampler, pname, param, true, false);
MG_State::pGLContext->MarkSamplerObjectForDeletion(samplers[i]); }
}
}
}
void CreateSamplers_State(GLsizei n, GLuint* samplers) { void SamplerParameteri(GLuint sampler, GLenum pname, GLint param) {
if (n < 0) { SamplerParameteriv(sampler, pname, &param);
MG_State::pGLContext->RecordError( }
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GenSamplers", "count must be non-negative"));
return;
}
auto names = MG_State::pGLContext->GenSamplerNames(n); void SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) {
for (GLsizei i = 0; i < n; ++i) { SamplerParameterfv(sampler, pname, &param);
samplers[i] = names[i]; }
MG_State::pGLContext->CreateSamplerObject(names[i]);
}
}
void BindSampler_State(GLuint unit, GLuint sampler) { GLboolean IsSampler(GLuint sampler) {
if (unit >= MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS) { return IsSampler_State(sampler);
MG_State::pGLContext->RecordError( }
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "BindSampler", "texture unit out of range"));
return;
}
auto& textureUnit = MG_State::pGLContext->GetTextureUnitObject(unit); void GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint* params) {
if (sampler == 0) { GetSamplerParam_State(sampler, pname, params, false, true);
textureUnit.SetSamplerObject(nullptr); }
} else {
if (!SamplerImpl::ValidateSamplerName(sampler)) return;
auto samplerObject = MG_State::pGLContext->GetSamplerObject(sampler);
if (!samplerObject) {
samplerObject = MG_State::pGLContext->CreateSamplerObject(sampler);
}
textureUnit.SetSamplerObject(MG_State::pGLContext->GetSamplerObject(sampler)); void GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint* params) {
} GetSamplerParam_State(sampler, pname, params, false, true);
} }
void BindSamplers_State(GLuint first, GLsizei count, const GLuint* samplers) { void GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) {
if (count < 0) { GetSamplerParam_State(sampler, pname, params, true, false);
MG_State::pGLContext->RecordError( }
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "BindSamplers", "count must be non-negative"));
return;
}
for (GLsizei i = 0; i < count; ++i) { void GenSamplers(GLsizei count, GLuint* samplers) {
BindSampler_State(first + i, samplers ? samplers[i] : 0); GenSamplers_State(count, samplers);
} }
}
/* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */ void DeleteSamplers(GLsizei count, const GLuint* samplers) {
void GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) { DeleteSamplers_State(count, samplers);
GetSamplerParam_State(sampler, pname, params, false, false); }
}
void SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint* param) { void CreateSamplers(GLsizei n, GLuint* samplers) {
SetSamplerParam_State(sampler, pname, param, false, true); CreateSamplers_State(n, samplers);
} }
void SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint* param) { void BindSamplers(GLuint first, GLsizei count, const GLuint* samplers) {
SetSamplerParam_State(sampler, pname, param, false, true); BindSamplers_State(first, count, samplers);
} }
void SamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param) { void BindSampler(GLuint unit, GLuint sampler) {
SetSamplerParam_State(sampler, pname, param, false, false); BindSampler_State(unit, sampler);
} }
} // namespace MobileGL::MG_Impl::GLImpl
void SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param) {
SetSamplerParam_State(sampler, pname, param, true, false);
}
void SamplerParameteri(GLuint sampler, GLenum pname, GLint param) {
SamplerParameteriv(sampler, pname, &param);
}
void SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) {
SamplerParameterfv(sampler, pname, &param);
}
GLboolean IsSampler(GLuint sampler) {
return IsSampler_State(sampler);
}
void GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint* params) {
GetSamplerParam_State(sampler, pname, params, false, true);
}
void GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint* params) {
GetSamplerParam_State(sampler, pname, params, false, true);
}
void GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) {
GetSamplerParam_State(sampler, pname, params, true, false);
}
void GenSamplers(GLsizei count, GLuint* samplers) {
GenSamplers_State(count, samplers);
}
void DeleteSamplers(GLsizei count, const GLuint* samplers) {
DeleteSamplers_State(count, samplers);
}
void CreateSamplers(GLsizei n, GLuint* samplers) {
CreateSamplers_State(n, samplers);
}
void BindSamplers(GLuint first, GLsizei count, const GLuint* samplers) {
BindSamplers_State(first, count, samplers);
}
void BindSampler(GLuint unit, GLuint sampler) {
BindSampler_State(unit, sampler);
}
} // namespace MG_Impl::GLImpl
} // namespace MobileGL
+19 -21
View File
@@ -9,24 +9,22 @@
#pragma once #pragma once
#include <Includes.h> #include <Includes.h>
namespace MobileGL { namespace MobileGL::MG_Impl::GLImpl {
namespace MG_Impl::GLImpl { /* @INSERTION_POINT:FUNCTION_DECLARATION@ */
/* @INSERTION_POINT:FUNCTION_DECLARATION@ */ void GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params);
void GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params); void SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint* param);
void SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint* param); void SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint* param);
void SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint* param); void SamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param);
void SamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param); void SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param);
void SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param); void SamplerParameteri(GLuint sampler, GLenum pname, GLint param);
void SamplerParameteri(GLuint sampler, GLenum pname, GLint param); void SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param);
void SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param); GLboolean IsSampler(GLuint sampler);
GLboolean IsSampler(GLuint sampler); void GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint* params);
void GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint* params); void GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint* params);
void GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint* params); void GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params);
void GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params); void GenSamplers(GLsizei count, GLuint* samplers);
void GenSamplers(GLsizei count, GLuint* samplers); void DeleteSamplers(GLsizei count, const GLuint* samplers);
void DeleteSamplers(GLsizei count, const GLuint* samplers); void CreateSamplers(GLsizei n, GLuint* samplers);
void CreateSamplers(GLsizei n, GLuint* samplers); void BindSamplers(GLuint first, GLsizei count, const GLuint* samplers);
void BindSamplers(GLuint first, GLsizei count, const GLuint* samplers); void BindSampler(GLuint unit, GLuint sampler);
void BindSampler(GLuint unit, GLuint sampler); } // namespace MobileGL::MG_Impl::GLImpl
} // namespace MG_Impl::GLImpl
} // namespace MobileGL
+113 -117
View File
@@ -11,126 +11,122 @@
#include <MG_State/GLState/ErrorState/Error.h> #include <MG_State/GLState/ErrorState/Error.h>
#include <MG_Util/Converters/GLToMG/TextureEnumConverter.h> #include <MG_Util/Converters/GLToMG/TextureEnumConverter.h>
namespace MobileGL::MG_Impl::GLImpl { namespace MobileGL::MG_Impl::GLImpl::SamplerImpl {
namespace SamplerImpl { Bool ValidateSamplerName(GLuint sampler) {
Bool ValidateSamplerName(GLuint sampler) { if (!MG_State::pGLContext->ValidateSamplerName(sampler)) {
if (!MG_State::pGLContext->ValidateSamplerName(sampler)) { MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerName",
std::format("Invalid sampler name {}", sampler)));
return false;
}
return true;
}
Bool ValidateSamplerObject(GLuint sampler) {
if (!MG_State::pGLContext->ValidateSamplerObject(sampler)) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerObject",
std::format("Sampler object {} does not exist", sampler)));
return false;
}
return true;
}
Bool ValidateSamplerParam(GLenum pname, GLenum param) {
using namespace MG_Util;
switch (pname) {
case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T:
case GL_TEXTURE_WRAP_R:
if (MG_Util::ConvertGLEnumToSamplerWrapMode(param) == SamplerWrapMode::Unknown) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerParam",
"Invalid wrap mode parameter"));
return false;
}
break;
case GL_TEXTURE_MIN_FILTER:
if (MG_Util::ConvertGLEnumToSamplerFilterMode(param) == SamplerFilterMode::Unknown) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerParam",
"Invalid min filter parameter"));
return false;
}
break;
case GL_TEXTURE_MAG_FILTER:
if (param != GL_NEAREST && param != GL_LINEAR) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerParam",
"Invalid mag filter parameter"));
return false;
}
break;
case GL_TEXTURE_COMPARE_MODE:
if (param != GL_NONE && param != GL_COMPARE_REF_TO_TEXTURE) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerParam",
"Invalid compare mode parameter"));
return false;
}
break;
case GL_TEXTURE_COMPARE_FUNC:
if (param < GL_LEQUAL || param > GL_ALWAYS) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerParam",
"Invalid compare function parameter"));
return false;
}
break;
default:
MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerParam",
"Invalid pname for sampler parameter"));
return false;
}
return true;
}
Bool ValidateSamplerFloatParam(GLenum pname, GLfloat param) {
switch (pname) {
case GL_TEXTURE_MIN_LOD:
case GL_TEXTURE_MAX_LOD:
case GL_TEXTURE_LOD_BIAS:
return true;
case GL_TEXTURE_BORDER_COLOR:
if (param < 0.0f || param > 1.0f) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerFloatParam",
"Border color component out of [0,1] range"));
return false;
}
return true;
default:
return ValidateSamplerParam(pname, static_cast<GLenum>(param));
}
}
Bool ValidateSamplerIntParam(GLenum pname, GLint param) {
switch (pname) {
case GL_TEXTURE_BORDER_COLOR:
if (param < 0 || param > 255) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerName", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerIntParam",
std::format("Invalid sampler name {}", sampler))); "Border color component out of [0,255] range"));
return false; return false;
} }
return true; return true;
default:
return ValidateSamplerParam(pname, static_cast<GLenum>(param));
} }
}
Bool ValidateSamplerObject(GLuint sampler) { } // namespace MobileGL::MG_Impl::GLImpl::SamplerImpl
if (!MG_State::pGLContext->ValidateSamplerObject(sampler)) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerObject",
std::format("Sampler object {} does not exist", sampler)));
return false;
}
return true;
}
Bool ValidateSamplerParam(GLenum pname, GLenum param) {
using namespace MG_Util;
switch (pname) {
case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T:
case GL_TEXTURE_WRAP_R:
if (MG_Util::ConvertGLEnumToSamplerWrapMode(param) == SamplerWrapMode::Unknown) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerParam",
"Invalid wrap mode parameter"));
return false;
}
break;
case GL_TEXTURE_MIN_FILTER:
if (MG_Util::ConvertGLEnumToSamplerFilterMode(param) == SamplerFilterMode::Unknown) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerParam",
"Invalid min filter parameter"));
return false;
}
break;
case GL_TEXTURE_MAG_FILTER:
if (param != GL_NEAREST && param != GL_LINEAR) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerParam",
"Invalid mag filter parameter"));
return false;
}
break;
case GL_TEXTURE_COMPARE_MODE:
if (param != GL_NONE && param != GL_COMPARE_REF_TO_TEXTURE) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerParam",
"Invalid compare mode parameter"));
return false;
}
break;
case GL_TEXTURE_COMPARE_FUNC:
if (param < GL_LEQUAL || param > GL_ALWAYS) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerParam",
"Invalid compare function parameter"));
return false;
}
break;
default:
MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerParam",
"Invalid pname for sampler parameter"));
return false;
}
return true;
}
Bool ValidateSamplerFloatParam(GLenum pname, GLfloat param) {
switch (pname) {
case GL_TEXTURE_MIN_LOD:
case GL_TEXTURE_MAX_LOD:
case GL_TEXTURE_LOD_BIAS:
return true;
case GL_TEXTURE_BORDER_COLOR:
if (param < 0.0f || param > 1.0f) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerFloatParam",
"Border color component out of [0,1] range"));
return false;
}
return true;
default:
return ValidateSamplerParam(pname, static_cast<GLenum>(param));
}
}
Bool ValidateSamplerIntParam(GLenum pname, GLint param) {
switch (pname) {
case GL_TEXTURE_BORDER_COLOR:
if (param < 0 || param > 255) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateSamplerIntParam",
"Border color component out of [0,255] range"));
return false;
}
return true;
default:
return ValidateSamplerParam(pname, static_cast<GLenum>(param));
}
}
} // namespace SamplerImpl
} // namespace MobileGL::MG_Impl::GLImpl
+7 -9
View File
@@ -10,12 +10,10 @@
#include <Includes.h> #include <Includes.h>
#include <MG_State/GLState/SamplerState/SamplerObject.h> #include <MG_State/GLState/SamplerState/SamplerObject.h>
namespace MobileGL::MG_Impl::GLImpl { namespace MobileGL::MG_Impl::GLImpl::SamplerImpl {
namespace SamplerImpl { Bool ValidateSamplerName(GLuint sampler);
Bool ValidateSamplerName(GLuint sampler); Bool ValidateSamplerObject(GLuint sampler);
Bool ValidateSamplerObject(GLuint sampler); Bool ValidateSamplerParam(GLenum pname, GLenum param);
Bool ValidateSamplerParam(GLenum pname, GLenum param); Bool ValidateSamplerFloatParam(GLenum pname, GLfloat param);
Bool ValidateSamplerFloatParam(GLenum pname, GLfloat param); Bool ValidateSamplerIntParam(GLenum pname, GLint param);
Bool ValidateSamplerIntParam(GLenum pname, GLint param); } // namespace MobileGL::MG_Impl::GLImpl::SamplerImpl
} // namespace SamplerImpl
} // namespace MobileGL::MG_Impl::GLImpl
+23 -25
View File
@@ -10,36 +10,34 @@
#include "MG_State/GLState/Core.h" #include "MG_State/GLState/Core.h"
namespace MobileGL { namespace MobileGL::MG_Impl::GLImpl {
namespace MG_Impl::GLImpl { GLsync FenceSync_Backend(GLenum condition, GLbitfield flags) {
GLsync FenceSync_Backend(GLenum condition, GLbitfield flags) { return 0;
return 0; }
}
GLenum ClientWaitSync_Backend(GLsync sync, GLbitfield flags, GLuint64 timeout) { GLenum ClientWaitSync_Backend(GLsync sync, GLbitfield flags, GLuint64 timeout) {
return 0; return 0;
} }
void DeleteSync_Backend(GLsync sync) {} void DeleteSync_Backend(GLsync sync) {}
GLsync FenceSync_State(GLenum condition, GLbitfield flags) { GLsync FenceSync_State(GLenum condition, GLbitfield flags) {
return 0; return 0;
} }
GLenum ClientWaitSync_State(GLsync sync, GLbitfield flags, GLuint64 timeout) { GLenum ClientWaitSync_State(GLsync sync, GLbitfield flags, GLuint64 timeout) {
return 0; return 0;
} }
void DeleteSync_State(GLsync sync) {} void DeleteSync_State(GLsync sync) {}
GLsync FenceSync(GLenum condition, GLbitfield flags) { GLsync FenceSync(GLenum condition, GLbitfield flags) {
return 0; return 0;
} }
GLenum ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) { GLenum ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
return 0; return 0;
} }
void DeleteSync(GLsync sync) {} void DeleteSync(GLsync sync) {}
} // namespace MG_Impl::GLImpl } // namespace MobileGL::MG_Impl::GLImpl
} // namespace MobileGL
+5 -7
View File
@@ -9,10 +9,8 @@
#pragma once #pragma once
#include <Includes.h> #include <Includes.h>
namespace MobileGL { namespace MobileGL::MG_Impl::GLImpl {
namespace MG_Impl::GLImpl { GLsync FenceSync(GLenum condition, GLbitfield flags);
GLsync FenceSync(GLenum condition, GLbitfield flags); GLenum ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
GLenum ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout); void DeleteSync(GLsync sync);
void DeleteSync(GLsync sync); } // namespace MobileGL::MG_Impl::GLImpl
} // namespace MG_Impl::GLImpl
} // namespace MobileGL
File diff suppressed because it is too large Load Diff
@@ -7,48 +7,47 @@
// End of Source File Header // End of Source File Header
#include "ProxyTexture.h" #include "ProxyTexture.h"
#include "MG_State/GLState/TextureState/TextureObject2D.h" #include <MG_State/GLState/TextureState/TextureObject2D.h>
#include "MG_Util/Types.h"
namespace MobileGL::MG_Impl::GLImpl { namespace MobileGL::MG_Impl::GLImpl::TextureImpl {
namespace TextureImpl { UniquePtr<ProxyTextureManager> pProxyTextureManager;
ProxyTextureManager* pProxyTextureManager;
Bool IsProxyTextureTarget(TextureUploadTarget target) { Bool IsProxyTextureTarget(TextureUploadTarget target) {
switch (target) { switch (target) {
case TextureUploadTarget::ProxyCubeMap: case TextureUploadTarget::ProxyCubeMap:
case TextureUploadTarget::ProxyTexture1DArray: case TextureUploadTarget::ProxyTexture1DArray:
case TextureUploadTarget::ProxyTexture2DArray: case TextureUploadTarget::ProxyTexture2DArray:
case TextureUploadTarget::ProxyTexture1D: case TextureUploadTarget::ProxyTexture1D:
case TextureUploadTarget::ProxyTexture2D: case TextureUploadTarget::ProxyTexture2D:
case TextureUploadTarget::ProxyTexture3D: case TextureUploadTarget::ProxyTexture3D:
case TextureUploadTarget::ProxyTexture2DMultisample: case TextureUploadTarget::ProxyTexture2DMultisample:
case TextureUploadTarget::ProxyTexture2DMultisampleArray: case TextureUploadTarget::ProxyTexture2DMultisampleArray:
case TextureUploadTarget::ProxyTextureRectangle: case TextureUploadTarget::ProxyTextureRectangle:
case TextureUploadTarget::ProxyCubeMapArray: case TextureUploadTarget::ProxyCubeMapArray:
return true; return true;
default: default:
return false; return false;
}
} }
}
SharedPtr<MG_State::GLState::ITextureObject> ProxyTextureManager::CreateOrReplaceProxyTextureObject( const SharedPtr<MG_State::GLState::ITextureObject>& ProxyTextureManager::CreateOrReplaceProxyTextureObject(
TextureUploadTarget target) { TextureUploadTarget target) {
auto it = m_proxyTexturesMap.find(target); auto it = m_proxyTexturesMap.find(target);
if (it != m_proxyTexturesMap.end()) { if (it != m_proxyTexturesMap.end()) {
m_proxyTexturesMap.erase(it); m_proxyTexturesMap.erase(it);
}
m_proxyTexturesMap[target] = MakeShared<MG_State::GLState::TextureObject2D>(0);
return m_proxyTexturesMap[target];
} }
auto& obj = m_proxyTexturesMap[target];
obj = MakeShared<MG_State::GLState::TextureObject2D>(0);
return obj;
}
SharedPtr<MG_State::GLState::ITextureObject> ProxyTextureManager::GetProxyTextureObject( const SharedPtr<MG_State::GLState::ITextureObject>& ProxyTextureManager::GetProxyTextureObject(
TextureUploadTarget target) { TextureUploadTarget target) {
auto it = m_proxyTexturesMap.find(target); auto it = m_proxyTexturesMap.find(target);
if (it != m_proxyTexturesMap.end()) { if (it != m_proxyTexturesMap.end()) {
return it->second; return it->second;
}
return nullptr;
} }
} // namespace TextureImpl static SharedPtr<MG_State::GLState::ITextureObject> nullTextureObject = nullptr;
} // namespace MobileGL::MG_Impl::GLImpl return nullTextureObject;
}
} // namespace MobileGL::MG_Impl::GLImpl::TextureImpl
+12 -13
View File
@@ -10,19 +10,18 @@
#include <Includes.h> #include <Includes.h>
#include <MG_State/GLState/Core.h> #include <MG_State/GLState/Core.h>
namespace MobileGL::MG_Impl::GLImpl { namespace MobileGL::MG_Impl::GLImpl::TextureImpl {
namespace TextureImpl { Bool IsProxyTextureTarget(TextureUploadTarget target);
Bool IsProxyTextureTarget(TextureUploadTarget target);
class ProxyTextureManager { class ProxyTextureManager {
public: public:
SharedPtr<MG_State::GLState::ITextureObject> CreateOrReplaceProxyTextureObject(TextureUploadTarget target); const SharedPtr<MG_State::GLState::ITextureObject>& CreateOrReplaceProxyTextureObject(
SharedPtr<MG_State::GLState::ITextureObject> GetProxyTextureObject(TextureUploadTarget target); TextureUploadTarget target);
const SharedPtr<MG_State::GLState::ITextureObject>& GetProxyTextureObject(TextureUploadTarget target);
private: private:
UnorderedMap<TextureUploadTarget, SharedPtr<MG_State::GLState::ITextureObject>> m_proxyTexturesMap; UnorderedMap<TextureUploadTarget, SharedPtr<MG_State::GLState::ITextureObject>> m_proxyTexturesMap;
}; };
extern ProxyTextureManager* pProxyTextureManager; extern UniquePtr<ProxyTextureManager> pProxyTextureManager;
} // namespace TextureImpl } // namespace MobileGL::MG_Impl::GLImpl::TextureImpl
} // namespace MobileGL::MG_Impl::GLImpl
+240 -254
View File
@@ -15,309 +15,295 @@
#include <MG_Util/Converters/MGToMG/TextureEnumConverter.h> #include <MG_Util/Converters/MGToMG/TextureEnumConverter.h>
#include <MG_Util/Converters/MGToStr/TextureEnumConverter.h> #include <MG_Util/Converters/MGToStr/TextureEnumConverter.h>
namespace MobileGL::MG_Impl::GLImpl { namespace MobileGL::MG_Impl::GLImpl::TextureImpl {
namespace TextureImpl { Bool ValidateTextureTarget(TextureTarget target) {
Bool ValidateTextureTarget(TextureTarget target) { if (target == TextureTarget::Unknown) {
if (target == TextureTarget::Unknown) { MG_State::pGLContext->RecordError(
MG_State::pGLContext->RecordError( ErrorCode::InvalidEnum,
ErrorCode::InvalidEnum, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureTarget", "Invalid texture target"));
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureTarget", "Invalid texture target")); return false;
return false; }
} return true;
return true; }
Bool ValidateTextureUploadTarget(TextureUploadTarget textureUploadTarget) {
if (textureUploadTarget == TextureUploadTarget::Unknown) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureUploadTarget",
"Invalid texture upload target"));
return false;
}
return true;
}
Bool ValidateTextureName(Uint texture, Bool allowZero) {
if (texture == 0) {
if (allowZero) return true;
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureName", "Texture name cannot be zero"));
return false;
} }
Bool ValidateTextureUploadTarget(TextureUploadTarget textureUploadTarget) { if (!MG_State::pGLContext->ValidateTextureName(texture)) {
if (textureUploadTarget == TextureUploadTarget::Unknown) { MG_State::pGLContext->RecordError(
MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum, ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureName", "Invalid texture name"));
"ValidateTextureUploadTarget", return false;
"Invalid texture upload target")); }
return false; return true;
} }
return true;
Bool ValidateTextureInputFormat(TextureInputFormat format) {
if (format == TextureInputFormat::Unknown) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureInputFormat",
"Invalid texture input format"));
return false;
}
return true;
}
Bool ValidateTexturePixelDataType(TexturePixelDataType texturePixelDataType) {
if (texturePixelDataType == TexturePixelDataType::Unknown) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTexturePixelDataType",
"Invalid texture pixel data type"));
return false;
}
return true;
}
Bool ValidateTextureLevelNumber(GLint level) {
if (level < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureLevelNumber",
"Texture level must be non-negative"));
return false;
} }
Bool ValidateTextureName(Uint texture, Bool allowZero) { // TODO: GL_INVALID_VALUE may be generated if level is greater than log2(max), where max is the returned
if (texture == 0) { // value of GL_MAX_TEXTURE_SIZE.
if (allowZero) return true;
MG_State::pGLContext->RecordError(ErrorCode::InvalidValue, return true;
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureName", }
"Texture name cannot be zero"));
return false;
}
if (!MG_State::pGLContext->ValidateTextureName(texture)) { Bool ValidateTextureSizeWithTextureUploadTarget(TextureUploadTarget target, GLsizei width, GLsizei height) {
if (target == TextureUploadTarget::CubeMapPositiveX || target == TextureUploadTarget::CubeMapNegativeX ||
target == TextureUploadTarget::CubeMapPositiveY || target == TextureUploadTarget::CubeMapNegativeY ||
target == TextureUploadTarget::CubeMapPositiveZ || target == TextureUploadTarget::CubeMapNegativeZ) {
if (width != height) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureName", "Invalid texture name")); MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureSizeWithTarget",
"Width and height must be equal for cube map textures"));
return false; return false;
} }
return true;
} }
Bool ValidateTextureInputFormat(TextureInputFormat format) { if (!(target == TextureUploadTarget::Texture1DArray || target == TextureUploadTarget::ProxyTexture1DArray)) {
if (format == TextureInputFormat::Unknown) { if (height < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureInputFormat",
"Invalid texture input format"));
return false;
}
return true;
}
Bool ValidateTexturePixelDataType(TexturePixelDataType texturePixelDataType) {
if (texturePixelDataType == TexturePixelDataType::Unknown) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl",
"ValidateTexturePixelDataType",
"Invalid texture pixel data type"));
return false;
}
return true;
}
Bool ValidateTextureLevelNumber(GLint level) {
if (level < 0) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl",
"ValidateTextureLevelNumber",
"Texture level must be non-negative"));
return false;
}
// TODO: GL_INVALID_VALUE may be generated if level is greater than log2(max), where max is the returned
// value of GL_MAX_TEXTURE_SIZE.
return true;
}
Bool ValidateTextureSizeWithTextureUploadTarget(TextureUploadTarget target, GLsizei width, GLsizei height) {
if (target == TextureUploadTarget::CubeMapPositiveX || target == TextureUploadTarget::CubeMapNegativeX ||
target == TextureUploadTarget::CubeMapPositiveY || target == TextureUploadTarget::CubeMapNegativeY ||
target == TextureUploadTarget::CubeMapPositiveZ || target == TextureUploadTarget::CubeMapNegativeZ) {
if (width != height) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureSizeWithTarget",
"Width and height must be equal for cube map textures"));
return false;
}
}
if (!(target == TextureUploadTarget::Texture1DArray ||
target == TextureUploadTarget::ProxyTexture1DArray)) {
if (height < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureSizeWithTarget",
"Height must be greater than or equal to zero"));
return false;
}
// TODO: GL_INVALID_VALUE is generated if target is not GL_TEXTURE_1D_ARRAY or GL_PROXY_TEXTURE_1D_ARRAY
// and height is greater than GL_MAX_TEXTURE_SIZE.
}
if (target == TextureUploadTarget::Texture1DArray || target == TextureUploadTarget::ProxyTexture1DArray) {
if (height < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureSizeWithTarget",
"Height must be greater than or equal to zero"));
return false;
}
// TODO: GL_INVALID_VALUE is generated if target is GL_TEXTURE_1D_ARRAY or GL_PROXY_TEXTURE_1D_ARRAY and
// height is greater than GL_MAX_ARRAY_TEXTURE_LAYERS.
}
return true;
}
Bool ValidateTextureSizeRange(SizeT width, SizeT height, SizeT depth) {
if (width < 0 || height < 0 || depth < 0) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureSizeRange", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureSizeWithTarget",
"Width and height must be greater than zero")); "Height must be greater than or equal to zero"));
return false; return false;
} }
// TODO: GL_INVALID_VALUE is generated if target is not GL_TEXTURE_1D_ARRAY or GL_PROXY_TEXTURE_1D_ARRAY
// TODO: GL_INVALID_VALUE is generated if width is greater than GL_MAX_TEXTURE_SIZE. // and height is greater than GL_MAX_TEXTURE_SIZE.
return true;
} }
Bool ValidateTextureInternalFormat(TextureInternalFormat format) { if (target == TextureUploadTarget::Texture1DArray || target == TextureUploadTarget::ProxyTexture1DArray) {
if (format == TextureInternalFormat::Unknown) { if (height < 0) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureInternalFormat", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureSizeWithTarget",
"Invalid texture sized internal format")); "Height must be greater than or equal to zero"));
return false; return false;
} }
return true; // TODO: GL_INVALID_VALUE is generated if target is GL_TEXTURE_1D_ARRAY or GL_PROXY_TEXTURE_1D_ARRAY and
// height is greater than GL_MAX_ARRAY_TEXTURE_LAYERS.
} }
Bool ValidateTextureBorderNumber(Int border) { return true;
if (border != 0) { }
MG_State::pGLContext->RecordError(ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", Bool ValidateTextureSizeRange(SizeT width, SizeT height, SizeT depth) {
"ValidateTextureBorderNumber", if (width < 0 || height < 0 || depth < 0) {
"Border must be zero")); MG_State::pGLContext->RecordError(
return false; ErrorCode::InvalidValue, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureSizeRange",
} "Width and height must be greater than zero"));
return true; return false;
} }
Bool ValidateTextureInternalFormatCompatibleWithInput(TextureInputFormat format, // TODO: GL_INVALID_VALUE is generated if width is greater than GL_MAX_TEXTURE_SIZE.
TextureInternalFormat internalFormat,
TexturePixelDataType type) {
if (type == TexturePixelDataType::UnsignedByte332 || type == TexturePixelDataType::UnsignedByte233Rev ||
type == TexturePixelDataType::UnsignedShort565 || type == TexturePixelDataType::UnsignedShort565Rev ||
type == TexturePixelDataType::UnsignedInt101111Rev) {
if (format != TextureInputFormat::RGB) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl",
"ValidateTextureInternalFormatCompatibleWithInput",
"Invalid format for the given type"));
return false;
}
}
if (type == TexturePixelDataType::UnsignedShort4444 || type == TexturePixelDataType::UnsignedShort4444Rev || return true;
type == TexturePixelDataType::UnsignedShort5551 || type == TexturePixelDataType::UnsignedShort1555Rev || }
type == TexturePixelDataType::UnsignedInt8888 || type == TexturePixelDataType::UnsignedInt8888Rev ||
type == TexturePixelDataType::UnsignedInt1010102 ||
type == TexturePixelDataType::UnsignedInt2101010Rev ||
type == TexturePixelDataType::UnsignedInt5999Rev) {
if (format != TextureInputFormat::RGBA && format != TextureInputFormat::BGRA) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl",
"ValidateTextureInternalFormatCompatibleWithInput",
"Invalid format for the given type"));
return false;
}
}
if (internalFormat == TextureInternalFormat::DepthComponent || Bool ValidateTextureInternalFormat(TextureInternalFormat format) {
internalFormat == TextureInternalFormat::DepthComponent16 || if (format == TextureInternalFormat::Unknown) {
internalFormat == TextureInternalFormat::DepthComponent24 || MG_State::pGLContext->RecordError(
internalFormat == TextureInternalFormat::DepthComponent32F) { ErrorCode::InvalidEnum, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureInternalFormat",
if (format != TextureInputFormat::DepthComponent) { "Invalid texture sized internal format"));
MG_State::pGLContext->RecordError( return false;
ErrorCode::InvalidOperation, }
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", return true;
"ValidateTextureInternalFormatCompatibleWithInput", }
"Invalid format for depth component internal format"));
return false;
}
}
if (format == TextureInputFormat::DepthComponent && Bool ValidateTextureBorderNumber(Int border) {
(internalFormat != TextureInternalFormat::DepthComponent && if (border != 0) {
internalFormat != TextureInternalFormat::DepthComponent16 && MG_State::pGLContext->RecordError(
internalFormat != TextureInternalFormat::DepthComponent24 && ErrorCode::InvalidValue,
internalFormat != TextureInternalFormat::DepthComponent32F && MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureBorderNumber", "Border must be zero"));
internalFormat != TextureInternalFormat::DepthComponent32 // workaround for Minecraft 1.21.5+ return false;
)) { }
return true;
}
Bool ValidateTextureInternalFormatCompatibleWithInput(TextureInputFormat format,
TextureInternalFormat internalFormat,
TexturePixelDataType type) {
if (type == TexturePixelDataType::UnsignedByte332 || type == TexturePixelDataType::UnsignedByte233Rev ||
type == TexturePixelDataType::UnsignedShort565 || type == TexturePixelDataType::UnsignedShort565Rev ||
type == TexturePixelDataType::UnsignedInt101111Rev) {
if (format != TextureInputFormat::RGB) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureInternalFormatCompatibleWithInput", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureInternalFormatCompatibleWithInput",
"Invalid internal format for depth component format")); "Invalid format for the given type"));
return false; return false;
} }
return true;
} }
Bool ValidateTextureLevelWithUploadTarget(TextureUploadTarget target, Int level) { if (type == TexturePixelDataType::UnsignedShort4444 || type == TexturePixelDataType::UnsignedShort4444Rev ||
if (target == TextureUploadTarget::TextureRectangle || type == TexturePixelDataType::UnsignedShort5551 || type == TexturePixelDataType::UnsignedShort1555Rev ||
target == TextureUploadTarget::ProxyTextureRectangle) { type == TexturePixelDataType::UnsignedInt8888 || type == TexturePixelDataType::UnsignedInt8888Rev ||
if (level != 0) { type == TexturePixelDataType::UnsignedInt1010102 || type == TexturePixelDataType::UnsignedInt2101010Rev ||
MG_State::pGLContext->RecordError( type == TexturePixelDataType::UnsignedInt5999Rev) {
ErrorCode::InvalidValue, if (format != TextureInputFormat::RGBA && format != TextureInputFormat::BGRA) {
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureLevelWithUploadTarget",
"Level must be zero for rectangle textures"));
return false;
}
}
return true;
}
Bool ValidateTextureObject(SharedPtr<MG_State::GLState::ITextureObject> textureObject) {
if (!textureObject) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureObject", "Texture object is null")); MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureInternalFormatCompatibleWithInput",
"Invalid format for the given type"));
return false; return false;
} }
return true;
} }
Bool ValidateTextureTargetUniformity(SharedPtr<MG_State::GLState::ITextureObject> textureObject, if (internalFormat == TextureInternalFormat::DepthComponent ||
TextureTarget target) { internalFormat == TextureInternalFormat::DepthComponent16 ||
if (!textureObject) return true; // should be created later internalFormat == TextureInternalFormat::DepthComponent24 ||
TextureTarget prevTarget = textureObject->GetTarget(); internalFormat == TextureInternalFormat::DepthComponent32F) {
if (prevTarget != target) { if (format != TextureInputFormat::DepthComponent) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureTargetUniformity", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureInternalFormatCompatibleWithInput",
"Texture target does not match the previously created texture")); "Invalid format for depth component internal format"));
return false; return false;
} }
return true;
} }
Bool ValidateTextureSubImageOffsets(SharedPtr<MG_State::GLState::ITextureObject> textureObject, Int xoffset, if (format == TextureInputFormat::DepthComponent &&
Int width, Int yoffset, Int height, Int zoffset, Int depth) { (internalFormat != TextureInternalFormat::DepthComponent &&
auto baseSize = textureObject->GetBaseSize(); internalFormat != TextureInternalFormat::DepthComponent16 &&
if (xoffset < 0 || (xoffset + width) > baseSize.x()) { internalFormat != TextureInternalFormat::DepthComponent24 &&
MG_State::pGLContext->RecordError( internalFormat != TextureInternalFormat::DepthComponent32F &&
ErrorCode::InvalidValue, internalFormat != TextureInternalFormat::DepthComponent32 // workaround for Minecraft 1.21.5+
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureSubImageOffsets", )) {
"xoffset must be non-negative and (xoffset + width) must not exceed " MG_State::pGLContext->RecordError(
"the texture width.")); ErrorCode::InvalidOperation,
return false; MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureInternalFormatCompatibleWithInput",
} "Invalid internal format for depth component format"));
if (baseSize.y() == 0) return true; return false;
if (yoffset < 0 || (yoffset + height) > baseSize.y()) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureSubImageOffsets",
"yoffset must be non-negative and (yoffset + height) must not exceed "
"the texture height."));
return false;
}
if (baseSize.z() == 0) return true;
if (zoffset < 0 || (zoffset + depth) > baseSize.z()) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureSubImageOffsets",
"zoffset must be non-negative and (zoffset + depth) must not exceed "
"the texture depth."));
return false;
}
return true;
} }
return true;
}
Bool ValidateBaseInternalFormatMatch(TextureInternalFormat format1, TextureInternalFormat format2) { Bool ValidateTextureLevelWithUploadTarget(TextureUploadTarget target, Int level) {
auto unsizedFormat1 = MG_Util::ConvertInternalFormatToUnsized(format1); if (target == TextureUploadTarget::TextureRectangle || target == TextureUploadTarget::ProxyTextureRectangle) {
auto unsizedFormat2 = MG_Util::ConvertInternalFormatToUnsized(format2); if (level != 0) {
if (unsizedFormat1 != unsizedFormat2) {
MG_State::pGLContext->RecordError( MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>( MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureLevelWithUploadTarget",
std::format("MG_Impl/GLImpl", "ValidateBaseInternalFormatMatch", "Level must be zero for rectangle textures"));
"The base internal format of the two formats do not match ({} vs. {})",
MG_Util::ConvertTextureInternalFormatToString(unsizedFormat1).c_str(),
MG_Util::ConvertTextureInternalFormatToString(unsizedFormat2).c_str())));
return false; return false;
} }
return true; }
} // namespace TextureImpl return true;
}
Bool ValidateTextureObject(SharedPtr<MG_State::GLState::ITextureObject> textureObject) {
if (!textureObject) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureObject", "Texture object is null"));
return false;
}
return true;
}
Bool ValidateTextureTargetUniformity(SharedPtr<MG_State::GLState::ITextureObject> textureObject,
TextureTarget target) {
if (!textureObject) return true; // should be created later
TextureTarget prevTarget = textureObject->GetTarget();
if (prevTarget != target) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureTargetUniformity",
"Texture target does not match the previously created texture"));
return false;
}
return true;
}
Bool ValidateTextureSubImageOffsets(SharedPtr<MG_State::GLState::ITextureObject> textureObject, Int xoffset,
Int width, Int yoffset, Int height, Int zoffset, Int depth) {
auto baseSize = textureObject->GetBaseSize();
if (xoffset < 0 || (xoffset + width) > baseSize.x()) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureSubImageOffsets",
"xoffset must be non-negative and (xoffset + width) must not exceed "
"the texture width."));
return false;
}
if (baseSize.y() == 0) return true;
if (yoffset < 0 || (yoffset + height) > baseSize.y()) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureSubImageOffsets",
"yoffset must be non-negative and (yoffset + height) must not exceed "
"the texture height."));
return false;
}
if (baseSize.z() == 0) return true;
if (zoffset < 0 || (zoffset + depth) > baseSize.z()) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateTextureSubImageOffsets",
"zoffset must be non-negative and (zoffset + depth) must not exceed "
"the texture depth."));
return false;
}
return true;
}
Bool ValidateBaseInternalFormatMatch(TextureInternalFormat format1, TextureInternalFormat format2) {
auto unsizedFormat1 = MG_Util::ConvertInternalFormatToUnsized(format1);
auto unsizedFormat2 = MG_Util::ConvertInternalFormatToUnsized(format2);
if (unsizedFormat1 != unsizedFormat2) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>(
std::format("MG_Impl/GLImpl", "ValidateBaseInternalFormatMatch",
"The base internal format of the two formats do not match ({} vs. {})",
MG_Util::ConvertTextureInternalFormatToString(unsizedFormat1).c_str(),
MG_Util::ConvertTextureInternalFormatToString(unsizedFormat2).c_str())));
return false;
}
return true;
} // namespace TextureImpl } // namespace TextureImpl
} // namespace MobileGL::MG_Impl::GLImpl } // namespace MobileGL::MG_Impl::GLImpl::TextureImpl
+22 -24
View File
@@ -12,27 +12,25 @@
#include <Includes.h> #include <Includes.h>
#include <MG_State/GLState/TextureState/TextureObject.h> #include <MG_State/GLState/TextureState/TextureObject.h>
namespace MobileGL::MG_Impl::GLImpl { namespace MobileGL::MG_Impl::GLImpl::TextureImpl {
namespace TextureImpl { Bool ValidateTextureTarget(TextureTarget target);
Bool ValidateTextureTarget(TextureTarget target); Bool ValidateTextureUploadTarget(TextureUploadTarget textureUploadTarget);
Bool ValidateTextureUploadTarget(TextureUploadTarget textureUploadTarget); Bool ValidateTextureName(Uint texture, Bool allowZero = false);
Bool ValidateTextureName(Uint texture, Bool allowZero = false); Bool ValidateTextureInputFormat(TextureInputFormat format);
Bool ValidateTextureInputFormat(TextureInputFormat format); Bool ValidateTexturePixelDataType(TexturePixelDataType texturePixelDataType);
Bool ValidateTexturePixelDataType(TexturePixelDataType texturePixelDataType); Bool ValidateTextureLevelNumber(Int level);
Bool ValidateTextureLevelNumber(Int level); Bool ValidateTextureSizeWithTextureUploadTarget(TextureUploadTarget target, GLsizei width, GLsizei height);
Bool ValidateTextureSizeWithTextureUploadTarget(TextureUploadTarget target, GLsizei width, GLsizei height); Bool ValidateTextureSizeRange(SizeT width, SizeT height, SizeT depth);
Bool ValidateTextureSizeRange(SizeT width, SizeT height, SizeT depth); Bool ValidateTextureInternalFormat(TextureInternalFormat format);
Bool ValidateTextureInternalFormat(TextureInternalFormat format); Bool ValidateTextureBorderNumber(Int border);
Bool ValidateTextureBorderNumber(Int border); Bool ValidateTextureInternalFormatCompatibleWithInput(TextureInputFormat format,
Bool ValidateTextureInternalFormatCompatibleWithInput(TextureInputFormat format, TextureInternalFormat internalFormat,
TextureInternalFormat internalFormat, TexturePixelDataType type);
TexturePixelDataType type); Bool ValidateTextureLevelWithUploadTarget(TextureUploadTarget target, Int level);
Bool ValidateTextureLevelWithUploadTarget(TextureUploadTarget target, Int level); Bool ValidateTextureObject(SharedPtr<MG_State::GLState::ITextureObject> textureObject);
Bool ValidateTextureObject(SharedPtr<MG_State::GLState::ITextureObject> textureObject); Bool ValidateTextureTargetUniformity(SharedPtr<MG_State::GLState::ITextureObject> textureObject,
Bool ValidateTextureTargetUniformity(SharedPtr<MG_State::GLState::ITextureObject> textureObject, TextureTarget target);
TextureTarget target); Bool ValidateTextureSubImageOffsets(SharedPtr<MG_State::GLState::ITextureObject> textureObject, Int xoffset,
Bool ValidateTextureSubImageOffsets(SharedPtr<MG_State::GLState::ITextureObject> textureObject, Int xoffset, Int width, Int yoffset = 0, Int height = 0, Int zoffset = 0, Int depth = 0);
Int width, Int yoffset = 0, Int height = 0, Int zoffset = 0, Int depth = 0); Bool ValidateBaseInternalFormatMatch(TextureInternalFormat format1, TextureInternalFormat format2);
Bool ValidateBaseInternalFormatMatch(TextureInternalFormat format1, TextureInternalFormat format2); } // namespace MobileGL::MG_Impl::GLImpl::TextureImpl
} // namespace TextureImpl
} // namespace MobileGL::MG_Impl::GLImpl
@@ -12,222 +12,216 @@
#include <MG_State/GLState/ErrorState/Error.h> #include <MG_State/GLState/ErrorState/Error.h>
#include <MG_Util/Converters/GLToMG/DataTypeConverter.h> #include <MG_Util/Converters/GLToMG/DataTypeConverter.h>
namespace MobileGL { namespace MobileGL::MG_Impl::GLImpl {
namespace MG_Impl::GLImpl { void DisableVertexAttribArray_State(GLuint index) {
void DisableVertexAttribArray_State(GLuint index) { if (!VertexArrayImpl::ValidateVertexAttributeIndex(index)) return;
if (!VertexArrayImpl::ValidateVertexAttributeIndex(index)) return;
auto vao = MG_State::pGLContext->GetBoundVertexArray(); auto& vao = MG_State::pGLContext->GetBoundVertexArray();
if (!vao) { if (!vao) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation, MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl",
"EnableVertexAttribArray_State", "EnableVertexAttribArray_State",
"No vertex array object is bound.")); "No vertex array object is bound."));
return; return;
}
vao->DisableAttribute(index);
} }
void EnableVertexAttribArray_State(GLuint index) { vao->DisableAttribute(index);
if (!VertexArrayImpl::ValidateVertexAttributeIndex(index)) return; }
auto vao = MG_State::pGLContext->GetBoundVertexArray(); void EnableVertexAttribArray_State(GLuint index) {
if (!vao) { if (!VertexArrayImpl::ValidateVertexAttributeIndex(index)) return;
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl",
"EnableVertexAttribArray_State",
"No vertex array object is bound."));
return;
}
vao->EnableAttribute(index); auto& vao = MG_State::pGLContext->GetBoundVertexArray();
if (!vao) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl",
"EnableVertexAttribArray_State",
"No vertex array object is bound."));
return;
} }
// TODO: implement GL_BGRA support vao->EnableAttribute(index);
void VertexAttribIPointer_State(GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer) { }
if (!VertexArrayImpl::ValidateVertexAttributeIndex(index)) return;
DataType dataType = MG_Util::ConvertGLEnumToDataType(type); // TODO: implement GL_BGRA support
if (!VertexArrayImpl::ValidateVertexAttribPointerParams(index, size, dataType, stride)) return; void VertexAttribIPointer_State(GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer) {
if (!VertexArrayImpl::ValidateVertexAttributeIndex(index)) return;
auto vao = MG_State::pGLContext->GetBoundVertexArray(); DataType dataType = MG_Util::ConvertGLEnumToDataType(type);
if (!vao) { if (!VertexArrayImpl::ValidateVertexAttribPointerParams(index, size, dataType, stride)) return;
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl",
"VertexAttribPointer_State",
"No vertex array object is bound."));
return;
}
auto& vboSlot = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Vertex); auto& vao = MG_State::pGLContext->GetBoundVertexArray();
auto vbo = vboSlot.GetBoundObject(); if (!vao) {
if (!vbo) { MG_State::pGLContext->RecordError(
MG_State::pGLContext->RecordError( ErrorCode::InvalidOperation, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "VertexAttribPointer_State",
ErrorCode::InvalidOperation, "No vertex array object is bound."));
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "VertexAttribPointer_State", return;
"No buffer is bound to GL_ARRAY_BUFFER."));
return;
}
SizeT offset = reinterpret_cast<SizeT>(pointer);
vao->SetAttributeFormat(index, size, dataType, false, stride, offset, true);
vao->BindAttributeBuffer(index, vbo);
} }
// TODO: implement GL_BGRA support auto& vboSlot = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Vertex);
void VertexAttribPointer_State(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, auto& vbo = vboSlot.GetBoundObject();
const void* pointer) { if (!vbo) {
if (!VertexArrayImpl::ValidateVertexAttributeIndex(index)) return; MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "VertexAttribPointer_State",
DataType dataType = MG_Util::ConvertGLEnumToDataType(type); "No buffer is bound to GL_ARRAY_BUFFER."));
if (!VertexArrayImpl::ValidateVertexAttribPointerParams(index, size, dataType, stride)) return; return;
auto vao = MG_State::pGLContext->GetBoundVertexArray();
if (!vao) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl",
"VertexAttribPointer_State",
"No vertex array object is bound."));
return;
}
auto& vboSlot = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Vertex);
auto vbo = vboSlot.GetBoundObject();
if (!vbo) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "VertexAttribPointer_State",
"No buffer is bound to GL_ARRAY_BUFFER."));
return;
}
SizeT offset = reinterpret_cast<SizeT>(pointer);
vao->SetAttributeFormat(index, size, dataType, normalized, stride, offset, false);
vao->BindAttributeBuffer(index, vbo);
} }
void BindVertexArray_State(GLuint array) { auto offset = reinterpret_cast<SizeT>(pointer);
if (array == 0) {
vao->SetAttributeFormat(index, size, dataType, false, stride, offset, true);
vao->BindAttributeBuffer(index, vbo);
}
// TODO: implement GL_BGRA support
void VertexAttribPointer_State(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride,
const void* pointer) {
if (!VertexArrayImpl::ValidateVertexAttributeIndex(index)) return;
DataType dataType = MG_Util::ConvertGLEnumToDataType(type);
if (!VertexArrayImpl::ValidateVertexAttribPointerParams(index, size, dataType, stride)) return;
auto& vao = MG_State::pGLContext->GetBoundVertexArray();
if (!vao) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "VertexAttribPointer_State",
"No vertex array object is bound."));
return;
}
auto& vboSlot = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Vertex);
auto& vbo = vboSlot.GetBoundObject();
if (!vbo) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "VertexAttribPointer_State",
"No buffer is bound to GL_ARRAY_BUFFER."));
return;
}
SizeT offset = reinterpret_cast<SizeT>(pointer);
vao->SetAttributeFormat(index, size, dataType, normalized, stride, offset, false);
vao->BindAttributeBuffer(index, vbo);
}
void BindVertexArray_State(GLuint array) {
if (array == 0) {
MG_State::pGLContext->BindVertexArray(0);
return;
}
if (!VertexArrayImpl::ValidateVertexArrayName(array)) return;
if (!MG_State::pGLContext->ValidateVertexArrayObject(array)) {
MG_State::pGLContext->CreateVertexArrayObject(array);
}
MG_State::pGLContext->BindVertexArray(array);
}
void DeleteVertexArrays_State(GLsizei n, const GLuint* arrays) {
if (n < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "DeleteVertexArrays_State", "n must be non-negative."));
return;
}
for (GLsizei i = 0; i < n; ++i) {
GLuint vao = arrays[i];
if (vao == 0) continue;
if (!VertexArrayImpl::ValidateVertexArrayName(vao)) continue;
if (MG_State::pGLContext->GetBoundVertexArray() &&
MG_State::pGLContext->GetBoundVertexArray() == MG_State::pGLContext->GetVertexArrayObject(vao)) {
MG_State::pGLContext->BindVertexArray(0); MG_State::pGLContext->BindVertexArray(0);
return;
} }
if (!VertexArrayImpl::ValidateVertexArrayName(array)) return; MG_State::pGLContext->MarkVertexArrayForDeletion(vao);
}
}
if (!MG_State::pGLContext->ValidateVertexArrayObject(array)) { void GenVertexArrays_State(GLsizei n, GLuint* arrays) {
MG_State::pGLContext->CreateVertexArrayObject(array); if (n < 0) {
} MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MG_State::pGLContext->BindVertexArray(array); MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "GenVertexArrays_State", "n must be non-negative."));
return;
} }
void DeleteVertexArrays_State(GLsizei n, const GLuint* arrays) { static thread_local Vector<Uint> vaos;
if (n < 0) { MG_State::pGLContext->GenVertexArrayNames(n, vaos);
MG_State::pGLContext->RecordError( Memcpy(arrays, vaos.data(), n * sizeof(GLuint));
ErrorCode::InvalidValue, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "DeleteVertexArrays_State", }
"n must be non-negative."));
return;
}
for (GLsizei i = 0; i < n; ++i) { GLboolean IsVertexArray_State(GLuint array) {
GLuint vao = arrays[i]; if (array == 0) {
if (vao == 0) continue; MG_State::pGLContext->RecordError(ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "IsVertexArray_State",
"Vertex array name 0 is not supported."));
return GL_FALSE;
}
if (!VertexArrayImpl::ValidateVertexArrayName(array)) return GL_FALSE;
if (!MG_State::pGLContext->ValidateVertexArrayObject(array)) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "IsVertexArray_State",
std::format("Vertex array object {} does not exist.", array)));
return GL_FALSE;
}
return GL_TRUE;
}
if (!VertexArrayImpl::ValidateVertexArrayName(vao)) continue; void VertexAttribDivisor_State(GLuint index, GLuint divisor) {
if (!VertexArrayImpl::ValidateVertexAttributeIndex(index)) return;
if (MG_State::pGLContext->GetBoundVertexArray() && auto& vao = MG_State::pGLContext->GetBoundVertexArray();
MG_State::pGLContext->GetBoundVertexArray() == MG_State::pGLContext->GetVertexArrayObject(vao)) { if (!vao) {
MG_State::pGLContext->BindVertexArray(0); MG_State::pGLContext->RecordError(
} ErrorCode::InvalidOperation, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "VertexAttribDivisor_State",
"No vertex array object is bound."));
MG_State::pGLContext->MarkVertexArrayForDeletion(vao); return;
}
} }
void GenVertexArrays_State(GLsizei n, GLuint* arrays) { vao->SetAttributeDivisor(index, divisor);
if (n < 0) { }
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GenVertexArrays_State", "n must be non-negative."));
return;
}
auto vaoNames = MG_State::pGLContext->GenVertexArrayNames(n); /* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */
Copy(vaoNames.data(), arrays, vaoNames.size()); void VertexAttribDivisor(GLuint index, GLuint divisor) {
} VertexAttribDivisor_State(index, divisor);
}
GLboolean IsVertexArray_State(GLuint array) { GLboolean IsVertexArray(GLuint array) {
if (array == 0) { return IsVertexArray_State(array);
MG_State::pGLContext->RecordError( }
ErrorCode::InvalidValue, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "IsVertexArray_State",
"Vertex array name 0 is not supported."));
return GL_FALSE;
}
if (!VertexArrayImpl::ValidateVertexArrayName(array)) return GL_FALSE;
if (!MG_State::pGLContext->ValidateVertexArrayObject(array)) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "IsVertexArray_State",
std::format("Vertex array object {} does not exist.", array)));
return GL_FALSE;
}
return GL_TRUE;
}
void VertexAttribDivisor_State(GLuint index, GLuint divisor) { void DisableVertexAttribArray(GLuint index) {
if (!VertexArrayImpl::ValidateVertexAttributeIndex(index)) return; DisableVertexAttribArray_State(index);
}
auto vao = MG_State::pGLContext->GetBoundVertexArray(); void EnableVertexAttribArray(GLuint index) {
if (!vao) { EnableVertexAttribArray_State(index);
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation, }
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl",
"VertexAttribDivisor_State",
"No vertex array object is bound."));
return;
}
vao->SetAttributeDivisor(index, divisor); void VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer) {
} VertexAttribIPointer_State(index, size, type, stride, pointer);
}
/* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */ void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride,
void VertexAttribDivisor(GLuint index, GLuint divisor) { const void* pointer) {
VertexAttribDivisor_State(index, divisor); VertexAttribPointer_State(index, size, type, normalized, stride, pointer);
} }
GLboolean IsVertexArray(GLuint array) { void BindVertexArray(GLuint array) {
return IsVertexArray_State(array); BindVertexArray_State(array);
} }
void DisableVertexAttribArray(GLuint index) { void DeleteVertexArrays(GLsizei n, const GLuint* arrays) {
DisableVertexAttribArray_State(index); DeleteVertexArrays_State(n, arrays);
} }
void EnableVertexAttribArray(GLuint index) { void GenVertexArrays(GLsizei n, GLuint* arrays) {
EnableVertexAttribArray_State(index); GenVertexArrays_State(n, arrays);
} }
} // namespace MobileGL::MG_Impl::GLImpl
void VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer) {
VertexAttribIPointer_State(index, size, type, stride, pointer);
}
void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride,
const void* pointer) {
VertexAttribPointer_State(index, size, type, normalized, stride, pointer);
}
void BindVertexArray(GLuint array) {
BindVertexArray_State(array);
}
void DeleteVertexArrays(GLsizei n, const GLuint* arrays) {
DeleteVertexArrays_State(n, arrays);
}
void GenVertexArrays(GLsizei n, GLuint* arrays) {
GenVertexArrays_State(n, arrays);
}
} // namespace MG_Impl::GLImpl
} // namespace MobileGL
@@ -9,18 +9,16 @@
#pragma once #pragma once
#include <Includes.h> #include <Includes.h>
namespace MobileGL { namespace MobileGL::MG_Impl::GLImpl {
namespace MG_Impl::GLImpl { /* @INSERTION_POINT:FUNCTION_DECLARATION@ */
/* @INSERTION_POINT:FUNCTION_DECLARATION@ */ void VertexAttribDivisor(GLuint index, GLuint divisor);
void VertexAttribDivisor(GLuint index, GLuint divisor); GLboolean IsVertexArray(GLuint array);
GLboolean IsVertexArray(GLuint array); void DisableVertexAttribArray(GLuint index);
void DisableVertexAttribArray(GLuint index); void EnableVertexAttribArray(GLuint index);
void EnableVertexAttribArray(GLuint index); void VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer);
void VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer); void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride,
void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer);
const void* pointer); void BindVertexArray(GLuint array);
void BindVertexArray(GLuint array); void DeleteVertexArrays(GLsizei n, const GLuint* arrays);
void DeleteVertexArrays(GLsizei n, const GLuint* arrays); void GenVertexArrays(GLsizei n, GLuint* arrays);
void GenVertexArrays(GLsizei n, GLuint* arrays); } // namespace MobileGL::MG_Impl::GLImpl
} // namespace MG_Impl::GLImpl
} // namespace MobileGL
@@ -12,74 +12,71 @@
#include <MG_Util/Converters/MGToGL/DataTypeConverter.h> #include <MG_Util/Converters/MGToGL/DataTypeConverter.h>
#include <MG_Util/Converters/MGToStr/DataTypeConverter.h> #include <MG_Util/Converters/MGToStr/DataTypeConverter.h>
namespace MobileGL::MG_Impl::GLImpl { namespace MobileGL::MG_Impl::GLImpl::VertexArrayImpl {
namespace VertexArrayImpl { Bool ValidateVertexArrayName(Uint index) {
Bool isValid = MG_State::pGLContext->ValidateVertexArrayName(index);
if (!isValid) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateVertexArrayName",
std::format("Vertex array name {} is not valid.", index)));
return false;
}
return true;
}
Bool ValidateVertexArrayName(Uint index) { Bool ValidateVertexArrayObject(Uint index) {
Bool isValid = MG_State::pGLContext->ValidateVertexArrayName(index); if (!MG_State::pGLContext->ValidateVertexArrayObject(index)) {
if (!isValid) { MG_State::pGLContext->RecordError(
MG_State::pGLContext->RecordError( ErrorCode::InvalidOperation,
ErrorCode::InvalidOperation, MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateVertexArrayObject",
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateVertexArrayName", std::format("Vertex array object {} does not exist.", index)));
std::format("Vertex array name {} is not valid.", index))); return false;
return false; }
} return true;
return true; }
Bool ValidateVertexAttributeIndex(Uint index) {
if (index >= MG_State::GLState::VertexArrayObject::MAX_VERTEX_ATTRIBS) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>(
"MG_Impl/GLImpl", "ValidateVertexAttributeIndex",
std::format("Attribute index {} exceeds maximum of {}.", index,
MG_State::GLState::VertexArrayObject::MAX_VERTEX_ATTRIBS - 1)));
return false;
}
return true;
}
Bool ValidateVertexAttribPointerParams(Uint index, SizeT size, DataType type, Int stride) {
if (size < 1 || size > 4) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>(
"MG_Impl/GLImpl", "ValidateVertexAttribPointerParams",
std::format("Invalid size {} for attribute {}. Must be 1-4.", size, index)));
return false;
} }
Bool ValidateVertexArrayObject(Uint index) { if (type == DataType::Unknown) {
if (!MG_State::pGLContext->ValidateVertexArrayObject(index)) { MG_State::pGLContext->RecordError(
MG_State::pGLContext->RecordError( ErrorCode::InvalidEnum,
ErrorCode::InvalidOperation, MakeUnique<GenericErrorInfo>(
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateVertexArrayObject", "MG_Impl/GLImpl", "ValidateVertexAttribPointerParams",
std::format("Vertex array object {} does not exist.", index))); std::format("Invalid type {} for attribute {}.", MG_Util::ConvertDataTypeToString(type), index)));
return false; return false;
}
return true;
} }
Bool ValidateVertexAttributeIndex(Uint index) { if (stride < 0) {
if (index >= MG_State::GLState::VertexArrayObject::MAX_VERTEX_ATTRIBS) { MG_State::pGLContext->RecordError(
MG_State::pGLContext->RecordError( ErrorCode::InvalidValue,
ErrorCode::InvalidValue, MakeUnique<GenericErrorInfo>(
MakeShared<GenericErrorInfo>( "MG_Impl/GLImpl", "ValidateVertexAttribPointerParams",
"MG_Impl/GLImpl", "ValidateVertexAttributeIndex", std::format("Negative stride {} is not allowed for attribute {}.", stride, index)));
std::format("Attribute index {} exceeds maximum of {}.", index, return false;
MG_State::GLState::VertexArrayObject::MAX_VERTEX_ATTRIBS - 1)));
return false;
}
return true;
} }
Bool ValidateVertexAttribPointerParams(Uint index, SizeT size, DataType type, Int stride) { return true;
if (size < 1 || size > 4) { }
MG_State::pGLContext->RecordError( } // namespace MobileGL::MG_Impl::GLImpl::VertexArrayImpl
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>(
"MG_Impl/GLImpl", "ValidateVertexAttribPointerParams",
std::format("Invalid size {} for attribute {}. Must be 1-4.", size, index)));
return false;
}
if (type == DataType::Unknown) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateVertexAttribPointerParams",
std::format("Invalid type {} for attribute {}.",
MG_Util::ConvertDataTypeToString(type).c_str(), index)));
return false;
}
if (stride < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>(
"MG_Impl/GLImpl", "ValidateVertexAttribPointerParams",
std::format("Negative stride {} is not allowed for attribute {}.", stride, index)));
return false;
}
return true;
}
} // namespace VertexArrayImpl
} // namespace MobileGL::MG_Impl::GLImpl
@@ -10,11 +10,9 @@
#include <Includes.h> #include <Includes.h>
#include <MG_State/GLState/VertexArrayState/VertexArrayObject.h> #include <MG_State/GLState/VertexArrayState/VertexArrayObject.h>
namespace MobileGL::MG_Impl::GLImpl { namespace MobileGL::MG_Impl::GLImpl::VertexArrayImpl {
namespace VertexArrayImpl { Bool ValidateVertexArrayName(Uint index);
Bool ValidateVertexArrayName(Uint index); Bool ValidateVertexArrayObject(Uint index);
Bool ValidateVertexArrayObject(Uint index); Bool ValidateVertexAttributeIndex(Uint index);
Bool ValidateVertexAttributeIndex(Uint index); Bool ValidateVertexAttribPointerParams(Uint index, SizeT size, DataType type, Int stride);
Bool ValidateVertexAttribPointerParams(Uint index, SizeT size, DataType type, Int stride); } // namespace MobileGL::MG_Impl::GLImpl::VertexArrayImpl
} // namespace VertexArrayImpl
} // namespace MobileGL::MG_Impl::GLImpl
+4 -6
View File
@@ -10,9 +10,7 @@
#include <Includes.h> #include <Includes.h>
#include "MG_Impl/GetProcAddress.h" #include "MG_Impl/GetProcAddress.h"
namespace MG_Impl { namespace MG_Impl::GLXImpl {
namespace GLXImpl { void* GetProcAddress(const char* name);
void* GetProcAddress(const char* name); void* GetProcAddressARB(const char* name);
void* GetProcAddressARB(const char* name); } // namespace MG_Impl::GLXImpl
} // namespace GLXImpl
} // namespace MG_Impl
File diff suppressed because it is too large Load Diff
+3 -5
View File
@@ -9,8 +9,6 @@
#pragma once #pragma once
#include <Includes.h> #include <Includes.h>
namespace MobileGL { namespace MobileGL::MG_Impl {
namespace MG_Impl { void* GetProcAddress(const char* name);
void* GetProcAddress(const char* name); } // namespace MobileGL::MG_Impl
} // namespace MG_Impl
} // namespace MobileGL
+3 -3
View File
@@ -18,10 +18,10 @@
namespace MobileGL::MG_Impl { namespace MobileGL::MG_Impl {
void Init() { void Init() {
MGLOG_D("Initializing MobileGL Implementation..."); MGLOG_D("Initializing MobileGL Implementation...");
GLImpl::TextureImpl::pProxyTextureManager = new GLImpl::TextureImpl::ProxyTextureManager(); GLImpl::TextureImpl::pProxyTextureManager = MakeUnique<GLImpl::TextureImpl::ProxyTextureManager>();
// TODO: get real info in EGL // TODO: get real info in EGL
auto fbo0 = MG_State::pGLContext->CreateFramebufferObject(0); auto& fbo0 = MG_State::pGLContext->CreateFramebufferObject(0);
auto colorTex = MakeShared<MG_State::GLState::TextureObject2D>(0); auto colorTex = MakeShared<MG_State::GLState::TextureObject2D>(0);
colorTex->SetInternalFormat(TextureInternalFormat::RGBA8); colorTex->SetInternalFormat(TextureInternalFormat::RGBA8);
colorTex->AllocateStorage(TextureUploadTarget::Texture2D, 0, {{512, 512, 1}, 0}); colorTex->AllocateStorage(TextureUploadTarget::Texture2D, 0, {{512, 512, 1}, 0});
@@ -38,6 +38,6 @@ namespace MobileGL::MG_Impl {
fbo0->AttachTexture(FramebufferAttachmentType::Depth, depthTex); fbo0->AttachTexture(FramebufferAttachmentType::Depth, depthTex);
fbo0->AttachTexture(FramebufferAttachmentType::Stencil, stencilTex); fbo0->AttachTexture(FramebufferAttachmentType::Stencil, stencilTex);
GLImpl::FramebufferImpl::pDefaultFramebufferInfo = GLImpl::FramebufferImpl::pDefaultFramebufferInfo =
new GLImpl::FramebufferImpl::DefaultFramebufferInfo(fbo0, colorTex, depthTex, stencilTex); MakeUnique<GLImpl::FramebufferImpl::DefaultFramebufferInfo>(fbo0, colorTex, depthTex, stencilTex);
} }
} // namespace MobileGL::MG_Impl } // namespace MobileGL::MG_Impl
+3 -5
View File
@@ -388,8 +388,6 @@ namespace MobileGL {
*value = cfg->SurfaceType; *value = cfg->SurfaceType;
return true; return true;
case EGL_RENDERABLE_TYPE: case EGL_RENDERABLE_TYPE:
*value = cfg->RenderableType;
return true;
case EGL_CONFORMANT: case EGL_CONFORMANT:
*value = cfg->RenderableType; *value = cfg->RenderableType;
return true; return true;
@@ -878,8 +876,8 @@ namespace MobileGL {
Bool EGLContext::MakeCurrent(EGLDisplayHandle display, EGLSurfaceHandle draw, EGLSurfaceHandle read, Bool EGLContext::MakeCurrent(EGLDisplayHandle display, EGLSurfaceHandle draw, EGLSurfaceHandle read,
EGLContextHandle context) { EGLContextHandle context) {
const std::lock_guard<std::recursive_mutex> lock(m_mutex); const std::lock_guard<std::recursive_mutex> lock(m_mutex);
const Bool releaseCurrentRequest = display == EGL_NO_DISPLAY && draw == EGL_NO_SURFACE && const Bool releaseCurrentRequest =
read == EGL_NO_SURFACE && context == nullptr; display == EGL_NO_DISPLAY && draw == EGL_NO_SURFACE && read == EGL_NO_SURFACE && context == nullptr;
const auto threadKey = CurrentThreadKey(); const auto threadKey = CurrentThreadKey();
if (releaseCurrentRequest) { if (releaseCurrentRequest) {
ReleaseThreadUnlocked(threadKey); ReleaseThreadUnlocked(threadKey);
@@ -1130,6 +1128,6 @@ namespace MobileGL {
} }
} // namespace EGLState } // namespace EGLState
EGLState::EGLContext* pEGLContext; UniquePtr<EGLState::EGLContext> pEGLContext;
} // namespace MG_State } // namespace MG_State
} // namespace MobileGL } // namespace MobileGL
+1 -1
View File
@@ -253,6 +253,6 @@ namespace MobileGL {
}; };
} // namespace EGLState } // namespace EGLState
extern EGLState::EGLContext* pEGLContext; extern UniquePtr<EGLState::EGLContext> pEGLContext;
} // namespace MG_State } // namespace MG_State
} // namespace MobileGL } // namespace MobileGL
@@ -7,210 +7,203 @@
// End of Source File Header // End of Source File Header
#include "BufferObject.h" #include "BufferObject.h"
#include "MG_Util/Types.h"
namespace MobileGL { namespace MobileGL::MG_State::GLState {
namespace MG_State { BufferObject::BufferObject(Uint externalIndex)
namespace GLState { : m_externalIndex(externalIndex), m_size(0), m_usage(BufferUsage::StaticDraw), m_isMapped(false),
BufferObject::BufferObject(Uint externalIndex) m_mappingAccess(BufferMappingAccessBit::Null),
: m_externalIndex(externalIndex), m_size(0), m_usage(BufferUsage::StaticDraw), m_isMapped(false), m_change(BufferChangeBits::DirtyBit | BufferChangeBits::PreferReallocationBit), m_mappedRange({0, 0}),
m_mappingAccess(BufferMappingAccessBit::Null), m_dataPtr(MakeShared<Data>()), m_ownsStagingData{} {
m_change(BufferChangeBits::DirtyBit | BufferChangeBits::PreferReallocationBit), m_mappedRange({0, 0}), m_change.DirtyRanges.reserve(BufferChange::DEFAULT_RESERVED_DIRTY_RANGES_COUNT);
m_dataPtr(MakeShared<Data>()) { }
m_change.DirtyRanges.reserve(BufferChange::DEFAULT_RESERVED_DIRTY_RANGES_COUNT);
}
void BufferObject::Resize(SizeT size) { void BufferObject::Resize(SizeT size) {
m_size = size; m_size = size;
m_dataPtr->reserve(std::bit_ceil(size)); // power-of-2 reserve m_dataPtr->reserve(std::bit_ceil(size)); // power-of-2 reserve
m_dataPtr->resize(size); m_dataPtr->resize(size);
m_change.Bits |= BufferChangeBits::DirtyBit;
m_change.Bits |= BufferChangeBits::PreferReallocationBit;
}
void BufferObject::UploadData(DataPtr data, SizeT atOffset) {
MOBILEGL_ASSERT(atOffset + data.size <= m_size,
"UploadData out of bounds: atOffset (%zu) + data.size (%zu) > m_size (%zu)", atOffset,
data.size, m_size);
MOBILEGL_ASSERT(!m_isMapped, "Cannot upload data while buffer is mapped.");
Memcpy(m_dataPtr->data() + atOffset, data.data, data.size);
m_change.DirtyRanges.Add({atOffset, atOffset + data.size});
m_change.Bits |= BufferChangeBits::DirtyBit;
m_change.Bits |= BufferChangeBits::ForbidInvalidationBit;
m_change.Bits |= BufferChangeBits::ForbidUnsynchronizationBit;
// This function may be called by `glBufferData`, but we still set the forbid bits above,
// because when `PreferReallocationBit` is set, those bits are ignored anyway.
// The bits can fit the `glBufferSubData` semantics
// (though `glBufferSubData` calls `UploadSubData` instead).
}
void BufferObject::SetUsage(BufferUsage usage) {
m_usage = usage;
}
void BufferObject::ReleaseMemory() {
if (!m_isMapped) return;
if (m_mappingAccess & BufferMappingAccessBit::Write) { // if we wrote to the buffer
if (!(m_mappingAccess & BufferMappingAccessBit::FlushExplicit)) { // if we didn't flush explicitly
Memcpy(m_dataPtr->data() + m_mappedRange.start, m_stagingData.data(),
m_mappedRange.end - m_mappedRange.start);
m_change.DirtyRanges.Add({m_mappedRange.start, m_mappedRange.end});
m_change.Bits |= BufferChangeBits::DirtyBit; m_change.Bits |= BufferChangeBits::DirtyBit;
m_change.Bits |= BufferChangeBits::PreferReallocationBit;
} }
void BufferObject::UploadData(DataPtr data, SizeT atOffset) { m_stagingData.clear();
MOBILEGL_ASSERT(atOffset + data.size <= m_size, }
"UploadData out of bounds: atOffset (%zu) + data.size (%zu) > m_size (%zu)", atOffset,
data.size, m_size);
MOBILEGL_ASSERT(!m_isMapped, "Cannot upload data while buffer is mapped.");
Memcpy(m_dataPtr->data() + atOffset, data.data, data.size);
m_change.DirtyRanges.Add({atOffset, atOffset + data.size});
m_change.Bits |= BufferChangeBits::DirtyBit;
m_change.Bits |= BufferChangeBits::ForbidInvalidationBit;
m_change.Bits |= BufferChangeBits::ForbidUnsynchronizationBit;
// This function may be called by `glBufferData`, but we still set the forbid bits above,
// because when `PreferReallocationBit` is set, those bits are ignored anyway.
// The bits can fit the `glBufferSubData` semantics
// (though `glBufferSubData` calls `UploadSubData` instead).
}
void BufferObject::SetUsage(BufferUsage usage) { m_isMapped = false;
m_usage = usage; m_mappingAccess = BufferMappingAccessBit::Null;
} m_mappedRange = {0, 0};
m_ownsStagingData = false;
}
void BufferObject::ReleaseMemory() { void BufferObject::FlushMemoryRange(SizeT offset, SizeT length) {
if (!m_isMapped) return; MOBILEGL_ASSERT(m_isMapped, "Buffer must be mapped to flush memory range.");
MOBILEGL_ASSERT((m_mappingAccess & BufferMappingAccessBit::FlushExplicit),
"Buffer must be mapped with FlushExplicit access to flush memory range.");
MOBILEGL_ASSERT((m_mappingAccess & BufferMappingAccessBit::Write),
"Buffer must be mapped with Write access to flush memory range.");
if (m_mappingAccess & BufferMappingAccessBit::Write) { // if we wrote to the buffer SizeT start = m_mappedRange.start + offset;
if (!(m_mappingAccess & BufferMappingAccessBit::FlushExplicit)) { // if we didn't flush explicitly SizeT end = start + length;
Memcpy(m_dataPtr->data() + m_mappedRange.start, m_stagingData.data(), MOBILEGL_ASSERT(end <= m_mappedRange.end, "Flush range out of bounds: mappedRange.end (%zu) < end (%zu)",
m_mappedRange.end - m_mappedRange.start); m_mappedRange.end, end);
m_change.DirtyRanges.Add({m_mappedRange.start, m_mappedRange.end});
m_change.Bits |= BufferChangeBits::DirtyBit;
}
m_stagingData.clear(); Memcpy(m_dataPtr->data() + start, m_stagingData.data() + offset, length);
m_change.DirtyRanges.Add({start, end});
m_change.Bits |= BufferChangeBits::DirtyBit;
}
void BufferObject::UploadSubData(DataPtr data, SizeT atOffset) {
MOBILEGL_ASSERT(!m_isMapped, "Cannot upload sub data while buffer is mapped.");
MOBILEGL_ASSERT(atOffset + data.size <= m_size,
"UploadSubData out of bounds: atOffset (%zu) + data.size (%zu) > m_size (%zu)", atOffset,
data.size, m_size);
Memcpy(m_dataPtr->data() + atOffset, data.data, data.size);
m_change.DirtyRanges.Add({atOffset, atOffset + data.size});
m_change.Bits |= BufferChangeBits::DirtyBit;
m_change.Bits |= BufferChangeBits::ForbidInvalidationBit;
m_change.Bits |= BufferChangeBits::ForbidUnsynchronizationBit;
}
void BufferObject::CopyDataFrom(const SharedPtr<BufferObject>& src, SizeT srcOffset, SizeT dstOffset, SizeT size) {
MOBILEGL_ASSERT(!m_isMapped, "Cannot copy data while buffer is mapped.");
MOBILEGL_ASSERT(!src->IsMapped(), "Cannot copy data from a buffer that is mapped.");
MOBILEGL_ASSERT(srcOffset + size <= src->GetSize(),
"Source buffer copy out of bounds: srcOffset (%zu) + size (%zu) > src->GetSize() (%zu)",
srcOffset, size, src->GetSize());
MOBILEGL_ASSERT(dstOffset + size <= m_size,
"Destination buffer copy out of bounds: dstOffset (%zu) + size (%zu) > m_size (%zu)", dstOffset,
size, m_size);
const Uint8* srcData = src->m_dataPtr->data() + srcOffset;
Memcpy(m_dataPtr->data() + dstOffset, srcData, size);
m_change.DirtyRanges.Add({dstOffset, dstOffset + size});
m_change.Bits |= BufferChangeBits::DirtyBit;
}
void* BufferObject::AcquireMemory(Bool markMapped, Bool read, Bool write) {
if (markMapped) {
m_isMapped = true;
auto a = BufferMappingAccessBit::Coherent | BufferMappingAccessBit::Read;
m_mappingAccess = (read ? BufferMappingAccessBit::Read : BufferMappingAccessBit::Null) |
(write ? BufferMappingAccessBit::Write : BufferMappingAccessBit::Null);
m_mappedRange = {0, m_size};
if (m_mappingAccess & BufferMappingAccessBit::Write) {
m_stagingData.resize(m_size);
m_ownsStagingData = true;
if (!(m_mappingAccess &
(BufferMappingAccessBit::InvalidateRange | BufferMappingAccessBit::InvalidateBuffer))) {
Memcpy(m_stagingData.data(), m_dataPtr->data(), m_size);
} }
m_isMapped = false; return m_stagingData.data();
m_mappingAccess = BufferMappingAccessBit::Null; }
m_mappedRange = {0, 0}; }
m_ownsStagingData = false;
return m_dataPtr->data();
}
void* BufferObject::AcquireMemoryRange(Range1D range, Flags<BufferMappingAccessBit> access) {
MOBILEGL_ASSERT(range.end <= m_size && range.start <= range.end,
"AcquireMemoryRange out of bounds: range (%zu, %zu) exceeds m_size (%zu)", range.start,
range.end, m_size);
m_isMapped = true;
m_mappingAccess = access;
m_mappedRange = range;
if (access & BufferMappingAccessBit::Write) {
m_stagingData.resize(range.end - range.start);
m_ownsStagingData = true;
if (!(access & (BufferMappingAccessBit::InvalidateRange | BufferMappingAccessBit::InvalidateBuffer))) {
Memcpy(m_stagingData.data(), m_dataPtr->data() + range.start, m_stagingData.size());
} }
void BufferObject::FlushMemoryRange(SizeT offset, SizeT length) { return m_stagingData.data();
MOBILEGL_ASSERT(m_isMapped, "Buffer must be mapped to flush memory range."); } else {
MOBILEGL_ASSERT((m_mappingAccess & BufferMappingAccessBit::FlushExplicit), m_ownsStagingData = false;
"Buffer must be mapped with FlushExplicit access to flush memory range."); return m_dataPtr->data() + range.start;
MOBILEGL_ASSERT((m_mappingAccess & BufferMappingAccessBit::Write), }
"Buffer must be mapped with Write access to flush memory range.");
SizeT start = m_mappedRange.start + offset; m_change.Bits |=
SizeT end = start + length; !(access & BufferMappingAccessBit::InvalidateBuffer || access & BufferMappingAccessBit::InvalidateRange)
MOBILEGL_ASSERT(end <= m_mappedRange.end, ? BufferChangeBits::ForbidInvalidationBit
"Flush range out of bounds: mappedRange.end (%zu) < end (%zu)", m_mappedRange.end, end); : BufferChangeBits::None;
m_change.Bits |= !(access & BufferMappingAccessBit::Unsynchronized)
? BufferChangeBits::ForbidUnsynchronizationBit
: BufferChangeBits::None;
}
Memcpy(m_dataPtr->data() + start, m_stagingData.data() + offset, length); const SharedPtr<Data>& BufferObject::GetDataReadOnly() const {
m_change.DirtyRanges.Add({start, end}); return m_dataPtr;
m_change.Bits |= BufferChangeBits::DirtyBit; }
}
void BufferObject::UploadSubData(DataPtr data, SizeT atOffset) { void BufferObject::ClearDirty() {
MOBILEGL_ASSERT(!m_isMapped, "Cannot upload sub data while buffer is mapped."); m_change.DirtyRanges.clear();
MOBILEGL_ASSERT(atOffset + data.size <= m_size, m_change.Bits = BufferChangeBits::None;
"UploadSubData out of bounds: atOffset (%zu) + data.size (%zu) > m_size (%zu)", }
atOffset, data.size, m_size);
Memcpy(m_dataPtr->data() + atOffset, data.data, data.size); SizeT BufferObject::GetSize() const {
m_change.DirtyRanges.Add({atOffset, atOffset + data.size}); return m_size;
m_change.Bits |= BufferChangeBits::DirtyBit; }
m_change.Bits |= BufferChangeBits::ForbidInvalidationBit;
m_change.Bits |= BufferChangeBits::ForbidUnsynchronizationBit;
}
void BufferObject::CopyDataFrom(const SharedPtr<BufferObject>& src, SizeT srcOffset, SizeT dstOffset, BufferUsage BufferObject::GetUsage() const {
SizeT size) { return m_usage;
MOBILEGL_ASSERT(!m_isMapped, "Cannot copy data while buffer is mapped."); }
MOBILEGL_ASSERT(!src->IsMapped(), "Cannot copy data from a buffer that is mapped.");
MOBILEGL_ASSERT(srcOffset + size <= src->GetSize(),
"Source buffer copy out of bounds: srcOffset (%zu) + size (%zu) > src->GetSize() (%zu)",
srcOffset, size, src->GetSize());
MOBILEGL_ASSERT(dstOffset + size <= m_size,
"Destination buffer copy out of bounds: dstOffset (%zu) + size (%zu) > m_size (%zu)",
dstOffset, size, m_size);
const Uint8* srcData = src->m_dataPtr->data() + srcOffset; const VecRange1D& BufferObject::GetDirtyRanges() const {
Memcpy(m_dataPtr->data() + dstOffset, srcData, size); return m_change.DirtyRanges;
m_change.DirtyRanges.Add({dstOffset, dstOffset + size}); }
m_change.Bits |= BufferChangeBits::DirtyBit;
}
void* BufferObject::AcquireMemory(Bool markMapped, Bool read, Bool write) { Flags<BufferChangeBits> BufferObject::GetChangeBits() const {
if (markMapped) { return m_change.Bits;
m_isMapped = true; }
auto a = BufferMappingAccessBit::Coherent | BufferMappingAccessBit::Read;
m_mappingAccess = (read ? BufferMappingAccessBit::Read : BufferMappingAccessBit::Null) |
(write ? BufferMappingAccessBit::Write : BufferMappingAccessBit::Null);
m_mappedRange = {0, m_size};
if (m_mappingAccess & BufferMappingAccessBit::Write) { Bool BufferObject::IsMapped() const {
m_stagingData.resize(m_size); return m_isMapped;
m_ownsStagingData = true; }
if (!(m_mappingAccess & Range1D BufferObject::GetMappedRange() const {
(BufferMappingAccessBit::InvalidateRange | BufferMappingAccessBit::InvalidateBuffer))) { return m_isMapped ? m_mappedRange : Range1D{0, 0};
Memcpy(m_stagingData.data(), m_dataPtr->data(), m_size); }
}
return m_stagingData.data(); Flags<BufferMappingAccessBit> BufferObject::GetMappingAccess() const {
} return m_isMapped ? m_mappingAccess : BufferMappingAccessBit::Null;
} }
return m_dataPtr->data(); Uint BufferObject::GetExternalIndex() const {
} return m_externalIndex;
}
void* BufferObject::AcquireMemoryRange(Range1D range, Flags<BufferMappingAccessBit> access) { } // namespace MobileGL::MG_State::GLState
MOBILEGL_ASSERT(range.end <= m_size && range.start <= range.end,
"AcquireMemoryRange out of bounds: range (%zu, %zu) exceeds m_size (%zu)", range.start,
range.end, m_size);
m_isMapped = true;
m_mappingAccess = access;
m_mappedRange = range;
if (access & BufferMappingAccessBit::Write) {
m_stagingData.resize(range.end - range.start);
m_ownsStagingData = true;
if (!(access &
(BufferMappingAccessBit::InvalidateRange | BufferMappingAccessBit::InvalidateBuffer))) {
Memcpy(m_stagingData.data(), m_dataPtr->data() + range.start, m_stagingData.size());
}
return m_stagingData.data();
} else {
m_ownsStagingData = false;
return m_dataPtr->data() + range.start;
}
m_change.Bits |= !(access & BufferMappingAccessBit::InvalidateBuffer ||
access & BufferMappingAccessBit::InvalidateRange)
? BufferChangeBits::ForbidInvalidationBit
: BufferChangeBits::None;
m_change.Bits |= !(access & BufferMappingAccessBit::Unsynchronized)
? BufferChangeBits::ForbidUnsynchronizationBit
: BufferChangeBits::None;
}
const SharedPtr<Data> BufferObject::GetDataReadOnly() const {
return m_dataPtr;
}
void BufferObject::ClearDirty() {
m_change.DirtyRanges.clear();
m_change.Bits = BufferChangeBits::None;
}
SizeT BufferObject::GetSize() const {
return m_size;
}
BufferUsage BufferObject::GetUsage() const {
return m_usage;
}
const VecRange1D& BufferObject::GetDirtyRanges() const {
return m_change.DirtyRanges;
}
Flags<BufferChangeBits> BufferObject::GetChangeBits() const {
return m_change.Bits;
}
Bool BufferObject::IsMapped() const {
return m_isMapped;
}
Range1D BufferObject::GetMappedRange() const {
return m_isMapped ? m_mappedRange : Range1D{0, 0};
}
Flags<BufferMappingAccessBit> BufferObject::GetMappingAccess() const {
return m_isMapped ? m_mappingAccess : BufferMappingAccessBit::Null;
}
Uint BufferObject::GetExternalIndex() const {
return m_externalIndex;
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
@@ -7,7 +7,6 @@
// End of Source File Header // End of Source File Header
#pragma once #pragma once
#include "MG_Util/Types.h"
#include <Includes.h> #include <Includes.h>
#include <MG_Util/Math/VectorTypes.h> #include <MG_Util/Math/VectorTypes.h>
@@ -73,47 +72,45 @@ namespace MobileGL {
VecRange1D DirtyRanges; VecRange1D DirtyRanges;
}; };
namespace MG_State { namespace MG_State::GLState {
namespace GLState { class BufferObject {
class BufferObject { public:
public: using TargetEnum = BufferTarget;
using TargetEnum = BufferTarget;
BufferObject(Uint externalIndex); BufferObject(Uint externalIndex);
void Resize(SizeT size); void Resize(SizeT size);
void UploadData(DataPtr data, SizeT atOffset); void UploadData(DataPtr data, SizeT atOffset);
void SetUsage(BufferUsage usage); void SetUsage(BufferUsage usage);
void* AcquireMemory(Bool markMapped, Bool read, Bool write); void* AcquireMemory(Bool markMapped, Bool read, Bool write);
void* AcquireMemoryRange(Range1D range, Flags<BufferMappingAccessBit> access); void* AcquireMemoryRange(Range1D range, Flags<BufferMappingAccessBit> access);
void ReleaseMemory(); void ReleaseMemory();
void FlushMemoryRange(SizeT offset, SizeT length); void FlushMemoryRange(SizeT offset, SizeT length);
void UploadSubData(DataPtr data, SizeT atOffset); void UploadSubData(DataPtr data, SizeT atOffset);
void CopyDataFrom(const SharedPtr<BufferObject>& src, SizeT srcOffset, SizeT dstOffset, SizeT size); void CopyDataFrom(const SharedPtr<BufferObject>& src, SizeT srcOffset, SizeT dstOffset, SizeT size);
void ClearDirty(); void ClearDirty();
Bool IsMapped() const; Bool IsMapped() const;
SizeT GetSize() const; SizeT GetSize() const;
BufferUsage GetUsage() const; BufferUsage GetUsage() const;
Range1D GetMappedRange() const; Range1D GetMappedRange() const;
const SharedPtr<Data> GetDataReadOnly() const; const SharedPtr<Data>& GetDataReadOnly() const;
Flags<BufferMappingAccessBit> GetMappingAccess() const; Flags<BufferMappingAccessBit> GetMappingAccess() const;
Uint GetExternalIndex() const; Uint GetExternalIndex() const;
const VecRange1D& GetDirtyRanges() const; const VecRange1D& GetDirtyRanges() const;
Flags<BufferChangeBits> GetChangeBits() const; Flags<BufferChangeBits> GetChangeBits() const;
private: private:
const Uint m_externalIndex = 0; const Uint m_externalIndex = 0;
SizeT m_size = 0; SizeT m_size = 0;
BufferUsage m_usage = BufferUsage::StaticDraw; BufferUsage m_usage = BufferUsage::StaticDraw;
SharedPtr<Data> m_dataPtr; SharedPtr<Data> m_dataPtr;
Bool m_isMapped; Bool m_isMapped;
Flags<BufferMappingAccessBit> m_mappingAccess; Flags<BufferMappingAccessBit> m_mappingAccess;
BufferChange m_change; BufferChange m_change;
Range1D m_mappedRange; Range1D m_mappedRange;
Vector<Uint8> m_stagingData; Vector<Uint8> m_stagingData;
Bool m_ownsStagingData; Bool m_ownsStagingData;
}; };
} // namespace GLState } // namespace MG_State::GLState
} // namespace MG_State
} // namespace MobileGL } // namespace MobileGL
@@ -8,78 +8,75 @@
#include "BufferState.h" #include "BufferState.h"
namespace MobileGL { namespace MobileGL::MG_State::GLState {
namespace MG_State { BufferState::BufferState() : m_indexGenerator(1024, 1) {
namespace GLState { for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
BufferState::BufferState() : m_indexGenerator(1024, 1) { m_bindingSlots[i] = BindingSlot<BufferObject>(GlobalBufferTargets[i]);
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) { }
m_bindingSlots[i] = BindingSlot<BufferObject>(GlobalBufferTargets[i]); }
}
}
SharedPtr<BufferObject> BufferState::GetBufferObject(Uint index) { const SharedPtr<BufferObject>& BufferState::GetBufferObject(Uint index) {
auto it = m_bufferObjects.find(index); auto it = m_bufferObjects.find(index);
if (it != m_bufferObjects.end()) { if (it != m_bufferObjects.end()) {
return it->second; return it->second;
} }
return nullptr; static SharedPtr<BufferObject> nullBufferObject = nullptr;
} return nullBufferObject;
}
Vector<Uint> BufferState::GenerateNames(Uint number) { void BufferState::GenerateNames(Uint number, Vector<Uint>& buffers) {
Vector<Uint> buffers(number); buffers.resize(number);
m_indexGenerator.Generate(number, buffers.data()); m_indexGenerator.Generate(number, buffers.data());
return buffers; }
}
SharedPtr<BufferObject> BufferState::CreateBufferObject(Uint index) { const SharedPtr<BufferObject>& BufferState::CreateBufferObject(Uint index) {
auto bufferObject = MakeShared<BufferObject>(index); auto& bufferObj = m_bufferObjects[index];
m_bufferObjects[index] = bufferObject; if (!bufferObj) {
return bufferObject; bufferObj = MakeShared<BufferObject>(index);
} }
return bufferObj;
}
BindingSlot<BufferObject>& BufferState::GetBindingSlot(BufferTarget target) { BindingSlot<BufferObject>& BufferState::GetBindingSlot(BufferTarget target) {
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) { for (auto& bindingSlot : m_bindingSlots) {
if (m_bindingSlots[i].GetTarget() == target) { if (bindingSlot.GetTarget() == target) {
return m_bindingSlots[i]; return bindingSlot;
}
}
MOBILEGL_ASSERT(false, "Invalid BufferTarget enum value: %d", static_cast<int>(target));
return m_bindingSlots[0];
}
void BufferState::MarkBufferObjectForDeletion(Uint index) {
if (m_indexGenerator.IsValid(index)) {
auto it = m_bufferObjects.find(index);
if (it != m_bufferObjects.end()) {
for (auto& bindingSlot : m_bindingSlots) {
if (bindingSlot.GetBoundObject() == it->second) {
bindingSlot.Bind(nullptr);
} }
} }
MOBILEGL_ASSERT(false, "Invalid BufferTarget enum value: %d", static_cast<int>(target)); m_bufferObjects.erase(it);
return m_bindingSlots[0];
} }
m_indexGenerator.Delete(index);
}
}
void BufferState::MarkBufferObjectForDeletion(Uint index) { Bool BufferState::ValidateName(Uint index) const {
if (m_indexGenerator.IsValid(index)) { return m_indexGenerator.IsValid(index);
auto it = m_bufferObjects.find(index); }
if (it != m_bufferObjects.end()) {
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
if (m_bindingSlots[i].GetBoundObject() == it->second) {
m_bindingSlots[i].Bind(nullptr);
}
}
m_bufferObjects.erase(it);
}
m_indexGenerator.Delete(index);
}
}
Bool BufferState::ValidateName(Uint index) const { Bool BufferState::ValidateBufferObject(Uint index) const {
return m_indexGenerator.IsValid(index); return m_bufferObjects.find(index) != m_bufferObjects.end();
} }
Bool BufferState::ValidateBufferObject(Uint index) const { BindingSlotRange1D<BufferObject>& BufferState::GetBindingPoint(BufferTarget target, Uint index) {
return m_bufferObjects.find(index) != m_bufferObjects.end(); for (SizeT i = 0; i < BufferBindPointTargets.size(); ++i) {
if (BufferBindPointTargets[i] == target) {
return m_bufferBindPointTargets[i][index];
} }
}
BindingSlotRange1D<BufferObject>& BufferState::GetBindingPoint(BufferTarget target, Uint index) { MOBILEGL_ASSERT(false, "Invalid BufferTarget enum value for binding point: %d", static_cast<int>(target));
for (SizeT i = 0; i < BufferBindPointTargets.size(); ++i) { return m_bufferBindPointTargets[0][index];
if (BufferBindPointTargets[i] == target) { }
return m_bufferBindPointTargets[i][index]; } // namespace MobileGL::MG_State::GLState
}
}
MOBILEGL_ASSERT(false, "Invalid BufferTarget enum value for binding point: %d",
static_cast<int>(target));
return m_bufferBindPointTargets[0][index];
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
@@ -11,46 +11,40 @@
#include <MG_Util/Miscellany/IndexGenerator.h> #include <MG_Util/Miscellany/IndexGenerator.h>
#include "BufferObject.h" #include "BufferObject.h"
namespace MobileGL { namespace MobileGL::MG_State::GLState {
namespace MG_State { constexpr const auto GlobalBufferTargets =
namespace GLState { ToArray(BufferTarget::Vertex, BufferTarget::Uniform, BufferTarget::CopyRead, BufferTarget::CopyWrite,
constexpr const auto GlobalBufferTargets = BufferTarget::PixelPack, BufferTarget::PixelUnpack, BufferTarget::Query, BufferTarget::Texture,
ToArray(BufferTarget::Vertex, BufferTarget::Uniform, BufferTarget::CopyRead, BufferTarget::CopyWrite, BufferTarget::TransformFeedback, BufferTarget::AtomicCounter, BufferTarget::DispatchIndirect,
BufferTarget::PixelPack, BufferTarget::PixelUnpack, BufferTarget::Query, BufferTarget::Texture, BufferTarget::DrawIndirect, BufferTarget::ShaderStorage);
BufferTarget::TransformFeedback, BufferTarget::AtomicCounter, BufferTarget::DispatchIndirect, constexpr const auto BufferBindPointTargets = ToArray(BufferTarget::Uniform, BufferTarget::TransformFeedback,
BufferTarget::DrawIndirect, BufferTarget::ShaderStorage); BufferTarget::AtomicCounter, BufferTarget::ShaderStorage);
constexpr const auto BufferBindPointTargets =
ToArray(BufferTarget::Uniform, BufferTarget::TransformFeedback, BufferTarget::AtomicCounter,
BufferTarget::ShaderStorage);
class BufferState { class BufferState {
public: public:
BufferState(); BufferState();
SharedPtr<BufferObject> GetBufferObject(Uint index); const SharedPtr<BufferObject>& GetBufferObject(Uint index);
Vector<Uint> GenerateNames(Uint number); void GenerateNames(Uint number, Vector<Uint>& buffers);
SharedPtr<BufferObject> CreateBufferObject(Uint index); const SharedPtr<BufferObject>& CreateBufferObject(Uint index);
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 { constexpr SizeT GetBindingPointCount(const BufferTarget target) const {
auto it = std::find(BufferBindPointTargets.begin(), BufferBindPointTargets.end(), target); auto it = std::find(BufferBindPointTargets.begin(), BufferBindPointTargets.end(), target);
auto index = std::distance(BufferBindPointTargets.begin(), it); auto index = std::distance(BufferBindPointTargets.begin(), it);
return m_bufferBindPointTargets[index].size(); 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;
private: private:
UnorderedMap<Uint, SharedPtr<BufferObject>> m_bufferObjects; UnorderedMap<Uint, SharedPtr<BufferObject>> m_bufferObjects;
IndexGenerator<Uint> m_indexGenerator; IndexGenerator<Uint> m_indexGenerator;
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>, 16>, BufferBindPointTargets.size()> Array<Array<BindingSlotRange1D<BufferObject>, 16>, BufferBindPointTargets.size()> m_bufferBindPointTargets;
m_bufferBindPointTargets; };
}; } // namespace MobileGL::MG_State::GLState
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
+388 -388
View File
@@ -10,436 +10,436 @@
#include "MG_State/GLState/RenderbufferState/RenderbufferObject.h" #include "MG_State/GLState/RenderbufferState/RenderbufferObject.h"
#include "MG_State/EGLState/Core.h" #include "MG_State/EGLState/Core.h"
namespace MobileGL { namespace MobileGL::MG_State {
namespace MG_State { void Init() {
void Init() { MGLOG_D("Initializing MobileGL State...");
MGLOG_D("Initializing MobileGL State..."); pGLContext = MakeUnique<GLState::GLContext>();
pGLContext = new MG_State::GLState::GLContext(); pEGLContext = MakeUnique<EGLState::EGLContext>();
pEGLContext = new MG_State::EGLState::EGLContext(); }
namespace GLState {
// Error
void GLContext::RecordError(ErrorCode code, UniquePtr<ErrorInfo> info) {
m_errorState.RecordError(code, Move(info));
} }
namespace GLState { Bool GLContext::HasGLError() const {
// Error return m_errorState.HasGLError();
void GLContext::RecordError(ErrorCode code, SharedPtr<ErrorInfo> info) { }
m_errorState.RecordError(code, info);
Optional<const Error*> GLContext::PeekGLError() const {
return m_errorState.PeekGLError();
}
Optional<UniquePtr<Error>> GLContext::PopGLError() {
return Move(m_errorState.PopGLError());
}
Bool GLContext::HasNonGLError() const {
return m_errorState.HasNonGLError();
}
Optional<const Error*> GLContext::PeekNonGLError() const {
return m_errorState.PeekNonGLError();
}
Optional<UniquePtr<Error>> GLContext::PopNonGLError() {
return Move(m_errorState.PopNonGLError());
}
void GLContext::ClearErrors() {
m_errorState.Clear();
}
// Buffer
void GLContext::GenBufferNames(Uint number, Vector<Uint>& buffers) {
m_bufferState.GenerateNames(number, buffers);
}
const SharedPtr<BufferObject>& GLContext::GetBufferObject(Uint index) {
return m_bufferState.GetBufferObject(index);
}
BindingSlot<BufferObject>& GLContext::GetBufferBindingSlot(BufferTarget target) {
if (target == BufferTarget::Index) {
const auto& vao = m_vertexArrayState.GetBoundVertexArray();
MOBILEGL_ASSERT(vao != nullptr, "No VAO is currently bound when accessing index buffer binding slot.");
return vao->GetIndexBufferBindingSlot();
} }
Bool GLContext::HasGLError() const { return m_bufferState.GetBindingSlot(target);
return m_errorState.HasGLError(); }
}
Optional<const Error> GLContext::PeekGLError() const { BindingSlotRange1D<BufferObject>& GLContext::GetBufferBindingPoint(BufferTarget target, Uint index) {
return m_errorState.PeekGLError(); return m_bufferState.GetBindingPoint(target, index);
} }
Optional<Error> GLContext::PopGLError() { const SharedPtr<BufferObject>& GLContext::CreateBufferObject(Uint index) {
return m_errorState.PopGLError(); return m_bufferState.CreateBufferObject(index);
} }
Bool GLContext::HasNonGLError() const { void GLContext::MarkBufferObjectForDeletion(Uint index) {
return m_errorState.HasNonGLError(); if (ValidateBufferObject(index)) {
} auto bufferObject = m_bufferState.GetBufferObject(index);
auto& vaos = m_vertexArrayState.GetAllVertexArrays();
for (auto& vao : vaos) {
if (vao == nullptr) continue;
Optional<const Error> GLContext::PeekNonGLError() const { if (vao->GetIndexBufferBindingSlot().GetBoundObject() == bufferObject) {
return m_errorState.PeekNonGLError(); vao->GetIndexBufferBindingSlot().Bind(nullptr);
} }
for (SizeT j = 0; j < VertexArrayObject::MAX_VERTEX_ATTRIBS; ++j) {
Optional<Error> GLContext::PopNonGLError() { if (vao->GetAttribute(j).Buffer == bufferObject) {
return m_errorState.PopNonGLError(); vao->BindAttributeBuffer(j, nullptr);
}
void GLContext::ClearErrors() {
m_errorState.Clear();
}
// Buffer
Vector<Uint> GLContext::GenBufferNames(Uint number) {
return m_bufferState.GenerateNames(number);
}
SharedPtr<BufferObject> GLContext::GetBufferObject(Uint index) {
return m_bufferState.GetBufferObject(index);
}
BindingSlot<BufferObject>& GLContext::GetBufferBindingSlot(BufferTarget target) {
if (target == BufferTarget::Index) {
const auto& vao = m_vertexArrayState.GetBoundVertexArray();
MOBILEGL_ASSERT(vao != nullptr,
"No VAO is currently bound when accessing index buffer binding slot.");
return vao->GetIndexBufferBindingSlot();
}
return m_bufferState.GetBindingSlot(target);
}
BindingSlotRange1D<BufferObject>& GLContext::GetBufferBindingPoint(BufferTarget target, Uint index) {
return m_bufferState.GetBindingPoint(target, index);
}
SharedPtr<BufferObject> GLContext::CreateBufferObject(Uint index) {
return m_bufferState.CreateBufferObject(index);
}
void GLContext::MarkBufferObjectForDeletion(Uint index) {
if (ValidateBufferObject(index)) {
auto bufferObject = m_bufferState.GetBufferObject(index);
auto& vaos = m_vertexArrayState.GetAllVertexArrays();
for (SizeT i = 0; i < vaos.size(); ++i) {
auto vao = vaos[i];
if (vao == nullptr) continue;
if (vao->GetIndexBufferBindingSlot().GetBoundObject() == bufferObject) {
vao->GetIndexBufferBindingSlot().Bind(nullptr);
}
for (SizeT j = 0; j < VertexArrayObject::MAX_VERTEX_ATTRIBS; ++j) {
if (vao->GetAttribute(j).Buffer == bufferObject) {
vao->BindAttributeBuffer(j, nullptr);
}
} }
} }
} }
m_bufferState.MarkBufferObjectForDeletion(index);
} }
Bool GLContext::ValidateBufferName(Uint index) const { m_bufferState.MarkBufferObjectForDeletion(index);
return m_bufferState.ValidateName(index); }
}
Bool GLContext::ValidateBufferObject(Uint index) const { Bool GLContext::ValidateBufferName(Uint index) const {
return m_bufferState.ValidateBufferObject(index); return m_bufferState.ValidateName(index);
} }
// VertexArray Bool GLContext::ValidateBufferObject(Uint index) const {
Vector<Uint> GLContext::GenVertexArrayNames(Uint number) { return m_bufferState.ValidateBufferObject(index);
return m_vertexArrayState.GenerateNames(number); }
}
SharedPtr<VertexArrayObject> GLContext::GetVertexArrayObject(Uint index) { // VertexArray
return m_vertexArrayState.GetVertexArrayObject(index); void GLContext::GenVertexArrayNames(Uint number, Vector<Uint>& vertexArrays) {
} m_vertexArrayState.GenerateNames(number, vertexArrays);
}
void GLContext::BindVertexArray(Uint index) { const SharedPtr<VertexArrayObject>& GLContext::GetVertexArrayObject(Uint index) {
m_vertexArrayState.Bind(index); return m_vertexArrayState.GetVertexArrayObject(index);
} }
SharedPtr<VertexArrayObject> GLContext::CreateVertexArrayObject(Uint index) { void GLContext::BindVertexArray(Uint index) {
return m_vertexArrayState.CreateVertexArrayObject(index); m_vertexArrayState.Bind(index);
} }
void GLContext::MarkVertexArrayForDeletion(Uint index) { const SharedPtr<VertexArrayObject>& GLContext::CreateVertexArrayObject(Uint index) {
m_vertexArrayState.MarkVertexArrayForDeletion(index); return m_vertexArrayState.CreateVertexArrayObject(index);
} }
Bool GLContext::ValidateVertexArrayName(Uint index) const { void GLContext::MarkVertexArrayForDeletion(Uint index) {
return m_vertexArrayState.ValidateName(index); m_vertexArrayState.MarkVertexArrayForDeletion(index);
} }
Bool GLContext::ValidateVertexArrayObject(Uint index) const { Bool GLContext::ValidateVertexArrayName(Uint index) const {
return m_vertexArrayState.ValidateVertexArrayObject(index); return m_vertexArrayState.ValidateName(index);
} }
SharedPtr<VertexArrayObject> GLContext::GetBoundVertexArray() { Bool GLContext::ValidateVertexArrayObject(Uint index) const {
return m_vertexArrayState.GetBoundVertexArray(); return m_vertexArrayState.ValidateVertexArrayObject(index);
} }
// Texture const SharedPtr<VertexArrayObject>& GLContext::GetBoundVertexArray() {
Vector<Uint> GLContext::GenTextureNames(Uint number) { return m_vertexArrayState.GetBoundVertexArray();
return m_textureState.GenerateNames(number); }
}
SharedPtr<ITextureObject> GLContext::GetTextureObject(Uint index) { // Texture
return m_textureState.GetTextureObject(index); void GLContext::GenTextureNames(Uint number, Vector<Uint>& textures) {
} m_textureState.GenerateNames(number, textures);
}
SharedPtr<ITextureObject> GLContext::CreateTextureObject(Uint index, TextureTarget target) { const SharedPtr<ITextureObject>& GLContext::GetTextureObject(Uint index) {
return m_textureState.CreateTextureObject(index, target); return m_textureState.GetTextureObject(index);
} }
void GLContext::MarkTextureObjectForDeletion(Uint index) { const SharedPtr<ITextureObject>& GLContext::CreateTextureObject(Uint index, TextureTarget target) {
m_textureState.MarkTextureObjectForDeletion(index); return m_textureState.CreateTextureObject(index, target);
} }
TextureUnit& GLContext::GetTextureUnitObject(Int unit) { void GLContext::MarkTextureObjectForDeletion(Uint index) {
return m_textureState.GetUnitObject(unit); m_textureState.MarkTextureObjectForDeletion(index);
} }
Bool GLContext::ValidateTextureName(Uint index) const { TextureUnit& GLContext::GetTextureUnitObject(Int unit) {
return m_textureState.ValidateName(index); return m_textureState.GetUnitObject(unit);
} }
Bool GLContext::ValidateTextureObject(Uint index) const {
return m_textureState.ValidateTextureObject(index);
}
Int GLContext::GetActiveTextureUnit() const {
return m_textureState.GetActiveTextureUnit();
}
void GLContext::SetActiveTextureUnit(Int unit) { Bool GLContext::ValidateTextureName(Uint index) const {
m_textureState.SetActiveTextureUnit(unit); return m_textureState.ValidateName(index);
} }
// Program Bool GLContext::ValidateTextureObject(Uint index) const {
Uint GLContext::CreateProgram() { return m_textureState.ValidateTextureObject(index);
return m_programState.CreateProgram(); }
}
Uint GLContext::CreateShader(const ShaderStage stage) { Int GLContext::GetActiveTextureUnit() const {
return m_programState.CreateShader(stage); return m_textureState.GetActiveTextureUnit();
} }
void GLContext::MarkProgramForDeletion(const Uint index) { void GLContext::SetActiveTextureUnit(Int unit) {
return m_programState.MarkProgramObjectForDeletion(index); m_textureState.SetActiveTextureUnit(unit);
} }
void GLContext::MarkShaderForDeletion(const Uint index) {
return m_programState.MarkShaderObjectForDeletion(index);
}
Bool GLContext::ValidateProgramName(const Uint index) const {
return m_programState.ValidateProgramObject(index);
}
Bool GLContext::ValidateShaderName(const Uint index) const {
return m_programState.ValidateShaderObject(index);
}
SharedPtr<ProgramObject> GLContext::GetProgramObject(const Uint index) {
return m_programState.GetProgramObject(index);
}
SharedPtr<ShaderObject> GLContext::GetShaderObject(const Uint index) {
return m_programState.GetShaderObject(index);
}
void GLContext::UseProgram(Uint program) {
return m_programState.UseProgram(program);
}
SharedPtr<ProgramObject> GLContext::GetCurrentProgram() {
return m_programState.GetCurrentProgram();
}
// RenderState
Uint GLContext::GetRenderStateParametersVersion() const {
return m_renderState.GetVersion();
}
const RenderStateParameters& GLContext::GetRenderStateParameters() const {
return m_renderState.GetAllParameters();
}
void GLContext::SetViewport(IntVec4 viewport) {
m_renderState.SetViewport(viewport);
}
const IntVec4& GLContext::GetViewport() const {
return m_renderState.GetViewport();
}
void GLContext::SetCapability(CapabilityInput cap, Bool enabled) {
m_renderState.SetCapability(cap, enabled);
}
Bool GLContext::IsCapabilityEnabled(CapabilityInput cap) const {
return m_renderState.IsCapabilityEnabled(cap);
}
void GLContext::SetCapabilityIndexed(CapabilityInput cap, Uint index, Bool enabled) {
m_renderState.SetCapabilityIndexed(cap, index, enabled);
}
Bool GLContext::IsCapabilityEnabledIndexed(CapabilityInput cap, Uint index) const {
return m_renderState.IsCapabilityEnabledIndexed(cap, index);
}
void GLContext::SetBlendFunc(BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha,
BlendFactor dstAlpha) {
m_renderState.SetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void GLContext::GetBlendFunc(BlendFactor& srcRGB, BlendFactor& dstRGB, BlendFactor& srcAlpha,
BlendFactor& dstAlpha) const {
m_renderState.GetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void GLContext::SetBlendFuncIndexed(Uint index, BlendFactor srcRGB, BlendFactor dstRGB,
BlendFactor srcAlpha, BlendFactor dstAlpha) {
m_renderState.SetBlendFuncIndexed(index, srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void GLContext::GetBlendFuncIndexed(Uint index, BlendFactor& srcRGB, BlendFactor& dstRGB,
BlendFactor& srcAlpha, BlendFactor& dstAlpha) const {
m_renderState.GetBlendFuncIndexed(index, srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void GLContext::SetDepthFunc(DepthTestFunc func) {
m_renderState.SetDepthFunc(func);
}
DepthTestFunc GLContext::GetDepthFunc() const {
return m_renderState.GetDepthFunc();
}
void GLContext::SetDepthMask(Bool flag) {
m_renderState.SetDepthMask(flag);
}
Bool GLContext::GetDepthMask() const {
return m_renderState.GetDepthMask();
}
void GLContext::SetColorMask(BoolVec4 mask) {
m_renderState.SetColorMask(mask);
}
const BoolVec4 GLContext::GetColorMask() const {
return m_renderState.GetColorMask();
}
void GLContext::SetClearColor(FloatVec4 color) {
m_renderState.SetClearColor(color);
}
const FloatVec4& GLContext::GetClearColor() const {
return m_renderState.GetClearColor();
}
void GLContext::SetClearDepth(Float depth) {
m_renderState.SetClearDepth(depth);
}
Float GLContext::GetClearDepth() const {
return m_renderState.GetClearDepth();
}
void GLContext::SetClearStencil(Int stencil) {
m_renderState.SetClearStencil(stencil);
}
Int GLContext::GetClearStencil() const {
return m_renderState.GetClearStencil();
}
void GLContext::SetPixelStoreParam(PixelStoreParam param, Int value) {
m_renderState.SetPixelStoreParam(param, value);
}
Int GLContext::GetPixelStoreParam(PixelStoreParam param) const {
return m_renderState.GetPixelStoreParam(param);
}
PixelStoreParameters GLContext::GetPixelStoreParameters(Bool isUnpack) const {
return m_renderState.GetPixelStoreParameters(isUnpack);
}
void GLContext::SetCullFaceMode(CullFaceMode mode) {
m_renderState.SetCullFaceMode(mode);
}
CullFaceMode GLContext::GetCullFaceMode() const {
return m_renderState.GetCullFaceMode();
}
void GLContext::SetScissorBox(IntVec4 box) {
m_renderState.SetScissorBox(box);
}
const IntVec4& GLContext::GetScissorBox() const {
return m_renderState.GetScissorBox();
}
// Framebuffer
Vector<Uint> GLContext::GenFramebufferNames(Uint number) {
return m_framebufferState.GenerateNames(number);
}
SharedPtr<FramebufferObject> GLContext::GetFramebufferObject(Uint index) {
return m_framebufferState.GetFramebufferObject(index);
}
BindingSlot<FramebufferObject>& GLContext::GetFramebufferBindingSlot(FramebufferTarget target) {
return m_framebufferState.GetBindingSlot(target);
}
SharedPtr<FramebufferObject> GLContext::CreateFramebufferObject(Uint index) {
return m_framebufferState.CreateFramebufferObject(index);
}
void GLContext::MarkFramebufferObjectForDeletion(Uint index) {
m_framebufferState.MarkFramebufferObjectForDeletion(index);
}
Bool GLContext::ValidateFramebufferName(Uint index) const {
return m_framebufferState.ValidateName(index);
}
Bool GLContext::ValidateFramebufferObject(Uint index) const {
return m_framebufferState.ValidateFramebufferObject(index);
}
// Sampler
Vector<Uint> GLContext::GenSamplerNames(Uint number) {
return m_samplerState.GenerateNames(number);
}
SharedPtr<SamplerObject> GLContext::GetSamplerObject(Uint index) {
return m_samplerState.GetSamplerObject(index);
}
SharedPtr<SamplerObject> GLContext::CreateSamplerObject(Uint index) {
return m_samplerState.CreateSamplerObject(index);
}
void GLContext::MarkSamplerObjectForDeletion(Uint index) { // Program
// Unbind the sampler from all texture units Uint GLContext::CreateProgram() {
if (ValidateSamplerObject(index)) { return m_programState.CreateProgram();
auto sampler = m_samplerState.GetSamplerObject(index); }
for (Int unit = 0; unit < TextureState::MAX_TEXTURE_IMAGE_UNITS; ++unit) {
auto& textureUnit = m_textureState.GetUnitObject(unit); Uint GLContext::CreateShader(const ShaderStage stage) {
if (textureUnit.GetSamplerObject() == sampler) { return m_programState.CreateShader(stage);
textureUnit.SetSamplerObject(nullptr); }
}
void GLContext::MarkProgramForDeletion(const Uint index) {
return m_programState.MarkProgramObjectForDeletion(index);
}
void GLContext::MarkShaderForDeletion(const Uint index) {
return m_programState.MarkShaderObjectForDeletion(index);
}
Bool GLContext::ValidateProgramName(const Uint index) const {
return m_programState.ValidateProgramObject(index);
}
Bool GLContext::ValidateShaderName(const Uint index) const {
return m_programState.ValidateShaderObject(index);
}
const SharedPtr<ProgramObject>& GLContext::GetProgramObject(const Uint index) {
return m_programState.GetProgramObject(index);
}
const SharedPtr<ShaderObject>& GLContext::GetShaderObject(const Uint index) {
return m_programState.GetShaderObject(index);
}
void GLContext::UseProgram(Uint program) {
return m_programState.UseProgram(program);
}
const SharedPtr<ProgramObject>& GLContext::GetCurrentProgram() {
return m_programState.GetCurrentProgram();
}
// RenderState
Uint GLContext::GetRenderStateParametersVersion() const {
return m_renderState.GetVersion();
}
const RenderStateParameters& GLContext::GetRenderStateParameters() const {
return m_renderState.GetAllParameters();
}
void GLContext::SetViewport(IntVec4 viewport) {
m_renderState.SetViewport(viewport);
}
const IntVec4& GLContext::GetViewport() const {
return m_renderState.GetViewport();
}
void GLContext::SetCapability(CapabilityInput cap, Bool enabled) {
m_renderState.SetCapability(cap, enabled);
}
Bool GLContext::IsCapabilityEnabled(CapabilityInput cap) const {
return m_renderState.IsCapabilityEnabled(cap);
}
void GLContext::SetCapabilityIndexed(CapabilityInput cap, Uint index, Bool enabled) {
m_renderState.SetCapabilityIndexed(cap, index, enabled);
}
Bool GLContext::IsCapabilityEnabledIndexed(CapabilityInput cap, Uint index) const {
return m_renderState.IsCapabilityEnabledIndexed(cap, index);
}
void GLContext::SetBlendFunc(BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha,
BlendFactor dstAlpha) {
m_renderState.SetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void GLContext::GetBlendFunc(BlendFactor& srcRGB, BlendFactor& dstRGB, BlendFactor& srcAlpha,
BlendFactor& dstAlpha) const {
m_renderState.GetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void GLContext::SetBlendFuncIndexed(Uint index, BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha,
BlendFactor dstAlpha) {
m_renderState.SetBlendFuncIndexed(index, srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void GLContext::GetBlendFuncIndexed(Uint index, BlendFactor& srcRGB, BlendFactor& dstRGB, BlendFactor& srcAlpha,
BlendFactor& dstAlpha) const {
m_renderState.GetBlendFuncIndexed(index, srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void GLContext::SetDepthFunc(DepthTestFunc func) {
m_renderState.SetDepthFunc(func);
}
DepthTestFunc GLContext::GetDepthFunc() const {
return m_renderState.GetDepthFunc();
}
void GLContext::SetDepthMask(Bool flag) {
m_renderState.SetDepthMask(flag);
}
Bool GLContext::GetDepthMask() const {
return m_renderState.GetDepthMask();
}
void GLContext::SetColorMask(BoolVec4 mask) {
m_renderState.SetColorMask(mask);
}
BoolVec4 GLContext::GetColorMask() const {
return m_renderState.GetColorMask();
}
void GLContext::SetClearColor(FloatVec4 color) {
m_renderState.SetClearColor(color);
}
const FloatVec4& GLContext::GetClearColor() const {
return m_renderState.GetClearColor();
}
void GLContext::SetClearDepth(Float depth) {
m_renderState.SetClearDepth(depth);
}
Float GLContext::GetClearDepth() const {
return m_renderState.GetClearDepth();
}
void GLContext::SetClearStencil(Int stencil) {
m_renderState.SetClearStencil(stencil);
}
Int GLContext::GetClearStencil() const {
return m_renderState.GetClearStencil();
}
void GLContext::SetPixelStoreParam(PixelStoreParam param, Int value) {
m_renderState.SetPixelStoreParam(param, value);
}
Int GLContext::GetPixelStoreParam(PixelStoreParam param) const {
return m_renderState.GetPixelStoreParam(param);
}
PixelStoreParameters GLContext::GetPixelStoreParameters(Bool isUnpack) const {
return m_renderState.GetPixelStoreParameters(isUnpack);
}
void GLContext::SetCullFaceMode(CullFaceMode mode) {
m_renderState.SetCullFaceMode(mode);
}
CullFaceMode GLContext::GetCullFaceMode() const {
return m_renderState.GetCullFaceMode();
}
void GLContext::SetScissorBox(IntVec4 box) {
m_renderState.SetScissorBox(box);
}
const IntVec4& GLContext::GetScissorBox() const {
return m_renderState.GetScissorBox();
}
// Framebuffer
void GLContext::GenFramebufferNames(Uint number, Vector<Uint>& framebuffers) {
m_framebufferState.GenerateNames(number, framebuffers);
}
const SharedPtr<FramebufferObject>& GLContext::GetFramebufferObject(Uint index) {
return m_framebufferState.GetFramebufferObject(index);
}
BindingSlot<FramebufferObject>& GLContext::GetFramebufferBindingSlot(FramebufferTarget target) {
return m_framebufferState.GetBindingSlot(target);
}
const SharedPtr<FramebufferObject>& GLContext::CreateFramebufferObject(Uint index) {
return m_framebufferState.CreateFramebufferObject(index);
}
void GLContext::MarkFramebufferObjectForDeletion(Uint index) {
m_framebufferState.MarkFramebufferObjectForDeletion(index);
}
Bool GLContext::ValidateFramebufferName(Uint index) const {
return m_framebufferState.ValidateName(index);
}
Bool GLContext::ValidateFramebufferObject(Uint index) const {
return m_framebufferState.ValidateFramebufferObject(index);
}
// Sampler
void GLContext::GenSamplerNames(Uint number, Vector<Uint>& samplers) {
m_samplerState.GenerateNames(number, samplers);
}
const SharedPtr<SamplerObject>& GLContext::GetSamplerObject(Uint index) {
return m_samplerState.GetSamplerObject(index);
}
const SharedPtr<SamplerObject>& GLContext::CreateSamplerObject(Uint index) {
return m_samplerState.CreateSamplerObject(index);
}
void GLContext::MarkSamplerObjectForDeletion(Uint index) {
// Unbind the sampler from all texture units
if (ValidateSamplerObject(index)) {
auto sampler = m_samplerState.GetSamplerObject(index);
for (Int unit = 0; unit < TextureState::MAX_TEXTURE_IMAGE_UNITS; ++unit) {
auto& textureUnit = m_textureState.GetUnitObject(unit);
if (textureUnit.GetSamplerObject() == sampler) {
textureUnit.SetSamplerObject(nullptr);
} }
} }
m_samplerState.MarkSamplerObjectForDeletion(index);
} }
m_samplerState.MarkSamplerObjectForDeletion(index);
}
Bool GLContext::ValidateSamplerName(Uint index) const { Bool GLContext::ValidateSamplerName(Uint index) const {
return m_samplerState.ValidateName(index); return m_samplerState.ValidateName(index);
} }
Bool GLContext::ValidateSamplerObject(Uint index) const { Bool GLContext::ValidateSamplerObject(Uint index) const {
return m_samplerState.ValidateSamplerObject(index); return m_samplerState.ValidateSamplerObject(index);
} }
// Renderbuffer // Renderbuffer
Vector<Uint> GLContext::GenRenderbufferNames(Uint number) { void GLContext::GenRenderbufferNames(Uint number, Vector<Uint>& renderbuffers) {
return m_renderbufferState.GenerateNames(number); m_renderbufferState.GenerateNames(number, renderbuffers);
} }
SharedPtr<RenderbufferObject> GLContext::GetRenderbufferObject(Uint index) { const SharedPtr<RenderbufferObject>& GLContext::GetRenderbufferObject(Uint index) {
return m_renderbufferState.GetRenderbufferObject(index); return m_renderbufferState.GetRenderbufferObject(index);
} }
BindingSlot<RenderbufferObject>& GLContext::GetRenderbufferBindingSlot(RenderbufferTarget target) { BindingSlot<RenderbufferObject>& GLContext::GetRenderbufferBindingSlot(RenderbufferTarget target) {
return m_renderbufferState.GetBindingSlot(target); return m_renderbufferState.GetBindingSlot(target);
} }
SharedPtr<RenderbufferObject> GLContext::CreateRenderbufferObject(Uint index) { const SharedPtr<RenderbufferObject>& GLContext::CreateRenderbufferObject(Uint index) {
return m_renderbufferState.CreateRenderbufferObject(index); return m_renderbufferState.CreateRenderbufferObject(index);
} }
void GLContext::MarkRenderbufferObjectForDeletion(Uint index) { void GLContext::MarkRenderbufferObjectForDeletion(Uint index) {
m_renderbufferState.MarkRenderbufferObjectForDeletion(index); m_renderbufferState.MarkRenderbufferObjectForDeletion(index);
} }
Bool GLContext::ValidateRenderbufferName(Uint index) const { Bool GLContext::ValidateRenderbufferName(Uint index) const {
return m_renderbufferState.ValidateName(index); return m_renderbufferState.ValidateName(index);
} }
} // namespace GLState
GLState::GLContext* pGLContext; Bool GLContext::ValidateRenderbufferObject(Uint index) const {
} // namespace MG_State return m_renderbufferState.ValidateRenderbufferObject(index);
} // namespace MobileGL }
} // namespace GLState
UniquePtr<GLState::GLContext> pGLContext;
} // namespace MobileGL::MG_State
+29 -29
View File
@@ -30,42 +30,42 @@ namespace MobileGL {
GLContext() = default; GLContext() = default;
// Error // Error
void RecordError(ErrorCode code, SharedPtr<ErrorInfo> info = nullptr); void RecordError(ErrorCode code, UniquePtr<ErrorInfo> info);
Bool HasGLError() const; Bool HasGLError() const;
Optional<const Error> PeekGLError() const; Optional<const Error*> PeekNonGLError() const;
Optional<Error> PopGLError(); Optional<UniquePtr<Error>> PopNonGLError();
Bool HasNonGLError() const; Bool HasNonGLError() const;
Optional<const Error> PeekNonGLError() const; Optional<const Error*> PeekGLError() const;
Optional<Error> PopNonGLError(); Optional<UniquePtr<Error>> PopGLError();
void ClearErrors(); void ClearErrors();
// Buffer // Buffer
Vector<Uint> GenBufferNames(Uint number); void GenBufferNames(Uint number, Vector<Uint>& buffers);
SharedPtr<BufferObject> GetBufferObject(Uint index); const 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 { constexpr SizeT GetBufferBindingPointCount(BufferTarget target) const {
return m_bufferState.GetBindingPointCount(target); return m_bufferState.GetBindingPointCount(target);
} }
SharedPtr<BufferObject> CreateBufferObject(Uint index); const SharedPtr<BufferObject>& CreateBufferObject(Uint index);
void MarkBufferObjectForDeletion(Uint index); void MarkBufferObjectForDeletion(Uint index);
Bool ValidateBufferName(Uint index) const; Bool ValidateBufferName(Uint index) const;
Bool ValidateBufferObject(Uint index) const; Bool ValidateBufferObject(Uint index) const;
// VertexArray // VertexArray
Vector<Uint> GenVertexArrayNames(Uint number); void GenVertexArrayNames(Uint number, Vector<Uint>& vertexArrays);
SharedPtr<VertexArrayObject> GetVertexArrayObject(Uint index); const SharedPtr<VertexArrayObject>& GetVertexArrayObject(Uint index);
void BindVertexArray(Uint index); void BindVertexArray(Uint index);
SharedPtr<VertexArrayObject> CreateVertexArrayObject(Uint index); const SharedPtr<VertexArrayObject>& CreateVertexArrayObject(Uint index);
void MarkVertexArrayForDeletion(Uint index); void MarkVertexArrayForDeletion(Uint index);
Bool ValidateVertexArrayName(Uint index) const; Bool ValidateVertexArrayName(Uint index) const;
Bool ValidateVertexArrayObject(Uint index) const; Bool ValidateVertexArrayObject(Uint index) const;
SharedPtr<VertexArrayObject> GetBoundVertexArray(); const SharedPtr<VertexArrayObject>& GetBoundVertexArray();
// Texture // Texture
Vector<Uint> GenTextureNames(Uint number); void GenTextureNames(Uint number, Vector<Uint>& textures);
SharedPtr<ITextureObject> GetTextureObject(Uint index); const SharedPtr<ITextureObject>& GetTextureObject(Uint index);
SharedPtr<ITextureObject> CreateTextureObject(Uint index, TextureTarget target); const SharedPtr<ITextureObject>& CreateTextureObject(Uint index, TextureTarget target);
void MarkTextureObjectForDeletion(Uint index); void MarkTextureObjectForDeletion(Uint index);
TextureUnit& GetTextureUnitObject(Int unit); TextureUnit& GetTextureUnitObject(Int unit);
Bool ValidateTextureName(Uint index) const; Bool ValidateTextureName(Uint index) const;
@@ -80,10 +80,10 @@ namespace MobileGL {
void MarkShaderForDeletion(Uint index); void MarkShaderForDeletion(Uint index);
Bool ValidateProgramName(Uint index) const; Bool ValidateProgramName(Uint index) const;
Bool ValidateShaderName(Uint index) const; Bool ValidateShaderName(Uint index) const;
SharedPtr<ProgramObject> GetProgramObject(Uint index); const SharedPtr<ProgramObject>& GetProgramObject(Uint index);
SharedPtr<ShaderObject> GetShaderObject(Uint index); const SharedPtr<ShaderObject>& GetShaderObject(Uint index);
void UseProgram(Uint program); void UseProgram(Uint program);
SharedPtr<ProgramObject> GetCurrentProgram(); const SharedPtr<ProgramObject>& GetCurrentProgram();
// RenderState // RenderState
Uint GetRenderStateParametersVersion() const; Uint GetRenderStateParametersVersion() const;
@@ -106,7 +106,7 @@ namespace MobileGL {
void SetDepthMask(Bool flag); void SetDepthMask(Bool flag);
Bool GetDepthMask() const; Bool GetDepthMask() const;
void SetColorMask(BoolVec4 mask); void SetColorMask(BoolVec4 mask);
const BoolVec4 GetColorMask() const; BoolVec4 GetColorMask() const;
void SetClearColor(FloatVec4 color); void SetClearColor(FloatVec4 color);
const FloatVec4& GetClearColor() const; const FloatVec4& GetClearColor() const;
void SetClearDepth(Float depth); void SetClearDepth(Float depth);
@@ -122,27 +122,27 @@ namespace MobileGL {
const IntVec4& GetScissorBox() const; // x, y, width, height const IntVec4& GetScissorBox() const; // x, y, width, height
// Framebuffer // Framebuffer
Vector<Uint> GenFramebufferNames(Uint number); void GenFramebufferNames(Uint number, Vector<Uint>& framebuffers);
SharedPtr<FramebufferObject> GetFramebufferObject(Uint index); const SharedPtr<FramebufferObject>& GetFramebufferObject(Uint index);
BindingSlot<FramebufferObject>& GetFramebufferBindingSlot(FramebufferTarget target); BindingSlot<FramebufferObject>& GetFramebufferBindingSlot(FramebufferTarget target);
SharedPtr<FramebufferObject> CreateFramebufferObject(Uint index); const SharedPtr<FramebufferObject>& CreateFramebufferObject(Uint index);
void MarkFramebufferObjectForDeletion(Uint index); void MarkFramebufferObjectForDeletion(Uint index);
Bool ValidateFramebufferName(Uint index) const; Bool ValidateFramebufferName(Uint index) const;
Bool ValidateFramebufferObject(Uint index) const; Bool ValidateFramebufferObject(Uint index) const;
// Sampler // Sampler
Vector<Uint> GenSamplerNames(Uint number); void GenSamplerNames(Uint number, Vector<Uint>& samplers);
SharedPtr<SamplerObject> GetSamplerObject(Uint index); const SharedPtr<SamplerObject>& GetSamplerObject(Uint index);
SharedPtr<SamplerObject> CreateSamplerObject(Uint index); const SharedPtr<SamplerObject>& CreateSamplerObject(Uint index);
void MarkSamplerObjectForDeletion(Uint index); void MarkSamplerObjectForDeletion(Uint index);
Bool ValidateSamplerName(Uint index) const; Bool ValidateSamplerName(Uint index) const;
Bool ValidateSamplerObject(Uint index) const; Bool ValidateSamplerObject(Uint index) const;
// Renderbuffer // Renderbuffer
Vector<Uint> GenRenderbufferNames(Uint number); void GenRenderbufferNames(Uint number, Vector<Uint>& renderbuffers);
SharedPtr<RenderbufferObject> GetRenderbufferObject(Uint index); const SharedPtr<RenderbufferObject>& GetRenderbufferObject(Uint index);
BindingSlot<RenderbufferObject>& GetRenderbufferBindingSlot(RenderbufferTarget target); BindingSlot<RenderbufferObject>& GetRenderbufferBindingSlot(RenderbufferTarget target);
SharedPtr<RenderbufferObject> CreateRenderbufferObject(Uint index); const SharedPtr<RenderbufferObject>& CreateRenderbufferObject(Uint index);
void MarkRenderbufferObjectForDeletion(Uint index); void MarkRenderbufferObjectForDeletion(Uint index);
Bool ValidateRenderbufferName(Uint index) const; Bool ValidateRenderbufferName(Uint index) const;
Bool ValidateRenderbufferObject(Uint index) const; Bool ValidateRenderbufferObject(Uint index) const;
@@ -161,6 +161,6 @@ namespace MobileGL {
}; };
} // namespace GLState } // namespace GLState
extern GLState::GLContext* pGLContext; extern UniquePtr<GLState::GLContext> pGLContext;
} // namespace MG_State } // namespace MG_State
} // namespace MobileGL } // namespace MobileGL
+43 -47
View File
@@ -10,57 +10,53 @@
#include <MG_Util/Converters/GLToStr/GLEnumConverter.h> #include <MG_Util/Converters/GLToStr/GLEnumConverter.h>
#include <MG_Util/Converters/MGToGL/ErrorCodeConverter.h> #include <MG_Util/Converters/MGToGL/ErrorCodeConverter.h>
namespace MobileGL { namespace MobileGL::MG_State::GLState {
namespace MG_State { void ErrorState::RecordError(ErrorCode code, UniquePtr<ErrorInfo> info) {
namespace GLState { if (code == ErrorCode::NoError) {
void ErrorState::RecordError(ErrorCode code, SharedPtr<ErrorInfo> info) { MGLOG_E("Recording Non-OpenGL error:\n%s", info->toString().c_str());
if (code == ErrorCode::NoError) { m_nonGLErrors.push_back(MakeUnique<Error>(code, Move(info)));
MGLOG_E("Recording Non-OpenGL error:\n%s", info->ToString().c_str()); } else {
m_nonGLErrors.push_back(Error{code, info}); MGLOG_E("Recording OpenGL error (%s):\n%s",
} else { MG_Util::ConvertGLEnumToString(MG_Util::ConvertErrorCodeToGLEnum(code)).c_str(),
MGLOG_E("Recording OpenGL error (%s):\n%s", info->toString().c_str());
MG_Util::ConvertGLEnumToString(MG_Util::ConvertErrorCodeToGLEnum(code)).c_str(), m_errors.push_back(MakeUnique<Error>(code, Move(info)));
info->ToString().c_str()); }
m_errors.push_back(Error{code, info}); }
}
}
Bool ErrorState::HasNonGLError() const { Bool ErrorState::HasNonGLError() const {
return !m_nonGLErrors.empty(); return !m_nonGLErrors.empty();
} }
Optional<const Error> ErrorState::PeekNonGLError() const { Optional<const Error*> ErrorState::PeekNonGLError() const {
if (m_nonGLErrors.empty()) return Optional<const Error>{}; if (m_nonGLErrors.empty()) return Nullopt;
return Optional<const Error>{m_nonGLErrors.front()}; return Optional<const Error*>{m_nonGLErrors.front().get()};
} }
Optional<Error> ErrorState::PopNonGLError() { Optional<UniquePtr<Error>> ErrorState::PopNonGLError() {
if (m_nonGLErrors.empty()) return Optional<const Error>{}; if (m_nonGLErrors.empty()) return Nullopt;
auto error = Move(m_nonGLErrors.front()); auto error = Move(m_nonGLErrors.front());
m_nonGLErrors.erase(m_nonGLErrors.begin()); m_nonGLErrors.erase(m_nonGLErrors.begin());
return Optional<const Error>{error}; return Move(error);
} }
Bool ErrorState::HasGLError() const { Bool ErrorState::HasGLError() const {
return !m_errors.empty(); return !m_errors.empty();
} }
Optional<const Error> ErrorState::PeekGLError() const { Optional<const Error*> ErrorState::PeekGLError() const {
if (m_errors.empty()) return Optional<const Error>{}; if (m_errors.empty()) return Optional<const Error*>{};
return Optional<const Error>{m_errors.front()}; return Optional<const Error*>{m_errors.front().get()};
} }
Optional<Error> ErrorState::PopGLError() { Optional<UniquePtr<Error>> ErrorState::PopGLError() {
if (m_errors.empty()) return Optional<const Error>{}; if (m_errors.empty()) return Nullopt;
auto error = Move(m_errors.front()); auto error = Move(m_errors.front());
m_errors.erase(m_errors.begin()); m_errors.erase(m_errors.begin());
return Optional<const Error>{error}; return Move(error);
} }
void ErrorState::Clear() { void ErrorState::Clear() {
m_errors.clear(); m_errors.clear();
m_nonGLErrors.clear(); m_nonGLErrors.clear();
} }
} // namespace GLState } // namespace MobileGL::MG_State::GLState
} // namespace MG_State
} // namespace MobileGL
+18 -20
View File
@@ -14,26 +14,24 @@
namespace MobileGL { namespace MobileGL {
struct Error { struct Error {
ErrorCode code; ErrorCode code;
SharedPtr<ErrorInfo> info; UniquePtr<ErrorInfo> info;
}; };
namespace MG_State { namespace MG_State::GLState {
namespace GLState { class ErrorState {
class ErrorState { public:
public: void RecordError(ErrorCode code, UniquePtr<ErrorInfo> info);
void RecordError(ErrorCode code, SharedPtr<ErrorInfo> info = nullptr); Bool HasNonGLError() const;
Bool HasNonGLError() const; Optional<const Error*> PeekNonGLError() const;
Optional<const Error> PeekNonGLError() const; Optional<UniquePtr<Error>> PopNonGLError();
Optional<Error> PopNonGLError(); Bool HasGLError() const;
Bool HasGLError() const; Optional<const Error*> PeekGLError() const;
Optional<const Error> PeekGLError() const; Optional<UniquePtr<Error>> PopGLError();
Optional<Error> PopGLError(); void Clear();
void Clear();
private: private:
Vector<Error> m_errors; Vector<UniquePtr<Error>> m_errors;
Vector<Error> m_nonGLErrors; Vector<UniquePtr<Error>> m_nonGLErrors;
}; };
} // namespace GLState } // namespace MG_State::GLState
} // namespace MG_State } // namespace MobileGL
} // namespace MobileGL
@@ -13,7 +13,7 @@ namespace MobileGL {
class ErrorInfo { class ErrorInfo {
public: public:
virtual ~ErrorInfo() = default; virtual ~ErrorInfo() = default;
virtual String ToString() const = 0; virtual String toString() const = 0;
}; };
class GenericErrorInfo : public ErrorInfo { class GenericErrorInfo : public ErrorInfo {
@@ -24,7 +24,7 @@ namespace MobileGL {
explicit GenericErrorInfo(String m_prefix, String m_prefix_2, String message) explicit GenericErrorInfo(String m_prefix, String m_prefix_2, String message)
: m_message(Move(message)), m_prefix(Move(m_prefix)), m_prefix_2(Move(m_prefix_2)) {} : m_message(Move(message)), m_prefix(Move(m_prefix)), m_prefix_2(Move(m_prefix_2)) {}
String ToString() const override { String toString() const override {
StringStream ss; StringStream ss;
if (m_prefix.has_value()) { if (m_prefix.has_value()) {
ss << "[" << m_prefix.value() << "] "; ss << "[" << m_prefix.value() << "] ";
@@ -9,157 +9,153 @@
#include "FramebufferObject.h" #include "FramebufferObject.h"
#include "MG_Util/Types.h" #include "MG_Util/Types.h"
namespace MobileGL { namespace MobileGL::MG_State::GLState {
namespace MG_State { // FramebufferAttachmentObject
namespace GLState { FramebufferAttachmentObject::FramebufferAttachmentObject(
// FramebufferAttachmentObject const SharedPtr<MG_State::GLState::ITextureObject>& texture, Int level)
FramebufferAttachmentObject::FramebufferAttachmentObject( : m_texture(texture), m_textureLevel(level) {}
SharedPtr<MG_State::GLState::ITextureObject> texture, Int level) FramebufferAttachmentObject::FramebufferAttachmentObject(const SharedPtr<RenderbufferObject>& renderbuffer)
: m_texture(texture), m_textureLevel(level) {} : m_renderbuffer(renderbuffer) {}
FramebufferAttachmentObject::FramebufferAttachmentObject(SharedPtr<RenderbufferObject> renderbuffer) FramebufferAttachmentObject::FramebufferAttachmentObject(Bool IsValid)
: m_renderbuffer(renderbuffer) {} : m_texture(nullptr), m_renderbuffer(nullptr) {
FramebufferAttachmentObject::FramebufferAttachmentObject(Bool IsValid) m_isValid = IsValid;
: m_texture(nullptr), m_renderbuffer(nullptr) { }
m_isValid = IsValid;
}
Bool FramebufferAttachmentObject::IsTexture() const { Bool FramebufferAttachmentObject::IsTexture() const {
return m_texture != nullptr; return m_texture != nullptr;
} }
Bool FramebufferAttachmentObject::IsRenderbuffer() const { Bool FramebufferAttachmentObject::IsRenderbuffer() const {
return m_renderbuffer != nullptr; return m_renderbuffer != nullptr;
} }
Bool FramebufferAttachmentObject::IsEmpty() const { Bool FramebufferAttachmentObject::IsEmpty() const {
return m_texture == nullptr && m_renderbuffer == nullptr; return m_texture == nullptr && m_renderbuffer == nullptr;
} }
SharedPtr<MG_State::GLState::ITextureObject> FramebufferAttachmentObject::GetTexture() const { const SharedPtr<MG_State::GLState::ITextureObject>& FramebufferAttachmentObject::GetTexture() const {
return m_texture; return m_texture;
} }
SharedPtr<RenderbufferObject> FramebufferAttachmentObject::GetRenderbuffer() const { const SharedPtr<RenderbufferObject>& FramebufferAttachmentObject::GetRenderbuffer() const {
return m_renderbuffer; return m_renderbuffer;
} }
Int FramebufferAttachmentObject::GetTextureLevel() const { Int FramebufferAttachmentObject::GetTextureLevel() const {
return m_textureLevel; return m_textureLevel;
} }
Bool FramebufferAttachmentObject::IsComplete() const { Bool FramebufferAttachmentObject::IsComplete() const {
if (IsTexture()) { if (IsTexture()) {
Bool complete = m_texture->IsComplete(); Bool complete = m_texture->IsComplete();
return complete; return complete;
} else if (IsRenderbuffer()) { } else if (IsRenderbuffer()) {
Bool complete = m_renderbuffer->IsAllocated(); Bool complete = m_renderbuffer->IsAllocated();
return complete; return complete;
} }
return false;
}
IntVec3 FramebufferAttachmentObject::GetSize() const {
if (IsTexture()) {
// TODO: get correct upload target
MOBILEGL_ASSERT(nullptr != dynamic_cast<MG_State::GLState::TextureObjectMipmap*>(m_texture.get()),
"Texture object here should always be an object with mipmap");
auto textureMipmapObject = dynamic_cast<MG_State::GLState::TextureObjectMipmap*>(m_texture.get());
return textureMipmapObject->GetMipmapTexelSize(TextureUploadTarget::Texture2D, m_textureLevel);
} else if (IsRenderbuffer()) {
return {m_renderbuffer->GetWidth(), m_renderbuffer->GetHeight(), 1};
}
return {0, 0, 0};
}
Bool FramebufferAttachmentObject::IsValid() const {
return m_isValid;
}
// FramebufferObject
FramebufferObject::FramebufferObject(Uint externalIndex)
: m_externalIndex(externalIndex), m_attachmentVersions{}, m_drawBuffers{} {
m_attachmentObjects.fill(FramebufferAttachmentObject(false));
m_drawBuffers.fill(FramebufferAttachmentType::None);
m_drawBuffers[0] = FramebufferAttachmentType::Color0;
m_attachmentVersions.fill(0);
}
void FramebufferObject::AttachTexture(FramebufferAttachmentType type, const SharedPtr<ITextureObject>& texture,
int level) {
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(texture, level);
BumpAttachmentVersion(type);
}
void FramebufferObject::AttachRenderbuffer(FramebufferAttachmentType type,
const SharedPtr<RenderbufferObject>& renderbuffer) {
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(renderbuffer);
BumpAttachmentVersion(type);
}
void FramebufferObject::Detach(FramebufferAttachmentType type) {
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(false);
BumpAttachmentVersion(type);
}
const FramebufferAttachmentObject& FramebufferObject::GetAttachment(FramebufferAttachmentType type) const {
return m_attachmentObjects[static_cast<SizeT>(type)];
}
const FramebufferObject::FramebufferAttachmentObjectArray& FramebufferObject::GetAllAttachmentObjects() const {
return m_attachmentObjects;
}
Bool FramebufferObject::CheckCompleteness() const {
if (m_attachmentObjects.empty()) {
return false;
}
Int width = -1, height = -1;
Int validAttachmentCount = 0;
for (const auto& attachmentObject : m_attachmentObjects) {
if (!attachmentObject.IsValid()) continue;
++validAttachmentCount;
const auto& attachment = attachmentObject;
auto attachmentSize = attachment.GetSize();
Int w = attachmentSize.x();
Int h = attachmentSize.y();
if (width == -1) {
width = w;
height = h;
} else if (width != w || height != h) {
return false; return false;
} }
IntVec3 FramebufferAttachmentObject::GetSize() const { if (!attachment.IsComplete()) {
if (IsTexture()) { return false;
// TODO: get correct upload target
MOBILEGL_ASSERT(nullptr != dynamic_cast<MG_State::GLState::TextureObjectMipmap*>(m_texture.get()),
"Texture object here should always be an object with mipmap");
auto textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(m_texture.get());
return textureMipmapObject->GetMipmapTexelSize(TextureUploadTarget::Texture2D, m_textureLevel);
} else if (IsRenderbuffer()) {
return IntVec3(m_renderbuffer->GetWidth(), m_renderbuffer->GetHeight(), 1);
}
return {0, 0, 0};
} }
}
Bool FramebufferAttachmentObject::IsValid() const { if (validAttachmentCount == 0) return false;
return m_isValid; return true;
} }
// FramebufferObject void FramebufferObject::SetDrawBuffer(Uint index, FramebufferAttachmentType buffer) {
FramebufferObject::FramebufferObject(Uint externalIndex) : m_externalIndex(externalIndex) { if (m_drawBuffers[index] == buffer) return;
m_attachmentObjects.fill(FramebufferAttachmentObject(false)); m_drawBuffers[index] = buffer;
m_drawBuffers.fill(FramebufferAttachmentType::None); BumpAttachmentVersion(buffer);
m_drawBuffers[0] = FramebufferAttachmentType::Color0; }
m_attachmentVersions.fill(0);
}
void FramebufferObject::AttachTexture(FramebufferAttachmentType type, SharedPtr<ITextureObject> texture, const FramebufferObject::FramebufferAttachmentArray& FramebufferObject::GetDrawBuffers() const {
int level) { return m_drawBuffers;
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(std::move(texture), level); }
BumpAttachmentVersion(type);
}
void FramebufferObject::AttachRenderbuffer(FramebufferAttachmentType type, Uint FramebufferObject::GetExternalIndex() const {
std::shared_ptr<RenderbufferObject> renderbuffer) { return m_externalIndex;
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(renderbuffer); }
BumpAttachmentVersion(type);
}
void FramebufferObject::Detach(FramebufferAttachmentType type) { void FramebufferObject::BumpAttachmentVersion(FramebufferAttachmentType type) {
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(false); ++m_attachmentVersions[static_cast<SizeT>(type)];
BumpAttachmentVersion(type); ++m_objectVersion;
} }
} // namespace MobileGL::MG_State::GLState
const FramebufferAttachmentObject& FramebufferObject::GetAttachment(FramebufferAttachmentType type) const {
return m_attachmentObjects[static_cast<SizeT>(type)];
}
const FramebufferObject::FramebufferAttachmentObjectArray& FramebufferObject::GetAllAttachmentObjects()
const {
return m_attachmentObjects;
}
Bool FramebufferObject::CheckCompleteness() const {
if (m_attachmentObjects.empty()) {
return false;
}
Int width = -1, height = -1;
Int validAttachmentCount = 0;
for (SizeT i = 0; i < m_attachmentObjects.size(); ++i) {
if (!m_attachmentObjects[i].IsValid()) continue;
++validAttachmentCount;
const auto& attachment = m_attachmentObjects[i];
auto attachmentSize = attachment.GetSize();
Int w = attachmentSize.x();
Int h = attachmentSize.y();
if (width == -1) {
width = w;
height = h;
} else if (width != w || height != h) {
return false;
}
if (!attachment.IsComplete()) {
return false;
}
}
if (validAttachmentCount == 0) return false;
return true;
}
void FramebufferObject::SetDrawBuffer(Uint index, FramebufferAttachmentType buffer) {
if (m_drawBuffers[index] == buffer) return;
m_drawBuffers[index] = buffer;
BumpAttachmentVersion(buffer);
}
const FramebufferObject::FramebufferAttachmentArray& FramebufferObject::GetDrawBuffers() const {
return m_drawBuffers;
}
Uint FramebufferObject::GetExternalIndex() const {
return m_externalIndex;
}
void FramebufferObject::BumpAttachmentVersion(FramebufferAttachmentType type) {
++m_attachmentVersions[static_cast<SizeT>(type)];
++m_objectVersion;
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
@@ -7,6 +7,7 @@
// End of Source File Header // End of Source File Header
#pragma once #pragma once
#include "MG_Util/Types.h"
#include <Includes.h> #include <Includes.h>
#include <MG_State/GLState/TextureState/TextureObject.h> #include <MG_State/GLState/TextureState/TextureObject.h>
#include <MG_State/GLState/RenderbufferState/RenderbufferObject.h> #include <MG_State/GLState/RenderbufferState/RenderbufferObject.h>
@@ -67,81 +68,78 @@ namespace MobileGL {
Unknown = -1 Unknown = -1
}; };
namespace MG_State { namespace MG_State::GLState {
namespace GLState { class FramebufferAttachmentObject {
class FramebufferAttachmentObject { public:
public: explicit FramebufferAttachmentObject(const SharedPtr<MG_State::GLState::ITextureObject>& texture,
explicit FramebufferAttachmentObject(SharedPtr<MG_State::GLState::ITextureObject> texture, Int level = 0);
Int level = 0); explicit FramebufferAttachmentObject(const SharedPtr<RenderbufferObject>& renderbuffer);
explicit FramebufferAttachmentObject(SharedPtr<RenderbufferObject> renderbuffer); explicit FramebufferAttachmentObject(Bool IsValid = true);
explicit FramebufferAttachmentObject(Bool IsValid = true);
Bool IsTexture() const; Bool IsTexture() const;
Bool IsRenderbuffer() const; Bool IsRenderbuffer() const;
Bool IsEmpty() const; Bool IsEmpty() const;
SharedPtr<MG_State::GLState::ITextureObject> GetTexture() const; const SharedPtr<MG_State::GLState::ITextureObject>& GetTexture() const;
SharedPtr<RenderbufferObject> GetRenderbuffer() const; const SharedPtr<RenderbufferObject>& GetRenderbuffer() const;
Int GetTextureLevel() const; Int GetTextureLevel() const;
Bool IsComplete() const; Bool IsComplete() const;
IntVec3 GetSize() const; IntVec3 GetSize() const;
Bool IsValid() const; Bool IsValid() const;
private: private:
SharedPtr<MG_State::GLState::ITextureObject> m_texture = nullptr; SharedPtr<MG_State::GLState::ITextureObject> m_texture = nullptr;
SharedPtr<RenderbufferObject> m_renderbuffer = nullptr; SharedPtr<RenderbufferObject> m_renderbuffer = nullptr;
Int m_textureLevel = 0; Int m_textureLevel = 0;
Bool m_isValid = true; Bool m_isValid = true;
}; };
class FramebufferObject { class FramebufferObject {
public: public:
static constexpr Uint MAX_DRAW_BUFFERS = 8; static constexpr Uint MAX_DRAW_BUFFERS = 8;
using TargetEnum = FramebufferTarget; using TargetEnum = FramebufferTarget;
using FramebufferAttachmentObjectArray = using FramebufferAttachmentObjectArray =
Array<FramebufferAttachmentObject, Array<FramebufferAttachmentObject,
static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>; static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>;
using FramebufferAttachmentArray = Array<FramebufferAttachmentType, MAX_DRAW_BUFFERS>; using FramebufferAttachmentArray = Array<FramebufferAttachmentType, MAX_DRAW_BUFFERS>;
using FramebufferAttachmentVersionArray = using FramebufferAttachmentVersionArray =
Array<Uint16, static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>; Array<Uint16, static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>;
FramebufferObject(Uint externalIndex); FramebufferObject(Uint externalIndex);
void AttachTexture(FramebufferAttachmentType type, SharedPtr<ITextureObject> texture, int level = 0); void AttachTexture(FramebufferAttachmentType type, const SharedPtr<ITextureObject>& texture, int level = 0);
void AttachRenderbuffer(FramebufferAttachmentType type, void AttachRenderbuffer(FramebufferAttachmentType type, const SharedPtr<RenderbufferObject>& renderbuffer);
std::shared_ptr<RenderbufferObject> renderbuffer); void Detach(FramebufferAttachmentType type);
void Detach(FramebufferAttachmentType type); const FramebufferAttachmentObject& GetAttachment(FramebufferAttachmentType type) const;
const FramebufferAttachmentObject& GetAttachment(FramebufferAttachmentType type) const; const FramebufferAttachmentObjectArray& GetAllAttachmentObjects() const;
const FramebufferAttachmentObjectArray& GetAllAttachmentObjects() const; Bool CheckCompleteness() const;
Bool CheckCompleteness() const; // aka. `buffer` as in glDrawBuffers/glReadBuffers
// aka. `buffer` as in glDrawBuffers/glReadBuffers void SetDrawBuffer(Uint index, FramebufferAttachmentType buffer);
void SetDrawBuffer(Uint index, FramebufferAttachmentType buffer); const FramebufferAttachmentArray& GetDrawBuffers() const;
const FramebufferAttachmentArray& GetDrawBuffers() const; void SetReadBuffer(FramebufferAttachmentType buf) { m_readBuffer = buf; }
void SetReadBuffer(FramebufferAttachmentType buf) { m_readBuffer = buf; } FramebufferAttachmentType GetReadBuffer() const { return m_readBuffer; }
FramebufferAttachmentType GetReadBuffer() const { return m_readBuffer; }
const FramebufferAttachmentVersionArray GetAllFramebufferAttachmentVersions() const { FramebufferAttachmentVersionArray GetAllFramebufferAttachmentVersions() const {
return m_attachmentVersions; return m_attachmentVersions;
} }
Uint16 GetObjectVersion() const { return m_objectVersion; } Uint16 GetObjectVersion() const { return m_objectVersion; }
Uint GetExternalIndex() const; Uint GetExternalIndex() const;
private: private:
void BumpAttachmentVersion(FramebufferAttachmentType type); void BumpAttachmentVersion(FramebufferAttachmentType type);
const Uint m_externalIndex = 0; const Uint m_externalIndex = 0;
FramebufferAttachmentObjectArray m_attachmentObjects; FramebufferAttachmentObjectArray m_attachmentObjects;
FramebufferAttachmentVersionArray m_attachmentVersions; FramebufferAttachmentVersionArray m_attachmentVersions;
FramebufferAttachmentArray m_drawBuffers; // Probably no versioning needed for this, just check equality FramebufferAttachmentArray m_drawBuffers; // Probably no versioning needed for this, just check equality
FramebufferAttachmentType m_readBuffer = FramebufferAttachmentType::Color0; // ditto FramebufferAttachmentType m_readBuffer = FramebufferAttachmentType::Color0; // ditto
// This version will bump when draw/read buffer changes (by `glDrawBuffer(s)`/`glReadBuffer`) // This version will bump when draw/read buffer changes (by `glDrawBuffer(s)`/`glReadBuffer`)
Uint16 m_objectVersion = 0; Uint16 m_objectVersion = 0;
}; };
} // namespace GLState } // namespace MG_State::GLState
} // namespace MG_State
} // namespace MobileGL } // namespace MobileGL
@@ -9,74 +9,73 @@
#include "FramebufferState.h" #include "FramebufferState.h"
#include "MG_State/GLState/FramebufferState/FramebufferObject.h" #include "MG_State/GLState/FramebufferState/FramebufferObject.h"
namespace MobileGL { namespace MobileGL::MG_State::GLState {
namespace MG_State { FramebufferState::FramebufferState() {
namespace GLState { for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
FramebufferState::FramebufferState() { m_bindingSlots[i] = BindingSlot<FramebufferObject>(static_cast<FramebufferTarget>(i));
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) { }
m_bindingSlots[i] = BindingSlot<FramebufferObject>(static_cast<FramebufferTarget>(i)); }
}
}
SharedPtr<FramebufferObject> FramebufferState::GetFramebufferObject(Uint index) { const SharedPtr<FramebufferObject>& FramebufferState::GetFramebufferObject(Uint index) {
auto it = m_framebufferObjects.find(index); auto it = m_framebufferObjects.find(index);
if (it != m_framebufferObjects.end()) { if (it != m_framebufferObjects.end()) {
return it->second; return it->second;
} }
return nullptr; static SharedPtr<FramebufferObject> nullFramebufferObject = nullptr;
} return nullFramebufferObject;
}
Vector<Uint> FramebufferState::GenerateNames(Uint number) { void FramebufferState::GenerateNames(Uint number, Vector<Uint>& buffers) {
Vector<Uint> buffers(number); buffers.resize(number);
m_indexGenerator.Generate(number, buffers.data()); m_indexGenerator.Generate(number, buffers.data());
return buffers; }
}
SharedPtr<FramebufferObject> FramebufferState::CreateFramebufferObject(Uint index) { const SharedPtr<FramebufferObject>& FramebufferState::CreateFramebufferObject(Uint index) {
if (index == 0) { if (index == 0) {
if (!m_indexGenerator.IsValid(0)) { if (!m_indexGenerator.IsValid(0)) {
m_indexGenerator.Insert(0); m_indexGenerator.Insert(0);
} else { } else {
return nullptr; static SharedPtr<FramebufferObject> nullFramebufferObject = nullptr;
return nullFramebufferObject;
}
}
auto& framebufferObject = m_framebufferObjects[index];
if (!framebufferObject) {
framebufferObject = MakeShared<FramebufferObject>(index);
}
return framebufferObject;
}
BindingSlot<FramebufferObject>& FramebufferState::GetBindingSlot(FramebufferTarget target) {
for (auto& bindingSlot : m_bindingSlots) {
if (bindingSlot.GetTarget() == target) {
return bindingSlot;
}
}
MOBILEGL_ASSERT(false, "Invalid FramebufferTarget enum value: %d", static_cast<int>(target));
return m_bindingSlots[0];
}
void FramebufferState::MarkFramebufferObjectForDeletion(Uint index) {
if (m_indexGenerator.IsValid(index)) {
auto it = m_framebufferObjects.find(index);
if (it != m_framebufferObjects.end()) {
for (auto& bindingSlot : m_bindingSlots) {
if (bindingSlot.GetBoundObject() == it->second) {
bindingSlot.Bind(nullptr);
} }
} }
auto bufferObject = MakeShared<FramebufferObject>(index); m_framebufferObjects.erase(it);
m_framebufferObjects[index] = bufferObject;
return bufferObject;
} }
m_indexGenerator.Delete(index);
}
}
BindingSlot<FramebufferObject>& FramebufferState::GetBindingSlot(FramebufferTarget target) { Bool FramebufferState::ValidateName(Uint index) const {
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) { return m_indexGenerator.IsValid(index);
if (m_bindingSlots[i].GetTarget() == target) { }
return m_bindingSlots[i];
}
}
MOBILEGL_ASSERT(false, "Invalid FramebufferTarget enum value: %d", static_cast<int>(target));
return m_bindingSlots[0];
}
void FramebufferState::MarkFramebufferObjectForDeletion(Uint index) { Bool FramebufferState::ValidateFramebufferObject(Uint index) const {
if (m_indexGenerator.IsValid(index)) { return m_framebufferObjects.find(index) != m_framebufferObjects.end();
auto it = m_framebufferObjects.find(index); }
if (it != m_framebufferObjects.end()) { } // namespace MobileGL::MG_State::GLState
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
if (m_bindingSlots[i].GetBoundObject() == it->second) {
m_bindingSlots[i].Bind(nullptr);
}
}
m_framebufferObjects.erase(it);
}
m_indexGenerator.Delete(index);
}
}
Bool FramebufferState::ValidateName(Uint index) const {
return m_indexGenerator.IsValid(index);
}
Bool FramebufferState::ValidateFramebufferObject(Uint index) const {
return m_framebufferObjects.find(index) != m_framebufferObjects.end();
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
@@ -11,28 +11,24 @@
#include <MG_Util/Miscellany/IndexGenerator.h> #include <MG_Util/Miscellany/IndexGenerator.h>
#include "FramebufferObject.h" #include "FramebufferObject.h"
namespace MobileGL { namespace MobileGL::MG_State::GLState {
namespace MG_State { class FramebufferState {
namespace GLState { public:
class FramebufferState { FramebufferState();
public:
FramebufferState();
// FBO 0 should be created by MG_Backend when initializing the context // FBO 0 should be created by MG_Backend when initializing the context
SharedPtr<FramebufferObject> GetFramebufferObject(Uint index); const SharedPtr<FramebufferObject>& GetFramebufferObject(Uint index);
Vector<Uint> GenerateNames(Uint number); void GenerateNames(Uint number, Vector<Uint>& framebuffers);
SharedPtr<FramebufferObject> CreateFramebufferObject(Uint index); const SharedPtr<FramebufferObject>& CreateFramebufferObject(Uint index);
BindingSlot<FramebufferObject>& GetBindingSlot(FramebufferTarget target); BindingSlot<FramebufferObject>& GetBindingSlot(FramebufferTarget target);
void MarkFramebufferObjectForDeletion(Uint index); void MarkFramebufferObjectForDeletion(Uint index);
Bool ValidateName(Uint index) const; Bool ValidateName(Uint index) const;
Bool ValidateFramebufferObject(Uint index) const; Bool ValidateFramebufferObject(Uint index) const;
private: private:
UnorderedMap<Uint, SharedPtr<FramebufferObject>> m_framebufferObjects; UnorderedMap<Uint, SharedPtr<FramebufferObject>> m_framebufferObjects;
IndexGenerator<Uint> m_indexGenerator; IndexGenerator<Uint> m_indexGenerator;
Array<BindingSlot<FramebufferObject>, static_cast<SizeT>(FramebufferTarget::FramebufferTargetCount)> Array<BindingSlot<FramebufferObject>, static_cast<SizeT>(FramebufferTarget::FramebufferTargetCount)>
m_bindingSlots; m_bindingSlots;
}; };
} // namespace GLState } // namespace MobileGL::MG_State::GLState
} // namespace MG_State
} // namespace MobileGL
File diff suppressed because it is too large Load Diff
@@ -9,180 +9,176 @@
#pragma once #pragma once
#include <Includes.h> #include <Includes.h>
#include "ShaderObject.h" #include "ShaderObject.h"
#include "MG_Util/Metrics/BufferMetrics.h"
#include "MG_Util/ShaderTranspiler/SpvcSession.h"
namespace MobileGL { #include <MG_Util/Metrics/BufferMetrics.h>
namespace MG_State { #include <MG_Util/ShaderTranspiler/SpvcSession.h>
namespace GLState {
class ProgramObject {
public:
ProgramObject(Uint externalIndex) : m_externalIndex(externalIndex) {}
bool ShaderIsAttached(SharedPtr<ShaderObject> shader);
bool AttachShader(SharedPtr<ShaderObject> shader);
SizeT DetachShader(SharedPtr<ShaderObject> shader);
SizeT RemoveShader(SharedPtr<ShaderObject> shader);
void Link(Bool addDefaultFSIfMissingForRenderingPipelineProgram = false);
void MarkAsDeleted();
void SetExplicitVertexInLocation(Uint index, const char* name); namespace MobileGL::MG_State::GLState {
void SetExplicitFragmentOutLocation(Uint index, const char* name); class ProgramObject {
Int GetFragmentDataLocation(const char* name); public:
ProgramObject(Uint externalIndex) : m_externalIndex(externalIndex) {}
bool ShaderIsAttached(const SharedPtr<ShaderObject>& shader);
bool AttachShader(const SharedPtr<ShaderObject>& shader);
SizeT DetachShader(const SharedPtr<ShaderObject>& shader);
SizeT RemoveShader(const SharedPtr<ShaderObject>& shader);
void Link(Bool addDefaultFSIfMissingForRenderingPipelineProgram = false);
void MarkAsDeleted();
Vector<SharedPtr<ShaderObject>>& GetAttachedShaders(); void SetExplicitVertexInLocation(Uint index, const char* name);
const Vector<SharedPtr<ShaderObject>>& GetAttachedShaders() const; void SetExplicitFragmentOutLocation(Uint index, const char* name);
const String& GetInfoLog() const { return m_infoLog; } Int GetFragmentDataLocation(const char* name);
Int GetUniformMaxLength() const { return m_uniformNameMaxLength; }
Uint GetUniformCount() { return m_activeUniformCount; }
Uint GetMaxUniformLocation() const { return m_maxUniformLocation; }
Int GetUniformLocation(const String& name) const {
const auto it = m_uniformLocations.find(name);
if (it == m_uniformLocations.end()) return -1;
return (Int)it->second;
}
GLenum GetUniformType(Uint location) const { Vector<SharedPtr<ShaderObject>>& GetAttachedShaders();
auto& uniform = m_program->getUniform(m_uniformIndexInTProgram[location]); const Vector<SharedPtr<ShaderObject>>& GetAttachedShaders() const;
return uniform.glDefineType; const String& GetInfoLog() const { return m_infoLog; }
} Int GetUniformMaxLength() const { return m_uniformNameMaxLength; }
Uint GetUniformCount() const { return m_activeUniformCount; }
Uint GetMaxUniformLocation() const { return m_maxUniformLocation; }
Int GetUniformLocation(const String& name) const {
const auto it = m_uniformLocations.find(name);
if (it == m_uniformLocations.end()) return -1;
return (Int)it->second;
}
const glslang::TType* GetUniformTType(Uint location) const { GLenum GetUniformType(Uint location) const {
auto& uniform = m_program->getUniform(m_uniformIndexInTProgram[location]); auto& uniform = m_program->getUniform(m_uniformIndexInTProgram[location]);
return uniform.getType(); return uniform.glDefineType;
} }
Bool IsUniformOpaqueAtLocation(Uint location) const { return GetUniformTType(location)->isOpaque(); } const glslang::TType* GetUniformTType(Uint location) const {
auto& uniform = m_program->getUniform(m_uniformIndexInTProgram[location]);
return uniform.getType();
}
const String& GetUniformName(Uint location) const { Bool IsUniformOpaqueAtLocation(Uint location) const { return GetUniformTType(location)->isOpaque(); }
auto& uniform = m_program->getUniform(m_uniformIndexInTProgram[location]);
return uniform.name;
}
Uint GetUniformOffset(Uint location) const { return m_uniformOffsets[location]; }
Uint GetUniformSizesInBytes(Uint location) const {
return MG_Util::GetGLTypeSize(GetUniformType(location));
}
Int GetAttributeLocation(const String& name) { const String& GetUniformName(Uint location) const {
const auto it = std::find(m_attribs.begin(), m_attribs.end(), name); auto& uniform = m_program->getUniform(m_uniformIndexInTProgram[location]);
return (it == m_attribs.end()) ? -1 : std::distance(m_attribs.begin(), it); return uniform.name;
} }
GLenum GetAttribType(Uint index) const { return m_attribTypes[index]; } Uint GetUniformOffset(Uint location) const { return m_uniformOffsets[location]; }
const String& GetAttribName(Uint index) const { return m_attribs[index]; } Uint GetUniformSizesInBytes(Uint location) const { return MG_Util::GetGLTypeSize(GetUniformType(location)); }
void* MapUBO() { return m_uboScratch.data(); }
const void* GetUBOData() const { return m_uboScratch.data(); }
Uint GetUBOSize() const { return static_cast<Uint>(m_uboScratch.size()); }
void SetUniformSamplerOrImageUnitIndex(Uint location, Int unit) { Int GetAttributeLocation(const String& name) {
m_uniformSamplerOrImageUnitIndex[location] = unit; const auto it = std::find(m_attribs.begin(), m_attribs.end(), name);
} return (it == m_attribs.end()) ? -1 : (Int)std::distance(m_attribs.begin(), it);
}
GLenum GetAttribType(Uint index) const { return m_attribTypes[index]; }
const String& GetAttribName(Uint index) const { return m_attribs[index]; }
void* MapUBO() { return m_uboScratch.data(); }
const void* GetUBOData() const { return m_uboScratch.data(); }
Uint GetUBOSize() const { return static_cast<Uint>(m_uboScratch.size()); }
Int GetUniformSamplerOrImageUnitIndex(Uint location) const { void SetUniformSamplerOrImageUnitIndex(Uint location, Int unit) {
return m_uniformSamplerOrImageUnitIndex[location]; m_uniformSamplerOrImageUnitIndex[location] = unit;
} }
Bool GetDeleteStatus() const { return m_deleteStatus; } Int GetUniformSamplerOrImageUnitIndex(Uint location) const {
Bool GetLinkStatus() const { return m_linkStatus; } return m_uniformSamplerOrImageUnitIndex[location];
Bool GetValidateStatus() const { return m_validateStatus; } }
Int GetActiveAtomicCounterCount() const { return m_program->getNumAtomicCounters(); }
Int GetActiveAttributesCount() const { return m_program->getNumPipeInputs(); }
Int GetActiveUniformBlocksCount() const { return m_program->getNumUniformBlocks(); }
Int GetActiveAttributesMaxLength() const { return m_attribInNameMaxLength; }
Int GetActiveUniformBlocksMaxNameLength() const { return m_uniformBlockNameMaxLength; }
Uint GetUniformBlockIndex(const char* name) const {
auto it = m_uniformBlockIndexByName.find(name);
if (it != m_uniformBlockIndexByName.end()) return it->second;
return 0xFFFFFFFFu; // GL_INVALID_INDEX
}
Bool IsActiveUniformBlock(Uint index) const {
if (index >= GetActiveUniformBlocksCount()) return false;
return true;
}
Uint GetUBOSizeAt(Uint index) const {
if (!IsActiveUniformBlock(index)) return 0;
return m_program->getUniformBlock(index).size;
}
const String& GetUniformBlockName(Uint index) const { Bool GetDeleteStatus() const { return m_deleteStatus; }
auto& ubo = m_program->getUniformBlock(index); Bool GetLinkStatus() const { return m_linkStatus; }
return ubo.name; Bool GetValidateStatus() const { return m_validateStatus; }
} Int GetActiveAtomicCounterCount() const { return m_program->getNumAtomicCounters(); }
Int GetActiveAttributesCount() const { return m_program->getNumPipeInputs(); }
Int GetActiveUniformBlocksCount() const { return m_program->getNumUniformBlocks(); }
Int GetActiveAttributesMaxLength() const { return m_attribInNameMaxLength; }
Int GetActiveUniformBlocksMaxNameLength() const { return m_uniformBlockNameMaxLength; }
Uint GetUniformBlockIndex(const char* name) const {
auto it = m_uniformBlockIndexByName.find(name);
if (it != m_uniformBlockIndexByName.end()) return it->second;
return 0xFFFFFFFFu; // GL_INVALID_INDEX
}
Bool IsActiveUniformBlock(Uint index) const {
if (index >= GetActiveUniformBlocksCount()) return false;
return true;
}
Uint GetUBOSizeAt(Uint index) const {
if (!IsActiveUniformBlock(index)) return 0;
return m_program->getUniformBlock((Int)index).size;
}
// Set by glUniformBlockBinding const String& GetUniformBlockName(Uint index) const {
void SetUniformBlockBinding(Uint index, Uint binding) { m_uniformBlockBinding[index] = binding; } auto& ubo = m_program->getUniformBlock((Int)index);
return ubo.name;
}
Uint GetUniformBlockBinding(Uint index) const { return m_uniformBlockBinding[index]; } // Set by glUniformBlockBinding
void SetUniformBlockBinding(Uint index, Uint binding) { m_uniformBlockBinding[index] = (Int)binding; }
Vector<Vector<unsigned>>& GetGeneratedSpirv() { return m_generatedSpirv; } Uint GetUniformBlockBinding(Uint index) const { return m_uniformBlockBinding[index]; }
const Vector<Vector<unsigned>>& GetGeneratedSpirv() const { return m_generatedSpirv; }
Int GetShaderIndexByStage(ShaderStage stage) const { Vector<Vector<unsigned>>& GetGeneratedSpirv() { return m_generatedSpirv; }
auto it = std::find_if(m_shaders.begin(), m_shaders.end(), const Vector<Vector<unsigned>>& GetGeneratedSpirv() const { return m_generatedSpirv; }
[stage](const SharedPtr<ShaderObject>& shader) { return shader->GetShaderStage() == stage; });
return it == m_shaders.end() ? -1 : std::distance(m_shaders.begin(), it);
}
Uint GetExternalIndex() const { return m_externalIndex; } Int GetShaderIndexByStage(ShaderStage stage) const {
auto it = std::find_if(m_shaders.begin(), m_shaders.end(), [stage](const SharedPtr<ShaderObject>& shader) {
return shader->GetShaderStage() == stage;
});
return it == m_shaders.end() ? -1 : (Int)std::distance(m_shaders.begin(), it);
}
// const UnorderedMap<String, Uint>& GetAttribLocationMap() const { return Uint GetExternalIndex() const { return m_externalIndex; }
// m_attribLocation; }
private: // const UnorderedMap<String, Uint>& GetAttribLocationMap() const { return
void DoReflection(); // m_attribLocation; }
void GenerateBinary();
void WaitUntilGenerationCompleted();
void AddDefaultFragmentShaderIfMissing();
const Uint m_externalIndex = 0; private:
Vector<SharedPtr<ShaderObject>> m_shaders; void DoReflection();
Vector<SharedPtr<ShaderObject>> m_detachedShaders; // Store detached shaders and remove on next link void GenerateBinary();
void WaitUntilGenerationCompleted() const;
void AddDefaultFragmentShaderIfMissing();
SharedPtr<glslang::TProgram> m_program; const Uint m_externalIndex = 0;
Vector<SharedPtr<ShaderObject>> m_shaders;
Vector<SharedPtr<ShaderObject>> m_detachedShaders; // Store detached shaders and remove on next link
Vector<Vector<unsigned>> m_generatedSpirv; SharedPtr<glslang::TProgram> m_program;
// Attributes (Vertex in) Vector<Vector<unsigned>> m_generatedSpirv;
UnorderedMap<String, Uint> m_explicitAttribLocations;
Vector<String> m_attribs;
Vector<GLenum> m_attribTypes;
// For SpvcSession::SetVertexAttribLocation()
// UnorderedMap<String, Uint> m_attribLocation;
// FragData (Frag out) // Attributes (Vertex in)
UnorderedMap<String, Uint> m_explicitFragDataLocation; UnorderedMap<String, Uint> m_explicitAttribLocations;
Vector<String> m_attribs;
Vector<GLenum> m_attribTypes;
// For SpvcSession::SetVertexAttribLocation()
// UnorderedMap<String, Uint> m_attribLocation;
// Uniforms // FragData (Frag out)
UnorderedMap<String, Uint> m_uniformLocations; UnorderedMap<String, Uint> m_explicitFragDataLocation;
// Ordered by location,
// aka. m_uniformIndexInTProgram[loc] == "uniform index of TProgram at location `loc`"
Vector<Int> m_uniformIndexInTProgram;
// ditto. Will be set at glUniform1i
Vector<Int> m_uniformSamplerOrImageUnitIndex;
// Ordered by uniform block index // Uniforms
// index is DIFFERENT from binding!!! UnorderedMap<String, Uint> m_uniformLocations;
// // Ordered by location,
// Let's define UniformBlockIndex == the order at glslang getUniformBlock() // aka. m_uniformIndexInTProgram[loc] == "uniform index of TProgram at location `loc`"
// aka `i = glGetUniformBlockIndex(prog, "BlockName")` implies: Vector<Int> m_uniformIndexInTProgram;
// `prog->getUniformBlock(i) == "BlockName"` // ditto. Will be set at glUniform1i
UnorderedMap<String, Uint> m_uniformBlockIndexByName; Vector<Int> m_uniformSamplerOrImageUnitIndex;
Vector<Int> m_uniformBlockBinding;
// Need to be reflected after linking of SPIR-V binary // Ordered by uniform block index
Vector<Uint> m_uniformOffsets; // index is DIFFERENT from binding!!!
Vector<Uint> m_uniformSizesInBytes; //
Vector<Uint8> m_uboScratch; // Let's define UniformBlockIndex == the order at glslang getUniformBlock()
// aka `i = glGetUniformBlockIndex(prog, "BlockName")` implies:
// `prog->getUniformBlock(i) == "BlockName"`
UnorderedMap<String, Uint> m_uniformBlockIndexByName;
Vector<Int> m_uniformBlockBinding;
Uint m_activeUniformCount = 0; // Need to be reflected after linking of SPIR-V binary
Uint m_maxUniformLocation = 0; Vector<Uint> m_uniformOffsets;
Int m_uniformNameMaxLength = 0; Vector<Uint> m_uniformSizesInBytes;
Int m_attribInNameMaxLength = 0; Vector<Uint8> m_uboScratch;
Int m_uniformBlockNameMaxLength = 0;
String m_infoLog; Uint m_activeUniformCount = 0;
Bool m_deleteStatus = false; Uint m_maxUniformLocation = 0;
Bool m_linkStatus = false; Int m_uniformNameMaxLength = 0;
Bool m_validateStatus = true; Int m_attribInNameMaxLength = 0;
}; Int m_uniformBlockNameMaxLength = 0;
} // namespace GLState
} // namespace MG_State String m_infoLog;
} // namespace MobileGL Bool m_deleteStatus = false;
Bool m_linkStatus = false;
Bool m_validateStatus = true;
};
} // namespace MobileGL::MG_State::GLState
@@ -8,73 +8,71 @@
#include "ProgramState.h" #include "ProgramState.h"
namespace MobileGL { namespace MobileGL::MG_State::GLState {
namespace MG_State { Uint ProgramState::CreateProgram() {
namespace GLState { Uint programId = 0;
Uint ProgramState::CreateProgram() { m_programIndexGenerator.Generate(1, &programId);
Uint programId = 0; EnsureIndexAvail(programId, m_programObjects);
m_programIndexGenerator.Generate(1, &programId); auto programObject = MakeShared<ProgramObject>(programId);
EnsureIndexAvail(programId, m_programObjects); if (programObject == nullptr) return 0;
auto programObject = MakeShared<ProgramObject>(programId); m_programObjects[programId] = programObject;
if (programObject == nullptr) return 0; return programId;
m_programObjects[programId] = programObject; }
return programId;
}
SharedPtr<ProgramObject> ProgramState::GetProgramObject(const Uint id) { const SharedPtr<ProgramObject>& ProgramState::GetProgramObject(const Uint id) {
if (!CheckIndexAvail(id, m_programObjects)) return nullptr; // FIXME: add error reporting here static SharedPtr<ProgramObject> nullProgramObject = nullptr;
return m_programObjects[id]; if (!CheckIndexAvail(id, m_programObjects)) return nullProgramObject; // FIXME: add error reporting here
} return m_programObjects[id];
}
void ProgramState::MarkProgramObjectForDeletion(const Uint program) { void ProgramState::MarkProgramObjectForDeletion(const Uint program) {
if (!CheckIndexAvail(program, m_programObjects)) return; // FIXME: add error reporting here if (!CheckIndexAvail(program, m_programObjects)) return; // FIXME: add error reporting here
auto& programObject = m_programObjects[program]; auto& programObject = m_programObjects[program];
if (programObject != nullptr) { if (programObject != nullptr) {
programObject->MarkAsDeleted(); programObject->MarkAsDeleted();
programObject.reset(); programObject.reset();
m_programIndexGenerator.Delete(program); m_programIndexGenerator.Delete(program);
} }
} }
Bool ProgramState::ValidateProgramObject(const Uint program) const { Bool ProgramState::ValidateProgramObject(const Uint program) const {
return CheckIndexAvail(program, m_programObjects) && m_programObjects[program] != nullptr; return CheckIndexAvail(program, m_programObjects) && m_programObjects[program] != nullptr;
} }
void ProgramState::UseProgram(Uint program) { void ProgramState::UseProgram(Uint program) {
if (program == 0) m_currentProgram.reset(); if (program == 0) m_currentProgram.reset();
if (!CheckIndexAvail(program, m_programObjects)) return; if (!CheckIndexAvail(program, m_programObjects)) return;
m_currentProgram = m_programObjects[program]; m_currentProgram = m_programObjects[program];
} }
Uint ProgramState::CreateShader(ShaderStage stage) { Uint ProgramState::CreateShader(ShaderStage stage) {
Uint shaderId = 0; Uint shaderId = 0;
m_shaderIndexGenerator.Generate(1, &shaderId); m_shaderIndexGenerator.Generate(1, &shaderId);
EnsureIndexAvail(shaderId, m_shaderObjects); EnsureIndexAvail(shaderId, m_shaderObjects);
auto shaderObject = MakeShared<ShaderObject>(stage, shaderId); auto shaderObject = MakeShared<ShaderObject>(stage, shaderId);
if (shaderObject == nullptr) return 0; if (shaderObject == nullptr) return 0;
m_shaderObjects[shaderId] = shaderObject; m_shaderObjects[shaderId] = shaderObject;
return shaderId; return shaderId;
} }
SharedPtr<ShaderObject> ProgramState::GetShaderObject(const Uint shader) { const SharedPtr<ShaderObject>& ProgramState::GetShaderObject(const Uint shader) {
if (!CheckIndexAvail(shader, m_shaderObjects)) return nullptr; static SharedPtr<ShaderObject> nullShaderObject = nullptr;
return m_shaderObjects[shader]; if (!CheckIndexAvail(shader, m_shaderObjects)) return nullShaderObject;
} return m_shaderObjects[shader];
}
void ProgramState::MarkShaderObjectForDeletion(Uint shader) { void ProgramState::MarkShaderObjectForDeletion(Uint shader) {
if (!CheckIndexAvail(shader, m_shaderObjects)) return; if (!CheckIndexAvail(shader, m_shaderObjects)) return;
auto& shaderObject = m_shaderObjects[shader]; auto& shaderObject = m_shaderObjects[shader];
if (shaderObject != nullptr) { if (shaderObject != nullptr) {
m_shaderObjects[shader]->MarkAsDeleted(); m_shaderObjects[shader]->MarkAsDeleted();
m_shaderObjects[shader].reset(); m_shaderObjects[shader].reset();
m_shaderIndexGenerator.Delete(shader); m_shaderIndexGenerator.Delete(shader);
} }
} }
Bool ProgramState::ValidateShaderObject(Uint shader) const { Bool ProgramState::ValidateShaderObject(Uint shader) const {
return CheckIndexAvail(shader, m_shaderObjects) && m_shaderObjects[shader] != nullptr; return CheckIndexAvail(shader, m_shaderObjects) && m_shaderObjects[shader] != nullptr;
} }
} // namespace GLState } // namespace MobileGL::MG_State::GLState
} // namespace MG_State
} // namespace MobileGL
@@ -11,49 +11,45 @@
#include <MG_Util/Miscellany/IndexGenerator.h> #include <MG_Util/Miscellany/IndexGenerator.h>
#include "ProgramObject.h" #include "ProgramObject.h"
namespace MobileGL { namespace MobileGL::MG_State::GLState {
namespace MG_State { class ProgramState {
namespace GLState { public:
class ProgramState { // This function WILL actually create the program object.
public: // To retrieve created program object, use GetProgramObject()
// This function WILL actually create the program object. Uint CreateProgram();
// To retrieve created program object, use GetProgramObject() const SharedPtr<ProgramObject>& GetProgramObject(Uint id);
Uint CreateProgram(); void MarkProgramObjectForDeletion(Uint program);
SharedPtr<ProgramObject> GetProgramObject(Uint id); Bool ValidateProgramObject(Uint program) const;
void MarkProgramObjectForDeletion(Uint program);
Bool ValidateProgramObject(Uint program) const;
void UseProgram(Uint program); void UseProgram(Uint program);
Uint CreateShader(ShaderStage stage); Uint CreateShader(ShaderStage stage);
SharedPtr<ShaderObject> GetShaderObject(Uint shader); const SharedPtr<ShaderObject>& GetShaderObject(Uint shader);
void MarkShaderObjectForDeletion(Uint shader); void MarkShaderObjectForDeletion(Uint shader);
Bool ValidateShaderObject(Uint shader) const; Bool ValidateShaderObject(Uint shader) const;
SharedPtr<ProgramObject> GetCurrentProgram() const { return m_currentProgram; } const SharedPtr<ProgramObject>& GetCurrentProgram() const { return m_currentProgram; }
private: private:
template <typename T> template <typename T>
static Bool CheckIndexAvail(const SizeT idx, const Vector<T>& vec) { static Bool CheckIndexAvail(const SizeT idx, const Vector<T>& vec) {
return idx < vec.size(); return idx < vec.size();
} }
template <typename T> template <typename T>
static void EnsureIndexAvail(const SizeT idx, Vector<T>& vec) { static void EnsureIndexAvail(const SizeT idx, Vector<T>& vec) {
if (CheckIndexAvail(idx, vec)) return; if (CheckIndexAvail(idx, vec)) return;
vec.reserve(std::bit_ceil(idx)); vec.reserve(std::bit_ceil(idx));
vec.resize(idx + 1); vec.resize(idx + 1);
} }
IndexGenerator<Uint> m_programIndexGenerator; IndexGenerator<Uint> m_programIndexGenerator;
Vector<SharedPtr<ProgramObject>> m_programObjects; Vector<SharedPtr<ProgramObject>> m_programObjects;
IndexGenerator<Uint> m_shaderIndexGenerator; IndexGenerator<Uint> m_shaderIndexGenerator;
Vector<SharedPtr<ShaderObject>> m_shaderObjects; Vector<SharedPtr<ShaderObject>> m_shaderObjects;
SharedPtr<ProgramObject> m_currentProgram; SharedPtr<ProgramObject> m_currentProgram;
}; };
} // namespace GLState } // namespace MobileGL::MG_State::GLState
} // namespace MG_State
} // namespace MobileGL
@@ -13,43 +13,40 @@
#include <MG_Util/ShaderTranspiler/ShaderSourceProcessor.h> #include <MG_Util/ShaderTranspiler/ShaderSourceProcessor.h>
#include <MG_Util/ShaderTranspiler/glslang/UniformTraverser.h> #include <MG_Util/ShaderTranspiler/glslang/UniformTraverser.h>
namespace MobileGL { namespace MobileGL::MG_State::GLState {
namespace MG_State { void ShaderObject::SetShaderSource(const String& source) {
namespace GLState { m_source = source;
void ShaderObject::SetShaderSource(const String& source) { }
m_source = source;
}
void ShaderObject::SetShaderSource(String&& source) { void ShaderObject::SetShaderSource(String&& source) {
m_source = Move(source); m_source = Move(source);
} }
void ShaderObject::Compile() { void ShaderObject::Compile() {
using namespace MG_Util::ShaderTranspiler; using namespace MG_Util::ShaderTranspiler;
MG_Util::ShaderTranspiler::PreprocessShaderSource(m_stage, m_source); MG_Util::ShaderTranspiler::PreprocessShaderSource(m_stage, m_source);
// Compile for OpenGL here, so that we can do validation and link // Compile for OpenGL here, so that we can do validation and link
// like a real OpenGL driver at linking stage // like a real OpenGL driver at linking stage
// Will compile for other backends later. // Will compile for other backends later.
ShaderAttrib attrib{ ShaderAttrib attrib{.shaderType = MG_Util::ConvertShaderStageToGLEnum(m_stage),
.shaderType = MG_Util::ConvertShaderStageToGLEnum(m_stage), .sourceStr = m_source, .flags = ShaderCompileBits::CompileForOpenGL}; .sourceStr = m_source,
.flags = ShaderCompileBits::CompileForOpenGL};
auto result = ShaderCompiler::CompileShader(attrib); auto result = ShaderCompiler::CompileShader(attrib);
if (result) { if (result) {
m_compileStatus = true; m_compileStatus = true;
m_shader = result.value(); m_shader = result.value();
} else { } else {
m_compileStatus = false; m_compileStatus = false;
m_infoLog = result.error().log; m_infoLog = result.error().log;
MGLOG_D("ShaderObject::Compile: Shader %d compilation failed.\nSource:\n%s\nInfoLog:\n%s\nSetting " MGLOG_D("ShaderObject::Compile: Shader %d compilation failed.\nSource:\n%s\nInfoLog:\n%s\nSetting "
"m_compileStatus = false as a result.", "m_compileStatus = false as a result.",
m_externalIndex, m_source.c_str(), m_infoLog.c_str()); m_externalIndex, m_source.c_str(), m_infoLog.c_str());
} }
} }
void ShaderObject::MarkAsDeleted() { void ShaderObject::MarkAsDeleted() {
m_deleteStatus = true; m_deleteStatus = true;
} }
} // namespace GLState } // namespace MobileGL::MG_State::GLState
} // namespace MG_State
} // namespace MobileGL
@@ -21,37 +21,35 @@ namespace MobileGL {
Unknown = -1 Unknown = -1
}; };
namespace MG_State { namespace MG_State::GLState {
namespace GLState { class ShaderObject {
class ShaderObject { public:
public: ShaderObject(const ShaderStage stage, Uint externalIndex)
ShaderObject(const ShaderStage stage, Uint externalIndex) : m_stage(stage), m_externalIndex(externalIndex) {}
: m_stage(stage), m_externalIndex(externalIndex) {} void SetShaderSource(const String& source);
void SetShaderSource(const String& source); void SetShaderSource(String&& source);
void SetShaderSource(String&& source); void Compile();
void Compile(); void MarkAsDeleted();
void MarkAsDeleted();
Uint GetExternalIndex() const { return m_externalIndex; } Uint GetExternalIndex() const { return m_externalIndex; }
ShaderStage GetShaderStage() const { return m_stage; } ShaderStage GetShaderStage() const { return m_stage; }
const String& GetShaderSource() const { return m_source; } const String& GetShaderSource() const { return m_source; }
SharedPtr<glslang::TShader> GetCompiledShader() const { return m_shader; } const SharedPtr<glslang::TShader>& GetCompiledShader() const { return m_shader; }
const String& GetInfoLog() const { return m_infoLog; } const String& GetInfoLog() const { return m_infoLog; }
const UnorderedMap<String, Uint>& GetUniformLocations() const { return m_uniforms; } const UnorderedMap<String, Uint>& GetUniformLocations() const { return m_uniforms; }
Bool GetCompileStatus() const { return m_compileStatus; } Bool GetCompileStatus() const { return m_compileStatus; }
Bool GetDeleteStatus() const { return m_deleteStatus; } Bool GetDeleteStatus() const { return m_deleteStatus; }
private: private:
const Uint m_externalIndex = 0; const Uint m_externalIndex = 0;
const ShaderStage m_stage; const ShaderStage m_stage;
String m_source; String m_source;
SharedPtr<glslang::TShader> m_shader; SharedPtr<glslang::TShader> m_shader;
UnorderedMap<String, Uint> m_uniforms; UnorderedMap<String, Uint> m_uniforms;
String m_infoLog; String m_infoLog;
Bool m_deleteStatus = false; Bool m_deleteStatus = false;
Bool m_compileStatus = false; Bool m_compileStatus = false;
}; };
} // namespace GLState } // namespace MG_State::GLState
} // namespace MG_State
} // namespace MobileGL } // namespace MobileGL
@@ -38,8 +38,8 @@ namespace MobileGL {
void RenderState::SetCapability(CapabilityInput cap, Bool enabled) { void RenderState::SetCapability(CapabilityInput cap, Bool enabled) {
#define SET_CAPABILITY(capability, flag) \ #define SET_CAPABILITY(capability, flag) \
case CapabilityInput::capability: \ case CapabilityInput::capability: \
if (m_parameters.capability##Enabled == flag) break; \ if (m_parameters.capability##Enabled == (flag)) break; \
m_parameters.capability##Enabled = flag; \ m_parameters.capability##Enabled = (flag); \
++m_version; \ ++m_version; \
break; break;
@@ -195,7 +195,7 @@ namespace MobileGL {
++m_version; ++m_version;
} }
const BoolVec4 RenderState::GetColorMask() const { BoolVec4 RenderState::GetColorMask() const {
return m_parameters.ColorMask; return m_parameters.ColorMask;
} }
@@ -237,8 +237,8 @@ namespace MobileGL {
void RenderState::SetPixelStoreParam(PixelStoreParam param, Int value) { void RenderState::SetPixelStoreParam(PixelStoreParam param, Int value) {
#define SET_PIXEL_STORE_PARAM(paramNameHead, paramNameTail, val) \ #define SET_PIXEL_STORE_PARAM(paramNameHead, paramNameTail, val) \
case PixelStoreParam::paramNameHead##paramNameTail: \ case PixelStoreParam::paramNameHead##paramNameTail: \
if (m_pixelStore##paramNameHead##Parameters.paramNameTail == val) break; \ if (m_pixelStore##paramNameHead##Parameters.paramNameTail == (val)) break; \
m_pixelStore##paramNameHead##Parameters.paramNameTail = val; \ m_pixelStore##paramNameHead##Parameters.paramNameTail = (val); \
break; break;
switch (param) { switch (param) {
@@ -201,7 +201,7 @@ namespace MobileGL {
// Color Mask // Color Mask
void SetColorMask(BoolVec4 mask); void SetColorMask(BoolVec4 mask);
const BoolVec4 GetColorMask() const; BoolVec4 GetColorMask() const;
// Clear State // Clear State
void SetClearColor(FloatVec4 color); void SetClearColor(FloatVec4 color);
@@ -7,68 +7,67 @@
// End of Source File Header // End of Source File Header
#include "RenderbufferState.h" #include "RenderbufferState.h"
#include "MG_Util/Types.h"
namespace MobileGL { namespace MobileGL::MG_State::GLState {
namespace MG_State { RenderbufferState::RenderbufferState() : m_indexGenerator(1024, 1) {
namespace GLState { for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
RenderbufferState::RenderbufferState() : m_indexGenerator(1024, 1) { m_bindingSlots[i] = BindingSlot<RenderbufferObject>(static_cast<RenderbufferTarget>(i));
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) { }
m_bindingSlots[i] = BindingSlot<RenderbufferObject>(static_cast<RenderbufferTarget>(i)); }
}
const SharedPtr<RenderbufferObject>& RenderbufferState::GetRenderbufferObject(Uint index) {
auto it = m_renderbufferObjects.find(index);
if (it != m_renderbufferObjects.end()) {
return it->second;
}
static SharedPtr<RenderbufferObject> nullRenderbufferObject = nullptr;
return nullRenderbufferObject;
}
void RenderbufferState::GenerateNames(Uint number, Vector<Uint>& renderbuffers) {
renderbuffers.resize(number);
m_indexGenerator.Generate(number, renderbuffers.data());
}
const SharedPtr<RenderbufferObject>& RenderbufferState::CreateRenderbufferObject(Uint index) {
auto& bufferObject = m_renderbufferObjects[index];
if (!bufferObject) {
bufferObject = MakeShared<RenderbufferObject>(index);
}
return bufferObject;
}
BindingSlot<RenderbufferObject>& RenderbufferState::GetBindingSlot(RenderbufferTarget target) {
for (auto& bindingSlot : m_bindingSlots) {
if (bindingSlot.GetTarget() == target) {
return bindingSlot;
} }
}
MOBILEGL_ASSERT(false, "Invalid RenderbufferTarget enum value: %d", static_cast<int>(target));
return m_bindingSlots[0];
}
SharedPtr<RenderbufferObject> RenderbufferState::GetRenderbufferObject(Uint index) { void RenderbufferState::MarkRenderbufferObjectForDeletion(Uint index) {
auto it = m_renderbufferObjects.find(index); if (m_indexGenerator.IsValid(index)) {
if (it != m_renderbufferObjects.end()) { auto it = m_renderbufferObjects.find(index);
return it->second; if (it != m_renderbufferObjects.end()) {
} for (auto& bindingSlot : m_bindingSlots) {
return nullptr; if (bindingSlot.GetBoundObject() == it->second) {
} bindingSlot.Bind(nullptr);
Vector<Uint> RenderbufferState::GenerateNames(Uint number) {
Vector<Uint> buffers(number);
m_indexGenerator.Generate(number, buffers.data());
return buffers;
}
SharedPtr<RenderbufferObject> RenderbufferState::CreateRenderbufferObject(Uint index) {
auto bufferObject = MakeShared<RenderbufferObject>(index);
m_renderbufferObjects[index] = bufferObject;
return bufferObject;
}
BindingSlot<RenderbufferObject>& RenderbufferState::GetBindingSlot(RenderbufferTarget target) {
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
if (m_bindingSlots[i].GetTarget() == target) {
return m_bindingSlots[i];
} }
} }
MOBILEGL_ASSERT(false, "Invalid RenderbufferTarget enum value: %d", static_cast<int>(target)); m_renderbufferObjects.erase(it);
return m_bindingSlots[0];
} }
m_indexGenerator.Delete(index);
}
}
void RenderbufferState::MarkRenderbufferObjectForDeletion(Uint index) { Bool RenderbufferState::ValidateName(Uint index) const {
if (m_indexGenerator.IsValid(index)) { return m_indexGenerator.IsValid(index);
auto it = m_renderbufferObjects.find(index); }
if (it != m_renderbufferObjects.end()) {
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
if (m_bindingSlots[i].GetBoundObject() == it->second) {
m_bindingSlots[i].Bind(nullptr);
}
}
m_renderbufferObjects.erase(it);
}
m_indexGenerator.Delete(index);
}
}
Bool RenderbufferState::ValidateName(Uint index) const { Bool RenderbufferState::ValidateRenderbufferObject(Uint index) const {
return m_indexGenerator.IsValid(index); return m_renderbufferObjects.find(index) != m_renderbufferObjects.end();
} }
} // namespace MobileGL::MG_State::GLState
Bool RenderbufferState::ValidateRenderbufferObject(Uint index) const {
return m_renderbufferObjects.find(index) != m_renderbufferObjects.end();
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
@@ -11,27 +11,23 @@
#include <MG_Util/Miscellany/IndexGenerator.h> #include <MG_Util/Miscellany/IndexGenerator.h>
#include "RenderbufferObject.h" #include "RenderbufferObject.h"
namespace MobileGL { namespace MobileGL::MG_State::GLState {
namespace MG_State { class RenderbufferState {
namespace GLState { public:
class RenderbufferState { RenderbufferState();
public:
RenderbufferState();
SharedPtr<RenderbufferObject> GetRenderbufferObject(Uint index); const SharedPtr<RenderbufferObject>& GetRenderbufferObject(Uint index);
Vector<Uint> GenerateNames(Uint number); void GenerateNames(Uint number, Vector<Uint>& renderbuffers);
SharedPtr<RenderbufferObject> CreateRenderbufferObject(Uint index); const SharedPtr<RenderbufferObject>& CreateRenderbufferObject(Uint index);
BindingSlot<RenderbufferObject>& GetBindingSlot(RenderbufferTarget target); BindingSlot<RenderbufferObject>& GetBindingSlot(RenderbufferTarget target);
void MarkRenderbufferObjectForDeletion(Uint index); void MarkRenderbufferObjectForDeletion(Uint index);
Bool ValidateName(Uint index) const; Bool ValidateName(Uint index) const;
Bool ValidateRenderbufferObject(Uint index) const; Bool ValidateRenderbufferObject(Uint index) const;
private: private:
UnorderedMap<Uint, SharedPtr<RenderbufferObject>> m_renderbufferObjects; UnorderedMap<Uint, SharedPtr<RenderbufferObject>> m_renderbufferObjects;
IndexGenerator<Uint> m_indexGenerator; IndexGenerator<Uint> m_indexGenerator;
Array<BindingSlot<RenderbufferObject>, static_cast<SizeT>(RenderbufferTarget::RenderbufferTargetCount)> Array<BindingSlot<RenderbufferObject>, static_cast<SizeT>(RenderbufferTarget::RenderbufferTargetCount)>
m_bindingSlots; m_bindingSlots;
}; };
} // namespace GLState } // namespace MobileGL::MG_State::GLState
} // namespace MG_State
} // namespace MobileGL
@@ -8,42 +8,38 @@
#include "SamplerState.h" #include "SamplerState.h"
namespace MobileGL { namespace MobileGL::MG_State::GLState {
namespace MG_State { SamplerState::SamplerState() : m_indexGenerator(1024, 1) {}
namespace GLState {
SamplerState::SamplerState() : m_indexGenerator(1024, 1) {}
Vector<Uint> SamplerState::GenerateNames(Uint number) { void SamplerState::GenerateNames(Uint number, Vector<Uint>& samplers) {
Vector<Uint> names(number); samplers.resize(number);
m_indexGenerator.Generate(number, names.data()); m_indexGenerator.Generate(number, samplers.data());
return names; }
}
SharedPtr<SamplerObject> SamplerState::GetSamplerObject(Uint index) { const SharedPtr<SamplerObject>& SamplerState::GetSamplerObject(Uint index) {
auto it = m_samplerObjects.find(index); auto it = m_samplerObjects.find(index);
return it != m_samplerObjects.end() ? it->second : nullptr; static SharedPtr<SamplerObject> nullSamplerObject = nullptr;
} return it != m_samplerObjects.end() ? it->second : nullSamplerObject;
}
SharedPtr<SamplerObject> SamplerState::CreateSamplerObject(Uint index) { const SharedPtr<SamplerObject>& SamplerState::CreateSamplerObject(Uint index) {
auto sampler = MakeShared<SamplerObject>(index); auto& sampler = m_samplerObjects[index];
m_samplerObjects[index] = sampler; sampler = MakeShared<SamplerObject>(index);
return sampler; return sampler;
} }
void SamplerState::MarkSamplerObjectForDeletion(Uint index) { void SamplerState::MarkSamplerObjectForDeletion(Uint index) {
if (m_indexGenerator.IsValid(index)) { if (m_indexGenerator.IsValid(index)) {
m_samplerObjects.erase(index); m_samplerObjects.erase(index);
m_indexGenerator.Delete(index); m_indexGenerator.Delete(index);
} }
} }
Bool SamplerState::ValidateName(Uint index) const { Bool SamplerState::ValidateName(Uint index) const {
return m_indexGenerator.IsValid(index); return m_indexGenerator.IsValid(index);
} }
Bool SamplerState::ValidateSamplerObject(Uint index) const { Bool SamplerState::ValidateSamplerObject(Uint index) const {
return m_samplerObjects.find(index) != m_samplerObjects.end(); return m_samplerObjects.find(index) != m_samplerObjects.end();
} }
} // namespace GLState } // namespace MobileGL::MG_State::GLState
} // namespace MG_State
} // namespace MobileGL
@@ -18,9 +18,9 @@ namespace MobileGL {
public: public:
SamplerState(); SamplerState();
Vector<Uint> GenerateNames(Uint number); void GenerateNames(Uint number, Vector<Uint>& samplers);
SharedPtr<SamplerObject> GetSamplerObject(Uint index); const SharedPtr<SamplerObject>& GetSamplerObject(Uint index);
SharedPtr<SamplerObject> CreateSamplerObject(Uint index); const SharedPtr<SamplerObject>& CreateSamplerObject(Uint index);
void MarkSamplerObjectForDeletion(Uint index); void MarkSamplerObjectForDeletion(Uint index);
Bool ValidateName(Uint index) const; Bool ValidateName(Uint index) const;
Bool ValidateSamplerObject(Uint index) const; Bool ValidateSamplerObject(Uint index) const;
@@ -31,7 +31,7 @@ namespace MobileGL {
return {0, 0, 0}; return {0, 0, 0};
} }
SharedPtr<SamplerObject> TextureObjectBase::GetSamplerObject() const { const SharedPtr<SamplerObject>& TextureObjectBase::GetSamplerObject() const {
return m_sampler; return m_sampler;
} }
@@ -14,113 +14,107 @@
#include <Includes.h> #include <Includes.h>
#include <MG_Util/Math/VectorTypes.h> #include <MG_Util/Math/VectorTypes.h>
namespace MobileGL { namespace MobileGL::MG_State::GLState {
namespace MG_State { class ITextureObject {
namespace GLState { public:
class ITextureObject { using TargetEnum = TextureTarget;
public: virtual ~ITextureObject() = default;
using TargetEnum = TextureTarget;
virtual ~ITextureObject() = default;
virtual TextureStorageType GetStorageType() const = 0; virtual TextureStorageType GetStorageType() const = 0;
virtual TextureInternalFormat GetFormat() const = 0; virtual TextureInternalFormat GetFormat() const = 0;
virtual TextureTarget GetTarget() const = 0; virtual TextureTarget GetTarget() const = 0;
virtual const Vector<TextureUploadTarget>& GetUploadTargets() const = 0; virtual const Vector<TextureUploadTarget>& GetUploadTargets() const = 0;
virtual IntVec3 GetBaseSize() const = 0; virtual IntVec3 GetBaseSize() const = 0;
virtual SharedPtr<SamplerObject> GetSamplerObject() const = 0; virtual const SharedPtr<SamplerObject>& GetSamplerObject() const = 0;
virtual void SetInternalFormat(TextureInternalFormat format) = 0; virtual void SetInternalFormat(TextureInternalFormat format) = 0;
virtual Bool IsComplete() const = 0; virtual Bool IsComplete() const = 0;
virtual Uint GetExternalIndex() const = 0; virtual Uint GetExternalIndex() const = 0;
virtual const FloatVec4& GetBorderColor() const = 0; virtual const FloatVec4& GetBorderColor() const = 0;
virtual void SetBorderColor(const FloatVec4& color) = 0; virtual void SetBorderColor(const FloatVec4& color) = 0;
virtual TextureSwizzleParam GetSwizzleParam(TextureSwizzleParam param) const = 0; virtual TextureSwizzleParam GetSwizzleParam(TextureSwizzleParam param) const = 0;
virtual void SetSwizzleParam(TextureSwizzleParam param, TextureSwizzleParam value) = 0; virtual void SetSwizzleParam(TextureSwizzleParam param, TextureSwizzleParam value) = 0;
virtual void SetSwizzleParamRGBA(const Vec4<TextureSwizzleParam>& values) = 0; virtual void SetSwizzleParamRGBA(const Vec4<TextureSwizzleParam>& values) = 0;
virtual const Vec4<TextureSwizzleParam>& GetAllSwizzleParams() const = 0; virtual const Vec4<TextureSwizzleParam>& GetAllSwizzleParams() const = 0;
virtual const UintVec2& GetLevelRange() const = 0; virtual const UintVec2& GetLevelRange() const = 0;
virtual void SetBaseLevel(Uint baseLevel) = 0; virtual void SetBaseLevel(Uint baseLevel) = 0;
virtual void SetMaxLevel(Uint maxLevel) = 0; virtual void SetMaxLevel(Uint maxLevel) = 0;
virtual Uint16 GetTextureParamsVersion() const = 0; virtual Uint16 GetTextureParamsVersion() const = 0;
protected: protected:
virtual Uint GetIndexOfTextureUploadTarget(TextureUploadTarget target) const = 0; virtual Uint GetIndexOfTextureUploadTarget(TextureUploadTarget target) const = 0;
}; };
class TextureObjectBase : public ITextureObject { class TextureObjectBase : public ITextureObject {
public: public:
TextureObjectBase(TextureTarget target, Uint externalIndex); TextureObjectBase(TextureTarget target, Uint externalIndex);
virtual ~TextureObjectBase() = default; virtual ~TextureObjectBase() = default;
TextureInternalFormat GetFormat() const override; TextureInternalFormat GetFormat() const override;
TextureTarget GetTarget() const override; TextureTarget GetTarget() const override;
IntVec3 GetBaseSize() const override; IntVec3 GetBaseSize() const override;
SharedPtr<SamplerObject> GetSamplerObject() const override; const SharedPtr<SamplerObject>& GetSamplerObject() const override;
void SetInternalFormat(TextureInternalFormat format) override; void SetInternalFormat(TextureInternalFormat format) override;
Bool IsComplete() const override; Bool IsComplete() const override;
Uint GetExternalIndex() const override; Uint GetExternalIndex() const override;
const FloatVec4& GetBorderColor() const override; const FloatVec4& GetBorderColor() const override;
void SetBorderColor(const FloatVec4& color) override; void SetBorderColor(const FloatVec4& color) override;
TextureSwizzleParam GetSwizzleParam(TextureSwizzleParam param) const override; TextureSwizzleParam GetSwizzleParam(TextureSwizzleParam param) const override;
const Vec4<TextureSwizzleParam>& GetAllSwizzleParams() const override; const Vec4<TextureSwizzleParam>& GetAllSwizzleParams() const override;
void SetSwizzleParam(TextureSwizzleParam param, TextureSwizzleParam value) override; void SetSwizzleParam(TextureSwizzleParam param, TextureSwizzleParam value) override;
void SetSwizzleParamRGBA(const Vec4<TextureSwizzleParam>& values) override; void SetSwizzleParamRGBA(const Vec4<TextureSwizzleParam>& values) override;
const UintVec2& GetLevelRange() const override; const UintVec2& GetLevelRange() const override;
void SetBaseLevel(Uint baseLevel) override; void SetBaseLevel(Uint baseLevel) override;
void SetMaxLevel(Uint maxLevel) override; void SetMaxLevel(Uint maxLevel) override;
Uint16 GetTextureParamsVersion() const override; Uint16 GetTextureParamsVersion() const override;
protected: protected:
const Uint m_externalIndex; const Uint m_externalIndex;
const TextureTarget m_target = TextureTarget::Unknown; const TextureTarget m_target = TextureTarget::Unknown;
TextureInternalFormat m_internalFormat = TextureInternalFormat::Unknown; TextureInternalFormat m_internalFormat = TextureInternalFormat::Unknown;
SharedPtr<SamplerObject> m_sampler = nullptr; SharedPtr<SamplerObject> m_sampler = nullptr;
FloatVec4 m_borderColor = {0.0f, 0.0f, 0.0f, 0.0f}; FloatVec4 m_borderColor = {0.0f, 0.0f, 0.0f, 0.0f};
Vec4<TextureSwizzleParam> m_swizzleParams = {TextureSwizzleParam::Red, TextureSwizzleParam::Green, Vec4<TextureSwizzleParam> m_swizzleParams = {TextureSwizzleParam::Red, TextureSwizzleParam::Green,
TextureSwizzleParam::Blue, TextureSwizzleParam::Alpha}; TextureSwizzleParam::Blue, TextureSwizzleParam::Alpha};
UintVec2 m_levelRange = {0, 1000}; UintVec2 m_levelRange = {0, 1000};
Uint16 m_textureParamsVersion = 0; Uint16 m_textureParamsVersion = 0;
}; };
class TextureObjectMipmap : public TextureObjectBase { class TextureObjectMipmap : public TextureObjectBase {
public: public:
TextureObjectMipmap(TextureTarget target, Uint externalIndex) TextureObjectMipmap(TextureTarget target, Uint externalIndex) : TextureObjectBase(target, externalIndex) {}
: TextureObjectBase(target, externalIndex) {}
TextureStorageType GetStorageType() const override { return TextureStorageType::Mipmap; } TextureStorageType GetStorageType() const override { return TextureStorageType::Mipmap; }
virtual Uint GetMipmapLevelCount() const = 0; virtual Uint GetMipmapLevelCount() const = 0;
virtual const IntVec3 GetMipmapTexelSize(TextureUploadTarget target, Uint mipmapLevel) const = 0; virtual const IntVec3 GetMipmapTexelSize(TextureUploadTarget target, Uint mipmapLevel) const = 0;
virtual const SizeT GetMipmapByteSize(TextureUploadTarget target, Uint mipmapLevel) const = 0; virtual const SizeT GetMipmapByteSize(TextureUploadTarget target, Uint mipmapLevel) const = 0;
virtual void AllocateStorage(TextureUploadTarget uploadTarget, Uint mipmapLevel, MipmapInput input) = 0; virtual void AllocateStorage(TextureUploadTarget uploadTarget, Uint mipmapLevel, MipmapInput input) = 0;
virtual void UpdateMipmapSubData(TextureUploadTarget uploadTarget, Uint mipmapLevel, DataPtr input) = 0; virtual void UpdateMipmapSubData(TextureUploadTarget uploadTarget, Uint mipmapLevel, DataPtr input) = 0;
virtual void* MapMipmapData(TextureUploadTarget uploadTarget, Uint mipmapLevel) = 0; virtual void* MapMipmapData(TextureUploadTarget uploadTarget, Uint mipmapLevel) = 0;
virtual void MarkStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel, virtual void MarkStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel, Bool dirty = true) = 0;
Bool dirty = true) = 0; virtual Bool IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const = 0;
virtual Bool IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const = 0; };
};
class TextureObjectWithOneMipmap : public TextureObjectMipmap { class TextureObjectWithOneMipmap : public TextureObjectMipmap {
public: public:
TextureObjectWithOneMipmap(TextureTarget target, Uint externalIndex) TextureObjectWithOneMipmap(TextureTarget target, Uint externalIndex)
: TextureObjectMipmap(target, externalIndex) {} : TextureObjectMipmap(target, externalIndex) {}
virtual ~TextureObjectWithOneMipmap() = default; virtual ~TextureObjectWithOneMipmap() = default;
Uint GetMipmapLevelCount() const override; Uint GetMipmapLevelCount() const override;
const IntVec3 GetMipmapTexelSize(TextureUploadTarget target, Uint mipmapLevel) const override; const IntVec3 GetMipmapTexelSize(TextureUploadTarget target, Uint mipmapLevel) const override;
const SizeT GetMipmapByteSize(TextureUploadTarget target, Uint mipmapLevel) const override; const SizeT GetMipmapByteSize(TextureUploadTarget target, Uint mipmapLevel) const override;
void AllocateStorage(TextureUploadTarget uploadTarget, Uint mipmapLevel, MipmapInput input) override; void AllocateStorage(TextureUploadTarget uploadTarget, Uint mipmapLevel, MipmapInput input) override;
void UpdateMipmapSubData(TextureUploadTarget uploadTarget, Uint mipmapLevel, DataPtr input) override; void UpdateMipmapSubData(TextureUploadTarget uploadTarget, Uint mipmapLevel, DataPtr input) override;
void* MapMipmapData(TextureUploadTarget uploadTarget, Uint mipmapLevel) override; void* MapMipmapData(TextureUploadTarget uploadTarget, Uint mipmapLevel) override;
void MarkStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel, Bool dirty) override; void MarkStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel, Bool dirty) override;
bool IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const override; bool IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const override;
IntVec3 GetBaseSize() const override; IntVec3 GetBaseSize() const override;
Bool IsComplete() const override; Bool IsComplete() const override;
protected: protected:
MipmapUploadTargetArray<1> m_textureStorage; MipmapUploadTargetArray<1> m_textureStorage;
}; };
} // namespace GLState } // namespace MobileGL::MG_State::GLState
} // namespace MG_State
} // namespace MobileGL
@@ -8,7 +8,7 @@
#pragma once #pragma once
#include "TextureObject.h" #include "TextureObject.h"
#include "MG_State/GLState/BufferState/BufferObject.h" #include <MG_State/GLState/BufferState/BufferObject.h>
namespace MobileGL { namespace MobileGL {
namespace MG_State { namespace MG_State {
@@ -17,115 +17,111 @@
#include "TextureObjectBuffer.h" #include "TextureObjectBuffer.h"
#include "TextureObjectStubs.h" #include "TextureObjectStubs.h"
namespace MobileGL { namespace MobileGL::MG_State::GLState {
namespace MG_State { TextureState::TextureState() : m_indexGenerator(1024, 1) {
namespace GLState { for (int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i) {
TextureState::TextureState() : m_indexGenerator(1024, 1) { m_textureUnits[i] = TextureUnit();
for (int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i) { }
m_textureUnits[i] = TextureUnit(); }
}
}
SharedPtr<ITextureObject> TextureState::GetTextureObject(Uint index) { const SharedPtr<ITextureObject>& TextureState::GetTextureObject(Uint index) {
auto it = m_textureObjects.find(index); auto it = m_textureObjects.find(index);
if (it != m_textureObjects.end()) { if (it != m_textureObjects.end()) {
return it->second; return it->second;
} }
return nullptr; static SharedPtr<ITextureObject> nullTextureObject = nullptr;
} return nullTextureObject;
}
Vector<Uint> TextureState::GenerateNames(Uint number) { void TextureState::GenerateNames(Uint number, Vector<Uint>& textures) {
Vector<Uint> textures(number); textures.resize(number);
m_indexGenerator.Generate(number, textures.data()); m_indexGenerator.Generate(number, textures.data());
return textures; }
}
SharedPtr<ITextureObject> TextureState::CreateTextureObject(Uint index, TextureTarget target) { const SharedPtr<ITextureObject>& TextureState::CreateTextureObject(Uint index, TextureTarget target) {
SharedPtr<ITextureObject> textureObject = nullptr; auto& textureObject = m_textureObjects[index];
switch (target) { switch (target) {
case TextureTarget::Texture1D: case TextureTarget::Texture1D:
textureObject = MakeShared<TextureObject1D>(index); textureObject = MakeShared<TextureObject1D>(index);
break; break;
case TextureTarget::TextureCubeMap: case TextureTarget::TextureCubeMap:
textureObject = MakeShared<TextureObject2DCube>(index); textureObject = MakeShared<TextureObject2DCube>(index);
break; break;
case TextureTarget::Texture2D: case TextureTarget::Texture2D:
textureObject = MakeShared<TextureObject2D>(index); textureObject = MakeShared<TextureObject2D>(index);
break; break;
case TextureTarget::Texture3D: case TextureTarget::Texture3D:
textureObject = MakeShared<TextureObject3D>(index); textureObject = MakeShared<TextureObject3D>(index);
break; break;
case TextureTarget::TextureBuffer: case TextureTarget::TextureBuffer:
textureObject = MakeShared<TextureObjectBuffer>(index); textureObject = MakeShared<TextureObjectBuffer>(index);
break; break;
// These texture types are stubbed: // These texture types are stubbed:
case TextureTarget::TextureRectangle: case TextureTarget::TextureRectangle:
textureObject = MakeShared<TextureObjectRectangle>(index); textureObject = MakeShared<TextureObjectRectangle>(index);
break; break;
case TextureTarget::Texture2DMultisample: case TextureTarget::Texture2DMultisample:
textureObject = MakeShared<TextureObject2DMultisample>(index); textureObject = MakeShared<TextureObject2DMultisample>(index);
break; break;
case TextureTarget::Texture1DArray: case TextureTarget::Texture1DArray:
textureObject = MakeShared<TextureObject1DArray>(index); textureObject = MakeShared<TextureObject1DArray>(index);
break; break;
case TextureTarget::Texture2DArray: case TextureTarget::Texture2DArray:
textureObject = MakeShared<TextureObject2DArray>(index); textureObject = MakeShared<TextureObject2DArray>(index);
break; break;
case TextureTarget::TextureCubeMapArray: case TextureTarget::TextureCubeMapArray:
textureObject = MakeShared<TextureObjectCubeMapArray>(index); textureObject = MakeShared<TextureObjectCubeMapArray>(index);
break; break;
case TextureTarget::Texture2DMultisampleArray: case TextureTarget::Texture2DMultisampleArray:
textureObject = MakeShared<TextureObject2DMultisampleArray>(index); textureObject = MakeShared<TextureObject2DMultisampleArray>(index);
break; break;
default: default:
MOBILEGL_ASSERT(false, "Unimplemented texture type when creating texture object!: %d", (int)target); MOBILEGL_ASSERT(false, "Unimplemented texture type when creating texture object!: %d", (int)target);
return nullptr; static SharedPtr<ITextureObject> nullTextureObject = nullptr;
} return nullTextureObject;
}
m_textureObjects[index] = textureObject; return textureObject;
return textureObject; }
}
void TextureState::MarkTextureObjectForDeletion(Uint index) { void TextureState::MarkTextureObjectForDeletion(Uint index) {
if (m_indexGenerator.IsValid(index)) { if (m_indexGenerator.IsValid(index)) {
auto it = m_textureObjects.find(index); auto it = m_textureObjects.find(index);
if (it != m_textureObjects.end()) { if (it != m_textureObjects.end()) {
for (auto& unit : m_textureUnits) { for (auto& unit : m_textureUnits) {
auto& bindingSlots = unit.GetAllBindingSlots(); auto& bindingSlots = unit.GetAllBindingSlots();
for (SizeT i = 0; i < bindingSlots.size(); ++i) { for (auto& bindingSlot : bindingSlots) {
if (bindingSlots[i].GetBoundObject() == it->second) { if (bindingSlot.GetBoundObject() == it->second) {
bindingSlots[i].Bind(nullptr); bindingSlot.Bind(nullptr);
}
}
} }
m_textureObjects.erase(it);
} }
m_indexGenerator.Delete(index);
} }
m_textureObjects.erase(it);
} }
m_indexGenerator.Delete(index);
}
}
TextureUnit& TextureState::GetUnitObject(Int unit) { TextureUnit& TextureState::GetUnitObject(Int unit) {
MOBILEGL_ASSERT(unit >= 0 && unit < MAX_TEXTURE_IMAGE_UNITS, "Texture unit is out of range: %d > %d", MOBILEGL_ASSERT(unit >= 0 && unit < MAX_TEXTURE_IMAGE_UNITS, "Texture unit is out of range: %d > %d", unit,
unit, MAX_TEXTURE_IMAGE_UNITS - 1); MAX_TEXTURE_IMAGE_UNITS - 1);
return m_textureUnits[unit]; return m_textureUnits[unit];
} }
Int TextureState::GetActiveTextureUnit() const { Int TextureState::GetActiveTextureUnit() const {
return m_activeTextureUnit; return m_activeTextureUnit;
} }
void TextureState::SetActiveTextureUnit(Int unit) { void TextureState::SetActiveTextureUnit(Int unit) {
m_activeTextureUnit = unit; m_activeTextureUnit = unit;
} }
Bool TextureState::ValidateName(Uint index) const { Bool TextureState::ValidateName(Uint index) const {
return m_indexGenerator.IsValid(index); return m_indexGenerator.IsValid(index);
} }
Bool TextureState::ValidateTextureObject(Uint index) const { Bool TextureState::ValidateTextureObject(Uint index) const {
return m_textureObjects.find(index) != m_textureObjects.end(); return m_textureObjects.find(index) != m_textureObjects.end();
} }
} // namespace GLState } // namespace MobileGL::MG_State::GLState
} // namespace MG_State
} // namespace MobileGL
@@ -13,30 +13,26 @@
#include "MG_Util/Types.h" #include "MG_Util/Types.h"
#include "TextureUnit.h" #include "TextureUnit.h"
namespace MobileGL { namespace MobileGL::MG_State::GLState {
namespace MG_State { class TextureState {
namespace GLState { public:
class TextureState { static constexpr int MAX_TEXTURE_IMAGE_UNITS = 32;
public:
static constexpr int MAX_TEXTURE_IMAGE_UNITS = 32;
TextureState(); TextureState();
Vector<Uint> GenerateNames(Uint number); void GenerateNames(Uint number, Vector<Uint>& textures);
SharedPtr<ITextureObject> CreateTextureObject(Uint index, TextureTarget target); const SharedPtr<ITextureObject>& CreateTextureObject(Uint index, TextureTarget target);
SharedPtr<ITextureObject> GetTextureObject(Uint index); const SharedPtr<ITextureObject>& GetTextureObject(Uint index);
TextureUnit& GetUnitObject(Int unit); TextureUnit& GetUnitObject(Int unit);
Int GetActiveTextureUnit() const; Int GetActiveTextureUnit() const;
void SetActiveTextureUnit(Int unit); void SetActiveTextureUnit(Int unit);
void MarkTextureObjectForDeletion(Uint index); void MarkTextureObjectForDeletion(Uint index);
Bool ValidateName(Uint index) const; Bool ValidateName(Uint index) const;
Bool ValidateTextureObject(Uint index) const; Bool ValidateTextureObject(Uint index) const;
private: private:
Int m_activeTextureUnit = 0; Int m_activeTextureUnit = 0;
Array<TextureUnit, MAX_TEXTURE_IMAGE_UNITS> m_textureUnits; Array<TextureUnit, MAX_TEXTURE_IMAGE_UNITS> m_textureUnits;
IndexGenerator<Uint> m_indexGenerator; IndexGenerator<Uint> m_indexGenerator;
UnorderedMap<GLuint, SharedPtr<ITextureObject>> m_textureObjects; UnorderedMap<GLuint, SharedPtr<ITextureObject>> m_textureObjects;
}; };
} // namespace GLState } // namespace MobileGL::MG_State::GLState
} // namespace MG_State
} // namespace MobileGL
@@ -8,31 +8,26 @@
#include "TextureUnit.h" #include "TextureUnit.h"
namespace MobileGL { namespace MobileGL::MG_State::GLState {
namespace MG_State { TextureUnit::TextureUnit() : m_sampler(nullptr) {
namespace GLState { for (int i = 0; i < (int)TextureTarget::TextureTargetCount; ++i) {
TextureUnit::TextureUnit() : m_sampler(nullptr) { m_slots[i] = BindingSlot<ITextureObject>(static_cast<TextureTarget>(i));
for (int i = 0; i < (int)TextureTarget::TextureTargetCount; ++i) { }
m_slots[i] = BindingSlot<ITextureObject>(static_cast<TextureTarget>(i)); }
}
}
BindingSlot<ITextureObject>& TextureUnit::GetBindingSlot(TextureTarget target) { BindingSlot<ITextureObject>& TextureUnit::GetBindingSlot(TextureTarget target) {
return m_slots[(int)target]; return m_slots[(int)target];
} }
Array<BindingSlot<ITextureObject>, (int)TextureTarget::TextureTargetCount>& TextureUnit:: Array<BindingSlot<ITextureObject>, (int)TextureTarget::TextureTargetCount>& TextureUnit::GetAllBindingSlots() {
GetAllBindingSlots() { return m_slots;
return m_slots; }
}
void TextureUnit::SetSamplerObject(SharedPtr<SamplerObject> sampler) { void TextureUnit::SetSamplerObject(const SharedPtr<SamplerObject>& sampler) {
m_sampler = sampler; m_sampler = sampler;
} }
SharedPtr<SamplerObject> TextureUnit::GetSamplerObject() const { const SharedPtr<SamplerObject>& TextureUnit::GetSamplerObject() const {
return m_sampler; return m_sampler;
} }
} // namespace GLState } // namespace MobileGL::MG_State::GLState
} // namespace MG_State
} // namespace MobileGL
@@ -11,21 +11,17 @@
#include <MG_State/GLState/SamplerState/SamplerObject.h> #include <MG_State/GLState/SamplerState/SamplerObject.h>
#include "TextureObject.h" #include "TextureObject.h"
namespace MobileGL { namespace MobileGL::MG_State::GLState {
namespace MG_State { class TextureUnit {
namespace GLState { public:
class TextureUnit { TextureUnit();
public: BindingSlot<ITextureObject>& GetBindingSlot(TextureTarget target);
TextureUnit(); const SharedPtr<SamplerObject>& GetSamplerObject() const;
BindingSlot<ITextureObject>& GetBindingSlot(TextureTarget target); Array<BindingSlot<ITextureObject>, (int)TextureTarget::TextureTargetCount>& GetAllBindingSlots();
SharedPtr<SamplerObject> GetSamplerObject() const; void SetSamplerObject(const SharedPtr<SamplerObject>& sampler);
Array<BindingSlot<ITextureObject>, (int)TextureTarget::TextureTargetCount>& GetAllBindingSlots();
void SetSamplerObject(SharedPtr<SamplerObject> sampler);
private: private:
Array<BindingSlot<ITextureObject>, (int)TextureTarget::TextureTargetCount> m_slots; Array<BindingSlot<ITextureObject>, (int)TextureTarget::TextureTargetCount> m_slots;
SharedPtr<SamplerObject> m_sampler; SharedPtr<SamplerObject> m_sampler;
}; };
} // namespace GLState } // namespace MobileGL::MG_State::GLState
} // namespace MG_State
} // namespace MobileGL
@@ -8,137 +8,132 @@
#include "VertexArrayObject.h" #include "VertexArrayObject.h"
namespace MobileGL { namespace MobileGL::MG_State::GLState {
namespace MG_State { VertexArrayObject::VertexArrayObject(Uint externIndex) : m_externalIndex(externIndex) {
namespace GLState { for (int index = 0; index < MAX_VERTEX_ATTRIBS; ++index) {
VertexArrayObject::VertexArrayObject(Uint externIndex) : m_externalIndex(externIndex) { auto& attr = m_attributes[index];
for (int index = 0; index < MAX_VERTEX_ATTRIBS; ++index) { attr.Enabled = false;
auto& attr = m_attributes[index]; attr.Size = 4;
attr.Enabled = false; attr.Type = DataType::Float32;
attr.Size = 4; attr.Normalized = false;
attr.Type = DataType::Float32; attr.Stride = 0;
attr.Normalized = false; attr.Offset = 0;
attr.Stride = 0; attr.Buffer = nullptr;
attr.Offset = 0;
attr.Buffer = nullptr;
BumpAttributeFormatVersion(index); BumpAttributeFormatVersion(index);
} }
} }
void VertexArrayObject::EnableAttribute(Uint index) { void VertexArrayObject::EnableAttribute(Uint index) {
if (index >= MAX_VERTEX_ATTRIBS) return; if (index >= MAX_VERTEX_ATTRIBS) return;
if (m_attributes[index].Enabled) return; if (m_attributes[index].Enabled) return;
m_attributes[index].Enabled = true; m_attributes[index].Enabled = true;
BumpAttributeSwitchVersion(index); BumpAttributeSwitchVersion(index);
} }
void VertexArrayObject::DisableAttribute(Uint index) { void VertexArrayObject::DisableAttribute(Uint index) {
if (index >= MAX_VERTEX_ATTRIBS) return; if (index >= MAX_VERTEX_ATTRIBS) return;
if (!m_attributes[index].Enabled) return; if (!m_attributes[index].Enabled) return;
m_attributes[index].Enabled = false; m_attributes[index].Enabled = false;
BumpAttributeSwitchVersion(index); BumpAttributeSwitchVersion(index);
} }
Bool VertexArrayObject::IsAttributeEnabled(Uint index) const { Bool VertexArrayObject::IsAttributeEnabled(Uint index) const {
if (index >= MAX_VERTEX_ATTRIBS) return false; if (index >= MAX_VERTEX_ATTRIBS) return false;
return m_attributes[index].Enabled; return m_attributes[index].Enabled;
} }
void VertexArrayObject::SetAttributeFormat(Uint index, int size, DataType type, Bool normalized, int stride, void VertexArrayObject::SetAttributeFormat(Uint index, int size, DataType type, Bool normalized, int stride,
SizeT offset, Bool isInteger) { SizeT offset, Bool isInteger) {
if (index >= MAX_VERTEX_ATTRIBS) return; if (index >= MAX_VERTEX_ATTRIBS) return;
if (m_attributes[index].Size == size && m_attributes[index].Type == type && if (m_attributes[index].Size == size && m_attributes[index].Type == type &&
m_attributes[index].Normalized == normalized && m_attributes[index].Stride == stride && m_attributes[index].Normalized == normalized && m_attributes[index].Stride == stride &&
m_attributes[index].Offset == offset && m_attributes[index].IsInteger == isInteger) { m_attributes[index].Offset == offset && m_attributes[index].IsInteger == isInteger) {
return; return;
} }
if (size < 1 || size > 4) { if (size < 1 || size > 4) {
return; return;
} }
auto& attr = m_attributes[index]; auto& attr = m_attributes[index];
attr.Size = size; attr.Size = size;
attr.Type = type; attr.Type = type;
attr.Normalized = normalized; attr.Normalized = normalized;
attr.Stride = stride; attr.Stride = stride;
attr.Offset = offset; attr.Offset = offset;
attr.IsInteger = isInteger; attr.IsInteger = isInteger;
BumpAttributeFormatVersion(index); BumpAttributeFormatVersion(index);
} }
void VertexArrayObject::BindAttributeBuffer(Uint index, const SharedPtr<BufferObject>& buffer) { void VertexArrayObject::BindAttributeBuffer(Uint index, const SharedPtr<BufferObject>& buffer) {
if (index >= MAX_VERTEX_ATTRIBS) return; if (index >= MAX_VERTEX_ATTRIBS) return;
if (m_attributes[index].Buffer == buffer) return; if (m_attributes[index].Buffer == buffer) return;
m_attributes[index].Buffer = buffer; m_attributes[index].Buffer = buffer;
BumpAttributeBufferVersion(index); BumpAttributeBufferVersion(index);
} }
BindingSlot<BufferObject>& VertexArrayObject::GetIndexBufferBindingSlot() { BindingSlot<BufferObject>& VertexArrayObject::GetIndexBufferBindingSlot() {
return m_indexBufferBindingSlot; return m_indexBufferBindingSlot;
} }
const VertexAttribute& VertexArrayObject::GetAttribute(Uint index) const { const VertexAttribute& VertexArrayObject::GetAttribute(Uint index) const {
static VertexAttribute emptyAttr; static VertexAttribute emptyAttr;
if (index >= MAX_VERTEX_ATTRIBS) return emptyAttr; if (index >= MAX_VERTEX_ATTRIBS) return emptyAttr;
return m_attributes[index]; return m_attributes[index];
} }
const Array<VertexAttribute, VertexArrayObject::MAX_VERTEX_ATTRIBS>& VertexArrayObject::GetAllAttributes() const Array<VertexAttribute, VertexArrayObject::MAX_VERTEX_ATTRIBS>& VertexArrayObject::GetAllAttributes() const {
const { return m_attributes;
return m_attributes; }
}
Uint VertexArrayObject::GetExternalIndex() const { Uint VertexArrayObject::GetExternalIndex() const {
return m_externalIndex; return m_externalIndex;
} }
void VertexArrayObject::SetAttributeDivisor(Uint index, Uint divisor) { void VertexArrayObject::SetAttributeDivisor(Uint index, Uint divisor) {
if (index >= MAX_VERTEX_ATTRIBS) return; if (index >= MAX_VERTEX_ATTRIBS) return;
if (m_attributes[index].Divisor == divisor) return; if (m_attributes[index].Divisor == divisor) return;
m_attributes[index].Divisor = divisor; m_attributes[index].Divisor = divisor;
BumpAttributeFormatVersion(index); BumpAttributeFormatVersion(index);
} }
Uint VertexArrayObject::GetAttributeDivisor(Uint index) const { Uint VertexArrayObject::GetAttributeDivisor(Uint index) const {
if (index >= MAX_VERTEX_ATTRIBS) return 0; if (index >= MAX_VERTEX_ATTRIBS) return 0;
return m_attributes[index].Divisor; return m_attributes[index].Divisor;
} }
void VertexArrayObject::BumpAttributeFormatVersion(Uint index) { void VertexArrayObject::BumpAttributeFormatVersion(Uint index) {
if (index >= MAX_VERTEX_ATTRIBS) return; if (index >= MAX_VERTEX_ATTRIBS) return;
++m_attributeVersions[index].FormatVersion; ++m_attributeVersions[index].FormatVersion;
} }
void VertexArrayObject::BumpAttributeBufferVersion(Uint index) { void VertexArrayObject::BumpAttributeBufferVersion(Uint index) {
if (index >= MAX_VERTEX_ATTRIBS) return; if (index >= MAX_VERTEX_ATTRIBS) return;
++m_attributeVersions[index].BufferVersion; ++m_attributeVersions[index].BufferVersion;
} }
void VertexArrayObject::BumpAttributeSwitchVersion(Uint index) { void VertexArrayObject::BumpAttributeSwitchVersion(Uint index) {
if (index >= MAX_VERTEX_ATTRIBS) return; if (index >= MAX_VERTEX_ATTRIBS) return;
++m_attributeVersions[index].SwitchVersion; ++m_attributeVersions[index].SwitchVersion;
} }
const VertexAttributeVersion& VertexArrayObject::GetAttributeVersion(Uint index) const { const VertexAttributeVersion& VertexArrayObject::GetAttributeVersion(Uint index) const {
static VertexAttributeVersion emptyVersion; static VertexAttributeVersion emptyVersion;
if (index >= MAX_VERTEX_ATTRIBS) return emptyVersion; if (index >= MAX_VERTEX_ATTRIBS) return emptyVersion;
return m_attributeVersions[index]; return m_attributeVersions[index];
} }
const Array<VertexAttributeVersion, VertexArrayObject::MAX_VERTEX_ATTRIBS>& VertexArrayObject:: const Array<VertexAttributeVersion, VertexArrayObject::MAX_VERTEX_ATTRIBS>& VertexArrayObject::
GetAllAttributeVersions() const { GetAllAttributeVersions() const {
return m_attributeVersions; return m_attributeVersions;
} }
} // namespace GLState } // namespace MobileGL::MG_State::GLState
} // namespace MG_State
} // namespace MobileGL
@@ -8,76 +8,74 @@
#include "VertexArrayState.h" #include "VertexArrayState.h"
namespace MobileGL { namespace MobileGL::MG_State::GLState {
namespace MG_State { VertexArrayState::VertexArrayState() : m_indexGenerator(1024, 1) {
namespace GLState { // Generate default VAO at index 0, which is not valid in core profile, but still remains for
VertexArrayState::VertexArrayState() : m_indexGenerator(1024, 1) { // compatibility reasons.
// Generate default VAO at index 0, which is not valid in core profile, but still remains for m_indexGenerator.Insert(0);
// compatibility reasons. auto defaultVAO = MakeShared<VertexArrayObject>(0);
m_indexGenerator.Insert(0); m_vertexArrays.push_back(defaultVAO);
auto defaultVAO = MakeShared<VertexArrayObject>(0); m_boundVertexArray = defaultVAO;
m_vertexArrays.push_back(defaultVAO); }
m_boundVertexArray = defaultVAO;
const SharedPtr<VertexArrayObject>& VertexArrayState::GetVertexArrayObject(Uint index) {
if (index >= m_vertexArrays.size()) {
// FIXME: report a GL error here
static SharedPtr<VertexArrayObject> nullVertexArrayObject = nullptr;
return nullVertexArrayObject;
}
return m_vertexArrays[index];
}
void VertexArrayState::GenerateNames(Uint number, Vector<Uint>& arrays) {
arrays.resize(number);
m_indexGenerator.Generate(number, arrays.data());
}
void VertexArrayState::Bind(Uint index) {
m_boundVertexArray = GetVertexArrayObject(index);
}
const SharedPtr<VertexArrayObject>& VertexArrayState::CreateVertexArrayObject(Uint index) {
if (index >= m_vertexArrays.size()) {
// power-of-2 reallocation
m_vertexArrays.reserve(std::bit_ceil(index + 1));
m_vertexArrays.resize(index + 1, nullptr);
}
auto& vao = m_vertexArrays[index];
vao = MakeShared<VertexArrayObject>(index);
return vao;
}
void VertexArrayState::MarkVertexArrayForDeletion(Uint index) {
if (m_indexGenerator.IsValid(index)) {
if (m_boundVertexArray) {
m_boundVertexArray = nullptr;
} }
SharedPtr<VertexArrayObject> VertexArrayState::GetVertexArrayObject(Uint index) { if (ValidateVertexArrayObject(index)) {
if (index >= m_vertexArrays.size()) m_vertexArrays[index] = nullptr;
// FIXME: report a GL error here
return nullptr;
return m_vertexArrays[index];
} }
Vector<Uint> VertexArrayState::GenerateNames(Uint number) { m_indexGenerator.Delete(index);
Vector<Uint> arrays(number); }
m_indexGenerator.Generate(number, arrays.data()); // FIXME: report GL error here?
return arrays; }
}
void VertexArrayState::Bind(Uint index) { Bool VertexArrayState::ValidateName(Uint index) const {
m_boundVertexArray = GetVertexArrayObject(index); return m_indexGenerator.IsValid(index);
} }
SharedPtr<VertexArrayObject> VertexArrayState::CreateVertexArrayObject(Uint index) { Bool VertexArrayState::ValidateVertexArrayObject(Uint index) const {
if (index >= m_vertexArrays.size()) { return index < m_vertexArrays.size() && m_vertexArrays[index] != nullptr;
// power-of-2 reallocation }
m_vertexArrays.reserve(std::bit_ceil(index + 1));
m_vertexArrays.resize(index + 1, nullptr);
}
auto vao = m_vertexArrays[index] = MakeShared<VertexArrayObject>(index);
return vao;
}
void VertexArrayState::MarkVertexArrayForDeletion(Uint index) { const SharedPtr<VertexArrayObject>& VertexArrayState::GetBoundVertexArray() {
if (m_indexGenerator.IsValid(index)) { return m_boundVertexArray;
if (m_boundVertexArray) { }
m_boundVertexArray = nullptr;
}
if (ValidateVertexArrayObject(index)) { Vector<SharedPtr<VertexArrayObject>>& VertexArrayState::GetAllVertexArrays() {
m_vertexArrays[index] = nullptr; return m_vertexArrays;
} }
} // namespace MobileGL::MG_State::GLState
m_indexGenerator.Delete(index);
}
// FIXME: report GL error here?
}
Bool VertexArrayState::ValidateName(Uint index) const {
return m_indexGenerator.IsValid(index);
}
Bool VertexArrayState::ValidateVertexArrayObject(Uint index) const {
return index < m_vertexArrays.size() && m_vertexArrays[index] != nullptr;
}
SharedPtr<VertexArrayObject> VertexArrayState::GetBoundVertexArray() {
return m_boundVertexArray;
}
Vector<SharedPtr<VertexArrayObject>>& VertexArrayState::GetAllVertexArrays() {
return m_vertexArrays;
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
@@ -18,14 +18,14 @@ namespace MobileGL {
public: public:
VertexArrayState(); VertexArrayState();
SharedPtr<VertexArrayObject> GetVertexArrayObject(Uint index); const SharedPtr<VertexArrayObject>& GetVertexArrayObject(Uint index);
Vector<Uint> GenerateNames(Uint number); void GenerateNames(Uint number, Vector<Uint>& arrays);
void Bind(Uint index); void Bind(Uint index);
SharedPtr<VertexArrayObject> CreateVertexArrayObject(Uint index); const SharedPtr<VertexArrayObject>& CreateVertexArrayObject(Uint index);
void MarkVertexArrayForDeletion(Uint index); void MarkVertexArrayForDeletion(Uint index);
Bool ValidateName(Uint index) const; Bool ValidateName(Uint index) const;
Bool ValidateVertexArrayObject(Uint index) const; Bool ValidateVertexArrayObject(Uint index) const;
SharedPtr<VertexArrayObject> GetBoundVertexArray(); const SharedPtr<VertexArrayObject>& GetBoundVertexArray();
Vector<SharedPtr<VertexArrayObject>>& GetAllVertexArrays(); Vector<SharedPtr<VertexArrayObject>>& GetAllVertexArrays();
private: private:
+4 -4
View File
@@ -148,15 +148,15 @@ namespace MobileGL {
public: public:
using TargetEnum = typename ObjectType::TargetEnum; using TargetEnum = typename ObjectType::TargetEnum;
BindingSlot() : m_target((TargetEnum)0), m_boundObject(nullptr) {} BindingSlot() : m_target((TargetEnum)0) {}
explicit BindingSlot(TargetEnum target) : m_target(target), m_boundObject(nullptr) {} explicit BindingSlot(TargetEnum target) : m_target(target) {}
void Bind(SharedPtr<ObjectType> object) { void Bind(SharedPtr<ObjectType> object) {
if (m_boundObject == object) return; if (m_boundObject == object) return;
m_boundObject = object; m_boundObject = Move(object);
++m_version; ++m_version;
} }
SharedPtr<ObjectType> GetBoundObject() const { return m_boundObject; } SharedPtr<ObjectType> const& GetBoundObject() const noexcept { return m_boundObject; }
TargetEnum GetTarget() const { return m_target; } TargetEnum GetTarget() const { return m_target; }
Uint16 GetVersion() const { return m_version; } Uint16 GetVersion() const { return m_version; }