OpenGL 4.6 on Metal

Related tags

Graphics MGL
Overview

MGL

OpenGL 4.6 on Metal

This is a start for porting OpenGL 4.6 on top of Metal, most of it is functional and has been tested. The tests are functional, not coverage tests so they test the functionality of a path not all the possible permutations.

So far the following parts of OpenGL work

Vertex Arrays Buffers Textures Programs Shaders Vertex Fragment Compute Samplers Alpha Blending Depth and Stencil Testing Framebuffer Objects Drawbuffers Most of the draw calls Elements / Instancing and such

GLFW support

I modified a version of GLFW to work with MGL, it replaces the default MacOS OpenGL contexts. The changes are included in the repository and should build correctly with the MGL xcode project.

Mapping OpenGL onto Metal

I mapped as much of the functionality of Metal I could into OpenGL 4.6, it's surprising how much I was able to map directly from OpenGL state to Metal. But I suppose Metal evolved to meet market requirements and since OpenGL was in place the same features existed just in another form.

Not all of the functionality for OpenGL is available, but I didn't build this for conformance I just wanted to program OpenGL on the MacOS platform.

Parsing the OpenGL 4.6 XML spec

In the beginning I used ezxml to parse the gl.xml file for all the enums and functions, then printed out one giant file with all the functions. I then used the same parser to create the dispatch tables and data structures. As each functional part was built I separated blocks of functions into these functions like buffers / textures / shaders / programs.

SPIRV to Metal

I really couldn't have done this project without all the SPIRV support from Khronos, once I found out I could translate GLSL into Metal using some of the SPIRV tools this project became a reality. There are some parts in GLSL that Metal just doesn't support like Geometry Shaders, I think the way forward on support for Geometry Shaders is to translate the vertex and geometry shaders into LLVM from SPIRV then execute the results from processing them on the CPU through a passthrough vertex shader in the pipeline. Some parts of the GLSL spec probably won't map to Metal but more testing and exposure to developers will show what works and what doesn't/

OpenGL functions and how they work

Each OpenGL function starts in gl_core.c

void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)
{
    GLMContext ctx = GET_CONTEXT();

    ctx->dispatch.tex_image2D(ctx, target, level, internalformat, width, height, border, format, type, pixels);
}

glTexImage2D calls into a dispatch table which lands on a mgl equivalent

void mglTexImage2D(GLMContext ctx, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) {
    Texture *tex;
    GLuint face;
    GLboolean is_array;
    GLboolean proxy;

    face = 0;
    is_array = false;
    proxy = false;

    switch(target)
    {
        case GL_TEXTURE_2D:
            break;

        case GL_PROXY_TEXTURE_2D:
        case GL_PROXY_TEXTURE_CUBE_MAP:
            proxy = true;
            break;

        case GL_PROXY_TEXTURE_1D_ARRAY:
            is_array = true;
            proxy = true;
            break;

        case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
        case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
        case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
        case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
            face = target - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
            break;

        case GL_PROXY_TEXTURE_RECTANGLE:
            proxy = true;
            ERROR_CHECK_RETURN(level==0, GL_INVALID_OPERATION);
            break;

        case GL_TEXTURE_RECTANGLE:
            ERROR_CHECK_RETURN(level==0, GL_INVALID_OPERATION);
            break;

        default:
            ERROR_RETURN(GL_INVALID_ENUM);
    }

    ERROR_CHECK_RETURN(level >= 0, GL_INVALID_VALUE);

    // verifyFormatType sets the error
    ERROR_CHECK_RETURN(verifyInternalFormatAndFormatType(ctx, internalformat, format, type), 0);

    ERROR_CHECK_RETURN(width >= 0, GL_INVALID_VALUE);
    ERROR_CHECK_RETURN(height >= 0, GL_INVALID_VALUE);

    ERROR_CHECK_RETURN(border == 0, GL_INVALID_VALUE);

    tex = getTex(ctx, 0, target);

    ERROR_CHECK_RETURN(tex, GL_INVALID_OPERATION);

    tex->access = GL_READ_ONLY;

    createTextureLevel(ctx, tex, face, level, is_array, internalformat, width, height, 1, format, type, (void *)pixels, proxy);
}

The mgl function checks input parameters then modifies the OpenGL state and marks it dirty. I use macros for error checking parameters... because I got sick of writing.

if (expr == false) {
  set error
  return;
}

Common use of code for most OpenGL calls

Most functions are like mglTexImage2D, there a lot of common entry points which check parameters then call a function like createTextureLevel() which is used by all the TexImage calls to do the actual work.

OpenGL state translated to Metal using glDrawArrays as an example

All state changes are evaluated on direct commands, these are commands that will issue a command to the GPU for things like drawing primitives, copying data or executing compute kernels.

Looking at glDrawArrays..

glDrawArrays lands on mglDrawArrays which does parameter testing and calls the Objective C interface through a jump table in the context. This lands you in MGLRenderere.m

void mglDrawArrays(GLMContext ctx, GLenum mode, GLint first, GLsizei count)
{
    ERROR_CHECK_RETURN(check_draw_modes(mode), GL_INVALID_ENUM);

    ERROR_CHECK_RETURN(count > 1, GL_INVALID_VALUE);

    ERROR_CHECK_RETURN(validate_vao(ctx), GL_INVALID_VALUE);

    ERROR_CHECK_RETURN(validate_program(ctx), GL_INVALID_VALUE);

    ctx->mtl_funcs.mtlDrawArrays(ctx, mode, first, count);
}

Which lands you in Objective C land, we do a C interface call to Objecitve C here

void mtlDrawArrays(GLMContext glm_ctx, GLenum mode, GLint first, GLsizei count)
{
    // Call the Objective-C method using Objective-C syntax
    [(__bridge id) glm_ctx->mtl_funcs.mtlObj mtlDrawArrays: glm_ctx mode: mode first: first count: count];
}

And now we speak Objective C

