summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian <brian@yutani.localnet.net>2007-03-26 10:13:02 -0600
committerBrian <brian@yutani.localnet.net>2007-03-26 10:13:02 -0600
commitd619cceea47dc3070ebb7f7ea4f8b6b31a672d38 (patch)
treef8b8a9f3fdc3f17a43436af270b22754b1749d31
parent76f3b66e0489526694d6a39b4a6ac3b1c2bee100 (diff)
parente71c34aaa173ca451fa02e526ead77758f7eeb74 (diff)
merge of glsl-compiler-1 branch
-rw-r--r--Makefile1
-rw-r--r--configs/linux-dri2
-rw-r--r--docs/contents.html1
-rw-r--r--docs/relnotes-6.5.3.html16
-rw-r--r--docs/shading.html286
-rw-r--r--progs/demos/Makefile7
-rw-r--r--progs/demos/fslight.c385
-rw-r--r--progs/glsl/CH06-brick.frag.txt36
-rw-r--r--progs/glsl/CH06-brick.vert.txt41
-rw-r--r--progs/glsl/CH11-bumpmap.frag.txt41
-rw-r--r--progs/glsl/CH11-bumpmap.vert.txt38
-rw-r--r--progs/glsl/CH11-toyball.frag.txt75
-rw-r--r--progs/glsl/CH11-toyball.vert.txt24
-rw-r--r--progs/glsl/CH18-mandel.frag.txt55
-rw-r--r--progs/glsl/CH18-mandel.vert.txt35
-rw-r--r--progs/glsl/Makefile74
-rw-r--r--progs/glsl/brick.c311
-rw-r--r--progs/glsl/bump.c411
-rw-r--r--progs/glsl/cubemap.frag.txt18
-rw-r--r--progs/glsl/mandelbrot.c328
-rw-r--r--progs/glsl/noise.c297
-rw-r--r--progs/glsl/reflect.vert.txt19
-rw-r--r--progs/glsl/shadowtex.frag.txt21
-rw-r--r--progs/glsl/simple.vert.txt9
-rw-r--r--progs/glsl/texdemo1.c570
-rw-r--r--progs/glsl/toyball.c339
-rw-r--r--progs/tests/Makefile9
-rw-r--r--progs/tests/drawbuffers.c298
-rw-r--r--progs/util/extfuncs.h118
-rw-r--r--src/mesa/drivers/common/driverfuncs.c49
-rw-r--r--src/mesa/drivers/common/driverfuncs.h8
-rw-r--r--src/mesa/drivers/dri/i915/i915_context.c3
-rw-r--r--src/mesa/drivers/dri/i915/i915_fragprog.c6
-rw-r--r--src/mesa/drivers/dri/i915/i915_program.c12
-rw-r--r--src/mesa/drivers/dri/i915/i915_state.c2
-rw-r--r--src/mesa/drivers/dri/i915/i915_vtbl.c4
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_context.c4
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_fragprog.c6
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_program.c12
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_curbe.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu.h2
-rw-r--r--src/mesa/drivers/dri/i965/brw_metaops.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_util.c32
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_constval.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_emit.c5
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_tnl.c77
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.h2
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_debug.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_emit.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_fp.c34
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_pass0.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_pass1.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_pass2.c4
-rw-r--r--src/mesa/drivers/dri/mach64/mach64_native_vb.c20
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_context.c2
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_shader.c5
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_shader_0.c16
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_shader_2.c3
-rw-r--r--src/mesa/drivers/dri/r200/r200_vertprog.c10
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.c2
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog.c5
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog.h5
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.c8
-rw-r--r--src/mesa/drivers/dri/r300/r300_vertprog.c10
-rw-r--r--src/mesa/drivers/dri/s3v/s3v_tritmp.h46
-rw-r--r--src/mesa/drivers/dri/tdfx/tdfx_tris.c16
-rw-r--r--src/mesa/drivers/dri/trident/trident_context.h2
-rw-r--r--src/mesa/drivers/glslcompiler/Makefile44
-rw-r--r--src/mesa/drivers/glslcompiler/glslcompiler.c358
-rw-r--r--src/mesa/main/colortab.c8
-rw-r--r--src/mesa/main/config.h14
-rw-r--r--src/mesa/main/context.c129
-rw-r--r--src/mesa/main/dd.h58
-rw-r--r--src/mesa/main/get.c18
-rw-r--r--src/mesa/main/get_gen.py11
-rw-r--r--src/mesa/main/getstring.c4
-rw-r--r--src/mesa/main/imports.c20
-rw-r--r--src/mesa/main/matrix.c12
-rw-r--r--src/mesa/main/mtypes.h240
-rw-r--r--src/mesa/main/pixel.c8
-rw-r--r--src/mesa/main/shaders.c680
-rw-r--r--src/mesa/main/shaders.h (renamed from src/mesa/shader/shaderobjects.h)131
-rw-r--r--src/mesa/main/state.c81
-rw-r--r--src/mesa/main/texenvprogram.c98
-rw-r--r--src/mesa/main/texstate.c71
-rw-r--r--src/mesa/shader/arbprogparse.c299
-rw-r--r--src/mesa/shader/arbprogram.c12
-rw-r--r--src/mesa/shader/asmopcodes.reg78
-rw-r--r--src/mesa/shader/grammar/grammar.c25
-rw-r--r--[-rwxr-xr-x]src/mesa/shader/grammar/grammar_crt.c0
-rw-r--r--[-rwxr-xr-x]src/mesa/shader/grammar/grammar_crt.h0
-rw-r--r--src/mesa/shader/nvfragparse.c35
-rw-r--r--src/mesa/shader/nvprogram.c7
-rw-r--r--src/mesa/shader/nvvertexec.c835
-rw-r--r--src/mesa/shader/nvvertparse.c7
-rw-r--r--src/mesa/shader/prog_debug.c259
-rw-r--r--src/mesa/shader/prog_debug.h (renamed from src/mesa/swrast/s_arbshader.h)26
-rw-r--r--src/mesa/shader/prog_execute.c1748
-rw-r--r--src/mesa/shader/prog_execute.h81
-rw-r--r--src/mesa/shader/prog_instruction.c243
-rw-r--r--src/mesa/shader/prog_instruction.h451
-rw-r--r--src/mesa/shader/prog_parameter.c600
-rw-r--r--src/mesa/shader/prog_parameter.h136
-rw-r--r--src/mesa/shader/prog_print.c749
-rw-r--r--src/mesa/shader/prog_print.h (renamed from src/mesa/shader/nvvertexec.h)58
-rw-r--r--src/mesa/shader/prog_statevars.c824
-rw-r--r--src/mesa/shader/prog_statevars.h129
-rw-r--r--src/mesa/shader/program.c1863
-rw-r--r--src/mesa/shader/program.h227
-rw-r--r--src/mesa/shader/program_instruction.h360
-rw-r--r--src/mesa/shader/programopt.c113
-rw-r--r--src/mesa/shader/programopt.h10
-rw-r--r--src/mesa/shader/shader_api.c1081
-rw-r--r--src/mesa/shader/shader_api.h172
-rw-r--r--src/mesa/shader/shaderobjects.c1191
-rwxr-xr-xsrc/mesa/shader/shaderobjects_3dlabs.c2144
-rwxr-xr-xsrc/mesa/shader/slang/Include/BaseTypes.h133
-rwxr-xr-xsrc/mesa/shader/slang/Include/Common.h288
-rwxr-xr-xsrc/mesa/shader/slang/Include/ConstantUnion.h50
-rwxr-xr-xsrc/mesa/shader/slang/Include/InfoSink.h135
-rwxr-xr-xsrc/mesa/shader/slang/Include/InitializeGlobals.h43
-rwxr-xr-xsrc/mesa/shader/slang/Include/InitializeParseContext.h44
-rwxr-xr-xsrc/mesa/shader/slang/Include/PoolAlloc.h346
-rwxr-xr-xsrc/mesa/shader/slang/Include/ResourceLimits.h61
-rwxr-xr-xsrc/mesa/shader/slang/Include/ShHandle.h177
-rwxr-xr-xsrc/mesa/shader/slang/Include/Types.h297
-rwxr-xr-xsrc/mesa/shader/slang/Include/intermediate.h516
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/Gen_glslang.cpp2942
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/Gen_glslang_tab.cpp4354
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/InfoSink.cpp107
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/Initialize.cpp948
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/Initialize.h58
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/IntermTraverse.cpp243
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/Intermediate.cpp2110
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/MMap.h84
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/ParseHelper.cpp1452
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/ParseHelper.h143
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/PoolAlloc.cpp349
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/QualifierAlive.cpp91
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/QualifierAlive.h35
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/RemoveTree.cpp98
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/RemoveTree.h35
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/ShaderLang.cpp607
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/SymbolTable.cpp235
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/SymbolTable.h320
-rw-r--r--src/mesa/shader/slang/MachineIndependent/glslang.l614
-rw-r--r--src/mesa/shader/slang/MachineIndependent/glslang.y2009
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/glslang_tab.h260
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/intermOut.cpp496
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/localintermediate.h91
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/parseConst.cpp344
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/atom.c768
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/atom.h96
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/compile.h132
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/cpp.c1037
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/cpp.h119
-rw-r--r--src/mesa/shader/slang/MachineIndependent/preprocessor/cpp_comment_fix.c76
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/cppstruct.c185
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/memory.c191
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/memory.h89
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/parser.h126
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/preprocess.h84
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/scanner.c789
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/scanner.h118
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/slglobals.h115
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/symbols.c318
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/symbols.h145
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/tokens.c462
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/tokens.h122
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/unistd.h1
-rwxr-xr-xsrc/mesa/shader/slang/OGLCompilersDLL/Initialisation.cpp151
-rwxr-xr-xsrc/mesa/shader/slang/OGLCompilersDLL/Initialisation.h47
-rwxr-xr-xsrc/mesa/shader/slang/OSDependent/Linux/osinclude.h78
-rwxr-xr-xsrc/mesa/shader/slang/OSDependent/Linux/ossource.cpp140
-rwxr-xr-xsrc/mesa/shader/slang/OSDependent/Windows/osinclude.h68
-rwxr-xr-xsrc/mesa/shader/slang/OSDependent/Windows/ossource.cpp119
-rwxr-xr-xsrc/mesa/shader/slang/Public/ShaderLang.h212
-rwxr-xr-xsrc/mesa/shader/slang/Public/ShaderLangExt.h57
-rw-r--r--src/mesa/shader/slang/library/Makefile8
-rw-r--r--[-rwxr-xr-x]src/mesa/shader/slang/library/gc_to_bin.c5
-rw-r--r--[-rwxr-xr-x]src/mesa/shader/slang/library/slang_120_core.gc0
-rw-r--r--[-rwxr-xr-x]src/mesa/shader/slang/library/slang_builtin_120_common.gc0
-rw-r--r--[-rwxr-xr-x]src/mesa/shader/slang/library/slang_builtin_120_fragment.gc0
-rwxr-xr-xsrc/mesa/shader/slang/library/slang_builtin_vec4.gc220
-rw-r--r--src/mesa/shader/slang/library/slang_builtin_vec4_gc.h62
-rw-r--r--[-rwxr-xr-x]src/mesa/shader/slang/library/slang_common_builtin.gc1725
-rw-r--r--src/mesa/shader/slang/library/slang_common_builtin_gc.h1374
-rw-r--r--[-rwxr-xr-x]src/mesa/shader/slang/library/slang_core.gc2751
-rw-r--r--src/mesa/shader/slang/library/slang_core_gc.h1400
-rw-r--r--[-rwxr-xr-x]src/mesa/shader/slang/library/slang_fragment_builtin.gc260
-rw-r--r--src/mesa/shader/slang/library/slang_fragment_builtin_gc.h166
-rw-r--r--src/mesa/shader/slang/library/slang_shader.syn21
-rw-r--r--src/mesa/shader/slang/library/slang_shader_syn.h16
-rw-r--r--[-rwxr-xr-x]src/mesa/shader/slang/library/slang_vertex_builtin.gc139
-rw-r--r--src/mesa/shader/slang/library/slang_vertex_builtin_gc.h129
-rw-r--r--src/mesa/shader/slang/slang_analyse.c100
-rw-r--r--src/mesa/shader/slang/slang_analyse.h50
-rw-r--r--src/mesa/shader/slang/slang_assemble.c1542
-rw-r--r--src/mesa/shader/slang/slang_assemble.h278
-rw-r--r--src/mesa/shader/slang/slang_assemble_assignment.c223
-rw-r--r--src/mesa/shader/slang/slang_assemble_conditional.c448
-rw-r--r--src/mesa/shader/slang/slang_assemble_conditional.h51
-rw-r--r--src/mesa/shader/slang/slang_assemble_constructor.c401
-rw-r--r--src/mesa/shader/slang/slang_assemble_constructor.h57
-rw-r--r--src/mesa/shader/slang/slang_assemble_typeinfo.c625
-rw-r--r--src/mesa/shader/slang/slang_builtin.c440
-rw-r--r--src/mesa/shader/slang/slang_builtin.h (renamed from src/mesa/shader/slang/slang_mesa.h)25
-rw-r--r--src/mesa/shader/slang/slang_codegen.c2833
-rw-r--r--src/mesa/shader/slang/slang_codegen.h (renamed from src/mesa/shader/slang/slang_assemble_assignment.h)30
-rw-r--r--src/mesa/shader/slang/slang_compile.c743
-rw-r--r--src/mesa/shader/slang/slang_compile.h42
-rw-r--r--src/mesa/shader/slang/slang_compile_function.c85
-rw-r--r--src/mesa/shader/slang/slang_compile_function.h22
-rw-r--r--src/mesa/shader/slang/slang_compile_operation.c129
-rw-r--r--src/mesa/shader/slang/slang_compile_operation.h155
-rw-r--r--src/mesa/shader/slang/slang_compile_struct.c218
-rw-r--r--src/mesa/shader/slang/slang_compile_variable.c247
-rw-r--r--src/mesa/shader/slang/slang_compile_variable.h36
-rw-r--r--src/mesa/shader/slang/slang_emit.c1591
-rw-r--r--src/mesa/shader/slang/slang_emit.h49
-rw-r--r--src/mesa/shader/slang/slang_execute.c783
-rw-r--r--src/mesa/shader/slang/slang_execute.h105
-rw-r--r--src/mesa/shader/slang/slang_execute_x86.c754
-rw-r--r--src/mesa/shader/slang/slang_export.c386
-rw-r--r--src/mesa/shader/slang/slang_export.h183
-rw-r--r--src/mesa/shader/slang/slang_ir.c389
-rw-r--r--src/mesa/shader/slang/slang_ir.h205
-rw-r--r--src/mesa/shader/slang/slang_label.c77
-rw-r--r--src/mesa/shader/slang/slang_label.h42
-rw-r--r--src/mesa/shader/slang/slang_library_noise.c4
-rw-r--r--src/mesa/shader/slang/slang_library_texsample.c172
-rw-r--r--src/mesa/shader/slang/slang_library_texsample.h44
-rw-r--r--src/mesa/shader/slang/slang_link.c1162
-rw-r--r--src/mesa/shader/slang/slang_link.h334
-rw-r--r--src/mesa/shader/slang/slang_log.c131
-rw-r--r--[-rwxr-xr-x]src/mesa/shader/slang/slang_log.h (renamed from src/mesa/shader/shaderobjects_3dlabs.h)40
-rw-r--r--src/mesa/shader/slang/slang_mesa.cpp144
-rw-r--r--src/mesa/shader/slang/slang_preprocess.h23
-rw-r--r--src/mesa/shader/slang/slang_print.c802
-rw-r--r--src/mesa/shader/slang/slang_print.h29
-rw-r--r--src/mesa/shader/slang/slang_simplify.c449
-rw-r--r--src/mesa/shader/slang/slang_simplify.h22
-rw-r--r--src/mesa/shader/slang/slang_storage.c397
-rw-r--r--src/mesa/shader/slang/slang_storage.h121
-rw-r--r--src/mesa/shader/slang/slang_typeinfo.c912
-rw-r--r--src/mesa/shader/slang/slang_typeinfo.h (renamed from src/mesa/shader/slang/slang_assemble_typeinfo.h)153
-rw-r--r--src/mesa/shader/slang/slang_utility.c15
-rw-r--r--src/mesa/shader/slang/slang_utility.h6
-rw-r--r--src/mesa/shader/slang/slang_vartable.c328
-rw-r--r--src/mesa/shader/slang/slang_vartable.h42
-rw-r--r--src/mesa/shader/slang/traverse_wrap.h112
-rw-r--r--src/mesa/sources68
-rw-r--r--src/mesa/swrast/s_aaline.c51
-rw-r--r--src/mesa/swrast/s_aalinetemp.h125
-rw-r--r--src/mesa/swrast/s_aatriangle.c52
-rw-r--r--src/mesa/swrast/s_aatritemp.h224
-rw-r--r--src/mesa/swrast/s_alpha.c2
-rw-r--r--src/mesa/swrast/s_arbshader.c126
-rw-r--r--src/mesa/swrast/s_atifragshader.c11
-rw-r--r--src/mesa/swrast/s_context.c160
-rw-r--r--src/mesa/swrast/s_context.h213
-rw-r--r--src/mesa/swrast/s_copypix.c2
-rw-r--r--src/mesa/swrast/s_drawpix.c2
-rw-r--r--src/mesa/swrast/s_feedback.c17
-rw-r--r--src/mesa/swrast/s_fog.c58
-rw-r--r--src/mesa/swrast/s_fragprog.c224
-rw-r--r--src/mesa/swrast/s_fragprog.h (renamed from src/mesa/swrast/s_nvfragprog.h)13
-rw-r--r--src/mesa/swrast/s_lines.c7
-rw-r--r--src/mesa/swrast/s_linetemp.h92
-rw-r--r--src/mesa/swrast/s_logic.c2
-rw-r--r--src/mesa/swrast/s_masking.c2
-rw-r--r--src/mesa/swrast/s_nvfragprog.c1665
-rw-r--r--src/mesa/swrast/s_pointtemp.h72
-rw-r--r--src/mesa/swrast/s_readpix.c2
-rw-r--r--src/mesa/swrast/s_span.c770
-rw-r--r--src/mesa/swrast/s_span.h179
-rw-r--r--src/mesa/swrast/s_texcombine.c6
-rw-r--r--src/mesa/swrast/s_triangle.c52
-rw-r--r--src/mesa/swrast/s_tritemp.h434
-rw-r--r--src/mesa/swrast/s_zoom.c19
-rw-r--r--src/mesa/swrast/swrast.h3
-rw-r--r--src/mesa/swrast_setup/ss_context.c29
-rw-r--r--src/mesa/swrast_setup/ss_triangle.c4
-rw-r--r--src/mesa/swrast_setup/ss_tritmp.h3
-rw-r--r--src/mesa/tnl/t_context.c24
-rw-r--r--src/mesa/tnl/t_context.h1
-rw-r--r--src/mesa/tnl/t_pipeline.c5
-rw-r--r--src/mesa/tnl/t_save_api.c1834
-rw-r--r--src/mesa/tnl/t_vb_arbprogram.c145
-rw-r--r--src/mesa/tnl/t_vb_arbprogram.h31
-rw-r--r--src/mesa/tnl/t_vb_arbprogram_sse.c2
-rw-r--r--src/mesa/tnl/t_vb_arbshader.c301
-rw-r--r--src/mesa/tnl/t_vb_cull.c5
-rw-r--r--src/mesa/tnl/t_vb_fog.c5
-rw-r--r--src/mesa/tnl/t_vb_light.c10
-rw-r--r--src/mesa/tnl/t_vb_normals.c7
-rw-r--r--src/mesa/tnl/t_vb_points.c5
-rw-r--r--src/mesa/tnl/t_vb_program.c244
-rw-r--r--src/mesa/tnl/t_vb_texgen.c10
-rw-r--r--src/mesa/tnl/t_vb_texmat.c5
-rw-r--r--src/mesa/tnl/t_vb_vertex.c5
-rw-r--r--src/mesa/tnl/t_vp_build.c96
-rw-r--r--src/mesa/tnl/tnl.h3
-rw-r--r--src/mesa/tnl_dd/t_dd_vb.c48
-rw-r--r--src/mesa/vbo/vbo_context.h4
-rw-r--r--src/mesa/vbo/vbo_exec_api.c1
-rw-r--r--src/mesa/vbo/vbo_save_draw.c1
311 files changed, 31224 insertions, 49338 deletions
diff --git a/Makefile b/Makefile
index 74784888981..c99ed53f218 100644
--- a/Makefile
+++ b/Makefile
@@ -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 \
diff --git a/configs/linux-dri b/configs/linux-dri
index 5f945a73f1a..1a9146e2990 100644
--- a/configs/linux-dri
+++ b/configs/linux-dri
@@ -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
diff --git a/docs/contents.html b/docs/contents.html
index 693145c2e3c..21eca4df871 100644
--- a/docs/contents.html
+++ b/docs/contents.html
@@ -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>
diff --git a/docs/relnotes-6.5.3.html b/docs/relnotes-6.5.3.html
index b3d2fe64556..27053c071b8 100644
--- a/docs/relnotes-6.5.3.html
+++ b/docs/relnotes-6.5.3.html
@@ -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
diff --git a/docs/shading.html b/docs/shading.html
new file mode 100644
index 00000000000..40a6d7ac90b
--- /dev/null
+++ b/docs/shading.html
@@ -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>
diff --git a/progs/demos/Makefile b/progs/demos/Makefile
index 4623d6c8d91..6369746f008 100644
--- a/progs/demos/Makefile
+++ b/progs/demos/Makefile
@@ -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 *~
diff --git a/progs/demos/fslight.c b/progs/demos/fslight.c
index 1c016cc75e9..b03ba2315a4 100644
--- a/progs/demos/fslight.c
+++ b/progs/demos/fslight.c
@@ -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)
@@ -217,16 +220,246 @@ 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;
}
+
diff --git a/progs/glsl/CH06-brick.frag.txt b/progs/glsl/CH06-brick.frag.txt
new file mode 100644
index 00000000000..06ef04e3afb
--- /dev/null
+++ b/progs/glsl/CH06-brick.frag.txt
@@ -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);
+}
diff --git a/progs/glsl/CH06-brick.vert.txt b/progs/glsl/CH06-brick.vert.txt
new file mode 100644
index 00000000000..e95e6f42f0b
--- /dev/null
+++ b/progs/glsl/CH06-brick.vert.txt
@@ -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();
+}
diff --git a/progs/glsl/CH11-bumpmap.frag.txt b/progs/glsl/CH11-bumpmap.frag.txt
new file mode 100644
index 00000000000..063576f5a3c
--- /dev/null
+++ b/progs/glsl/CH11-bumpmap.frag.txt
@@ -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);
+}
diff --git a/progs/glsl/CH11-bumpmap.vert.txt b/progs/glsl/CH11-bumpmap.vert.txt
new file mode 100644
index 00000000000..d3d19f62ac3
--- /dev/null
+++ b/progs/glsl/CH11-bumpmap.vert.txt
@@ -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);
+}
diff --git a/progs/glsl/CH11-toyball.frag.txt b/progs/glsl/CH11-toyball.frag.txt
new file mode 100644
index 00000000000..90ec1c27fc1
--- /dev/null
+++ b/progs/glsl/CH11-toyball.frag.txt
@@ -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;
+}
diff --git a/progs/glsl/CH11-toyball.vert.txt b/progs/glsl/CH11-toyball.vert.txt
new file mode 100644
index 00000000000..b7da3ac839e
--- /dev/null
+++ b/progs/glsl/CH11-toyball.vert.txt
@@ -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();
+}
diff --git a/progs/glsl/CH18-mandel.frag.txt b/progs/glsl/CH18-mandel.frag.txt
new file mode 100644
index 00000000000..a472d812526
--- /dev/null
+++ b/progs/glsl/CH18-mandel.frag.txt
@@ -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);
+}
diff --git a/progs/glsl/CH18-mandel.vert.txt b/progs/glsl/CH18-mandel.vert.txt
new file mode 100644
index 00000000000..c4ca66405d3
--- /dev/null
+++ b/progs/glsl/CH18-mandel.vert.txt
@@ -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();
+
+} \ No newline at end of file
diff --git a/progs/glsl/Makefile b/progs/glsl/Makefile
new file mode 100644
index 00000000000..e08d4102c88
--- /dev/null
+++ b/progs/glsl/Makefile
@@ -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
diff --git a/progs/glsl/brick.c b/progs/glsl/brick.c
new file mode 100644
index 00000000000..522698b5d43
--- /dev/null
+++ b/progs/glsl/brick.c
@@ -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;
+}
+
diff --git a/progs/glsl/bump.c b/progs/glsl/bump.c
new file mode 100644
index 00000000000..a6846acf7e4
--- /dev/null
+++ b/progs/glsl/bump.c
@@ -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;
+}
+
diff --git a/progs/glsl/cubemap.frag.txt b/progs/glsl/cubemap.frag.txt
new file mode 100644
index 00000000000..9c27648aaf9
--- /dev/null
+++ b/progs/glsl/cubemap.frag.txt
@@ -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;
+}
diff --git a/progs/glsl/mandelbrot.c b/progs/glsl/mandelbrot.c
new file mode 100644
index 00000000000..7a2bad6dde3
--- /dev/null
+++ b/progs/glsl/mandelbrot.c
@@ -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;
+}
+
diff --git a/progs/glsl/noise.c b/progs/glsl/noise.c
new file mode 100644
index 00000000000..a26a8059449
--- /dev/null
+++ b/progs/glsl/noise.c
@@ -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;
+}
+
diff --git a/progs/glsl/reflect.vert.txt b/progs/glsl/reflect.vert.txt
new file mode 100644
index 00000000000..402be38bf7b
--- /dev/null
+++ b/progs/glsl/reflect.vert.txt
@@ -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();
+}
diff --git a/progs/glsl/shadowtex.frag.txt b/progs/glsl/shadowtex.frag.txt
new file mode 100644
index 00000000000..a6a80da47f2
--- /dev/null
+++ b/progs/glsl/shadowtex.frag.txt
@@ -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);
+}
diff --git a/progs/glsl/simple.vert.txt b/progs/glsl/simple.vert.txt
new file mode 100644
index 00000000000..a0abe0dc0b2
--- /dev/null
+++ b/progs/glsl/simple.vert.txt
@@ -0,0 +1,9 @@
+// Simple vertex shader
+// Brian Paul
+
+
+void main()
+{
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+ gl_Position = ftransform();
+}
diff --git a/progs/glsl/texdemo1.c b/progs/glsl/texdemo1.c
new file mode 100644
index 00000000000..d29ecf452b1
--- /dev/null
+++ b/progs/glsl/texdemo1.c
@@ -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;
+}
diff --git a/progs/glsl/toyball.c b/progs/glsl/toyball.c
new file mode 100644
index 00000000000..cef52c04a6c
--- /dev/null
+++ b/progs/glsl/toyball.c
@@ -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;
+}
+
diff --git a/progs/tests/Makefile b/progs/tests/Makefile
index 3a22285250c..9edef74fb2c 100644
--- a/progs/tests/Makefile
+++ b/progs/tests/Makefile
@@ -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 .
diff --git a/progs/tests/drawbuffers.c b/progs/tests/drawbuffers.c
new file mode 100644
index 00000000000..8583bac0ddf
--- /dev/null
+++ b/progs/tests/drawbuffers.c
@@ -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;
+}
diff --git a/progs/util/extfuncs.h b/progs/util/extfuncs.h
new file mode 100644
index 00000000000..f5ea5feaa84
--- /dev/null
+++ b/progs/util/extfuncs.h
@@ -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");
+
+}
+
diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c
index 1e44904b930..f543de183a1 100644
--- a/src/mesa/drivers/common/driverfuncs.c
+++ b/src/mesa/drivers/common/driverfuncs.c
@@ -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;
}
diff --git a/src/mesa/drivers/common/driverfuncs.h b/src/mesa/drivers/common/driverfuncs.h
index 64f56d91f95..50f2b4271dc 100644
--- a/src/mesa/drivers/common/driverfuncs.h
+++ b/src/mesa/drivers/common/driverfuncs.h
@@ -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
diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c
index 6ec34e5bdef..4ab9d2686cb 100644
--- a/src/mesa/drivers/dri/i915/i915_context.c
+++ b/src/mesa/drivers/dri/i915/i915_context.c
@@ -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 );
diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c
index ef14f3eef7c..a28c8bb6fc2 100644
--- a/src/mesa/drivers/dri/i915/i915_fragprog.c
+++ b/src/mesa/drivers/dri/i915/i915_fragprog.c
@@ -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;
diff --git a/src/mesa/drivers/dri/i915/i915_program.c b/src/mesa/drivers/dri/i915/i915_program.c
index 9c13290d118..68491124449 100644
--- a/src/mesa/drivers/dri/i915/i915_program.c
+++ b/src/mesa/drivers/dri/i915/i915_program.c
@@ -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;
diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c
index 5e00e6597b0..d126208ce05 100644
--- a/src/mesa/drivers/dri/i915/i915_state.c
+++ b/src/mesa/drivers/dri/i915/i915_state.c
@@ -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;
diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c
index b533e153beb..c920fc47ea0 100644
--- a/src/mesa/drivers/dri/i915/i915_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i915_vtbl.c
@@ -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 );
}
}
diff --git a/src/mesa/drivers/dri/i915tex/i915_context.c b/src/mesa/drivers/dri/i915tex/i915_context.c
index 9b4d72eab3e..d4187238f3c 100644
--- a/src/mesa/drivers/dri/i915tex/i915_context.c
+++ b/src/mesa/drivers/dri/i915tex/i915_context.c
@@ -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);
diff --git a/src/mesa/drivers/dri/i915tex/i915_fragprog.c b/src/mesa/drivers/dri/i915tex/i915_fragprog.c
index 8772e702307..cbea6092a81 100644
--- a/src/mesa/drivers/dri/i915tex/i915_fragprog.c
+++ b/src/mesa/drivers/dri/i915tex/i915_fragprog.c
@@ -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)
{
diff --git a/src/mesa/drivers/dri/i915tex/i915_program.c b/src/mesa/drivers/dri/i915tex/i915_program.c
index 0be89d33206..ed45e4f8069 100644
--- a/src/mesa/drivers/dri/i915tex/i915_program.c
+++ b/src/mesa/drivers/dri/i915tex/i915_program.c
@@ -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;
diff --git a/src/mesa/drivers/dri/i915tex/i915_state.c b/src/mesa/drivers/dri/i915tex/i915_state.c
index 1fafadced02..c2c2ff366f1 100644
--- a/src/mesa/drivers/dri/i915tex/i915_state.c
+++ b/src/mesa/drivers/dri/i915tex/i915_state.c
@@ -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;
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 6faee65542b..397a9bd3f5c 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -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 );
diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c
index 4352c3bcb0f..3f0aaa1f86d 100644
--- a/src/mesa/drivers/dri/i965/brw_curbe.c
+++ b/src/mesa/drivers/dri/i965/brw_curbe.c
@@ -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"
diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
index d4dbcf38a7a..52f89d577ca 100644
--- a/src/mesa/drivers/dri/i965/brw_eu.h
+++ b/src/mesa/drivers/dri/i965/brw_eu.h
@@ -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)
diff --git a/src/mesa/drivers/dri/i965/brw_metaops.c b/src/mesa/drivers/dri/i965/brw_metaops.c
index 1579762b6d1..6e030f191ef 100644
--- a/src/mesa/drivers/dri/i965/brw_metaops.c
+++ b/src/mesa/drivers/dri/i965/brw_metaops.c
@@ -35,8 +35,6 @@
#include "glheader.h"
#include "context.h"
#include "macros.h"
-#include "enums.h"
-#include "dd.h"
#include "shader/arbprogparse.h"
diff --git a/src/mesa/drivers/dri/i965/brw_util.c b/src/mesa/drivers/dri/i965/brw_util.c
index 9d12c26486d..b6deee23769 100644
--- a/src/mesa/drivers/dri/i965/brw_util.c
+++ b/src/mesa/drivers/dri/i965/brw_util.c
@@ -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;
diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c
index 74c9d88e464..e173f6fce3e 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.c
+++ b/src/mesa/drivers/dri/i965/brw_vs.c
@@ -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"
diff --git a/src/mesa/drivers/dri/i965/brw_vs_constval.c b/src/mesa/drivers/dri/i965/brw_vs_constval.c
index 528e164db8c..caef042f1cd 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_constval.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_constval.c
@@ -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
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index ffdb843e85f..6eb11b19ad2 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -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"
diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c
index dd1664bf33a..35adc4846a0 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c
@@ -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 );
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 0f842d289d7..1497dc79687 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -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 )
{
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index ec6ad6105ca..f5fddfdb68a 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -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
diff --git a/src/mesa/drivers/dri/i965/brw_wm_debug.c b/src/mesa/drivers/dri/i965/brw_wm_debug.c
index 9a6154b3336..f31d0974ecf 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_debug.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_debug.c
@@ -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,
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index d96a9b717c0..fd605159727 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -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)
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index ba2dbeccde2..ff97d87dc45 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c
@@ -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 */
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass0.c b/src/mesa/drivers/dri/i965/brw_wm_pass0.c
index 36b69b70681..00f6f6b9a4f 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass0.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass0.c
@@ -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"
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass1.c b/src/mesa/drivers/dri/i965/brw_wm_pass1.c
index 21d0881d57e..d668def7007 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass1.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass1.c
@@ -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,
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass2.c b/src/mesa/drivers/dri/i965/brw_wm_pass2.c
index cb8d51fb5cf..a1edbd6168d 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass2.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass2.c
@@ -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
diff --git a/src/mesa/drivers/dri/mach64/mach64_native_vb.c b/src/mesa/drivers/dri/mach64/mach64_native_vb.c
index 7872c206f58..519ec81e548 100644
--- a/src/mesa/drivers/dri/mach64/mach64_native_vb.c
+++ b/src/mesa/drivers/dri/mach64/mach64_native_vb.c
@@ -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:
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c
index f217c4404e9..8e11eb61342 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_context.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c
@@ -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 );
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c
index 3d5b6843a15..b6837c5de14 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_shader.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c
@@ -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"
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
index 7c2e2b9443b..8c203cc664b 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
@@ -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);
}
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c
index 130ef35e57b..cd27daca88b 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c
@@ -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"
diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c
index 4960d481d5d..6089d617c6b 100644
--- a/src/mesa/drivers/dri/r200/r200_vertprog.c
+++ b/src/mesa/drivers/dri/r200/r200_vertprog.c
@@ -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);
}
diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
index 68c8f5b87d0..1f8d95078fb 100644
--- a/src/mesa/drivers/dri/r300/r300_context.c
+++ b/src/mesa/drivers/dri/r300/r300_context.c
@@ -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);
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c
index e01f56d99df..77f95605e4d 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog.c
+++ b/src/mesa/drivers/dri/r300/r300_fragprog.c
@@ -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"
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.h b/src/mesa/drivers/dri/r300/r300_fragprog.h
index 73986abc3cc..d883aee2d72 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog.h
+++ b/src/mesa/drivers/dri/r300/r300_fragprog.h
@@ -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 */
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index 17658efdb2f..ff3c51c5edf 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -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);
diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c
index 092ebb1140e..aa2f20127ba 100644
--- a/src/mesa/drivers/dri/r300/r300_vertprog.c
+++ b/src/mesa/drivers/dri/r300/r300_vertprog.c
@@ -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;
diff --git a/src/mesa/drivers/dri/s3v/s3v_tritmp.h b/src/mesa/drivers/dri/s3v/s3v_tritmp.h
index 16318f4c402..696fc02250f 100644
--- a/src/mesa/drivers/dri/s3v/s3v_tritmp.h
+++ b/src/mesa/drivers/dri/s3v/s3v_tritmp.h
@@ -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]); \
-\
- 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]); \
+ 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]].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; \
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_tris.c b/src/mesa/drivers/dri/tdfx/tdfx_tris.c
index ac8daf47497..4ba2f40b9e8 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_tris.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_tris.c
@@ -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;
}
}
}
diff --git a/src/mesa/drivers/dri/trident/trident_context.h b/src/mesa/drivers/dri/trident/trident_context.h
index b1e68b01663..1d3ca84400d 100644
--- a/src/mesa/drivers/dri/trident/trident_context.h
+++ b/src/mesa/drivers/dri/trident/trident_context.h
@@ -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];
diff --git a/src/mesa/drivers/glslcompiler/Makefile b/src/mesa/drivers/glslcompiler/Makefile
new file mode 100644
index 00000000000..858457ddd40
--- /dev/null
+++ b/src/mesa/drivers/glslcompiler/Makefile
@@ -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)
diff --git a/src/mesa/drivers/glslcompiler/glslcompiler.c b/src/mesa/drivers/glslcompiler/glslcompiler.c
new file mode 100644
index 00000000000..016b53d57aa
--- /dev/null
+++ b/src/mesa/drivers/glslcompiler/glslcompiler.c
@@ -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;
+}
diff --git a/src/mesa/main/colortab.c b/src/mesa/main/colortab.c
index d8c4136f49e..610acba3068 100644
--- a/src/mesa/main/colortab.c
+++ b/src/mesa/main/colortab.c
@@ -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:
{
diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h
index 13c6281f077..8ea2d2c615a 100644
--- a/src/mesa/main/config.h
+++ b/src/mesa/main/config.h
@@ -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
/*@}*/
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 135c814c0a6..72c85de7ba2 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -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);
}
}
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 1de2542bee2..88f33943b31 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -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
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index 4eda3491341..eb81ee4a528 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -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);
}
diff --git a/src/mesa/main/get_gen.py b/src/mesa/main/get_gen.py
index 0b6cd3e5c58..33be7689997 100644
--- a/src/mesa/main/get_gen.py
+++ b/src/mesa/main/get_gen.py
@@ -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"] )
]
diff --git a/src/mesa/main/getstring.c b/src/mesa/main/getstring.c
index 0c925ed761b..973649da0dd 100644
--- a/src/mesa/main/getstring.c
+++ b/src/mesa/main/getstring.c
@@ -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;
diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c
index 890d1a4e32e..e2d44fa07c4 100644
--- a/src/mesa/main/imports.c
+++ b/src/mesa/main/imports.c
@@ -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() */
diff --git a/src/mesa/main/matrix.c b/src/mesa/main/matrix.c
index b2aa83e1890..0f96f949096 100644
--- a/src/mesa/main/matrix.c
+++ b/src/mesa/main/matrix.c
@@ -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++) {
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index df77c6cbf90..828b0f2384e 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -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"),
@@ -45,6 +45,12 @@
/**
+ * Special, internal token
+ */
+#define GL_SHADER_PROGRAM 0x9999
+
+
+/**
* Color channel data type.
*/
#if CHAN_BITS == 8
@@ -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
diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c
index b9e23d80b62..eb4fd6e7c94 100644
--- a/src/mesa/main/pixel.c
+++ b/src/mesa/main/pixel.c
@@ -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)" );
diff --git a/src/mesa/main/shaders.c b/src/mesa/main/shaders.c
new file mode 100644
index 00000000000..58be1f46e57
--- /dev/null
+++ b/src/mesa/main/shaders.c
@@ -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);
+}
+
diff --git a/src/mesa/shader/shaderobjects.h b/src/mesa/main/shaders.h
index 09ba807255e..17339ccf623 100644
--- a/src/mesa/shader/shaderobjects.h
+++ b/src/mesa/main/shaders.h
@@ -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 */
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index f4f73a5089f..6ed7ae6c7dd 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -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);
}
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index d1994f76d1b..0c6fa82f112 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -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));
+
+ 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);
- 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);
+ 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);
}
}
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
index bcedcafe19e..bed2c1220a0 100644
--- a/src/mesa/main/texstate.c
+++ b/src/mesa/main/texstate.c
@@ -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 );
diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c
index c6ea5c4f973..5027264f031 100644
--- a/src/mesa/shader/arbprogparse.c
+++ b/src/mesa/shader/arbprogparse.c
@@ -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);
@@ -3329,198 +3338,18 @@ 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)
{
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;
diff --git a/src/mesa/shader/arbprogram.c b/src/mesa/shader/arbprogram.c
index 91f3a5e8ee7..5583f16ce8d 100644
--- a/src/mesa/shader/arbprogram.c
+++ b/src/mesa/shader/arbprogram.c
@@ -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;
diff --git a/src/mesa/shader/asmopcodes.reg b/src/mesa/shader/asmopcodes.reg
deleted file mode 100644
index efd8918f21f..00000000000
--- a/src/mesa/shader/asmopcodes.reg
+++ /dev/null
@@ -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
-
diff --git a/src/mesa/shader/grammar/grammar.c b/src/mesa/shader/grammar/grammar.c
index 7f2ee42d21d..989e9544911 100644
--- a/src/mesa/shader/grammar/grammar.c
+++ b/src/mesa/shader/grammar/grammar.c
@@ -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;
}
diff --git a/src/mesa/shader/grammar/grammar_crt.c b/src/mesa/shader/grammar/grammar_crt.c
index bdf2da9b2e2..bdf2da9b2e2 100755..100644
--- a/src/mesa/shader/grammar/grammar_crt.c
+++ b/src/mesa/shader/grammar/grammar_crt.c
diff --git a/src/mesa/shader/grammar/grammar_crt.h b/src/mesa/shader/grammar/grammar_crt.h
index 492711e96ae..492711e96ae 100755..100644
--- a/src/mesa/shader/grammar/grammar_crt.h
+++ b/src/mesa/shader/grammar/grammar_crt.h
diff --git a/src/mesa/shader/nvfragparse.c b/src/mesa/shader/nvfragparse.c
index 79e6dbd87b7..ffa7ba4701b 100644
--- a/src/mesa/shader/nvfragparse.c
+++ b/src/mesa/shader/nvfragparse.c
@@ -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;
diff --git a/src/mesa/shader/nvprogram.c b/src/mesa/shader/nvprogram.c
index 4f160b14312..337784bfe25 100644
--- a/src/mesa/shader/nvprogram.c
+++ b/src/mesa/shader/nvprogram.c
@@ -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");
}
diff --git a/src/mesa/shader/nvvertexec.c b/src/mesa/shader/nvvertexec.c
deleted file mode 100644
index 10962d7e14a..00000000000
--- a/src/mesa/shader/nvvertexec.c
+++ /dev/null
@@ -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);
-}
diff --git a/src/mesa/shader/nvvertparse.c b/src/mesa/shader/nvvertparse.c
index 6d395c6011e..ac96d4a60ed 100644
--- a/src/mesa/shader/nvvertparse.c
+++ b/src/mesa/shader/nvvertparse.c
@@ -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;
diff --git a/src/mesa/shader/prog_debug.c b/src/mesa/shader/prog_debug.c
new file mode 100644
index 00000000000..57929fcbcae
--- /dev/null
+++ b/src/mesa/shader/prog_debug.c
@@ -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;
+ }
+}
diff --git a/src/mesa/swrast/s_arbshader.h b/src/mesa/shader/prog_debug.h
index 5df80c870b0..fc400e19de1 100644
--- a/src/mesa/swrast/s_arbshader.h
+++ b/src/mesa/shader/prog_debug.h
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 6.5.3
*
- * Copyright (C) 2006 David Airlie 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"),
@@ -17,22 +17,28 @@
* 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
- * DAVID AIRLIE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * 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.
*/
-#ifndef S_ARBSHADER_H
-#define S_ARBSHADER_H
+#ifndef PROG_DEBUG_H
+#define PROG_DEBUG_H 1
-#include "s_context.h"
-#if FEATURE_ARB_fragment_shader
+/*
+ * GL_MESA_program_debug
+ */
+
+extern void
+_mesa_ProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback,
+ GLvoid *data);
-extern void _swrast_exec_arbshader (GLcontext *ctx, SWspan *span);
+extern void
+_mesa_GetProgramRegisterfvMESA(GLenum target, GLsizei len,
+ const GLubyte *registerName, GLfloat *v);
-#endif /* FEATURE_ARB_fragment_shader */
-#endif
+#endif /* PROG_DEBUG_H */
diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c
new file mode 100644
index 00000000000..f881d477caa
--- /dev/null
+++ b/src/mesa/shader/prog_execute.c
@@ -0,0 +1,1748 @@
+/*
+ * 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.
+ */
+
+/**
+ * \file prog_execute.c
+ * Software interpreter for vertex/fragment programs.
+ * \author Brian Paul
+ */
+
+/*
+ * NOTE: we do everything in single-precision floating point; we don't
+ * currently observe the single/half/fixed-precision qualifiers.
+ *
+ */
+
+
+#include "glheader.h"
+#include "colormac.h"
+#include "context.h"
+#include "program.h"
+#include "prog_execute.h"
+#include "prog_instruction.h"
+#include "prog_parameter.h"
+#include "prog_print.h"
+#include "slang_library_noise.h"
+
+
+/* See comments below for info about this */
+#define LAMBDA_ZERO 1
+
+/* debug predicate */
+#define DEBUG_PROG 0
+
+
+/**
+ * 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
+
+
+static const GLfloat ZeroVec[4] = { 0.0F, 0.0F, 0.0F, 0.0F };
+
+
+
+/**
+ * Return a pointer to the 4-element float vector specified by the given
+ * source register.
+ */
+static INLINE const GLfloat *
+get_register_pointer(const struct prog_src_register *source,
+ const struct gl_program_machine *machine)
+{
+ if (source->RelAddr) {
+ const GLint reg = source->Index + machine->AddressReg[0][0];
+ if (source->File == PROGRAM_ENV_PARAM)
+ if (reg < 0 || reg >= MAX_PROGRAM_ENV_PARAMS)
+ return ZeroVec;
+ else
+ return machine->EnvParams[reg];
+ else {
+ const struct gl_program_parameter_list *params;
+ ASSERT(source->File == PROGRAM_LOCAL_PARAM ||
+ source->File == PROGRAM_STATE_VAR);
+ params = machine->CurProgram->Parameters;
+ if (reg < 0 || reg >= params->NumParameters)
+ return ZeroVec;
+ else
+ return params->ParameterValues[reg];
+ }
+ }
+
+ switch (source->File) {
+ case PROGRAM_TEMPORARY:
+ ASSERT(source->Index < MAX_PROGRAM_TEMPS);
+ return machine->Temporaries[source->Index];
+
+ case PROGRAM_INPUT:
+ if (machine->CurProgram->Target == GL_VERTEX_PROGRAM_ARB) {
+ ASSERT(source->Index < VERT_ATTRIB_MAX);
+ return machine->VertAttribs[source->Index];
+ }
+ else {
+ ASSERT(source->Index < FRAG_ATTRIB_MAX);
+ return machine->Attribs[source->Index][machine->CurElement];
+ }
+
+ case PROGRAM_OUTPUT:
+ ASSERT(source->Index < MAX_PROGRAM_OUTPUTS);
+ return machine->Outputs[source->Index];
+
+ case PROGRAM_LOCAL_PARAM:
+ ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS);
+ return machine->CurProgram->LocalParams[source->Index];
+
+ case PROGRAM_ENV_PARAM:
+ ASSERT(source->Index < MAX_PROGRAM_ENV_PARAMS);
+ return machine->EnvParams[source->Index];
+
+ case PROGRAM_STATE_VAR:
+ /* Fallthrough */
+ case PROGRAM_CONSTANT:
+ /* Fallthrough */
+ case PROGRAM_UNIFORM:
+ /* Fallthrough */
+ case PROGRAM_NAMED_PARAM:
+ ASSERT(source->Index <
+ (GLint) machine->CurProgram->Parameters->NumParameters);
+ return machine->CurProgram->Parameters->ParameterValues[source->Index];
+
+ default:
+ _mesa_problem(NULL,
+ "Invalid input register file %d in get_register_pointer()",
+ source->File);
+ return NULL;
+ }
+}
+
+
+#if FEATURE_MESA_program_debug
+static struct gl_program_machine *CurrentMachine = NULL;
+
+/**
+ * For GL_MESA_program_debug.
+ * Return current value (4*GLfloat) of a program register.
+ * Called via ctx->Driver.GetProgramRegister().
+ */
+void
+_mesa_get_program_register(GLcontext *ctx, enum register_file file,
+ GLuint index, GLfloat val[4])
+{
+ if (CurrentMachine) {
+ struct prog_src_register src;
+ const GLfloat *reg;
+ src.File = file;
+ src.Index = index;
+ reg = get_register_pointer(&src, CurrentMachine);
+ COPY_4V(val, reg);
+ }
+}
+#endif /* FEATURE_MESA_program_debug */
+
+
+/**
+ * Fetch a 4-element float vector from the given source register.
+ * Apply swizzling and negating as needed.
+ */
+static void
+fetch_vector4(const struct prog_src_register *source,
+ const struct gl_program_machine *machine, GLfloat result[4])
+{
+ const GLfloat *src = get_register_pointer(source, machine);
+ ASSERT(src);
+
+ if (source->Swizzle == SWIZZLE_NOOP) {
+ /* no swizzling */
+ COPY_4V(result, src);
+ }
+ else {
+ ASSERT(GET_SWZ(source->Swizzle, 0) <= 3);
+ ASSERT(GET_SWZ(source->Swizzle, 1) <= 3);
+ ASSERT(GET_SWZ(source->Swizzle, 2) <= 3);
+ ASSERT(GET_SWZ(source->Swizzle, 3) <= 3);
+ 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];
+ }
+ if (source->Abs) {
+ result[0] = FABSF(result[0]);
+ result[1] = FABSF(result[1]);
+ result[2] = FABSF(result[2]);
+ result[3] = FABSF(result[3]);
+ }
+ if (source->NegateAbs) {
+ result[0] = -result[0];
+ result[1] = -result[1];
+ result[2] = -result[2];
+ result[3] = -result[3];
+ }
+}
+
+#if 0
+/**
+ * Fetch the derivative with respect to X for the given register.
+ * \return GL_TRUE if it was easily computed or GL_FALSE if we
+ * need to execute another instance of the program (ugh)!
+ */
+static GLboolean
+fetch_vector4_deriv(GLcontext * ctx,
+ const struct prog_src_register *source,
+ const SWspan * span,
+ char xOrY, GLint column, GLfloat result[4])
+{
+ GLfloat src[4];
+
+ ASSERT(xOrY == 'X' || xOrY == 'Y');
+
+ switch (source->Index) {
+ case FRAG_ATTRIB_WPOS:
+ if (xOrY == 'X') {
+ src[0] = 1.0;
+ src[1] = 0.0;
+ src[2] = span->attrStepX[FRAG_ATTRIB_WPOS][2]
+ / ctx->DrawBuffer->_DepthMaxF;
+ src[3] = span->attrStepX[FRAG_ATTRIB_WPOS][3];
+ }
+ else {
+ src[0] = 0.0;
+ src[1] = 1.0;
+ src[2] = span->attrStepY[FRAG_ATTRIB_WPOS][2]
+ / ctx->DrawBuffer->_DepthMaxF;
+ src[3] = span->attrStepY[FRAG_ATTRIB_WPOS][3];
+ }
+ break;
+ case FRAG_ATTRIB_COL0:
+ case FRAG_ATTRIB_COL1:
+ if (xOrY == 'X') {
+ src[0] = span->attrStepX[source->Index][0] * (1.0F / CHAN_MAXF);
+ src[1] = span->attrStepX[source->Index][1] * (1.0F / CHAN_MAXF);
+ src[2] = span->attrStepX[source->Index][2] * (1.0F / CHAN_MAXF);
+ src[3] = span->attrStepX[source->Index][3] * (1.0F / CHAN_MAXF);
+ }
+ else {
+ src[0] = span->attrStepY[source->Index][0] * (1.0F / CHAN_MAXF);
+ src[1] = span->attrStepY[source->Index][1] * (1.0F / CHAN_MAXF);
+ src[2] = span->attrStepY[source->Index][2] * (1.0F / CHAN_MAXF);
+ src[3] = span->attrStepY[source->Index][3] * (1.0F / CHAN_MAXF);
+ }
+ break;
+ case FRAG_ATTRIB_FOGC:
+ if (xOrY == 'X') {
+ src[0] = span->attrStepX[FRAG_ATTRIB_FOGC][0] * (1.0F / CHAN_MAXF);
+ src[1] = 0.0;
+ src[2] = 0.0;
+ src[3] = 0.0;
+ }
+ else {
+ src[0] = span->attrStepY[FRAG_ATTRIB_FOGC][0] * (1.0F / CHAN_MAXF);
+ src[1] = 0.0;
+ src[2] = 0.0;
+ src[3] = 0.0;
+ }
+ break;
+ default:
+ assert(source->Index < FRAG_ATTRIB_MAX);
+ /* texcoord or varying */
+ if (xOrY == 'X') {
+ /* this is a little tricky - I think I've got it right */
+ const GLfloat invQ = 1.0f / (span->attrStart[source->Index][3]
+ +
+ span->attrStepX[source->Index][3] *
+ column);
+ src[0] = span->attrStepX[source->Index][0] * invQ;
+ src[1] = span->attrStepX[source->Index][1] * invQ;
+ src[2] = span->attrStepX[source->Index][2] * invQ;
+ src[3] = span->attrStepX[source->Index][3] * invQ;
+ }
+ else {
+ /* Tricky, as above, but in Y direction */
+ const GLfloat invQ = 1.0f / (span->attrStart[source->Index][3]
+ + span->attrStepY[source->Index][3]);
+ src[0] = span->attrStepY[source->Index][0] * invQ;
+ src[1] = span->attrStepY[source->Index][1] * invQ;
+ src[2] = span->attrStepY[source->Index][2] * invQ;
+ src[3] = span->attrStepY[source->Index][3] * invQ;
+ }
+ break;
+ }
+
+ 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];
+ }
+ if (source->Abs) {
+ result[0] = FABSF(result[0]);
+ result[1] = FABSF(result[1]);
+ result[2] = FABSF(result[2]);
+ result[3] = FABSF(result[3]);
+ }
+ if (source->NegateAbs) {
+ result[0] = -result[0];
+ result[1] = -result[1];
+ result[2] = -result[2];
+ result[3] = -result[3];
+ }
+ return GL_TRUE;
+}
+#endif
+
+
+/**
+ * As above, but only return result[0] element.
+ */
+static void
+fetch_vector1(const struct prog_src_register *source,
+ const struct gl_program_machine *machine, GLfloat result[4])
+{
+ const GLfloat *src = get_register_pointer(source, machine);
+ ASSERT(src);
+
+ result[0] = src[GET_SWZ(source->Swizzle, 0)];
+
+ if (source->NegateBase) {
+ result[0] = -result[0];
+ }
+ if (source->Abs) {
+ result[0] = FABSF(result[0]);
+ }
+ if (source->NegateAbs) {
+ result[0] = -result[0];
+ }
+}
+
+
+/**
+ * Test value against zero and return GT, LT, EQ or UN if NaN.
+ */
+static INLINE GLuint
+generate_cc(float value)
+{
+ if (value != value)
+ return COND_UN; /* NaN */
+ if (value > 0.0F)
+ return COND_GT;
+ if (value < 0.0F)
+ return COND_LT;
+ return COND_EQ;
+}
+
+
+/**
+ * Test if the ccMaskRule is satisfied by the given condition code.
+ * Used to mask destination writes according to the current condition code.
+ */
+static INLINE GLboolean
+test_cc(GLuint condCode, GLuint ccMaskRule)
+{
+ switch (ccMaskRule) {
+ case COND_EQ: return (condCode == COND_EQ);
+ case COND_NE: return (condCode != COND_EQ);
+ case COND_LT: return (condCode == COND_LT);
+ case COND_GE: return (condCode == COND_GT || condCode == COND_EQ);
+ case COND_LE: return (condCode == COND_LT || condCode == COND_EQ);
+ case COND_GT: return (condCode == COND_GT);
+ case COND_TR: return GL_TRUE;
+ case COND_FL: return GL_FALSE;
+ default: return GL_TRUE;
+ }
+}
+
+
+/**
+ * Evaluate the 4 condition codes against a predicate and return GL_TRUE
+ * or GL_FALSE to indicate result.
+ */
+static INLINE GLboolean
+eval_condition(const struct gl_program_machine *machine,
+ const struct prog_instruction *inst)
+{
+ const GLuint swizzle = inst->DstReg.CondSwizzle;
+ const GLuint condMask = inst->DstReg.CondMask;
+ if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
+ test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
+ test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
+ test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
+ return GL_TRUE;
+ }
+ else {
+ return GL_FALSE;
+ }
+}
+
+
+
+/**
+ * Store 4 floats into a register. Observe the instructions saturate and
+ * set-condition-code flags.
+ */
+static void
+store_vector4(const struct prog_instruction *inst,
+ struct gl_program_machine *machine, const GLfloat value[4])
+{
+ const struct prog_dst_register *dest = &(inst->DstReg);
+ const GLboolean clamp = inst->SaturateMode == SATURATE_ZERO_ONE;
+ GLfloat *dstReg;
+ GLfloat dummyReg[4];
+ GLfloat clampedValue[4];
+ GLuint writeMask = dest->WriteMask;
+
+ switch (dest->File) {
+ case PROGRAM_OUTPUT:
+ ASSERT(dest->Index < MAX_PROGRAM_OUTPUTS);
+ dstReg = machine->Outputs[dest->Index];
+ break;
+ case PROGRAM_TEMPORARY:
+ ASSERT(dest->Index < MAX_PROGRAM_TEMPS);
+ dstReg = machine->Temporaries[dest->Index];
+ break;
+ case PROGRAM_WRITE_ONLY:
+ dstReg = dummyReg;
+ return;
+ default:
+ _mesa_problem(NULL, "bad register file in store_vector4(fp)");
+ return;
+ }
+
+#if 0
+ if (value[0] > 1.0e10 ||
+ IS_INF_OR_NAN(value[0]) ||
+ IS_INF_OR_NAN(value[1]) ||
+ IS_INF_OR_NAN(value[2]) || IS_INF_OR_NAN(value[3]))
+ printf("store %g %g %g %g\n", value[0], value[1], value[2], value[3]);
+#endif
+
+ if (clamp) {
+ clampedValue[0] = CLAMP(value[0], 0.0F, 1.0F);
+ clampedValue[1] = CLAMP(value[1], 0.0F, 1.0F);
+ clampedValue[2] = CLAMP(value[2], 0.0F, 1.0F);
+ clampedValue[3] = CLAMP(value[3], 0.0F, 1.0F);
+ value = clampedValue;
+ }
+
+ if (dest->CondMask != COND_TR) {
+ /* condition codes may turn off some writes */
+ if (writeMask & WRITEMASK_X) {
+ if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 0)],
+ dest->CondMask))
+ writeMask &= ~WRITEMASK_X;
+ }
+ if (writeMask & WRITEMASK_Y) {
+ if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 1)],
+ dest->CondMask))
+ writeMask &= ~WRITEMASK_Y;
+ }
+ if (writeMask & WRITEMASK_Z) {
+ if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 2)],
+ dest->CondMask))
+ writeMask &= ~WRITEMASK_Z;
+ }
+ if (writeMask & WRITEMASK_W) {
+ if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 3)],
+ dest->CondMask))
+ writeMask &= ~WRITEMASK_W;
+ }
+ }
+
+ if (writeMask & WRITEMASK_X)
+ dstReg[0] = value[0];
+ if (writeMask & WRITEMASK_Y)
+ dstReg[1] = value[1];
+ if (writeMask & WRITEMASK_Z)
+ dstReg[2] = value[2];
+ if (writeMask & WRITEMASK_W)
+ dstReg[3] = value[3];
+
+ if (inst->CondUpdate) {
+ if (writeMask & WRITEMASK_X)
+ machine->CondCodes[0] = generate_cc(value[0]);
+ if (writeMask & WRITEMASK_Y)
+ machine->CondCodes[1] = generate_cc(value[1]);
+ if (writeMask & WRITEMASK_Z)
+ machine->CondCodes[2] = generate_cc(value[2]);
+ if (writeMask & WRITEMASK_W)
+ machine->CondCodes[3] = generate_cc(value[3]);
+ }
+}
+
+
+#if 0
+/**
+ * Initialize a new machine state instance from an existing one, adding
+ * the partial derivatives onto the input registers.
+ * Used to implement DDX and DDY instructions in non-trivial cases.
+ */
+static void
+init_machine_deriv(GLcontext * ctx,
+ const struct gl_program_machine *machine,
+ const struct gl_fragment_program *program,
+ const SWspan * span, char xOrY,
+ struct gl_program_machine *dMachine)
+{
+ GLuint attr;
+
+ ASSERT(xOrY == 'X' || xOrY == 'Y');
+
+ /* copy existing machine */
+ _mesa_memcpy(dMachine, machine, sizeof(struct gl_program_machine));
+
+ if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) {
+ /* XXX also need to do this when using valgrind */
+ /* Clear temporary registers (undefined for ARB_f_p) */
+ _mesa_bzero((void *) machine->Temporaries,
+ MAX_PROGRAM_TEMPS * 4 * sizeof(GLfloat));
+ }
+
+ /* Add derivatives */
+ if (program->Base.InputsRead & FRAG_BIT_WPOS) {
+ GLfloat *wpos = machine->Attribs[FRAG_ATTRIB_WPOS][machine->CurElement];
+ if (xOrY == 'X') {
+ wpos[0] += 1.0F;
+ wpos[1] += 0.0F;
+ wpos[2] += span->attrStepX[FRAG_ATTRIB_WPOS][2];
+ wpos[3] += span->attrStepX[FRAG_ATTRIB_WPOS][3];
+ }
+ else {
+ wpos[0] += 0.0F;
+ wpos[1] += 1.0F;
+ wpos[2] += span->attrStepY[FRAG_ATTRIB_WPOS][2];
+ wpos[3] += span->attrStepY[FRAG_ATTRIB_WPOS][3];
+ }
+ }
+
+ /* primary, secondary colors */
+ for (attr = FRAG_ATTRIB_COL0; attr <= FRAG_ATTRIB_COL1; attr++) {
+ if (program->Base.InputsRead & (1 << attr)) {
+ GLfloat *col = machine->Attribs[attr][machine->CurElement];
+ if (xOrY == 'X') {
+ col[0] += span->attrStepX[attr][0] * (1.0F / CHAN_MAXF);
+ col[1] += span->attrStepX[attr][1] * (1.0F / CHAN_MAXF);
+ col[2] += span->attrStepX[attr][2] * (1.0F / CHAN_MAXF);
+ col[3] += span->attrStepX[attr][3] * (1.0F / CHAN_MAXF);
+ }
+ else {
+ col[0] += span->attrStepY[attr][0] * (1.0F / CHAN_MAXF);
+ col[1] += span->attrStepY[attr][1] * (1.0F / CHAN_MAXF);
+ col[2] += span->attrStepY[attr][2] * (1.0F / CHAN_MAXF);
+ col[3] += span->attrStepY[attr][3] * (1.0F / CHAN_MAXF);
+ }
+ }
+ }
+ if (program->Base.InputsRead & FRAG_BIT_FOGC) {
+ GLfloat *fogc = machine->Attribs[FRAG_ATTRIB_FOGC][machine->CurElement];
+ if (xOrY == 'X') {
+ fogc[0] += span->attrStepX[FRAG_ATTRIB_FOGC][0];
+ }
+ else {
+ fogc[0] += span->attrStepY[FRAG_ATTRIB_FOGC][0];
+ }
+ }
+ /* texcoord and varying vars */
+ for (attr = FRAG_ATTRIB_TEX0; attr < FRAG_ATTRIB_MAX; attr++) {
+ if (program->Base.InputsRead & (1 << attr)) {
+ GLfloat *val = machine->Attribs[attr][machine->CurElement];
+ /* XXX perspective-correct interpolation */
+ if (xOrY == 'X') {
+ val[0] += span->attrStepX[attr][0];
+ val[1] += span->attrStepX[attr][1];
+ val[2] += span->attrStepX[attr][2];
+ val[3] += span->attrStepX[attr][3];
+ }
+ else {
+ val[0] += span->attrStepY[attr][0];
+ val[1] += span->attrStepY[attr][1];
+ val[2] += span->attrStepY[attr][2];
+ val[3] += span->attrStepY[attr][3];
+ }
+ }
+ }
+
+ /* init condition codes */
+ dMachine->CondCodes[0] = COND_EQ;
+ dMachine->CondCodes[1] = COND_EQ;
+ dMachine->CondCodes[2] = COND_EQ;
+ dMachine->CondCodes[3] = COND_EQ;
+}
+#endif
+
+
+/**
+ * Execute the given vertex/fragment program.
+ *
+ * \param ctx rendering context
+ * \param program the program to execute
+ * \param machine machine state (must be initialized)
+ * \return GL_TRUE if program completed or GL_FALSE if program executed KIL.
+ */
+GLboolean
+_mesa_execute_program(GLcontext * ctx,
+ const struct gl_program *program,
+ struct gl_program_machine *machine)
+{
+ const GLuint numInst = program->NumInstructions;
+ const GLuint maxExec = 10000;
+ GLint pc, numExec = 0;
+
+ machine->CurProgram = program;
+
+ if (DEBUG_PROG) {
+ printf("execute program %u --------------------\n", program->Id);
+ }
+
+#if FEATURE_MESA_program_debug
+ CurrentMachine = machine;
+#endif
+
+ if (program->Target == GL_VERTEX_PROGRAM_ARB) {
+ machine->EnvParams = ctx->VertexProgram.Parameters;
+ }
+ else {
+ machine->EnvParams = ctx->FragmentProgram.Parameters;
+ }
+
+ for (pc = 0; pc < numInst; pc++) {
+ const struct prog_instruction *inst = program->Instructions + pc;
+
+#if FEATURE_MESA_program_debug
+ if (ctx->FragmentProgram.CallbackEnabled &&
+ ctx->FragmentProgram.Callback) {
+ ctx->FragmentProgram.CurrentPosition = inst->StringPos;
+ ctx->FragmentProgram.Callback(program->Target,
+ ctx->FragmentProgram.CallbackData);
+ }
+#endif
+
+ if (DEBUG_PROG) {
+ _mesa_print_instruction(inst);
+ }
+
+ switch (inst->Opcode) {
+ case OPCODE_ABS:
+ {
+ GLfloat a[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ result[0] = FABSF(a[0]);
+ result[1] = FABSF(a[1]);
+ result[2] = FABSF(a[2]);
+ result[3] = FABSF(a[3]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_ADD:
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = a[0] + b[0];
+ result[1] = a[1] + b[1];
+ result[2] = a[2] + b[2];
+ result[3] = a[3] + b[3];
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("ADD (%g %g %g %g) = (%g %g %g %g) + (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_ARL:
+ {
+ GLfloat t[4];
+ fetch_vector4(&inst->SrcReg[0], machine, t);
+ machine->AddressReg[0][0] = (GLint) FLOORF(t[0]);
+ }
+ break;
+ case OPCODE_BGNLOOP:
+ /* no-op */
+ break;
+ case OPCODE_ENDLOOP:
+ /* subtract 1 here since pc is incremented by for(pc) loop */
+ pc = inst->BranchTarget - 1; /* go to matching BNGLOOP */
+ break;
+ case OPCODE_BGNSUB: /* begin subroutine */
+ break;
+ case OPCODE_ENDSUB: /* end subroutine */
+ break;
+ case OPCODE_BRA: /* branch (conditional) */
+ /* fall-through */
+ case OPCODE_BRK: /* break out of loop (conditional) */
+ /* fall-through */
+ case OPCODE_CONT: /* continue loop (conditional) */
+ if (eval_condition(machine, inst)) {
+ /* take branch */
+ /* Subtract 1 here since we'll do pc++ at end of for-loop */
+ pc = inst->BranchTarget - 1;
+ }
+ break;
+ case OPCODE_BRK0: /* Break if zero */
+ /* fall-through */
+ case OPCODE_CONT0: /* Continue if zero */
+ {
+ GLfloat a[4];
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ if (a[0] == 0.0) {
+ /* take branch */
+ /* Subtract 1 here since we'll do pc++ at end of for-loop */
+ pc = inst->BranchTarget - 1;
+ }
+ }
+ break;
+ case OPCODE_BRK1: /* Break if non-zero */
+ /* fall-through */
+ case OPCODE_CONT1: /* Continue if non-zero */
+ {
+ GLfloat a[4];
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ if (a[0] != 0.0) {
+ /* take branch */
+ /* Subtract 1 here since we'll do pc++ at end of for-loop */
+ pc = inst->BranchTarget - 1;
+ }
+ }
+ break;
+ case OPCODE_CAL: /* Call subroutine (conditional) */
+ if (eval_condition(machine, inst)) {
+ /* call the subroutine */
+ if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) {
+ return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
+ }
+ machine->CallStack[machine->StackDepth++] = pc + 1;
+ pc = inst->BranchTarget; /* XXX - 1 ??? */
+ }
+ break;
+ case OPCODE_CMP:
+ {
+ GLfloat a[4], b[4], c[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ fetch_vector4(&inst->SrcReg[2], machine, c);
+ result[0] = a[0] < 0.0F ? b[0] : c[0];
+ result[1] = a[1] < 0.0F ? b[1] : c[1];
+ result[2] = a[2] < 0.0F ? b[2] : c[2];
+ result[3] = a[3] < 0.0F ? b[3] : c[3];
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_COS:
+ {
+ GLfloat a[4], result[4];
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ result[0] = result[1] = result[2] = result[3]
+ = (GLfloat) _mesa_cos(a[0]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_DDX: /* Partial derivative with respect to X */
+ {
+#if 0
+ GLfloat a[4], aNext[4], result[4];
+ struct gl_program_machine dMachine;
+ if (!fetch_vector4_deriv(ctx, &inst->SrcReg[0], span, 'X',
+ column, result)) {
+ /* This is tricky. Make a copy of the current machine state,
+ * increment the input registers by the dx or dy partial
+ * derivatives, then re-execute the program up to the
+ * preceeding instruction, then fetch the source register.
+ * Finally, find the difference in the register values for
+ * the original and derivative runs.
+ */
+ fetch_vector4(&inst->SrcReg[0], machine, program, a);
+ init_machine_deriv(ctx, machine, program, span,
+ 'X', &dMachine);
+ execute_program(ctx, program, pc, &dMachine, span, column);
+ fetch_vector4(&inst->SrcReg[0], &dMachine, program,
+ aNext);
+ result[0] = aNext[0] - a[0];
+ result[1] = aNext[1] - a[1];
+ result[2] = aNext[2] - a[2];
+ result[3] = aNext[3] - a[3];
+ }
+ store_vector4(inst, machine, result);
+#else
+ store_vector4(inst, machine, ZeroVec);
+#endif
+ }
+ break;
+ case OPCODE_DDY: /* Partial derivative with respect to Y */
+ {
+#if 0
+ GLfloat a[4], aNext[4], result[4];
+ struct gl_program_machine dMachine;
+ if (!fetch_vector4_deriv(ctx, &inst->SrcReg[0], span, 'Y',
+ column, result)) {
+ init_machine_deriv(ctx, machine, program, span,
+ 'Y', &dMachine);
+ fetch_vector4(&inst->SrcReg[0], machine, program, a);
+ execute_program(ctx, program, pc, &dMachine, span, column);
+ fetch_vector4(&inst->SrcReg[0], &dMachine, program,
+ aNext);
+ result[0] = aNext[0] - a[0];
+ result[1] = aNext[1] - a[1];
+ result[2] = aNext[2] - a[2];
+ result[3] = aNext[3] - a[3];
+ }
+ store_vector4(inst, machine, result);
+#else
+ store_vector4(inst, machine, ZeroVec);
+#endif
+ }
+ break;
+ case OPCODE_DP3:
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = result[1] = result[2] = result[3] = DOT3(a, b);
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("DP3 %g = (%g %g %g) . (%g %g %g)\n",
+ result[0], a[0], a[1], a[2], b[0], b[1], b[2]);
+ }
+ }
+ break;
+ case OPCODE_DP4:
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = result[1] = result[2] = result[3] = DOT4(a, b);
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("DP4 %g = (%g, %g %g %g) . (%g, %g %g %g)\n",
+ result[0], a[0], a[1], a[2], a[3],
+ b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_DPH:
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = result[1] = result[2] = result[3] =
+ a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + b[3];
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_DST: /* Distance vector */
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = 1.0F;
+ result[1] = a[1] * b[1];
+ result[2] = a[2];
+ result[3] = b[3];
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_EXP:
+ {
+ GLfloat t[4], q[4], floor_t0;
+ fetch_vector1(&inst->SrcReg[0], machine, 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 {
+ q[0] = LDEXPF(1.0, (int) floor_t0);
+ /* Note: GL_NV_vertex_program expects
+ * result.z = result.x * APPX(result.y)
+ * We do what the ARB extension says.
+ */
+ q[2] = pow(2.0, t[0]);
+ }
+ q[1] = t[0] - floor_t0;
+ q[3] = 1.0F;
+ store_vector4( inst, machine, q );
+ }
+ break;
+ case OPCODE_EX2: /* Exponential base 2 */
+ {
+ GLfloat a[4], result[4];
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ result[0] = result[1] = result[2] = result[3] =
+ (GLfloat) _mesa_pow(2.0, a[0]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_FLR:
+ {
+ GLfloat a[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ result[0] = FLOORF(a[0]);
+ result[1] = FLOORF(a[1]);
+ result[2] = FLOORF(a[2]);
+ result[3] = FLOORF(a[3]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_FRC:
+ {
+ GLfloat a[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ result[0] = a[0] - FLOORF(a[0]);
+ result[1] = a[1] - FLOORF(a[1]);
+ result[2] = a[2] - FLOORF(a[2]);
+ result[3] = a[3] - FLOORF(a[3]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_IF:
+ {
+ GLboolean cond;
+ /* eval condition */
+ if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
+ GLfloat a[4];
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ cond = (a[0] != 0.0);
+ }
+ else {
+ cond = eval_condition(machine, inst);
+ }
+ /* do if/else */
+ if (cond) {
+ /* do if-clause (just continue execution) */
+ }
+ else {
+ /* go to the instruction after ELSE or ENDIF */
+ assert(inst->BranchTarget >= 0);
+ pc = inst->BranchTarget - 1;
+ }
+ }
+ break;
+ case OPCODE_ELSE:
+ /* goto ENDIF */
+ assert(inst->BranchTarget >= 0);
+ pc = inst->BranchTarget - 1;
+ break;
+ case OPCODE_ENDIF:
+ /* nothing */
+ break;
+ case OPCODE_INT: /* float to int */
+ {
+ GLfloat a[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ result[0] = (GLfloat) (GLint) a[0];
+ result[1] = (GLfloat) (GLint) a[1];
+ result[2] = (GLfloat) (GLint) a[2];
+ result[3] = (GLfloat) (GLint) a[3];
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_KIL_NV: /* NV_f_p only (conditional) */
+ if (eval_condition(machine, inst)) {
+ return GL_FALSE;
+ }
+ break;
+ case OPCODE_KIL: /* ARB_f_p only */
+ {
+ GLfloat a[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ if (a[0] < 0.0F || a[1] < 0.0F || a[2] < 0.0F || a[3] < 0.0F) {
+ return GL_FALSE;
+ }
+ }
+ break;
+ case OPCODE_LG2: /* log base 2 */
+ {
+ GLfloat a[4], result[4];
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ result[0] = result[1] = result[2] = result[3] = LOG2(a[0]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_LIT:
+ {
+ const GLfloat epsilon = 1.0F / 256.0F; /* from NV VP spec */
+ GLfloat a[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ a[0] = MAX2(a[0], 0.0F);
+ a[1] = MAX2(a[1], 0.0F);
+ /* XXX ARB version clamps a[3], NV version doesn't */
+ a[3] = CLAMP(a[3], -(128.0F - epsilon), (128.0F - epsilon));
+ result[0] = 1.0F;
+ result[1] = a[0];
+ /* XXX we could probably just use pow() here */
+ if (a[0] > 0.0F) {
+ if (a[1] == 0.0 && a[3] == 0.0)
+ result[2] = 1.0;
+ else
+ result[2] = EXPF(a[3] * LOGF(a[1]));
+ }
+ else {
+ result[2] = 0.0;
+ }
+ result[3] = 1.0F;
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("LIT (%g %g %g %g) : (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3]);
+ }
+ }
+ break;
+ case OPCODE_LOG:
+ {
+ GLfloat t[4], q[4], abs_t0;
+ fetch_vector1(&inst->SrcReg[0], machine, 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_LRP:
+ {
+ GLfloat a[4], b[4], c[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ fetch_vector4(&inst->SrcReg[2], machine, c);
+ result[0] = a[0] * b[0] + (1.0F - a[0]) * c[0];
+ result[1] = a[1] * b[1] + (1.0F - a[1]) * c[1];
+ result[2] = a[2] * b[2] + (1.0F - a[2]) * c[2];
+ result[3] = a[3] * b[3] + (1.0F - a[3]) * c[3];
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("LRP (%g %g %g %g) = (%g %g %g %g), "
+ "(%g %g %g %g), (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3],
+ b[0], b[1], b[2], b[3], c[0], c[1], c[2], c[3]);
+ }
+ }
+ break;
+ case OPCODE_MAD:
+ {
+ GLfloat a[4], b[4], c[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ fetch_vector4(&inst->SrcReg[2], machine, c);
+ result[0] = a[0] * b[0] + c[0];
+ result[1] = a[1] * b[1] + c[1];
+ result[2] = a[2] * b[2] + c[2];
+ result[3] = a[3] * b[3] + c[3];
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("MAD (%g %g %g %g) = (%g %g %g %g) * "
+ "(%g %g %g %g) + (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3],
+ b[0], b[1], b[2], b[3], c[0], c[1], c[2], c[3]);
+ }
+ }
+ break;
+ case OPCODE_MAX:
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = MAX2(a[0], b[0]);
+ result[1] = MAX2(a[1], b[1]);
+ result[2] = MAX2(a[2], b[2]);
+ result[3] = MAX2(a[3], b[3]);
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("MAX (%g %g %g %g) = (%g %g %g %g), (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_MIN:
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = MIN2(a[0], b[0]);
+ result[1] = MIN2(a[1], b[1]);
+ result[2] = MIN2(a[2], b[2]);
+ result[3] = MIN2(a[3], b[3]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_MOV:
+ {
+ GLfloat result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, result);
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("MOV (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3]);
+ }
+ }
+ break;
+ case OPCODE_MUL:
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = a[0] * b[0];
+ result[1] = a[1] * b[1];
+ result[2] = a[2] * b[2];
+ result[3] = a[3] * b[3];
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("MUL (%g %g %g %g) = (%g %g %g %g) * (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_NOISE1:
+ {
+ GLfloat a[4], result[4];
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ result[0] =
+ result[1] =
+ result[2] = result[3] = _slang_library_noise1(a[0]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_NOISE2:
+ {
+ GLfloat a[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ result[0] =
+ result[1] =
+ result[2] = result[3] = _slang_library_noise2(a[0], a[1]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_NOISE3:
+ {
+ GLfloat a[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ result[0] =
+ result[1] =
+ result[2] =
+ result[3] = _slang_library_noise3(a[0], a[1], a[2]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_NOISE4:
+ {
+ GLfloat a[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ result[0] =
+ result[1] =
+ result[2] =
+ result[3] = _slang_library_noise4(a[0], a[1], a[2], a[3]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_NOP:
+ break;
+ case OPCODE_PK2H: /* pack two 16-bit floats in one 32-bit float */
+ {
+ GLfloat a[4], result[4];
+ GLhalfNV hx, hy;
+ GLuint *rawResult = (GLuint *) result;
+ GLuint twoHalves;
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ hx = _mesa_float_to_half(a[0]);
+ hy = _mesa_float_to_half(a[1]);
+ twoHalves = hx | (hy << 16);
+ rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3]
+ = twoHalves;
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_PK2US: /* pack two GLushorts into one 32-bit float */
+ {
+ GLfloat a[4], result[4];
+ GLuint usx, usy, *rawResult = (GLuint *) result;
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ a[0] = CLAMP(a[0], 0.0F, 1.0F);
+ a[1] = CLAMP(a[1], 0.0F, 1.0F);
+ usx = IROUND(a[0] * 65535.0F);
+ usy = IROUND(a[1] * 65535.0F);
+ rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3]
+ = usx | (usy << 16);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_PK4B: /* pack four GLbytes into one 32-bit float */
+ {
+ GLfloat a[4], result[4];
+ GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result;
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ a[0] = CLAMP(a[0], -128.0F / 127.0F, 1.0F);
+ a[1] = CLAMP(a[1], -128.0F / 127.0F, 1.0F);
+ a[2] = CLAMP(a[2], -128.0F / 127.0F, 1.0F);
+ a[3] = CLAMP(a[3], -128.0F / 127.0F, 1.0F);
+ ubx = IROUND(127.0F * a[0] + 128.0F);
+ uby = IROUND(127.0F * a[1] + 128.0F);
+ ubz = IROUND(127.0F * a[2] + 128.0F);
+ ubw = IROUND(127.0F * a[3] + 128.0F);
+ rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3]
+ = ubx | (uby << 8) | (ubz << 16) | (ubw << 24);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_PK4UB: /* pack four GLubytes into one 32-bit float */
+ {
+ GLfloat a[4], result[4];
+ GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result;
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ a[0] = CLAMP(a[0], 0.0F, 1.0F);
+ a[1] = CLAMP(a[1], 0.0F, 1.0F);
+ a[2] = CLAMP(a[2], 0.0F, 1.0F);
+ a[3] = CLAMP(a[3], 0.0F, 1.0F);
+ ubx = IROUND(255.0F * a[0]);
+ uby = IROUND(255.0F * a[1]);
+ ubz = IROUND(255.0F * a[2]);
+ ubw = IROUND(255.0F * a[3]);
+ rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3]
+ = ubx | (uby << 8) | (ubz << 16) | (ubw << 24);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_POW:
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ fetch_vector1(&inst->SrcReg[1], machine, b);
+ result[0] = result[1] = result[2] = result[3]
+ = (GLfloat) _mesa_pow(a[0], b[0]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_RCP:
+ {
+ GLfloat a[4], result[4];
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ if (DEBUG_PROG) {
+ if (a[0] == 0)
+ printf("RCP(0)\n");
+ else if (IS_INF_OR_NAN(a[0]))
+ printf("RCP(inf)\n");
+ }
+ result[0] = result[1] = result[2] = result[3] = 1.0F / a[0];
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_RET: /* return from subroutine (conditional) */
+ if (eval_condition(machine, inst)) {
+ if (machine->StackDepth == 0) {
+ return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
+ }
+ pc = machine->CallStack[--machine->StackDepth];
+ }
+ break;
+ case OPCODE_RFL: /* reflection vector */
+ {
+ GLfloat axis[4], dir[4], result[4], tmpX, tmpW;
+ fetch_vector4(&inst->SrcReg[0], machine, axis);
+ fetch_vector4(&inst->SrcReg[1], machine, dir);
+ tmpW = DOT3(axis, axis);
+ tmpX = (2.0F * DOT3(axis, dir)) / tmpW;
+ result[0] = tmpX * axis[0] - dir[0];
+ result[1] = tmpX * axis[1] - dir[1];
+ result[2] = tmpX * axis[2] - dir[2];
+ /* result[3] is never written! XXX enforce in parser! */
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_RSQ: /* 1 / sqrt() */
+ {
+ GLfloat a[4], result[4];
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ a[0] = FABSF(a[0]);
+ result[0] = result[1] = result[2] = result[3] = INV_SQRTF(a[0]);
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("RSQ %g = 1/sqrt(|%g|)\n", result[0], a[0]);
+ }
+ }
+ break;
+ case OPCODE_SCS: /* sine and cos */
+ {
+ GLfloat a[4], result[4];
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ result[0] = (GLfloat) _mesa_cos(a[0]);
+ result[1] = (GLfloat) _mesa_sin(a[0]);
+ result[2] = 0.0; /* undefined! */
+ result[3] = 0.0; /* undefined! */
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_SEQ: /* set on equal */
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = (a[0] == b[0]) ? 1.0F : 0.0F;
+ result[1] = (a[1] == b[1]) ? 1.0F : 0.0F;
+ result[2] = (a[2] == b[2]) ? 1.0F : 0.0F;
+ result[3] = (a[3] == b[3]) ? 1.0F : 0.0F;
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("SEQ (%g %g %g %g) = (%g %g %g %g) == (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3],
+ b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_SFL: /* set false, operands ignored */
+ {
+ static const GLfloat result[4] = { 0.0F, 0.0F, 0.0F, 0.0F };
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_SGE: /* set on greater or equal */
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = (a[0] >= b[0]) ? 1.0F : 0.0F;
+ result[1] = (a[1] >= b[1]) ? 1.0F : 0.0F;
+ result[2] = (a[2] >= b[2]) ? 1.0F : 0.0F;
+ result[3] = (a[3] >= b[3]) ? 1.0F : 0.0F;
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("SGE (%g %g %g %g) = (%g %g %g %g) >= (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3],
+ b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_SGT: /* set on greater */
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = (a[0] > b[0]) ? 1.0F : 0.0F;
+ result[1] = (a[1] > b[1]) ? 1.0F : 0.0F;
+ result[2] = (a[2] > b[2]) ? 1.0F : 0.0F;
+ result[3] = (a[3] > b[3]) ? 1.0F : 0.0F;
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("SGT (%g %g %g %g) = (%g %g %g %g) > (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3],
+ b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_SIN:
+ {
+ GLfloat a[4], result[4];
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ result[0] = result[1] = result[2] = result[3]
+ = (GLfloat) _mesa_sin(a[0]);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_SLE: /* set on less or equal */
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = (a[0] <= b[0]) ? 1.0F : 0.0F;
+ result[1] = (a[1] <= b[1]) ? 1.0F : 0.0F;
+ result[2] = (a[2] <= b[2]) ? 1.0F : 0.0F;
+ result[3] = (a[3] <= b[3]) ? 1.0F : 0.0F;
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("SLE (%g %g %g %g) = (%g %g %g %g) <= (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3],
+ b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_SLT: /* set on less */
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = (a[0] < b[0]) ? 1.0F : 0.0F;
+ result[1] = (a[1] < b[1]) ? 1.0F : 0.0F;
+ result[2] = (a[2] < b[2]) ? 1.0F : 0.0F;
+ result[3] = (a[3] < b[3]) ? 1.0F : 0.0F;
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("SLT (%g %g %g %g) = (%g %g %g %g) < (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3],
+ b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_SNE: /* set on not equal */
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = (a[0] != b[0]) ? 1.0F : 0.0F;
+ result[1] = (a[1] != b[1]) ? 1.0F : 0.0F;
+ result[2] = (a[2] != b[2]) ? 1.0F : 0.0F;
+ result[3] = (a[3] != b[3]) ? 1.0F : 0.0F;
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("SNE (%g %g %g %g) = (%g %g %g %g) != (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3],
+ b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_STR: /* set true, operands ignored */
+ {
+ static const GLfloat result[4] = { 1.0F, 1.0F, 1.0F, 1.0F };
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_SUB:
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = a[0] - b[0];
+ result[1] = a[1] - b[1];
+ result[2] = a[2] - b[2];
+ result[3] = a[3] - b[3];
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("SUB (%g %g %g %g) = (%g %g %g %g) - (%g %g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
+ }
+ }
+ break;
+ case OPCODE_SWZ: /* extended swizzle */
+ {
+ const struct prog_src_register *source = &inst->SrcReg[0];
+ const GLfloat *src = get_register_pointer(source, machine);
+ GLfloat result[4];
+ GLuint i;
+ 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_TEX: /* Both ARB and NV frag prog */
+ /* Texel lookup */
+ {
+ /* Note: only use the precomputed lambda value when we're
+ * sampling texture unit [K] with texcoord[K].
+ * Otherwise, the lambda value may have no relation to the
+ * instruction's texcoord or texture image. Using the wrong
+ * lambda is usually bad news.
+ * The rest of the time, just use zero (until we get a more
+ * sophisticated way of computing lambda).
+ */
+ GLfloat coord[4], color[4], lambda;
+#if 0
+ if (inst->SrcReg[0].File == PROGRAM_INPUT &&
+ inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit)
+ lambda = span->array->lambda[inst->TexSrcUnit][column];
+ else
+#endif
+ lambda = 0.0;
+ fetch_vector4(&inst->SrcReg[0], machine, coord);
+ machine->FetchTexelLod(ctx, coord, lambda, inst->TexSrcUnit,
+ color);
+ if (DEBUG_PROG) {
+ printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g], "
+ "lod %f\n",
+ color[0], color[1], color[2], color[3],
+ inst->TexSrcUnit,
+ coord[0], coord[1], coord[2], coord[3], lambda);
+ }
+ store_vector4(inst, machine, color);
+ }
+ break;
+ case OPCODE_TXB: /* GL_ARB_fragment_program only */
+ /* Texel lookup with LOD bias */
+ {
+ const struct gl_texture_unit *texUnit
+ = &ctx->Texture.Unit[inst->TexSrcUnit];
+ GLfloat coord[4], color[4], lambda, bias;
+#if 0
+ if (inst->SrcReg[0].File == PROGRAM_INPUT &&
+ inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit)
+ lambda = span->array->lambda[inst->TexSrcUnit][column];
+ else
+#endif
+ lambda = 0.0;
+ fetch_vector4(&inst->SrcReg[0], machine, coord);
+ /* coord[3] is the bias to add to lambda */
+ bias = texUnit->LodBias + coord[3];
+ if (texUnit->_Current)
+ bias += texUnit->_Current->LodBias;
+ machine->FetchTexelLod(ctx, coord, lambda + bias,
+ inst->TexSrcUnit, color);
+ store_vector4(inst, machine, color);
+ }
+ break;
+ case OPCODE_TXD: /* GL_NV_fragment_program only */
+ /* Texture lookup w/ partial derivatives for LOD */
+ {
+ GLfloat texcoord[4], dtdx[4], dtdy[4], color[4];
+ fetch_vector4(&inst->SrcReg[0], machine, texcoord);
+ fetch_vector4(&inst->SrcReg[1], machine, dtdx);
+ fetch_vector4(&inst->SrcReg[2], machine, dtdy);
+ machine->FetchTexelDeriv(ctx, texcoord, dtdx, dtdy,
+ inst->TexSrcUnit, color);
+ store_vector4(inst, machine, color);
+ }
+ break;
+ case OPCODE_TXP: /* GL_ARB_fragment_program only */
+ /* Texture lookup w/ projective divide */
+ {
+ GLfloat texcoord[4], color[4], lambda;
+#if 0
+ if (inst->SrcReg[0].File == PROGRAM_INPUT &&
+ inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit)
+ lambda = span->array->lambda[inst->TexSrcUnit][column];
+ else
+#endif
+ lambda = 0.0;
+ fetch_vector4(&inst->SrcReg[0], machine, texcoord);
+ /* Not so sure about this test - if texcoord[3] is
+ * zero, we'd probably be fine except for an ASSERT in
+ * IROUND_POS() which gets triggered by the inf values created.
+ */
+ if (texcoord[3] != 0.0) {
+ texcoord[0] /= texcoord[3];
+ texcoord[1] /= texcoord[3];
+ texcoord[2] /= texcoord[3];
+ }
+ machine->FetchTexelLod(ctx, texcoord, lambda,
+ inst->TexSrcUnit, color);
+ store_vector4(inst, machine, color);
+ }
+ break;
+ case OPCODE_TXP_NV: /* GL_NV_fragment_program only */
+ /* Texture lookup w/ projective divide */
+ {
+ GLfloat texcoord[4], color[4], lambda;
+#if 0
+ if (inst->SrcReg[0].File == PROGRAM_INPUT &&
+ inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit)
+ lambda = span->array->lambda[inst->TexSrcUnit][column];
+ else
+#endif
+ lambda = 0.0;
+ fetch_vector4(&inst->SrcReg[0], machine, texcoord);
+ if (inst->TexSrcTarget != TEXTURE_CUBE_INDEX &&
+ texcoord[3] != 0.0) {
+ texcoord[0] /= texcoord[3];
+ texcoord[1] /= texcoord[3];
+ texcoord[2] /= texcoord[3];
+ }
+ machine->FetchTexelLod(ctx, texcoord, lambda,
+ inst->TexSrcUnit, color);
+ store_vector4(inst, machine, color);
+ }
+ break;
+ case OPCODE_UP2H: /* unpack two 16-bit floats */
+ {
+ GLfloat a[4], result[4];
+ const GLuint *rawBits = (const GLuint *) a;
+ GLhalfNV hx, hy;
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ hx = rawBits[0] & 0xffff;
+ hy = rawBits[0] >> 16;
+ result[0] = result[2] = _mesa_half_to_float(hx);
+ result[1] = result[3] = _mesa_half_to_float(hy);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_UP2US: /* unpack two GLushorts */
+ {
+ GLfloat a[4], result[4];
+ const GLuint *rawBits = (const GLuint *) a;
+ GLushort usx, usy;
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ usx = rawBits[0] & 0xffff;
+ usy = rawBits[0] >> 16;
+ result[0] = result[2] = usx * (1.0f / 65535.0f);
+ result[1] = result[3] = usy * (1.0f / 65535.0f);
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_UP4B: /* unpack four GLbytes */
+ {
+ GLfloat a[4], result[4];
+ const GLuint *rawBits = (const GLuint *) a;
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ result[0] = (((rawBits[0] >> 0) & 0xff) - 128) / 127.0F;
+ result[1] = (((rawBits[0] >> 8) & 0xff) - 128) / 127.0F;
+ result[2] = (((rawBits[0] >> 16) & 0xff) - 128) / 127.0F;
+ result[3] = (((rawBits[0] >> 24) & 0xff) - 128) / 127.0F;
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_UP4UB: /* unpack four GLubytes */
+ {
+ GLfloat a[4], result[4];
+ const GLuint *rawBits = (const GLuint *) a;
+ fetch_vector1(&inst->SrcReg[0], machine, a);
+ result[0] = ((rawBits[0] >> 0) & 0xff) / 255.0F;
+ result[1] = ((rawBits[0] >> 8) & 0xff) / 255.0F;
+ result[2] = ((rawBits[0] >> 16) & 0xff) / 255.0F;
+ result[3] = ((rawBits[0] >> 24) & 0xff) / 255.0F;
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_XPD: /* cross product */
+ {
+ GLfloat a[4], b[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ result[0] = a[1] * b[2] - a[2] * b[1];
+ result[1] = a[2] * b[0] - a[0] * b[2];
+ result[2] = a[0] * b[1] - a[1] * b[0];
+ result[3] = 1.0;
+ store_vector4(inst, machine, result);
+ if (DEBUG_PROG) {
+ printf("XPD (%g %g %g %g) = (%g %g %g) X (%g %g %g)\n",
+ result[0], result[1], result[2], result[3],
+ a[0], a[1], a[2], b[0], b[1], b[2]);
+ }
+ }
+ break;
+ case OPCODE_X2D: /* 2-D matrix transform */
+ {
+ GLfloat a[4], b[4], c[4], result[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ fetch_vector4(&inst->SrcReg[1], machine, b);
+ fetch_vector4(&inst->SrcReg[2], machine, c);
+ result[0] = a[0] + b[0] * c[0] + b[1] * c[1];
+ result[1] = a[1] + b[0] * c[2] + b[1] * c[3];
+ result[2] = a[2] + b[0] * c[0] + b[1] * c[1];
+ result[3] = a[3] + b[0] * c[2] + b[1] * c[3];
+ store_vector4(inst, machine, result);
+ }
+ break;
+ case OPCODE_PRINT:
+ {
+ if (inst->SrcReg[0].File != -1) {
+ GLfloat a[4];
+ fetch_vector4(&inst->SrcReg[0], machine, a);
+ _mesa_printf("%s%g, %g, %g, %g\n", (const char *) inst->Data,
+ a[0], a[1], a[2], a[3]);
+ }
+ else {
+ _mesa_printf("%s\n", (const char *) inst->Data);
+ }
+ }
+ break;
+ case OPCODE_END:
+ return GL_TRUE;
+ default:
+ _mesa_problem(ctx, "Bad opcode %d in _mesa_exec_fragment_program",
+ inst->Opcode);
+ return GL_TRUE; /* return value doesn't matter */
+
+ }
+
+ numExec++;
+ if (numExec > maxExec) {
+ _mesa_problem(ctx, "Infinite loop detected in fragment program");
+ return GL_TRUE;
+ }
+
+ } /* for pc */
+
+#if FEATURE_MESA_program_debug
+ CurrentMachine = NULL;
+#endif
+
+ return GL_TRUE;
+}
diff --git a/src/mesa/shader/prog_execute.h b/src/mesa/shader/prog_execute.h
new file mode 100644
index 00000000000..47845e9111f
--- /dev/null
+++ b/src/mesa/shader/prog_execute.h
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+#ifndef PROG_EXECUTE_H
+#define PROG_EXECUTE_H
+
+
+typedef void (*FetchTexelLodFunc)(GLcontext *ctx, const GLfloat texcoord[4],
+ GLfloat lambda, GLuint unit, GLfloat color[4]);
+
+typedef void (*FetchTexelDerivFunc)(GLcontext *ctx, const GLfloat texcoord[4],
+ const GLfloat texdx[4],
+ const GLfloat texdy[4],
+ GLuint unit, GLfloat color[4]);
+
+
+/** The larger of VERT_RESULT_MAX, FRAG_RESULT_MAX */
+#define MAX_PROGRAM_OUTPUTS VERT_RESULT_MAX
+
+
+/**
+ * Virtual machine state used during execution of vertex/fragment programs.
+ */
+struct gl_program_machine
+{
+ const struct gl_program *CurProgram;
+
+ /** Fragment Input attributes */
+ GLfloat (*Attribs)[MAX_WIDTH][4];
+ GLuint CurElement; /**< Index into Attribs arrays */
+
+ /** Vertex Input attribs */
+ GLfloat VertAttribs[VERT_ATTRIB_MAX][4];
+
+ GLfloat Temporaries[MAX_PROGRAM_TEMPS][4];
+ GLfloat Outputs[MAX_PROGRAM_OUTPUTS][4];
+ GLfloat (*EnvParams)[4]; /**< Vertex or Fragment env parameters */
+ GLuint CondCodes[4]; /**< COND_* value for x/y/z/w */
+ GLint AddressReg[MAX_PROGRAM_ADDRESS_REGS][4];
+
+ GLuint CallStack[MAX_PROGRAM_CALL_DEPTH]; /**< For CAL/RET instructions */
+ GLuint StackDepth; /**< Index/ptr to top of CallStack[] */
+
+ /** Texture fetch functions */
+ FetchTexelLodFunc FetchTexelLod;
+ FetchTexelDerivFunc FetchTexelDeriv;
+};
+
+
+extern void
+_mesa_get_program_register(GLcontext *ctx, enum register_file file,
+ GLuint index, GLfloat val[4]);
+
+extern GLboolean
+_mesa_execute_program(GLcontext *ctx,
+ const struct gl_program *program,
+ struct gl_program_machine *machine);
+
+
+#endif /* PROG_EXECUTE_H */
diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c
new file mode 100644
index 00000000000..272caf6c746
--- /dev/null
+++ b/src/mesa/shader/prog_instruction.c
@@ -0,0 +1,243 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5.3
+ *
+ * Copyright (C) 1999-2005 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 "imports.h"
+#include "mtypes.h"
+#include "prog_instruction.h"
+
+
+/**
+ * Initialize program instruction fields to defaults.
+ * \param inst first instruction to initialize
+ * \param count number of instructions to initialize
+ */
+void
+_mesa_init_instructions(struct prog_instruction *inst, GLuint count)
+{
+ GLuint i;
+
+ _mesa_bzero(inst, count * sizeof(struct prog_instruction));
+
+ for (i = 0; i < count; i++) {
+ inst[i].SrcReg[0].File = PROGRAM_UNDEFINED;
+ inst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP;
+ inst[i].SrcReg[1].File = PROGRAM_UNDEFINED;
+ inst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP;
+ inst[i].SrcReg[2].File = PROGRAM_UNDEFINED;
+ inst[i].SrcReg[2].Swizzle = SWIZZLE_NOOP;
+
+ inst[i].DstReg.File = PROGRAM_UNDEFINED;
+ inst[i].DstReg.WriteMask = WRITEMASK_XYZW;
+ inst[i].DstReg.CondMask = COND_TR;
+ inst[i].DstReg.CondSwizzle = SWIZZLE_NOOP;
+
+ inst[i].SaturateMode = SATURATE_OFF;
+ inst[i].Precision = FLOAT32;
+ }
+}
+
+
+/**
+ * Allocate an array of program instructions.
+ * \param numInst number of instructions
+ * \return pointer to instruction memory
+ */
+struct prog_instruction *
+_mesa_alloc_instructions(GLuint numInst)
+{
+ return (struct prog_instruction *)
+ _mesa_calloc(numInst * sizeof(struct prog_instruction));
+}
+
+
+/**
+ * Reallocate memory storing an array of program instructions.
+ * This is used when we need to append additional instructions onto an
+ * program.
+ * \param oldInst pointer to first of old/src instructions
+ * \param numOldInst number of instructions at <oldInst>
+ * \param numNewInst desired size of new instruction array.
+ * \return pointer to start of new instruction array.
+ */
+struct prog_instruction *
+_mesa_realloc_instructions(struct prog_instruction *oldInst,
+ GLuint numOldInst, GLuint numNewInst)
+{
+ struct prog_instruction *newInst;
+
+ newInst = (struct prog_instruction *)
+ _mesa_realloc(oldInst,
+ numOldInst * sizeof(struct prog_instruction),
+ numNewInst * sizeof(struct prog_instruction));
+
+ return newInst;
+}
+
+
+/**
+ * Copy an array of program instructions.
+ * \param dest pointer to destination.
+ * \param src pointer to source.
+ * \param n number of instructions to copy.
+ * \return pointer to destination.
+ */
+struct prog_instruction *
+_mesa_copy_instructions(struct prog_instruction *dest,
+ const struct prog_instruction *src, GLuint n)
+{
+ return _mesa_memcpy(dest, src, n * sizeof(struct prog_instruction));
+}
+
+
+/**
+ * Basic info about each instruction
+ */
+struct instruction_info
+{
+ gl_inst_opcode Opcode;
+ const char *Name;
+ GLuint NumSrcRegs;
+};
+
+/**
+ * Instruction info
+ * \note Opcode should equal array index!
+ */
+static const struct instruction_info InstInfo[MAX_OPCODE] = {
+ { OPCODE_NOP, "NOP", 0 },
+ { OPCODE_ABS, "ABS", 1 },
+ { OPCODE_ADD, "ADD", 2 },
+ { OPCODE_ARA, "ARA", 1 },
+ { OPCODE_ARL, "ARL", 1 },
+ { OPCODE_ARL_NV, "ARL", 1 },
+ { OPCODE_ARR, "ARL", 1 },
+ { OPCODE_BGNLOOP,"BGNLOOP", 0 },
+ { OPCODE_BGNSUB, "BGNSUB", 0 },
+ { OPCODE_BRA, "BRA", 0 },
+ { OPCODE_BRK, "BRK", 0 },
+ { OPCODE_BRK0, "BRK0", 1 },
+ { OPCODE_BRK1, "BRK1", 1 },
+ { OPCODE_CAL, "CAL", 0 },
+ { OPCODE_CMP, "CMP", 3 },
+ { OPCODE_CONT, "CONT", 0 },
+ { OPCODE_CONT0, "CONT0", 1 },
+ { OPCODE_CONT1, "CONT1", 1 },
+ { OPCODE_COS, "COS", 1 },
+ { OPCODE_DDX, "DDX", 1 },
+ { OPCODE_DDY, "DDY", 1 },
+ { OPCODE_DP3, "DP3", 2 },
+ { OPCODE_DP4, "DP4", 2 },
+ { OPCODE_DPH, "DPH", 2 },
+ { OPCODE_DST, "DST", 2 },
+ { OPCODE_ELSE, "ELSE", 0 },
+ { OPCODE_END, "END", 0 },
+ { OPCODE_ENDIF, "ENDIF", 0 },
+ { OPCODE_ENDLOOP,"ENDLOOP", 0 },
+ { OPCODE_ENDSUB, "ENDSUB", 0 },
+ { OPCODE_EX2, "EX2", 1 },
+ { OPCODE_EXP, "EXP", 1 },
+ { OPCODE_FLR, "FLR", 1 },
+ { OPCODE_FRC, "FRC", 1 },
+ { OPCODE_IF, "IF", 0 },
+ { OPCODE_INT, "INT", 1 },
+ { OPCODE_KIL, "KIL", 1 },
+ { OPCODE_KIL_NV, "KIL", 0 },
+ { OPCODE_LG2, "LG2", 1 },
+ { OPCODE_LIT, "LIT", 1 },
+ { OPCODE_LOG, "LOG", 1 },
+ { OPCODE_LRP, "LRP", 3 },
+ { OPCODE_MAD, "MAD", 3 },
+ { OPCODE_MAX, "MAX", 2 },
+ { OPCODE_MIN, "MIN", 2 },
+ { OPCODE_MOV, "MOV", 1 },
+ { OPCODE_MUL, "MUL", 2 },
+ { OPCODE_NOISE1, "NOISE1", 1 },
+ { OPCODE_NOISE2, "NOISE2", 1 },
+ { OPCODE_NOISE3, "NOISE3", 1 },
+ { OPCODE_NOISE4, "NOISE4", 1 },
+ { OPCODE_PK2H, "PK2H", 1 },
+ { OPCODE_PK2US, "PK2US", 1 },
+ { OPCODE_PK4B, "PK4B", 1 },
+ { OPCODE_PK4UB, "PK4UB", 1 },
+ { OPCODE_POW, "POW", 2 },
+ { OPCODE_POPA, "POPA", 0 },
+ { OPCODE_PRINT, "PRINT", 1 },
+ { OPCODE_PUSHA, "PUSHA", 0 },
+ { OPCODE_RCC, "RCC", 1 },
+ { OPCODE_RCP, "RCP", 1 },
+ { OPCODE_RET, "RET", 0 },
+ { OPCODE_RFL, "RFL", 1 },
+ { OPCODE_RSQ, "RSQ", 1 },
+ { OPCODE_SCS, "SCS", 1 },
+ { OPCODE_SEQ, "SEQ", 2 },
+ { OPCODE_SFL, "SFL", 0 },
+ { OPCODE_SGE, "SGE", 2 },
+ { OPCODE_SGT, "SGT", 2 },
+ { OPCODE_SIN, "SIN", 1 },
+ { OPCODE_SLE, "SLE", 2 },
+ { OPCODE_SLT, "SLT", 2 },
+ { OPCODE_SNE, "SNE", 2 },
+ { OPCODE_SSG, "SSG", 1 },
+ { OPCODE_STR, "STR", 0 },
+ { OPCODE_SUB, "SUB", 2 },
+ { OPCODE_SWZ, "SWZ", 1 },
+ { OPCODE_TEX, "TEX", 1 },
+ { OPCODE_TXB, "TXB", 1 },
+ { OPCODE_TXD, "TXD", 3 },
+ { OPCODE_TXL, "TXL", 1 },
+ { OPCODE_TXP, "TXP", 1 },
+ { OPCODE_TXP_NV, "TXP", 1 },
+ { OPCODE_UP2H, "UP2H", 1 },
+ { OPCODE_UP2US, "UP2US", 1 },
+ { OPCODE_UP4B, "UP4B", 1 },
+ { OPCODE_UP4UB, "UP4UB", 1 },
+ { OPCODE_X2D, "X2D", 3 },
+ { OPCODE_XPD, "XPD", 2 }
+};
+
+
+/**
+ * Return the number of src registers for the given instruction/opcode.
+ */
+GLuint
+_mesa_num_inst_src_regs(gl_inst_opcode opcode)
+{
+ ASSERT(opcode == InstInfo[opcode].Opcode);
+ ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode);
+ return InstInfo[opcode].NumSrcRegs;
+}
+
+
+/**
+ * Return string name for given program opcode.
+ */
+const char *
+_mesa_opcode_string(gl_inst_opcode opcode)
+{
+ ASSERT(opcode < MAX_OPCODE);
+ return InstInfo[opcode].Name;
+}
+
diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h
new file mode 100644
index 00000000000..dc2d2dc29b4
--- /dev/null
+++ b/src/mesa/shader/prog_instruction.h
@@ -0,0 +1,451 @@
+/*
+ * 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.
+ */
+
+
+/**
+ * \file prog_instruction.h
+ *
+ * Vertex/fragment program instruction datatypes and constants.
+ *
+ * \author Brian Paul
+ * \author Keith Whitwell
+ * \author Ian Romanick <idr@us.ibm.com>
+ */
+
+
+#ifndef PROG_INSTRUCTION_H
+#define PROG_INSTRUCTION_H
+
+
+/**
+ * Swizzle indexes.
+ * Do not change!
+ */
+/*@{*/
+#define SWIZZLE_X 0
+#define SWIZZLE_Y 1
+#define SWIZZLE_Z 2
+#define SWIZZLE_W 3
+#define SWIZZLE_ZERO 4 /**< For SWZ instruction only */
+#define SWIZZLE_ONE 5 /**< For SWZ instruction only */
+#define SWIZZLE_NIL 7 /**< used during shader code gen (undefined value) */
+/*@}*/
+
+#define MAKE_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<3) | ((c)<<6) | ((d)<<9))
+#define SWIZZLE_NOOP MAKE_SWIZZLE4(0,1,2,3)
+#define GET_SWZ(swz, idx) (((swz) >> ((idx)*3)) & 0x7)
+#define GET_BIT(msk, idx) (((msk) >> (idx)) & 0x1)
+
+#define SWIZZLE_XYZW MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W)
+#define SWIZZLE_XXXX MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X)
+#define SWIZZLE_YYYY MAKE_SWIZZLE4(SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y)
+#define SWIZZLE_ZZZZ MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z)
+#define SWIZZLE_WWWW MAKE_SWIZZLE4(SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W)
+
+
+/**
+ * Writemask values, 1 bit per component.
+ */
+/*@{*/
+#define WRITEMASK_X 0x1
+#define WRITEMASK_Y 0x2
+#define WRITEMASK_XY 0x3
+#define WRITEMASK_Z 0x4
+#define WRITEMASK_XZ 0x5
+#define WRITEMASK_YZ 0x6
+#define WRITEMASK_XYZ 0x7
+#define WRITEMASK_W 0x8
+#define WRITEMASK_XW 0x9
+#define WRITEMASK_YW 0xa
+#define WRITEMASK_XYW 0xb
+#define WRITEMASK_ZW 0xc
+#define WRITEMASK_XZW 0xd
+#define WRITEMASK_YZW 0xe
+#define WRITEMASK_XYZW 0xf
+/*@}*/
+
+
+/**
+ * Condition codes
+ */
+/*@{*/
+#define COND_GT 1 /**< greater than zero */
+#define COND_EQ 2 /**< equal to zero */
+#define COND_LT 3 /**< less than zero */
+#define COND_UN 4 /**< unordered (NaN) */
+#define COND_GE 5 /**< greater then or equal to zero */
+#define COND_LE 6 /**< less then or equal to zero */
+#define COND_NE 7 /**< not equal to zero */
+#define COND_TR 8 /**< always true */
+#define COND_FL 9 /**< always false */
+/*@}*/
+
+
+/**
+ * Instruction precision for GL_NV_fragment_program
+ */
+/*@{*/
+#define FLOAT32 0x1
+#define FLOAT16 0x2
+#define FIXED12 0x4
+/*@}*/
+
+
+/**
+ * Saturation modes when storing values.
+ */
+/*@{*/
+#define SATURATE_OFF 0
+#define SATURATE_ZERO_ONE 1
+#define SATURATE_PLUS_MINUS_ONE 2
+/*@}*/
+
+
+/**
+ * Per-component negation masks
+ */
+/*@{*/
+#define NEGATE_X 0x1
+#define NEGATE_Y 0x2
+#define NEGATE_Z 0x4
+#define NEGATE_W 0x8
+#define NEGATE_XYZW 0xf
+#define NEGATE_NONE 0x0
+/*@}*/
+
+
+/**
+ * Program instruction opcodes, for both vertex and fragment programs.
+ * \note changes to this opcode list must be reflected in t_vb_arbprogram.c
+ */
+typedef enum prog_opcode {
+ /* ARB_vp ARB_fp NV_vp NV_fp GLSL */
+ /*------------------------------------------*/
+ OPCODE_NOP = 0, /* X */
+ OPCODE_ABS, /* X X 1.1 X */
+ OPCODE_ADD, /* X X X X X */
+ OPCODE_ARA, /* 2 */
+ OPCODE_ARL, /* X X */
+ OPCODE_ARL_NV, /* 2 */
+ OPCODE_ARR, /* 2 */
+ OPCODE_BGNLOOP, /* opt */
+ OPCODE_BGNSUB, /* opt */
+ OPCODE_BRA, /* 2 X */
+ OPCODE_BRK, /* 2 opt */
+ OPCODE_BRK0, /* opt */
+ OPCODE_BRK1, /* opt */
+ OPCODE_CAL, /* 2 2 */
+ OPCODE_CMP, /* X */
+ OPCODE_CONT, /* opt */
+ OPCODE_CONT0, /* opt */
+ OPCODE_CONT1, /* opt */
+ OPCODE_COS, /* X 2 X X */
+ OPCODE_DDX, /* X X */
+ OPCODE_DDY, /* X X */
+ OPCODE_DP3, /* X X X X X */
+ OPCODE_DP4, /* X X X X X */
+ OPCODE_DPH, /* X X 1.1 */
+ OPCODE_DST, /* X X X X */
+ OPCODE_ELSE, /* X */
+ OPCODE_END, /* X X X X opt */
+ OPCODE_ENDIF, /* opt */
+ OPCODE_ENDLOOP, /* opt */
+ OPCODE_ENDSUB, /* opt */
+ OPCODE_EX2, /* X X 2 X X */
+ OPCODE_EXP, /* X X X */
+ OPCODE_FLR, /* X X 2 X X */
+ OPCODE_FRC, /* X X 2 X X */
+ OPCODE_IF, /* opt */
+ OPCODE_INT, /* X */
+ OPCODE_KIL, /* X */
+ OPCODE_KIL_NV, /* X X */
+ OPCODE_LG2, /* X X 2 X X */
+ OPCODE_LIT, /* X X X X */
+ OPCODE_LOG, /* X X X */
+ OPCODE_LRP, /* X X */
+ OPCODE_MAD, /* X X X X X */
+ OPCODE_MAX, /* X X X X X */
+ OPCODE_MIN, /* X X X X X */
+ OPCODE_MOV, /* X X X X X */
+ OPCODE_MUL, /* X X X X X */
+ OPCODE_NOISE1, /* X */
+ OPCODE_NOISE2, /* X */
+ OPCODE_NOISE3, /* X */
+ OPCODE_NOISE4, /* X */
+ OPCODE_PK2H, /* X */
+ OPCODE_PK2US, /* X */
+ OPCODE_PK4B, /* X */
+ OPCODE_PK4UB, /* X */
+ OPCODE_POW, /* X X X X */
+ OPCODE_POPA, /* 3 */
+ OPCODE_PRINT, /* X X */
+ OPCODE_PUSHA, /* 3 */
+ OPCODE_RCC, /* 1.1 */
+ OPCODE_RCP, /* X X X X X */
+ OPCODE_RET, /* 2 2 */
+ OPCODE_RFL, /* X X */
+ OPCODE_RSQ, /* X X X X X */
+ OPCODE_SCS, /* X */
+ OPCODE_SEQ, /* 2 X X */
+ OPCODE_SFL, /* 2 X */
+ OPCODE_SGE, /* X X X X X */
+ OPCODE_SGT, /* 2 X X */
+ OPCODE_SIN, /* X 2 X X */
+ OPCODE_SLE, /* 2 X X */
+ OPCODE_SLT, /* X X X X X */
+ OPCODE_SNE, /* 2 X X */
+ OPCODE_SSG, /* 2 */
+ OPCODE_STR, /* 2 X */
+ OPCODE_SUB, /* X X 1.1 X X */
+ OPCODE_SWZ, /* X X */
+ OPCODE_TEX, /* X 3 X X */
+ OPCODE_TXB, /* X 3 X */
+ OPCODE_TXD, /* X X */
+ OPCODE_TXL, /* 3 2 X */
+ OPCODE_TXP, /* X X */
+ OPCODE_TXP_NV, /* 3 X */
+ OPCODE_UP2H, /* X */
+ OPCODE_UP2US, /* X */
+ OPCODE_UP4B, /* X */
+ OPCODE_UP4UB, /* X */
+ OPCODE_X2D, /* X */
+ OPCODE_XPD, /* X X X */
+ MAX_OPCODE
+} gl_inst_opcode;
+
+
+/**
+ * Instruction source register.
+ */
+struct prog_src_register
+{
+ GLuint File:4; /**< One of the PROGRAM_* register file values. */
+ GLint Index:9; /**< May be negative for relative addressing. */
+ GLuint Swizzle:12;
+ GLuint RelAddr:1;
+
+ /**
+ * \name Source register "sign" control.
+ *
+ * The ARB and NV extensions allow varrying degrees of control over the
+ * sign of the source vector components. These values allow enough control
+ * for all flavors of the extensions.
+ */
+ /*@{*/
+ /**
+ * Per-component negation for the SWZ instruction. For non-SWZ
+ * instructions the only possible values are NEGATE_XYZW and NEGATE_NONE.
+ *
+ * \since
+ * ARB_vertex_program, ARB_fragment_program
+ */
+ GLuint NegateBase:4;
+
+ /**
+ * Take the component-wise absolute value.
+ *
+ * \since
+ * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
+ * NV_vertex_program2_option.
+ */
+ GLuint Abs:1;
+
+ /**
+ * Post-absolute value negation (all components).
+ */
+ GLuint NegateAbs:1;
+ /*@}*/
+};
+
+
+/**
+ * Instruction destination register.
+ */
+struct prog_dst_register
+{
+ /**
+ * One of the PROGRAM_* register file values.
+ */
+ GLuint File:4;
+
+ GLuint Index:8;
+ GLuint WriteMask:4;
+
+ /**
+ * \name Conditional destination update control.
+ *
+ * \since
+ * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
+ * NV_vertex_program2_option.
+ */
+ /*@{*/
+ /**
+ * Takes one of the 9 possible condition values (EQ, FL, GT, GE, LE, LT,
+ * NE, TR, or UN). Dest reg is only written to if the matching
+ * (swizzled) condition code value passes. When a conditional update mask
+ * is not specified, this will be \c COND_TR.
+ */
+ GLuint CondMask:4;
+
+ /**
+ * Condition code swizzle value.
+ */
+ GLuint CondSwizzle:12;
+
+ /**
+ * Selects the condition code register to use for conditional destination
+ * update masking. In NV_fragmnet_program or NV_vertex_program2 mode, only
+ * condition code register 0 is available. In NV_vertex_program3 mode,
+ * condition code registers 0 and 1 are available.
+ */
+ GLuint CondSrc:1;
+ /*@}*/
+
+ GLuint pad:31;
+};
+
+
+/**
+ * Vertex/fragment program instruction.
+ */
+struct prog_instruction
+{
+ gl_inst_opcode Opcode;
+#if FEATURE_MESA_program_debug
+ GLshort StringPos;
+#endif
+ /**
+ * Arbitrary data. Used for the PRINT, CAL, and BRA instructions.
+ */
+ void *Data;
+
+ struct prog_src_register SrcReg[3];
+ struct prog_dst_register DstReg;
+
+ /**
+ * Indicates that the instruction should update the condition code
+ * register.
+ *
+ * \since
+ * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
+ * NV_vertex_program2_option.
+ */
+ GLuint CondUpdate:1;
+
+ /**
+ * If prog_instruction::CondUpdate is \c GL_TRUE, this value selects the
+ * condition code register that is to be updated.
+ *
+ * In GL_NV_fragment_program or GL_NV_vertex_program2 mode, only condition
+ * code register 0 is available. In GL_NV_vertex_program3 mode, condition
+ * code registers 0 and 1 are available.
+ *
+ * \since
+ * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
+ * NV_vertex_program2_option.
+ */
+ GLuint CondDst:1;
+
+ /**
+ * Saturate each value of the vectored result to the range [0,1] or the
+ * range [-1,1]. \c SSAT mode (i.e., saturation to the range [-1,1]) is
+ * only available in NV_fragment_program2 mode.
+ * Value is one of the SATURATE_* tokens.
+ *
+ * \since
+ * NV_fragment_program, NV_fragment_program_option, NV_vertex_program3.
+ */
+ GLuint SaturateMode:2;
+
+ /**
+ * Per-instruction selectable precision.
+ *
+ * \since
+ * NV_fragment_program, NV_fragment_program_option.
+ */
+ GLuint Precision:3;
+
+ /**
+ * \name Texture source controls.
+ *
+ * The texture source controls are only used with the \c TEX, \c TXD,
+ * \c TXL, and \c TXP instructions.
+ *
+ * \since
+ * ARB_fragment_program, NV_fragment_program, NV_vertex_program3.
+ */
+ /*@{*/
+ /**
+ * Source texture unit. OpenGL supports a maximum of 32 texture
+ * units.
+ */
+ GLuint TexSrcUnit:5;
+
+ /**
+ * Source texture target, one of TEXTURE_{1D,2D,3D,CUBE,RECT}_INDEX.
+ */
+ GLuint TexSrcTarget:3;
+ /*@}*/
+
+ /**
+ * For BRA and CAL instructions, the location to jump to.
+ * For BGNLOOP, points to ENDLOOP (and vice-versa).
+ * For BRK, points to BGNLOOP (which points to ENDLOOP).
+ * For IF, points to else or endif.
+ * For ELSE, points to endif.
+ */
+ GLint BranchTarget;
+
+ /**
+ * For TEX instructions in shaders, the sampler to use for the
+ * texture lookup.
+ */
+ GLint Sampler;
+
+ const char *Comment;
+};
+
+
+extern void
+_mesa_init_instructions(struct prog_instruction *inst, GLuint count);
+
+extern struct prog_instruction *
+_mesa_alloc_instructions(GLuint numInst);
+
+extern struct prog_instruction *
+_mesa_realloc_instructions(struct prog_instruction *oldInst,
+ GLuint numOldInst, GLuint numNewInst);
+
+extern struct prog_instruction *
+_mesa_copy_instructions(struct prog_instruction *dest,
+ const struct prog_instruction *src, GLuint n);
+
+extern GLuint
+_mesa_num_inst_src_regs(gl_inst_opcode opcode);
+
+extern const char *
+_mesa_opcode_string(gl_inst_opcode opcode);
+
+
+#endif /* PROG_INSTRUCTION_H */
diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c
new file mode 100644
index 00000000000..adffafdd713
--- /dev/null
+++ b/src/mesa/shader/prog_parameter.c
@@ -0,0 +1,600 @@
+/*
+ * 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.
+ */
+
+/**
+ * \file prog_parameter.c
+ * Program parameter lists and functions.
+ * \author Brian Paul
+ */
+
+
+#include "glheader.h"
+#include "imports.h"
+#include "macros.h"
+#include "prog_instruction.h"
+#include "prog_parameter.h"
+#include "prog_statevars.h"
+
+
+struct gl_program_parameter_list *
+_mesa_new_parameter_list(void)
+{
+ return (struct gl_program_parameter_list *)
+ _mesa_calloc(sizeof(struct gl_program_parameter_list));
+}
+
+
+/**
+ * Free a parameter list and all its parameters
+ */
+void
+_mesa_free_parameter_list(struct gl_program_parameter_list *paramList)
+{
+ GLuint i;
+ for (i = 0; i < paramList->NumParameters; i++) {
+ if (paramList->Parameters[i].Name)
+ _mesa_free((void *) paramList->Parameters[i].Name);
+ }
+ _mesa_free(paramList->Parameters);
+ if (paramList->ParameterValues)
+ _mesa_align_free(paramList->ParameterValues);
+ _mesa_free(paramList);
+}
+
+
+
+/**
+ * Add a new parameter to a parameter list.
+ * Note that parameter values are usually 4-element GLfloat vectors.
+ * When size > 4 we'll allocate a sequential block of parameters to
+ * store all the values (in blocks of 4).
+ *
+ * \param paramList the list to add the parameter to
+ * \param type type of parameter, such as
+ * \param name the parameter name, will be duplicated/copied!
+ * \param size number of elements in 'values' vector (1..4, or more)
+ * \param values initial parameter value, up to 4 GLfloats, or NULL
+ * \param state state indexes, or NULL
+ * \return index of new parameter in the list, or -1 if error (out of mem)
+ */
+GLint
+_mesa_add_parameter(struct gl_program_parameter_list *paramList,
+ enum register_file type, const char *name,
+ GLuint size, const GLfloat *values,
+ const gl_state_index state[STATE_LENGTH])
+{
+ const GLuint oldNum = paramList->NumParameters;
+ const GLuint sz4 = (size + 3) / 4; /* no. of new param slots needed */
+
+ assert(size > 0);
+
+ if (oldNum + sz4 > paramList->Size) {
+ /* Need to grow the parameter list array (alloc some extra) */
+ paramList->Size = paramList->Size + 4 * sz4;
+
+ /* realloc arrays */
+ paramList->Parameters = (struct gl_program_parameter *)
+ _mesa_realloc(paramList->Parameters,
+ oldNum * sizeof(struct gl_program_parameter),
+ paramList->Size * sizeof(struct gl_program_parameter));
+
+ paramList->ParameterValues = (GLfloat (*)[4])
+ _mesa_align_realloc(paramList->ParameterValues, /* old buf */
+ oldNum * 4 * sizeof(GLfloat), /* old size */
+ paramList->Size * 4 *sizeof(GLfloat), /* new sz */
+ 16);
+ }
+
+ if (!paramList->Parameters ||
+ !paramList->ParameterValues) {
+ /* out of memory */
+ paramList->NumParameters = 0;
+ paramList->Size = 0;
+ return -1;
+ }
+ else {
+ GLuint i;
+
+ paramList->NumParameters = oldNum + sz4;
+
+ _mesa_memset(&paramList->Parameters[oldNum], 0,
+ sz4 * sizeof(struct gl_program_parameter));
+
+ for (i = 0; i < sz4; i++) {
+ struct gl_program_parameter *p = paramList->Parameters + oldNum + i;
+ p->Name = name ? _mesa_strdup(name) : NULL;
+ p->Type = type;
+ p->Size = size;
+ if (values) {
+ COPY_4V(paramList->ParameterValues[oldNum + i], values);
+ values += 4;
+ }
+ else {
+ /* silence valgrind */
+ ASSIGN_4V(paramList->ParameterValues[oldNum + i], 0, 0, 0, 0);
+ }
+ size -= 4;
+ }
+
+ if (state) {
+ for (i = 0; i < STATE_LENGTH; i++)
+ paramList->Parameters[oldNum].StateIndexes[i] = state[i];
+ }
+
+ return (GLint) oldNum;
+ }
+}
+
+
+/**
+ * Add a new named program parameter (Ex: NV_fragment_program DEFINE statement)
+ * \return index of the new entry in the parameter list
+ */
+GLint
+_mesa_add_named_parameter(struct gl_program_parameter_list *paramList,
+ const char *name, const GLfloat values[4])
+{
+ return _mesa_add_parameter(paramList, PROGRAM_NAMED_PARAM, name,
+ 4, values, NULL);
+
+}
+
+
+/**
+ * Add a new named constant to the parameter list.
+ * This will be used when the program contains something like this:
+ * PARAM myVals = { 0, 1, 2, 3 };
+ *
+ * \param paramList the parameter list
+ * \param name the name for the constant
+ * \param values four float values
+ * \return index/position of the new parameter in the parameter list
+ */
+GLint
+_mesa_add_named_constant(struct gl_program_parameter_list *paramList,
+ const char *name, const GLfloat values[4],
+ GLuint size)
+{
+#if 0 /* disable this for now -- we need to save the name! */
+ GLint pos;
+ GLuint swizzle;
+ ASSERT(size == 4); /* XXX future feature */
+ /* check if we already have this constant */
+ if (_mesa_lookup_parameter_constant(paramList, values, 4, &pos, &swizzle)) {
+ return pos;
+ }
+#endif
+ size = 4; /** XXX fix */
+ return _mesa_add_parameter(paramList, PROGRAM_CONSTANT, name,
+ size, values, NULL);
+}
+
+
+/**
+ * Add a new unnamed constant to the parameter list. This will be used
+ * when a fragment/vertex program contains something like this:
+ * MOV r, { 0, 1, 2, 3 };
+ * We'll search the parameter list for an existing instance of the
+ * constant. If swizzleOut is non-null, we'll try swizzling when
+ * looking for a match.
+ *
+ * \param paramList the parameter list
+ * \param values four float values
+ * \param swizzleOut returns swizzle mask for accessing the constant
+ * \return index/position of the new parameter in the parameter list.
+ */
+GLint
+_mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList,
+ const GLfloat values[4], GLuint size,
+ GLuint *swizzleOut)
+{
+ GLint pos;
+ ASSERT(size >= 1);
+ ASSERT(size <= 4);
+
+ if (_mesa_lookup_parameter_constant(paramList, values,
+ size, &pos, swizzleOut)) {
+ return pos;
+ }
+
+ /* Look for empty space in an already unnamed constant parameter
+ * to add this constant. This will only work for single-element
+ * constants because we rely on smearing (i.e. .yyyy or .zzzz).
+ */
+ if (size == 1 && swizzleOut) {
+ for (pos = 0; pos < (GLint) paramList->NumParameters; pos++) {
+ struct gl_program_parameter *p = paramList->Parameters + pos;
+ if (p->Type == PROGRAM_CONSTANT && p->Size + size <= 4) {
+ /* ok, found room */
+ GLfloat *pVal = paramList->ParameterValues[pos];
+ GLuint swz = p->Size; /* 1, 2 or 3 for Y, Z, W */
+ pVal[p->Size] = values[0];
+ p->Size++;
+ *swizzleOut = MAKE_SWIZZLE4(swz, swz, swz, swz);
+ return pos;
+ }
+ }
+ }
+
+ /* add a new parameter to store this constant */
+ pos = _mesa_add_parameter(paramList, PROGRAM_CONSTANT, NULL,
+ size, values, NULL);
+ if (pos >= 0 && swizzleOut) {
+ if (size == 1)
+ *swizzleOut = SWIZZLE_XXXX;
+ else
+ *swizzleOut = SWIZZLE_NOOP;
+ }
+ return pos;
+}
+
+
+GLint
+_mesa_add_uniform(struct gl_program_parameter_list *paramList,
+ const char *name, GLuint size)
+{
+ GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
+ if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_UNIFORM) {
+ /* already in list */
+ return i;
+ }
+ else {
+ i = _mesa_add_parameter(paramList, PROGRAM_UNIFORM, name,
+ size, NULL, NULL);
+
+ return i;
+ }
+}
+
+
+GLint
+_mesa_add_sampler(struct gl_program_parameter_list *paramList,
+ const char *name)
+{
+ GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
+ if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_SAMPLER) {
+ /* already in list */
+ return i;
+ }
+ else {
+ const GLint size = 1;
+ i = _mesa_add_parameter(paramList, PROGRAM_SAMPLER, name,
+ size, NULL, NULL);
+ return i;
+ }
+}
+
+
+/**
+ * Add parameter representing a varying variable.
+ */
+GLint
+_mesa_add_varying(struct gl_program_parameter_list *paramList,
+ const char *name, GLuint size)
+{
+ GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
+ if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_VARYING) {
+ /* already in list */
+ return i;
+ }
+ else {
+ assert(size == 4);
+ i = _mesa_add_parameter(paramList, PROGRAM_VARYING, name,
+ size, NULL, NULL);
+ return i;
+ }
+}
+
+
+/**
+ * Add parameter representing a vertex program attribute.
+ * \param size size of attribute (in floats), may be -1 if unknown
+ * \param attrib the attribute index, or -1 if unknown
+ */
+GLint
+_mesa_add_attribute(struct gl_program_parameter_list *paramList,
+ const char *name, GLint size, GLint attrib)
+{
+ GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
+ if (i >= 0) {
+ /* replace */
+ if (attrib < 0)
+ attrib = i;
+ paramList->Parameters[i].StateIndexes[0] = attrib;
+ }
+ else {
+ /* add */
+ gl_state_index state[STATE_LENGTH];
+ state[0] = (gl_state_index) attrib;
+ if (size < 0)
+ size = 4;
+ i = _mesa_add_parameter(paramList, PROGRAM_INPUT, name,
+ size, NULL, state);
+ }
+ return i;
+}
+
+
+
+#if 0 /* not used yet */
+/**
+ * Returns the number of 4-component registers needed to store a piece
+ * of GL state. For matrices this may be as many as 4 registers,
+ * everything else needs
+ * just 1 register.
+ */
+static GLuint
+sizeof_state_reference(const GLint *stateTokens)
+{
+ if (stateTokens[0] == STATE_MATRIX) {
+ GLuint rows = stateTokens[4] - stateTokens[3] + 1;
+ assert(rows >= 1);
+ assert(rows <= 4);
+ return rows;
+ }
+ else {
+ return 1;
+ }
+}
+#endif
+
+
+/**
+ * Add a new state reference to the parameter list.
+ * This will be used when the program contains something like this:
+ * PARAM ambient = state.material.front.ambient;
+ *
+ * \param paramList the parameter list
+ * \param state an array of 6 (STATE_LENGTH) state tokens
+ * \return index of the new parameter.
+ */
+GLint
+_mesa_add_state_reference(struct gl_program_parameter_list *paramList,
+ const gl_state_index stateTokens[STATE_LENGTH])
+{
+ const GLuint size = 4; /* XXX fix */
+ const char *name;
+ GLint index;
+
+ /* Check if the state reference is already in the list */
+ for (index = 0; index < (GLint) paramList->NumParameters; index++) {
+ GLuint i, match = 0;
+ for (i = 0; i < STATE_LENGTH; i++) {
+ if (paramList->Parameters[index].StateIndexes[i] == stateTokens[i]) {
+ match++;
+ }
+ else {
+ break;
+ }
+ }
+ if (match == STATE_LENGTH) {
+ /* this state reference is already in the parameter list */
+ return index;
+ }
+ }
+
+ name = _mesa_program_state_string(stateTokens);
+ index = _mesa_add_parameter(paramList, PROGRAM_STATE_VAR, name,
+ size, NULL, (gl_state_index *) stateTokens);
+ paramList->StateFlags |= _mesa_program_state_flags(stateTokens);
+
+ /* free name string here since we duplicated it in add_parameter() */
+ _mesa_free((void *) name);
+
+ return index;
+}
+
+
+/**
+ * Lookup a parameter value by name in the given parameter list.
+ * \return pointer to the float[4] values.
+ */
+GLfloat *
+_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList,
+ GLsizei nameLen, const char *name)
+{
+ GLuint i = _mesa_lookup_parameter_index(paramList, nameLen, name);
+ if (i < 0)
+ return NULL;
+ else
+ return paramList->ParameterValues[i];
+}
+
+
+/**
+ * Given a program parameter name, find its position in the list of parameters.
+ * \param paramList the parameter list to search
+ * \param nameLen length of name (in chars).
+ * If length is negative, assume that name is null-terminated.
+ * \param name the name to search for
+ * \return index of parameter in the list.
+ */
+GLint
+_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList,
+ GLsizei nameLen, const char *name)
+{
+ GLint i;
+
+ if (!paramList)
+ return -1;
+
+ if (nameLen == -1) {
+ /* name is null-terminated */
+ for (i = 0; i < (GLint) paramList->NumParameters; i++) {
+ if (paramList->Parameters[i].Name &&
+ _mesa_strcmp(paramList->Parameters[i].Name, name) == 0)
+ return i;
+ }
+ }
+ else {
+ /* name is not null-terminated, use nameLen */
+ for (i = 0; i < (GLint) paramList->NumParameters; i++) {
+ if (paramList->Parameters[i].Name &&
+ _mesa_strncmp(paramList->Parameters[i].Name, name, nameLen) == 0
+ && _mesa_strlen(paramList->Parameters[i].Name) == (size_t)nameLen)
+ return i;
+ }
+ }
+ return -1;
+}
+
+
+/**
+ * Look for a float vector in the given parameter list. The float vector
+ * may be of length 1, 2, 3 or 4. If swizzleOut is non-null, we'll try
+ * swizzling to find a match.
+ * \param list the parameter list to search
+ * \param v the float vector to search for
+ * \param size number of element in v
+ * \param posOut returns the position of the constant, if found
+ * \param swizzleOut returns a swizzle mask describing location of the
+ * vector elements if found.
+ * \return GL_TRUE if found, GL_FALSE if not found
+ */
+GLboolean
+_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list,
+ const GLfloat v[], GLuint vSize,
+ GLint *posOut, GLuint *swizzleOut)
+{
+ GLuint i;
+
+ assert(vSize >= 1);
+ assert(vSize <= 4);
+
+ if (!list)
+ return -1;
+
+ for (i = 0; i < list->NumParameters; i++) {
+ if (list->Parameters[i].Type == PROGRAM_CONSTANT) {
+ if (!swizzleOut) {
+ /* swizzle not allowed */
+ GLuint j, match = 0;
+ for (j = 0; j < vSize; j++) {
+ if (v[j] == list->ParameterValues[i][j])
+ match++;
+ }
+ if (match == vSize) {
+ *posOut = i;
+ return GL_TRUE;
+ }
+ }
+ else {
+ /* try matching w/ swizzle */
+ if (vSize == 1) {
+ /* look for v[0] anywhere within float[4] value */
+ GLuint j;
+ for (j = 0; j < 4; j++) {
+ if (list->ParameterValues[i][j] == v[0]) {
+ /* found it */
+ *posOut = i;
+ *swizzleOut = MAKE_SWIZZLE4(j, j, j, j);
+ return GL_TRUE;
+ }
+ }
+ }
+ else if (vSize <= list->Parameters[i].Size) {
+ /* see if we can match this constant (with a swizzle) */
+ GLuint swz[4];
+ GLuint match = 0, j, k;
+ for (j = 0; j < vSize; j++) {
+ if (v[j] == list->ParameterValues[i][j]) {
+ swz[j] = j;
+ match++;
+ }
+ else {
+ for (k = 0; k < list->Parameters[i].Size; k++) {
+ if (v[j] == list->ParameterValues[i][k]) {
+ swz[j] = k;
+ match++;
+ break;
+ }
+ }
+ }
+ }
+ if (match == vSize) {
+ *posOut = i;
+ *swizzleOut = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
+ return GL_TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ *posOut = -1;
+ return GL_FALSE;
+}
+
+
+struct gl_program_parameter_list *
+_mesa_clone_parameter_list(const struct gl_program_parameter_list *list)
+{
+ struct gl_program_parameter_list *clone;
+ GLuint i;
+
+ clone = _mesa_new_parameter_list();
+ if (!clone)
+ return NULL;
+
+ /** Not too efficient, but correct */
+ for (i = 0; i < list->NumParameters; i++) {
+ struct gl_program_parameter *p = list->Parameters + i;
+ GLuint size = MIN2(p->Size, 4);
+ GLint j = _mesa_add_parameter(clone, p->Type, p->Name,
+ size, list->ParameterValues[i], NULL);
+ ASSERT(j >= 0);
+ /* copy state indexes */
+ if (p->Type == PROGRAM_STATE_VAR) {
+ GLint k;
+ struct gl_program_parameter *q = clone->Parameters + j;
+ for (k = 0; k < STATE_LENGTH; k++) {
+ q->StateIndexes[k] = p->StateIndexes[k];
+ }
+ }
+ else {
+ clone->Parameters[j].Size = p->Size;
+ }
+ }
+
+ return clone;
+}
+
+
+/**
+ * Find longest name of any parameter in list.
+ */
+GLuint
+_mesa_parameter_longest_name(const struct gl_program_parameter_list *list)
+{
+ GLuint i, maxLen = 0;
+ if (!list)
+ return 0;
+ for (i = 0; i < list->NumParameters; i++) {
+ GLuint len = _mesa_strlen(list->Parameters[i].Name);
+ if (len > maxLen)
+ maxLen = len;
+ }
+ return maxLen;
+}
+
diff --git a/src/mesa/shader/prog_parameter.h b/src/mesa/shader/prog_parameter.h
new file mode 100644
index 00000000000..3d32a64f383
--- /dev/null
+++ b/src/mesa/shader/prog_parameter.h
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+/**
+ * \file prog_parameter.c
+ * Program parameter lists and functions.
+ * \author Brian Paul
+ */
+
+#ifndef PROG_PARAMETER_H
+#define PROG_PARAMETER_H
+
+#include "mtypes.h"
+#include "prog_statevars.h"
+
+
+/**
+ * Program parameter.
+ * Used for NV_fragment_program for "DEFINE"d constants and "DECLARE"d
+ * parameters.
+ * Also used by ARB_vertex/fragment_programs for state variables, etc.
+ * Used by shaders for uniforms, constants, varying vars, etc.
+ */
+struct gl_program_parameter
+{
+ const char *Name; /**< Null-terminated string */
+ enum register_file Type; /**< PROGRAM_NAMED_PARAM, CONSTANT or STATE_VAR */
+ GLuint Size; /**< Number of components (1..4) */
+ /**
+ * A sequence of STATE_* tokens and integers to identify GL state.
+ */
+ gl_state_index StateIndexes[STATE_LENGTH];
+};
+
+
+/**
+ * List of gl_program_parameter instances.
+ */
+struct gl_program_parameter_list
+{
+ GLuint Size; /**< allocated size of Parameters, ParameterValues */
+ GLuint NumParameters; /**< number of parameters in arrays */
+ struct gl_program_parameter *Parameters; /**< Array [Size] */
+ GLfloat (*ParameterValues)[4]; /**< Array [Size] of GLfloat[4] */
+ GLbitfield StateFlags; /**< _NEW_* flags indicating which state changes
+ might invalidate ParameterValues[] */
+};
+
+
+extern struct gl_program_parameter_list *
+_mesa_new_parameter_list(void);
+
+extern void
+_mesa_free_parameter_list(struct gl_program_parameter_list *paramList);
+
+extern struct gl_program_parameter_list *
+_mesa_clone_parameter_list(const struct gl_program_parameter_list *list);
+
+extern GLint
+_mesa_add_parameter(struct gl_program_parameter_list *paramList,
+ enum register_file type, const char *name,
+ GLuint size, const GLfloat *values,
+ const gl_state_index state[STATE_LENGTH]);
+
+extern GLint
+_mesa_add_named_parameter(struct gl_program_parameter_list *paramList,
+ const char *name, const GLfloat values[4]);
+
+extern GLint
+_mesa_add_named_constant(struct gl_program_parameter_list *paramList,
+ const char *name, const GLfloat values[4],
+ GLuint size);
+
+extern GLint
+_mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList,
+ const GLfloat values[4], GLuint size,
+ GLuint *swizzleOut);
+
+extern GLint
+_mesa_add_uniform(struct gl_program_parameter_list *paramList,
+ const char *name, GLuint size);
+
+extern GLint
+_mesa_add_sampler(struct gl_program_parameter_list *paramList,
+ const char *name);
+
+extern GLint
+_mesa_add_varying(struct gl_program_parameter_list *paramList,
+ const char *name, GLuint size);
+
+extern GLint
+_mesa_add_attribute(struct gl_program_parameter_list *paramList,
+ const char *name, GLint size, GLint attrib);
+
+extern GLint
+_mesa_add_state_reference(struct gl_program_parameter_list *paramList,
+ const gl_state_index stateTokens[STATE_LENGTH]);
+
+extern GLfloat *
+_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList,
+ GLsizei nameLen, const char *name);
+
+extern GLint
+_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList,
+ GLsizei nameLen, const char *name);
+
+extern GLboolean
+_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list,
+ const GLfloat v[], GLuint vSize,
+ GLint *posOut, GLuint *swizzleOut);
+
+extern GLuint
+_mesa_parameter_longest_name(const struct gl_program_parameter_list *list);
+
+#endif /* PROG_PARAMETER_H */
diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c
new file mode 100644
index 00000000000..3f7ad47e05e
--- /dev/null
+++ b/src/mesa/shader/prog_print.c
@@ -0,0 +1,749 @@
+/*
+ * 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.
+ */
+
+/**
+ * \file prog_print.c
+ * Print vertex/fragment programs - for debugging.
+ * \author Brian Paul
+ */
+
+#include "glheader.h"
+#include "context.h"
+#include "imports.h"
+#include "prog_instruction.h"
+#include "prog_parameter.h"
+#include "prog_print.h"
+#include "prog_statevars.h"
+
+
+
+/**
+ * Return string name for given program/register file.
+ */
+static const char *
+file_string(enum register_file f, gl_prog_print_mode mode)
+{
+ switch (f) {
+ case PROGRAM_TEMPORARY:
+ return "TEMP";
+ case PROGRAM_LOCAL_PARAM:
+ return "LOCAL";
+ case PROGRAM_ENV_PARAM:
+ return "ENV";
+ case PROGRAM_STATE_VAR:
+ return "STATE";
+ case PROGRAM_INPUT:
+ return "INPUT";
+ case PROGRAM_OUTPUT:
+ return "OUTPUT";
+ case PROGRAM_NAMED_PARAM:
+ return "NAMED";
+ case PROGRAM_CONSTANT:
+ return "CONST";
+ case PROGRAM_UNIFORM:
+ return "UNIFORM";
+ case PROGRAM_VARYING:
+ return "VARYING";
+ case PROGRAM_WRITE_ONLY:
+ return "WRITE_ONLY";
+ case PROGRAM_ADDRESS:
+ return "ADDR";
+ case PROGRAM_SAMPLER:
+ return "SAMPLER";
+ default:
+ return "Unknown program file!";
+ }
+}
+
+
+/**
+ * Return ARB_v/f_prog-style input attrib string.
+ */
+static const char *
+arb_input_attrib_string(GLint index, GLenum progType)
+{
+ const char *vertAttribs[] = {
+ "vertex.position",
+ "vertex.weight",
+ "vertex.normal",
+ "vertex.color.primary",
+ "vertex.color.secondary",
+ "vertex.fogcoord",
+ "vertex.(six)",
+ "vertex.(seven)",
+ "vertex.texcoord[0]",
+ "vertex.texcoord[1]",
+ "vertex.texcoord[2]",
+ "vertex.texcoord[3]",
+ "vertex.texcoord[4]",
+ "vertex.texcoord[5]",
+ "vertex.texcoord[6]",
+ "vertex.texcoord[7]"
+ };
+ const char *fragAttribs[] = {
+ "fragment.position",
+ "fragment.color.primary",
+ "fragment.color.secondary",
+ "fragment.fogcoord",
+ "fragment.texcoord[0]",
+ "fragment.texcoord[1]",
+ "fragment.texcoord[2]",
+ "fragment.texcoord[3]",
+ "fragment.texcoord[4]",
+ "fragment.texcoord[5]",
+ "fragment.texcoord[6]",
+ "fragment.texcoord[7]",
+ "fragment.varying[0]",
+ "fragment.varying[1]",
+ "fragment.varying[2]",
+ "fragment.varying[3]",
+ "fragment.varying[4]",
+ "fragment.varying[5]",
+ "fragment.varying[6]",
+ "fragment.varying[7]"
+ };
+
+ if (progType == GL_VERTEX_PROGRAM_ARB) {
+ assert(index < sizeof(vertAttribs) / sizeof(vertAttribs[0]));
+ return vertAttribs[index];
+ }
+ else {
+ assert(index < sizeof(fragAttribs) / sizeof(fragAttribs[0]));
+ return fragAttribs[index];
+ }
+}
+
+
+/**
+ * Return ARB_v/f_prog-style output attrib string.
+ */
+static const char *
+arb_output_attrib_string(GLint index, GLenum progType)
+{
+ const char *vertResults[] = {
+ "result.position",
+ "result.color.primary",
+ "result.color.secondary",
+ "result.fogcoord",
+ "result.texcoord[0]",
+ "result.texcoord[1]",
+ "result.texcoord[2]",
+ "result.texcoord[3]",
+ "result.texcoord[4]",
+ "result.texcoord[5]",
+ "result.texcoord[6]",
+ "result.texcoord[7]",
+ "result.varying[0]",
+ "result.varying[1]",
+ "result.varying[2]",
+ "result.varying[3]",
+ "result.varying[4]",
+ "result.varying[5]",
+ "result.varying[6]",
+ "result.varying[7]"
+ };
+ const char *fragResults[] = {
+ "result.color",
+ "result.depth"
+ };
+
+ if (progType == GL_VERTEX_PROGRAM_ARB) {
+ assert(index < sizeof(vertResults) / sizeof(vertResults[0]));
+ return vertResults[index];
+ }
+ else {
+ assert(index < sizeof(fragResults) / sizeof(fragResults[0]));
+ return fragResults[index];
+ }
+}
+
+
+/**
+ * Return string representation of the given register.
+ * Note that some types of registers (like PROGRAM_UNIFORM) aren't defined
+ * by the ARB/NV program languages so we've taken some liberties here.
+ * \param file the register file (PROGRAM_INPUT, PROGRAM_TEMPORARY, etc)
+ * \param index number of the register in the register file
+ * \param mode the output format/mode/style
+ * \param prog pointer to containing program
+ */
+static const char *
+reg_string(enum register_file f, GLint index, gl_prog_print_mode mode,
+ const struct gl_program *prog)
+{
+ static char str[100];
+
+ str[0] = 0;
+
+ switch (mode) {
+ case PROG_PRINT_DEBUG:
+ sprintf(str, "%s[%d]", file_string(f, mode), index);
+ break;
+
+ case PROG_PRINT_ARB:
+ switch (f) {
+ case PROGRAM_INPUT:
+ sprintf(str, "%s", arb_input_attrib_string(index, prog->Target));
+ break;
+ case PROGRAM_OUTPUT:
+ sprintf(str, "%s", arb_output_attrib_string(index, prog->Target));
+ break;
+ case PROGRAM_TEMPORARY:
+ sprintf(str, "temp%d", index);
+ break;
+ case PROGRAM_ENV_PARAM:
+ sprintf(str, "program.env[%d]", index);
+ break;
+ case PROGRAM_LOCAL_PARAM:
+ sprintf(str, "program.local[%d]", index);
+ break;
+ case PROGRAM_VARYING: /* extension */
+ sprintf(str, "varying[%d]", index);
+ break;
+ case PROGRAM_CONSTANT: /* extension */
+ sprintf(str, "constant[%d]", index);
+ break;
+ case PROGRAM_UNIFORM: /* extension */
+ sprintf(str, "uniform[%d]", index);
+ break;
+ case PROGRAM_STATE_VAR:
+ {
+ struct gl_program_parameter *param
+ = prog->Parameters->Parameters + index;
+ sprintf(str, _mesa_program_state_string(param->StateIndexes));
+ }
+ break;
+ case PROGRAM_ADDRESS:
+ sprintf(str, "A%d", index);
+ break;
+ default:
+ _mesa_problem(NULL, "bad file in reg_string()");
+ }
+ break;
+
+ case PROG_PRINT_NV:
+ switch (f) {
+ case PROGRAM_INPUT:
+ if (prog->Target == GL_VERTEX_PROGRAM_ARB)
+ sprintf(str, "v[%d]", index);
+ else
+ sprintf(str, "f[%d]", index);
+ break;
+ case PROGRAM_OUTPUT:
+ sprintf(str, "o[%d]", index);
+ break;
+ case PROGRAM_TEMPORARY:
+ sprintf(str, "R%d", index);
+ break;
+ case PROGRAM_ENV_PARAM:
+ sprintf(str, "c[%d]", index);
+ break;
+ case PROGRAM_VARYING: /* extension */
+ sprintf(str, "varying[%d]", index);
+ break;
+ case PROGRAM_UNIFORM: /* extension */
+ sprintf(str, "uniform[%d]", index);
+ break;
+ case PROGRAM_CONSTANT: /* extension */
+ sprintf(str, "constant[%d]", index);
+ break;
+ case PROGRAM_STATE_VAR: /* extension */
+ sprintf(str, "state[%d]", index);
+ break;
+ default:
+ _mesa_problem(NULL, "bad file in reg_string()");
+ }
+ break;
+
+ default:
+ _mesa_problem(NULL, "bad mode in reg_string()");
+ }
+
+ return str;
+}
+
+
+/**
+ * Return a string representation of the given swizzle word.
+ * If extended is true, use extended (comma-separated) format.
+ * \param swizzle the swizzle field
+ * \param negateBase 4-bit negation vector
+ * \param extended if true, also allow 0, 1 values
+ */
+const char *
+_mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended)
+{
+ static const char swz[] = "xyzw01?!";
+ static char s[20];
+ GLuint i = 0;
+
+ if (!extended && swizzle == SWIZZLE_NOOP && negateBase == 0)
+ return ""; /* no swizzle/negation */
+
+ if (!extended)
+ s[i++] = '.';
+
+ if (negateBase & 0x1)
+ s[i++] = '-';
+ s[i++] = swz[GET_SWZ(swizzle, 0)];
+
+ if (extended) {
+ s[i++] = ',';
+ }
+
+ if (negateBase & 0x2)
+ s[i++] = '-';
+ s[i++] = swz[GET_SWZ(swizzle, 1)];
+
+ if (extended) {
+ s[i++] = ',';
+ }
+
+ if (negateBase & 0x4)
+ s[i++] = '-';
+ s[i++] = swz[GET_SWZ(swizzle, 2)];
+
+ if (extended) {
+ s[i++] = ',';
+ }
+
+ if (negateBase & 0x8)
+ s[i++] = '-';
+ s[i++] = swz[GET_SWZ(swizzle, 3)];
+
+ s[i] = 0;
+ return s;
+}
+
+
+static const char *
+writemask_string(GLuint writeMask)
+{
+ static char s[10];
+ GLuint i = 0;
+
+ if (writeMask == WRITEMASK_XYZW)
+ return "";
+
+ s[i++] = '.';
+ if (writeMask & WRITEMASK_X)
+ s[i++] = 'x';
+ if (writeMask & WRITEMASK_Y)
+ s[i++] = 'y';
+ if (writeMask & WRITEMASK_Z)
+ s[i++] = 'z';
+ if (writeMask & WRITEMASK_W)
+ s[i++] = 'w';
+
+ s[i] = 0;
+ return s;
+}
+
+
+static const char *
+condcode_string(GLuint condcode)
+{
+ switch (condcode) {
+ case COND_GT: return "GT";
+ case COND_EQ: return "EQ";
+ case COND_LT: return "LT";
+ case COND_UN: return "UN";
+ case COND_GE: return "GE";
+ case COND_LE: return "LE";
+ case COND_NE: return "NE";
+ case COND_TR: return "TR";
+ case COND_FL: return "FL";
+ default: return "cond???";
+ }
+}
+
+
+static void
+print_dst_reg(const struct prog_dst_register *dstReg, gl_prog_print_mode mode,
+ const struct gl_program *prog)
+{
+ _mesa_printf("%s%s",
+ reg_string((enum register_file) dstReg->File,
+ dstReg->Index, mode, prog),
+ writemask_string(dstReg->WriteMask));
+
+ if (dstReg->CondMask != COND_TR) {
+ _mesa_printf(" (%s.%s)",
+ condcode_string(dstReg->CondMask),
+ _mesa_swizzle_string(dstReg->CondSwizzle, GL_FALSE, GL_FALSE));
+ }
+
+#if 0
+ _mesa_printf("%s[%d]%s",
+ file_string((enum register_file) dstReg->File, mode),
+ dstReg->Index,
+ writemask_string(dstReg->WriteMask));
+#endif
+}
+
+static void
+print_src_reg(const struct prog_src_register *srcReg, gl_prog_print_mode mode,
+ const struct gl_program *prog)
+{
+ _mesa_printf("%s%s",
+ reg_string((enum register_file) srcReg->File,
+ srcReg->Index, mode, prog),
+ _mesa_swizzle_string(srcReg->Swizzle,
+ srcReg->NegateBase, GL_FALSE));
+#if 0
+ _mesa_printf("%s[%d]%s",
+ file_string((enum register_file) srcReg->File, mode),
+ srcReg->Index,
+ _mesa_swizzle_string(srcReg->Swizzle,
+ srcReg->NegateBase, GL_FALSE));
+#endif
+}
+
+static void
+print_comment(const struct prog_instruction *inst)
+{
+ if (inst->Comment)
+ _mesa_printf("; # %s\n", inst->Comment);
+ else
+ _mesa_printf(";\n");
+}
+
+
+static void
+print_alu_instruction(const struct prog_instruction *inst,
+ const char *opcode_string, GLuint numRegs,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog)
+{
+ GLuint j;
+
+ _mesa_printf("%s", opcode_string);
+ if (inst->CondUpdate)
+ _mesa_printf(".C");
+
+ /* frag prog only */
+ if (inst->SaturateMode == SATURATE_ZERO_ONE)
+ _mesa_printf("_SAT");
+
+ _mesa_printf(" ");
+ if (inst->DstReg.File != PROGRAM_UNDEFINED) {
+ print_dst_reg(&inst->DstReg, mode, prog);
+ }
+ else {
+ _mesa_printf(" ???");
+ }
+
+ if (numRegs > 0)
+ _mesa_printf(", ");
+
+ for (j = 0; j < numRegs; j++) {
+ print_src_reg(inst->SrcReg + j, mode, prog);
+ if (j + 1 < numRegs)
+ _mesa_printf(", ");
+ }
+
+ print_comment(inst);
+}
+
+
+void
+_mesa_print_alu_instruction(const struct prog_instruction *inst,
+ const char *opcode_string, GLuint numRegs)
+{
+ print_alu_instruction(inst, opcode_string, numRegs, PROG_PRINT_DEBUG, NULL);
+}
+
+
+void
+_mesa_print_instruction(const struct prog_instruction *inst)
+{
+ /* note: 4th param should be ignored for PROG_PRINT_DEBUG */
+ _mesa_print_instruction_opt(inst, 0, PROG_PRINT_DEBUG, NULL);
+}
+
+
+/**
+ * Print a single vertex/fragment program instruction.
+ */
+GLint
+_mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog)
+{
+ GLint i;
+
+ if (inst->Opcode == OPCODE_ELSE ||
+ inst->Opcode == OPCODE_ENDIF ||
+ inst->Opcode == OPCODE_ENDLOOP ||
+ inst->Opcode == OPCODE_ENDSUB) {
+ indent -= 3;
+ }
+ for (i = 0; i < indent; i++) {
+ _mesa_printf(" ");
+ }
+
+ switch (inst->Opcode) {
+ case OPCODE_PRINT:
+ _mesa_printf("PRINT '%s'", inst->Data);
+ if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
+ _mesa_printf(", ");
+ _mesa_printf("%s[%d]%s",
+ file_string((enum register_file) inst->SrcReg[0].File,
+ mode),
+ inst->SrcReg[0].Index,
+ _mesa_swizzle_string(inst->SrcReg[0].Swizzle,
+ inst->SrcReg[0].NegateBase, GL_FALSE));
+ }
+ if (inst->Comment)
+ _mesa_printf(" # %s", inst->Comment);
+ print_comment(inst);
+ break;
+ case OPCODE_SWZ:
+ _mesa_printf("SWZ");
+ if (inst->SaturateMode == SATURATE_ZERO_ONE)
+ _mesa_printf("_SAT");
+ _mesa_printf(" ");
+ print_dst_reg(&inst->DstReg, mode, prog);
+ _mesa_printf("%s[%d], %s",
+ file_string((enum register_file) inst->SrcReg[0].File,
+ mode),
+ inst->SrcReg[0].Index,
+ _mesa_swizzle_string(inst->SrcReg[0].Swizzle,
+ inst->SrcReg[0].NegateBase, GL_TRUE));
+ print_comment(inst);
+ break;
+ case OPCODE_TEX:
+ case OPCODE_TXP:
+ case OPCODE_TXB:
+ _mesa_printf("%s", _mesa_opcode_string(inst->Opcode));
+ if (inst->SaturateMode == SATURATE_ZERO_ONE)
+ _mesa_printf("_SAT");
+ _mesa_printf(" ");
+ print_dst_reg(&inst->DstReg, mode, prog);
+ _mesa_printf(", ");
+ print_src_reg(&inst->SrcReg[0], mode, prog);
+ _mesa_printf(", texture[%d], ", inst->TexSrcUnit);
+ switch (inst->TexSrcTarget) {
+ case TEXTURE_1D_INDEX: _mesa_printf("1D"); break;
+ case TEXTURE_2D_INDEX: _mesa_printf("2D"); break;
+ case TEXTURE_3D_INDEX: _mesa_printf("3D"); break;
+ case TEXTURE_CUBE_INDEX: _mesa_printf("CUBE"); break;
+ case TEXTURE_RECT_INDEX: _mesa_printf("RECT"); break;
+ default:
+ ;
+ }
+ print_comment(inst);
+ break;
+ case OPCODE_ARL:
+ _mesa_printf("ARL addr.x, ");
+ print_src_reg(&inst->SrcReg[0], mode, prog);
+ print_comment(inst);
+ break;
+ case OPCODE_BRA:
+ _mesa_printf("BRA %u (%s%s)",
+ inst->BranchTarget,
+ condcode_string(inst->DstReg.CondMask),
+ _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
+ print_comment(inst);
+ break;
+ case OPCODE_CAL:
+ _mesa_printf("CAL %u", inst->BranchTarget);
+ print_comment(inst);
+ break;
+ case OPCODE_IF:
+ if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
+ /* Use ordinary register */
+ _mesa_printf("IF ");
+ print_src_reg(&inst->SrcReg[0], mode, prog);
+ _mesa_printf("; ");
+ }
+ else {
+ /* Use cond codes */
+ _mesa_printf("IF (%s%s);",
+ condcode_string(inst->DstReg.CondMask),
+ _mesa_swizzle_string(inst->DstReg.CondSwizzle,
+ 0, GL_FALSE));
+ }
+ _mesa_printf(" # (if false, goto %d)", inst->BranchTarget);
+ print_comment(inst);
+ return indent + 3;
+ case OPCODE_ELSE:
+ _mesa_printf("ELSE; # (goto %d)\n", inst->BranchTarget);
+ return indent + 3;
+ case OPCODE_ENDIF:
+ _mesa_printf("ENDIF;\n");
+ break;
+ case OPCODE_BGNLOOP:
+ _mesa_printf("BGNLOOP; # (end at %d)\n", inst->BranchTarget);
+ return indent + 3;
+ case OPCODE_ENDLOOP:
+ _mesa_printf("ENDLOOP; # (goto %d)\n", inst->BranchTarget);
+ break;
+ case OPCODE_BRK:
+ case OPCODE_CONT:
+ _mesa_printf("%s (%s%s); # (goto %d)",
+ _mesa_opcode_string(inst->Opcode),
+ condcode_string(inst->DstReg.CondMask),
+ _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE),
+ inst->BranchTarget);
+ print_comment(inst);
+ break;
+
+ case OPCODE_BRK0:
+ case OPCODE_BRK1:
+ case OPCODE_CONT0:
+ case OPCODE_CONT1:
+ _mesa_printf("%s ", _mesa_opcode_string(inst->Opcode));
+ print_src_reg(&inst->SrcReg[0], mode, prog);
+ _mesa_printf("; ");
+ _mesa_printf(" # (goto %d)", inst->BranchTarget);
+ print_comment(inst);
+ break;
+
+ case OPCODE_BGNSUB:
+ _mesa_printf("SUB");
+ print_comment(inst);
+ return indent + 3;
+ case OPCODE_ENDSUB:
+ _mesa_printf("ENDSUB");
+ print_comment(inst);
+ break;
+ case OPCODE_END:
+ _mesa_printf("END\n");
+ break;
+ case OPCODE_NOP:
+ if (mode == PROG_PRINT_DEBUG) {
+ _mesa_printf("NOP");
+ print_comment(inst);
+ }
+ else if (inst->Comment) {
+ /* ARB/NV extensions don't have NOP instruction */
+ _mesa_printf("# %s\n", inst->Comment);
+ }
+ break;
+ /* XXX may need other special-case instructions */
+ default:
+ /* typical alu instruction */
+ print_alu_instruction(inst,
+ _mesa_opcode_string(inst->Opcode),
+ _mesa_num_inst_src_regs(inst->Opcode),
+ mode, prog);
+ break;
+ }
+ return indent;
+}
+
+
+/**
+ * Print program to stdout, default options.
+ */
+void
+_mesa_print_program(const struct gl_program *prog)
+{
+ _mesa_print_program_opt(prog, PROG_PRINT_DEBUG, GL_TRUE);
+}
+
+
+/**
+ * Print program, with options.
+ */
+void
+_mesa_print_program_opt(const struct gl_program *prog,
+ gl_prog_print_mode mode,
+ GLboolean lineNumbers)
+{
+ GLuint i, indent = 0;
+
+ switch (prog->Target) {
+ case GL_VERTEX_PROGRAM_ARB:
+ if (mode == PROG_PRINT_ARB)
+ _mesa_printf("!!ARBvp1.0\n");
+ else if (mode == PROG_PRINT_NV)
+ _mesa_printf("!!VP1.0\n");
+ else
+ _mesa_printf("# Vertex Program/Shader\n");
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ case GL_FRAGMENT_PROGRAM_NV:
+ if (mode == PROG_PRINT_ARB)
+ _mesa_printf("!!ARBfp1.0\n");
+ else if (mode == PROG_PRINT_NV)
+ _mesa_printf("!!FP1.0\n");
+ else
+ _mesa_printf("# Fragment Program/Shader\n");
+ break;
+ }
+
+ for (i = 0; i < prog->NumInstructions; i++) {
+ if (lineNumbers)
+ _mesa_printf("%3d: ", i);
+ indent = _mesa_print_instruction_opt(prog->Instructions + i,
+ indent, mode, prog);
+ }
+}
+
+
+/**
+ * Print all of a program's parameters.
+ */
+void
+_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog)
+{
+ _mesa_printf("InputsRead: 0x%x\n", prog->InputsRead);
+ _mesa_printf("OutputsWritten: 0x%x\n", prog->OutputsWritten);
+ _mesa_printf("NumInstructions=%d\n", prog->NumInstructions);
+ _mesa_printf("NumTemporaries=%d\n", prog->NumTemporaries);
+ _mesa_printf("NumParameters=%d\n", prog->NumParameters);
+ _mesa_printf("NumAttributes=%d\n", prog->NumAttributes);
+ _mesa_printf("NumAddressRegs=%d\n", prog->NumAddressRegs);
+
+ _mesa_load_state_parameters(ctx, prog->Parameters);
+
+#if 0
+ _mesa_printf("Local Params:\n");
+ for (i = 0; i < MAX_PROGRAM_LOCAL_PARAMS; i++){
+ const GLfloat *p = prog->LocalParams[i];
+ _mesa_printf("%2d: %f, %f, %f, %f\n", i, p[0], p[1], p[2], p[3]);
+ }
+#endif
+ _mesa_print_parameter_list(prog->Parameters);
+}
+
+
+void
+_mesa_print_parameter_list(const struct gl_program_parameter_list *list)
+{
+ const gl_prog_print_mode mode = PROG_PRINT_DEBUG;
+ GLuint i;
+
+ _mesa_printf("param list %p\n", (void *) list);
+ for (i = 0; i < list->NumParameters; i++){
+ struct gl_program_parameter *param = list->Parameters + i;
+ const GLfloat *v = list->ParameterValues[i];
+ _mesa_printf("param[%d] sz=%d %s %s = {%.3g, %.3g, %.3g, %.3g};\n",
+ i, param->Size,
+ file_string(list->Parameters[i].Type, mode),
+ param->Name, v[0], v[1], v[2], v[3]);
+ }
+}
diff --git a/src/mesa/shader/nvvertexec.h b/src/mesa/shader/prog_print.h
index b1cf31bd3c4..9c7607f9d58 100644
--- a/src/mesa/shader/nvvertexec.h
+++ b/src/mesa/shader/prog_print.h
@@ -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"),
@@ -20,48 +20,50 @@
* 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.
- *
- * Authors:
- * Brian Paul
*/
-#ifndef NVVERTEXEC_H
-#define NVVERTEXEC_H
+
+#ifndef PROG_PRINT_H
+#define PROG_PRINT_H
/**
- * Virtual vertex program machine state.
- * Only used during program execution.
+ * The output style to use when printing programs.
*/
-struct vp_machine
-{
- GLfloat Temporaries[MAX_NV_VERTEX_PROGRAM_TEMPS][4];
- GLfloat Inputs[MAX_NV_VERTEX_PROGRAM_INPUTS][4];
- GLuint InputsSize[MAX_NV_VERTEX_PROGRAM_INPUTS];
- GLfloat Outputs[MAX_NV_VERTEX_PROGRAM_OUTPUTS][4];
- GLint AddressReg[4];
-};
+typedef enum {
+ PROG_PRINT_ARB,
+ PROG_PRINT_NV,
+ PROG_PRINT_DEBUG
+} gl_prog_print_mode;
+
+extern const char *
+_mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended);
+extern void
+_mesa_print_alu_instruction(const struct prog_instruction *inst,
+ const char *opcode_string, GLuint numRegs);
extern void
-_mesa_init_vp_per_vertex_registers(GLcontext *ctx, struct vp_machine *machine);
+_mesa_print_instruction(const struct prog_instruction *inst);
+
+extern GLint
+_mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog);
extern void
-_mesa_init_vp_per_primitive_registers(GLcontext *ctx);
+_mesa_print_program(const struct gl_program *prog);
extern void
-_mesa_exec_vertex_program(GLcontext *ctx,
- struct vp_machine *machine,
- const struct gl_vertex_program *program);
+_mesa_print_program_opt(const struct gl_program *prog, gl_prog_print_mode mode,
+ GLboolean lineNumbers);
extern void
-_mesa_exec_vertex_state_program(GLcontext *ctx,
- struct gl_vertex_program *vprog,
- const GLfloat *params);
+_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog);
extern void
-_mesa_dump_vp_state( const struct gl_vertex_program_state *state,
- const struct vp_machine *machine);
+_mesa_print_parameter_list(const struct gl_program_parameter_list *list);
+
-#endif
+#endif /* PROG_PRINT_H */
diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c
new file mode 100644
index 00000000000..953fbb9b9f7
--- /dev/null
+++ b/src/mesa/shader/prog_statevars.c
@@ -0,0 +1,824 @@
+/*
+ * 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.
+ */
+
+/**
+ * \file prog_statevars.c
+ * Program state variable management.
+ * \author Brian Paul
+ */
+
+
+#include "glheader.h"
+#include "context.h"
+#include "hash.h"
+#include "imports.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "prog_statevars.h"
+#include "prog_parameter.h"
+#include "nvvertparse.h"
+
+
+/**
+ * Use the list of tokens in the state[] array to find global GL state
+ * and return it in <value>. Usually, four values are returned in <value>
+ * but matrix queries may return as many as 16 values.
+ * This function is used for ARB vertex/fragment programs.
+ * The program parser will produce the state[] values.
+ */
+static void
+_mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
+ GLfloat *value)
+{
+ switch (state[0]) {
+ case STATE_MATERIAL:
+ {
+ /* state[1] is either 0=front or 1=back side */
+ const GLuint face = (GLuint) state[1];
+ const struct gl_material *mat = &ctx->Light.Material;
+ ASSERT(face == 0 || face == 1);
+ /* we rely on tokens numbered so that _BACK_ == _FRONT_+ 1 */
+ ASSERT(MAT_ATTRIB_FRONT_AMBIENT + 1 == MAT_ATTRIB_BACK_AMBIENT);
+ /* XXX we could get rid of this switch entirely with a little
+ * work in arbprogparse.c's parse_state_single_item().
+ */
+ /* state[2] is the material attribute */
+ switch (state[2]) {
+ case STATE_AMBIENT:
+ COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_AMBIENT + face]);
+ return;
+ case STATE_DIFFUSE:
+ COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_DIFFUSE + face]);
+ return;
+ case STATE_SPECULAR:
+ COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_SPECULAR + face]);
+ return;
+ case STATE_EMISSION:
+ COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_EMISSION + face]);
+ return;
+ case STATE_SHININESS:
+ value[0] = mat->Attrib[MAT_ATTRIB_FRONT_SHININESS + face][0];
+ value[1] = 0.0F;
+ value[2] = 0.0F;
+ value[3] = 1.0F;
+ return;
+ default:
+ _mesa_problem(ctx, "Invalid material state in fetch_state");
+ return;
+ }
+ }
+ case STATE_LIGHT:
+ {
+ /* state[1] is the light number */
+ const GLuint ln = (GLuint) state[1];
+ /* state[2] is the light attribute */
+ switch (state[2]) {
+ case STATE_AMBIENT:
+ COPY_4V(value, ctx->Light.Light[ln].Ambient);
+ return;
+ case STATE_DIFFUSE:
+ COPY_4V(value, ctx->Light.Light[ln].Diffuse);
+ return;
+ case STATE_SPECULAR:
+ COPY_4V(value, ctx->Light.Light[ln].Specular);
+ return;
+ case STATE_POSITION:
+ COPY_4V(value, ctx->Light.Light[ln].EyePosition);
+ return;
+ case STATE_ATTENUATION:
+ value[0] = ctx->Light.Light[ln].ConstantAttenuation;
+ value[1] = ctx->Light.Light[ln].LinearAttenuation;
+ value[2] = ctx->Light.Light[ln].QuadraticAttenuation;
+ value[3] = ctx->Light.Light[ln].SpotExponent;
+ return;
+ case STATE_SPOT_DIRECTION:
+ COPY_3V(value, ctx->Light.Light[ln].EyeDirection);
+ value[3] = ctx->Light.Light[ln]._CosCutoff;
+ return;
+ case STATE_SPOT_CUTOFF:
+ value[0] = ctx->Light.Light[ln].SpotCutoff;
+ return;
+ case STATE_HALF_VECTOR:
+ {
+ GLfloat eye_z[] = {0, 0, 1};
+
+ /* Compute infinite half angle vector:
+ * half-vector = light_position + (0, 0, 1)
+ * and then normalize. w = 0
+ *
+ * light.EyePosition.w should be 0 for infinite lights.
+ */
+ ADD_3V(value, eye_z, ctx->Light.Light[ln].EyePosition);
+ NORMALIZE_3FV(value);
+ value[3] = 0;
+ }
+ return;
+ case STATE_POSITION_NORMALIZED:
+ COPY_4V(value, ctx->Light.Light[ln].EyePosition);
+ NORMALIZE_3FV( value );
+ return;
+ default:
+ _mesa_problem(ctx, "Invalid light state in fetch_state");
+ return;
+ }
+ }
+ case STATE_LIGHTMODEL_AMBIENT:
+ COPY_4V(value, ctx->Light.Model.Ambient);
+ return;
+ case STATE_LIGHTMODEL_SCENECOLOR:
+ if (state[1] == 0) {
+ /* front */
+ GLint i;
+ for (i = 0; i < 3; i++) {
+ value[i] = ctx->Light.Model.Ambient[i]
+ * ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT][i]
+ + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION][i];
+ }
+ value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
+ }
+ else {
+ /* back */
+ GLint i;
+ for (i = 0; i < 3; i++) {
+ value[i] = ctx->Light.Model.Ambient[i]
+ * ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_AMBIENT][i]
+ + ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_EMISSION][i];
+ }
+ value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
+ }
+ return;
+ case STATE_LIGHTPROD:
+ {
+ const GLuint ln = (GLuint) state[1];
+ const GLuint face = (GLuint) state[2];
+ GLint i;
+ ASSERT(face == 0 || face == 1);
+ switch (state[3]) {
+ case STATE_AMBIENT:
+ for (i = 0; i < 3; i++) {
+ value[i] = ctx->Light.Light[ln].Ambient[i] *
+ ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][i];
+ }
+ /* [3] = material alpha */
+ value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3];
+ return;
+ case STATE_DIFFUSE:
+ for (i = 0; i < 3; i++) {
+ value[i] = ctx->Light.Light[ln].Diffuse[i] *
+ ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][i];
+ }
+ /* [3] = material alpha */
+ value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3];
+ return;
+ case STATE_SPECULAR:
+ for (i = 0; i < 3; i++) {
+ value[i] = ctx->Light.Light[ln].Specular[i] *
+ ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][i];
+ }
+ /* [3] = material alpha */
+ value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3];
+ return;
+ default:
+ _mesa_problem(ctx, "Invalid lightprod state in fetch_state");
+ return;
+ }
+ }
+ case STATE_TEXGEN:
+ {
+ /* state[1] is the texture unit */
+ const GLuint unit = (GLuint) state[1];
+ /* state[2] is the texgen attribute */
+ switch (state[2]) {
+ case STATE_TEXGEN_EYE_S:
+ COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneS);
+ return;
+ case STATE_TEXGEN_EYE_T:
+ COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneT);
+ return;
+ case STATE_TEXGEN_EYE_R:
+ COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneR);
+ return;
+ case STATE_TEXGEN_EYE_Q:
+ COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneQ);
+ return;
+ case STATE_TEXGEN_OBJECT_S:
+ COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneS);
+ return;
+ case STATE_TEXGEN_OBJECT_T:
+ COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneT);
+ return;
+ case STATE_TEXGEN_OBJECT_R:
+ COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneR);
+ return;
+ case STATE_TEXGEN_OBJECT_Q:
+ COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneQ);
+ return;
+ default:
+ _mesa_problem(ctx, "Invalid texgen state in fetch_state");
+ return;
+ }
+ }
+ case STATE_TEXENV_COLOR:
+ {
+ /* state[1] is the texture unit */
+ const GLuint unit = (GLuint) state[1];
+ COPY_4V(value, ctx->Texture.Unit[unit].EnvColor);
+ }
+ return;
+ case STATE_FOG_COLOR:
+ COPY_4V(value, ctx->Fog.Color);
+ return;
+ case STATE_FOG_PARAMS:
+ value[0] = ctx->Fog.Density;
+ value[1] = ctx->Fog.Start;
+ value[2] = ctx->Fog.End;
+ value[3] = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
+ return;
+ case STATE_CLIPPLANE:
+ {
+ const GLuint plane = (GLuint) state[1];
+ COPY_4V(value, ctx->Transform.EyeUserPlane[plane]);
+ }
+ return;
+ case STATE_POINT_SIZE:
+ value[0] = ctx->Point.Size;
+ value[1] = ctx->Point.MinSize;
+ value[2] = ctx->Point.MaxSize;
+ value[3] = ctx->Point.Threshold;
+ return;
+ case STATE_POINT_ATTENUATION:
+ value[0] = ctx->Point.Params[0];
+ value[1] = ctx->Point.Params[1];
+ value[2] = ctx->Point.Params[2];
+ value[3] = 1.0F;
+ return;
+ case STATE_MODELVIEW_MATRIX:
+ case STATE_PROJECTION_MATRIX:
+ case STATE_MVP_MATRIX:
+ case STATE_TEXTURE_MATRIX:
+ case STATE_PROGRAM_MATRIX:
+ {
+ /* state[0] = modelview, projection, texture, etc. */
+ /* state[1] = which texture matrix or program matrix */
+ /* state[2] = first row to fetch */
+ /* state[3] = last row to fetch */
+ /* state[4] = transpose, inverse or invtrans */
+ const GLmatrix *matrix;
+ const gl_state_index mat = state[0];
+ const GLuint index = (GLuint) state[1];
+ const GLuint firstRow = (GLuint) state[2];
+ const GLuint lastRow = (GLuint) state[3];
+ const gl_state_index modifier = state[4];
+ const GLfloat *m;
+ GLuint row, i;
+ ASSERT(firstRow >= 0);
+ ASSERT(firstRow < 4);
+ ASSERT(lastRow >= 0);
+ ASSERT(lastRow < 4);
+ if (mat == STATE_MODELVIEW_MATRIX) {
+ matrix = ctx->ModelviewMatrixStack.Top;
+ }
+ else if (mat == STATE_PROJECTION_MATRIX) {
+ matrix = ctx->ProjectionMatrixStack.Top;
+ }
+ else if (mat == STATE_MVP_MATRIX) {
+ matrix = &ctx->_ModelProjectMatrix;
+ }
+ else if (mat == STATE_TEXTURE_MATRIX) {
+ matrix = ctx->TextureMatrixStack[index].Top;
+ }
+ else if (mat == STATE_PROGRAM_MATRIX) {
+ matrix = ctx->ProgramMatrixStack[index].Top;
+ }
+ else {
+ _mesa_problem(ctx, "Bad matrix name in _mesa_fetch_state()");
+ return;
+ }
+ if (modifier == STATE_MATRIX_INVERSE ||
+ modifier == STATE_MATRIX_INVTRANS) {
+ /* Be sure inverse is up to date:
+ */
+ _math_matrix_alloc_inv( (GLmatrix *) matrix );
+ _math_matrix_analyse( (GLmatrix*) matrix );
+ m = matrix->inv;
+ }
+ else {
+ m = matrix->m;
+ }
+ if (modifier == STATE_MATRIX_TRANSPOSE ||
+ modifier == STATE_MATRIX_INVTRANS) {
+ for (i = 0, row = firstRow; row <= lastRow; row++) {
+ value[i++] = m[row * 4 + 0];
+ value[i++] = m[row * 4 + 1];
+ value[i++] = m[row * 4 + 2];
+ value[i++] = m[row * 4 + 3];
+ }
+ }
+ else {
+ for (i = 0, row = firstRow; row <= lastRow; row++) {
+ value[i++] = m[row + 0];
+ value[i++] = m[row + 4];
+ value[i++] = m[row + 8];
+ value[i++] = m[row + 12];
+ }
+ }
+ }
+ return;
+ case STATE_DEPTH_RANGE:
+ value[0] = ctx->Viewport.Near; /* near */
+ value[1] = ctx->Viewport.Far; /* far */
+ value[2] = ctx->Viewport.Far - ctx->Viewport.Near; /* far - near */
+ value[3] = 0;
+ return;
+ case STATE_FRAGMENT_PROGRAM:
+ {
+ /* state[1] = {STATE_ENV, STATE_LOCAL} */
+ /* state[2] = parameter index */
+ const int idx = (int) state[2];
+ switch (state[1]) {
+ case STATE_ENV:
+ COPY_4V(value, ctx->FragmentProgram.Parameters[idx]);
+ break;
+ case STATE_LOCAL:
+ COPY_4V(value, ctx->FragmentProgram.Current->Base.LocalParams[idx]);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()");
+ return;
+ }
+ }
+ return;
+
+ case STATE_VERTEX_PROGRAM:
+ {
+ /* state[1] = {STATE_ENV, STATE_LOCAL} */
+ /* state[2] = parameter index */
+ const int idx = (int) state[2];
+ switch (state[1]) {
+ case STATE_ENV:
+ COPY_4V(value, ctx->VertexProgram.Parameters[idx]);
+ break;
+ case STATE_LOCAL:
+ COPY_4V(value, ctx->VertexProgram.Current->Base.LocalParams[idx]);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()");
+ return;
+ }
+ }
+ return;
+
+ case STATE_NORMAL_SCALE:
+ ASSIGN_4V(value, ctx->_ModelViewInvScale, 0, 0, 1);
+ return;
+
+ case STATE_INTERNAL:
+ switch (state[1]) {
+ case STATE_NORMAL_SCALE:
+ ASSIGN_4V(value, ctx->_ModelViewInvScale, 0, 0, 1);
+ return;
+ case STATE_TEXRECT_SCALE:
+ {
+ const int unit = (int) state[2];
+ const struct gl_texture_object *texObj
+ = ctx->Texture.Unit[unit]._Current;
+ if (texObj) {
+ struct gl_texture_image *texImage = texObj->Image[0][0];
+ ASSIGN_4V(value, 1.0 / texImage->Width,
+ 1.0 / texImage->Height,
+ 0.0, 1.0);
+ }
+ }
+ return;
+ case STATE_FOG_PARAMS_OPTIMIZED:
+ /* for simpler per-vertex/pixel fog calcs. POW (for EXP/EXP2 fog)
+ * might be more expensive than EX2 on some hw, plus it needs
+ * another constant (e) anyway. Linear fog can now be done with a
+ * single MAD.
+ * linear: fogcoord * -1/(end-start) + end/(end-start)
+ * exp: 2^-(density/ln(2) * fogcoord)
+ * exp2: 2^-((density/(ln(2)^2) * fogcoord)^2)
+ */
+ value[0] = -1.0F / (ctx->Fog.End - ctx->Fog.Start);
+ value[1] = ctx->Fog.End / (ctx->Fog.End - ctx->Fog.Start);
+ value[2] = ctx->Fog.Density * ONE_DIV_LN2;
+ value[3] = ctx->Fog.Density * ONE_DIV_SQRT_LN2;
+ return;
+ case STATE_SPOT_DIR_NORMALIZED: {
+ /* here, state[2] is the light number */
+ /* pre-normalize spot dir */
+ const GLuint ln = (GLuint) state[2];
+ COPY_3V(value, ctx->Light.Light[ln].EyeDirection);
+ NORMALIZE_3FV(value);
+ value[3] = ctx->Light.Light[ln]._CosCutoff;
+ return;
+ }
+ default:
+ /* unknown state indexes are silently ignored
+ * should be handled by the driver.
+ */
+ return;
+ }
+ return;
+
+ default:
+ _mesa_problem(ctx, "Invalid state in _mesa_fetch_state");
+ return;
+ }
+}
+
+
+/**
+ * Return a bitmask of the Mesa state flags (_NEW_* values) which would
+ * indicate that the given context state may have changed.
+ * The bitmask is used during validation to determine if we need to update
+ * vertex/fragment program parameters (like "state.material.color") when
+ * some GL state has changed.
+ */
+GLbitfield
+_mesa_program_state_flags(const gl_state_index state[STATE_LENGTH])
+{
+ switch (state[0]) {
+ case STATE_MATERIAL:
+ case STATE_LIGHT:
+ case STATE_LIGHTMODEL_AMBIENT:
+ case STATE_LIGHTMODEL_SCENECOLOR:
+ case STATE_LIGHTPROD:
+ return _NEW_LIGHT;
+
+ case STATE_TEXGEN:
+ case STATE_TEXENV_COLOR:
+ return _NEW_TEXTURE;
+
+ case STATE_FOG_COLOR:
+ case STATE_FOG_PARAMS:
+ return _NEW_FOG;
+
+ case STATE_CLIPPLANE:
+ return _NEW_TRANSFORM;
+
+ case STATE_POINT_SIZE:
+ case STATE_POINT_ATTENUATION:
+ return _NEW_POINT;
+
+ 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;
+
+ case STATE_FRAGMENT_PROGRAM:
+ case STATE_VERTEX_PROGRAM:
+ return _NEW_PROGRAM;
+
+ case STATE_NORMAL_SCALE:
+ return _NEW_MODELVIEW;
+
+ case STATE_INTERNAL:
+ switch (state[1]) {
+ case STATE_TEXRECT_SCALE:
+ return _NEW_TEXTURE;
+ default:
+ /* unknown state indexes are silently ignored and
+ * no flag set, since it is handled by the driver.
+ */
+ return 0;
+ }
+
+ default:
+ _mesa_problem(NULL, "unexpected state[0] in make_state_flags()");
+ return 0;
+ }
+}
+
+
+static void
+append(char *dst, const char *src)
+{
+ while (*dst)
+ dst++;
+ while (*src)
+ *dst++ = *src++;
+ *dst = 0;
+}
+
+
+static void
+append_token(char *dst, gl_state_index k)
+{
+ switch (k) {
+ case STATE_MATERIAL:
+ append(dst, "material");
+ break;
+ case STATE_LIGHT:
+ append(dst, "light");
+ break;
+ case STATE_LIGHTMODEL_AMBIENT:
+ append(dst, "lightmodel.ambient");
+ break;
+ case STATE_LIGHTMODEL_SCENECOLOR:
+ break;
+ case STATE_LIGHTPROD:
+ append(dst, "lightprod");
+ break;
+ case STATE_TEXGEN:
+ append(dst, "texgen");
+ break;
+ case STATE_FOG_COLOR:
+ append(dst, "fog.color");
+ break;
+ case STATE_FOG_PARAMS:
+ append(dst, "fog.params");
+ break;
+ case STATE_CLIPPLANE:
+ append(dst, "clip");
+ break;
+ case STATE_POINT_SIZE:
+ append(dst, "point.size");
+ break;
+ case STATE_POINT_ATTENUATION:
+ append(dst, "point.attenuation");
+ break;
+ case STATE_MODELVIEW_MATRIX:
+ append(dst, "matrix.modelview");
+ break;
+ case STATE_PROJECTION_MATRIX:
+ append(dst, "matrix.projection");
+ break;
+ case STATE_MVP_MATRIX:
+ append(dst, "matrix.mvp");
+ break;
+ case STATE_TEXTURE_MATRIX:
+ append(dst, "matrix.texture");
+ break;
+ case STATE_PROGRAM_MATRIX:
+ append(dst, "matrix.program");
+ break;
+ case STATE_MATRIX_INVERSE:
+ append(dst, ".inverse");
+ break;
+ case STATE_MATRIX_TRANSPOSE:
+ append(dst, ".transpose");
+ break;
+ case STATE_MATRIX_INVTRANS:
+ append(dst, ".invtrans");
+ break;
+ case STATE_AMBIENT:
+ append(dst, ".ambient");
+ break;
+ case STATE_DIFFUSE:
+ append(dst, ".diffuse");
+ break;
+ case STATE_SPECULAR:
+ append(dst, ".specular");
+ break;
+ case STATE_EMISSION:
+ append(dst, ".emission");
+ break;
+ case STATE_SHININESS:
+ append(dst, "lshininess");
+ break;
+ case STATE_HALF_VECTOR:
+ append(dst, ".half");
+ break;
+ case STATE_POSITION:
+ append(dst, ".position");
+ break;
+ case STATE_ATTENUATION:
+ append(dst, ".attenuation");
+ break;
+ case STATE_SPOT_DIRECTION:
+ append(dst, ".spot.direction");
+ break;
+ case STATE_SPOT_CUTOFF:
+ append(dst, ".spot.cutoff");
+ break;
+ case STATE_TEXGEN_EYE_S:
+ append(dst, "eye.s");
+ break;
+ case STATE_TEXGEN_EYE_T:
+ append(dst, "eye.t");
+ break;
+ case STATE_TEXGEN_EYE_R:
+ append(dst, "eye.r");
+ break;
+ case STATE_TEXGEN_EYE_Q:
+ append(dst, "eye.q");
+ break;
+ case STATE_TEXGEN_OBJECT_S:
+ append(dst, "object.s");
+ break;
+ case STATE_TEXGEN_OBJECT_T:
+ append(dst, "object.t");
+ break;
+ case STATE_TEXGEN_OBJECT_R:
+ append(dst, "object.r");
+ break;
+ case STATE_TEXGEN_OBJECT_Q:
+ append(dst, "object.q");
+ break;
+ case STATE_TEXENV_COLOR:
+ append(dst, "texenv");
+ break;
+ case STATE_DEPTH_RANGE:
+ append(dst, "depth.range");
+ break;
+ case STATE_VERTEX_PROGRAM:
+ case STATE_FRAGMENT_PROGRAM:
+ break;
+ case STATE_ENV:
+ append(dst, "env");
+ break;
+ case STATE_LOCAL:
+ append(dst, "local");
+ break;
+ case STATE_NORMAL_SCALE:
+ append(dst, "normalScale");
+ break;
+ case STATE_INTERNAL:
+ case STATE_POSITION_NORMALIZED:
+ append(dst, "(internal)");
+ break;
+ default:
+ ;
+ }
+}
+
+static void
+append_face(char *dst, GLint face)
+{
+ if (face == 0)
+ append(dst, "front.");
+ else
+ append(dst, "back.");
+}
+
+static void
+append_index(char *dst, GLint index)
+{
+ char s[20];
+ _mesa_sprintf(s, "[%d]", index);
+ append(dst, s);
+}
+
+/**
+ * Make a string from the given state vector.
+ * For example, return "state.matrix.texture[2].inverse".
+ * Use _mesa_free() to deallocate the string.
+ */
+const char *
+_mesa_program_state_string(const gl_state_index state[STATE_LENGTH])
+{
+ char str[1000] = "";
+ char tmp[30];
+
+ append(str, "state.");
+ append_token(str, (gl_state_index) state[0]);
+
+ switch (state[0]) {
+ case STATE_MATERIAL:
+ append_face(str, state[1]);
+ append_token(str, (gl_state_index) state[2]);
+ break;
+ case STATE_LIGHT:
+ append_index(str, state[1]); /* light number [i]. */
+ append_token(str, (gl_state_index) state[2]); /* coefficients */
+ break;
+ case STATE_LIGHTMODEL_AMBIENT:
+ append(str, "lightmodel.ambient");
+ break;
+ case STATE_LIGHTMODEL_SCENECOLOR:
+ if (state[1] == 0) {
+ append(str, "lightmodel.front.scenecolor");
+ }
+ else {
+ append(str, "lightmodel.back.scenecolor");
+ }
+ break;
+ case STATE_LIGHTPROD:
+ append_index(str, state[1]); /* light number [i]. */
+ append_face(str, state[2]);
+ append_token(str, (gl_state_index) state[3]);
+ break;
+ case STATE_TEXGEN:
+ append_index(str, state[1]); /* tex unit [i] */
+ append_token(str, (gl_state_index) state[2]); /* plane coef */
+ break;
+ case STATE_TEXENV_COLOR:
+ append_index(str, state[1]); /* tex unit [i] */
+ append(str, "color");
+ break;
+ case STATE_CLIPPLANE:
+ append_index(str, state[1]); /* plane [i] */
+ append(str, ".plane");
+ break;
+ case STATE_MODELVIEW_MATRIX:
+ case STATE_PROJECTION_MATRIX:
+ case STATE_MVP_MATRIX:
+ case STATE_TEXTURE_MATRIX:
+ case STATE_PROGRAM_MATRIX:
+ {
+ /* state[0] = modelview, projection, texture, etc. */
+ /* state[1] = which texture matrix or program matrix */
+ /* state[2] = first row to fetch */
+ /* state[3] = last row to fetch */
+ /* state[4] = transpose, inverse or invtrans */
+ const gl_state_index mat = (gl_state_index) state[0];
+ const GLuint index = (GLuint) state[1];
+ const GLuint firstRow = (GLuint) state[2];
+ const GLuint lastRow = (GLuint) state[3];
+ const gl_state_index modifier = (gl_state_index) state[4];
+ if (index ||
+ mat == STATE_TEXTURE_MATRIX ||
+ mat == STATE_PROGRAM_MATRIX)
+ append_index(str, index);
+ if (modifier)
+ append_token(str, modifier);
+ if (firstRow == lastRow)
+ _mesa_sprintf(tmp, ".row[%d]", firstRow);
+ else
+ _mesa_sprintf(tmp, ".row[%d..%d]", firstRow, lastRow);
+ append(str, tmp);
+ }
+ break;
+ case STATE_POINT_SIZE:
+ break;
+ case STATE_POINT_ATTENUATION:
+ break;
+ case STATE_FOG_PARAMS:
+ break;
+ case STATE_FOG_COLOR:
+ break;
+ case STATE_DEPTH_RANGE:
+ break;
+ case STATE_FRAGMENT_PROGRAM:
+ case STATE_VERTEX_PROGRAM:
+ /* state[1] = {STATE_ENV, STATE_LOCAL} */
+ /* state[2] = parameter index */
+ append_token(str, (gl_state_index) state[1]);
+ append_index(str, state[2]);
+ break;
+ case STATE_INTERNAL:
+ break;
+ default:
+ _mesa_problem(NULL, "Invalid state in _mesa_program_state_string");
+ break;
+ }
+
+ return _mesa_strdup(str);
+}
+
+
+/**
+ * Loop over all the parameters in a parameter list. If the parameter
+ * is a GL state reference, look up the current value of that state
+ * variable and put it into the parameter's Value[4] array.
+ * This would be called at glBegin time when using a fragment program.
+ */
+void
+_mesa_load_state_parameters(GLcontext *ctx,
+ struct gl_program_parameter_list *paramList)
+{
+ GLuint i;
+
+ if (!paramList)
+ return;
+
+ for (i = 0; i < paramList->NumParameters; i++) {
+ if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) {
+ _mesa_fetch_state(ctx,
+ (gl_state_index *) paramList->Parameters[i].StateIndexes,
+ paramList->ParameterValues[i]);
+ }
+ }
+}
+
diff --git a/src/mesa/shader/prog_statevars.h b/src/mesa/shader/prog_statevars.h
new file mode 100644
index 00000000000..3281a4a2a0f
--- /dev/null
+++ b/src/mesa/shader/prog_statevars.h
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+#ifndef PROG_STATEVARS_H
+#define PROG_STATEVARS_H
+
+#include "mtypes.h"
+
+
+/**
+ * Number of STATE_* values we need to address any GL state.
+ * Used to dimension arrays.
+ */
+#define STATE_LENGTH 5
+
+
+/**
+ * Used for describing GL state referenced from inside ARB vertex and
+ * fragment programs.
+ * A string such as "state.light[0].ambient" gets translated into a
+ * sequence of tokens such as [ STATE_LIGHT, 0, STATE_AMBIENT ].
+ *
+ * For state that's an array, like STATE_CLIPPLANE, the 2nd token [1] should
+ * always be the array index.
+ */
+typedef enum gl_state_index_ {
+ STATE_MATERIAL = 100, /* start at 100 so small ints are seen as ints */
+
+ STATE_LIGHT,
+ STATE_LIGHTMODEL_AMBIENT,
+ STATE_LIGHTMODEL_SCENECOLOR,
+ STATE_LIGHTPROD,
+
+ STATE_TEXGEN,
+
+ STATE_FOG_COLOR,
+ STATE_FOG_PARAMS,
+
+ STATE_CLIPPLANE,
+
+ STATE_POINT_SIZE,
+ STATE_POINT_ATTENUATION,
+
+ STATE_MODELVIEW_MATRIX,
+ STATE_PROJECTION_MATRIX,
+ STATE_MVP_MATRIX,
+ STATE_TEXTURE_MATRIX,
+ STATE_PROGRAM_MATRIX,
+ STATE_MATRIX_INVERSE,
+ STATE_MATRIX_TRANSPOSE,
+ STATE_MATRIX_INVTRANS,
+
+ STATE_AMBIENT,
+ STATE_DIFFUSE,
+ STATE_SPECULAR,
+ STATE_EMISSION,
+ STATE_SHININESS,
+ STATE_HALF_VECTOR,
+
+ STATE_POSITION,
+ STATE_ATTENUATION,
+ STATE_SPOT_DIRECTION,
+ STATE_SPOT_CUTOFF,
+
+ STATE_TEXGEN_EYE_S,
+ STATE_TEXGEN_EYE_T,
+ STATE_TEXGEN_EYE_R,
+ STATE_TEXGEN_EYE_Q,
+ STATE_TEXGEN_OBJECT_S,
+ STATE_TEXGEN_OBJECT_T,
+ STATE_TEXGEN_OBJECT_R,
+ STATE_TEXGEN_OBJECT_Q,
+
+ STATE_TEXENV_COLOR,
+
+ STATE_DEPTH_RANGE,
+
+ STATE_VERTEX_PROGRAM,
+ STATE_FRAGMENT_PROGRAM,
+
+ STATE_ENV,
+ STATE_LOCAL,
+
+ STATE_INTERNAL, /* Mesa additions */
+ STATE_NORMAL_SCALE,
+ STATE_TEXRECT_SCALE,
+ STATE_POSITION_NORMALIZED, /* normalized light position */
+ STATE_FOG_PARAMS_OPTIMIZED, /* for faster fog calc */
+ STATE_SPOT_DIR_NORMALIZED, /* pre-normalized spot dir */
+ STATE_INTERNAL_DRIVER /* first available state index for drivers (must be last) */
+} gl_state_index;
+
+
+
+extern void
+_mesa_load_state_parameters(GLcontext *ctx,
+ struct gl_program_parameter_list *paramList);
+
+
+extern GLbitfield
+_mesa_program_state_flags(const gl_state_index state[STATE_LENGTH]);
+
+
+extern const char *
+_mesa_program_state_string(const gl_state_index state[STATE_LENGTH]);
+
+
+#endif /* PROG_STATEVARS_H */
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index 98daf7062f2..e872d78611f 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -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"),
@@ -32,29 +32,13 @@
#include "glheader.h"
#include "context.h"
#include "hash.h"
-#include "imports.h"
-#include "macros.h"
-#include "mtypes.h"
#include "program.h"
-#include "nvfragparse.h"
-#include "program_instruction.h"
-#include "nvvertparse.h"
-#include "atifragshader.h"
+#include "prog_parameter.h"
+#include "prog_instruction.h"
-static const char *
-make_state_string(const GLint stateTokens[6]);
-
-static GLbitfield
-make_state_flags(const GLint state[]);
-
-
-/**********************************************************************/
-/* Utility functions */
-/**********************************************************************/
-
-
-/* A pointer to this dummy program is put into the hash table when
+/**
+ * A pointer to this dummy program is put into the hash table when
* glGenPrograms is called.
*/
struct gl_program _mesa_DummyProgram;
@@ -203,6 +187,7 @@ _mesa_init_program_struct( GLcontext *ctx, struct gl_program *prog,
{
(void) ctx;
if (prog) {
+ _mesa_bzero(prog, sizeof(*prog));
prog->Id = id;
prog->Target = target;
prog->Resident = GL_TRUE;
@@ -303,6 +288,12 @@ _mesa_delete_program(GLcontext *ctx, struct gl_program *prog)
if (prog->Parameters) {
_mesa_free_parameter_list(prog->Parameters);
}
+ if (prog->Varying) {
+ _mesa_free_parameter_list(prog->Varying);
+ }
+ if (prog->Attributes) {
+ _mesa_free_parameter_list(prog->Attributes);
+ }
/* XXX this is a little ugly */
if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
@@ -330,1556 +321,86 @@ _mesa_lookup_program(GLcontext *ctx, GLuint id)
}
-/**********************************************************************/
-/* Program parameter functions */
-/**********************************************************************/
-
-struct gl_program_parameter_list *
-_mesa_new_parameter_list(void)
-{
- return (struct gl_program_parameter_list *)
- _mesa_calloc(sizeof(struct gl_program_parameter_list));
-}
-
-
/**
- * Free a parameter list and all its parameters
+ * Return a copy of a program.
+ * XXX Problem here if the program object is actually OO-derivation
+ * made by a device driver.
*/
-void
-_mesa_free_parameter_list(struct gl_program_parameter_list *paramList)
-{
- GLuint i;
- for (i = 0; i < paramList->NumParameters; i++) {
- if (paramList->Parameters[i].Name)
- _mesa_free((void *) paramList->Parameters[i].Name);
- }
- _mesa_free(paramList->Parameters);
- if (paramList->ParameterValues)
- _mesa_align_free(paramList->ParameterValues);
- _mesa_free(paramList);
-}
-
-
-/**
- * Add a new parameter to a parameter list.
- * \param paramList the list to add the parameter to
- * \param name the parameter name, will be duplicated/copied!
- * \param values initial parameter value, 4 GLfloats
- * \param type type of parameter, such as
- * \return index of new parameter in the list, or -1 if error (out of mem)
- */
-static GLint
-add_parameter(struct gl_program_parameter_list *paramList,
- const char *name, const GLfloat values[4],
- enum register_file type)
-{
- const GLuint n = paramList->NumParameters;
-
- if (n == paramList->Size) {
- /* Need to grow the parameter list array */
- if (paramList->Size == 0)
- paramList->Size = 8;
- else
- paramList->Size *= 2;
-
- /* realloc arrays */
- paramList->Parameters = (struct gl_program_parameter *)
- _mesa_realloc(paramList->Parameters,
- n * sizeof(struct gl_program_parameter),
- paramList->Size * sizeof(struct gl_program_parameter));
-
- paramList->ParameterValues = (GLfloat (*)[4])
- _mesa_align_realloc(paramList->ParameterValues, /* old buf */
- n * 4 * sizeof(GLfloat), /* old size */
- paramList->Size * 4 *sizeof(GLfloat), /* new sz */
- 16);
- }
-
- if (!paramList->Parameters ||
- !paramList->ParameterValues) {
- /* out of memory */
- paramList->NumParameters = 0;
- paramList->Size = 0;
- return -1;
- }
- else {
- paramList->NumParameters = n + 1;
-
- _mesa_memset(&paramList->Parameters[n], 0,
- sizeof(struct gl_program_parameter));
-
- paramList->Parameters[n].Name = name ? _mesa_strdup(name) : NULL;
- paramList->Parameters[n].Type = type;
- if (values)
- COPY_4V(paramList->ParameterValues[n], values);
- return (GLint) n;
- }
-}
-
-
-/**
- * Add a new named program parameter (Ex: NV_fragment_program DEFINE statement)
- * \return index of the new entry in the parameter list
- */
-GLint
-_mesa_add_named_parameter(struct gl_program_parameter_list *paramList,
- const char *name, const GLfloat values[4])
-{
- return add_parameter(paramList, name, values, PROGRAM_NAMED_PARAM);
-}
-
-
-/**
- * Add a new named constant to the parameter list.
- * This will be used when the program contains something like this:
- * PARAM myVals = { 0, 1, 2, 3 };
- *
- * \param paramList the parameter list
- * \param name the name for the constant
- * \param values four float values
- * \return index/position of the new parameter in the parameter list
- */
-GLint
-_mesa_add_named_constant(struct gl_program_parameter_list *paramList,
- const char *name, const GLfloat values[4],
- GLuint size)
-{
-#if 0 /* disable this for now -- we need to save the name! */
- GLuint pos, swizzle;
- ASSERT(size == 4); /* XXX future feature */
- /* check if we already have this constant */
- if (_mesa_lookup_parameter_constant(paramList, values, 4, &pos, &swizzle)) {
- return pos;
- }
-#endif
- return add_parameter(paramList, name, values, PROGRAM_CONSTANT);
-}
-
-
-/**
- * Add a new unnamed constant to the parameter list.
- * This will be used when the program contains something like this:
- * MOV r, { 0, 1, 2, 3 };
- *
- * \param paramList the parameter list
- * \param values four float values
- * \return index/position of the new parameter in the parameter list.
- */
-GLint
-_mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList,
- const GLfloat values[4], GLuint size)
-{
- GLuint pos, swizzle;
- ASSERT(size == 4); /* XXX future feature */
- /* check if we already have this constant */
- if (_mesa_lookup_parameter_constant(paramList, values, 4, &pos, &swizzle)) {
- return pos;
- }
- return add_parameter(paramList, NULL, values, PROGRAM_CONSTANT);
-}
-
-
-/**
- * Add a new state reference to the parameter list.
- * This will be used when the program contains something like this:
- * PARAM ambient = state.material.front.ambient;
- *
- * \param paramList the parameter list
- * \param state an array of 6 state tokens
- * \return index of the new parameter.
- */
-GLint
-_mesa_add_state_reference(struct gl_program_parameter_list *paramList,
- const GLint *stateTokens)
-{
- /* XXX we should probably search the current parameter list to see if
- * the new state reference is already present.
- */
- GLint index;
- const char *name = make_state_string(stateTokens);
-
- index = add_parameter(paramList, name, NULL, PROGRAM_STATE_VAR);
- if (index >= 0) {
- GLuint i;
- for (i = 0; i < 6; i++) {
- paramList->Parameters[index].StateIndexes[i]
- = (enum state_index) stateTokens[i];
- }
- paramList->StateFlags |= make_state_flags(stateTokens);
- }
-
- /* free name string here since we duplicated it in add_parameter() */
- _mesa_free((void *) name);
-
- return index;
-}
-
-
-/**
- * Lookup a parameter value by name in the given parameter list.
- * \return pointer to the float[4] values.
- */
-GLfloat *
-_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList,
- GLsizei nameLen, const char *name)
+struct gl_program *
+_mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)
{
- GLuint i;
+ struct gl_program *clone;
- if (!paramList)
+ clone = _mesa_new_program(ctx, prog->Target, prog->Id);
+ if (!clone)
return NULL;
- if (nameLen == -1) {
- /* name is null-terminated */
- for (i = 0; i < paramList->NumParameters; i++) {
- if (paramList->Parameters[i].Name &&
- _mesa_strcmp(paramList->Parameters[i].Name, name) == 0)
- return paramList->ParameterValues[i];
- }
- }
- else {
- /* name is not null-terminated, use nameLen */
- for (i = 0; i < paramList->NumParameters; i++) {
- if (paramList->Parameters[i].Name &&
- _mesa_strncmp(paramList->Parameters[i].Name, name, nameLen) == 0
- && _mesa_strlen(paramList->Parameters[i].Name) == (size_t)nameLen)
- return paramList->ParameterValues[i];
- }
- }
- return NULL;
-}
-
-
-/**
- * Given a program parameter name, find its position in the list of parameters.
- * \param paramList the parameter list to search
- * \param nameLen length of name (in chars).
- * If length is negative, assume that name is null-terminated.
- * \param name the name to search for
- * \return index of parameter in the list.
- */
-GLint
-_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList,
- GLsizei nameLen, const char *name)
-{
- GLint i;
-
- if (!paramList)
- return -1;
-
- if (nameLen == -1) {
- /* name is null-terminated */
- for (i = 0; i < (GLint) paramList->NumParameters; i++) {
- if (paramList->Parameters[i].Name &&
- _mesa_strcmp(paramList->Parameters[i].Name, name) == 0)
- return i;
- }
- }
- else {
- /* name is not null-terminated, use nameLen */
- for (i = 0; i < (GLint) paramList->NumParameters; i++) {
- if (paramList->Parameters[i].Name &&
- _mesa_strncmp(paramList->Parameters[i].Name, name, nameLen) == 0
- && _mesa_strlen(paramList->Parameters[i].Name) == (size_t)nameLen)
- return i;
- }
- }
- return -1;
-}
-
-
-/**
- * Look for a float vector in the given parameter list. The float vector
- * may be of length 1, 2, 3 or 4.
- * \param paramList the parameter list to search
- * \param v the float vector to search for
- * \param size number of element in v
- * \param posOut returns the position of the constant, if found
- * \param swizzleOut returns a swizzle mask describing location of the
- * vector elements if found
- * \return GL_TRUE if found, GL_FALSE if not found
- */
-GLboolean
-_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *paramList,
- const GLfloat v[], GLsizei vSize,
- GLuint *posOut, GLuint *swizzleOut)
-{
- GLuint i;
-
- assert(vSize >= 1);
- assert(vSize <= 4);
-
- if (!paramList)
- return -1;
-
- for (i = 0; i < paramList->NumParameters; i++) {
- if (paramList->Parameters[i].Type == PROGRAM_CONSTANT) {
- const GLint maxShift = 4 - vSize;
- GLint shift, j;
- for (shift = 0; shift <= maxShift; shift++) {
- GLint matched = 0;
- GLuint swizzle[4];
- swizzle[0] = swizzle[1] = swizzle[2] = swizzle[3] = 0;
- /* XXX we could do out-of-order swizzle matches too, someday */
- for (j = 0; j < vSize; j++) {
- assert(shift + j < 4);
- if (paramList->ParameterValues[i][shift + j] == v[j]) {
- matched++;
- swizzle[j] = shift + j;
- }
- }
- if (matched == vSize) {
- /* found! */
- *posOut = i;
- *swizzleOut = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
- swizzle[2], swizzle[3]);
- return GL_TRUE;
- }
- }
- }
+ assert(clone->Target == prog->Target);
+ clone->String = (GLubyte *) _mesa_strdup((char *) prog->String);
+ clone->RefCount = 1;
+ clone->Format = prog->Format;
+ clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions);
+ if (!clone->Instructions) {
+ _mesa_delete_program(ctx, clone);
+ return NULL;
}
-
- return GL_FALSE;
-}
-
-
-/**
- * Use the list of tokens in the state[] array to find global GL state
- * and return it in <value>. Usually, four values are returned in <value>
- * but matrix queries may return as many as 16 values.
- * This function is used for ARB vertex/fragment programs.
- * The program parser will produce the state[] values.
- */
-static void
-_mesa_fetch_state(GLcontext *ctx, const enum state_index state[],
- GLfloat *value)
-{
- switch (state[0]) {
- case STATE_MATERIAL:
+ _mesa_copy_instructions(clone->Instructions, prog->Instructions,
+ prog->NumInstructions);
+ clone->InputsRead = prog->InputsRead;
+ clone->OutputsWritten = prog->OutputsWritten;
+ memcpy(clone->TexturesUsed, prog->TexturesUsed, sizeof(prog->TexturesUsed));
+
+ if (prog->Parameters)
+ clone->Parameters = _mesa_clone_parameter_list(prog->Parameters);
+ memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams));
+ if (prog->Varying)
+ clone->Varying = _mesa_clone_parameter_list(prog->Varying);
+ if (prog->Attributes)
+ clone->Attributes = _mesa_clone_parameter_list(prog->Attributes);
+ memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams));
+ clone->NumInstructions = prog->NumInstructions;
+ clone->NumTemporaries = prog->NumTemporaries;
+ clone->NumParameters = prog->NumParameters;
+ clone->NumAttributes = prog->NumAttributes;
+ clone->NumAddressRegs = prog->NumAddressRegs;
+ clone->NumNativeInstructions = prog->NumNativeInstructions;
+ clone->NumNativeTemporaries = prog->NumNativeTemporaries;
+ clone->NumNativeParameters = prog->NumNativeParameters;
+ clone->NumNativeAttributes = prog->NumNativeAttributes;
+ clone->NumNativeAddressRegs = prog->NumNativeAddressRegs;
+ clone->NumAluInstructions = prog->NumAluInstructions;
+ clone->NumTexInstructions = prog->NumTexInstructions;
+ clone->NumTexIndirections = prog->NumTexIndirections;
+ clone->NumNativeAluInstructions = prog->NumNativeAluInstructions;
+ clone->NumNativeTexInstructions = prog->NumNativeTexInstructions;
+ clone->NumNativeTexIndirections = prog->NumNativeTexIndirections;
+
+ switch (prog->Target) {
+ case GL_VERTEX_PROGRAM_ARB:
{
- /* state[1] is either 0=front or 1=back side */
- const GLuint face = (GLuint) state[1];
- const struct gl_material *mat = &ctx->Light.Material;
- ASSERT(face == 0 || face == 1);
- /* we rely on tokens numbered so that _BACK_ == _FRONT_+ 1 */
- ASSERT(MAT_ATTRIB_FRONT_AMBIENT + 1 == MAT_ATTRIB_BACK_AMBIENT);
- /* XXX we could get rid of this switch entirely with a little
- * work in arbprogparse.c's parse_state_single_item().
- */
- /* state[2] is the material attribute */
- switch (state[2]) {
- case STATE_AMBIENT:
- COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_AMBIENT + face]);
- return;
- case STATE_DIFFUSE:
- COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_DIFFUSE + face]);
- return;
- case STATE_SPECULAR:
- COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_SPECULAR + face]);
- return;
- case STATE_EMISSION:
- COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_EMISSION + face]);
- return;
- case STATE_SHININESS:
- value[0] = mat->Attrib[MAT_ATTRIB_FRONT_SHININESS + face][0];
- value[1] = 0.0F;
- value[2] = 0.0F;
- value[3] = 1.0F;
- return;
- default:
- _mesa_problem(ctx, "Invalid material state in fetch_state");
- return;
- }
+ const struct gl_vertex_program *vp
+ = (const struct gl_vertex_program *) prog;
+ struct gl_vertex_program *vpc = (struct gl_vertex_program *) clone;
+ vpc->IsPositionInvariant = vp->IsPositionInvariant;
}
- case STATE_LIGHT:
- {
- /* state[1] is the light number */
- const GLuint ln = (GLuint) state[1];
- /* state[2] is the light attribute */
- switch (state[2]) {
- case STATE_AMBIENT:
- COPY_4V(value, ctx->Light.Light[ln].Ambient);
- return;
- case STATE_DIFFUSE:
- COPY_4V(value, ctx->Light.Light[ln].Diffuse);
- return;
- case STATE_SPECULAR:
- COPY_4V(value, ctx->Light.Light[ln].Specular);
- return;
- case STATE_POSITION:
- COPY_4V(value, ctx->Light.Light[ln].EyePosition);
- return;
- case STATE_ATTENUATION:
- value[0] = ctx->Light.Light[ln].ConstantAttenuation;
- value[1] = ctx->Light.Light[ln].LinearAttenuation;
- value[2] = ctx->Light.Light[ln].QuadraticAttenuation;
- value[3] = ctx->Light.Light[ln].SpotExponent;
- return;
- case STATE_SPOT_DIRECTION:
- COPY_3V(value, ctx->Light.Light[ln].EyeDirection);
- value[3] = ctx->Light.Light[ln]._CosCutoff;
- return;
- case STATE_HALF:
- {
- GLfloat eye_z[] = {0, 0, 1};
-
- /* Compute infinite half angle vector:
- * half-vector = light_position + (0, 0, 1)
- * and then normalize. w = 0
- *
- * light.EyePosition.w should be 0 for infinite lights.
- */
- ADD_3V(value, eye_z, ctx->Light.Light[ln].EyePosition);
- NORMALIZE_3FV(value);
- value[3] = 0;
- }
- return;
- case STATE_POSITION_NORMALIZED:
- COPY_4V(value, ctx->Light.Light[ln].EyePosition);
- NORMALIZE_3FV( value );
- return;
- default:
- _mesa_problem(ctx, "Invalid light state in fetch_state");
- return;
- }
- }
- case STATE_LIGHTMODEL_AMBIENT:
- COPY_4V(value, ctx->Light.Model.Ambient);
- return;
- case STATE_LIGHTMODEL_SCENECOLOR:
- if (state[1] == 0) {
- /* front */
- GLint i;
- for (i = 0; i < 3; i++) {
- value[i] = ctx->Light.Model.Ambient[i]
- * ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT][i]
- + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION][i];
- }
- value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
- }
- else {
- /* back */
- GLint i;
- for (i = 0; i < 3; i++) {
- value[i] = ctx->Light.Model.Ambient[i]
- * ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_AMBIENT][i]
- + ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_EMISSION][i];
- }
- value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
- }
- return;
- case STATE_LIGHTPROD:
- {
- const GLuint ln = (GLuint) state[1];
- const GLuint face = (GLuint) state[2];
- GLint i;
- ASSERT(face == 0 || face == 1);
- switch (state[3]) {
- case STATE_AMBIENT:
- for (i = 0; i < 3; i++) {
- value[i] = ctx->Light.Light[ln].Ambient[i] *
- ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][i];
- }
- /* [3] = material alpha */
- value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3];
- return;
- case STATE_DIFFUSE:
- for (i = 0; i < 3; i++) {
- value[i] = ctx->Light.Light[ln].Diffuse[i] *
- ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][i];
- }
- /* [3] = material alpha */
- value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3];
- return;
- case STATE_SPECULAR:
- for (i = 0; i < 3; i++) {
- value[i] = ctx->Light.Light[ln].Specular[i] *
- ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][i];
- }
- /* [3] = material alpha */
- value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3];
- return;
- default:
- _mesa_problem(ctx, "Invalid lightprod state in fetch_state");
- return;
- }
- }
- case STATE_TEXGEN:
- {
- /* state[1] is the texture unit */
- const GLuint unit = (GLuint) state[1];
- /* state[2] is the texgen attribute */
- switch (state[2]) {
- case STATE_TEXGEN_EYE_S:
- COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneS);
- return;
- case STATE_TEXGEN_EYE_T:
- COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneT);
- return;
- case STATE_TEXGEN_EYE_R:
- COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneR);
- return;
- case STATE_TEXGEN_EYE_Q:
- COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneQ);
- return;
- case STATE_TEXGEN_OBJECT_S:
- COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneS);
- return;
- case STATE_TEXGEN_OBJECT_T:
- COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneT);
- return;
- case STATE_TEXGEN_OBJECT_R:
- COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneR);
- return;
- case STATE_TEXGEN_OBJECT_Q:
- COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneQ);
- return;
- default:
- _mesa