merge of glsl-compiler-1 branch

This commit is contained in:
Brian 2007-03-26 10:13:02 -06:00
commit d619cceea4
311 changed files with 31449 additions and 49563 deletions

View file

@ -92,6 +92,7 @@ linux-alpha-static \
linux-debug \
linux-directfb \
linux-dri \
linux-dri-debug \
linux-dri-x86 \
linux-dri-x86-64 \
linux-dri-ppc \

View file

@ -67,4 +67,4 @@ WINDOW_SYSTEM=dri
# gamma are missing because they have not been converted to use the new
# interface.
DRI_DIRS = i810 i915tex i915 i965 mach64 mga r128 r200 r300 radeon s3v \
savage sis tdfx trident unichrome ffb
savage sis tdfx trident unichrome ffb nouveau

View file

@ -64,6 +64,7 @@ a:visited {
<ul>
<li><a href="http://sourceforge.net/projects/mesa3d" target="_parent">SourceForge homepage</a>
<li><a href="repository.html" target="MainFrame">Source Code Repository</a>
<li><a href="shading.html" target="MainFrame">Shading Language</a>
<li><a href="utilities.html" target="MainFrame">Utilities</a>
<li><a href="helpwanted.html" target="MainFrame">Help Wanted</a>
<li><a href="devinfo.html" target="MainFrame">Development Notes</a>

View file

@ -11,8 +11,7 @@
<H1>Mesa 6.5.3 Release Notes / (in progress)</H1>
<p>
Mesa 6.5.3 is a 6.5 follow-on development release mostly consisting of
bug fixes</a>.
Mesa 6.5.3 is a 6.5 follow-on development release with many internal changes.
</p>
@ -24,8 +23,14 @@ TBD
<h2>New features</h2>
<ul>
<li>OpenGL 2.0 support.
<li>Entirely new Shading Language code generator.
<li>Much faster software execution of vertex, fragment shaders.
<li>New vertex buffer object infrastructure (replaces old array_cache code).
<li>Updated glext.h file (version 39)
<li>Updated glxext.h file (version 18)
<li>GL_MAX_DRAWBUFFERS is now 4 (software rendering) so
"multiple render targets" are really supported.
</ul>
<h2>Bug fixes</h2>
@ -33,6 +38,7 @@ TBD
<li>Fog was errantly applied when a fragment shader was enabled (bug 9346)
<li>glPush/PopClientAttrib didn't handle VBO bindings correctly (bug 9445)
<li>With 32-bit Z buffer, the fragment Z of lines and points was sometimes wrong.
<li>GL_POST_CONVOLUTION_ALPHA_BIAS/SCALE was broken.
<li>1D convolution state could effect 2D image transfers
</ul>
@ -40,6 +46,7 @@ TBD
<h2>Internal code changes</h2>
<ul>
<li>Massive changes to the Shading Language compiler.
<li>The _MaintainTnlProgram, _MaintainTexEnvProgram, _TexEnvProgram and
_TnlProgram fields have been moved.
<li>The ctx->FragmentProgram._Active field has been removed.
@ -53,7 +60,6 @@ fixed-function program.
<h2>To Do (someday) items</h2>
<ul>
<li>Switch to freeglut
<li>Increase MAX_DRAWBUFFERS
<li>Fix linux-glide target/driver.
<li>Improved lambda and derivative calculation for frag progs.
</ul>
@ -65,8 +71,8 @@ fixed-function program.
Driver Status
---------------------- ----------------------
DRI drivers varies with the driver
XMesa/GLX (on Xlib) implements OpenGL 1.5
OSMesa (off-screen) implements OpenGL 1.5
XMesa/GLX (on Xlib) implements OpenGL 2.0
OSMesa (off-screen) implements OpenGL 2.0
Glide (3dfx Voodoo1/2) implements OpenGL 1.3
SVGA implements OpenGL 1.3
Wind River UGL implements OpenGL 1.3

286
docs/shading.html Normal file
View file

@ -0,0 +1,286 @@
<HTML>
<TITLE>Shading Language Support</TITLE>
<link rel="stylesheet" type="text/css" href="mesa.css"></head>
<BODY>
<H1>Shading Language Support</H1>
<p>
This page describes the features and status of Mesa's support for the
<a href="http://opengl.org/documentation/glsl/" target="_parent">
OpenGL Shading Language</a>.
</p>
<p>
Last updated on 17 Feb 2007.
</p>
<p>
Contents
</p>
<ul>
<li><a href="#unsup">Unsupported Features</a>
<li><a href="#notes">Implementation Notes</a>
<li><a href="#hints">Programming Hints</a>
<li><a href="#standalone">Stand-alone Compiler</a>
<li><a href="#implementation">Compiler Implementation</a>
</ul>
<a name="unsup">
<h2>Unsupported Features</h2>
<p>
The following features of the shading language are not yet supported
in Mesa:
</p>
<ul>
<li>Dereferencing arrays with non-constant indexes
<li>User-defined structs
<li>Linking of multiple shaders is not supported
<li>Integer operations are not fully implemented (most are implemented
as floating point).
<li>gl_ClipVertex
</ul>
<p>
All other major features of the shading language should function.
</p>
<a name="notes">
<h2>Implementation Notes</h2>
<ul>
<li>Shading language programs are compiled into low-level programs
very similar to those of GL_ARB_vertex/fragment_program.
<li>All vector types (vec2, vec3, vec4, bvec2, etc) currently occupy full
float[4] registers.
<li>Float constants and variables are packed so that up to four floats
can occupy one program parameter/register.
<li>All function calls are inlined.
<li>Shaders which use too many registers will not compile.
<li>The quality of generated code is pretty good, register usage is fair.
<li>Shader error detection and reporting of errors (InfoLog) is not
very good yet.
<li>There are known memory leaks in the compiler.
</ul>
<p>
These issues will be addressed/resolved in the future.
</p>
<a name="hints">
<h2>Programming Hints</h2>
<ul>
<li>Declare <em>in</em> function parameters as <em>const</em> whenever possible.
This improves the efficiency of function inlining.
</li>
<br>
<li>To reduce register usage, declare variables within smaller scopes.
For example, the following code:
<pre>
void main()
{
vec4 a1, a2, b1, b2;
gl_Position = expression using a1, a2.
gl_Color = expression using b1, b2;
}
</pre>
Can be rewritten as follows to use half as many registers:
<pre>
void main()
{
{
vec4 a1, a2;
gl_Position = expression using a1, a2.
}
{
vec4 b1, b2;
gl_Color = expression using b1, b2;
}
}
</pre>
Alternately, rather than using several float variables, use
a vec4 instead. Use swizzling and writemasks to access the
components of the vec4 as floats.
</li>
<br>
<li>Use the built-in library functions whenever possible.
For example, instead of writing this:
<pre>
float x = 1.0 / sqrt(y);
</pre>
Write this:
<pre>
float x = inversesqrt(y);
</pre>
</ul>
<a name="standalone">
<h2>Stand-alone Compiler</h2>
<p>
A unique stand-alone GLSL compiler driver has been added to Mesa.
<p>
<p>
The stand-alone compiler (like a conventional command-line compiler)
is a tool that accepts Shading Language programs and emits low-level
GPU programs.
</p>
<p>
This tool is useful for:
<p>
<ul>
<li>Inspecting GPU code to gain insight into compilation
<li>Generating initial GPU code for subsequent hand-tuning
<li>Debugging the GLSL compiler itself
</ul>
<p>
To build the glslcompiler program (this will be improved someday):
</p>
<pre>
cd src/mesa
make libmesa.a
cd drivers/glslcompiler
make
</pre>
<p>
Here's an example of using the compiler to compile a vertex shader and
emit GL_ARB_vertex_program-style instructions:
</p>
<pre>
glslcompiler --arb --linenumbers --vs vertshader.txt
</pre>
<p>
The output may look similar to this:
</p>
<pre>
!!ARBvp1.0
0: MOV result.texcoord[0], vertex.texcoord[0];
1: DP4 temp0.x, state.matrix.mvp.row[0], vertex.position;
2: DP4 temp0.y, state.matrix.mvp.row[1], vertex.position;
3: DP4 temp0.z, state.matrix.mvp.row[2], vertex.position;
4: DP4 temp0.w, state.matrix.mvp.row[3], vertex.position;
5: MOV result.position, temp0;
6: END
</pre>
<p>
Note that some shading language constructs (such as uniform and varying
variables) aren't expressible in ARB or NV-style programs.
Therefore, the resulting output is not always legal by definition of
those program languages.
</p>
<p>
Also note that this compiler driver is still under development.
Over time, the correctness of the GPU programs, with respect to the ARB
and NV languagues, should improve.
</p>
<a name="implementation">
<h2>Compiler Implementation</h2>
<p>
The source code for Mesa's shading language compiler is in the
<code>src/mesa/shader/slang/</code> directory.
</p>
<p>
The compiler follows a fairly standard design and basically works as follows:
</p>
<ul>
<li>The input string is tokenized (see grammar.c) and parsed
(see slang_compiler_*.c) to produce an Abstract Syntax Tree (AST).
The nodes in this tree are slang_operation structures
(see slang_compile_operation.h).
The nodes are decorated with symbol table, scoping and datatype information.
<li>The AST is converted into an Intermediate representation (IR) tree
(see the slang_codegen.c file).
The IR nodes represent basic GPU instructions, like add, dot product,
move, etc.
The IR tree is mostly a binary tree, but a few nodes have three or four
children.
In principle, the IR tree could be executed by doing an in-order traversal.
<li>The IR tree is traversed in-order to emit code (see slang_emit.c).
This is also when registers are allocated to store variables and temps.
<li>In the future, a pattern-matching code generator-generator may be
used for code generation.
Programs such as L-BURG (Bottom-Up Rewrite Generator) and Twig look for
patterns in IR trees, compute weights for subtrees and use the weights
to select the best instructions to represent the sub-tree.
<li>The emitted GPU instructions (see prog_instruction.h) are stored in a
gl_program object (see mtypes.h).
<li>When a fragment shader and vertex shader are linked (see slang_link.c)
the varying vars are matched up, uniforms are merged, and vertex
attributes are resolved (rewriting instructions as needed).
</ul>
<p>
The final vertex and fragment programs may be interpreted in software
(see prog_execute.c) or translated into a specific hardware architecture
(see drivers/dri/i915/i915_fragprog.c for example).
</p>
<h3>Code Generation Options</h3>
<p>
Internally, there are several options that control the compiler's code
generation and instruction selection.
These options are seen in the gl_shader_state struct and may be set
by the device driver to indicate its preferences:
<pre>
struct gl_shader_state
{
...
/** Driver-selectable options: */
GLboolean EmitHighLevelInstructions;
GLboolean EmitCondCodes;
GLboolean EmitComments;
};
</pre>
<ul>
<li>EmitHighLevelInstructions
<br>
This option controls instruction selection for loops and conditionals.
If the option is set high-level IF/ELSE/ENDIF, LOOP/ENDLOOP, CONT/BRK
instructions will be emitted.
Otherwise, those constructs will be implemented with BRA instructions.
</li>
<li>EmitCondCodes
<br>
If set, condition codes (ala GL_NV_fragment_program) will be used for
branching and looping.
Otherwise, ordinary registers will be used (the IF instruction will
examine the first operand's X component and do the if-part if non-zero).
This option is only relevant if EmitHighLevelInstructions is set.
</li>
<li>EmitComments
<br>
If set, instructions will be annoted with comments to help with debugging.
Extra NOP instructions will also be inserted.
</br>
</ul>
</BODY>
</HTML>

View file

@ -113,6 +113,10 @@ trackball.o: trackball.c trackball.h
$(CC) -c -I$(INCDIR) $(CFLAGS) trackball.c
extfuncs.h: $(TOP)/progs/util/extfuncs.h
cp $< .
reflect: reflect.o showbuffer.o readtex.o
$(CC) -I$(INCDIR) $(CFLAGS) reflect.o showbuffer.o readtex.o $(APP_LIB_DEPS) -o $@
@ -141,6 +145,9 @@ engine.o: engine.c trackball.h
$(CC) -c -I$(INCDIR) $(CFLAGS) engine.c
fslight.c: extfuncs.h
clean:
-rm -f $(PROGS)
-rm -f *.o *~

View file

@ -20,46 +20,37 @@
#include <GL/gl.h>
#include <GL/glut.h>
#include <GL/glext.h>
#include "extfuncs.h"
static GLint CoordAttrib = 0;
static char *FragProgFile = NULL;
static char *VertProgFile = NULL;
static GLfloat diffuse[4] = { 0.5f, 0.5f, 1.0f, 1.0f };
static GLfloat specular[4] = { 0.8f, 0.8f, 0.8f, 1.0f };
static GLfloat lightPos[4] = { 0.0f, 10.0f, 20.0f, 1.0f };
static GLfloat lightPos[4] = { 0.0f, 10.0f, 20.0f, 0.0f };
static GLfloat delta = 1.0f;
static GLuint fragShader;
static GLuint vertShader;
static GLuint program;
static GLint uLightPos;
static GLint uDiffuse;
static GLint uSpecular;
static GLint uTexture;
static GLuint SphereList, RectList, CurList;
static GLint win = 0;
static GLboolean anim = GL_TRUE;
static GLboolean anim = GL_FALSE;
static GLboolean wire = GL_FALSE;
static GLboolean pixelLight = GL_TRUE;
static GLint t0 = 0;
static GLint frames = 0;
static GLfloat xRot = 0.0f, yRot = 0.0f;
static PFNGLCREATESHADERPROC glCreateShader_func = NULL;
static PFNGLSHADERSOURCEPROC glShaderSource_func = NULL;
static PFNGLGETSHADERSOURCEPROC glGetShaderSource_func = NULL;
static PFNGLCOMPILESHADERPROC glCompileShader_func = NULL;
static PFNGLCREATEPROGRAMPROC glCreateProgram_func = NULL;
static PFNGLDELETEPROGRAMPROC glDeleteProgram_func = NULL;
static PFNGLDELETESHADERPROC glDeleteShader_func = NULL;
static PFNGLATTACHSHADERPROC glAttachShader_func = NULL;
static PFNGLLINKPROGRAMPROC glLinkProgram_func = NULL;
static PFNGLUSEPROGRAMPROC glUseProgram_func = NULL;
static PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation_func = NULL;
static PFNGLISPROGRAMPROC glIsProgram_func = NULL;
static PFNGLISSHADERPROC glIsShader_func = NULL;
static PFNGLUNIFORM3FVPROC glUniform3fv_func = NULL;
static PFNGLUNIFORM3FVPROC glUniform4fv_func = NULL;
static GLfloat xRot = 90.0f, yRot = 0.0f;
static void
@ -69,31 +60,37 @@ normalize(GLfloat *dst, const GLfloat *src)
dst[0] = src[0] / len;
dst[1] = src[1] / len;
dst[2] = src[2] / len;
dst[3] = src[3];
}
static void
Redisplay(void)
{
GLfloat vec[4];
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* update light position */
normalize(vec, lightPos);
glLightfv(GL_LIGHT0, GL_POSITION, vec);
if (pixelLight) {
GLfloat vec[3];
glUseProgram_func(program);
normalize(vec, lightPos);
glUniform3fv_func(uLightPos, 1, vec);
glDisable(GL_LIGHTING);
}
else {
glUseProgram_func(0);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
glEnable(GL_LIGHTING);
}
glPushMatrix();
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
/*
glutSolidSphere(2.0, 10, 5);
*/
glCallList(CurList);
glPopMatrix();
glutSwapBuffers();
@ -174,6 +171,12 @@ Key(unsigned char key, int x, int y)
else
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
break;
case 'o':
if (CurList == SphereList)
CurList = RectList;
else
CurList = SphereList;
break;
case 'p':
pixelLight = !pixelLight;
if (pixelLight)
@ -216,17 +219,247 @@ SpecialKey(int key, int x, int y)
}
static void
TestFunctions(void)
{
printf("Error 0x%x at line %d\n", glGetError(), __LINE__);
{
GLfloat pos[3];
printf("Error 0x%x at line %d\n", glGetError(), __LINE__);
printf("Light pos %g %g %g\n", pos[0], pos[1], pos[2]);
}
{
GLfloat m[16], result[16];
GLint mPos;
int i;
for (i = 0; i < 16; i++)
m[i] = (float) i;
mPos = glGetUniformLocation_func(program, "m");
printf("Error 0x%x at line %d\n", glGetError(), __LINE__);
glUniformMatrix4fv_func(mPos, 1, GL_FALSE, m);
printf("Error 0x%x at line %d\n", glGetError(), __LINE__);
glGetUniformfv_func(program, mPos, result);
printf("Error 0x%x at line %d\n", glGetError(), __LINE__);
for (i = 0; i < 16; i++) {
printf("%8g %8g\n", m[i], result[i]);
}
}
assert(glIsProgram_func(program));
assert(glIsShader_func(fragShader));
assert(glIsShader_func(vertShader));
/* attached shaders */
{
GLuint shaders[20];
GLsizei count;
int i;
glGetAttachedShaders_func(program, 20, &count, shaders);
for (i = 0; i < count; i++) {
printf("Attached: %u\n", shaders[i]);
assert(shaders[i] == fragShader ||
shaders[i] == vertShader);
}
}
{
GLchar log[1000];
GLsizei len;
glGetShaderInfoLog_func(vertShader, 1000, &len, log);
printf("Vert Shader Info Log: %s\n", log);
glGetShaderInfoLog_func(fragShader, 1000, &len, log);
printf("Frag Shader Info Log: %s\n", log);
glGetProgramInfoLog_func(program, 1000, &len, log);
printf("Program Info Log: %s\n", log);
}
}
static void
MakeTexture(void)
{
#define SZ0 128
#define SZ1 64
GLubyte image0[SZ0][SZ0][SZ0][4];
GLubyte image1[SZ1][SZ1][SZ1][4];
GLuint i, j, k;
/* level 0: two-tone gray checkboard */
for (i = 0; i < SZ0; i++) {
for (j = 0; j < SZ0; j++) {
for (k = 0; k < SZ0; k++) {
if ((i/8 + j/8 + k/8) & 1) {
image0[i][j][k][0] =
image0[i][j][k][1] =
image0[i][j][k][2] = 200;
}
else {
image0[i][j][k][0] =
image0[i][j][k][1] =
image0[i][j][k][2] = 100;
}
image0[i][j][k][3] = 255;
}
}
}
/* level 1: two-tone green checkboard */
for (i = 0; i < SZ1; i++) {
for (j = 0; j < SZ1; j++) {
for (k = 0; k < SZ1; k++) {
if ((i/8 + j/8 + k/8) & 1) {
image1[i][j][k][0] = 0;
image1[i][j][k][1] = 250;
image1[i][j][k][2] = 0;
}
else {
image1[i][j][k][0] = 0;
image1[i][j][k][1] = 200;
image1[i][j][k][2] = 0;
}
image1[i][j][k][3] = 255;
}
}
}
glActiveTexture(GL_TEXTURE2); /* unit 2 */
glBindTexture(GL_TEXTURE_2D, 42);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ0, SZ0, 0,
GL_RGBA, GL_UNSIGNED_BYTE, image0);
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, SZ1, SZ1, 0,
GL_RGBA, GL_UNSIGNED_BYTE, image1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glActiveTexture(GL_TEXTURE4); /* unit 4 */
glBindTexture(GL_TEXTURE_3D, 43);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, SZ0, SZ0, SZ0, 0,
GL_RGBA, GL_UNSIGNED_BYTE, image0);
glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA, SZ1, SZ1, SZ1, 0,
GL_RGBA, GL_UNSIGNED_BYTE, image1);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
static void
MakeSphere(void)
{
GLUquadricObj *obj = gluNewQuadric();
SphereList = glGenLists(1);
gluQuadricTexture(obj, GL_TRUE);
glNewList(SphereList, GL_COMPILE);
gluSphere(obj, 2.0f, 10, 5);
glEndList();
}
static void
VertAttrib(GLint index, float x, float y)
{
#if 1
glVertexAttrib2f_func(index, x, y);
#else
glTexCoord2f(x, y);
#endif
}
static void
MakeRect(void)
{
RectList = glGenLists(1);
glNewList(RectList, GL_COMPILE);
glNormal3f(0, 0, 1);
glBegin(GL_POLYGON);
VertAttrib(CoordAttrib, 0, 0); glVertex2f(-2, -2);
VertAttrib(CoordAttrib, 1, 0); glVertex2f( 2, -2);
VertAttrib(CoordAttrib, 1, 1); glVertex2f( 2, 2);
VertAttrib(CoordAttrib, 0, 1); glVertex2f(-2, 2);
glEnd(); /* XXX omit this and crash! */
glEndList();
}
static void
LoadAndCompileShader(GLuint shader, const char *text)
{
GLint stat;
glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
glCompileShader_func(shader);
glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
if (!stat) {
GLchar log[1000];
GLsizei len;
glGetShaderInfoLog_func(shader, 1000, &len, log);
fprintf(stderr, "fslight: problem compiling shader:\n%s\n", log);
exit(1);
}
}
/**
* Read a shader from a file.
*/
static void
ReadShader(GLuint shader, const char *filename)
{
const int max = 100*1000;
int n;
char *buffer = (char*) malloc(max);
FILE *f = fopen(filename, "r");
if (!f) {
fprintf(stderr, "fslight: Unable to open shader file %s\n", filename);
exit(1);
}
n = fread(buffer, 1, max, f);
printf("fslight: read %d bytes from shader file %s\n", n, filename);
if (n > 0) {
buffer[n] = 0;
LoadAndCompileShader(shader, buffer);
}
fclose(f);
free(buffer);
}
static void
CheckLink(GLuint prog)
{
GLint stat;
glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
if (!stat) {
GLchar log[1000];
GLsizei len;
glGetProgramInfoLog_func(prog, 1000, &len, log);
fprintf(stderr, "Linker error:\n%s\n", log);
}
}
static void
Init(void)
{
static const char *fragShaderText =
"uniform vec3 lightPos;\n"
"uniform vec4 diffuse;\n"
"uniform vec4 specular;\n"
"varying vec3 normal;\n"
"void main() {\n"
" // Compute dot product of light direction and normal vector\n"
" float dotProd = max(dot(lightPos, normalize(normal)), 0.0);\n"
" float dotProd = max(dot(gl_LightSource[0].position.xyz, \n"
" normalize(normal)), 0.0);\n"
" // Compute diffuse and specular contributions\n"
" gl_FragColor = diffuse * dotProd + specular * pow(dotProd, 20.0);\n"
"}\n";
@ -236,8 +469,6 @@ Init(void)
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
" normal = gl_NormalMatrix * gl_Normal;\n"
"}\n";
const char *version;
version = (const char *) glGetString(GL_VERSION);
@ -246,43 +477,55 @@ Init(void)
/*exit(1);*/
}
glCreateShader_func = (PFNGLCREATESHADERPROC) glutGetProcAddress("glCreateShader");
glDeleteShader_func = (PFNGLDELETESHADERPROC) glutGetProcAddress("glDeleteShader");
glDeleteProgram_func = (PFNGLDELETEPROGRAMPROC) glutGetProcAddress("glDeleteProgram");
glShaderSource_func = (PFNGLSHADERSOURCEPROC) glutGetProcAddress("glShaderSource");
glGetShaderSource_func = (PFNGLGETSHADERSOURCEPROC) glutGetProcAddress("glGetShaderSource");
glCompileShader_func = (PFNGLCOMPILESHADERPROC) glutGetProcAddress("glCompileShader");
glCreateProgram_func = (PFNGLCREATEPROGRAMPROC) glutGetProcAddress("glCreateProgram");
glAttachShader_func = (PFNGLATTACHSHADERPROC) glutGetProcAddress("glAttachShader");
glLinkProgram_func = (PFNGLLINKPROGRAMPROC) glutGetProcAddress("glLinkProgram");
glUseProgram_func = (PFNGLUSEPROGRAMPROC) glutGetProcAddress("glUseProgram");
glGetUniformLocation_func = (PFNGLGETUNIFORMLOCATIONPROC) glutGetProcAddress("glGetUniformLocation");
glIsProgram_func = (PFNGLISPROGRAMPROC) glutGetProcAddress("glIsProgram");
glIsShader_func = (PFNGLISSHADERPROC) glutGetProcAddress("glIsShader");
glUniform3fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform3fv");
glUniform4fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform4fv");
GetExtensionFuncs();
fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
glShaderSource_func(fragShader, 1, &fragShaderText, NULL);
glCompileShader_func(fragShader);
if (FragProgFile)
ReadShader(fragShader, FragProgFile);
else
LoadAndCompileShader(fragShader, fragShaderText);
vertShader = glCreateShader_func(GL_VERTEX_SHADER);
glShaderSource_func(vertShader, 1, &vertShaderText, NULL);
glCompileShader_func(vertShader);
if (VertProgFile)
ReadShader(vertShader, VertProgFile);
else
LoadAndCompileShader(vertShader, vertShaderText);
program = glCreateProgram_func();
glAttachShader_func(program, fragShader);
glAttachShader_func(program, vertShader);
glLinkProgram_func(program);
CheckLink(program);
glUseProgram_func(program);
uLightPos = glGetUniformLocation_func(program, "lightPos");
uDiffuse = glGetUniformLocation_func(program, "diffuse");
uSpecular = glGetUniformLocation_func(program, "specular");
uTexture = glGetUniformLocation_func(program, "texture");
printf("DiffusePos %d SpecularPos %d TexturePos %d\n",
uDiffuse, uSpecular, uTexture);
glUniform4fv_func(uDiffuse, 1, diffuse);
glUniform4fv_func(uSpecular, 1, specular);
/* assert(glGetError() == 0);*/
glUniform1i_func(uTexture, 2); /* use texture unit 2 */
/*assert(glGetError() == 0);*/
if (CoordAttrib) {
int i;
glBindAttribLocation_func(program, CoordAttrib, "coord");
i = glGetAttribLocation_func(program, "coord");
assert(i >= 0);
if (i != CoordAttrib) {
printf("Hmmm, NVIDIA bug?\n");
CoordAttrib = i;
}
else {
printf("Mesa bind attrib: coord = %d\n", i);
}
}
/*assert(glGetError() == 0);*/
glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
glEnable(GL_DEPTH_TEST);
@ -292,11 +535,18 @@ Init(void)
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20.0f);
MakeSphere();
MakeRect();
CurList = SphereList;
MakeTexture();
printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
printf("Press p to toggle between per-pixel and per-vertex lighting\n");
/* test glGetShaderSource() */
{
if (0) {
GLsizei len = strlen(fragShaderText) + 1;
GLsizei lenOut;
GLchar *src =(GLchar *) malloc(len * sizeof(GLchar));
@ -310,6 +560,35 @@ Init(void)
assert(glIsProgram_func(program));
assert(glIsShader_func(fragShader));
assert(glIsShader_func(vertShader));
glColor3f(1, 0, 0);
/* for testing state vars */
{
static GLfloat fc[4] = { 1, 1, 0, 0 };
static GLfloat amb[4] = { 1, 0, 1, 0 };
glFogfv(GL_FOG_COLOR, fc);
glLightfv(GL_LIGHT1, GL_AMBIENT, amb);
}
#if 0
TestFunctions();
#endif
}
static void
ParseOptions(int argc, char *argv[])
{
int i;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-fs") == 0) {
FragProgFile = argv[i+1];
}
else if (strcmp(argv[i], "-vs") == 0) {
VertProgFile = argv[i+1];
}
}
}
@ -318,7 +597,7 @@ main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowPosition( 0, 0);
glutInitWindowSize(200, 200);
glutInitWindowSize(100, 100);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
win = glutCreateWindow(argv[0]);
glutReshapeFunc(Reshape);
@ -327,8 +606,10 @@ main(int argc, char *argv[])
glutDisplayFunc(Redisplay);
if (anim)
glutIdleFunc(Idle);
ParseOptions(argc, argv);
Init();
glutMainLoop();
return 0;
}

View file

@ -0,0 +1,36 @@
//
// Fragment shader for procedural bricks
//
// Authors: Dave Baldwin, Steve Koren, Randi Rost
// based on a shader by Darwyn Peachey
//
// Copyright (c) 2002-2006 3Dlabs Inc. Ltd.
//
// See 3Dlabs-License.txt for license information
//
uniform vec3 BrickColor, MortarColor;
uniform vec2 BrickSize;
uniform vec2 BrickPct;
varying vec2 MCposition;
varying float LightIntensity;
void main()
{
vec3 color;
vec2 position, useBrick;
position = MCposition / BrickSize;
if (fract(position.y * 0.5) > 0.5)
position.x += 0.5;
position = fract(position);
useBrick = step(position, BrickPct);
color = mix(MortarColor, BrickColor, useBrick.x * useBrick.y);
color *= LightIntensity;
gl_FragColor = vec4(color, 1.0);
}

View file

@ -0,0 +1,41 @@
//
// Vertex shader for procedural bricks
//
// Authors: Dave Baldwin, Steve Koren, Randi Rost
// based on a shader by Darwyn Peachey
//
// Copyright (c) 2002-2006 3Dlabs Inc. Ltd.
//
// See 3Dlabs-License.txt for license information
//
uniform vec3 LightPosition;
const float SpecularContribution = 0.3;
const float DiffuseContribution = 1.0 - SpecularContribution;
varying float LightIntensity;
varying vec2 MCposition;
void main()
{
vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Vertex);
vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal);
vec3 lightVec = normalize(LightPosition - ecPosition);
vec3 reflectVec = reflect(-lightVec, tnorm);
vec3 viewVec = normalize(-ecPosition);
float diffuse = max(dot(lightVec, tnorm), 0.0);
float spec = 0.0;
if (diffuse > 0.0)
{
spec = max(dot(reflectVec, viewVec), 0.0);
spec = pow(spec, 16.0);
}
LightIntensity = DiffuseContribution * diffuse +
SpecularContribution * spec;
MCposition = gl_Vertex.xy;
gl_Position = ftransform();
}

View file

@ -0,0 +1,41 @@
//
// Fragment shader for procedural bumps
//
// Authors: John Kessenich, Randi Rost
//
// Copyright (c) 2002-2006 3Dlabs Inc. Ltd.
//
// See 3Dlabs-License.txt for license information
//
varying vec3 LightDir;
varying vec3 EyeDir;
uniform vec3 SurfaceColor; // = (0.7, 0.6, 0.18)
uniform float BumpDensity; // = 16.0
uniform float BumpSize; // = 0.15
uniform float SpecularFactor; // = 0.5
void main()
{
vec3 litColor;
vec2 c = BumpDensity * gl_TexCoord[0].st;
vec2 p = fract(c) - vec2(0.5);
float d, f;
d = p.x * p.x + p.y * p.y;
f = 1.0 / sqrt(d + 1.0);
if (d >= BumpSize)
{ p = vec2(0.0); f = 1.0; }
vec3 normDelta = vec3(p.x, p.y, 1.0) * f;
litColor = SurfaceColor * max(dot(normDelta, LightDir), 0.0);
vec3 reflectDir = reflect(LightDir, normDelta);
float spec = max(dot(EyeDir, reflectDir), 0.0);
spec *= SpecularFactor;
litColor = min(litColor + spec, vec3(1.0));
gl_FragColor = vec4(litColor, 1.0);
}

View file

@ -0,0 +1,38 @@
//
// Vertex shader for procedural bumps
//
// Authors: Randi Rost, John Kessenich
//
// Copyright (c) 2002-2006 3Dlabs Inc. Ltd.
//
// See 3Dlabs-License.txt for license information
//
varying vec3 LightDir;
varying vec3 EyeDir;
uniform vec3 LightPosition;
attribute vec3 Tangent;
void main()
{
EyeDir = vec3(gl_ModelViewMatrix * gl_Vertex);
gl_Position = ftransform();
gl_TexCoord[0] = gl_MultiTexCoord0;
vec3 n = normalize(gl_NormalMatrix * gl_Normal);
vec3 t = normalize(gl_NormalMatrix * Tangent);
vec3 b = cross(n, t);
vec3 v;
v.x = dot(LightPosition, t);
v.y = dot(LightPosition, b);
v.z = dot(LightPosition, n);
LightDir = normalize(v);
v.x = dot(EyeDir, t);
v.y = dot(EyeDir, b);
v.z = dot(EyeDir, n);
EyeDir = normalize(v);
}

View file

@ -0,0 +1,75 @@
//
// Fragment shader for procedurally generated toy ball
//
// Author: Bill Licea-Kane
//
// Copyright (c) 2002-2003 ATI Research
//
// See ATI-License.txt for license information
//
varying vec4 ECposition; // surface position in eye coordinates
varying vec4 ECballCenter; // ball center in eye coordinates
uniform vec4 LightDir; // light direction, should be normalized
uniform vec4 HVector; // reflection vector for infinite light source
uniform vec4 SpecularColor;
uniform vec4 Red, Yellow, Blue;
uniform vec4 HalfSpace0; // half-spaces used to define star pattern
uniform vec4 HalfSpace1;
uniform vec4 HalfSpace2;
uniform vec4 HalfSpace3;
uniform vec4 HalfSpace4;
uniform float InOrOutInit; // = -3
uniform float StripeWidth; // = 0.3
uniform float FWidth; // = 0.005
void main()
{
vec4 normal; // Analytically computed normal
vec4 p; // Point in shader space
vec4 surfColor; // Computed color of the surface
float intensity; // Computed light intensity
vec4 distance; // Computed distance values
float inorout; // Counter for computing star pattern
p.xyz = normalize(ECposition.xyz - ECballCenter.xyz); // Calculate p
p.w = 1.0;
inorout = InOrOutInit; // initialize inorout to -3
distance[0] = dot(p, HalfSpace0);
distance[1] = dot(p, HalfSpace1);
distance[2] = dot(p, HalfSpace2);
distance[3] = dot(p, HalfSpace3);
distance = smoothstep(-FWidth, FWidth, distance);
inorout += dot(distance, vec4(1.0));
distance.x = dot(p, HalfSpace4);
distance.y = StripeWidth - abs(p.z);
distance = smoothstep(-FWidth, FWidth, distance);
inorout += distance.x;
inorout = clamp(inorout, 0.0, 1.0);
surfColor = mix(Yellow, Red, inorout);
surfColor = mix(surfColor, Blue, distance.y);
// normal = point on surface for sphere at (0,0,0)
normal = p;
// Per fragment diffuse lighting
intensity = 0.2; // ambient
intensity += 0.8 * clamp(dot(LightDir, normal), 0.0, 1.0);
surfColor *= intensity;
// Per fragment specular lighting
intensity = clamp(dot(HVector, normal), 0.0, 1.0);
intensity = pow(intensity, SpecularColor.a);
surfColor += SpecularColor * intensity;
gl_FragColor = surfColor;
}

View file

@ -0,0 +1,24 @@
//
// Fragment shader for procedurally generated toy ball
//
// Author: Bill Licea-Kane
//
// Copyright (c) 2002-2003 ATI Research
//
// See ATI-License.txt for license information
//
varying vec4 ECposition; // surface position in eye coordinates
varying vec4 ECballCenter; // ball center in eye coordinates
uniform vec4 BallCenter; // ball center in modelling coordinates
void main()
{
//orig: ECposition = gl_ModelViewMatrix * gl_Vertex;
ECposition = gl_TextureMatrix[0] * gl_Vertex;
ECposition = gl_ModelViewMatrix * ECposition;
ECballCenter = gl_ModelViewMatrix * BallCenter;
gl_Position = ftransform();
}

View file

