2 * Copyright (C) 2009 Maciej Cencora <m.cencora@gmail.com>
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 * Fragment program compiler. Perform transformations on the intermediate
32 * representation until the program is in a form where we can translate
33 * it more or less directly into machine-readable form.
35 * \author Ben Skeggs <darktama@iinet.net.au>
36 * \author Jerome Glisse <j.glisse@gmail.com>
39 #include "r300_fragprog_common.h"
41 #include "shader/program.h"
42 #include "shader/prog_parameter.h"
43 #include "shader/prog_print.h"
45 #include "compiler/radeon_compiler.h"
47 #include "r300_state.h"
50 static GLuint build_dtm(GLuint depthmode)
54 case GL_LUMINANCE: return 0;
55 case GL_INTENSITY: return 1;
56 case GL_ALPHA: return 2;
60 static GLuint build_func(GLuint comparefunc)
62 return comparefunc - GL_NEVER;
66 * Collect all external state that is relevant for compiling the given
69 static void build_state(
71 struct gl_fragment_program *fp,
72 struct r300_fragment_program_external_state *state)
76 _mesa_bzero(state, sizeof(*state));
78 for(unit = 0; unit < 16; ++unit) {
79 if (fp->Base.ShadowSamplers & (1 << unit)) {
80 struct gl_texture_object* tex = r300->radeon.glCtx->Texture.Unit[unit]._Current;
82 state->unit[unit].depth_texture_mode = build_dtm(tex->DepthMode);
83 state->unit[unit].texture_compare_func = build_func(tex->CompareFunc);
89 static void translate_fragment_program(GLcontext *ctx, struct r300_fragment_program_cont *cont, struct r300_fragment_program *fp)
91 r300ContextPtr r300 = R300_CONTEXT(ctx);
92 struct r300_fragment_program_compiler compiler;
94 rc_init(&compiler.Base);
95 compiler.Base.Debug = (RADEON_DEBUG & DEBUG_PIXEL) ? GL_TRUE : GL_FALSE;
97 compiler.code = &fp->code;
98 compiler.state = fp->state;
99 compiler.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) ? GL_TRUE : GL_FALSE;
101 if (compiler.Base.Debug) {
103 _mesa_printf("Fragment Program: Initial program:\n");
104 _mesa_print_program(&cont->Base.Base);
108 rc_mesa_to_rc_program(&compiler.Base, &cont->Base.Base);
110 r3xx_compile_fragment_program(&compiler);
111 fp->error = compiler.Base.Error;
113 fp->InputsRead = compiler.Base.Program.InputsRead;
115 rc_destroy(&compiler.Base);
118 struct r300_fragment_program *r300SelectAndTranslateFragmentShader(GLcontext *ctx)
120 r300ContextPtr r300 = R300_CONTEXT(ctx);
121 struct r300_fragment_program_cont *fp_list;
122 struct r300_fragment_program *fp;
123 struct r300_fragment_program_external_state state;
125 fp_list = (struct r300_fragment_program_cont *)ctx->FragmentProgram._Current;
126 build_state(r300, ctx->FragmentProgram._Current, &state);
130 if (_mesa_memcmp(&fp->state, &state, sizeof(state)) == 0) {
131 return r300->selected_fp = fp;
136 fp = _mesa_calloc(sizeof(struct r300_fragment_program));
140 fp->next = fp_list->progs;
143 translate_fragment_program(ctx, fp_list, fp);
145 return r300->selected_fp = fp;