-(void) mtlDrawArrays: (GLMContext) ctx mode:(GLenum) mode first: (GLint) first count: (GLsizei) count
{
    MTLPrimitiveType primitiveType;

    RETURN_ON_FAILURE([self processGLState: true]);

    primitiveType = getMTLPrimitiveType(mode);
    assert(primitiveType != 0xFFFFFFFF);

     [_currentRenderEncoder drawPrimitives: primitiveType
                              vertexStart: first
                              vertexCount: count];
}

processGLState does all the state mapping from OpenGL to Metal

On OpenGL drawing calls the OpenGL state is processed for any dirty state in processGLState, you have to do this before each draw command to ensure changed state is captured into Metal.

State is transferred from OpenGL to Metal state using a Metal command queue with a MTLRenderCommandEncoder. Occasionally a new MTLRenderCommandEncoder will need to be built if the state changes need to modify the MTLRenderPipelineState so neRenderEncoder is called to create a new encoder with the current OpenGL state.

Most of the work is done in MGLRenderer.m, at first it can look like a giant piece of code. But it's simple once you figure out the mapping process.

binding buffers and textures from shader layouts

You have to bind all the buffers and textures to Metal, there are mapping operations you need to do to transfer OpenGL buffers / textures to Metal. Since all of this is driven by the GLSL shader in 4.5 which requires you to map your bindings and locations

An example vertex shader defines a vertex buffer object at location 0 and a uniform buffer at binding 0. These are not the same location, but relative to the type.

const char* vertex_shader =
GLSL(450 core,
     layout(location = 0) in vec3 position;

     layout(binding = 0) uniform matrices
     {
         mat4 rotMatrix;
     };

     void main() {
        gl_Position = rotMatrix * vec4(position, 1.0);
     }
);

Each binding point in OpenGL is a 2D array one for each type, like GL_ARRAY_BUFFER

glBindBuffer(GL_ARRAY_BUFFER, vbo);

Indexes an array like

buffers[GL_ARRAY_BUFFER].buffer = vbo

So internal to processGLState the vertex buffer array is taken apart, buffers and attributes mapped then we walk through uniforms / textures through their binding points in the GL state and map these to Metal state.

Once you walk a glDrawArrays call through processGLState, you will get a jist of how this all works.

Grabbing the SPIRV sources and building

There is an Xcode project build most of this, but you will need to clone a bunch of external projects from GitHub.

In MGL/external there is a file

clone_external.sh

Run this and all the external repositories will be downloaded.

SPIRV-Cross SPIRV-Headers SPIRV-Tools ezxml glfw glm glslang

You will need to build the following SPIRV-Cross SPIRV-Headers SPIRV-Tools glslang glm

Each is distributed by Khronos with a CMake style build

For each of the projects above build you will need to do the following

cd mkdir build cd build cmake .. make make install

Once installed in /usr/local the Xcode project should be able to build all the required dependencies for MGL.

Where to start

Start by building test_mgl_glfw, this is a chunk of test code I used to get most of the functionality up and running.

Performance

I really don't know what the performance comaprison is, how much is in overhead or in the driver. I wrote most of this as a functional exercise knowing that once it reached some level of functional coverage I would go back and address the performance issue. But I didn't write this without thinking about performance issues as I implemented the code.

Contributing

If you want to contribute that would be great, it's all written in C.. in the same style all of the OpenGL framework from Apple was written in. If you don't like the coding style, don't change it. Just follow the same coding style and put your efforts into testing and functionality.

Future

I would like to implement OpenCL directly into this framework, its much simpler mapping from OpenCL to Metal and there is zero state to deal with so you should be able to use all the buffers / textures and other resources directly on top of a OpenGL context.

Questions?

You can reach me at [email protected] for more information, it would be great to see this used by others and developed into a full fledged project anyone can use.

Cheers

Mike

