New glTexImage code.
[mesa.git] / src / mesa / swrast / s_tcc.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.1
4 *
5 * Copyright (C) 1999-2004 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 /* An attempt to hook s_fragprog_to_c.c up to libtcc.a to try &
26 * generate some real code.
27 *
28 * TCC isn't threadsafe, so it will need additional locking help if we
29 * end up using it as a backend in mesa.
30 */
31
32 #include <stdlib.h>
33 #include <stdio.h>
34
35
36 #include "glheader.h"
37 #include "colormac.h"
38 #include "context.h"
39 #include "nvfragprog.h"
40 #include "macros.h"
41 #include "program.h"
42
43 #include "s_nvfragprog.h"
44 #include "s_texture.h"
45
46 #ifdef USE_TCC
47
48 #include <libtcc.h>
49
50 typedef int (*cfunc)( void *ctx,
51 const GLfloat (*local_param)[4],
52 const GLfloat (*env_param)[4],
53 const struct program_parameter *state_param,
54 const GLfloat (*interp)[4],
55 GLfloat (*outputs)[4]);
56
57
58 static cfunc current_func;
59 static struct fragment_program *current_program;
60 static TCCState *current_tcc_state;
61
62
63 static void TEX( void *cc, const float *texcoord, int unit, float *result )
64 {
65 GLcontext *ctx = (GLcontext *)cc;
66 SWcontext *swrast = SWRAST_CONTEXT(ctx);
67 GLfloat lambda = 1.0; /* hack */
68 GLchan rgba[4];
69
70 swrast->TextureSample[unit](ctx, unit, ctx->Texture.Unit[unit]._Current,
71 1, (const GLfloat (*)[4]) texcoord,
72 &lambda, &rgba);
73
74 result[0] = CHAN_TO_FLOAT(rgba[0]);
75 result[1] = CHAN_TO_FLOAT(rgba[1]);
76 result[2] = CHAN_TO_FLOAT(rgba[2]);
77 result[3] = CHAN_TO_FLOAT(rgba[3]);
78 }
79
80
81 static void TXB( void *cc, const float *texcoord, int unit, float *result )
82 {
83 GLcontext *ctx = (GLcontext *)cc;
84 SWcontext *swrast = SWRAST_CONTEXT(ctx);
85 GLfloat lambda = 1.0; /* hack */
86 GLchan rgba[4];
87
88 /* texcoord[3] is the bias to add to lambda */
89 lambda += texcoord[3];
90
91
92 /* Is it necessary to reset texcoord[3] to 1 at this point?
93 */
94 swrast->TextureSample[unit](ctx, unit, ctx->Texture.Unit[unit]._Current,
95 1, (const GLfloat (*)[4]) texcoord,
96 &lambda, &rgba);
97
98 result[0] = CHAN_TO_FLOAT(rgba[0]);
99 result[1] = CHAN_TO_FLOAT(rgba[1]);
100 result[2] = CHAN_TO_FLOAT(rgba[2]);
101 result[3] = CHAN_TO_FLOAT(rgba[3]);
102 }
103
104
105 static void TXP( void *cc, const float *texcoord, int unit, float *result )
106 {
107 /* I think that TEX needs to undo the perspective divide which has
108 * already occurred. In the meantime, TXP is correct to do this:
109 */
110 TEX( cc, texcoord, unit, result );
111 }
112
113
114 static cfunc codegen( TCCState *s, const char *prog, const char *fname )
115 {
116 unsigned long val;
117
118 if (s)
119 tcc_delete(s);
120
121 s = tcc_new();
122 if (!s)
123 return 0;
124
125 tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
126 tcc_compile_string(s, prog);
127
128 /* tcc_add_dll("/usr/lib/libm.so"); */
129
130 tcc_add_symbol(s, "TEX", (unsigned long)&TEX);
131 tcc_add_symbol(s, "TXB", (unsigned long)&TXB);
132 tcc_add_symbol(s, "TXP", (unsigned long)&TXP);
133
134
135 tcc_relocate(s);
136 tcc_get_symbol(s, &val, fname);
137 return (cfunc) val;
138 }
139
140 /* TCC isn't threadsafe and even seems not to like having more than
141 * one TCCState created or used at any one time in a single threaded
142 * environment. So, this code is all for investigation only and can't
143 * currently be used in Mesa proper.
144 *
145 * I've taken some liberties with globals myself, now.
146 */
147 GLboolean
148 _swrast_execute_codegen_program( GLcontext *ctx,
149 const struct fragment_program *program, GLuint maxInst,
150 struct fp_machine *machine, const struct sw_span *span,
151 GLuint column )
152 {
153 if (program != current_program) {
154
155 _swrast_translate_program( ctx );
156
157 fprintf(stderr, "%s: compiling:\n%s\n", __FUNCTION__, program->c_str);
158
159 current_program = program;
160 current_func = codegen( current_tcc_state, program->c_str,
161 "run_program" );
162 }
163
164 assert(current_func);
165
166 return current_func( ctx,
167 program->Base.LocalParams,
168 (const GLfloat (*)[4])ctx->FragmentProgram.Parameters,
169 program->Parameters->Parameters,
170 (const GLfloat (*)[4])machine->Inputs,
171 machine->Outputs );
172 }
173
174 #else /* USE_TCC */
175
176 GLboolean
177 _swrast_execute_codegen_program( GLcontext *ctx,
178 const struct fragment_program *program, GLuint maxInst,
179 struct fp_machine *machine, const struct sw_span *span,
180 GLuint column )
181 {
182 return 0;
183 }
184
185 #endif