OpegnGL on OSX PPC

Started by cavva, May 05, 2009, 02:53:29 PM

Previous topic - Next topic

cavva

Reading the comment on the opengl demo

(http://www.newlisp.org/syntax.cgi?downloads/OpenGL/opengl-demo-lsp.txt">http://www.newlisp.org/syntax.cgi?downl ... mo-lsp.txt">http://www.newlisp.org/syntax.cgi?downloads/OpenGL/opengl-demo-lsp.txt)



i've read that on ppc i'm not able to see the drawing, and that's true, but could someone explain me why?



It's because float and double are passed correctly only on x86 as i read here?

http://www.newlisp.org/CodePatterns.html#extending">http://www.newlisp.org/CodePatterns.html#extending



Is there a work around?

Lutz

#1
newLISP assumes that all parameters are passed on the stack when calling into an imported shared library regardless of their type. The OpenGL library as compiled for the PPC passes floats via registers.



The workaround would be to compile a bridge library into which newLISP can call.

cavva

#2
thanks lutz,



but how did you know that? is it documented somewhere ?



just curious... in the case i'll encouter a similar problem with others lib

TedWalther

#3
Actually, I saw on the webpage that trick for doing inline assembly in newlisp.



Lutz, what if you made that more formalized?  An officially supported thing instead of a hack?  Then we could directly access registers, etc.  One thing that held me back from lisp a long time ago was that it seemed too abstract, I didn't see how it could be used to connect directly with the machine.  newLisp is the first lisp where I now see that as a possibility.



Now, admittedly, assembly code in newlisp wouldn't be portable.  But if an architecture string was put into the binary, you could do conditional assembly based on the platform.
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.

Lutz

#4
cavva:



http://www.agner.org/optimize/calling_conventions.pdf">http://www.agner.org/optimize/calling_conventions.pdf



there is also some general info on this topic on Wikipedia



TedWalther:



this would probably be best written in newLISP, e.g.:


(define-macro (assemble callpattern body)
   ...
   ...
)

(assemble (myadd x y) [text]
mov acc, x
add acc, y
ret acc
[/text])


After translating 'body' into the platform assembly language, 'exec' could be used to shell out to the OS and assemble the binary.



This: http://www.newlisp.org/index.cgi?page=Embedded_Binary">http://www.newlisp.org/index.cgi?page=Embedded_Binary



could then be used to configure the function as a callable newLISP function.



The same could be done for 'C'. Perhaps that would even be the preferred way to go. In either case you also would have to know the binary object format and calling conventions of the platform OS.

TedWalther

#5
Quote from: "Lutz"cavva:



http://www.agner.org/optimize/calling_conventions.pdf">http://www.agner.org/optimize/calling_conventions.pdf



there is also some general info on this topic on Wikipedia



TedWalther:



this would probably be best written in newLISP, e.g.:


(define-macro (assemble callpattern body)
   ...
   ...
)

(assemble (myadd x y) [text]
mov acc, x
add acc, y
ret acc
[/text])


After translating 'body' into the platform assembly language, 'exec' could be used to shell out to the OS and assemble the binary.



This: http://www.newlisp.org/index.cgi?page=Embedded_Binary">http://www.newlisp.org/index.cgi?page=Embedded_Binary



could then be used to configure the function as a callable newLISP function.



The same could be done for 'C'. Perhaps that would even be the preferred way to go. In either case you also would have to know the binary object format and calling conventions of the platform OS.


That is probably the best we can do for now.  That looks a lot simpler than my concept of separate assembly primitives for each platform and architecture.  And yes, the interaction with the outer environment changes with each environment.  Yuck.  I was thinking of a directive like (xorlw r32 r8) returning a packed structure, then (asm ...) generating the raw code.  And a separate (cdecl ..) which would wrap the assembly code in all the function all stuff relevant to interacting with C, so you could really do straight assembly with no overhead using the (asm directive.



Too much work for now; we'd probably need a government grant to do this.  Because really, asm isn't that interesting without a simple and good model for shuttling data out of the registers and into newlisp.
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.

cavva

#6
ok, i must admit that i don't have understood the 100% of the replies;



i have little knowledge in C and newlisp, two thing that i'm start using because i want to learn more about programming (right now i'm a java programmer)



So, from the start, what a bridge would look like?

In my mind it would simply a "wrapper", so i've written a little c function to test if i was wrong

// testlib.c
//
// compiled on OSX with: gcc testlib.c -bundle -o testlib.so -framework OpenGL

#include stdio.h

#import OpenGL/OpenGL.h
#import OpenGL/gl.h
#import OpenGL/glu.h


int testVertex3d(double x, double y, double z)
{
glVertex3d( x, y, z);
return 1;
}

int testDouble(double x)
{
printf("the number: %fn", x);
return 1;
}
   
/* eof */

(in the include i've removed the "<>", problems with phpbb i think...)

and it doesn't work, probably i'm wrong...

i've also made some test in the area "passing double values" with the tstDouble function, and got strange results... first, the lisp program i'm using:



(set 'TEST_LIB "/Users/carlo/Desktop/test new lisp C/testlib.so")

(import TEST_LIB "testDouble")


(set 'GLUT_LIB "/System/Library/Frameworks/GLUT.Framework/GLUT")

(import GLUT_LIB "glutInit")
(import GLUT_LIB "glutDisplayFunc")
(import GLUT_LIB "glutCreateWindow")
(import GLUT_LIB "glutMainLoop")
(import GLUT_LIB "glutSwapBuffers")


(set 'argc 0)
(set 'argv1 "")
(set 'argv (pack "lu" argv1))

(define (draw)
(testDouble 1.5)
(print "test")
)

(glutInit (address argc) (address argv))
(set 'id (glutCreateWindow "Test OpenGL"))
(glutDisplayFunc (callback 0 'draw))

(testDouble 1.5)
(glutMainLoop)


calling testDouble before glutMainLoop output the correct value, inside 'draw it will output "the number: 16.000000"



have you a little patience for exlain me what's heppening here?

Lutz

#7
Here is an example how wrap a library for the PPC CPU on older Mac OS X systems, where the normal newLISP FFI does not work because of non cdecl calling conventions:



http://www.newlisp.org/code/wrapper.c">http://www.newlisp.org/code/wrapper.c

cavva

#8
Quote from: "Lutz"Here is an example how wrap a library for the PPC CPU on older Mac OS X systems, where the normal newLISP FFI does not work because of non cdecl calling conventions:



http://www.newlisp.org/code/wrapper.c">http://www.newlisp.org/code/wrapper.c


thanks a lot