From 6fb235661a3a78174e7554b292332a1dbb24f171 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 14 Apr 2004 21:19:34 +0000 Subject: Use tcc and the emitted C code from s_fragprog_to_c.c to dynamically compile and execute fragment programs. Very limited and experimental, but works well enough to run arbfplight.c. http://fabrice.bellard.free.fr/tcc/ Compile with 'make linux-tcc', being sure to make clean first. --- src/mesa/swrast/s_tcc.c | 185 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 src/mesa/swrast/s_tcc.c (limited to 'src/mesa/swrast/s_tcc.c') diff --git a/src/mesa/swrast/s_tcc.c b/src/mesa/swrast/s_tcc.c new file mode 100644 index 0000000000..3d8f550ece --- /dev/null +++ b/src/mesa/swrast/s_tcc.c @@ -0,0 +1,185 @@ +/* + * Mesa 3-D graphics library + * Version: 6.1 + * + * Copyright (C) 1999-2004 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. + */ + +/* An attempt to hook s_fragprog_to_c.c up to libtcc.a to try & + * generate some real code. + * + * TCC isn't threadsafe, so it will need additional locking help if we + * end up using it as a backend in mesa. + */ + +#include +#include + + +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "nvfragprog.h" +#include "macros.h" +#include "program.h" + +#include "s_nvfragprog.h" +#include "s_texture.h" + +#ifdef USE_TCC + +#include + +typedef int (*cfunc)( void *ctx, + const GLfloat (*local_param)[4], + const GLfloat (*env_param)[4], + const struct program_parameter *state_param, + const GLfloat (*interp)[4], + GLfloat (*outputs)[4]); + + +static cfunc current_func; +static struct fragment_program *current_program; +static TCCState *current_tcc_state; + + +static void TEX( void *cc, const float *texcoord, int unit, float *result ) +{ + GLcontext *ctx = (GLcontext *)cc; + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLfloat lambda = 1.0; /* hack */ + GLchan rgba[4]; + + swrast->TextureSample[unit](ctx, unit, ctx->Texture.Unit[unit]._Current, + 1, (const GLfloat (*)[4]) texcoord, + &lambda, &rgba); + + result[0] = CHAN_TO_FLOAT(rgba[0]); + result[1] = CHAN_TO_FLOAT(rgba[1]); + result[2] = CHAN_TO_FLOAT(rgba[2]); + result[3] = CHAN_TO_FLOAT(rgba[3]); +} + + +static void TXB( void *cc, const float *texcoord, int unit, float *result ) +{ + GLcontext *ctx = (GLcontext *)cc; + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLfloat lambda = 1.0; /* hack */ + GLchan rgba[4]; + + /* texcoord[3] is the bias to add to lambda */ + lambda += texcoord[3]; + + + /* Is it necessary to reset texcoord[3] to 1 at this point? + */ + swrast->TextureSample[unit](ctx, unit, ctx->Texture.Unit[unit]._Current, + 1, (const GLfloat (*)[4]) texcoord, + &lambda, &rgba); + + result[0] = CHAN_TO_FLOAT(rgba[0]); + result[1] = CHAN_TO_FLOAT(rgba[1]); + result[2] = CHAN_TO_FLOAT(rgba[2]); + result[3] = CHAN_TO_FLOAT(rgba[3]); +} + + +static void TXP( void *cc, const float *texcoord, int unit, float *result ) +{ + /* I think that TEX needs to undo the perspective divide which has + * already occurred. In the meantime, TXP is correct to do this: + */ + TEX( cc, texcoord, unit, result ); +} + + +static cfunc codegen( TCCState *s, const char *prog, const char *fname ) +{ + unsigned long val; + + if (s) + tcc_delete(s); + + s = tcc_new(); + if (!s) + return 0; + + tcc_set_output_type(s, TCC_OUTPUT_MEMORY); + tcc_compile_string(s, prog); + +/* tcc_add_dll("/usr/lib/libm.so"); */ + + tcc_add_symbol(s, "TEX", (unsigned long)&TEX); + tcc_add_symbol(s, "TXB", (unsigned long)&TXB); + tcc_add_symbol(s, "TXP", (unsigned long)&TXP); + + + tcc_relocate(s); + tcc_get_symbol(s, &val, fname); + return (cfunc) val; +} + +/* TCC isn't threadsafe and even seems not to like having more than + * one TCCState created or used at any one time in a single threaded + * environment. So, this code is all for investigation only and can't + * currently be used in Mesa proper. + * + * I've taken some liberties with globals myself, now. + */ +GLboolean +_swrast_execute_codegen_program( GLcontext *ctx, + const struct fragment_program *program, GLuint maxInst, + struct fp_machine *machine, const struct sw_span *span, + GLuint column ) +{ + if (program != current_program) { + + _swrast_translate_program( ctx ); + + fprintf(stderr, "%s: compiling:\n%s\n", __FUNCTION__, program->c_str); + + current_program = program; + current_func = codegen( current_tcc_state, program->c_str, + "run_program" ); + } + + assert(current_func); + + return current_func( ctx, + program->Base.LocalParams, + (const GLfloat (*)[4])ctx->FragmentProgram.Parameters, + program->Parameters->Parameters, + (const GLfloat (*)[4])machine->Inputs, + machine->Outputs ); +} + +#else /* USE_TCC */ + +GLboolean +_swrast_execute_codegen_program( GLcontext *ctx, + const struct fragment_program *program, GLuint maxInst, + struct fp_machine *machine, const struct sw_span *span, + GLuint column ) +{ + return 0; +} + +#endif -- cgit v1.2.3