@ -0,0 +1,55 @@
//
// Fragment shader for drawing the Mandelbrot set
//
// Authors: Dave Baldwin, Steve Koren, Randi Rost
// based on a shader by Michael Rivero
//
// Copyright (c) 2002-2005: 3Dlabs, Inc.
//
// See 3Dlabs-License.txt for license information
//
varying vec3 Position;
varying float LightIntensity;
uniform float MaxIterations;
uniform float Zoom;
uniform float Xcenter;
uniform float Ycenter;
uniform vec3 InnerColor;
uniform vec3 OuterColor1;
uniform vec3 OuterColor2;
void main()
{
float real = Position.x * Zoom + Xcenter;
float imag = Position.y * Zoom + Ycenter;
float Creal = real; // Change this line...
float Cimag = imag; // ...and this one to get a Julia set
float r2 = 0.0;
float iter;
// for (iter = 0.0; iter < MaxIterations && r2 < 4.0; ++iter)
for (iter = 0.0; iter < 12 && r2 < 4.0; ++iter)
{
float tempreal = real;
real = (tempreal * tempreal) - (imag * imag) + Creal;
imag = 2.0 * tempreal * imag + Cimag;
r2 = (real * real) + (imag * imag);
}
// Base the color on the number of iterations
vec3 color;
if (r2 < 4.0)
color = InnerColor;
else
color = mix(OuterColor1, OuterColor2, fract(iter * 0.05));
color *= LightIntensity;
gl_FragColor = vec4(color, 1.0);
}

View file

@ -0,0 +1,35 @@
//
// Vertex shader for drawing the Mandelbrot set
//
// Authors: Dave Baldwin, Steve Koren, Randi Rost
// based on a shader by Michael Rivero
//
// Copyright (c) 2002-2005: 3Dlabs, Inc.
//
// See 3Dlabs-License.txt for license information
//
uniform vec3 LightPosition;
uniform float SpecularContribution;
uniform float DiffuseContribution;
uniform float Shininess;
varying float LightIntensity;
varying vec3 Position;
void main()
{
vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Vertex);
vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal);
vec3 lightVec = normalize(LightPosition - ecPosition);
vec3 reflectVec = reflect(-lightVec, tnorm);
vec3 viewVec = normalize(-ecPosition);
float spec = max(dot(reflectVec, viewVec), 0.0);
spec = pow(spec, Shininess);
LightIntensity = DiffuseContribution *
max(dot(lightVec, tnorm), 0.0) +
SpecularContribution * spec;
Position = vec3(gl_MultiTexCoord0 - 0.5) * 5.0;
gl_Position = ftransform();
}

74
progs/glsl/Makefile Normal file
View file

@ -0,0 +1,74 @@
# progs/demos/Makefile
TOP = ../..
include $(TOP)/configs/current
INCDIR = $(TOP)/include
OSMESA_LIBS = -L$(TOP)/$(LIB_DIR) -lglut -lOSMesa -lGLU -lGL $(APP_LIB_DEPS)
OSMESA16_LIBS = -L$(TOP)/$(LIB_DIR) -lglut -lOSMesa16 -lGLU -lGL $(APP_LIB_DEPS)
OSMESA32_LIBS = -L$(TOP)/$(LIB_DIR) -lglut -lOSMesa32 -lGLU -lGL $(APP_LIB_DEPS)
LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME)
PROGS = \
brick \
bump \
mandelbrot \
noise \
toyball \
texdemo1
##### RULES #####
.SUFFIXES:
.SUFFIXES: .c
# make executable from .c file:
.c: $(LIB_DEP)
$(CC) -I$(INCDIR) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@
##### TARGETS #####
default: $(PROGS)
##### Extra dependencies
extfuncs.h: $(TOP)/progs/util/extfuncs.h
cp $< .
readtex.c: $(TOP)/progs/util/readtex.c
cp $< .
readtex.h: $(TOP)/progs/util/readtex.h
cp $< .
readtex.o: readtex.c readtex.h
$(CC) -c -I$(INCDIR) $(CFLAGS) readtex.c
brick.c: extfuncs.h
bump.c: extfuncs.h
mandelbrot.c: extfuncs.h
toyball.c: extfuncs.h
texdemo1: texdemo1.o readtex.o
$(CC) -I$(INCDIR) $(CFLAGS) texdemo1.o readtex.o $(APP_LIB_DEPS) -o $@
texdemo1.o: texdemo1.c readtex.h extfuncs.h
$(CC) -c -I$(INCDIR) $(CFLAGS) texdemo1.c
clean:
-rm -f $(PROGS)
-rm -f *.o *~
-rm -f extfuncs.h

311
progs/glsl/brick.c Normal file
View file

@ -0,0 +1,311 @@
/**
* "Brick" shader demo. Uses the example shaders from chapter 6 of
* the OpenGL Shading Language "orange" book.
* 10 Jan 2007
*/
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <GL/glext.h>
#include "extfuncs.h"
static char *FragProgFile = "CH06-brick.frag.txt";
static char *VertProgFile = "CH06-brick.vert.txt";
/* program/shader objects */
static GLuint fragShader;
static GLuint vertShader;
static GLuint program;
struct uniform_info {
const char *name;
GLuint size;
GLint location;
GLfloat value[4];
};
static struct uniform_info Uniforms[] = {
/* vert */
{ "LightPosition", 3, -1, { 0.1, 0.1, 9.0, 0} },
/* frag */
{ "BrickColor", 3, -1, { 0.8, 0.2, 0.2, 0 } },
{ "MortarColor", 3, -1, { 0.6, 0.6, 0.6, 0 } },
{ "BrickSize", 2, -1, { 1.0, 0.3, 0, 0 } },
{ "BrickPct", 2, -1, { 0.9, 0.8, 0, 0 } },
{ NULL, 0, 0, { 0, 0, 0, 0 } }
};
static GLint win = 0;
static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f;
static void
Redisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
glRotatef(zRot, 0.0f, 0.0f, 1.0f);
glBegin(GL_POLYGON);
glTexCoord2f(0, 0); glVertex2f(-2, -2);
glTexCoord2f(1, 0); glVertex2f( 2, -2);
glTexCoord2f(1, 1); glVertex2f( 2, 2);
glTexCoord2f(0, 1); glVertex2f(-2, 2);
glEnd();
glPopMatrix();
glutSwapBuffers();
}
static void
Reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -15.0f);
}
static void
CleanUp(void)
{
glDeleteShader_func(fragShader);
glDeleteShader_func(vertShader);
glDeleteProgram_func(program);
glutDestroyWindow(win);
}
static void
Key(unsigned char key, int x, int y)
{
(void) x;
(void) y;
switch(key) {
case 'z':
zRot -= 1.0;
break;
case 'Z':
zRot += 1.0;
break;
case 27:
CleanUp();
exit(0);
break;
}
glutPostRedisplay();
}
static void
SpecialKey(int key, int x, int y)
{
const GLfloat step = 3.0f;
(void) x;
(void) y;
switch(key) {
case GLUT_KEY_UP:
xRot -= step;
break;
case GLUT_KEY_DOWN:
xRot += step;
break;
case GLUT_KEY_LEFT:
yRot -= step;
break;
case GLUT_KEY_RIGHT:
yRot += step;
break;
}
glutPostRedisplay();
}
static void
LoadAndCompileShader(GLuint shader, const char *text)
{
GLint stat;
glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
glCompileShader_func(shader);
glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
if (!stat) {
GLchar log[1000];
GLsizei len;
glGetShaderInfoLog_func(shader, 1000, &len, log);
fprintf(stderr, "brick: problem compiling shader: %s\n", log);
exit(1);
}
else {
printf("Shader compiled OK\n");
}
}
/**
* Read a shader from a file.
*/
static void
ReadShader(GLuint shader, const char *filename)
{
const int max = 100*1000;
int n;
char *buffer = (char*) malloc(max);
FILE *f = fopen(filename, "r");
if (!f) {
fprintf(stderr, "brick: Unable to open shader file %s\n", filename);
exit(1);
}
n = fread(buffer, 1, max, f);
printf("brick: read %d bytes from shader file %s\n", n, filename);
if (n > 0) {
buffer[n] = 0;
LoadAndCompileShader(shader, buffer);
}
fclose(f);
free(buffer);
}
static void
CheckLink(GLuint prog)
{
GLint stat;
glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
if (!stat) {
GLchar log[1000];
GLsizei len;
glGetProgramInfoLog_func(prog, 1000, &len, log);
fprintf(stderr, "Linker error:\n%s\n", log);
}
else {
fprintf(stderr, "Link success!\n");
}
}
static void
Init(void)
{
const char *version;
GLint i;
version = (const char *) glGetString(GL_VERSION);
if (version[0] != '2' || version[1] != '.') {
printf("Warning: this program expects OpenGL 2.0\n");
/*exit(1);*/
}
GetExtensionFuncs();
vertShader = glCreateShader_func(GL_VERTEX_SHADER);
ReadShader(vertShader, VertProgFile);
fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
ReadShader(fragShader, FragProgFile);
program = glCreateProgram_func();
glAttachShader_func(program, fragShader);
glAttachShader_func(program, vertShader);
glLinkProgram_func(program);
CheckLink(program);
glUseProgram_func(program);
for (i = 0; Uniforms[i].name; i++) {
Uniforms[i].location
= glGetUniformLocation_func(program, Uniforms[i].name);
printf("Uniform %s location: %d\n", Uniforms[i].name,
Uniforms[i].location);
switch (Uniforms[i].size) {
case 1:
glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value);
break;
case 2:
glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value);
break;
case 3:
glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value);
break;
case 4:
glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value);
break;
default:
abort();
}
}
assert(glGetError() == 0);
glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
assert(glIsProgram_func(program));
assert(glIsShader_func(fragShader));
assert(glIsShader_func(vertShader));
glColor3f(1, 0, 0);
}
static void
ParseOptions(int argc, char *argv[])
{
int i;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-fs") == 0) {
FragProgFile = argv[i+1];
}
else if (strcmp(argv[i], "-vs") == 0) {
VertProgFile = argv[i+1];
}
}
}
int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowPosition( 0, 0);
glutInitWindowSize(400, 400);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
win = glutCreateWindow(argv[0]);
glutReshapeFunc(Reshape);
glutKeyboardFunc(Key);
glutSpecialFunc(SpecialKey);
glutDisplayFunc(Redisplay);
ParseOptions(argc, argv);
Init();
glutMainLoop();
return 0;
}

411
progs/glsl/bump.c Normal file
View file

@ -0,0 +1,411 @@
/**
* Procedural Bump Mapping demo. Uses the example shaders from
* chapter 11 of the OpenGL Shading Language "orange" book.
* 16 Jan 2007
*/
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/glu.h>
#include <GL/glext.h>
#include "extfuncs.h"
static char *FragProgFile = "CH11-bumpmap.frag.txt";
static char *VertProgFile = "CH11-bumpmap.vert.txt";
/* program/shader objects */
static GLuint fragShader;
static GLuint vertShader;
static GLuint program;
struct uniform_info {
const char *name;
GLuint size;
GLint location;
GLfloat value[4];
};
static struct uniform_info Uniforms[] = {
{ "LightPosition", 3, -1, { 0.57737, 0.57735, 0.57735, 0.0 } },
{ "SurfaceColor", 3, -1, { 0.8, 0.8, 0.2, 0 } },
{ "BumpDensity", 1, -1, { 10.0, 0, 0, 0 } },
{ "BumpSize", 1, -1, { 0.125, 0, 0, 0 } },
{ "SpecularFactor", 1, -1, { 0.5, 0, 0, 0 } },
{ NULL, 0, 0, { 0, 0, 0, 0 } }
};
static GLint win = 0;
static GLfloat xRot = 20.0f, yRot = 0.0f, zRot = 0.0f;
static GLuint tangentAttrib;
static GLboolean Anim = GL_FALSE;
static void
CheckError(int line)
{
GLenum err = glGetError();
if (err) {
printf("GL Error %s (0x%x) at line %d\n",
gluErrorString(err), (int) err, line);
}
}
/*
* Draw a square, specifying normal and tangent vectors.
*/
static void
Square(GLfloat size)
{
glNormal3f(0, 0, 1);
glVertexAttrib3f_func(tangentAttrib, 1, 0, 0);
glBegin(GL_POLYGON);
glTexCoord2f(0, 0); glVertex2f(-size, -size);
glTexCoord2f(1, 0); glVertex2f( size, -size);
glTexCoord2f(1, 1); glVertex2f( size, size);
glTexCoord2f(0, 1); glVertex2f(-size, size);
glEnd();
}
static void
Cube(GLfloat size)
{
/* +X */
glPushMatrix();
glRotatef(90, 0, 1, 0);
glTranslatef(0, 0, size);
Square(size);
glPopMatrix();
/* -X */
glPushMatrix();
glRotatef(-90, 0, 1, 0);
glTranslatef(0, 0, size);
Square(size);
glPopMatrix();
/* +Y */
glPushMatrix();
glRotatef(90, 1, 0, 0);
glTranslatef(0, 0, size);
Square(size);
glPopMatrix();
/* -Y */
glPushMatrix();
glRotatef(-90, 1, 0, 0);
glTranslatef(0, 0, size);
Square(size);
glPopMatrix();
/* +Z */
glPushMatrix();
glTranslatef(0, 0, size);
Square(size);
glPopMatrix();
/* -Z */
glPushMatrix();
glRotatef(180, 0, 1, 0);
glTranslatef(0, 0, size);
Square(size);
glPopMatrix();
}
static void
Idle(void)
{
GLint t = glutGet(GLUT_ELAPSED_TIME);
yRot = t * 0.05;
glutPostRedisplay();
}
static void
Redisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
glRotatef(zRot, 0.0f, 0.0f, 1.0f);
Cube(1.5);
glPopMatrix();
glFinish();
glFlush();
CheckError(__LINE__);
glutSwapBuffers();
}
static void
Reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -15.0f);
}
static void
CleanUp(void)
{
glDeleteShader_func(fragShader);
glDeleteShader_func(vertShader);
glDeleteProgram_func(program);
glutDestroyWindow(win);
}
static void
Key(unsigned char key, int x, int y)
{
const GLfloat step = 2.0;
(void) x;
(void) y;
switch(key) {
case 'a':
Anim = !Anim;
glutIdleFunc(Anim ? Idle : NULL);
break;
case 'z':
zRot += step;
break;
case 'Z':
zRot -= step;
break;
case 27:
CleanUp();
exit(0);
break;
}
glutPostRedisplay();
}
static void
SpecialKey(int key, int x, int y)
{
const GLfloat step = 2.0;
(void) x;
(void) y;
switch(key) {
case GLUT_KEY_UP:
xRot += step;
break;
case GLUT_KEY_DOWN:
xRot -= step;
break;
case GLUT_KEY_LEFT:
yRot -= step;
break;
case GLUT_KEY_RIGHT:
yRot += step;
break;
}
glutPostRedisplay();
}
static void
LoadAndCompileShader(GLuint shader, const char *text)
{
GLint stat;
glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
glCompileShader_func(shader);
glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
if (!stat) {
GLchar log[1000];
GLsizei len;
glGetShaderInfoLog_func(shader, 1000, &len, log);
fprintf(stderr, "brick: problem compiling shader: %s\n", log);
exit(1);
}
else {
printf("Shader compiled OK\n");
}
}
/**
* Read a shader from a file.
*/
static void
ReadShader(GLuint shader, const char *filename)
{
const int max = 100*1000;
int n;
char *buffer = (char*) malloc(max);
FILE *f = fopen(filename, "r");
if (!f) {
fprintf(stderr, "brick: Unable to open shader file %s\n", filename);
exit(1);
}
n = fread(buffer, 1, max, f);
printf("brick: read %d bytes from shader file %s\n", n, filename);
if (n > 0) {
buffer[n] = 0;
LoadAndCompileShader(shader, buffer);
}
fclose(f);
free(buffer);
}
static void
CheckLink(GLuint prog)
{
GLint stat;
glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
if (!stat) {
GLchar log[1000];
GLsizei len;
glGetProgramInfoLog_func(prog, 1000, &len, log);
fprintf(stderr, "Linker error:\n%s\n", log);
}
else {
fprintf(stderr, "Link success!\n");
}
}
static void
Init(void)
{
const char *version;
GLint i;
version = (const char *) glGetString(GL_VERSION);
if (version[0] != '2' || version[1] != '.') {
printf("Warning: this program expects OpenGL 2.0\n");
/*exit(1);*/
}
printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
GetExtensionFuncs();
vertShader = glCreateShader_func(GL_VERTEX_SHADER);
ReadShader(vertShader, VertProgFile);
fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
ReadShader(fragShader, FragProgFile);
program = glCreateProgram_func();
glAttachShader_func(program, fragShader);
glAttachShader_func(program, vertShader);
glLinkProgram_func(program);
CheckLink(program);
glUseProgram_func(program);
assert(glIsProgram_func(program));
assert(glIsShader_func(fragShader));
assert(glIsShader_func(vertShader));
assert(glGetError() == 0);
CheckError(__LINE__);
for (i = 0; Uniforms[i].name; i++) {
Uniforms[i].location
= glGetUniformLocation_func(program, Uniforms[i].name);
printf("Uniform %s location: %d\n", Uniforms[i].name,
Uniforms[i].location);
switch (Uniforms[i].size) {
case 1:
glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value);
break;
case 2:
glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value);
break;
case 3:
glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value);
break;
case 4:
glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value);
break;
default:
abort();
}
}
CheckError(__LINE__);
tangentAttrib = glGetAttribLocation_func(program, "Tangent");
printf("Tangent Attrib: %d\n", tangentAttrib);
assert(tangentAttrib >= 0);
CheckError(__LINE__);
glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
glEnable(GL_DEPTH_TEST);
glColor3f(1, 0, 0);
}
static void
ParseOptions(int argc, char *argv[])
{
int i;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-fs") == 0) {
FragProgFile = argv[i+1];
}
else if (strcmp(argv[i], "-vs") == 0) {
VertProgFile = argv[i+1];
}
}
}
int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowPosition( 0, 0);
glutInitWindowSize(400, 400);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
win = glutCreateWindow(argv[0]);
glutReshapeFunc(Reshape);
glutKeyboardFunc(Key);
glutSpecialFunc(SpecialKey);
glutDisplayFunc(Redisplay);
ParseOptions(argc, argv);
Init();
glutMainLoop();
return 0;
}

View file

@ -0,0 +1,18 @@
// Fragment shader for cube-texture reflection mapping
// Brian Paul
uniform samplerCube cubeTex;
varying vec3 normal;
uniform vec3 lightPos;
void main()
{
// simple diffuse, specular lighting:
vec3 lp = normalize(lightPos);
float dp = dot(lp, normalize(normal));
float spec = pow(dp, 5.0);
// final color:
gl_FragColor = dp * textureCube(cubeTex, gl_TexCoord[0].xyz, 0.0) + spec;
}

328
progs/glsl/mandelbrot.c Normal file
View file

@ -0,0 +1,328 @@
/**
* "Mandelbrot" shader demo. Uses the example shaders from
* chapter 15 (or 18) of the OpenGL Shading Language "orange" book.
* 15 Jan 2007
*/
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <GL/glext.h>
#include "extfuncs.h"
static char *FragProgFile = "CH18-mandel.frag.txt";
static char *VertProgFile = "CH18-mandel.vert.txt";
/* program/shader objects */
static GLuint fragShader;
static GLuint vertShader;
static GLuint program;
struct uniform_info {
const char *name;
GLuint size;
GLint location;
GLfloat value[4];
};
static struct uniform_info Uniforms[] = {
/* vert */
{ "LightPosition", 3, -1, { 0.1, 0.1, 9.0, 0} },
{ "SpecularContribution", 1, -1, { 0.5, 0, 0, 0 } },
{ "DiffuseContribution", 1, -1, { 0.5, 0, 0, 0 } },
{ "Shininess", 1, -1, { 20.0, 0, 0, 0 } },
/* frag */
{ "MaxIterations", 1, -1, { 12, 0, 0, 0 } },
{ "Zoom", 1, -1, { 0.125, 0, 0, 0 } },
{ "Xcenter", 1, -1, { -1.5, 0, 0, 0 } },
{ "Ycenter", 1, -1, { .005, 0, 0, 0 } },
{ "InnerColor", 3, -1, { 1, 0, 0, 0 } },
{ "OuterColor1", 3, -1, { 0, 1, 0, 0 } },
{ "OuterColor2", 3, -1, { 0, 0, 1, 0 } },
{ NULL, 0, 0, { 0, 0, 0, 0 } }
};
static GLint win = 0;
static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f;
static GLint uZoom, uXcenter, uYcenter;
static GLfloat zoom = 1.0, xCenter = -1.5, yCenter = 0.0;
static void
Redisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* set interactive uniform parameters */
glUniform1fv_func(uZoom, 1, &zoom);
glUniform1fv_func(uXcenter, 1, &xCenter);
glUniform1fv_func(uYcenter, 1, &yCenter);
glPushMatrix();
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
glRotatef(zRot, 0.0f, 0.0f, 1.0f);
glBegin(GL_POLYGON);
glTexCoord2f(0, 0); glVertex2f(-1, -1);
glTexCoord2f(1, 0); glVertex2f( 1, -1);
glTexCoord2f(1, 1); glVertex2f( 1, 1);
glTexCoord2f(0, 1); glVertex2f(-1, 1);
glEnd();
glPopMatrix();
glFinish();
glFlush();
glutSwapBuffers();
}
static void
Reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -6.0f);
}
static void
CleanUp(void)
{
glDeleteShader_func(fragShader);
glDeleteShader_func(vertShader);
glDeleteProgram_func(program);
glutDestroyWindow(win);
}
static void
Key(unsigned char key, int x, int y)
{
(void) x;
(void) y;
switch(key) {
case 'z':
zoom *= 0.9;
break;
case 'Z':
zoom /= 0.9;
break;
case 27:
CleanUp();
exit(0);
break;
}
glutPostRedisplay();
}
static void
SpecialKey(int key, int x, int y)
{
const GLfloat step = 0.1 * zoom;
(void) x;
(void) y;
switch(key) {
case GLUT_KEY_UP:
yCenter += step;
break;
case GLUT_KEY_DOWN:
yCenter -= step;
break;
case GLUT_KEY_LEFT:
xCenter -= step;
break;
case GLUT_KEY_RIGHT:
xCenter += step;
break;
}
glutPostRedisplay();
}
static void
LoadAndCompileShader(GLuint shader, const char *text)
{
GLint stat;
glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
glCompileShader_func(shader);
glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
if (!stat) {
GLchar log[1000];
GLsizei len;
glGetShaderInfoLog_func(shader, 1000, &len, log);
fprintf(stderr, "brick: problem compiling shader: %s\n", log);
exit(1);
}
else {
printf("Shader compiled OK\n");
}
}
/**
* Read a shader from a file.
*/
static void
ReadShader(GLuint shader, const char *filename)
{
const int max = 100*1000;
int n;
char *buffer = (char*) malloc(max);
FILE *f = fopen(filename, "r");
if (!f) {
fprintf(stderr, "brick: Unable to open shader file %s\n", filename);
exit(1);
}
n = fread(buffer, 1, max, f);
printf("brick: read %d bytes from shader file %s\n", n, filename);
if (n > 0) {
buffer[n] = 0;
LoadAndCompileShader(shader, buffer);
}
fclose(f);
free(buffer);
}
static void
CheckLink(GLuint prog)
{
GLint stat;
glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
if (!stat) {
GLchar log[1000];
GLsizei len;
glGetProgramInfoLog_func(prog, 1000, &len, log);
fprintf(stderr, "Linker error:\n%s\n", log);
}
else {
fprintf(stderr, "Link success!\n");
}
}
static void
Init(void)
{
const char *version;
GLint i;
version = (const char *) glGetString(GL_VERSION);
if (version[0] != '2' || version[1] != '.') {
printf("Warning: this program expects OpenGL 2.0\n");
/*exit(1);*/
}
GetExtensionFuncs();
vertShader = glCreateShader_func(GL_VERTEX_SHADER);
ReadShader(vertShader, VertProgFile);
fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
ReadShader(fragShader, FragProgFile);
program = glCreateProgram_func();
glAttachShader_func(program, fragShader);
glAttachShader_func(program, vertShader);
glLinkProgram_func(program);
CheckLink(program);
glUseProgram_func(program);
for (i = 0; Uniforms[i].name; i++) {
Uniforms[i].location
= glGetUniformLocation_func(program, Uniforms[i].name);
printf("Uniform %s location: %d\n", Uniforms[i].name,
Uniforms[i].location);
switch (Uniforms[i].size) {
case 1:
glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value);
break;
case 2:
glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value);
break;
case 3:
glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value);
break;
case 4:
glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value);
break;
default:
abort();
}
}
uZoom = glGetUniformLocation_func(program, "Zoom");
uXcenter = glGetUniformLocation_func(program, "Xcenter");
uYcenter = glGetUniformLocation_func(program, "Ycenter");
assert(glGetError() == 0);
glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
assert(glIsProgram_func(program));
assert(glIsShader_func(fragShader));
assert(glIsShader_func(vertShader));
glColor3f(1, 0, 0);
}
static void
ParseOptions(int argc, char *argv[])
{
int i;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-fs") == 0) {
FragProgFile = argv[i+1];
}
else if (strcmp(argv[i], "-vs") == 0) {
VertProgFile = argv[i+1];
}
}
}
int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowPosition( 0, 0);
glutInitWindowSize(400, 400);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
win = glutCreateWindow(argv[0]);
glutReshapeFunc(Reshape);
glutKeyboardFunc(Key);
glutSpecialFunc(SpecialKey);
glutDisplayFunc(Redisplay);
ParseOptions(argc, argv);
Init();
glutMainLoop();
return 0;
}

297
progs/glsl/noise.c Normal file
View file

@ -0,0 +1,297 @@
/**
* Test noise() functions.
* 28 Jan 2007
*/
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <GL/glext.h>
#include "extfuncs.h"
static const char *VertShaderText =
"void main() {\n"
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
" gl_TexCoord[0] = gl_MultiTexCoord0;\n"
"}\n";
static const char *FragShaderText =
"uniform vec4 Scale, Bias;\n"
"uniform float Slice;\n"
"void main()\n"
"{\n"
" vec4 scale = vec4(5.0);\n"
" vec4 p;\n"
" p.xy = gl_TexCoord[0].xy;\n"
" p.z = Slice;\n"
" vec4 n = noise4(p * scale);\n"
" gl_FragColor = n * Scale + Bias;\n"
"}\n";
struct uniform_info {
const char *name;
GLuint size;
GLint location;
GLfloat value[4];
};
static struct uniform_info Uniforms[] = {
{ "Scale", 4, -1, { 0.5, 0.4, 0.0, 0} },
{ "Bias", 4, -1, { 0.5, 0.3, 0.0, 0} },
{ "Slice", 1, -1, { 0.5, 0, 0, 0} },
{ NULL, 0, 0, { 0, 0, 0, 0 } }
};
/* program/shader objects */
static GLuint fragShader;
static GLuint vertShader;
static GLuint program;
static GLint win = 0;
static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f;
static GLfloat Slice = 0.0;
static GLboolean Anim = GL_FALSE;
static void
Idle(void)
{
Slice += 0.01;
glutPostRedisplay();
}
static void
Redisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUniform1fv_func(Uniforms[2].location, 1, &Slice);
glPushMatrix();
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
glRotatef(zRot, 0.0f, 0.0f, 1.0f);
glBegin(GL_POLYGON);
glTexCoord2f(0, 0); glVertex2f(-2, -2);
glTexCoord2f(1, 0); glVertex2f( 2, -2);
glTexCoord2f(1, 1); glVertex2f( 2, 2);
glTexCoord2f(0, 1); glVertex2f(-2, 2);
glEnd();
glPopMatrix();
glutSwapBuffers();
}
static void
Reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -15.0f);
}
static void
CleanUp(void)
{
glDeleteShader_func(fragShader);
glDeleteShader_func(vertShader);
glDeleteProgram_func(program);
glutDestroyWindow(win);
}
static void
Key(unsigned char key, int x, int y)
{
const GLfloat step = 0.01;
(void) x;
(void) y;
switch(key) {
case 'a':
Anim = !Anim;
glutIdleFunc(Anim ? Idle : NULL);
case 's':
Slice -= step;
break;
case 'S':
Slice += step;
break;
case 'z':
zRot -= 1.0;
break;
case 'Z':
zRot += 1.0;
break;
case 27:
CleanUp();
exit(0);
break;
}
glutPostRedisplay();
}
static void
SpecialKey(int key, int x, int y)
{
const GLfloat step = 3.0f;
(void) x;
(void) y;
switch(key) {
case GLUT_KEY_UP:
xRot -= step;
break;
case GLUT_KEY_DOWN:
xRot += step;
break;
case GLUT_KEY_LEFT:
yRot -= step;
break;
case GLUT_KEY_RIGHT:
yRot += step;
break;
}
glutPostRedisplay();
}
static void
LoadAndCompileShader(GLuint shader, const char *text)
{
GLint stat;
glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
glCompileShader_func(shader);
glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
if (!stat) {
GLchar log[1000];
GLsizei len;
glGetShaderInfoLog_func(shader, 1000, &len, log);
fprintf(stderr, "brick: problem compiling shader: %s\n", log);
exit(1);
}
else {
printf("Shader compiled OK\n");
}
}
static void
CheckLink(GLuint prog)
{
GLint stat;
glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
if (!stat) {
GLchar log[1000];
GLsizei len;
glGetProgramInfoLog_func(prog, 1000, &len, log);
fprintf(stderr, "Linker error:\n%s\n", log);
}
else {
fprintf(stderr, "Link success!\n");
}
}
static void
Init(void)
{
const char *version;
GLint i;
version = (const char *) glGetString(GL_VERSION);
if (version[0] != '2' || version[1] != '.') {
printf("Warning: this program expects OpenGL 2.0\n");
/*exit(1);*/
}
GetExtensionFuncs();
vertShader = glCreateShader_func(GL_VERTEX_SHADER);
LoadAndCompileShader(vertShader, VertShaderText);
fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
LoadAndCompileShader(fragShader, FragShaderText);
program = glCreateProgram_func();
glAttachShader_func(program, fragShader);
glAttachShader_func(program, vertShader);
glLinkProgram_func(program);
CheckLink(program);
glUseProgram_func(program);
for (i = 0; Uniforms[i].name; i++) {
Uniforms[i].location
= glGetUniformLocation_func(program, Uniforms[i].name);
printf("Uniform %s location: %d\n", Uniforms[i].name,
Uniforms[i].location);
switch (Uniforms[i].size) {
case 1:
glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value);
break;
case 2:
glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value);
break;
case 3:
glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value);
break;
case 4:
glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value);
break;
default:
abort();
}
}
assert(glGetError() == 0);
glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
assert(glIsProgram_func(program));
assert(glIsShader_func(fragShader));
assert(glIsShader_func(vertShader));
glColor3f(1, 0, 0);
}
int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowPosition( 0, 0);
glutInitWindowSize(400, 400);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
win = glutCreateWindow(argv[0]);
glutReshapeFunc(Reshape);
glutKeyboardFunc(Key);
glutSpecialFunc(SpecialKey);
glutDisplayFunc(Redisplay);
Init();
glutMainLoop();
return 0;
}

View file

@ -0,0 +1,19 @@
// Vertex shader for cube-texture reflection mapping
// Brian Paul
varying vec3 normal;
void main()
{
vec3 n = gl_NormalMatrix * gl_Normal;
vec3 u = normalize(vec3(gl_ModelViewMatrix * gl_Vertex));
float two_n_dot_u = 2.0 * dot(n, u);
vec4 f;
f.xyz = u - n * two_n_dot_u;
// outputs
normal = n;
gl_TexCoord[0] = gl_TextureMatrix[0] * f;
gl_Position = ftransform();
}

View file

@ -0,0 +1,21 @@
// Fragment shader for 2D texture with shadow attenuation
// Brian Paul
uniform sampler2D tex2d;
uniform vec3 lightPos;
void main()
{
// XXX should compute this from lightPos
vec2 shadowCenter = vec2(-0.25, -0.25);
// d = distance from center
float d = distance(gl_TexCoord[0].xy, shadowCenter);
// attenuate and clamp
d = clamp(d * d * d, 0.0, 2.0);
// modulate texture by d for shadow effect
gl_FragColor = d * texture2D(tex2d, gl_TexCoord[0].xy, 0.0);
}

View file

@ -0,0 +1,9 @@
// Simple vertex shader
// Brian Paul
void main()
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}

570
progs/glsl/texdemo1.c Normal file
View file

