[Feat] (MG_Backend/DirectGLES): support compute shaders

This commit is contained in:
2026-06-05 10:41:23 +08:00
parent dcd37f3c38
commit 3bd8a62aa8
19 changed files with 775 additions and 46 deletions
+17
View File
@@ -64,6 +64,23 @@ namespace MobileGL {
void (*ReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
void* pixels);
void (*GetTexImage)(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels);
void (*DispatchCompute)(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ);
void (*DispatchComputeIndirect)(GLintptr indirect);
void (*MemoryBarrier)(GLbitfield barriers);
void (*MemoryBarrierByRegion)(GLbitfield barriers);
void (*BindImageTexture)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer,
GLenum access, GLenum format);
void (*GetIntegeri_v)(GLenum target, GLuint index, GLint* data);
void (*GetInteger64i_v)(GLenum target, GLuint index, GLint64* data);
void (*GetProgramInterfaceiv)(GLuint program, GLenum programInterface, GLenum pname, GLint* params);
GLuint (*GetProgramResourceIndex)(GLuint program, GLenum programInterface, const GLchar* name);
void (*GetProgramResourceName)(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize,
GLsizei* length, GLchar* name);
void (*GetProgramResourceiv)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount,
const GLenum* props, GLsizei bufSize, GLsizei* length, GLint* params);
GLint (*GetProgramResourceLocation)(GLuint program, GLenum programInterface, const GLchar* name);
GLint (*GetProgramResourceLocationIndex)(GLuint program, GLenum programInterface, const GLchar* name);
void (*ShaderStorageBlockBinding)(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding);
};
struct GlobalBackendFunctionsTable {
GLFunctionsTable GL;
@@ -119,7 +119,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
.TargetGLVersion = {3, 3, 0}, // Target OpenGL Version
.TargetGLSLVersion = {4, 6, 0}, // Target Shading Language Version
.Extensions = {V_OpenGL30, V_OpenGL31, V_OpenGL32, // OpenGL Extensions
V_OpenGL33, E_GL_ARB_draw_buffers_blend},
V_OpenGL33, E_GL_ARB_draw_buffers_blend, E_GL_ARB_compute_shader,
E_GL_ARB_shader_storage_buffer_object, E_GL_ARB_shader_image_load_store,
E_GL_ARB_program_interface_query},
.IsCompatibilityProfile = false // Is Compatibility Profile
},
.StaticBackendCapability = {.AllowVSOnlyPrograms = false} // Backend Capability
@@ -164,6 +166,20 @@ namespace MobileGL::MG_Backend::DirectGLES {
funcsTable.GL.DrawArraysInstanced = DrawArraysInstanced;
funcsTable.GL.DrawElementsIndirect = DrawElementsIndirect;
funcsTable.GL.DrawArraysIndirect = DrawArraysIndirect;
funcsTable.GL.DispatchCompute = DispatchCompute;
funcsTable.GL.DispatchComputeIndirect = DispatchComputeIndirect;
funcsTable.GL.MemoryBarrier = MemoryBarrier;
funcsTable.GL.MemoryBarrierByRegion = MemoryBarrierByRegion;
funcsTable.GL.BindImageTexture = BindImageTexture;
funcsTable.GL.GetIntegeri_v = GetIntegeri_v;
funcsTable.GL.GetInteger64i_v = GetInteger64i_v;
funcsTable.GL.GetProgramInterfaceiv = GetProgramInterfaceiv;
funcsTable.GL.GetProgramResourceIndex = GetProgramResourceIndex;
funcsTable.GL.GetProgramResourceName = GetProgramResourceName;
funcsTable.GL.GetProgramResourceiv = GetProgramResourceiv;
funcsTable.GL.GetProgramResourceLocation = GetProgramResourceLocation;
funcsTable.GL.GetProgramResourceLocationIndex = GetProgramResourceLocationIndex;
funcsTable.GL.ShaderStorageBlockBinding = ShaderStorageBlockBinding;
funcsTable.GL.Clear = Clear;
funcsTable.GL.ClearBufferfi = ClearBufferfi;
funcsTable.GL.ClearBufferfv = ClearBufferfv;
+357 -15
View File
@@ -105,6 +105,59 @@ namespace MobileGL::MG_Backend::DirectGLES {
backendObj->SyncToBackend(bufferObject);
}
void SyncBufferBindingPoints(BufferTarget target, GLenum glTarget) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
auto bindingPointCnt = MG_State::pGLContext->GetBufferBindingPointCount(target);
for (SizeT i = 0; i < bindingPointCnt; ++i) {
auto& point = MG_State::pGLContext->GetBufferBindingPoint(target, i);
auto& obj = point.GetBoundObject();
if (!obj) {
g_GLESFuncs.glBindBufferBase(glTarget, static_cast<GLuint>(i), 0);
continue;
}
CreateAndSyncBufferObject(obj);
const auto& backendBufferIt = g_backendBufferObjects.find(obj.get());
if (backendBufferIt == g_backendBufferObjects.end()) {
MGLOG_E("No backend buffer found for %s binding point %zu.",
MG_Util::ConvertGLEnumToString(glTarget).c_str(), i);
continue;
}
const auto& range = point.GetRange();
auto backendBufferId = backendBufferIt->second->GetBackendBufferId();
if (range.start == 0 && range.end >= obj->GetSize()) {
g_GLESFuncs.glBindBufferBase(glTarget, static_cast<GLuint>(i), backendBufferId);
} else {
const auto start = std::min(range.start, obj->GetSize());
const auto end = std::min(range.end, obj->GetSize());
g_GLESFuncs.glBindBufferRange(glTarget, static_cast<GLuint>(i), backendBufferId,
static_cast<GLintptr>(start), static_cast<GLsizeiptr>(end - start));
}
}
}
void SyncBoundBuffer(BufferTarget target, GLenum glTarget) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
auto& bufferObject = MG_State::pGLContext->GetBufferBindingSlot(target).GetBoundObject();
if (!bufferObject) {
g_GLESFuncs.glBindBuffer(glTarget, 0);
return;
}
CreateAndSyncBufferObject(bufferObject);
const auto& backendBufferIt = g_backendBufferObjects.find(bufferObject.get());
if (backendBufferIt == g_backendBufferObjects.end()) {
MGLOG_E("No backend buffer found for %s.", MG_Util::ConvertGLEnumToString(glTarget).c_str());
return;
}
backendBufferIt->second->Bind(glTarget);
}
void SyncNeccessaryBuffers(Bool includeIBO = false, Bool includeIndirectBuffer = false) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
@@ -112,7 +165,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
g_backendBufferObjects.CollectGarbageIfNeeded();
// All buffers we need are:
// 1.VBO 2.IBO (if needed) 3.UBO 4.IndirectBuffer (if needed) 5.SSBO (TODO)
// 1.VBO 2.IBO (if needed) 3.UBO 4.IndirectBuffer (if needed)
// PBO is not needed since it should be handled in frontend
const auto& currentVAOObject = MG_State::pGLContext->GetBoundVertexArray();
@@ -147,14 +200,18 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
}
// UBO
auto uboBindingPointCnt = MG_State::pGLContext->GetBufferBindingPointCount(BufferTarget::Uniform);
for (SizeT i = 0; i < uboBindingPointCnt; ++i) {
auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::Uniform, i);
auto& obj = point.GetBoundObject();
if (obj) {
CreateAndSyncBufferObject(obj);
}
SyncBufferBindingPoints(BufferTarget::Uniform, GL_UNIFORM_BUFFER);
}
void SyncComputeBuffers(Bool includeDispatchIndirectBuffer) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
g_backendBufferObjects.CollectGarbageIfNeeded();
SyncBufferBindingPoints(BufferTarget::Uniform, GL_UNIFORM_BUFFER);
SyncBufferBindingPoints(BufferTarget::ShaderStorage, GL_SHADER_STORAGE_BUFFER);
if (includeDispatchIndirectBuffer) {
SyncBoundBuffer(BufferTarget::DispatchIndirect, GL_DISPATCH_INDIRECT_BUFFER);
}
}
} // namespace BufferImpl
@@ -234,6 +291,31 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
}
}
void SyncImageTextureBinding(Uint unit) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
auto& imageBinding = MG_State::pGLContext->GetImageTextureBinding(static_cast<Int>(unit));
if (!imageBinding.Texture) {
g_GLESFuncs.glBindImageTexture(unit, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
return;
}
auto& backendTexture = SyncTextureObjectToBackend(imageBinding.Texture);
g_GLESFuncs.glBindImageTexture(unit, backendTexture->GetBackendTextureId(), imageBinding.Level,
imageBinding.Layered, imageBinding.Layer, imageBinding.Access,
imageBinding.Format);
}
void SyncImageTextureBindings() {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
for (Uint unit = 0; unit < MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS; ++unit) {
SyncImageTextureBinding(unit);
}
}
} // namespace TextureImpl
namespace FramebufferImpl {
@@ -588,6 +670,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
if (backendProgramIt != PrgramImpl::g_backendProgramObjects.end()) {
backendProgramIt->second->Use();
auto backendProgramId = backendProgramIt->second->GetBackendProgramId();
// Global UBO
if (currentProgram->GetUBOSize() > 0) {
#ifdef TRACY_ENABLE
@@ -600,11 +683,15 @@ namespace MobileGL::MG_Backend::DirectGLES {
Uint blockIndex = g_GLESFuncs.glGetUniformBlockIndex(backendProgramId,
MG_Util::ShaderTranspiler::GLOBAL_UBO_NAME);
if (blockIndex == GL_INVALID_INDEX) {
MGLOG_W("Program %u has frontend global UBO storage, but backend has no %s block.",
currentProgram->GetExternalIndex(), MG_Util::ShaderTranspiler::GLOBAL_UBO_NAME);
} else {
g_GLESFuncs.glUniformBlockBinding(backendProgramId, blockIndex, 0);
g_GLESFuncs.glUniformBlockBinding(backendProgramId, blockIndex, 0);
g_GLESFuncs.glBindBufferBase(GL_UNIFORM_BUFFER, 0,
backendProgramIt->second->GetBackendGlobalUBOId());
g_GLESFuncs.glBindBufferBase(GL_UNIFORM_BUFFER, 0,
backendProgramIt->second->GetBackendGlobalUBOId());
}
}
{
@@ -655,10 +742,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
#endif
// Sampler unit binding
auto maxUniformLoc = currentProgram->GetMaxUniformLocation();
for (int loc = 0; loc < maxUniformLoc; ++loc) {
for (Uint loc = 0; loc <= maxUniformLoc; ++loc) {
auto& name = currentProgram->GetUniformName(loc);
if (name.empty()) continue;
auto unit = currentProgram->GetUniformSamplerOrImageUnitIndex(loc);
if (unit == -1) continue;
auto& name = currentProgram->GetUniformName(loc);
auto locAtBackend = g_GLESFuncs.glGetUniformLocation(
backendProgramIt->second->GetBackendProgramId(), name.c_str());
g_GLESFuncs.glUniform1i(locAtBackend, unit);
@@ -687,6 +775,55 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
}
void PrepareForCompute(Bool includeDispatchIndirectBuffer) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
BufferImpl::SyncComputeBuffers(includeDispatchIndirectBuffer);
TextureImpl::SyncNeccessaryTextures();
TextureImpl::SyncImageTextureBindings();
PrgramImpl::SyncCurrentProgram();
const auto& currentProgram = MG_State::pGLContext->GetCurrentProgram();
if (!currentProgram || !currentProgram->GetLinkStatus()) {
g_GLESFuncs.glUseProgram(0);
return;
}
const auto& backendProgramIt = PrgramImpl::g_backendProgramObjects.find(currentProgram.get());
if (backendProgramIt != PrgramImpl::g_backendProgramObjects.end()) {
backendProgramIt->second->Use();
} else {
g_GLESFuncs.glUseProgram(0);
MGLOG_E("No backend program found (maybe not synced) for current compute program.");
}
}
GLuint GetBackendProgramId(GLuint program) {
if (!MG_State::pGLContext->ValidateProgramName(program)) {
MGLOG_E("Invalid frontend program object: %u", program);
return 0;
}
auto& programObject = MG_State::pGLContext->GetProgramObject(program);
if (!programObject) {
MGLOG_E("Program object %u is null.", program);
return 0;
}
const auto& backendProgramIt = PrgramImpl::g_backendProgramObjects.find(programObject.get());
Bool exist = (backendProgramIt != PrgramImpl::g_backendProgramObjects.end());
auto& backendObj =
exist ? backendProgramIt->second : PrgramImpl::g_backendProgramObjects.GetOrCreate(programObject);
if (!exist) {
backendObj = MakeShared<PrgramImpl::BackendProgramObjectImpl>();
}
if (!backendObj->GetBackendProgramId()) {
backendObj->SyncToBackend(programObject);
}
return backendObj->GetBackendProgramId();
}
void Clear(GLbitfield mask) {
#if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG && MOBILEGL_ENABLE_SCOPE_MARKER
DebugImpl::OpenGLScopeMarker marker(__func__);
@@ -1132,6 +1269,211 @@ namespace MobileGL::MG_Backend::DirectGLES {
return g_GLESFuncs.glGetString(name);
}
void DispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ) {
#if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG && MOBILEGL_ENABLE_SCOPE_MARKER
DebugImpl::OpenGLScopeMarker marker(__func__);
#endif
PrepareForCompute(false);
g_GLESFuncs.glDispatchCompute(numGroupsX, numGroupsY, numGroupsZ);
}
void DispatchComputeIndirect(GLintptr indirect) {
#if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG && MOBILEGL_ENABLE_SCOPE_MARKER
DebugImpl::OpenGLScopeMarker marker(__func__);
#endif
PrepareForCompute(true);
g_GLESFuncs.glDispatchComputeIndirect(indirect);
}
void MemoryBarrier(GLbitfield barriers) {
g_GLESFuncs.glMemoryBarrier(barriers);
}
void MemoryBarrierByRegion(GLbitfield barriers) {
g_GLESFuncs.glMemoryBarrierByRegion(barriers);
}
void BindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access,
GLenum format) {
(void)texture;
(void)level;
(void)layered;
(void)layer;
(void)access;
(void)format;
TextureImpl::SyncImageTextureBinding(unit);
}
void GetIntegeri_v(GLenum target, GLuint index, GLint* data) {
if (!data) return;
switch (target) {
case GL_SHADER_STORAGE_BUFFER_BINDING: {
auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::ShaderStorage, index);
auto& obj = point.GetBoundObject();
*data = obj ? static_cast<GLint>(obj->GetExternalIndex()) : 0;
return;
}
case GL_SHADER_STORAGE_BUFFER_START: {
auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::ShaderStorage, index);
*data = static_cast<GLint>(point.GetRange().start);
return;
}
case GL_SHADER_STORAGE_BUFFER_SIZE: {
auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::ShaderStorage, index);
auto& obj = point.GetBoundObject();
if (!obj) {
*data = 0;
return;
}
const auto& range = point.GetRange();
const auto start = std::min(range.start, obj->GetSize());
const auto end = std::min(range.end, obj->GetSize());
*data = static_cast<GLint>(end - start);
return;
}
case GL_IMAGE_BINDING_NAME: {
if (index >= MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS) {
*data = 0;
return;
}
auto& imageBinding = MG_State::pGLContext->GetImageTextureBinding(static_cast<Int>(index));
*data = imageBinding.Texture ? static_cast<GLint>(imageBinding.Texture->GetExternalIndex()) : 0;
return;
}
case GL_IMAGE_BINDING_LEVEL: {
if (index >= MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS) {
*data = 0;
return;
}
auto& imageBinding = MG_State::pGLContext->GetImageTextureBinding(static_cast<Int>(index));
*data = imageBinding.Level;
return;
}
case GL_IMAGE_BINDING_LAYERED: {
if (index >= MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS) {
*data = 0;
return;
}
auto& imageBinding = MG_State::pGLContext->GetImageTextureBinding(static_cast<Int>(index));
*data = imageBinding.Layered;
return;
}
case GL_IMAGE_BINDING_LAYER: {
if (index >= MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS) {
*data = 0;
return;
}
auto& imageBinding = MG_State::pGLContext->GetImageTextureBinding(static_cast<Int>(index));
*data = imageBinding.Layer;
return;
}
case GL_IMAGE_BINDING_ACCESS: {
if (index >= MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS) {
*data = 0;
return;
}
auto& imageBinding = MG_State::pGLContext->GetImageTextureBinding(static_cast<Int>(index));
*data = static_cast<GLint>(imageBinding.Access);
return;
}
case GL_IMAGE_BINDING_FORMAT: {
if (index >= MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS) {
*data = 0;
return;
}
auto& imageBinding = MG_State::pGLContext->GetImageTextureBinding(static_cast<Int>(index));
*data = static_cast<GLint>(imageBinding.Format);
return;
}
default:
if (g_GLESFuncs.glGetIntegeri_v) {
g_GLESFuncs.glGetIntegeri_v(target, index, data);
} else {
*data = 0;
}
return;
}
}
void GetInteger64i_v(GLenum target, GLuint index, GLint64* data) {
if (!data) return;
switch (target) {
case GL_SHADER_STORAGE_BUFFER_START: {
auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::ShaderStorage, index);
*data = static_cast<GLint64>(point.GetRange().start);
return;
}
case GL_SHADER_STORAGE_BUFFER_SIZE: {
auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::ShaderStorage, index);
auto& obj = point.GetBoundObject();
if (!obj) {
*data = 0;
return;
}
const auto& range = point.GetRange();
const auto start = std::min(range.start, obj->GetSize());
const auto end = std::min(range.end, obj->GetSize());
*data = static_cast<GLint64>(end - start);
return;
}
default:
if (g_GLESFuncs.glGetInteger64i_v) {
g_GLESFuncs.glGetInteger64i_v(target, index, data);
} else {
*data = 0;
}
return;
}
}
void GetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint* params) {
GLuint backendProgramId = GetBackendProgramId(program);
if (!backendProgramId) return;
g_GLESFuncs.glGetProgramInterfaceiv(backendProgramId, programInterface, pname, params);
}
GLuint GetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar* name) {
GLuint backendProgramId = GetBackendProgramId(program);
if (!backendProgramId) return GL_INVALID_INDEX;
return g_GLESFuncs.glGetProgramResourceIndex(backendProgramId, programInterface, name);
}
void GetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize,
GLsizei* length, GLchar* name) {
GLuint backendProgramId = GetBackendProgramId(program);
if (!backendProgramId) return;
g_GLESFuncs.glGetProgramResourceName(backendProgramId, programInterface, index, bufSize, length, name);
}
void GetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount,
const GLenum* props, GLsizei bufSize, GLsizei* length, GLint* params) {
GLuint backendProgramId = GetBackendProgramId(program);
if (!backendProgramId) return;
g_GLESFuncs.glGetProgramResourceiv(backendProgramId, programInterface, index, propCount, props, bufSize,
length, params);
}
GLint GetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar* name) {
GLuint backendProgramId = GetBackendProgramId(program);
if (!backendProgramId) return -1;
return g_GLESFuncs.glGetProgramResourceLocation(backendProgramId, programInterface, name);
}
GLint GetProgramResourceLocationIndex(GLuint program, GLenum programInterface, const GLchar* name) {
(void)program;
(void)programInterface;
(void)name;
return -1;
}
void ShaderStorageBlockBinding(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding) {
GLuint backendProgramId = GetBackendProgramId(program);
if (!backendProgramId) return;
g_GLESFuncs.glShaderStorageBlockBinding(backendProgramId, storageBlockIndex, storageBlockBinding);
}
void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) {
TextureImpl::SyncNeccessaryTextures();
FramebufferImpl::SyncCurrentFBO();
@@ -56,6 +56,23 @@ namespace MobileGL::MG_Backend::DirectGLES {
const GLubyte* GetString(GLenum name);
void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels);
void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels);
void DispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ);
void DispatchComputeIndirect(GLintptr indirect);
void MemoryBarrier(GLbitfield barriers);
void MemoryBarrierByRegion(GLbitfield barriers);
void BindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access,
GLenum format);
void GetIntegeri_v(GLenum target, GLuint index, GLint* data);
void GetInteger64i_v(GLenum target, GLuint index, GLint64* data);
void GetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint* params);
GLuint GetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar* name);
void GetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize,
GLsizei* length, GLchar* name);
void GetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount,
const GLenum* props, GLsizei bufSize, GLsizei* length, GLint* params);
GLint GetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar* name);
GLint GetProgramResourceLocationIndex(GLuint program, GLenum programInterface, const GLchar* name);
void ShaderStorageBlockBinding(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding);
Bool InitWindowSurface(NativeWindowType window);
void Present();
void SetEGLFuncsTable(const MG_External::EGLFunctionsTable& eglFuncs);
@@ -156,6 +156,52 @@ namespace MobileGL::MG_Impl::GLImpl {
}
/* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */
void DispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ) {
auto dispatchCompute = MG_Backend::gBackendFunctionsTable.GL.DispatchCompute;
if (!dispatchCompute) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "Backend does not support compute dispatch."));
return;
}
dispatchCompute(numGroupsX, numGroupsY, numGroupsZ);
}
void DispatchComputeIndirect(GLintptr indirect) {
auto dispatchComputeIndirect = MG_Backend::gBackendFunctionsTable.GL.DispatchComputeIndirect;
if (!dispatchComputeIndirect) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"Backend does not support indirect compute dispatch."));
return;
}
dispatchComputeIndirect(indirect);
}
void MemoryBarrier(GLbitfield barriers) {
auto memoryBarrier = MG_Backend::gBackendFunctionsTable.GL.MemoryBarrier;
if (!memoryBarrier) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "Backend does not support memory barriers."));
return;
}
memoryBarrier(barriers);
}
void MemoryBarrierByRegion(GLbitfield barriers) {
auto memoryBarrierByRegion = MG_Backend::gBackendFunctionsTable.GL.MemoryBarrierByRegion;
if (!memoryBarrierByRegion) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"Backend does not support regional memory barriers."));
return;
}
memoryBarrierByRegion(barriers);
}
void MultiDrawElementsIndirect(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, GLsizei stride) {
MultiDrawElementsIndirect_Backend(mode, type, indirect, drawcount, stride);
}
@@ -11,6 +11,10 @@
namespace MobileGL::MG_Impl::GLImpl {
/* @INSERTION_POINT:FUNCTION_DECLARATION@ */
void DispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ);
void DispatchComputeIndirect(GLintptr indirect);
void MemoryBarrier(GLbitfield barriers);
void MemoryBarrierByRegion(GLbitfield barriers);
void MultiDrawElementsIndirect(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, GLsizei stride);
void MultiDrawArraysIndirect(GLenum mode, const void* indirect, GLsizei drawcount, GLsizei stride);
void DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type,
@@ -233,7 +233,7 @@ DECLARE_GL_FUNCTION_HEAD(void, BindVertexArray, GLuint array) DECLARE_GL_FUNCTIO
DECLARE_GL_FUNCTION_HEAD(void, DeleteVertexArrays, GLsizei n, const GLuint* arrays) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DeleteVertexArrays, n, arrays)
DECLARE_GL_FUNCTION_HEAD(void, GenVertexArrays, GLsizei n, GLuint* arrays) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GenVertexArrays, n, arrays)
DECLARE_GL_FUNCTION_HEAD(GLboolean, IsVertexArray, GLuint array) DECLARE_GL_FUNCTION_END(GLboolean, IsVertexArray, array)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetIntegeri_v, GLenum target, GLuint index, GLint* data) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetIntegeri_v, target, index, data)
DECLARE_GL_FUNCTION_HEAD(void, GetIntegeri_v, GLenum target, GLuint index, GLint* data) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetIntegeri_v, target, index, data)
DECLARE_GL_FUNCTION_STUB_HEAD(void, BeginTransformFeedback, GLenum primitiveMode) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BeginTransformFeedback, primitiveMode)
DECLARE_GL_FUNCTION_STUB_HEAD(void, EndTransformFeedback) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, EndTransformFeedback)
DECLARE_GL_FUNCTION_HEAD(void, BindBufferRange, GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BindBufferRange, target, index, buffer, offset, size)
@@ -277,7 +277,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(GLenum, ClientWaitSync, GLsync sync, GLbitfield fl
DECLARE_GL_FUNCTION_STUB_HEAD(void, WaitSync, GLsync sync, GLbitfield flags, GLuint64 timeout) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, WaitSync, sync, flags, timeout)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetInteger64v, GLenum pname, GLint64* data) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetInteger64v, pname, data)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetSynciv, GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetSynciv, sync, pname, bufSize, length, values)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetInteger64i_v, GLenum target, GLuint index, GLint64* data) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetInteger64i_v, target, index, data)
DECLARE_GL_FUNCTION_HEAD(void, GetInteger64i_v, GLenum target, GLuint index, GLint64* data) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetInteger64i_v, target, index, data)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetBufferParameteri64v, GLenum target, GLenum pname, GLint64* params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetBufferParameteri64v, target, pname, params)
DECLARE_GL_FUNCTION_HEAD(void, GenSamplers, GLsizei count, GLuint* samplers) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GenSamplers, count, samplers)
DECLARE_GL_FUNCTION_HEAD(void, DeleteSamplers, GLsizei count, const GLuint* samplers) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DeleteSamplers, count, samplers)
@@ -304,17 +304,17 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, InvalidateSubFramebuffer, GLenum target, GLs
DECLARE_GL_FUNCTION_STUB_HEAD(void, TexStorage2D, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TexStorage2D, target, levels, internalformat, width, height)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TexStorage3D, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TexStorage3D, target, levels, internalformat, width, height, depth)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetInternalformativ, GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetInternalformativ, target, internalformat, pname, bufSize, params)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DispatchCompute, GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DispatchCompute, num_groups_x, num_groups_y, num_groups_z)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DispatchComputeIndirect, GLintptr indirect) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DispatchComputeIndirect, indirect)
DECLARE_GL_FUNCTION_HEAD(void, DispatchCompute, GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DispatchCompute, num_groups_x, num_groups_y, num_groups_z)
DECLARE_GL_FUNCTION_HEAD(void, DispatchComputeIndirect, GLintptr indirect) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DispatchComputeIndirect, indirect)
DECLARE_GL_FUNCTION_HEAD(void, DrawArraysIndirect, GLenum mode, const void* indirect) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DrawArraysIndirect, mode, indirect)
DECLARE_GL_FUNCTION_HEAD(void, DrawElementsIndirect, GLenum mode, GLenum type, const void* indirect) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DrawElementsIndirect, mode, type, indirect)
DECLARE_GL_FUNCTION_STUB_HEAD(void, FramebufferParameteri, GLenum target, GLenum pname, GLint param) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, FramebufferParameteri, target, pname, param)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetFramebufferParameteriv, GLenum target, GLenum pname, GLint* params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetFramebufferParameteriv, target, pname, params)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetProgramInterfaceiv, GLuint program, GLenum programInterface, GLenum pname, GLint* params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetProgramInterfaceiv, program, programInterface, pname, params)
DECLARE_GL_FUNCTION_STUB_HEAD(GLuint, GetProgramResourceIndex, GLuint program, GLenum programInterface, const GLchar* name) DECLARE_GL_FUNCTION_STUB_END(GLuint, GetProgramResourceIndex, program, programInterface, name)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetProgramResourceName, GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar* name) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetProgramResourceName, program, programInterface, index, bufSize, length, name)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetProgramResourceiv, GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum* props, GLsizei bufSize, GLsizei* length, GLint* params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetProgramResourceiv, program, programInterface, index, propCount, props, bufSize, length, params)
DECLARE_GL_FUNCTION_STUB_HEAD(GLint, GetProgramResourceLocation, GLuint program, GLenum programInterface, const GLchar* name) DECLARE_GL_FUNCTION_STUB_END(GLint, GetProgramResourceLocation, program, programInterface, name)
DECLARE_GL_FUNCTION_HEAD(void, GetProgramInterfaceiv, GLuint program, GLenum programInterface, GLenum pname, GLint* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetProgramInterfaceiv, program, programInterface, pname, params)
DECLARE_GL_FUNCTION_HEAD(GLuint, GetProgramResourceIndex, GLuint program, GLenum programInterface, const GLchar* name) DECLARE_GL_FUNCTION_END(GLuint, GetProgramResourceIndex, program, programInterface, name)
DECLARE_GL_FUNCTION_HEAD(void, GetProgramResourceName, GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar* name) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetProgramResourceName, program, programInterface, index, bufSize, length, name)
DECLARE_GL_FUNCTION_HEAD(void, GetProgramResourceiv, GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum* props, GLsizei bufSize, GLsizei* length, GLint* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetProgramResourceiv, program, programInterface, index, propCount, props, bufSize, length, params)
DECLARE_GL_FUNCTION_HEAD(GLint, GetProgramResourceLocation, GLuint program, GLenum programInterface, const GLchar* name) DECLARE_GL_FUNCTION_END(GLint, GetProgramResourceLocation, program, programInterface, name)
DECLARE_GL_FUNCTION_STUB_HEAD(void, UseProgramStages, GLuint pipeline, GLbitfield stages, GLuint program) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, UseProgramStages, pipeline, stages, program)
DECLARE_GL_FUNCTION_STUB_HEAD(void, ActiveShaderProgram, GLuint pipeline, GLuint program) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ActiveShaderProgram, pipeline, program)
DECLARE_GL_FUNCTION_STUB_HEAD(GLuint, CreateShaderProgramv, GLenum type, GLsizei count, const GLchar* const* strings) DECLARE_GL_FUNCTION_STUB_END(GLuint, CreateShaderProgramv, type, count, strings)
@@ -358,10 +358,10 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, ProgramUniformMatrix3x4fv, GLuint program, G
DECLARE_GL_FUNCTION_STUB_HEAD(void, ProgramUniformMatrix4x3fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ProgramUniformMatrix4x3fv, program, location, count, transpose, value)
DECLARE_GL_FUNCTION_STUB_HEAD(void, ValidateProgramPipeline, GLuint pipeline) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ValidateProgramPipeline, pipeline)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetProgramPipelineInfoLog, GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetProgramPipelineInfoLog, pipeline, bufSize, length, infoLog)
DECLARE_GL_FUNCTION_STUB_HEAD(void, BindImageTexture, GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BindImageTexture, unit, texture, level, layered, layer, access, format)
DECLARE_GL_FUNCTION_HEAD(void, BindImageTexture, GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BindImageTexture, unit, texture, level, layered, layer, access, format)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetBooleani_v, GLenum target, GLuint index, GLboolean* data) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetBooleani_v, target, index, data)
DECLARE_GL_FUNCTION_STUB_HEAD(void, MemoryBarrier, GLbitfield barriers) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, MemoryBarrier, barriers)
DECLARE_GL_FUNCTION_STUB_HEAD(void, MemoryBarrierByRegion, GLbitfield barriers) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, MemoryBarrierByRegion, barriers)
DECLARE_GL_FUNCTION_HEAD(void, MemoryBarrier, GLbitfield barriers) DECLARE_GL_FUNCTION_END_NO_RETURN(void, MemoryBarrier, barriers)
DECLARE_GL_FUNCTION_HEAD(void, MemoryBarrierByRegion, GLbitfield barriers) DECLARE_GL_FUNCTION_END_NO_RETURN(void, MemoryBarrierByRegion, barriers)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TexStorage2DMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TexStorage2DMultisample, target, samples, internalformat, width, height, fixedsamplelocations)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetMultisamplefv, GLenum pname, GLuint index, GLfloat* val) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetMultisamplefv, pname, index, val)
DECLARE_GL_FUNCTION_HEAD(void, SampleMaski, GLuint maskNumber, GLbitfield mask) DECLARE_GL_FUNCTION_END_NO_RETURN(void, SampleMaski, maskNumber, mask)
@@ -977,8 +977,8 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, InvalidateBufferSubData, GLuint buffer, GLin
DECLARE_GL_FUNCTION_STUB_HEAD(void, InvalidateBufferData, GLuint buffer) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, InvalidateBufferData, buffer)
DECLARE_GL_FUNCTION_HEAD(void, MultiDrawArraysIndirect, GLenum mode, const void* indirect, GLsizei drawcount, GLsizei stride) DECLARE_GL_FUNCTION_END_NO_RETURN(void, MultiDrawArraysIndirect, mode, indirect, drawcount, stride)
DECLARE_GL_FUNCTION_HEAD(void, MultiDrawElementsIndirect, GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, GLsizei stride) DECLARE_GL_FUNCTION_END_NO_RETURN(void, MultiDrawElementsIndirect, mode, type, indirect, drawcount, stride)
DECLARE_GL_FUNCTION_STUB_HEAD(GLint, GetProgramResourceLocationIndex, GLuint program, GLenum programInterface, const GLchar* name) DECLARE_GL_FUNCTION_STUB_END(GLint, GetProgramResourceLocationIndex, program, programInterface, name)
DECLARE_GL_FUNCTION_STUB_HEAD(void, ShaderStorageBlockBinding, GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ShaderStorageBlockBinding, program, storageBlockIndex, storageBlockBinding)
DECLARE_GL_FUNCTION_HEAD(GLint, GetProgramResourceLocationIndex, GLuint program, GLenum programInterface, const GLchar* name) DECLARE_GL_FUNCTION_END(GLint, GetProgramResourceLocationIndex, program, programInterface, name)
DECLARE_GL_FUNCTION_HEAD(void, ShaderStorageBlockBinding, GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ShaderStorageBlockBinding, program, storageBlockIndex, storageBlockBinding)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TextureView, GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TextureView, texture, target, origtexture, internalformat, minlevel, numlevels, minlayer, numlayers)
DECLARE_GL_FUNCTION_STUB_HEAD(void, VertexAttribLFormat, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, VertexAttribLFormat, attribindex, size, type, relativeoffset)
DECLARE_GL_FUNCTION_STUB_HEAD(void, BufferStorage, GLenum target, GLsizeiptr size, const void* data, GLbitfield flags) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BufferStorage, target, size, data, flags)
+76 -16
View File
@@ -120,6 +120,42 @@ namespace MobileGL::MG_Impl::GLImpl {
return (const GLubyte*)extStrings[index].c_str();
}
void GetIntegeri_v(GLenum target, GLuint index, GLint* data) {
if (!data) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "data pointer cannot be null"));
return;
}
auto getIntegeri = MG_Backend::gBackendFunctionsTable.GL.GetIntegeri_v;
if (!getIntegeri) {
*data = 0;
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "Backend does not support indexed integer queries."));
return;
}
getIntegeri(target, index, data);
}
void GetInteger64i_v(GLenum target, GLuint index, GLint64* data) {
if (!data) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "data pointer cannot be null"));
return;
}
auto getInteger64i = MG_Backend::gBackendFunctionsTable.GL.GetInteger64i_v;
if (!getInteger64i) {
*data = 0;
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "Backend does not support indexed integer queries."));
return;
}
getInteger64i(target, index, data);
}
void GetIntegerv(GLenum pname, GLint* params) {
MGLOG_D("glGetIntegerv, pname: %s", MG_Util::ConvertGLEnumToString(pname).c_str());
if (!params) {
@@ -213,41 +249,47 @@ namespace MobileGL::MG_Impl::GLImpl {
*params = 0; // TODO
break;
case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
*params = 0; // TODO
*params = 16; // TODO: use backend value
break;
case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
*params = 0; // TODO
*params = 96; // TODO: use backend value
break;
case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
*params = 0; // TODO
*params = 14; // TODO: use backend value
break;
case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
*params = 0; // TODO
*params = MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS; // TODO: use backend value
break;
case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
*params = 0; // TODO
*params = 1024 * 4; // TODO: use backend value
break;
case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
*params = 0; // TODO
*params = 8; // TODO: use backend value
break;
case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
*params = 0; // TODO
*params = 8; // TODO: use backend value
break;
case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
*params = 0; // TODO
*params = 1024 * 228; // TODO: use backend value
break;
case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
*params = 0; // TODO
*params = 1024; // TODO: use backend value
break;
case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
*params = 0; // TODO
GetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &params[0]);
GetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &params[1]);
GetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, &params[2]);
break;
case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
*params = 0; // TODO
GetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &params[0]);
GetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &params[1]);
GetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, &params[2]);
break;
case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
*params = 0; // TODO
case GL_DISPATCH_INDIRECT_BUFFER_BINDING: {
auto& obj = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::DispatchIndirect).GetBoundObject();
*params = obj ? static_cast<GLint>(obj->GetExternalIndex()) : 0;
break;
}
case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
*params = 0; // TODO
break;
@@ -437,6 +479,22 @@ namespace MobileGL::MG_Impl::GLImpl {
case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS:
*params = 1024 * 4; // TODO
break;
case GL_MAX_IMAGE_UNITS:
*params = MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS; // TODO: use backend value
break;
case GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS:
*params = MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS +
MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS;
break;
case GL_MAX_COMBINED_IMAGE_UNIFORMS:
*params = MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS; // TODO: use backend value
break;
case GL_MAX_IMAGE_SAMPLES:
*params = 0; // multisampled image load/store is not exposed by the DirectGLES frontend
break;
case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
*params = MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS; // TODO: use backend value
break;
case GL_MAX_INTEGER_SAMPLES:
*params = 16; // TODO
break;
@@ -674,11 +732,13 @@ namespace MobileGL::MG_Impl::GLImpl {
case GL_SHADER_COMPILER:
*params = 0; // TODO
break;
case GL_SHADER_STORAGE_BUFFER_BINDING:
*params = 0; // TODO
case GL_SHADER_STORAGE_BUFFER_BINDING: {
auto& obj = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::ShaderStorage).GetBoundObject();
*params = obj ? static_cast<GLint>(obj->GetExternalIndex()) : 0;
break;
}
case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
*params = 0; // TODO
*params = 256; // TODO: use backend value
break;
case GL_SHADER_STORAGE_BUFFER_START:
*params = 0; // TODO
@@ -14,5 +14,7 @@ namespace MobileGL::MG_Impl::GLImpl {
const GLubyte* GetString(GLenum name);
const GLubyte* GetStringi(GLenum name, GLuint index);
void GetIntegerv(GLenum pname, GLint* params);
void GetIntegeri_v(GLenum target, GLuint index, GLint* data);
void GetInteger64i_v(GLenum target, GLuint index, GLint64* data);
GLenum GetError();
} // namespace MobileGL::MG_Impl::GLImpl
@@ -13,6 +13,7 @@
#include <MG_Util/Converters/GLToMG/ProgramEnumConverter.h>
#include <MG_Util/Converters/MGToGL/ProgramEnumConverter.h>
#include <MG_Util/Converters/SPIRVCrossToGL/SpvcTypeConverter.h>
#include <MG_Backend/BackendObjects.h>
namespace MobileGL::MG_Impl::GLImpl {
static bool CheckShaderNameValidity(Uint shader) {
@@ -1168,6 +1169,112 @@ namespace MobileGL::MG_Impl::GLImpl {
return GetFragDataLocation_State(program, name);
}
void GetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint* params) {
auto& programObject = TryToGetProgramObject(program);
if (!programObject || !programObject->GetLinkStatus()) return;
auto getProgramInterfaceiv = MG_Backend::gBackendFunctionsTable.GL.GetProgramInterfaceiv;
if (!getProgramInterfaceiv) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"Backend does not support program interface queries."));
return;
}
getProgramInterfaceiv(program, programInterface, pname, params);
}
GLuint GetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar* name) {
auto& programObject = TryToGetProgramObject(program);
if (!programObject || !programObject->GetLinkStatus()) return GL_INVALID_INDEX;
auto getProgramResourceIndex = MG_Backend::gBackendFunctionsTable.GL.GetProgramResourceIndex;
if (!getProgramResourceIndex) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"Backend does not support program interface queries."));
return GL_INVALID_INDEX;
}
return getProgramResourceIndex(program, programInterface, name);
}
void GetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize,
GLsizei* length, GLchar* name) {
auto& programObject = TryToGetProgramObject(program);
if (!programObject || !programObject->GetLinkStatus()) return;
if (bufSize < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "bufSize must be non-negative."));
return;
}
auto getProgramResourceName = MG_Backend::gBackendFunctionsTable.GL.GetProgramResourceName;
if (!getProgramResourceName) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"Backend does not support program interface queries."));
return;
}
getProgramResourceName(program, programInterface, index, bufSize, length, name);
}
void GetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount,
const GLenum* props, GLsizei bufSize, GLsizei* length, GLint* params) {
auto& programObject = TryToGetProgramObject(program);
if (!programObject || !programObject->GetLinkStatus()) return;
if (propCount < 0 || bufSize < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "propCount and bufSize must be non-negative."));
return;
}
auto getProgramResourceiv = MG_Backend::gBackendFunctionsTable.GL.GetProgramResourceiv;
if (!getProgramResourceiv) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"Backend does not support program interface queries."));
return;
}
getProgramResourceiv(program, programInterface, index, propCount, props, bufSize, length, params);
}
GLint GetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar* name) {
auto& programObject = TryToGetProgramObject(program);
if (!programObject || !programObject->GetLinkStatus()) return -1;
auto getProgramResourceLocation = MG_Backend::gBackendFunctionsTable.GL.GetProgramResourceLocation;
if (!getProgramResourceLocation) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"Backend does not support program interface queries."));
return -1;
}
return getProgramResourceLocation(program, programInterface, name);
}
GLint GetProgramResourceLocationIndex(GLuint program, GLenum programInterface, const GLchar* name) {
auto& programObject = TryToGetProgramObject(program);
if (!programObject || !programObject->GetLinkStatus()) return -1;
auto getProgramResourceLocationIndex = MG_Backend::gBackendFunctionsTable.GL.GetProgramResourceLocationIndex;
if (!getProgramResourceLocationIndex) return -1;
return getProgramResourceLocationIndex(program, programInterface, name);
}
void ShaderStorageBlockBinding(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding) {
auto& programObject = TryToGetProgramObject(program);
if (!programObject || !programObject->GetLinkStatus()) return;
auto shaderStorageBlockBinding = MG_Backend::gBackendFunctionsTable.GL.ShaderStorageBlockBinding;
if (!shaderStorageBlockBinding) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"Backend does not support shader storage block binding."));
return;
}
shaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding);
}
void ValidateProgram(GLuint program) {
ValidateProgram_State(program);
}
@@ -63,5 +63,14 @@ namespace MobileGL::MG_Impl::GLImpl {
GLchar* uniformBlockName);
void BindFragDataLocation(GLuint program, GLuint colorNumber, const char* name);
GLint GetFragDataLocation(GLuint program, const char* name);
void GetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint* params);
GLuint GetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar* name);
void GetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize,
GLsizei* length, GLchar* name);
void GetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount,
const GLenum* props, GLsizei bufSize, GLsizei* length, GLint* params);
GLint GetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar* name);
GLint GetProgramResourceLocationIndex(GLuint program, GLenum programInterface, const GLchar* name);
void ShaderStorageBlockBinding(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding);
void ValidateProgram(GLuint program);
} // namespace MobileGL::MG_Impl::GLImpl
@@ -1471,6 +1471,58 @@ namespace MobileGL::MG_Impl::GLImpl {
}
/* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */
void BindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access,
GLenum format) {
if (unit >= MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "Image texture unit is out of range."));
return;
}
if (level < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "Texture level must be non-negative."));
return;
}
if (layer < 0 && layered == GL_FALSE) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "Texture layer must be non-negative."));
return;
}
if (access != GL_READ_ONLY && access != GL_WRITE_ONLY && access != GL_READ_WRITE) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "Invalid image texture access."));
return;
}
SharedPtr<MG_State::GLState::ITextureObject> textureObject;
if (texture != 0) {
if (!MG_State::pGLContext->ValidateTextureObject(texture)) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "Texture name is not a texture object."));
return;
}
textureObject = MG_State::pGLContext->GetTextureObject(texture);
}
MG_State::pGLContext->GetImageTextureBinding(static_cast<Int>(unit))
.Bind(textureObject, level, layered, layer, access, format);
auto bindImageTexture = MG_Backend::gBackendFunctionsTable.GL.BindImageTexture;
if (!bindImageTexture) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"Backend does not support image texture binding."));
return;
}
bindImageTexture(unit, texture, level, layered, layer, access, format);
}
void GenerateMipmap(GLenum target) {
GenerateMipmap_Backend(target);
}
@@ -11,6 +11,8 @@
namespace MobileGL::MG_Impl::GLImpl {
/* @INSERTION_POINT:FUNCTION_DECLARATION@ */
void BindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access,
GLenum format);
void GenerateMipmap(GLenum target);
void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels);
void TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width,
+8
View File
@@ -203,6 +203,14 @@ namespace MobileGL::MG_State {
return m_textureState.GetUnitObject(unit);
}
ImageTextureBinding& GLContext::GetImageTextureBinding(Int unit) {
return m_textureState.GetImageTextureBinding(unit);
}
const ImageTextureBinding& GLContext::GetImageTextureBinding(Int unit) const {
return m_textureState.GetImageTextureBinding(unit);
}
Bool GLContext::ValidateTextureName(Uint index) const {
return m_textureState.ValidateName(index);
}
+2
View File
@@ -78,6 +78,8 @@ namespace MobileGL {
const SharedPtr<ITextureObject>& CreateTextureObject(Uint index, TextureTarget target);
void MarkTextureObjectForDeletion(Uint index);
TextureUnit& GetTextureUnitObject(Int unit);
ImageTextureBinding& GetImageTextureBinding(Int unit);
const ImageTextureBinding& GetImageTextureBinding(Int unit) const;
Bool ValidateTextureName(Uint index) const;
Bool ValidateTextureObject(Uint index) const;
Int GetActiveTextureUnit() const;
@@ -97,6 +97,11 @@ namespace MobileGL::MG_State::GLState {
}
}
}
for (auto& imageBinding : m_imageTextureBindings) {
if (imageBinding.Texture == it->second) {
imageBinding.Bind(nullptr, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
}
}
m_textureObjects.erase(it);
}
m_indexGenerator.Delete(index);
@@ -109,6 +114,18 @@ namespace MobileGL::MG_State::GLState {
return m_textureUnits[unit];
}
ImageTextureBinding& TextureState::GetImageTextureBinding(Int unit) {
MOBILEGL_ASSERT(unit >= 0 && unit < MAX_TEXTURE_IMAGE_UNITS, "Image unit is out of range: %d > %d", unit,
MAX_TEXTURE_IMAGE_UNITS - 1);
return m_imageTextureBindings[unit];
}
const ImageTextureBinding& TextureState::GetImageTextureBinding(Int unit) const {
MOBILEGL_ASSERT(unit >= 0 && unit < MAX_TEXTURE_IMAGE_UNITS, "Image unit is out of range: %d > %d", unit,
MAX_TEXTURE_IMAGE_UNITS - 1);
return m_imageTextureBindings[unit];
}
Int TextureState::GetActiveTextureUnit() const {
return m_activeTextureUnit;
}
@@ -14,6 +14,27 @@
#include "TextureUnit.h"
namespace MobileGL::MG_State::GLState {
struct ImageTextureBinding {
SharedPtr<ITextureObject> Texture;
GLint Level = 0;
GLboolean Layered = GL_FALSE;
GLint Layer = 0;
GLenum Access = GL_READ_ONLY;
GLenum Format = GL_RGBA8;
Uint16 Version = 0;
void Bind(SharedPtr<ITextureObject> texture, GLint level, GLboolean layered, GLint layer, GLenum access,
GLenum format) {
Texture = Move(texture);
Level = level;
Layered = layered;
Layer = layer;
Access = access;
Format = format;
++Version;
}
};
class TextureState {
public:
static constexpr int MAX_TEXTURE_IMAGE_UNITS = 32;
@@ -23,6 +44,8 @@ namespace MobileGL::MG_State::GLState {
const SharedPtr<ITextureObject>& CreateTextureObject(Uint index, TextureTarget target);
const SharedPtr<ITextureObject>& GetTextureObject(Uint index);
TextureUnit& GetUnitObject(Int unit);
ImageTextureBinding& GetImageTextureBinding(Int unit);
const ImageTextureBinding& GetImageTextureBinding(Int unit) const;
Int GetActiveTextureUnit() const;
void SetActiveTextureUnit(Int unit);
void MarkTextureObjectForDeletion(Uint index);
@@ -32,6 +55,7 @@ namespace MobileGL::MG_State::GLState {
private:
Int m_activeTextureUnit = 0;
Array<TextureUnit, MAX_TEXTURE_IMAGE_UNITS> m_textureUnits;
Array<ImageTextureBinding, MAX_TEXTURE_IMAGE_UNITS> m_imageTextureBindings;
IndexGenerator<Uint> m_indexGenerator;
UnorderedMap<GLuint, SharedPtr<ITextureObject>> m_textureObjects;
};
@@ -311,6 +311,7 @@ namespace MobileGL::MG_Util::BackendLoader {
INIT_GLES_FUNC(glFramebufferParameteri)
INIT_GLES_FUNC(glGetFramebufferParameteriv)
INIT_GLES_FUNC(glGetProgramInterfaceiv)
INIT_GLES_FUNC(glShaderStorageBlockBinding)
INIT_GLES_FUNC(glGetProgramResourceIndex)
INIT_GLES_FUNC(glGetProgramResourceName)
INIT_GLES_FUNC(glGetProgramResourceiv)
@@ -447,6 +447,8 @@ namespace MobileGL {
GL_FUNC_TYPEDEF(void, glGetFramebufferParameteriv, GLenum target, GLenum pname, GLint* params)
GL_FUNC_TYPEDEF(void, glGetProgramInterfaceiv, GLuint program, GLenum programInterface, GLenum pname,
GLint* params)
GL_FUNC_TYPEDEF(void, glShaderStorageBlockBinding, GLuint program, GLuint storageBlockIndex,
GLuint storageBlockBinding)
GL_FUNC_TYPEDEF(GLuint, glGetProgramResourceIndex, GLuint program, GLenum programInterface,
const GLchar* name)
GL_FUNC_TYPEDEF(void, glGetProgramResourceName, GLuint program, GLenum programInterface, GLuint index,
@@ -884,6 +886,7 @@ namespace MobileGL {
GL_FUNC_DECL(glFramebufferParameteri)
GL_FUNC_DECL(glGetFramebufferParameteriv)
GL_FUNC_DECL(glGetProgramInterfaceiv)
GL_FUNC_DECL(glShaderStorageBlockBinding)
GL_FUNC_DECL(glGetProgramResourceIndex)
GL_FUNC_DECL(glGetProgramResourceName)
GL_FUNC_DECL(glGetProgramResourceiv)