Skip to content
This repository was archived by the owner on Mar 19, 2025. It is now read-only.

Commit 24e2ebd

Browse files
committed
Add some xs for gpgpu and _o GL routines
Still need to figure out how to merged this into OpenGL::Modern in a clean way. This appears to include the main functions of concern.
1 parent c146014 commit 24e2ebd

File tree

2 files changed

+1063
-0
lines changed

2 files changed

+1063
-0
lines changed

gpgpu_gl.xs

+246
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
/* Last saved: Mon 07 Aug 2017 04:53:34 PM */
2+
3+
/* Copyright (c) 1998 Kenneth Albanowski. All rights reserved.
4+
* Copyright (c) 2007 Bob Free. All rights reserved.
5+
* Copyright (c) 2009 Chris Marshall. All rights reserved.
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the same terms as Perl itself.
8+
*/
9+
10+
#include <stdio.h>
11+
12+
#include "pgopogl.h"
13+
14+
#ifdef HAVE_GL
15+
#include "gl_util.h"
16+
17+
/* Note: this is caching procs once for all contexts */
18+
/* !!! This should instead cache per context */
19+
#if defined(_WIN32) || (defined(__CYGWIN__) && defined(HAVE_W32API))
20+
#define loadProc(proc,name) \
21+
{ \
22+
if (!proc) \
23+
{ \
24+
proc = (void *)wglGetProcAddress(name); \
25+
if (!proc) croak(name " is not supported by this renderer"); \
26+
} \
27+
}
28+
#define testProc(proc,name) ((proc) ? 1 : !!(proc = (void *)wglGetProcAddress(name)))
29+
#else /* not using WGL */
30+
#define loadProc(proc,name)
31+
#define testProc(proc,name) 1
32+
#endif /* not defined _WIN32, __CYGWIN__, and HAVE_W32API */
33+
#endif /* defined HAVE_GL */
34+
35+
36+
/********************/
37+
/* GPGPU Utils */
38+
/********************/
39+
40+
GLint FBO_MAX = -1;
41+
42+
/* Get max GPGPU data size */
43+
int gpgpu_size(void)
44+
{
45+
#if defined(GL_ARB_texture_rectangle) && defined(GL_ARB_texture_float) && \
46+
defined(GL_ARB_fragment_program) && defined(GL_EXT_framebuffer_object)
47+
if (FBO_MAX == -1)
48+
{
49+
if (testProc(glProgramStringARB,"glProgramStringARB") &&
50+
testProc(glGenProgramsARB,"glGenProgramsARB") &&
51+
testProc(glBindProgramARB,"glBindProgramARB") &&
52+
testProc(glIsProgramARB,"glIsProgramARB") &&
53+
testProc(glProgramLocalParameter4fvARB,"glProgramLocalParameter4fvARB") &&
54+
testProc(glDeleteProgramsARB,"glDeleteProgramsARB") &&
55+
testProc(glGenFramebuffersEXT,"glGenFramebuffersEXT") &&
56+
testProc(glGenRenderbuffersEXT,"glGenRenderbuffersEXT") &&
57+
testProc(glBindFramebufferEXT,"glBindFramebufferEXT") &&
58+
testProc(glFramebufferTexture2DEXT,"glFramebufferTexture2DEXT") &&
59+
testProc(glBindRenderbufferEXT,"glBindRenderbufferEXT") &&
60+
testProc(glRenderbufferStorageEXT,"glRenderbufferStorageEXT") &&
61+
testProc(glFramebufferRenderbufferEXT,"glFramebufferRenderbufferEXT") &&
62+
testProc(glCheckFramebufferStatusEXT,"glCheckFramebufferStatusEXT") &&
63+
testProc(glDeleteRenderbuffersEXT,"glDeleteRenderbuffersEXT") &&
64+
testProc(glDeleteFramebuffersEXT,"glDeleteFramebuffersEXT"))
65+
{
66+
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT,&FBO_MAX);
67+
}
68+
else
69+
{
70+
FBO_MAX = 0;
71+
}
72+
}
73+
return(FBO_MAX);
74+
#else
75+
return(0);
76+
#endif
77+
}
78+
79+
/* Get max square array width for a given GPGPU data size */
80+
int gpgpu_width(int len)
81+
{
82+
int max = gpgpu_size();
83+
if (max && len && !(len%3))
84+
{
85+
int count = len / 3;
86+
int w = (int)sqrt(count);
87+
88+
while ((w <= count) && (w <= max))
89+
{
90+
if (!(count%w)) return(w);
91+
w++;
92+
}
93+
}
94+
return(0);
95+
}
96+
97+
#ifdef GL_ARB_fragment_program
98+
static char affine_prog[] =
99+
"!!ARBfp1.0\n"
100+
"PARAM affine[4] = {program.local[0..3]};\n"
101+
"TEMP decal;\n"
102+
"TEX decal, fragment.texcoord[0], texture[0], RECT;\n"
103+
"MOV decal.w, 1.0;\n"
104+
"DP4 result.color.x, decal, affine[0];\n"
105+
"DP4 result.color.y, decal, affine[1];\n"
106+
"DP4 result.color.z, decal, affine[2];\n"
107+
"END\n";
108+
109+
/* Enable affine shader program */
110+
void enable_affine(oga_struct * oga)
111+
{
112+
if (!oga) return;
113+
if (!oga->affine_handle)
114+
{
115+
/* Load shader program */
116+
glGenProgramsARB(1,&oga->affine_handle);
117+
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB,oga->affine_handle);
118+
glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB,
119+
GL_PROGRAM_FORMAT_ASCII_ARB, strlen(affine_prog),affine_prog);
120+
121+
/* Validate shader program */
122+
if (!glIsProgramARB(oga->affine_handle))
123+
{
124+
GLint errorPos;
125+
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB,&errorPos);
126+
if (errorPos < 0) errorPos = strlen(affine_prog);
127+
croak("Affine fragment program error\n%s",&affine_prog[errorPos]);
128+
}
129+
}
130+
glEnable(GL_FRAGMENT_PROGRAM_ARB);
131+
}
132+
133+
/* Disable affine shader program */
134+
void disable_affine(oga_struct * oga)
135+
{
136+
if (!oga) return;
137+
if (oga->affine_handle) glDisable(GL_FRAGMENT_PROGRAM_ARB);
138+
}
139+
#endif
140+
141+
#ifdef GL_EXT_framebuffer_object
142+
/* Unbind an FBO to an OGA */
143+
void release_fbo(oga_struct * oga)
144+
{
145+
if (oga->fbo_handle)
146+
{
147+
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
148+
glDeleteFramebuffersEXT(1,&oga->fbo_handle);
149+
}
150+
151+
if (oga->tex_handle[0] || oga->tex_handle[1])
152+
{
153+
glBindTexture(oga->target,0);
154+
if (oga->tex_handle[0]) glDeleteTextures(1,&oga->tex_handle[0]);
155+
if (oga->tex_handle[1]) glDeleteTextures(1,&oga->tex_handle[1]);
156+
}
157+
}
158+
159+
/* Enable an FBO bound to an OGA */
160+
void enable_fbo(oga_struct * oga, int w, int h, GLuint target,
161+
GLuint pixel_type, GLuint pixel_format, GLuint element_size)
162+
{
163+
if (!oga) return;
164+
165+
if ((oga->fbo_w != w) || (oga->fbo_h != h) ||
166+
(oga->target != target) ||
167+
(oga->pixel_type != pixel_type) ||
168+
(oga->pixel_format != pixel_format) ||
169+
(oga->element_size != element_size)) release_fbo(oga);
170+
171+
if (!oga->fbo_handle)
172+
{
173+
GLenum status;
174+
175+
/* Save params */
176+
oga->fbo_w = w;
177+
oga->fbo_h = h;
178+
oga->target = target;
179+
oga->pixel_type = pixel_type;
180+
oga->pixel_format = pixel_format;
181+
oga->element_size = element_size;
182+
183+
/* Set up FBO */
184+
glGenTextures(2,oga->tex_handle);
185+
glGenFramebuffersEXT(1,&oga->fbo_handle);
186+
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,oga->fbo_handle);
187+
188+
glViewport(0,0,w,h);
189+
glMatrixMode(GL_PROJECTION);
190+
glLoadIdentity();
191+
gluOrtho2D(0,w,0,h);
192+
glMatrixMode(GL_MODELVIEW);
193+
glLoadIdentity();
194+
195+
glBindTexture(target,oga->tex_handle[1]);
196+
glTexParameteri(target,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
197+
glTexParameteri(target,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
198+
glTexParameteri(target,GL_TEXTURE_WRAP_S,GL_CLAMP);
199+
glTexParameteri(target,GL_TEXTURE_WRAP_T,GL_CLAMP);
200+
201+
glTexImage2D(target,0,pixel_type,w,h,0,
202+
pixel_format,element_size,0);
203+
204+
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
205+
GL_COLOR_ATTACHMENT0_EXT,target,oga->tex_handle[1],0);
206+
207+
status = glCheckFramebufferStatusEXT(GL_RENDERBUFFER_EXT);
208+
if (status) croak("enable_fbo status: %04X\n",status);
209+
}
210+
else
211+
{
212+
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,oga->fbo_handle);
213+
}
214+
215+
/* Load data */
216+
glBindTexture(target,oga->tex_handle[0]);
217+
glTexImage2D(target,0,pixel_type,w,h,0,
218+
pixel_format,element_size,oga->data);
219+
220+
glEnable(target);
221+
//glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
222+
glBindTexture(target,oga->tex_handle[0]);
223+
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);
224+
}
225+
226+
/* Disable an FBO bound to an OGA */
227+
void disable_fbo(oga_struct * oga)
228+
{
229+
if (!oga) return;
230+
if (oga->fbo_handle)
231+
{
232+
glDisable(oga->target);
233+
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
234+
}
235+
}
236+
#endif
237+
238+
MODULE = OpenGL::Array PACKAGE = OpenGL::Array
239+
240+
#//# glpHasGPGPU();
241+
int
242+
glpHasGPGPU()
243+
CODE:
244+
RETVAL = gpgpu_size();
245+
OUTPUT:
246+
RETVAL

0 commit comments

Comments
 (0)