Comments
  • Building without installing

    Building without installing

    How do I build without having to install all of these things into my /usr directory, and what should I reinstall/delete from that directory with brew. I don't want to stuff up my installations of things. Thanks :)

    opened by hamarb123 21
  • viewport

    viewport

    In the course of fixing hidpi support, I managed to get the highest possible rendering quality (i.e. no scaling, no filtering). However, I recently found that it's only working with some examples (e.g. test_2D_textures), and not with others (e.g. test_2D_array_textures): the rendering is limited to the upper-left corner of the window.

    I could not fix it as of yet. I changed the view port with glViewPort(w2, h2) for hidpi, but it's only working with test_2D_textures), I do not know why it does not with other examples...

    opened by conversy 9
  • Makefile usage

    Makefile usage

    This PR makes it easier to compile the lib and launch the test the from scratch using uninstalled SPIRV stuff. It uses the regular, brew-provided glfw, but this requires to request an OpenGL 4.1 context instead of 4.6 in the test program.

    opened by conversy 4
  • Can't Build

    Can't Build

    Trying to build on my Mac, M1 Max, Monterey 12.1.

    I keep getting the error

    MGL/include/glm_context.h:152:5: error: unknown type name 'uint'; did you mean 'int'?
    
    

    When using xcodebuild, it succeeds, but I'm not sure it should.

    error: unable to spawn process '/usr/bin/make' (No such file or directory) (in target 'SPIRV-Headers' from project 'MGL')

    opened by lbibass 4
  • CGLGetParameter

    CGLGetParameter

    Currently trying to get MC running using MGL.

    1.17 and onwards are suprisingly very close to working, with the glUniform* set of functions remaining.

    The OpenGL Profiler by apple seems to hang MC so the list of OpenGL commands (here) that I'm using might be inaccurate.

    One of the functions I found while profiling MC is CGLGetParameter. What is this function and can it be implemented in MGL? It doesn't seem to be referenced anywhere in the MGL codebase.

    opened by r58Playz 3
  • Fix xcode build

    Fix xcode build

    Also reverts https://github.com/openglonmetal/MGL/commit/d0e034508573e2a66034fa44d9202eff740f09ca because test_mgl_glfw is supposed to test mgl, not regular apple opengl.

    You can now run test_mgl_glfw in xcode, which lets you easily turn on metal api validation which reveals an error with the viewport! Screen Shot 2022-07-29 at 3 16 00 PM

    opened by r58Playz 3
  • Unable to run test_mgl_glfw

    Unable to run test_mgl_glfw

    Hi, I'm not able to run the mgl test on my machine, M1 Max macOS 12.2

    I get this error from Xcode which I don't really know how to debug,

    Xcode Error
    Details
    
    Could not launch “test_mgl_glfw”
    Domain: IDEDebugSessionErrorDomain
    Code: 3
    Failure Reason: LLDB provided no error string.
    User Info: {
        DVTErrorCreationDateKey = "2022-02-06 07:55:44 +0000";
        DVTRadarComponentKey = 855031;
        IDERunOperationFailingWorker = DBGLLDBLauncher;
        RawUnderlyingErrorMessage = "LLDB provided no error string.";
    }
    --
    
    Analytics Event: com.apple.dt.IDERunOperationWorkerFinished : {
        "device_model" = "MacBookPro18,2";
        "device_osBuild" = "12.2 (21D49)";
        "device_platform" = "com.apple.platform.macosx";
        "launchSession_schemeCommand" = Run;
        "launchSession_state" = 1;
        "launchSession_targetArch" = arm64;
        "operation_duration_ms" = 16;
        "operation_errorCode" = 3;
        "operation_errorDomain" = IDEDebugSessionErrorDomain;
        "operation_errorWorker" = DBGLLDBLauncher;
        "operation_name" = IDERunOperationWorkerGroup;
        "param_consoleMode" = 0;
        "param_debugger_attachToExtensions" = 0;
        "param_debugger_attachToXPC" = 1;
        "param_debugger_type" = 3;
        "param_destination_isProxy" = 0;
        "param_destination_platform" = "com.apple.platform.macosx";
        "param_diag_MainThreadChecker_stopOnIssue" = 0;
        "param_diag_MallocStackLogging_enableDuringAttach" = 0;
        "param_diag_MallocStackLogging_enableForXPC" = 1;
        "param_diag_allowLocationSimulation" = 1;
        "param_diag_gpu_frameCapture_enable" = 0;
        "param_diag_gpu_shaderValidation_enable" = 0;
        "param_diag_gpu_validation_enable" = 0;
        "param_diag_memoryGraphOnResourceException" = 0;
        "param_diag_queueDebugging_enable" = 1;
        "param_diag_runtimeProfile_generate" = 0;
        "param_diag_sanitizer_asan_enable" = 0;
        "param_diag_sanitizer_tsan_enable" = 0;
        "param_diag_sanitizer_tsan_stopOnIssue" = 0;
        "param_diag_sanitizer_ubsan_stopOnIssue" = 0;
        "param_diag_showNonLocalizedStrings" = 0;
        "param_diag_viewDebugging_enabled" = 1;
        "param_diag_viewDebugging_insertDylibOnLaunch" = 1;
        "param_install_style" = 0;
        "param_launcher_UID" = 2;
        "param_launcher_allowDeviceSensorReplayData" = 0;
        "param_launcher_kind" = 0;
        "param_launcher_style" = 0;
        "param_launcher_substyle" = 0;
        "param_runnable_appExtensionHostRunMode" = 0;
        "param_runnable_productType" = "com.apple.product-type.tool";
        "param_runnable_swiftVersion" = "5.5.2";
        "param_runnable_type" = 2;
        "param_testing_launchedForTesting" = 0;
        "param_testing_suppressSimulatorApp" = 0;
        "param_testing_usingCLI" = 0;
        "sdk_canonicalName" = "macosx12.1";
        "sdk_osVersion" = "12.1";
        "sdk_variant" = macos;
    }
    --
    
    
    System Information
    
    macOS Version 12.2 (Build 21D49)
    Xcode 13.2.1 (19586) (Build 13C100)
    Timestamp: 2022-02-06T00:55:44-07:00
    

    Actually, I saw this has been brought up in #9

    When trying to build through the makefile I get a missing KHR header presumably from some dependency misconfiguration on my end but I've been fiddling with this for a while and can't quite figure it out.

    Makefile Error
    ❯ make -j test
    c++ -std=c++14 -MMD -gfull -Og -arch arm64 -I/usr/local/include/spirv/1.2 -Iexternal/SPIRV-Cross -I/opt/homebrew/opt/glslang/include/glslang/Include -I/opt/homebrew/include  -I/opt/homebrew/Cellar/spirv-tools/2022.1/include -I/opt/homebrew/Cellar/glm/0.9.9.8/include -IMGL/include -IMGL/SPIRV/SPIRV-Cross -DENABLE_OPT=0 -DSPIRV_CROSS_C_API_MSL=1 -DSPIRV_CROSS_C_API_GLSL=1 -DSPIRV_CROSS_C_API_CPP=1 -DSPIRV_CROSS_C_API_REFLECT=1 -I/opt/homebrew/Cellar/glfw/3.3.6/include -c test_mgl_glfw/main.cpp -o build/test_mgl_glfw/main.o
    cc -std=gnu17 -MMD -gfull -Og -arch arm64 -I/usr/local/include/spirv/1.2 -Iexternal/SPIRV-Cross -I/opt/homebrew/opt/glslang/include/glslang/Include -I/opt/homebrew/include  -I/opt/homebrew/Cellar/spirv-tools/2022.1/include -I/opt/homebrew/Cellar/glm/0.9.9.8/include -IMGL/include -IMGL/SPIRV/SPIRV-Cross -DENABLE_OPT=0 -DSPIRV_CROSS_C_API_MSL=1 -DSPIRV_CROSS_C_API_GLSL=1 -DSPIRV_CROSS_C_API_CPP=1 -DSPIRV_CROSS_C_API_REFLECT=1 -c MGL/src/buffers.c -o build/MGL/src/buffers.o
    cc -std=gnu17 -MMD -gfull -Og -arch arm64 -I/usr/local/include/spirv/1.2 -Iexternal/SPIRV-Cross -I/opt/homebrew/opt/glslang/include/glslang/Include -I/opt/homebrew/include  -I/opt/homebrew/Cellar/spirv-tools/2022.1/include -I/opt/homebrew/Cellar/glm/0.9.9.8/include -IMGL/include -IMGL/SPIRV/SPIRV-Cross -DENABLE_OPT=0 -DSPIRV_CROSS_C_API_MSL=1 -DSPIRV_CROSS_C_API_GLSL=1 -DSPIRV_CROSS_C_API_CPP=1 -DSPIRV_CROSS_C_API_REFLECT=1 -c MGL/src/compute.c -o build/MGL/src/compute.o
    cc -std=gnu17 -MMD -gfull -Og -arch arm64 -I/usr/local/include/spirv/1.2 -Iexternal/SPIRV-Cross -I/opt/homebrew/opt/glslang/include/glslang/Include -I/opt/homebrew/include  -I/opt/homebrew/Cellar/spirv-tools/2022.1/include -I/opt/homebrew/Cellar/glm/0.9.9.8/include -IMGL/include -IMGL/SPIRV/SPIRV-Cross -DENABLE_OPT=0 -DSPIRV_CROSS_C_API_MSL=1 -DSPIRV_CROSS_C_API_GLSL=1 -DSPIRV_CROSS_C_API_CPP=1 -DSPIRV_CROSS_C_API_REFLECT=1 -c MGL/src/draw_buffers.c -o build/MGL/src/draw_buffers.o
    cc -std=gnu17 -MMD -gfull -Og -arch arm64 -I/usr/local/include/spirv/1.2 -Iexternal/SPIRV-Cross -I/opt/homebrew/opt/glslang/include/glslang/Include -I/opt/homebrew/include  -I/opt/homebrew/Cellar/spirv-tools/2022.1/include -I/opt/homebrew/Cellar/glm/0.9.9.8/include -IMGL/include -IMGL/SPIRV/SPIRV-Cross -DENABLE_OPT=0 -DSPIRV_CROSS_C_API_MSL=1 -DSPIRV_CROSS_C_API_GLSL=1 -DSPIRV_CROSS_C_API_CPP=1 -DSPIRV_CROSS_C_API_REFLECT=1 -c MGL/src/error.c -o build/MGL/src/error.o
    cc -std=gnu17 -MMD -gfull -Og -arch arm64 -I/usr/local/include/spirv/1.2 -Iexternal/SPIRV-Cross -I/opt/homebrew/opt/glslang/include/glslang/Include -I/opt/homebrew/include  -I/opt/homebrew/Cellar/spirv-tools/2022.1/include -I/opt/homebrew/Cellar/glm/0.9.9.8/include -IMGL/include -IMGL/SPIRV/SPIRV-Cross -DENABLE_OPT=0 -DSPIRV_CROSS_C_API_MSL=1 -DSPIRV_CROSS_C_API_GLSL=1 -DSPIRV_CROSS_C_API_CPP=1 -DSPIRV_CROSS_C_API_REFLECT=1 -c MGL/src/fence.c -o build/MGL/src/fence.o
    In file included from MGL/src/compute.c:21:
    In file included from MGL/include/glm_context.h:28:
    In file included from MGL/include/glm_dispatch.h:13:
    MGL/include/glcorearb.h:65:10: fatal error: 'KHR/khrplatform.h' file not found
    #include <KHR/khrplatform.h>
             ^~~~~~~~~~~~~~~~~~~
    In file included from MGL/src/buffers.c:26:
    In file included from MGL/include/glm_context.h:28:
    In file included from MGL/include/glm_dispatch.h:13:
    MGL/include/glcorearb.h:65:10: fatal error: 'KHR/khrplatform.h' file not found
    #include <KHR/khrplatform.h>
             ^~~~~~~~~~~~~~~~~~~
    test_mgl_glfw/main.cpp:32:10: fatal error: 'GL/glcorearb.h' file not found
    #include <GL/glcorearb.h>
             ^~~~~~~~~~~~~~~~
    1 error generated.
    cc -std=gnu17 -MMD -gfull -Og -arch arm64 -I/usr/local/include/spirv/1.2 -Iexternal/SPIRV-Cross -I/opt/homebrew/opt/glslang/include/glslang/Include -I/opt/homebrew/include  -I/opt/homebrew/Cellar/spirv-tools/2022.1/include -I/opt/homebrew/Cellar/glm/0.9.9.8/include -IMGL/include -IMGL/SPIRV/SPIRV-Cross -DENABLE_OPT=0 -DSPIRV_CROSS_C_API_MSL=1 -DSPIRV_CROSS_C_API_GLSL=1 -DSPIRV_CROSS_C_API_CPP=1 -DSPIRV_CROSS_C_API_REFLECT=1 -c MGL/src/framebuffers.c -o build/MGL/src/framebuffers.o
    make: *** [build/MGL/src/compute.o] Error 1
    make: *** Waiting for unfinished jobs....
    cc -std=gnu17 -MMD -gfull -Og -arch arm64 -I/usr/local/include/spirv/1.2 -Iexternal/SPIRV-Cross -I/opt/homebrew/opt/glslang/include/glslang/Include -I/opt/homebrew/include  -I/opt/homebrew/Cellar/spirv-tools/2022.1/include -I/opt/homebrew/Cellar/glm/0.9.9.8/include -IMGL/include -IMGL/SPIRV/SPIRV-Cross -DENABLE_OPT=0 -DSPIRV_CROSS_C_API_MSL=1 -DSPIRV_CROSS_C_API_GLSL=1 -DSPIRV_CROSS_C_API_CPP=1 -DSPIRV_CROSS_C_API_REFLECT=1 -c MGL/src/get.c -o build/MGL/src/get.o
    1 error generated.
    In file included from MGL/src/draw_buffers.c:25:
    In file included from MGL/include/glm_context.h:28:
    In file included from MGL/include/glm_dispatch.h:13:
    MGL/include/glcorearb.h:65:10: fatal error: 'KHR/khrplatform.h' file not found
    #include <KHR/khrplatform.h>
             ^~~~~~~~~~~~~~~~~~~
    make: *** [build/MGL/src/buffers.o] Error 1
    In file included from MGL/src/error.c:25:
    In file included from MGL/include/error.h:25:
    In file included from MGL/include/glm_context.h:28:
    In file included from MGL/include/glm_dispatch.h:13:
    MGL/include/glcorearb.h:65:10: fatal error: 'KHR/khrplatform.h' file not found
    #include <KHR/khrplatform.h>
             ^~~~~~~~~~~~~~~~~~~
    In file included from MGL/src/fence.c:23:
    In file included from MGL/include/glm_context.h:28:
    In file included from MGL/include/glm_dispatch.h:13:
    MGL/include/glcorearb.h:65:10: fatal error: 'KHR/khrplatform.h' file not found
    #include <KHR/khrplatform.h>
             ^~~~~~~~~~~~~~~~~~~
    1 error generated.
    make: *** [build/MGL/src/draw_buffers.o] Error 1
    1 error generated.
    1 error generated.
    make: *** [build/MGL/src/error.o] Error 1
    make: *** [build/MGL/src/fence.o] Error 1
    In file included from MGL/src/get.c:21:
    In file included from MGL/include/glm_context.h:28:
    In file included from MGL/include/glm_dispatch.h:13:
    MGL/include/glcorearb.h:65:10: fatal error: 'KHR/khrplatform.h' file not found
    #include <KHR/khrplatform.h>
             ^~~~~~~~~~~~~~~~~~~
    In file included from MGL/src/framebuffers.c:24:
    In file included from MGL/include/glm_context.h:28:
    In file included from MGL/include/glm_dispatch.h:13:
    MGL/include/glcorearb.h:65:10: fatal error: 'KHR/khrplatform.h' file not found
    #include <KHR/khrplatform.h>
             ^~~~~~~~~~~~~~~~~~~
    1 error generated.
    make: *** [build/MGL/src/framebuffers.o] Error 1
    1 error generated.
    make: *** [build/MGL/src/get.o] Error 1
    1 error generated.
    make: *** [build/test_mgl_glfw/main.o] Error 1
    
    opened by cadenkriese 3
  • Issue when running make install

    Issue when running make install

    When trying to run make install, I get this error: CMake Error at cmake_install.cmake:41 (file): file INSTALL cannot copy file "/Users/*****/MGL/external/SPIRV-Cross/build/libspirv-cross-core.a" to "/usr/local/lib/libspirv-cross-core.a": Permission denied.

    opened by awsomenes 3
  • MGL as an EGL platform?

    MGL as an EGL platform?

    This issue could probably be summarized as: why did MGL choose to write their own GL platform instead of adapting something else, such as EGL.

    And then ramble how EGL could be implemented.

    The rationale for providing an MGL platform for EGL would allow app developers to reuse their EGL toolkit support if Linux or EGL on Windows is already supported.

    I believe the approach to take for EGL would be to write an extension to provide a new EGL platform and a way to create an EGLSurface from something like a CAMetalLayer.

    I understand that EGL is no small task to implement. There are also issues like the bureaucracy if the idea goes beyond experimentation if an MGL EGL platform were to be added to the EGL registry.

    opened by i509VCB 2
  • Using an Organization vs a User account

    Using an Organization vs a User account

    It seems like you created a GitHub user to hold this repository (and possibly related ones in the future).

    From https://docs.github.com/en/get-started/learning-about-github/types-of-github-accounts:

    Tip: Personal accounts are intended for humans, but you can create accounts to automate activity on GitHub. This type of account is called a machine user. For example, you can create a machine user account to automate continuous integration (CI) workflows.

    GitHub has a feature designed to group repositories together without being attached to a single user: an Organization. GitHub recommends as best practice to instead have a GitHub user for your person, and then group related community repositories under an organization that you manage. From https://docs.github.com/en/organizations/collaborating-with-groups-in-organizations/about-organizations:

    Your team can collaborate on GitHub by using an organization account. Each person that uses GitHub signs into a user account. Multiple user accounts can collaborate on shared projects by joining the same organization account, which owns the repositories. A subset of these user accounts can be given the role of organization owner, which allows those people to granularly manage access to the organization's resources using sophisticated security and administrative features.

    It is possible to convert an existing GitHub user into an organization here: https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-user-account/managing-user-account-settings/converting-a-user-into-an-organization I recommend doing this with @openglonmetal and then creating or using existing personal accounts for individuals contributing to the project.

    opened by magneticflux- 2
  • add CMakeLists.txt and few tweaks. compiles but get runtime error

    add CMakeLists.txt and few tweaks. compiles but get runtime error

    This is to start the discussion on getting a working version of a build using CMake. This PR has a working build.

    The goal of this is so that I can get up and running to start to contribute to the library. I can't get the xcode project to build so I thought I would go with what I'm familiar with and get a cmake setup going.

    This currently can compile the library from the in tree (or installed) dependencies and build the test_mgl application. There is a runtime error however when the Command buffer is committed in MGLRenderer.m L:3002. I'm hoping to pick up some objective c again (its been about 15 years since I last touched it) so I can debug these issues more easily.

    Current theorising is that I have something wrong with the compilation mode (objective-c vs objective-c++) or are not linking something like a needed framework correctly. I'm hoping I can collaborate with others and figure this out.

    Thanks Dan

    opened by dokipen3d 1
  • licensing

    licensing

    Hi there,

    I reached out to Mike over email, and he suggested I open a ticket here to discuss it with everyone.

    I work with VideoLAN, the non-profit organization that maintains the VLC media player and related software.

    We have come across your great work, and we would be interested in using it in VLC for the Apple platforms that VLC targets. However, VLC being licensed under GPL, using an Apache 2 dependency is complicated and makes the whole resulting solution LGPLv3, which is problematic for us.

    I was wondering whether you would agree to either changing the current license, or offering an additional alternative license through dual licensing. Compatible licenses for us would include MIT, BSD or LGPL2.1 (here's an incomplete sample of our dependencies and their licenses https://github.com/videolan/vlc/blob/master/THANKS).

    Let me know what you think!

    Thanks.

    opened by mfkl 1
  • Why wouldn't you use mesa?

    Why wouldn't you use mesa?

    Mesa already implements a fully abstracted compliant OpenGL 4.6 frontend, it has expended a lot of dev years. Instead of writing all that again you just write a gallium driver and NIR to metal shader layer.

    opened by airlied 5
  • undefined 'SPVC_RESOURCE_TYPE_UNIFORM_CONSTANT' compile error

    undefined 'SPVC_RESOURCE_TYPE_UNIFORM_CONSTANT' compile error

    Hi al, I just merged in the latest uniform changes to give them a go and I'm getting this compile error.... Haven't looked deeper, but thought I'd post in case anyone know whats up.

    [  9%] Building C object CMakeFiles/mgl.dir/MGL/src/fence.c.o
    [  9%] Building C object CMakeFiles/mgl.dir/MGL/src/buffers.c.o
    [  9%] Building C object CMakeFiles/mgl.dir/MGL/src/compute.c.o
    [ 12%] Building C object CMakeFiles/mgl.dir/MGL/src/draw_buffers.c.o
    [ 15%] Building C object CMakeFiles/mgl.dir/MGL/src/error.c.o
    [ 18%] Building C object CMakeFiles/mgl.dir/MGL/src/glm_context.c.o
    [ 21%] Building C object CMakeFiles/mgl.dir/MGL/src/get.c.o
    [ 25%] Building C object CMakeFiles/mgl.dir/MGL/src/framebuffers.c.o
    [ 28%] Building C object CMakeFiles/mgl.dir/MGL/src/glm_params.c.o
    [ 31%] Building C object CMakeFiles/mgl.dir/MGL/src/glm_dispatch.c.o
    [ 34%] Building C object CMakeFiles/mgl.dir/MGL/src/gl_core.c.o
    [ 37%] Building C object CMakeFiles/mgl.dir/MGL/src/hash_table.c.o
    [ 40%] Building C object CMakeFiles/mgl.dir/MGL/src/mgl_funcs_to_be_implemented.c.o
    [ 46%] Building C object CMakeFiles/mgl.dir/MGL/src/program.c.o
    [ 50%] Building C object CMakeFiles/mgl.dir/MGL/src/non_core_unimplemented.c.o
    [ 50%] Building C object CMakeFiles/mgl.dir/MGL/src/pixel_utils.c.o
    [ 53%] Building C object CMakeFiles/mgl.dir/MGL/src/shaders.c.o
    [ 56%] Building C object CMakeFiles/mgl.dir/MGL/src/state.c.o
    [ 62%] Building C object CMakeFiles/mgl.dir/MGL/src/tex_param.c.o
    [ 62%] Building C object CMakeFiles/mgl.dir/MGL/src/rendering.c.o
    [ 65%] Building C object CMakeFiles/mgl.dir/MGL/src/samplers.c.o
    [ 68%] Building C object CMakeFiles/mgl.dir/MGL/src/utils.c.o
    [ 71%] Building C object CMakeFiles/mgl.dir/MGL/src/textures.c.o
    [ 78%] Building C object CMakeFiles/mgl.dir/MGL/src/vertex_buffers.c.o
    [ 78%] Building C object CMakeFiles/mgl.dir/MGL/src/vertex_arrays.c.o
    [ 81%] Building C object CMakeFiles/mgl.dir/MGL/src/MGLRenderer.m.o
    [ 84%] Building C object CMakeFiles/mgl.dir/MGL/src/MGLTextures.m.o
    /Users/danielelliott/Documents/projects/MGL_dokip2/MGL/src/program.c:556:50: error: use of undeclared identifier 'SPVC_RESOURCE_TYPE_UNIFORM_CONSTANT'; did you mean 'SPVC_RESOURCE_TYPE_PUSH_CONSTANT'?
            count = ptr->spirv_resources_list[stage][SPVC_RESOURCE_TYPE_UNIFORM_CONSTANT].count;
                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                                     SPVC_RESOURCE_TYPE_PUSH_CONSTANT
    /Users/danielelliott/Documents/projects/MGL_dokip2/external/SPIRV-Cross/spirv_cross_c.h:223:2: note: 'SPVC_RESOURCE_TYPE_PUSH_CONSTANT' declared here
            SPVC_RESOURCE_TYPE_PUSH_CONSTANT = 9,
            ^
    /Users/danielelliott/Documents/projects/MGL_dokip2/MGL/src/program.c:560:64: error: use of undeclared identifier 'SPVC_RESOURCE_TYPE_UNIFORM_CONSTANT'; did you mean 'SPVC_RESOURCE_TYPE_PUSH_CONSTANT'?
                const char *str = ptr->spirv_resources_list[stage][SPVC_RESOURCE_TYPE_UNIFORM_CONSTANT].list[i].name;
                                                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                                                   SPVC_RESOURCE_TYPE_PUSH_CONSTANT
    /Users/danielelliott/Documents/projects/MGL_dokip2/external/SPIRV-Cross/spirv_cross_c.h:223:2: note: 'SPVC_RESOURCE_TYPE_PUSH_CONSTANT' declared here
            SPVC_RESOURCE_TYPE_PUSH_CONSTANT = 9,
            ^
    /Users/danielelliott/Documents/projects/MGL_dokip2/MGL/src/program.c:566:60: error: use of undeclared identifier 'SPVC_RESOURCE_TYPE_UNIFORM_CONSTANT'; did you mean 'SPVC_RESOURCE_TYPE_PUSH_CONSTANT'?
                    binding = ptr->spirv_resources_list[stage][SPVC_RESOURCE_TYPE_UNIFORM_CONSTANT].list[i].binding;
                                                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                                               SPVC_RESOURCE_TYPE_PUSH_CONSTANT
    /Users/danielelliott/Documents/projects/MGL_dokip2/external/SPIRV-Cross/spirv_cross_c.h:223:2: note: 'SPVC_RESOURCE_TYPE_PUSH_CONSTANT' declared here
            SPVC_RESOURCE_TYPE_PUSH_CONSTANT = 9,
            ^
    3 errors generated.
    make[2]: *** [CMakeFiles/mgl.dir/MGL/src/program.c.o] Error 1
    make[2]: *** Waiting for unfinished jobs....
    /Users/danielelliott/Documents/projects/MGL_dokip2/MGL/src/MGLRenderer.m:379:10: error: use of undeclared identifier 'SPVC_RESOURCE_TYPE_UNIFORM_CONSTANT'; did you mean 'SPVC_RESOURCE_TYPE_PUSH_CONSTANT'?
            {SPVC_RESOURCE_TYPE_UNIFORM_CONSTANT, _UNIFORM_CONSTANT},
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             SPVC_RESOURCE_TYPE_PUSH_CONSTANT
    /Users/danielelliott/Documents/projects/MGL_dokip2/external/SPIRV-Cross/spirv_cross_c.h:223:2: note: 'SPVC_RESOURCE_TYPE_PUSH_CONSTANT' declared here
            SPVC_RESOURCE_TYPE_PUSH_CONSTANT = 9,
            ^
    /Users/danielelliott/Documents/projects/MGL_dokip2/MGL/src/MGLRenderer.m:1400:14: error: use of undeclared identifier 'SPVC_RESOURCE_TYPE_UNIFORM_CONSTANT'; did you mean 'SPVC_RESOURCE_TYPE_PUSH_CONSTANT'?
            case SPVC_RESOURCE_TYPE_UNIFORM_CONSTANT:
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                 SPVC_RESOURCE_TYPE_PUSH_CONSTANT
    /Users/danielelliott/Documents/projects/MGL_dokip2/external/SPIRV-Cross/spirv_cross_c.h:223:2: note: 'SPVC_RESOURCE_TYPE_PUSH_CONSTANT' declared here
            SPVC_RESOURCE_TYPE_PUSH_CONSTANT = 9,
            ^
    /Users/danielelliott/Documents/projects/MGL_dokip2/MGL/src/MGLRenderer.m:1426:13: error: use of undeclared identifier 'SPVC_RESOURCE_TYPE_UNIFORM_CONSTANT'; did you mean 'SPVC_RESOURCE_TYPE_PUSH_CONSTANT'?
           case SPVC_RESOURCE_TYPE_UNIFORM_CONSTANT:
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                SPVC_RESOURCE_TYPE_PUSH_CONSTANT
    /Users/danielelliott/Documents/projects/MGL_dokip2/external/SPIRV-Cross/spirv_cross_c.h:223:2: note: 'SPVC_RESOURCE_TYPE_PUSH_CONSTANT' declared here
            SPVC_RESOURCE_TYPE_PUSH_CONSTANT = 9,
            ^
    3 errors generated.
    make[2]: *** [CMakeFiles/mgl.dir/MGL/src/MGLRenderer.m.o] Error 1
    make[1]: *** [CMakeFiles/mgl.dir/all] Error 2
    make: *** [all] Error 2
    
    opened by dokipen3d 2
  • drawArrays without buffers

    drawArrays without buffers

    hiya, I'm in the middle of trying out my tutorial series with MGL and have hit a couple of issues (one of which I believe is coming in a current uniform pull request by @r58Playz for mglProgramUniformMatrix4fv.

    https://github.com/dokipen3d/OpenGLTutorial/tree/main/src

    The other issue is that I am making a draw call that refers to its vertex locations from a const array in the shader to draw a full screen triangle. I'm hitting an assertion...

    Assertion failed: (mapped_buffers == count), function -[MGLRenderer mapGLBuffersToMTLBufferMap:stage:], file MGLRenderer.m, line 511.

    I haven't had time to dive deep into the library yet but is that something that should be supported?

    opened by dokipen3d 2
  • [not issue] MC on MGL

    [not issue] MC on MGL

    Creating an issue here for the current status of getting Minecraft to run using MGL.

    This checklist may change.

    • [x] inject MGL
    • [x] dock icon
    • [ ] window shown on screen
    • [ ] loading screen
    • [ ] title screen
    • [ ] ingame

    Current stacktrace/error log/etc:

    #
    # A fatal error has been detected by the Java Runtime Environment:
    #
    #  SIGSEGV (0xb) at pc=0x00000001a677a4d0, pid=7124, tid=259
    #
    # JRE version: OpenJDK Runtime Environment Zulu17.34+19-CA (17.0.3+7) (build 17.0.3+7-LTS)
    # Java VM: OpenJDK 64-Bit Server VM Zulu17.34+19-CA (17.0.3+7-LTS, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, bsd-aarch64)
    # Problematic frame:
    # C  [libobjc.A.dylib+0x74d0]  objc_retain+0x10
    #
    # No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
    #
    # If you would like to submit a bug report, please visit:
    #   http://www.azul.com/support/
    # The crash happened outside the Java Virtual Machine in native code.
    # See problematic frame for where to report the bug.
    #
    
    Current thread (0x000000012c009200):  JavaThread "Render thread" [_thread_in_native, id=259, stack(0x000000016af4c000,0x000000016b748000)]
    
    Stack: [0x000000016af4c000,0x000000016b748000],  sp=0x000000016b741600,  free space=8149k
    Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
    C  [libobjc.A.dylib+0x74d0]  objc_retain+0x10
    C  [libMGL.dylib+0x597e38]  -[MGLRenderer newRenderEncoder]+0x11e0
    C  [libMGL.dylib+0x59a15c]  -[MGLRenderer processGLState:]+0x5f0
    C  [libMGL.dylib+0x59d32c]  -[MGLRenderer mtlDrawElements:mode:count:type:indices:]+0x40
    C  [libMGL.dylib+0x59d534]  mtlDrawElements+0x48
    C  [libMGL.dylib+0x87b4dc]  mglDrawElements+0x188
    C  [libMGL.dylib+0x81de4]  glDrawElements+0x4c
    j  org.lwjgl.opengl.GL11C.nglDrawElements(IIIJ)V+0
    j  org.lwjgl.opengl.GL11C.glDrawElements(IIIJ)V+4
    j  org.lwjgl.opengl.GL11.glDrawElements(IIIJ)V+4
    

    Modifications to get to this point:

    • See https://github.com/r58Playz/MGL/tree/mc-mgl-fixes

    How to inject MGL:

    • Use mglmod https://github.com/r58Playz/mglmod
    opened by r58Playz 24
  • being able to compile - almost out of the box.. feedback about my troubles with Xcode

    being able to compile - almost out of the box.. feedback about my troubles with Xcode

    it might be of use for someone also doing a first compile attempt following the steps in Build.md

    When doing so with Xcode.. step by step as written

    in Build.md is something written to compile glm first. That left me confused, i was searching for a folder according to the text to compile before i start. Turns out glm seems to be MGL which is the project target.. so i assumed glm==MGL and hmm i was right, i hope. But first the other 3 issues found..

    #include "spirv.h" was missing. so i dropped that file into the workspace MGL>SPIRV>SPIRV-Cross> folder making a reference for Xcode. Same for ... #include "spirv_cross_c.h"

    and short before the compilation would succeed it failed with missing symbols .. following the error message the symbol for spvtools::val::RayTracingPass(... was missing.. which can only happen when the cpp file is not compiled at that stage. turns out the function spv_result_t RayTracingPass(...) resides in validate_ray_tracing.cpp that had to be dropped manually to workspace MGL>SPIRV>SPIRV-Tools> and of course checkmarked for being part of the MGL target.

    from there it compiled like a charm. Now sipping coffee and testing.. cheers

    opened by designerfuzzi 2
Owner
null
Low Level Graphics Library (LLGL) is a thin abstraction layer for the modern graphics APIs OpenGL, Direct3D, Vulkan, and Metal

Low Level Graphics Library (LLGL) Documentation NOTE: This repository receives bug fixes only, but no major updates. Pull requests may still be accept

Lukas Hermanns 1.5k Nov 28, 2022
OpenGL 4.6 on Metal

MGL OpenGL 4.6 on Metal This is a start for porting OpenGL 4.6 on top of Metal, most of it is functional and has been tested. The tests are functional

null 539 Nov 27, 2022
A multi-platform library for OpenGL, OpenGL ES, Vulkan, window and input

GLFW Introduction GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan application development. It provides a simple, platf

GLFW 9.8k Nov 19, 2022
A legacy OpenGL simulator for OpenGL 4.4, written in C++.

the-ancient-tri A legacy OpenGL simulator for OpenGL 4.4, written in C++. Why? My Uni forces us to use legacy OpenGL (eww!), and I didn't want to lear

Mohammad Issawi 4 Feb 10, 2022
🎮 C Bindings/Wrappers for Apple's METAL framework

Apple's Metal for C C Wrapper for Apple's METAL framework. This library is C bindings of Metal API (MetalGL). Since OpenGL is deprecated, this library

Recep Aslantas 115 Nov 29, 2022
A header-only C-like shading language compiler that writes Metal, HLSL, GLSL

GPUC A generic shading language compiler that writes metal, HLSL, and GLSL GPUC is a work in progress, not ready for prime time. The primary motivatio

Garett Bass 61 Oct 18, 2022
Antialiased 2D vector drawing library on top of OpenGL for UI and visualizations.

This project is not actively maintained. NanoVG NanoVG is small antialiased vector graphics rendering library for OpenGL. It has lean API modeled afte

Mikko Mononen 4.5k Nov 22, 2022
Epoxy is a library for handling OpenGL function pointer management for you

Epoxy is a library for handling OpenGL function pointer management for you. It hides the complexity of dlopen(), dlsym(), glXGetProcAddress(), eglGetP

Eric Anholt 574 Nov 24, 2022
3D engine from scratch (without OpenGL or any other 3D graphics library)

Simple 3d engine based on SFML library. I tried to make this engine powerful and easy to understand.

Vectozavr 62 Nov 16, 2022
RGL - 3D visualization device system for R using OpenGL

RGL - 3D visualization device system for R using OpenGL INTRODUCTION The RGL package is a visualization device system for R, using OpenGL or WebGL as

null 66 Oct 3, 2022
OpenGL Demo: Simulating Ocean Waves with FFT

OceanFFT Realistic ocean wave simulation, primarily based on J. Tessendorf's paper, using OpenGL compute shaders. Checkout the demo video here. In the

Achal Pandey 67 Nov 21, 2022
OBS Linux Vulkan/OpenGL game capture

OBS Linux Vulkan/OpenGL game capture OBS plugin for Vulkan/OpenGL game capture on Linux. Requires OBS with EGL support (currently unreleased, you need

David Rosca 266 Nov 19, 2022
NodeEditor basiced on Qt and OpenGL/CV

Vapour 基于Qt的轻量级的节点式几何建模工具与shader材质生成工具 可能加入图像处理(合成)的功能 日志: 2021-5-17: 完成背景绘制,右键菜单,节点连线,节点删除,初步拓扑排序 (细节)连线位于节点层级之下,使用lambda处理右键菜单slot,节点创建生成在鼠标位置处 2021

Cuimi 15 Aug 11, 2022
C Wavefront OBJ loader for OpenGL

OBJ GL Loader v2 Quite fast .OBJ loader written in C How to use it Put objgl2.c and objgl2.h files in Your project and include them. To put it simply:

null 9 Oct 14, 2022
Orbit is a multiplatform-focus graphical engine build on top of OpenGl, ImGui

Orbit Engine Orbit is a multiplatform-focus graphical engine build on top of OpenGl, ImGui and more... The development of the engine is documented via

Madsycode 11 Jul 3, 2021
Axel Gneiting 1.4k Nov 20, 2022
A 2d Graphing Calculator using OpenGL

glGraph A 2d Graphing Calculator using Modern OpenGL Demo glGraph.mp4 Information This has only been tested on Fedora 34, it should work on other OS's

Nathan Medros 16 Nov 26, 2022
Tetris written with C++ and OpenGL.

Tetrec This is yet another Tetris game, which is in 3D, written using C++ and OpenGL 2.1, aiming at being lightweight towards not-so-beefy computers (

Lê Duy Quang 14 Jan 17, 2022
OpenGL made easy.

SmartGL OpenGL made easy. Demo video: https://youtu.be/zDuNxg4LJ18 (sorry for low-quality recording) For an example of how my engine is used, please r

null 18 Nov 11, 2022