@ -0,0 +1,570 @@
/**
* Test texturing with GL shading language.
*
* Copyright (C) 2007 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "GL/glut.h"
#include "readtex.h"
#include "extfuncs.h"
static const char *Demo = "texdemo1";
static const char *ReflectVertFile = "reflect.vert.txt";
static const char *CubeFragFile = "cubemap.frag.txt";
static const char *SimpleVertFile = "simple.vert.txt";
static const char *SimpleTexFragFile = "shadowtex.frag.txt";
static const char *GroundImage = "../images/tile.rgb";
static GLuint Program1, Program2;
static GLfloat TexXrot = 0, TexYrot = 0;
static GLfloat Xrot = 20.0, Yrot = 20.0, Zrot = 0.0;
static GLfloat EyeDist = 10;
static GLboolean Anim = GL_TRUE;
struct uniform_info {
const char *name;
GLuint size;
GLint location;
GLenum type; /**< GL_FLOAT or GL_INT */
GLfloat value[4];
};
static struct uniform_info ReflectUniforms[] = {
{ "cubeTex", 1, -1, GL_INT, { 0, 0, 0, 0 } },
{ "lightPos", 3, -1, GL_FLOAT, { 10, 10, 20, 0 } },
{ NULL, 0, 0, 0, { 0, 0, 0, 0 } }
};
static struct uniform_info SimpleUniforms[] = {
{ "tex2d", 1, -1, GL_INT, { 1, 0, 0, 0 } },
{ "lightPos", 3, -1, GL_FLOAT, { 10, 10, 20, 0 } },
{ NULL, 0, 0, 0, { 0, 0, 0, 0 } }
};
static void
CheckError(int line)
{
GLenum err = glGetError();
if (err) {
printf("GL Error %s (0x%x) at line %d\n",
gluErrorString(err), (int) err, line);
}
}
static void
DrawGround(GLfloat size)
{
glPushMatrix();
glRotatef(90, 1, 0, 0);
glNormal3f(0, 0, 1);
glBegin(GL_POLYGON);
glTexCoord2f(-2, -2); glVertex2f(-size, -size);
glTexCoord2f( 2, -2); glVertex2f( size, -size);
glTexCoord2f( 2, 2); glVertex2f( size, size);
glTexCoord2f(-2, 2); glVertex2f(-size, size);
glEnd();
glPopMatrix();
}
static void
draw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glPushMatrix(); /* modelview matrix */
glTranslatef(0.0, 0.0, -EyeDist);
glRotatef(Xrot, 1, 0, 0);
glRotatef(Yrot, 0, 1, 0);
glRotatef(Zrot, 0, 0, 1);
/* sphere w/ reflection map */
glPushMatrix();
glTranslatef(0, 1, 0);
glUseProgram_func(Program1);
/* setup texture matrix */
glActiveTexture(GL_TEXTURE0);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glRotatef(-TexYrot, 0, 1, 0);
glRotatef(-TexXrot, 1, 0, 0);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glutSolidSphere(2.0, 20, 20);
glLoadIdentity(); /* texture matrix */
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
/* ground */
glUseProgram_func(Program2);
glTranslatef(0, -1.0, 0);
DrawGround(5);
glPopMatrix();
glutSwapBuffers();
}
static void
idle(void)
{
GLfloat t = 0.05 * glutGet(GLUT_ELAPSED_TIME);
TexYrot = t;
glutPostRedisplay();
}
static void
key(unsigned char k, int x, int y)
{
(void) x;
(void) y;
switch (k) {
case ' ':
case 'a':
Anim = !Anim;
if (Anim)
glutIdleFunc(idle);
else
glutIdleFunc(NULL);
break;
case 'z':
EyeDist -= 0.5;
if (EyeDist < 6.0)
EyeDist = 6.0;
break;
case 'Z':
EyeDist += 0.5;
if (EyeDist > 90.0)
EyeDist = 90;
break;
case 27:
exit(0);
}
glutPostRedisplay();
}
static void
specialkey(int key, int x, int y)
{
GLfloat step = 2.0;
(void) x;
(void) y;
switch (key) {
case GLUT_KEY_UP:
Xrot += step;
break;
case GLUT_KEY_DOWN:
Xrot -= step;
break;
case GLUT_KEY_LEFT:
Yrot -= step;
break;
case GLUT_KEY_RIGHT:
Yrot += step;
break;
}
glutPostRedisplay();
}
/* new window size or exposure */
static void
Reshape(int width, int height)
{
GLfloat ar = (float) width / (float) height;
glViewport(0, 0, (GLint)width, (GLint)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-2.0*ar, 2.0*ar, -2.0, 2.0, 4.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
static void
InitCheckers(void)
{
#define CUBE_TEX_SIZE 64
GLubyte image[CUBE_TEX_SIZE][CUBE_TEX_SIZE][3];
static const GLubyte colors[6][3] = {
{ 255, 0, 0 }, /* face 0 - red */
{ 0, 255, 255 }, /* face 1 - cyan */
{ 0, 255, 0 }, /* face 2 - green */
{ 255, 0, 255 }, /* face 3 - purple */
{ 0, 0, 255 }, /* face 4 - blue */
{ 255, 255, 0 } /* face 5 - yellow */
};
static const GLenum targets[6] = {
GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
};
GLint i, j, f;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
/* make colored checkerboard cube faces */
for (f = 0; f < 6; f++) {
for (i = 0; i < CUBE_TEX_SIZE; i++) {
for (j = 0; j < CUBE_TEX_SIZE; j++) {
if ((i/4 + j/4) & 1) {
image[i][j][0] = colors[f][0];
image[i][j][1] = colors[f][1];
image[i][j][2] = colors[f][2];
}
else {
image[i][j][0] = 255;
image[i][j][1] = 255;
image[i][j][2] = 255;
}
}
}
glTexImage2D(targets[f], 0, GL_RGB, CUBE_TEX_SIZE, CUBE_TEX_SIZE, 0,
GL_RGB, GL_UNSIGNED_BYTE, image);
}
}
static void
LoadFace(GLenum target, const char *filename,
GLboolean flipTB, GLboolean flipLR)
{
GLint w, h;
GLenum format;
GLubyte *img = LoadRGBImage(filename, &w, &h, &format);
if (!img) {
printf("Error: couldn't load texture image %s\n", filename);
exit(1);
}
assert(format == GL_RGB);
/* <sigh> the way the texture cube mapping works, we have to flip
* images to make things look right.
*/
if (flipTB) {
const int stride = 3 * w;
GLubyte temp[3*1024];
int i;
for (i = 0; i < h / 2; i++) {
memcpy(temp, img + i * stride, stride);
memcpy(img + i * stride, img + (h - i - 1) * stride, stride);
memcpy(img + (h - i - 1) * stride, temp, stride);
}
}
if (flipLR) {
const int stride = 3 * w;
GLubyte temp[3];
GLubyte *row;
int i, j;
for (i = 0; i < h; i++) {
row = img + i * stride;
for (j = 0; j < w / 2; j++) {
int k = w - j - 1;
temp[0] = row[j*3+0];
temp[1] = row[j*3+1];
temp[2] = row[j*3+2];
row[j*3+0] = row[k*3+0];
row[j*3+1] = row[k*3+1];
row[j*3+2] = row[k*3+2];
row[k*3+0] = temp[0];
row[k*3+1] = temp[1];
row[k*3+2] = temp[2];
}
}
}
gluBuild2DMipmaps(target, GL_RGB, w, h, format, GL_UNSIGNED_BYTE, img);
free(img);
}
static void
LoadEnvmaps(void)
{
LoadFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, "right.rgb", GL_TRUE, GL_FALSE);
LoadFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, "left.rgb", GL_TRUE, GL_FALSE);
LoadFace(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, "top.rgb", GL_FALSE, GL_TRUE);
LoadFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, "bottom.rgb", GL_FALSE, GL_TRUE);
LoadFace(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, "front.rgb", GL_TRUE, GL_FALSE);
LoadFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, "back.rgb", GL_TRUE, GL_FALSE);
}
static void
InitTextures(GLboolean useImageFiles)
{
GLenum filter;
/*
* Env map
*/
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, 1);
if (useImageFiles) {
LoadEnvmaps();
filter = GL_LINEAR;
}
else {
InitCheckers();
filter = GL_NEAREST;
}
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, filter);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, filter);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
/*
* Ground texture
*/
{
GLint imgWidth, imgHeight;
GLenum imgFormat;
GLubyte *image = NULL;
image = LoadRGBImage(GroundImage, &imgWidth, &imgHeight, &imgFormat);
if (!image) {
printf("Couldn't read %s\n", GroundImage);
exit(0);
}
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 2);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, imgWidth, imgHeight,
imgFormat, GL_UNSIGNED_BYTE, image);
free(image);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
}
static void
LoadAndCompileShader(GLuint shader, const char *text)
{
GLint stat;
glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
glCompileShader_func(shader);
glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
if (!stat) {
GLchar log[1000];
GLsizei len;
glGetShaderInfoLog_func(shader, 1000, &len, log);
fprintf(stderr, "%s: problem compiling shader: %s\n", Demo, log);
exit(1);
}
else {
printf("Shader compiled OK\n");
}
}
/**
* Read a shader from a file.
*/
static void
ReadShader(GLuint shader, const char *filename)
{
const int max = 100*1000;
int n;
char *buffer = (char*) malloc(max);
FILE *f = fopen(filename, "r");
if (!f) {
fprintf(stderr, "%s: Unable to open shader file %s\n", Demo, filename);
exit(1);
}
n = fread(buffer, 1, max, f);
printf("%s: read %d bytes from shader file %s\n", Demo, n, filename);
if (n > 0) {
buffer[n] = 0;
LoadAndCompileShader(shader, buffer);
}
fclose(f);
free(buffer);
}
static void
CheckLink(GLuint prog)
{
GLint stat;
glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
if (!stat) {
GLchar log[1000];
GLsizei len;
glGetProgramInfoLog_func(prog, 1000, &len, log);
fprintf(stderr, "Linker error:\n%s\n", log);
}
else {
fprintf(stderr, "Link success!\n");
}
}
static GLuint
CreateProgram(const char *vertProgFile, const char *fragProgFile,
struct uniform_info *uniforms)
{
GLuint fragShader = 0, vertShader = 0, program = 0;
GLint i;
program = glCreateProgram_func();
if (vertProgFile) {
vertShader = glCreateShader_func(GL_VERTEX_SHADER);
ReadShader(vertShader, vertProgFile);
glAttachShader_func(program, vertShader);
}
if (fragProgFile) {
fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
ReadShader(fragShader, fragProgFile);
glAttachShader_func(program, fragShader);
}
glLinkProgram_func(program);
CheckLink(program);
glUseProgram_func(program);
assert(glIsProgram_func(program));
assert(glIsShader_func(fragShader));
assert(glIsShader_func(vertShader));
CheckError(__LINE__);
for (i = 0; uniforms[i].name; i++) {
uniforms[i].location
= glGetUniformLocation_func(program, uniforms[i].name);
printf("Uniform %s location: %d\n", uniforms[i].name,
uniforms[i].location);
switch (uniforms[i].size) {
case 1:
if (uniforms[i].type == GL_INT)
glUniform1i_func(uniforms[i].location,
(GLint) uniforms[i].value[0]);
else
glUniform1fv_func(uniforms[i].location, 1, uniforms[i].value);
break;
case 2:
glUniform2fv_func(uniforms[i].location, 1, uniforms[i].value);
break;
case 3:
glUniform3fv_func(uniforms[i].location, 1, uniforms[i].value);
break;
case 4:
glUniform4fv_func(uniforms[i].location, 1, uniforms[i].value);
break;
default:
abort();
}
}
CheckError(__LINE__);
return program;
}
static void
InitPrograms(void)
{
Program1 = CreateProgram(ReflectVertFile, CubeFragFile, ReflectUniforms);
Program2 = CreateProgram(SimpleVertFile, SimpleTexFragFile, SimpleUniforms);
}
static void
Init(GLboolean useImageFiles)
{
const char *version = (const char *) glGetString(GL_VERSION);
if (version[0] != '2' || version[1] != '.') {
printf("Warning: this program expects OpenGL 2.0\n");
/*exit(1);*/
}
printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
GetExtensionFuncs();
InitTextures(useImageFiles);
InitPrograms();
glEnable(GL_DEPTH_TEST);
glClearColor(.6, .6, .9, 0);
glColor3f(1.0, 1.0, 1.0);
}
int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(500, 400);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutCreateWindow(Demo);
glutReshapeFunc(Reshape);
glutKeyboardFunc(key);
glutSpecialFunc(specialkey);
glutDisplayFunc(draw);
if (Anim)
glutIdleFunc(idle);
if (argc > 1 && strcmp(argv[1] , "-i") == 0)
Init(1);
else
Init(0);
glutMainLoop();
return 0;
}

339
progs/glsl/toyball.c Normal file
View file

@ -0,0 +1,339 @@
/**
* "Toy Ball" shader demo. Uses the example shaders from
* chapter 11 of the OpenGL Shading Language "orange" book.
* 16 Jan 2007
*/
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <GL/glext.h>
#include "extfuncs.h"
static char *FragProgFile = "CH11-toyball.frag.txt";
static char *VertProgFile = "CH11-toyball.vert.txt";
/* program/shader objects */
static GLuint fragShader;
static GLuint vertShader;
static GLuint program;
struct uniform_info {
const char *name;
GLuint size;
GLint location;
GLfloat value[4];
};
static struct uniform_info Uniforms[] = {
{ "LightDir", 4, -1, { 0.57737, 0.57735, 0.57735, 0.0 } },
{ "HVector", 4, -1, { 0.32506, 0.32506, 0.88808, 0.0 } },
{ "BallCenter", 4, -1, { 0.0, 0.0, 0.0, 1.0 } },
{ "SpecularColor", 4, -1, { 0.4, 0.4, 0.4, 60.0 } },
{ "Red", 4, -1, { 0.6, 0.0, 0.0, 1.0 } },
{ "Blue", 4, -1, { 0.0, 0.3, 0.6, 1.0 } },
{ "Yellow", 4, -1, { 0.6, 0.5, 0.0, 1.0 } },
{ "HalfSpace0", 4, -1, { 1.0, 0.0, 0.0, 0.2 } },
{ "HalfSpace1", 4, -1, { 0.309016994, 0.951056516, 0.0, 0.2 } },
{ "HalfSpace2", 4, -1, { -0.809016994, 0.587785252, 0.0, 0.2 } },
{ "HalfSpace3", 4, -1, { -0.809016994, -0.587785252, 0.0, 0.2 } },
{ "HalfSpace4", 4, -1, { 0.309116994, -0.951056516, 0.0, 0.2 } },
{ "InOrOutInit", 1, -1, { -3.0, 0, 0, 0 } },
{ "StripeWidth", 1, -1, { 0.3, 0, 0, 0 } },
{ "FWidth", 1, -1, { 0.005, 0, 0, 0 } },
{ NULL, 0, 0, { 0, 0, 0, 0 } }
};
static GLint win = 0;
static GLboolean Anim = GL_FALSE;
static GLfloat TexRot = 0.0;
static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f;
static void
Idle(void)
{
TexRot += 2.0;
if (TexRot > 360.0)
TexRot -= 360.0;
glutPostRedisplay();
}
static void
Redisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
glRotatef(zRot, 0.0f, 0.0f, 1.0f);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glRotatef(TexRot, 0.0f, 1.0f, 0.0f);
glMatrixMode(GL_MODELVIEW);
glutSolidSphere(2.0, 20, 10);
glPopMatrix();
glFinish();
glFlush();
glutSwapBuffers();
}
static void
Reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -15.0f);
}
static void
CleanUp(void)
{
glDeleteShader_func(fragShader);
glDeleteShader_func(vertShader);
glDeleteProgram_func(program);
glutDestroyWindow(win);
}
static void
Key(unsigned char key, int x, int y)
{
const GLfloat step = 2.0;
(void) x;
(void) y;
switch(key) {
case 'a':
Anim = !Anim;
if (Anim)
glutIdleFunc(Idle);
else
glutIdleFunc(NULL);
break;
case 'z':
zRot += step;
break;
case 'Z':
zRot -= step;
break;
case 27:
CleanUp();
exit(0);
break;
}
glutPostRedisplay();
}
static void
SpecialKey(int key, int x, int y)
{
const GLfloat step = 2.0;
(void) x;
(void) y;
switch(key) {
case GLUT_KEY_UP:
xRot += step;
break;
case GLUT_KEY_DOWN:
xRot -= step;
break;
case GLUT_KEY_LEFT:
yRot -= step;
break;
case GLUT_KEY_RIGHT:
yRot += step;
break;
}
glutPostRedisplay();
}
static void
LoadAndCompileShader(GLuint shader, const char *text)
{
GLint stat;
glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
glCompileShader_func(shader);
glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
if (!stat) {
GLchar log[1000];
GLsizei len;
glGetShaderInfoLog_func(shader, 1000, &len, log);
fprintf(stderr, "brick: problem compiling shader: %s\n", log);
exit(1);
}
else {
printf("Shader compiled OK\n");
}
}
/**
* Read a shader from a file.
*/
static void
ReadShader(GLuint shader, const char *filename)
{
const int max = 100*1000;
int n;
char *buffer = (char*) malloc(max);
FILE *f = fopen(filename, "r");
if (!f) {
fprintf(stderr, "brick: Unable to open shader file %s\n", filename);
exit(1);
}
n = fread(buffer, 1, max, f);
printf("brick: read %d bytes from shader file %s\n", n, filename);
if (n > 0) {
buffer[n] = 0;
LoadAndCompileShader(shader, buffer);
}
fclose(f);
free(buffer);
}
static void
CheckLink(GLuint prog)
{
GLint stat;
glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
if (!stat) {
GLchar log[1000];
GLsizei len;
glGetProgramInfoLog_func(prog, 1000, &len, log);
fprintf(stderr, "Linker error:\n%s\n", log);
}
else {
fprintf(stderr, "Link success!\n");
}
}
static void
Init(void)
{
const char *version;
GLint i;
version = (const char *) glGetString(GL_VERSION);
if (version[0] != '2' || version[1] != '.') {
printf("Warning: this program expects OpenGL 2.0\n");
/*exit(1);*/
}
printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
GetExtensionFuncs();
vertShader = glCreateShader_func(GL_VERTEX_SHADER);
ReadShader(vertShader, VertProgFile);
fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
ReadShader(fragShader, FragProgFile);
program = glCreateProgram_func();
glAttachShader_func(program, fragShader);
glAttachShader_func(program, vertShader);
glLinkProgram_func(program);
CheckLink(program);
glUseProgram_func(program);
assert(glIsProgram_func(program));
assert(glIsShader_func(fragShader));
assert(glIsShader_func(vertShader));
for (i = 0; Uniforms[i].name; i++) {
Uniforms[i].location
= glGetUniformLocation_func(program, Uniforms[i].name);
printf("Uniform %s location: %d\n", Uniforms[i].name,
Uniforms[i].location);
switch (Uniforms[i].size) {
case 1:
glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value);
break;
case 2:
glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value);
break;
case 3:
glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value);
break;
case 4:
glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value);
break;
default:
abort();
}
}
assert(glGetError() == 0);
glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
glEnable(GL_DEPTH_TEST);
glColor3f(1, 0, 0);
}
static void
ParseOptions(int argc, char *argv[])
{
int i;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-fs") == 0) {
FragProgFile = argv[i+1];
}
else if (strcmp(argv[i], "-vs") == 0) {
VertProgFile = argv[i+1];
}
}
}
int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowPosition( 0, 0);
glutInitWindowSize(400, 400);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
win = glutCreateWindow(argv[0]);
glutReshapeFunc(Reshape);
glutKeyboardFunc(Key);
glutSpecialFunc(SpecialKey);
glutDisplayFunc(Redisplay);
ParseOptions(argc, argv);
Init();
glutMainLoop();
return 0;
}

View file

@ -33,6 +33,7 @@ SOURCES = \
crossbar.c \
cva.c \
dinoshade.c \
drawbuffers.c \
floattex.c \
fbotest1.c \
fbotest2.c \
@ -122,6 +123,12 @@ afsmultiarb: afsmultiarb.o readtex.o
afsmultiarb.o: afsmultiarb.c readtex.h
$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
drawbuffers: drawbuffers.o
$(CC) $(CFLAGS) drawbuffers.o $(LIBS) -o $@
drawbuffers.o: drawbuffers.c extfuncs.h
$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
texrect: texrect.o readtex.o
$(CC) $(CFLAGS) texrect.o readtex.o $(LIBS) -o $@
@ -150,6 +157,8 @@ readtex.h: $(TOP)/progs/util/readtex.h
readtex.c: $(TOP)/progs/util/readtex.c
ln -s $(TOP)/progs/util/readtex.c .
extfuncs.h: $(TOP)/progs/util/extfuncs.h
ln -s $(TOP)/progs/util/extfuncs.h .

298
progs/tests/drawbuffers.c Normal file
View file

@ -0,0 +1,298 @@
/*
* Test GL_ARB_draw_buffers, GL_EXT_framebuffer_object
* and GLSL's gl_FragData[].
*
* Brian Paul
* 11 March 2007
*/
#define GL_GLEXT_PROTOTYPES
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include "extfuncs.h"
static int Win;
static int Width = 400, Height = 400;
static GLuint FBobject, RBobjects[3];
static GLfloat Xrot = 0.0, Yrot = 0.0;
static void
CheckError(int line)
{
GLenum err = glGetError();
if (err) {
printf("GL Error 0x%x at line %d\n", (int) err, line);
}
}
static void
Display(void)
{
GLubyte *buffer = malloc(Width * Height * 4);
static const GLenum buffers[2] = {
GL_COLOR_ATTACHMENT0_EXT,
GL_COLOR_ATTACHMENT1_EXT
};
/* draw to user framebuffer */
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBobject);
/* Clear color buffer 0 (blue) */
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
glClearColor(0.5, 0.5, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
/* Clear color buffer 1 (1 - blue) */
glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
glClearColor(0.5, 0.5, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glClear(GL_DEPTH_BUFFER_BIT);
/* draw to two buffers w/ fragment shader */
glDrawBuffersARB(2, buffers);
glPushMatrix();
glRotatef(Xrot, 1, 0, 0);
glRotatef(Yrot, 0, 1, 0);
glutSolidTorus(0.75, 2.0, 10, 20);
glPopMatrix();
/* read from user framebuffer */
/* bottom half = colorbuffer 0 */
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadPixels(0, 0, Width, Height / 2, GL_RGBA, GL_UNSIGNED_BYTE,
buffer);
/* top half = colorbuffer 1 */
glReadBuffer(GL_COLOR_ATTACHMENT1_EXT);
glReadPixels(0, Height/2, Width, Height / 2, GL_RGBA, GL_UNSIGNED_BYTE,
buffer + Width * Height / 2 * 4);
/* draw to window */
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glWindowPos2iARB(0, 0);
glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
free(buffer);
glutSwapBuffers();
CheckError(__LINE__);
}
static void
Reshape(int width, int height)
{
float ar = (float) width / (float) height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-ar, ar, -1.0, 1.0, 5.0, 35.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -20.0);
Width = width;
Height = height;
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[0]);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[1]);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[2]);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,
Width, Height);
}
static void
CleanUp(void)
{
glDeleteFramebuffersEXT(1, &FBobject);
glDeleteRenderbuffersEXT(3, RBobjects);
glutDestroyWindow(Win);
exit(0);
}
static void
Key(unsigned char key, int x, int y)
{
(void) x;
(void) y;
switch (key) {
case 'x':
Xrot += 5.0;
break;
case 'y':
Yrot += 5.0;
break;
case 27:
CleanUp();
break;
}
glutPostRedisplay();
}
static void
CheckExtensions(void)
{
const char *version = (const char *) glGetString(GL_VERSION);
GLint numBuf;
if (!glutExtensionSupported("GL_EXT_framebuffer_object")) {
printf("Sorry, GL_EXT_framebuffer_object is required!\n");
exit(1);
}
if (!glutExtensionSupported("GL_ARB_draw_buffers")) {
printf("Sorry, GL_ARB_draw_buffers is required!\n");
exit(1);
}
if (version[0] != '2') {
printf("Sorry, OpenGL 2.0 is required!\n");
exit(1);
}
glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &numBuf);
printf("GL_MAX_DRAW_BUFFERS_ARB = %d\n", numBuf);
if (numBuf < 2) {
printf("Sorry, GL_MAX_DRAW_BUFFERS_ARB needs to be >= 2\n");
exit(1);
}
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
}
static void
SetupRenderbuffers(void)
{
glGenFramebuffersEXT(1, &FBobject);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBobject);
glGenRenderbuffersEXT(3, RBobjects);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[0]);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[1]);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[2]);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,
Width, Height);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_RENDERBUFFER_EXT, RBobjects[0]);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT,
GL_RENDERBUFFER_EXT, RBobjects[1]);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, RBobjects[2]);
CheckError(__LINE__);
}
static GLuint
LoadAndCompileShader(GLenum target, const char *text)
{
GLint stat;
GLuint shader = glCreateShader_func(target);
glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
glCompileShader_func(shader);
glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
if (!stat) {
GLchar log[1000];
GLsizei len;
glGetShaderInfoLog_func(shader, 1000, &len, log);
fprintf(stderr, "drawbuffers: problem compiling shader:\n%s\n", log);
exit(1);
}
return shader;
}
static void
CheckLink(GLuint prog)
{
GLint stat;
glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
if (!stat) {
GLchar log[1000];
GLsizei len;
glGetProgramInfoLog_func(prog, 1000, &len, log);
fprintf(stderr, "drawbuffers: shader link error:\n%s\n", log);
}
}
static void
SetupShaders(void)
{
/* second color output = 1 - first color */
static const char *fragShaderText =
"void main() {\n"
" gl_FragData[0] = gl_Color; \n"
" gl_FragData[1] = vec4(1.0) - gl_Color; \n"
"}\n";
GLuint fragShader, program;
fragShader = LoadAndCompileShader(GL_FRAGMENT_SHADER, fragShaderText);
program = glCreateProgram_func();
glAttachShader_func(program, fragShader);
glLinkProgram_func(program);
CheckLink(program);
glUseProgram_func(program);
}
static void
SetupLighting(void)
{
static const GLfloat frontMat[4] = { 1.0, 0.5, 0.5, 1.0 };
static const GLfloat backMat[4] = { 1.0, 0.5, 0.5, 1.0 };
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, frontMat);
glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, backMat);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
}
static void
Init(void)
{
CheckExtensions();
GetExtensionFuncs();
SetupRenderbuffers();
SetupShaders();
SetupLighting();
glEnable(GL_DEPTH_TEST);
}
int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowPosition(0, 0);
glutInitWindowSize(Width, Height);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
Win = glutCreateWindow(argv[0]);
glutReshapeFunc(Reshape);
glutKeyboardFunc(Key);
glutDisplayFunc(Display);
Init();
glutMainLoop();
return 0;
}

118
progs/util/extfuncs.h Normal file
View file

@ -0,0 +1,118 @@
/**
* Utility for getting OpenGL extension function pointers
* Meant to be #included.
*/
/* OpenGL 2.0 */
static PFNGLATTACHSHADERPROC glAttachShader_func = NULL;
static PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation_func = NULL;
static PFNGLCOMPILESHADERPROC glCompileShader_func = NULL;
static PFNGLCREATEPROGRAMPROC glCreateProgram_func = NULL;
static PFNGLCREATESHADERPROC glCreateShader_func = NULL;
static PFNGLDELETEPROGRAMPROC glDeleteProgram_func = NULL;
static PFNGLDELETESHADERPROC glDeleteShader_func = NULL;
static PFNGLGETATTACHEDSHADERSPROC glGetAttachedShaders_func = NULL;
static PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation_func = NULL;
static PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog_func = NULL;
static PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog_func = NULL;
static PFNGLGETSHADERIVPROC glGetShaderiv_func = NULL;
static PFNGLGETPROGRAMIVPROC glGetProgramiv_func = NULL;
static PFNGLGETSHADERSOURCEPROC glGetShaderSource_func = NULL;
static PFNGLGETUNIFORMFVPROC glGetUniformfv_func = NULL;
static PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation_func = NULL;
static PFNGLISPROGRAMPROC glIsProgram_func = NULL;
static PFNGLISSHADERPROC glIsShader_func = NULL;
static PFNGLLINKPROGRAMPROC glLinkProgram_func = NULL;
static PFNGLSHADERSOURCEPROC glShaderSource_func = NULL;
static PFNGLUNIFORM1IPROC glUniform1i_func = NULL;
static PFNGLUNIFORM1FVPROC glUniform1fv_func = NULL;
static PFNGLUNIFORM2FVPROC glUniform2fv_func = NULL;
static PFNGLUNIFORM3FVPROC glUniform3fv_func = NULL;
static PFNGLUNIFORM4FVPROC glUniform4fv_func = NULL;
static PFNGLUNIFORMMATRIX2FVPROC glUniformMatrix2fv_func = NULL;
static PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv_func = NULL;
static PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv_func = NULL;
static PFNGLUSEPROGRAMPROC glUseProgram_func = NULL;
static PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f_func = NULL;
static PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f_func = NULL;
static PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f_func = NULL;
static PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f_func = NULL;
/* GL_ARB_vertex/fragment_program */
static PFNGLBINDPROGRAMARBPROC glBindProgramARB_func = NULL;
static PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB_func = NULL;
static PFNGLGENPROGRAMSARBPROC glGenProgramsARB_func = NULL;
static PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glGetProgramLocalParameterdvARB_func = NULL;
static PFNGLISPROGRAMARBPROC glIsProgramARB_func = NULL;
static PFNGLPROGRAMLOCALPARAMETER4DARBPROC glProgramLocalParameter4dARB_func = NULL;
static PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glProgramLocalParameter4fvARB_func = NULL;
static PFNGLPROGRAMSTRINGARBPROC glProgramStringARB_func = NULL;
static PFNGLVERTEXATTRIB1FARBPROC glVertexAttrib1fARB_func = NULL;
/* GL_APPLE_vertex_array_object */
static PFNGLBINDVERTEXARRAYAPPLEPROC glBindVertexArrayAPPLE_func = NULL;
static PFNGLDELETEVERTEXARRAYSAPPLEPROC glDeleteVertexArraysAPPLE_func = NULL;
static PFNGLGENVERTEXARRAYSAPPLEPROC glGenVertexArraysAPPLE_func = NULL;
static PFNGLISVERTEXARRAYAPPLEPROC glIsVertexArrayAPPLE_func = NULL;
static void
GetExtensionFuncs(void)
{
/* OpenGL 2.0 */
glAttachShader_func = (PFNGLATTACHSHADERPROC) glutGetProcAddress("glAttachShader");
glBindAttribLocation_func = (PFNGLBINDATTRIBLOCATIONPROC) glutGetProcAddress("glBindAttribLocation");
glCompileShader_func = (PFNGLCOMPILESHADERPROC) glutGetProcAddress("glCompileShader");
glCreateProgram_func = (PFNGLCREATEPROGRAMPROC) glutGetProcAddress("glCreateProgram");
glCreateShader_func = (PFNGLCREATESHADERPROC) glutGetProcAddress("glCreateShader");
glDeleteProgram_func = (PFNGLDELETEPROGRAMPROC) glutGetProcAddress("glDeleteProgram");
glDeleteShader_func = (PFNGLDELETESHADERPROC) glutGetProcAddress("glDeleteShader");
glGetAttachedShaders_func = (PFNGLGETATTACHEDSHADERSPROC) glutGetProcAddress("glGetAttachedShaders");
glGetAttribLocation_func = (PFNGLGETATTRIBLOCATIONPROC) glutGetProcAddress("glGetAttribLocation");
glGetProgramInfoLog_func = (PFNGLGETPROGRAMINFOLOGPROC) glutGetProcAddress("glGetProgramInfoLog");
glGetShaderInfoLog_func = (PFNGLGETSHADERINFOLOGPROC) glutGetProcAddress("glGetShaderInfoLog");
glGetProgramiv_func = (PFNGLGETPROGRAMIVPROC) glutGetProcAddress("glGetProgramiv");
glGetShaderiv_func = (PFNGLGETSHADERIVPROC) glutGetProcAddress("glGetShaderiv");
glGetShaderSource_func = (PFNGLGETSHADERSOURCEPROC) glutGetProcAddress("glGetShaderSource");
glGetUniformLocation_func = (PFNGLGETUNIFORMLOCATIONPROC) glutGetProcAddress("glGetUniformLocation");
glGetUniformfv_func = (PFNGLGETUNIFORMFVPROC) glutGetProcAddress("glGetUniformfv");
glIsProgram_func = (PFNGLISPROGRAMPROC) glutGetProcAddress("glIsProgram");
glIsShader_func = (PFNGLISSHADERPROC) glutGetProcAddress("glIsShader");
glLinkProgram_func = (PFNGLLINKPROGRAMPROC) glutGetProcAddress("glLinkProgram");
glShaderSource_func = (PFNGLSHADERSOURCEPROC) glutGetProcAddress("glShaderSource");
glUniform1i_func = (PFNGLUNIFORM1IPROC) glutGetProcAddress("glUniform1i");
glUniform1fv_func = (PFNGLUNIFORM1FVPROC) glutGetProcAddress("glUniform1fv");
glUniform2fv_func = (PFNGLUNIFORM2FVPROC) glutGetProcAddress("glUniform2fv");
glUniform3fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform3fv");
glUniform4fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform4fv");
glUniformMatrix2fv_func = (PFNGLUNIFORMMATRIX2FVPROC) glutGetProcAddress("glUniformMatrix2fv");
glUniformMatrix3fv_func = (PFNGLUNIFORMMATRIX3FVPROC) glutGetProcAddress("glUniformMatrix3fv");
glUniformMatrix4fv_func = (PFNGLUNIFORMMATRIX4FVPROC) glutGetProcAddress("glUniformMatrix4fv");
glUseProgram_func = (PFNGLUSEPROGRAMPROC) glutGetProcAddress("glUseProgram");
glVertexAttrib1f_func = (PFNGLVERTEXATTRIB1FPROC) glutGetProcAddress("glVertexAttrib1f");
glVertexAttrib2f_func = (PFNGLVERTEXATTRIB2FPROC) glutGetProcAddress("glVertexAttrib2f");
glVertexAttrib3f_func = (PFNGLVERTEXATTRIB3FPROC) glutGetProcAddress("glVertexAttrib3f");
glVertexAttrib4f_func = (PFNGLVERTEXATTRIB4FPROC) glutGetProcAddress("glVertexAttrib4f");
/* GL_ARB_vertex/fragment_program */
glBindProgramARB_func = (PFNGLBINDPROGRAMARBPROC) glutGetProcAddress("glBindProgramARB");
glDeleteProgramsARB_func = (PFNGLDELETEPROGRAMSARBPROC) glutGetProcAddress("glDeleteProgramsARB");
glGenProgramsARB_func = (PFNGLGENPROGRAMSARBPROC) glutGetProcAddress("glGenProgramsARB");
glGetProgramLocalParameterdvARB_func = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) glutGetProcAddress("glGetProgramLocalParameterdvARB");
glIsProgramARB_func = (PFNGLISPROGRAMARBPROC) glutGetProcAddress("glIsProgramARB");
glProgramLocalParameter4dARB_func = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC) glutGetProcAddress("glProgramLocalParameter4dARB");
glProgramLocalParameter4fvARB_func = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) glutGetProcAddress("glProgramLocalParameter4fvARB");
glProgramStringARB_func = (PFNGLPROGRAMSTRINGARBPROC) glutGetProcAddress("glProgramStringARB");
glVertexAttrib1fARB_func = (PFNGLVERTEXATTRIB1FARBPROC) glutGetProcAddress("glVertexAttrib1fARB");
/* GL_APPLE_vertex_array_object */
glBindVertexArrayAPPLE_func = (PFNGLBINDVERTEXARRAYAPPLEPROC) glutGetProcAddress("glBindVertexArrayAPPLE");
glDeleteVertexArraysAPPLE_func = (PFNGLDELETEVERTEXARRAYSAPPLEPROC) glutGetProcAddress("glDeleteVertexArraysAPPLE");
glGenVertexArraysAPPLE_func = (PFNGLGENVERTEXARRAYSAPPLEPROC) glutGetProcAddress("glGenVertexArraysAPPLE");
glIsVertexArrayAPPLE_func = (PFNGLISVERTEXARRAYAPPLEPROC) glutGetProcAddress("glIsVertexArrayAPPLE");
}

View file

@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
* Version: 6.5
* Version: 6.5.3
*
* Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -30,6 +30,7 @@
#include "framebuffer.h"
#include "occlude.h"
#include "program.h"
#include "prog_execute.h"
#include "renderbuffer.h"
#include "texcompress.h"
#include "texformat.h"
@ -43,6 +44,7 @@
#include "fbobject.h"
#include "texrender.h"
#endif
#include "shader_api.h"
#include "arrayobj.h"
#include "driverfuncs.h"
@ -127,7 +129,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
driver->NewProgram = _mesa_new_program;
driver->DeleteProgram = _mesa_delete_program;
#if FEATURE_MESA_program_debug
driver->GetFragmentProgramRegister = _swrast_get_program_register;
driver->GetProgramRegister = _mesa_get_program_register;
#endif /* FEATURE_MESA_program_debug */
/* simple state commands */
@ -248,4 +250,45 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
driver->EndList = NULL;
driver->BeginCallList = NULL;
driver->EndCallList = NULL;
/* XXX temporary here */
_mesa_init_glsl_driver_functions(driver);
}
/**
* Plug in Mesa's GLSL functions.
*/
void
_mesa_init_glsl_driver_functions(struct dd_function_table *driver)
{
driver->AttachShader = _mesa_attach_shader;
driver->BindAttribLocation = _mesa_bind_attrib_location;
driver->CompileShader = _mesa_compile_shader;
driver->CreateProgram = _mesa_create_program;
driver->CreateShader = _mesa_create_shader;
driver->DeleteProgram2 = _mesa_delete_program2;
driver->DeleteShader = _mesa_delete_shader;
driver->DetachShader = _mesa_detach_shader;
driver->GetActiveAttrib = _mesa_get_active_attrib;
driver->GetActiveUniform = _mesa_get_active_uniform;
driver->GetAttachedShaders = _mesa_get_attached_shaders;
driver->GetAttribLocation = _mesa_get_attrib_location;
driver->GetHandle = _mesa_get_handle;
driver->GetProgramiv = _mesa_get_programiv;
driver->GetProgramInfoLog = _mesa_get_program_info_log;
driver->GetShaderiv = _mesa_get_shaderiv;
driver->GetShaderInfoLog = _mesa_get_shader_info_log;
driver->GetShaderSource = _mesa_get_shader_source;
driver->GetUniformfv = _mesa_get_uniformfv;
driver->GetUniformLocation = _mesa_get_uniform_location;
driver->IsProgram = _mesa_is_program;
driver->IsShader = _mesa_is_shader;
driver->LinkProgram = _mesa_link_program;
driver->ShaderSource = _mesa_shader_source;
driver->Uniform = _mesa_uniform;
driver->UniformMatrix = _mesa_uniform_matrix;
driver->UseProgram = _mesa_use_program;
driver->ValidateProgram = _mesa_validate_program;
}

View file

@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
* Version: 6.1
* Version: 6.5.3
*
* Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -29,4 +29,8 @@
extern void
_mesa_init_driver_functions(struct dd_function_table *driver);
extern void
_mesa_init_glsl_driver_functions(struct dd_function_table *driver);
#endif

View file

