mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 04:08:32 +09:00
[Feat] (MG_Backend/DirectGLES): support compute shaders
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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, ¶ms[0]);
|
||||
GetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, ¶ms[1]);
|
||||
GetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, ¶ms[2]);
|
||||
break;
|
||||
case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
|
||||
*params = 0; // TODO
|
||||
GetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, ¶ms[0]);
|
||||
GetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, ¶ms[1]);
|
||||
GetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, ¶ms[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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user