Okay thanks, I'll take a close look at it. Hope you're both right. If it gets inlined, Isaiah's solution will be a lot nicer after all !
2014-04-02 14:59 GMT+02:00 Mike Innes <[email protected]>: > Ok, you're right about the @eval include - I forgot that include doesn't > remember its module like eval. > > But again, check the llvm output or run a benchmark. The lowered code > doesn't tell you all that much, because the ccall hasn't been compiled at > that point. > > > On 2 April 2014 13:51, Simon Danisch <[email protected]> wrote: > >> But without the eval, the include will be evaluated in the module, from >> where you call "load". >> Which means, the functions don't get exported by the OpenGL module. >> So I need one @eval to evaluate things inside the OpenGL module, and the >> other is for inlining the function ptr. >> (As far as I understand the code... At least with the code I posted >> everything seems fine) >> Isaiah solution emits this code, which should be slower: >> >> >> >> >> >> >> >> >> >> >> >> >> >> 123 >> >> >> >> $(Expr(:lambda, {:name}, {{},{{:name,Uint16,0}},{}}, :(begin #penGL.jl, >> line 6: >> >> >> >> >> return top(ccall)($(Expr(:call1, :getFuncPointer, >> "glGetString"))::Ptr{None},Ptr{Int8},(Ptr{Int8},),top(box)(Ptr{Int8},top(box)(Uint64,top(zext_int)(Uint64,name::Uint16))::Uint64)::Ptr{Int8},name::Uint16)::Ptr{Int8} >> >> >> >> >> end::Ptr{Int8}))) >> >> >> >> 2014-04-02 14:38 GMT+02:00 Mike Innes <[email protected]>: >> >> Ok, if you're using an include then you don't need those @evals. Your @eval >>> include("gl4_3.jl") is definitely redundant, since include happens at >>> run time anyway. >>> >>> You should benchmark it yourself to be sure (or perhaps check the llvm >>> output) but I'm pretty sure Isaiah is right here - you can also get rid of >>> the @eval in gl4_3.jl without any performance penalty, and that >>> definitely cleans things up. >>> >>> In which case you end up with: >>> >>> #OpenGL.jl: >>> >>> >>> >>> >>> function load(getProc::Function) >>> >>> >>> >>> >>> global const getProcAddress = getProc >>> >>> >>> >>> >>> include("gl4_3.jl") >>> end >>> >>> #gl4_3.jl >>> >>> >>> >>> >>> glGetString(name::Uint16) = ccall(getProcAddress("glGetString"), >>> Ptr{Cchar}, (Uint16,), name) >>> >>> >>> >>> >>> export glGetString >>> >>> >>> On Wednesday, 2 April 2014 13:15:45 UTC+1, Simon Danisch wrote: >>>> >>>> Hm... just the pointer to getProcAddress will be inlined, but not the >>>> pointer to glGetString, right? >>>> >>>> with Mike's solution the lowered code looks like I want to have it: >>>> >>>> $(Expr(:lambda, {:name}, {{},{{:name,Uint16,0}},{}}, :(begin # >>>> /home/s/load.jl, line 2: >>>> >>>> >>>> >>>> >>>> return top(ccall)(Ptr{Void} >>>> @0x00007f402e6dadc0,Ptr{Int8},(Uint16,),name::Uint16,0)::Ptr{Int8} >>>> >>>> >>>> >>>> >>>> end::Ptr{Int8}))) >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> I've one more question, though! >>>> >>>> >>>> >>>> >>>> I use this code to include the definitions from another file, but this >>>> doesn't look very elegant... >>>> >>>> >>>> >>>> >>>> Are there better options? >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> #OpenGL.jl: >>>> function load(getProc::Function) >>>> >>>> >>>> >>>> >>>> global const getProcAddress = getProc >>>> >>>> >>>> >>>> >>>> @eval include("gl4_3.jl") >>>> >>>> >>>> >>>> >>>> >>>> end >>>> >>>> #gl4_3.jl >>>> @eval begin >>>> >>>> >>>> >>>> >>>> glGetString(name::Uint16) = ccall($(getProcAddress("glGetString")), >>>> Ptr{Cchar}, (Uint16,), name) >>>> >>>> >>>> >>>> >>>> export glGetString >>>> end >>>> >>>> >>>> >>>> Thank you very much! >>>> >>>> Am Dienstag, 1. April 2014 14:30:12 UTC+2 schrieb Simon Danisch: >>>>> >>>>> Hi, >>>>> I'm working on the OpenGL package and I want to make it finally usable >>>>> in a nice and clean way on all platforms. >>>>> The problem is, that one needs pointer for the GL functions, which you >>>>> can only get, after initialization of the OpenGL context. >>>>> But initializing the context and creating a window shouldn't be part >>>>> of the OpenGL package. >>>>> >>>>> So I tried two different approaches, which both seem to have their >>>>> downsides: >>>>> >>>>> 1. >>>>> Initialize OpenGL context when including the OpenGL package >>>>> This is bad, because this makes the OpenGL package dependent on some >>>>> third party OpenGL context creation library. >>>>> >>>>> 2. >>>>> Load the functions later with a loading Function. >>>>> Bad, because the function definitions are not visible for any other >>>>> module, that relies on the OpenGL package. >>>>> >>>>> My ideal solution would be, to evaluate a macro when the function is >>>>> called and not when the module is included. >>>>> Like this, I can define all the OpenGL functions already in the OpenGL >>>>> module, and when you call them the first time, >>>>> the right function ptr gets inserted into the ccall, or an error is >>>>> raised, when OpenGL context is not initialized. >>>>> >>>>> this could look like this: >>>>> >>>>> >>>>> module OpenGL >>>>> >>>>> macro getFuncPointer(name::ASCIIString) >>>>> return getProcAddress(name) >>>>> end >>>>> >>>>> glGetString(name::GLenum) = ccall(@getFuncPointer("glGetString"), ...., >>>>> ...., name) >>>>> export glGetString >>>>> end >>>>> >>>>> >>>>> using OpenGL >>>>> ...create OpenGL context >>>>> #define getProcAddress >>>>> global const getProcAddress = glutGetProcAddress # If using GLUT for GL >>>>> context creation >>>>> #call gl Functions >>>>> glGetString(GL_VERSION) >>>>> >>>>> Any ideas how to do this in a clean way? >>>>> >>>>> >>>>> Cheers, >>>>> >>>>> Simon >>>>> >>>> >> >
