blob: 015d01a1d84bab94ff86390863174332e14674c0 [file] [log] [blame]
Brian Paulc6511ab2006-08-24 22:11:40 +00001/*
2 * Mesa 3-D graphics library
3 * Version: 6.5.1
4 *
5 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25/**
26 * \file programopt.c
27 * Vertex/Fragment program optimizations and transformations for program
28 * options, etc.
29 *
30 * \author Brian Paul
31 */
32
33
34#include "glheader.h"
35#include "context.h"
36#include "imports.h"
37#include "mtypes.h"
38#include "program.h"
39#include "programopt.h"
40#include "program_instruction.h"
41
42
43/**
44 * This is used for helping with position-invariant vertex programs.
45 * It appends extra instructions to the given program to do the
46 * vertex position transformation (multiply by the MVP matrix).
47 */
48void
49_mesa_append_modelview_code(GLcontext *ctx, struct gl_vertex_program *vprog)
50{
51 struct prog_instruction newInst[5];
52 const GLuint origLen = vprog->Base.NumInstructions;
53 GLuint i;
54
55 /*
56 * Setup state references for the modelview/projection matrix.
57 * XXX we should check if these state vars are already declared.
58 */
59 static const GLint mvpState[4][5] = {
60 { STATE_MATRIX, STATE_MVP, 0, 0, 0 }, /* state.matrix.mvp.row[0] */
61 { STATE_MATRIX, STATE_MVP, 0, 1, 1 }, /* state.matrix.mvp.row[1] */
62 { STATE_MATRIX, STATE_MVP, 0, 2, 2 }, /* state.matrix.mvp.row[2] */
63 { STATE_MATRIX, STATE_MVP, 0, 3, 3 }, /* state.matrix.mvp.row[3] */
64 };
65 GLint mvpRef[4];
66
67 for (i = 0; i < 4; i++) {
68 mvpRef[i] = _mesa_add_state_reference(vprog->Base.Parameters,
69 mvpState[i]);
70 }
71
72 /*
73 * Generated instructions:
74 * newInst[0] = DP4 result.position.x, mvp.row[0], vertex.position;
75 * newInst[1] = DP4 result.position.y, mvp.row[1], vertex.position;
76 * newInst[2] = DP4 result.position.z, mvp.row[2], vertex.position;
77 * newInst[3] = DP4 result.position.w, mvp.row[3], vertex.position;
78 * newInst[4] = END;
79 */
80 for (i = 0; i < 4; i++) {
81 _mesa_init_instruction(newInst + i);
82 newInst[i].Opcode = OPCODE_DP4;
83 newInst[i].DstReg.File = PROGRAM_OUTPUT;
84 newInst[i].DstReg.Index = VERT_RESULT_HPOS;
85 newInst[i].DstReg.WriteMask = (WRITEMASK_X << i);
86 newInst[i].SrcReg[0].File = PROGRAM_STATE_VAR;
87 newInst[i].SrcReg[0].Index = mvpRef[i];
88 newInst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP;
89 newInst[i].SrcReg[1].File = PROGRAM_INPUT;
90 newInst[i].SrcReg[1].Index = VERT_ATTRIB_POS;
91 newInst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP;
92 }
93 newInst[4].Opcode = OPCODE_END;
94
95 /*
96 * Append new instructions onto program.
97 */
98 vprog->Base.Instructions
99 = _mesa_realloc_instructions(vprog->Base.Instructions,
100 origLen, origLen + 4);
101 if (!vprog->Base.Instructions) {
102 _mesa_error(ctx, GL_OUT_OF_MEMORY,
103 "glProgramString(generating position transformation code)");
104 return;
105 }
106 /* subtract one to overwrite original program's END instruction */
107 _mesa_memcpy(vprog->Base.Instructions + origLen - 1,
108 newInst, sizeof(newInst));
109
110 vprog->Base.NumInstructions = origLen + 4;
111 vprog->Base.InputsRead |= VERT_BIT_POS;
112 vprog->Base.OutputsWritten |= (1 << VERT_RESULT_HPOS);
113}
114
115
116
117/**
118 * Append extra instructions onto the given fragment program to implement
119 * the fog mode specified by program->FogOption.
120 * XXX incomplete.
121 */
122void
123_mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog)
124{
125 struct prog_instruction newInst[10];
126
127 switch (fprog->FogOption) {
128 case GL_LINEAR:
129 /* lerp */
130 break;
131 case GL_EXP:
132 break;
133 case GL_EXP2:
134 break;
135 case GL_NONE:
136 /* no-op */
137 return;
138 default:
139 _mesa_problem(ctx, "Invalid fog option");
140 return;
141 }
142
143
144 (void) newInst;
145
146}