@ -167,8 +167,7 @@ GLboolean i915CreateContext( const __GLcontextModes *mesaVis,
I915_MAX_TEX_INSN);
ctx->Const.FragmentProgram.MaxNativeTexIndirections = I915_MAX_TEX_INDIRECT;
ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* I don't think we have one */
ctx->_MaintainTexEnvProgram = 1;
ctx->_UseTexEnvProgram = 1;
ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
driInitExtensions( ctx, i915_extensions, GL_FALSE );

View file

@ -37,7 +37,8 @@
#include "i915_context.h"
#include "i915_program.h"
#include "program_instruction.h"
#include "prog_instruction.h"
#include "prog_parameter.h"
#include "program.h"
#include "programopt.h"
@ -782,9 +783,6 @@ static void fixup_depth_write( struct i915_fragment_program *p )
}
#define FRAG_BIT_TEX(n) (FRAG_BIT_TEX0 << (n))
static void check_wpos( struct i915_fragment_program *p )
{
GLuint inputs = p->FragProg.Base.InputsRead;

View file

@ -430,17 +430,17 @@ void i915_fini_program( struct i915_fragment_program *p )
if (p->error) {
p->FragProg.Base.NumNativeInstructions = 0;
p->FragProg.NumNativeAluInstructions = 0;
p->FragProg.NumNativeTexInstructions = 0;
p->FragProg.NumNativeTexIndirections = 0;
p->FragProg.Base.NumNativeAluInstructions = 0;
p->FragProg.Base.NumNativeTexInstructions = 0;
p->FragProg.Base.NumNativeTexIndirections = 0;
}
else {
p->FragProg.Base.NumNativeInstructions = (p->nr_alu_insn +
p->nr_tex_insn +
p->nr_decl_insn);
p->FragProg.NumNativeAluInstructions = p->nr_alu_insn;
p->FragProg.NumNativeTexInstructions = p->nr_tex_insn;
p->FragProg.NumNativeTexIndirections = p->nr_tex_indirect;
p->FragProg.Base.NumNativeAluInstructions = p->nr_alu_insn;
p->FragProg.Base.NumNativeTexInstructions = p->nr_tex_insn;
p->FragProg.Base.NumNativeTexIndirections = p->nr_tex_indirect;
}
p->declarations[0] |= program_size + decl_size - 2;

View file

@ -531,7 +531,7 @@ void i915_update_fog( GLcontext *ctx )
GLboolean enabled;
GLboolean try_pixel_fog;
if (ctx->FragmentProgram._Active) {
if (ctx->FragmentProgram._Enabled) {
/* Pull in static fog state from program */
mode = ctx->FragmentProgram._Current->FogOption;

View file

@ -46,10 +46,10 @@ static void i915_render_start( intelContextPtr intel )
GLcontext *ctx = &intel->ctx;
i915ContextPtr i915 = I915_CONTEXT(intel);
if (ctx->FragmentProgram._Active)
if (ctx->FragmentProgram._Current)
i915ValidateFragmentProgram( i915 );
else {
assert(!ctx->_MaintainTexEnvProgram);
assert(!ctx->FragmentProgram._MaintainTexEnvProgram);
i915ValidateTextureProgram( i915 );
}
}

View file

@ -157,8 +157,8 @@ i915CreateContext(const __GLcontextModes * mesaVis,
I915_MAX_TEX_INDIRECT;
ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* I don't think we have one */
ctx->_MaintainTexEnvProgram = 1;
ctx->_UseTexEnvProgram = 1;
ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
/*ctx->_UseTexEnvProgram = 1;*/
driInitExtensions(ctx, i915_extensions, GL_FALSE);

View file

@ -37,7 +37,8 @@
#include "i915_context.h"
#include "i915_program.h"
#include "program_instruction.h"
#include "prog_instruction.h"
#include "prog_parameter.h"
#include "program.h"
#include "programopt.h"
@ -772,9 +773,6 @@ fixup_depth_write(struct i915_fragment_program *p)
}
#define FRAG_BIT_TEX(n) (FRAG_BIT_TEX0 << (n))
static void
check_wpos(struct i915_fragment_program *p)
{

View file

@ -446,17 +446,17 @@ i915_fini_program(struct i915_fragment_program *p)
if (p->error) {
p->FragProg.Base.NumNativeInstructions = 0;
p->FragProg.NumNativeAluInstructions = 0;
p->FragProg.NumNativeTexInstructions = 0;
p->FragProg.NumNativeTexIndirections = 0;
p->FragProg.Base.NumNativeAluInstructions = 0;
p->FragProg.Base.NumNativeTexInstructions = 0;
p->FragProg.Base.NumNativeTexIndirections = 0;
}
else {
p->FragProg.Base.NumNativeInstructions = (p->nr_alu_insn +
p->nr_tex_insn +
p->nr_decl_insn);
p->FragProg.NumNativeAluInstructions = p->nr_alu_insn;
p->FragProg.NumNativeTexInstructions = p->nr_tex_insn;
p->FragProg.NumNativeTexIndirections = p->nr_tex_indirect;
p->FragProg.Base.NumNativeAluInstructions = p->nr_alu_insn;
p->FragProg.Base.NumNativeTexInstructions = p->nr_tex_insn;
p->FragProg.Base.NumNativeTexIndirections = p->nr_tex_indirect;
}
p->declarations[0] |= program_size + decl_size - 2;

View file

@ -561,7 +561,7 @@ i915_update_fog(GLcontext * ctx)
GLboolean enabled;
GLboolean try_pixel_fog;
if (ctx->FragmentProgram._Active) {
if (ctx->FragmentProgram._Enabled) {
/* Pull in static fog state from program */
mode = ctx->FragmentProgram._Current->FogOption;

View file

@ -148,7 +148,7 @@ GLboolean brwCreateContext( const __GLcontextModes *mesaVis,
brw->emit_state_always = 0;
ctx->_MaintainTexEnvProgram = 1;
ctx->FragmentProgram._MaintainTexEnvProgram = 1;
brw_draw_init( brw );

View file

@ -35,7 +35,8 @@
#include "context.h"
#include "macros.h"
#include "enums.h"
#include "shader/program.h"
#include "shader/prog_parameter.h"
#include "shader/prog_statevars.h"
#include "intel_batchbuffer.h"
#include "brw_context.h"
#include "brw_defines.h"

View file

@ -35,7 +35,7 @@
#include "brw_structs.h"
#include "brw_defines.h"
#include "shader/program.h"
#include "shader/prog_instruction.h"
#define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
#define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)

View file

@ -35,8 +35,6 @@
#include "glheader.h"
#include "context.h"
#include "macros.h"
#include "enums.h"
#include "dd.h"
#include "shader/arbprogparse.h"

View file

@ -30,9 +30,9 @@
*/
#include "brw_util.h"
#include "mtypes.h"
#include "shader/program.h"
#include "shader/prog_parameter.h"
#include "brw_util.h"
#include "brw_defines.h"
GLuint brw_count_bits( GLuint val )
@ -45,7 +45,7 @@ GLuint brw_count_bits( GLuint val )
}
static GLuint brw_parameter_state_flags(const enum state_index state[])
static GLuint brw_parameter_state_flags(const gl_state_index state[])
{
switch (state[0]) {
case STATE_MATERIAL:
@ -70,22 +70,16 @@ static GLuint brw_parameter_state_flags(const enum state_index state[])
case STATE_POINT_ATTENUATION:
return _NEW_POINT;
case STATE_MATRIX:
switch (state[1]) {
case STATE_MODELVIEW:
return _NEW_MODELVIEW;
case STATE_PROJECTION:
return _NEW_PROJECTION;
case STATE_MVP:
return _NEW_MODELVIEW | _NEW_PROJECTION;
case STATE_TEXTURE:
return _NEW_TEXTURE_MATRIX;
case STATE_PROGRAM:
return _NEW_TRACK_MATRIX;
default:
assert(0);
return 0;
}
case STATE_MODELVIEW_MATRIX:
return _NEW_MODELVIEW;
case STATE_PROJECTION_MATRIX:
return _NEW_PROJECTION;
case STATE_MVP_MATRIX:
return _NEW_MODELVIEW | _NEW_PROJECTION;
case STATE_TEXTURE_MATRIX:
return _NEW_TEXTURE_MATRIX;
case STATE_PROGRAM_MATRIX:
return _NEW_TRACK_MATRIX;
case STATE_DEPTH_RANGE:
return _NEW_VIEWPORT;

View file

@ -34,8 +34,7 @@
#include "brw_vs.h"
#include "brw_util.h"
#include "brw_state.h"
#include "program.h"
#include "shader/arbprogparse.h"
#include "shader/prog_print.h"

View file

@ -30,10 +30,8 @@
*/
#include "brw_context.h"
#include "program.h"
#include "program_instruction.h"
#include "macros.h"
#include "brw_context.h"
#include "brw_vs.h"
/* Component is active if it may diverge from [0,0,0,1]. Undef values

View file

@ -30,10 +30,11 @@
*/
#include "brw_context.h"
#include "program.h"
#include "program_instruction.h"
#include "macros.h"
#include "shader/prog_parameter.h"
#include "shader/prog_print.h"
#include "brw_context.h"
#include "brw_vs.h"

View file

@ -33,12 +33,11 @@
#include "glheader.h"
#include "macros.h"
#include "enums.h"
#include "shader/prog_parameter.h"
#include "shader/prog_print.h"
#include "brw_vs.h"
#include "brw_state.h"
#include "shader/program.h"
#include "shader/program_instruction.h"
#include "shader/arbprogparse.h"
struct state_key {
unsigned light_global_enabled:1;
@ -398,11 +397,14 @@ static struct ureg register_const4f( struct tnl_program *p,
{
GLfloat values[4];
GLint idx;
GLuint swizzle;
values[0] = s0;
values[1] = s1;
values[2] = s2;
values[3] = s3;
idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4 );
idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4,
&swizzle);
/* XXX what about swizzle? */
return make_ureg(PROGRAM_STATE_VAR, idx);
}
@ -424,40 +426,37 @@ static struct ureg get_identity_param( struct tnl_program *p )
return p->identity;
}
static struct ureg register_param6( struct tnl_program *p,
GLint s0,
GLint s1,
GLint s2,
GLint s3,
GLint s4,
GLint s5)
static struct ureg register_param5( struct tnl_program *p,
GLint s0,
GLint s1,
GLint s2,
GLint s3,
GLint s4)
{
GLint tokens[6];
gl_state_index tokens[STATE_LENGTH];
GLint idx;
tokens[0] = s0;
tokens[1] = s1;
tokens[2] = s2;
tokens[3] = s3;
tokens[4] = s4;
tokens[5] = s5;
idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens );
return make_ureg(PROGRAM_STATE_VAR, idx);
}
#define register_param1(p,s0) register_param6(p,s0,0,0,0,0,0)
#define register_param2(p,s0,s1) register_param6(p,s0,s1,0,0,0,0)
#define register_param3(p,s0,s1,s2) register_param6(p,s0,s1,s2,0,0,0)
#define register_param4(p,s0,s1,s2,s3) register_param6(p,s0,s1,s2,s3,0,0)
#define register_param1(p,s0) register_param5(p,s0,0,0,0,0)
#define register_param2(p,s0,s1) register_param5(p,s0,s1,0,0,0)
#define register_param3(p,s0,s1,s2) register_param5(p,s0,s1,s2,0,0)
#define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0)
static void register_matrix_param6( struct tnl_program *p,
GLint s0,
GLint s1,
GLint s2,
GLint s3,
GLint s4,
GLint s5,
static void register_matrix_param5( struct tnl_program *p,
GLint s0, /* matrix name */
GLint s1, /* texture matrix number */
GLint s2, /* first row */
GLint s3, /* last row */
GLint s4, /* modifier */
struct ureg *matrix )
{
GLint i;
@ -465,8 +464,8 @@ static void register_matrix_param6( struct tnl_program *p,
/* This is a bit sad as the support is there to pull the whole
* matrix out in one go:
*/
for (i = 0; i <= s4 - s3; i++)
matrix[i] = register_param6( p, s0, s1, s2, i, i, s5 );
for (i = 0; i <= s3 - s2; i++)
matrix[i] = register_param5( p, s0, s1, i, i, s4 );
}
@ -650,13 +649,13 @@ static struct ureg get_eye_position( struct tnl_program *p )
p->eye_position = reserve_temp(p);
if (PREFER_DP4) {
register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 3,
STATE_MATRIX, modelview );
register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3,
0, modelview );
emit_matrix_transform_vec4(p, p->eye_position, modelview, pos);
}
else {
register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 3,
register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3,
STATE_MATRIX_TRANSPOSE, modelview );
emit_transpose_matrix_transform_vec4(p, p->eye_position, modelview, pos);
@ -710,7 +709,7 @@ static struct ureg get_eye_normal( struct tnl_program *p )
struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL );
struct ureg mvinv[3];
register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 2,
register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 2,
STATE_MATRIX_INVTRANS, mvinv );
p->eye_normal = reserve_temp(p);
@ -745,12 +744,12 @@ static void build_hpos( struct tnl_program *p )
struct ureg mvp[4];
if (PREFER_DP4) {
register_matrix_param6( p, STATE_MATRIX, STATE_MVP, 0, 0, 3,
STATE_MATRIX, mvp );
register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3,
0, mvp );
emit_matrix_transform_vec4( p, hpos, mvp, pos );
}
else {
register_matrix_param6( p, STATE_MATRIX, STATE_MVP, 0, 0, 3,
register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3,
STATE_MATRIX_TRANSPOSE, mvp );
emit_transpose_matrix_transform_vec4( p, hpos, mvp, pos );
}
@ -894,7 +893,7 @@ static struct ureg calculate_light_attenuation( struct tnl_program *p,
/* Need to add some addtional parameters to allow lighting in object
* space - STATE_SPOT_DIRECTION and STATE_HALF implicitly assume eye
* space - STATE_SPOT_DIRECTION and STATE_HALF_VECTOR implicitly assume eye
* space lighting.
*/
static void build_lighting( struct tnl_program *p )
@ -993,7 +992,7 @@ static void build_lighting( struct tnl_program *p )
emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat);
emit_normalize_vec3(p, half, half);
} else {
half = register_param3(p, STATE_LIGHT, i, STATE_HALF);
half = register_param3(p, STATE_LIGHT, i, STATE_HALF_VECTOR);
}
}
else {
@ -1360,13 +1359,13 @@ static void build_texture_transform( struct tnl_program *p )
out_texgen :
register_input(p, VERT_ATTRIB_TEX0+i));
if (PREFER_DP4) {
register_matrix_param6( p, STATE_MATRIX, STATE_TEXTURE, i,
0, 3, STATE_MATRIX, texmat );
register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3,
0, texmat );
emit_matrix_transform_vec4( p, out, texmat, in );
}
else {
register_matrix_param6( p, STATE_MATRIX, STATE_TEXTURE, i,
0, 3, STATE_MATRIX_TRANSPOSE, texmat );
register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3,
STATE_MATRIX_TRANSPOSE, texmat );
emit_transpose_matrix_transform_vec4( p, out, texmat, in );
}
}

View file

