Merge branch 'Feat/dev-es-shittily-draw' into dev-es without ShittilyDraw

# Conflict:
#	MG/Includes.h

# Changes:
#      Remove ShittilyDraw, ready to implement MG_RHI...
#      Update progress.
This commit is contained in:
BZLZHH
2025-05-17 11:50:47 +08:00
40 changed files with 3163 additions and 321 deletions
+2 -2
View File
@@ -4,7 +4,7 @@ project("MobileGL")
enable_language(CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
@@ -118,4 +118,4 @@ if (PROFILING)
add_library(perfetto STATIC ${CMAKE_SOURCE_DIR}/3rdparty/perfetto/sdk/perfetto.cc)
target_link_libraries(MobileGL perfetto ${CMAKE_THREAD_LIBS_INIT})
target_compile_definitions(MobileGL PUBLIC PROFILING=1)
endif()
endif()
+33 -24
View File
@@ -5,6 +5,12 @@
#ifndef MOBILEGL_CONSTANTS_H
#define MOBILEGL_CONSTANTS_H
#include <array>
#include <unordered_map>
#include <unordered_set>
#include <GL/gl.h>
#include <ankerl/unordered_dense.h>
#ifdef __ANDROID__
#define __ANDROID_API__ 26
#endif
@@ -15,10 +21,13 @@
#define MG_EXPORT extern "C" __attribute__((visibility("default")))
#endif
#include <array>
#include <unordered_map>
#include <unordered_set>
#include <GL/gl.h>
namespace ankerl {
template <typename K, typename V>
using unordered_map = ankerl::unordered_dense::map<K, V>;
template <typename T>
using unordered_set = ankerl::unordered_dense::set<T>;
}
namespace MG_Constants {
namespace Common {
@@ -30,7 +39,7 @@ namespace MG_Constants {
}
namespace Blend {
static const std::unordered_set<GLenum> VALID_FACTORS = {
static const ankerl::unordered_set<GLenum> VALID_FACTORS = {
GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR,
GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR,
@@ -39,51 +48,51 @@ namespace MG_Constants {
}
namespace Depth {
static const std::unordered_set<GLenum> VALID_FUNCS = {
static const ankerl::unordered_set<GLenum> VALID_FUNCS = {
GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL, GL_GEQUAL, GL_ALWAYS
}; // OpenGL 3
}
namespace CommonState {
static const std::unordered_set<GLenum> VALID_CAPS = {
static const ankerl::unordered_set<GLenum> VALID_CAPS = {
GL_BLEND, GL_DEPTH_TEST, GL_STENCIL_TEST, GL_SCISSOR_TEST, GL_CULL_FACE,
GL_POLYGON_OFFSET_FILL, GL_SAMPLE_ALPHA_TO_COVERAGE, GL_SAMPLE_COVERAGE
}; // OpenGL 3
}
namespace Framebuffer {
static const std::unordered_set<GLenum> VALID_ATTACHMENTS = {
static const ankerl::unordered_set<GLenum> VALID_ATTACHMENTS = {
GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT,
GL_STENCIL_ATTACHMENT, GL_DEPTH_STENCIL_ATTACHMENT
}; // OpenGL 3
static const std::unordered_set<GLenum> VALID_TARGETS = {
static const ankerl::unordered_set<GLenum> VALID_TARGETS = {
GL_FRAMEBUFFER, GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER
}; // OpenGL 3
static const std::unordered_set<GLenum> VALID_ACCESS = {
static const ankerl::unordered_set<GLenum> VALID_ACCESS = {
GL_READ_ONLY, GL_WRITE_ONLY, GL_READ_WRITE
}; // OpenGL 3
}
namespace Buffer {
static const std::unordered_set<GLenum> VALID_PARAM_NAMES = {
static const ankerl::unordered_set<GLenum> VALID_PARAM_NAMES = {
GL_BUFFER_ACCESS, GL_BUFFER_MAPPED, GL_BUFFER_SIZE, GL_BUFFER_USAGE
}; // OpenGL 3
static const std::unordered_set<GLenum> VALID_TARGETS = {
static const ankerl::unordered_set<GLenum> VALID_TARGETS = {
GL_ARRAY_BUFFER, GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, GL_ELEMENT_ARRAY_BUFFER,
GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER, GL_TEXTURE_BUFFER,
GL_TRANSFORM_FEEDBACK_BUFFER, GL_UNIFORM_BUFFER
}; // OpenGL 3
static const std::unordered_set<GLenum> VALID_ACCESS = {
static const ankerl::unordered_set<GLenum> VALID_ACCESS = {
GL_READ_ONLY, GL_WRITE_ONLY, GL_READ_WRITE
}; // OpenGL 3
}
namespace PixelStore {
static const std::unordered_map<GLenum, GLint> DEFAULT_VALUES_MAP = {
static const ankerl::unordered_map<GLenum, GLint> DEFAULT_VALUES_MAP = {
{GL_PACK_SWAP_BYTES, GL_FALSE},
{GL_PACK_LSB_FIRST, GL_FALSE},
{GL_PACK_ROW_LENGTH, 0},
@@ -102,7 +111,7 @@ namespace MG_Constants {
{GL_UNPACK_ALIGNMENT, 4}
}; // OpenGL 3
static const std::unordered_set<GLenum> VALID_PARAM_NAMES = {
static const ankerl::unordered_set<GLenum> VALID_PARAM_NAMES = {
GL_PACK_SWAP_BYTES, GL_PACK_LSB_FIRST, GL_PACK_ROW_LENGTH, GL_PACK_IMAGE_HEIGHT,
GL_PACK_SKIP_ROWS, GL_PACK_SKIP_PIXELS, GL_PACK_SKIP_IMAGES, GL_PACK_ALIGNMENT,
GL_UNPACK_SWAP_BYTES, GL_UNPACK_LSB_FIRST, GL_UNPACK_ROW_LENGTH,
@@ -116,18 +125,18 @@ namespace MG_Constants {
inline const GLuint MAX_TEXTURE_UNITS = 80;
const GLsizei MAX_TEXTURE_SIZE = 32768;
const GLsizei MAX_ARRAY_LAYERS = 256;
inline const std::unordered_set<GLenum> VALID_TARGETS = {
inline const ankerl::unordered_set<GLenum> VALID_TARGETS = {
GL_TEXTURE_2D, GL_PROXY_TEXTURE_2D, GL_TEXTURE_1D_ARRAY, GL_PROXY_TEXTURE_1D_ARRAY,
GL_TEXTURE_RECTANGLE, GL_PROXY_TEXTURE_RECTANGLE, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, GL_PROXY_TEXTURE_CUBE_MAP
}; // OpenGL 3
inline const std::unordered_set<GLenum> VALID_FORMATS = {
inline const ankerl::unordered_set<GLenum> VALID_FORMATS = {
GL_RED, GL_RG, GL_RGB, GL_BGR, GL_RGBA, GL_BGRA, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL
}; // OpenGL 3
inline const std::unordered_set<GLenum> VALID_INTERNAL_FORMATS = {
inline const ankerl::unordered_set<GLenum> VALID_INTERNAL_FORMATS = {
GL_RED, GL_RG, GL_RGB, GL_BGR, GL_RGBA, GL_BGRA, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL,
GL_RGBA32F, GL_RGBA32I, GL_RGBA32UI, GL_RGBA16, GL_RGBA16F, GL_RGBA16I,
GL_RGBA16UI, GL_RGBA8, GL_RGBA8UI, GL_SRGB8_ALPHA8, GL_RGB10_A2, GL_RGB10_A2UI,
@@ -137,12 +146,12 @@ namespace MG_Constants {
GL_RGB32F, GL_RGB32I, GL_RGB32UI, GL_RGB16_SNORM, GL_RGB16F, GL_RGB16I, GL_RGB16UI,
GL_RGB16, GL_RGB8_SNORM, GL_RGB8, GL_RGB8I, GL_RGB8UI, GL_SRGB8, GL_RGB9_E5,
GL_RG16_SNORM, GL_RG8_SNORM, GL_COMPRESSED_RG_RGTC2, GL_COMPRESSED_SIGNED_RG_RGTC2,
GL_R16_SNORM, GL_R8_SNORM, GL_COMPRESSED_RED_RGTC1, GL_COMPRESSED_SIGNED_RED_RGTC1,
GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16, GL_DEPTH32F_STENCIL8,
GL_DEPTH24_STENCIL8
GL_R16_SNORM, GL_R8_SNORM, GL_COMPRESSED_RED_RGTC1, GL_COMPRESSED_SIGNED_RED_RGTC1,
GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16,
GL_DEPTH32F_STENCIL8, GL_DEPTH24_STENCIL8
}; // OpenGL 3
inline const std::unordered_set<GLenum> VALID_TYPES = {
inline const ankerl::unordered_set<GLenum> VALID_TYPES = {
GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT,
GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV, GL_UNSIGNED_SHORT_5_6_5,
GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV,
@@ -150,14 +159,14 @@ namespace MG_Constants {
GL_UNSIGNED_INT_8_8_8_8_REV, GL_UNSIGNED_INT_10_10_10_2, GL_UNSIGNED_INT_2_10_10_10_REV
}; // OpenGL 3
inline const std::unordered_set<GLenum> VALID_TEXTURE_PARAM_NAMES = {
inline const ankerl::unordered_set<GLenum> VALID_TEXTURE_PARAM_NAMES = {
GL_TEXTURE_BASE_LEVEL, GL_TEXTURE_COMPARE_FUNC, GL_TEXTURE_COMPARE_MODE, GL_TEXTURE_MIN_FILTER,
GL_TEXTURE_MAG_FILTER, GL_TEXTURE_MAX_LEVEL, GL_TEXTURE_SWIZZLE_R, GL_TEXTURE_SWIZZLE_G,
GL_TEXTURE_SWIZZLE_B, GL_TEXTURE_SWIZZLE_A, GL_TEXTURE_SWIZZLE_RGBA, GL_TEXTURE_WRAP_S,
GL_TEXTURE_WRAP_T, GL_TEXTURE_WRAP_R, GL_TEXTURE_LOD_BIAS, GL_TEXTURE_MIN_LOD, GL_TEXTURE_MAX_LOD, GL_TEXTURE_BORDER_COLOR
}; // OpenGL 3
inline const std::unordered_set<GLenum> VALID_QUERY_LEVEL_PROPERTY_PARAM_NAMES = {
inline const ankerl::unordered_set<GLenum> VALID_QUERY_LEVEL_PROPERTY_PARAM_NAMES = {
GL_TEXTURE_WIDTH, GL_TEXTURE_HEIGHT, GL_TEXTURE_DEPTH, GL_TEXTURE_INTERNAL_FORMAT,
GL_TEXTURE_RED_SIZE, GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE, GL_TEXTURE_ALPHA_SIZE,
GL_TEXTURE_DEPTH_SIZE, GL_TEXTURE_COMPRESSED, GL_TEXTURE_COMPRESSED_IMAGE_SIZE
+1 -1
View File
@@ -27,7 +27,7 @@ namespace MG_Global {
}
namespace Common {
inline const int LogLevel = MG_Constants::Common::LOG_LEVEL_DEBUG;
inline constexpr int LogLevel = MG_Constants::Common::LOG_LEVEL_INFO;
#ifdef __ANDROID__
inline const char* LOG_FILE_PATH = "/sdcard/MG/latest.log";
+3 -1
View File
@@ -100,6 +100,7 @@
#include <optional>
#include <unordered_map>
#include <queue>
#include <format>
#include <glslang/Public/ShaderLang.h>
#include <glslang/Include/Types.h>
#include <glslang/Public/ShaderLang.h>
@@ -107,7 +108,8 @@
#include <glslang/SPIRV/GlslangToSpv.h>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/glm.hpp>
#include "GLES3/gl32.h"
#include <ankerl/unordered_dense.h>
#include <GLES3/gl32.h>
#include "MG_Include/UncertainBool.hpp"
+3 -3
View File
@@ -11,9 +11,9 @@ std::atomic<uintptr_t> g_nextSurfaceId{1};
EGLenum g_currentAPI = EGL_OPENGL_ES_API;
std::mutex g_globalMutex;
std::unordered_map<EGLDisplay, VulkanDisplay> g_displays;
std::unordered_map<EGLSurface, VulkanSurface> g_surfaces;
std::unordered_map<EGLContext, VulkanContext> g_contexts;
ankerl::unordered_map<EGLDisplay, VulkanDisplay> g_displays;
ankerl::unordered_map<EGLSurface, VulkanSurface> g_surfaces;
ankerl::unordered_map<EGLContext, VulkanContext> g_contexts;
EGLint g_lastError = EGL_SUCCESS;
thread_local EGLContext tls_currentContext = EGL_NO_CONTEXT;
+3 -3
View File
@@ -69,9 +69,9 @@ extern std::atomic<uintptr_t> g_nextSurfaceId;
extern EGLenum g_currentAPI;
extern std::mutex g_globalMutex;
extern std::unordered_map<EGLDisplay, VulkanDisplay> g_displays;
extern std::unordered_map<EGLSurface, VulkanSurface> g_surfaces;
extern std::unordered_map<EGLContext, VulkanContext> g_contexts;
extern ankerl::unordered_map<EGLDisplay, VulkanDisplay> g_displays;
extern ankerl::unordered_map<EGLSurface, VulkanSurface> g_surfaces;
extern ankerl::unordered_map<EGLContext, VulkanContext> g_contexts;
extern EGLint g_lastError;
extern thread_local EGLContext tls_currentContext;
@@ -5,41 +5,98 @@
#include "GL_Buffer.h"
namespace MG_GL::GL {
void* MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
GLbitfield access) {
MG_Util::Debug::LogD("glMapBufferRange, target: %s, offset: %lld, length: %lld, access: 0x%X",
MG_Util::Debug::GLEnumToString(target),
static_cast<long long>(offset),
static_cast<long long>(length),
access);
void* mappedPointer = nullptr;
GLenum result = MG_State::AcquireBufferMemoryRange(target, offset, length, access, &mappedPointer);
if (result == GL_NO_ERROR) {
MG_Util::Debug::LogD("Mapped pointer: %p", mappedPointer);
return mappedPointer;
}
MG_State::SetError(result);
MG_Util::Debug::LogE("Error mapping buffer range: %s", MG_Util::Debug::GLEnumToString(result));
return nullptr;
}
void FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) {
MG_Util::Debug::LogD("glFlushMappedBufferRange, target: %s, offset: %lld, length: %lld",
MG_Util::Debug::GLEnumToString(target),
static_cast<long long>(offset),
static_cast<long long>(length));
GLenum result = MG_State::SyncBufferMemory(target, offset, length);
if (result == GL_NO_ERROR) {
return;
}
MG_State::SetError(result);
MG_Util::Debug::LogE("Error flushing mapped buffer range: %s",
MG_Util::Debug::GLEnumToString(result));
}
void CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
GLintptr readOffset, GLintptr writeOffset,
GLsizeiptr size) {
MG_Util::Debug::LogD("glCopyBufferSubData, readTarget: %s, writeTarget: %s, "
"readOffset: %lld, writeOffset: %lld, size: %lld",
MG_Util::Debug::GLEnumToString(readTarget),
MG_Util::Debug::GLEnumToString(writeTarget),
static_cast<long long>(readOffset),
static_cast<long long>(writeOffset),
static_cast<long long>(size));
GLenum result = MG_State::CopyBufferRange(readTarget, writeTarget, readOffset, writeOffset, size);
if (result == GL_NO_ERROR) {
return;
}
MG_State::SetError(result);
MG_Util::Debug::LogE("Error copying buffer subdata: %s",
MG_Util::Debug::GLEnumToString(result));
}
void* MapBuffer(GLenum target, GLenum access) {
MG_Util::Debug::LogD("glMapBuffer(target=0x%x, access=0x%x)", target, access);
void* mappedPtr = nullptr;
GLenum err = MG_State::AcquireBufferMemory(target, access, &mappedPtr);
if (err != GL_NO_ERROR) {
MG_State::SetError(err);
MG_Util::Debug::LogE("glMapBuffer failed: %s",
MG_Util::Debug::GLEnumToString(err));
MG_Util::Debug::LogE("glMapBuffer failed: %s", MG_Util::Debug::GLEnumToString(err));
return nullptr;
}
MG_Util::Debug::LogD("glMapBuffer returns %p", mappedPtr);
return mappedPtr;
}
GLboolean UnmapBuffer(GLenum target) {
MG_Util::Debug::LogD("glUnmapBuffer(target=0x%x)", target);
GLenum err = MG_State::ReleaseBufferMemory(target);
if (err != GL_NO_ERROR) {
MG_State::SetError(err);
MG_Util::Debug::LogE("glUnmapBuffer failed: %s",
MG_Util::Debug::GLEnumToString(err));
MG_Util::Debug::LogE("glUnmapBuffer failed: %s", MG_Util::Debug::GLEnumToString(err));
return GL_FALSE;
}
MG_Util::Debug::LogD("glUnmapBuffer succeeded");
return GL_TRUE;
}
void BindBuffer(GLenum target, GLuint buffer) {
MG_Util::Debug::LogD("glBindBuffer, target: %d, buffer: %d", target, buffer);
if (buffer != 0 && !MG_State::ValidateBufferHandle(buffer)) {
MG_Util::Debug::LogD("glBindBuffer, target: %s, buffer: %d", MG_Util::Debug::GLEnumToString(target), buffer);
if (buffer != 0 &&
MG_State::ValidateGeneratedName(buffer) &&
!MG_State::ValidateAllocatedBufferHandle(buffer)) {
MG_Util::Debug::LogD("Actually creating buffer: %u", buffer);
GLenum result = MG_State::CreateBuffer(buffer);
if (result != GL_NO_ERROR) {
MG_State::SetError(result);
MG_Util::Debug::LogE("Error from MG State: %s", MG_Util::Debug::GLEnumToString(result));
return;
}
}
if (buffer != 0 && !MG_State::ValidateAllocatedBufferHandle(buffer)) {
MG_State::SetError(GL_INVALID_VALUE);
MG_Util::Debug::LogE("Invalid buffer handle: %u", buffer);
return;
@@ -52,8 +109,8 @@ namespace MG_GL::GL {
}
void BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage) {
MG_Util::Debug::LogD("glBufferData, target: %d, size: %zd, data: %p, usage: %d",
target, size, data, usage);
MG_Util::Debug::LogD("glBufferData, target: %s, size: %zd, data: %p, usage: %s",
MG_Util::Debug::GLEnumToString(target), size, data, MG_Util::Debug::GLEnumToString(usage));
GLenum result = MG_State::CommitBufferStorage(target, size, data, usage);
if (result == GL_NO_ERROR)
return;
@@ -80,9 +137,9 @@ namespace MG_GL::GL {
return;
}
GLenum result = MG_State::CreateBuffers(n, buffers);
GLenum result = MG_State::GenBufferNames(n, buffers);
if (result == GL_NO_ERROR) {
MG_Util::Debug::LogD("Generated buffers:");
MG_Util::Debug::LogD("Generated buffer names:");
for (GLsizei i = 0; i < n; ++i) {
MG_Util::Debug::LogD(" Buffer[%d] = %u", i, buffers[i]);
}
@@ -100,9 +157,32 @@ namespace MG_GL::GL {
return GL_FALSE;
}
bool isValid = MG_State::ValidateBufferHandle(buffer);
bool isValid = MG_State::ValidateAllocatedBufferHandle(buffer);
// Should we report gl error here or in MG_State?
MG_Util::Debug::LogD("Buffer %u is %s", buffer, isValid ? "valid" : "invalid");
return isValid ? GL_TRUE : GL_FALSE;
}
void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void* data) {
MG_Util::Debug::LogD("glBufferSubData, target: %s, offset: %lld, size: %lld, data: %p",
MG_Util::Debug::GLEnumToString(target),
static_cast<long long>(offset),
static_cast<long long>(size),
data);
GLenum result = MG_State::CommitBufferStorageRegion(target, offset, size, data);
if (result != GL_NO_ERROR) {
MG_State::SetError(result);
MG_Util::Debug::LogE("Error from MG State: %s", MG_Util::Debug::GLEnumToString(result));
}
}
void DeleteBuffers(GLsizei n, const GLuint *buffers) {
MG_Util::Debug::LogD("glDeleteBuffers, n: %d, buffers: %p", n, buffers);
GLenum result = MG_State::DeleteBuffers(n, buffers);
if (result == GL_NO_ERROR)
return;
MG_State::SetError(result);
MG_Util::Debug::LogE("Error from MG State: %s", MG_Util::Debug::GLEnumToString(result));
}
}
@@ -8,12 +8,17 @@
#include "../../../../Includes.h"
namespace MG_GL::GL {
void* MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
void FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length);
void CopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
void* MapBuffer(GLenum target, GLenum access);
GLboolean UnmapBuffer(GLenum target);
void BindBuffer(GLenum target, GLuint buffer);
void BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void* data);
void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params);
void GenBuffers(GLsizei n, GLuint* buffers);
void DeleteBuffers(GLsizei n, const GLuint *buffers);
GLboolean IsBuffer(GLuint buffer);
}
@@ -5,6 +5,16 @@
#include "GL_Common.h"
namespace MG_GL::GL {
void Clear(GLbitfield mask) {
MG_Util::Debug::LogD("glClear, mask: 0x%X", mask);
GLenum result = MG_State::glClear(mask);
if (result == GL_NO_ERROR) {
return;
}
MG_State::SetError(result);
MG_Util::Debug::LogE("Error clearing buffers: %s", MG_Util::Debug::GLEnumToString(result));
}
void Enable(GLenum cap) {
MG_Util::Debug::LogD("glEnable, cap: %s", MG_Util::Debug::GLEnumToString(cap));
GLenum result = MG_State::glEnable(cap);
@@ -43,14 +53,6 @@ namespace MG_GL::GL {
MG_Util::Debug::LogE("Error setting separate blend func: %s", MG_Util::Debug::GLEnumToString(result));
}
void Clear(GLbitfield mask) {
MG_Util::Debug::LogD("glClear, mask: 0x%X", mask);
GLenum result = MG_State::glClear(mask);
if (result == GL_NO_ERROR) return;
MG_State::SetError(result);
MG_Util::Debug::LogE("Error clearing buffers: %s", MG_Util::Debug::GLEnumToString(result));
}
void ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
MG_Util::Debug::LogD("glClearColor, rgba: [%.2f, %.2f, %.2f, %.2f]", red, green, blue, alpha);
GLenum result = MG_State::glClearColor(red, green, blue, alpha);
@@ -5,13 +5,27 @@
#include "GL_Drawing.h"
namespace MG_GL::GL {
// This is a test function that directly draws textures.
void DrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) {
::GLES::glViewport(0,0,3200,1440);
MG_RHI::GLES::Test::DrawAllTextures();
};
// TODO
}
void DrawArrays(GLenum mode, GLint first, GLsizei count) {
::GLES::glViewport(0,0,3200,1440);
MG_RHI::GLES::Test::DrawAllTextures();
};
// TODO
}
void DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex) {
// TODO
}
void MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, const GLvoid *const *indices, GLsizei drawcount) {
// TODO
}
void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, GLenum type, const GLvoid *const *indices, GLsizei drawcount, const GLint *basevertex) {
// TODO
}
void DrawBuffer(GLenum buf) {
// TODO
}
}
@@ -4,12 +4,15 @@
#ifndef MOBILEGL_GL_DRAWING_H
#define MOBILEGL_GL_DRAWING_H
#include "../../../../Includes.h"
namespace MG_GL::GL {
void DrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
void DrawArrays(GLenum mode, GLint first, GLsizei count);
void DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
void MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, const GLvoid *const *indices, GLsizei drawcount);
void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, GLenum type, const GLvoid *const *indices, GLsizei drawcount, const GLint *basevertex);
void DrawBuffer(GLenum buf);
}
#endif //MOBILEGL_GL_DRAWING_H
@@ -45,6 +45,7 @@ namespace MG_GL::GL {
GLenum result = MG_State::AttachTexture2DToFramebuffer(
target, attachment, textarget, texture, level
);
if (result == GL_NO_ERROR) return;
MG_State::SetError(result);
MG_Util::Debug::LogE("Texture attachment failed: %s", MG_Util::Debug::GLEnumToString(result));
@@ -64,4 +65,9 @@ namespace MG_GL::GL {
MG_Util::Debug::GLEnumToString(result));
return result;
}
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
// TODO
}
}
@@ -13,6 +13,7 @@ namespace MG_GL::GL {
void BindFramebuffer(GLenum target, GLuint framebuffer);
void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
GLenum CheckFramebufferStatus(GLenum target);
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
}
#endif //MOBILEGL_GL_FRAMEBUFFER_H
@@ -46,7 +46,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, BlendEquationSeparate, GLenum modeRGB, GLenu
DECLARE_GL_FUNCTION_HEAD(void, BlendFunc, GLenum sfactor, GLenum dfactor) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BlendFunc, sfactor,dfactor)
DECLARE_GL_FUNCTION_HEAD(void, BlendFuncSeparate, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BlendFuncSeparate, sfactorRGB,dfactorRGB,sfactorAlpha,dfactorAlpha)
DECLARE_GL_FUNCTION_HEAD(void, BufferData, GLenum target, GLsizeiptr size, const void *data, GLenum usage) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BufferData, target,size,data,usage)
DECLARE_GL_FUNCTION_STUB_HEAD(void, BufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const void *data) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BufferSubData, target,offset,size,data)
DECLARE_GL_FUNCTION_HEAD(void, BufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const void *data) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BufferSubData, target,offset,size,data)
DECLARE_GL_FUNCTION_HEAD(GLenum, CheckFramebufferStatus, GLenum target) DECLARE_GL_FUNCTION_END(GLenum, CheckFramebufferStatus, target)
DECLARE_GL_FUNCTION_HEAD(void, Clear, GLbitfield mask) DECLARE_GL_FUNCTION_END_NO_RETURN(void, Clear, mask)
DECLARE_GL_FUNCTION_HEAD(void, ClearColor, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ClearColor, red,green,blue,alpha)
@@ -61,7 +61,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, CopyTexSubImage2D, GLenum target, GLint leve
DECLARE_GL_FUNCTION_HEAD(GLuint, CreateProgram) DECLARE_GL_FUNCTION_END(GLuint, CreateProgram)
DECLARE_GL_FUNCTION_HEAD(GLuint, CreateShader, GLenum type) DECLARE_GL_FUNCTION_END(GLuint, CreateShader, type)
DECLARE_GL_FUNCTION_STUB_HEAD(void, CullFace, GLenum mode) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, CullFace, mode)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DeleteBuffers, GLsizei n, const GLuint *buffers) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DeleteBuffers, n,buffers)
DECLARE_GL_FUNCTION_HEAD(void, DeleteBuffers, GLsizei n, const GLuint *buffers) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DeleteBuffers, n,buffers)
DECLARE_GL_FUNCTION_HEAD(void, DeleteFramebuffers, GLsizei n, const GLuint *framebuffers) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DeleteFramebuffers, n,framebuffers)
DECLARE_GL_FUNCTION_HEAD(void, DeleteProgram, GLuint program) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DeleteProgram, program)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DeleteRenderbuffers, GLsizei n, const GLuint *renderbuffers) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DeleteRenderbuffers, n,renderbuffers)
@@ -197,10 +197,11 @@ DECLARE_GL_FUNCTION_HEAD(void, UniformMatrix2x4fv, GLint location, GLsizei count
DECLARE_GL_FUNCTION_HEAD(void, UniformMatrix4x2fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, UniformMatrix4x2fv, location,count,transpose,value)
DECLARE_GL_FUNCTION_HEAD(void, UniformMatrix3x4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, UniformMatrix3x4fv, location,count,transpose,value)
DECLARE_GL_FUNCTION_HEAD(void, UniformMatrix4x3fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, UniformMatrix4x3fv, location,count,transpose,value)
DECLARE_GL_FUNCTION_STUB_HEAD(void, BlitFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BlitFramebuffer, srcX0,srcY0,srcX1,srcY1,dstX0,dstY0,dstX1,dstY1,mask,filter)
DECLARE_GL_FUNCTION_HEAD(void, BlitFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BlitFramebuffer, srcX0,srcY0,srcX1,srcY1,dstX0,dstY0,dstX1,dstY1,mask,filter)
//DECLARE_GL_FUNCTION_STUB_HEAD(void, BlitFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BlitFramebuffer, srcX0,srcY0,srcX1,srcY1,dstX0,dstY0,dstX1,dstY1,mask,filter)
DECLARE_GL_FUNCTION_STUB_HEAD(void, RenderbufferStorageMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, RenderbufferStorageMultisample, target,samples,internalformat,width,height)
DECLARE_GL_FUNCTION_STUB_HEAD(void, FramebufferTextureLayer, GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, FramebufferTextureLayer, target,attachment,texture,level,layer)
DECLARE_GL_FUNCTION_STUB_HEAD(void, FlushMappedBufferRange, GLenum target, GLintptr offset, GLsizeiptr length) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, FlushMappedBufferRange, target,offset,length)
DECLARE_GL_FUNCTION_HEAD(void, FlushMappedBufferRange, GLenum target, GLintptr offset, GLsizeiptr length) DECLARE_GL_FUNCTION_END_NO_RETURN(void, FlushMappedBufferRange, target,offset,length)
DECLARE_GL_FUNCTION_HEAD(void, BindVertexArray, GLuint array) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BindVertexArray, array)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DeleteVertexArrays, GLsizei n, const GLuint *arrays) DECLARE_GL_FUNCTION_STUB_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)
@@ -233,7 +234,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, ClearBufferiv, GLenum buffer, GLint drawbuff
DECLARE_GL_FUNCTION_STUB_HEAD(void, ClearBufferuiv, GLenum buffer, GLint drawbuffer, const GLuint *value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ClearBufferuiv, buffer,drawbuffer,value)
DECLARE_GL_FUNCTION_STUB_HEAD(void, ClearBufferfv, GLenum buffer, GLint drawbuffer, const GLfloat *value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ClearBufferfv, buffer,drawbuffer,value)
DECLARE_GL_FUNCTION_STUB_HEAD(void, ClearBufferfi, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ClearBufferfi, buffer,drawbuffer,depth,stencil)
DECLARE_GL_FUNCTION_STUB_HEAD(void, CopyBufferSubData, GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, CopyBufferSubData, readTarget,writeTarget,readOffset,writeOffset,size)
DECLARE_GL_FUNCTION_HEAD(void, CopyBufferSubData, GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) DECLARE_GL_FUNCTION_END_NO_RETURN(void, CopyBufferSubData, readTarget,writeTarget,readOffset,writeOffset,size)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetUniformIndices, GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetUniformIndices, program,uniformCount,uniformNames,uniformIndices)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetActiveUniformsiv, GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetActiveUniformsiv, program,uniformCount,uniformIndices,pname,params)
DECLARE_GL_FUNCTION_STUB_HEAD(GLuint, GetUniformBlockIndex, GLuint program, const GLchar *uniformBlockName) DECLARE_GL_FUNCTION_STUB_END(GLuint, GetUniformBlockIndex, program,uniformBlockName)
@@ -365,7 +366,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, BlendFunci, GLuint buf, GLenum src, GLenum d
DECLARE_GL_FUNCTION_STUB_HEAD(void, BlendFuncSeparatei, GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BlendFuncSeparatei, buf,srcRGB,dstRGB,srcAlpha,dstAlpha)
DECLARE_GL_FUNCTION_STUB_HEAD(void, ColorMaski, GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ColorMaski, index,r,g,b,a)
DECLARE_GL_FUNCTION_STUB_HEAD(GLboolean, IsEnabledi, GLenum target, GLuint index) DECLARE_GL_FUNCTION_STUB_END(GLboolean, IsEnabledi, target,index)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DrawElementsBaseVertex, GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DrawElementsBaseVertex, mode,count,type,indices,basevertex)
DECLARE_GL_FUNCTION_HEAD(void, DrawElementsBaseVertex, GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DrawElementsBaseVertex, mode,count,type,indices,basevertex)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DrawRangeElementsBaseVertex, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DrawRangeElementsBaseVertex, mode,start,end,count,type,indices,basevertex)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DrawElementsInstancedBaseVertex, GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DrawElementsInstancedBaseVertex, mode,count,type,indices,instancecount,basevertex)
DECLARE_GL_FUNCTION_STUB_HEAD(void, FramebufferTexture, GLenum target, GLenum attachment, GLuint texture, GLint level) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, FramebufferTexture, target,attachment,texture,level)
@@ -388,7 +389,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, GetSamplerParameterIuiv, GLuint sampler, GLe
DECLARE_GL_FUNCTION_STUB_HEAD(void, TexBuffer, GLenum target, GLenum internalformat, GLuint buffer) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TexBuffer, target,internalformat,buffer)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TexBufferRange, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TexBufferRange, target,internalformat,buffer,offset,size)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TexStorage3DMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TexStorage3DMultisample, target,samples,internalformat,width,height,depth,fixedsamplelocations)
DECLARE_GL_FUNCTION_STUB_HEAD(void*, MapBufferRange, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) DECLARE_GL_FUNCTION_STUB_END(void*, MapBufferRange, target,offset,length,access)
DECLARE_GL_FUNCTION_HEAD(void*, MapBufferRange, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) DECLARE_GL_FUNCTION_END(void*, MapBufferRange, target,offset,length,access)
DECLARE_GL_FUNCTION_STUB_HEAD(void, ClearIndex, GLfloat c ) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ClearIndex,c)
DECLARE_GL_FUNCTION_STUB_HEAD(void, IndexMask, GLuint mask ) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, IndexMask,mask)
DECLARE_GL_FUNCTION_STUB_HEAD(void, AlphaFunc, GLenum func, GLclampf ref ) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, AlphaFunc,func,ref)
@@ -402,7 +403,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, EdgeFlag, GLboolean flag ) DECLARE_GL_FUNCTI
DECLARE_GL_FUNCTION_STUB_HEAD(void, EdgeFlagv, const GLboolean *flag ) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, EdgeFlagv,flag)
DECLARE_GL_FUNCTION_STUB_HEAD(void, ClipPlane, GLenum plane, const GLdouble *equation ) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ClipPlane,plane,equation)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetClipPlane, GLenum plane, GLdouble *equation ) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetClipPlane,plane,equation)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DrawBuffer, GLenum mode ) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DrawBuffer,mode)
DECLARE_GL_FUNCTION_HEAD(void, DrawBuffer, GLenum mode ) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DrawBuffer,mode)
DECLARE_GL_FUNCTION_STUB_HEAD(void, EnableClientState, GLenum cap ) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, EnableClientState,cap)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DisableClientState, GLenum cap ) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DisableClientState,cap)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetDoublev, GLenum pname, GLdouble *params ) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetDoublev,pname,params)
@@ -738,7 +739,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, LoadTransposeMatrixd,const GLdouble* m) DECL
DECLARE_GL_FUNCTION_STUB_HEAD(void, MultTransposeMatrixf,const GLfloat* m) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, MultTransposeMatrixf,m)
DECLARE_GL_FUNCTION_STUB_HEAD(void, MultTransposeMatrixd,const GLdouble* m) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, MultTransposeMatrixd,m)
DECLARE_GL_FUNCTION_STUB_HEAD(void, MultiDrawArrays, GLenum mode, const GLint* first, const GLsizei* count, GLsizei drawcount) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, MultiDrawArrays,mode,first,count,drawcount)
DECLARE_GL_FUNCTION_STUB_HEAD(void, MultiDrawElements, GLenum mode, const GLsizei* count, GLenum type, const void* const*indices, GLsizei drawcount) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, MultiDrawElements,mode,count,type,indices,drawcount)
DECLARE_GL_FUNCTION_HEAD(void, MultiDrawElements, GLenum mode, const GLsizei* count, GLenum type, const void* const*indices, GLsizei drawcount) DECLARE_GL_FUNCTION_END_NO_RETURN(void, MultiDrawElements,mode,count,type,indices,drawcount)
DECLARE_GL_FUNCTION_STUB_HEAD(void, PointParameterf, GLenum pname, GLfloat param) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, PointParameterf,pname,param)
DECLARE_GL_FUNCTION_STUB_HEAD(void, PointParameterfv, GLenum pname, const GLfloat* params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, PointParameterfv,pname,params)
DECLARE_GL_FUNCTION_STUB_HEAD(void, PointParameteri, GLenum pname, GLint param) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, PointParameteri,pname,param)
@@ -814,7 +815,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, VertexAttrib4uiv, GLuint index, const GLuint
DECLARE_GL_FUNCTION_STUB_HEAD(void, VertexAttrib4usv, GLuint index, const GLushort* v) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, VertexAttrib4usv,index,v)
DECLARE_GL_FUNCTION_STUB_HEAD(void, PrimitiveRestartIndex, GLuint index) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, PrimitiveRestartIndex,index)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetActiveUniformName, GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformName) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetActiveUniformName,program,uniformIndex,bufSize,length,uniformName)
DECLARE_GL_FUNCTION_STUB_HEAD(void, MultiDrawElementsBaseVertex, GLenum mode, const GLsizei* count, GLenum type, const void* const*indices, GLsizei drawcount, const GLint* basevertex) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, MultiDrawElementsBaseVertex,mode,count,type,indices,drawcount,basevertex)
DECLARE_GL_FUNCTION_HEAD(void, MultiDrawElementsBaseVertex, GLenum mode, const GLsizei* count, GLenum type, const void* const*indices, GLsizei drawcount, const GLint* basevertex) DECLARE_GL_FUNCTION_END_NO_RETURN(void, MultiDrawElementsBaseVertex,mode,count,type,indices,drawcount,basevertex)
DECLARE_GL_FUNCTION_STUB_HEAD(void, ProvokingVertex, GLenum mode) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ProvokingVertex,mode)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TexImage2DMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TexImage2DMultisample,target,samples,internalformat,width,height,fixedsamplelocations)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TexImage3DMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TexImage3DMultisample,target,samples,internalformat,width,height,depth,fixedsamplelocations)
+167 -23
View File
@@ -44,7 +44,7 @@ namespace MG_GL::GL {
}
return (const GLubyte *)rendererString.c_str();
*/
return (const GLubyte *)(MG_GL::Getter::GetMGName() + "(MobileGL Core) Renderer").c_str();
return (const GLubyte *)(MG_GL::Getter::GetMGName() + " (MobileGL Core) Renderer").c_str();
}
case GL_SHADING_LANGUAGE_VERSION:
return (const GLubyte *) "4.50 MobileGL with glslang";
@@ -114,37 +114,181 @@ namespace MG_GL::GL {
void GetIntegerv(GLenum pname, GLint *params) {
MG_Util::Debug::LogD("glGetIntegerv, pname: %s", MG_Util::Debug::GLEnumToString(pname));
if (!params) {
MG_State::SetError(GL_INVALID_VALUE);
return;
}
switch (pname) {
case GL_CONTEXT_PROFILE_MASK:
(*params) = GL_CONTEXT_CORE_PROFILE_BIT;
// Viewport and scissor
case GL_VIEWPORT:
memcpy(params, MG_State_T::commonState->viewport, 4 * sizeof(GLint));
break;
case GL_NUM_EXTENSIONS:
static GLint num_extensions = -1;
if (num_extensions == -1) {
const GLubyte* ext_str = MG_GL::GL::GetString(GL_EXTENSIONS);
char *copy = strdup((const char *) ext_str);
char *token = strtok(copy, " ");
num_extensions = 0;
while (token) {
num_extensions++;
token = strtok(nullptr, " ");
}
free(copy);
}
(*params) = num_extensions;
case GL_SCISSOR_BOX:
// TODO: memcpy(params, MG_State_T::commonState->scissorBox, 4 * sizeof(GLint));
break;
case GL_MAJOR_VERSION:
(*params) = MG_Global::GL::GLVersionMajor;
case GL_MAX_VIEWPORT_DIMS: {
static const GLint maxDims[2] = {16384, 16384};
memcpy(params, maxDims, sizeof(maxDims));
break;
case GL_MINOR_VERSION:
(*params) = MG_Global::GL::GLVersionMinor;
}
// Buffer bindings
case GL_ARRAY_BUFFER_BINDING:
params[0] = static_cast<GLint>(MG_State_T::bufferState->GetCurrentBinding(GL_ARRAY_BUFFER));
break;
case GL_ELEMENT_ARRAY_BUFFER_BINDING:
params[0] = static_cast<GLint>(MG_State_T::vertexArrayState->GetBoundElementBuffer());
break;
case GL_DRAW_FRAMEBUFFER_BINDING:
params[0] = static_cast<GLint>(MG_State_T::framebufferState->currentBindings_[GL_DRAW_FRAMEBUFFER]);
break;
case GL_READ_FRAMEBUFFER_BINDING:
params[0] = static_cast<GLint>(MG_State_T::framebufferState->currentBindings_[GL_READ_FRAMEBUFFER]);
break;
case GL_RENDERBUFFER_BINDING:
// TODO: params[0] = static_cast<GLint>(MG_State_T::framebufferState->currentRenderbuffer_);
break;
// Program state
case GL_CURRENT_PROGRAM:
params[0] = static_cast<GLint>(MG_State_T::programState->currentProgram_);
break;
case GL_MAX_VERTEX_ATTRIBS:
// TODO: Check the real value
params[0] = 64;
break;
// Texture state
case GL_TEXTURE_BINDING_2D: {
GLuint unit = MG_State_T::textureState->activeTextureUnit_;
auto& textures = MG_State_T::textureState->textureUnits_[unit].boundTextures;
params[0] = textures.count(GL_TEXTURE_2D) ? static_cast<GLint>(textures[GL_TEXTURE_2D]) : 0;
break;
}
case GL_ACTIVE_TEXTURE:
params[0] = GL_TEXTURE0 + MG_State_T::textureState->activeTextureUnit_;
break;
case GL_MAX_TEXTURE_SIZE:
// TODO: Get real GL_MAX_TEXTURE_SIZE.
(*params) = 32768;
params[0] = 8192;
break;
// Blend state
case GL_BLEND_SRC_RGB:
params[0] = static_cast<GLint>(MG_State_T::commonState->blendSrcRGB);
break;
case GL_BLEND_DST_RGB:
params[0] = static_cast<GLint>(MG_State_T::commonState->blendDstRGB);
break;
case GL_BLEND_SRC_ALPHA:
params[0] = static_cast<GLint>(MG_State_T::commonState->blendSrcAlpha);
break;
case GL_BLEND_DST_ALPHA:
params[0] = static_cast<GLint>(MG_State_T::commonState->blendDstAlpha);
break;
// Depth and stencil
case GL_DEPTH_FUNC:
params[0] = static_cast<GLint>(MG_State_T::commonState->depthFunc);
break;
case GL_DEPTH_WRITEMASK:
params[0] = static_cast<GLint>(MG_State_T::commonState->depthMask);
break;
case GL_STENCIL_REF:
// TODO: params[0] = MG_State_T::commonState->stencilRef;
break;
// Capability enables
case GL_BLEND:
params[0] = MG_State_T::commonState->capabilities[GL_BLEND] ? GL_TRUE : GL_FALSE;
break;
case GL_DEPTH_TEST:
params[0] = MG_State_T::commonState->capabilities[GL_DEPTH_TEST] ? GL_TRUE : GL_FALSE;
break;
case GL_SCISSOR_TEST:
params[0] = MG_State_T::commonState->capabilities[GL_SCISSOR_TEST] ? GL_TRUE : GL_FALSE;
break;
// Pixel operations
case GL_PACK_ALIGNMENT:
params[0] = MG_State_T::commonState->QueryPixelStoreInt(GL_PACK_ALIGNMENT);
break;
case GL_UNPACK_ALIGNMENT:
params[0] = MG_State_T::commonState->QueryPixelStoreInt(GL_UNPACK_ALIGNMENT);
break;
// Hardware limits, TODO: Check the real values
case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
params[0] = 32;
break;
case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
params[0] = 32;
break;
case GL_MAX_TEXTURE_IMAGE_UNITS:
params[0] = 32;
break;
case GL_MAX_RENDERBUFFER_SIZE:
params[0] = 65537;
break;
case GL_MAX_DRAW_BUFFERS:
params[0] = 32;
break;
case GL_MAX_COLOR_ATTACHMENTS:
params[0] = 32;
break;
// Color state
case GL_COLOR_CLEAR_VALUE: {
const auto& c = MG_State_T::commonState->clearColor;
params[0] = static_cast<GLint>(c[0] * 0x7FFF);
params[1] = static_cast<GLint>(c[1] * 0x7FFF);
params[2] = static_cast<GLint>(c[2] * 0x7FFF);
params[3] = static_cast<GLint>(c[3] * 0x7FFF);
break;
}
case GL_COLOR_WRITEMASK:
params[0] = MG_State_T::commonState->colorMask[0];
params[1] = MG_State_T::commonState->colorMask[1];
params[2] = MG_State_T::commonState->colorMask[2];
params[3] = MG_State_T::commonState->colorMask[3];
break;
// Stencil operations
case GL_STENCIL_CLEAR_VALUE:
// TODO: params[0] = MG_State_T::commonState->stencilClearValue;
break;
case GL_STENCIL_BITS:
// TODO: Check the real value
params[0] = 8;
break;
// Implementation limits
case GL_SUBPIXEL_BITS:
// TODO: Check the real value
params[0] = 4;
break;
case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
// TODO: params[0] = static_cast<GLint>(MG_State_T::textureState->compressedFormats_.size());
break;
case GL_COMPRESSED_TEXTURE_FORMATS:
// TODO: Implement GL_COMPRESSED_TEXTURE_FORMATS
break;
// Polygon state
case GL_POLYGON_OFFSET_FACTOR:
// TODO: params[0] = static_cast<GLint>(MG_State_T::commonState->polygonOffsetFactor);
break;
case GL_POLYGON_OFFSET_UNITS:
// TODO: params[0] = static_cast<GLint>(MG_State_T::commonState->polygonOffsetUnits);
break;
// Others...
default:
MG_Util::Debug::LogE("glGetIntegerv: Invalid enum %s (0x%X)", MG_Util::Debug::GLEnumToString(pname), pname);
MG_State::SetError(GL_INVALID_ENUM);
break;
}
}
}
@@ -7,7 +7,7 @@
namespace MG_GL::GL {
void GenVertexArrays(GLsizei n, GLuint* arrays) {
MG_Util::Debug::LogD("glGenVertexArrays, n: %d, arrays: %p", n, arrays);
GLenum result = MG_State::CreateVertexArrays(n, arrays);
GLenum result = MG_State::GenVertexArraysNames(n, arrays);
if (result == GL_NO_ERROR) return;
MG_State::SetError(result);
MG_Util::Debug::LogE("Error from MG State: %s", MG_Util::Debug::GLEnumToString(result));
+182 -58
View File
@@ -6,58 +6,60 @@
#include "BufferState.h"
GLenum BufferState::Create(GLuint* buffer) {
MG_Util::Debug::LogD("MG_State: Buffer: Create called");
if (!buffer) return GL_INVALID_VALUE;
GLenum BufferState::GenName(GLuint *buffer) {
MG_Util::Debug::LogD("MG_State: Buffer: GenName");
if (!buffer)
return GL_INVALID_VALUE;
GLuint id = 0;
if (!freeIds_.empty()) {
id = *freeIds_.begin();
freeIds_.erase(freeIds_.begin());
if (freeId_.empty()) {
id = lastId_++;
} else {
id = ++lastId_;
id = freeId_.back();
freeId_.pop_back();
}
*buffer = id;
BufferObject& obj = buffers_[id];
MG_Util::Debug::LogD("MG_State: Buffer: Create created buffer %d", id);
obj.generated = true;
MG_Util::Debug::LogD("MG_State: Buffer: Gen new name %d", id);
return GL_NO_ERROR;
}
GLenum BufferState::CreateN(GLsizei n, GLuint* buffers) {
MG_Util::Debug::LogD("MG_State: Buffer: CreateN called with n=%d", n);
GLenum BufferState::GenNameN(GLsizei n, GLuint* buffers) {
MG_Util::Debug::LogD("MG_State: Buffer: GenNameN called with n=%d", n);
if (n < 0) return GL_INVALID_VALUE;
for (GLsizei i = 0; i < n; ++i) {
GLenum result = Create(&buffers[i]);
GLenum result = GenName(&buffers[i]);
if (result != GL_NO_ERROR) {
MG_Util::Debug::LogE("MG_State: Buffer: CreateN create buffer failed with error 0x%x", result);
MG_Util::Debug::LogE("MG_State: Buffer: GenNameN failed with error 0x%x", result);
return result;
}
}
MG_Util::Debug::LogD("MG_State: Buffer: CreateN created buffers successfully");
MG_Util::Debug::LogD("MG_State: Buffer: GenNameN created buffers successfully");
return GL_NO_ERROR;
}
GLenum BufferState::Create(GLuint buffer) {
MG_Util::Debug::LogD("MG_State: Buffer: Create called");
if (!buffer)
return GL_INVALID_VALUE;
if (ValidateAllocatedHandle(buffer))
return GL_INVALID_VALUE;
BufferObject& obj = buffers_[buffer];
MG_Util::Debug::LogD("MG_State: Buffer: Create created buffer %d", buffer);
obj.generated = true;
obj.dirty = true;
return GL_NO_ERROR;
}
GLenum BufferState::Bind(GLenum target, GLuint buffer) {
// We don't handle unallocated buffer names here, just plain bind
if (!IsValidTarget_(target)) return GL_INVALID_ENUM;
MG_Util::Debug::LogD("MG_State: Buffer: Bind called with target=0x%x, buffer=%u", target, buffer);
if (buffer != 0) {
auto it = buffers_.find(buffer);
if (it == buffers_.end()) {
buffers_[buffer];
} else {
BufferObject& obj = it->second;
if (obj.target != 0 && obj.target != target) {
MG_Util::Debug::LogE("MG_State: Buffer: Bind can not bind a buffer to different target 0x%x, current bind target is 0x%x", target, obj.target);
return GL_INVALID_OPERATION;
}
}
buffers_[buffer].target = target;
}
MG_Util::Debug::LogD("MG_State: Buffer: Bind called with target=%s, buffer=%u", MG_Util::Debug::GLEnumToString(target), buffer);
currentBindings_[target] = buffer;
MG_Util::Debug::LogD("MG_State: Buffer: Bind succeed bind buffer %u to target 0x%x", buffer, target);
return GL_NO_ERROR;
@@ -73,68 +75,190 @@ GLenum BufferState::CommitStorage(GLenum target, GLsizeiptr size, const void* da
MG_Util::Debug::LogD("MG_State: Buffer: CommitStorage get buffer object %u at target 0x%x",it->second,target);
obj.usage = usage;
obj.data.resize(size);
if (data) memcpy(obj.data.data(), data, size);
if (data) {
memcpy(obj.data.data(), data, size);
obj.dataValid = true;
}
obj.dirty = true;
MG_Util::Debug::LogD("MG_State: Buffer: CommitStorage buffer at target 0x%x committed storage, size = %zu, usage=0x%x", target, size, usage);
return GL_NO_ERROR;
}
GLenum BufferState::AcquireBufferMemory(GLenum target, GLenum access, void** mappedPointer) {
GLenum BufferState::CommitStorageRegion(GLenum target, GLintptr offset, GLsizeiptr size, const void* data) {
MG_Util::Debug::LogD("MG_State: Buffer: BufferSubData called on target 0x%x, offset=%ld, size=%ld", target, offset, size);
if (!IsValidTarget_(target)) return GL_INVALID_ENUM;
if (MG_Constants::Buffer::VALID_ACCESS.find(access) == MG_Constants::Buffer::VALID_ACCESS.end()) {
return GL_INVALID_ENUM;
MG_Util::Debug::LogD("MG_State: Buffer: AcquireBufferMemory buffer at target 0x%x acquired mapped memory, access mode = 0x%x", target, access);
}
if (offset < 0 || size < 0) return GL_INVALID_VALUE;
auto it = currentBindings_.find(target);
if (it == currentBindings_.end() || it->second == 0)
return GL_INVALID_OPERATION;
BufferObject& obj = buffers_[it->second];
if (obj.isMapped) return GL_INVALID_OPERATION;
MG_Util::Debug::LogD("MG_State: Buffer: BufferSubData get buffer object %u at target 0x%x", it->second, target);
obj.isMapped = true;
*mappedPointer = obj.data.data();
obj.isMapped = true;
obj.accessMode = access;
if (static_cast<size_t>(offset + size) > obj.data.size()) return GL_INVALID_VALUE;
if (data) {
memcpy(obj.data.data() + offset, data, size);
obj.dirty = true;
}
return GL_NO_ERROR;
}
GLenum BufferState::AcquireBufferMemoryRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, void** mappedPointer) {
MG_Util::Debug::LogD("MG_State: Buffer: AcquireBufferMemoryRange called with target=0x%x, offset=%ld, length=%ld, access=0x%x", target, offset, length, access);
if (!IsValidTarget_(target)) {
MG_Util::Debug::LogE("MG_State: Buffer: AcquireBufferMemoryRange failed: invalid target 0x%x", target);
return GL_INVALID_ENUM;
}
if (offset < 0 || length <= 0) {
MG_Util::Debug::LogE("MG_State: Buffer: AcquireBufferMemoryRange failed: invalid offset %ld or length %ld", offset, length);
return GL_INVALID_VALUE;
}
auto it = currentBindings_.find(target);
if (it == currentBindings_.end() || it->second == 0) {
MG_Util::Debug::LogE("MG_State: Buffer: AcquireBufferMemoryRange failed: no buffer bound to target 0x%x", target);
return GL_INVALID_OPERATION;
}
BufferObject& obj = buffers_[it->second];
MG_Util::Debug::LogD("MG_State: Buffer: AcquireBufferMemoryRange operating on buffer %u", it->second);
if (obj.isMapped) {
MG_Util::Debug::LogE("MG_State: Buffer: AcquireBufferMemoryRange failed: buffer %u is already mapped", it->second);
return GL_INVALID_OPERATION;
}
const GLbitfield validFlags = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT ;
if ((access & ~validFlags) != 0) {
MG_Util::Debug::LogE("MG_State: Buffer: AcquireBufferMemoryRange failed: invalid access flags 0x%x", access);
return GL_INVALID_VALUE;
}
if (static_cast<size_t>(offset + length) > obj.data.size()) {
MG_Util::Debug::LogE("MG_State: Buffer: AcquireBufferMemoryRange failed: requested range [%ld, %ld) exceeds buffer size %zu", offset, offset + length, obj.data.size());
return GL_INVALID_VALUE;
}
obj.isMapped = true;
obj.mapOffset = offset;
obj.mapLength = length;
obj.mapAccessFlags = access;
obj.dirty = true;
*mappedPointer = obj.data.data() + offset;
MG_Util::Debug::LogD("MG_State: Buffer: AcquireBufferMemoryRange succeeded for buffer %u. Mapped pointer: %p", it->second, *mappedPointer);
return GL_NO_ERROR;
}
GLenum BufferState::SyncBufferMemory(GLenum target, GLintptr offset, GLsizeiptr length) {
if (!IsValidTarget_(target)) return GL_INVALID_ENUM;
if (offset < 0 || length <= 0) return GL_INVALID_VALUE;
auto it = currentBindings_.find(target);
if (it == currentBindings_.end() || it->second == 0)
return GL_INVALID_OPERATION;
BufferObject& obj = buffers_[it->second];
if (!obj.isMapped || !(obj.mapAccessFlags & GL_MAP_FLUSH_EXPLICIT_BIT))
return GL_INVALID_OPERATION;
if (offset < obj.mapOffset || offset + length > obj.mapOffset + obj.mapLength)
return GL_INVALID_VALUE;
// TODO: Add support for flush range.
// Now only mark it as dirty.
obj.dirty = true;
return GL_NO_ERROR;
}
GLenum BufferState::CopyBufferRange(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) {
if (!IsValidTarget_(readTarget) || !IsValidTarget_(writeTarget))
return GL_INVALID_ENUM;
if (readOffset < 0 || writeOffset < 0 || size < 0)
return GL_INVALID_VALUE;
GLuint readBuffer = currentBindings_[readTarget];
GLuint writeBuffer = currentBindings_[writeTarget];
if (readBuffer == 0 || writeBuffer == 0 || readBuffer == writeBuffer)
return GL_INVALID_OPERATION;
BufferObject& src = buffers_[readBuffer];
BufferObject& dst = buffers_[writeBuffer];
if (static_cast<size_t>(readOffset + size) > src.data.size() ||
static_cast<size_t>(writeOffset + size) > dst.data.size())
return GL_INVALID_VALUE;
memcpy(dst.data.data() + writeOffset, src.data.data() + readOffset, size);
dst.dirty = true;
return GL_NO_ERROR;
}
GLenum BufferState::AcquireBufferMemory(GLenum target, GLenum access, void** mappedPointer) {
return AcquireBufferMemoryRange(target, 0, buffers_[currentBindings_[target]].data.size(), access, mappedPointer);
}
GLenum BufferState::ReleaseBufferMemory(GLenum target) {
MG_Util::Debug::LogD("MG_State: Buffer: ReleaseBufferMemory called on target 0x%x",target);
if (!IsValidTarget_(target)) return GL_INVALID_ENUM;
if (!IsValidTarget_(target))
return GL_INVALID_ENUM;
auto it = currentBindings_.find(target);
if (it == currentBindings_.end() || it->second == 0)
return GL_INVALID_OPERATION;
BufferObject& obj = buffers_[it->second];
if (!obj.isMapped) return GL_INVALID_OPERATION;
if (!obj.isMapped)
return GL_INVALID_OPERATION;
if ((obj.mapAccessFlags & GL_MAP_FLUSH_EXPLICIT_BIT) == 0) {
obj.dirty = true;
}
obj.isMapped = false;
obj.mapOffset = 0;
obj.mapLength = 0;
obj.mapAccessFlags = 0;
obj.accessMode = GL_READ_WRITE;
MG_Util::Debug::LogD("MG_State: Buffer: ReleaseBufferMemory buffer at target 0x%x released mapped memory", target);
return GL_NO_ERROR;
}
bool BufferState::ValidateHandle(GLuint buffer) {
bool isvalid = buffers_.count(buffer) > 0;
MG_Util::Debug::LogD("MG_State: Buffer: ValidateHandle called on buffer %u returns %d", buffer, isvalid);
return isvalid;
bool BufferState::ValidateAllocatedHandle(GLuint buffer) {
bool isValid = buffers_.find(buffer) != buffers_.end();
MG_Util::Debug::LogD("MG_State: Buffer: ValidateAllocatedHandle called on buffer %u returns %d", buffer, isValid);
return isValid;
}
bool BufferState::ValidateGeneratedName(GLuint buffer) {
bool inFreeList = std::find(freeId_.begin(), freeId_.end(), buffer) != freeId_.end();
bool lessThanLast = buffer < lastId_; // lastId_ is not generated yet
MG_Util::Debug::LogD("MG_State: Buffer: ValidateGeneratedName called on buffer %u returns %d", buffer, lessThanLast && !inFreeList);
return lessThanLast && !inFreeList;
}
void BufferState::Delete(GLuint buffer) {
if (buffers_.erase(buffer)) {
freeIds_.insert(buffer);
for (auto& [target, id] : currentBindings_) {
if (id == buffer) id = 0;
}
buffers_.erase(buffer);
if (ValidateGeneratedName(buffer))
// TODO: Prevent the object that uses a freeId from conflicting with legacy object in the backend.
//freeId_.emplace_back(buffer);
for (auto& [target, id] : currentBindings_) {
if (id == buffer) id = 0;
}
MG_Util::Debug::LogD("MG_State: Buffer: Delete buffer %u", buffer);
}
GLenum BufferState::DeleteN(GLsizei n, const GLuint* buffers) {
MG_Util::Debug::LogD("MG_State: Buffer: DeleteN called with n=%d", n);
if (n < 0) return GL_INVALID_VALUE;
for (GLsizei i = 0; i < n; ++i) {
Delete(buffers[i]);
}
MG_Util::Debug::LogD("MG_State: Buffer: DeleteN deleted buffers successfully");
return GL_NO_ERROR;
}
bool BufferState::IsValidTarget_(GLenum target) {
MG_Util::Debug::LogD("MG_State: Buffer: IsValidTarget_ called with target=0x%x,result=%d", target, !(MG_Constants::Buffer::VALID_TARGETS.find(target) == MG_Constants::Buffer::VALID_TARGETS.end()));
return !(MG_Constants::Buffer::VALID_TARGETS.find(target) == MG_Constants::Buffer::VALID_TARGETS.end());
@@ -179,7 +303,7 @@ GLenum BufferState::QueryPropertyIntVector(GLenum target, GLenum pname, GLint* p
case GL_BUFFER_USAGE:
*params = static_cast<GLint>(buffer.usage);
break;
MG_Util::Debug::LogD("MG_State: Buffer: QueryPropertyIntVector Query info about buffer %u succeed",buffer.target);
MG_Util::Debug::LogD("MG_State: Buffer: QueryPropertyIntVector Query info about buffer %u succeed", target);
default:
return GL_INVALID_ENUM;
}
+22 -8
View File
@@ -9,34 +9,48 @@
#include "../../../Includes.h"
class BufferState {
template <typename K, typename V>
using unordered_map = ankerl::unordered_dense::map<K, V>;
public:
struct BufferObject {
GLenum target = 0;
GLenum usage = GL_STATIC_DRAW;
std::vector<GLubyte> data;
bool dataValid = false;
bool dirty = false; // TODO: encapsulate this with an public API to RHI
bool isMapped = false;
bool generated = false;
GLenum accessMode = GL_READ_WRITE;
GLintptr mapOffset = 0;
GLsizeiptr mapLength = 0;
GLbitfield mapAccessFlags = 0;
};
// Return: the validity of the operation, according to OpenGL 3 standard
GLenum Create(GLuint* buffer);
GLenum CreateN(GLsizei n, GLuint* buffers);
GLenum GenName(GLuint* buffer);
GLenum GenNameN(GLsizei n, GLuint* buffers);
GLenum Create(GLuint buffer);
GLenum Bind(GLenum target, GLuint buffer);
GLenum CommitStorage(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
GLenum CommitStorageRegion(GLenum target, GLintptr offset, GLsizeiptr size, const void* data);
GLenum AcquireBufferMemoryRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, void** mappedPointer);
GLenum SyncBufferMemory(GLenum target, GLintptr offset, GLsizeiptr length);
GLenum CopyBufferRange(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
GLenum AcquireBufferMemory(GLenum target, GLenum access, void** mappedPointer);
GLenum ReleaseBufferMemory(GLenum target);
GLenum QueryPropertyIntVector(GLenum target, GLenum pname, GLint* params) const;
GLenum DeleteN(GLsizei n, const GLuint* buffers);
bool ValidateHandle(GLuint buffer);
bool ValidateAllocatedHandle(GLuint buffer);
bool ValidateGeneratedName(GLuint buffer);
void Delete(GLuint buffer);
GLuint GetCurrentBinding(GLenum target) const;
unordered_map<GLenum, GLuint> currentBindings_;
unordered_map<GLuint, BufferObject> buffers_;
private:
std::unordered_map<GLuint, BufferObject> buffers_;
std::set<GLuint> freeIds_;
GLuint lastId_ = 0;
std::unordered_map<GLenum, GLuint> currentBindings_;
std::vector<GLuint> freeId_;
GLuint lastId_ = 1;
static bool IsValidTarget_(GLenum target);
};
+1
View File
@@ -107,6 +107,7 @@ GLenum CommonState::Clear(GLbitfield mask) {
if ((mask & ~validBits) != 0) {
return GL_INVALID_VALUE;
}
clearMask = mask;
return GL_NO_ERROR;
}
+15 -12
View File
@@ -9,9 +9,17 @@
#include "../../../Includes.h"
class CommonState {
private:
template <typename K, typename V>
using unordered_map = ankerl::unordered_dense::map<K, V>;
public:
// Viewport
GLint viewport[4] = {0, 0, 0, 0};
// Color mask
GLboolean colorMask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
// Pixel storage parameters
std::unordered_map<GLenum, GLint> pixelStoreParams;
unordered_map<GLenum, GLint> pixelStoreParams;
// Blend state
GLenum blendSrcRGB = GL_ONE;
@@ -22,21 +30,15 @@ private:
// Clear state
GLfloat clearColor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
GLfloat clearDepth = 1.0f;
// Color mask
GLboolean colorMask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
GLenum clearMask;
// Depth state
GLenum depthFunc = GL_LESS;
GLboolean depthMask = GL_TRUE;
// Viewport
GLint viewport[4] = {0, 0, 0, 0};
// Capability enables
std::unordered_map<GLenum, bool> capabilities;
unordered_map<GLenum, bool> capabilities;
public:
CommonState();
// Return: the validity of the operation, according to OpenGL 3 standard
@@ -57,6 +59,7 @@ public:
GLenum Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
GLint QueryPixelStoreInt(GLenum pname);
};
#endif //MOBILEGL_COMMONSTATE_H
+38 -8
View File
@@ -155,17 +155,30 @@ namespace MG_State {
GLenum AcquireBufferMemory(GLenum target, GLenum access, void** mappedPtr) {
return MG_State_T::bufferState->AcquireBufferMemory(target, access, mappedPtr);
}
GLenum AcquireBufferMemoryRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, void** mappedPointer) {
return MG_State_T::bufferState->AcquireBufferMemoryRange(target, offset, length, access, mappedPointer);
}
GLenum SyncBufferMemory(GLenum target, GLintptr offset, GLsizeiptr length) {
return MG_State_T::bufferState->SyncBufferMemory(target, offset, length);
}
GLenum CopyBufferRange(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) {
return MG_State_T::bufferState->CopyBufferRange(readTarget, writeTarget, readOffset,
writeOffset, size);
}
GLenum ReleaseBufferMemory(GLenum target) {
return MG_State_T::bufferState->ReleaseBufferMemory(target);
}
GLenum CreateBuffer(GLuint* buffer) {
GLenum CreateBuffer(GLuint buffer) {
return MG_State_T::bufferState->Create(buffer);
}
GLenum CreateBuffers(GLsizei n, GLuint* buffers) {
return MG_State_T::bufferState->CreateN(n, buffers);
GLenum GenBufferNames(GLsizei n, GLuint* buffers) {
return MG_State_T::bufferState->GenNameN(n, buffers);
}
GLenum BindBuffer(GLenum target, GLuint buffer) {
@@ -173,6 +186,7 @@ namespace MG_State {
auto* vao = MG_State_T::vertexArrayState->GetCurrentVAO();
if (!vao) return GL_INVALID_OPERATION;
vao->elementBuffer = (GLuint)buffer;
vao->eboDirty = true;
}
return MG_State_T::bufferState->Bind(target, buffer);
}
@@ -181,14 +195,26 @@ namespace MG_State {
return MG_State_T::bufferState->CommitStorage(target, size, data, usage);
}
bool ValidateBufferHandle(GLuint buffer) {
return MG_State_T::bufferState->ValidateHandle(buffer);
GLenum CommitBufferStorageRegion(GLenum target, GLintptr offset, GLsizeiptr size, const void* data) {
return MG_State_T::bufferState->CommitStorageRegion(target, offset, size, data);
}
bool ValidateAllocatedBufferHandle(GLuint buffer) {
return MG_State_T::bufferState->ValidateAllocatedHandle(buffer);
}
bool ValidateGeneratedName(GLuint buffer) {
return MG_State_T::bufferState->ValidateGeneratedName(buffer);
}
void DeleteBuffer(GLuint buffer) {
return MG_State_T::bufferState->Delete(buffer);
}
GLenum DeleteBuffers(GLsizei n, const GLuint* buffers) {
return MG_State_T::bufferState->DeleteN(n, buffers);
}
GLenum QueryBufferPropertyIntVector(GLenum target, GLenum pname, GLint* params) {
return MG_State_T::bufferState->QueryPropertyIntVector(target, pname, params);
}
@@ -206,6 +232,10 @@ namespace MG_State {
return MG_State_T::vertexArrayState->CreateN(n, arrays);
}
GLenum GenVertexArraysNames(GLsizei n, GLuint* arrays) {
return MG_State_T::vertexArrayState->GenNameN(n, arrays);
}
GLenum EnableVertexAttribArray(GLuint index) {
return MG_State_T::vertexArrayState->EnableAttrib(index);
}
@@ -367,11 +397,11 @@ void UpdateProgramUniformMatrix##suffix##Vector(GLint location, GLsizei count, G
GLenum MG_State::AttachTexture2DToFramebuffer(GLenum target, GLenum attachment, GLenum textarget,
GLuint texture, GLint level) {
return MG_State_T::framebufferState->glAttachTexture2D(target, attachment, textarget,
texture, level);
return MG_State_T::framebufferState->AttachTexture2D(target, attachment, textarget,
texture, level);
}
GLenum MG_State::ValidateFramebufferCompleteness(GLenum target) {
return MG_State_T::framebufferState->glValidateCompleteness(target);
return MG_State_T::framebufferState->ValidateCompleteness(target);
}
}
+10 -3
View File
@@ -57,18 +57,25 @@ namespace MG_State {
// Buffer
GLenum AcquireBufferMemory(GLenum target, GLenum access, void** mappedPtr);
GLenum AcquireBufferMemoryRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, void** mappedPointer);
GLenum SyncBufferMemory(GLenum target, GLintptr offset, GLsizeiptr length);
GLenum CopyBufferRange(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
GLenum ReleaseBufferMemory(GLenum target);
GLenum CreateBuffer(GLuint* buffer);
GLenum CreateBuffers(GLsizei n, GLuint* buffers);
GLenum CreateBuffer(GLuint buffer);
GLenum GenBufferNames(GLsizei n, GLuint* buffers);
GLenum BindBuffer(GLenum target, GLuint buffer);
GLenum CommitBufferStorage(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
bool ValidateBufferHandle(GLuint buffer);
GLenum CommitBufferStorageRegion(GLenum target, GLintptr offset, GLsizeiptr size, const void* data);
bool ValidateAllocatedBufferHandle(GLuint buffer);
bool ValidateGeneratedName(GLuint buffer);
void DeleteBuffer(GLuint buffer);
GLenum DeleteBuffers(GLsizei n, const GLuint* buffers);
GLenum QueryBufferPropertyIntVector(GLenum target, GLenum pname, GLint* params);
// VertexArray
GLenum CreateVertexArray(GLuint* array);
GLenum CreateVertexArrays(GLsizei n, GLuint* arrays);
GLenum GenVertexArraysNames(GLsizei n, GLuint* arrays);
GLenum BindVertexArray(GLuint array);
GLenum EnableVertexAttribArray(GLuint index);
GLenum DisableVertexAttribArray(GLuint index);
@@ -32,7 +32,8 @@ GLenum FramebufferState::Delete(GLuint framebuffer) {
if (framebuffer == 0) return GL_INVALID_VALUE;
if (framebuffers_.erase(framebuffer)) {
freeIds_.insert(framebuffer);
// TODO: Prevent the object that uses a freeId from conflicting with legacy object in the backend.
//freeIds_.insert(framebuffer);
for (auto& [target, id] : currentBindings_) {
if (id == framebuffer) id = 0;
}
@@ -48,18 +49,18 @@ GLenum FramebufferState::Bind(GLenum target, GLuint framebuffer) {
if (target == GL_FRAMEBUFFER) {
currentBindings_[GL_READ_FRAMEBUFFER] = framebuffer;
currentBindings_[GL_DRAW_FRAMEBUFFER] = framebuffer;
currentBindings_[GL_FRAMEBUFFER] = framebuffer;
} else {
currentBindings_[target] = framebuffer;
}
return GL_NO_ERROR;
}
GLenum FramebufferState::glAttachTexture2D(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level) {
GLenum FramebufferState::AttachTexture2D(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level) {
if (MG_Constants::Framebuffer::VALID_ATTACHMENTS.find(attachment) == MG_Constants::Framebuffer::VALID_ATTACHMENTS.end() ||
MG_Constants::Texture::VALID_TARGETS.find(textarget) == MG_Constants::Texture::VALID_TARGETS.end())
return GL_INVALID_ENUM;
if (target == GL_FRAMEBUFFER) target = GL_DRAW_FRAMEBUFFER;
FramebufferObject* fbo = GetCurrentFBO(target);
if (!fbo) return GL_INVALID_OPERATION;
if (texture != 0 && !MG_State_T::textureState->IsTexture(texture))
@@ -83,7 +84,8 @@ GLenum FramebufferState::glAttachTexture2D(GLenum target, GLenum attachment,
return GL_NO_ERROR;
}
GLenum FramebufferState::glValidateCompleteness(GLenum target) {
GLenum FramebufferState::ValidateCompleteness(GLenum target) {
if (target == GL_FRAMEBUFFER) target = GL_DRAW_FRAMEBUFFER;
FramebufferObject* fbo = GetCurrentFBO(target);
if (!fbo) return GL_INVALID_OPERATION;
return fbo->status;
@@ -17,7 +17,7 @@ struct FramebufferAttachment {
struct FramebufferObject {
bool generated = false;
std::unordered_map<GLenum, FramebufferAttachment> attachments;
ankerl::unordered_map<GLenum, FramebufferAttachment> attachments;
GLenum status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
GLsizei width = 0;
GLsizei height = 0;
@@ -30,14 +30,15 @@ public:
GLenum CreateN(GLsizei n, GLuint* framebuffers);
GLenum Delete(GLuint framebuffer);
GLenum Bind(GLenum target, GLuint framebuffer);
GLenum glAttachTexture2D(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level);
GLenum glValidateCompleteness(GLenum target);
GLenum AttachTexture2D(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level);
GLenum ValidateCompleteness(GLenum target);
FramebufferObject* GetCurrentFBO(GLenum target);
ankerl::unordered_map<GLenum, GLuint> currentBindings_; // READ/DRAW
private:
std::unordered_map<GLuint, FramebufferObject> framebuffers_;
std::unordered_map<GLenum, GLuint> currentBindings_; // READ/DRAW/FRAMEBUFFER
ankerl::unordered_map<GLuint, FramebufferObject> framebuffers_;
std::set<GLuint> freeIds_;
GLuint lastId_ = 0;
bool ValidateHandle(GLuint framebuffer);
+55 -8
View File
@@ -48,7 +48,7 @@ GLenum ProgramState::DeleteProgram(GLuint program) {
}
programs_.erase(program);
freeProgramIds_.insert(program);
//freeProgramIds_.insert(program);
if (currentProgram_ == program)
currentProgram_ = 0;
MG_Util::Debug::LogD("MG_State: Program: DeleteProgram success, id=%u", program);
@@ -261,6 +261,7 @@ GLenum ProgramState::SetUniform(GLuint program, GLint location, GLsizei count, c
}
UniformValue& uniform = prog.uniformValues[uniformName];
uniform.setData(type, count, value);
MG_Util::Debug::LogD("MG_State: Program: SetUniform success: %s set", uniformName.c_str());
return GL_NO_ERROR;
@@ -303,7 +304,7 @@ GLenum ProgramState::SetUniformMatrix(GLuint program, GLint location, GLsizei co
}
UniformValue& uniform = prog.uniformValues[uniformName];
uniform.setData(matrixType, count * MG_Util::Program::GetMatrixElementCount(matrixType), value);
uniform.setData(matrixType, count, value);
MG_Util::Debug::LogD("MG_State: Program: SetUniformMatrix success: %s set", uniformName.c_str());
return GL_NO_ERROR;
}
@@ -334,15 +335,15 @@ void ProgramState::UpdateUniform##suffix##Vector1(GLint location, GLsizei count,
} \
void ProgramState::UpdateUniform##suffix##Vector2(GLint location, GLsizei count, const type* value) { \
MG_Util::Debug::LogD("MG_State: Program: UpdateUniform" #suffix "Vector2 called, location=%d, count=%d", location, count); \
SetUniform<type>(currentProgram_, location, count * 2, value, vecType); \
SetUniform<type>(currentProgram_, location, count, value, vecType); \
} \
void ProgramState::UpdateUniform##suffix##Vector3(GLint location, GLsizei count, const type* value) { \
MG_Util::Debug::LogD("MG_State: Program: UpdateUniform" #suffix "Vector3 called, location=%d, count=%d", location, count); \
SetUniform<type>(currentProgram_, location, count * 3, value, vecType); \
SetUniform<type>(currentProgram_, location, count, value, vecType); \
} \
void ProgramState::UpdateUniform##suffix##Vector4(GLint location, GLsizei count, const type* value) { \
MG_Util::Debug::LogD("MG_State: Program: UpdateUniform" #suffix "Vector4 called, location=%d, count=%d", location, count); \
SetUniform<type>(currentProgram_, location, count * 4, value, vecType); \
SetUniform<type>(currentProgram_, location, count, value, vecType); \
}
IMPLEMENT_UNIFORM_FUNCTIONS(GLfloat, Float, GL_FLOAT_VEC4)
@@ -462,16 +463,62 @@ void ProgramState::CleanupShaders_() {
// UniformValue
template<typename T>
void UniformValue::setData(GLenum uniformType, GLsizei numElements, const T* values) {
MG_Util::Debug::LogD("MG_State: Program: UniformValue::setData called, type=0x%X, count=%d", uniformType, numElements);
void UniformValue::setData(GLenum uniformType, GLsizei count_, const T* values) {
MG_Util::Debug::LogD("MG_State: Program: UniformValue::setData called, type=0x%X, count=%d", uniformType, count_);
//type = uniformType;
count = numElements;
count = count_;
floatData.clear();
intData.clear();
uintData.clear();
boolData.clear();
switch (type) {
case GL_FLOAT: numElements = count_ * 1; break;
case GL_FLOAT_VEC2: numElements = count_ * 2; break;
case GL_FLOAT_VEC3: numElements = count_ * 3; break;
case GL_FLOAT_VEC4: numElements = count_ * 4; break;
case GL_INT: numElements = count_ * 1; break;
case GL_INT_VEC2: numElements = count_ * 2; break;
case GL_INT_VEC3: numElements = count_ * 3; break;
case GL_INT_VEC4: numElements = count_ * 4; break;
case GL_UNSIGNED_INT: numElements = count_ * 1; break;
case GL_UNSIGNED_INT_VEC2: numElements = count_ * 2; break;
case GL_UNSIGNED_INT_VEC3: numElements = count_ * 3; break;
case GL_UNSIGNED_INT_VEC4: numElements = count_ * 4; break;
case GL_BOOL: numElements = count_ * 1; break;
case GL_BOOL_VEC2: numElements = count_ * 2; break;
case GL_BOOL_VEC3: numElements = count_ * 3; break;
case GL_BOOL_VEC4: numElements = count_ * 4; break;
case GL_FLOAT_MAT2: numElements = count_ * 4; break; // 2x2
case GL_FLOAT_MAT3: numElements = count_ * 9; break; // 3x3
case GL_FLOAT_MAT4: numElements = count_ * 16; break; // 4x4
case GL_FLOAT_MAT2x3: numElements = count_ * 6; break; // 2x3
case GL_FLOAT_MAT2x4: numElements = count_ * 8; break; // 2x4
case GL_FLOAT_MAT3x2: numElements = count_ * 6; break; // 3x2
case GL_FLOAT_MAT3x4: numElements = count_ * 12; break; // 3x4
case GL_FLOAT_MAT4x2: numElements = count_ * 8; break; // 4x2
case GL_FLOAT_MAT4x3: numElements = count_ * 12; break; // 4x3
case GL_SAMPLER_1D:
case GL_SAMPLER_2D:
case GL_SAMPLER_3D:
case GL_SAMPLER_CUBE:
case GL_SAMPLER_1D_SHADOW:
case GL_SAMPLER_2D_SHADOW:
case GL_SAMPLER_CUBE_SHADOW:
case GL_SAMPLER_1D_ARRAY:
case GL_SAMPLER_2D_ARRAY:
case GL_SAMPLER_1D_ARRAY_SHADOW:
case GL_SAMPLER_2D_ARRAY_SHADOW:
case GL_SAMPLER_BUFFER:
case GL_SAMPLER_2D_MULTISAMPLE:
case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: numElements = count_ * 1; break;
default:
MG_Util::Debug::LogW("MG_State: Program: UniformValue::setData warning: unsupported type 0x%X for numElements", uniformType);
numElements = 1;
return;
}
for (GLsizei i = 0; i < numElements; ++i) {
switch (uniformType) {
case GL_FLOAT:
+10 -9
View File
@@ -27,36 +27,37 @@ struct UniformValue {
std::vector<GLuint> uintData;
std::vector<GLboolean> boolData;
GLsizei count;
GLsizei numElements;
UniformValue() : type(0), count(0) {}
template<typename T>
void setData(GLenum uniformType, GLsizei numElements, const T* values);
void setData(GLenum uniformType, GLsizei count_, const T* values);
};
struct ProgramObject {
std::vector<GLuint> attachedShaders;
UncertainBool linked;
bool dirty;
GLint linkStatus;
std::string infoLog;
std::unordered_map<std::string, GLint> attribBindings;
std::unordered_map<std::string, GLint> attribLocations;
std::unordered_map<std::string, GLint> uniformLocations;
std::unordered_map<std::string, UniformValue> uniformValues;
ankerl::unordered_map<std::string, GLint> attribBindings;
ankerl::unordered_map<std::string, GLint> attribLocations;
ankerl::unordered_map<std::string, GLint> uniformLocations;
ankerl::unordered_map<std::string, UniformValue> uniformValues;
bool markedForDeletion;
};
class ProgramState {
private:
std::unordered_map<GLuint, ShaderObject> shaders_;
std::unordered_map<GLuint, ProgramObject> programs_;
public:
ankerl::unordered_map<GLuint, ShaderObject> shaders_;
ankerl::unordered_map<GLuint, ProgramObject> programs_;
std::set<GLuint> freeShaderIds_;
std::set<GLuint> freeProgramIds_;
GLuint lastShaderId_ = 0;
GLuint lastProgramId_ = 0;
GLuint currentProgram_ = 0;
public:
ProgramState();
~ProgramState();
+2 -1
View File
@@ -60,7 +60,8 @@ GLenum ProgramState::DeleteShader(GLuint shader) {
MG_Util::Debug::LogD("MG_State: Program: DeleteShader info: shader %u marked for deferred deletion (in use)", shader);
} else {
shaders_.erase(shader);
freeShaderIds_.insert(shader);
// TODO: Prevent the object that uses a freeId from conflicting with legacy object in the backend.
//freeShaderIds_.insert(shader);
MG_Util::Debug::LogD("MG_State: Program: DeleteShader success: shader %u deleted immediately", shader);
}
return GL_NO_ERROR;
+134 -64
View File
@@ -11,7 +11,7 @@
// TextureObject
bool TextureObject::IsImmutable() const {
bool immutable = params.texPropertiesInt.count(GL_TEXTURE_IMMUTABLE_FORMAT);
bool immutable = params.texPropertiesInt.find(GL_TEXTURE_IMMUTABLE_FORMAT) != params.texPropertiesInt.end();
MG_Util::Debug::LogD("MG_State: Texture: TextureObject::IsImmutable returns %d", immutable);
return immutable;
}
@@ -54,7 +54,7 @@ bool TextureState::IsTextureGenerated(GLuint texture) {
if (!isValidTexture) {
MG_Util::Debug::LogD("MG_State: Texture: IsTextureGenerated invalid texture %d", texture);
} else {
generated = textures.at(texture).generated;
generated = textures[texture].generated;
if (!generated) {
MG_Util::Debug::LogD("MG_State: Texture: IsTextureGenerated texture %d not generated", texture, generated);
}
@@ -101,12 +101,12 @@ GLenum TextureState::CreateN(GLsizei n, GLuint* textures) {
for (GLsizei i = 0; i < n; ++i) {
GLuint id = 0;
if (!freeIDs_.empty()) {
id = *freeIDs_.begin();
freeIDs_.erase(freeIDs_.begin());
if (!freeID_.empty()) {
id = freeID_.back();
freeID_.pop_back();
MG_Util::Debug::LogD("MG_State: Texture: CreateN reusing free id=%u", id);
} else {
id = ++lastUsedID_;
id = lastUsedID_++;
MG_Util::Debug::LogD("MG_State: Texture: CreateN new id=%u", id);
}
TextureObject obj;
@@ -258,7 +258,7 @@ GLenum TextureState::Upload2D(GLenum target, GLint level, GLint internalFormat,
if (isProxyTexture) {
MG_Util::Debug::LogD("MG_State: Texture: Upload2D proxy texture detected");
TextureObject& proxyTex = proxyTextures_[target];
TextureParams::MipmapLevel mip{};
auto& mip = proxyTex.params.mipmapData[level];
mip.width = width;
mip.height = height;
mip.internalFormat = internalFormat;
@@ -266,19 +266,25 @@ GLenum TextureState::Upload2D(GLenum target, GLint level, GLint internalFormat,
mip.type = type;
proxyTex.generated = true;
proxyTex.target = target;
proxyTex.params.mipmapData[level] = mip;
return GL_NO_ERROR;
}
GLuint boundTex = textureUnits_[activeTextureUnit_].GetBoundTexture(target);
TextureObject& tex = textures[boundTex];
TextureParams::MipmapLevel mip{};
// TextureParams::MipmapLevel mip{};
auto& mip = tex.params.mipmapData[level];
mip.width = width;
mip.height = height;
mip.internalFormat = internalFormat;
mip.format = format;
mip.type = type;
if (data != nullptr) {
mip.dirty = true;
if (data == nullptr) {
mip.hasData = false;
MG_Util::Debug::LogD("MG_State: Texture: Upload2D data pointer is null");
} else {
GLint unpackSwapBytes = GetUnpackParam_(GL_UNPACK_SWAP_BYTES);
GLint unpackLSBFirst = GetUnpackParam_(GL_UNPACK_LSB_FIRST);
GLint unpackSkipPixels = GetUnpackParam_(GL_UNPACK_SKIP_PIXELS);
@@ -288,47 +294,69 @@ GLenum TextureState::Upload2D(GLenum target, GLint level, GLint internalFormat,
GLint unpackImageHeight = GetUnpackParam_(GL_UNPACK_IMAGE_HEIGHT);
GLint unpackSkipImages = GetUnpackParam_(GL_UNPACK_SKIP_IMAGES);
GLsizei rowLength = (unpackRowLength > 0) ? unpackRowLength : width;
bool isDefaultUnpack = (unpackSwapBytes == 0) && (unpackLSBFirst == 0) &&
(unpackSkipPixels == 0) && (unpackSkipRows == 0) &&
(unpackRowLength == 0) && (unpackAlignment == 4) &&
(unpackImageHeight == 0) && (unpackSkipImages == 0);
size_t bytesPerPixel = CalculateBytesPerPixel_(format, type);
size_t componentSize = GetComponentSize_(type);
size_t srcRowSize = rowLength * bytesPerPixel;
size_t srcRowStride = (srcRowSize + unpackAlignment - 1) & ~(unpackAlignment - 1);
size_t srcImageStride = (unpackImageHeight > 0) ?
srcRowStride * unpackImageHeight :
srcRowStride * height;
const GLubyte* srcData = static_cast<const GLubyte*>(data);
srcData += unpackSkipImages * srcImageStride;
srcData += unpackSkipRows * srcRowStride;
srcData += unpackSkipPixels * bytesPerPixel;
size_t dstRowStride = width * bytesPerPixel;
size_t dstSize = dstRowStride * height;
mip.pixelData.resize(dstSize);
GLubyte* dstData = mip.pixelData.data();
GLubyte *dstData = mip.pixelData.data();
for (GLsizei y = 0; y < height; ++y) {
const GLubyte* srcRow = srcData + y * srcRowStride;
GLubyte* dstRow = dstData + y * dstRowStride;
if (isDefaultUnpack) {
const GLubyte *srcData = static_cast<const GLubyte *>(data);
size_t srcRowSize = width * bytesPerPixel;
size_t srcRowStride = (srcRowSize + unpackAlignment - 1) & ~(unpackAlignment - 1);
if (unpackSwapBytes) {
SwapBytesForTexture_(format, type, srcRow, dstRow, width);
if (srcRowStride == dstRowStride) {
memcpy(dstData, srcData, dstSize);
MG_Util::Debug::LogD(
"MG_State: Texture: Upload2D uploaded %zu bytes with fast path - block memcpy", dstSize);
} else {
for (GLsizei y = 0; y < height; ++y) {
const GLubyte *srcRow = srcData + y * srcRowStride;
GLubyte *dstRow = dstData + y * dstRowStride;
memcpy(dstRow, srcRow, srcRowSize);
}
MG_Util::Debug::LogD(
"MG_State: Texture: Upload2D uploaded %zu bytes with fast path - row memcpy", dstSize);
}
else if (unpackLSBFirst && componentSize == 1) {
ReverseBitOrder_(srcRow, dstRow, width * bytesPerPixel);
}
else {
memcpy(dstRow, srcRow, width * bytesPerPixel);
} else {
GLsizei rowLength = (unpackRowLength > 0) ? unpackRowLength : width;
size_t srcRowSize = rowLength * bytesPerPixel;
size_t srcRowStride = (srcRowSize + unpackAlignment - 1) & ~(unpackAlignment - 1);
size_t srcImageStride = (unpackImageHeight > 0) ?
srcRowStride * unpackImageHeight :
srcRowStride * height;
const GLubyte *srcData = static_cast<const GLubyte *>(data);
srcData += unpackSkipImages * srcImageStride;
srcData += unpackSkipRows * srcRowStride;
srcData += unpackSkipPixels * bytesPerPixel;
for (GLsizei y = 0; y < height; ++y) {
const GLubyte *srcRow = srcData + y * srcRowStride;
GLubyte *dstRow = dstData + y * dstRowStride;
if (unpackSwapBytes) {
SwapBytesForTexture_(format, type, srcRow, dstRow, width);
} else if (unpackLSBFirst && componentSize == 1) {
ReverseBitOrder_(srcRow, dstRow, width * bytesPerPixel);
} else {
memcpy(dstRow, srcRow, width * bytesPerPixel);
}
}
mip.hasData = true;
MG_Util::Debug::LogD(
"MG_State: Texture: Upload2D uploaded %zu bytes with unpack params", dstSize);
}
mip.hasData = true;
MG_Util::Debug::LogD("MG_State: Texture: Upload2D uploaded %zu bytes with unpack params", dstSize);
} else {
mip.hasData = false;
MG_Util::Debug::LogD("MG_State: Texture: Upload2D data pointer is null");
}
tex.params.mipmapData[level] = mip;
// tex.params.mipmapData[level] = mip;
return GL_NO_ERROR;
}
@@ -364,7 +392,7 @@ GLenum TextureState::UpdateRegion2D(GLenum target, GLint level, GLint xoffset,
const size_t bytesPerPixel = CalculateBytesPerPixel_(format, type);
const size_t srcSize = CalculatePixelDataSize_(format, type, width, height);
if (bytesPerPixel == 0) {
MG_Util::Debug::LogE("MG_State: Texture: Invalid format/type combination");
return GL_INVALID_ENUM;
@@ -402,27 +430,68 @@ GLenum TextureState::UpdateRegion2D(GLenum target, GLint level, GLint xoffset,
MG_Util::Debug::LogD("MG_State: Texture: UpdateRegion2D srcData=%p, dstData=%p", srcData, dstData);
MG_Util::Debug::LogD("MG_State: Texture: UpdateRegion2D bytesPerPixel=%zu", bytesPerPixel);
for (GLsizei y = 0; y < height; ++y) {
const GLubyte* srcRow = srcData + y * srcRowStride;
GLubyte* dstRow = dstData + y * dstRowStride;
// Check if fast path is applicable
const bool isDefaultUnpack = (unpackSwapBytes == 0) && (unpackLSBFirst == 0) &&
(unpackRowLength == 0) && (unpackAlignment == 4) &&
(unpackSkipPixels == 0) && (unpackSkipRows == 0) &&
(unpackImageHeight == 0) && (unpackSkipImages == 0);
if (unpackSwapBytes) {
for (GLsizei x = 0; x < width; ++x) {
const GLubyte* srcPixel = srcRow + x * bytesPerPixel;
GLubyte* dstPixel = dstRow + x * bytesPerPixel;
SwapPixelBytes_(format, type, srcPixel, dstPixel);
}
} else if (unpackLSBFirst && GetComponentSize_(type) == 1) {
for (size_t i = 0; i < width * bytesPerPixel; ++i) {
dstRow[i] = ReverseBits_(srcRow[i]);
}
if (isDefaultUnpack) {
const size_t copySize = width * bytesPerPixel;
if (srcRowStride == dstRowStride) {
MG_Util::Debug::LogD("MG_State: Texture: UpdateRegion2D block memcpy(dst=%p, src=%p, size=%zu) called.", dstData, srcData, width * bytesPerPixel);
memcpy(dstData, srcData, copySize * height);
} else {
MG_Util::Debug::LogD("MG_State: Texture: UpdateRegion2D memcpy(dst=%p, src=%p, size=%zu) called.", dstRow, srcRow, width * bytesPerPixel);
memcpy(dstRow, srcRow, width * bytesPerPixel);
for (GLsizei y = 0; y < height; ++y) {
const GLubyte* srcRow = srcData + y * srcRowStride;
GLubyte* dstRow = dstData + y * dstRowStride;
memcpy(dstRow, srcRow, copySize);
MG_Util::Debug::LogD("MG_State: Texture: UpdateRegion2D row memcpy(dst=%p, src=%p, size=%zu) called.", dstRow, srcRow, width * bytesPerPixel);
}
}
} else {
const size_t componentSize = GetComponentSize_(type);
for (GLsizei y = 0; y < height; ++y) {
const GLubyte* srcRow = srcData + y * srcRowStride;
GLubyte* dstRow = dstData + y * dstRowStride;
if (unpackSwapBytes) {
for (GLsizei x = 0; x < width; ++x) {
SwapPixelBytes_(format, type, srcRow + x*bytesPerPixel, dstRow + x*bytesPerPixel);
}
} else if (unpackLSBFirst && componentSize == 1) {
for (size_t i = 0; i < width * bytesPerPixel; ++i) {
dstRow[i] = ReverseBits_(srcRow[i]);
}
} else {
memcpy(dstRow, srcRow, width * bytesPerPixel);
}
}
}
// for (GLsizei y = 0; y < height; ++y) {
// const GLubyte* srcRow = srcData + y * srcRowStride;
// GLubyte* dstRow = dstData + y * dstRowStride;
//
// if (unpackSwapBytes) {
// for (GLsizei x = 0; x < width; ++x) {
// const GLubyte* srcPixel = srcRow + x * bytesPerPixel;
// GLubyte* dstPixel = dstRow + x * bytesPerPixel;
// SwapPixelBytes_(format, type, srcPixel, dstPixel);
// }
// } else if (unpackLSBFirst && GetComponentSize_(type) == 1) {
// for (size_t i = 0; i < width * bytesPerPixel; ++i) {
// dstRow[i] = ReverseBits_(srcRow[i]);
// }
// } else {
// MG_Util::Debug::LogD("MG_State: Texture: UpdateRegion2D memcpy(dst=%p, src=%p, size=%zu) called.", dstRow, srcRow, width * bytesPerPixel);
// memcpy(dstRow, srcRow, width * bytesPerPixel);
// }
// }
mip.hasData = true;
mip.dirty = true;
MG_Util::Debug::LogD("MG_State: Texture: UpdateRegion2D succeeded");
return GL_NO_ERROR;
}
@@ -541,7 +610,7 @@ GLenum TextureState::Delete(GLuint texture) {
if (it != this->textures.end()) {
InvalidateTextureInAllUnits_(texture);
this->textures.erase(it);
freeIDs_.insert(texture);
//freeID_.emplace_back(texture);
MG_Util::Debug::LogD("MG_State: Texture: Delete succeeded for texture=%u", texture);
} else {
MG_Util::Debug::LogW("MG_State: Texture: Delete texture %u not found", texture);
@@ -563,7 +632,8 @@ GLenum TextureState::DeleteN(GLsizei n, const GLuint* textures) {
if (it != this->textures.end()) {
InvalidateTextureInAllUnits_(id);
this->textures.erase(it);
freeIDs_.insert(id);
// TODO: Prevent the object that uses a freeId from conflicting with legacy object in the backend.
//freeID_.emplace_back(id);
MG_Util::Debug::LogD("MG_State: Texture: DeleteN deleted texture=%u", id);
} else {
MG_Util::Debug::LogW("MG_State: Texture: DeleteN texture %u not found", id);
@@ -630,7 +700,7 @@ GLenum TextureState::QueryLevelPropertyIntVector(GLenum target, GLint level, GLe
return GL_NO_ERROR;
}
std::unordered_map<GLuint, TextureObject>::iterator texIt;
unordered_map<GLuint, TextureObject>::iterator texIt;
if (!isProxyTexture) {
texIt = textures.find(boundTexture);
@@ -803,10 +873,10 @@ GLenum TextureState::CheckUploadingTexture2DValidity_(GLenum target, GLint level
return GL_INVALID_OPERATION;
}
bool isDepthInternal = (internalFormat == GL_DEPTH_COMPONENT32F || internalFormat == GL_DEPTH_COMPONENT24
|| internalFormat == GL_DEPTH_COMPONENT16 || internalFormat == GL_DEPTH32F_STENCIL8
|| internalFormat == GL_DEPTH24_STENCIL8 || internalFormat == GL_DEPTH_COMPONENT
|| internalFormat == GL_DEPTH_STENCIL);
bool isDepthInternal = (internalFormat == GL_DEPTH_COMPONENT32 || internalFormat == GL_DEPTH_COMPONENT32F ||
internalFormat == GL_DEPTH_COMPONENT24 || internalFormat == GL_DEPTH_COMPONENT16 ||
internalFormat == GL_DEPTH32F_STENCIL8 || internalFormat == GL_DEPTH24_STENCIL8 ||
internalFormat == GL_DEPTH_COMPONENT || internalFormat == GL_DEPTH_STENCIL);
bool isDepthFormat = (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL);
if (isDepthInternal != isDepthFormat) {
MG_Util::Debug::LogE("MG_State: Texture: CheckUploadingTexture2DValidity_ depth internal/format mismatch");
@@ -895,7 +965,7 @@ GLenum TextureState::CheckUpdatingTextureRegion2DValidity_(GLenum target, GLint
return GL_INVALID_OPERATION;
}
auto tex = textures[boundTex];
const auto& tex = textures[boundTex];
if (tex.IsImmutable()) {
MG_Util::Debug::LogE("MG_State: Texture: CheckUpdatingTextureRegion2DValidity_ texture is immutable");
@@ -934,7 +1004,7 @@ GLenum TextureState::CheckUpdatingTextureRegion2DValidity_(GLenum target, GLint
return GL_INVALID_OPERATION;
}
TextureParams::MipmapLevel& mip = mipIt->second;
const auto& mip = mipIt->second;
if (xoffset + width > mip.width || yoffset + height > mip.height) {
MG_Util::Debug::LogE("MG_State: Texture: CheckUpdatingTextureRegion2DValidity_ region out of bounds: "
"x=%d+%d > %d or y=%d+%d > %d",
+18 -10
View File
@@ -19,8 +19,10 @@ struct ComponentSizes {
};
struct TextureParams {
std::unordered_map<GLenum, GLfloat> texPropertiesFloat;
std::unordered_map<GLenum, GLint> texPropertiesInt;
template <typename K, typename V>
using unordered_map = ankerl::unordered_dense::map<K, V>;
unordered_map<GLenum, GLfloat> texPropertiesFloat;
unordered_map<GLenum, GLint> texPropertiesInt;
struct MipmapLevel {
GLsizei width = 0;
GLsizei height = 0;
@@ -29,8 +31,9 @@ struct TextureParams {
GLenum type = GL_UNSIGNED_BYTE;
std::vector<GLubyte> pixelData;
bool hasData = false;
bool dirty = false; // TODO: encapsulate this with an public API to RHI
};
std::unordered_map<GLint, MipmapLevel> mipmapData;
unordered_map<GLint, MipmapLevel> mipmapData;
};
class TextureObject {
@@ -44,24 +47,27 @@ public:
};
class TextureUnitState {
template <typename K, typename V>
using unordered_map = ankerl::unordered_dense::map<K, V>;
private:
GLenum activeTarget = GL_TEXTURE_2D;
public:
std::unordered_map<GLenum, GLuint> boundTextures;
unordered_map<GLenum, GLuint> boundTextures;
void Bind(GLenum target, GLuint texture);
GLuint GetBoundTexture(GLenum target);
};
class TextureState {
template <typename K, typename V>
using unordered_map = ankerl::unordered_dense::map<K, V>;
private:
std::vector<TextureUnitState> textureUnits_;
GLuint activeTextureUnit_ = 0;
GLuint lastUsedID_ = 0;
std::set<GLuint> freeIDs_;
GLuint lastUsedID_ = 1;
// ankerl::unordered_set<GLuint> freeIDs_;
std::vector<GLuint> freeID_;
std::unordered_map<GLenum, TextureObject> proxyTextures_;
unordered_map<GLenum, TextureObject> proxyTextures_;
static GLint GetUnpackParam_(GLenum pname);
public:
@@ -69,7 +75,7 @@ public:
bool IsTextureGenerated(GLuint texture);
bool IsTexture(GLuint texture);
std::unordered_map<GLuint, TextureObject> textures;
unordered_map<GLuint, TextureObject> textures;
// Return: the validity of the operation, according to OpenGL 3 standard
GLenum BindUnit(GLenum textureUnit);
@@ -88,6 +94,8 @@ public:
GLenum DeleteN(GLsizei n, const GLuint* textures);
GLenum QueryLevelPropertyIntVector(GLenum target, GLint level, GLenum pname, GLint* params);
std::vector<TextureUnitState> textureUnits_;
GLuint activeTextureUnit_ = 0;
private:
size_t CalculatePixelDataSize_(GLenum format, GLenum type, GLsizei width, GLsizei height);
void InvalidateTextureInAllUnits_(GLuint texture);
@@ -10,6 +10,37 @@ VertexArrayState::VertexArrayState() {
vaos_[0];
}
GLenum VertexArrayState::GenName(GLuint *array) {
MG_Util::Debug::LogD("MG_State: VAO: GenName");
if (!array)
return GL_INVALID_VALUE;
GLuint id;
if (freeIds_.empty()) {
id = ++lastId_;
} else {
id = *freeIds_.begin();
freeIds_.erase(freeIds_.begin());
}
*array = id;
MG_Util::Debug::LogD("MG_State: VAO: Generated new name %d", id);
return GL_NO_ERROR;
}
GLenum VertexArrayState::GenNameN(GLsizei n, GLuint* arrays) {
MG_Util::Debug::LogD("MG_State: VAO: GenNameN called with n=%d", n);
if (n < 0)
return GL_INVALID_VALUE;
for (GLsizei i = 0; i < n; ++i) {
GLenum result = GenName(&arrays[i]);
if (result != GL_NO_ERROR) {
MG_Util::Debug::LogE("MG_State: VAO: GenNameN failed at index %d with error 0x%x", i, result);
return result;
}
}
MG_Util::Debug::LogD("MG_State: VAO: GenNameN created %d names", n);
return GL_NO_ERROR;
}
GLenum VertexArrayState::Create(GLuint* array) {
if (array == nullptr) return GL_INVALID_VALUE;
@@ -41,24 +72,57 @@ GLenum VertexArrayState::CreateN(GLsizei n, GLuint* arrays) {
}
GLenum VertexArrayState::Bind(GLuint array) {
if (array != 0 && !vaos_.count(array)) return GL_INVALID_OPERATION;
MG_Util::Debug::LogD("MG_State: VAO: Bind called for %u", array);
if (array != 0) {
if (!ValidateGeneratedName(array)) {
MG_Util::Debug::LogE("MG_State: VAO: Bind invalid name %u", array);
return GL_INVALID_OPERATION;
}
auto& vao = vaos_[array];
if (!vao.generated) {
MG_Util::Debug::LogD("MG_State: VAO: Creating VAO %u during bind", array);
vao.generated = true;
}
}
currentVao_ = array;
MG_Util::Debug::LogD("MG_State: VAO: Bound to %u", array);
return GL_NO_ERROR;
}
bool VertexArrayState::ValidateGeneratedName(GLuint array) {
if (array == 0)
return true;
bool inFreeList = freeIds_.count(array) > 0;
bool valid = (array <= lastId_) && !inFreeList;
MG_Util::Debug::LogD("MG_State: VAO: ValidateGeneratedName %u: %d", array, valid);
return valid;
}
bool VertexArrayState::ValidateAllocatedHandle(GLuint array) {
bool exists = vaos_.count(array) && vaos_[array].generated;
MG_Util::Debug::LogD("MG_State: VAO: ValidateAllocatedHandle %u: %d", array, exists);
return exists;
}
GLenum VertexArrayState::EnableAttrib(GLuint index) {
if (currentVao_ == 0) return GL_INVALID_OPERATION;
if (!ValidateAllocatedHandle(currentVao_))
return GL_INVALID_OPERATION;
if (index >= GL_MAX_VERTEX_ATTRIBS) return GL_INVALID_VALUE;
GetCurrentVAO()->attribs[index].enabled = true;
MG_Util::Debug::LogD("Attrib vaos_[%u].attribs[%u].enabled = %d", currentVao_, index, vaos_[currentVao_].attribs[index].enabled);
GetCurrentVAO()->attribDirty = true;
return GL_NO_ERROR;
}
GLenum VertexArrayState::DisableAttrib(GLuint index) {
if (currentVao_ == 0) return GL_INVALID_OPERATION;
if (!ValidateAllocatedHandle(currentVao_))
return GL_INVALID_OPERATION;
if (index >= GL_MAX_VERTEX_ATTRIBS) return GL_INVALID_VALUE;
GetCurrentVAO()->attribs[index].enabled = false;
MG_Util::Debug::LogD("Attrib vaos_[%u].attribs[%u].enabled = %d", currentVao_, index, vaos_[currentVao_].attribs[index].enabled);
GetCurrentVAO()->attribDirty = true;
return GL_NO_ERROR;
}
@@ -66,7 +130,8 @@ GLenum VertexArrayState::SetAttribPointer(GLuint index, GLint size, GLenum type,
GLboolean normalized, GLsizei stride,
const void* pointer, bool isInteger,
GLuint currentArrayBuffer) {
if (currentVao_ == 0) return GL_INVALID_OPERATION;
if (!ValidateAllocatedHandle(currentVao_))
return GL_INVALID_OPERATION;
if (index >= GL_MAX_VERTEX_ATTRIBS) return GL_INVALID_VALUE;
VertexAttribState state;
@@ -81,6 +146,8 @@ GLenum VertexArrayState::SetAttribPointer(GLuint index, GLint size, GLenum type,
state.enabled = true;
vaos_[currentVao_].attribs[index] = state;
GetCurrentVAO()->attribDirty = true;
return GL_NO_ERROR;
}
+10 -4
View File
@@ -9,7 +9,7 @@
#include "../../../Includes.h"
struct VertexAttribState {
bool enabled = false;
bool enabled;
GLint size = 4;
GLenum type = GL_FLOAT;
GLboolean normalized = GL_FALSE;
@@ -21,8 +21,10 @@ struct VertexAttribState {
struct VertexArrayObject {
bool generated = false;
bool attribDirty = false;
bool eboDirty = false;
GLuint elementBuffer = 0;
std::unordered_map<GLuint, VertexAttribState> attribs;
ankerl::unordered_map<GLuint, VertexAttribState> attribs;
};
class VertexArrayState {
@@ -30,6 +32,8 @@ public:
VertexArrayState();
// Return: the validity of the operation, according to OpenGL 3 standard
GLenum GenName(GLuint* array);
GLenum GenNameN(GLsizei n, GLuint* arrays);
GLenum Create(GLuint* array);
GLenum CreateN(GLsizei n, GLuint* arrays);
GLenum Bind(GLuint array);
@@ -42,12 +46,14 @@ public:
GLuint GetBoundElementBuffer();
VertexArrayObject* GetCurrentVAO();
bool ValidateGeneratedName(GLuint array);
bool ValidateAllocatedHandle(GLuint array);
GLuint currentVao_ = 0;
ankerl::unordered_map<GLuint, VertexArrayObject> vaos_;
private:
std::unordered_map<GLuint, VertexArrayObject> vaos_;
std::set<GLuint> freeIds_;
GLuint lastId_ = 0;
GLuint currentVao_ = 0;
};
#endif //MOBILEGL_VERTEXARRAYSTATE_H
+2 -2
View File
@@ -48,8 +48,8 @@ namespace MG_RHI::GLES::Test {
GLuint quadVBO = 0;
GLint uTexLoc = -1;
GLint uMVPLoc = -1;
std::unordered_map<GLuint, GLuint> textureCache;
std::unordered_map<GLuint, bool> textureDirty;
ankerl::unordered_map<GLuint, GLuint> textureCache;
ankerl::unordered_map<GLuint, bool> textureDirty;
};
static ScreenResources sRes;
+9
View File
@@ -1206,6 +1206,15 @@ void Log##name(const char* format, ...) { \
CASE(GL_DOT3_RGBA)
/* texture_border_clamp */
CASE(GL_CLAMP_TO_BORDER)
/* framebuffer_status */
CASE(GL_FRAMEBUFFER_COMPLETE)
CASE(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
CASE(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
CASE(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS)
CASE(GL_FRAMEBUFFER_UNSUPPORTED)
CASE(GL_COLOR_ATTACHMENT0)
CASE(GL_DEPTH_ATTACHMENT)
CASE(GL_STENCIL_ATTACHMENT)
/*
* Miscellaneous
*/
+1 -1
View File
@@ -54,7 +54,7 @@ namespace MG_Util::Program {
std::ostringstream ss;
ss << "[";
const size_t elemCount = std::min<size_t>(value.count, 16); // 限制最大显示元素
const size_t elemCount = std::min<size_t>(value.count, 16);
switch(value.type) {
case GL_FLOAT:
+36 -3
View File
@@ -108,7 +108,7 @@ namespace MG_Util::Program {
return;
}
std::unordered_set<GLint> used_locations;
ankerl::unordered_set<GLint> used_locations;
GLint auto_location = 0;
for (auto spirv: allSpirv) {
spvc_parsed_ir ir = nullptr;
@@ -395,11 +395,44 @@ namespace MG_Util::Program {
prog.uniformLocations[name] = final_location;
UniformValue uniformValue;
uniformValue.type = gl_type;
uniformValue.count = spvc_type_get_array_dimension(type, 0) > 0 ?
spvc_type_get_array_dimension(type, 0) : 1;
prog.uniformValues[name] = uniformValue;
}
}
spvc_context_destroy(context);
}
std::string CompileSPIRVToGLSL(std::vector<unsigned int> spirv, uint glslVersion, bool isES) {
spvc_context context = nullptr;
spvc_parsed_ir ir = nullptr;
spvc_compiler compiler_glsl = nullptr;
spvc_compiler_options options = nullptr;
spvc_resources resources = nullptr;
const spvc_reflected_resource *list = nullptr;
const char *result = nullptr;
size_t count;
const SpvId *p_spirv = spirv.data();
size_t word_count = spirv.size();
spvc_context_create(&context);
spvc_context_parse_spirv(context, p_spirv, word_count, &ir);
spvc_context_create_compiler(context, SPVC_BACKEND_GLSL, ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &compiler_glsl);
spvc_compiler_create_shader_resources(compiler_glsl, &resources);
spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER, &list, &count);
spvc_compiler_create_compiler_options(compiler_glsl, &options);
spvc_compiler_options_set_uint(options, SPVC_COMPILER_OPTION_GLSL_VERSION, glslVersion);
spvc_compiler_options_set_bool(options, SPVC_COMPILER_OPTION_GLSL_ES, isES ? SPVC_TRUE : SPVC_FALSE);
spvc_compiler_install_compiler_options(compiler_glsl, options);
spvc_compiler_compile(compiler_glsl, &result);
if (!result) {
return{};
}
std::string essl = result;
spvc_context_destroy(context);
return essl;
}
}
+1
View File
@@ -177,6 +177,7 @@ namespace MG_Util::Program {
std::string CompileGLSLToTShader(GLenum shaderType, const std::string& source, glslang::TShader *&shader);
std::vector<std::vector<unsigned>> CompileMultipleShadersToSPIRV(const ProgramState& state, ProgramObject& prog, std::string& infoLog);
void ReflectSPIRVUniforms(const std::vector<std::vector<unsigned>>& allSpirv, ProgramObject& prog, std::string& infoLog);
std::string CompileSPIRVToGLSL(std::vector<unsigned int> spirv, uint glslVersion, bool isES);
}
#endif //MOBILEGL_GLSLTOOL_H
+20 -11
View File
@@ -4,7 +4,7 @@
- [x] glGetAttribLocation
- [x] glGetBufferParameteriv
- [x] glGetError
- [ ] glGetIntegerv
- [x] glGetIntegerv
- [x] glGetProgramiv
- [x] glGetShaderiv
- [x] glGetString
@@ -33,6 +33,8 @@
- [x] glFramebufferTexture2D
- [x] glGenFramebuffers
  ~~glBlitFramebuffer~~
---
### **4. Shader & Program Management**
@@ -60,6 +62,10 @@
- [x] glUnmapBuffer
- [x] glVertexAttribIPointer
- [x] glVertexAttribPointer
- [x] glBufferSubData
- [x] glMapBufferRange
- [x] glFlushMappedBufferRange
- [x] glCopyBufferSubData
---
@@ -90,28 +96,27 @@
---
### **8. Drawing Commands**
- [ ] glDrawElements
- [ ] glDrawArrays
  ~~glDrawElements~~
## Abstraction Layer (MG_RHI)
### **1. Initialization & Query Functions**
glGetAttribLocation~~
  ~~glGetAttribLocation~~
glGetBufferParameteriv~~
  ~~glGetBufferParameteriv~~
glGetError~~
  ~~glGetError~~
- [ ] glGetIntegerv
  ~~glGetIntegerv~~
- [ ] glGetProgramiv
- [ ] glGetShaderiv
- [ ] glGetString
- [ ] glGetStringi
glGetTexLevelParameteriv~~
  ~~glGetTexLevelParameteriv~~
glGetUniformLocation~~
  ~~glGetUniformLocation~~
---
@@ -133,6 +138,7 @@ glGetUniformLocation~~
- [ ] glDeleteFramebuffers
- [ ] glFramebufferTexture2D
- [ ] glGenFramebuffers
- [ ] glBlitFramebuffer
---
@@ -161,6 +167,10 @@ glGetUniformLocation~~
- [ ] glUnmapBuffer
- [ ] glVertexAttribIPointer
- [ ] glVertexAttribPointer
- [ ] glBufferSubData
- [ ] glMapBufferRange
- [ ] glFlushMappedBufferRange
- [ ] glCopyBufferSubData
---
@@ -191,5 +201,4 @@ glGetUniformLocation~~
---
### **8. Drawing Commands**
- [ ] glDrawElements
- [ ] glDrawArrays
- [ ] glDrawElements
+8 -4
View File
@@ -6,7 +6,11 @@
**glslang** by **KhronosGroup**: [github](https://github.com/KhronosGroup/glslang)
**GlslOptimizerV2** by **aiekick**: [github](https://github.com/aiekick/GlslOptimizerV2)
*(Unused Currently)* **GlslOptimizerV2** by **aiekick**: [github](https://github.com/aiekick/GlslOptimizerV2)
**unordered_dense** by **Martin Leitner-Ankerl**: [github](https://github.com/martinus/unordered_dense)
**OpenGL Mathematics (*GLM*)** by **G-Truc Creation**: [github](https://github.com/g-truc/glm)
## Progress
@@ -21,12 +25,12 @@
---
**Target**: **OpenGL implementation compatible with Minecraft 1.17 to 1.21.1**
**Target**: **OpenGL implementation compatible with Minecraft 1.17 to 1.21.5**
| Component | Development Progress\* |
|--------------------------------|------------------------|
| **OpenGL State Manager** | **59 / 62** |
| **Abstraction Layer (MG_RHI)** | **0 / 57** |
| **OpenGL State Manager** | **65 / 65** |
| **Abstraction Layer (MG_RHI)** | **0 / 61** |
| **OpenGL ES Backend** | **N/A** (of MG_RHI) |
| **Vulkan Backend** | **planned** |
+36
View File
@@ -0,0 +1,36 @@
apply plugin: 'com.android.library'
android {
namespace 'top.mobilegl.mobilegl'
compileSdk 34
defaultConfig {
minSdk 26
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
}
proguard {
minifyEnabled true
initWith debug
}
fordebug {
debuggable true
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
version "3.22.1"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
ndkVersion '27.2.12479018'
}
File diff suppressed because it is too large Load Diff