mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 04:08:32 +09:00
Merge remote-tracking branch 'origin/Feat/Backend-Direct-GLES' into Feat/Backend-Direct-GLES
This commit is contained in:
@@ -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
|
||||
|
||||
+1
Submodule 3rdparty/tracy added at e6b9ea4609
+22
-2
@@ -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
@@ -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()
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -8,6 +8,12 @@ android {
|
||||
minSdk 26
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
// externalNativeBuild {
|
||||
// cmake {
|
||||
// arguments "-DTRACY_ENABLE=ON"
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
|
||||
Reference in New Issue
Block a user