@ -36,10 +36,6 @@
#include "brw_state.h"
#include "brw_hal.h"
#include "program.h"
#include "program_instruction.h"
#include "arbprogparse.h"
GLuint brw_wm_nr_args( GLuint opcode )
{

View file

@ -36,7 +36,7 @@
#include "brw_context.h"
#include "brw_eu.h"
#include "program_instruction.h"
#include "prog_instruction.h"
/* A big lookup table is used to figure out which and how many
* additional regs will inserted before the main payload in the WM

View file

@ -32,9 +32,6 @@
#include "brw_context.h"
#include "brw_wm.h"
#include "program.h"
#include "shader/arbprogparse.h"
#include "shader/program_instruction.h"
void brw_wm_print_value( struct brw_wm_compile *c,

View file

@ -30,10 +30,8 @@
*/
#include "brw_context.h"
#include "program.h"
#include "program_instruction.h"
#include "macros.h"
#include "brw_context.h"
#include "brw_wm.h"
#define SATURATE (1<<5)

View file

@ -37,9 +37,10 @@
#include "brw_wm.h"
#include "brw_util.h"
#include "shader/program.h"
#include "shader/program_instruction.h"
#include "shader/arbprogparse.h"
#include "shader/prog_parameter.h"
#include "shader/prog_print.h"
#include "shader/prog_statevars.h"
#define FIRST_INTERNAL_TEMP MAX_NV_FRAGMENT_PROGRAM_TEMPS
@ -370,23 +371,21 @@ static void emit_interp( struct brw_wm_compile *c,
* harm and it's not as if the parameter handling isn't a big hack
* anyway.
*/
static struct prog_src_register search_or_add_param6( struct brw_wm_compile *c,
GLint s0,
GLint s1,
GLint s2,
GLint s3,
GLint s4,
GLint s5)
static struct prog_src_register search_or_add_param5(struct brw_wm_compile *c,
GLint s0,
GLint s1,
GLint s2,
GLint s3,
GLint s4)
{
struct gl_program_parameter_list *paramList = c->fp->program.Base.Parameters;
GLint tokens[6];
gl_state_index tokens[STATE_LENGTH];
GLuint idx;
tokens[0] = s0;
tokens[1] = s1;
tokens[2] = s2;
tokens[3] = s3;
tokens[4] = s4;
tokens[5] = s5;
for (idx = 0; idx < paramList->NumParameters; idx++) {
if (paramList->Parameters[idx].Type == PROGRAM_STATE_VAR &&
@ -413,6 +412,7 @@ static struct prog_src_register search_or_add_const4f( struct brw_wm_compile *c,
struct gl_program_parameter_list *paramList = c->fp->program.Base.Parameters;
GLfloat values[4];
GLuint idx;
GLuint swizzle;
values[0] = s0;
values[1] = s1;
@ -432,8 +432,8 @@ static struct prog_src_register search_or_add_const4f( struct brw_wm_compile *c,
return src_reg(PROGRAM_STATE_VAR, idx);
}
idx = _mesa_add_unnamed_constant( paramList, values, 4 );
idx = _mesa_add_unnamed_constant( paramList, values, 4, &swizzle );
/* XXX what about swizzle? */
return src_reg(PROGRAM_STATE_VAR, idx);
}
@ -527,11 +527,11 @@ static void precalc_tex( struct brw_wm_compile *c,
if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) {
struct prog_src_register scale =
search_or_add_param6( c,
search_or_add_param5( c,
STATE_INTERNAL,
STATE_TEXRECT_SCALE,
inst->TexSrcUnit,
0,0,0 );
0,0 );
tmpcoord = get_temp(c);
@ -724,7 +724,7 @@ static void fog_blend( struct brw_wm_compile *c,
struct prog_src_register fog_factor )
{
struct prog_dst_register outcolor = dst_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);
struct prog_src_register fogcolor = search_or_add_param6( c, STATE_FOG_COLOR, 0,0,0,0,0 );
struct prog_src_register fogcolor = search_or_add_param5( c, STATE_FOG_COLOR, 0,0,0,0 );
/* color.xyz = LRP fog_factor.xxxx, output_color, fog_color */

View file

@ -32,9 +32,7 @@
#include "brw_context.h"
#include "brw_wm.h"
#include "program.h"
#include "arbprogparse.h"
#include "program_instruction.h"
#include "shader/prog_parameter.h"

View file

@ -32,9 +32,6 @@
#include "brw_context.h"
#include "brw_wm.h"
#include "program.h"
#include "arbprogparse.h"
#include "program_instruction.h"
static GLuint get_tracked_mask(struct brw_wm_compile *c,

View file

@ -32,9 +32,7 @@
#include "brw_context.h"
#include "brw_wm.h"
#include "program.h"
#include "arbprogparse.h"
#include "program_instruction.h"
/* Use these to force spilling so that that functionality can be
* tested with known-good examples rather than having to construct new

View file

@ -52,14 +52,14 @@ void TAG(translate_vertex)(GLcontext *ctx,
{
float rhw = 1.0 / LE32_IN_FLOAT( p + 2 );
dst->texcoord[1][0] = rhw*LE32_IN_FLOAT( p++ );
dst->texcoord[1][1] = rhw*LE32_IN_FLOAT( p++ );
dst->attrib[FRAG_ATTRIB_TEX1][0] = rhw*LE32_IN_FLOAT( p++ );
dst->attrib[FRAG_ATTRIB_TEX1][1] = rhw*LE32_IN_FLOAT( p++ );
}
#else
dst->texcoord[1][0] = LE32_IN_FLOAT( p++ );
dst->texcoord[1][1] = LE32_IN_FLOAT( p++ );
dst->attrib[FRAG_ATTRIB_TEX1][0] = LE32_IN_FLOAT( p++ );
dst->attrib[FRAG_ATTRIB_TEX1][1] = LE32_IN_FLOAT( p++ );
#endif
dst->texcoord[1][3] = 1.0;
dst->attrib[FRAG_ATTRIB_TEX1][3] = 1.0;
p++;
case TEX0_VERTEX_FORMAT:
@ -67,14 +67,14 @@ void TAG(translate_vertex)(GLcontext *ctx,
{
float rhw = 1.0 / LE32_IN_FLOAT( p + 2 );
dst->texcoord[0][0] = rhw*LE32_IN_FLOAT( p++ );
dst->texcoord[0][1] = rhw*LE32_IN_FLOAT( p++ );
dst->attrib[FRAG_ATTRIB_TEX0][0] = rhw*LE32_IN_FLOAT( p++ );
dst->attrib[FRAG_ATTRIB_TEX0][1] = rhw*LE32_IN_FLOAT( p++ );
}
#else
dst->texcoord[0][0] = LE32_IN_FLOAT( p++ );
dst->texcoord[0][1] = LE32_IN_FLOAT( p++ );
dst->attrib[FRAG_ATTRIB_TEX0][0] = LE32_IN_FLOAT( p++ );
dst->attrib[FRAG_ATTRIB_TEX0][1] = LE32_IN_FLOAT( p++ );
#endif
dst->texcoord[0][3] = 1.0;
dst->attrib[FRAG_ATTRIB_TEX0][3] = 1.0;
dst->win[3] = LE32_IN_FLOAT( p++ );
case NOTEX_VERTEX_FORMAT:

View file

@ -201,7 +201,7 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
nouveauShaderInitFuncs(ctx);
/* Install Mesa's fixed-function texenv shader support */
if (nmesa->screen->card->type >= NV_40)
ctx->_MaintainTexEnvProgram = GL_TRUE;
ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
/* Initialize the swrast */
_swrast_CreateContext( ctx );

View file

@ -35,9 +35,10 @@
#include "enums.h"
#include "extensions.h"
#include "program.h"
#include "shader/program.h"
#include "shader/prog_instruction.h"
/*#include "shader/arbprogparse.h"*/
#include "tnl/tnl.h"
#include "shader/arbprogparse.h"
#include "nouveau_context.h"
#include "nouveau_shader.h"

View file

@ -34,9 +34,10 @@
#include "macros.h"
#include "enums.h"
#include "program.h"
#include "programopt.h"
#include "program_instruction.h"
#include "shader/prog_instruction.h"
#include "shader/prog_parameter.h"
#include "shader/prog_statevars.h"
#include "shader/programopt.h"
#include "nouveau_context.h"
#include "nouveau_shader.h"
@ -428,8 +429,10 @@ pass0_fixup_swizzle(nvsPtr nvs, nvsFragmentHeader *parent, int fpos,
if (!rec->swzconst_done) {
struct gl_program *prog = &nvs->mesa.vp.Base;
GLuint swizzle;
rec->swzconst_id = _mesa_add_unnamed_constant(prog->Parameters,
sc, 4);
sc, 4, &swizzle);
/* XXX what about swizzle? */
rec->swzconst_done = 1;
COPY_4V(nvs->params[rec->swzconst_id].val, sc);
}
@ -839,7 +842,8 @@ pass0_vp_insert_ff_clip_planes(GLcontext *ctx, nouveauShader *nvs)
nvsInstruction *nvsinst;
GLuint fpos = 0;
nvsRegister opos, epos, eqn, mv[4];
GLint tokens[6] = { STATE_MATRIX, STATE_MODELVIEW, 0, 0, 0, 0 };
gl_state_index tokens[STATE_LENGTH]
= { STATE_MODELVIEW_MATRIX, 0, 0, 0, 0 };
GLint id;
int i;
@ -847,7 +851,7 @@ pass0_vp_insert_ff_clip_planes(GLcontext *ctx, nouveauShader *nvs)
pass0_make_reg(nvs, &opos, NVS_FILE_ATTRIB, NVS_FR_POSITION);
pass0_make_reg(nvs, &epos, NVS_FILE_TEMP , -1);
for (i=0; i<4; i++) {
tokens[3] = tokens[4] = i;
tokens[2] = tokens[3] = i;
id = _mesa_add_state_reference(prog->Parameters, tokens);
pass0_make_reg(nvs, &mv[i], NVS_FILE_CONST, id);
}

View file

@ -34,7 +34,8 @@
#include "macros.h"
#include "enums.h"
#include "program.h"
#include "shader/prog_parameter.h"
#include "shader/prog_print.h"
#include "nouveau_context.h"
#include "nouveau_shader.h"

View file

@ -34,14 +34,16 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "macros.h"
#include "enums.h"
#include "program.h"
#include "shader/prog_instruction.h"
#include "shader/prog_parameter.h"
#include "shader/prog_statevars.h"
#include "shader/programopt.h"
#include "tnl/tnl.h"
#include "r200_context.h"
#include "r200_vertprog.h"
#include "r200_ioctl.h"
#include "r200_tcl.h"
#include "program_instruction.h"
#include "programopt.h"
#include "tnl/tnl.h"
#if SWIZZLE_X != VSF_IN_COMPONENT_X || \
SWIZZLE_Y != VSF_IN_COMPONENT_Y || \
@ -462,7 +464,7 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
base e isn't directly available neither. */
if ((mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_FOGC)) && !vp->fogpidx) {
struct gl_program_parameter_list *paramList;
GLint tokens[6] = { STATE_FOG_PARAMS, 0, 0, 0, 0, 0 };
gl_state_index tokens[STATE_LENGTH] = { STATE_FOG_PARAMS, 0, 0, 0, 0 };
paramList = mesa_vp->Base.Parameters;
vp->fogpidx = _mesa_add_state_reference(paramList, tokens);
}

View file

@ -331,7 +331,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
ctx->Const.FragmentProgram.MaxNativeTexIndirections = PFS_MAX_TEX_INDIRECT;
ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* and these are?? */
_tnl_ProgramCacheInit(ctx);
ctx->_MaintainTexEnvProgram = GL_TRUE;
ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
driInitExtensions(ctx, card_extensions, GL_TRUE);

View file

@ -43,9 +43,10 @@
#include "glheader.h"
#include "macros.h"
#include "enums.h"
#include "shader/prog_instruction.h"
#include "shader/prog_parameter.h"
#include "shader/prog_print.h"
#include "program.h"
#include "program_instruction.h"
#include "r300_context.h"
#include "r300_fragprog.h"
#include "r300_reg.h"

View file

@ -36,10 +36,11 @@
#include "glheader.h"
#include "macros.h"
#include "enums.h"
#include "shader/program.h"
#include "shader/prog_instruction.h"
#include "program.h"
#include "r300_context.h"
#include "program_instruction.h"
#if 0
/* representation of a register for emit_arith/swizzle */

View file

@ -46,6 +46,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "api_arrayelt.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "shader/prog_parameter.h"
#include "shader/prog_statevars.h"
#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "texformat.h"
@ -1055,8 +1057,10 @@ r300UpdateDrawBuffer(GLcontext *ctx)
#endif
}
static void r300FetchStateParameter(GLcontext *ctx, const enum state_index state[],
GLfloat *value)
static void
r300FetchStateParameter(GLcontext *ctx,
const gl_state_index state[STATE_LENGTH],
GLfloat *value)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);

View file

@ -33,11 +33,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "macros.h"
#include "enums.h"
#include "program.h"
#include "nvvertexec.h"
#include "shader/prog_instruction.h"
#include "shader/prog_parameter.h"
#include "shader/prog_statevars.h"
#include "tnl/tnl.h"
#include "r300_context.h"
#include "r300_program.h"
#include "program_instruction.h"
#if SWIZZLE_X != VSF_IN_COMPONENT_X || \
SWIZZLE_Y != VSF_IN_COMPONENT_Y || \
@ -103,7 +105,7 @@ int r300VertexProgUpdateParams(GLcontext *ctx, struct r300_vertex_program_cont *
struct gl_program_parameter_list *paramList;
if (mesa_vp->IsNVProgram) {
_mesa_init_vp_per_primitive_registers(ctx);
_mesa_load_tracked_matrices(ctx);
for (pi=0; pi < MAX_NV_VERTEX_PROGRAM_PARAMS; pi++) {
*dst++=ctx->VertexProgram.Parameters[pi][0];
@ -880,7 +882,7 @@ static void position_invariant(struct gl_program *prog)
struct gl_program_parameter_list *paramList;
int i;
GLint tokens[6] = { STATE_MATRIX, STATE_MVP, 0, 0, 0, STATE_MATRIX };
gl_state_index tokens[STATE_LENGTH] = { STATE_MVP_MATRIX, 0, 0, 0, 0 };
#ifdef PREFER_DP4
tokens[5] = STATE_MATRIX;

View file

@ -407,17 +407,17 @@ do { \
ctx->Texture.Unit[0]._Current->DriverData); \
deltwx = deltwy = wstart = deltdx = deltdy = dstart = 0; \
\
u0 = (v[idx[0]].texcoord[0][0] \
u0 = (v[idx[0]].attrib[FRAG_ATTRIB_TEX0][0] \
* (GLfloat)(t->image[0].image->Width) * 256.0); \
u1 = (v[idx[1]].texcoord[0][0] \
u1 = (v[idx[1]].attrib[FRAG_ATTRIB_TEX0][0] \
* (GLfloat)(t->globj->Image[0][0]->Width) * 256.0); \
u2 = (v[idx[2]].texcoord[0][0] \
u2 = (v[idx[2]].attrib[FRAG_ATTRIB_TEX0][0] \
* (GLfloat)(t->globj->Image[0][0]->Width) * 256.0); \
v0 = (v[idx[0]].texcoord[0][1] \
v0 = (v[idx[0]].attrib[FRAG_ATTRIB_TEX0][1] \
* (GLfloat)(t->globj->Image[0][0]->Height) * 256.0); \
v1 = (v[idx[1]].texcoord[0][1] \
v1 = (v[idx[1]].attrib[FRAG_ATTRIB_TEX0][1] \
* (GLfloat)(t->globj->Image[0][0]->Height) * 256.0); \
v2 = (v[idx[2]].texcoord[0][1] \
v2 = (v[idx[2]].attrib[FRAG_ATTRIB_TEX0][1] \
* (GLfloat)(t->globj->Image[0][0]->Height) * 256.0); \
\
w0 = (v[idx[0]].win[3]); \
@ -485,23 +485,23 @@ do { \
GLfloat sxy, suv; \
int lev; \
\
suv = (v[idx[0]].texcoord[0][0] - \
v[idx[2]].texcoord[0][0]) * \
(v[idx[1]].texcoord[0][1] - \
v[idx[2]].texcoord[0][1]) - \
(v[idx[1]].texcoord[0][0] - \
v[idx[2]].texcoord[0][0]) * \
(v[idx[0]].texcoord[0][1] - \
v[idx[2]].texcoord[0][2]); \
suv = (v[idx[0]].attrib[FRAG_ATTRIB_TEX0][0] - \
v[idx[2]].attrib[FRAG_ATTRIB_TEX0][0]) * \
(v[idx[1]].attrib[FRAG_ATTRIB_TEX0][1] - \
v[idx[2]].attrib[FRAG_ATTRIB_TEX0][1]) - \
(v[idx[1]].attrib[FRAG_ATTRIB_TEX0][0] - \
v[idx[2]].attrib[FRAG_ATTRIB_TEX0][0]) * \
(v[idx[0]].attrib[FRAG_ATTRIB_TEX0][1] - \
v[idx[2]].attrib[FRAG_ATTRIB_TEX0][2]); \
\
sxy = (v[idx[0]].texcoord[0][0] - \
v[idx[2]].texcoord[0][0]) * \
(v[idx[1]].texcoord[0][1] - \
v[idx[2]].texcoord[0][1]) - \
(v[idx[1]].texcoord[0][0] - \
v[idx[2]].texcoord[0][0]) * \
(v[idx[0]].texcoord[0][1] - \
v[idx[2]].texcoord[0][2]); \
sxy = (v[idx[0]].attrib[FRAG_ATTRIB_TEX0][0] - \
v[idx[2]].attrib[FRAG_ATTRIB_TEX0][0]) * \
(v[idx[1]].attrib[FRAG_ATTRIB_TEX0][1] - \
v[idx[2]].attrib[FRAG_ATTRIB_TEX0][1]) - \
(v[idx[1]].attrib[FRAG_ATTRIB_TEX0][0] - \
v[idx[2]].attrib[FRAG_ATTRIB_TEX0][0]) * \
(v[idx[0]].attrib[FRAG_ATTRIB_TEX0][1] - \
v[idx[2]].attrib[FRAG_ATTRIB_TEX0][2]); \
\
if (sxy < 0) sxy *= -1.0; \
if (suv < 0) suv *= -1.0; \

View file

@ -165,21 +165,21 @@ tdfx_translate_vertex( GLcontext *ctx, const tdfxVertex *src, SWvertex *dst)
dst->color[2] = src->color[0];
dst->color[3] = src->color[3];
dst->texcoord[0][0] = 1.0 / fxMesa->sScale0 * w * src->tu0;
dst->texcoord[0][1] = 1.0 / fxMesa->tScale0 * w * src->tv0;
dst->attrib[FRAG_ATTRIB_TEX0][0] = 1.0 / fxMesa->sScale0 * w * src->tu0;
dst->attrib[FRAG_ATTRIB_TEX0][1] = 1.0 / fxMesa->tScale0 * w * src->tv0;
if (fxMesa->vertexFormat == TDFX_LAYOUT_PROJ1 || fxMesa->vertexFormat == TDFX_LAYOUT_PROJ2) {
dst->texcoord[0][3] = w * src->tq0;
dst->attrib[FRAG_ATTRIB_TEX0][3] = w * src->tq0;
} else {
dst->texcoord[0][3] = 1.0;
dst->attrib[FRAG_ATTRIB_TEX0][3] = 1.0;
}
if (fxMesa->SetupIndex & TDFX_TEX1_BIT) {
dst->texcoord[1][0] = 1.0 / fxMesa->sScale1 * w * src->tu1;
dst->texcoord[1][1] = 1.0 / fxMesa->tScale1 * w * src->tv1;
dst->attrib[FRAG_ATTRIB_TEX1][0] = 1.0 / fxMesa->sScale1 * w * src->tu1;
dst->attrib[FRAG_ATTRIB_TEX1][1] = 1.0 / fxMesa->tScale1 * w * src->tv1;
if (fxMesa->vertexFormat == TDFX_LAYOUT_PROJ2) {
dst->texcoord[1][3] = w * src->tq1;
dst->attrib[FRAG_ATTRIB_TEX1][3] = w * src->tq1;
} else {
dst->texcoord[1][3] = 1.0;
dst->attrib[FRAG_ATTRIB_TEX1][3] = 1.0;
}
}
}

View file

@ -179,7 +179,7 @@ struct trident_context {
GLuint vertex_format;
GLuint vertex_size;
GLuint vertex_stride_shift;
char *verts;
GLubyte *verts;
GLint tmu_source[2];

View file

@ -0,0 +1,44 @@
# Makefile for stand-alone GL-SL compiler
TOP = ../../../..
include $(TOP)/configs/current
PROGRAM = glslcompiler
OBJECTS = \
glslcompiler.o \
../../glapi/glapi.o \
../../glapi/glthread.o \
../../main/dispatch.o \
../common/driverfuncs.o \
../../libmesa.a
INCLUDES = \
-I$(TOP)/include \
-I$(TOP)/include/GL/internal \
-I$(TOP)/src/mesa \
-I$(TOP)/src/mesa/main \
-I$(TOP)/src/mesa/glapi \
-I$(TOP)/src/mesa/math \
-I$(TOP)/src/mesa/transform \
-I$(TOP)/src/mesa/shader \
-I$(TOP)/src/mesa/swrast \
-I$(TOP)/src/mesa/swrast_setup \
default: $(PROGRAM)
$(INSTALL) $(PROGRAM) $(TOP)/bin
glslcompiler: $(OBJECTS)
$(CC) $(OBJECTS) -lm -lpthread -o $@
glslcompiler.o: glslcompiler.c
$(CC) -c $(CFLAGS) $(INCLUDES) glslcompiler.c -o $@
clean:
rm -f *.o *~ $(PROGRAM)

View file

@ -0,0 +1,358 @@
/*
* Mesa 3-D graphics library
* Version: 6.5.3
*
* Copyright (C) 1999-2007 Brian Paul, Tungsten Graphics, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \mainpage
*
* Stand-alone Shading Language compiler.
* Basically, a command-line program which accepts GLSL shaders and emits
* vertex/fragment programs (GPU instructions).
*
* This file is basically just a Mesa device driver but instead of building
* a shared library we build an executable.
*
* We can emit programs in three different formats:
* 1. ARB-style (GL_ARB_vertex/fragment_program)
* 2. NV-style (GL_NV_vertex/fragment_program)
* 3. debug-style (a slightly more sophisticated, internal format)
*
* Note that the ARB and NV program languages can't express all the
* features that might be used by a fragment program (examples being
* uniform and varying vars). So, the ARB/NV programs that are
* emitted aren't always legal programs in those languages.
*/
#include "imports.h"
#include "context.h"
#include "extensions.h"
#include "framebuffer.h"
#include "shaders.h"
#include "shader/shader_api.h"
#include "shader/prog_print.h"
#include "drivers/common/driverfuncs.h"
#include "tnl/tnl.h"
#include "tnl/t_context.h"
#include "tnl/t_pipeline.h"
#include "swrast/swrast.h"
#include "swrast/s_context.h"
#include "swrast/s_triangle.h"
#include "swrast_setup/swrast_setup.h"
#include "vbo/vbo.h"
static const char *Prog = "glslcompiler";
struct options {
GLboolean LineNumbers;
gl_prog_print_mode Mode;
const char *VertFile;
const char *FragFile;
const char *OutputFile;
};
static struct options Options;
/**
* GLSL compiler driver context. (kind of an artificial thing for now)
*/
struct compiler_context
{
GLcontext MesaContext;
int foo;
};
typedef struct compiler_context CompilerContext;
static void
UpdateState(GLcontext *ctx, GLuint new_state)
{
/* easy - just propogate */
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
_vbo_InvalidateState( ctx, new_state );
}
static GLboolean
CreateContext(void)
{
struct dd_function_table ddFuncs;
GLvisual *vis;
GLframebuffer *buf;
GLcontext *ctx;
CompilerContext *cc;
vis = _mesa_create_visual(GL_TRUE, GL_FALSE, GL_FALSE, /* RGB */
8, 8, 8, 8, /* color */
0, 0, 0, /* z, stencil */
0, 0, 0, 0, 1); /* accum */
buf = _mesa_create_framebuffer(vis);
cc = _mesa_calloc(sizeof(*cc));
if (!vis || !buf || !cc) {
if (vis)
_mesa_destroy_visual(vis);
if (buf)
_mesa_destroy_framebuffer(buf);
return GL_FALSE;
}
_mesa_init_driver_functions(&ddFuncs);
ddFuncs.GetString = NULL;/*get_string;*/
ddFuncs.UpdateState = UpdateState;
ddFuncs.GetBufferSize = NULL;
ctx = &cc->MesaContext;
_mesa_initialize_context(ctx, vis, NULL, &ddFuncs, cc);
_mesa_enable_sw_extensions(ctx);
if (!_swrast_CreateContext( ctx ) ||
!_vbo_CreateContext( ctx ) ||
!_tnl_CreateContext( ctx ) ||
!_swsetup_CreateContext( ctx )) {
_mesa_destroy_visual(vis);
_mesa_free_context_data(ctx);
_mesa_free(cc);
return GL_FALSE;
}
TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
_swsetup_Wakeup( ctx );
_mesa_make_current(ctx, buf, buf);
return GL_TRUE;
}
static void
LoadAndCompileShader(GLuint shader, const char *text)
{
GLint stat;
_mesa_ShaderSourceARB(shader, 1, (const GLchar **) &text, NULL);
_mesa_CompileShaderARB(shader);
_mesa_GetShaderiv(shader, GL_COMPILE_STATUS, &stat);
if (!stat) {
GLchar log[1000];
GLsizei len;
_mesa_GetShaderInfoLog(shader, 1000, &len, log);
fprintf(stderr, "%s: problem compiling shader: %s\n", Prog, log);
exit(1);
}
else {
printf("Shader compiled OK\n");
}
}
/**
* Read a shader from a file.
*/
static void
ReadShader(GLuint shader, const char *filename)
{
const int max = 100*1000;
int n;
char *buffer = (char*) malloc(max);
FILE *f = fopen(filename, "r");
if (!f) {
fprintf(stderr, "%s: Unable to open shader file %s\n", Prog, filename);
exit(1);
}
n = fread(buffer, 1, max, f);
/*
printf("%s: read %d bytes from shader file %s\n", Prog, n, filename);
*/
if (n > 0) {
buffer[n] = 0;
LoadAndCompileShader(shader, buffer);
}
fclose(f);
free(buffer);
}
#if 0
static void
CheckLink(GLuint prog)
{
GLint stat;
_mesa_GetProgramiv(prog, GL_LINK_STATUS, &stat);
if (!stat) {
GLchar log[1000];
GLsizei len;
_mesa_GetProgramInfoLog(prog, 1000, &len, log);
fprintf(stderr, "%s: Linker error:\n%s\n", Prog, log);
}
else {
fprintf(stderr, "%s: Link success!\n", Prog);
}
}
#endif
static void
PrintShaderInstructions(GLuint shader, FILE *f)
{
GET_CURRENT_CONTEXT(ctx);
struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
GLuint i;
for (i = 0; i < sh->NumPrograms; i++) {
struct gl_program *prog = sh->Programs[i];
_mesa_print_program_opt(prog, Options.Mode, Options.LineNumbers);
}
}
static GLuint
CompileShader(const char *filename, GLenum type)
{
GLuint shader;
assert(type == GL_FRAGMENT_SHADER ||
type == GL_VERTEX_SHADER);
shader = _mesa_CreateShader(type);
ReadShader(shader, filename);
return shader;
}
static void
Usage(void)
{
printf("Mesa GLSL stand-alone compiler\n");
printf("Usage:\n");
printf(" --vs FILE vertex shader input filename\n");
printf(" --fs FILE fragment shader input filename\n");
printf(" --arb emit ARB-style instructions (the default)\n");
printf(" --nv emit NV-style instructions\n");
printf(" --debug emit debug-style instructions\n");
printf(" --number, -n emit line numbers\n");
printf(" --output, -o FILE output filename\n");
printf(" --help display this information\n");
}
static void
ParseOptions(int argc, char *argv[])
{
int i;
Options.LineNumbers = GL_FALSE;
Options.Mode = PROG_PRINT_ARB;
Options.VertFile = NULL;
Options.FragFile = NULL;
Options.OutputFile = NULL;
if (argc == 1) {
Usage();
exit(0);
}
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "--vs") == 0) {
Options.VertFile = argv[i + 1];
i++;
}
else if (strcmp(argv[i], "--fs") == 0) {
Options.FragFile = argv[i + 1];
i++;
}
else if (strcmp(argv[i], "--arb") == 0) {
Options.Mode = PROG_PRINT_ARB;
}
else if (strcmp(argv[i], "--nv") == 0) {
Options.Mode = PROG_PRINT_NV;
}
else if (strcmp(argv[i], "--debug") == 0) {
Options.Mode = PROG_PRINT_DEBUG;
}
else if (strcmp(argv[i], "--number") == 0 ||
strcmp(argv[i], "-n") == 0) {
Options.LineNumbers = GL_TRUE;
}
else if (strcmp(argv[i], "--output") == 0 ||
strcmp(argv[i], "-o") == 0) {
Options.OutputFile = argv[i + 1];
i++;
}
else if (strcmp(argv[i], "--help") == 0) {
Usage();
exit(0);
}
else {
printf("Unknown option: %s\n", argv[i]);
Usage();
exit(1);
}
}
}
int
main(int argc, char *argv[])
{
GLuint shader = 0;
if (!CreateContext()) {
fprintf(stderr, "%s: Failed to create compiler context\n", Prog);
exit(1);
}
ParseOptions(argc, argv);
if (Options.VertFile) {
shader = CompileShader(Options.VertFile, GL_VERTEX_SHADER);
}
else if (Options.FragFile) {
shader = CompileShader(Options.FragFile, GL_FRAGMENT_SHADER);
}
if (shader) {
if (Options.OutputFile) {
fclose(stdout);
/*stdout =*/ freopen(Options.OutputFile, "w", stdout);
}
if (stdout) {
PrintShaderInstructions(shader, stdout);
}
if (Options.OutputFile) {
fclose(stdout);
}
}
return 0;
}

View file

@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
* Version: 6.5.2
* Version: 6.5.3
*
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -678,6 +678,10 @@ _mesa_GetColorTable( GLenum target, GLenum format,
ASSERT(table);
if (table->Size <= 0) {
return;
}
switch (table->_BaseFormat) {
case GL_ALPHA:
{

View file

@ -196,21 +196,19 @@
/** For any program target/extension */
/*@{*/
#define MAX_PROGRAM_LOCAL_PARAMS 128 /* KW: power of two */
#define MAX_PROGRAM_ENV_PARAMS 128
#define MAX_PROGRAM_MATRICES 8
#define MAX_PROGRAM_MATRIX_STACK_DEPTH 4
#define MAX_PROGRAM_CALL_DEPTH 8
/*@}*/
/** For GL_ARB_fragment_shader */
/*@{*/
#define MAX_FRAGMENT_UNIFORM_COMPONENTS 64
#define MAX_PROGRAM_TEMPS 128
#define MAX_PROGRAM_ADDRESS_REGS 2
#define MAX_UNIFORMS 128
#define MAX_VARYING 8
/*@}*/
/** For GL_ARB_vertex_shader */
/*@{*/
#define MAX_VERTEX_ATTRIBS 16
#define MAX_VERTEX_UNIFORM_COMPONENTS 512
#define MAX_VARYING_FLOATS 32
#define MAX_VERTEX_TEXTURE_IMAGE_UNITS 0
#define MAX_COMBINED_TEXTURE_IMAGE_UNITS (MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS)
/*@}*/
@ -218,7 +216,7 @@
/** For GL_ARB_draw_buffers */
/*@{*/
#define MAX_DRAW_BUFFERS 1
#define MAX_DRAW_BUFFERS 4
/*@}*/

View file

@ -132,7 +132,7 @@
#include "math/m_xform.h"
#include "math/mathmod.h"
#endif
#include "shaderobjects.h"
#include "shader_api.h"
#ifdef USE_SPARC_ASM
#include "sparc/sparc.h"
@ -701,7 +701,7 @@ alloc_shared_state( GLcontext *ctx )
ss->ArrayObjects = _mesa_NewHashTable();
#if FEATURE_ARB_shader_objects
ss->GL2Objects = _mesa_NewHashTable ();
ss->ShaderObjects = _mesa_NewHashTable();
#endif
ss->Default1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
@ -778,8 +778,8 @@ alloc_shared_state( GLcontext *ctx )
_mesa_DeleteHashTable (ss->ArrayObjects);
#if FEATURE_ARB_shader_objects
if (ss->GL2Objects)
_mesa_DeleteHashTable (ss->GL2Objects);
if (ss->ShaderObjects)
_mesa_DeleteHashTable (ss->ShaderObjects);
#endif
#if FEATURE_EXT_framebuffer_object
@ -873,13 +873,22 @@ delete_arrayobj_cb(GLuint id, void *data, void *userData)
}
/**
* Callback for deleting an shader object. Called by _mesa_HashDeleteAll().
* Callback for deleting shader and shader programs objects.
* Called by _mesa_HashDeleteAll().
*/
static void
delete_shaderobj_cb(GLuint id, void *data, void *userData)
delete_shader_cb(GLuint id, void *data, void *userData)
{
/* XXX probably need to fix this */
_mesa_free(data);
GLcontext *ctx = (GLcontext *) userData;
struct gl_shader *sh = (struct gl_shader *) data;
if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER) {
_mesa_free_shader(ctx, sh);
}
else {
struct gl_shader_program *shProg = (struct gl_shader_program *) data;
ASSERT(shProg->Type == GL_SHADER_PROGRAM);
_mesa_free_shader_program(ctx, shProg);
}
}
@ -944,8 +953,8 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
_mesa_DeleteHashTable(ss->ArrayObjects);
#if FEATURE_ARB_shader_objects
_mesa_HashDeleteAll(ss->GL2Objects, delete_shaderobj_cb, ctx);
_mesa_DeleteHashTable(ss->GL2Objects);
_mesa_HashDeleteAll(ss->ShaderObjects, delete_shader_cb, ctx);
_mesa_DeleteHashTable(ss->ShaderObjects);
#endif
#if FEATURE_EXT_framebuffer_object
@ -963,7 +972,7 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
* Initialize fields of gl_current_attrib (aka ctx->Current.*)
*/
static void
_mesa_init_current( GLcontext *ctx )
_mesa_init_current(GLcontext *ctx)
{
GLuint i;
@ -1005,7 +1014,7 @@ init_natives(struct gl_program_constants *prog)
* some of these values (such as number of texture units).
*/
static void
_mesa_init_constants( GLcontext *ctx )
_mesa_init_constants(GLcontext *ctx)
{
assert(ctx);
@ -1058,9 +1067,10 @@ _mesa_init_constants( GLcontext *ctx )
ctx->Const.VertexProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
ctx->Const.VertexProgram.MaxEnvParams = MAX_NV_VERTEX_PROGRAM_PARAMS;
ctx->Const.VertexProgram.MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
ctx->Const.VertexProgram.MaxUniformComponents = MAX_VERTEX_UNIFORM_COMPONENTS;
ctx->Const.VertexProgram.MaxUniformComponents = 4 * MAX_UNIFORMS;
init_natives(&ctx->Const.VertexProgram);
#endif
#if FEATURE_ARB_fragment_program
ctx->Const.FragmentProgram.MaxInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS;
ctx->Const.FragmentProgram.MaxAluInstructions = MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS;
@ -1072,7 +1082,7 @@ _mesa_init_constants( GLcontext *ctx )
ctx->Const.FragmentProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
ctx->Const.FragmentProgram.MaxEnvParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
ctx->Const.FragmentProgram.MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
ctx->Const.FragmentProgram.MaxUniformComponents = MAX_FRAGMENT_UNIFORM_COMPONENTS;
ctx->Const.FragmentProgram.MaxUniformComponents = 4 * MAX_UNIFORMS;
init_natives(&ctx->Const.FragmentProgram);
#endif
ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
@ -1095,7 +1105,7 @@ _mesa_init_constants( GLcontext *ctx )
#if FEATURE_ARB_vertex_shader
ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
ctx->Const.MaxVaryingFloats = MAX_VARYING_FLOATS;
ctx->Const.MaxVarying = MAX_VARYING;
#endif
/* sanity checks */
@ -1103,6 +1113,11 @@ _mesa_init_constants( GLcontext *ctx )
ctx->Const.MaxTextureCoordUnits));
ASSERT(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
ASSERT(ctx->Const.VertexProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
ASSERT(MAX_NV_FRAGMENT_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS);
ASSERT(MAX_NV_VERTEX_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS);
ASSERT(MAX_NV_VERTEX_PROGRAM_INPUTS <= VERT_ATTRIB_MAX);
ASSERT(MAX_NV_VERTEX_PROGRAM_OUTPUTS <= VERT_RESULT_MAX);
}
@ -1144,7 +1159,7 @@ check_context_limits(GLcontext *ctx)
* functions for the more complex data structures.
*/
static GLboolean
init_attrib_groups( GLcontext *ctx )
init_attrib_groups(GLcontext *ctx)
{
assert(ctx);
@ -1180,7 +1195,7 @@ init_attrib_groups( GLcontext *ctx )
_mesa_init_query( ctx );
_mesa_init_rastpos( ctx );
_mesa_init_scissor( ctx );
_mesa_init_shaderobjects (ctx);
_mesa_init_shader_state( ctx );
_mesa_init_stencil( ctx );
_mesa_init_transform( ctx );
_mesa_init_varray( ctx );
@ -1267,11 +1282,11 @@ alloc_dispatch_table(void)
* \param driverContext pointer to driver-specific context data
*/
GLboolean
_mesa_initialize_context( GLcontext *ctx,
const GLvisual *visual,
GLcontext *share_list,
const struct dd_function_table *driverFunctions,
void *driverContext )
_mesa_initialize_context(GLcontext *ctx,
const GLvisual *visual,
GLcontext *share_list,
const struct dd_function_table *driverFunctions,
void *driverContext)
{
ASSERT(driverContext);
assert(driverFunctions->NewTextureObject);
@ -1340,12 +1355,14 @@ _mesa_initialize_context( GLcontext *ctx,
ctx->TnlModule.SwapCount = 0;
#endif
ctx->_MaintainTexEnvProgram = (_mesa_getenv("MESA_TEX_PROG") != NULL);
ctx->_UseTexEnvProgram = ctx->_MaintainTexEnvProgram;
ctx->_MaintainTnlProgram = (_mesa_getenv("MESA_TNL_PROG") != NULL);
if (ctx->_MaintainTnlProgram)
ctx->_MaintainTexEnvProgram = 1; /* this is required... */
ctx->VertexProgram._MaintainTnlProgram
= (_mesa_getenv("MESA_TNL_PROG") != NULL);
if (ctx->VertexProgram._MaintainTnlProgram)
/* this is required... */
ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
else
ctx->FragmentProgram._MaintainTexEnvProgram
= (_mesa_getenv("MESA_TEX_PROG") != NULL);
ctx->FirstTimeCurrent = GL_TRUE;
@ -1368,11 +1385,10 @@ _mesa_initialize_context( GLcontext *ctx,
* \return pointer to a new __GLcontextRec or NULL if error.
*/
GLcontext *
_mesa_create_context( const GLvisual *visual,
GLcontext *share_list,
const struct dd_function_table *driverFunctions,
void *driverContext )
_mesa_create_context(const GLvisual *visual,
GLcontext *share_list,
const struct dd_function_table *driverFunctions,
void *driverContext)
{
GLcontext *ctx;
@ -1423,6 +1439,7 @@ _mesa_free_context_data( GLcontext *ctx )
_mesa_free_viewport_data( ctx );
_mesa_free_colortables_data( ctx );
_mesa_free_program_data(ctx);
_mesa_free_shader_state(ctx);
_mesa_free_query_data(ctx);
#if FEATURE_ARB_vertex_buffer_object
@ -1696,6 +1713,30 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
}
}
#if 0 /** XXX enable this someday */
if (oldCtx && oldCtx != newCtx) {
/* unbind old context's draw/read buffers */
if (oldCtx->DrawBuffer && oldCtx->DrawBuffer->Name == 0) {
oldCtx->DrawBuffer->RefCount--;
oldCtx->DrawBuffer = NULL;
}
if (oldCtx->ReadBuffer && oldCtx->ReadBuffer->Name == 0) {
oldCtx->ReadBuffer->RefCount--;
oldCtx->ReadBuffer = NULL;
}
if (oldCtx->WinSysDrawBuffer) {
ASSERT(oldCtx->WinSysDrawBuffer->Name == 0);
oldCtx->WinSysDrawBuffer->RefCount--;
oldCtx->WinSysDrawBuffer = NULL;
}
if (oldCtx->WinSysReadBuffer) {
ASSERT(oldCtx->WinSysReadBuffer->Name == 0);
oldCtx->WinSysReadBuffer->RefCount--;
oldCtx->WinSysReadBuffer = NULL;
}
}
#endif
/* We used to call _glapi_check_multithread() here. Now do it in drivers */
_glapi_set_context((void *) newCtx);
ASSERT(_mesa_get_current_context() == newCtx);
@ -1813,12 +1854,11 @@ _mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare)
/**
* Get current context for the calling thread.
*
* \return pointer to the current GL context.
* \return pointer to the current GL context for this thread.
*
* Calls _glapi_get_context(). This isn't the fastest way to get the current
* context. If you need speed, see the #GET_CURRENT_CONTEXT macro in context.h.
* context. If you need speed, see the #GET_CURRENT_CONTEXT macro in
* context.h.
*/
GLcontext *
_mesa_get_current_context( void )
@ -1826,6 +1866,7 @@ _mesa_get_current_context( void )
return (GLcontext *) _glapi_get_context();
}
/**
* Get context's current API dispatch table.
*
@ -1865,7 +1906,7 @@ _mesa_get_dispatch(GLcontext *ctx)
* This is called via _mesa_error().
*/
void
_mesa_record_error( GLcontext *ctx, GLenum error )
_mesa_record_error(GLcontext *ctx, GLenum error)
{
if (!ctx)
return;
@ -1876,10 +1917,11 @@ _mesa_record_error( GLcontext *ctx, GLenum error )
/* Call device driver's error handler, if any. This is used on the Mac. */
if (ctx->Driver.Error) {
(*ctx->Driver.Error)( ctx );
ctx->Driver.Error(ctx);
}
}
/**
* Execute glFinish().
*
@ -1887,15 +1929,16 @@ _mesa_record_error( GLcontext *ctx, GLenum error )
* dd_function_table::Finish driver callback, if not NULL.
*/
void GLAPIENTRY
_mesa_Finish( void )
_mesa_Finish(void)
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (ctx->Driver.Finish) {
(*ctx->Driver.Finish)( ctx );
ctx->Driver.Finish(ctx);
}
}
/**
* Execute glFlush().
*
@ -1903,12 +1946,12 @@ _mesa_Finish( void )
* dd_function_table::Flush driver callback, if not NULL.
*/
void GLAPIENTRY
_mesa_Flush( void )
_mesa_Flush(void)
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (ctx->Driver.Flush) {
(*ctx->Driver.Flush)( ctx );
ctx->Driver.Flush(ctx);
}
}

View file

@ -570,9 +570,9 @@ struct dd_function_table {
/** Notify driver that a program string has been specified. */
void (*ProgramStringNotify)(GLcontext *ctx, GLenum target,
struct gl_program *prog);
/** Get value of a fragment program register during program execution. */
void (*GetFragmentProgramRegister)(GLcontext *ctx, enum register_file file,
GLuint index, GLfloat val[4]);
/** Get value of a program register during program execution. */
void (*GetProgramRegister)(GLcontext *ctx, enum register_file file,
GLuint index, GLfloat val[4]);
/** Query if program can be loaded onto hardware */
GLboolean (*IsProgramNative)(GLcontext *ctx, GLenum target,
@ -821,6 +821,58 @@ struct dd_function_table {
void (*BindArrayObject)(GLcontext *ctx, struct gl_array_object *obj);
/*@}*/
/**
* \name GLSL-related functions (ARB extensions and OpenGL 2.x)
*/
/*@{*/
void (*AttachShader)(GLcontext *ctx, GLuint program, GLuint shader);
void (*BindAttribLocation)(GLcontext *ctx, GLuint program, GLuint index,
const GLcharARB *name);
void (*CompileShader)(GLcontext *ctx, GLuint shader);
GLuint (*CreateShader)(GLcontext *ctx, GLenum type);
GLuint (*CreateProgram)(GLcontext *ctx);
void (*DeleteProgram2)(GLcontext *ctx, GLuint program);
void (*DeleteShader)(GLcontext *ctx, GLuint shader);
void (*DetachShader)(GLcontext *ctx, GLuint program, GLuint shader);
void (*GetActiveAttrib)(GLcontext *ctx, GLuint program, GLuint index,
GLsizei maxLength, GLsizei * length, GLint * size,
GLenum * type, GLcharARB * name);
void (*GetActiveUniform)(GLcontext *ctx, GLuint program, GLuint index,
GLsizei maxLength, GLsizei *length, GLint *size,
GLenum *type, GLcharARB *name);
void (*GetAttachedShaders)(GLcontext *ctx, GLuint program, GLsizei maxCount,
GLsizei *count, GLuint *obj);
GLint (*GetAttribLocation)(GLcontext *ctx, GLuint program,
const GLcharARB *name);
GLuint (*GetHandle)(GLcontext *ctx, GLenum pname);
void (*GetProgramiv)(GLcontext *ctx, GLuint program,
GLenum pname, GLint *params);
void (*GetProgramInfoLog)(GLcontext *ctx, GLuint program, GLsizei bufSize,
GLsizei *length, GLchar *infoLog);
void (*GetShaderiv)(GLcontext *ctx, GLuint shader,
GLenum pname, GLint *params);
void (*GetShaderInfoLog)(GLcontext *ctx, GLuint shader, GLsizei bufSize,
GLsizei *length, GLchar *infoLog);
void (*GetShaderSource)(GLcontext *ctx, GLuint shader, GLsizei maxLength,
GLsizei *length, GLcharARB *sourceOut);
void (*GetUniformfv)(GLcontext *ctx, GLuint program, GLint location,
GLfloat *params);
GLint (*GetUniformLocation)(GLcontext *ctx, GLuint program,
const GLcharARB *name);
GLboolean (*IsProgram)(GLcontext *ctx, GLuint name);
GLboolean (*IsShader)(GLcontext *ctx, GLuint name);
void (*LinkProgram)(GLcontext *ctx, GLuint program);
void (*ShaderSource)(GLcontext *ctx, GLuint shader, const GLchar *source);
void (*Uniform)(GLcontext *ctx, GLint location, GLsizei count,
const GLvoid *values, GLenum type);
void (*UniformMatrix)(GLcontext *ctx, GLint cols, GLint rows,
GLenum matrixType, GLint location, GLsizei count,
GLboolean transpose, const GLfloat *values);
void (*UseProgram)(GLcontext *ctx, GLuint program);
void (*ValidateProgram)(GLcontext *ctx, GLuint program);
/* XXX many more to come */
/*@}*/
/**
* \name Support for multiple T&L engines

View file

@ -1878,7 +1878,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
break;
case GL_MAX_VARYING_FLOATS_ARB:
CHECK_EXT1(ARB_vertex_shader, "GetBooleanv");
params[0] = INT_TO_BOOLEAN(ctx->Const.MaxVaryingFloats);
params[0] = INT_TO_BOOLEAN(ctx->Const.MaxVarying * 4);
break;
case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB:
CHECK_EXT1(ARB_vertex_shader, "GetBooleanv");
@ -1888,6 +1888,10 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
CHECK_EXT1(ARB_vertex_shader, "GetBooleanv");
params[0] = INT_TO_BOOLEAN(MAX_COMBINED_TEXTURE_IMAGE_UNITS);
break;
case GL_CURRENT_PROGRAM:
CHECK_EXT1(ARB_shader_objects, "GetBooleanv");
params[0] = INT_TO_BOOLEAN(ctx->Shader.CurrentProgram ? ctx->Shader.CurrentProgram->Name : 0);
break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv(pname=0x%x)", pname);
}
@ -3705,7 +3709,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
break;
case GL_MAX_VARYING_FLOATS_ARB:
CHECK_EXT1(ARB_vertex_shader, "GetFloatv");
params[0] = (GLfloat)(ctx->Const.MaxVaryingFloats);
params[0] = (GLfloat)(ctx->Const.MaxVarying * 4);
break;
case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB:
CHECK_EXT1(ARB_vertex_shader, "GetFloatv");
@ -3715,6 +3719,10 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
CHECK_EXT1(ARB_vertex_shader, "GetFloatv");
params[0] = (GLfloat)(MAX_COMBINED_TEXTURE_IMAGE_UNITS);
break;
case GL_CURRENT_PROGRAM:
CHECK_EXT1(ARB_shader_objects, "GetFloatv");
params[0] = (GLfloat)(ctx->Shader.CurrentProgram ? ctx->Shader.CurrentProgram->Name : 0);
break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv(pname=0x%x)", pname);
}
@ -5532,7 +5540,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
break;
case GL_MAX_VARYING_FLOATS_ARB:
CHECK_EXT1(ARB_vertex_shader, "GetIntegerv");
params[0] = ctx->Const.MaxVaryingFloats;
params[0] = ctx->Const.MaxVarying * 4;
break;
case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB:
CHECK_EXT1(ARB_vertex_shader, "GetIntegerv");
@ -5542,6 +5550,10 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
CHECK_EXT1(ARB_vertex_shader, "GetIntegerv");
params[0] = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
break;
case GL_CURRENT_PROGRAM:
CHECK_EXT1(ARB_shader_objects, "GetIntegerv");
params[0] = ctx->Shader.CurrentProgram ? ctx->Shader.CurrentProgram->Name : 0;
break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv(pname=0x%x)", pname);
}

View file

@ -989,11 +989,18 @@ StateVars = [
["ctx->Const.VertexProgram.MaxUniformComponents"], "",
["ARB_vertex_shader"] ),
( "GL_MAX_VARYING_FLOATS_ARB", GLint,
["ctx->Const.MaxVaryingFloats"], "", ["ARB_vertex_shader"] ),
["ctx->Const.MaxVarying * 4"], "", ["ARB_vertex_shader"] ),
( "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB", GLint,
["ctx->Const.MaxVertexTextureImageUnits"], "", ["ARB_vertex_shader"] ),
( "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB", GLint,
["MAX_COMBINED_TEXTURE_IMAGE_UNITS"], "", ["ARB_vertex_shader"] )
["MAX_COMBINED_TEXTURE_IMAGE_UNITS"], "", ["ARB_vertex_shader"] ),
# GL_ARB_shader_objects
# Actually, this token isn't part of GL_ARB_shader_objects, but is
# close enough for now.
( "GL_CURRENT_PROGRAM", GLint,
["ctx->Shader.CurrentProgram ? ctx->Shader.CurrentProgram->Name : 0"],
"", ["ARB_shader_objects"] )
]

View file

@ -54,8 +54,8 @@ _mesa_GetString( GLenum name )
static const char *version_1_3 = "1.3 Mesa " MESA_VERSION_STRING;
static const char *version_1_4 = "1.4 Mesa " MESA_VERSION_STRING;
static const char *version_1_5 = "1.5 Mesa " MESA_VERSION_STRING;
static const char *version_2_0 = "1.5 Mesa " MESA_VERSION_STRING;
static const char *version_2_1 = "1.5 Mesa " MESA_VERSION_STRING;
static const char *version_2_0 = "2.0 Mesa " MESA_VERSION_STRING;
static const char *version_2_1 = "2.1 Mesa " MESA_VERSION_STRING;
#if FEATURE_ARB_shading_language_100
static const char *sl_version_110 = "1.10 Mesa " MESA_VERSION_STRING;

View file

@ -849,15 +849,23 @@ _mesa_strncmp( const char *s1, const char *s2, size_t n )
return strncmp(s1, s2, n);
}
/** Implemented using _mesa_malloc() and _mesa_strcpy */
/**
* Implemented using _mesa_malloc() and _mesa_strcpy.
* Note that NULL is handled accordingly.
*/
char *
_mesa_strdup( const char *s )
{
size_t l = _mesa_strlen(s);
char *s2 = (char *) _mesa_malloc(l + 1);
if (s2)
_mesa_strcpy(s2, s);
return s2;
if (s) {
size_t l = _mesa_strlen(s);
char *s2 = (char *) _mesa_malloc(l + 1);
if (s2)
_mesa_strcpy(s2, s);
return s2;
}
else {
return NULL;
}
}
/** Wrapper around atoi() */

View file

@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
* Version: 6.3
* Version: 6.5.3
*
* Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -230,7 +230,7 @@ void GLAPIENTRY
_mesa_PushMatrix( void )
{
GET_CURRENT_CONTEXT(ctx);
struct matrix_stack *stack = ctx->CurrentStack;
struct gl_matrix_stack *stack = ctx->CurrentStack;
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (MESA_VERBOSE&VERBOSE_API)
@ -270,7 +270,7 @@ void GLAPIENTRY
_mesa_PopMatrix( void )
{
GET_CURRENT_CONTEXT(ctx);
struct matrix_stack *stack = ctx->CurrentStack;
struct gl_matrix_stack *stack = ctx->CurrentStack;
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (MESA_VERBOSE&VERBOSE_API)
@ -766,7 +766,7 @@ void _mesa_update_modelview_project( GLcontext *ctx, GLuint new_state )
* initialize it.
*/
static void
init_matrix_stack( struct matrix_stack *stack,
init_matrix_stack( struct gl_matrix_stack *stack,
GLuint maxDepth, GLuint dirtyFlag )
{
GLuint i;
@ -792,7 +792,7 @@ init_matrix_stack( struct matrix_stack *stack,
* frees the array.
*/
static void
free_matrix_stack( struct matrix_stack *stack )
free_matrix_stack( struct gl_matrix_stack *stack )
{
GLuint i;
for (i = 0; i < stack->MaxDepth; i++) {

View file

@ -7,9 +7,9 @@
/*
* Mesa 3-D graphics library
* Version: 6.5
* Version: 6.5.3
*
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -44,6 +44,12 @@
#include "bitset.h"
/**
* Special, internal token
*/
#define GL_SHADER_PROGRAM 0x9999
/**
* Color channel data type.
*/
@ -213,22 +219,6 @@ enum
#define VERT_BIT_GENERIC(g) (1 << (VERT_ATTRIB_GENERIC0 + (g)))
/*@}*/
/**
* GLSL allows shader writers to allocate vertex result attributes (varyings) in
* single float component granularity. This is in contrast to vertex / fragment
* programs, where result attributes (actually texcoords) were allocated
* in 4-component vectors of floats granularity.
* For performance reasons, it would be optimal to stick with this scheme on a scalar
* processor. Varyings will likely be allocated as 3-component vectors, so statistically
* we win 2 floats.
* The constant VARYINGS_PER_VECTOR tells us how much of float components we pack into
* one result vector. For scalar processor it would be 1, for vector processor - 4.
*
* NOTE: Currently we pack varyings into vertex attributes.
*/
#define VARYINGS_PER_VECTOR 2
#define VARYING_EMIT_STYLE EMIT_2F
#define MAX_VARYING_VECTORS ((MAX_VARYING_FLOATS + VARYINGS_PER_VECTOR - 1) / VARYINGS_PER_VECTOR)
/**
* Indexes for vertex program result attributes
@ -250,7 +240,8 @@ enum
#define VERT_RESULT_BFC0 13
#define VERT_RESULT_BFC1 14
#define VERT_RESULT_EDGE 15
#define VERT_RESULT_MAX 16
#define VERT_RESULT_VAR0 16 /**< shader varying */
#define VERT_RESULT_MAX (VERT_RESULT_VAR0 + MAX_VARYING)
/*@}*/
@ -271,7 +262,8 @@ enum
FRAG_ATTRIB_TEX5 = 9,
FRAG_ATTRIB_TEX6 = 10,
FRAG_ATTRIB_TEX7 = 11,
FRAG_ATTRIB_MAX = 12
FRAG_ATTRIB_VAR0 = 12, /**< shader varying */
FRAG_ATTRIB_MAX = (FRAG_ATTRIB_VAR0 + MAX_VARYING)
};
/**
@ -290,6 +282,10 @@ enum
#define FRAG_BIT_TEX5 (1 << FRAG_ATTRIB_TEX5)
#define FRAG_BIT_TEX6 (1 << FRAG_ATTRIB_TEX6)
#define FRAG_BIT_TEX7 (1 << FRAG_ATTRIB_TEX7)
#define FRAG_BIT_VAR0 (1 << FRAG_ATTRIB_VAR0)
#define FRAG_BIT_TEX(U) (FRAG_BIT_TEX0 << (U))
#define FRAG_BIT_VAR(V) (FRAG_BIT_VAR0 << (V))
#define FRAG_BITS_TEX_ANY (FRAG_BIT_TEX0| \
FRAG_BIT_TEX1| \
@ -305,12 +301,14 @@ enum
/**
* Fragment program results
*/
/*@{*/
#define FRAG_RESULT_COLR 0
#define FRAG_RESULT_COLH 1
#define FRAG_RESULT_DEPR 2
#define FRAG_RESULT_MAX 3
/*@}*/
enum
{
FRAG_RESULT_COLR = 0,
FRAG_RESULT_COLH = 1,
FRAG_RESULT_DEPR = 2,
FRAG_RESULT_DATA0 = 3,
FRAG_RESULT_MAX = (FRAG_RESULT_DATA0 + MAX_DRAW_BUFFERS)
};
/**
@ -1829,22 +1827,31 @@ struct gl_evaluators
/**
* Names of the various vertex/fragment program register files, etc.
*
* NOTE: first four tokens must fit into 2 bits (see t_vb_arbprogram.c)
* All values should fit in a 4-bit field.
*
* NOTE: PROGRAM_ENV_PARAM, PROGRAM_STATE_VAR, PROGRAM_NAMED_PARAM,
* PROGRAM_CONSTANT, and PROGRAM_UNIFORM can all be considered to
* be "uniform" variables since they can only be set outside glBegin/End.
* They're also all stored in the same Parameters array.
*/
enum register_file
{
PROGRAM_TEMPORARY = 0,
PROGRAM_LOCAL_PARAM = 1,
PROGRAM_ENV_PARAM = 2,
PROGRAM_STATE_VAR = 3,
PROGRAM_INPUT = 4,
PROGRAM_OUTPUT = 5,
PROGRAM_NAMED_PARAM = 6,
PROGRAM_CONSTANT = 7,
PROGRAM_WRITE_ONLY = 8,
PROGRAM_ADDRESS = 9,
PROGRAM_UNDEFINED = 10, /* invalid value */
PROGRAM_TEMPORARY = 0, /**< machine->Temporary[] */
PROGRAM_LOCAL_PARAM = 1, /**< gl_program->LocalParams[] */
PROGRAM_ENV_PARAM = 2, /**< gl_program->Parameters[] */
PROGRAM_STATE_VAR = 3, /**< gl_program->Parameters[] */
PROGRAM_INPUT = 4, /**< machine->Inputs[] */
PROGRAM_OUTPUT = 5, /**< machine->Outputs[] */
PROGRAM_NAMED_PARAM = 6, /**< gl_program->Parameters[] */
PROGRAM_CONSTANT = 7, /**< gl_program->Parameters[] */
PROGRAM_UNIFORM = 8, /**< gl_program->Parameters[] */
PROGRAM_VARYING = 9, /**< machine->Inputs[]/Outputs[] */
PROGRAM_WRITE_ONLY = 10, /**< A dummy, write-only register */
PROGRAM_ADDRESS = 11, /**< machine->AddressReg */
PROGRAM_SAMPLER = 12, /**< for shader samplers, compile-time only */
PROGRAM_UNDEFINED = 13, /**< Invalid value */
PROGRAM_FILE_MAX
};
@ -1860,22 +1867,28 @@ struct gl_program_parameter_list;
struct gl_program
{
GLuint Id;
GLubyte *String; /**< Null-terminated program text */
GLubyte *String; /**< Null-terminated program text */
GLint RefCount;
GLenum Target;
GLenum Format; /**< String encoding format */
GLenum Target; /**< GL_VERTEX/FRAGMENT_PROGRAM_ARB, GL_FRAGMENT_PROGRAM_NV */
GLenum Format; /**< String encoding format */
GLboolean Resident;
struct prog_instruction *Instructions;
GLbitfield InputsRead; /* Bitmask of which input regs are read */
GLbitfield OutputsWritten; /* Bitmask of which output regs are written to */
GLbitfield InputsRead; /**< Bitmask of which input regs are read */
GLbitfield OutputsWritten; /**< Bitmask of which output regs are written to */
GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS]; /**< TEXTURE_x_BIT bitmask */
/** Named parameters, constants, etc. from program text */
struct gl_program_parameter_list *Parameters;
/** Numbered local parameters */
GLfloat LocalParams[MAX_PROGRAM_LOCAL_PARAMS][4];
/** Vertex/fragment shader varying vars */
struct gl_program_parameter_list *Varying;
/** Vertex program user-defined attributes */
struct gl_program_parameter_list *Attributes;
/** Logical counts */
/*@{*/
GLuint NumInstructions;
@ -1883,6 +1896,9 @@ struct gl_program
GLuint NumParameters;
GLuint NumAttributes;
GLuint NumAddressRegs;
GLuint NumAluInstructions;
GLuint NumTexInstructions;
GLuint NumTexIndirections;
/*@}*/
/** Native, actual h/w counts */
/*@{*/
@ -1891,6 +1907,9 @@ struct gl_program
GLuint NumNativeParameters;
GLuint NumNativeAttributes;
GLuint NumNativeAddressRegs;
GLuint NumNativeAluInstructions;
GLuint NumNativeTexInstructions;
GLuint NumNativeTexIndirections;
/*@}*/
};
@ -1909,13 +1928,6 @@ struct gl_vertex_program
struct gl_fragment_program
{
struct gl_program Base; /**< base class */
GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS]; /**< TEXTURE_x_BIT bitmask */
GLuint NumAluInstructions; /**< GL_ARB_fragment_program */
GLuint NumTexInstructions;
GLuint NumTexIndirections;
GLuint NumNativeAluInstructions; /**< GL_ARB_fragment_program */
GLuint NumNativeTexInstructions;
GLuint NumNativeTexIndirections;
GLenum FogOption;
GLboolean UsesKill;
};
@ -1940,16 +1952,24 @@ struct gl_vertex_program_state
GLboolean _Enabled; /**< Enabled and valid program? */
GLboolean PointSizeEnabled; /**< GL_VERTEX_PROGRAM_POINT_SIZE_ARB/NV */
GLboolean TwoSideEnabled; /**< GL_VERTEX_PROGRAM_TWO_SIDE_ARB/NV */
struct gl_vertex_program *Current; /**< ptr to currently bound program */
const struct gl_vertex_program *_Current; /**< ptr to currently bound
program, including internal
(t_vp_build.c) programs */
struct gl_vertex_program *Current; /**< user-bound vertex program */
GLfloat Parameters[MAX_NV_VERTEX_PROGRAM_PARAMS][4]; /**< Env params */
/** Currently enabled and valid program (including internal programs
* and compiled shader programs).
*/
struct gl_vertex_program *_Current;
GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */
/* For GL_NV_vertex_program only: */
GLenum TrackMatrix[MAX_NV_VERTEX_PROGRAM_PARAMS / 4];
GLenum TrackMatrixTransform[MAX_NV_VERTEX_PROGRAM_PARAMS / 4];
GLenum TrackMatrix[MAX_PROGRAM_ENV_PARAMS / 4];
GLenum TrackMatrixTransform[MAX_PROGRAM_ENV_PARAMS / 4];
/** Should fixed-function T&L be implemented with a vertex prog? */
GLboolean _MaintainTnlProgram;
/** Program to emulate fixed-function T&L (see above) */
struct gl_vertex_program *_TnlProgram;
#if FEATURE_MESA_program_debug
GLprogramcallbackMESA Callback;
@ -1967,11 +1987,20 @@ struct gl_fragment_program_state
{
GLboolean Enabled; /**< User-set fragment program enable flag */
GLboolean _Enabled; /**< Fragment program enabled and valid? */
GLboolean _Active; /**< Is a user program or internal program active? */
struct gl_fragment_program *Current; /**< User-bound program */
const struct gl_fragment_program *_Current; /**< currently active program
(including internal programs) */
GLfloat Parameters[MAX_NV_FRAGMENT_PROGRAM_PARAMS][4]; /**< Env params */
struct gl_fragment_program *Current; /**< User-bound fragment program */
/** Currently enabled and valid program (including internal programs
* and compiled shader programs).
*/
struct gl_fragment_program *_Current;
GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */
/** Should fixed-function texturing be implemented with a fragment prog? */
GLboolean _MaintainTexEnvProgram;
/** Program to emulate fixed-function texture env/combine (see above) */
struct gl_fragment_program *_TexEnvProgram;
#if FEATURE_MESA_program_debug
GLprogramcallbackMESA Callback;
@ -2048,14 +2077,60 @@ struct gl_query_state
};
/**
* Context state for vertex/fragment shaders.
* A GLSL shader object.
*/
struct gl_shader_objects_state
struct gl_shader
{
struct gl2_program_intf **CurrentProgram;
GLboolean _VertexShaderPresent;
GLboolean _FragmentShaderPresent;
GLenum Type; /**< GL_FRAGMENT_SHADER || GL_VERTEX_SHADER (first field!) */
GLuint Name; /**< AKA the handle */
GLint RefCount; /**< Reference count */
GLboolean DeletePending;
const GLchar *Source; /**< Source code string */
GLboolean CompileStatus;
GLuint NumPrograms; /**< size of Programs[] array */
struct gl_program **Programs; /**< Post-compile assembly code */
GLchar *InfoLog;
};
/**
* A GLSL program object. Basically a linked collection of "shaders".
*/
struct gl_shader_program
{
GLenum Type; /**< Always GL_SHADER_PROGRAM (internal token) */
GLuint Name; /**< aka handle or ID */
GLint RefCount; /**< Reference count */
GLboolean DeletePending;
GLuint NumShaders; /**< number of attached shaders */
struct gl_shader **Shaders; /**< List of attached the shaders */
/* post-link info: */
struct gl_vertex_program *VertexProgram; /**< Linked vertex program */
struct gl_fragment_program *FragmentProgram; /**< Linked fragment prog */
struct gl_program_parameter_list *Uniforms; /**< Plus constants, etc */
struct gl_program_parameter_list *Varying;
struct gl_program_parameter_list *Attributes; /**< Vertex attributes */
GLboolean LinkStatus; /**< GL_LINK_STATUS */
GLboolean Validated;
GLchar *InfoLog;
};
/**
* Context state for GLSL vertex/fragment shaders.
*/
struct gl_shader_state
{
struct gl_shader_program *CurrentProgram; /**< The user-bound program */
/** Driver-selectable options: */
GLboolean EmitHighLevelInstructions; /**< IF/ELSE/ENDIF vs. BRA, etc. */
GLboolean EmitCondCodes; /**< Use condition codes? */
GLboolean EmitComments; /**< Annotated instructions */
};
@ -2116,7 +2191,8 @@ struct gl_shared_state
#endif
#if FEATURE_ARB_shader_objects
struct _mesa_HashTable *GL2Objects;
/** Table of both gl_shader and gl_shader_program objects */
struct _mesa_HashTable *ShaderObjects;
#endif
#if FEATURE_EXT_framebuffer_object
@ -2396,7 +2472,7 @@ struct gl_constants
GLuint MaxRenderbufferSize;
/* GL_ARB_vertex_shader */
GLuint MaxVertexTextureImageUnits;
GLuint MaxVaryingFloats;
GLuint MaxVarying;
};
@ -2534,7 +2610,7 @@ struct gl_extensions
/**
* A stack of matrices (projection, modelview, color, texture, etc).
*/
struct matrix_stack
struct gl_matrix_stack
{
GLmatrix *Top; /**< points into Stack */
GLmatrix *Stack; /**< array [MaxDepth] of GLmatrix */
@ -2765,7 +2841,7 @@ struct mesa_display_list
/**
* State used during display list compilation and execution.
*/
struct mesa_list_state
struct gl_dlist_state
{
struct mesa_display_list *CallStack[MAX_LIST_NESTING];
GLuint CallDepth; /**< Current recursion calling depth */
@ -2837,26 +2913,25 @@ struct __GLcontextRec
struct dd_function_table Driver;
void *DriverCtx; /**< Points to device driver context/state */
void *DriverMgrCtx; /**< Points to device driver manager (optional)*/
/** Core/Driver constants */
struct gl_constants Const;
/** \name The various 4x4 matrix stacks */
/*@{*/
struct matrix_stack ModelviewMatrixStack;
struct matrix_stack ProjectionMatrixStack;
struct matrix_stack ColorMatrixStack;
struct matrix_stack TextureMatrixStack[MAX_TEXTURE_COORD_UNITS];
struct matrix_stack ProgramMatrixStack[MAX_PROGRAM_MATRICES];
struct matrix_stack *CurrentStack; /**< Points to one of the above stacks */
struct gl_matrix_stack ModelviewMatrixStack;
struct gl_matrix_stack ProjectionMatrixStack;
struct gl_matrix_stack ColorMatrixStack;
struct gl_matrix_stack TextureMatrixStack[MAX_TEXTURE_COORD_UNITS];
struct gl_matrix_stack ProgramMatrixStack[MAX_PROGRAM_MATRICES];
struct gl_matrix_stack *CurrentStack; /**< Points to one of the above stacks */
/*@}*/
/** Combined modelview and projection matrix */
GLmatrix _ModelProjectMatrix;
/** \name Display lists */
struct mesa_list_state ListState;
struct gl_dlist_state ListState;
GLboolean ExecuteFlag; /**< Execute GL commands? */
GLboolean CompileFlag; /**< Compile GL commands into display list? */
@ -2939,16 +3014,9 @@ struct __GLcontextRec
struct gl_fragment_program_state FragmentProgram; /**< GL_ARB/NV_vertex_program */
struct gl_ati_fragment_shader_state ATIFragmentShader; /**< GL_ATI_fragment_shader */
struct gl_fragment_program *_TexEnvProgram; /**< Texture state as fragment program */
struct gl_vertex_program *_TnlProgram; /**< Fixed func TNL state as vertex program */
GLboolean _MaintainTnlProgram;
GLboolean _MaintainTexEnvProgram;
GLboolean _UseTexEnvProgram;
struct gl_query_state Query; /**< GL_ARB_occlusion_query */
struct gl_shader_objects_state ShaderObjects; /* GL_ARB_shader_objects */
struct gl_shader_state Shader; /**< GLSL shader object state */
/*@}*/
#if FEATURE_EXT_framebuffer_object

View file

@ -911,16 +911,16 @@ _mesa_PixelTransferf( GLenum pname, GLfloat param )
ctx->Pixel.PostConvolutionBias[2] = param;
break;
case GL_POST_CONVOLUTION_ALPHA_SCALE:
if (ctx->Pixel.PostConvolutionScale[2] == param)
if (ctx->Pixel.PostConvolutionScale[3] == param)
return;
FLUSH_VERTICES(ctx, _NEW_PIXEL);
ctx->Pixel.PostConvolutionScale[2] = param;
ctx->Pixel.PostConvolutionScale[3] = param;
break;
case GL_POST_CONVOLUTION_ALPHA_BIAS:
if (ctx->Pixel.PostConvolutionBias[2] == param)
if (ctx->Pixel.PostConvolutionBias[3] == param)
return;
FLUSH_VERTICES(ctx, _NEW_PIXEL);
ctx->Pixel.PostConvolutionBias[2] = param;
ctx->Pixel.PostConvolutionBias[3] = param;
break;
default:
_mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" );

680
src/mesa/main/shaders.c Normal file
View file

@ -0,0 +1,680 @@
/*
* Mesa 3-D graphics library
* Version: 6.5.3
*
* Copyright (C) 2004-2007 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "glheader.h"
#include "context.h"
#include "shaders.h"
/**
* These are basically just wrappers/adaptors for calling the
* ctx->Driver.foobar() GLSL-related functions.
*
* Things are biased toward the OpenGL 2.0 functions rather than the
* ARB extensions (i.e. the ARB functions are layered on the 2.0 functions).
*
* The general idea here is to allow enough modularity such that a
* completely different GLSL implemenation can be plugged in and co-exist
* with Mesa's native GLSL code.
*/
void GLAPIENTRY
_mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.AttachShader(ctx, program, shader);
}
void GLAPIENTRY
_mesa_AttachShader(GLuint program, GLuint shader)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.AttachShader(ctx, program, shader);
}
void GLAPIENTRY
_mesa_BindAttribLocationARB(GLhandleARB program, GLuint index,
const GLcharARB *name)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.BindAttribLocation(ctx, program, index, name);
}
void GLAPIENTRY
_mesa_CompileShaderARB(GLhandleARB shaderObj)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.CompileShader(ctx, shaderObj);
}
GLuint GLAPIENTRY
_mesa_CreateShader(GLenum type)
{
GET_CURRENT_CONTEXT(ctx);
return ctx->Driver.CreateShader(ctx, type);
}
GLhandleARB APIENTRY
_mesa_CreateShaderObjectARB(GLenum type)
{
GET_CURRENT_CONTEXT(ctx);
return ctx->Driver.CreateShader(ctx, type);
}
GLuint GLAPIENTRY
_mesa_CreateProgram(void)
{
GET_CURRENT_CONTEXT(ctx);
return ctx->Driver.CreateProgram(ctx);
}
GLhandleARB APIENTRY
_mesa_CreateProgramObjectARB(void)
{
GET_CURRENT_CONTEXT(ctx);
return ctx->Driver.CreateProgram(ctx);
}
void GLAPIENTRY
_mesa_DeleteObjectARB(GLhandleARB obj)
{
if (obj) {
GET_CURRENT_CONTEXT(ctx);
if (ctx->Driver.IsProgram(ctx, obj)) {
ctx->Driver.DeleteProgram2(ctx, obj);
}
else if (ctx->Driver.IsShader(ctx, obj)) {
ctx->Driver.DeleteShader(ctx, obj);
}
else {
/* error? */
}
}
}
void GLAPIENTRY
_mesa_DeleteProgram(GLuint name)
{
if (name) {
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.DeleteProgram2(ctx, name);
}
}
void GLAPIENTRY
_mesa_DeleteShader(GLuint name)
{
if (name) {
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.DeleteShader(ctx, name);
}
}
void GLAPIENTRY
_mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.DetachShader(ctx, program, shader);
}
void GLAPIENTRY
_mesa_DetachShader(GLuint program, GLuint shader)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.DetachShader(ctx, program, shader);
}
void GLAPIENTRY
_mesa_GetActiveAttribARB(GLhandleARB program, GLuint index,
GLsizei maxLength, GLsizei * length, GLint * size,
GLenum * type, GLcharARB * name)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.GetActiveAttrib(ctx, program, index, maxLength, length, size,
type, name);
}
void GLAPIENTRY
_mesa_GetActiveUniformARB(GLhandleARB program, GLuint index,
GLsizei maxLength, GLsizei * length, GLint * size,
GLenum * type, GLcharARB * name)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.GetActiveUniform(ctx, program, index, maxLength, length, size,
type, name);
}
void GLAPIENTRY
_mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
GLsizei * count, GLhandleARB * obj)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.GetAttachedShaders(ctx, container, maxCount, count, obj);
}
void GLAPIENTRY
_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
GLsizei *count, GLuint *obj)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.GetAttachedShaders(ctx, program, maxCount, count, obj);
}
GLint GLAPIENTRY
_mesa_GetAttribLocationARB(GLhandleARB program, const GLcharARB * name)
{
GET_CURRENT_CONTEXT(ctx);
return ctx->Driver.GetAttribLocation(ctx, program, name);
}
void GLAPIENTRY
_mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
GLcharARB * infoLog)
{
GET_CURRENT_CONTEXT(ctx);
/* Implement in terms of GetProgramInfoLog, GetShaderInfoLog */
if (ctx->Driver.IsProgram(ctx, object)) {
ctx->Driver.GetProgramInfoLog(ctx, object, maxLength, length, infoLog);
}
else if (ctx->Driver.IsShader(ctx, object)) {
ctx->Driver.GetShaderInfoLog(ctx, object, maxLength, length, infoLog);
}
else {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB");
}
}
void GLAPIENTRY
_mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
{
GET_CURRENT_CONTEXT(ctx);
/* Implement in terms of GetProgramiv, GetShaderiv */
if (ctx->Driver.IsProgram(ctx, object)) {
ctx->Driver.GetProgramiv(ctx, object, pname, params);
}
else if (ctx->Driver.IsShader(ctx, object)) {
ctx->Driver.GetShaderiv(ctx, object, pname, params);
}
else {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB");
}
}
void GLAPIENTRY
_mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
GLfloat *params)
{
GLint iparams[1]; /* XXX is one element enough? */
_mesa_GetObjectParameterivARB(object, pname, iparams);
params[0] = (GLfloat) iparams[0];
}
void GLAPIENTRY
_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.GetProgramiv(ctx, program, pname, params);
}
void GLAPIENTRY
_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.GetShaderiv(ctx, shader, pname, params);
}
void GLAPIENTRY
_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
GLsizei *length, GLchar *infoLog)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.GetProgramInfoLog(ctx, program, bufSize, length, infoLog);
}
void GLAPIENTRY
_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
GLsizei *length, GLchar *infoLog)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.GetShaderInfoLog(ctx, shader, bufSize, length, infoLog);
}
void GLAPIENTRY
_mesa_GetShaderSourceARB(GLhandleARB shader, GLsizei maxLength,
GLsizei *length, GLcharARB *sourceOut)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.GetShaderSource(ctx, shader, maxLength, length, sourceOut);
}
void GLAPIENTRY
_mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat * params)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.GetUniformfv(ctx, program, location, params);
}
void GLAPIENTRY
_mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint * params)
{
GET_CURRENT_CONTEXT(ctx);
GLfloat fparams[16]; /* XXX is 16 enough? */
GLuint i;
ctx->Driver.GetUniformfv(ctx, program, location, fparams);
for (i = 0; i < 16; i++)
params[i] = (GLint) fparams[i]; /* XXX correct? */
}
#if 0
GLint APIENTRY
_mesa_GetUniformLocation(GLuint program, const GLcharARB *name)
{
GET_CURRENT_CONTEXT(ctx);
return ctx->Driver.GetUniformLocation(ctx, program, name);
}
#endif
GLhandleARB GLAPIENTRY
_mesa_GetHandleARB(GLenum pname)
{
GET_CURRENT_CONTEXT(ctx);
return ctx->Driver.GetHandle(ctx, pname);
}
GLint APIENTRY
_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
{
GET_CURRENT_CONTEXT(ctx);
return ctx->Driver.GetUniformLocation(ctx, programObj, name);
}
GLboolean GLAPIENTRY
_mesa_IsProgram(GLuint name)
{
GET_CURRENT_CONTEXT(ctx);
return ctx->Driver.IsProgram(ctx, name);
}
GLboolean GLAPIENTRY
_mesa_IsShader(GLuint name)
{
GET_CURRENT_CONTEXT(ctx);
return ctx->Driver.IsShader(ctx, name);
}
void GLAPIENTRY
_mesa_LinkProgramARB(GLhandleARB programObj)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.LinkProgram(ctx, programObj);
}
/**
* Called via glShaderSource() and glShaderSourceARB() API functions.
* Basically, concatenate the source code strings into one long string
* and pass it to ctx->Driver.ShaderSource().
*/
void GLAPIENTRY
_mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
const GLcharARB ** string, const GLint * length)
{
GET_CURRENT_CONTEXT(ctx);
GLint *offsets;
GLsizei i, totalLength;
GLcharARB *source;
if (string == NULL) {
_mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
return;
}
/*
* This array holds offsets of where the appropriate string ends, thus the
* last element will be set to the total length of the source code.
*/
offsets = (GLint *) _mesa_malloc(count * sizeof(GLint));
if (offsets == NULL) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
return;
}
for (i = 0; i < count; i++) {
if (string[i] == NULL) {
_mesa_free((GLvoid *) offsets);
_mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB(null string)");
return;
}
if (length == NULL || length[i] < 0)
offsets[i] = _mesa_strlen(string[i]);
else
offsets[i] = length[i];
/* accumulate string lengths */
if (i > 0)
offsets[i] += offsets[i - 1];
}
/* Total length of source string is sum off all strings plus two.
* One extra byte for terminating zero, another extra byte to silence
* valgrind warnings in the parser/grammer code.
*/
totalLength = offsets[count - 1] + 2;
source = (GLcharARB *) _mesa_malloc(totalLength * sizeof(GLcharARB));
if (source == NULL) {
_mesa_free((GLvoid *) offsets);
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
return;
}
for (i = 0; i < count; i++) {
GLint start = (i > 0) ? offsets[i - 1] : 0;
_mesa_memcpy(source + start, string[i],
(offsets[i] - start) * sizeof(GLcharARB));
}
source[totalLength - 1] = '\0';
source[totalLength - 2] = '\0';
ctx->Driver.ShaderSource(ctx, shaderObj, source);
_mesa_free(offsets);
}
void GLAPIENTRY
_mesa_Uniform1fARB(GLint location, GLfloat v0)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, 1, &v0, GL_FLOAT);
}
void GLAPIENTRY
_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
{
GET_CURRENT_CONTEXT(ctx);
GLfloat v[2];
v[0] = v0;
v[1] = v1;
ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC2);
}
void GLAPIENTRY
_mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
{
GET_CURRENT_CONTEXT(ctx);
GLfloat v[3];
v[0] = v0;
v[1] = v1;
v[2] = v2;
ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC3);
}
void GLAPIENTRY
_mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
GLfloat v3)
{
GET_CURRENT_CONTEXT(ctx);
GLfloat v[4];
v[0] = v0;
v[1] = v1;
v[2] = v2;
v[3] = v3;
ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC4);
}
void GLAPIENTRY
_mesa_Uniform1iARB(GLint location, GLint v0)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, 1, &v0, GL_INT);
}
void GLAPIENTRY
_mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
{
GET_CURRENT_CONTEXT(ctx);
GLint v[2];
v[0] = v0;
v[1] = v1;
ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC2);
}
void GLAPIENTRY
_mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
{
GET_CURRENT_CONTEXT(ctx);
GLint v[3];
v[0] = v0;
v[1] = v1;
v[2] = v2;
ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC3);
}
void GLAPIENTRY
_mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
{
GET_CURRENT_CONTEXT(ctx);
GLint v[4];
v[0] = v0;
v[1] = v1;
v[2] = v2;
v[3] = v3;
ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC4);
}
void GLAPIENTRY
_mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT);
}
void GLAPIENTRY
_mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC2);
}
void GLAPIENTRY
_mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC3);
}
void GLAPIENTRY
_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC4);
}
void GLAPIENTRY
_mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_INT);
}
void GLAPIENTRY
_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC2);
}
void GLAPIENTRY
_mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC3);
}
void GLAPIENTRY
_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC4);
}
void GLAPIENTRY
_mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.UniformMatrix(ctx, 2, 2, GL_FLOAT_MAT2,
location, count, transpose, value);
}
void GLAPIENTRY
_mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.UniformMatrix(ctx, 3, 3, GL_FLOAT_MAT3,
location, count, transpose, value);
}
void GLAPIENTRY
_mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.UniformMatrix(ctx, 4, 4, GL_FLOAT_MAT4,
location, count, transpose, value);
}
/**
* Non-square UniformMatrix are OpenGL 2.1
*/
void GLAPIENTRY
_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.UniformMatrix(ctx, 2, 3, GL_FLOAT_MAT2x3,
location, count, transpose, value);
}
void GLAPIENTRY
_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.UniformMatrix(ctx, 3, 2, GL_FLOAT_MAT3x2,
location, count, transpose, value);
}
void GLAPIENTRY
_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.UniformMatrix(ctx, 2, 4, GL_FLOAT_MAT2x4,
location, count, transpose, value);
}
void GLAPIENTRY
_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.UniformMatrix(ctx, 4, 2, GL_FLOAT_MAT4x2,
location, count, transpose, value);
}
void GLAPIENTRY
_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.UniformMatrix(ctx, 3, 4, GL_FLOAT_MAT3x4,
location, count, transpose, value);
}
void GLAPIENTRY
_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.UniformMatrix(ctx, 4, 3, GL_FLOAT_MAT4x3,
location, count, transpose, value);
}
void GLAPIENTRY
_mesa_UseProgramObjectARB(GLhandleARB program)
{
GET_CURRENT_CONTEXT(ctx);
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
ctx->Driver.UseProgram(ctx, program);
}
void GLAPIENTRY
_mesa_ValidateProgramARB(GLhandleARB program)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.ValidateProgram(ctx, program);
}

