Merge remote-tracking branch 'origin/Feat/Backend-Direct-GLES' into Feat/Backend-Direct-GLES

This commit is contained in:
BZLZHH
2025-12-14 08:17:48 +08:00
28 changed files with 977 additions and 282 deletions
+3
View File
@@ -10,3 +10,6 @@
[submodule "include/FastSTL"]
path = include/FastSTL
url = https://github.com/MobileGL-Dev/FastSTL.git
[submodule "3rdparty/tracy"]
path = 3rdparty/tracy
url = https://github.com/wolfpld/tracy.git
Vendored Submodule
+1
Submodule 3rdparty/tracy added at e6b9ea4609
+22 -2
View File
@@ -15,9 +15,9 @@ if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug" OR MOBILEGL_FORCE_RELEASE_OPT)
add_compile_options(-O3 -ffunction-sections -fdata-sections)
add_link_options(-Wl,--gc-sections)
elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
add_compile_options(/O2 /GL)
# add_compile_options(/O2)
else ()
add_compile_options(-O3)
add_compile_options(-O2)
endif()
endif()
@@ -77,6 +77,18 @@ set(SPIRV_CROSS_STATIC ON CACHE BOOL "Prefer static libs" FORCE)
add_subdirectory(3rdparty/glslang)
add_subdirectory(3rdparty/SPIRV-Cross)
option(TRACY_ENABLE "Enable Tracy" OFF)
if (TRACY_ENABLE)
set(TRACY_ON_DEMAND ON CACHE BOOL "Enable profiling only connected" FORCE)
set(TRACY_NO_EXIT OFF CACHE BOOL "Don't exit Tracy until connected" FORCE)
set(TRACY_DELAYED_INIT ON CACHE BOOL "Don't init Tracy on library load" FORCE)
set(TRACY_MANUAL_LIFETIME ON CACHE BOOL "Manually control Tracy lifetime" FORCE)
set(TRACY_NO_CRASH_HANDLER ON CACHE BOOL "Disable crash handling" FORCE)
add_subdirectory(3rdparty/tracy)
endif ()
set(SOURCE_FILES
MobileGL/Init.cpp
@@ -165,6 +177,7 @@ set(SOURCE_FILES
MobileGL/MG_State/GLState/TextureState/TextureObject2D.cpp
MobileGL/MG_State/GLState/TextureState/TextureObject2DCube.cpp
MobileGL/MG_State/GLState/TextureState/TextureObject3D.cpp
MobileGL/MG_State/GLState/TextureState/TextureObjectBuffer.cpp
MobileGL/MG_State/GLState/TextureState/TextureUnit.cpp
MobileGL/MG_State/GLState/TextureState/TextureState.cpp
MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp
@@ -249,6 +262,13 @@ target_link_libraries(${CMAKE_PROJECT_NAME}_s
spirv-cross-c
)
if (TRACY_ENABLE)
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC Tracy::TracyClient)
target_link_libraries(${CMAKE_PROJECT_NAME}_s PUBLIC Tracy::TracyClient)
target_compile_definitions(${CMAKE_PROJECT_NAME} PUBLIC -DTRACY_ENABLE)
target_compile_definitions(${CMAKE_PROJECT_NAME}_s PUBLIC -DTRACY_ENABLE)
endif ()
if (ANDROID)
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC
android
+2 -2
View File
@@ -31,7 +31,7 @@
#define MOBILEGL_BACKEND_TYPE_DIRECT_GLES 3
// ====================== MobileGL configurations ======================= //
#define MOBILEGL_LOG_ACTIVE_LEVEL MOBILEGL_LOG_LEVEL_DEBUG
#define MOBILEGL_LOG_ACTIVE_LEVEL MOBILEGL_LOG_LEVEL_FATAL
#define MOBILEGL_LOG_ENABLE_CONSOLE 0
#define MOBILEGL_LOG_ENABLE_FILE 1
@@ -43,7 +43,7 @@
#define MOBILEGL_LOG_FILE_PATH ""
#endif
#if _MSC_VER
#if defined _MSC_VER or defined __MINGW32__ or defined __MINGW64__
#define TRAP assert(false)
#elif __clang__
#define TRAP __builtin_debugtrap()
+8
View File
@@ -33,6 +33,7 @@
#include <string_view>
#include <unordered_map>
#include <mutex>
#include <bitset>
// Include FastSTL
#include <FastSTL/UnorderedMap.h>
@@ -76,6 +77,13 @@
#include <vulkan/vulkan_android.h>
#endif
#ifdef TRACY_ENABLE
#include <tracy/Tracy.hpp>
#define TRACY_ZONECOLOR_ENTRY 0xFF0000
#define TRACY_ZONECOLOR_FRONTEND 0x00FF00
#define TRACY_ZONECOLOR_BACKEND 0x00FF00
#endif
// Post-includes for significant project headers
#include "MG_Util/Debug/Log.h"
#include "MG_Util/Types.h"
+172 -97
View File
@@ -30,24 +30,21 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
namespace DebugImpl {
void ErrorLopper::Loop(std::function<void(GLenum)> func) {
#if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG
void ErrorLopper::Loop(std::function<void(GLenum)> func) {
GLenum err = MG_External::GLES::glGetError();
while (err != GL_NO_ERROR) {
func(err);
err = MG_External::GLES::glGetError();
}
#endif
}
void ErrorLopper::Clear() {
#if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG
GLenum err = MG_External::GLES::glGetError();
while (err != GL_NO_ERROR) {
MGLOG_D("Stray GL Error cleared: %s", MG_Util::ConvertGLEnumToString(err).c_str());
err = MG_External::GLES::glGetError();
}
#endif
}
ErrorLopper::ErrorLopper() {
@@ -56,12 +53,21 @@ namespace MobileGL::MG_Backend::DirectGLES {
ErrorLopper::~ErrorLopper() {
Clear();
}
#else
void ErrorLopper::Loop(std::function<void(GLenum)> func) {}
void ErrorLopper::Clear() {}
ErrorLopper::ErrorLopper() {}
ErrorLopper::~ErrorLopper() {}
#endif
} // namespace DebugImpl
// TODO: deletion for deleted objects
namespace BufferImpl {
void SyncNeccessaryBuffers(Bool includeIBO = false, Bool includeIndirectBuffer = false) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
// All buffers we need are:
// 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
@@ -138,6 +144,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
namespace VertexArrayImpl {
void SyncCurrentVAO(Bool needDivisor) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
auto currentVAOObject = MG_State::pGLContext->GetBoundVertexArray();
if (!currentVAOObject) {
MGLOG_E("No VAO is currently bound, cannot sync current VAO.");
@@ -159,6 +168,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
namespace TextureImpl {
SharedPtr<BackendTextureObject> SyncTextureObjectToBackend(
SharedPtr<MG_State::GLState::ITextureObject>& textureObject) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
const auto& backendTextureIt = g_backendTextureObjects.find(textureObject);
SharedPtr<BackendTextureObject> backendTextureObject;
if (backendTextureIt == g_backendTextureObjects.end()) {
@@ -172,10 +184,15 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
void SyncNeccessaryTextures() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
// All textures we need are:
// 1. textures bound to texture units (TODO: only sync ones that are used in current program)
// 2. textures used in current FBO
// 3. textures bound to image units (TODO)
constexpr SizeT TextureTargetCount = static_cast<SizeT>(TextureTarget::TextureTargetCount);
std::bitset<TextureTargetCount> dirtyTextureTargetBits;
Vector<SharedPtr<MG_State::GLState::ITextureObject>> texturesToSync;
@@ -187,6 +204,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
const auto& end = texturesToSync.end();
if (std::find(texturesToSync.begin(), end, textureObject) == end) {
texturesToSync.push_back(textureObject);
dirtyTextureTargetBits.set(static_cast<SizeT>(textureObject->GetTarget()));
}
}
}
@@ -202,11 +220,23 @@ namespace MobileGL::MG_Backend::DirectGLES {
const auto& end = texturesToSync.end();
if (std::find(texturesToSync.begin(), end, textureObject) == end) {
texturesToSync.push_back(textureObject);
dirtyTextureTargetBits.set(static_cast<SizeT>(textureObject->GetTarget()));
}
}
}
}
BufferImpl::BackendBufferBindingProtector pixelUnpackProtector =
BufferImpl::BackendBufferBindingProtector(GL_PIXEL_UNPACK_BUFFER);
Vector<BackendTextureBindingProtector> textureBindingProtectors;
for (SizeT target = 0; target < TextureTargetCount; ++target) {
if (dirtyTextureTargetBits[target]) {
textureBindingProtectors.emplace_back(
MG_Util::ConvertTextureTargetToGLEnum(static_cast<TextureTarget>(target)));
}
}
// Do real sync
for (auto& textureObject : texturesToSync) {
SyncTextureObjectToBackend(textureObject);
@@ -216,6 +246,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
namespace FramebufferImpl {
void SyncCurrentFBO() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
const FramebufferTarget fboTargets[] = {FramebufferTarget::Draw, FramebufferTarget::Read};
MG_State::GLState::FramebufferObject* lastUpdatedFBO = nullptr;
@@ -257,6 +290,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
namespace RenderStateImpl {
void SyncRenderState() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
MG_External::GLES::glViewport(
MG_State::pGLContext->GetViewport().x(), MG_State::pGLContext->GetViewport().y(),
MG_State::pGLContext->GetViewport().z(), MG_State::pGLContext->GetViewport().w());
@@ -317,6 +353,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
namespace PrgramImpl {
void SyncCurrentProgram() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
auto currentProgram = MG_State::pGLContext->GetCurrentProgram();
if (!currentProgram || !currentProgram->GetLinkStatus()) {
MG_External::GLES::glUseProgram(0);
@@ -338,6 +377,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
} // namespace PrgramImpl
void BindCurrentFBO(FramebufferTarget target) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
const auto& currentFBO = MG_State::pGLContext->GetFramebufferBindingSlot(target).GetBoundObject();
if (currentFBO && currentFBO != MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo->defaultFBO) {
const auto& backendFBOIt = FramebufferImpl::g_backendFramebufferObjects.find(currentFBO);
@@ -355,6 +397,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
void PrepareForDraw(DrawSyncBit syncBit) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
BufferImpl::SyncNeccessaryBuffers(syncBit & DrawSyncBit::IndexBuffer, syncBit & DrawSyncBit::IndirectBuffer);
VertexArrayImpl::SyncCurrentVAO(syncBit & DrawSyncBit::Instancing);
TextureImpl::SyncNeccessaryTextures();
@@ -364,63 +409,79 @@ namespace MobileGL::MG_Backend::DirectGLES {
BindCurrentFBO(FramebufferTarget::Draw);
const auto& currentVAO = MG_State::pGLContext->GetBoundVertexArray();
if (currentVAO) {
const auto& backendVAOIt = VertexArrayImpl::g_backendVertexArrayObjects.find(currentVAO);
if (backendVAOIt != VertexArrayImpl::g_backendVertexArrayObjects.end()) {
backendVAOIt->second->Bind();
}
} else {
MG_External::GLES::glBindVertexArray(0);
}
Int maxTextureUnits = MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS;
for (Int unit = 0; unit < maxTextureUnits; ++unit) {
auto& textureUnit = MG_State::pGLContext->GetTextureUnitObject(unit);
MG_External::GLES::glActiveTexture(GL_TEXTURE0 + unit);
for (const auto& bindingSlot : textureUnit.GetAllBindingSlots()) {
const auto& textureObject = bindingSlot.GetBoundObject();
if (!textureObject) continue;
// Bind texture object
auto target = textureObject->GetTarget();
if (target == TextureTarget::TextureBuffer || target == TextureTarget::Texture1D ||
target == TextureTarget::TextureRectangle || target == TextureTarget::Texture2DMultisampleArray ||
target == TextureTarget::Texture1DArray || target == TextureTarget::Texture3D ||
target == TextureTarget::Texture2DMultisample || target == TextureTarget::Texture2DArray) {
MGLOG_D(" Texture target %s is not supported, skipping.",
MG_Util::ConvertTextureTargetToString(target).c_str());
continue;
}
const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject);
if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) continue;
GLenum targetGL = MG_Util::ConvertTextureTargetToGLEnum(target);
backendTextureIt->second->Bind(targetGL);
}
// Bind sampler object
const auto& samplerObject = textureUnit.GetSamplerObject();
if (samplerObject) {
const auto& backendSamplerIt = SamplerImpl::g_backendSamplerObjects.find(samplerObject);
if (backendSamplerIt != SamplerImpl::g_backendSamplerObjects.end()) {
backendSamplerIt->second->Bind(unit);
{
#ifdef TRACY_ENABLE
ZoneScopedNC("BindCurrentVAO", TRACY_ZONECOLOR_BACKEND);
#endif
const auto& currentVAO = MG_State::pGLContext->GetBoundVertexArray();
if (currentVAO) {
const auto& backendVAOIt = VertexArrayImpl::g_backendVertexArrayObjects.find(currentVAO);
if (backendVAOIt != VertexArrayImpl::g_backendVertexArrayObjects.end()) {
backendVAOIt->second->Bind();
}
} else {
MG_External::GLES::glBindSampler(unit, 0);
MG_External::GLES::glBindVertexArray(0);
}
}
{
#ifdef TRACY_ENABLE
ZoneScopedNC("BindCurrentTextures", TRACY_ZONECOLOR_BACKEND);
#endif
Int maxTextureUnits = MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS;
for (Int unit = 0; unit < maxTextureUnits; ++unit) {
auto& textureUnit = MG_State::pGLContext->GetTextureUnitObject(unit);
MG_External::GLES::glActiveTexture(GL_TEXTURE0 + unit);
for (const auto& bindingSlot : textureUnit.GetAllBindingSlots()) {
const auto& textureObject = bindingSlot.GetBoundObject();
if (!textureObject) continue;
// Bind texture object
auto target = textureObject->GetTarget();
if (target == TextureTarget::Texture1D ||
target == TextureTarget::TextureRectangle || target == TextureTarget::Texture2DMultisampleArray ||
target == TextureTarget::Texture1DArray || target == TextureTarget::Texture3D ||
target == TextureTarget::Texture2DMultisample || target == TextureTarget::Texture2DArray) {
MGLOG_D(" Texture target %s is not supported, skipping.",
MG_Util::ConvertTextureTargetToString(target).c_str());
continue;
}
const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject);
if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) continue;
GLenum targetGL = MG_Util::ConvertTextureTargetToGLEnum(target);
backendTextureIt->second->Bind(targetGL);
}
// Bind sampler object
const auto& samplerObject = textureUnit.GetSamplerObject();
if (samplerObject) {
const auto& backendSamplerIt = SamplerImpl::g_backendSamplerObjects.find(samplerObject);
if (backendSamplerIt != SamplerImpl::g_backendSamplerObjects.end()) {
backendSamplerIt->second->Bind(unit);
}
} else {
MG_External::GLES::glBindSampler(unit, 0);
}
}
}
const auto& currentProgram = MG_State::pGLContext->GetCurrentProgram();
if (currentProgram && currentProgram->GetLinkStatus()) {
#ifdef TRACY_ENABLE
ZoneScopedNC("BindCurrentProgram", TRACY_ZONECOLOR_BACKEND);
#endif
const auto& backendProgramIt = PrgramImpl::g_backendProgramObjects.find(currentProgram);
if (backendProgramIt != PrgramImpl::g_backendProgramObjects.end()) {
backendProgramIt->second->Use();
auto backendProgramId = backendProgramIt->second->GetBackendProgramId();
// Global UBO
if (currentProgram->GetUBOSize() > 0) {
#ifdef TRACY_ENABLE
ZoneScopedNC("UpdateGlobalUBO", TRACY_ZONECOLOR_BACKEND);
#endif
MG_External::GLES::glBindBuffer(GL_UNIFORM_BUFFER,
backendProgramIt->second->GetBackendGlobalUBOId());
MG_External::GLES::glBufferSubData(GL_UNIFORM_BUFFER, 0, currentProgram->GetUBOSize(),
@@ -435,67 +496,78 @@ namespace MobileGL::MG_Backend::DirectGLES {
MG_External::GLES::glBindBufferBase(GL_UNIFORM_BUFFER, 0,
backendProgramIt->second->GetBackendGlobalUBOId());
}
// Normal UBO
auto uboCount = currentProgram->GetActiveUniformBlocksCount();
Uint lastUBOBinding = 0; // to prevent overlapping bindings between global UBO and normal UBOs
for (Int i = 0; i < uboCount; ++i) {
++lastUBOBinding;
// program state binding index == backend binding index
// Connect program ubo index to backend binding point
auto binding = currentProgram->GetUniformBlockBinding(i);
auto& name = currentProgram->GetUniformBlockName(i);
GLuint backendBlkIdx = MG_External::GLES::glGetUniformBlockIndex(backendProgramId, name.c_str());
MG_External::GLES::glUniformBlockBinding(backendProgramId, backendBlkIdx, lastUBOBinding);
{
#ifdef TRACY_ENABLE
ZoneScopedNC("UpdateUBO", TRACY_ZONECOLOR_BACKEND);
#endif
// Normal UBO
auto uboCount = currentProgram->GetActiveUniformBlocksCount();
Uint lastUBOBinding = 0; // to prevent overlapping bindings between global UBO and normal UBOs
for (Int i = 0; i < uboCount; ++i) {
++lastUBOBinding;
// program state binding index == backend binding index
// Connect buffer to backend binding point
auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::Uniform, binding);
auto bufferObj = point.GetBoundObject();
auto range = point.GetRange();
// Connect program ubo index to backend binding point
auto binding = currentProgram->GetUniformBlockBinding(i);
auto& name = currentProgram->GetUniformBlockName(i);
GLuint backendBlkIdx = MG_External::GLES::glGetUniformBlockIndex(backendProgramId, name.c_str());
MG_External::GLES::glUniformBlockBinding(backendProgramId, backendBlkIdx, lastUBOBinding);
if (bufferObj) {
const auto& backendBufferIt = BufferImpl::g_backendBufferObjects.find(bufferObj);
if (backendBufferIt != BufferImpl::g_backendBufferObjects.end()) {
const auto& backendBufferObject = backendBufferIt->second;
backendBufferObject->Bind(GL_UNIFORM_BUFFER);
if (range.end == 0) {
MG_External::GLES::glBindBufferBase(GL_UNIFORM_BUFFER, lastUBOBinding,
backendBufferObject->GetBackendBufferId());
// Connect buffer to backend binding point
auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::Uniform, binding);
auto bufferObj = point.GetBoundObject();
auto range = point.GetRange();
if (bufferObj) {
const auto& backendBufferIt = BufferImpl::g_backendBufferObjects.find(bufferObj);
if (backendBufferIt != BufferImpl::g_backendBufferObjects.end()) {
const auto& backendBufferObject = backendBufferIt->second;
backendBufferObject->Bind(GL_UNIFORM_BUFFER);
if (range.end == 0) {
MG_External::GLES::glBindBufferBase(GL_UNIFORM_BUFFER, lastUBOBinding,
backendBufferObject->GetBackendBufferId());
} else {
MG_External::GLES::glBindBufferRange(GL_UNIFORM_BUFFER, lastUBOBinding,
backendBufferObject->GetBackendBufferId(),
range.start, range.end - range.start);
}
} else {
MG_External::GLES::glBindBufferRange(GL_UNIFORM_BUFFER, lastUBOBinding,
backendBufferObject->GetBackendBufferId(),
range.start, range.end - range.start);
MGLOG_E("No backend buffer found for UBO binding, cannot bind UBO.");
}
} else {
MGLOG_E("No backend buffer found for UBO binding, cannot bind UBO.");
}
}
}
// Sampler unit binding
auto maxUniformLoc = currentProgram->GetMaxUniformLocation();
for (int loc = 0; loc < maxUniformLoc; ++loc) {
auto unit = currentProgram->GetUniformSamplerOrImageUnitIndex(loc);
if (unit == -1) continue;
auto& name = currentProgram->GetUniformName(loc);
auto locAtBackend = MG_External::GLES::glGetUniformLocation(
backendProgramIt->second->GetBackendProgramId(), name.c_str());
MG_External::GLES::glUniform1i(locAtBackend, unit);
{
#ifdef TRACY_ENABLE
ZoneScopedNC("BindSamplerUnit", TRACY_ZONECOLOR_BACKEND);
#endif
// Sampler unit binding
auto maxUniformLoc = currentProgram->GetMaxUniformLocation();
for (int loc = 0; loc < maxUniformLoc; ++loc) {
auto unit = currentProgram->GetUniformSamplerOrImageUnitIndex(loc);
if (unit == -1) continue;
auto& name = currentProgram->GetUniformName(loc);
auto locAtBackend = MG_External::GLES::glGetUniformLocation(
backendProgramIt->second->GetBackendProgramId(), name.c_str());
MG_External::GLES::glUniform1i(locAtBackend, unit);
auto samplerObject = MG_State::pGLContext->GetTextureUnitObject(unit).GetSamplerObject();
auto samplerObject = MG_State::pGLContext->GetTextureUnitObject(unit).GetSamplerObject();
if (samplerObject) {
const auto& backendSamplerIt = SamplerImpl::g_backendSamplerObjects.find(samplerObject);
SharedPtr<SamplerImpl::BackendSamplerObject> backendSamplerObject;
if (backendSamplerIt == SamplerImpl::g_backendSamplerObjects.end()) {
backendSamplerObject = MakeShared<SamplerImpl::BackendSamplerObject>();
SamplerImpl::g_backendSamplerObjects[samplerObject] = backendSamplerObject;
if (samplerObject) {
const auto& backendSamplerIt = SamplerImpl::g_backendSamplerObjects.find(samplerObject);
SharedPtr<SamplerImpl::BackendSamplerObject> backendSamplerObject;
if (backendSamplerIt == SamplerImpl::g_backendSamplerObjects.end()) {
backendSamplerObject = MakeShared<SamplerImpl::BackendSamplerObject>();
SamplerImpl::g_backendSamplerObjects[samplerObject] = backendSamplerObject;
} else {
backendSamplerObject = backendSamplerIt->second;
}
backendSamplerObject->SyncToBackend(samplerObject);
} else {
backendSamplerObject = backendSamplerIt->second;
MG_External::GLES::glBindSampler(unit, 0);
}
backendSamplerObject->SyncToBackend(samplerObject);
} else {
MG_External::GLES::glBindSampler(unit, 0);
}
}
} else {
@@ -750,7 +822,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
auto textureObject = bindingSlot.GetBoundObject();
textureObject->SetInternalFormat(mglInternalFormat);
textureObject->AllocateStorage(TextureUploadTarget::Texture2D, level, {{width, height, 1}, 0});
MOBILEGL_ASSERT(nullptr != dynamic_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get()),
"Texture object here should always be an object with mipmap");
auto textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
textureMipmapObject->AllocateStorage(TextureUploadTarget::Texture2D, level, {{width, height, 1}, 0});
}
void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width,
+193 -79
View File
@@ -2,6 +2,8 @@
#include "MG_Backend/Backends.h"
#include "Utils.h"
#include "DirectGLES.h"
#include "MG_State/GLState/TextureState/TextureObjectBuffer.h"
#include <MG_Util/BackendLoaders/OpenGL/Loader.h>
#include <MG_Util/Converters/GLToStr/GLEnumConverter.h>
#include <MG_Util/Converters/MGToStr/TextureEnumConverter.h>
@@ -16,6 +18,9 @@
namespace MobileGL::MG_Backend::DirectGLES {
namespace BufferImpl {
BackendBufferObject::BackendBufferObject() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
MG_External::GLES::glGenBuffers(1, &m_backendBufferId);
if (m_backendBufferId == 0) {
MGLOG_E("Failed to generate buffer object.");
@@ -27,6 +32,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
const GLenum TempBufferTarget = GL_ARRAY_BUFFER;
void BackendBufferObject::SyncToBackend(SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
if (!stateBufferObject) {
MGLOG_E("State buffer object is null, cannot sync to backend.");
return;
@@ -72,6 +80,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
void BackendBufferObject::SyncToBackend_glBufferData(
SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
BackendBufferBindingProtector backendBufferBindingProtector(TempBufferTarget);
MGLOG_D("Syncing buffer data (glBufferData) for object with ID : %u", m_backendBufferId);
@@ -88,6 +99,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
void BackendBufferObject::SyncToBackend_glBufferSubData(
SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
BackendBufferBindingProtector backendBufferBindingProtector(TempBufferTarget);
MGLOG_D("Syncing buffer sub-data (glBufferSubData) for object with ID : %u", m_backendBufferId);
@@ -107,6 +121,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
void BackendBufferObject::SyncToBackend_glMapBufferRange(
SharedPtr<MG_State::GLState::BufferObject>& stateBufferObject, Bool invalidate) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
BackendBufferBindingProtector backendBufferBindingProtector(TempBufferTarget);
MGLOG_D("Syncing buffer map (glMapBuffer) for object with ID : %u", m_backendBufferId);
@@ -131,10 +148,16 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
void BackendBufferObject::Bind() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
MG_External::GLES::glBindBuffer(TempBufferTarget, m_backendBufferId);
}
void BackendBufferObject::Bind(GLenum target) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
MG_External::GLES::glBindBuffer(target, m_backendBufferId);
}
@@ -143,6 +166,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
namespace VertexArrayImpl {
BackendVertexArrayObject::BackendVertexArrayObject() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
MG_External::GLES::glGenVertexArrays(1, &m_backendVAOId);
if (m_backendVAOId == 0) {
MGLOG_E("Failed to generate vertex array object.");
@@ -153,11 +179,17 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
void BackendVertexArrayObject::Bind() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
MG_External::GLES::glBindVertexArray(m_backendVAOId);
}
void BackendVertexArrayObject::SyncToBackend(SharedPtr<MG_State::GLState::VertexArrayObject>& stateVAOObject,
Bool needDivisor) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
if (!stateVAOObject) {
MGLOG_E("State VAO object is null, cannot sync to backend.");
return;
@@ -231,6 +263,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
namespace TextureImpl {
BackendTextureObject::BackendTextureObject() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
MG_External::GLES::glGenTextures(1, &m_backendTextureId);
if (m_backendTextureId == 0) {
MGLOG_E("Failed to generate texture object.");
@@ -241,14 +276,23 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
void BackendTextureObject::Bind(GLenum target) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
MG_External::GLES::glBindTexture(target, m_backendTextureId);
}
Uint BackendTextureObject::GetBackendTextureId() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
return m_backendTextureId;
}
void BackendTextureObject::SyncToBackend(SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
DebugImpl::ErrorLopper errorLopper;
if (!stateTextureObject) {
MGLOG_E("State texture object is null, cannot sync to backend.");
@@ -262,7 +306,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
auto targetInternal = stateTextureObject->GetTarget();
MGLOG_D(" Texture target for syncing is %s",
MG_Util::ConvertTextureTargetToString(targetInternal).c_str());
if (targetInternal == TextureTarget::TextureBuffer || targetInternal == TextureTarget::Texture1D ||
if (targetInternal == TextureTarget::Texture1D ||
targetInternal == TextureTarget::TextureRectangle ||
targetInternal == TextureTarget::Texture2DMultisampleArray ||
targetInternal == TextureTarget::Texture1DArray || targetInternal == TextureTarget::Texture3D ||
@@ -284,63 +328,137 @@ namespace MobileGL::MG_Backend::DirectGLES {
return;
}
BackendTextureBindingProtector backendTextureBindingProtector(target);
// BackendTextureBindingProtector backendTextureBindingProtector(target);
Bind(target);
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());
});
const auto mipmapCount = stateTextureObject->GetMipmapLevelCount();
const auto baseSize = stateTextureObject->GetBaseSize();
StateTextureBasicInfo currentTextureInfo = {
stateTextureObject->GetFormat(), static_cast<SizeT>(baseSize.x()), static_cast<SizeT>(baseSize.y()),
static_cast<SizeT>(baseSize.z()), mipmapCount};
static_cast<SizeT>(baseSize.z()), 0, 0};
switch (stateTextureObject->GetStorageType()) {
case TextureStorageType::Mipmap: {
auto* textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(stateTextureObject.get());
const auto mipmapCount = textureMipmapObject->GetMipmapLevelCount();
currentTextureInfo.mipmapLevels = mipmapCount;
Bool needsRegeneration = !m_isInitialized || (currentTextureInfo != m_prevTextureInfo);
Bool needsRegeneration = !m_isInitialized || (currentTextureInfo != m_prevTextureInfo);
MGLOG_D("%s: Got texture info: %dx%dx%d, mips %d, format %s", __func__, baseSize.x(), baseSize.y(),
baseSize.z(), mipmapCount,
MG_Util::ConvertTextureInternalFormatToString(stateTextureObject->GetFormat()).c_str());
MGLOG_D("%s: Got texture info: %dx%dx%d, mips %d, format %s", __func__, baseSize.x(), baseSize.y(),
baseSize.z(), mipmapCount,
MG_Util::ConvertTextureInternalFormatToString(textureMipmapObject->GetFormat()).c_str());
if (needsRegeneration) {
MGLOG_D("Texture state changed significantly or not initialized, regenerating texture with ID: %u",
m_backendTextureId);
if (needsRegeneration) {
MGLOG_D("Texture state changed significantly or not initialized, regenerating texture with ID: %u",
m_backendTextureId);
// Regenerate all mipmap levels
GLenum glInternalFormat, glType, glFormat;
TextureImpl::GenerateTextureFormatInfo(stateTextureObject->GetFormat(), &glInternalFormat, &glType,
&glFormat);
// Regenerate all mipmap levels
GLenum glInternalFormat, glType, glFormat;
TextureImpl::GenerateTextureFormatInfo(textureMipmapObject->GetFormat(), &glInternalFormat, &glType,
&glFormat);
const auto& uploadTargets = stateTextureObject->GetUploadTargets();
for (auto uploadTarget : uploadTargets) {
for (SizeT level = 0; level < mipmapCount; ++level) {
auto levelTexelSize = stateTextureObject->GetMipmapTexelSize(uploadTarget, level);
auto levelByteSize = stateTextureObject->GetMipmapByteSize(uploadTarget, level);
bool levelDirty = stateTextureObject->IsStorageDirty(uploadTarget, 0);
auto glUploadTarget = MG_Util::ConvertTextureUploadTargetToGLEnum(uploadTarget);
auto* pData = (levelDirty && levelByteSize != 0)
? stateTextureObject->MapMipmapData(uploadTarget, level)
: nullptr;
MGLOG_D("%s: target: %s: syncing mip %d: %dx%dx%d, byteSize = %d, pData = %p", __func__,
MG_Util::ConvertTextureUploadTargetToString(uploadTarget).c_str(), level,
levelTexelSize.x(), levelTexelSize.y(), levelTexelSize.z(), levelByteSize, pData);
BufferImpl::BackendBufferBindingProtector pixelUnpackProtector =
BufferImpl::BackendBufferBindingProtector(GL_PIXEL_UNPACK_BUFFER);
errorLopper.Clear();
MG_External::GLES::glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
MG_External::GLES::glTexImage2D(glUploadTarget, static_cast<GLint>(level), glInternalFormat,
static_cast<GLsizei>(levelTexelSize.x()),
static_cast<GLsizei>(levelTexelSize.y()), 0, glFormat, glType,
pData);
const auto& uploadTargets = textureMipmapObject->GetUploadTargets();
for (auto uploadTarget : uploadTargets) {
for (SizeT level = 0; level < mipmapCount; ++level) {
auto levelTexelSize = textureMipmapObject->GetMipmapTexelSize(uploadTarget, level);
auto levelByteSize = textureMipmapObject->GetMipmapByteSize(uploadTarget, level);
bool levelDirty = textureMipmapObject->IsStorageDirty(uploadTarget, 0);
auto glUploadTarget = MG_Util::ConvertTextureUploadTargetToGLEnum(uploadTarget);
auto* pData = (levelDirty && levelByteSize != 0)
? textureMipmapObject->MapMipmapData(uploadTarget, level)
: nullptr;
MGLOG_D("%s: target: %s: syncing mip %d: %dx%dx%d, byteSize = %d, pData = %p", __func__,
MG_Util::ConvertTextureUploadTargetToString(uploadTarget).c_str(), level,
levelTexelSize.x(), levelTexelSize.y(), levelTexelSize.z(), levelByteSize, pData);
// TODO: handle more texture types
errorLopper.Clear();
MG_External::GLES::glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
MG_External::GLES::glTexImage2D(glUploadTarget, static_cast<GLint>(level), glInternalFormat,
static_cast<GLsizei>(levelTexelSize.x()),
static_cast<GLsizei>(levelTexelSize.y()), 0, glFormat, glType,
pData);
MGLOG_D("Regenerated mipmap level %d for texture with ID: %u", level, m_backendTextureId);
stateTextureObject->MarkStorageDirty(uploadTarget, level, false);
// TODO: handle more texture types
MGLOG_D("Regenerated mipmap level %d for texture with ID: %u", level, m_backendTextureId);
textureMipmapObject->MarkStorageDirty(uploadTarget, level, false);
}
}
m_isInitialized = true;
}
}
m_isInitialized = true;
{ // Update all dirty mipmap levels
const auto mipmapCount = textureMipmapObject->GetMipmapLevelCount();
GLenum glInternalFormat, glType, glFormat;
TextureImpl::GenerateTextureFormatInfo(textureMipmapObject->GetFormat(), &glInternalFormat, &glType,
&glFormat);
const auto& uploadTargets = textureMipmapObject->GetUploadTargets();
for (auto uploadTarget : uploadTargets) {
for (SizeT level = 0; level < mipmapCount; ++level) {
if (!textureMipmapObject->IsStorageDirty(uploadTarget, level)) {
continue;
}
auto byteSize = textureMipmapObject->GetMipmapByteSize(uploadTarget, level);
if (byteSize == 0) {
MGLOG_W("Mipmap level %d has no data, skipping update.", level);
continue;
}
auto glUploadTarget = MG_Util::ConvertTextureUploadTargetToGLEnum(uploadTarget);
MG_External::GLES::glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
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());
});
auto texelSize = textureMipmapObject->GetMipmapTexelSize(uploadTarget, level);
MG_External::GLES::glTexSubImage2D(glUploadTarget, static_cast<GLint>(level), 0, 0,
static_cast<GLsizei>(texelSize.x()),
static_cast<GLsizei>(texelSize.y()), glFormat, glType,
textureMipmapObject->MapMipmapData(uploadTarget, level));
textureMipmapObject->MarkStorageDirty(uploadTarget, level, false);
}
}
}
break;
}
case TextureStorageType::Buffer: {
auto* textureBufferObject = static_cast<MG_State::GLState::TextureObjectBuffer*>(stateTextureObject.get());
auto& slot = textureBufferObject->GetBufferBindingSlot();
auto buffer = slot.GetBoundObject();
auto bufferIndex = buffer->GetExternalIndex();
currentTextureInfo.bufferExternalIndex = bufferIndex;
Bool needsRegeneration = !m_isInitialized || (currentTextureInfo != m_prevTextureInfo);
MGLOG_D("Texture state changed significantly or not initialized, regenerating texture (tex buffer) with ID: %u",
m_backendTextureId);
// Need to sync texture buffer if not synced yet
auto& backendBuffers = BufferImpl::g_backendBufferObjects;
SharedPtr<BufferImpl::BackendBufferObject> backendBufferObject;
const auto& backendBufferIt = backendBuffers.find(buffer);
if (backendBufferIt == backendBuffers.end()) {
backendBufferObject = MakeShared<BufferImpl::BackendBufferObject>();
backendBuffers[buffer] = backendBufferObject;
} else {
backendBufferObject = backendBufferIt->second;
}
backendBufferObject->SyncToBackend(buffer);
// Bind buffer to texture
auto backendId = backendBufferObject->GetBackendBufferId();
GLenum glInternalFormat, glType, glFormat;
TextureImpl::GenerateTextureFormatInfo(textureBufferObject->GetFormat(), &glInternalFormat, &glType,
&glFormat);
MG_External::GLES::glTexBuffer(GL_TEXTURE_BUFFER, glInternalFormat, backendId);
break;
}
default: THROW_UNIMPL_EXCEPTION;
}
{ // Update built-in sampler parameters
@@ -448,43 +566,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
}
{ // Update all dirty mipmap levels
const auto mipmapCount = stateTextureObject->GetMipmapLevelCount();
GLenum glInternalFormat, glType, glFormat;
TextureImpl::GenerateTextureFormatInfo(stateTextureObject->GetFormat(), &glInternalFormat, &glType,
&glFormat);
const auto& uploadTargets = stateTextureObject->GetUploadTargets();
for (auto uploadTarget : uploadTargets) {
for (SizeT level = 0; level < mipmapCount; ++level) {
if (!stateTextureObject->IsStorageDirty(uploadTarget, level)) {
continue;
}
auto byteSize = stateTextureObject->GetMipmapByteSize(uploadTarget, level);
if (byteSize == 0) {
MGLOG_W("Mipmap level %d has no data, skipping update.", level);
continue;
}
auto glUploadTarget = MG_Util::ConvertTextureUploadTargetToGLEnum(uploadTarget);
BufferImpl::BackendBufferBindingProtector pixelUnpackProtector =
BufferImpl::BackendBufferBindingProtector(GL_PIXEL_UNPACK_BUFFER);
MG_External::GLES::glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
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());
});
auto texelSize = stateTextureObject->GetMipmapTexelSize(uploadTarget, level);
MG_External::GLES::glTexSubImage2D(glUploadTarget, static_cast<GLint>(level), 0, 0,
static_cast<GLsizei>(texelSize.x()),
static_cast<GLsizei>(texelSize.y()), glFormat, glType,
stateTextureObject->MapMipmapData(uploadTarget, level));
stateTextureObject->MarkStorageDirty(uploadTarget, level, false);
}
}
}
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());
});
@@ -498,6 +579,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
namespace FramebufferImpl {
BackendFramebufferObject::BackendFramebufferObject() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
MG_External::GLES::glGenFramebuffers(1, &m_backendFBOId);
if (m_backendFBOId == 0) {
MGLOG_E("Failed to generate framebuffer object.");
@@ -508,6 +592,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
void BackendFramebufferObject::Bind(FramebufferTarget target) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
if (target == FramebufferTarget::Read)
MG_External::GLES::glBindFramebuffer(GL_READ_FRAMEBUFFER, m_backendFBOId);
else
@@ -516,6 +603,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
void BackendFramebufferObject::SyncToBackend(SharedPtr<MG_State::GLState::FramebufferObject>& stateFBOObject,
FramebufferTarget asTarget) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
if (!stateFBOObject) {
MGLOG_E("State FBO object is null, cannot sync to backend.");
return;
@@ -621,6 +711,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
g_backendProgramObjects;
BackendProgramObjectImpl::BackendProgramObjectImpl() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
m_backendProgramId = MG_External::GLES::glCreateProgram();
if (m_backendProgramId == 0) {
MGLOG_E("Failed to create program object in backend.");
@@ -632,6 +725,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
BackendProgramObjectImpl::~BackendProgramObjectImpl() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
if (m_backendProgramId != 0) {
MGLOG_D("Deleting backend program object with ID: %u", m_backendProgramId);
MG_External::GLES::glDeleteProgram(m_backendProgramId);
@@ -639,6 +735,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
void BackendProgramObjectImpl::SyncToBackend(SharedPtr<MG_State::GLState::ProgramObject>& stateProgramObject) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
if (!stateProgramObject) {
MGLOG_E("State program object is null, skipping backend sync.");
return;
@@ -779,6 +878,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
void BackendProgramObjectImpl::Use() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
MGLOG_D("Using program %u", m_backendProgramId);
MG_External::GLES::glUseProgram(m_backendProgramId);
}
@@ -786,6 +888,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
namespace SamplerImpl {
BackendSamplerObject::BackendSamplerObject() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
MG_External::GLES::glGenSamplers(1, &m_backendSamplerId);
if (m_backendSamplerId == 0) {
MGLOG_E("Failed to generate sampler object.");
@@ -796,6 +901,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
void BackendSamplerObject::SyncToBackend(SharedPtr<MG_State::GLState::SamplerObject>& stateSamplerObject) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
if (!stateSamplerObject) {
MGLOG_E("State sampler object is null, cannot sync to backend.");
return;
@@ -846,10 +954,16 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
void BackendSamplerObject::Bind(Uint unit) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
MG_External::GLES::glBindSampler(static_cast<GLenum>(unit), m_backendSamplerId);
}
Uint BackendSamplerObject::GetBackendSamplerId() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
return m_backendSamplerId;
}
+2 -1
View File
@@ -54,10 +54,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
SizeT height = 0;
SizeT depth = 0;
SizeT mipmapLevels = 0;
Uint bufferExternalIndex = 0;
bool operator==(const StateTextureBasicInfo& other) const {
return internalFormat == other.internalFormat && width == other.width && height == other.height &&
depth == other.depth && mipmapLevels == other.mipmapLevels;
depth == other.depth && mipmapLevels == other.mipmapLevels && bufferExternalIndex == other.bufferExternalIndex;
}
bool operator!=(const StateTextureBasicInfo& other) const { return !(*this == other); }
+51
View File
@@ -11,37 +11,58 @@
namespace MobileGL::MG_Backend::DirectGLES {
namespace BufferImpl {
BackendBufferBindingProtector::BackendBufferBindingProtector(GLenum target) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
m_target = target;
MG_External::GLES::glGetIntegerv(Utils::GetBindingQuery(target, false), &m_previousBinding);
}
BackendBufferBindingProtector::~BackendBufferBindingProtector() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
MG_External::GLES::glBindBuffer(m_target, m_previousBinding);
}
} // namespace BufferImpl
namespace VertexArrayImpl {
BackendVertexArrayBindingProtector::BackendVertexArrayBindingProtector() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
MG_External::GLES::glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &m_previousBinding);
}
BackendVertexArrayBindingProtector::~BackendVertexArrayBindingProtector() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
MG_External::GLES::glBindVertexArray(m_previousBinding);
}
} // namespace VertexArrayImpl
namespace TextureImpl {
BackendTextureBindingProtector::BackendTextureBindingProtector(GLenum target) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
m_target = target;
MG_External::GLES::glGetIntegerv(Utils::GetBindingQuery(target, true), &m_previousBinding);
}
BackendTextureBindingProtector::~BackendTextureBindingProtector() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
MG_External::GLES::glBindTexture(m_target, m_previousBinding);
}
void NormalizePixelFormat(GLenum internalFormat, GLenum* outInternalFormat, GLenum* outType,
GLenum* outFormat) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
switch (internalFormat) {
case GL_DEPTH_COMPONENT16:
if (outInternalFormat) *outInternalFormat = internalFormat;
@@ -365,6 +386,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
void GenerateTextureFormatInfo(TextureInternalFormat internalFormat, GLenum* outInternalFormat, GLenum* outType,
GLenum* outFormat) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
NormalizePixelFormat(MG_Util::ConvertTextureInternalFormatToGLEnum(internalFormat), outInternalFormat,
outType, outFormat);
}
@@ -372,15 +396,24 @@ namespace MobileGL::MG_Backend::DirectGLES {
namespace FramebufferImpl {
BackendFramebufferBindingProtector::BackendFramebufferBindingProtector(GLenum target) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
m_target = target;
MG_External::GLES::glGetIntegerv(Utils::GetBindingQuery(target, false), &m_previousBinding);
}
BackendFramebufferBindingProtector::~BackendFramebufferBindingProtector() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
MG_External::GLES::glBindFramebuffer(m_target, m_previousBinding);
}
GLuint BackendFramebufferBindingProtector::GetTempFBO(FramebufferTarget target) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
GLenum glTarget = MG_Util::ConvertFramebufferTargetToGLEnum(target);
GLuint& fbo = (glTarget == GL_DRAW_FRAMEBUFFER) ? s_tempDrawFBO : s_tempReadFBO;
if (fbo == 0) {
@@ -390,6 +423,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
void BackendFramebufferBindingProtector::BindTempFBO(MobileGL::FramebufferTarget target) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
GLuint fbo = GetTempFBO(target);
GLenum glTarget = MG_Util::ConvertFramebufferTargetToGLEnum(target);
MG_External::GLES::glBindFramebuffer(glTarget, fbo);
@@ -398,12 +434,18 @@ namespace MobileGL::MG_Backend::DirectGLES {
namespace PrgramImpl {
String ProcessOutColorLocations(const String& glslCode) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
const static std::regex pattern(R"(\n(out highp vec4 outColor)(\d+);)");
const String replacement = "\nlayout(location=$2) $1$2;";
return std::regex_replace(glslCode, pattern, replacement);
}
String ForceSupporterOutput(const String& glslCode) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
Bool hasPrecisionFloat =
glslCode.find("precision ") != String::npos && glslCode.find("float;") != String::npos;
Bool hasPrecisionInt = glslCode.find("precision ") != String::npos && glslCode.find("int;") != String::npos;
@@ -460,6 +502,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
String RemoveLayoutBinding(const String& glslCode) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
static std::regex bindingRegex(R"(layout\s*\(\s*binding\s*=\s*\d+\s*\)\s*)");
String result = std::regex_replace(glslCode, bindingRegex, "");
static std::regex bindingRegex2(R"(layout\s*\(\s*binding\s*=\s*\d+\s*,)");
@@ -470,12 +515,18 @@ namespace MobileGL::MG_Backend::DirectGLES {
namespace Utils {
void CheckGLESError() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
while (GLenum err = MG_External::GLES::glGetError() != GL_NO_ERROR) {
MGLOG_E("-> GLES Error: %s", MG_Util::ConvertGLEnumToString(err).c_str());
}
}
GLenum GetBindingQuery(GLenum target, bool isTexture) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
switch (target) {
case GL_TEXTURE_BUFFER:
return isTexture ? GL_TEXTURE_BINDING_BUFFER : GL_TEXTURE_BUFFER_BINDING;
@@ -13,6 +13,9 @@ MOBILEGL_EGL_API EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint* attrib
MOBILEGL_EGL_API EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext shareCtx,
const EGLint* attrib_list) {
#ifdef TRACY_ENABLE
tracy::StartupProfiler();
#endif
return MobileGL::MG_Impl::EGLImpl::CreateContext(dpy, config, shareCtx, attrib_list);
}
@@ -33,6 +36,9 @@ MOBILEGL_EGL_API EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLS
}
MOBILEGL_EGL_API EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) {
#ifdef TRACY_ENABLE
tracy::ShutdownProfiler();
#endif
return MobileGL::MG_Impl::EGLImpl::DestroyContext(dpy, ctx);
}
@@ -73,6 +79,9 @@ MOBILEGL_EGL_API EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) {
}
MOBILEGL_EGL_API EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw) {
#ifdef TRACY_ENABLE
FrameMark;
#endif
return MobileGL::MG_Impl::EGLImpl::SwapBuffers(dpy, draw);
}
@@ -9,12 +9,18 @@
namespace MobileGL {
namespace MG_Impl::GLImpl {
void Clear_Backend(GLbitfield mask) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
MG_Backend::DirectGLES::Clear(mask);
#endif
}
void DrawElements_Backend(GLenum mode, GLsizei count, GLenum type, const void* indices) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
MG_Backend::DirectGLES::DrawElements(mode, count, type, indices);
#endif
@@ -22,6 +28,9 @@ namespace MobileGL {
void MultiDrawElements_Backend(GLenum mode, const GLsizei* count, GLenum type, const void* const* indices,
GLsizei drawcount) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
MG_Backend::DirectGLES::MultiDrawElements(mode, count, type, indices, drawcount);
#endif
@@ -30,12 +39,18 @@ namespace MobileGL {
void MultiDrawElementsBaseVertex_Backend(GLenum mode, const GLsizei* count, GLenum type,
const void* const* indices, GLsizei drawcount,
const GLint* basevertex) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
MG_Backend::DirectGLES::MultiDrawElementsBaseVertex(mode, count, type, indices, drawcount, basevertex);
#endif
}
void DrawArrays_Backend(GLenum mode, GLint first, GLsizei count) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
MG_Backend::DirectGLES::DrawArrays(mode, first, count);
#endif
@@ -43,6 +58,9 @@ namespace MobileGL {
void DrawElementsBaseVertex_Backend(GLenum mode, GLsizei count, GLenum type, const void* indices,
GLint basevertex) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
MG_Backend::DirectGLES::DrawElementsBaseVertex(mode, count, type, indices, basevertex);
#endif
@@ -50,12 +68,18 @@ namespace MobileGL {
void MultiDrawElementsIndirect_Backend(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount,
GLsizei stride) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
MG_Backend::DirectGLES::MultiDrawElementsIndirect(mode, type, indirect, drawcount, stride);
#endif
}
void MultiDrawArraysIndirect_Backend(GLenum mode, const void* indirect, GLsizei drawcount, GLsizei stride) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
MG_Backend::DirectGLES::MultiDrawArraysIndirect(mode, indirect, drawcount, stride);
#endif
@@ -63,6 +87,9 @@ namespace MobileGL {
void DrawRangeElementsBaseVertex_Backend(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type,
const void* indices, GLint basevertex) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
MG_Backend::DirectGLES::DrawRangeElementsBaseVertex(mode, start, end, count, type, indices, basevertex);
#endif
@@ -70,6 +97,9 @@ namespace MobileGL {
void DrawRangeElements_Backend(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type,
const void* indices) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
MG_Backend::DirectGLES::DrawRangeElements(mode, start, end, count, type, indices);
#endif
@@ -78,6 +108,9 @@ namespace MobileGL {
void DrawElementsInstancedBaseVertexBaseInstance_Backend(GLenum mode, GLsizei count, GLenum type,
const void* indices, GLsizei instancecount,
GLint basevertex, GLuint baseinstance) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
MG_Backend::DirectGLES::DrawElementsInstancedBaseVertexBaseInstance(
mode, count, type, indices, instancecount, basevertex, baseinstance);
@@ -86,6 +119,9 @@ namespace MobileGL {
void DrawElementsInstancedBaseVertex_Backend(GLenum mode, GLsizei count, GLenum type, const void* indices,
GLsizei instancecount, GLint basevertex) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
MG_Backend::DirectGLES::DrawElementsInstancedBaseVertex(mode, count, type, indices, instancecount,
basevertex);
@@ -94,6 +130,9 @@ namespace MobileGL {
void DrawElementsInstancedBaseInstance_Backend(GLenum mode, GLsizei count, GLenum type, const void* indices,
GLsizei instancecount, GLuint baseinstance) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
MG_Backend::DirectGLES::DrawElementsInstancedBaseInstance(mode, count, type, indices, instancecount,
baseinstance);
@@ -102,30 +141,45 @@ namespace MobileGL {
void DrawElementsInstanced_Backend(GLenum mode, GLsizei count, GLenum type, const void* indices,
GLsizei instancecount) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
MG_Backend::DirectGLES::DrawElementsInstanced(mode, count, type, indices, instancecount);
#endif
}
void DrawElementsIndirect_Backend(GLenum mode, GLenum type, const void* indirect) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
MG_Backend::DirectGLES::DrawElementsIndirect(mode, type, indirect);
#endif
}
void DrawArraysInstancedBaseInstance_Backend(GLenum mode, GLint first, GLsizei count, GLsizei instancecount,
GLuint baseinstance) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
MG_Backend::DirectGLES::DrawArraysInstancedBaseInstance(mode, first, count, instancecount, baseinstance);
#endif
}
void DrawArraysInstanced_Backend(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
MG_Backend::DirectGLES::DrawArraysInstanced(mode, first, count, instancecount);
#endif
}
void DrawArraysIndirect_Backend(GLenum mode, const void* indirect) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
MG_Backend::DirectGLES::DrawArraysIndirect(mode, indirect);
#endif
@@ -24,15 +24,29 @@ MOBILEGL_GL_API type gl##name(__VA_ARGS__) {
#define DECLARE_GL_FUNCTION_HEAD(type,name,...) \
MOBILEGL_GL_API type gl##name(__VA_ARGS__) {
#define DECLARE_GL_FUNCTION_END(type,name,...) \
MGLOG_D("Implementing function: %s(...)", __FUNCTION__); \
return MobileGL::MG_Impl::GLImpl::name(__VA_ARGS__); \
}
#ifdef TRACY_ENABLE
#define DECLARE_GL_FUNCTION_END(type,name,...) \
ZoneScopedC(TRACY_ZONECOLOR_ENTRY); \
MGLOG_D("Implementing function: %s(...)", __FUNCTION__); \
return MobileGL::MG_Impl::GLImpl::name(__VA_ARGS__); \
}
#define DECLARE_GL_FUNCTION_END_NO_RETURN(type,name,...) \
MGLOG_D("Implementing function: %s(...)", __FUNCTION__); \
MobileGL::MG_Impl::GLImpl::name(__VA_ARGS__); \
}
#define DECLARE_GL_FUNCTION_END_NO_RETURN(type,name,...) \
ZoneScopedC(TRACY_ZONECOLOR_ENTRY); \
MGLOG_D("Implementing function: %s(...)", __FUNCTION__); \
MobileGL::MG_Impl::GLImpl::name(__VA_ARGS__); \
}
#else
#define DECLARE_GL_FUNCTION_END(type,name,...) \
MGLOG_D("Implementing function: %s(...)", __FUNCTION__); \
return MobileGL::MG_Impl::GLImpl::name(__VA_ARGS__); \
}
#define DECLARE_GL_FUNCTION_END_NO_RETURN(type,name,...) \
MGLOG_D("Implementing function: %s(...)", __FUNCTION__); \
MobileGL::MG_Impl::GLImpl::name(__VA_ARGS__); \
}
#endif
DECLARE_GL_FUNCTION_HEAD(const GLubyte*, GetStringi, GLenum name, GLuint index) DECLARE_GL_FUNCTION_END(const GLubyte*, GetStringi, name, index)
DECLARE_GL_FUNCTION_HEAD(const GLubyte*, GetString, GLenum name) DECLARE_GL_FUNCTION_END(const GLubyte*, GetString, name)
@@ -144,9 +158,9 @@ DECLARE_GL_FUNCTION_HEAD(void, StencilOp, GLenum fail, GLenum zfail, GLenum zpas
DECLARE_GL_FUNCTION_HEAD(void, StencilOpSeparate, GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) DECLARE_GL_FUNCTION_END_NO_RETURN(void, StencilOpSeparate, face, sfail, dpfail, dppass)
DECLARE_GL_FUNCTION_HEAD(void, TexImage2D, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TexImage2D, target, level, internalformat, width, height, border, format, type, pixels)
DECLARE_GL_FUNCTION_HEAD(void, TexParameterf, GLenum target, GLenum pname, GLfloat param) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TexParameterf, target, pname, param)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TexParameterfv, GLenum target, GLenum pname, const GLfloat* params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TexParameterfv, target, pname, params)
DECLARE_GL_FUNCTION_HEAD(void, TexParameterfv, GLenum target, GLenum pname, const GLfloat* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TexParameterfv, target, pname, params)
DECLARE_GL_FUNCTION_HEAD(void, TexParameteri, GLenum target, GLenum pname, GLint param) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TexParameteri, target, pname, param)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TexParameteriv, GLenum target, GLenum pname, const GLint* params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TexParameteriv, target, pname, params)
DECLARE_GL_FUNCTION_HEAD(void, TexParameteriv, GLenum target, GLenum pname, const GLint* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TexParameteriv, target, pname, params)
DECLARE_GL_FUNCTION_HEAD(void, TexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TexSubImage2D, target, level, xoffset, yoffset, width, height, format, type, pixels)
DECLARE_GL_FUNCTION_HEAD(void, Uniform1f, GLint location, GLfloat v0) DECLARE_GL_FUNCTION_END_NO_RETURN(void, Uniform1f, location, v0)
DECLARE_GL_FUNCTION_HEAD(void, Uniform1fv, GLint location, GLsizei count, const GLfloat* value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, Uniform1fv, location, count, value)
@@ -387,8 +401,8 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, GetnUniformiv, GLuint program, GLint locatio
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetnUniformuiv, GLuint program, GLint location, GLsizei bufSize, GLuint* params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetnUniformuiv, program, location, bufSize, params)
DECLARE_GL_FUNCTION_STUB_HEAD(void, MinSampleShading, GLfloat value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, MinSampleShading, value)
DECLARE_GL_FUNCTION_STUB_HEAD(void, PatchParameteri, GLenum pname, GLint value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, PatchParameteri, pname, value)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TexParameterIiv, GLenum target, GLenum pname, const GLint* params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TexParameterIiv, target, pname, params)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TexParameterIuiv, GLenum target, GLenum pname, const GLuint* params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TexParameterIuiv, target, pname, params)
DECLARE_GL_FUNCTION_HEAD(void, TexParameterIiv, GLenum target, GLenum pname, const GLint* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TexParameterIiv, target, pname, params)
DECLARE_GL_FUNCTION_HEAD(void, TexParameterIuiv, GLenum target, GLenum pname, const GLuint* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, TexParameterIuiv, target, pname, params)
DECLARE_GL_FUNCTION_HEAD(void, GetTexParameterIiv, GLenum target, GLenum pname, GLint* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetTexParameterIiv, target, pname, params)
DECLARE_GL_FUNCTION_HEAD(void, GetTexParameterIuiv, GLenum target, GLenum pname, GLuint* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetTexParameterIuiv, target, pname, params)
DECLARE_GL_FUNCTION_HEAD(void, SamplerParameterIiv, GLuint sampler, GLenum pname, const GLint* param) DECLARE_GL_FUNCTION_END_NO_RETURN(void, SamplerParameterIiv, sampler, pname, param)
+332 -55
View File
@@ -7,6 +7,8 @@
#include "MG_Util/Types.h"
#include "Validators.h"
#include "ProxyTexture.h"
#include "MG_State/GLState/TextureState/TextureObjectBuffer.h"
#include <MG_State/GLState/Core.h>
#include <MG_Util/Metrics/TextureMetrics.h>
#include <MG_State/GLState/ErrorState/Error.h>
@@ -18,6 +20,24 @@
namespace MobileGL {
namespace MG_Impl::GLImpl {
SharedPtr<MG_State::GLState::ITextureObject> GetTextureObjectByTarget(TextureUploadTarget textureUploadingTarget, TextureTarget textureTarget) {
SharedPtr<MG_State::GLState::ITextureObject> textureObject = nullptr;
if (TextureImpl::IsProxyTextureTarget(textureUploadingTarget)) {
textureObject =
TextureImpl::pProxyTextureManager->CreateOrReplaceProxyTextureObject(textureUploadingTarget);
} else {
auto activeUnit =
MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit());
auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget);
textureObject = bindingSlot.GetBoundObject();
}
if (!TextureImpl::ValidateTextureObject(textureObject))
return nullptr;
return textureObject;
}
void TexSubImage3D_State(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width,
GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) {
// TODO: implement
@@ -64,9 +84,14 @@ namespace MobileGL {
if (!TextureImpl::ValidateTextureSubImageOffsets(textureObject, xoffset, width, yoffset, height)) return;
// ======================= Processing ================================
// auto& mipmap = textureObject->GetMipmap(level);
// Vector<Uint8>& data = mipmap.data;
auto texelSize = textureObject->GetMipmapTexelSize(textureUploadingTarget, level);
// Texture object here should always be an object with mipmap
// Assert this for extra safety.
// This should automatically compiled out in release,
// so that we don't take the perf hit of dyn-cast.
MOBILEGL_ASSERT(nullptr != dynamic_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get()),
"Texture object here should always be an object with mipmap");
auto textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
auto texelSize = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level);
SizeT imageSize = 0;
const SizeT bytesPerPixel = MG_Util::GetInputBytesPerPixel(textureInternalFormat, texturePixelDataType);
@@ -107,7 +132,7 @@ namespace MobileGL {
}
const auto* srcData = static_cast<const Uint8*>(processedPixels);
Uint8* destData = (Uint8*)textureObject->MapMipmapData(textureUploadingTarget, level);
Uint8* destData = (Uint8*)textureMipmapObject->MapMipmapData(textureUploadingTarget, level);
// No allocation should be done here
// if (data.empty()) {
// SizeT totalSize = texelSize.x() * texelSize.y() * bytesPerPixel;
@@ -122,7 +147,7 @@ namespace MobileGL {
free(processedPixels);
textureObject->MarkStorageDirty(textureUploadingTarget, level, true);
textureMipmapObject->MarkStorageDirty(textureUploadingTarget, level, true);
// mipmap.dirty = true;
// mipmap.hasData = true;
}
@@ -140,18 +165,10 @@ namespace MobileGL {
TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
// ======================= Processing ================================
SharedPtr<MG_State::GLState::ITextureObject> textureObject = nullptr;
if (TextureImpl::IsProxyTextureTarget(textureUploadingTarget)) {
textureObject =
TextureImpl::pProxyTextureManager->CreateOrReplaceProxyTextureObject(textureUploadingTarget);
} else {
auto activeUnit =
MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit());
auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget);
textureObject = bindingSlot.GetBoundObject();
}
if (!TextureImpl::ValidateTextureObject(textureObject)) return;
SharedPtr<MG_State::GLState::ITextureObject> textureObject =
GetTextureObjectByTarget(textureUploadingTarget, textureTarget);
if (!textureObject)
return;
switch (pname) {
case GL_TEXTURE_MAG_FILTER:
@@ -186,12 +203,6 @@ namespace MobileGL {
textureObject->SetSwizzleParam(swizzleParam, swizzleValue);
break;
}
case GL_TEXTURE_SWIZZLE_RGBA:
// Not supported in this function
break;
case GL_TEXTURE_BORDER_COLOR:
// Not supported in this function
break;
case GL_TEXTURE_WRAP_S:
textureObject->GetSamplerObject()->SetWrapS(MG_Util::ConvertGLEnumToSamplerWrapMode(param));
break;
@@ -208,6 +219,10 @@ namespace MobileGL {
textureObject->GetSamplerObject()->SetSamplerCompareFunc(
MG_Util::ConvertGLEnumToSamplerCompareFunc(param));
break;
case GL_TEXTURE_SWIZZLE_RGBA:
// Not supported in this function
case GL_TEXTURE_BORDER_COLOR:
// Not supported in this function
default:
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "TexParameteri_State",
@@ -222,18 +237,10 @@ namespace MobileGL {
TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
// ======================= Processing ================================
SharedPtr<MG_State::GLState::ITextureObject> textureObject = nullptr;
if (TextureImpl::IsProxyTextureTarget(textureUploadingTarget)) {
textureObject =
TextureImpl::pProxyTextureManager->CreateOrReplaceProxyTextureObject(textureUploadingTarget);
} else {
auto activeUnit =
MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit());
auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget);
textureObject = bindingSlot.GetBoundObject();
}
if (!TextureImpl::ValidateTextureObject(textureObject)) return;
SharedPtr<MG_State::GLState::ITextureObject> textureObject =
GetTextureObjectByTarget(textureUploadingTarget, textureTarget);
if (!textureObject)
return;
switch (pname) {
case GL_TEXTURE_MAG_FILTER:
@@ -268,12 +275,6 @@ namespace MobileGL {
textureObject->SetSwizzleParam(swizzleParam, swizzleValue);
break;
}
case GL_TEXTURE_SWIZZLE_RGBA:
// Not supported in this function
break;
case GL_TEXTURE_BORDER_COLOR:
// Not supported in this function
break;
case GL_TEXTURE_WRAP_S:
textureObject->GetSamplerObject()->SetWrapS(MG_Util::ConvertGLEnumToSamplerWrapMode(param));
break;
@@ -290,6 +291,10 @@ namespace MobileGL {
textureObject->GetSamplerObject()->SetSamplerCompareFunc(
MG_Util::ConvertGLEnumToSamplerCompareFunc(param));
break;
case GL_TEXTURE_SWIZZLE_RGBA:
// Not supported in this function
case GL_TEXTURE_BORDER_COLOR:
// Not supported in this function
default:
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "TexParameteri_State",
@@ -298,6 +303,171 @@ namespace MobileGL {
}
}
// Quick and dirty TexParameter*v implementation to make NeoForge happy.
// TODO: implement the missing part
void TexParameterfv_State(GLenum target, GLenum pname, const GLfloat * params) {
switch (pname) {
case GL_TEXTURE_BORDER_COLOR: {
// ======================= Converting ================================
TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target);
TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
// ======================= Processing ================================
SharedPtr<MG_State::GLState::ITextureObject> textureObject =
GetTextureObjectByTarget(textureUploadingTarget, textureTarget);
if (!textureObject)
return;
THROW_UNIMPL_EXCEPTION;
break;
}
case GL_TEXTURE_SWIZZLE_RGBA: {
// ======================= Converting ================================
TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target);
TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
// ======================= Processing ================================
SharedPtr<MG_State::GLState::ITextureObject> textureObject =
GetTextureObjectByTarget(textureUploadingTarget, textureTarget);
if (!textureObject)
return;
Vec4<TextureSwizzleParam> swizzleParams;
for (int i = 0; i < 4; i++) {
swizzleParams[i] = MG_Util::ConvertGLEnumToTextureSwizzleParam(static_cast<GLint>(params[i]));
if (TextureSwizzleParam::Unknown == swizzleParams[i]) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`params` is not valid."));
return;
}
}
textureObject->SetSwizzleParamRGBA(swizzleParams);
break;
}
default:
TexParameterf_State(target, pname, *params);
break;
}
}
void TexParameteriv_State(GLenum target, GLenum pname, const GLint * params) {
switch (pname) {
case GL_TEXTURE_BORDER_COLOR: {
// ======================= Converting ================================
TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target);
TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
// ======================= Processing ================================
SharedPtr<MG_State::GLState::ITextureObject> textureObject =
GetTextureObjectByTarget(textureUploadingTarget, textureTarget);
if (!textureObject)
return;
THROW_UNIMPL_EXCEPTION;
break;
}
case GL_TEXTURE_SWIZZLE_RGBA: {
// ======================= Converting ================================
TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target);
TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
// ======================= Processing ================================
SharedPtr<MG_State::GLState::ITextureObject> textureObject =
GetTextureObjectByTarget(textureUploadingTarget, textureTarget);
if (!textureObject)
return;
Vec4<TextureSwizzleParam> swizzleParams;
for (int i = 0; i < 4; i++) {
swizzleParams[i] = MG_Util::ConvertGLEnumToTextureSwizzleParam(static_cast<GLint>(params[i]));
if (TextureSwizzleParam::Unknown == swizzleParams[i]) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`params` is not valid."));
return;
}
}
textureObject->SetSwizzleParamRGBA(swizzleParams);
break;
}
default:
TexParameteri_State(target, pname, *params);
break;
}
}
void TexParameterIiv_State(GLenum target, GLenum pname, const GLint * params) {
switch (pname) {
case GL_TEXTURE_BORDER_COLOR: {
THROW_UNIMPL_EXCEPTION;
break;
}
case GL_TEXTURE_SWIZZLE_RGBA: {
// ======================= Converting ================================
TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target);
TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
// ======================= Processing ================================
SharedPtr<MG_State::GLState::ITextureObject> textureObject =
GetTextureObjectByTarget(textureUploadingTarget, textureTarget);
if (!textureObject)
return;
Vec4<TextureSwizzleParam> swizzleParams;
for (int i = 0; i < 4; i++) {
swizzleParams[i] = MG_Util::ConvertGLEnumToTextureSwizzleParam(static_cast<GLint>(params[i]));
if (TextureSwizzleParam::Unknown == swizzleParams[i]) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`params` is not valid."));
return;
}
}
textureObject->SetSwizzleParamRGBA(swizzleParams);
break;
}
default:
TexParameteri_State(target, pname, *params);
break;
}
}
void TexParameterIuiv_State(GLenum target, GLenum pname, const GLuint * params) {
switch (pname) {
case GL_TEXTURE_BORDER_COLOR: {
THROW_UNIMPL_EXCEPTION;
break;
}
case GL_TEXTURE_SWIZZLE_RGBA: {
// ======================= Converting ================================
TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target);
TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
// ======================= Processing ================================
SharedPtr<MG_State::GLState::ITextureObject> textureObject =
GetTextureObjectByTarget(textureUploadingTarget, textureTarget);
if (!textureObject)
return;
Vec4<TextureSwizzleParam> swizzleParams;
for (int i = 0; i < 4; i++) {
swizzleParams[i] = MG_Util::ConvertGLEnumToTextureSwizzleParam(static_cast<GLint>(params[i]));
if (TextureSwizzleParam::Unknown == swizzleParams[i]) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`params` is not valid."));
return;
}
}
textureObject->SetSwizzleParamRGBA(swizzleParams);
break;
}
default:
TexParameteri_State(target, pname, static_cast<GLint>(*params));
break;
}
}
void TexImage3DMultisample_State(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width,
GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) {
// TODO: implement
@@ -398,8 +568,13 @@ namespace MobileGL {
reinterpret_cast<SizeT>(pixels);
}
MOBILEGL_ASSERT(nullptr != dynamic_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get()),
"Texture object here should always be an object with mipmap");
auto textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
// Allocate in TextureObject
textureObject->AllocateStorage(textureUploadingTarget, level, {{width, height, 1}, totalBytes});
textureMipmapObject->AllocateStorage(textureUploadingTarget, level, {{width, height, 1}, totalBytes});
if (!originalPixels) {
MGLOG_D("TexImage2D_State: No input pixel and no PBO bound, no pixel transfer");
@@ -420,7 +595,7 @@ namespace MobileGL {
const SizeT copySize = std::min(imageSize, totalBytes);
DataPtr texelInput{processedPixels, copySize};
textureObject->UpdateMipmapSubData(textureUploadingTarget, level, texelInput);
textureMipmapObject->UpdateMipmapSubData(textureUploadingTarget, level, texelInput);
}
free(processedPixels);
@@ -432,9 +607,48 @@ namespace MobileGL {
THROW_UNIMPL_EXCEPTION;
}
void TexBuffer_State(GLenum target, GLenum internalformat, GLuint texture) {
// TODO: implement
THROW_UNIMPL_EXCEPTION;
void TexBuffer_State(GLenum target, GLenum internalformat, GLuint buffer) {
// ======================= Converting ================================
TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target);
TextureInternalFormat textureInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat);
// ===================== Error Checking ==============================
if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return;
if (!TextureImpl::ValidateTextureInternalFormat(textureInternalFormat)) return;
// TODO: make sure `internalformat` is in one of supported format for TexBuffer
auto bufferObject = MG_State::pGLContext->GetBufferObject(buffer);
if (!bufferObject) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`buffer` is not zero and is not the name of an existing buffer object."));
return;
}
// ======================= Processing ================================
auto activeUnit =
MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit());
auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget);
auto textureObject = bindingSlot.GetBoundObject();
// ===================== Error Checking ==============================
if (!TextureImpl::ValidateTextureObject(textureObject)) return;
if (textureObject->GetStorageType() != TextureStorageType::Buffer) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"The effective target of `texture` is not `GL_TEXTURE_BUFFER`."));
return;
}
// ======================= Processing ================================
// Now we can rest assured, and down-cast texture object to texture buffer
auto* texBufferObject = static_cast<MG_State::GLState::TextureObjectBuffer*>(textureObject.get());
auto& bufferSlot = texBufferObject->GetBufferBindingSlot();
bufferSlot.Bind(bufferObject);
texBufferObject->SetInternalFormat(textureInternalFormat);
}
GLboolean IsTexture_State(GLuint texture) {
@@ -648,17 +862,41 @@ namespace MobileGL {
switch (pname) {
case GL_TEXTURE_WIDTH:
if (params) {
*params = textureObject->GetMipmapTexelSize(textureUploadingTarget, level).x();
switch (textureObject->GetStorageType()) {
case TextureStorageType::Mipmap: {
const auto textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
*params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).x();
break;
}
default:
THROW_UNIMPL_EXCEPTION;
}
}
break;
case GL_TEXTURE_HEIGHT:
if (params) {
*params = textureObject->GetMipmapTexelSize(textureUploadingTarget, level).y();
switch (textureObject->GetStorageType()) {
case TextureStorageType::Mipmap: {
const auto textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
*params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).y();
break;
}
default:
THROW_UNIMPL_EXCEPTION;
}
}
break;
case GL_TEXTURE_DEPTH:
if (params) {
*params = textureObject->GetMipmapTexelSize(textureUploadingTarget, level).z();
switch (textureObject->GetStorageType()) {
case TextureStorageType::Mipmap: {
const auto textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
*params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).z();
break;
}
default:
THROW_UNIMPL_EXCEPTION;
}
}
break;
case GL_TEXTURE_INTERNAL_FORMAT:
@@ -714,18 +952,41 @@ namespace MobileGL {
switch (pname) {
case GL_TEXTURE_WIDTH:
if (params) {
*params = textureObject->GetMipmapTexelSize(textureUploadingTarget, level).x();
switch (textureObject->GetStorageType()) {
case TextureStorageType::Mipmap: {
const auto textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
*params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).x();
break;
}
default:
THROW_UNIMPL_EXCEPTION;
}
}
break;
case GL_TEXTURE_HEIGHT:
if (params) {
*params = textureObject->GetMipmapTexelSize(textureUploadingTarget, level).y();
switch (textureObject->GetStorageType()) {
case TextureStorageType::Mipmap: {
const auto textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
*params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).y();
break;
}
default:
THROW_UNIMPL_EXCEPTION;
}
}
break;
case GL_TEXTURE_DEPTH:
if (params) {
*params = textureObject->GetMipmapTexelSize(textureUploadingTarget, level).z();
}
switch (textureObject->GetStorageType()) {
case TextureStorageType::Mipmap: {
const auto textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
*params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).z();
break;
}
default:
THROW_UNIMPL_EXCEPTION;
} }
break;
case GL_TEXTURE_INTERNAL_FORMAT:
if (params) {
@@ -935,6 +1196,22 @@ namespace MobileGL {
TexParameteri_State(target, pname, param);
}
void TexParameterfv(GLenum target, GLenum pname, const GLfloat * params) {
TexParameterfv_State(target, pname, params);
}
void TexParameteriv(GLenum target, GLenum pname, const GLint * params) {
TexParameteriv_State(target, pname, params);
}
void TexParameterIiv(GLenum target, GLenum pname, const GLint * params) {
TexParameterIiv_State(target, pname, params);
}
void TexParameterIuiv(GLenum target, GLenum pname, const GLuint * params) {
TexParameterIuiv_State(target, pname, params);
}
void TexImage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height,
GLsizei depth, GLboolean fixedsamplelocations) {
TexImage3DMultisample_State(target, samples, internalformat, width, height, depth, fixedsamplelocations);
@@ -960,8 +1237,8 @@ namespace MobileGL {
TexImage1D_State(target, level, internalFormat, width, border, format, type, pixels);
}
void TexBuffer(GLenum target, GLenum internalformat, GLuint texture) {
TexBuffer_State(target, internalformat, texture);
void TexBuffer(GLenum target, GLenum internalformat, GLuint buffer) {
TexBuffer_State(target, internalformat, buffer);
}
GLboolean IsTexture(GLuint texture) {
@@ -12,6 +12,11 @@ namespace MobileGL {
const GLvoid* pixels);
void TexParameterf(GLenum target, GLenum pname, GLfloat param);
void TexParameteri(GLenum target, GLenum pname, GLint param);
void TexParameterfv(GLenum target, GLenum pname, const GLfloat * params);
void TexParameteriv(GLenum target, GLenum pname, const GLint * params);
void TexParameterIiv(GLenum target, GLenum pname, const GLint * params);
void TexParameterIuiv(GLenum target, GLenum pname, const GLuint * params);
void TexImage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height,
GLsizei depth, GLboolean fixedsamplelocations);
void TexImage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height,
@@ -52,7 +52,9 @@ namespace MobileGL {
IntVec3 FramebufferAttachment::GetSize() const {
if (IsTexture()) {
// TODO: get correct upload target
return m_texture->GetMipmapTexelSize(TextureUploadTarget::Texture2D, m_textureLevel);
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()) {
// TODO
}
@@ -51,7 +51,7 @@ namespace MobileGL {
SamplerWrapMode wrapS = SamplerWrapMode::Repeat;
SamplerWrapMode wrapT = SamplerWrapMode::Repeat;
SamplerWrapMode wrapR = SamplerWrapMode::Repeat;
SamplerFilterMode minFilter = SamplerFilterMode::Linear;
SamplerFilterMode minFilter = SamplerFilterMode::Nearest;
SamplerFilterMode magFilter = SamplerFilterMode::Linear;
SamplerMipmapMode mipmapMode = SamplerMipmapMode::Linear;
Float minLod = -1000.0f;
@@ -2,7 +2,7 @@
namespace MobileGL {
enum class TextureTarget {
Texture1D,
Texture1D = 0,
Texture2D,
Texture3D,
TextureCubeMap,
@@ -20,7 +20,7 @@ namespace MobileGL {
// Don't tinker with order in this enum (especially CubeMap faces),
// it is used in MipmapUploadTargetArray
enum class TextureUploadTarget {
Texture1D,
Texture1D = 0,
Texture2D,
Texture3D,
ProxyTexture1D,
@@ -38,6 +38,7 @@ namespace MobileGL {
CubeMapNegativeY,
CubeMapPositiveZ,
CubeMapNegativeZ,
TextureBuffer,
ProxyCubeMap,
CubeMapArray,
ProxyCubeMapArray,
@@ -49,6 +50,11 @@ namespace MobileGL {
Unknown = -1
};
enum class TextureStorageType {
Mipmap,
Buffer
};
enum class TextureInputFormat {
Red,
RG,
@@ -91,6 +91,9 @@ namespace MobileGL {
break;
}
}
void TextureObjectBase::SetSwizzleParamRGBA(const Vec4<TextureSwizzleParam>& values) {
m_swizzleParams = values;
}
const UintVec2& TextureObjectBase::GetLevelRange() const {
return m_levelRange;
@@ -14,14 +14,7 @@ namespace MobileGL {
using TargetEnum = TextureTarget;
virtual ~ITextureObject() = default;
virtual Uint GetMipmapLevelCount() const = 0;
virtual const IntVec3 GetMipmapTexelSize(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 UpdateMipmapSubData(TextureUploadTarget uploadTarget, Uint mipmapLevel, DataPtr input) = 0;
virtual void* MapMipmapData(TextureUploadTarget uploadTarget, Uint mipmapLevel) = 0;
virtual void MarkStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel, bool dirty) = 0;
virtual bool IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const = 0;
virtual TextureStorageType GetStorageType() const = 0;
virtual TextureInternalFormat GetFormat() const = 0;
virtual TextureTarget GetTarget() const = 0;
@@ -35,6 +28,7 @@ namespace MobileGL {
virtual void SetBorderColor(const FloatVec4& color) = 0;
virtual TextureSwizzleParam GetSwizzleParam(TextureSwizzleParam param) const = 0;
virtual void SetSwizzleParam(TextureSwizzleParam param, TextureSwizzleParam value) = 0;
virtual void SetSwizzleParamRGBA(const Vec4<TextureSwizzleParam>& values) = 0;
virtual const Vec4<TextureSwizzleParam>& GetAllSwizzleParams() const = 0;
virtual const UintVec2& GetLevelRange() const = 0;
virtual void SetBaseLevel(Uint baseLevel) = 0;
@@ -49,17 +43,6 @@ namespace MobileGL {
TextureObjectBase(TextureTarget target, Uint externalIndex);
virtual ~TextureObjectBase() = default;
// Mipmap ops
// Uint GetMipmapLevelCount() const = 0;
// const IntVec3 GetMipmapTexelSize(TextureUploadTarget target, Uint mipmapLevel) const =
// 0; const SizeT GetMipmapByteSize(TextureUploadTarget target, Uint mipmapLevel) const =
// 0; void AllocateStorage(TextureUploadTarget uploadTarget, Uint mipmapLevel,
// MipmapInput input) = 0; void UpdateMipmapSubData(TextureUploadTarget uploadTarget,
// Uint mipmapLevel, DataPtr input) = 0; void* MapMipmapData(TextureUploadTarget
// uploadTarget, Uint mipmapLevel) = 0; void MarkStorageDirty(TextureUploadTarget
// uploadTarget, Uint mipmapLevel, bool dirty) = 0; bool
// IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const = 0;
TextureInternalFormat GetFormat() const override;
TextureTarget GetTarget() const override;
IntVec3 GetBaseSize() const override;
@@ -72,6 +55,7 @@ namespace MobileGL {
TextureSwizzleParam GetSwizzleParam(TextureSwizzleParam param) const override;
const Vec4<TextureSwizzleParam>& GetAllSwizzleParams() const override;
void SetSwizzleParam(TextureSwizzleParam param, TextureSwizzleParam value) override;
void SetSwizzleParamRGBA(const Vec4<TextureSwizzleParam>& values) override;
const UintVec2& GetLevelRange() const override;
void SetBaseLevel(Uint baseLevel) override;
void SetMaxLevel(Uint maxLevel) override;
@@ -87,10 +71,26 @@ namespace MobileGL {
UintVec2 m_levelRange = {0, 1000};
};
class TextureObjectWithOneMipmap : public TextureObjectBase {
class TextureObjectMipmap : public TextureObjectBase {
public:
TextureObjectMipmap(TextureTarget target, Uint externalIndex): TextureObjectBase(target, externalIndex) {}
TextureStorageType GetStorageType() const override { return TextureStorageType::Mipmap; }
virtual Uint GetMipmapLevelCount() const = 0;
virtual const IntVec3 GetMipmapTexelSize(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 UpdateMipmapSubData(TextureUploadTarget uploadTarget, Uint mipmapLevel, DataPtr input) = 0;
virtual void* MapMipmapData(TextureUploadTarget uploadTarget, Uint mipmapLevel) = 0;
virtual void MarkStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel, bool dirty) = 0;
virtual bool IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const = 0;
};
class TextureObjectWithOneMipmap : public TextureObjectMipmap {
public:
TextureObjectWithOneMipmap(TextureTarget target, Uint externalIndex)
: TextureObjectBase(target, externalIndex) {}
: TextureObjectMipmap(target, externalIndex) {}
virtual ~TextureObjectWithOneMipmap() = default;
Uint GetMipmapLevelCount() const override;
@@ -4,7 +4,7 @@ namespace MobileGL {
namespace MG_State {
namespace GLState {
TextureObject2DCube::TextureObject2DCube(Uint externalIndex)
: TextureObjectBase(TextureTarget::TextureCubeMap, externalIndex) {}
: TextureObjectMipmap(TextureTarget::TextureCubeMap, externalIndex) {}
Uint TextureObject2DCube::GetMipmapLevelCount() const {
return m_textureStorage.GetLevelCount();
@@ -4,7 +4,7 @@
namespace MobileGL {
namespace MG_State {
namespace GLState {
class TextureObject2DCube : public TextureObjectBase {
class TextureObject2DCube : public TextureObjectMipmap {
public:
explicit TextureObject2DCube(Uint externalIndex);
@@ -0,0 +1,20 @@
#include "TextureObjectBuffer.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
TextureObjectBuffer::TextureObjectBuffer(Uint externalIndex)
: TextureObjectBase(TextureTarget::TextureBuffer, externalIndex) {}
Uint TextureObjectBuffer::GetIndexOfTextureUploadTarget(TextureUploadTarget target) const {
MOBILEGL_ASSERT(target == TextureUploadTarget::TextureBuffer, "Invalid TextureUploadTarget!");
return 0;
}
BindingSlot<BufferObject>& TextureObjectBuffer::GetBufferBindingSlot(TextureUploadTarget target) {
MOBILEGL_ASSERT(target == TextureUploadTarget::TextureBuffer, "Invalid TextureUploadTarget!");
return m_bufferBindingSlot;
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
@@ -0,0 +1,23 @@
#pragma once
#include "TextureObject.h"
#include "MG_State/GLState/BufferState/BufferObject.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
class TextureObjectBuffer : public TextureObjectBase {
public:
TextureStorageType GetStorageType() const override { return TextureStorageType::Buffer; }
explicit TextureObjectBuffer(Uint externalIndex);
const Vector<TextureUploadTarget>& GetUploadTargets() const override { return m_uploadTargets; }
BindingSlot<BufferObject>& GetBufferBindingSlot(TextureUploadTarget target = TextureUploadTarget::TextureBuffer);
protected:
Uint GetIndexOfTextureUploadTarget(TextureUploadTarget target) const override;
BindingSlot<BufferObject> m_bufferBindingSlot = BindingSlot<BufferObject>(BufferTarget::Texture);
const Vector<TextureUploadTarget> m_uploadTargets{TextureUploadTarget::TextureBuffer};
};
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
@@ -31,8 +31,8 @@ namespace MobileGL {
STUB_TEXTURE_OBJECT_CLASS_DEFINITION(TextureObject2DMultisample, TextureTarget::Texture2DMultisample,
{TextureUploadTarget::Texture2DMultisample});
STUB_TEXTURE_OBJECT_CLASS_DEFINITION(TextureObjectBuffer, TextureTarget::TextureBuffer,
{TextureUploadTarget::Unknown});
// STUB_TEXTURE_OBJECT_CLASS_DEFINITION(TextureObjectBuffer, TextureTarget::TextureBuffer,
// {TextureUploadTarget::Unknown});
STUB_TEXTURE_OBJECT_CLASS_DEFINITION(TextureObject1DArray, TextureTarget::Texture1DArray,
{TextureUploadTarget::Texture1DArray});
@@ -6,6 +6,7 @@
#include "TextureObject2D.h"
#include "TextureObject3D.h"
#include "TextureObject2DCube.h"
#include "TextureObjectBuffer.h"
#include "TextureObjectStubs.h"
namespace MobileGL {
@@ -46,6 +47,9 @@ namespace MobileGL {
case TextureTarget::Texture3D:
textureObject = MakeShared<TextureObject3D>(index);
break;
case TextureTarget::TextureBuffer:
textureObject = MakeShared<TextureObjectBuffer>(index);
break;
// These texture types are stubbed:
case TextureTarget::TextureRectangle:
@@ -54,9 +58,6 @@ namespace MobileGL {
case TextureTarget::Texture2DMultisample:
textureObject = MakeShared<TextureObject2DMultisample>(index);
break;
case TextureTarget::TextureBuffer:
textureObject = MakeShared<TextureObjectBuffer>(index);
break;
case TextureTarget::Texture1DArray:
textureObject = MakeShared<TextureObject1DArray>(index);
break;
+2 -2
View File
@@ -1204,9 +1204,9 @@ TEST_F(ProgramTest, CompileShaderWithSamplerAsVarName) {
spvc_compiler_options options;
spvcSession.CreateOptions(&options);
spvc_compiler_options_set_uint(options, SPVC_COMPILER_OPTION_GLSL_VERSION, 460);
spvc_compiler_options_set_uint(options, SPVC_COMPILER_OPTION_GLSL_VERSION, 320);
spvc_compiler_options_set_bool(options, SPVC_COMPILER_OPTION_GLSL_ES, SPVC_TRUE);
// spvc_compiler_options_set_bool(options, SPVC_COMPILER_OPTION_GLSL_VULKAN_SEMANTICS, SPVC_FALSE);
spvc_compiler_options_set_bool(options, SPVC_COMPILER_OPTION_GLSL_VULKAN_SEMANTICS, SPVC_FALSE);
spvcSession.SetOptions(options);
@@ -317,6 +317,8 @@ namespace MobileGL {
return TextureUploadTarget::CubeMapPositiveZ;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
return TextureUploadTarget::CubeMapNegativeZ;
case GL_TEXTURE_BUFFER:
return TextureUploadTarget::TextureBuffer;
case GL_PROXY_TEXTURE_CUBE_MAP:
return TextureUploadTarget::ProxyCubeMap;
case GL_TEXTURE_2D_MULTISAMPLE:
+6
View File
@@ -8,6 +8,12 @@ android {
minSdk 26
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
// externalNativeBuild {
// cmake {
// arguments "-DTRACY_ENABLE=ON"
// }
// }
}
buildTypes {