View file

@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
* Version: 6.5
* Version: 6.5.3
*
* Copyright (C) 2004-2006 Brian Paul All Rights Reserved.
* Copyright (C) 2004-2007 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -22,124 +22,13 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef SHADEROBJECTS_H
#define SHADEROBJECTS_H
#include "context.h"
#ifndef SHADERS_H
#define SHADERS_H
#if FEATURE_ARB_shader_objects
/**
* gl2 unique interface identifier.
* Each gl2 interface has its own interface id used for object queries.
*/
enum gl2_uiid
{
UIID_UNKNOWN, /* supported by all objects */
UIID_GENERIC, /* generic object */
UIID_CONTAINER, /* contains generic objects */
UIID_SHADER, /* shader object */
UIID_FRAGMENT_SHADER, /* fragment shader */
UIID_VERTEX_SHADER, /* vertex shader */
UIID_PROGRAM, /* program object */
UIID_3DLABS_SHHANDLE, /* encapsulates 3DLabs' ShHandle */
UIID_DEBUG /* debug object */
};
struct gl2_unknown_intf
{
GLvoid (* AddRef) (struct gl2_unknown_intf **);
GLvoid (* Release) (struct gl2_unknown_intf **);
struct gl2_unknown_intf **(* QueryInterface) (struct gl2_unknown_intf **, enum gl2_uiid uiid);
};
struct gl2_generic_intf
{
struct gl2_unknown_intf _unknown;
GLvoid (* Delete) (struct gl2_generic_intf **);
GLenum (* GetType) (struct gl2_generic_intf **);
GLhandleARB (* GetName) (struct gl2_generic_intf **);
GLboolean (* GetDeleteStatus) (struct gl2_generic_intf **);
GLvoid (* GetInfoLog) (struct gl2_generic_intf **, GLsizei, GLcharARB *);
GLsizei (* GetInfoLogLength) (struct gl2_generic_intf **);
};
struct gl2_container_intf
{
struct gl2_generic_intf _generic;
GLboolean (* Attach) (struct gl2_container_intf **, struct gl2_generic_intf **);
GLboolean (* Detach) (struct gl2_container_intf **, struct gl2_generic_intf **);
GLsizei (* GetAttachedCount) (struct gl2_container_intf **);
struct gl2_generic_intf **(* GetAttached) (struct gl2_container_intf **, GLuint);
};
struct gl2_shader_intf
{
struct gl2_generic_intf _generic;
GLenum (* GetSubType) (struct gl2_shader_intf **);
GLboolean (* GetCompileStatus) (struct gl2_shader_intf **);
GLvoid (* SetSource) (struct gl2_shader_intf **, GLcharARB *, GLint *, GLsizei);
const GLcharARB *(* GetSource) (struct gl2_shader_intf **);
GLvoid (* Compile) (struct gl2_shader_intf **);
};
struct gl2_program_intf
{
struct gl2_container_intf _container;
GLboolean (* GetLinkStatus) (struct gl2_program_intf **);
GLboolean (* GetValidateStatus) (struct gl2_program_intf **);
GLvoid (* Link) (struct gl2_program_intf **);
GLvoid (* Validate) (struct gl2_program_intf **);
GLvoid (* UpdateFixedUniforms) (struct gl2_program_intf **);
GLvoid (* UpdateFixedAttrib) (struct gl2_program_intf **, GLuint, GLvoid *, GLuint, GLuint,
GLboolean);
GLvoid (* UpdateFixedVarying) (struct gl2_program_intf **, GLuint, GLvoid *, GLuint, GLuint,
GLboolean);
GLvoid (* GetTextureImageUsage) (struct gl2_program_intf **, GLbitfield *);
GLboolean (* IsShaderPresent) (struct gl2_program_intf **, GLenum);
GLvoid (* GetActiveUniform) (struct gl2_program_intf **, GLuint index, GLsizei maxLength,
GLsizei *length, GLint *size, GLenum *type, GLchar *name);
GLuint (* GetActiveUniformMaxLength) (struct gl2_program_intf **);
GLuint (* GetActiveUniformCount) (struct gl2_program_intf **);
GLint (* GetUniformLocation) (struct gl2_program_intf **, const GLchar *name);
GLboolean (* WriteUniform) (struct gl2_program_intf **, GLint loc, GLsizei count,
const GLvoid *data, GLenum type);
GLboolean (* ReadUniform) (struct gl2_program_intf **, GLint loc, GLsizei count,
GLvoid *data, GLenum type);
GLvoid (* GetActiveAttrib) (struct gl2_program_intf **, GLuint index, GLsizei maxLength,
GLsizei *length, GLint *size, GLenum *type, GLchar *name);
GLuint (* GetActiveAttribMaxLength) (struct gl2_program_intf **);
GLuint (* GetActiveAttribCount) (struct gl2_program_intf **);
GLint (* GetAttribLocation) (struct gl2_program_intf **, const GLchar *name);
GLvoid (* OverrideAttribBinding) (struct gl2_program_intf **, GLuint, const GLchar *);
GLvoid (* WriteAttrib) (struct gl2_program_intf **, GLuint, const GLfloat *);
GLvoid (* UpdateVarying) (struct gl2_program_intf **, GLuint, GLfloat *, GLboolean);
};
struct gl2_fragment_shader_intf
{
struct gl2_shader_intf _shader;
};
struct gl2_vertex_shader_intf
{
struct gl2_shader_intf _shader;
};
struct gl2_3dlabs_shhandle_intf
{
struct gl2_unknown_intf _unknown;
GLvoid *(* GetShHandle) (struct gl2_3dlabs_shhandle_intf **);
};
struct gl2_debug_intf
{
struct gl2_generic_intf _generic;
GLvoid (* ClearDebugLog) (struct gl2_debug_intf **, GLenum logType, GLenum shaderType);
GLvoid (* GetDebugLog) (struct gl2_debug_intf **, GLenum logType, GLenum shaderType,
GLsizei maxLength, GLsizei *length, GLcharARB *infoLog);
GLsizei (* GetDebugLogLength) (struct gl2_debug_intf **, GLenum logType, GLenum shaderType);
};
#include "glheader.h"
#include "mtypes.h"
extern void GLAPIENTRY
@ -344,10 +233,4 @@ _mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value);
#endif /* FEATURE_ARB_shader_objects */
extern void
_mesa_init_shaderobjects (GLcontext *ctx);
#endif /* SHADEROBJECTS_H */
#endif /* SHADERS_H */

View file

@ -93,7 +93,7 @@
#include "texenvprogram.h"
#endif
#if FEATURE_ARB_shader_objects
#include "shaderobjects.h"
#include "shaders.h"
#endif
#include "debug.h"
#include "dispatch.h"
@ -832,11 +832,7 @@ update_arrays( GLcontext *ctx )
/* find min of _MaxElement values for all enabled arrays */
/* 0 */
if (ctx->ShaderObjects._VertexShaderPresent
&& ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) {
min = ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0]._MaxElement;
}
else if (ctx->VertexProgram._Enabled
if (ctx->VertexProgram._Current
&& ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) {
min = ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS]._MaxElement;
}
@ -920,7 +916,7 @@ update_arrays( GLcontext *ctx )
}
/* 16..31 */
if (ctx->ShaderObjects._VertexShaderPresent) {
if (ctx->VertexProgram._Current) {
for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) {
if (ctx->Array.ArrayObj->VertexAttrib[i].Enabled) {
min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[i]._MaxElement);
@ -943,30 +939,66 @@ update_arrays( GLcontext *ctx )
static void
update_program(GLcontext *ctx)
{
/* For now, just set the _Enabled (really enabled) flags.
* In the future we may have to check other state to be sure we really
* have a runable program or shader.
*/
const struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
/* These _Enabled flags indicate if the program is enabled AND valid. */
ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled
&& ctx->VertexProgram.Current->Base.Instructions;
ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled
&& ctx->FragmentProgram.Current->Base.Instructions;
ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled
&& ctx->ATIFragmentShader.Current->Instructions;
ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled;
if (ctx->_MaintainTexEnvProgram && !ctx->FragmentProgram._Enabled) {
#if 0
if (!ctx->_TexEnvProgram)
ctx->_TexEnvProgram = (struct gl_fragment_program *)
ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
ctx->FragmentProgram._Current = ctx->_TexEnvProgram;
#endif
/*
* Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current
* pointers to the programs that should be enabled/used.
*
* These programs may come from several sources. The priority is as
* follows:
* 1. OpenGL 2.0/ARB vertex/fragment shaders
* 2. ARB/NV vertex/fragment programs
* 3. Programs derived from fixed-function state.
*/
if (ctx->_UseTexEnvProgram)
ctx->FragmentProgram._Active = GL_TRUE;
ctx->FragmentProgram._Current = NULL;
if (shProg && shProg->LinkStatus) {
/* Use shader programs */
ctx->VertexProgram._Current = shProg->VertexProgram;
ctx->FragmentProgram._Current = shProg->FragmentProgram;
}
else {
if (ctx->VertexProgram._Enabled) {
/* use user-defined vertex program */
ctx->VertexProgram._Current = ctx->VertexProgram.Current;
}
else if (ctx->VertexProgram._MaintainTnlProgram) {
/* Use vertex program generated from fixed-function state.
* The _Current pointer will get set in
* _tnl_UpdateFixedFunctionProgram() later if appropriate.
*/
ctx->VertexProgram._Current = NULL;
}
else {
/* no vertex program */
ctx->VertexProgram._Current = NULL;
}
if (ctx->FragmentProgram._Enabled) {
/* use user-defined vertex program */
ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
}
else if (ctx->FragmentProgram._MaintainTexEnvProgram) {
/* Use fragment program generated from fixed-function state.
* The _Current pointer will get set in _mesa_UpdateTexEnvProgram()
* later if appropriate.
*/
ctx->FragmentProgram._Current = NULL;
}
else {
/* no fragment program */
ctx->FragmentProgram._Current = NULL;
}
}
}
@ -1003,6 +1035,7 @@ update_color(GLcontext *ctx)
}
/**
* Update the ctx->_TriangleCaps bitfield.
* XXX that bitfield should really go away someday!
@ -1133,7 +1166,7 @@ _mesa_update_state_locked( GLcontext *ctx )
| _NEW_STENCIL | _DD_NEW_SEPARATE_SPECULAR))
update_tricaps( ctx, new_state );
if (ctx->_MaintainTexEnvProgram) {
if (ctx->FragmentProgram._MaintainTexEnvProgram) {
if (new_state & (_NEW_TEXTURE | _DD_NEW_SEPARATE_SPECULAR | _NEW_FOG))
_mesa_UpdateTexEnvProgram(ctx);
}

View file

@ -28,11 +28,12 @@
#include "glheader.h"
#include "macros.h"
#include "enums.h"
#include "prog_parameter.h"
#include "prog_instruction.h"
#include "prog_print.h"
#include "prog_statevars.h"
#include "texenvprogram.h"
#include "shader/program.h"
#include "shader/program_instruction.h"
/**
* According to Glean's texCombine test, no more than 21 instructions
* are needed. Allow a few extra just in case.
@ -410,31 +411,29 @@ static void release_temps( struct texenv_fragment_program *p )
}
static struct ureg register_param6( struct texenv_fragment_program *p,
static struct ureg register_param5( struct texenv_fragment_program *p,
GLint s0,
GLint s1,
GLint s2,
GLint s3,
GLint s4,
GLint s5)
GLint s4)
{
GLint tokens[6];
gl_state_index tokens[STATE_LENGTH];
GLuint idx;
tokens[0] = s0;
tokens[1] = s1;
tokens[2] = s2;
tokens[3] = s3;
tokens[4] = s4;
tokens[5] = s5;
idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens );
return make_ureg(PROGRAM_STATE_VAR, idx);
}
#define register_param1(p,s0) register_param6(p,s0,0,0,0,0,0)
#define register_param2(p,s0,s1) register_param6(p,s0,s1,0,0,0,0)
#define register_param3(p,s0,s1,s2) register_param6(p,s0,s1,s2,0,0,0)
#define register_param4(p,s0,s1,s2,s3) register_param6(p,s0,s1,s2,s3,0,0)
#define register_param1(p,s0) register_param5(p,s0,0,0,0,0)
#define register_param2(p,s0,s1) register_param5(p,s0,s1,0,0,0)
#define register_param3(p,s0,s1,s2) register_param5(p,s0,s1,s2,0,0)
#define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0)
static struct ureg register_input( struct texenv_fragment_program *p, GLuint input )
@ -523,7 +522,7 @@ static struct ureg emit_arith( struct texenv_fragment_program *p,
if (dest.file == PROGRAM_TEMPORARY)
p->alu_temps |= 1 << dest.idx;
p->program->NumAluInstructions++;
p->program->Base.NumAluInstructions++;
return dest;
}
@ -545,7 +544,7 @@ static struct ureg emit_texld( struct texenv_fragment_program *p,
inst->TexSrcTarget = tex_idx;
inst->TexSrcUnit = tex_unit;
p->program->NumTexInstructions++;
p->program->Base.NumTexInstructions++;
/* Is this a texture indirection?
*/
@ -553,7 +552,7 @@ static struct ureg emit_texld( struct texenv_fragment_program *p,
(p->temps_output & (1<<coord.idx))) ||
(dest.file == PROGRAM_TEMPORARY &&
(p->alu_temps & (1<<dest.idx)))) {
p->program->NumTexIndirections++;
p->program->Base.NumTexIndirections++;
p->temps_output = 1<<coord.idx;
p->alu_temps = 0;
assert(0); /* KW: texture env crossbar */
@ -570,12 +569,14 @@ static struct ureg register_const4f( struct texenv_fragment_program *p,
GLfloat s3)
{
GLfloat values[4];
GLuint idx;
GLuint idx, swizzle;
values[0] = s0;
values[1] = s1;
values[2] = s2;
values[3] = s3;
idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4 );
idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4,
&swizzle );
ASSERT(swizzle == SWIZZLE_NOOP);
return make_ureg(PROGRAM_STATE_VAR, idx);
}
@ -1010,9 +1011,9 @@ create_new_program(GLcontext *ctx, struct state_key *key,
*/
p.program->Base.Instructions = instBuffer;
p.program->Base.Target = GL_FRAGMENT_PROGRAM_ARB;
p.program->NumTexIndirections = 1; /* correct? */
p.program->NumTexInstructions = 0;
p.program->NumAluInstructions = 0;
p.program->Base.NumTexIndirections = 1; /* correct? */
p.program->Base.NumTexInstructions = 0;
p.program->Base.NumAluInstructions = 0;
p.program->Base.String = NULL;
p.program->Base.NumInstructions =
p.program->Base.NumTemporaries =
@ -1083,13 +1084,13 @@ create_new_program(GLcontext *ctx, struct state_key *key,
} else
p.program->FogOption = GL_NONE;
if (p.program->NumTexIndirections > ctx->Const.FragmentProgram.MaxTexIndirections)
if (p.program->Base.NumTexIndirections > ctx->Const.FragmentProgram.MaxTexIndirections)
program_error(&p, "Exceeded max nr indirect texture lookups");
if (p.program->NumTexInstructions > ctx->Const.FragmentProgram.MaxTexInstructions)
if (p.program->Base.NumTexInstructions > ctx->Const.FragmentProgram.MaxTexInstructions)
program_error(&p, "Exceeded max TEX instructions");
if (p.program->NumAluInstructions > ctx->Const.FragmentProgram.MaxAluInstructions)
if (p.program->Base.NumAluInstructions > ctx->Const.FragmentProgram.MaxAluInstructions)
program_error(&p, "Exceeded max ALU instructions");
ASSERT(p.program->Base.NumInstructions <= MAX_INSTRUCTIONS);
@ -1221,32 +1222,49 @@ static GLuint hash_key( const struct state_key *key )
return hash;
}
void _mesa_UpdateTexEnvProgram( GLcontext *ctx )
/**
* If _MaintainTexEnvProgram is set we'll generate a fragment program that
* implements the current texture env/combine mode.
* This function generates that program and puts it into effect.
*/
void
_mesa_UpdateTexEnvProgram( GLcontext *ctx )
{
struct state_key key;
GLuint hash;
const struct gl_fragment_program *prev = ctx->FragmentProgram._Current;
if (!ctx->FragmentProgram._Enabled) {
ASSERT(ctx->FragmentProgram._MaintainTexEnvProgram);
/* If a conventional fragment program/shader isn't in effect... */
if (!ctx->FragmentProgram._Enabled &&
!ctx->Shader.CurrentProgram) {
make_state_key(ctx, &key);
hash = hash_key(&key);
ctx->FragmentProgram._Current =
ctx->_TexEnvProgram =
search_cache(&ctx->Texture.env_fp_cache, hash, &key, sizeof(key));
if (!ctx->_TexEnvProgram) {
if (0) _mesa_printf("Building new texenv proggy for key %x\n", hash);
ctx->FragmentProgram._Current = ctx->_TexEnvProgram =
(struct gl_fragment_program *)
ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
create_new_program(ctx, &key, ctx->_TexEnvProgram);
ctx->FragmentProgram._TexEnvProgram =
search_cache(&ctx->Texture.env_fp_cache, hash, &key, sizeof(key));
cache_item(&ctx->Texture.env_fp_cache, hash, &key, ctx->_TexEnvProgram);
} else {
if (0) _mesa_printf("Found existing texenv program for key %x\n", hash);
if (!ctx->FragmentProgram._TexEnvProgram) {
if (0)
_mesa_printf("Building new texenv proggy for key %x\n", hash);
/* create new tex env program */
ctx->FragmentProgram._Current =
ctx->FragmentProgram._TexEnvProgram =
(struct gl_fragment_program *)
ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
create_new_program(ctx, &key, ctx->FragmentProgram._TexEnvProgram);
cache_item(&ctx->Texture.env_fp_cache, hash, &key,
ctx->FragmentProgram._TexEnvProgram);
}
else {
if (0)
_mesa_printf("Found existing texenv program for key %x\n", hash);
}
}
else {
@ -1258,7 +1276,7 @@ void _mesa_UpdateTexEnvProgram( GLcontext *ctx )
*/
if (ctx->FragmentProgram._Current != prev && ctx->Driver.BindProgram) {
ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB,
(struct gl_program *) ctx->FragmentProgram._Current);
(struct gl_program *) ctx->FragmentProgram._Current);
}
}

View file

@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
* Version: 6.5.1
* Version: 6.5.3
*
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -41,8 +41,6 @@
#include "texenvprogram.h"
#include "mtypes.h"
#include "math/m_xform.h"
#include "shaderobjects.h"
#define ENUM_TO_FLOAT(X) ((GLfloat)(GLint)(X))
@ -2919,11 +2917,18 @@ static void
update_texture_state( GLcontext *ctx )
{
GLuint unit;
struct gl_fragment_program *fprog;
#if FEATURE_ARB_fragment_shader
struct gl2_program_intf **prog = ctx->ShaderObjects.CurrentProgram;
GLbitfield progteximageusage[MAX_TEXTURE_IMAGE_UNITS];
#endif
if (ctx->Shader.CurrentProgram &&
ctx->Shader.CurrentProgram->LinkStatus) {
fprog = ctx->Shader.CurrentProgram->FragmentProgram;
}
else if (ctx->FragmentProgram._Enabled) {
fprog = ctx->FragmentProgram.Current;
}
else {
fprog = NULL;
}
ctx->NewState |= _NEW_TEXTURE; /* TODO: only set this if there are
* actual changes.
@ -2934,17 +2939,6 @@ update_texture_state( GLcontext *ctx )
ctx->Texture._TexMatEnabled = 0;
ctx->Texture._TexGenEnabled = 0;
#if FEATURE_ARB_fragment_shader
/*
* Grab texture image usage state from shader program. It must be
* grabbed every time uniform sampler changes, so maybe there is a
* better place to perform these rather expensive computations.
*/
if (ctx->ShaderObjects._FragmentShaderPresent) {
(**prog).GetTextureImageUsage (prog, progteximageusage);
}
#endif /* FEATURE_ARB_fragment_shader */
/*
* Update texture unit state.
*/
@ -2956,15 +2950,14 @@ update_texture_state( GLcontext *ctx )
texUnit->_ReallyEnabled = 0;
texUnit->_GenFlags = 0;
/* Get the bitmask of texture enables */
#if FEATURE_ARB_fragment_shader
if (ctx->ShaderObjects._FragmentShaderPresent) {
enableBits = progteximageusage[unit];
}
else
#endif
if (ctx->FragmentProgram._Enabled) {
enableBits = ctx->FragmentProgram.Current->TexturesUsed[unit];
/* Get the bitmask of texture enables.
* enableBits will be a mask of the TEXTURE_*_BIT flags indicating
* which texture targets are enabled (fixed function) or referenced
* by a fragment shader/program. When multiple flags are set, we'll
* settle on the one with highest priority (see texture_override below).
*/
if (fprog) {
enableBits = fprog->Base.TexturesUsed[unit];
}
else {
if (!texUnit->Enabled)
@ -3081,21 +3074,23 @@ update_texture_state( GLcontext *ctx )
ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit);
}
ctx->Texture._EnabledCoordUnits = ctx->Texture._EnabledUnits;
/* Fragment programs may need texture coordinates but not the
* corresponding texture images.
*/
if (ctx->ShaderObjects.CurrentProgram != NULL) {
ctx->Texture._EnabledCoordUnits |= (1 << ctx->Const.MaxTextureCoordUnits) - 1;
/* Determine which texture coordinate sets are actually needed */
if (fprog) {
const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
ctx->Texture._EnabledCoordUnits
= (fprog->Base.InputsRead >> FRAG_ATTRIB_TEX0) & coordMask;
}
else if (ctx->FragmentProgram._Enabled) {
ctx->Texture._EnabledCoordUnits |=
(ctx->FragmentProgram.Current->Base.InputsRead >> FRAG_ATTRIB_TEX0);
else {
ctx->Texture._EnabledCoordUnits = ctx->Texture._EnabledUnits;
}
}
void _mesa_update_texture( GLcontext *ctx, GLuint new_state )
/**
* Update texture-related derived state.
*/
void
_mesa_update_texture( GLcontext *ctx, GLuint new_state )
{
if (new_state & _NEW_TEXTURE_MATRIX)
update_texture_matrices( ctx );

View file

@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
* Version: 6.5.1
* Version: 6.5.3
*
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -35,10 +35,12 @@
#include "arbprogparse.h"
#include "grammar_mesa.h"
#include "program.h"
#include "prog_parameter.h"
#include "prog_statevars.h"
#include "context.h"
#include "macros.h"
#include "mtypes.h"
#include "program_instruction.h"
#include "prog_instruction.h"
/* For ARB programs, use the NV instruction limits */
@ -1008,7 +1010,7 @@ parse_matrix (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Progra
switch (mat) {
case MATRIX_MODELVIEW:
*matrix = STATE_MODELVIEW;
*matrix = STATE_MODELVIEW_MATRIX;
*matrix_idx = parse_integer (inst, Program);
if (*matrix_idx > 0) {
program_error(ctx, Program->Position,
@ -1018,15 +1020,15 @@ parse_matrix (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Progra
break;
case MATRIX_PROJECTION:
*matrix = STATE_PROJECTION;
*matrix = STATE_PROJECTION_MATRIX;
break;
case MATRIX_MVP:
*matrix = STATE_MVP;
*matrix = STATE_MVP_MATRIX;
break;
case MATRIX_TEXTURE:
*matrix = STATE_TEXTURE;
*matrix = STATE_TEXTURE_MATRIX;
*matrix_idx = parse_integer (inst, Program);
if (*matrix_idx >= (GLint) ctx->Const.MaxTextureUnits) {
program_error(ctx, Program->Position, "Invalid Texture Unit");
@ -1044,7 +1046,7 @@ parse_matrix (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Progra
break;
case MATRIX_PROGRAM:
*matrix = STATE_PROGRAM;
*matrix = STATE_PROGRAM_MATRIX;
*matrix_idx = parse_integer (inst, Program);
if (*matrix_idx >= (GLint) ctx->Const.MaxProgramMatrices) {
program_error(ctx, Program->Position, "Invalid Program Matrix");
@ -1083,7 +1085,8 @@ parse_matrix (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Progra
*/
static GLuint
parse_state_single_item (GLcontext * ctx, const GLubyte ** inst,
struct arb_program *Program, GLint * state_tokens)
struct arb_program *Program,
gl_state_index state_tokens[STATE_LENGTH])
{
switch (*(*inst)++) {
case STATE_MATERIAL_PARSER:
@ -1136,7 +1139,7 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst,
state_tokens[2] = STATE_ATTENUATION;
break;
case LIGHT_HALF:
state_tokens[2] = STATE_HALF;
state_tokens[2] = STATE_HALF_VECTOR;
break;
case LIGHT_SPOT_DIRECTION:
state_tokens[2] = STATE_SPOT_DIRECTION;
@ -1265,7 +1268,8 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst,
case STATE_CLIP_PLANE:
state_tokens[0] = STATE_CLIPPLANE;
state_tokens[1] = parse_integer (inst, Program);
if (parse_clipplane_num (ctx, inst, Program, &state_tokens[1]))
if (parse_clipplane_num (ctx, inst, Program,
(GLint *) &state_tokens[1]))
return 1;
break;
@ -1283,17 +1287,17 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst,
/* XXX: I think this is the correct format for a matrix row */
case STATE_MATRIX_ROWS:
state_tokens[0] = STATE_MATRIX;
if (parse_matrix
(ctx, inst, Program, &state_tokens[1], &state_tokens[2],
&state_tokens[5]))
if (parse_matrix(ctx, inst, Program,
(GLint *) &state_tokens[0],
(GLint *) &state_tokens[1],
(GLint *) &state_tokens[4]))
return 1;
state_tokens[3] = parse_integer (inst, Program); /* The first row to grab */
state_tokens[2] = parse_integer (inst, Program); /* The first row to grab */
if ((**inst) != 0) { /* Either the last row, 0 */
state_tokens[4] = parse_integer (inst, Program);
if (state_tokens[4] < state_tokens[3]) {
state_tokens[3] = parse_integer (inst, Program);
if (state_tokens[3] < state_tokens[2]) {
program_error(ctx, Program->Position,
"Second matrix index less than the first");
/* state_tokens[4] vs. state_tokens[3] */
@ -1301,7 +1305,7 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst,
}
}
else {
state_tokens[4] = state_tokens[3];
state_tokens[3] = state_tokens[2];
(*inst)++;
}
break;
@ -1342,7 +1346,8 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst,
*/
static GLuint
parse_program_single_item (GLcontext * ctx, const GLubyte ** inst,
struct arb_program *Program, GLint * state_tokens)
struct arb_program *Program,
gl_state_index state_tokens[STATE_LENGTH])
{
if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB)
state_tokens[0] = STATE_FRAGMENT_PROGRAM;
@ -1459,7 +1464,7 @@ parse_attrib_binding(GLcontext * ctx, const GLubyte ** inst,
break;
case FRAGMENT_ATTRIB_TEXCOORD:
{
GLuint texcoord;
GLuint texcoord = 0;
err = parse_texcoord_num (ctx, inst, Program, &texcoord);
*inputReg = FRAG_ATTRIB_TEX0 + texcoord;
}
@ -1520,7 +1525,7 @@ parse_attrib_binding(GLcontext * ctx, const GLubyte ** inst,
case VERTEX_ATTRIB_TEXCOORD:
{
GLuint unit;
GLuint unit = 0;
err = parse_texcoord_num (ctx, inst, Program, &unit);
*inputReg = VERT_ATTRIB_TEX0 + unit;
}
@ -1717,7 +1722,7 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst,
{
GLint idx;
GLuint err = 0;
GLint state_tokens[6];
gl_state_index state_tokens[STATE_LENGTH];
GLfloat const_values[4];
switch (*(*inst)++) {
@ -1728,14 +1733,18 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst,
/* If we adding STATE_MATRIX that has multiple rows, we need to
* unroll it and call _mesa_add_state_reference() for each row
*/
if ((state_tokens[0] == STATE_MATRIX)
&& (state_tokens[3] != state_tokens[4])) {
if ((state_tokens[0] == STATE_MODELVIEW_MATRIX ||
state_tokens[0] == STATE_PROJECTION_MATRIX ||
state_tokens[0] == STATE_MVP_MATRIX ||
state_tokens[0] == STATE_TEXTURE_MATRIX ||
state_tokens[0] == STATE_PROGRAM_MATRIX)
&& (state_tokens[2] != state_tokens[3])) {
GLint row;
GLint first_row = state_tokens[3];
GLint last_row = state_tokens[4];
const GLint first_row = state_tokens[2];
const GLint last_row = state_tokens[3];
for (row = first_row; row <= last_row; row++) {
state_tokens[3] = state_tokens[4] = row;
state_tokens[2] = state_tokens[3] = row;
idx = _mesa_add_state_reference(Program->Base.Parameters,
state_tokens);
@ -3328,186 +3337,6 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,
#if DEBUG_PARSING
static GLvoid
print_state_token (GLint token)
{
switch (token) {
case STATE_MATERIAL:
fprintf (stderr, "STATE_MATERIAL ");
break;
case STATE_LIGHT:
fprintf (stderr, "STATE_LIGHT ");
break;
case STATE_LIGHTMODEL_AMBIENT:
fprintf (stderr, "STATE_AMBIENT ");
break;
case STATE_LIGHTMODEL_SCENECOLOR:
fprintf (stderr, "STATE_SCENECOLOR ");
break;
case STATE_LIGHTPROD:
fprintf (stderr, "STATE_LIGHTPROD ");
break;
case STATE_TEXGEN:
fprintf (stderr, "STATE_TEXGEN ");
break;
case STATE_FOG_COLOR:
fprintf (stderr, "STATE_FOG_COLOR ");
break;
case STATE_FOG_PARAMS:
fprintf (stderr, "STATE_FOG_PARAMS ");
break;
case STATE_CLIPPLANE:
fprintf (stderr, "STATE_CLIPPLANE ");
break;
case STATE_POINT_SIZE:
fprintf (stderr, "STATE_POINT_SIZE ");
break;
case STATE_POINT_ATTENUATION:
fprintf (stderr, "STATE_ATTENUATION ");
break;
case STATE_MATRIX:
fprintf (stderr, "STATE_MATRIX ");
break;
case STATE_MODELVIEW:
fprintf (stderr, "STATE_MODELVIEW ");
break;
case STATE_PROJECTION:
fprintf (stderr, "STATE_PROJECTION ");
break;
case STATE_MVP:
fprintf (stderr, "STATE_MVP ");
break;
case STATE_TEXTURE:
fprintf (stderr, "STATE_TEXTURE ");
break;
case STATE_PROGRAM:
fprintf (stderr, "STATE_PROGRAM ");
break;
case STATE_MATRIX_INVERSE:
fprintf (stderr, "STATE_INVERSE ");
break;
case STATE_MATRIX_TRANSPOSE:
fprintf (stderr, "STATE_TRANSPOSE ");
break;
case STATE_MATRIX_INVTRANS:
fprintf (stderr, "STATE_INVTRANS ");
break;
case STATE_AMBIENT:
fprintf (stderr, "STATE_AMBIENT ");
break;
case STATE_DIFFUSE:
fprintf (stderr, "STATE_DIFFUSE ");
break;
case STATE_SPECULAR:
fprintf (stderr, "STATE_SPECULAR ");
break;
case STATE_EMISSION:
fprintf (stderr, "STATE_EMISSION ");
break;
case STATE_SHININESS:
fprintf (stderr, "STATE_SHININESS ");
break;
case STATE_HALF:
fprintf (stderr, "STATE_HALF ");
break;
case STATE_POSITION:
fprintf (stderr, "STATE_POSITION ");
break;
case STATE_ATTENUATION:
fprintf (stderr, "STATE_ATTENUATION ");
break;
case STATE_SPOT_DIRECTION:
fprintf (stderr, "STATE_DIRECTION ");
break;
case STATE_TEXGEN_EYE_S:
fprintf (stderr, "STATE_TEXGEN_EYE_S ");
break;
case STATE_TEXGEN_EYE_T:
fprintf (stderr, "STATE_TEXGEN_EYE_T ");
break;
case STATE_TEXGEN_EYE_R:
fprintf (stderr, "STATE_TEXGEN_EYE_R ");
break;
case STATE_TEXGEN_EYE_Q:
fprintf (stderr, "STATE_TEXGEN_EYE_Q ");
break;
case STATE_TEXGEN_OBJECT_S:
fprintf (stderr, "STATE_TEXGEN_EYE_S ");
break;
case STATE_TEXGEN_OBJECT_T:
fprintf (stderr, "STATE_TEXGEN_OBJECT_T ");
break;
case STATE_TEXGEN_OBJECT_R:
fprintf (stderr, "STATE_TEXGEN_OBJECT_R ");
break;
case STATE_TEXGEN_OBJECT_Q:
fprintf (stderr, "STATE_TEXGEN_OBJECT_Q ");
break;
case STATE_TEXENV_COLOR:
fprintf (stderr, "STATE_TEXENV_COLOR ");
break;
case STATE_DEPTH_RANGE:
fprintf (stderr, "STATE_DEPTH_RANGE ");
break;
case STATE_VERTEX_PROGRAM:
fprintf (stderr, "STATE_VERTEX_PROGRAM ");
break;
case STATE_FRAGMENT_PROGRAM:
fprintf (stderr, "STATE_FRAGMENT_PROGRAM ");
break;
case STATE_ENV:
fprintf (stderr, "STATE_ENV ");
break;
case STATE_LOCAL:
fprintf (stderr, "STATE_LOCAL ");
break;
}
fprintf (stderr, "[%d] ", token);
}
static GLvoid
debug_variables (GLcontext * ctx, struct var_cache *vc_head,
struct arb_program *Program)
@ -3515,12 +3344,12 @@ debug_variables (GLcontext * ctx, struct var_cache *vc_head,
struct var_cache *vc;
GLint a, b;
fprintf (stderr, "debug_variables, vc_head: %x\n", vc_head);
fprintf (stderr, "debug_variables, vc_head: %p\n", (void*) vc_head);
/* First of all, print out the contents of the var_cache */
vc = vc_head;
while (vc) {
fprintf (stderr, "[%x]\n", vc);
fprintf (stderr, "[%p]\n", (void*) vc);
switch (vc->type) {
case vt_none:
fprintf (stderr, "UNDEFINED %s\n", vc->name);
@ -3535,27 +3364,20 @@ debug_variables (GLcontext * ctx, struct var_cache *vc_head,
b = vc->param_binding_begin;
for (a = 0; a < vc->param_binding_length; a++) {
fprintf (stderr, "%s\n",
Program->Parameters->Parameters[a + b].Name);
if (Program->Parameters->Parameters[a + b].Type == STATE) {
print_state_token (Program->Parameters->Parameters[a + b].
StateIndexes[0]);
print_state_token (Program->Parameters->Parameters[a + b].
StateIndexes[1]);
print_state_token (Program->Parameters->Parameters[a + b].
StateIndexes[2]);
print_state_token (Program->Parameters->Parameters[a + b].
StateIndexes[3]);
print_state_token (Program->Parameters->Parameters[a + b].
StateIndexes[4]);
print_state_token (Program->Parameters->Parameters[a + b].
StateIndexes[5]);
Program->Base.Parameters->Parameters[a + b].Name);
if (Program->Base.Parameters->Parameters[a + b].Type == PROGRAM_STATE_VAR) {
const char *s;
s = _mesa_program_state_string(Program->Base.Parameters->Parameters
[a + b].StateIndexes);
fprintf(stderr, "%s\n", s);
_mesa_free((char *) s);
}
else
fprintf (stderr, "%f %f %f %f\n",
Program->Parameters->Parameters[a + b].Values[0],
Program->Parameters->Parameters[a + b].Values[1],
Program->Parameters->Parameters[a + b].Values[2],
Program->Parameters->Parameters[a + b].Values[3]);
Program->Base.Parameters->ParameterValues[a + b][0],
Program->Base.Parameters->ParameterValues[a + b][1],
Program->Base.Parameters->ParameterValues[a + b][2],
Program->Base.Parameters->ParameterValues[a + b][3]);
}
break;
case vt_temp:
@ -3568,9 +3390,12 @@ debug_variables (GLcontext * ctx, struct var_cache *vc_head,
break;
case vt_alias:
fprintf (stderr, "ALIAS %s\n", vc->name);
fprintf (stderr, " binding: 0x%x (%s)\n",
vc->alias_binding, vc->alias_binding->name);
fprintf (stderr, " binding: 0x%p (%s)\n",
(void*) vc->alias_binding, vc->alias_binding->name);
break;
default:
/* nothing */
;
}
vc = vc->next;
}
@ -4027,16 +3852,16 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target,
program->Base.NumNativeParameters = ap.Base.NumNativeParameters;
program->Base.NumNativeAttributes = ap.Base.NumNativeAttributes;
program->Base.NumNativeAddressRegs = ap.Base.NumNativeAddressRegs;
program->NumAluInstructions = ap.NumAluInstructions;
program->NumTexInstructions = ap.NumTexInstructions;
program->NumTexIndirections = ap.NumTexIndirections;
program->NumNativeAluInstructions = ap.NumAluInstructions;
program->NumNativeTexInstructions = ap.NumTexInstructions;
program->NumNativeTexIndirections = ap.NumTexIndirections;
program->Base.NumAluInstructions = ap.Base.NumAluInstructions;
program->Base.NumTexInstructions = ap.Base.NumTexInstructions;
program->Base.NumTexIndirections = ap.Base.NumTexIndirections;
program->Base.NumNativeAluInstructions = ap.Base.NumAluInstructions;
program->Base.NumNativeTexInstructions = ap.Base.NumTexInstructions;
program->Base.NumNativeTexIndirections = ap.Base.NumTexIndirections;
program->Base.InputsRead = ap.Base.InputsRead;
program->Base.OutputsWritten = ap.Base.OutputsWritten;
for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
program->TexturesUsed[i] = ap.TexturesUsed[i];
program->Base.TexturesUsed[i] = ap.TexturesUsed[i];
program->FogOption = ap.FogOption;
program->UsesKill = ap.UsesKill;

View file

@ -720,22 +720,22 @@ _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
const struct gl_fragment_program *fp = ctx->FragmentProgram.Current;
switch (pname) {
case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
*params = fp->NumNativeAluInstructions;
*params = fp->Base.NumNativeAluInstructions;
return;
case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
*params = fp->NumAluInstructions;
*params = fp->Base.NumAluInstructions;
return;
case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
*params = fp->NumTexInstructions;
*params = fp->Base.NumTexInstructions;
return;
case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
*params = fp->NumNativeTexInstructions;
*params = fp->Base.NumNativeTexInstructions;
return;
case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
*params = fp->NumTexIndirections;
*params = fp->Base.NumTexIndirections;
return;
case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
*params = fp->NumNativeTexIndirections;
*params = fp->Base.NumNativeTexIndirections;
return;
case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
*params = limits->MaxAluInstructions;

View file

@ -1,78 +0,0 @@
/* */
/* ARB program opcode registry */
/* each instruction code has its own unique number */
/* this registry exists to ensure that this relation retains */
/* */
/* GL_ARB_vertex_program */
ABS 0x00
ADD 0x01
ARL 0x02
DP3 0x03
DP4 0x04
DPH 0x05
DST 0x06
EX2 0x07
EXP 0x08
FLR 0x09
FRC 0x0A
LG2 0x0B
LIT 0x0C
LOG 0x0D
MAD 0x0E
MAX 0x0F
MIN 0x10
MOV 0x11
MUL 0x12
POW 0x13
RCP 0x14
RSQ 0x15
SGE 0x16
SLT 0x17
SUB 0x18
SWZ 0x19
XPD 0x1A
/* GL_ARB_fragment_program */
ABS_SAT 0x1B
ADD_SAT 0x1C
CMP 0x1D
CMP_SAT 0x1E
COS 0x1F
COS_SAT 0x20
DP3_SAT 0x21
DP4_SAT 0x22
DPH_SAT 0x23
DST_SAT 0x24
EX2_SAT 0x25
FLR_SAT 0x26
FRC_SAT 0x27
KIL 0x28
LG2_SAT 0x29
LIT_SAT 0x2A
LRP 0x2B
LRP_SAT 0x2C
MAD_SAT 0x2D
MAX_SAT 0x2E
MIN_SAT 0x2F
MOV_SAT 0x30
MUL_SAT 0x31
POW_SAT 0x32
RCP_SAT 0x33
RSQ_SAT 0x34
SCS 0x35
SCS_SAT 0x36
SGE_SAT 0x37
SIN 0x38
SIN_SAT 0x39
SLT_SAT 0x3A
SUB_SAT 0x3B
SWZ_SAT 0x3C
TEX 0x3D
TEX_SAT 0x3E
TXB 0x3F
TXB_SAT 0x40
TXP 0x41
TXP_SAT 0x42
XPD_SAT 0x43

View file

@ -260,6 +260,8 @@
first).
*/
#include <stdio.h>
static void mem_free (void **);
/*
@ -2797,10 +2799,16 @@ static void grammar_load_state_destroy (grammar_load_state **gr)
}
}
static void error_msg(int line, const char *msg)
{
fprintf(stderr, "Error in grammar_load_from_text() at line %d: %s\n", line, msg);
}
/*
the API
*/
grammar grammar_load_from_text (const byte *text)
{
grammar_load_state *g = NULL;
@ -2809,13 +2817,16 @@ grammar grammar_load_from_text (const byte *text)
clear_last_error ();
grammar_load_state_create (&g);
if (g == NULL)
if (g == NULL) {
error_msg(__LINE__, "");
return 0;
}
dict_create (&g->di);
if (g->di == NULL)
{
grammar_load_state_destroy (&g);
error_msg(__LINE__, "");
return 0;
}
@ -2829,6 +2840,7 @@ grammar grammar_load_from_text (const byte *text)
if (get_identifier (&text, &g->syntax_symbol))
{
grammar_load_state_destroy (&g);
error_msg(__LINE__, "");
return 0;
}
eat_spaces (&text);
@ -2848,6 +2860,7 @@ grammar grammar_load_from_text (const byte *text)
if (get_identifier (&text, &symbol))
{
grammar_load_state_destroy (&g);
error_msg(__LINE__, "");
return 0;
}
eat_spaces (&text);
@ -2862,6 +2875,7 @@ grammar grammar_load_from_text (const byte *text)
if (get_emtcode (&text, &ma))
{
grammar_load_state_destroy (&g);
error_msg(__LINE__, "");
return 0;
}
@ -2877,6 +2891,7 @@ grammar grammar_load_from_text (const byte *text)
if (get_regbyte (&text, &ma))
{
grammar_load_state_destroy (&g);
error_msg(__LINE__, "");
return 0;
}
@ -2892,6 +2907,7 @@ grammar grammar_load_from_text (const byte *text)
if (get_errtext (&text, &ma))
{
grammar_load_state_destroy (&g);
error_msg(__LINE__, "");
return 0;
}
@ -2905,12 +2921,14 @@ grammar grammar_load_from_text (const byte *text)
if (g->di->m_string != NULL)
{
grammar_load_state_destroy (&g);
error_msg(__LINE__, "");
return 0;
}
if (get_identifier (&text, &g->string_symbol))
{
grammar_load_state_destroy (&g);
error_msg(__LINE__, "");
return 0;
}
@ -2927,6 +2945,7 @@ grammar grammar_load_from_text (const byte *text)
if (get_rule (&text, &ru, g->maps, g->mapb))
{
grammar_load_state_destroy (&g);
error_msg(__LINE__, "");
return 0;
}
@ -2940,6 +2959,7 @@ grammar grammar_load_from_text (const byte *text)
if (ma == NULL)
{
grammar_load_state_destroy (&g);
error_msg(__LINE__, "");
return 0;
}
@ -2953,6 +2973,7 @@ grammar grammar_load_from_text (const byte *text)
g->di->m_regbytes))
{
grammar_load_state_destroy (&g);
error_msg(__LINE__, "update_dependencies() failed");
return 0;
}

0
src/mesa/shader/grammar/grammar_crt.c Executable file → Normal file
View file

0
src/mesa/shader/grammar/grammar_crt.h Executable file → Normal file
View file

View file

@ -39,13 +39,11 @@
#include "glheader.h"
#include "context.h"
#include "hash.h"
#include "imports.h"
#include "macros.h"
#include "mtypes.h"
#include "program_instruction.h"
#include "prog_parameter.h"
#include "prog_instruction.h"
#include "nvfragparse.h"
#include "nvprogram.h"
#include "program.h"
@ -1038,21 +1036,25 @@ Parse_VectorSrc(struct parse_state *parseState,
else if (IsDigit(token[0]) || token[0] == '-' || token[0] == '+' || token[0] == '.'){
/* literal scalar constant */
GLfloat values[4];
GLuint paramIndex;
GLuint paramIndex, swizzle;
if (!Parse_ScalarConstant(parseState, values))
RETURN_ERROR;
paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values, 4);
paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
values, 4, NULL);
ASSERT(swizzle == SWIZZLE_NOOP);
srcReg->File = PROGRAM_NAMED_PARAM;
srcReg->Index = paramIndex;
}
else if (token[0] == '{'){
/* literal vector constant */
GLfloat values[4];
GLuint paramIndex;
GLuint paramIndex, swizzle;
(void) Parse_String(parseState, "{");
if (!Parse_VectorConstant(parseState, values))
RETURN_ERROR;
paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values, 4);
paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
values, 4, NULL);
ASSERT(swizzle == SWIZZLE_NOOP);
srcReg->File = PROGRAM_NAMED_PARAM;
srcReg->Index = paramIndex;
}
@ -1138,11 +1140,13 @@ Parse_ScalarSrcReg(struct parse_state *parseState,
else if (token[0] == '{') {
/* vector literal */
GLfloat values[4];
GLuint paramIndex;
GLuint paramIndex, swizzle;
(void) Parse_String(parseState, "{");
if (!Parse_VectorConstant(parseState, values))
RETURN_ERROR;
paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values, 4);
paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
values, 4, NULL);
ASSERT(swizzle == SWIZZLE_NOOP);
srcReg->File = PROGRAM_NAMED_PARAM;
srcReg->Index = paramIndex;
}
@ -1163,10 +1167,12 @@ Parse_ScalarSrcReg(struct parse_state *parseState,
else if (IsDigit(token[0])) {
/* scalar literal */
GLfloat values[4];
GLuint paramIndex;
GLuint paramIndex, swizzle;
if (!Parse_ScalarConstant(parseState, values))
RETURN_ERROR;
paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values, 4);
paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
values, 4, NULL);
ASSERT(swizzle == SWIZZLE_NOOP);
srcReg->Index = paramIndex;
srcReg->File = PROGRAM_NAMED_PARAM;
needSuffix = GL_FALSE;
@ -1539,8 +1545,7 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
return; /* out of memory */
}
_mesa_memcpy(newInst, instBuffer,
parseState.numInst * sizeof(struct prog_instruction));
_mesa_copy_instructions(newInst, instBuffer, parseState.numInst);
/* install the program */
program->Base.Target = target;
@ -1557,7 +1562,7 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,
program->Base.InputsRead = parseState.inputsRead;
program->Base.OutputsWritten = parseState.outputsWritten;
for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++)
program->TexturesUsed[u] = parseState.texturesUsed[u];
program->Base.TexturesUsed[u] = parseState.texturesUsed[u];
/* save program parameters */
program->Base.Parameters = parseState.parameters;

View file

@ -42,10 +42,9 @@
#include "hash.h"
#include "imports.h"
#include "macros.h"
#include "mtypes.h"
#include "prog_parameter.h"
#include "prog_instruction.h"
#include "nvfragparse.h"
#include "program_instruction.h"
#include "nvvertexec.h"
#include "nvvertparse.h"
#include "nvprogram.h"
#include "program.h"
@ -77,7 +76,7 @@ _mesa_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params)
return;
}
_mesa_exec_vertex_state_program(ctx, vprog, params);
_mesa_problem(ctx, "glExecuteProgramNV() not supported");
}

View file

@ -1,835 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 6.5.2
*
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file nvvertexec.c
* Code to execute vertex programs.
* \author Brian Paul
*/
#include "glheader.h"
#include "context.h"
#include "imports.h"
#include "macros.h"
#include "mtypes.h"
#include "nvvertexec.h"
#include "program_instruction.h"
#include "program.h"
#include "math/m_matrix.h"
static const GLfloat ZeroVec[4] = { 0.0F, 0.0F, 0.0F, 0.0F };
/**
* Load/initialize the vertex program registers which need to be set
* per-vertex.
*/
void
_mesa_init_vp_per_vertex_registers(GLcontext *ctx, struct vp_machine *machine)
{
/* Input registers get initialized from the current vertex attribs */
MEMCPY(machine->Inputs, ctx->Current.Attrib,
MAX_VERTEX_PROGRAM_ATTRIBS * 4 * sizeof(GLfloat));
if (ctx->VertexProgram.Current->IsNVProgram) {
GLuint i;
/* Output/result regs are initialized to [0,0,0,1] */
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) {
ASSIGN_4V(machine->Outputs[i], 0.0F, 0.0F, 0.0F, 1.0F);
}
/* Temp regs are initialized to [0,0,0,0] */
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) {
ASSIGN_4V(machine->Temporaries[i], 0.0F, 0.0F, 0.0F, 0.0F);
}
ASSIGN_4V(machine->AddressReg, 0, 0, 0, 0);
}
}
/**
* Copy the 16 elements of a matrix into four consecutive program
* registers starting at 'pos'.
*/
static void
load_matrix(GLfloat registers[][4], GLuint pos, const GLfloat mat[16])
{
GLuint i;
for (i = 0; i < 4; i++) {
registers[pos + i][0] = mat[0 + i];
registers[pos + i][1] = mat[4 + i];
registers[pos + i][2] = mat[8 + i];
registers[pos + i][3] = mat[12 + i];
}
}
/**
* As above, but transpose the matrix.
*/
static void
load_transpose_matrix(GLfloat registers[][4], GLuint pos,
const GLfloat mat[16])
{
MEMCPY(registers[pos], mat, 16 * sizeof(GLfloat));
}
/**
* Load program parameter registers with tracked matrices (if NV program)
* or GL state values (if ARB program).
* This needs to be done per glBegin/glEnd, not per-vertex.
*/
void
_mesa_init_vp_per_primitive_registers(GLcontext *ctx)
{
if (ctx->VertexProgram.Current->IsNVProgram) {
GLuint i;
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) {
/* point 'mat' at source matrix */
GLmatrix *mat;
if (ctx->VertexProgram.TrackMatrix[i] == GL_MODELVIEW) {
mat = ctx->ModelviewMatrixStack.Top;
}
else if (ctx->VertexProgram.TrackMatrix[i] == GL_PROJECTION) {
mat = ctx->ProjectionMatrixStack.Top;
}
else if (ctx->VertexProgram.TrackMatrix[i] == GL_TEXTURE) {
mat = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top;
}
else if (ctx->VertexProgram.TrackMatrix[i] == GL_COLOR) {
mat = ctx->ColorMatrixStack.Top;
}
else if (ctx->VertexProgram.TrackMatrix[i]==GL_MODELVIEW_PROJECTION_NV) {
/* XXX verify the combined matrix is up to date */
mat = &ctx->_ModelProjectMatrix;
}
else if (ctx->VertexProgram.TrackMatrix[i] >= GL_MATRIX0_NV &&
ctx->VertexProgram.TrackMatrix[i] <= GL_MATRIX7_NV) {
GLuint n = ctx->VertexProgram.TrackMatrix[i] - GL_MATRIX0_NV;
ASSERT(n < MAX_PROGRAM_MATRICES);
mat = ctx->ProgramMatrixStack[n].Top;
}
else {
/* no matrix is tracked, but we leave the register values as-is */
assert(ctx->VertexProgram.TrackMatrix[i] == GL_NONE);
continue;
}
/* load the matrix values into sequential registers */
if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_IDENTITY_NV) {
load_matrix(ctx->VertexProgram.Parameters, i*4, mat->m);
}
else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_INVERSE_NV) {
_math_matrix_analyse(mat); /* update the inverse */
ASSERT(!_math_matrix_is_dirty(mat));
load_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv);
}
else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_TRANSPOSE_NV) {
load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->m);
}
else {
assert(ctx->VertexProgram.TrackMatrixTransform[i]
== GL_INVERSE_TRANSPOSE_NV);
_math_matrix_analyse(mat); /* update the inverse */
ASSERT(!_math_matrix_is_dirty(mat));
load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv);
}
}
}
else {
/* ARB vertex program */
if (ctx->VertexProgram.Current->Base.Parameters) {
/* Grab the state GL state and put into registers */
_mesa_load_state_parameters(ctx,
ctx->VertexProgram.Current->Base.Parameters);
}
}
}
/**
* For debugging. Dump the current vertex program machine registers.
*/
void
_mesa_dump_vp_state( const struct gl_vertex_program_state *state,
const struct vp_machine *machine)
{
int i;
_mesa_printf("VertexIn:\n");
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_INPUTS; i++) {
_mesa_printf("%d: %f %f %f %f ", i,
machine->Inputs[i][0],
machine->Inputs[i][1],
machine->Inputs[i][2],
machine->Inputs[i][3]);
}
_mesa_printf("\n");
_mesa_printf("VertexOut:\n");
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) {
_mesa_printf("%d: %f %f %f %f ", i,
machine->Outputs[i][0],
machine->Outputs[i][1],
machine->Outputs[i][2],
machine->Outputs[i][3]);
}
_mesa_printf("\n");
_mesa_printf("Registers:\n");
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) {
_mesa_printf("%d: %f %f %f %f ", i,
machine->Temporaries[i][0],
machine->Temporaries[i][1],
machine->Temporaries[i][2],
machine->Temporaries[i][3]);
}
_mesa_printf("\n");
_mesa_printf("Parameters:\n");
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS; i++) {
_mesa_printf("%d: %f %f %f %f ", i,
state->Parameters[i][0],
state->Parameters[i][1],
state->Parameters[i][2],
state->Parameters[i][3]);
}
_mesa_printf("\n");
}
/**
* Return a pointer to the 4-element float vector specified by the given
* source register.
*/
static INLINE const GLfloat *
get_register_pointer( GLcontext *ctx,
const struct prog_src_register *source,
struct vp_machine *machine,
const struct gl_vertex_program *program )
{
if (source->RelAddr) {
const GLint reg = source->Index + machine->AddressReg[0];
ASSERT( (source->File == PROGRAM_ENV_PARAM) ||
(source->File == PROGRAM_STATE_VAR) );
if (reg < 0 || reg > MAX_NV_VERTEX_PROGRAM_PARAMS)
return ZeroVec;
else if (source->File == PROGRAM_ENV_PARAM)
return ctx->VertexProgram.Parameters[reg];
else {
ASSERT(source->File == PROGRAM_LOCAL_PARAM);
return program->Base.Parameters->ParameterValues[reg];
}
}
else {
switch (source->File) {
case PROGRAM_TEMPORARY:
ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_TEMPS);
return machine->Temporaries[source->Index];
case PROGRAM_INPUT:
ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_INPUTS);
return machine->Inputs[source->Index];
case PROGRAM_OUTPUT:
/* This is only needed for the PRINT instruction */
ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_OUTPUTS);
return machine->Outputs[source->Index];
case PROGRAM_LOCAL_PARAM:
ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS);
return program->Base.LocalParams[source->Index];
case PROGRAM_ENV_PARAM:
ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_PARAMS);
return ctx->VertexProgram.Parameters[source->Index];
case PROGRAM_STATE_VAR:
ASSERT(source->Index < program->Base.Parameters->NumParameters);
return program->Base.Parameters->ParameterValues[source->Index];
default:
_mesa_problem(NULL,
"Bad source register file in get_register_pointer");
return NULL;
}
}
return NULL;
}
/**
* Fetch a 4-element float vector from the given source register.
* Apply swizzling and negating as needed.
*/
static INLINE void
fetch_vector4( GLcontext *ctx,
const struct prog_src_register *source,
struct vp_machine *machine,
const struct gl_vertex_program *program,
GLfloat result[4] )
{
const GLfloat *src = get_register_pointer(ctx, source, machine, program);
ASSERT(src);
result[0] = src[GET_SWZ(source->Swizzle, 0)];
result[1] = src[GET_SWZ(source->Swizzle, 1)];
result[2] = src[GET_SWZ(source->Swizzle, 2)];
result[3] = src[GET_SWZ(source->Swizzle, 3)];
if (source->NegateBase) {
result[0] = -result[0];
result[1] = -result[1];
result[2] = -result[2];
result[3] = -result[3];
}
}
/**
* As above, but only return result[0] element.
*/
static INLINE void
fetch_vector1( GLcontext *ctx,
const struct prog_src_register *source,
struct vp_machine *machine,
const struct gl_vertex_program *program,
GLfloat result[4] )
{
const GLfloat *src = get_register_pointer(ctx, source, machine, program);
ASSERT(src);
result[0] = src[GET_SWZ(source->Swizzle, 0)];
if (source->NegateBase) {
result[0] = -result[0];
}
}
/**
* Store 4 floats into a register.
*/
static void
store_vector4( const struct prog_instruction *inst,
struct vp_machine *machine,
const GLfloat value[4] )
{
const struct prog_dst_register *dest = &(inst->DstReg);
GLfloat *dst;
switch (dest->File) {
case PROGRAM_OUTPUT:
dst = machine->Outputs[dest->Index];
break;
case PROGRAM_TEMPORARY:
dst = machine->Temporaries[dest->Index];
break;
case PROGRAM_ENV_PARAM:
/* Only for VP state programs */
{
/* a slight hack */
GET_CURRENT_CONTEXT(ctx);
dst = ctx->VertexProgram.Parameters[dest->Index];
}
break;
default:
_mesa_problem(NULL, "Invalid register file in store_vector4(file=%d)",
dest->File);
return;
}
if (dest->WriteMask & WRITEMASK_X)
dst[0] = value[0];
if (dest->WriteMask & WRITEMASK_Y)
dst[1] = value[1];
if (dest->WriteMask & WRITEMASK_Z)
dst[2] = value[2];
if (dest->WriteMask & WRITEMASK_W)
dst[3] = value[3];
}
/**
* Set x to positive or negative infinity.
*/
#if defined(USE_IEEE) || defined(_WIN32)
#define SET_POS_INFINITY(x) ( *((GLuint *) (void *)&x) = 0x7F800000 )
#define SET_NEG_INFINITY(x) ( *((GLuint *) (void *)&x) = 0xFF800000 )
#elif defined(VMS)
#define SET_POS_INFINITY(x) x = __MAXFLOAT
#define SET_NEG_INFINITY(x) x = -__MAXFLOAT
#else
#define SET_POS_INFINITY(x) x = (GLfloat) HUGE_VAL
#define SET_NEG_INFINITY(x) x = (GLfloat) -HUGE_VAL
#endif
#define SET_FLOAT_BITS(x, bits) ((fi_type *) (void *) &(x))->i = bits
/**
* Execute the given vertex program
*/
void
_mesa_exec_vertex_program(GLcontext *ctx,
struct vp_machine *machine,
const struct gl_vertex_program *program)
{
const struct prog_instruction *inst;
ctx->_CurrentProgram = GL_VERTEX_PROGRAM_ARB; /* or NV, doesn't matter */
/* If the program is position invariant, multiply the input position
* by the MVP matrix and store in the vertex position result register.
*/
if (ctx->VertexProgram.Current->IsPositionInvariant) {
TRANSFORM_POINT( machine->Outputs[VERT_RESULT_HPOS],
ctx->_ModelProjectMatrix.m,
machine->Inputs[VERT_ATTRIB_POS]);
/* XXX: This could go elsewhere */
ctx->VertexProgram.Current->Base.OutputsWritten |= VERT_BIT_POS;
}
for (inst = program->Base.Instructions; ; inst++) {
if (ctx->VertexProgram.CallbackEnabled &&
ctx->VertexProgram.Callback) {
ctx->VertexProgram.CurrentPosition = inst->StringPos;
ctx->VertexProgram.Callback(program->Base.Target,
ctx->VertexProgram.CallbackData);
}
switch (inst->Opcode) {
case OPCODE_MOV:
{
GLfloat t[4];
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
store_vector4( inst, machine, t );
}
break;
case OPCODE_LIT:
{
const GLfloat epsilon = 1.0F / 256.0F; /* per NV spec */
GLfloat t[4], lit[4];
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
t[0] = MAX2(t[0], 0.0F);
t[1] = MAX2(t[1], 0.0F);
t[3] = CLAMP(t[3], -(128.0F - epsilon), (128.0F - epsilon));
lit[0] = 1.0;
lit[1] = t[0];
lit[2] = (t[0] > 0.0) ? (GLfloat) _mesa_pow(t[1], t[3]) : 0.0F;
lit[3] = 1.0;
store_vector4( inst, machine, lit );
}
break;
case OPCODE_RCP:
{
GLfloat t[4];
fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t );
if (t[0] != 1.0F)
t[0] = 1.0F / t[0]; /* div by zero is infinity! */
t[1] = t[2] = t[3] = t[0];
store_vector4( inst, machine, t );
}
break;
case OPCODE_RSQ:
{
GLfloat t[4];
fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t );
t[0] = INV_SQRTF(FABSF(t[0]));
t[1] = t[2] = t[3] = t[0];
store_vector4( inst, machine, t );
}
break;
case OPCODE_EXP:
{
GLfloat t[4], q[4], floor_t0;
fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t );
floor_t0 = FLOORF(t[0]);
if (floor_t0 > FLT_MAX_EXP) {
SET_POS_INFINITY(q[0]);
SET_POS_INFINITY(q[2]);
}
else if (floor_t0 < FLT_MIN_EXP) {
q[0] = 0.0F;
q[2] = 0.0F;
}
else {
#ifdef USE_IEEE
GLint ii = (GLint) floor_t0;
ii = (ii < 23) + 0x3f800000;
SET_FLOAT_BITS(q[0], ii);
q[0] = *((GLfloat *) (void *)&ii);
#else
q[0] = (GLfloat) pow(2.0, floor_t0);
#endif
q[2] = (GLfloat) (q[0] * LOG2(q[1]));
}
q[1] = t[0] - floor_t0;
q[3] = 1.0F;
store_vector4( inst, machine, q );
}
break;
case OPCODE_LOG:
{
GLfloat t[4], q[4], abs_t0;
fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t );
abs_t0 = FABSF(t[0]);
if (abs_t0 != 0.0F) {
/* Since we really can't handle infinite values on VMS
* like other OSes we'll use __MAXFLOAT to represent
* infinity. This may need some tweaking.
*/
#ifdef VMS
if (abs_t0 == __MAXFLOAT)
#else
if (IS_INF_OR_NAN(abs_t0))
#endif
{
SET_POS_INFINITY(q[0]);
q[1] = 1.0F;
SET_POS_INFINITY(q[2]);
}
else {
int exponent;
GLfloat mantissa = FREXPF(t[0], &exponent);
q[0] = (GLfloat) (exponent - 1);
q[1] = (GLfloat) (2.0 * mantissa); /* map [.5, 1) -> [1, 2) */
q[2] = (GLfloat) (q[0] + LOG2(q[1]));
}
}
else {
SET_NEG_INFINITY(q[0]);
q[1] = 1.0F;
SET_NEG_INFINITY(q[2]);
}
q[3] = 1.0;
store_vector4( inst, machine, q );
}
break;
case OPCODE_MUL:
{
GLfloat t[4], u[4], prod[4];
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
prod[0] = t[0] * u[0];
prod[1] = t[1] * u[1];
prod[2] = t[2] * u[2];
prod[3] = t[3] * u[3];
store_vector4( inst, machine, prod );
}
break;
case OPCODE_ADD:
{
GLfloat t[4], u[4], sum[4];
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
sum[0] = t[0] + u[0];
sum[1] = t[1] + u[1];
sum[2] = t[2] + u[2];
sum[3] = t[3] + u[3];
store_vector4( inst, machine, sum );
}
break;
case OPCODE_DP3:
{
GLfloat t[4], u[4], dot[4];
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2];
dot[1] = dot[2] = dot[3] = dot[0];
store_vector4( inst, machine, dot );
}
break;
case OPCODE_DP4:
{
GLfloat t[4], u[4], dot[4];
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2] + t[3] * u[3];
dot[1] = dot[2] = dot[3] = dot[0];
store_vector4( inst, machine, dot );
}
break;
case OPCODE_DST:
{
GLfloat t[4], u[4], dst[4];
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
dst[0] = 1.0F;
dst[1] = t[1] * u[1];
dst[2] = t[2];
dst[3] = u[3];
store_vector4( inst, machine, dst );
}
break;
case OPCODE_MIN:
{
GLfloat t[4], u[4], min[4];
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
min[0] = (t[0] < u[0]) ? t[0] : u[0];
min[1] = (t[1] < u[1]) ? t[1] : u[1];
min[2] = (t[2] < u[2]) ? t[2] : u[2];
min[3] = (t[3] < u[3]) ? t[3] : u[3];
store_vector4( inst, machine, min );
}
break;
case OPCODE_MAX:
{
GLfloat t[4], u[4], max[4];
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
max[0] = (t[0] > u[0]) ? t[0] : u[0];
max[1] = (t[1] > u[1]) ? t[1] : u[1];
max[2] = (t[2] > u[2]) ? t[2] : u[2];
max[3] = (t[3] > u[3]) ? t[3] : u[3];
store_vector4( inst, machine, max );
}
break;
case OPCODE_SLT:
{
GLfloat t[4], u[4], slt[4];
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
slt[0] = (t[0] < u[0]) ? 1.0F : 0.0F;
slt[1] = (t[1] < u[1]) ? 1.0F : 0.0F;
slt[2] = (t[2] < u[2]) ? 1.0F : 0.0F;
slt[3] = (t[3] < u[3]) ? 1.0F : 0.0F;
store_vector4( inst, machine, slt );
}
break;
case OPCODE_SGE:
{
GLfloat t[4], u[4], sge[4];
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
sge[0] = (t[0] >= u[0]) ? 1.0F : 0.0F;
sge[1] = (t[1] >= u[1]) ? 1.0F : 0.0F;
sge[2] = (t[2] >= u[2]) ? 1.0F : 0.0F;
sge[3] = (t[3] >= u[3]) ? 1.0F : 0.0F;
store_vector4( inst, machine, sge );
}
break;
case OPCODE_MAD:
{
GLfloat t[4], u[4], v[4], sum[4];
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
fetch_vector4( ctx, &inst->SrcReg[2], machine, program, v );
sum[0] = t[0] * u[0] + v[0];
sum[1] = t[1] * u[1] + v[1];
sum[2] = t[2] * u[2] + v[2];
sum[3] = t[3] * u[3] + v[3];
store_vector4( inst, machine, sum );
}
break;
case OPCODE_ARL:
{
GLfloat t[4];
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
machine->AddressReg[0] = (GLint) FLOORF(t[0]);
}
break;
case OPCODE_DPH:
{
GLfloat t[4], u[4], dot[4];
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2] + u[3];
dot[1] = dot[2] = dot[3] = dot[0];
store_vector4( inst, machine, dot );
}
break;
case OPCODE_RCC:
{
GLfloat t[4], u;
fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t );
if (t[0] == 1.0F)
u = 1.0F;
else
u = 1.0F / t[0];
if (u > 0.0F) {
if (u > 1.884467e+019F) {
u = 1.884467e+019F; /* IEEE 32-bit binary value 0x5F800000 */
}
else if (u < 5.42101e-020F) {
u = 5.42101e-020F; /* IEEE 32-bit binary value 0x1F800000 */
}
}
else {
if (u < -1.884467e+019F) {
u = -1.884467e+019F; /* IEEE 32-bit binary value 0xDF800000 */
}
else if (u > -5.42101e-020F) {
u = -5.42101e-020F; /* IEEE 32-bit binary value 0x9F800000 */
}
}
t[0] = t[1] = t[2] = t[3] = u;
store_vector4( inst, machine, t );
}
break;
case OPCODE_SUB: /* GL_NV_vertex_program1_1 */
{
GLfloat t[4], u[4], sum[4];
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
sum[0] = t[0] - u[0];
sum[1] = t[1] - u[1];
sum[2] = t[2] - u[2];
sum[3] = t[3] - u[3];
store_vector4( inst, machine, sum );
}
break;
case OPCODE_ABS: /* GL_NV_vertex_program1_1 */
{
GLfloat t[4];
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
if (t[0] < 0.0) t[0] = -t[0];
if (t[1] < 0.0) t[1] = -t[1];
if (t[2] < 0.0) t[2] = -t[2];
if (t[3] < 0.0) t[3] = -t[3];
store_vector4( inst, machine, t );
}
break;
case OPCODE_FLR: /* GL_ARB_vertex_program */
{
GLfloat t[4];
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
t[0] = FLOORF(t[0]);
t[1] = FLOORF(t[1]);
t[2] = FLOORF(t[2]);
t[3] = FLOORF(t[3]);
store_vector4( inst, machine, t );
}
break;
case OPCODE_FRC: /* GL_ARB_vertex_program */
{
GLfloat t[4];
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
t[0] = t[0] - FLOORF(t[0]);
t[1] = t[1] - FLOORF(t[1]);
t[2] = t[2] - FLOORF(t[2]);
t[3] = t[3] - FLOORF(t[3]);
store_vector4( inst, machine, t );
}
break;
case OPCODE_EX2: /* GL_ARB_vertex_program */
{
GLfloat t[4];
fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t );
t[0] = t[1] = t[2] = t[3] = (GLfloat)_mesa_pow(2.0, t[0]);
store_vector4( inst, machine, t );
}
break;
case OPCODE_LG2: /* GL_ARB_vertex_program */
{
GLfloat t[4];
fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t );
t[0] = t[1] = t[2] = t[3] = LOG2(t[0]);
store_vector4( inst, machine, t );
}
break;
case OPCODE_POW: /* GL_ARB_vertex_program */
{
GLfloat t[4], u[4];
fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t );
fetch_vector1( ctx, &inst->SrcReg[1], machine, program, u );
t[0] = t[1] = t[2] = t[3] = (GLfloat)_mesa_pow(t[0], u[0]);
store_vector4( inst, machine, t );
}
break;
case OPCODE_XPD: /* GL_ARB_vertex_program */
{
GLfloat t[4], u[4], cross[4];
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u );
cross[0] = t[1] * u[2] - t[2] * u[1];
cross[1] = t[2] * u[0] - t[0] * u[2];
cross[2] = t[0] * u[1] - t[1] * u[0];
store_vector4( inst, machine, cross );
}
break;
case OPCODE_SWZ: /* GL_ARB_vertex_program */
{
const struct prog_src_register *source = &inst->SrcReg[0];
const GLfloat *src = get_register_pointer(ctx, source,
machine, program);
GLfloat result[4];
GLuint i;
/* do extended swizzling here */
for (i = 0; i < 4; i++) {
const GLuint swz = GET_SWZ(source->Swizzle, i);
if (swz == SWIZZLE_ZERO)
result[i] = 0.0;
else if (swz == SWIZZLE_ONE)
result[i] = 1.0;
else {
ASSERT(swz >= 0);
ASSERT(swz <= 3);
result[i] = src[swz];
}
if (source->NegateBase & (1 << i))
result[i] = -result[i];
}
store_vector4( inst, machine, result );
}
break;
case OPCODE_PRINT:
if (inst->SrcReg[0].File) {
GLfloat t[4];
fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t );
_mesa_printf("%s%g, %g, %g, %g\n",
(char *) inst->Data, t[0], t[1], t[2], t[3]);
}
else {
_mesa_printf("%s\n", (char *) inst->Data);
}
break;
case OPCODE_END:
ctx->_CurrentProgram = 0;
return;
default:
/* bad instruction opcode */
_mesa_problem(ctx, "Bad VP Opcode in _mesa_exec_vertex_program");
ctx->_CurrentProgram = 0;
return;
} /* switch */
} /* for */
ctx->_CurrentProgram = 0;
}
/**
* Execute a vertex state program.
* \sa _mesa_ExecuteProgramNV
*/
void
_mesa_exec_vertex_state_program(GLcontext *ctx,
struct gl_vertex_program *vprog,
const GLfloat *params)
{
struct vp_machine machine;
_mesa_init_vp_per_vertex_registers(ctx, &machine);
_mesa_init_vp_per_primitive_registers(ctx);
COPY_4V(machine.Inputs[VERT_ATTRIB_POS], params);
_mesa_exec_vertex_program(ctx, &machine, vprog);
}

View file

@ -39,13 +39,11 @@
#include "glheader.h"
#include "context.h"
#include "hash.h"
#include "imports.h"
#include "macros.h"
#include "mtypes.h"
#include "nvprogram.h"
#include "nvvertparse.h"
#include "program_instruction.h"
#include "prog_instruction.h"
#include "program.h"
@ -1380,8 +1378,7 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget,
_mesa_free(programString);
return; /* out of memory */
}
_mesa_memcpy(newInst, instBuffer,
parseState.numInst * sizeof(struct prog_instruction));
_mesa_copy_instructions(newInst, instBuffer, parseState.numInst);
/* install the program */
program->Base.Target = target;

View file

@ -0,0 +1,259 @@
/*
* Mesa 3-D graphics library
* Version: 6.5.3
*
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "glheader.h"
#include "context.h"
#include "macros.h"
#include "nvfragparse.h"
#include "nvvertparse.h"
#include "program.h"
#include "prog_debug.h"
#include "prog_parameter.h"
#include "prog_instruction.h"
/**
* Functions for the experimental GL_MESA_program_debug extension.
*/
/* XXX temporary */
GLAPI void GLAPIENTRY
glProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback,
GLvoid *data)
{
_mesa_ProgramCallbackMESA(target, callback, data);
}
void
_mesa_ProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback,
GLvoid *data)
{
GET_CURRENT_CONTEXT(ctx);
switch (target) {
case GL_FRAGMENT_PROGRAM_ARB:
if (!ctx->Extensions.ARB_fragment_program) {
_mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)");
return;
}
ctx->FragmentProgram.Callback = callback;
ctx->FragmentProgram.CallbackData = data;
break;
case GL_FRAGMENT_PROGRAM_NV:
if (!ctx->Extensions.NV_fragment_program) {
_mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)");
return;
}
ctx->FragmentProgram.Callback = callback;
ctx->FragmentProgram.CallbackData = data;
break;
case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */
if (!ctx->Extensions.ARB_vertex_program &&
!ctx->Extensions.NV_vertex_program) {
_mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)");
return;
}
ctx->VertexProgram.Callback = callback;
ctx->VertexProgram.CallbackData = data;
break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)");
return;
}
}
/* XXX temporary */
GLAPI void GLAPIENTRY
glGetProgramRegisterfvMESA(GLenum target,
GLsizei len, const GLubyte *registerName,
GLfloat *v)
{
_mesa_GetProgramRegisterfvMESA(target, len, registerName, v);
}
void
_mesa_GetProgramRegisterfvMESA(GLenum target,
GLsizei len, const GLubyte *registerName,
GLfloat *v)
{
char reg[1000];
GET_CURRENT_CONTEXT(ctx);
/* We _should_ be inside glBegin/glEnd */
#if 0
if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramRegisterfvMESA");
return;
}
#endif
/* make null-terminated copy of registerName */
len = MIN2((unsigned int) len, sizeof(reg) - 1);
_mesa_memcpy(reg, registerName, len);
reg[len] = 0;
switch (target) {
case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */
if (!ctx->Extensions.ARB_vertex_program &&
!ctx->Extensions.NV_vertex_program) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetProgramRegisterfvMESA(target)");
return;
}
if (!ctx->VertexProgram._Enabled) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetProgramRegisterfvMESA");
return;
}
/* GL_NV_vertex_program */
if (reg[0] == 'R') {
/* Temp register */
GLint i = _mesa_atoi(reg + 1);
if (i >= (GLint)ctx->Const.VertexProgram.MaxTemps) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glGetProgramRegisterfvMESA(registerName)");
return;
}
ctx->Driver.GetProgramRegister(ctx, PROGRAM_TEMPORARY, i, v);
}
else if (reg[0] == 'v' && reg[1] == '[') {
/* Vertex Input attribute */
GLuint i;
for (i = 0; i < ctx->Const.VertexProgram.MaxAttribs; i++) {
const char *name = _mesa_nv_vertex_input_register_name(i);
char number[10];
_mesa_sprintf(number, "%d", i);
if (_mesa_strncmp(reg + 2, name, 4) == 0 ||
_mesa_strncmp(reg + 2, number, _mesa_strlen(number)) == 0) {
ctx->Driver.GetProgramRegister(ctx, PROGRAM_INPUT, i, v);
return;
}
}
_mesa_error(ctx, GL_INVALID_VALUE,
"glGetProgramRegisterfvMESA(registerName)");
return;
}
else if (reg[0] == 'o' && reg[1] == '[') {
/* Vertex output attribute */
}
/* GL_ARB_vertex_program */
else if (_mesa_strncmp(reg, "vertex.", 7) == 0) {
}
else {
_mesa_error(ctx, GL_INVALID_VALUE,
"glGetProgramRegisterfvMESA(registerName)");
return;
}
break;
case GL_FRAGMENT_PROGRAM_ARB:
if (!ctx->Extensions.ARB_fragment_program) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetProgramRegisterfvMESA(target)");
return;
}
if (!ctx->FragmentProgram._Enabled) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetProgramRegisterfvMESA");
return;
}
/* XXX to do */
break;
case GL_FRAGMENT_PROGRAM_NV:
if (!ctx->Extensions.NV_fragment_program) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetProgramRegisterfvMESA(target)");
return;
}
if (!ctx->FragmentProgram._Enabled) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetProgramRegisterfvMESA");
return;
}
if (reg[0] == 'R') {
/* Temp register */
GLint i = _mesa_atoi(reg + 1);
if (i >= (GLint)ctx->Const.FragmentProgram.MaxTemps) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glGetProgramRegisterfvMESA(registerName)");
return;
}
ctx->Driver.GetProgramRegister(ctx, PROGRAM_TEMPORARY,
i, v);
}
else if (reg[0] == 'f' && reg[1] == '[') {
/* Fragment input attribute */
GLuint i;
for (i = 0; i < ctx->Const.FragmentProgram.MaxAttribs; i++) {
const char *name = _mesa_nv_fragment_input_register_name(i);
if (_mesa_strncmp(reg + 2, name, 4) == 0) {
ctx->Driver.GetProgramRegister(ctx, PROGRAM_INPUT, i, v);
return;
}
}
_mesa_error(ctx, GL_INVALID_VALUE,
"glGetProgramRegisterfvMESA(registerName)");
return;
}
else if (_mesa_strcmp(reg, "o[COLR]") == 0) {
/* Fragment output color */
ctx->Driver.GetProgramRegister(ctx, PROGRAM_OUTPUT,
FRAG_RESULT_COLR, v);
}
else if (_mesa_strcmp(reg, "o[COLH]") == 0) {
/* Fragment output color */
ctx->Driver.GetProgramRegister(ctx, PROGRAM_OUTPUT,
FRAG_RESULT_COLH, v);
}
else if (_mesa_strcmp(reg, "o[DEPR]") == 0) {
/* Fragment output depth */
ctx->Driver.GetProgramRegister(ctx, PROGRAM_OUTPUT,
FRAG_RESULT_DEPR, v);
}
else {
/* try user-defined identifiers */
const GLfloat *value = _mesa_lookup_parameter_value(
ctx->FragmentProgram.Current->Base.Parameters, -1, reg);
if (value) {
COPY_4V(v, value);
}
else {
_mesa_error(ctx, GL_INVALID_VALUE,
"glGetProgramRegisterfvMESA(registerName)");
return;
}
}
break;
default:
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetProgramRegisterfvMESA(target)");
return;
}
}

Some files were not shown because too many files have changed in this diff Show more